diff options
author | Brian Evans <grknight@gentoo.org> | 2022-11-02 09:23:17 -0400 |
---|---|---|
committer | Brian Evans <grknight@gentoo.org> | 2022-11-02 09:23:17 -0400 |
commit | acb25f28f67e141f3a9ea26f19a8f79bfe8fde35 (patch) | |
tree | 7392ebb2f04ffc6da9339f22cb4efc6a8b9c5050 | |
parent | Update DisableAccount to master as of 2022-11-02 (diff) | |
download | extensions-acb25f28f67e141f3a9ea26f19a8f79bfe8fde35.tar.gz extensions-acb25f28f67e141f3a9ea26f19a8f79bfe8fde35.tar.bz2 extensions-acb25f28f67e141f3a9ea26f19a8f79bfe8fde35.zip |
Update Echo to master as of 2022-11-02
Signed-off-by: Brian Evans <grknight@gentoo.org>
502 files changed, 22855 insertions, 9712 deletions
diff --git a/Echo/.eslintignore b/Echo/.eslintignore new file mode 100644 index 00000000..e3a484ca --- /dev/null +++ b/Echo/.eslintignore @@ -0,0 +1,8 @@ +# Build +/vendor/ +/docs/ + +# Language files written automatically by TranslateWiki +/**/i18n/**/*.json +!/**/i18n/**/en.json +!/**/i18n/**/qqq.json diff --git a/Echo/.eslintrc.json b/Echo/.eslintrc.json index 742b306d..f77c254b 100644 --- a/Echo/.eslintrc.json +++ b/Echo/.eslintrc.json @@ -1,15 +1,7 @@ { "root": true, "extends": [ - "wikimedia/client", - "wikimedia/jquery", - "wikimedia/mediawiki" - ], - "env": { - "commonjs": true - }, - "rules": { - "max-len": "off", - "mediawiki/class-doc": "warn" - } + "wikimedia/server", + "wikimedia/jsduck" + ] } diff --git a/Echo/.gitignore b/Echo/.gitignore index b61d4e07..74882eb4 100644 --- a/Echo/.gitignore +++ b/Echo/.gitignore @@ -5,6 +5,8 @@ scripts/remotes/ /docs composer.lock .eslintcache +/tests/selenium/log +.DS_STORE # Editors *.kate-swp diff --git a/Echo/.mailmap b/Echo/.mailmap index b970c896..0fe9e842 100644 --- a/Echo/.mailmap +++ b/Echo/.mailmap @@ -3,9 +3,10 @@ Erik Bernhardson <ebernhardson@wikimedia.org> Jon Robson <jrobson@wikimedia.org> Jon Robson <jrobson@wikimedia.org> <jdlrobson@gmail.com> Luke Welling <lwelling@wikimedia.org> -Kunal Mehta <legoktm@gmail.com> -Kunal Mehta <legoktm@gmail.com> <legoktm@member.fsf.org> -Kunal Mehta <legoktm@gmail.com> <legoktm.wikpedia@gmail.com> +Kunal Mehta <legoktm@debian.org> +Kunal Mehta <legoktm@debian.org> <legoktm@member.fsf.org> +Kunal Mehta <legoktm@debian.org> <legoktm.wikipedia@gmail.com> +Kunal Mehta <legoktm@debian.org> <legoktm@gmail.com> Max Semenik <maxsem.wiki@gmail.com> Niklas Laxström <niklas.laxstrom@gmail.com> Roan Kattouw <roan.kattouw@gmail.com> diff --git a/Echo/.phpcs.xml b/Echo/.phpcs.xml index d463e42c..68ddc529 100644 --- a/Echo/.phpcs.xml +++ b/Echo/.phpcs.xml @@ -6,11 +6,13 @@ <exclude name="MediaWiki.Files.ClassMatchesFilename.NotMatch" /> <exclude name="MediaWiki.Commenting.FunctionComment.MissingDocumentationProtected" /> <exclude name="MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic" /> + <exclude name="MediaWiki.Commenting.FunctionComment.WrongStyle" /> <exclude name="MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName" /> + <exclude name="MediaWiki.PHPUnit.AssertEmpty.AssertEmptyUsed" /> + <exclude name="MediaWiki.Usage.ExtendClassUsage.FunctionConfigUsage" /> <exclude name="MediaWiki.WhiteSpace.SpaceBeforeSingleLineComment.NewLineComment" /> - <exclude name="PSR12.Properties.ConstantVisibility.NotFound" /> </rule> <arg name="encoding" value="UTF-8" /> - <arg name="extensions" value="php,php5,inc" /> + <arg name="extensions" value="php" /> <arg name="colors" /> </ruleset> diff --git a/Echo/.stylelintrc.json b/Echo/.stylelintrc.json index dab9de6b..79cb9b79 100644 --- a/Echo/.stylelintrc.json +++ b/Echo/.stylelintrc.json @@ -1,7 +1,11 @@ { - "extends": "stylelint-config-wikimedia", + "extends": [ + "stylelint-config-wikimedia/support-modern", + "stylelint-config-wikimedia/mediawiki" + ], "rules": { "declaration-no-important": null, - "selector-max-id": null + "selector-max-id": null, + "declaration-property-unit-disallowed-list": null } } diff --git a/Echo/.svgo.config.js b/Echo/.svgo.config.js new file mode 100644 index 00000000..9b21d28a --- /dev/null +++ b/Echo/.svgo.config.js @@ -0,0 +1,43 @@ +/** + * SVGO Configuration + * Compatible to v2.4.0+ + * Recommended options from: + * https://www.mediawiki.org/wiki/Manual:Coding_conventions/SVG#Exemplified_safe_configuration + */ + +'use strict'; + +module.exports = { + plugins: [ + { + // Set of built-in plugins enabled by default. + name: 'preset-default', + params: { + overrides: { + cleanupIDs: false, + removeDesc: false, + removeTitle: false, + removeViewBox: false, + // If the SVG doesn't start with an XML declaration, then its MIME type will + // be detected as "text/plain" rather than "image/svg+xml" by libmagic and, + // consequently, MediaWiki's CSSMin CSS minifier. libmagic's default database + // currently requires that SVGs contain an XML declaration: + // https://github.com/threatstack/libmagic/blob/master/magic/Magdir/sgml#L5 + removeXMLProcInst: false + } + } + }, + 'removeRasterImages', + 'sortAttrs' + ], + // Set whitespace according to Wikimedia Coding Conventions. + // @see https://github.com/svg/svgo/blob/main/lib/svgo/coa.js#L194 for more config options + js2svg: { + eol: 'lf', + finalNewline: true, + // Configure the indent to tabs (default 4 spaces) used by `--pretty` here. + indent: '\t', + pretty: true + }, + multipass: true +}; diff --git a/Echo/Echo.alias.php b/Echo/Echo.alias.php index 193e00df..61b6c319 100644 --- a/Echo/Echo.alias.php +++ b/Echo/Echo.alias.php @@ -137,6 +137,11 @@ $specialPageAliases['ko'] = [ 'Notifications' => [ '알림' ], ]; +/** Kurdish (Latin script) (Kurdî (latînî)) */ +$specialPageAliases['ku-latn'] = [ + 'Notifications' => [ 'Agahdarî' ], +]; + /** Cornish (kernowek) */ $specialPageAliases['kw'] = [ 'Notifications' => [ 'Argemynow' ], diff --git a/Echo/Gruntfile.js b/Echo/Gruntfile.js index bdf44714..70b65ade 100644 --- a/Echo/Gruntfile.js +++ b/Echo/Gruntfile.js @@ -1,12 +1,12 @@ -/* eslint-env node, es6 */ +'use strict'; + module.exports = function ( grunt ) { - var conf = grunt.file.readJSON( 'extension.json' ); + const conf = grunt.file.readJSON( 'extension.json' ); grunt.loadNpmTasks( 'grunt-banana-checker' ); grunt.loadNpmTasks( 'grunt-contrib-watch' ); grunt.loadNpmTasks( 'grunt-eslint' ); grunt.loadNpmTasks( 'grunt-stylelint' ); - grunt.loadNpmTasks( 'grunt-svgmin' ); grunt.initConfig( { eslint: { @@ -15,57 +15,15 @@ module.exports = function ( grunt ) { fix: grunt.option( 'fix' ) }, all: [ - '**/*.{js,json}', - '!{tests/externals,docs}/**', - '!{vendor,node_modules}/**' + '.' ] }, // Lint – Styling stylelint: { - options: { - syntax: 'less' - }, all: [ 'modules/**/*.{css,less}' ] }, - // SVG Optimization - svgmin: { - options: { - js2svg: { - indent: '\t', - pretty: true - }, - multipass: true, - plugins: [ { - cleanupIDs: false - }, { - removeDesc: false - }, { - removeRasterImages: true - }, { - removeTitle: false - }, { - removeViewBox: false - }, { - removeXMLProcInst: false - }, { - sortAttrs: true - } ] - }, - all: { - files: [ { - expand: true, - cwd: 'modules/icons', - src: [ - '**/*.svg' - ], - dest: 'modules/icons/', - ext: '.svg' - } ] - } - }, - // eslint-disable-next-line es/no-object-assign banana: Object.assign( { options: { requireLowerCase: false } }, conf.MessagesDirs ), @@ -79,8 +37,7 @@ module.exports = function ( grunt ) { } } ); - grunt.registerTask( 'minify', 'svgmin' ); grunt.registerTask( 'lint', [ 'eslint', 'stylelint', 'banana' ] ); grunt.registerTask( 'test', 'lint' ); - grunt.registerTask( 'default', [ 'minify', 'test' ] ); + grunt.registerTask( 'default', [ 'test' ] ); }; diff --git a/Echo/ServiceWiring.php b/Echo/ServiceWiring.php index 62558f25..af20a8b3 100644 --- a/Echo/ServiceWiring.php +++ b/Echo/ServiceWiring.php @@ -1,15 +1,34 @@ <?php -use EchoPush\NotificationServiceClient; -use EchoPush\SubscriptionManager; +use MediaWiki\Extension\Notifications\Push\NotificationServiceClient; +use MediaWiki\Extension\Notifications\Push\SubscriptionManager; use MediaWiki\Logger\LoggerFactory; use MediaWiki\MediaWikiServices; use MediaWiki\Storage\NameTableStore; return [ - 'EchoPushNotificationServiceClient' => function ( MediaWikiServices $services ): - NotificationServiceClient { + 'EchoAttributeManager' => static function ( MediaWikiServices $services ): EchoAttributeManager { + $userGroupManager = $services->getUserGroupManager(); + $echoConfig = $services->getConfigFactory()->makeConfig( 'Echo' ); + $notifications = $echoConfig->get( 'EchoNotifications' ); + $categories = $echoConfig->get( 'EchoNotificationCategories' ); + $typeAvailability = $echoConfig->get( 'DefaultNotifyTypeAvailability' ); + $typeAvailabilityByCategory = $echoConfig->get( 'NotifyTypeAvailabilityByCategory' ); + + return new EchoAttributeManager( + $notifications, + $categories, + $typeAvailability, + $typeAvailabilityByCategory, + $userGroupManager, + $services->getUserOptionsLookup() + ); + }, + + 'EchoPushNotificationServiceClient' => static function ( + MediaWikiServices $services + ): NotificationServiceClient { $echoConfig = $services->getConfigFactory()->makeConfig( 'Echo' ); $httpRequestFactory = $services->getHttpRequestFactory(); $url = $echoConfig->get( 'EchoPushServiceBaseUrl' ); @@ -18,7 +37,7 @@ return [ return $client; }, - 'EchoPushSubscriptionManager' => function ( MediaWikiServices $services ): SubscriptionManager { + 'EchoPushSubscriptionManager' => static function ( MediaWikiServices $services ): SubscriptionManager { $echoConfig = $services->getConfigFactory()->makeConfig( 'Echo' ); // Use shared DB/cluster for push subscriptions $cluster = $echoConfig->get( 'EchoSharedTrackingCluster' ); @@ -27,10 +46,8 @@ return [ $loadBalancer = $cluster ? $loadBalancerFactory->getExternalLB( $cluster ) : $loadBalancerFactory->getMainLB( $database ); - $dbw = $loadBalancer->getLazyConnectionRef( DB_MASTER, [], $database ); - $dbr = $loadBalancer->getLazyConnectionRef( DB_REPLICA, [], $database ); - - $centralIdLookup = CentralIdLookup::factory(); + $dbw = $loadBalancer->getConnectionRef( DB_PRIMARY, [], $database ); + $dbr = $loadBalancer->getConnectionRef( DB_REPLICA, [], $database ); $pushProviderStore = new NameTableStore( $loadBalancer, @@ -43,7 +60,26 @@ return [ $database ); - return new SubscriptionManager( $dbw, $dbr, $centralIdLookup, $pushProviderStore ); + $pushTopicStore = new NameTableStore( + $loadBalancer, + $services->getMainWANObjectCache(), + LoggerFactory::getInstance( 'Echo' ), + 'echo_push_topic', + 'ept_id', + 'ept_text', + null, + $database + ); + + $maxSubscriptionsPerUser = $echoConfig->get( 'EchoPushMaxSubscriptionsPerUser' ); + + return new SubscriptionManager( + $dbw, + $dbr, + $pushProviderStore, + $pushTopicStore, + $maxSubscriptionsPerUser + ); } ]; diff --git a/Echo/composer.json b/Echo/composer.json index 5fc76235..9811f68f 100644 --- a/Echo/composer.json +++ b/Echo/composer.json @@ -1,20 +1,22 @@ { "require-dev": { - "mediawiki/mediawiki-codesniffer": "31.0.0", - "mediawiki/mediawiki-phan-config": "0.10.2", - "mediawiki/minus-x": "1.1.0", - "php-parallel-lint/php-console-highlighter": "0.5.0", - "php-parallel-lint/php-parallel-lint": "1.2.0" + "mediawiki/mediawiki-codesniffer": "39.0.0", + "mediawiki/mediawiki-phan-config": "0.12.0", + "mediawiki/minus-x": "1.1.1", + "php-parallel-lint/php-console-highlighter": "1.0.0", + "php-parallel-lint/php-parallel-lint": "1.3.2" }, "scripts": { "test": [ "parallel-lint . --exclude vendor --exclude node_modules", - "phpcs -p -s", + "@phpcs", "minus-x check ." ], "fix": [ "minus-x fix .", "phpcbf" - ] + ], + "phan": "phan -d . --long-progress-bar", + "phpcs": "phpcs -sp --cache" } } diff --git a/Echo/db_patches/echo_email_batch.sql b/Echo/db_patches/echo_email_batch.sql deleted file mode 100644 index 825eec00..00000000 --- a/Echo/db_patches/echo_email_batch.sql +++ /dev/null @@ -1,9 +0,0 @@ -CREATE TABLE /*_*/echo_email_batch ( - eeb_id int unsigned not null primary key auto_increment, - eeb_user_id int unsigned not null, - eeb_event_priority tinyint unsigned not null default 10, -- event priority - eeb_event_id int unsigned not null -) /*$wgDBTableOptions*/; - -CREATE UNIQUE INDEX /*i*/echo_email_batch_user_event ON /*_*/echo_email_batch (eeb_user_id,eeb_event_id); -CREATE UNIQUE INDEX /*i*/echo_email_batch_user_priority_event ON /*_*/echo_email_batch (eeb_user_id,eeb_event_priority,eeb_event_id); diff --git a/Echo/db_patches/echo_target_page.sql b/Echo/db_patches/echo_target_page.sql deleted file mode 100644 index f6e5c4a2..00000000 --- a/Echo/db_patches/echo_target_page.sql +++ /dev/null @@ -1,8 +0,0 @@ -CREATE TABLE /*_*/echo_target_page ( - etp_user int unsigned not null default 0, - etp_page int unsigned not null default 0, - etp_event int unsigned not null default 0 -) /*$wgDBTableOptions*/; - -CREATE UNIQUE INDEX /*i*/echo_target_page_user_event ON /*_*/echo_target_page (etp_user, etp_event); -CREATE INDEX /*i*/echo_target_page_user_page_event ON /*_*/echo_target_page (etp_user, etp_page, etp_event); diff --git a/Echo/db_patches/echo_unread_wikis.sql b/Echo/db_patches/echo_unread_wikis.sql deleted file mode 100644 index 32f9c837..00000000 --- a/Echo/db_patches/echo_unread_wikis.sql +++ /dev/null @@ -1,18 +0,0 @@ -CREATE TABLE /*_*/echo_unread_wikis ( - # Primary key - euw_id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, - # Global user id - euw_user INT UNSIGNED NOT NULL, - # Name of wiki - euw_wiki VARCHAR(64) NOT NULL, - # unread alerts count on that wiki - euw_alerts INT UNSIGNED NOT NULL, - # Timestamp of the most recent unread alert - euw_alerts_ts BINARY(14) NOT NULL, - # unread messages count on that wiki - euw_messages INT UNSIGNED NOT NULL, - # Timestamp of the most recent unread message - euw_messages_ts BINARY(14) NOT NULL -) /*$wgDBTableOptions*/; - -CREATE UNIQUE INDEX /*i*/echo_unread_wikis_user_wiki ON /*_*/echo_unread_wikis (euw_user,euw_wiki); diff --git a/Echo/db_patches/patch-add-echo_event-event_deleted.sql b/Echo/db_patches/patch-add-echo_event-event_deleted.sql deleted file mode 100644 index 3d8d61fd..00000000 --- a/Echo/db_patches/patch-add-echo_event-event_deleted.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE /*_*/echo_event ADD COLUMN event_deleted tinyint unsigned NOT NULL DEFAULT 0; diff --git a/Echo/db_patches/patch-add-echo_event-event_page_id.sql b/Echo/db_patches/patch-add-echo_event-event_page_id.sql deleted file mode 100644 index 3c4ae714..00000000 --- a/Echo/db_patches/patch-add-echo_event-event_page_id.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE /*_*/echo_event ADD event_page_id int unsigned; diff --git a/Echo/db_patches/patch-add-event_page_id-index.sql b/Echo/db_patches/patch-add-event_page_id-index.sql deleted file mode 100644 index b3b99eeb..00000000 --- a/Echo/db_patches/patch-add-event_page_id-index.sql +++ /dev/null @@ -1 +0,0 @@ -CREATE INDEX /*i*/echo_event_page_id ON /*_*/echo_event (event_page_id); diff --git a/Echo/db_patches/patch-add-notification_event-index.sql b/Echo/db_patches/patch-add-notification_event-index.sql deleted file mode 100644 index 1243b804..00000000 --- a/Echo/db_patches/patch-add-notification_event-index.sql +++ /dev/null @@ -1 +0,0 @@ -CREATE INDEX /*i*/echo_notification_event ON /*_*/echo_notification (notification_event); diff --git a/Echo/db_patches/patch-add-page_event-index.sql b/Echo/db_patches/patch-add-page_event-index.sql deleted file mode 100644 index d656fd0f..00000000 --- a/Echo/db_patches/patch-add-page_event-index.sql +++ /dev/null @@ -1 +0,0 @@ -CREATE INDEX /*i*/echo_target_page_page_event ON /*_*/echo_target_page (etp_page, etp_event); diff --git a/Echo/db_patches/patch-add-user_read_timestamp-index.sql b/Echo/db_patches/patch-add-user_read_timestamp-index.sql deleted file mode 100644 index 012e4371..00000000 --- a/Echo/db_patches/patch-add-user_read_timestamp-index.sql +++ /dev/null @@ -1 +0,0 @@ -CREATE INDEX /*i*/echo_notification_user_read_timestamp ON /*_*/echo_notification (notification_user, notification_read_timestamp); diff --git a/Echo/db_patches/patch-alter-event_type-index.sql b/Echo/db_patches/patch-alter-event_type-index.sql deleted file mode 100644 index 2bfb2b0b..00000000 --- a/Echo/db_patches/patch-alter-event_type-index.sql +++ /dev/null @@ -1,3 +0,0 @@ -DROP INDEX /*i*/event_type ON /*_*/echo_event; - -CREATE INDEX /*i*/echo_event_type ON /*_*/echo_event (event_type); diff --git a/Echo/db_patches/patch-alter-type_page-index.sql b/Echo/db_patches/patch-alter-type_page-index.sql deleted file mode 100644 index e43b4519..00000000 --- a/Echo/db_patches/patch-alter-type_page-index.sql +++ /dev/null @@ -1,3 +0,0 @@ -DROP INDEX /*i*/type_page ON /*_*/echo_event; - -CREATE INDEX /*i*/event_type ON /*_*/echo_event (event_type); diff --git a/Echo/db_patches/patch-alter-user_timestamp-index.sql b/Echo/db_patches/patch-alter-user_timestamp-index.sql deleted file mode 100644 index e5710c4f..00000000 --- a/Echo/db_patches/patch-alter-user_timestamp-index.sql +++ /dev/null @@ -1,2 +0,0 @@ -CREATE INDEX /*i*/echo_user_timestamp ON /*_*/echo_notification (notification_user, notification_timestamp); -DROP INDEX /*i*/user_timestamp ON /*_*/echo_notification; diff --git a/Echo/db_patches/patch-drop-echo_event-event_timestamp.sql b/Echo/db_patches/patch-drop-echo_event-event_timestamp.sql deleted file mode 100644 index 57f6331a..00000000 --- a/Echo/db_patches/patch-drop-echo_event-event_timestamp.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE /*_*/echo_event DROP event_timestamp; diff --git a/Echo/db_patches/patch-drop-echo_subscription.sql b/Echo/db_patches/patch-drop-echo_subscription.sql deleted file mode 100644 index f04a4f0a..00000000 --- a/Echo/db_patches/patch-drop-echo_subscription.sql +++ /dev/null @@ -1,2 +0,0 @@ --- drop this table because subscription is not supported -DROP TABLE /*_*/echo_subscription; diff --git a/Echo/db_patches/patch-drop-echo_target_page-etp_user.sql b/Echo/db_patches/patch-drop-echo_target_page-etp_user.sql deleted file mode 100644 index dad413cb..00000000 --- a/Echo/db_patches/patch-drop-echo_target_page-etp_user.sql +++ /dev/null @@ -1,11 +0,0 @@ --- Patch to drop unused etp_user - --- Drop indexes depending on etp_user -DROP INDEX /*i*/echo_target_page_user_event ON /*_*/echo_target_page; -DROP INDEX /*i*/echo_target_page_user_page_event ON /*_*/echo_target_page; - --- Drop etp_user column -ALTER TABLE /*_*/echo_target_page DROP etp_user; - --- Add index on etp_event -CREATE INDEX /*i*/echo_target_page_event ON /*_*/echo_target_page (etp_event); diff --git a/Echo/db_patches/patch-drop-echo_target_page-etp_user.sqlite.sql b/Echo/db_patches/patch-drop-echo_target_page-etp_user.sqlite.sql deleted file mode 100644 index 17aec6e2..00000000 --- a/Echo/db_patches/patch-drop-echo_target_page-etp_user.sqlite.sql +++ /dev/null @@ -1,26 +0,0 @@ --- Patch to drop unused etp_user - --- give current table temporary name -ALTER TABLE /*_*/echo_target_page RENAME TO /*_*/temp_echo_target_page; - --- recreate table without etp_user -CREATE TABLE /*_*/echo_target_page ( - etp_id int unsigned not null primary key auto_increment, - etp_page int unsigned not null default 0, - etp_event int unsigned not null default 0 -) /*$wgDBTableOptions*/; - --- copy over old data into new table -INSERT INTO /*_*/echo_target_page - (etp_page, etp_event) -SELECT DISTINCT - etp_page, etp_event -FROM - /*_*/temp_echo_target_page; - --- drop the original table -DROP TABLE /*_*/temp_echo_target_page; - --- recreate indexes -CREATE INDEX /*i*/echo_target_page_event ON /*_*/echo_target_page (etp_event); -CREATE INDEX /*i*/echo_target_page_page_event ON /*_*/echo_target_page (etp_page, etp_event); diff --git a/Echo/db_patches/patch-email_batch-new-field.sql b/Echo/db_patches/patch-email_batch-new-field.sql deleted file mode 100644 index f25f913b..00000000 --- a/Echo/db_patches/patch-email_batch-new-field.sql +++ /dev/null @@ -1,7 +0,0 @@ -ALTER TABLE /*_*/echo_email_batch ADD COLUMN eeb_event_hash varchar(32) binary not null default ''; - -DROP INDEX /*i*/echo_email_batch_user_priority_event ON /*_*/echo_email_batch; - -CREATE INDEX /*i*/echo_email_batch_user_hash_priority ON /*_*/echo_email_batch (eeb_user_id, eeb_event_hash, eeb_event_priority); - - diff --git a/Echo/db_patches/patch-event_agent-split.sql b/Echo/db_patches/patch-event_agent-split.sql deleted file mode 100644 index b543e858..00000000 --- a/Echo/db_patches/patch-event_agent-split.sql +++ /dev/null @@ -1,4 +0,0 @@ --- 2012-05-06: Split event_agent field to allow anonymous agents. - -ALTER TABLE echo_event CHANGE COLUMN event_agent event_agent_id int unsigned null; -ALTER TABLE echo_event ADD COLUMN event_agent_ip varchar(255) binary null;
\ No newline at end of file diff --git a/Echo/db_patches/patch-event_agent-split.sqlite.sql b/Echo/db_patches/patch-event_agent-split.sqlite.sql deleted file mode 100644 index 3650e86c..00000000 --- a/Echo/db_patches/patch-event_agent-split.sqlite.sql +++ /dev/null @@ -1,34 +0,0 @@ --- Split event_agent field to allow anonymous agents -ALTER TABLE echo_event ADD COLUMN event_agent_id int unsigned null; -ALTER TABLE echo_event ADD COLUMN event_agent_ip varchar binary null; -UPDATE echo_event SET event_agent_id = event_agent; - --- Rename current table to temporary name -ALTER TABLE /*_*/echo_event RENAME TO /*_*/temp_echo_event_split_event_agent; - --- Recreate table using the proper nullability constraint for event_variant -CREATE TABLE /*_*/echo_event ( - event_id int unsigned not null primary key auto_increment, - event_type varchar(64) binary not null, - event_variant varchar(64) binary null, - event_agent_id int unsigned null, -- The user who triggered it, if any - event_agent_ip varchar(39) binary null, -- IP address who triggered it, if any - event_page_title varchar(255) binary null, - event_extra BLOB NULL -) /*$wgDBTableOptions*/; - --- Copy over all the old data into the new table -INSERT INTO /*_*/echo_event - (event_id, event_type, event_variant, event_agent_id, event_page_title, event_extra) -SELECT - event_id, event_type, event_variant, event_agent, event_page_title, event_extra -FROM - /*_*/temp_echo_event_split_event_agent; - --- Drop the original table -DROP TABLE /*_*/temp_echo_event_split_event_agent; - --- recreate indexes -CREATE INDEX /*i*/echo_event_type ON /*_*/echo_event (event_type); - - diff --git a/Echo/db_patches/patch-event_agent_ip-size.sql b/Echo/db_patches/patch-event_agent_ip-size.sql deleted file mode 100644 index 5ba0bb2c..00000000 --- a/Echo/db_patches/patch-event_agent_ip-size.sql +++ /dev/null @@ -1,2 +0,0 @@ --- Patch to update ip size from varbinary(255) to varbinary(39) -ALTER TABLE /*_*/echo_event CHANGE COLUMN event_agent_ip event_agent_ip varchar(39) binary NULL; diff --git a/Echo/db_patches/patch-event_extra-size.sql b/Echo/db_patches/patch-event_extra-size.sql deleted file mode 100644 index 0f67672f..00000000 --- a/Echo/db_patches/patch-event_extra-size.sql +++ /dev/null @@ -1,2 +0,0 @@ --- Patch to add extra space to event_extra -alter table /*_*/echo_event change column event_extra event_extra BLOB NULL;
\ No newline at end of file diff --git a/Echo/db_patches/patch-event_variant_nullability.sql b/Echo/db_patches/patch-event_variant_nullability.sql deleted file mode 100644 index 4a1d5e0c..00000000 --- a/Echo/db_patches/patch-event_variant_nullability.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE /*_*/echo_event CHANGE COLUMN event_variant event_variant varchar(64) binary null;
\ No newline at end of file diff --git a/Echo/db_patches/patch-event_variant_nullability.sqlite.sql b/Echo/db_patches/patch-event_variant_nullability.sqlite.sql deleted file mode 100644 index f5988f96..00000000 --- a/Echo/db_patches/patch-event_variant_nullability.sqlite.sql +++ /dev/null @@ -1,33 +0,0 @@ --- Sqlites alter table statement can NOT change existing columns. The only --- option since we need to change the nullability of event_variant is to --- recreate the table and copy the data over. - --- Rename current table to temporary name -ALTER TABLE /*_*/echo_event RENAME TO /*_*/temp_echo_event_variant_nullability; - --- Recreate table using the proper nullability constraint for event_variant -CREATE TABLE /*_*/echo_event ( - event_id int unsigned not null primary key auto_increment, - event_type varchar(64) binary not null, - event_variant varchar(64) binary null, - event_agent_id int unsigned null, -- The user who triggered it, if any - event_agent_ip varchar(39) binary null, -- IP address who triggered it, if any - event_extra BLOB NULL, - event_page_id int unsigned null, - event_deleted tinyint unsigned not null default 0 -) /*$wgDBTableOptions*/; - --- Copy over all the old data into the new table -INSERT INTO /*_*/echo_event - (event_id, event_type, event_variant, event_agent_id, event_agent_ip, event_extra, event_page_id, event_deleted) -SELECT - event_id, event_type, event_variant, event_agent_id, event_agent_ip, event_extra, event_page_id, event_deleted -FROM - /*_*/temp_echo_event_variant_nullability; - --- Drop the original table -DROP TABLE /*_*/temp_echo_event_variant_nullability; - --- recreate indexes -CREATE INDEX /*i*/echo_event_type ON /*_*/echo_event (event_type); - diff --git a/Echo/db_patches/patch-multiple_target_pages.sql b/Echo/db_patches/patch-multiple_target_pages.sql deleted file mode 100644 index 5d574f95..00000000 --- a/Echo/db_patches/patch-multiple_target_pages.sql +++ /dev/null @@ -1,3 +0,0 @@ -ALTER TABLE /*_*/echo_target_page ADD etp_id int unsigned not null primary key auto_increment; -DROP INDEX /*i*/echo_target_page_user_event ON /*_*/echo_target_page; -CREATE INDEX /*i*/echo_target_page_user_event ON /*_*/echo_target_page (etp_user, etp_event); diff --git a/Echo/db_patches/patch-multiple_target_pages.sqlite.sql b/Echo/db_patches/patch-multiple_target_pages.sqlite.sql deleted file mode 100644 index 0943bca2..00000000 --- a/Echo/db_patches/patch-multiple_target_pages.sqlite.sql +++ /dev/null @@ -1,27 +0,0 @@ --- Sqlite can't add a primary key to an existing table - --- give current table temporary name -ALTER TABLE /*_*/echo_target_page RENAME TO /*_*/temp_echo_target_page; - --- recreate table with our new setup -CREATE TABLE /*_*/echo_target_page ( - etp_id int unsigned not null primary key auto_increment, - etp_user int unsigned not null default 0, - etp_page int unsigned not null default 0, - etp_event int unsigned not null default 0 -) /*$wgDBTableOptions*/; - --- copy over old data into new table -INSERT INTO /*_*/echo_target_page - (etp_user, etp_page, etp_event) -SELECT - etp_user, etp_page, etp_event -FROM - /*_*/temp_echo_target_page; - --- drop the original table -DROP TABLE /*_*/temp_echo_target_page; - --- recreate indexes -CREATE INDEX /*i*/echo_target_page_user_event ON /*_*/echo_target_page (etp_user, etp_event); -CREATE INDEX /*i*/echo_target_page_user_page_event ON /*_*/echo_target_page (etp_user, etp_page, etp_event); diff --git a/Echo/db_patches/patch-notification-bundling-field.sql b/Echo/db_patches/patch-notification-bundling-field.sql deleted file mode 100644 index f6d5938e..00000000 --- a/Echo/db_patches/patch-notification-bundling-field.sql +++ /dev/null @@ -1,8 +0,0 @@ -ALTER TABLE /*_*/echo_notification ADD COLUMN notification_bundle_base boolean not null default 1; -ALTER TABLE /*_*/echo_notification ADD COLUMN notification_bundle_hash varchar(32) binary not null default ''; -ALTER TABLE /*_*/echo_notification ADD COLUMN notification_bundle_display_hash varchar(32) binary not null default ''; - -CREATE INDEX /*i*/echo_notification_user_base_read_timestamp ON /*_*/echo_notification (notification_user, notification_bundle_base, notification_read_timestamp); -CREATE INDEX /*i*/echo_notification_user_base_timestamp ON /*_*/echo_notification (notification_user, notification_bundle_base, notification_timestamp, notification_event); -CREATE INDEX /*i*/echo_notification_user_hash_timestamp ON /*_*/echo_notification (notification_user, notification_bundle_hash, notification_timestamp); -CREATE INDEX /*i*/echo_notification_user_hash_base_timestamp ON /*_*/echo_notification (notification_user, notification_bundle_display_hash, notification_bundle_base, notification_timestamp); diff --git a/Echo/db_patches/patch-notification-pk.sql b/Echo/db_patches/patch-notification-pk.sql deleted file mode 100644 index 9072d1f3..00000000 --- a/Echo/db_patches/patch-notification-pk.sql +++ /dev/null @@ -1,3 +0,0 @@ -DROP INDEX /*i*/user_event ON /*_*/echo_notification; - -ALTER TABLE /*_*/echo_notification ADD PRIMARY KEY (notification_user, notification_event); diff --git a/Echo/echo.sql b/Echo/echo.sql deleted file mode 100644 index 36316f93..00000000 --- a/Echo/echo.sql +++ /dev/null @@ -1,96 +0,0 @@ --- Database Schema for Echo notification system - --- An event is a thing that happened that caused one or more users to be notified. --- For every notified user, there is a corresponding row in the echo_notification table. -CREATE TABLE /*_*/echo_event ( - -- Unique auto-increment ID - event_id int unsigned not null primary key auto_increment, - -- Event type; one of the keys in $wgEchoNotifications - event_type varchar(64) binary not null, - -- Unused, always null - event_variant varchar(64) binary null, - -- The agent (user who triggered the event), if any. If the agent is a logged-in user, - -- event_agent_id contains their user ID and event_agent_ip is null. If the agent is - -- an anonymous user , event_agent_ip contains their IP address and event_agent_id is null. - -- If the event doesn't have an agent, both fields are null. - event_agent_id int unsigned null, - event_agent_ip varchar(39) binary null, - -- JSON blob with additional information about the event - event_extra BLOB NULL, - -- Page ID of the page the event happened on, if any (key to page_id) - event_page_id int unsigned null, - -- Whether the event pertains to a deleted page and should be hidden. Events are marked as - -- deleted when the related page is deleted, and unmarked as deleted when the related page - -- is undeleted - event_deleted tinyint unsigned not null default 0 -) /*$wgDBTableOptions*/; - --- Index to get only "alert" types or only "message" types -CREATE INDEX /*i*/echo_event_type ON /*_*/echo_event (event_type); --- Index to find events for a specific page -CREATE INDEX /*i*/echo_event_page_id ON /*_*/echo_event (event_page_id); - --- A notification is a user being notified about a certain event. Multiple users can be notified --- about the same event. -CREATE TABLE /*_*/echo_notification ( - -- Key to event_id - notification_event int unsigned not null, - -- Key to user_id - notification_user int unsigned not null, - -- Timestamp when the notification was created - notification_timestamp binary(14) not null, - -- Timestamp when the user read the notification, or null if unread - notification_read_timestamp binary(14) null, - -- Hash for bundling together similar notifications. Notifications that can be bundled together - -- will have the same hash - notification_bundle_hash varchar(32) binary not null, - PRIMARY KEY (notification_user, notification_event) -) /*$wgDBTableOptions*/; - --- Index to get a user's notifications in chronological order -CREATE INDEX /*i*/echo_user_timestamp ON /*_*/echo_notification (notification_user,notification_timestamp); --- Used to get all notifications for a given event -CREATE INDEX /*i*/echo_notification_event ON /*_*/echo_notification (notification_event); --- Used to get read/unread notifications for a user -CREATE INDEX /*i*/echo_notification_user_read_timestamp ON /*_*/echo_notification (notification_user, notification_read_timestamp); - --- Table gathering events for batch emails --- If a user asks to receive batch emails, events are gathered in this table until it's time to --- send an email. Once a user has been emailed about an event, it's deleted from this table. -CREATE TABLE /*_*/echo_email_batch ( - -- Unique auto-increment ID - eeb_id int unsigned not null primary key auto_increment, - -- Key to user_id - eeb_user_id int unsigned not null, - -- Priority of the event as defined in $wgEchoNotifications; events with lower numbers are listed first - eeb_event_priority tinyint unsigned not null default 10, - -- Key to event_id - eeb_event_id int unsigned not null, - -- Same value as notification_bundle_hash, or a unique value if notification_bundle_hash is empty - eeb_event_hash varchar(32) binary not null -) /*$wgDBTableOptions*/; - --- Used to delete events once they have been processed, and to identify users with events to process -CREATE UNIQUE INDEX /*i*/echo_email_batch_user_event ON /*_*/echo_email_batch (eeb_user_id,eeb_event_id); --- Used to get a list of events for a user, grouping events with the same hash and ordering by priority -CREATE INDEX /*i*/echo_email_batch_user_hash_priority ON /*_*/echo_email_batch (eeb_user_id, eeb_event_hash, eeb_event_priority); - --- A "target page" of an event is a page that, when the user visits it, causes the event to be --- marked as read. Typically this is the same as the event's event_page_id, but some events --- have multiple target pages, and many events don't set a target page at all. An event's --- target pages are derived from the 'target-page' key in event_extra. --- This table is also used for moderating events when the related page is deleted, --- but this should use event_page_id instead (T217452). -CREATE TABLE /*_*/echo_target_page ( - -- Unique auto-increment ID - etp_id int unsigned not null primary key auto_increment, - -- Key to page_id - etp_page int unsigned not null default 0, - -- Key to event_id - etp_event int unsigned not null default 0 -) /*$wgDBTableOptions*/; - --- Not currently used -CREATE INDEX /*i*/echo_target_page_event ON /*_*/echo_target_page (etp_event); --- Used to get the events associated with a given page -CREATE INDEX /*i*/echo_target_page_page_event ON /*_*/echo_target_page (etp_page, etp_event); diff --git a/Echo/extension.json b/Echo/extension.json index 19fcf66d..a9fd1575 100644 --- a/Echo/extension.json +++ b/Echo/extension.json @@ -15,35 +15,61 @@ "license-name": "MIT", "type": "specialpage", "requires": { - "MediaWiki": ">= 1.35.0" + "MediaWiki": ">= 1.37.0" }, "APIMetaModules": { - "notifications": "ApiEchoNotifications", - "unreadnotificationpages": "ApiEchoUnreadNotificationPages" + "notifications": { + "class": "MediaWiki\\Extension\\Notifications\\Api\\ApiEchoNotifications", + "services": [ "MainConfig" ] + }, + "unreadnotificationpages": { + "class": "MediaWiki\\Extension\\Notifications\\Api\\ApiEchoUnreadNotificationPages", + "services": [ "PageStore", "TitleFactory" ] + } }, "APIModules": { - "echomarkread": "ApiEchoMarkRead", - "echomarkseen": "ApiEchoMarkSeen", - "echoarticlereminder": "ApiEchoArticleReminder", - "echomute": "ApiEchoMute" + "echomarkread": "MediaWiki\\Extension\\Notifications\\Api\\ApiEchoMarkRead", + "echomarkseen": "MediaWiki\\Extension\\Notifications\\Api\\ApiEchoMarkSeen", + "echoarticlereminder": "MediaWiki\\Extension\\Notifications\\Api\\ApiEchoArticleReminder", + "echomute": { + "class": "MediaWiki\\Extension\\Notifications\\Api\\ApiEchoMute", + "services": [ + "CentralIdLookup", + "UserOptionsManager" + ] + } }, "DefaultUserOptions": { "echo-email-frequency": 0, "echo-dont-email-read-notifications": false }, "ExtensionFunctions": [ - "EchoHooks::initEchoExtension" + "MediaWiki\\Extension\\Notifications\\Hooks::initEchoExtension" ], "JobClasses": { "EchoNotificationJob": "EchoNotificationJob", "EchoNotificationDeleteJob": "EchoNotificationDeleteJob", - "EchoPushNotificationRequest": "EchoPush\\NotificationRequestJob" + "EchoPushNotificationRequest": "MediaWiki\\Extension\\Notifications\\Push\\NotificationRequestJob" }, "SpecialPages": { "Notifications": "SpecialNotifications", - "DisplayNotificationsConfiguration": "SpecialDisplayNotificationsConfiguration", + "DisplayNotificationsConfiguration": { + "class": "SpecialDisplayNotificationsConfiguration", + "services": [ + "EchoAttributeManager", + "UserOptionsManager" + ] + }, "NotificationsMarkRead": "SpecialNotificationsMarkRead" }, + "AvailableRights": [ + "manage-all-push-subscriptions" + ], + "GroupPermissions": { + "push-subscription-manager": { + "manage-all-push-subscriptions": true + } + }, "MessagesDirs": { "Echo": [ "i18n", @@ -56,13 +82,22 @@ "QUnitTestModule": { "localBasePath": "", "remoteExtPath": "Echo", - "templates": { - "NotificationBadge.mustache": "modules/mobile/NotificationBadge.mustache" - }, - "packageFiles": [ - "tests/qunit/mobile/index.js", + "dependencies": [ + "ext.echo.dm", + "ext.echo.mobile" + ], + "scripts": [ "tests/qunit/mobile/test_NotificationBadge.js", - "modules/mobile/NotificationBadge.js" + "tests/qunit/model/test_mw.echo.dm.BundleNotificationItem.js", + "tests/qunit/model/test_mw.echo.dm.CrossWikiNotificationItem.js", + "tests/qunit/model/test_mw.echo.dm.FiltersModel.js", + "tests/qunit/model/test_mw.echo.dm.NotificationGroupsList.js", + "tests/qunit/model/test_mw.echo.dm.NotificationItem.js", + "tests/qunit/model/test_mw.echo.dm.NotificationsList.js", + "tests/qunit/model/test_mw.echo.dm.PaginationModel.js", + "tests/qunit/model/test_mw.echo.dm.SeenTimeModel.js", + "tests/qunit/model/test_mw.echo.dm.SourcePagesModel.js", + "tests/qunit/model/test_mw.echo.dm.UnreadNotificationCounter.js" ] }, "ResourceModules": { @@ -71,7 +106,7 @@ "logger/mw.echo.Logger.js", { "name": "logger/config.json", - "callback": "EchoHooks::getLoggerConfigVars" + "callback": "MediaWiki\\Extension\\Notifications\\Hooks::getLoggerConfigVars" } ], "dependencies": [ @@ -145,8 +180,14 @@ "vector": [ "styles/mw.echo.ui.overlay.vector.less" ], + "vector-2022": [ + "styles/mw.echo.ui.overlay.vector.less" + ], "minerva": [ "styles/mw.echo.ui.overlay.minerva.less" + ], + "wikimediaapiportal": [ + "styles/mw.echo.ui.overlay.wikimediaapiportal.less" ] }, "dependencies": [ @@ -289,6 +330,10 @@ "packageFiles": [ "mobile/notifications.js", "mobile/list.js", + { + "name": "mobile/config.json", + "callback": "MediaWiki\\Extension\\Notifications\\Hooks::getConfigVars" + }, "mobile/overlay.js", "mobile/NotificationBadge.js", "mobile/notificationsFilterOverlay.js" @@ -303,7 +348,7 @@ "ext.echo.init.js", { "name": "config.json", - "callback": "EchoHooks::getConfigVars" + "callback": "MediaWiki\\Extension\\Notifications\\Hooks::getConfigVars" } ], "dependencies": [ @@ -331,9 +376,6 @@ ], "monobook": [ "nojs/mw.echo.badge.monobook.less" - ], - "vector": [ - "nojs/mw.echo.badge.vector.less" ] }, "targets": [ @@ -388,6 +430,11 @@ "styles/mw.echo.ui.CrossWikiUnreadFilterWidget.less", "styles/mw.echo.ui.SpecialHelpMenuWidget.less" ], + "skinStyles": { + "minerva": [ + "styles/mw.echo.ui.NotificationsInboxWidget.minerva.less" + ] + }, "dependencies": [ "ext.echo.ui", "mediawiki.Uri", @@ -406,7 +453,8 @@ "echo-learn-more", "mypreferences", "echo-specialpage-section-markread", - "echo-specialpage-pagefilterwidget-aria-label" + "echo-specialpage-pagefilterwidget-aria-label", + "echo-specialpage-special-help-menu-widget-aria-label" ], "targets": [ "desktop", @@ -428,44 +476,42 @@ "remoteExtPath": "Echo/modules" }, "Hooks": { - "SkinMinervaReplaceNotificationsBadge": "EchoHooks::onSkinMinervaReplaceNotificationsBadge", - "LoadExtensionSchemaUpdates": "EchoHooks::onLoadExtensionSchemaUpdates", - "GetPreferences": "EchoHooks::getPreferences", - "PersonalUrls": "EchoHooks::onPersonalUrls", - "BeforePageDisplay": "EchoHooks::beforePageDisplay", - "ResourceLoaderRegisterModules": "EchoHooks::onResourceLoaderRegisterModules", - "ResourceLoaderTestModules": "EchoHooks::onResourceLoaderTestModules", - "UserGroupsChanged": "EchoHooks::onUserGroupsChanged", - "UserLoadOptions": "EchoHooks::onUserLoadOptions", - "UserSaveOptions": "EchoHooks::onUserSaveOptions", - "UserGetDefaultOptions": "EchoHooks::onUserGetDefaultOptions", - "UserClearNewTalkNotification": "EchoHooks::onUserClearNewTalkNotification", - "ParserTestTables": "EchoHooks::onParserTestTables", - "EmailUserComplete": "EchoHooks::onEmailUserComplete", - "LoginFormValidErrorMessages": "EchoHooks::onLoginFormValidErrorMessages", - "OutputPageCheckLastModified": "EchoHooks::onOutputPageCheckLastModified", - "ArticleDeleteComplete": "EchoHooks::onArticleDeleteComplete", - "ArticleUndelete": "EchoHooks::onArticleUndelete", - "UserMergeAccountFields": "EchoHooks::onUserMergeAccountFields", - "MergeAccountFromTo": "EchoHooks::onMergeAccountFromTo", - "UserMergeAccountDeleteTables": "EchoHooks::onUserMergeAccountDeleteTables", - "EchoGetBundleRules": "EchoHooks::onEchoGetBundleRules", - "EchoAbortEmailNotification": "EchoHooks::onEchoAbortEmailNotification", - "PageSaveComplete": "EchoHooks::onPageSaveComplete", - "LocalUserCreated": "EchoHooks::onLocalUserCreated", - "RollbackComplete": "EchoHooks::onRollbackComplete", - "UserSaveSettings": "EchoHooks::onUserSaveSettings", - "AbortTalkPageEmailNotification": "EchoHooks::onAbortTalkPageEmailNotification", - "SendWatchlistEmailNotification": "EchoHooks::onSendWatchlistEmailNotification", - "GetNewMessagesAlert": "EchoHooks::abortNewMessagesAlert", - "LinksUpdateAfterInsert": "EchoHooks::onLinksUpdateAfterInsert", - "SpecialMuteModifyFormFields": "EchoHooks::onSpecialMuteModifyFormFields", + "LoadExtensionSchemaUpdates": "MediaWiki\\Extension\\Notifications\\Hooks::onLoadExtensionSchemaUpdates", + "GetPreferences": "main", + "BeforePageDisplay": "main", + "ResourceLoaderRegisterModules": "main", + "UserGroupsChanged": "main", + "LoadUserOptions": "main", + "SaveUserOptions": "main", + "UserGetDefaultOptions": "main", + "UserClearNewTalkNotification": "main", + "EmailUserComplete": "main", + "LoginFormValidErrorMessages": "main", + "OutputPageCheckLastModified": "main", + "ArticleDeleteComplete": "main", + "ArticleUndelete": "main", + "UserMergeAccountFields": "MediaWiki\\Extension\\Notifications\\Hooks::onUserMergeAccountFields", + "MergeAccountFromTo": "MediaWiki\\Extension\\Notifications\\Hooks::onMergeAccountFromTo", + "UserMergeAccountDeleteTables": "MediaWiki\\Extension\\Notifications\\Hooks::onUserMergeAccountDeleteTables", + "EchoGetBundleRules": "MediaWiki\\Extension\\Notifications\\Hooks::onEchoGetBundleRules", + "EchoAbortEmailNotification": "MediaWiki\\Extension\\Notifications\\Hooks::onEchoAbortEmailNotification", + "PageSaveComplete": "main", + "LocalUserCreated": "main", + "RollbackComplete": "main", + "UserSaveSettings": "main", + "AbortTalkPageEmailNotification": "main", + "SendWatchlistEmailNotification": "main", + "GetNewMessagesAlert": "main", + "LinksUpdateComplete": "main", + "SpecialMuteModifyFormFields": "MediaWiki\\Extension\\Notifications\\Hooks::onSpecialMuteModifyFormFields", "RecentChange_save": "main", - "ApiMain::moduleManager": "EchoHooks::onApiMainModuleManager" + "ApiMain::moduleManager": "main", + "SkinTemplateNavigation::Universal": "main", + "PreferencesGetIcon": "main" }, "HookHandlers": { "main": { - "class": "\\EchoHooks", + "class": "MediaWiki\\Extension\\Notifications\\Hooks", "services": [ "MainConfig" ] } }, @@ -656,6 +702,12 @@ }, "EchoNotificationIcons": { "value": { + "watchlist-progressive": { + "path": { + "ltr": "Echo/modules/icons/watchlist-ltr-progressive.svg", + "rtl": "Echo/modules/icons/watchlist-rtl-progressive.svg" + } + }, "placeholder": { "path": "Echo/modules/icons/notice.svg" }, @@ -749,10 +801,10 @@ "category": "system-noemail", "group": "positive", "section": "message", - "presentation-model": "EchoWelcomePresentationModel" + "presentation-model": "MediaWiki\\Extension\\Notifications\\Formatters\\EchoWelcomePresentationModel" }, "edit-user-talk": { - "presentation-model": "EchoEditUserTalkPresentationModel", + "presentation-model": "MediaWiki\\Extension\\Notifications\\Formatters\\EchoEditUserTalkPresentationModel", "user-locators": [ "EchoUserLocator::locateTalkPageOwner" ], @@ -767,7 +819,7 @@ "immediate": true }, "reverted": { - "presentation-model": "EchoRevertedPresentationModel", + "presentation-model": "MediaWiki\\Extension\\Notifications\\Formatters\\EchoRevertedPresentationModel", "user-locators": [ [ "EchoUserLocator::locateFromEventExtra", @@ -781,7 +833,7 @@ "section": "alert" }, "page-linked": { - "presentation-model": "EchoPageLinkedPresentationModel", + "presentation-model": "MediaWiki\\Extension\\Notifications\\Formatters\\EchoPageLinkedPresentationModel", "user-locators": [ "EchoUserLocator::locateArticleCreator" ], @@ -800,7 +852,8 @@ ], "category": "minor-watchlist", "group": "interactive", - "presentation-model": "EchoWatchlistChangePresentationModel", + "section": "message", + "presentation-model": "MediaWiki\\Extension\\Notifications\\Formatters\\EchoWatchlistChangePresentationModel", "bundle": { "web": true, "email": true, @@ -811,9 +864,10 @@ "user-locators": [ "EchoUserLocator::locateUsersWatchingTitle" ], + "section": "message", "category": "watchlist", "group": "interactive", - "presentation-model": "EchoWatchlistChangePresentationModel", + "presentation-model": "MediaWiki\\Extension\\Notifications\\Formatters\\EchoWatchlistChangePresentationModel", "bundle": { "web": true, "email": true, @@ -832,7 +886,7 @@ "category": "mention", "group": "interactive", "section": "alert", - "presentation-model": "EchoMentionPresentationModel" + "presentation-model": "MediaWiki\\Extension\\Notifications\\Formatters\\EchoMentionPresentationModel" }, "mention-summary": { "user-locators": [ @@ -846,7 +900,7 @@ "category": "mention", "group": "interactive", "section": "alert", - "presentation-model": "EchoMentionInSummaryPresentationModel" + "presentation-model": "MediaWiki\\Extension\\Notifications\\Formatters\\EchoMentionInSummaryPresentationModel" }, "mention-failure": { "user-locators": [ @@ -862,7 +916,7 @@ }, "group": "negative", "section": "alert", - "presentation-model": "EchoMentionStatusPresentationModel" + "presentation-model": "MediaWiki\\Extension\\Notifications\\Formatters\\EchoMentionStatusPresentationModel" }, "mention-failure-too-many": { "user-locators": [ @@ -874,7 +928,7 @@ "category": "mention-failure", "group": "negative", "section": "alert", - "presentation-model": "EchoMentionStatusPresentationModel" + "presentation-model": "MediaWiki\\Extension\\Notifications\\Formatters\\EchoMentionStatusPresentationModel" }, "mention-success": { "user-locators": [ @@ -889,8 +943,8 @@ "expandable": true }, "group": "positive", - "section": "alert", - "presentation-model": "EchoMentionStatusPresentationModel" + "section": "message", + "presentation-model": "MediaWiki\\Extension\\Notifications\\Formatters\\EchoMentionStatusPresentationModel" }, "user-rights": { "user-locators": [ @@ -904,10 +958,10 @@ "category": "user-rights", "group": "neutral", "section": "alert", - "presentation-model": "EchoUserRightsPresentationModel" + "presentation-model": "MediaWiki\\Extension\\Notifications\\Formatters\\EchoUserRightsPresentationModel" }, "emailuser": { - "presentation-model": "EchoEmailUserPresentationModel", + "presentation-model": "MediaWiki\\Extension\\Notifications\\Formatters\\EchoEmailUserPresentationModel", "user-locators": [ [ "EchoUserLocator::locateFromEventExtra", @@ -921,7 +975,7 @@ "section": "alert" }, "foreign": { - "presentation-model": "EchoForeignPresentationModel", + "presentation-model": "MediaWiki\\Extension\\Notifications\\Formatters\\EchoForeignPresentationModel", "user-locators": [ "EchoUserLocator::locateEventAgent" ], @@ -936,7 +990,7 @@ "canNotifyAgent": true, "category": "thank-you-edit", "group": "positive", - "presentation-model": "EchoEditThresholdPresentationModel", + "presentation-model": "MediaWiki\\Extension\\Notifications\\Formatters\\EchoEditThresholdPresentationModel", "section": "message" }, "article-reminder": { @@ -946,7 +1000,7 @@ "canNotifyAgent": true, "category": "article-reminder", "group": "positive", - "presentation-model": "EchoArticleReminderPresentationModel", + "presentation-model": "MediaWiki\\Extension\\Notifications\\Formatters\\EchoArticleReminderPresentationModel", "section": "message" } }, @@ -999,24 +1053,22 @@ "EchoPushServiceBaseUrl": { "value": false, "description": "Request endpoint URL for the push notification service" + }, + "EchoPushMaxSubscriptionsPerUser": { + "value": 0, + "description": "Maximum number of push subscriptions that may be stored in the DB at any given time for a single central user ID." } }, "attributes": { "EventLogging": { "Schemas": { - "EchoInteraction": 15823738 + "EchoInteraction": "/analytics/legacy/echointeraction/1.0.0", + "EchoMail": "/analytics/legacy/echomail/1.0.0" } } }, "manifest_version": 2, "AutoloadClasses": { - "ApiCrossWiki": "includes/api/ApiCrossWiki.php", - "ApiEchoArticleReminder": "includes/api/ApiEchoArticleReminder.php", - "ApiEchoMarkRead": "includes/api/ApiEchoMarkRead.php", - "ApiEchoMarkSeen": "includes/api/ApiEchoMarkSeen.php", - "ApiEchoMute": "includes/api/ApiEchoMute.php", - "ApiEchoNotifications": "includes/api/ApiEchoNotifications.php", - "ApiEchoUnreadNotificationPages": "includes/api/ApiEchoUnreadNotificationPages.php", "BackfillUnreadWikis": "maintenance/backfillUnreadWikis.php", "Bundleable": "includes/Bundleable.php", "Bundler": "includes/Bundler.php", @@ -1034,32 +1086,22 @@ "EchoDiffGroup": "includes/EchoDiffGroup.php", "EchoDiffParser": "includes/EchoDiffParser.php", "EchoDiscussionParser": "includes/DiscussionParser.php", - "EchoEditThresholdPresentationModel": "includes/formatters/EditThresholdPresentationModel.php", - "EchoEditUserTalkPresentationModel": "includes/formatters/EditUserTalkPresentationModel.php", - "EchoArticleReminderPresentationModel": "includes/formatters/ArticleReminderPresentationModel.php", + "EchoEditUserTalkPresentationModel": "includes/Formatters/EchoEditUserTalkPresentationModel.php", + "MediaWiki\\Extension\\Notifications\\Formatters\\EchoEditUserTalkPresentationModel": "includes/Formatters/EchoEditUserTalkPresentationModel.php", "EchoEmailFormat": "includes/EmailFormat.php", "EchoEmailFrequency": "includes/EmailFrequency.php", - "EchoEmailUserPresentationModel": "includes/formatters/EmailUserPresentationModel.php", "EchoEvent": "includes/model/Event.php", - "EchoEventDigestFormatter": "includes/formatters/EchoEventDigestFormatter.php", - "EchoEventFormatter": "includes/formatters/EchoEventFormatter.php", "EchoEventMapper": "includes/mapper/EventMapper.php", - "EchoEventPresentationModel": "includes/formatters/EventPresentationModel.php", + "EchoEventPresentationModel": "includes/Formatters/EchoEventPresentationModel.php", + "MediaWiki\\Extension\\Notifications\\Formatters\\EchoEventPresentationModel": "includes/Formatters/EchoEventPresentationModel.php", "EchoFilteredSequentialIterator": "includes/iterator/FilteredSequentialIterator.php", - "EchoFlyoutFormatter": "includes/formatters/EchoFlyoutFormatter.php", "EchoForeignNotifications": "includes/ForeignNotifications.php", - "EchoForeignPresentationModel": "includes/formatters/EchoForeignPresentationModel.php", "EchoForeignWikiRequest": "includes/ForeignWikiRequest.php", - "EchoHooks": "includes/EchoHooks.php", - "EchoHtmlDigestEmailFormatter": "includes/formatters/EchoHtmlDigestEmailFormatter.php", - "EchoHtmlEmailFormatter": "includes/formatters/EchoHtmlEmailFormatter.php", - "EchoIcon": "includes/formatters/EchoIcon.php", - "EchoIteratorDecorator": "includes/iterator/IteratorDecorator.php", "EchoLocalCache": "includes/cache/LocalCache.php", - "EchoMentionInSummaryPresentationModel": "includes/formatters/MentionInSummaryPresentationModel.php", - "EchoMentionPresentationModel": "includes/formatters/MentionPresentationModel.php", - "EchoMentionStatusPresentationModel": "includes/formatters/MentionStatusPresentationModel.php", - "EchoModelFormatter": "includes/formatters/EchoModelFormatter.php", + "EchoMentionPresentationModel": "includes/Formatters/EchoMentionPresentationModel.php", + "MediaWiki\\Extension\\Notifications\\Formatters\\EchoMentionPresentationModel": "includes/Formatters/EchoMentionPresentationModel.php", + "EchoMentionStatusPresentationModel": "includes/Formatters/EchoMentionStatusPresentationModel.php", + "MediaWiki\\Extension\\Notifications\\Formatters\\EchoMentionStatusPresentationModel": "includes/Formatters/EchoMentionStatusPresentationModel.php", "EchoModerationController": "includes/controller/ModerationController.php", "EchoMultipleIterator": "includes/iterator/MultipleIterator.php", "EchoNotRecursiveIterator": "includes/iterator/NotRecursiveIterator.php", @@ -1070,11 +1112,8 @@ "EchoNotificationMapper": "includes/mapper/NotificationMapper.php", "EchoNotifier": "includes/Notifier.php", "EchoOnWikiList": "includes/EchoOnWikiList.php", - "EchoPageLinkedPresentationModel": "includes/formatters/PageLinkedPresentationModel.php", - "EchoPlainTextDigestEmailFormatter": "includes/formatters/EchoPlainTextDigestEmailFormatter.php", - "EchoPlainTextEmailFormatter": "includes/formatters/EchoPlainTextEmailFormatter.php", - "EchoPresentationModelSection": "includes/formatters/PresentationModelSection.php", - "EchoRevertedPresentationModel": "includes/formatters/RevertedPresentationModel.php", + "EchoPresentationModelSection": "includes/Formatters/EchoPresentationModelSection.php", + "MediaWiki\\Extension\\Notifications\\Formatters\\EchoPresentationModelSection": "includes/Formatters/EchoPresentationModelSection.php", "EchoRevisionLocalCache": "includes/cache/RevisionLocalCache.php", "EchoSeenTime": "includes/SeenTime.php", "EchoServices": "includes/EchoServices.php", @@ -1086,9 +1125,6 @@ "EchoUnreadWikis": "includes/UnreadWikis.php", "EchoUserLocator": "includes/UserLocator.php", "EchoUserNotificationGateway": "includes/gateway/UserNotificationGateway.php", - "EchoUserRightsPresentationModel": "includes/formatters/UserRightsPresentationModel.php", - "EchoWelcomePresentationModel": "includes/formatters/WelcomePresentationModel.php", - "EchoWatchlistChangePresentationModel": "includes/formatters/WatchlistChangePresentationModel.php", "GenerateSampleNotifications": "maintenance/generateSampleNotifications.php", "MWEchoDbFactory": "includes/EchoDbFactory.php", "MWEchoEmailBatch": "includes/EmailBatch.php", @@ -1102,15 +1138,14 @@ "ResourceLoaderEchoImageModule": "includes/ResourceLoaderEchoImageModule.php", "SpecialDisplayNotificationsConfiguration": "includes/special/SpecialDisplayNotificationsConfiguration.php", "SpecialNotifications": "includes/special/SpecialNotifications.php", - "SpecialNotificationsFormatter": "includes/formatters/SpecialNotificationsFormatter.php", "SpecialNotificationsMarkRead": "includes/special/SpecialNotificationsMarkRead.php", "UpdateEchoSchemaForSuppression": "maintenance/updateEchoSchemaForSuppression.php", - "EchoUpdatePerUserBlacklist": "maintenance/updatePerUserBlacklist.php" + "EchoUpdatePerUserBlacklist": "maintenance/updatePerUserBlacklist.php", + "EchoPush\\PushNotifier": "includes/Push/PushNotifier.php", + "MediaWiki\\Extension\\Notifications\\Push\\PushNotifier": "includes/Push/PushNotifier.php" }, "AutoloadNamespaces": { - "EchoOOUI\\": "includes/ooui/", - "EchoPush\\": "includes/Push/", - "EchoPush\\Api\\": "includes/api/Push/" + "MediaWiki\\Extension\\Notifications\\": "includes/" }, "TestAutoloadClasses": { "EchoAbstractMapperStub": "tests/phpunit/mapper/EchoAbstractMapperStub.php", diff --git a/Echo/i18n/alt.json b/Echo/i18n/alt.json new file mode 100644 index 00000000..c9a18822 --- /dev/null +++ b/Echo/i18n/alt.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Батыр Комдошев" + ] + }, + "tooltip-pt-notifications-alert": "{{GENDER:|Слердиҥ}} угузыларыр" +} diff --git a/Echo/i18n/ami.json b/Echo/i18n/ami.json index 86286172..b95cb9e0 100644 --- a/Echo/i18n/ami.json +++ b/Echo/i18n/ami.json @@ -1,10 +1,11 @@ { "@metadata": { "authors": [ + "Amire80", "Vickylin77s" ] }, "tooltip-pt-notifications-alert": "{{GENDER:|no miso}} mipalal", - "notification-link-text-expand-all": " misatapang", - "notification-inbox-filter-all": " Maemin/po:long" + "notification-link-text-expand-all": "misatapang", + "notification-inbox-filter-all": "Maemin/po:long" } diff --git a/Echo/i18n/ang.json b/Echo/i18n/ang.json deleted file mode 100644 index d5c84333..00000000 --- a/Echo/i18n/ang.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Gott wisst" - ] - } -} diff --git a/Echo/i18n/api/as.json b/Echo/i18n/api/as.json new file mode 100644 index 00000000..0ad8a483 --- /dev/null +++ b/Echo/i18n/api/as.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Simbu123" + ] + }, + "apihelp-echomarkread-example-2": "সকলো জাননী পঢ়া-হৈছে হিচাপে চিহ্নিত কৰক" +} diff --git a/Echo/i18n/api/be.json b/Echo/i18n/api/be.json new file mode 100644 index 00000000..a181cfe4 --- /dev/null +++ b/Echo/i18n/api/be.json @@ -0,0 +1,20 @@ +{ + "@metadata": { + "authors": [ + "Chadyka" + ] + }, + "apihelp-echomarkread-description": "Пазначыць апавяшчэнні для бягучага ўдзельніка як прачытаныя.", + "apihelp-echomarkread-summary": "Пазначыць апавяшчэнні для бягучага ўдзельніка як прачытаныя.", + "apihelp-echomarkread-param-list": "Спіс ідэнтыфікатараў апавяшчэнняў, якія трэба пазначыць як прачытаныя.", + "apihelp-echomarkread-param-unreadlist": "Спіс ідэнтыфікатараў апавяшчэнняў, якія трэба пазначыць як прачытаныя.", + "apihelp-echomarkread-param-all": "Калі зададзена, пазначае ўсе апавяшчэнні ўдзельніка як прачытаныя.", + "apihelp-echomarkread-param-sections": "Спіс раздзелаў, якія трэба пазначыць як прачытаныя.", + "apihelp-echomarkread-param-wikis": "Спіс вікі для пазначэння паведамлення як прачытанага (па змаўчанні толькі бягучая вікі).", + "apihelp-echomarkread-example-1": "Пазначыць апавяшчэнне 8 як прачытанае", + "apihelp-echomarkread-example-2": "Пазначыць усе апавяшчэнні як прачытаныя", + "apihelp-echomarkread-example-3": "Пазначыць апавяшчэнне 1 як непрачытанае", + "apihelp-echomarkseen-description": "Пазначыць апавяшчэнні як прагледжаныя для бягучага ўдзельніка.", + "apihelp-echomarkseen-summary": "Пазначыць апавяшчэнні як прагледжаныя для бягучага ўдзельніка.", + "apihelp-echomarkseen-example-1": "Пазначаць апавяшчэнні ўсіх тыпаў як прагледжаныя" +} diff --git a/Echo/i18n/api/bg.json b/Echo/i18n/api/bg.json index e68e7644..dd6a521f 100644 --- a/Echo/i18n/api/bg.json +++ b/Echo/i18n/api/bg.json @@ -37,8 +37,8 @@ "apihelp-query+notifications-param-messageunreadfirst": "Дали първо да се показват непрочетените съобщения (използва се само ако groupbysection е зададено).", "apihelp-query+notifications-param-titles": "Извежда известия само за тези страници. За да получавате известия, които не са свързани с нито една страница, вместо името използвайте [].", "apihelp-query+notifications-param-bundle": "Дали да се показват включените съвместими непрочетени известия, според вида на правилата за видове известяване.", - "apihelp-query+notifications-example-1": "Списък на известията", - "apihelp-query+notifications-example-2": "Списък с известия, групирани в раздели, с посочване на броя им", + "apihelp-query+notifications-example-1": "Списък на уеб известията", + "apihelp-query+notifications-example-2": "Списък с уеб известия, групирани в раздели, с посочване на броя им", "apihelp-query+unreadnotificationpages-description": "Получаване на страници, за които има непрочетени известия за текущия потребител.", "apihelp-query+unreadnotificationpages-param-grouppages": "Групиране на беседи заедно с беседите им, и групиране на известията, които не са свързани със страница, заедно със страницата на текущия потребител.", "apihelp-query+unreadnotificationpages-param-limit": "Максималният брой на страници за връщане.", diff --git a/Echo/i18n/api/bs.json b/Echo/i18n/api/bs.json deleted file mode 100644 index be4dc742..00000000 --- a/Echo/i18n/api/bs.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Srdjan m" - ] - }, - "apihelp-query+notifications-example-1": "Ispiši obavještenja" -} diff --git a/Echo/i18n/api/ca.json b/Echo/i18n/api/ca.json index b202c77c..5361d435 100644 --- a/Echo/i18n/api/ca.json +++ b/Echo/i18n/api/ca.json @@ -7,5 +7,5 @@ "apihelp-echomarkread-example-2": "Marca totes les notificacions com a llegides", "apihelp-query+notifications-param-prop": "Detalls per sol·licitar.", "apihelp-query+notifications-param-wikis": "Llista de wikis d'on recollir les notificacions (per defecte només el wiki actual).", - "apihelp-query+notifications-example-1": "Llista les notificacions" + "apihelp-query+notifications-example-1": "Llista les notificacions web" } diff --git a/Echo/i18n/api/ce.json b/Echo/i18n/api/ce.json index 8735a8a0..f40e8640 100644 --- a/Echo/i18n/api/ce.json +++ b/Echo/i18n/api/ce.json @@ -4,17 +4,17 @@ "Умар" ] }, - "apihelp-echomarkread-description": "Билгалде дӀахаийтарш хьаьжна сана.", - "apihelp-echomarkread-param-list": "Хьажжина сана билгалдаран ID дӀахаийтарийн могӀам.", + "apihelp-echomarkread-description": "Билгалде дӀахаийтарш хьаьжна санна.", + "apihelp-echomarkread-param-list": "Йешна санна билгалдаран ID дӀахаийтарийн могӀам.", "apihelp-echomarkread-param-all": "Декъашхочун массо дӀахаийтарш дешна санна билгалдо.", - "apihelp-echomarkread-param-sections": "Хьажжина сана билгалдаран декъийн могӀам.", + "apihelp-echomarkread-param-sections": "Йешна санна билгалдаран декъийн могӀам.", "apihelp-echomarkread-example-1": "Билгалде 8 дӀахаийтар дешна санна", "apihelp-echomarkread-example-2": "Билгалде массо дӀахаийтарш дешна санна", - "apihelp-echomarkseen-description": "Билгалде хӀокху декъашхочун дӀахаийтарш дешна сана.", + "apihelp-echomarkseen-description": "Билгалде хӀокху декъашхочун дӀахаийтарш дешна санна.", "apihelp-echomarkseen-example-1": "Билгалде массо тайпа долу дӀахаийтарш дешна санна", "apihelp-query+notifications-param-prop": "Дехарна ма-дарра.", - "apihelp-query+notifications-param-filter": "Юхадирзина дӀахаийтарш литта.", + "apihelp-query+notifications-param-filter": "Йухадирзина дӀахаийтарш литта.", "apihelp-query+notifications-paramvalue-format-model": "Кечъбанза дӀахаийтаран хаамаш", "apihelp-query+notifications-example-1": "ДӀахаийтарийн могӀам", - "apihelp-query+unreadnotificationpages-param-limit": "Юхаялоран агӀонийн максимале дукхалла" + "apihelp-query+unreadnotificationpages-param-limit": "Йухайалоран агӀонийн максимале дукхалла" } diff --git a/Echo/i18n/api/ckb.json b/Echo/i18n/api/ckb.json deleted file mode 100644 index 0bb16736..00000000 --- a/Echo/i18n/api/ckb.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Asoxor" - ] - }, - "apihelp-query+notifications-example-1": "پێرستی ئاگادارییەکان", - "apihelp-query+notifications-example-2": "پێرستی پۆلێن کراوی ئاگادارییەکان لەگەڵ ژمارەکانیان" -} diff --git a/Echo/i18n/api/cs.json b/Echo/i18n/api/cs.json index 74d20653..7c674476 100644 --- a/Echo/i18n/api/cs.json +++ b/Echo/i18n/api/cs.json @@ -2,9 +2,10 @@ "@metadata": { "authors": [ "Martin Urbanec", - "Mormegil" + "Mormegil", + "Robins7" ] }, - "apihelp-echomarkread-example-2": "Označit všechny upozornění jako přečtené", + "apihelp-echomarkread-example-2": "Označit všechna upozornění jako přečtená", "apihelp-echomarkseen-example-1": "Označit oznámení všech typů jako přečtená" } diff --git a/Echo/i18n/api/cu.json b/Echo/i18n/api/cu.json new file mode 100644 index 00000000..2956b80e --- /dev/null +++ b/Echo/i18n/api/cu.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "NR Deblocked" + ] + }, + "apihelp-query+notifications-param-notifiertypes": "Типы ᲂуведомителей длѧ кото́рыхъ нꙋ́жно возвращать ᲂуведомленїѧ.", + "apihelp-query+notifications-example-1": "Списокъ вебъ-ᲂуведомленїй", + "apihelp-query+notifications-example-2": "Списокъ вебъ-ᲂуведомленїй сгрꙋппированныхъ по разделамъ съ подсчетомъ", + "apihelp-query+notifications-example-3": "Списокъ ᲂуведомленїй по электронной почтѐ" +} diff --git a/Echo/i18n/api/de-formal.json b/Echo/i18n/api/de-formal.json new file mode 100644 index 00000000..16e96008 --- /dev/null +++ b/Echo/i18n/api/de-formal.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Killarnee" + ] + }, + "apihelp-echopushsubscriptions+create-param-topic": "Das APNS-Thema ''(app bundle ID)'', an das die Benachrichtigung gesendet werden soll." +} diff --git a/Echo/i18n/api/de.json b/Echo/i18n/api/de.json index ca1a1dea..395642aa 100644 --- a/Echo/i18n/api/de.json +++ b/Echo/i18n/api/de.json @@ -33,9 +33,11 @@ "apihelp-echopushsubscriptions+create-summary": "Registrieren eines Push-Abonnements für den aktuellen Benutzer.", "apihelp-echopushsubscriptions+create-param-provider": "Der Push-Dienstleister, für den ein Token registriert werden soll.", "apihelp-echopushsubscriptions+create-param-providertoken": "Das Token zur Registrierung.", + "apihelp-echopushsubscriptions+create-param-topic": "Das APNS-Thema ''(app bundle ID)'', an das die Benachrichtigung gesendet werden soll.", "apihelp-echopushsubscriptions+create-example": "Registrieren eines Push-Abonnements für den aktuellen Benutzer.", - "apihelp-echopushsubscriptions+delete-summary": "Aufheben der Registrierung von Push-Abonnements für den aktuellen Benutzer auf.", + "apihelp-echopushsubscriptions+delete-summary": "Aufheben der Registrierung von Push-Abonnements für den aktuellen Benutzer oder einen anderen angegebenen Benutzer.", "apihelp-echopushsubscriptions+delete-param-providertoken": "Das mit dem Push-Abonnement zur Abmeldung verbundene Token.", + "apihelp-echopushsubscriptions+delete-param-centraluserid": "Die zentrale Benutzer-ID, die mit dem Abonnement zur Aufhebung der Registrierung verbunden ist.", "apihelp-echopushsubscriptions+delete-example": "Aufheben der Registrierung eines Push-Abonnements für den aktuellen Benutzer auf.", "apihelp-query+notifications-description": "Benachrichtigungen abrufen, die auf den aktuellen Benutzer warten.", "apihelp-query+notifications-summary": "Ruft wartende Benachrichtigungen für den aktuellen Benutzer ab.", @@ -58,8 +60,10 @@ "apihelp-query+notifications-param-messageunreadfirst": "Ob ungelesene Meldungen zuerst angezeigt werden sollen (wird nur verwendet, wenn groupbysection festgelegt ist).", "apihelp-query+notifications-param-titles": "Gibt nur Benachrichtigungen für diese Seiten zurück. Um Benachrichtigungen abzurufen, die mit keiner bestimmten Seite verknüpft sind, verwende als Titel [].", "apihelp-query+notifications-param-bundle": "Ob bündelkompatible ungelesene Benachrichtigungen übereinstimmend mit den Benachrichtigungstyp-Bündelregeln angezeigt werden sollen.", - "apihelp-query+notifications-example-1": "Benachrichtigungen auflisten", - "apihelp-query+notifications-example-2": "Benachrichtigungen auflisten, gruppiert nach Abschnitt, mit Zählern", + "apihelp-query+notifications-param-notifiertypes": "Benachrichtigungstypen, für die Benachrichtigungen zurückgegeben werden sollen.", + "apihelp-query+notifications-example-1": "Web-Benachrichtigungen auflisten", + "apihelp-query+notifications-example-2": "Web-Benachrichtigungen auflisten, gruppiert nach Abschnitt, mit Zählern", + "apihelp-query+notifications-example-3": "E-Mail-Benachrichtigungen auflisten", "apihelp-query+unreadnotificationpages-description": "Ruft Seiten ab, für die es für den aktuellen Benutzer ungelesene Benachrichtigungen gibt.", "apihelp-query+unreadnotificationpages-summary": "Ruft Seiten ab, für die es für den aktuellen Benutzer ungelesene Benachrichtigungen gibt.", "apihelp-query+unreadnotificationpages-param-grouppages": "Gruppiert Diskussionsseiten zusammen mit ihrer dazugehörigen Seite und Gruppenbenachrichtigungen, die nicht mit einer Seite zusammen mit der aktuellen Benutzerseite verknüpft sind.", @@ -78,5 +82,7 @@ "apiwarn-echo-deprecation-html": "<kbd>notformat=html</kbd> ist veraltet und wird bald entfernt. Verwende stattdessen <kbd>notformat=special</kbd>.", "apierror-echo-event-creation-failed": "Es konnte kein Echo-Ereignis erstellt werden", "apierror-echo-push-token-exists": "Das angegebene Token ist bereits in der Datenbank vorhanden.", - "apierror-echo-push-token-not-found": "Das angegebene Token wurde in der Datenbank nicht gefunden." + "apierror-echo-push-token-not-found": "Das angegebene Token wurde in der Datenbank nicht gefunden.", + "apierror-echo-push-too-many-subscriptions": "Der aktuelle Benutzer hat bereits die maximal zulässige Anzahl von Push-Abonnements ($1) registriert.", + "apierror-echo-push-topic-required": "Das topic-Feld ist für diesen Anbieter erforderlich." } diff --git a/Echo/i18n/api/diq.json b/Echo/i18n/api/diq.json deleted file mode 100644 index 62a6a4ba..00000000 --- a/Echo/i18n/api/diq.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Kumkumuk" - ] - }, - "apihelp-query+notifications-example-1": "Akerdenê liste" -} diff --git a/Echo/i18n/api/en.json b/Echo/i18n/api/en.json index dff5fca5..b1da973d 100644 --- a/Echo/i18n/api/en.json +++ b/Echo/i18n/api/en.json @@ -23,7 +23,7 @@ "apihelp-echomarkseen-summary": "Mark notifications as seen for the current user.", "apihelp-echomarkseen-example-1": "Mark notifications of all types as seen", "apihelp-echomarkseen-param-type": "Type of notifications to mark as seen: 'alert', 'message' or 'all'.", - "apihelp-echomarkseen-param-timestampFormat": "Timestamp format to use for output, 'ISO_8601' or 'MW'. 'MW' is deprecated here, so all clients should switch to 'ISO_8601'. This parameter will be removed, and 'ISO_8601' will become the only output format.", + "apihelp-echomarkseen-param-timestampFormat": "Timestamp format to use for output, 'ISO_8601' or 'MW'. 'MW' is deprecated here, so all clients should switch to 'ISO_8601'. This parameter will be removed, and 'ISO_8601' will become the only output format.", "apihelp-echomute-description": "Mute or unmute notifications from certain users or pages.", "apihelp-echomute-summary": "Mute or unmute notifications from certain users or pages.", "apihelp-echomute-param-type": "Which mute list to add to or remove from", @@ -34,9 +34,11 @@ "apihelp-echopushsubscriptions+create-summary": "Register push subscriptions for the current user.", "apihelp-echopushsubscriptions+create-param-provider": "The push service provider for which to register a token.", "apihelp-echopushsubscriptions+create-param-providertoken": "The token to register.", + "apihelp-echopushsubscriptions+create-param-topic": "The APNS topic (app bundle ID) to send the notification to.", "apihelp-echopushsubscriptions+create-example": "Register a push subscription for the current user.", - "apihelp-echopushsubscriptions+delete-summary": "Unegister push subscriptions for the current user.", + "apihelp-echopushsubscriptions+delete-summary": "Unregister push subscriptions for the current user or another specified user.", "apihelp-echopushsubscriptions+delete-param-providertoken": "The token associated with the push subscription to unregister.", + "apihelp-echopushsubscriptions+delete-param-centraluserid": "The central user ID associated with the subscription to unregister.", "apihelp-echopushsubscriptions+delete-example": "Unregister a push subscription for the current user.", "apihelp-query+notifications-description": "Get notifications waiting for the current user.", "apihelp-query+notifications-summary": "Get notifications waiting for the current user.", @@ -59,8 +61,10 @@ "apihelp-query+notifications-param-messageunreadfirst": "Whether to show unread alert notifications first (only used if groupbysection is set).", "apihelp-query+notifications-param-titles": "Only return notifications for these pages. To get notifications not associated with any page, use [] as a title.", "apihelp-query+notifications-param-bundle": "Whether to show bundle compatible unread notifications according to notification types bundling rules.", - "apihelp-query+notifications-example-1": "List notifications", - "apihelp-query+notifications-example-2": "List notifications, grouped by section, with counts", + "apihelp-query+notifications-param-notifiertypes": "Notifier types for which to return notifications.", + "apihelp-query+notifications-example-1": "List web notifications", + "apihelp-query+notifications-example-2": "List web notifications, grouped by section, with counts", + "apihelp-query+notifications-example-3": "List email notifications", "apihelp-query+unreadnotificationpages-description": "Get pages for which there are unread notifications for the current user.", "apihelp-query+unreadnotificationpages-summary": "Get pages for which there are unread notifications for the current user.", "apihelp-query+unreadnotificationpages-param-grouppages": "Group talk pages together with their subject page, and group notifications not associated with a page together with the current user's user page.", @@ -72,12 +76,14 @@ "apihelp-echoarticlereminder-param-title": "Title of article to remind the user about", "apihelp-echoarticlereminder-param-timestamp": "On which timestamp to remind the user", "apihelp-echoarticlereminder-param-comment": "Optional user comment to include in the reminder", - "apihelp-echoarticlereminder-example-1" : "Create an article reminder notification for tomorrow with comment", - "apihelp-echoarticlereminder-example-2" : "Create an article reminder notification for tomorrow without comment", - "apiwarn-echo-deprecation-timestampformat": "The MW timestamp output format is deprecated here. In the future, ISO 8601 will always be used for the output timestamp format. Adjust your client and set <var>timestampFormat</var> to <kbd>ISO_8601</kbd>.", + "apihelp-echoarticlereminder-example-1": "Create an article reminder notification for tomorrow with comment", + "apihelp-echoarticlereminder-example-2": "Create an article reminder notification for tomorrow without comment", + "apiwarn-echo-deprecation-timestampformat": "The MW timestamp output format is deprecated here. In the future, ISO 8601 will always be used for the output timestamp format. Adjust your client and set <var>timestampFormat</var> to <kbd>ISO_8601</kbd>.", "apiwarn-echo-deprecation-flyout": "<kbd>notformat=flyout</kbd> has been deprecated and will be removed soon. Use <kbd>notformat=model</kbd> to get the raw data or <kbd>notformat=special</kbd> for pre-rendered HTML.", "apiwarn-echo-deprecation-html": "<kbd>notformat=html</kbd> has been deprecated and will be removed soon. Use <kbd>notformat=special</kbd> instead.", "apierror-echo-event-creation-failed": "Could not create Echo event", "apierror-echo-push-token-exists": "The provided token already exists in the database.", - "apierror-echo-push-token-not-found": "The provided token was not found in the database." + "apierror-echo-push-token-not-found": "The provided token was not found in the database.", + "apierror-echo-push-too-many-subscriptions": "The current user has already registered the maximum allowed number of push subscriptions ($1).", + "apierror-echo-push-topic-required": "The topic field is required for this provider." } diff --git a/Echo/i18n/api/es.json b/Echo/i18n/api/es.json index 47e56308..67c73e3b 100644 --- a/Echo/i18n/api/es.json +++ b/Echo/i18n/api/es.json @@ -3,7 +3,10 @@ "authors": [ "Allan Aguilar", "Dgstranz", + "DiegoAmbrocio", "Fitoschido", + "Jackiezelaya", + "Jakeukalane", "Jduranboger", "Macofe", "Tiberius1701" @@ -23,7 +26,12 @@ "apihelp-echomarkseen-example-1": "Marca las notificaciones de todos los tipos como vistas", "apihelp-echomarkseen-param-type": "Tipo de notificaciones para marcar como leídas: 'alert' (alerta), 'message' (mensaje) o 'all' (todas).", "apihelp-echomarkseen-param-timestampFormat": "Formato de fecha y hora que utilizar para la salida, «ISO_8601» o «MW». «MW» aquí está desusado, por lo que todos los clientes deben cambiar a «ISO_8601». Este parámetro desaparecerá y el único formato de salida será «ISO_8601».", + "apihelp-echomute-description": "Silenciar o anular el silencio de las notificaciones de determinados usuarios o páginas.", + "apihelp-echomute-summary": "Silenciar o anular el silencio de las notificaciones de determinados usuarios o páginas.", + "apihelp-echomute-param-mute": "Páginas o usuarios a añadir a la lista de silenciados", + "apihelp-echomute-param-unmute": "Páginas o usuarios que hay que eliminar de la lista de silenciados", "apihelp-echopushsubscriptions-param-command": "La acción que debe realizarse.", + "apihelp-echopushsubscriptions+create-param-topic": "El APNS tema (fardo de aplicación ID) para enviar la notificación a.", "apihelp-query+notifications-description": "Recibe notificaciones en espera para el usuario actual.", "apihelp-query+notifications-summary": "Recibir notificaciones pendientes del usuario actual.", "apihelp-query+notifications-param-prop": "Detalles que solicitar.", @@ -36,7 +44,7 @@ "apihelp-query+notifications-paramvalue-format-flyout": "<span class=\"apihelp-deprecated\">Desaconsejado</span>. Usa <kbd>$1format=model</kbd> para datos en crudo", "apihelp-query+notifications-paramvalue-format-html": "<span class=\"apihelp-deprecated\">Desaconsejado</span>. Usa <kbd>$1format=model</kbd> para datos en crudo", "apihelp-query+notifications-param-limit": "Número máximo de notificaciones a recibir.", - "apihelp-query+notifications-param-wikis": "Lista de wikis desde las cuales obtener notificaciones (usa el wiki actual de manera predeterminada).", + "apihelp-query+notifications-param-wikis": "Lista de wikis desde las cuales obtener notificaciones (usa la wiki actual de manera predeterminada).", "apihelp-query+notifications-param-alertcontinue": "Cuando haya más resultados de alerta disponibles, utiliza esto para continuar.", "apihelp-query+notifications-param-unreadfirst": "Si se muestran las notificaciones sin leer primero (sólo se utiliza si se establece groupbysection).", "apihelp-query+notifications-param-alertunreadfirst": "Si se muestran las notificaciones de mensajes sin leer primero (sólo se usa si se establece groupbysection).", @@ -49,7 +57,7 @@ "apihelp-query+unreadnotificationpages-summary": "Recibir páginas para las que hay notificaciones no leídas para el usuario actual.", "apihelp-query+unreadnotificationpages-param-grouppages": "Agrupar páginas de discusión junto con su página de asunto asociada, y agrupar notificaciones no asociadas con una página junto con la página de usuario del usuario actual.", "apihelp-query+unreadnotificationpages-param-limit": "El máximo número de páginas que se devolverán.", - "apihelp-query+unreadnotificationpages-param-wikis": "Lista de wikis desde las cuales obtener notificaciones sin leer (usa el wiki actual de manera predeterminada).", + "apihelp-query+unreadnotificationpages-param-wikis": "Lista de wikis desde las cuales obtener notificaciones sin leer (usa la wiki actual de manera predeterminada).", "apihelp-query+unreadnotificationpages-example-1": "Lista páginas con (la cantidad de) notificaciones sin leer", "apihelp-echoarticlereminder-summary": "Solicitar un recordatorio futuro sobre el artículo especificado", "apihelp-echoarticlereminder-param-pageid": "Identificador del artículo sobre el cual recordar al usuario", diff --git a/Echo/i18n/api/et.json b/Echo/i18n/api/et.json index 54636106..4763ff2d 100644 --- a/Echo/i18n/api/et.json +++ b/Echo/i18n/api/et.json @@ -24,6 +24,6 @@ "apihelp-query+notifications-param-alertunreadfirst": "Kas näidata kõigepealt lugemata sõnumeid (kasutuses ainult siis, kui \"groupbysection\" on määratud).", "apihelp-query+notifications-param-messagecontinue": "Kui tulemustes on saadaval rohkem sõnumeid, kasutada seda jätkamiseks.", "apihelp-query+notifications-param-messageunreadfirst": "Kas näidata kõigepealt lugemata teavitusi (kasutuses ainult siis, kui \"groupbysection\" on määratud).", - "apihelp-query+notifications-example-1": "Loetle teavitused", - "apihelp-query+notifications-example-2": "Loetle teavitused jaotiste kaupa üldarvudega" + "apihelp-query+notifications-example-1": "Loetle veebiteavitused", + "apihelp-query+notifications-example-2": "Loetle veebiteavitused jaotiste kaupa üldarvudega" } diff --git a/Echo/i18n/api/fa.json b/Echo/i18n/api/fa.json index 450d4c54..88f7e1bc 100644 --- a/Echo/i18n/api/fa.json +++ b/Echo/i18n/api/fa.json @@ -2,40 +2,46 @@ "@metadata": { "authors": [ "4nn1l2", + "Beginneruser", "Dalba", "Huji", + "Jeeputer", "Mjbmr", + "Mohammad ebz", "Reza1615", "فلورانس" ] }, - "apihelp-echomarkread-description": "آگاهیها برای کاربر کنونی به عنوان خواندهشده نشانهگذاری شوند.", - "apihelp-echomarkread-summary": "علامت گذاری آگاهسازیها به عنوان خوانده شده برای کاربر فعلی", + "apihelp-echomarkread-description": "آگاهسازیها برای کاربر کنونی به عنوان خواندهشده نشانهگذاری شوند.", + "apihelp-echomarkread-summary": "علامت گذاری آگاهسازیها به عنوان خوانده شده برای کاربر کنونی", "apihelp-echomarkread-param-list": "فهرستی از شناسه های آگاه سازی به عنوان خوانده شده", "apihelp-echomarkread-param-unreadlist": "فهرستی از شناسههای آگاهسازی برای علامت زدن به عنوان خواندهنشده", - "apihelp-echomarkread-param-all": "اگر تنظیم شدهباشد، همهٔ آگهیهای یک کاربر به عنوان خواندهشده نشانهگذاری شوند.", + "apihelp-echomarkread-param-all": "اگر تنظیم شدهباشد، همهٔ آگاهسازیها یک کاربر به عنوان خواندهشده نشانهگذاری شوند.", "apihelp-echomarkread-param-sections": "فهرستی از شناسه های آگاه سازی به عنوان خوانده شده", + "apihelp-echomarkread-param-wikis": "فهرست ویکیها برای علامتزدن اعلانها بهعنوان خواندهشده (پیشفرض آن بر روی تنها ویکی کنونی است).", "apihelp-echomarkread-example-1": "علامتگذاری آگاهسازی 8 به عنوان خوانده شده", - "apihelp-echomarkread-example-2": "علامتگذاری تمامی اعلانها به عنوان خوانده شده", + "apihelp-echomarkread-example-2": "علامتگذاری تمامی آگاهسازیها به عنوان خواندهشده", "apihelp-echomarkread-example-3": "علامتگذاری آگاهسازی 1 به عنوان خواندهنشده", - "apihelp-echomarkseen-description": "علامت گذاری به عنوان اطلاعیه خوانده شده برای کاربر فعلی", - "apihelp-echomarkseen-summary": "علامت گذاری آگاهسازیها به عنوان دیده شده برای کاربر فعلی.", - "apihelp-echomarkseen-example-1": "علامتگذاری همهٔ انواع اعلانها به عنوان دیدهشده", - "apihelp-echomarkseen-param-type": "نوع اعلانهایی که خواندهشده علامت زده شوند: «آگاهسازی»، «پیام»، یا «همه»", + "apihelp-echomarkseen-description": "علامت گذاری به عنوان آگاهسازیهای خوانده شده برای کاربر کنونی", + "apihelp-echomarkseen-summary": "علامت گذاری آگاهسازیها به عنوان دیده شده برای کاربر کنونی.", + "apihelp-echomarkseen-example-1": "علامتگذاری آگاهسازیها از همۀ نوعها به عنوان دیدهشده", + "apihelp-echomarkseen-param-type": "انواع آگاهسازیهایی که بهعنوان خواندهشده علامت زده شدند: 'هشدار'، 'پیام'، یا 'همه'.", "apihelp-echomarkseen-param-timestampFormat": "ساختار تاریخ استفاده شده برای خروجی 'ISO_8601' یا 'MW' است. 'MW' در اینجا دیگر مورد استفاده نیست در نتیجه همهٔ کاربران باید از 'ISO_8601' استفاده کنند. این متغیر حذف خواهد شد و 'ISO_8601' به عنوان تنها ساختار خروجی انتخاب خواهد شد.", - "apihelp-query+notifications-description": "دریافت اعلانهای منتظر کاربر کنونی.", - "apihelp-query+notifications-summary": "دریافت اعلانهای منتظر کاربر کنونی.", + "apihelp-echomute-description": "بیصدا یا باصدا کردن اعلانها از کاربران یا صفحههای خاص.", + "apihelp-echomute-summary": "بیصدا یا باصدا کردن اعلانها از کاربران یا صفحههای خاص.", + "apihelp-query+notifications-description": "دریافت آگاهسازیهای منتظر کاربر کنونی.", + "apihelp-query+notifications-summary": "دریافت آگاهسازیهای منتظر کاربر کنونی.", "apihelp-query+notifications-param-prop": "جزئیات به درخواست.", "apihelp-query+notifications-param-sections": "بخش آگاهسازی پرسمان (مانند هشدار و پیام بعضی از مشارکتها)", "apihelp-query+notifications-param-groupbysection": "برای گروهبندی نتایج توسط بخش، در صورت تنظیم هر بخش به صورت جداگانه دریافت میشود.", - "apihelp-query+notifications-param-filter": "پالایش آگاهسازیهای دریافتی", + "apihelp-query+notifications-param-filter": "پالایش آگاهیسازیهای برگردانده شده.", "apihelp-query+notifications-param-format": "در صورت تخصیص داده شدن، آگاهسازیها به صورت این فرمت بازگردانده میشوند.", "apihelp-query+notifications-paramvalue-format-model": "اطلاعات خام آگاهسازی", "apihelp-query+notifications-paramvalue-format-special": "ساختار یافته برای صفحهٔ Special:Notifications (فقط برای آن!) به HTML توجه نکنید که هر زمان ممکن است عوض شود.", "apihelp-query+notifications-paramvalue-format-flyout": "<span class=\"apihelp-deprecated\">نهی شده</span>. از <kbd>$1format=model</kbd> برای اطلاعات خام استفاده کنید", "apihelp-query+notifications-paramvalue-format-html": "<span class=\"apihelp-deprecated\">نهی شده</span>. از <kbd>$1format=model</kbd> برای اطلاعات خام استفاده کنید", - "apihelp-query+notifications-param-limit": "حداکثر تعداد آگاهسازیها برگردانده شده.", - "apihelp-query+notifications-param-wikis": "فهرست ویکیهایی که آگاهسازی از آنها دریافت میشود (پیشفرض فقط این ویکی)", + "apihelp-query+notifications-param-limit": "حداکثر تعداد آگاهسازیهای برگردانده شده.", + "apihelp-query+notifications-param-wikis": "فهرست ویکیهایی که آگاهسازیها از آنها واکشی میشود (پیشفرض فقط ویکی کنونی است)", "apihelp-query+notifications-param-crosswikisummary": "True to opt in to a summary notification of notifications on foreign wikis.", "apihelp-query+notifications-param-alertcontinue": "زمانی که هشدارهای زیادی موجود هست، از این برای ادامه دادن استفاده کنید.", "apihelp-query+notifications-param-unreadfirst": "برای نمایش آگاهسازیهای مطالعه نشده در ابتدا (فقط اگر گروه بندی بر پایهٔ بخش تنظیم نشدهباشد، استفاده میشود).", @@ -44,23 +50,23 @@ "apihelp-query+notifications-param-messageunreadfirst": "برای نمایش آگاهسازیهای خواندهنشده در ابتدای کار (فقط اگر گروه بندی بر پایهٔ بخش تنظیم نشدهباشد، استفاده میشود).", "apihelp-query+notifications-param-titles": "Only return notifications for these pages. To get notifications not associated with any page, use [] as a title.", "apihelp-query+notifications-param-bundle": "\nWhether to show bundle compatible unread notifications according to notification types bundling rules.", - "apihelp-query+notifications-example-1": "اعلانها را فهرست کن", - "apihelp-query+notifications-example-2": "فهرست اعلانها، بخش بندیش شده، همراه با شمار آنها.", + "apihelp-query+notifications-example-1": "اعلانهای وب را فهرست کن", + "apihelp-query+notifications-example-2": "آگاهسازیهای وب را، بهصورت گروهبندیشده بر پایه بخش، به همراه تعدادشان فهرست کن", "apihelp-query+unreadnotificationpages-description": "دریافت صفحههایی که برایش آگاهسازیهای خواندهنشدهای برای کاربر فعلی وجود دارد.", "apihelp-query+unreadnotificationpages-summary": "دریافت صفحههایی که برایش آگاهسازیهای خواندهنشدهای برای کاربر فعلی وجود دارد.", - "apihelp-query+unreadnotificationpages-param-grouppages": "گروه صفحهٔ بحثها همراه با صفحهٔ موضوعشان و آگاهسازی گروهی ارتباطی به صفحهٔ کاربری این کاربر ندارد.", + "apihelp-query+unreadnotificationpages-param-grouppages": "گروه صفحهٔ بحثها همراه با صفحهٔ موضوعشان و آگاهسازیهای گروهی ارتباطی به صفحهٔ کاربری این کاربر ندارد.", "apihelp-query+unreadnotificationpages-param-limit": "حداکثر صفحاتی که برگردانده میشود.", "apihelp-query+unreadnotificationpages-param-wikis": "فهرست ویکیهایی که آگاهسازی از آنها دریافت میشود (پیشفرض فقط این ویکی).", - "apihelp-query+unreadnotificationpages-example-1": "فهرست کردن صفحهها همراه (مقدار) آگاهسازیهای خواندهنشده", + "apihelp-query+unreadnotificationpages-example-1": "فهرست کردن صفحهها همراه (مقدارشان از) آگاهسازیهای خواندهنشده", "apihelp-echoarticlereminder-summary": "درخواست یادآور برای یک مقالهٔ خاص", "apihelp-echoarticlereminder-param-pageid": "شناسهٔ مقاله برای یادآوری به کاربر", "apihelp-echoarticlereminder-param-title": "عنوان مقاله برای یادآوری به کاربر", "apihelp-echoarticlereminder-param-timestamp": "در چه زمانی یادآوری به کاربر انجام شد", "apihelp-echoarticlereminder-param-comment": "توضیح اختیاری کاربر برای یادآوری", - "apihelp-echoarticlereminder-example-1": "ساخت یادآوری برای فردا همراه با توضیح", - "apihelp-echoarticlereminder-example-2": "ساخت یادآوری برای فردا همراه بدون توضیح", + "apihelp-echoarticlereminder-example-1": "ایجاد یک آگاهسازی یادآور برای فردا همراه با توضیح", + "apihelp-echoarticlereminder-example-2": "ساخت آگاهسازی یادآور برای فردا همراه بدون توضیح", "apiwarn-echo-deprecation-timestampformat": "قالب خروجی مدیاویکی در اینجا منسوخ شدهاست. در آینده، ایزو ۸۶۰۱ همواره برای قالب خروجی برچسب زمان استفاده خواهد شد. برنامهٔ خود را تنظیم کنید و <var>timestampFormat</var> را برابر <kbd>ISO_8601</kbd> قرار دهید.", "apiwarn-echo-deprecation-flyout": "<kbd>notformat=flyout</kbd> منسوخ شده و به زودی حذف خواهد شد. از <kbd>notformat=model</kbd> برای گرفتن دادههای خام و از <kbd>notformat=special</kbd> برای گرفتن اچتیامال استفاده کنید.", "apiwarn-echo-deprecation-html": "<kbd>notformat=html</kbd> منسوخ شده و به زودی حذف خواهد شد. به جای آن از <kbd>notformat=special</kbd> استفاده کنید.", - "apierror-echo-event-creation-failed": "امکان ساخت رویداد سامانه آگاهسازی وجود ندارد" + "apierror-echo-event-creation-failed": "امکان ایجاد رویداد سامانه آگاهسازی وجود ندارد" } diff --git a/Echo/i18n/api/fi.json b/Echo/i18n/api/fi.json index 9d8a8419..92bebf68 100644 --- a/Echo/i18n/api/fi.json +++ b/Echo/i18n/api/fi.json @@ -2,7 +2,8 @@ "@metadata": { "authors": [ "Nike", - "Pxos" + "Pxos", + "Rönttönen" ] }, "apihelp-echomarkread-description": "Merkitse ilmoitukset luetuiksi nykyisen käyttäjän kohdalla.", @@ -16,7 +17,7 @@ "apihelp-echomarkseen-example-1": "Merkitse kaikenlaiset ilmoitukset nähdyiksi", "apihelp-echomarkseen-param-type": "Nähdyiksi merkittävien ilmoitusten laatu: 'hälytysilmoitus', 'viesti' tai 'kaikki'.", "apihelp-query+notifications-example-1": "Luettele ilmoitukset", - "apihelp-query+notifications-example-2": "Luettele ilmoitukset ryhmiteltyinä osioihin lukumäärän kera", + "apihelp-query+notifications-example-2": "Luettele ilmoitukset ryhmiteltyinä osioihin lukumäärien kera", "apihelp-query+unreadnotificationpages-description": "Hae sivut, joihin liittyy lukemattomia ilmoituksia pyynnön tekevällä käyttäjällä.", "apihelp-query+unreadnotificationpages-param-limit": "Sivujen enimmäismäärä vastauksessa.", "apihelp-query+unreadnotificationpages-example-1": "Luettele sivut ja niihin liittyvien lukemattomien ilmoitusten määrä" diff --git a/Echo/i18n/api/fr.json b/Echo/i18n/api/fr.json index 5feee802..099d0e76 100644 --- a/Echo/i18n/api/fr.json +++ b/Echo/i18n/api/fr.json @@ -15,8 +15,8 @@ }, "apihelp-echomarkread-description": "Marquer les notifications comme lues pour l’utilisateur actuel.", "apihelp-echomarkread-summary": "Marquer les notifications comme lues pour l’utilisateur actuel.", - "apihelp-echomarkread-param-list": "Une liste des IDs de notification à marquer comme lues.", - "apihelp-echomarkread-param-unreadlist": "Une liste des IDs de notification à marquer comme non lue.", + "apihelp-echomarkread-param-list": "Une liste des identifiants de notifications à marquer comme lues.", + "apihelp-echomarkread-param-unreadlist": "Une liste des identifiants de notifications à marquer comme lues.", "apihelp-echomarkread-param-all": "Si défini, marque toutes les notifications de l’utilisateur comme lues.", "apihelp-echomarkread-param-sections": "Une liste des sections à marquer comme lues.", "apihelp-echomarkread-param-wikis": "Liste des wikis sur lesquels marquer la notification comme lue (par défaut, uniquement le wiki actuel).", @@ -26,62 +26,68 @@ "apihelp-echomarkseen-description": "Marquer les notifications comme vues pour l’utilisateur actuel.", "apihelp-echomarkseen-summary": "Marquer les notifications comme vues pour l’utilisateur courant.", "apihelp-echomarkseen-example-1": "Marquer les notifications de tous types comme vues.", - "apihelp-echomarkseen-param-type": "Type de notifications à marquer comme vues : 'alert', 'message' ou 'all'.", - "apihelp-echomarkseen-param-timestampFormat": "Format d’horodatage à utiliser pour la sortie, 'ISO_8601' ou 'MW'. 'MW' est ici désuet, donc tous les clients devraient basculer vers 'ISO_8601'. Ce paramètre sera supprimé, et 'ISO_8601' deviendra le seul format de sortie.", - "apihelp-echomute-description": "Faire taire ou non les notifications de certains utilisateurs ou pages.", - "apihelp-echomute-summary": "Faire taire ou non les notifications de certains utilisateurs ou pages.", + "apihelp-echomarkseen-param-type": "Type de notifications à marquer comme vues : « alert » (alerte), « message » ou « all » (tous).", + "apihelp-echomarkseen-param-timestampFormat": "Format d’horodatage à utiliser pour la sortie, « ISO_8601 » ou « MW ». « MW » est désuet ici, donc tous les clients devraient basculer vers « ISO_8601 ». Ce paramètre sera supprimé et « ISO_8601 » deviendra le seul format de sortie.", + "apihelp-echomute-description": "Faire taire ou non les notifications issues de certains utilisateurs ou pages.", + "apihelp-echomute-summary": "Faire taire ou non les notifications issues de certains utilisateurs ou pages.", "apihelp-echomute-param-type": "Quelle liste de mise en silence à laquelle ajouter ou de laquelle supprimer", "apihelp-echomute-param-mute": "Pages ou utilisateurs à ajouter à la liste de mise en silence", - "apihelp-echomute-param-unmute": "Pages ou utilisateurs à supprimer de la liste de mise en silence", - "apihelp-echopushsubscriptions-summary": "Garer les abonnements de poussée d’information pour l’utilisateur actuel.", + "apihelp-echomute-param-unmute": "Pages ou utilisateurs à enlever de la liste de mise en silence", + "apihelp-echopushsubscriptions-summary": "Gérer les abonnements de poussée d’informations pour l’utilisateur actuel.", "apihelp-echopushsubscriptions-param-command": "Action à effectuer.", - "apihelp-echopushsubscriptions+create-summary": "Enregistrer les inscriptions de poussée d’information pour l’utilisateur actuel.", - "apihelp-echopushsubscriptions+create-param-provider": "Le fournisseur de service de poussée pour lequel enregistrer un jeton.", - "apihelp-echopushsubscriptions+create-param-providertoken": "Le jeton à enregistrer.", - "apihelp-echopushsubscriptions+create-example": "Enregistrer une inscription de poussée d’information pour l’utilisateur actuel.", - "apihelp-echopushsubscriptions+delete-summary": "Désinscrire les inscriptions de poussée d’information pour l’utilisateur actuel.", - "apihelp-echopushsubscriptions+delete-param-providertoken": "Le jeton associé avec l’inscription de poussée d’information à désinscrire.", - "apihelp-echopushsubscriptions+delete-example": "Désinscrire une inscription de poussée d’information pour l’utilisateur actuel.", - "apihelp-query+notifications-description": "Obtenir les notifications en attente pour l’utilisateur courant.", + "apihelp-echopushsubscriptions+create-summary": "Inscrire des abonnements de poussée d’informations pour l’utilisateur actuel.", + "apihelp-echopushsubscriptions+create-param-provider": "Le fournisseur de service de poussée pour lequel inscrire un jeton.", + "apihelp-echopushsubscriptions+create-param-providertoken": "Le jeton à inscrire.", + "apihelp-echopushsubscriptions+create-param-topic": "Le sujet APNS (identifiant du paquet d’application) vers lequel envoyer la notification.", + "apihelp-echopushsubscriptions+create-example": "Inscrire un abonnement de poussée d’informations pour l’utilisateur actuel.", + "apihelp-echopushsubscriptions+delete-summary": "Désinscrire les abonnements en poussée de l’utilisateur actuel ou d’un autre utilisateur spécifié.", + "apihelp-echopushsubscriptions+delete-param-providertoken": "Le jeton associé avec l’abonnement de poussée d’informations à désinscrire.", + "apihelp-echopushsubscriptions+delete-param-centraluserid": "L’identifiant d’utilisateur central associé avec l’abonnement à désinscrire.", + "apihelp-echopushsubscriptions+delete-example": "Désinscrire un abonnement de poussée d’informations pour l’utilisateur actuel.", + "apihelp-query+notifications-description": "Obtenir les notifications en attente pour l’utilisateur actuel.", "apihelp-query+notifications-summary": "Obtenir les notifications en attente pour l’utilisateur actuel.", "apihelp-query+notifications-param-prop": "Détails à demander.", - "apihelp-query+notifications-param-sections": "Les sections de notification à demander (c'est-à-dire une combinaison de 'alert' et 'message').", - "apihelp-query+notifications-param-groupbysection": "Indique s’il faut grouper les résultats par section. Chaque section est analysée séparément si défini.", + "apihelp-query+notifications-param-sections": "Les sections de notification à demander (c’est-à-dire une combinaison de « alert » et « message »).", + "apihelp-query+notifications-param-groupbysection": "Indique s’il faut grouper les résultats par section. Si défini, chaque section est récupérée séparément.", "apihelp-query+notifications-param-filter": "Filtrer les notifications renvoyées.", - "apihelp-query+notifications-param-format": "Si spécifié, les notifications seront renvoyées dans ce format.", + "apihelp-query+notifications-param-format": "Si spécifié, les notifications seront renvoyées de cette façon.", "apihelp-query+notifications-paramvalue-format-model": "Données de notification brutes", - "apihelp-query+notifications-paramvalue-format-special": "Formaté pour la page Special:Notifications (et seulement pour elle !) Ne vous fiez pas au code HTML, car il peut changer à tout moment.", + "apihelp-query+notifications-paramvalue-format-special": "Formaté pour la page Special:Notifications (et seulement pour elle !). Ne vous fiez pas au code HTML généré, car il peut changer à tout moment.", "apihelp-query+notifications-paramvalue-format-flyout": "<span class=\"apihelp-deprecated\">Désuet</span>. Utiliser <kbd>$1format=model</kbd> pour les données brutes", "apihelp-query+notifications-paramvalue-format-html": "<span class=\"apihelp-deprecated\">Désuet</span>. Utiliser <kbd>$1format=model</kbd> pour les données brutes", "apihelp-query+notifications-param-limit": "Le nombre maximal de notifications à renvoyer.", - "apihelp-query+notifications-param-wikis": "Liste des wikis à partir desquels récupérer les notifications (par défaut, seul le wiki courant).", - "apihelp-query+notifications-param-crosswikisummary": "Vrai pour choisir une notification de résumé pour les notifications sur les wikis externes", - "apihelp-query+notifications-param-alertcontinue": "Quand plus d’alertes sont disponibles, utiliser cela pour continuer.", + "apihelp-query+notifications-param-wikis": "Liste des wikis depuis lesquels récupérer les notifications (par défaut, seul le wiki actuel).", + "apihelp-query+notifications-param-crosswikisummary": "Vrai pour choisir une notification récapitulative des notifications sur les wikis externes.", + "apihelp-query+notifications-param-alertcontinue": "Quand plus de résultats d’alertes sont disponibles, utiliser cela pour continuer.", "apihelp-query+notifications-param-unreadfirst": "S’il faut afficher les notifications non lues en premier ou non (utilisé uniquement si <kbd>groupbysection</kbd> n’est pas défini).", "apihelp-query+notifications-param-alertunreadfirst": "S’il faut afficher d’abord les notifications de messages non lus ou non (utilisé uniquement si <kbd>groupbysection</kbd> est défini).", - "apihelp-query+notifications-param-messagecontinue": "Quand plus de résultats de message sont disponibles, utiliser cela pour continuer.", + "apihelp-query+notifications-param-messagecontinue": "Quand plus de résultats de messages sont disponibles, utiliser cela pour continuer.", "apihelp-query+notifications-param-messageunreadfirst": "S’il faut afficher les notifications d’alerte non lues en premier ou non (utilisé uniquement si <kbd>groupbysection</kbd> est défini).", - "apihelp-query+notifications-param-titles": "Retourne uniquement les notifications concernant ces pages. Pour obtenir des notifications associées à aucune page, utilisez [] comme titre.", - "apihelp-query+notifications-param-bundle": "Indique s'il faut afficher les notifications non lues compatibles avec les règles de regroupement des types de notification.", - "apihelp-query+notifications-example-1": "Lister les notifications", - "apihelp-query+notifications-example-2": "Lister les notifications, groupées par section, avec les compteurs", - "apihelp-query+unreadnotificationpages-description": "Obtenez les pages pour lesquelles il y a des notifications non lues pour l'utilisateur actuel.", + "apihelp-query+notifications-param-titles": "Retourne uniquement les notifications concernant ces pages. Pour obtenir des notifications associées à aucune page, utiliser [] comme titre.", + "apihelp-query+notifications-param-bundle": "Indique s'il faut afficher les notifications non lues selon les règles de regroupement des types de notification.", + "apihelp-query+notifications-param-notifiertypes": "Types de notificateur pour lesquels renvoyer des notifications.", + "apihelp-query+notifications-example-1": "Lister les notifications web", + "apihelp-query+notifications-example-2": "Lister les notifications web, groupées par section, avec les compteurs", + "apihelp-query+notifications-example-3": "Lister les notifications par courriel", + "apihelp-query+unreadnotificationpages-description": "Obtenir les pages pour lesquelles il y a des notifications non lues pour l’utilisateur actuel.", "apihelp-query+unreadnotificationpages-summary": "Obtenir les pages pour lesquelles il y a des notifications non lues concernant l’utilisateur courant.", - "apihelp-query+unreadnotificationpages-param-grouppages": "Grouper les pages de discussion ensemble avec leur page de sujet, et grouper ensemble les notifications non associées avec une page avec la page de l’utilisateur actuel.", + "apihelp-query+unreadnotificationpages-param-grouppages": "Regrouper les pages de discussion avec leur page de sujet et regrouper les notifications non associées à une page avec la page de l’utilisateur actuel.", "apihelp-query+unreadnotificationpages-param-limit": "Nombre maximal de pages à renvoyer.", - "apihelp-query+unreadnotificationpages-param-wikis": "Liste des wikis pour télécharger les pages comportant des notifications non lues (par défaut, seulement pour le wiki courant).", - "apihelp-query+unreadnotificationpages-example-1": "Liste des pages avec (leur quantité) de notifications non lues", - "apihelp-echoarticlereminder-summary": "Demander un rappel futur concernant l’article spécifié", - "apihelp-echoarticlereminder-param-pageid": "ID de l’article à rappeler à l’utilisateur", + "apihelp-query+unreadnotificationpages-param-wikis": "Liste des wikis d’où récupérer les pages avec des notifications non lues (par défaut, seulement le wiki actuel).", + "apihelp-query+unreadnotificationpages-example-1": "Lister les pages avec des notifications non lues (et leur quantité)", + "apihelp-echoarticlereminder-summary": "Demander un rappel futur au sujet de l’article spécifié", + "apihelp-echoarticlereminder-param-pageid": "Identifiant de l’article à rappeler à l’utilisateur", "apihelp-echoarticlereminder-param-title": "Titre de l’article à rappeler à l’utilisateur", - "apihelp-echoarticlereminder-param-timestamp": "A quel moment rappeler l’utilisateur", - "apihelp-echoarticlereminder-param-comment": "Commentaire optionnel utilisateur à inclure lors du rappel", - "apihelp-echoarticlereminder-example-1": "Créer une notification de rappel d’article pour demain avec commentaire", + "apihelp-echoarticlereminder-param-timestamp": "À quel moment rappeler l’utilisateur", + "apihelp-echoarticlereminder-param-comment": "Commentaire utilisateur facultatif à inclure dans le rappel", + "apihelp-echoarticlereminder-example-1": "Créer une notification de rappel d’article pour demain avec un commentaire", "apihelp-echoarticlereminder-example-2": "Créer une notification de rappel d’article pour demain sans commentaire", "apiwarn-echo-deprecation-timestampformat": "Le format de sortie utilisant l’horodatage MW est désuet ici. À l’avenir, la norme ISO 8601 sera toujours utilisée pour le format d’horodatage en sortie. Ajustez votre client et mettez <var>timestampFormat</var> à <kbd>ISO_8601</kbd>.", - "apiwarn-echo-deprecation-flyout": "<kbd>notformat=flyout</kbd> est devenu désuet et va être supprimé bientôt. Utiliser <kbd>notformat=model</kbd> pour avoir le format brut ou <kbd>notformat=special</kbd> pour le html préformaté.", + "apiwarn-echo-deprecation-flyout": "<kbd>notformat=flyout</kbd> est devenu désuet et va bientôt être supprimé. Utilisez <kbd>notformat=model</kbd> pour obtenir le format brut ou <kbd>notformat=special</kbd> pour du HTML préformaté.", "apiwarn-echo-deprecation-html": "<kbd>notformat=html</kbd> est désuet et sera bientôt supprimé. Utilisez <kbd>notformat=special</kbd> à la place.", "apierror-echo-event-creation-failed": "Impossible de créer l’évènement Echo", "apierror-echo-push-token-exists": "Le jeton fourni existe déjà dans la base de données.", - "apierror-echo-push-token-not-found": "Le jeton fourni n’a pas été trouvé dans la base de données." + "apierror-echo-push-token-not-found": "Le jeton fourni n’a pas été trouvé dans la base de données.", + "apierror-echo-push-too-many-subscriptions": "L’utilisateur actuel a déjà inscrit le nombre maximal autorisé de demandes d’abonnement ($1).", + "apierror-echo-push-topic-required": "Le champ sujet est obligatoire pour ce fournisseur." } diff --git a/Echo/i18n/api/he.json b/Echo/i18n/api/he.json index 4f850c12..f40b6f65 100644 --- a/Echo/i18n/api/he.json +++ b/Echo/i18n/api/he.json @@ -10,7 +10,7 @@ "apihelp-echomarkread-param-list": "רשימת מזהי התראות שצריך לסמן שהן נקראו.", "apihelp-echomarkread-param-unreadlist": "רשימת מזהי הודעה לסימון כהודעות שלא נקראו.", "apihelp-echomarkread-param-all": "אם זה מוגדר, כל ההודעות של המשתמש תסומנה בתור הודעות שנקראו.", - "apihelp-echomarkread-param-sections": "רשימת פסקאות שיש לסמן שהן נקראו.", + "apihelp-echomarkread-param-sections": "רשימת פרקים שיש לסמן שהן נקראו.", "apihelp-echomarkread-param-wikis": "רשימת אתרי ויקי שבהם יסומן שההתראה נקראה (ברירת המחדל היא הוויקי הנוכחי).", "apihelp-echomarkread-example-1": "לסמן שהודעה 8 נקראה", "apihelp-echomarkread-example-2": "לסמן שכל ההתראות נקראו", @@ -30,15 +30,17 @@ "apihelp-echopushsubscriptions+create-summary": "רישום מינויים בדחיפה עבור המשתמש הנוכחי.", "apihelp-echopushsubscriptions+create-param-provider": "ספק שירותי הדחיפה שצריך לרשום אסימון עבורו.", "apihelp-echopushsubscriptions+create-param-providertoken": "האסימון שצריך לרשום.", + "apihelp-echopushsubscriptions+create-param-topic": "נושא ה־APNS (מזהה חבילת יישומים) שצריך לשלוח אליו את ההתראה.", "apihelp-echopushsubscriptions+create-example": "רישום מינוי בדחיפה עבור המשתמש הנוכחי.", - "apihelp-echopushsubscriptions+delete-summary": "ביטול רישום מינויים בדחיפה עבור המשתמש הנוכחי.", + "apihelp-echopushsubscriptions+delete-summary": "ביטול רישום מינויי דחיפה עבור המשתמש הנוכחי או משתמש אחר שיצוין.", "apihelp-echopushsubscriptions+delete-param-providertoken": "האסימון המשויך עם המינוי בדחיפה שצריך לבטל את הרישום שלו.", + "apihelp-echopushsubscriptions+delete-param-centraluserid": "מזהה המשתמש המרכזי שמזוהה עם המינוי שצריך לבטל את הרישום שלו.", "apihelp-echopushsubscriptions+delete-example": "ביטול רישום מינוי בדחיפה עבור המשתמש הנוכחי.", "apihelp-query+notifications-description": "קבלת התראות שממתינות למשתמש הנוכחי.", "apihelp-query+notifications-summary": "קבלת התראות שממתינות למשתמש הנוכחי.", "apihelp-query+notifications-param-prop": "אילו פרטים לבקש.", - "apihelp-query+notifications-param-sections": "אזורי ההודעות שצריך לאחזר (כלומר, שילוב כלשהו של 'alert' ו־'message').", - "apihelp-query+notifications-param-groupbysection": "האם לקבץ את התוצאות לפי פסקה. כל פסקה מאוחזרת בנפרד אם זה מוגדר.", + "apihelp-query+notifications-param-sections": "חלקי ההתראות שצריך לאחזר (כלומר, שילוב כלשהו של 'alert' ו־'message').", + "apihelp-query+notifications-param-groupbysection": "האם לקבץ את התוצאות לפי חלקים. כל חלק מאוחזר בנפרד אם זה מוגדר.", "apihelp-query+notifications-param-filter": "סינון ההודעות שהוחזרו.", "apihelp-query+notifications-param-format": "אם זה מצוין, ההודעות תוחזרנה עם עיצוב כזה.", "apihelp-query+notifications-paramvalue-format-model": "נתוני התראה גולמיים", @@ -55,8 +57,10 @@ "apihelp-query+notifications-param-messageunreadfirst": "האם להציג הודעות התראה שלא נקראו תחילה (משמש רק אם groupbysection לא הוגדר).", "apihelp-query+notifications-param-titles": "להחזיר רק התראות עבור הדפים האלה. כדי לקבל התראות שאינן שייכות לשום דף, יש להשתמש בטקסט [] בתור הכותרת.", "apihelp-query+notifications-param-bundle": "האם להציג התראות תואמות־חבילה בהתאם לחוקי החבילה של סוגי ההתראות.", - "apihelp-query+notifications-example-1": "רשימת הודעות", - "apihelp-query+notifications-example-2": "רשימת הודעות, מקובצות לפי פסקה, עם מונים", + "apihelp-query+notifications-param-notifiertypes": "סוגי מודיעים שעבורם צריכים להחזיר התראות.", + "apihelp-query+notifications-example-1": "רשימת התראות וב", + "apihelp-query+notifications-example-2": "רשימת התראות וב, מקובצות לפי חלק, עם מונים", + "apihelp-query+notifications-example-3": "רשימת התראות דוא\"ל", "apihelp-query+unreadnotificationpages-description": "קבלת דפים שעבורם יש הודעות שלא נקראו למשתמש הנוכחי.", "apihelp-query+unreadnotificationpages-summary": "קבלת דפים שעבורם יש הודעות שלא נקראו למשתמש הנוכחי.", "apihelp-query+unreadnotificationpages-param-grouppages": "לקבץ דפי שיחה יחד עם דפי התוכן המשויכים להם, ולקבץ הודעות שאינן משויכות לשום דף לדף המשתמש של המשתמש הנוכחי.", @@ -67,7 +71,7 @@ "apihelp-echoarticlereminder-param-pageid": "מזהה הערך שלגביו המשתמש יתוזכר", "apihelp-echoarticlereminder-param-title": "שם הערך שלגביו המשתמש יתוזכר", "apihelp-echoarticlereminder-param-timestamp": "מתי לתזכר את המשתמש (תאריך ושעה)", - "apihelp-echoarticlereminder-param-comment": "הערת משתמש אופציונלית שתיכלל בתזכור", + "apihelp-echoarticlereminder-param-comment": "הערת משתמש אופציונלית שתיכלל בתזכורת", "apihelp-echoarticlereminder-example-1": "יצירת הודעת תזכור לגבי ערך למחר עם הערה", "apihelp-echoarticlereminder-example-2": "יצירת הודעת תזכור לגבי ערך למחר ללא הערה", "apiwarn-echo-deprecation-timestampformat": "תסדיר חותם־הזמן של מדיה־ויקי הוגדר כאן בתור מיושן. בעתיד, ISO 8601 תמיד ישמש לפלט של חותם־הזמן. נא לתקן את הלקוח שלך ולהגדיר את <var>timestampFormat</var> לערך <kbd>ISO_8601</kbd>.", @@ -75,5 +79,7 @@ "apiwarn-echo-deprecation-html": "<kbd>notformat=html</kbd> הוכרז בתור מיושן ויוסר כליל בקרוב. נא להשתמש ב־<kbd>notformat=special</kbd> במקומו.", "apierror-echo-event-creation-failed": "לא ניתן היה ליצור את פעולת ה־Echo", "apierror-echo-push-token-exists": "האסימון שסופק כבר קיים במסד הנתונים.", - "apierror-echo-push-token-not-found": "האסימון שסופק לא נמצא במסד הנתונים." + "apierror-echo-push-token-not-found": "האסימון שסופק לא נמצא במסד הנתונים.", + "apierror-echo-push-too-many-subscriptions": "המשתמש הנוכחי כבר רשם את המספר המרבי של מינויי דחיפה ($1)", + "apierror-echo-push-topic-required": "שדה הנושא נדרש על־ידי הספק הזה." } diff --git a/Echo/i18n/api/hi.json b/Echo/i18n/api/hi.json index 93af4b84..ece8f16c 100644 --- a/Echo/i18n/api/hi.json +++ b/Echo/i18n/api/hi.json @@ -2,20 +2,43 @@ "@metadata": { "authors": [ "Hindustanilanguage", + "Saurmandal", "Sfic" ] }, "apihelp-echomarkread-description": "वर्तमान सदस्य की अधिसूचनाओं पढ़ी गई रेखांकित करें।", + "apihelp-echomarkread-summary": "वर्तमान सदस्य के लिए अधिसूचनाओं को पठित चिह्नित करें।", "apihelp-echomarkread-param-list": "अधिसूचनाओं के आई०डी० की सूची जिन्हें पढ़े जाने के तौर पर रेखांकित करना है।", + "apihelp-echomarkread-param-unreadlist": "अपठित चिह्नित करने के लिए अधिसूचना ID-ओं की एक सूची।", "apihelp-echomarkread-param-all": "यदि तय हो, किसी सदस्य की सारे अधिसूचनाओं पढ़े जाने के तौर पर रेखांकित करें।", "apihelp-echomarkread-param-sections": "अनुभागों की सूची जिन्हें पढ़े जाने के तौर पर रेखांकित करना है।", + "apihelp-echomarkread-param-wikis": "पठित चिह्नित करने के लिए अधिसूचनाओं वाले विकियों की एक सूची (डिफ़ॉल्ट है सिर्फ वर्तमान विकि)।", "apihelp-echomarkread-example-1": "अधिसूचना ८ को पढ़े जाने के तौर पर चिन्हित करें", "apihelp-echomarkread-example-2": "सभी अधिसूचनाओं को पढ़े जाने के तौर पर चिन्हित करें", - "apihelp-echomarkread-example-3": "सूचना 1 को न पढ़ा चिन्हित करें", + "apihelp-echomarkread-example-3": "अधिसूचना 1 को अपठित चिह्नित करें", "apihelp-echomarkseen-description": "वर्तमान सदस्य की अधिसूचनाओं पढ़ी गई रेखांकित करें।", + "apihelp-echomarkseen-summary": "वर्तमान सदस्य के लिए अधिसूचनाओं को देखा गया चिह्नित करें।", "apihelp-echomarkseen-example-1": "अधिसूचनाओं को देखे जाने के तौर पर चिन्हित करें", + "apihelp-echomarkseen-param-type": "देखा गया चिह्नित करने के लिए अधिसूचनाओं के प्रकार: 'alert', 'message', या 'all'।", + "apihelp-echomarkseen-param-timestampFormat": "आउटपुट के लिए प्रयुक्त टाइमस्टैम्प प्रारूप, 'ISO_8601' या 'MW'। 'MW' यहाँ पर कालग्रस्त है, तो सभी क्लाइंट्स को 'ISO_8601' में बदल लेना चाहिए। यह पैरामीटर हटा दिया जाएगा, और 'ISO_8601' एकमात्र आउटपुट प्रारूप बन जाएगा।", + "apihelp-echomute-description": "विशिष्ट सदस्यों या पृष्ठों से अधिसूचनाएँ म्यूट या अनम्यूट करें", + "apihelp-echomute-summary": "विशिष्ट सदस्यों या पृष्ठों से अधिसूचनाएँ म्यूट या अनम्यूट करें।", + "apihelp-echomute-param-type": "किस म्यूट सूची पर जोड़ना है या जिससे हटाना है", + "apihelp-echomute-param-mute": "म्यूट सूची पर जोड़ने के लिए पृष्ठ या सदस्य", + "apihelp-echomute-param-unmute": "म्यूट सूची से हटाने के लिए पृष्ठ या सदस्य", + "apihelp-echopushsubscriptions-summary": "वर्तमान सदस्य के लिए पुश सदस्यताएँ प्रबंधित करें।", + "apihelp-echopushsubscriptions-param-command": "करने के लिए कार्य।", + "apihelp-echopushsubscriptions+create-summary": "वर्तमान सदस्य के लिए पुश सदस्यताएँ पंजीकृत करें।", + "apihelp-echopushsubscriptions+create-param-provider": "पुश सेवा प्रदाता जिसके लिए टोकन पंजीकृत करना है।", + "apihelp-echopushsubscriptions+create-param-providertoken": "पंजीकृत करने के लिए टोकन।", + "apihelp-echopushsubscriptions+create-param-topic": "APNS विषय (ऐप बंडल ID) जहाँ पर अधिसूचना भेजी जाएगी।", + "apihelp-echopushsubscriptions+create-example": "वर्तमान सदस्य के लिए एक पुश सदस्यता पंजीकृत करें।", + "apihelp-echopushsubscriptions+delete-summary": "वर्तमान सदस्य या किसीी दूसरे निर्दिष्ट सदस्य के लिए पुश सदस्यताएँ अपंजीकृत करें।", + "apihelp-echopushsubscriptions+delete-param-providertoken": "अपंजीकृत करने के लिए पुश सदस्यता से जुड़ा टोकन।", + "apihelp-echopushsubscriptions+delete-param-centraluserid": "अपंजीकृत करने के लिए सदस्यता से जुड़ा केंद्रीय सदस्य ID।", "apihelp-query+notifications-param-sections": "पूछताछ के अधिसूचना अनुभाग", - "apihelp-query+notifications-paramvalue-format-model": "पंक्ति में सूचना डाटा", - "apihelp-query+notifications-example-1": "अधिसूचनाओं को सूचीबद्ध करें", - "apihelp-query+notifications-example-2": "अधिसूचनाओं को सूचीबद्ध अनुभाग के अनुसार सम्मिलित करके गिनकर करें" + "apihelp-query+notifications-paramvalue-format-model": "रॉ अधिसूचना डेटा", + "apihelp-query+notifications-example-1": "वेब अधिसूचनाओं को सूचीबद्ध करें", + "apihelp-query+notifications-example-2": "वेब अधिसूचनाओं को सूचीबद्ध अनुभाग के अनुसार सम्मिलित करके गिनकर करें", + "apihelp-query+notifications-example-3": "ईमेल अधिसूचनाओं को सूचीबद्ध करें" } diff --git a/Echo/i18n/api/hr.json b/Echo/i18n/api/hr.json index 4c1fdfc7..b4c23f14 100644 --- a/Echo/i18n/api/hr.json +++ b/Echo/i18n/api/hr.json @@ -4,5 +4,7 @@ "Bugoslav" ] }, - "apihelp-query+notifications-example-1": "Ispis obavijesti" + "apihelp-echopushsubscriptions+delete-summary": "Otkaži nametnute (''push'') pretplate za suradnika koji je trenutačno prijavljen ili drugoga specificiranoga suradnika.", + "apihelp-query+notifications-example-1": "Ispis obavijesti", + "apierror-echo-push-topic-required": "Polje za predmet obvezno je popuniti za ovoga davatelja." } diff --git a/Echo/i18n/api/hu.json b/Echo/i18n/api/hu.json index 06b98e8c..9109cf0f 100644 --- a/Echo/i18n/api/hu.json +++ b/Echo/i18n/api/hu.json @@ -7,18 +7,37 @@ ] }, "apihelp-echomarkread-description": "Értesítések olvasottnak jelölése az aktuális felhasználó számára.", + "apihelp-echomarkread-summary": "A jelenlegi felhasználó értesítéseinek olvasottnak jelölése.", "apihelp-echomarkread-param-list": "Az olvasottnak jelölendő értesítések ID-inek listája.", "apihelp-echomarkread-param-unreadlist": "Olvasatlannak jelölendő értesítésazonosítók listája.", "apihelp-echomarkread-param-all": "Ha meg van adva, az adott felhasználó összes értesítését olvasottnak jelöli.", "apihelp-echomarkread-param-sections": "Az olvasottnak jelölendő szakaszok listája.", + "apihelp-echomarkread-param-wikis": "Az olvasottnak jelölendő wikik listája (alapértelmezetten a csak jelenlegi wiki).", "apihelp-echomarkread-example-1": "A 8-as számú értesítés olvasottnak jelölése", "apihelp-echomarkread-example-2": "Az összes értesítés olvasottnak jelölése", "apihelp-echomarkread-example-3": "1-es azonosítójú értesítés megjelölése olvasatlanként", "apihelp-echomarkseen-description": "Értesítések látottnak jelölése az aktuális felhasználó számára.", + "apihelp-echomarkseen-summary": "Értesítések látottnak jelölése az aktuális felhasználó számára.", "apihelp-echomarkseen-example-1": "Az összes fajta értesítés látottnak jelölése.", "apihelp-echomarkseen-param-type": "A látottnak jelölendő értesítések típusa: 'alert', 'message' vagy 'all'.", "apihelp-echomarkseen-param-timestampFormat": "A kimenetben használandó időbélyeg-formátum, „ISO_8601” vagy „MW”. Az „MW” elavult itt, minden kliensnek „ISO_8601”-re kellene váltania. Ez a paraméter el lesz távolítva, és az „ISO_8601” lesz az egyetlen kimeneti formátum.", + "apihelp-echomute-description": "Értesítések némítása vagy engedélyezése bizonyos felhasználóktól vagy bizonyos lapokhoz kapcsolódóan.", + "apihelp-echomute-summary": "Értesítések némítása vagy engedélyezése bizonyos felhasználóktól vagy bizonyos lapokhoz kapcsolódóan.", + "apihelp-echomute-param-type": "A módosítandó némításlista", + "apihelp-echomute-param-mute": "A listához adandó lapok vagy felhasználók", + "apihelp-echomute-param-unmute": "A listáról eltávolítandó lapok vagy felhasználók", + "apihelp-echopushsubscriptions-summary": "A jelenlegi felhasználó leküldéses értesítéseinek kezelése.", + "apihelp-echopushsubscriptions-param-command": "A végrehajtandó művelet.", + "apihelp-echopushsubscriptions+create-summary": "Leküldéses értesítések regisztrálása a jelenlegi felhasználónak.", + "apihelp-echopushsubscriptions+create-param-provider": "A token regisztrálása ehhez leküldésesértesítés-szolgáltatóhoz.", + "apihelp-echopushsubscriptions+create-param-providertoken": "A regisztrálandó token.", + "apihelp-echopushsubscriptions+create-example": "Egy leküldéses feliratkozás regisztrálása a jelenlegi felhasználónak.", + "apihelp-echopushsubscriptions+delete-summary": "A jelenlegi vagy egy másik felhasználó leküldéses feliratkozásainak törlése.", + "apihelp-echopushsubscriptions+delete-param-providertoken": "A törlendő feliratkozáshoz kapcsolódó token.", + "apihelp-echopushsubscriptions+delete-param-centraluserid": "A törlendő feliratkozáshoz kapcsolódó központi felhasználóazonosító.", + "apihelp-echopushsubscriptions+delete-example": "Egy leküldéses feliratkozás törlése a jelenlegi felhasználónak.", "apihelp-query+notifications-description": "Az aktuális felhasználónak szóló értesítések lekérdezése.", + "apihelp-query+notifications-summary": "Az aktuális felhasználónak szóló várakozó értesítések lekérdezése.", "apihelp-query+notifications-param-prop": "A lekérdezendő részletek.", "apihelp-query+notifications-param-sections": "A lekérdezendő szakaszok ('alert' és/vagy 'message').", "apihelp-query+notifications-param-groupbysection": "Eredmény csoportosítása szakaszok szerint.", @@ -30,6 +49,7 @@ "apihelp-query+notifications-paramvalue-format-html": "<span class=\"apihelp-deprecated\">Elavult</span>. Használd a(z) <kbd>$1format=model</kbd>t nyers adatokért.", "apihelp-query+notifications-param-limit": "Az egy választban visszaadott értesítések maximális száma.", "apihelp-query+notifications-param-wikis": "Az értesítésekért lekérdezendő wikik listája (alapértelmezetten csak a jelenlegi).", + "apihelp-query+notifications-param-crosswikisummary": "Más wikik értesítéseinek összefoglalóinak visszaadása a helyi értesítések mellett.", "apihelp-query+notifications-param-alertcontinue": "Ha nem minden figyelmeztetés fért bele a válaszba, ezzel lehet lekérdezni a továbbiakat.", "apihelp-query+notifications-param-unreadfirst": "Előrevegye-e az olvasatlan értesítéseket (csak akkor van használatban, ha a groupbysection meg van adva).", "apihelp-query+notifications-param-alertunreadfirst": "Előrevegye-e az olvasatlan üzeneteket (csak akkor van használatban, ha a groupbysection meg van adva).", diff --git a/Echo/i18n/api/ia.json b/Echo/i18n/api/ia.json index f7b211c8..9227bb0a 100644 --- a/Echo/i18n/api/ia.json +++ b/Echo/i18n/api/ia.json @@ -4,6 +4,81 @@ "McDutchie" ] }, + "apihelp-echomarkread-description": "Marcar notificationes como legite pro le usator actual.", + "apihelp-echomarkread-summary": "Marcar notificationes como legite pro le usator actual.", + "apihelp-echomarkread-param-list": "Un lista de IDs de notification a marcar como legite.", "apihelp-echomarkread-param-unreadlist": "Un lista de IDs de notification a marcar como non legite.", - "apihelp-echomarkread-example-3": "Marcar le notification 1 como non legite" + "apihelp-echomarkread-param-all": "Si definite, marca tote le notificationes de un usator como legite.", + "apihelp-echomarkread-param-sections": "Un lista de sectiones a marcar como legite.", + "apihelp-echomarkread-param-wikis": "Lista de wikis in le quales marcar notificationes como legite (predefinite al wiki actual solmente).", + "apihelp-echomarkread-example-1": "Marcar le notification 8 como legite", + "apihelp-echomarkread-example-2": "Marcar tote le notificationes como legite", + "apihelp-echomarkread-example-3": "Marcar le notification 1 como non legite", + "apihelp-echomarkseen-description": "Marcar notificationes como vidite pro le usator actual.", + "apihelp-echomarkseen-summary": "Marcar notificationes como vidite pro le usator actual.", + "apihelp-echomarkseen-example-1": "Marcar notificationes de tote le typos como vidite", + "apihelp-echomarkseen-param-type": "Typo de notificationes de marcar como vidite: 'alert', 'message' o 'all'.", + "apihelp-echomarkseen-param-timestampFormat": "Formato del data e hora a usar pro le sortita, 'ISO_8601' o 'MW'. 'MW' es obsolescente hic, dunque tote le clientes deberea cambiar a 'ISO_8601'. Iste parametro essera removite e 'ISO_8601' devenira le unic formato de sortita.", + "apihelp-echomute-description": "Silentiar o non plus silentiar notificationes de certe usatores o paginas.", + "apihelp-echomute-summary": "Silentiar o non plus silentiar notificationes de certe usatores o paginas.", + "apihelp-echomute-param-type": "In qual lista de silentiamento adder o remover", + "apihelp-echomute-param-mute": "Paginas o usatores a adder al lista de silentiamento", + "apihelp-echomute-param-unmute": "Paginas o usatores a remover del lista de silentiamento", + "apihelp-echopushsubscriptions-summary": "Gerer subscriptiones push pro le usator actual.", + "apihelp-echopushsubscriptions-param-command": "Action a exequer.", + "apihelp-echopushsubscriptions+create-summary": "Registrar subscriptiones push pro le usator actual.", + "apihelp-echopushsubscriptions+create-param-provider": "Le fornitor del servicio push pro le qual registrar un token.", + "apihelp-echopushsubscriptions+create-param-providertoken": "Le token a registrar.", + "apihelp-echopushsubscriptions+create-param-topic": "Le topico APNS ''(app bundle ID)'' al qual inviar le notification.", + "apihelp-echopushsubscriptions+create-example": "Registrar un subscription push pro le usator actual.", + "apihelp-echopushsubscriptions+delete-summary": "Cancellar le registration de subscriptiones push pro le usator actual o un altere usator specificate.", + "apihelp-echopushsubscriptions+delete-param-providertoken": "Le token associate al subscription push pro le qual cancellar le registration.", + "apihelp-echopushsubscriptions+delete-param-centraluserid": "Le ID de usator central associate al subscription pro le qual cancellar le subscription.", + "apihelp-echopushsubscriptions+delete-example": "Cancellar le registration de un subscription push pro le usator actual.", + "apihelp-query+notifications-description": "Obtener notificationes attendente pro le usator actual.", + "apihelp-query+notifications-summary": "Obtener notificationes attendente pro le usator actual.", + "apihelp-query+notifications-param-prop": "Le detalios a requestar.", + "apihelp-query+notifications-param-sections": "Le sectiones de notification a consultar (i.e. alcun combination de 'alert' e 'message')", + "apihelp-query+notifications-param-groupbysection": "Indica si gruppar le resultato per section. Cata section se obtene separatemente si isto es definite.", + "apihelp-query+notifications-param-filter": "Filtrar le notificationes restituite.", + "apihelp-query+notifications-param-format": "Si specificate, notificationes se restituera in iste formato.", + "apihelp-query+notifications-paramvalue-format-model": "Datos crude de notification", + "apihelp-query+notifications-paramvalue-format-special": "Formatate pro le pagina Special:Notifications (e solo iste!). Evita depender de iste codice HTML perque illo pote cambiar quandocunque.", + "apihelp-query+notifications-paramvalue-format-flyout": "<span class=\"apihelp-deprecated\">Obsolescente</span>. Usa <kbd>$1format=model</kbd> pro datos crude.", + "apihelp-query+notifications-paramvalue-format-html": "<span class=\"apihelp-deprecated\">Obsolescente</span>. Usa <kbd>$1format=model</kbd> pro datos crude.", + "apihelp-query+notifications-param-limit": "Le numero maxime de notificationes a restituer.", + "apihelp-query+notifications-param-wikis": "Lista de wikis del quales obtener notificationes (predefinite al wiki actual solmente).", + "apihelp-query+notifications-param-crosswikisummary": "Defini isto como ver pro reciper un notification de summario sur le notificationes de wikis externe.", + "apihelp-query+notifications-param-alertcontinue": "Quando plus resultatos de alerta es disponibile, usar isto pro continuar.", + "apihelp-query+notifications-param-unreadfirst": "Indica si monstrar notificationes non legite primo (usate solmente si groupbysection non es definite).", + "apihelp-query+notifications-param-alertunreadfirst": "Indica si monstrar notificationes de messages non legite primo (usate solmente si groupbysection non es definite).", + "apihelp-query+notifications-param-messagecontinue": "Quando plus resultatos de message es disponibile, usar isto pro continuar.", + "apihelp-query+notifications-param-messageunreadfirst": "Indica si monstrar notificationes de alertas non legite primo (usate solmente si groupbysection non es definite).", + "apihelp-query+notifications-param-titles": "Solmente restituer notificationes pro iste paginas. Pro obtener notificationes non associate a alcun pagina, usa [] como titulo.", + "apihelp-query+notifications-param-bundle": "Indica si notificationes non legite compatibile con gruppamentos, debe esser monstrate de accordo con le regulas de gruppamento de typos de notification.", + "apihelp-query+notifications-param-notifiertypes": "Typos de notificator pro le quales restituer notificationes.", + "apihelp-query+notifications-example-1": "Listar notificationes web", + "apihelp-query+notifications-example-2": "Listar notificationes web, gruppate per section, con quantitates", + "apihelp-query+notifications-example-3": "Listar notificationes per e-mail", + "apihelp-query+unreadnotificationpages-description": "Obtener paginas pro le quales il ha notificationes non legite pro le usator actual.", + "apihelp-query+unreadnotificationpages-summary": "Obtener paginas pro le quales il ha notificationes non legite pro le usator actual.", + "apihelp-query+unreadnotificationpages-param-grouppages": "Gruppar paginas de discussion con lor paginas de subjecto, e gruppar notificationes non associate a un pagina con le pagina de usator del usator actual.", + "apihelp-query+unreadnotificationpages-param-limit": "Le numero maxime de paginas a restituer.", + "apihelp-query+unreadnotificationpages-param-wikis": "Lista de wikis del quales obtener paginas con notificationes non legite (predefinite al wiki actual solmente).", + "apihelp-query+unreadnotificationpages-example-1": "Listar paginas con (lor quantitate de) notificationes non legite", + "apihelp-echoarticlereminder-summary": "Requestar un rememoration futur sur le articulo specificate", + "apihelp-echoarticlereminder-param-pageid": "ID del articulo sur le qual rememorar le usator", + "apihelp-echoarticlereminder-param-title": "Titulo del articulo sur le qual rememorar le usator", + "apihelp-echoarticlereminder-param-timestamp": "A qual data e hora rememorar le usator", + "apihelp-echoarticlereminder-param-comment": "Commento de usator optional pro includer in le rememoration", + "apihelp-echoarticlereminder-example-1": "Crear un notification de rememoration de articulo pro deman, con un commento", + "apihelp-echoarticlereminder-example-2": "Crear un notification de rememoration de articulo pro deman, sin commento", + "apiwarn-echo-deprecation-timestampformat": "Le formato de sortita de data e hora MW es obsolescente hic. In le futuro, ISO 8601 essera sempre usate pro le formato de data e hora de sortita. Adjusta tu cliente e mitte <var>timestampFormat</var> a <kbd>ISO_8601</kbd>.", + "apiwarn-echo-deprecation-flyout": "<kbd>notformat=flyout</kbd> ha devenite obsolescente e essera removite tosto. Usa <kbd>notformat=model</kbd> pro obtener le datos crude o <kbd>notformat=special</kbd> pro obtener codice HTML pre-formatate.", + "apiwarn-echo-deprecation-html": "<kbd>notformat=html</kbd> ha devenite obsolescente e essera removite tosto. Usa <kbd>notformat=special</kbd> in su loco.", + "apierror-echo-event-creation-failed": "Non poteva crear evento Echo", + "apierror-echo-push-token-exists": "Le token fornite jam existe in le base de datos.", + "apierror-echo-push-token-not-found": "Le token fornite non ha essite trovate in le base de datos.", + "apierror-echo-push-too-many-subscriptions": "Le usator actual ha jam registrate le numero maxime de subscriptiones push ($1).", + "apierror-echo-push-topic-required": "Le campo de topico es obligatori pro iste fornitor." } diff --git a/Echo/i18n/api/id.json b/Echo/i18n/api/id.json index 524b28a1..96237f34 100644 --- a/Echo/i18n/api/id.json +++ b/Echo/i18n/api/id.json @@ -1,6 +1,7 @@ { "@metadata": { "authors": [ + "Daud I.F. Argana", "Kenrick95", "Rachmat.Wahidi", "Rachmat04", @@ -13,20 +14,32 @@ "apihelp-echomarkread-param-unreadlist": "Daftar ID pemberitahuan yang ingin ditandai sebagai belum dibaca.", "apihelp-echomarkread-param-all": "Jika ditetapkan, menandai semua pemberitahuan pengguna sebagai telah dibaca.", "apihelp-echomarkread-param-sections": "Daftar bagian yang ingin ditandai sebagai telah dibaca.", + "apihelp-echomarkread-param-wikis": "Daftar wiki yang ingin ditandai pemberitahuannya sebagai telah dibaca (secara baku hanya berlaku untuk wiki saat ini).", "apihelp-echomarkread-example-1": "Tandai pemberitahuan 8 sebagai telah dibaca", "apihelp-echomarkread-example-2": "Tandai semua pemberitahuan sebagai telah dibaca", + "apihelp-echomarkread-example-3": "Tandai pemberitahuan 1 sebagai telah dibaca", + "apihelp-echomarkseen-description": "Tandai pemberitahuan dari pengguna ini sebagai telah dibaca.", + "apihelp-echomarkseen-summary": "Tandai pemberitahuan dari pengguna ini sebagai telah dibaca.", + "apihelp-echomarkseen-example-1": "Tandai pemberitahuan dari semua jenis sebagai telah dibaca", + "apihelp-echomarkseen-param-type": "Jenis pemberitahuan untuk ditandai telah dilihat: 'peringatan', 'pesan' atau 'semua'.", + "apihelp-echomute-description": "Bisukan atau suarakan pemberitahuan dari pengguna atau halaman tertentu.", + "apihelp-echomute-summary": "Bisukan atau suarakan pemberitahuan dari pengguna atau halaman tertentu.", + "apihelp-echopushsubscriptions-param-command": "Tindakan untuk dilakukan.", "apihelp-query+notifications-description": "Dapatkan penungguan pemberitahuan untuk pengguna ini.", + "apihelp-query+notifications-summary": "Dapatkan penungguan pemberitahuan untuk pengguna ini.", "apihelp-query+notifications-param-prop": "Rincian yang diminta.", - "apihelp-query+notifications-param-sections": "Bagian pemberitahuan yang ingin didapatkan.", + "apihelp-query+notifications-param-sections": "Bagian pemberitahuan yang ingin didapatkan (misalnya, kombinasi antara 'peringatan' dan 'pesan').", "apihelp-query+notifications-param-groupbysection": "Menentukan apakah perlu mengelompokkan hasil berdasarkan bagian. Jika ditetapkan, setiap bagian diambil secara terpisah.", + "apihelp-query+notifications-param-filter": "Saring pemberitahuan yang dikembalikan.", "apihelp-query+notifications-param-format": "Jika ditetapkan, pemberitahuan akan menghasilkan format seperti ini.", + "apihelp-query+notifications-paramvalue-format-model": "Data pemberitahuan mentah", "apihelp-query+notifications-param-limit": "Jumlah maksimum pemberitahuan yang dihasilkan.", - "apihelp-query+notifications-param-alertcontinue": "Saat ada lebih banyak hasil penanda yang tersedia, gunakan ini untuk melanjutkan.", + "apihelp-query+notifications-param-alertcontinue": "Saat ada lebih banyak hasil peringatan yang tersedia, gunakan ini untuk melanjutkan.", "apihelp-query+notifications-param-alertunreadfirst": "Menentukan apakah harus menampilkan pemberitahuan pesan yang belum dibaca terlebih dahulu.", "apihelp-query+notifications-param-messagecontinue": "Saat ada lebih banyak hasil pesan yang tersedia, gunakan ini untuk melanjutkan.", - "apihelp-query+notifications-param-messageunreadfirst": "Menentukan apakah harus menampilkan pemberitahuan penanda terlebih dahulu.", - "apihelp-query+notifications-example-1": "Daftar pemberitahuan", - "apihelp-query+notifications-example-2": "Daftar pemberitahuan, dikelompokkan berdasarkan bagian, dengan jumlah", + "apihelp-query+notifications-param-messageunreadfirst": "Menentukan apakah harus menampilkan pemberitahuan peringatan terlebih dahulu (hanya digunakan jika groupbysection ditetapkan).", + "apihelp-query+notifications-example-1": "Daftar pemberitahuan web", + "apihelp-query+notifications-example-2": "Daftar pemberitahuan web, dikelompokkan berdasarkan bagian, dengan jumlah", "apihelp-query+unreadnotificationpages-param-limit": "Jumlah halaman maksimum yang ditampilkan.", "apihelp-query+unreadnotificationpages-param-wikis": "Daftar wiki untuk mengambil halaman dengan pemberitahuan belum dibaca (baku hanya pada wiki ini).", "apihelp-query+unreadnotificationpages-example-1": "Daftarkan halaman dengan (jumlah) pemberitahuan belum dibaca" diff --git a/Echo/i18n/api/io.json b/Echo/i18n/api/io.json index e56327c7..15d2c5ef 100644 --- a/Echo/i18n/api/io.json +++ b/Echo/i18n/api/io.json @@ -4,5 +4,8 @@ "Joao Xavier" ] }, - "apihelp-echopushsubscriptions-param-command": "Agado facenda." + "apihelp-echomarkread-description": "Markizez avizi kom lektita, por la nuna uzero.", + "apihelp-echomarkread-example-2": "Markizez omna avizi kom ''vidida''", + "apihelp-echopushsubscriptions-param-command": "Agado facenda.", + "apihelp-query+notifications-description": "Recevar avizi qui vartas la nuna uzero." } diff --git a/Echo/i18n/api/it.json b/Echo/i18n/api/it.json index 1af83416..d0d8ad1e 100644 --- a/Echo/i18n/api/it.json +++ b/Echo/i18n/api/it.json @@ -3,6 +3,7 @@ "authors": [ "Beta16", "Fringio", + "Mannivu", "Matteocng" ] }, @@ -39,7 +40,7 @@ "apihelp-query+notifications-param-messageunreadfirst": "Se mostrare le notifiche degli avvisi non letti prima (usato solo se groupbysection è impostato).", "apihelp-query+notifications-param-titles": "Restituisce solo le notifiche per queste pagine. Per ottenere le notifiche non associate ad alcuna pagina, usa [] come titolo.", "apihelp-query+notifications-example-1": "Elenco notifiche", - "apihelp-query+notifications-example-2": "Elenco notifiche, raggruppate per sezione, con i conteggi", + "apihelp-query+notifications-example-2": "Elenco notifiche web, raggruppate per sezione, con i conteggi", "apihelp-query+unreadnotificationpages-description": "Ottieni le pagine per le quali ci sono notifiche non lette per l'utente attuale.", "apihelp-query+unreadnotificationpages-summary": "Ottieni le pagine per le quali ci sono notifiche non lette per l'utente attuale.", "apihelp-query+unreadnotificationpages-param-limit": "Il numero massimo di pagine da restituire.", diff --git a/Echo/i18n/api/ja.json b/Echo/i18n/api/ja.json index 503a4c82..50a35e67 100644 --- a/Echo/i18n/api/ja.json +++ b/Echo/i18n/api/ja.json @@ -3,7 +3,8 @@ "authors": [ "2nd-player", "Ochaochaocha3", - "Otokoume" + "Otokoume", + "RYOUMA1117" ] }, "apihelp-echomarkread-description": "現在の利用者への通知を既読にする。", @@ -16,7 +17,7 @@ "apihelp-echomarkread-example-3": "通知 1 を未読にする", "apihelp-echomarkseen-param-type": "既読としてマークする通知の種類:'alert'、'message'、あるいは 'all'。", "apihelp-query+notifications-param-limit": "返す通知の最大数。", - "apihelp-query+notifications-example-1": "通知を一覧表示する", - "apihelp-query+notifications-example-2": "通知をセクションによりグループ化し、カウントで一覧表示する", + "apihelp-query+notifications-example-1": "Web通知を一覧表示する", + "apihelp-query+notifications-example-2": "セクションごとにグループ化されたWeb通知をカウントとともに一覧表示します", "apihelp-query+unreadnotificationpages-param-limit": "返すページの最大数。" } diff --git a/Echo/i18n/api/ko.json b/Echo/i18n/api/ko.json index 7af88789..eea1d14f 100644 --- a/Echo/i18n/api/ko.json +++ b/Echo/i18n/api/ko.json @@ -1,8 +1,10 @@ { "@metadata": { "authors": [ + "Bluehill", "Ellif", "Hwangjy9", + "MemphisA5", "Priviet", "Revi", "Ykhwong", @@ -25,16 +27,27 @@ "apihelp-echomarkseen-param-timestampFormat": "출력을 위해 사용할 타임스탬프 포맷 'ISO_8601' 또는 'MW'입니다. 'MW'는 구식이므로 모든 클라이언트는 'ISO_8601'로 전환하는 것이 좋습니다. 이 변수는 제거될 것이며 'ISO_8601'이 유일한 출력 포맷이 될 것입니다.", "apihelp-echomute-description": "특정 사용자나 문서로부터 오는 알림을 끄거나 다시 켭니다.", "apihelp-echomute-summary": "특정 사용자나 문서로부터 오는 알림을 끄거나 다시 켭니다.", + "apihelp-echopushsubscriptions-summary": "현재 사용자의 푸시 구독을 관리합니다.", + "apihelp-echopushsubscriptions-param-command": "수행할 동작입니다.", + "apihelp-echopushsubscriptions+create-summary": "현재 사용자의 푸시 구독을 등록합니다.", + "apihelp-echopushsubscriptions+create-param-provider": "토큰을 등록할 푸시 서비스 제공자입니다.", + "apihelp-echopushsubscriptions+create-param-providertoken": "등록할 토큰입니다.", + "apihelp-echopushsubscriptions+create-example": "현재 사용자의 푸시 구독을 등록합니다.", + "apihelp-echopushsubscriptions+delete-summary": "현재 사용자 또는 다른 지정된 사용자의 푸시 구독의 등록을 취소합니다.", + "apihelp-echopushsubscriptions+delete-param-providertoken": "등록을 취소할 푸시 구독과 관련된 토큰입니다.", + "apihelp-echopushsubscriptions+delete-param-centraluserid": "구독 등록 취소와 관련된 중앙 사용자 ID입니다.", "apihelp-query+notifications-description": "현재 사용자를 기다리고 있는 알림을 얻어옵니다.", "apihelp-query+notifications-summary": "현재 사용자를 기다리고 있는 알림을 가져옵니다.", "apihelp-query+notifications-param-prop": "상세한 요청 내용.", "apihelp-query+notifications-param-sections": "쿼리로의 알림 부분 (예를 들어 'alert'과 'message'의 어떤 조합).", "apihelp-query+notifications-param-filter": "필터 알림 반환됨.", + "apihelp-query+notifications-paramvalue-format-model": "미가공 알림 데이터", + "apihelp-query+notifications-param-limit": "반환할 최대 알림 수입니다.", "apihelp-query+notifications-param-alertcontinue": "더 많은 경보 결과를 사용할 수 있을 때, 계속하려면 이것을 사용합니다.", "apihelp-query+notifications-param-messageunreadfirst": "읽지 않은 경보 알림을 먼저 보여줄지 여부 (groupbysection이 설정되어 있는 경우에만 사용됨).", "apihelp-query+notifications-param-titles": "이 문서들의 알림만 반환합니다. 어떠한 문서에도 속하지 않은 알림을 받으려면 제목으로 []를 사용하세요.", "apihelp-query+notifications-param-bundle": "규칙을 묶는 알림 유형에 따라 묶음과 호환되는 읽지 않은 알림을 보여줄지의 여부.", - "apihelp-query+notifications-example-1": "알림 리스트", + "apihelp-query+notifications-example-1": "웹 알림 리스트", "apihelp-query+unreadnotificationpages-param-limit": "반환할 문서의 최대 수입니다.", "apihelp-query+unreadnotificationpages-param-wikis": "읽지 않은 알림 문서를 가져올 위키 목록입니다. (기본값으로는 현재 위키만)", "apierror-echo-event-creation-failed": "Echo 이벤트를 만들 수 없습니다" diff --git a/Echo/i18n/api/lv.json b/Echo/i18n/api/lv.json index c8b1ecc2..fcb94b1e 100644 --- a/Echo/i18n/api/lv.json +++ b/Echo/i18n/api/lv.json @@ -8,6 +8,8 @@ "apihelp-echomarkread-example-1": "Atzīmēt paziņojumu 8 kā izlasītu", "apihelp-echomarkread-example-2": "Atzīmēt visus paziņojumus kā izlasītus", "apihelp-echomarkread-example-3": "Atzīmēt paziņojumu 1 kā nelasītu", + "apihelp-echomarkseen-example-1": "Atzīmēt visu veidu paziņojumus kā redzētus", + "apihelp-echopushsubscriptions-param-command": "Veicamā darbība.", "apihelp-query+notifications-param-alertcontinue": "Ja pieejami vēl paziņojumu rezultāti, izmanto šo, lai turpinātu.", "apihelp-query+unreadnotificationpages-param-limit": "Maksimālais atgriežamo lapu skaits.", "apihelp-echoarticlereminder-param-pageid": "Raksta ID, par ko dalībniekam atgādināt", diff --git a/Echo/i18n/api/mk.json b/Echo/i18n/api/mk.json index 9ef0b2c8..211bfe62 100644 --- a/Echo/i18n/api/mk.json +++ b/Echo/i18n/api/mk.json @@ -29,9 +29,11 @@ "apihelp-echopushsubscriptions+create-summary": "Пријави претплати на наметнувања за тековниот корисник.", "apihelp-echopushsubscriptions+create-param-provider": "Наметнувачкиот услужник за кој се пријавува шифра.", "apihelp-echopushsubscriptions+create-param-providertoken": "Шифрата која се пријавува.", + "apihelp-echopushsubscriptions+create-param-topic": "APNS-темата (назнака на приложен збир) на која ќе се испрати известувањето.", "apihelp-echopushsubscriptions+create-example": "Пријави претплата на наметнувања за тековниот корисник.", - "apihelp-echopushsubscriptions+delete-summary": "Отпријави претплати на наметнувања за тековниот корисник.", + "apihelp-echopushsubscriptions+delete-summary": "Отпријави претплати на наметнувања за тековниот корисник или друг укажан корисник.", "apihelp-echopushsubscriptions+delete-param-providertoken": "Шифрата поврзана со претплатеното наметнување кое треба да се отстрани од пријавени.", + "apihelp-echopushsubscriptions+delete-param-centraluserid": "Централната корисничка назнака поврзана со претплатата што треба да се отпријави.", "apihelp-echopushsubscriptions+delete-example": "Отпријави претплата на наметнувања за тековниот корисинк.", "apihelp-query+notifications-description": "Дај ги известувањата што го исчекуваат тековниот корисник.", "apihelp-query+notifications-summary": "Дај ги известувањата што го исчекуваат тековниот корисник.", @@ -54,8 +56,10 @@ "apihelp-query+notifications-param-messageunreadfirst": "Дали прво да се прикажуваат непрочитаните напомени за известувања. (се користи само ако е зададен groupbysection).", "apihelp-query+notifications-param-titles": "Добивање на известувања само од од овие страници. За да добивате известувања неповрзани со ниедна страница, користете го [] како наслов.", "apihelp-query+notifications-param-bundle": "Дали да се прикажува збир од складни непрочитани известувања според правилата за збирање на видовите известувања.", - "apihelp-query+notifications-example-1": "Испиши известувања", - "apihelp-query+notifications-example-2": "Испиши известувања, групирани по поднаслови, со бројност", + "apihelp-query+notifications-param-notifiertypes": "Видови известувања кои ќе се добиваат.", + "apihelp-query+notifications-example-1": "Испиши семрежни известувања", + "apihelp-query+notifications-example-2": "Испиши семрежни известувања, групирани по поднаслови, со бројност", + "apihelp-query+notifications-example-3": "Испиши известувања по е-пошта", "apihelp-query+unreadnotificationpages-description": "Дај страници за кои постојат непрочитани известувања за тековниот корисник.", "apihelp-query+unreadnotificationpages-summary": "Дај страници за кои постојат непрочитани известувања за тековниот корисник.", "apihelp-query+unreadnotificationpages-param-grouppages": "Групните разговорни страници заедно со нивните предметни страници и групните известувања неповрзани со страница заедно со корисничката страница на тековниот корисник.", @@ -74,5 +78,7 @@ "apiwarn-echo-deprecation-html": "<kbd>notformat=html</kbd> е застарен и наскоро ќе биде отстранет. Наместо него, користете го <kbd>notformat=special</kbd>.", "apierror-echo-event-creation-failed": "Не можев да направам настан за Ехо", "apierror-echo-push-token-exists": "Укажаната шифра веќе постои во базата.", - "apierror-echo-push-token-not-found": "Укажаната шифра не е пронајдена во базата." + "apierror-echo-push-token-not-found": "Укажаната шифра не е пронајдена во базата.", + "apierror-echo-push-too-many-subscriptions": "Тековниот корисник веќе го направил дозволениот број на претплати за наметнувања ($1).", + "apierror-echo-push-topic-required": "За услужников се бара поле за тема." } diff --git a/Echo/i18n/api/nb.json b/Echo/i18n/api/nb.json index f8899769..c51aa9de 100644 --- a/Echo/i18n/api/nb.json +++ b/Echo/i18n/api/nb.json @@ -21,6 +21,22 @@ "apihelp-echomarkseen-example-1": "Merk beskjeder av alle typer som sett", "apihelp-echomarkseen-param-type": "Type beskjeder som skal merkes som sett: 'alert', 'message' eller 'all'.", "apihelp-echomarkseen-param-timestampFormat": "Tidsstempelformat for resultatet, «ISO_8601» eller «MW». «MW» er foreldet her, så alle klienter bør bytte til «ISO_8601». Denne parameteren vil fjernes, og «ISO_8601» vil bli det eneste mulige formatet.", + "apihelp-echomute-description": "Slå av eller på varsler fra visse brukere eller sider.", + "apihelp-echomute-summary": "Slå av eller på varsler fra visse brukere eller sider.", + "apihelp-echomute-param-type": "Hvilken liste det skal legges til eller fjernes fra", + "apihelp-echomute-param-mute": "Sider eller brukere som skal legges til i dempingslista", + "apihelp-echomute-param-unmute": "Sider eller brukere som skal fjernes fra dempingslista", + "apihelp-echopushsubscriptions-summary": "Behandle push-abonnementer for den gjeldende brukeren.", + "apihelp-echopushsubscriptions-param-command": "Handling som skal utføres.", + "apihelp-echopushsubscriptions+create-summary": "Registrer push-abonnement for den gjeldende brukeren.", + "apihelp-echopushsubscriptions+create-param-provider": "Push-tjenestetilbyderen det skal registreres en nøkkel for.", + "apihelp-echopushsubscriptions+create-param-providertoken": "Nøkkelen som skal registreres.", + "apihelp-echopushsubscriptions+create-param-topic": "APNS-emnet (app bundle ID) varselet skal sendes til.", + "apihelp-echopushsubscriptions+create-example": "Registrer et push-abonnement for den gjeldende brukeren.", + "apihelp-echopushsubscriptions+delete-summary": "Avregistrer push-abonnementer for den gjeldende brukeren eller en annen angitt bruker.", + "apihelp-echopushsubscriptions+delete-param-providertoken": "Nøkkelen tilknyttet push-abonnementet som skal avregistreres.", + "apihelp-echopushsubscriptions+delete-param-centraluserid": "Sentral bruker-ID tilknyttet abonnementet som skal avregistreres.", + "apihelp-echopushsubscriptions+delete-example": "Avregistrer et push-abonnement for den gjeldende brukeren.", "apihelp-query+notifications-description": "Hent ventende beskjeder for den aktuelle brukeren.", "apihelp-query+notifications-summary": "Hent varsler som venter for den gjeldende brukeren.", "apihelp-query+notifications-param-prop": "Detaljer som skal forespørres.", @@ -42,8 +58,10 @@ "apihelp-query+notifications-param-messageunreadfirst": "Hvorvidt uleste beskjeder skal vises først (kun brukt hvos groupbysection er satt).", "apihelp-query+notifications-param-titles": "Bare returner notiser for disse sidene. For å få notiser som ikke er knyttet til noen side, bruk [] som tittel.", "apihelp-query+notifications-param-bundle": "Hvorvidt uleste beskjeder skal grupperes.", - "apihelp-query+notifications-example-1": "List beskjeder", - "apihelp-query+notifications-example-2": "List beskjeder, gruppert etter seksjon, med antall", + "apihelp-query+notifications-param-notifiertypes": "Varslingstyper varsel skal returneres for.", + "apihelp-query+notifications-example-1": "List opp nettvarsler.", + "apihelp-query+notifications-example-2": "List opp nettvarsler, gruppert etter seksjon, med antall", + "apihelp-query+notifications-example-3": "List opp epostvarsler", "apihelp-query+unreadnotificationpages-description": "Få sider som har uleste notiser for gjeldende bruker.", "apihelp-query+unreadnotificationpages-summary": "Hent sider det er uleste varsler for for den gjeldende brukeren.", "apihelp-query+unreadnotificationpages-param-grouppages": "Grupper diskusjonssider sammen med hovedsidene, og grupper beskjeder som ikke er knytta til en side sammen med den aktive brukerens brukerside.", @@ -60,5 +78,9 @@ "apiwarn-echo-deprecation-timestampformat": "MW-tidsstempelformatet er utdatert her. I fermtiden vil alltid ISO 8601 brukes for resultatet av tidsstempelformatet. Endre innstillingene i klienten din og sett <var>timestampFormat</var> til <kbd>ISO_8601</kbd>.", "apiwarn-echo-deprecation-flyout": "<kbd>notformat=flyout</kbd> er utdatert og vil fjernes snart. Bruk <kbd>notformat=model</kbd> for å få rådata eller <kbd>notformat=special</kbd> for forhåndsrendret HTML.", "apiwarn-echo-deprecation-html": "<kbd>notformat=html</kbd> er utdatert og vil fjernes snart. Bruk <kbd>notformat=special</kbd> i stedet.", - "apierror-echo-event-creation-failed": "Kunne ikke opprette Echo-hendelse" + "apierror-echo-event-creation-failed": "Kunne ikke opprette Echo-hendelse", + "apierror-echo-push-token-exists": "Den gitte nøkkelen finnes allerede i databasen.", + "apierror-echo-push-token-not-found": "Den gitte nøkkelen ble ikke funnet i databasen.", + "apierror-echo-push-too-many-subscriptions": "Den gjeldende brukeren har allerede registrert maksimalt antall pushabonnementer ($1).", + "apierror-echo-push-topic-required": "Emnefeltet er påkrevd for denne tilbyderen." } diff --git a/Echo/i18n/api/nl-informal.json b/Echo/i18n/api/nl-informal.json new file mode 100644 index 00000000..d3db0f5d --- /dev/null +++ b/Echo/i18n/api/nl-informal.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "McDutchie" + ] + }, + "apihelp-query+notifications-param-alertcontinue": "Als er meer waarschuwingsresultaten beschikbaar zijn, gebruik je dit om verder te gaan.", + "apihelp-query+notifications-param-messagecontinue": "Als er meer berichtresultaten beschikbaar zijn, gebruik je dit om verder te gaan." +} diff --git a/Echo/i18n/api/nl.json b/Echo/i18n/api/nl.json index fecb2c04..d13b81cc 100644 --- a/Echo/i18n/api/nl.json +++ b/Echo/i18n/api/nl.json @@ -3,6 +3,7 @@ "authors": [ "Catrope", "Mainframe98", + "McDutchie", "MrLeopold", "Romaine", "Siebrand", @@ -25,7 +26,7 @@ "apihelp-echomarkseen-param-type": "Soorten meldingen om te markeren als gezien: 'alert', 'message' of 'all'.", "apihelp-query+notifications-description": "Wachtende meldingen voor de huidige gebruiker opvragen.", "apihelp-query+notifications-param-prop": "Details voor verzoek.", - "apihelp-query+notifications-param-sections": "De notificatieonderdelen in de zoekopdracht, bijvoorbeeld een combinatie van \"alert\" en \"message\".", + "apihelp-query+notifications-param-sections": "De notificatieonderdelen in de zoekopdracht, d.w.z. een combinatie van \"alert\" en \"message\".", "apihelp-query+notifications-param-groupbysection": "Of resultaat op onderdeel gegroepeerd moeten worden. Elk onderdeel wordt separaat opgehaald als dit is ingesteld.", "apihelp-query+notifications-param-filter": "De opgevraagde meldingen filteren.", "apihelp-query+notifications-param-format": "Indien opgegeven, worden meldingen teruggegeven met deze opmaak.", @@ -36,13 +37,13 @@ "apihelp-query+notifications-param-limit": "Het maximum aantal opgevraagde meldingen beperken.", "apihelp-query+notifications-param-wikis": "Lijst van wiki's om meldingen van te ontvangen (standaard alleen de huidige wiki).", "apihelp-query+notifications-param-crosswikisummary": "Voeg samengevatte informatie over meldingen op andere wiki's toe.", - "apihelp-query+notifications-param-alertcontinue": "Gebruik dit voor continueren als er meer waarschuwingen beschikbaar zijn.", + "apihelp-query+notifications-param-alertcontinue": "Als er meer waarschuwingsresultaten beschikbaar zijn, gebruikt u dit om verder te gaan.", "apihelp-query+notifications-param-unreadfirst": "Of ongelezen meldingen als eerste moeten worden weergegeven (wordt genegeerd als groupbysection niet gebruikt is).", "apihelp-query+notifications-param-alertunreadfirst": "Of ongelezen meldingen over berichten als eerste moeten worden weergeven (wordt genegeerd als groupbysection niet gebruikt is).", - "apihelp-query+notifications-param-messagecontinue": "Gebruik dit voor continueren als er meer berichten beschikbaar zijn.", + "apihelp-query+notifications-param-messagecontinue": "Als er meer berichtresultaten beschikbaar zijn, gebruikt u dit om verder te gaan.", "apihelp-query+notifications-param-messageunreadfirst": "Of ongelezen meldingen als eerste moeten worden weergeven (wordt genegeerd als groupbysection niet gebruikt is).", - "apihelp-query+notifications-example-1": "Meldingen opvragen", - "apihelp-query+notifications-example-2": "Meldingen, gesorteerd op sectie en met aantal meldingen, opvragen", + "apihelp-query+notifications-example-1": "Webmeldingen weergeven", + "apihelp-query+notifications-example-2": "Webmeldingen weergeven, gegroepeerd op sectie, met aantallen", "apihelp-query+unreadnotificationpages-param-grouppages": "Groepeer overlegpagina's samen met hun onderwerpspagina en groepsmeldingen die niet verbonden zijn aan een pagina samen met de gebruikerspagina van de huidige gebruiker.", "apihelp-query+unreadnotificationpages-param-limit": "Het maximale aantal weer te geven pagina's." } diff --git a/Echo/i18n/api/pl.json b/Echo/i18n/api/pl.json index 3e34d358..5643a7f3 100644 --- a/Echo/i18n/api/pl.json +++ b/Echo/i18n/api/pl.json @@ -4,6 +4,7 @@ "Chrumps", "Rail", "Railfail536", + "SemanticPioneer", "Woytecr" ] }, @@ -20,6 +21,9 @@ "apihelp-echomarkseen-summary": "Oznacz powiadomienia jako przeczytane dla bieżącego użytkownika.", "apihelp-echomarkseen-example-1": "Oznacz powiadomienia wszystkich typów jako przeczytane", "apihelp-echomarkseen-param-type": "Typ powiadomień do oznaczenia jako przeczytane: 'alert', 'message' lub 'all'.", + "apihelp-echomute-param-type": "Do której listy wyciszonych należy dodać lub z której usunąć", + "apihelp-echomute-param-mute": "Strony lub użytkownicy do dodania do listy ignorowanych", + "apihelp-echopushsubscriptions-param-command": "Akcja do wykonania.", "apihelp-query+notifications-description": "Pobierz powiadomienia oczekujące dla bieżącego użytkownika.", "apihelp-query+notifications-summary": "Pobierz powiadomienia oczekujące dla bieżącego użytkownika.", "apihelp-query+notifications-param-prop": "Szczegóły żądania.", diff --git a/Echo/i18n/api/pt-br.json b/Echo/i18n/api/pt-br.json index 222e2b9b..6a8c6a15 100644 --- a/Echo/i18n/api/pt-br.json +++ b/Echo/i18n/api/pt-br.json @@ -2,6 +2,7 @@ "@metadata": { "authors": [ "Eduardo Addad de Oliveira", + "Eduardoaddad", "Felipe L. Ewald", "TheEduGobi" ] @@ -32,8 +33,9 @@ "apihelp-echopushsubscriptions+create-param-provider": "O provedor de serviços push para o qual registrar um token.", "apihelp-echopushsubscriptions+create-param-providertoken": "O token para registrar.", "apihelp-echopushsubscriptions+create-example": "Registre uma assinatura push para o usuário atual.", - "apihelp-echopushsubscriptions+delete-summary": "Cancele o registro de assinaturas push para o usuário atual.", + "apihelp-echopushsubscriptions+delete-summary": "Cancele o registro de assinaturas push para o usuário atual ou outro usuário especificado.", "apihelp-echopushsubscriptions+delete-param-providertoken": "O token associado à assinatura push para cancelar o registro.", + "apihelp-echopushsubscriptions+delete-param-centraluserid": "O ID do usuário central associado à assinatura para cancelar o registro.", "apihelp-echopushsubscriptions+delete-example": "Cancele o registro de uma assinatura push para o usuário atual.", "apihelp-query+notifications-description": "Receber notificações aguardando pelo usuário atual.", "apihelp-query+notifications-summary": "Receber notificações aguardando pelo usuário atual.", @@ -56,8 +58,10 @@ "apihelp-query+notifications-param-messageunreadfirst": "Se exibir notificações de alertas não lidas primeiro ou não.", "apihelp-query+notifications-param-titles": "Somente as notificações de retorno para essas páginas. Para receber notificações não associadas a qualquer página, use [] como título.", "apihelp-query+notifications-param-bundle": "Seja para mostrar notificações não lidas compatíveis com o pacote de acordo com as regras de agrupamento dos tipos de notificação.", - "apihelp-query+notifications-example-1": "Listar notificações", - "apihelp-query+notifications-example-2": "Listar notificações agrupadas por seção, incluindo contadores", + "apihelp-query+notifications-param-notifiertypes": "Tipos de notificadores para os quais retornar notificações.", + "apihelp-query+notifications-example-1": "Listar notificações web", + "apihelp-query+notifications-example-2": "Listar notificações web agrupadas por seção, incluindo contadores", + "apihelp-query+notifications-example-3": "Listar notificações por e-mail", "apihelp-query+unreadnotificationpages-description": "Obter páginas para as quais há notificações não lidas para o usuário atual.", "apihelp-query+unreadnotificationpages-summary": "Obter páginas para as quais há notificações não lidas para o usuário atual.", "apihelp-query+unreadnotificationpages-param-grouppages": "Agrupar páginas de discussão em conjunto com a página de assunto e notificações de grupo não associadas a uma página juntamente com a página de usuário do usuário atual.", @@ -76,5 +80,7 @@ "apiwarn-echo-deprecation-html": "<kbd>notformat=html</kbd> foi depreciado e será removido em breve. Use <kbd>notformat=special</kbd> em vez disso.", "apierror-echo-event-creation-failed": "Não foi possível criar evento Echo", "apierror-echo-push-token-exists": "O token fornecido já existe no banco de dados.", - "apierror-echo-push-token-not-found": "O token fornecido não foi encontrado no banco de dados." + "apierror-echo-push-token-not-found": "O token fornecido não foi encontrado no banco de dados.", + "apierror-echo-push-too-many-subscriptions": "O usuário atual já registrou o número máximo permitido de assinaturas push ($1).", + "apierror-echo-push-topic-required": "O campo do tópico é obrigatório para este provedor." } diff --git a/Echo/i18n/api/pt.json b/Echo/i18n/api/pt.json index 3299eac1..c8489324 100644 --- a/Echo/i18n/api/pt.json +++ b/Echo/i18n/api/pt.json @@ -22,6 +22,22 @@ "apihelp-echomarkseen-example-1": "Marcar as notificações de todos os tipos como vistas", "apihelp-echomarkseen-param-type": "Tipos de notificações a marcar como vistas: 'alert', 'message' ou 'all'.", "apihelp-echomarkseen-param-timestampFormat": "Formato da data e hora a usar no resultado, 'ISO_8601' ou 'MW'. 'MW' é agora obsoleto aqui, por isso todos os clientes devem mudar para 'ISO_8601'. Este parâmetro será removido e 'ISO_8601' passará a ser o único formato de saída.", + "apihelp-echomute-description": "Silenciar ou remover o silenciamento de notificações originadas por certos utilizadores ou páginas.", + "apihelp-echomute-summary": "Silenciar ou remover o silenciamento de notificações originadas por certos utilizadores ou páginas.", + "apihelp-echomute-param-type": "Lista de silenciamento à qual adicionar ou da qual remover entradas", + "apihelp-echomute-param-mute": "Páginas ou utilizadores a adicionar à lista de silenciamento", + "apihelp-echomute-param-unmute": "Páginas ou utilizadores a remover da lista de silenciamento", + "apihelp-echopushsubscriptions-summary": "Gerir as subscrições de envio imediato do utilizador atual.", + "apihelp-echopushsubscriptions-param-command": "Operação a executar.", + "apihelp-echopushsubscriptions+create-summary": "Registar subscrições de envio imediato para o utilizador atual.", + "apihelp-echopushsubscriptions+create-param-provider": "O fornecedor de serviços de envio imediato para o qual registar uma chave.", + "apihelp-echopushsubscriptions+create-param-providertoken": "A chave a registar.", + "apihelp-echopushsubscriptions+create-param-topic": "O tópico APNS (identificador de pacote da aplicação) para o qual enviar a notificação.", + "apihelp-echopushsubscriptions+create-example": "Registar uma subscrição de envio imediato para o utilizador atual.", + "apihelp-echopushsubscriptions+delete-summary": "Cancelar registo de subscrições de envio imediato para o utilizador atual ou outro utilizador especificado.", + "apihelp-echopushsubscriptions+delete-param-providertoken": "A chave associada à subscrição de envio imediato cujo registo pretende cancelar.", + "apihelp-echopushsubscriptions+delete-param-centraluserid": "O identificador do utilizador central associado à subscrição cujo registo pretende cancelar.", + "apihelp-echopushsubscriptions+delete-example": "Cancelar registo de uma subscrição de envio imediato para o utilizador atual.", "apihelp-query+notifications-description": "Obter notificações à espera do utilizador atual.", "apihelp-query+notifications-summary": "Obter notificações à espera do utilizador atual.", "apihelp-query+notifications-param-prop": "Detalhes a pedir.", @@ -43,8 +59,10 @@ "apihelp-query+notifications-param-messageunreadfirst": "Indica se as notificações de alerta não lidas devem ser mostradas primeiro (só é usado se groupbysection estiver definido).", "apihelp-query+notifications-param-titles": "Devolver só as notificações associadas a estas páginas. Para obter as notificações não associadas a qualquer página, use [] como título.", "apihelp-query+notifications-param-bundle": "Indica se as notificações não lidas compatíveis com agrupamentos, devem ser mostradas de acordo com as regras de agrupamento de tipos de notificação.", - "apihelp-query+notifications-example-1": "Listar notificações", - "apihelp-query+notifications-example-2": "Listar notificações, agrupadas por secção, com contagens", + "apihelp-query+notifications-param-notifiertypes": "Tipos de notificador para os quais devolver notificações.", + "apihelp-query+notifications-example-1": "Listar notificações da internet", + "apihelp-query+notifications-example-2": "Listar notificações da internet, agrupadas por secção, com contagens", + "apihelp-query+notifications-example-3": "Listar notificações por correio eletrónico", "apihelp-query+unreadnotificationpages-description": "Obter as páginas que contêm notificações não lidas para o utilizador atual.", "apihelp-query+unreadnotificationpages-summary": "Obter as páginas que contêm notificações não lidas para o utilizador atual.", "apihelp-query+unreadnotificationpages-param-grouppages": "Agrupar as páginas de discussão com a respetiva página de conteúdo, e agrupar as notificações não associadas a uma página com a página do utilizador atual.", @@ -61,5 +79,9 @@ "apiwarn-echo-deprecation-timestampformat": "O formato de saída MediaWiki de data e hora foi descontinuado. De futuro, será sempre usado como formato de saída de data e hora o ISO 8601. Ajuste o seu cliente e defina o <var>timestampFormat</var> como <kbd>ISO_8601</kbd>.", "apiwarn-echo-deprecation-flyout": "<kbd>notformat=flyout</kbd> foi descontinuado e será removido em breve. Use <kbd>notformat=model</kbd> para obter os dados em bruto ou <kbd>notformat=special</kbd> para obter HTML pré-composto.", "apiwarn-echo-deprecation-html": "<kbd>notformat=html</kbd> foi descontinuado e será removido em breve. Substituir por <kbd>notformat=special</kbd>.", - "apierror-echo-event-creation-failed": "Não foi possível criar o evento Echo" + "apierror-echo-event-creation-failed": "Não foi possível criar o evento Echo", + "apierror-echo-push-token-exists": "A chave fornecida já existe na base de dados.", + "apierror-echo-push-token-not-found": "A chave fornecida não foi encontrada na base de dados.", + "apierror-echo-push-too-many-subscriptions": "O utilizador atual já registou o número máximo permitido de subscrições de envio imediato ($1).", + "apierror-echo-push-topic-required": "O campo do tópico é obrigatório para este fornecedor." } diff --git a/Echo/i18n/api/qqq.json b/Echo/i18n/api/qqq.json index 73507836..473b76bd 100644 --- a/Echo/i18n/api/qqq.json +++ b/Echo/i18n/api/qqq.json @@ -36,9 +36,11 @@ "apihelp-echopushsubscriptions+create-summary": "{{doc-apihelp-summary|echopushsubscriptions+create}}", "apihelp-echopushsubscriptions+create-param-provider": "{{doc-apihelp-param|echopushsubscriptions+create|provider}}", "apihelp-echopushsubscriptions+create-param-providertoken": "{{doc-apihelp-param|echopushsubscriptions+create|providertoken}}", + "apihelp-echopushsubscriptions+create-param-topic": "{{doc-apihelp-param|echopushsubscriptions+create|topic}}", "apihelp-echopushsubscriptions+create-example": "{{doc-apihelp-example|echopushsubscriptions+create}}", "apihelp-echopushsubscriptions+delete-summary": "{{doc-apihelp-summary|echopushsubscriptions+delete}}", "apihelp-echopushsubscriptions+delete-param-providertoken": "{{doc-apihelp-param|echopushsubscriptions+delete|providertoken}}", + "apihelp-echopushsubscriptions+delete-param-centraluserid": "{{doc-apihelp-param|echopushsubscriptions+delete|centraluserid}}", "apihelp-echopushsubscriptions+delete-example": "{{doc-apihelp-example|echopushsubscriptions+delete}}", "apihelp-query+notifications-description": "{{doc-apihelp-description|query+notifications}}", "apihelp-query+notifications-summary": "{{doc-apihelp-summary|query+notifications}}", @@ -61,8 +63,10 @@ "apihelp-query+notifications-param-messageunreadfirst": "{{doc-apihelp-param|query+notifications|messageunreadfirst}}", "apihelp-query+notifications-param-titles": "{{doc-apihelp-param|query+notifications|titles}}", "apihelp-query+notifications-param-bundle": "{{doc-apihelp-param|query+notifications|bundle}}", + "apihelp-query+notifications-param-notifiertypes": "{{doc-apihelp-param|query+notifications|notifiertypes}}", "apihelp-query+notifications-example-1": "{{doc-apihelp-example|query+notifications}}", "apihelp-query+notifications-example-2": "{{doc-apihelp-example|query+notifications}}", + "apihelp-query+notifications-example-3": "{{doc-apihelp-example|query+notifications}}", "apihelp-query+unreadnotificationpages-description": "{{doc-apihelp-description|query+unreadnotificationpages}}", "apihelp-query+unreadnotificationpages-summary": "{{doc-apihelp-summary|query+unreadnotificationpages}}", "apihelp-query+unreadnotificationpages-param-grouppages": "{{doc-apihelp-param|query+unreadnotificationpages|grouppages}}", @@ -81,5 +85,7 @@ "apiwarn-echo-deprecation-html": "{{doc-apierror}}", "apierror-echo-event-creation-failed": "{{doc-apierror}}", "apierror-echo-push-token-exists": "{{doc-apierror}}", - "apierror-echo-push-token-not-found": "{{doc-apierror}}" + "apierror-echo-push-token-not-found": "{{doc-apierror}}", + "apierror-echo-push-too-many-subscriptions": "{{doc-apierror}}", + "apierror-echo-push-topic-required": "{{doc-apierror}}" } diff --git a/Echo/i18n/api/ro.json b/Echo/i18n/api/ro.json index 25f9ef9b..c5a287cd 100644 --- a/Echo/i18n/api/ro.json +++ b/Echo/i18n/api/ro.json @@ -1,15 +1,18 @@ { "@metadata": { "authors": [ + "NGC 54", "Reception123" ] }, "apihelp-echomarkread-description": "Marcați notificările ca citite pentru utilizatorul curent.", "apihelp-echomarkread-param-list": "Lista de ID-ul de notificare pentru a marca ca fiind citite.", - "apihelp-echomarkread-param-all": "Dacă este setat, marchează toate notificările a unui utilizator ca citite.", - "apihelp-echomarkread-param-sections": "O listă de sectiuni a fi marcată ca citită.", - "apihelp-echomarkread-example-1": "Marca notificare 8 ca fiind citită.", - "apihelp-echomarkread-example-2": "Marchează toate notificările ca find citite.", + "apihelp-echomarkread-param-all": "Dacă este setat, marchează toate notificările ale unui utilizator ca citite.", + "apihelp-echomarkread-param-sections": "O listă de secțiuni pentru a fi marcată ca citită.", + "apihelp-echomarkread-example-1": "Marcați notificarea 8 ca citită.", + "apihelp-echomarkread-example-2": "Marcați toate notificările ca citite.", + "apihelp-echomarkread-example-3": "Marchează notificarea 1 ca necitită", "apihelp-echomarkseen-description": "Marcați notificările ca citite pentru utilizatorul curent.", - "apihelp-echomarkseen-example-1": "Marcați notificarile de toate tipurile ca văzute" + "apihelp-echomarkseen-example-1": "Marcați notificarile de toate tipurile ca văzute", + "apihelp-echopushsubscriptions-param-command": "Acțiunea de efectuat." } diff --git a/Echo/i18n/api/roa-tara.json b/Echo/i18n/api/roa-tara.json index c8610ad2..e0f0f071 100644 --- a/Echo/i18n/api/roa-tara.json +++ b/Echo/i18n/api/roa-tara.json @@ -19,6 +19,22 @@ "apihelp-echomarkseen-example-1": "Signe le notifeche de tutte le tipe cumme 'ndrucate", "apihelp-echomarkseen-param-type": "Tipe de notifeche da signà cumme 'ndrucate: 'alert', 'message' o 'all'.", "apihelp-echomarkseen-param-timestampFormat": "'U formate de l'orarie de stambe ausate pe l'immissione, 'ISO_8601' o 'MW'. 'MW' jè sconzigliate aqquà, accussì tutte le client ponne passà a 'ISO_8601'. Stu parametre avène luate, e 'ISO_8601' addevende luneche formate d'u resultate.", + "apihelp-echomute-description": "Silenzie o attive le notifeche da certe utinde o pàggene.", + "apihelp-echomute-summary": "Silenzie o attive le notifeche da certe utinde o pàggene.", + "apihelp-echomute-param-type": "Ce elenghe de silenziatore aggiungere o luà", + "apihelp-echomute-param-mute": "Pàggene o utinde da aggiungere a l'elenghe de silenziatore", + "apihelp-echomute-param-unmute": "Pàggene o utinde da luà da l'elenghe de silenziatore", + "apihelp-echopushsubscriptions-summary": "Gestisce le abbonamende push pe l'utende de mò.", + "apihelp-echopushsubscriptions-param-command": "Azione da fà.", + "apihelp-echopushsubscriptions+create-summary": "Reggìstre le abbonamende push pe l'utende de mò.", + "apihelp-echopushsubscriptions+create-param-provider": "'U fornitore de servizie push pu quale reggistrà 'u gettone.", + "apihelp-echopushsubscriptions+create-param-providertoken": "'U gettore da reggistrà.", + "apihelp-echopushsubscriptions+create-param-topic": "L'argomende APNS (ID d'u bundle de l'app) pe mannà 'a notifeche.", + "apihelp-echopushsubscriptions+create-example": "Reggìstre le abbonamende push pe l'utende de mò.", + "apihelp-echopushsubscriptions+delete-summary": "Live 'a reggistrazione de le abbonamende push pe l'utende de mò o 'n'otre utende specificate.", + "apihelp-echopushsubscriptions+delete-param-providertoken": "'U gettone associate cu l'abbonamende push da luà.", + "apihelp-echopushsubscriptions+delete-param-centraluserid": "L'ID utende cendrale associate cu l'abbonamende da luà-", + "apihelp-echopushsubscriptions+delete-example": "Live 'n'abbonamende push pe l'utende de mò.", "apihelp-query+notifications-description": "Pigghie tutte le notifeche in attese pe l'utende de mò.", "apihelp-query+notifications-summary": "Pigghie tutte le notifeche in attese pe l'utende de mò.", "apihelp-query+notifications-param-prop": "Dettaglie da cercà.", @@ -40,8 +56,10 @@ "apihelp-query+notifications-param-messageunreadfirst": "Ce a fà 'ndrucà le notifeche de le avvise non lette apprime (ausate sulamende ce groupbysection non g'è 'mbostate).", "apihelp-query+notifications-param-titles": "Torne sulamende le notifeche pe ste pàggene. Pe avè le notifeche non associate a nisciuna pàgene, ause [] cumme titole.", "apihelp-query+notifications-param-bundle": "Ce a fà 'ndrucà le notifeche non lette combatibbele cu 'u pacchette in base a le regole de raggruppamende de le tipe de notifeche.", - "apihelp-query+notifications-example-1": "Elenghe de le notifiche", - "apihelp-query+notifications-example-2": "Elenghe le notifeche, raggruppate pe sezione, cu le condegge", + "apihelp-query+notifications-param-notifiertypes": "Tipe de notifeche pe le quale turnà 'na notifeche.", + "apihelp-query+notifications-example-1": "Elenghe de le notifiche web", + "apihelp-query+notifications-example-2": "Elenghe le notifeche web, raggruppate pe sezione, cu le condegge", + "apihelp-query+notifications-example-3": "Elenghe de le notefeche pe mail", "apihelp-query+unreadnotificationpages-description": "Pigghie le pàggene pe le quale stonne notifeche non lette pe l'utende de mò.", "apihelp-query+unreadnotificationpages-summary": "Pigghie le pàggene pe le quale stonne notifeche non lette pe l'utende de mò.", "apihelp-query+unreadnotificationpages-param-grouppages": "Raggruppe le pàggene de le 'ngazzaminde 'nzieme cu le lore sottopàggene, e raggruppe le notifeche none associate cu 'na pàgene 'nzieme cu 'a pàgene utende de l'utende de mò.", @@ -58,5 +76,9 @@ "apiwarn-echo-deprecation-timestampformat": "'U formate d'u resultate de l'orarie MW jè sconzigliate aqquà. Jndr'à 'u future, ISO 8601 avène ausate cumme formate d'u resultate. Regole 'u client tune e 'mboste <var>timestampFormat</var> a <kbd>ISO_8601</kbd>.", "apiwarn-echo-deprecation-flyout": "<kbd>notformat=flyout</kbd> ha state sconzigliate e adda essere luate preste. Ause <kbd>notformat=model</kbd> pe pigghià le date grezze o <kbd>notformat=special</kbd> pe l'HTML pre renderizzate.", "apiwarn-echo-deprecation-html": "<kbd>notformat=html</kbd> ha state sconzigliate e adda essere luate preste. Invece ause <kbd>notformat=special</kbd>.", - "apierror-echo-event-creation-failed": "Non ge pozze ccrejà l'avvenimende Echo" + "apierror-echo-event-creation-failed": "Non ge pozze ccrejà l'avvenimende Echo", + "apierror-echo-push-token-exists": "'U gettone date ggià esiste jndr'à 'u dataabase.", + "apierror-echo-push-token-not-found": "'U gettone date non g0ha state acchiate jndr'à 'u dataabase.", + "apierror-echo-push-too-many-subscriptions": "L'utende de mò ave ggià reggistrate 'u massime numere de abbonamende push ($1).", + "apierror-echo-push-topic-required": "'U cambe argomende jè obbligatorie pe stu fornitore." } diff --git a/Echo/i18n/api/ru.json b/Echo/i18n/api/ru.json index 12107b7a..81a48214 100644 --- a/Echo/i18n/api/ru.json +++ b/Echo/i18n/api/ru.json @@ -4,6 +4,7 @@ "Diralik", "Mailman", "Marina Melik-Adamyan", + "Megakott", "Mouse21", "Okras", "Putnik", @@ -36,7 +37,7 @@ "apihelp-echopushsubscriptions+create-param-provider": "Поставщик push-сервиса для которого регистрируется токен.", "apihelp-echopushsubscriptions+create-param-providertoken": "Токен для регистрации.", "apihelp-echopushsubscriptions+create-example": "Регистрация push-подписки для текущего участника.", - "apihelp-echopushsubscriptions+delete-summary": "Разрегистрация push-подписок для текущего участника.", + "apihelp-echopushsubscriptions+delete-summary": "Разрегистрация push-подписок для текущего участника или другого указанного участника.", "apihelp-echopushsubscriptions+delete-param-providertoken": "Токен ассоциирован с push-подпиской к разрегистрации.", "apihelp-echopushsubscriptions+delete-example": "Разрегистрация push-подписки для текущего участника.", "apihelp-query+notifications-description": "Получать уведомления, ожидающие текущего пользователя.", @@ -60,8 +61,8 @@ "apihelp-query+notifications-param-messageunreadfirst": "Нужно ли показывать непрочитанные уведомления о оповещениях в первую очередь (используется только если указан groupbysection).", "apihelp-query+notifications-param-titles": "Только возвращать уведомления для этих страниц. Чтобы получать уведомления, не связанные с какой-либо страницей, используйте [] как заголовок.", "apihelp-query+notifications-param-bundle": "Является ли показать совместимые с пакетом непрочитанные уведомления в соответствии со стандартами связывания типов уведомлений.", - "apihelp-query+notifications-example-1": "Список уведомлений", - "apihelp-query+notifications-example-2": "Список уведомлений, сгруппированных по разделам, с указанием количества", + "apihelp-query+notifications-example-1": "Список веб-уведомлений", + "apihelp-query+notifications-example-2": "Список веб-уведомлений, сгруппированных по разделам, с указанием количества", "apihelp-query+unreadnotificationpages-description": "Получите страницы, для которых есть непрочитанные уведомления для текущего пользователя.", "apihelp-query+unreadnotificationpages-summary": "Получите страницы, для которых есть непрочитанные уведомления для текущего пользователя.", "apihelp-query+unreadnotificationpages-param-grouppages": "Групповые страницы разговора вместе со своей тематической страницей и групповые уведомления, не связанные со страницей, вместе с пользовательской страницей пользователя.", diff --git a/Echo/i18n/api/sh.json b/Echo/i18n/api/sh.json index 82d46175..c314dbf6 100644 --- a/Echo/i18n/api/sh.json +++ b/Echo/i18n/api/sh.json @@ -10,6 +10,7 @@ "apihelp-echomarkread-param-unreadlist": "Spisak naznaka obavještenja što treba da se označe kao nepročitana.", "apihelp-echomarkread-param-all": "Ako je zadano, označava sva obavještenja jednog korisnika kao pročitana.", "apihelp-echomarkread-param-sections": "Spisak podnaslova što treba da se označe kao pročitani.", + "apihelp-echomarkread-param-wikis": "Popis wikija čije obavijesti treba označavati kao pročitane (zadano: samo trenutni wiki).", "apihelp-echomarkread-example-1": "Označi obavještenje 8 kao pročitano", "apihelp-echomarkread-example-2": "Označiu sva obaveštenja pročitanim", "apihelp-echomarkread-example-3": "Označi obavještenje 1 kao pročitano", @@ -17,6 +18,7 @@ "apihelp-echomarkseen-summary": "Označi obavještenja kao pročitana za trenutni korisnik.", "apihelp-echomarkseen-example-1": "Označi obavještenja svih vrsta kao pročitana", "apihelp-echomarkseen-param-type": "Vrste obavještenja što treba da se označe kao viđena: „alert“, „message“ ili „all“.", + "apihelp-echopushsubscriptions-param-command": "Akcija za izvesti.", "apihelp-query+notifications-description": "Daj obavještenja što isčekavaju trenutnoga korisnika.", "apihelp-query+notifications-summary": "Daj obavještenja što isčekavaju trenutnoga korisnika.", "apihelp-query+notifications-param-prop": "Pojedinosti što treba da se potraže.", @@ -25,5 +27,5 @@ "apihelp-query+notifications-param-filter": "Filtriraj obavještenja u ishodu.", "apihelp-query+notifications-param-format": "Ako je zadano, obavještenja će se dati kao formatirana ovim načinom.", "apihelp-query+notifications-paramvalue-format-model": "Sirovo obavještenje", - "apihelp-query+notifications-example-1": "Ispiši obavještenja" + "apihelp-query+notifications-example-1": "Ispiši web obavještenja" } diff --git a/Echo/i18n/api/sl.json b/Echo/i18n/api/sl.json index 2f67f3a7..36833d3a 100644 --- a/Echo/i18n/api/sl.json +++ b/Echo/i18n/api/sl.json @@ -1,15 +1,16 @@ { "@metadata": { "authors": [ + "Eleassar", "Janezdrilc" ] }, "apihelp-echomarkread-description": "Označi obvestila kot prebrana za trenutnega uporabnika.", "apihelp-echomarkread-summary": "Označi obvestila kot prebrana za trenutnega uporabnika.", - "apihelp-echomarkread-param-list": "Seznam ID-jev obvestil za označitev za prebrano.", - "apihelp-echomarkread-param-unreadlist": "Seznam ID-jev obvestil za označitev za neprebrano.", + "apihelp-echomarkread-param-list": "Seznam ID-jev obvestil za označitev kot prebranih.", + "apihelp-echomarkread-param-unreadlist": "Seznam ID-jev obvestil, ki bodo označena kot neprebrana.", "apihelp-echomarkread-param-all": "Ob nastavitvi označi vsa uporabnikova obvestila kot prebrana.", - "apihelp-echomarkread-param-sections": "Seznam delov za označitev za prebrano.", + "apihelp-echomarkread-param-sections": "Seznam razdelkov za označitev kot prebranih.", "apihelp-echomarkread-example-1": "Označi obvestilo 8 kot prebrano", "apihelp-echomarkread-example-2": "Označi vsa obvestila kot prebrana", "apihelp-echomarkread-example-3": "Označi obvestilo 1 kot neprebrano", @@ -18,8 +19,9 @@ "apihelp-echomarkseen-example-1": "Označi vse vrste obvestil kot ogledane", "apihelp-echomarkseen-param-type": "Vrste obvestil za označitev za ogledano: 'opomnik', 'sporočilo' ali 'vse'.", "apihelp-echomarkseen-param-timestampFormat": "Datumski odtis pri izpisovanju, 'ISO_8601' ali 'MW'. 'MW' se ne priporoča, zato ga naj uporabniki zamenjajo z 'ISO_8601'. Ko bo ukinjen, bo ostal v uporabi le 'ISO_8601'.", - "apihelp-query+notifications-description": "Poglej obvestila, ki so na čakanju za trenutnega uporabnika.", + "apihelp-query+notifications-description": "Prikaži obvestila, ki čakajo na trenutnega uporabnika.", "apihelp-query+notifications-param-prop": "Zahtevane podrobnosti.", + "apihelp-query+notifications-param-filter": "Vrnjena filtrirana obvestila.", "apihelp-query+notifications-paramvalue-format-model": "Surovi podatki obvestil", "apihelp-query+notifications-param-limit": "Največje število prikazanih obvestil.", "apihelp-query+unreadnotificationpages-param-limit": "Največje število prikazanih strani." diff --git a/Echo/i18n/api/sr-ec.json b/Echo/i18n/api/sr-ec.json index 7169f955..4ff8b5c0 100644 --- a/Echo/i18n/api/sr-ec.json +++ b/Echo/i18n/api/sr-ec.json @@ -2,10 +2,12 @@ "@metadata": { "authors": [ "BadDog", + "Kizule", "Milicevic01" ] }, "apihelp-echomarkread-example-2": "Означи сва обавештења као прочитана", - "apihelp-query+notifications-example-1": "Списак обавештења", + "apihelp-query+notifications-example-1": "Списак веб обавештења", + "apihelp-query+notifications-example-3": "Списак имејл обавештења", "apierror-echo-event-creation-failed": "Не могу да направим дешавања Echo" } diff --git a/Echo/i18n/api/sv.json b/Echo/i18n/api/sv.json index 56cd8d7e..aedabdd6 100644 --- a/Echo/i18n/api/sv.json +++ b/Echo/i18n/api/sv.json @@ -3,6 +3,7 @@ "authors": [ "Ainali", "Lokal Profil", + "Sabelöga", "WikiPhoenix" ] }, @@ -12,7 +13,7 @@ "apihelp-echomarkread-param-unreadlist": "En lista över aviserings-ID att markera som olästa.", "apihelp-echomarkread-param-all": "Om angiven, markerar en användares alla aviseringar som lästa.", "apihelp-echomarkread-param-sections": "En lista över avsnitt att markera som lästa.", - "apihelp-echomarkread-param-wikis": "Lista över wikis att markera aviseringar som lästa (är endast aktuell wiki som standard).", + "apihelp-echomarkread-param-wikis": "Lista över wikier att markera aviseringar som lästa (är endast aktuell wiki som standard).", "apihelp-echomarkread-example-1": "Markera avisering 8 som läst", "apihelp-echomarkread-example-2": "Markera alla aviseringar som lästa", "apihelp-echomarkread-example-3": "Markera avisering 1 som oläst", @@ -21,7 +22,22 @@ "apihelp-echomarkseen-example-1": "Märk alla sorters aviseringar som lästa", "apihelp-echomarkseen-param-type": "Aviseringstypen att märka som läst: 'alert', 'message' eller 'all'.", "apihelp-echomarkseen-param-timestampFormat": "Tidstämpelformat att använda som utmatning, 'ISO_8601' eller 'MW'. 'MW' är föråldrat här, så alla klienter bör byta till 'ISO_8601'. Denna parameter kommer att tas bort och 'ISO_8601' kommer att bli det enda utmatningsformatet.", + "apihelp-echomute-description": "Tysta eller sluta tysta aviseringar från vissa användare eller sidor.", + "apihelp-echomute-summary": "Tysta eller sluta tysta aviseringar från vissa användare eller sidor.", + "apihelp-echomute-param-type": "Vilken lista att lägga till eller ta bort från", + "apihelp-echomute-param-mute": "Sidor eller användare att lägga till i listan", + "apihelp-echomute-param-unmute": "Sidor eller användare att ta bort från listan", + "apihelp-echopushsubscriptions-summary": "Hantera push-prenumerationer för nuvarande användare.", "apihelp-echopushsubscriptions-param-command": "Åtgärd att utföra.", + "apihelp-echopushsubscriptions+create-summary": "Registrera push-prenumerationer för nuvarande användare.", + "apihelp-echopushsubscriptions+create-param-provider": "Push-tjänstleverantör som en nyckel ska registreras till.", + "apihelp-echopushsubscriptions+create-param-providertoken": "Nyckeln att registrera.", + "apihelp-echopushsubscriptions+create-param-topic": "APNS-ämnet (appakets-ID) att skicka aviseringen till.", + "apihelp-echopushsubscriptions+create-example": "Registrera en push-prenumeration för nuvarande användare.", + "apihelp-echopushsubscriptions+delete-summary": "Avregistrera push-prenumerationer för nuvarande användare eller annan vald användare.", + "apihelp-echopushsubscriptions+delete-param-providertoken": "Nyckeln som associeras med den utgivarinitierade prenumerationen att avregistrera.", + "apihelp-echopushsubscriptions+delete-param-centraluserid": "Det centrala användar-ID som associeras med prenumerationen att avregistrera.", + "apihelp-echopushsubscriptions+delete-example": "Avregistrera en utgivarinitierad prenumeration för nuvarande användare.", "apihelp-query+notifications-description": "Hämta aviseringar som väntar på aktuell användare.", "apihelp-query+notifications-summary": "Hämta aviseringar som väntar på aktuell användare.", "apihelp-query+notifications-param-prop": "Detaljer som ska begäras.", @@ -34,8 +50,8 @@ "apihelp-query+notifications-paramvalue-format-flyout": "<span class=\"apihelp-deprecated\">Föråldrad</span>. Använd <kbd>$1format=model</kbd> för rå data", "apihelp-query+notifications-paramvalue-format-html": "<span class=\"apihelp-deprecated\">Föråldrad</span>. Använd <kbd>$1format=model</kbd> för rå data", "apihelp-query+notifications-param-limit": "Det maximala antalet aviseringar som ska returneras.", - "apihelp-query+notifications-param-wikis": "Lista över wikis att hämta aviseringar från (är endast aktuell wiki som standard).", - "apihelp-query+notifications-param-crosswikisummary": "Aktivera för att få en sammanfattning över aviseringar på andra wikis.", + "apihelp-query+notifications-param-wikis": "Lista över wikier att hämta aviseringar från (är endast aktuell wiki som standard).", + "apihelp-query+notifications-param-crosswikisummary": "Aktivera för att få en sammanfattning över aviseringar på andra wikier.", "apihelp-query+notifications-param-alertcontinue": "När fler resultat finns för systemmeddelande, använd detta för att fortsätta.", "apihelp-query+notifications-param-unreadfirst": "Om du vill visa olästa aviseringar först (används endast om groupbysection inte är inställd).", "apihelp-query+notifications-param-alertunreadfirst": "Om du vill visa olästa meddelandeaviseringar först (används endast om groupbysection inte är inställd).", @@ -43,13 +59,15 @@ "apihelp-query+notifications-param-messageunreadfirst": "Om du vill visa olästa systemmeddelandeaviseringar först (används endast om groupbysection inte är inställd).", "apihelp-query+notifications-param-titles": "Returnera endast aviseringar för dessa sidor. Använd [] som en titel för att få aviseringar som inte associeras med någon sida.", "apihelp-query+notifications-param-bundle": "Om olästa aviseringar ska grupperas enligt reglerna för grupperade aviseringstyper.", - "apihelp-query+notifications-example-1": "Lista aviseringar", - "apihelp-query+notifications-example-2": "Listan aviseringar grupperade efter avsnitt, med antal", + "apihelp-query+notifications-param-notifiertypes": "Aviseringstyper som ska returnera aviseringar.", + "apihelp-query+notifications-example-1": "Lista webbaviseringar", + "apihelp-query+notifications-example-2": "Lista webbaviseringar grupperade efter avsnitt, med antal", + "apihelp-query+notifications-example-3": "Lista e-postaviseringar", "apihelp-query+unreadnotificationpages-description": "Hämta sidor där det finns olästa aviseringar för aktuell användare.", "apihelp-query+unreadnotificationpages-summary": "Hämta sidor där det finns olästa aviseringar för aktuell användare.", "apihelp-query+unreadnotificationpages-param-grouppages": "Gruppera diskussionssidor tillsammans med dess ämnessidor och gruppera aviseringar som inte är associerade med en sida tillsammans med den aktuella användarens användarsida.", "apihelp-query+unreadnotificationpages-param-limit": "Maximala antalet sidor att returnera.", - "apihelp-query+unreadnotificationpages-param-wikis": "Lista över wikis att hämta sidor med olästa aviseringar ifrån (endast aktuell wiki är standard).", + "apihelp-query+unreadnotificationpages-param-wikis": "Lista över wikier att hämta sidor med olästa aviseringar ifrån (endast aktuell wiki är standard).", "apihelp-query+unreadnotificationpages-example-1": "Lista sidor med (deras antal av) olästa aviseringar", "apihelp-echoarticlereminder-summary": "Begär en framtida påminnelse om den valda artikeln", "apihelp-echoarticlereminder-param-pageid": "ID för artikeln att påminna användaren om", @@ -61,5 +79,9 @@ "apiwarn-echo-deprecation-timestampformat": "MW-tidsstämpelns utmatningsformat är föråldrat här. I framtiden kommer ISO 8601 alltid att användas för utmatningens tidstämpelsformat. Justera din klient och ändra <var>timestampFormat</var> till <kbd>ISO_8601</kbd>.", "apiwarn-echo-deprecation-flyout": "<kbd>notformat=flyout</kbd> har blivit föråldrat och kommer att tas bort snart. Använd <kbd>notformat=model</kbd> för att få rå data eller <kbd>notformat=special</kbd> för förrenderad HTML.", "apiwarn-echo-deprecation-html": "<kbd>notformat=html</kbd> har blivit föråldrat och kommer snart att tas bort. Använd <kbd>notformat=special</kbd> istället.", - "apierror-echo-event-creation-failed": "Kunde inte skapa Echo-händelse" + "apierror-echo-event-creation-failed": "Kunde inte skapa Echo-händelse", + "apierror-echo-push-token-exists": "Den angivna nyckeln finns redan i databasen.", + "apierror-echo-push-token-not-found": "Den angivna nyckeln finns inte i databasen.", + "apierror-echo-push-too-many-subscriptions": "Den nuvarande användaren har redan registrerat det maximalt tillåtna antalet push-prenumerationer ($1).", + "apierror-echo-push-topic-required": "Ämnesfältet krävs för denna tillhandahållare." } diff --git a/Echo/i18n/api/tr.json b/Echo/i18n/api/tr.json index 9d16df14..a3b7ece8 100644 --- a/Echo/i18n/api/tr.json +++ b/Echo/i18n/api/tr.json @@ -3,26 +3,28 @@ "authors": [ "Arystanbek", "BaRaN6161 TURK", + "Hedda", "KorkmazO", "McAang", + "MuratTheTurkish", "Sayginer" ] }, "apihelp-echomarkread-description": "Bildirimleri geçerli kullanıcı için okundu olarak işaretleyin.", "apihelp-echomarkread-summary": "Bildirimleri geçerli kullanıcı için okundu olarak işaretleyin.", - "apihelp-echomarkread-param-list": "Okundu olarak işaretlemek için bildirim Kimliklerinin bir listesini.", + "apihelp-echomarkread-param-list": "Okundu olarak işaretlenecek bildirim kimliklerinin listesi.", "apihelp-echomarkread-param-unreadlist": "Okunmamış olarak işaretlenecek bildirim kimlikleri listesi.", - "apihelp-echomarkread-param-all": "Set, okumak gibi bir kullanıcı Bildirimleri tüm işaretler.", - "apihelp-echomarkread-param-sections": "Okundu olarak işaretlemek için bölümler bir listesini.", + "apihelp-echomarkread-param-all": "Ayarlanırsa, bir kullanıcının tüm bildirimlerini okundu olarak işaretler.", + "apihelp-echomarkread-param-sections": "Okundu olarak işaretlenecek bölümlerin listesi.", "apihelp-echomarkread-param-wikis": "Bildirimi okundu olarak işaretlemek için vikilerin listesi (varsayılan olarak yalnızca geçerli vikidir).", - "apihelp-echomarkread-example-1": "Mark bildirim 8 gibi okumak", - "apihelp-echomarkread-example-2": "Tüm bildirimleri okunmuş olarak işaretle", - "apihelp-echomarkread-example-3": "Bildirim 1'i okunmadı olarak işaretle", + "apihelp-echomarkread-example-1": "Bildirimi 8 okundu olarak işaretleyin", + "apihelp-echomarkread-example-2": "Tüm bildirimleri okundu olarak işaretleyin", + "apihelp-echomarkread-example-3": "Bildirimi 1 okunmadı olarak işaretleyin", "apihelp-echomarkseen-description": "Bildirimleri geçerli kullanıcı için göründüğü gibi işaretleyin.", "apihelp-echomarkseen-summary": "Bildirimleri geçerli kullanıcı için göründüğü gibi işaretleyin.", - "apihelp-echomarkseen-example-1": "Her tür bildirimi okundu olarak işaretle", - "apihelp-echomarkseen-param-type": "'Uyarı', 'mesaj' ya da 'tümü' olarak işaretlemek için bildirimlerin türü.", - "apihelp-echomarkseen-param-timestampFormat": "'ISO_8601' veya 'MW' çıkışı için kullanılacak zaman damgası biçimi. 'MW' burada kullanımdan kaldırılmıştır, bu nedenle tüm istemciler 'ISO_8601' e geçmelidir. Bu parametre kaldırılacak ve 'ISO_8601' tek çıkış biçimi olacak.", + "apihelp-echomarkseen-example-1": "Her türden bildirimleri görüldüğü olarak işaretleyin", + "apihelp-echomarkseen-param-type": "Görüldüğü gibi işaretlenecek bildirim türleri: 'alert', 'message' veya 'all'.", + "apihelp-echomarkseen-param-timestampFormat": "'ISO_8601' veya 'MW' çıkışı için kullanılacak zaman damgası biçimi. 'MW' burada kullanımdan kaldırılmıştır, bu nedenle tüm istemciler 'ISO_8601' ile geçmelidir. Bu parametre kaldırılacak ve 'ISO_8601' tek çıkış biçimi olacak.", "apihelp-echomute-description": "Belirli kullanıcılardan veya sayfalardan gelen bildirimlerin sesini kapatın veya açın.", "apihelp-echomute-summary": "Belirli kullanıcılardan veya sayfalardan gelen bildirimlerin sesini kapatın veya açın.", "apihelp-echomute-param-type": "Sessiz listesine eklenecek veya listeden kaldırılacağı", @@ -33,42 +35,45 @@ "apihelp-echopushsubscriptions+create-summary": "Geçerli kullanıcı için push abonelikleri kaydedin.", "apihelp-echopushsubscriptions+create-param-provider": "Anahtar kaydedilecek push servis sağlayıcısı.", "apihelp-echopushsubscriptions+create-param-providertoken": "Kaydedilecek anahtar.", + "apihelp-echopushsubscriptions+create-param-topic": "Bildirimin gönderileceği APNS konusu (uygulama paketi kimliği).", "apihelp-echopushsubscriptions+create-example": "Geçerli kullanıcı için push aboneliği kaydedin.", - "apihelp-echopushsubscriptions+delete-summary": "Geçerli kullanıcı için push aboneliklerin kaydını kaldırın.", + "apihelp-echopushsubscriptions+delete-summary": "Geçerli kullanıcı veya başka bir belirtilen kullanıcı için push aboneliklerinin kaydını kaldırın.", "apihelp-echopushsubscriptions+delete-param-providertoken": "Kaydı silmek için push aboneliği ile ilişkili anahtar.", + "apihelp-echopushsubscriptions+delete-param-centraluserid": "Kaydı silme aboneliği ile ilişkili merkezi kullanıcı kimliği.", "apihelp-echopushsubscriptions+delete-example": "Geçerli kullanıcı için push aboneliğinin kaydını kaldırın.", - "apihelp-query+notifications-description": "Bildirimler, geçerli kullanıcı için bekliyor.", - "apihelp-query+notifications-summary": "Bildirimler, geçerli kullanıcı için bekliyor.", - "apihelp-query+notifications-param-prop": "İstek detayları.", - "apihelp-query+notifications-param-sections": "Sorgu için bildirim bölümleri (örneğin bazı 'uyarı' ve 'mesaj'kombinasyonu)", - "apihelp-query+notifications-param-groupbysection": "Olsun bölüm sonuç grup için. Her bölüm set halinde ayrı ayrı getirildi.", + "apihelp-query+notifications-description": "Mevcut kullanıcıyı bekleyen bildirimler alın.", + "apihelp-query+notifications-summary": "Mevcut kullanıcıyı bekleyen bildirimler alın.", + "apihelp-query+notifications-param-prop": "İstek ayrıntıları.", + "apihelp-query+notifications-param-sections": "Sorgulanacak bildirim bölümleri (yani, 'alert' ve 'message' bazı kombinasyonları).", + "apihelp-query+notifications-param-groupbysection": "Sonucun bölümlere göre gruplanıp gruplandırılmayacağı. Ayarlanmışsa her bölüm ayrı olarak getirilir.", "apihelp-query+notifications-param-filter": "Filtre bildirimleri döndürüldü.", - "apihelp-query+notifications-param-format": "Belirtilmişse, bildirimleri biçimlendirilmiş bu şekilde iade edilecektir.", + "apihelp-query+notifications-param-format": "Belirtilmişse, bildirimleri biçimlendirilmiş bu şekilde döndürecektir.", "apihelp-query+notifications-paramvalue-format-model": "Ham bildirim verileri", "apihelp-query+notifications-paramvalue-format-special": "Special:Notifications sayfası için biçimlendirilmiş (ve yalnızca bu!) HTML'ye güvenmeyin, çünkü herhangi bir zamanda değişebilir.", "apihelp-query+notifications-paramvalue-format-flyout": "<span class=\"apihelp-deprecated\">Kaldırıldı</span>. Ham veriler için <kbd>$1format=model</kbd> kullanın", "apihelp-query+notifications-paramvalue-format-html": "<span class=\"apihelp-deprecated\">Kaldırıldı</span>. Ham veriler için <kbd>$1format=model</kbd> kullanın", "apihelp-query+notifications-param-limit": "Gösterilebilecek azami bildirim sayısı.", - "apihelp-query+notifications-param-wikis": "Adlı kullanıcıdan bildirim alınacak wikilerin listesi (varsayılan olarak yalnızca geçerli wikidir).", - "apihelp-query+notifications-param-crosswikisummary": "Yabancı wikilerle ilgili bildirimlerin özet bildirimini seçmek doğrudur.", - "apihelp-query+notifications-param-alertcontinue": "Daha uyanık sonuçlar mevcut olduğunda, bu devam etmek için kullanın.", + "apihelp-query+notifications-param-wikis": "Bildirimlerin alınacağı vikilerin listesi (varsayılanlar yalnızca geçerli vikidir).", + "apihelp-query+notifications-param-crosswikisummary": "Yabancı vikilerle ilgili bildirimlerin özet bildirimini seçmek doğrudur.", + "apihelp-query+notifications-param-alertcontinue": "Daha fazla uyarı sonucu mevcut olduğunda, devam etmek için bunu kullanın.", "apihelp-query+notifications-param-unreadfirst": "Önce okunmamış bildirimlerin gösterilip gösterilmeyeceği (yalnızca groupbysection ayarlanmamışsa kullanılır).", - "apihelp-query+notifications-param-alertunreadfirst": "İster okunmamış mesaj bildirimlerini göstermek.", - "apihelp-query+notifications-param-messagecontinue": "Daha fazla ileti sonuçlar mevcut olduğunda, bu devam etmek için kullanın.", - "apihelp-query+notifications-param-messageunreadfirst": "İster okunmamış uyarı bildirimleri göstermek.", - "apihelp-query+notifications-param-titles": "Yalnızca bu sayfalar için bildirimler gönderin. Herhangi bir sayfa ile ilişkili olmayan bildirimler almak için başlık olarak [] kullanın.", - "apihelp-query+notifications-param-bundle": "Bildirim türlerine göre gruplama kurallarına göre paket uyumlu okunmamış bildirimlerin gösterilip gösterilmeyeceği.", - "apihelp-query+notifications-example-1": "Liste bildirimleri", - "apihelp-query+notifications-example-2": "Sayılarla birlikte bölümlere göre gruplandırılmış bildirimler listesi", + "apihelp-query+notifications-param-alertunreadfirst": "Önce okunmamış mesaj bildirimlerinin gösterilip gösterilmeyeceği (yalnızca groupbysection ayarlanmışsa kullanılır).", + "apihelp-query+notifications-param-messagecontinue": "Daha fazla mesaj sonucu mevcut olduğunda, devam etmek için bunu kullanın.", + "apihelp-query+notifications-param-messageunreadfirst": "Önce okunmamış uyarı bildirimlerinin gösterilip gösterilmeyeceği (yalnızca groupbysection ayarlanmışsa kullanılır).", + "apihelp-query+notifications-param-titles": "Yalnızca bu sayfalar için bildirim döndürün. Herhangi bir sayfayla ilişkili olmayan bildirimleri almak için, başlık olarak [] kullanın.", + "apihelp-query+notifications-param-bundle": "Bildirim türleri gruplama kurallarına göre paket uyumlu okunmamış bildirimlerin gösterilip gösterilmeyeceği.", + "apihelp-query+notifications-example-1": "Web bildirimleri listeleyin", + "apihelp-query+notifications-example-2": "Sayımlarla birlikte bölümlere göre gruplandırılmış web bildirimleri listeleyin", + "apihelp-query+notifications-example-3": "E-posta bildirimlerini listele", "apihelp-query+unreadnotificationpages-description": "Geçerli kullanıcı için okunmamış bildirimlerin bulunduğu sayfaları alın.", "apihelp-query+unreadnotificationpages-summary": "Geçerli kullanıcı için okunmamış bildirimlerin bulunduğu sayfaları alın.", - "apihelp-query+unreadnotificationpages-param-grouppages": "Konuşma sayfalarını konu sayfalarıyla birlikte gruplandırın ve bir sayfayla ilişkili olmayan grup bildirimlerini geçerli kullanıcının kullanıcı sayfasıyla birlikte gruplandırın.", + "apihelp-query+unreadnotificationpages-param-grouppages": "Tartışma sayfalarını konu sayfalarıyla birlikte gruplandırın ve bir sayfayla ilişkili olmayan grup bildirimlerini geçerli kullanıcının kullanıcı sayfasıyla birlikte gruplandırın.", "apihelp-query+unreadnotificationpages-param-limit": "Döndürülecek maksimum sayfa sayısı.", - "apihelp-query+unreadnotificationpages-param-wikis": "Sitesinden okunmamış bildirimleri olan sayfaları getirecek wikilerin listesi (varsayılan olarak yalnızca geçerli wikidir).", - "apihelp-query+unreadnotificationpages-example-1": "Okunmayan bildirimleri olan (miktarlarını) sayfalar listele", - "apihelp-echoarticlereminder-summary": "Belirtilen madde hakkında gelecekteki bir hatırlatma iste", - "apihelp-echoarticlereminder-param-pageid": "Kullanıcıyı hatırlatmak için makalenin kimliği", - "apihelp-echoarticlereminder-param-title": "Kullanıcıya hatırlatmak için makalenin başlığı", + "apihelp-query+unreadnotificationpages-param-wikis": "Sitesinden okunmamış bildirimleri olan sayfaları getirecek vikilerin listesi (varsayılan olarak yalnızca geçerli vikidir).", + "apihelp-query+unreadnotificationpages-example-1": "Okunmamış bildirimleri (miktarları) olan sayfaları listeleyin", + "apihelp-echoarticlereminder-summary": "Belirtilen madde hakkında gelecekteki bir hatırlatma isteyin", + "apihelp-echoarticlereminder-param-pageid": "Kullanıcıyı hatırlatmak için maddenin kimliği", + "apihelp-echoarticlereminder-param-title": "Kullanıcıya hatırlatmak için maddenin başlığı", "apihelp-echoarticlereminder-param-timestamp": "Kullanıcıya hangi zaman damgasını hatırlatması", "apihelp-echoarticlereminder-param-comment": "Hatırlatıcıya dahil edilecek isteğe bağlı kullanıcı yorumu", "apihelp-echoarticlereminder-example-1": "Yorum ile yarın için bir madde hatırlatıcı bildirimi oluşturun", @@ -78,5 +83,7 @@ "apiwarn-echo-deprecation-html": "<kbd>notformat=html</kbd> kullanımdan kaldırıldı ve yakında kaldırılacak. Bunun yerine <kbd>notformat=special</kbd> kullanın.", "apierror-echo-event-creation-failed": "Echo etkinliği oluşturulamadı", "apierror-echo-push-token-exists": "Sağlanan simge veritabanında zaten var.", - "apierror-echo-push-token-not-found": "Sağlanan anahtar veritabanında bulunamadı." + "apierror-echo-push-token-not-found": "Sağlanan anahtar veritabanında bulunamadı.", + "apierror-echo-push-too-many-subscriptions": "Mevcut kullanıcı, izin verilen maksimum push abonelik sayısını ($1) zaten kaydetti.", + "apierror-echo-push-topic-required": "Bu sağlayıcı için konu alanı gereklidir." } diff --git a/Echo/i18n/api/uk.json b/Echo/i18n/api/uk.json index b08690ef..911ad7d6 100644 --- a/Echo/i18n/api/uk.json +++ b/Echo/i18n/api/uk.json @@ -2,6 +2,8 @@ "@metadata": { "authors": [ "Base", + "DDPAT", + "Ice bulldog", "Piramidion", "Ата" ] @@ -28,6 +30,15 @@ "apihelp-echomute-param-unmute": "Сторінки чи користувачі, яких прибрати зі списку приглушення", "apihelp-echopushsubscriptions-summary": "Керувати пуш-підписками для поточного користувача.", "apihelp-echopushsubscriptions-param-command": "Дія, яку потрібно виконати.", + "apihelp-echopushsubscriptions+create-summary": "Реєструвати пуш-підписки для поточного користувача.", + "apihelp-echopushsubscriptions+create-param-provider": "Провайдер push-сервісу для якого зареєструвати токен.", + "apihelp-echopushsubscriptions+create-param-providertoken": "Токен для реєстрації.", + "apihelp-echopushsubscriptions+create-param-topic": "Тема APNS (ідентифікатор пакета додатків) для надсилання сповіщення.", + "apihelp-echopushsubscriptions+create-example": "Зареєструвати push-підписку для поточного користувача.", + "apihelp-echopushsubscriptions+delete-summary": "Скасувати реєстрацію push-підписок для поточного чи іншого вказаного користувача.", + "apihelp-echopushsubscriptions+delete-param-providertoken": "Токен пов'язаний з push-підпискою, реєстрацію якої необхідно скасувати.", + "apihelp-echopushsubscriptions+delete-param-centraluserid": "Центральний ідентифікатор користувача асоційований з підпискою для скасування реєстрації.", + "apihelp-echopushsubscriptions+delete-example": "Скасувати реєстрацію push-підписки для поточного користувача.", "apihelp-query+notifications-description": "Отримати сповіщення, які чекають поточного користувача.", "apihelp-query+notifications-summary": "Отримувати сповіщення, що очікують на дію поточного користувача.", "apihelp-query+notifications-param-prop": "Деталі запиту.", @@ -49,8 +60,10 @@ "apihelp-query+notifications-param-messageunreadfirst": "Чи показувати спершу непрочитані звістки (використовується лише якщо встановлено groupbysection).", "apihelp-query+notifications-param-titles": "Виводити лише сповіщення для цих сторінок. Щоб отримати сповіщення, не пов'язані з жодною сторінкою, замість назви використайте [].", "apihelp-query+notifications-param-bundle": "Чи показувати пучок сумісних непрочитаних сповіщень згідно з правилами зв'язування типів сповіщень.", - "apihelp-query+notifications-example-1": "Список сповіщень", - "apihelp-query+notifications-example-2": "Список сповіщень, згрупованих за розділами, із зазначенням кількостей", + "apihelp-query+notifications-param-notifiertypes": "Типи сповіщувачів, для яких потрібно повертати сповіщення.", + "apihelp-query+notifications-example-1": "Список веб-сповіщень", + "apihelp-query+notifications-example-2": "Список веб-сповіщень, згрупованих за розділами, із зазначенням кількостей", + "apihelp-query+notifications-example-3": "Список повідомлень ел. поштою", "apihelp-query+unreadnotificationpages-description": "Отримати сторінки, для яких є непрочитані сповіщення для поточного користувача.", "apihelp-query+unreadnotificationpages-summary": "Отримувати сповіщення, щодо яких є непрочитані сповіщення для поточного користувача.", "apihelp-query+unreadnotificationpages-param-grouppages": "Згрупувати сторінки обговорення з їхніми основними сторінками, та згрупувати сповіщення, не пов'язані зі сторінкою, разом зі сторінкою поточного користувача.", @@ -67,5 +80,9 @@ "apiwarn-echo-deprecation-timestampformat": "Вихідний формат мітки часу MW є застарілим тут. У майбутньому для вихідного формату мітки часу завжди використовуватиметься ISO 8601. Налаштуйте свій клієнт і встановіть <kbd>ISO_8601</kbd> для <var>timestampFormat</var>.", "apiwarn-echo-deprecation-flyout": "Параметр <kbd>notformat=flyout</kbd> є застарілим і невдовзі його буде усунуто. Використовуйте <kbd>notformat=model</kbd>, щоб отримати сирі дані, або <kbd>notformat=special</kbd>, щоб отримати попередньо оброблений HTML.", "apiwarn-echo-deprecation-html": "Параметр <kbd>notformat=html</kbd> є застарілим, і невдовзі його буде усунуто. Натомість використовуйте <kbd>notformat=special</kbd>.", - "apierror-echo-event-creation-failed": "Не вдалося створити Echo-подію" + "apierror-echo-event-creation-failed": "Не вдалося створити Echo-подію", + "apierror-echo-push-token-exists": "Наданий токен вже є в базі даних.", + "apierror-echo-push-token-not-found": "Наданий токен не знайдено в базі даних.", + "apierror-echo-push-too-many-subscriptions": "Поточний користувач вже зареєстрував максимально дозволене число push-підписок ($1).", + "apierror-echo-push-topic-required": "Поле теми є обов'язковим для цього провайдера." } diff --git a/Echo/i18n/api/vi.json b/Echo/i18n/api/vi.json index ccb81952..78ba100a 100644 --- a/Echo/i18n/api/vi.json +++ b/Echo/i18n/api/vi.json @@ -2,12 +2,14 @@ "@metadata": { "authors": [ "Max20091", - "Minh Nguyen" + "Minh Nguyen", + "Nguyễn Mạnh An" ] }, "apihelp-echomarkread-param-list": "Danh sách các ID thông báo để đánh dấu là đã đọc.", "apihelp-echomarkread-example-2": "Đánh dấu tất cả thông báo là đã đọc", "apihelp-query+notifications-param-prop": "Chi tiết để yêu cầu.", "apihelp-query+notifications-paramvalue-format-model": "Dữ liệu thông báo thô", - "apihelp-query+notifications-example-1": "Danh sách thông báo" + "apihelp-query+notifications-example-1": "Danh sách thông báo", + "apierror-echo-push-topic-required": "Trường chủ đề là bắt buộc đối với nhà cung cấp này." } diff --git a/Echo/i18n/api/zh-hans.json b/Echo/i18n/api/zh-hans.json index e94d78a2..ec896860 100644 --- a/Echo/i18n/api/zh-hans.json +++ b/Echo/i18n/api/zh-hans.json @@ -2,7 +2,11 @@ "@metadata": { "authors": [ "Liuxinyu970226", - "Yfdyh000" + "Shizhao", + "SkyEye FAST", + "Tr jason", + "Yfdyh000", + "忒有钱" ] }, "apihelp-echomarkread-description": "对当前用户标记通知为已读。", @@ -11,6 +15,7 @@ "apihelp-echomarkread-param-unreadlist": "要标记未读的通知ID列表。", "apihelp-echomarkread-param-all": "如果设置,标记一位用户的所有通知为已读。", "apihelp-echomarkread-param-sections": "要标记为已读的部分列表。", + "apihelp-echomarkread-param-wikis": "将通知标记为已读的wiki列表(默认为仅当前wiki)。", "apihelp-echomarkread-example-1": "标记通知8为已读", "apihelp-echomarkread-example-2": "标记所有通知为已读", "apihelp-echomarkread-example-3": "标记通知1为未读", @@ -19,6 +24,22 @@ "apihelp-echomarkseen-example-1": "标记所有类型的通知为已读", "apihelp-echomarkseen-param-type": "要标记为已读的通知类型:“alert”、“message”或“all”。", "apihelp-echomarkseen-param-timestampFormat": "用于输出的时间戳格式,“ISO_8601”或“MW”。“MW”在此被弃用,因此所有客户端应切换为“ISO_8601”。此参数将被移除,且“ISO_8601”将成为唯一的输出格式。", + "apihelp-echomute-description": "将来自某些用户或页面的通知静音或取消静音。", + "apihelp-echomute-summary": "将来自某些用户或页面的通知静音或取消静音。", + "apihelp-echomute-param-type": "要添加或移除的静音列表", + "apihelp-echomute-param-mute": "要添加到屏蔽列表的页面或用户", + "apihelp-echomute-param-unmute": "要从静音列表中移除的页面或用户", + "apihelp-echopushsubscriptions-summary": "管理当前用户的推送订阅。", + "apihelp-echopushsubscriptions-param-command": "要执行的操作。", + "apihelp-echopushsubscriptions+create-summary": "为当前用户注册推送订阅。", + "apihelp-echopushsubscriptions+create-param-provider": "为其注册令牌的推送服务提供者。", + "apihelp-echopushsubscriptions+create-param-providertoken": "要注册的令牌。", + "apihelp-echopushsubscriptions+create-param-topic": "要发送通知的 APNS 主题(应用程序包 ID)。", + "apihelp-echopushsubscriptions+create-example": "为当前用户注册推送订阅。", + "apihelp-echopushsubscriptions+delete-summary": "取消注册当前用户或其他指定用户的推送订阅。", + "apihelp-echopushsubscriptions+delete-param-providertoken": "与取消注册的推送订阅关联的令牌。", + "apihelp-echopushsubscriptions+delete-param-centraluserid": "与取消注册订阅相关联的中央用户ID。", + "apihelp-echopushsubscriptions+delete-example": "取消注册当前用户的推送订阅。", "apihelp-query+notifications-description": "获取当前用户等待的通知。", "apihelp-query+notifications-summary": "获取当前用户等待的通知。", "apihelp-query+notifications-param-prop": "请求的细节。", @@ -40,8 +61,10 @@ "apihelp-query+notifications-param-messageunreadfirst": "是否首先显示未读的提醒通知(只当groupbysection已设置时使用)。", "apihelp-query+notifications-param-titles": "只返回这些页面的通知。要获取未分配给任何页面的通知,使用[]作为标题。", "apihelp-query+notifications-param-bundle": "是否根据通知类型捆绑规则,显示兼容捆绑的未读通知。", - "apihelp-query+notifications-example-1": "列举通知", - "apihelp-query+notifications-example-2": "列出通知,按节分组,带有数量", + "apihelp-query+notifications-param-notifiertypes": "要返回通知的类型。", + "apihelp-query+notifications-example-1": "列举网络通知", + "apihelp-query+notifications-example-2": "列出网络通知,按节分组,带有数量", + "apihelp-query+notifications-example-3": "列举电子邮件通知", "apihelp-query+unreadnotificationpages-description": "获取当前用户未读通知的相关页面。", "apihelp-query+unreadnotificationpages-summary": "获取当前用户未读通知的相关页面。", "apihelp-query+unreadnotificationpages-param-grouppages": "将讨论页与它们的主题页面一起分组,并将未分配给某一页面的通知与当前用户的用户页一起分组。", @@ -58,5 +81,9 @@ "apiwarn-echo-deprecation-timestampformat": "MW时间戳输出格式在此处已弃用。今后输出的时间戳格式将总是使用ISO 8601格式。请调整您的客户端,并设置<var>timestampFormat</var>为<kbd>ISO_8601</kbd>", "apiwarn-echo-deprecation-flyout": "<kbd>notformat=flyout</kbd>已弃用,并将很快被移除。请使用<kbd>notformat=model</kbd>以获取原始数据,或使用<kbd>notformat=special</kbd>以获取预渲染HTML。", "apiwarn-echo-deprecation-html": "<kbd>notformat=html</kbd>已弃用,并将很快被移除。请改用<kbd>notformat=special</kbd>。", - "apierror-echo-event-creation-failed": "无法创建Echo活动" + "apierror-echo-event-creation-failed": "无法创建Echo活动", + "apierror-echo-push-token-exists": "提供的令牌已存在于数据库中。", + "apierror-echo-push-token-not-found": "在数据库中找不到提供的令牌。", + "apierror-echo-push-too-many-subscriptions": "当前用户已经注册了最大允许数量的推送订阅 ($1)。", + "apierror-echo-push-topic-required": "此提供程序需要主题字段。" } diff --git a/Echo/i18n/api/zh-hant.json b/Echo/i18n/api/zh-hant.json index cb382972..702747b3 100644 --- a/Echo/i18n/api/zh-hant.json +++ b/Echo/i18n/api/zh-hant.json @@ -31,9 +31,11 @@ "apihelp-echopushsubscriptions+create-summary": "註銷目前使用者的推送訂閱。", "apihelp-echopushsubscriptions+create-param-provider": "註冊權杖的推送服務提供者。", "apihelp-echopushsubscriptions+create-param-providertoken": "註冊的權杖。", + "apihelp-echopushsubscriptions+create-param-topic": "要將通知發送到的 APNS 主題(App bundle ID)。", "apihelp-echopushsubscriptions+create-example": "為目前使用者註冊推送訂閱。", - "apihelp-echopushsubscriptions+delete-summary": "註銷目前使用者的推送訂閱。", + "apihelp-echopushsubscriptions+delete-summary": "註銷目前使用者或是其他指定使用者的推送訂閱。", "apihelp-echopushsubscriptions+delete-param-providertoken": "關聯註銷推送訂閱的權杖。", + "apihelp-echopushsubscriptions+delete-param-centraluserid": "取消註冊的與訂閱關聯之中央使用者 ID。", "apihelp-echopushsubscriptions+delete-example": "註銷目前使用者的推送訂閱。", "apihelp-query+notifications-description": "取得目前使用者等待的通知。", "apihelp-query+notifications-summary": "取得目前使用者等待的通知。", @@ -54,10 +56,12 @@ "apihelp-query+notifications-param-alertunreadfirst": "是否要先顯示未讀的訊息通知(僅當groupbysection未設定時使用)。", "apihelp-query+notifications-param-messagecontinue": "當有更多訊息結果時,使用此參數來繼續。", "apihelp-query+notifications-param-messageunreadfirst": "是否要先顯示未讀的警告通知(僅當groupbysection未設定時使用)。", - "apihelp-query+notifications-param-titles": "只返回这些页面的通知。要獲取未分配給任何頁面的通知,使用[]作為標題。", + "apihelp-query+notifications-param-titles": "只回傳這些頁面的通知。要獲取未分配給任何頁面的通知,請使用[]作為標題。", "apihelp-query+notifications-param-bundle": "是否根據通知類型捆綁規則,顯示兼容捆綁的未讀通知。", - "apihelp-query+notifications-example-1": "通知清單", - "apihelp-query+notifications-example-2": "依章節分類通知清單並顯示總數", + "apihelp-query+notifications-param-notifiertypes": "用於要回傳通知的通知者類型", + "apihelp-query+notifications-example-1": "列出網路通知", + "apihelp-query+notifications-example-2": "列出網路通知(依章節分組並帶有計數)", + "apihelp-query+notifications-example-3": "列出電子郵件通知", "apihelp-query+unreadnotificationpages-description": "獲取目前使用者有未讀通知的頁面。", "apihelp-query+unreadnotificationpages-summary": "取得目前使用者有未讀通知的頁面。", "apihelp-query+unreadnotificationpages-param-grouppages": "將討論頁與對應的主題頁面歸在一起,並將未分配給某一頁面的通知與目前使用者的使用者頁面歸在一起。", @@ -76,5 +80,7 @@ "apiwarn-echo-deprecation-html": "<kbd>notformat=html</kbd>已棄用,並將很快被移除。請改用<kbd>notformat=special</kbd>。", "apierror-echo-event-creation-failed": "無法建立 Echo 事件", "apierror-echo-push-token-exists": "提供的權杖已存在於資料庫。", - "apierror-echo-push-token-not-found": "在資料庫裡找不到提供的權杖。" + "apierror-echo-push-token-not-found": "在資料庫裡找不到提供的權杖。", + "apierror-echo-push-too-many-subscriptions": "目前使用者已註冊所允許的最大推送訂閱數目($1)。", + "apierror-echo-push-topic-required": "提供者的主題欄位為必須。" } diff --git a/Echo/i18n/ar.json b/Echo/i18n/ar.json index 259ac814..6214595c 100644 --- a/Echo/i18n/ar.json +++ b/Echo/i18n/ar.json @@ -7,6 +7,7 @@ "Asaifm", "Catrope", "Ciphers", + "FShbib", "Hiba Alshawi", "Izoozo", "Khaled", @@ -14,6 +15,7 @@ "Maroen1990", "Meno25", "Mido", + "Mohanad Kh", "Moud hosny", "Omar Ghrida", "Omda4wady", @@ -168,7 +170,7 @@ "notification-header-user-rights-remove-only": "{{GENDER:$4|صلاحياتك}} تم {{GENDER:$1|تغييرها}}. أنت لم تعد عضوا في: $2.", "notification-header-user-rights-add-and-remove": "{{GENDER:$6|صلاحياتك}} تم {{GENDER:$1|تغييرها}}. أنت تمت إضافتك إلى: $2. أنت لم تعد عضوا في: $4.", "notification-header-user-rights-expiry-change": "تاريخ انتهاء {{GENDER:$4|عضويتك}} في {{PLURAL:$3|المجموعة|المجموعات}} التالية تم {{GENDER:$1|تغييرها}}: $2.", - "notification-header-welcome": "{{GENDER:$2|مرحبًا بك|مرحبًا بكِ}} في {{SITENAME}}، $1! نحن سعداءٌ {{GENDER:$2|بتواجدك|بتواجدكِ}} هنا.", + "notification-header-welcome": "{{GENDER:$2|مرحبًا بك|مرحبًا بكِ}} في {{SITENAME}}، $1! نحن سعداءُ {{GENDER:$2|بتواجدك|بتواجدكِ}} هنا.", "notification-header-mention-summary": "$1 {{GENDER:$2|ذكر|ذكرت}}{{GENDER:$3|ك}} في ملخص تعديل في <strong>$4</strong>.", "notification-header-watchlist-changed": "$1 {{GENDER:$2|غير|غيرت}} <strong>$3</strong>، صفحة في {{GENDER:$4|قائمة مراقبتك}} {{PLURAL:$5||، $5 مرات}}.", "notification-header-watchlist-created": "$1 {{GENDER:$2|أنشأ|أنشأت}} <strong>$3</strong>، صفحة في {{GENDER:$4|قائمة مراقبتك}} {{PLURAL:$5||، $5 مرات}}.", @@ -209,7 +211,7 @@ "notification-inbox-filter-read": "المقروءة", "notification-inbox-filter-unread": "غير المقروءة", "notification-inbox-filter-all": "الكل", - "echo-specialmute-label-mute-notifications": "تجاهل الإشعارات من هذا المستخدم", + "echo-specialmute-label-mute-notifications": "تجاهل الإشعارات من {{GENDER:$1|هذا المستخدم|هذه المستخدمة}}", "echo-email-plain-footer": "للتحكم في ما هي رسائل البريد الإلكتروني التي نرسلها {{GENDER:$1|إليك}}، تحقق من {{GENDER:$1|تفضيلاتك}}:", "echo-email-html-footer-preference-link-text": "تحقق من {{GENDER:$1|تفضيلاتك}}", "echo-email-html-footer-with-link": "للتحكم في ما هي رسائل البريد الإلكتروني التي نرسلها {{GENDER:$2|إليك}}، $1.", @@ -234,5 +236,8 @@ "notification-header-foreign-alert": "إخطارات أكثر من {{PLURAL:$5|لا موقع ويكي|موقع ويكي آخر|موقعين ويكي آخرين|$5 مواقع ويكي أخرى}}", "notification-header-foreign-notice": "مزيد من الإشعارات من {{PLURAL:$5|ويكي أخر|$5 ويكيات أخرى}}", "notification-header-foreign-all": "المزيد من الإخطارات من {{PLURAL:$5|ويكي أخرى|$5 ويكيات أخرى}}", - "echo-badge-count": "{{PLURAL:$1|$1|100={{formatnum:99}}+}}" + "echo-badge-count": "{{PLURAL:$1|$1|100={{formatnum:99}}+}}", + "group-push-subscription-manager": "إداريو مصادقات التسليم", + "group-push-subscription-manager-member": "{{GENDER:$1|إداري مصادقات التسليم}}", + "grouppage-push-subscription-manager": "{{ns:project}}:إداريو مصادقات التسليم" } diff --git a/Echo/i18n/ary.json b/Echo/i18n/ary.json index 66b4667c..bc5d6dad 100644 --- a/Echo/i18n/ary.json +++ b/Echo/i18n/ary.json @@ -7,5 +7,16 @@ }, "echo-new-messages": "عندك ميساجات جداد", "tooltip-pt-notifications-alert": "{{GENDER:|تنبيهاتك}}", + "notification-link-text-collapse-all": "طوي", + "notification-link-text-view-message": "وري لميساج", + "notification-header-mention-other": "{{GENDER:$2|نغز|نغزات}} $1 {{GENDER:$3|ليك}} ف صفحة <strong>$4</strong> ف لقسم \"<strong>$5</strong>\".", + "notification-header-mention-article-talkpage-nosection": "{{GENDER:$2|نغز|نغزات}} $1 ليك ف صفحة نيقاش <strong>$4</strong>.", + "notification-welcome-linktext": "مرحبا بيك", + "notification-header-thank-you-1-edit": "درتي عاد دابا تبديل ديالك لول؛ شكرا بزاف ؤ مرحبا بيك!", + "notification-header-thank-you-10-edit": "درتي عاد دابا تبديل ديالك لعاشر؛ شكرا ليك، {{GENDER:$2|راك غادي|راكي غادية}} مزيان!", + "notification-header-thank-you-100-edit": "درتي عاد دابا تبديل ديالك لمية؛ شكرا ليك بزاف!", + "notification-header-thank-you-10000-edit": "درتي عاد دابا تبديل ديالك لعشرالاف؛ شكرا ليك بزاف!", + "notification-edit-talk-page-email-subject2": "{{GENDER:$2|صافط|صافطات}} ليك $1 ميساج ف {{SITENAME}}", + "notification-mention-email-subject": "{{GENDER:$2|نغز|نغزات}} $1 {{GENDER:$3|ليك}} ف {{SITENAME}}", "notification-inbox-filter-all": "كلشي" } diff --git a/Echo/i18n/arz.json b/Echo/i18n/arz.json index 8b4a685f..1ed74095 100644 --- a/Echo/i18n/arz.json +++ b/Echo/i18n/arz.json @@ -3,5 +3,6 @@ "authors": [ "Ghaly" ] - } + }, + "tooltip-pt-notifications-alert": "{{GENDER:|تنبيهاتك}}" } diff --git a/Echo/i18n/as.json b/Echo/i18n/as.json index e50ee236..e2391625 100644 --- a/Echo/i18n/as.json +++ b/Echo/i18n/as.json @@ -2,12 +2,227 @@ "@metadata": { "authors": [ "Gitartha.bordoloi", + "Paradox", "Simbu123" ] }, + "echo-desc": "ঘটনা আৰু বাৰ্তাৰ বিষয়ে সদস্যক জাননী দিয়াৰ ব্যৱস্থা", "prefs-echo": "জাননী", - "echo-new-messages": "আপোনালৈ নতুন বাৰ্তা আহিছে", + "prefs-emailsettings": "ই-মেইল বিকল্প", + "prefs-echosubscriptions": "এই ঘটনাবোৰৰ বিষয়ে মোক জাননী দিয়ক", + "prefs-echocrosswiki": "আন্তঃ-ৱিকি জাননী", + "prefs-blocknotificationslist": "মৌন সদস্য", + "prefs-mutedpageslist": "পৃষ্ঠা লিংক জাননীৰ বাবে নিঃশব্দ কৰা পৃষ্ঠাসমূহ", + "prefs-echopollupdates": "পোনপটীয়া জাননী", + "echo-mobile-notifications-filter-title": "জাননীসমূহ ছেকক", + "echo-pref-show-poll-updates": "নতুন জাননীসমূহ আগমনৰ লগে লগে প্ৰদৰ্শন কৰক", + "echo-pref-show-poll-updates-help": "শীৰ্ষক দণ্ডিকাত অপঠিত জাননীৰ সংখ্যা দেখুৱাওক, আৰু প্ৰতিটো জাননী আগমনৰ লগে লগে তাৰ একাংশ দেখুৱাওক।", + "echo-pref-send-me": "মোক পঠিয়াওক:", + "echo-pref-send-to": "প্ৰতি:", + "echo-pref-email-format": "ই-মেইল ফৰমেট:", + "echo-pref-web": "ৱেব", + "echo-pref-email": "ই-মেইল", + "echo-pref-push": "এপ্প", + "echo-pref-email-frequency-never": "মোক কোনো জাননী ই-মেইলত প্ৰেৰণ নকৰিব", + "echo-pref-email-frequency-immediately": "স্বতন্ত্ৰ জাননী আগমনৰ লগে লগেই", + "echo-pref-email-frequency-daily": "জাননীসমূহৰ এক দৈনিক সাৰাংশ", + "echo-pref-email-frequency-weekly": "জাননীসমূহৰ এক সাপ্তাহিক সাৰাংশ", + "echo-pref-email-format-html": "এইচটিএমএল", + "echo-pref-email-format-plain-text": "সাধাৰণ পাঠ্য", + "echo-pref-cross-wiki-notifications": "আন ৱিকিৰ জাননীসমূহ দেখুৱাওক", + "echo-pref-notifications-blacklist": "এই সদস্যসকলৰ পৰা অহা জাননী প্ৰদৰ্শন নকৰিব।\n([[mw:Special:MyLanguage/Help:Notifications#mute|অধিক শিকক]])", + "echo-pref-notifications-page-linked-title-muted-list": "এই পৃষ্ঠাবোৰৰ বাবে \"পৃষ্ঠা লিংক\" জাননী প্ৰদৰ্শন নকৰিব।\n([[mw:Special:MyLanguage/Help:Notifications#mute|অধিক শিকক]])", + "echo-pref-dont-email-read-notifications": "সাৰাংশ ই-মেইলত পঠিত জাননীসমূহ অন্তৰ্ভুক্ত নকৰিব", + "echo-learn-more": "অধিক শিকক", + "echo-log": "ৰাজহুৱা লগ", + "echo-new-messages": "আপোনাৰ আলোচনা পৃষ্ঠাত এটা নতুন বাৰ্তা আহিছে", + "echo-category-title-edit-user-talk": "আলোচনা পৃষ্ঠাৰ {{PLURAL:$1|বাৰ্তা|বাৰ্তাসমূহ}}", + "echo-category-title-article-linked": "পৃষ্ঠাৰ {{PLURAL:$1|সংযোগ|সংযোগসমূহ}}", + "echo-category-title-reverted": "{{PLURAL:$1|পূৰ্ববত হোৱা}} সম্পাদনা", + "echo-category-title-mention": "{{PLURAL:$1|উল্লেখ|উল্লেখসমূহ}}", + "echo-category-title-mention-failure": "ব্যৰ্থ {{PLURAL:$1|উল্লেখ|উল্লেখসমূহ}}", + "echo-category-title-mention-success": "সফল {{PLURAL:$1|উল্লেখ|উল্লেখসমূহ}}", + "echo-category-title-other": "{{PLURAL:$1|অন্য}}", + "echo-category-title-system": "{{PLURAL:$1|চিষ্টেম}}", + "echo-category-title-system-noemail": "{{PLURAL:$1|চিষ্টেম}}", + "echo-category-title-system-emailonly": "{{PLURAL:$1|চিষ্টেম}}", + "echo-category-title-user-rights": "{{PLURAL:$1|সদস্যৰ অধিকাৰ পৰিৱৰ্তন}}", + "echo-category-title-emailuser": "{{PLURAL:$1|অন্য সদস্যৰ পৰা ই-মেইল}}", + "echo-category-title-article-reminder": "পৃষ্ঠাৰ {{PLURAL:$1|স্মাৰক}}", + "echo-category-title-thank-you-edit": "সম্পাদনাৰ {{PLURAL:$1|মাইলৰ খুঁটি}}", + "echo-category-title-watchlist": "লক্ষ্য-তালিকাৰ পৃষ্ঠাৰ সম্পাদনা", + "echo-category-title-minor-watchlist": "লক্ষ্য-তালিকাৰ পৃষ্ঠাৰ অগুৰুত্বপূৰ্ণ সম্পাদনা", + "echo-pref-tooltip-edit-user-talk": "কোনোবাই মোৰ আলোচনা পৃষ্ঠাত বাৰ্তা এটা দিলে বা উত্তৰ দিলে মোক জাননী দিয়ক।", + "echo-pref-tooltip-article-linked": "কোনোবাই মই আন পৃষ্ঠাৰ পৰা সৃষ্টি কৰা পৃষ্ঠা এটাৰ লিংক প্ৰদান কৰিলে মোক জাননী দিয়ক।", + "echo-pref-tooltip-reverted": "কোনোবাই মই কৰা সম্পাদনা এটা আনডু বা ৰ'লবেক সঁজুলিৰে পূৰ্ববত কৰিলে মোক জাননী দিয়ক।", + "echo-pref-tooltip-mention": "কোনোবাই মোৰ সদস্য পৃষ্ঠালৈ লিংক প্ৰদান কৰিলে মোক জাননী দিয়ক।", + "echo-pref-tooltip-mention-failure": "মই কাৰোবাক কৰা উল্লেখ প্ৰেৰণ কৰিব নোৱাৰিলে মোক জাননী দিয়ক।", + "echo-pref-tooltip-mention-success": "মই কাৰোবাক কৰা উল্লেখ প্ৰেৰণ কৰিলে মোক জাননী দিয়ক।", + "echo-pref-tooltip-user-rights": "কোনোবাই মোৰ সদস্যৰ অধিকাৰ সলনি কৰিলে মোক জাননী দিয়ক।", + "echo-pref-tooltip-emailuser": "কোনোবাই মোলৈ ই-মেইল প্ৰেৰণ কৰিলে মোক জাননী দিয়ক।", + "echo-pref-tooltip-article-reminder": "মই বিচাৰিলে এই পৃষ্ঠাটোৰ বিষয়ে মোক জাননী দিয়ক।", + "echo-pref-tooltip-thank-you-edit": "মই মোৰ প্ৰথম, দশম, ১০০তম... সম্পাদনাত উপনীত হওঁতে মোক জাননী দিয়ক।", + "echo-pref-tooltip-watchlist": "কোনোবাই মোৰ লক্ষ্য-তালিকাৰ পৃষ্ঠা এটাত (গুৰুত্বপূৰ্ণ) সম্পাদনা কৰিলে মোক জাননী দিয়ক।", + "echo-pref-tooltip-minor-watchlist": "কোনোবাই মোৰ লক্ষ্য-তালিকাৰ পৃষ্ঠা এটাত অগুৰুত্বপূৰ্ণ সম্পাদনা কৰিলে মোক জাননী দিয়ক।", "notifications": "জাননী", "tooltip-pt-notifications-alert": "{{GENDER:|আপোনাৰ}} জাননী", - "echo-specialpage": "জাননী" + "tooltip-pt-notifications-notice": "{{GENDER:|আপোনাৰ}} জাননী", + "echo-displaynotificationsconfiguration": "জাননী কনফিগাৰেচন প্ৰদৰ্শন কৰক", + "echo-displaynotificationsconfiguration-summary": "এই ৱিকিত জাননীসমূহ কেনেদৰে কনফিগাৰ কৰা হৈছে তাৰ এক অৱলোকন।", + "echo-displaynotificationsconfiguration-notifications-by-category-header": "শ্ৰেণী অনুসৰি জাননীসমূহ", + "echo-displaynotificationsconfiguration-sorting-by-section-header": "প্ৰকাৰ অনুসৰি ক্ৰমবিন্যাস", + "echo-displaynotificationsconfiguration-sorting-by-section-legend": "প্ৰতিটো জাননীৰ প্ৰকাৰ কোনটো অন্চ্ছেদত সজোৱা হৈছে", + "echo-displaynotificationsconfiguration-available-notification-methods-header": "অনুমোদিত জাননী পদ্ধতিসমূহ", + "echo-displaynotificationsconfiguration-available-notification-methods-by-category-legend": "প্ৰতিটো শ্ৰেণীৰ বাবে কোনবোৰ জাননী পদ্ধতি সমৰ্থিত", + "echo-displaynotificationsconfiguration-enabled-default-header": "পূৰ্বনিৰ্ধাৰিত ৰূপে সক্ৰিয়", + "echo-displaynotificationsconfiguration-enabled-default-existing-users-legend": "বিদ্যমান সদস্যসকল", + "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "নতুন সদস্যসকল", + "echo-displaynotificationsconfiguration-mandatory-notification-methods-header": "প্ৰয়োজনীয় জাননী পদ্ধতিসমূহ", + "echo-displaynotificationsconfiguration-mandatory-notification-methods-by-category-legend": "প্ৰতিটো শ্ৰেণীৰ বাবে কোনবোৰ জাননী পদ্ধতি বাধ্যতামূলক", + "echo-specialpage": "জাননী", + "echo-specialpage-section-markread": "গোটটো পঠিত বুলি চিহ্নিত কৰক", + "echo-specialpage-markasread": "জাননী: পঠিত বুলি চিহ্নিত কৰক", + "echo-specialpage-markasread-invalid-id": "অবৈধ ঘটনা আইডি", + "echo-specialpage-pagefilterwidget-aria-label": "ৱিকি আৰু পৃষ্ঠাৰ শিৰোনাম অনুসৰি ছেকক", + "echo-specialpage-special-help-menu-widget-aria-label": "অতিৰিক্ত বিকল্প আৰু জাননীৰ পছন্দসমূহ।", + "echo-specialpage-pagination-numnotifications": "$1টা {{PLURAL:$1|জাননী}}", + "echo-specialpage-pagefilters-title": "শেহতীয়া কাৰ্যকলাপ", + "echo-specialpage-pagefilters-subtitle": "অপঠিত জাননী থকা পৃষ্ঠাসমূহ", + "notificationsmarkread-legend": "জাননী পঠিত বুলি চিহ্নিত কৰক", + "echo-none": "আপোনাৰ কোনো জাননী নাই।", + "echo-api-failure": "জাননীসমূহ প্ৰাপ্ত কৰাত ব্যৰ্থ হৈছে।", + "echo-api-failure-cross-wiki": "ৰিম'ট ডমেইনলৈ প্ৰৱেশাধিকাৰ অস্বীকাৰ কৰা হৈছে।", + "echo-notification-placeholder": "কোনো জাননী নাই।", + "echo-notification-placeholder-filters": "এই মানদণ্ডসমূহৰ সৈতে মিলা কোনো জাননী নাই।", + "echo-notification-loginrequired": "আপুনি আপোনাৰ জাননীসমূহ চাবলৈ লগ্ ইন কৰিব লাগিব।", + "echo-notification-popup-loginrequired": "অনুগ্ৰহ কৰি আপোনাৰ জাননীসমূহ চাবলৈ লগ্ ইন কৰক।", + "echo-notification-markasread": "পঠিত বুলি চিহ্নিত কৰক", + "echo-notification-markasunread": "অপঠিত বুলি চিহ্নিত কৰক", + "echo-notification-markasread-tooltip": "পঠিত বুলি চিহ্নিত কৰক", + "echo-notification-more-options-tooltip": "অধিক বিকল্প", + "notification-dynamic-actions-mute-page-linked": "\"$1\"-ত লিংক জাননীসমূহ {{GENDER:$2|নিঃশব্দ কৰক}}", + "notification-dynamic-actions-mute-page-linked-confirmation": "\"পৃষ্ঠা লিংক\" জাননীসমূহ এতিয়া \"$1\" পৃষ্ঠাৰ বাবে নিষ্ক্ৰিয় কৰা হৈছে", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|আপুনি}} যিকোনো সময়তে [$1 পছন্দসমূহত] আপোনাৰ নিঃশব্দ কৰা পৃষ্ঠাবোৰ পৰিচালনা কৰিব পাৰে।", + "notification-dynamic-actions-unmute-page-linked": "\"$1\"-ত লিংক জাননীসমূহ {{GENDER:$2|নিঃশব্দ কৰা বন্ধ কৰক}}", + "notification-dynamic-actions-unmute-page-linked-confirmation": "\"পৃষ্ঠা লিংক\" জাননীসমূহ এতিয়া \"$1\" পৃষ্ঠাৰ বাবে সক্ৰিয় কৰা হৈছে", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|আপুনি}} যিকোনো সময়তে [$1 পছন্দসমূহত] আপোনাৰ নিঃশব্দ কৰা পৃষ্ঠাবোৰ পৰিচালনা কৰিব পাৰে।", + "notification-dynamic-actions-unwatch": "\"$1\"ত নতুন কাৰ্যকলাপ চোৱা {{GENDER:$3|বন্ধ কৰক}}", + "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3|আপুনি}} আৰু \"$1\" পৃষ্ঠাটোত লক্ষ্য ৰখা নাই", + "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|আপুনি}} যিকোনো সময়তে [$2 এই পৃষ্ঠাটোত] লক্ষ্য ৰখিব পাৰে।", + "notification-dynamic-actions-watch": "\"$1\"ত নতুন কাৰ্যকলাপ {{GENDER:$3|অনুসৰণ কৰক}}", + "notification-dynamic-actions-watch-confirmation": "{{GENDER:$3|আপুনি}} এতিয়া \"$1\" পৃষ্ঠাটো লক্ষ্য কৰি আছে", + "notification-dynamic-actions-watch-confirmation-description": "{{GENDER:$3|আপুনি}} যিকোনো সময়তে [$2 এই পৃষ্ঠাটোত] লক্ষ্য ৰখা বন্ধ কৰিব পাৰে।", + "notification-link-text-expand-all": "বহলাওক", + "notification-link-text-expand-alert-count": "{{PLURAL:$1|$1টা বাৰ্তা}} চাওক", + "notification-link-text-expand-notice-count": "{{PLURAL:$1|$1টা জাননী}} চাওক", + "notification-link-text-expand-all-count": "{{PLURAL:$1|$1টা জাননী}} চাওক", + "notification-link-text-collapse-all": "সংকোচ কৰক", + "notification-link-text-view-message": "বাৰ্তা চাওক", + "notification-link-text-view-mention": "উল্লেখ চাওক", + "notification-link-text-view-mention-failure": "{{PLURAL:$1|উল্লেখ চাওক|উল্লেখসমূহ চাওক}}", + "notification-link-text-view-changes": "পৰিবৰ্তনসমূহ {{GENDER:$1|চাওক}}", + "notification-link-text-view-page": "পৃষ্ঠা চাওক", + "notification-header-edit-user-talk": "$1-এ <strong>{{GENDER:$3|আপোনাৰ}} আলোচনা পৃষ্ঠা</strong>ত এটা বাৰ্তা {{GENDER:$2|দিছে}}।", + "notification-header-edit-user-talk-with-section": "$1-এ <strong>{{GENDER:$3|আপোনাৰ}} আলোচনা পৃষ্ঠা</strong>ৰ \"<strong>$4</strong>\"ত এটা বাৰ্তা {{GENDER:$2|দিছে}}।", + "notification-compact-header-edit-user-talk": "$1-এ {{GENDER:$3|আপোনালৈ}} এটা বাৰ্তা {{GENDER:$2|দিছে}}।", + "notification-compact-header-edit-user-talk-with-section": "$1-এ {{GENDER:$3|আপোনালৈ}} \"<strong>$4</strong>\"ত এটা বাৰ্তা {{GENDER:$2|দিছে}}।", + "notification-header-page-linked": "<strong>$4</strong>ৰ পৰা <strong>$3</strong>লৈ এটা লিংক সৃষ্টি কৰা হৈছে।", + "notification-compact-header-page-linked": "<strong>$1</strong>ৰ পৰা লিংক কৰা হৈছে।", + "notification-bundle-header-page-linked": "{{PLURAL:$5||$5 পৃষ্ঠাৰ|100=৯৯+ পৃষ্ঠাৰ}} পৰা <strong>$3</strong>লৈ লিংক সৃষ্টি কৰা হৈছে।", + "notification-header-article-reminder": "{{GENDER:$2|আপুনি}} মনত পেলাবলৈ অনুৰোধ কৰা এটা পৃষ্ঠা হৈছে <strong>$3</strong>", + "notification-link-text-what-links-here": "এই পৃষ্ঠালৈ থকা সকলো সংযোগ", + "notification-header-mention-other": "$1-এ {{GENDER:$3|আপোনাক}} <strong>$4</strong>ৰ \"<strong>$5</strong>\"ত {{GENDER:$2|উল্লেখ কৰিছে}}।", + "notification-header-mention-other-nosection": "$1-এ {{GENDER:$3|আপোনাক}} <strong>$4</strong>ত {{GENDER:$2|উল্লেখ কৰিছে}}।", + "notification-header-mention-user-talkpage-v2": "$1-এ {{GENDER:$3|আপোনাক}} $4{{GENDER:$5|ৰ}} সদস্য আলোচনা পৃষ্ঠাৰ \"<strong>$6</strong>\"ত {{GENDER:$2|উল্লেখ কৰিছে}}।", + "notification-header-mention-user-talkpage-nosection": "$1-এ {{GENDER:$3|আপোনাক}} $4{{GENDER:$5|ৰ}} সদস্য আলোচনা পৃষ্ঠাত {{GENDER:$2|উল্লেখ কৰিছে}}।", + "notification-header-mention-agent-talkpage": "$1-এ {{GENDER:$3|আপোনাক}} <strong>{{GENDER:$2|তেওঁৰ}} আলোচনা পৃষ্ঠা</strong>ৰ \"<strong>$4</strong>\"ত {{GENDER:$2|উল্লেখ কৰিছে}}।", + "notification-header-mention-agent-talkpage-nosection": "$1-এ {{GENDER:$3|আপোনাক}} <strong>{{GENDER:$2|তেওঁৰ}} আলোচনা পৃষ্ঠা</strong>ত {{GENDER:$2|উল্লেখ কৰিছে}}।", + "notification-header-mention-article-talkpage": "$1-এ {{GENDER:$3|আপোনাক}} <strong>$4</strong> আলোচনা পৃষ্ঠাৰ \"<strong>$5</strong>\"ত {{GENDER:$2|উল্লেখ কৰিছে}}।", + "notification-header-mention-article-talkpage-nosection": "$1-এ {{GENDER:$3|আপোনাক}} <strong>$4</strong> আলোচনা পৃষ্ঠাত {{GENDER:$2|উল্লেখ কৰিছে}}।", + "notification-header-mention-failure-user-unknown": "{{GENDER:$2|আপুনি}} <strong>$3</strong>লৈ কৰা উল্লেখটো প্ৰেৰণ কৰিব পৰা নগ'ল কিয়নো সদস্যজনক বিচাৰি পোৱা নগ'ল।", + "notification-header-mention-failure-user-anonymous": "{{GENDER:$2|আপুনি}} <strong>$3</strong>লৈ কৰা উল্লেখটো প্ৰেৰণ কৰিব পৰা নগ'ল কিয়নো তেওঁ এক অনামী সদস্য।", + "notification-header-mention-failure-too-many": "{{GENDER:$2|আপুনি}} $3জনতকৈ অধিক {{PLURAL:$3|সদস্যক}} উল্লেখ কৰিবলৈ চেষ্টা কৰিছে। এই সীমাৰ বাহিৰত থকা সকলো উল্লেখ প্ৰেৰণ কৰা নহ'ল।", + "notification-header-mention-failure-bundle": "<strong>$4</strong> আলোচনা পৃষ্ঠাত {{GENDER:$2|আপুনি কৰা}} {{PLURAL:$3|এটা উল্লেখ|$3টা উল্লেখ}} প্ৰেৰণ কৰিব পৰা {{PLURAL:$3|নগ'ল}}।", + "notification-compact-header-mention-failure-user-unknown": "<strong>সদস্য নামৰ অস্তিত্ব নাই:</strong> $1", + "notification-compact-header-mention-failure-user-anonymous": "<strong>আইপি ঠিকনাক উল্লেখ কৰিব নোৱাৰি:</strong> $1", + "notification-header-mention-success": "{{GENDER:$2|আপুনি}} <strong>$3</strong>লৈ কৰা উল্লেখটো প্ৰেৰণ কৰা হ'ল।", + "notification-header-mention-success-bundle": "<strong>$4</strong> আলোচনা পৃষ্ঠাত {{GENDER:$2|আপুনি কৰা}} {{PLURAL:$3|এটা উল্লেখ|$3টা উল্লেখ}} প্ৰেৰণ কৰা {{PLURAL:$3|হ'ল}}।", + "notification-compact-header-mention-success": "<strong>{{GENDER:$2|আপুনি উল্লেখ কৰিছে}}:</strong> $3", + "notification-header-mention-status-bundle": "আপুনি <strong>$4</strong> আলোচনা পৃষ্ঠাত {{GENDER:$2|কৰা উল্লেখৰ}} বিষয়ে {{PLURAL:$3|এক জাননী|$3টা জাননী}}: {{PLURAL:$5|$5টা প্ৰেৰণ কৰা নহ'ল}}, {{PLURAL:$6|$6টা প্ৰেৰণ কৰা হ'ল}}।", + "notification-header-user-rights-add-only": "{{GENDER:$4|আপোনাৰ}} সদস্যৰ অধিকাৰ {{GENDER:$1|সলনি কৰা হৈছে}}। আপোনাক $2-ত যোগ কৰা হৈছে।", + "notification-header-user-rights-remove-only": "{{GENDER:$4|আপোনাৰ}} সদস্যৰ অধিকাৰ {{GENDER:$1|সলনি কৰা হৈছে}}। আপুনি এতিয়া $2-ৰ সদস্য নহয়।", + "notification-header-user-rights-add-and-remove": "{{GENDER:$6|আপোনাৰ}} সদস্যৰ অধিকাৰ {{GENDER:$1|সলনি কৰা হৈছে}}। আপোনাক $2-ত যোগ কৰা হৈছে। আপুনি এতিয়া $4-ৰ সদস্য নহয়।", + "notification-header-user-rights-expiry-change": "নিম্নলিখিত {{PLURAL:$3|গোটত|গোটবোৰত}} {{GENDER:$4|আপোনাৰ}} সদস্যপদৰ ম্যাদ উকলি যোৱাটো {{GENDER:$1|সলনি কৰা হৈছে}}: $2।", + "notification-header-welcome": "$1, {{SITENAME}}লৈ আপোনাক {{GENDER:$2|আদৰিছোঁ}}! {{GENDER:$2|আপোনাক}} ইয়াত দেখি আমি অতি আনন্দিত।", + "notification-header-mention-summary": "$1-এ {{GENDER:$3|আপোনাক}} <strong>$4</strong>ৰ সম্পাদনা সাৰাংশত {{GENDER:$2|উল্লেখ কৰিছে}}।", + "notification-header-watchlist-changed": "$1-এ {{GENDER:$4|আপোনাৰ}} লক্ষ্য-তালিকাৰ <strong>$3</strong> নামৰ পৃষ্ঠাক {{GENDER:$2|সাল-সলনি কৰিছে}}{{PLURAL:$5||, $5 বাৰ}}।", + "notification-header-watchlist-created": "$1-এ {{GENDER:$4|আপোনাৰ}} লক্ষ্য-তালিকাৰ <strong>$3</strong> নামৰ পৃষ্ঠাক {{GENDER:$2|সৃষ্টি কৰিছে}}{{PLURAL:$5||, $5 বাৰ}}।", + "notification-header-watchlist-deleted": "$1-এ {{GENDER:$4|আপোনাৰ}} লক্ষ্য-তালিকাৰ <strong>$3</strong> নামৰ পৃষ্ঠাক {{GENDER:$2|বিলোপ কৰিছে}}{{PLURAL:$5||, $5 বাৰ}}।", + "notification-header-watchlist-moved": "$1-এ {{GENDER:$4|আপোনাৰ}} লক্ষ্য-তালিকাৰ <strong>$3</strong> নামৰ পৃষ্ঠাক {{GENDER:$2|স্থানান্তৰ কৰিছে}}{{PLURAL:$5||, $5 বাৰ}}।", + "notification-header-watchlist-restored": "$1-এ {{GENDER:$4|আপোনাৰ}} লক্ষ্য-তালিকাৰ <strong>$3</strong> নামৰ পৃষ্ঠাক {{GENDER:$2|পুনৰুদ্ধাৰ কৰিছে}}{{PLURAL:$5||, $5 বাৰ}}।", + "notification-header-watchlist-multiuser-changed": "{{GENDER:$2|আপোনাৰ}} লক্ষ্য-তালিকাৰ <strong>$1</strong> নামৰ পৃষ্ঠাক $3 {{PLURAL:$3|বাৰ}} সাল-সলনি কৰা হৈছে।", + "notification-header-watchlist-multiuser-created": "{{GENDER:$2|আপোনাৰ}} লক্ষ্য-তালিকাৰ <strong>$1</strong> নামৰ পৃষ্ঠাক $3 {{PLURAL:$3|বাৰ}} সৃষ্টি কৰা হৈছে।", + "notification-header-watchlist-multiuser-deleted": "{{GENDER:$2|আপোনাৰ}} লক্ষ্য-তালিকাৰ <strong>$1</strong> নামৰ পৃষ্ঠাক $3 {{PLURAL:$3|বাৰ}} বিলোপ কৰা হৈছে।", + "notification-header-watchlist-multiuser-moved": "{{GENDER:$2|আপোনাৰ}} লক্ষ্য-তালিকাৰ <strong>$1</strong> নামৰ পৃষ্ঠাক $3 {{PLURAL:$3|বাৰ}} স্থানান্তৰ কৰা হৈছে।", + "notification-header-watchlist-multiuser-restored": "{{GENDER:$2|আপোনাৰ}} লক্ষ্য-তালিকাৰ <strong>$1</strong> নামৰ পৃষ্ঠাক $3 {{PLURAL:$3|বাৰ}} পুনৰুদ্ধাৰ কৰা হৈছে।", + "notification-welcome-linktext": "আদৰিছোঁ!", + "notification-header-thank-you-1-edit": "{{GENDER:$2|আপুনি}} এইমাত্ৰ {{GENDER:$2|আপোনাৰ}} প্ৰথমটো সম্পাদনা কৰিলে; {{GENDER:$2|আপোনাক}} ধন্যবাদ আৰু আদৰিছোঁ!", + "notification-header-thank-you-10-edit": "{{GENDER:$2|আপুনি}} এইমাত্ৰ {{GENDER:$2|আপোনাৰ}} দশমটো সম্পাদনা কৰিলে; {{GENDER:$2|আপোনাক}} ধন্যবাদ, আৰু এয়া অব্যাহত ৰাখক!", + "notification-header-thank-you-100-edit": "{{GENDER:$2|আপুনি}} এইমাত্ৰ {{GENDER:$2|আপোনাৰ}} এশটা সম্পাদনা সম্পন্ন কৰিলে; {{GENDER:$2|আপোনাক}} অশেষ ধন্যবাদ!", + "notification-header-thank-you-1000-edit": "{{GENDER:$2|আপুনি}} এইমাত্ৰ {{GENDER:$2|আপোনাৰ}} এহেজাৰটা সম্পাদনা সম্পন্ন কৰিলে; এজন দুৰ্দান্ত বৰঙণিদাতা হোৱাৰ বাবে {{GENDER:$2|আপোনাক}} ধন্যবাদ!", + "notification-header-thank-you-10000-edit": "{{GENDER:$2|আপুনি}} এইমাত্ৰ {{GENDER:$2|আপোনাৰ}} দহ হেজাৰটা সম্পাদনা সম্পন্ন কৰিলে; {{GENDER:$2|আপোনাক}} অশেষ ধন্যবাদ!", + "notification-header-thank-you-100000-edit": "{{GENDER:$2|আপুনি}} এইমাত্ৰ {{GENDER:$2|আপোনাৰ}} এক লাখটা সম্পাদনা সম্পন্ন কৰিলে; এজন অসাধাৰণ বৰঙণিদাতা হোৱাৰ বাবে {{GENDER:$2|আপোনাক}} ধন্যবাদ!", + "notification-header-thank-you-1000000-edit": "{{GENDER:$2|আপুনি}} এইমাত্ৰ {{GENDER:$2|আপোনাৰ}} দহ লাখটা সম্পাদনা সম্পন্ন কৰিলে; এক আশ্চৰ্যজনক বৰঙণিৰ বাবে {{GENDER:$2|আপোনাক}} ধন্যবাদ!", + "notification-header-thank-you-10000000-edit": "{{GENDER:$2|আপুনি}} এইমাত্ৰ {{GENDER:$2|আপোনাৰ}} এক কোটিটা সম্পাদনা সম্পন্ন কৰিলে; আপোনাৰ অতুলনীয় কৰ্মনিষ্ঠাৰ বাবে {{GENDER:$2|আপোনাক}} অশেষ ধন্যবাদ!", + "notification-link-thank-you-edit": "{{GENDER:$1|আপোনাৰ}} সম্পাদনা", + "notification-link-text-view-edit": "সম্পাদনা চাওক", + "notification-link-article-reminder": "পৃষ্ঠা চাওক", + "notification-header-reverted": "<strong>$3</strong>ত কৰা আপোনাৰ {{PLURAL:$4|সম্পাদনা|সম্পাদনাসমূহ}} {{GENDER:$2|পূৰ্ববত কৰা হৈছে}}।", + "notification-header-emailuser": "$1-এ আপোনালৈ এটা ই-মেইল {{GENDER:$2|প্ৰেৰণ কৰিছে}}।", + "notification-edit-talk-page-email-subject2": "$1-এ {{GENDER:$3|আপোনালৈ}} {{SITENAME}}ত এটা বাৰ্তা {{GENDER:$2|দিছে}}।", + "notification-page-linked-email-subject": "{{GENDER:$3|আপুনি}} সৃষ্টি কৰা এটা পৃষ্ঠা {{SITENAME}}ত লিংক কৰা হৈছে।", + "notification-reverted-email-subject2": "{{SITENAME}}ত কৰা {{GENDER:$3|আপোনাৰ}} {{PLURAL:$4|সম্পাদনা|সম্পাদনাসমূহ}} {{GENDER:$2|পূৰ্ববত কৰা হৈছে}}", + "notification-mention-email-subject": "$1-এ {{GENDER:$3|আপোনাক}} {{SITENAME}}ত {{GENDER:$2|উল্লেখ কৰিছে}}।", + "notification-user-rights-email-subject": "{{SITENAME}}ত {{GENDER:$3|আপোনাৰ}} সদস্যৰ অধিকাৰ সলনি হৈছে।", + "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1 চে}}", + "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1 মি}}", + "notification-timestamp-ago-hours": "{{PLURAL:$1|$1 ঘণ্টা}}", + "notification-timestamp-ago-days": "{{PLURAL:$1|$1 দিন}}", + "notification-timestamp-ago-months": "{{PLURAL:$1|$1 মাহ}}", + "notification-timestamp-ago-years": "{{PLURAL:$1|$1 বছৰ}}", + "notification-timestamp-today": "আজি", + "notification-timestamp-yesterday": "কালি", + "notification-inbox-filter-read": "পঠিত", + "notification-inbox-filter-unread": "অপঠিত", + "notification-inbox-filter-all": "সকলো", + "echo-specialmute-label-mute-notifications": "এই {{GENDER:$1|সদস্যৰ}} জাননীসমূহ বন্ধ কৰক", + "echo-email-plain-footer": "আমি {{GENDER:$1|আপোনাক}} কোনবোৰ ই-মেইল প্ৰেৰণ কৰোঁ তাক নিয়ন্ত্ৰণ কৰিবলৈ {{GENDER:$1|আপোনাৰ}} পছন্দসমূহ চাওক:", + "echo-email-html-footer-preference-link-text": "{{GENDER:$1|আপোনাৰ}} পছন্দসমূহ চাওক", + "echo-email-html-footer-with-link": "আমি {{GENDER:$2|আপোনালৈ}} কোনবোৰ ই-মেইল প্ৰেৰণ কৰিম তাক নিয়ন্ত্ৰণ কৰিবলৈ, $1।", + "echo-notification-alert": "{{PLURAL:$1|বাৰ্তা ($1)|100=বাৰ্তা (৯৯+)}}", + "echo-notification-notice": "{{PLURAL:$1|জাননী ($1)|100=জাননী (৯৯+)}}", + "echo-notification-alert-text-only": "বাৰ্তা", + "echo-notification-notice-text-only": "জাননী", + "echo-overlay-link": "সকলো জাননী", + "echo-overlay-title": "<b>জাননী</b>", + "echo-mark-all-as-read": "সকলো পঠিত বুলি চিহ্নিত কৰক", + "echo-mark-all-as-read-confirmation": "$1টা {{PLURAL:$1|জাননী}} পঠিত বুলি চিহ্নিত কৰা হ'ল", + "echo-mark-wiki-as-read": "নিৰ্বাচিত ৱিকিত সকলোবোৰ পঠিত বুলি চিহ্নিত কৰক: $1", + "echo-displaysnippet-title": "নতুন জাননী", + "echo-date-today": "আজি", + "echo-date-yesterday": "কালি", + "notification-bundle-header-edit-user-talk-v2": "<strong>{{GENDER:$3|আপোনা}}ৰ আলোচনা পৃষ্ঠাত</strong> {{PLURAL:$1|এটা নতুন বাৰ্তা|$1টা নতুন বাৰ্তা|100=৯৯টাতকৈ অধিক নতুন বাৰ্তা}} আহিছে।", + "echo-email-batch-subject-daily": "আপোনাৰ বাবে {{SITENAME}}ত {{PLURAL:$2|এটা নতুন জাননী|নতুন জাননী}} আছে", + "echo-email-batch-subject-weekly": "এই সপ্তাহত আপোনাৰ বাবে {{SITENAME}}ত {{PLURAL:$2|এটা নতুন জাননী|নতুন জাননী}} আছে", + "echo-email-batch-body-intro-daily": "প্ৰিয় $1,\nইয়াত আপোনাৰ বাবে {{SITENAME}}ত আজিৰ কাৰ্যকলাপৰ সাৰাংশ দিয়া হৈছে।", + "echo-email-batch-body-intro-weekly": "প্ৰিয় $1,\nইয়াত আপোনাৰ বাবে {{SITENAME}}ত এই সপ্তাহৰ কাৰ্যকলাপৰ সাৰাংশ দিয়া হৈছে।", + "echo-email-batch-link-text-view-all-notifications": "সকলো জাননী চাওক", + "notification-header-foreign-alert": "{{PLURAL:$5|আন ৱিকিৰ|$5টা আন ৱিকিৰ}} পৰা অধিক বাৰ্তা", + "notification-header-foreign-notice": "{{PLURAL:$5|আন ৱিকিৰ|$5টা আন ৱিকিৰ}} পৰা অধিক জাননী", + "notification-header-foreign-all": "{{PLURAL:$5|আন ৱিকিৰ|$5টা আন ৱিকিৰ}} পৰা অধিক জাননী", + "right-manage-all-push-subscriptions": "সকলো পুছ চাবস্ক্ৰিপশ্বন ব্যৱস্থাপনা কৰক", + "action-manage-all-push-subscriptions": "সকলো পুছ চাবস্ক্ৰিপশ্বন ব্যৱস্থাপনা কৰক", + "group-push-subscription-manager": "পুছ চাবস্ক্ৰিপশ্বন ব্যৱস্থাপক", + "group-push-subscription-manager-member": "{{GENDER:$1|পুছ চাবস্ক্ৰিপশ্বন ব্যৱস্থাপক}}", + "grouppage-push-subscription-manager": "{{ns:project}}:পুছ চাবস্ক্ৰিপশ্বন ব্যৱস্থাপক" } diff --git a/Echo/i18n/ast.json b/Echo/i18n/ast.json index 8e4cd300..ad9f5da7 100644 --- a/Echo/i18n/ast.json +++ b/Echo/i18n/ast.json @@ -2,6 +2,7 @@ "@metadata": { "authors": [ "Macofe", + "Tokvo", "Xuacu" ] }, @@ -167,7 +168,7 @@ "notification-inbox-filter-read": "Lleer", "notification-inbox-filter-unread": "Non lleíes", "notification-inbox-filter-all": "Toes", - "echo-specialmute-label-mute-notifications": "Silenciar los avisos d'esti usuariu", + "echo-specialmute-label-mute-notifications": "Silenciar los avisos d'{{GENDER:$1|esti usuariu|esta usuaria}}", "echo-email-plain-footer": "Para controlar qué correos electrónicos {{GENDER:$1|t}}'unviamos, revisa les {{GENDER:$1|tos}} preferencies:", "echo-email-html-footer-preference-link-text": "comprueba les {{GENDER:$1|tos}} preferencies", "echo-email-html-footer-with-link": "Pa controlar qué mensaxes de corréu electrónicu {{GENDER:$2|t'unviamos}}, $1.", diff --git a/Echo/i18n/av.json b/Echo/i18n/av.json index cc8543e5..7bba6ed8 100644 --- a/Echo/i18n/av.json +++ b/Echo/i18n/av.json @@ -1,8 +1,8 @@ { "@metadata": { "authors": [ - "Gazimagomedov" + "Omarov M." ] }, - "echo-new-messages": "Духъе цIиял кагътал руго" + "echo-new-messages": "Духъе цӀиял ругьелал руго" } diff --git a/Echo/i18n/az.json b/Echo/i18n/az.json index 795b65d9..351456d5 100644 --- a/Echo/i18n/az.json +++ b/Echo/i18n/az.json @@ -4,19 +4,22 @@ "Dağlı95", "Interfase", "Khan27", + "NMW03", "Serkanland", "Toghrul Rahimli", + "Turkmen", "Vesely35", "Wertuose", "Zoranzoki21" ] }, - "echo-desc": "Bildiriş sistemi", + "echo-desc": "İstifadəçilərə hadisələr və mesajlar barədə məlumat vermə sistemi", "prefs-echo": "Bildirişlər", "prefs-emailsettings": "Elektron poçtun parametrləri", "prefs-echosubscriptions": "Bu hadisələr barədə mənə bildiriş göndərilsin", "prefs-echocrosswiki": "Digər vikilərdən bildirişlər", "prefs-blocknotificationslist": "Səssizə alınmış istifadəçilər", + "prefs-mutedpageslist": "Səhifə keçidi bildirişləri səssizə alınmış səhifələr", "echo-mobile-notifications-filter-title": "Bildirişlərin süzgəci", "echo-pref-send-me": "Mənə göndər:", "echo-pref-send-to": "Göndər", @@ -32,18 +35,20 @@ "echo-pref-email-format-plain-text": "Sadə mətn", "echo-pref-cross-wiki-notifications": "Digər vikipediyalardan bildirişləri göstər", "echo-pref-notifications-blacklist": "Bu istifadəçilərdən gələn bildirişləri göstərmə. ([[mw:Special:MyLanguage/Help:Notifications#mute|daha ətraflı]])", + "echo-pref-notifications-page-linked-title-muted-list": "Bu səhifələrdə \"Səhifə keçidləri\" bildirişlərini göstərmə. ([[mw:Special:MyLanguage/Help:Notifications#mute|daha ətraflı]])", "echo-learn-more": "Daha ətraflı", - "echo-new-messages": "Yeni mesajlarınız var", + "echo-log": "Public log\nBütün qeydlər", + "echo-new-messages": "Müzakirə səhifənizdə yeni mesajınız var", "echo-category-title-edit-user-talk": "Müzakirə səhifəsi {{PLURAL:$1|mesajı|mesajları}}", "echo-category-title-article-linked": "Səhifəyə {{PLURAL:$1|keçid|keçidlər}}", - "echo-category-title-reverted": "Redaktələrin geri qaytarılması", + "echo-category-title-reverted": "Redaktələrin {{PLURAL:$1|geri qaytarılması}}", "echo-category-title-mention": "{{PLURAL:$1|Ad qeydetmə|Ad qeydetmələri}}", "echo-category-title-mention-failure": "Uğursuz {{PLURAL:$1|ad qeydetmə|ad qeydetmələr}}", "echo-category-title-mention-success": "Uğurlu {{PLURAL:$1|ad qeydetmə|ad qeydetmələr}}", "echo-category-title-other": "{{PLURAL:$1|Digər}}", "echo-category-title-system": "{{PLURAL:$1|Sistem}}", "echo-category-title-user-rights": "{{PLURAL:$1|İstifadəçi hüquqları dəyişikliyi|İstifadəçi hüquqları dəyişiklikləri}}", - "echo-category-title-emailuser": "{{PLURAL:$1|Başqa istifadəçidən gələn elektron məktub|Başqa istifadəçilərdən gələn elektron məktublar}}", + "echo-category-title-emailuser": "{{PLURAL:$1|Başqa istifadəçidən gələn e-məktub|Başqa istifadəçilərdən gələn e-məktublar}}", "echo-category-title-thank-you-edit": "Əlamətdar {{PLURAL:$1|redaktə|redaktələr}}", "echo-pref-tooltip-edit-user-talk": "Müzakirəmə səhifəm redaktə olunduğunda mənə bildiriş göndər.", "echo-pref-tooltip-article-linked": "Başqa səhifədən yaratdığım səhifəyə keçid verildikdə mənə bildiriş göndər.", @@ -71,29 +76,38 @@ "notification-link-text-collapse-all": "Bağla", "notification-link-text-view-message": "Məktuba bax", "notification-link-text-view-mention": "Qeydə bax", - "notification-link-text-view-changes": "Dəyişikliklərə bax", + "notification-link-text-view-changes": "Dəyişikliklərə {{GENDER:$1|bax}}", "notification-link-text-view-page": "Səhifəyə bax", - "notification-header-edit-user-talk": "$1 <strong>müzakirə {{GENDER:$3|səhifənizə}}</strong> bir mesaj {{GENDER:$2|qoyub}}.", - "notification-header-edit-user-talk-with-section": "[[User:$1|$1]] müzakirə səhifənizdə \"[[User talk:$2#$3|$4]]\" başlıqlı mesaj {{GENDER:$1|qoyub}}.", + "notification-header-edit-user-talk": "$1 <strong>müzakirə {{GENDER:$3|səhifənizə}}</strong> mesaj {{GENDER:$2|qoyub}}.", + "notification-header-edit-user-talk-with-section": "$1 <strong>müzakirə {{GENDER:$3|səhifənizdə}}</strong> \"<strong>$4</strong>\" bölməsində bir mesaj {{GENDER:$2|yazıb}}.", + "notification-compact-header-edit-user-talk": "$1 {{GENDER:$3|sənə}} mesaj {{GENDER:$2|yazıb.}}", + "notification-compact-header-edit-user-talk-with-section": "$1 {{GENDER:$3|sənə}} \"<strong>$4</strong>\" adlı yerdə mesaj {{GENDER:$2|yazıb.}}", "notification-header-page-linked": "<strong>$4</strong> səhifəsindən <strong>$3</strong> səhifəsinə keçid verildi.", "notification-bundle-header-page-linked": "{{PLURAL:$5||$5 səhifə|100=99+ səhifə}}dən <strong>$3</strong> səhifəsinə keçid verildi.", "notification-link-text-what-links-here": "Bu səhifəyə olan bütün keçidlər", "notification-header-mention-other": "$1 {{GENDER:$3|sizi}} <strong>$4</strong> səhifəsinin \"<strong>$5</strong>\" bölməsində {{GENDER:$2|qeyd etdi}}.", "notification-header-mention-other-nosection": "$1 {{GENDER:$3|sizi}} <strong>$4</strong> səhifəsində {{GENDER:$2|qeyd etdi}}.", - "notification-header-mention-user-talkpage-v2": "$1 {{GENDER:$3|sizi}} <strong> $4 adlı {{GENDER:$5|istifadəçinin}} müzakirə səhifəsindəki</strong> \"<strong>$6</strong>\" bölməsində qeyd etdi.", + "notification-header-mention-user-talkpage-v2": "$1 {{GENDER:$3|sizi}} <strong>$4 adlı {{GENDER:$5|istifadəçinin}} müzakirə səhifəsinin \"<strong>$6</strong>\" bölməsində </strong> {{GENDER:$2|qeyd etdi}}.", "notification-header-mention-user-talkpage-nosection": "$1 {{GENDER:$3|sizi}} <strong>$4 adlı {{GENDER:$5|istifadəçinin}} müzakirə səhifəsində</strong> {{GENDER:$2|qeyd etdi}}.", - "notification-header-mention-agent-talkpage": "$1 {{GENDER:$3|sizi}} <strong>öz müzakirə səhifəsindəki</strong> \"<strong>$4</strong>\" bölməsində qeyd etdi.", - "notification-header-mention-agent-talkpage-nosection": "$1 {{GENDER:$3|sizi}} <strong>öz müzakirə səhifəsində</strong> qeyd etdi.", + "notification-header-mention-agent-talkpage": "$1 {{GENDER:$3|sizi}} <strong>{{GENDER:$2|öz}} müzakirə səhifəsinin</strong> \"<strong>$4</strong>\" bölməsində qeyd etdi.", + "notification-header-mention-agent-talkpage-nosection": "$1 {{GENDER:$3|sizi}} <strong>{{GENDER:$2|öz}} müzakirə səhifəsində</strong> qeyd etdi.", "notification-header-mention-article-talkpage": "$1 {{GENDER:$3|sizi}} <strong>$4</strong> müzakirə səhifəsinin \"<strong>$5</strong>\" bölməsində {{GENDER:$2|qeyd etdi}}.", "notification-header-mention-article-talkpage-nosection": "$1 {{GENDER:$3|sizi}} <strong>$4</strong> müzakirə səhifəsində {{GENDER:$2|qeyd etdi}}.", - "notification-header-mention-failure-user-unknown": "<strong>$3</strong> adlı istifadəçi mövcud olmadığından qeyd etmə uğursuz oldu.", - "notification-header-mention-failure-user-anonymous": "<strong>$3</strong> adlı istifadəçi anonim olduğundan qeyd etmə uğursuz oldu.", + "notification-header-mention-failure-user-unknown": "<strong>$3</strong> adlı istifadəçi mövcud olmadığından istifadəçini işarələmə uğursuz oldu.", + "notification-header-mention-failure-user-anonymous": "<strong>$3</strong> adlı istifadəçi anonim olduğundan istifadəçini işarələmə uğursuz oldu.", "notification-header-mention-success": "{{GENDER:$2|Siz}} <strong>$3</strong> adlı istifadəçini qeyd etdiniz.", "notification-header-welcome": "{{SITENAME}} saytına {{GENDER:$2|xoş gəldiniz}}, $1! Sizi burada görməyimizə çox şadıq!", "notification-header-mention-summary": "$1 {{GENDER:$3|sizi}} <strong>$4</strong> səhifəsinin qısa məzmununda {{GENDER:$2|qeyd etdi}}.", + "notification-header-thank-you-1-edit": "İlk {{GENDER:$2|redaktənizi}} {{GENDER:$2|etdiniz}}; təşəkkürlər və xoş gəlmişsiniz!", + "notification-header-thank-you-10-edit": "Onuncu {{GENDER:$2|redaktəni}} {{GENDER:$2|etdin}}, {{GENDER:$2|təşəkkürlər}}! Sükanı belə saxla!", + "notification-header-thank-you-100-edit": "Yüzüncü {{GENDER:$2|redaktənizi}} {{GENDER:$2|etdiniz}}; {{GENDER:$2|təşəkkürlər}}!", + "notification-header-thank-you-1000-edit": "Mininci {{GENDER:$2|redaktəni}} {{GENDER:$2|etdin}}, möhtəşəm töhfələrinə görə {{GENDER:$2|təşəkkürlər}}!", + "notification-header-thank-you-10000-edit": "On mininci {{GENDER:$2|redaktəni}} {{GENDER:$2|etdin}}, çox {{GENDER:$2|sağol}}!", + "notification-header-thank-you-100000-edit": "Yüz mininci {{GENDER:$2|redaktəni}} {{GENDER:$2|etdin}}, möhtəşəm töhfələrinə görə {{GENDER:$2|təşəkkürlər}}!", + "notification-header-thank-you-1000000-edit": "Bir milyonuncu {{GENDER:$2|redaktəni}} {{GENDER:$2|etdin}}, möhtəşəm töhfələrinə görə {{GENDER:$2|təşəkkürlər}}!", "notification-link-text-view-edit": "Redaktəyə bax", - "notification-edit-talk-page-email-subject2": "İstifadəçi $1 \"{{SITENAME}}\" saytındakı müzakirə səhifənizdə sizə mesaj yazıb", - "notification-mention-email-subject": "{{GENDER:$2|İstifadəçi}} sizi «{{SITENAME}}» səhifəsində $1 {{GENDER:$2|qeyd etdi}}", + "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$3|sənə}} {{SITENAME}} saytında mesaj {{GENDER:$2|yazıb.}}", + "notification-mention-email-subject": "$1 {{GENDER:$3|sizi}} {{SITENAME}} saytında {{GENDER:$2|qeyd etdi}}.", "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1 sn}}", "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1 dq}}", "notification-timestamp-ago-hours": "{{PLURAL:$1|$1 st}}", @@ -105,8 +119,8 @@ "notification-inbox-filter-read": "Oxunmuş", "notification-inbox-filter-unread": "Oxunmamış", "notification-inbox-filter-all": "Hamısı", - "echo-specialmute-label-mute-notifications": "Bundan gələn bildirişləri səssizləşdirin {{GENDER:$1|istifadəçi}}", - "echo-email-html-footer-preference-link-text": "nizamlamalarınızı nəzərdən keçirin.", + "echo-specialmute-label-mute-notifications": "Bu {{GENDER:$1|istifadəçidən}} gələn bildirişləri səssizləşdirin", + "echo-email-html-footer-preference-link-text": "{{GENDER:$1|nizamlamalarınızı}} nəzərdən keçirin.", "echo-email-html-footer-with-link": "{{GENDER:$2|Sizə}} hansı e-meylləri göndərdiyimizə nəzarət etmək üçün $1.", "echo-notification-alert": "{{PLURAL:$1|Xəbərdarlıq ($1)|Xəbərdarlıqlar ($1)|100=Xəbərdarlıqlar (99+)}}", "echo-notification-notice": "{{PLURAL:$1|Bildiri. ($1)|Bildirişlər ($1)|100=Bildirişlər (99+)}}", @@ -119,8 +133,10 @@ "echo-mark-wiki-as-read": "$1da hamısını oxunmuş kimi qeyd et", "echo-date-today": "Bu gün", "echo-date-yesterday": "Dünən", + "notification-bundle-header-edit-user-talk-v2": "<strong>Müzakirə {{GENDER:$3|səhifəndə}}</strong> $1 yeni mesaj var.", "echo-email-batch-subject-daily": "Sizin {{SITENAME}}-da {{PLURAL:$2|yeni bildiriş|yeni bildirişləriniz|}} var", "echo-email-batch-subject-weekly": "Sizin bu həftə {{SITENAME}}-da {{PLURAL:$2|yeni bildiriş|yeni bildirişləriniz|}} var", "echo-email-batch-link-text-view-all-notifications": "Bütün bildirişlərə bax", + "notification-header-foreign-notice": "{{PLURAL:$5|Başqa vikidən|$5 başqa vikidən}} bildirişlər", "notification-header-foreign-all": "Digər {{PLURAL:$5|vikidən|$5 vikidən}} bildirişlər" } diff --git a/Echo/i18n/azb.json b/Echo/i18n/azb.json index daa01624..72fd9e9d 100644 --- a/Echo/i18n/azb.json +++ b/Echo/i18n/azb.json @@ -34,6 +34,7 @@ "tooltip-pt-notifications-notice": "بیلدیریلرینیز", "echo-specialpage": "بیلدیریلر", "echo-specialpage-pagefilters-title": "سوْن چالیشمالار", + "echo-specialpage-pagefilters-subtitle": "اوْخونمامیش بیلدیریلری اوْلان صفحهلر", "echo-none": "سیزین بیلدیرینیز یوخدور.", "notification-link-text-view-changes": "دییشیکلره {{GENDER:$1|باخ}}", "notification-header-edit-user-talk-with-section": "$1 <strong>{{GENDER:$3|سیزین}} دانیشیق صفحهنیزین \"</strong>$4\"<strong>-ده </strong> بیر مساژ {{GENDER:$2|یازیبدیر}}.", diff --git a/Echo/i18n/ban-bali.json b/Echo/i18n/ban-bali.json new file mode 100644 index 00000000..5266af99 --- /dev/null +++ b/Echo/i18n/ban-bali.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Chinamoonroll" + ] + }, + "notification-inbox-filter-read": "ᬯᬘᬾᬦ᭄" +} diff --git a/Echo/i18n/ban.json b/Echo/i18n/ban.json index 81f9a58d..74eebb8e 100644 --- a/Echo/i18n/ban.json +++ b/Echo/i18n/ban.json @@ -1,8 +1,47 @@ { "@metadata": { "authors": [ + "Carma Citrawati", + "Chinamoonroll", "Luh Gede Krismayanti" ] }, - "tooltip-pt-notifications-alert": "Atur piuning {{GENDER:|ragané}}" + "echo-desc": "Sistem pambiwara majeng sang anganggé indik séwala miwah paristiwa", + "prefs-echo": "Pakélingan", + "prefs-emailsettings": "Opsi rerepél", + "prefs-echosubscriptions": "Biwara titiang indik paristiwa puniki", + "prefs-echocrosswiki": "Pambiwara antarwiki", + "prefs-blocknotificationslist": "Sang anganggé kamenengang.", + "echo-pref-web": "Wéb", + "echo-pref-email": "Rerepél", + "echo-pref-push": "Aplikasi", + "echo-pref-email-format-html": "HTML", + "echo-pref-email-format-plain-text": "Suratan polos", + "echo-pref-cross-wiki-notifications": "Sinahang pambiwara saking wiki liyanan", + "echo-learn-more": "Pelajahin sajangkepné", + "echo-new-messages": "Ragané madué séwala Pabligbagan anyar", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|uah}} ring kaca pabligbagan tiangé", + "echo-category-title-article-linked": "{{PLURAL:$1|Pranala}} kaca", + "echo-category-title-other": "{{PLURAL:$1|Liyanan}}", + "echo-category-title-system": "{{PLURAL:$1|Sistem}}", + "echo-category-title-system-noemail": "{{PLURAL:$1|Sistem}}", + "echo-category-title-system-emailonly": "{{PLURAL:$1|Sistem}}", + "echo-category-title-article-reminder": "Kaca {{PLURAL:$1|pikelingan}}", + "notifications": "Pakélingan", + "tooltip-pt-notifications-alert": "Atur piuning {{GENDER:|ragané}}", + "echo-displaynotificationsconfiguration-notifications-by-category-header": "Pakelingan olih kategori", + "echo-specialpage-section-markread": "Cihna seka dados kawacén", + "echo-specialpage-markasread": "Pambiwara: Cihna dados kawacén", + "echo-specialpage-pagination-range": "$1 - $2", + "notificationsmarkread-legend": "Cihna pambiwara dados kawacén", + "echo-notification-markasread": "Cihna dados kawacén", + "echo-notification-markasunread": "Cihna dados durung kawacén", + "echo-notification-markasread-tooltip": "Cihna dados kawacén", + "notification-link-text-view-message": "Cingak séwala", + "notification-welcome-linktext": "Rahajeng rauh", + "notification-timestamp-yesterday": "Dibi", + "notification-inbox-filter-read": "Wacén", + "echo-mark-all-as-read": "Cihna makasami dados kawacén", + "echo-mark-all-as-read-confirmation": "$1 {{PLURAL:$1|pambiwara}} sampun kacihna dados kawacén", + "echo-date-yesterday": "Dibi" } diff --git a/Echo/i18n/be-tarask.json b/Echo/i18n/be-tarask.json index c2be2966..f7bc17d4 100644 --- a/Echo/i18n/be-tarask.json +++ b/Echo/i18n/be-tarask.json @@ -32,8 +32,8 @@ "echo-pref-notifications-page-linked-title-muted-list": "Не паказваць паведамленьні «Спасылкі на старонку» для гэтых старонак ([[mw:Special:MyLanguage/Help:Notifications#mute|даведацца болей]]).", "echo-learn-more": "Даведацца болей", "echo-log": "Публічны журнал", - "echo-new-messages": "Вы маеце новыя паведамленьні", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|1=Паведамленьне|Паведамленьні}} ў гутарках", + "echo-new-messages": "Вы маеце новае паведамленьне на старонцы гутарак", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|1=Зьмена|Зьмены|Зьменаў}} на маёй старонцы гутарак", "echo-category-title-article-linked": "{{PLURAL:$1|1=Спасылка|Спасылкі}} на старонку", "echo-category-title-reverted": "{{PLURAL:$1|1=Адкат рэдагаваньня|Адкаты рэдагаваньняў}}", "echo-category-title-mention": "{{PLURAL:$1|1=Згадваньне|Згадваньні}}", @@ -46,7 +46,7 @@ "echo-category-title-emailuser": "{{PLURAL:$1|1=Ліст электроннай пошты ад іншага ўдзельніка|Лісты электроннай пошты ад іншых удзельнікаў}}", "echo-category-title-article-reminder": "{{PLURAL:$1|напамін з старонкі|напаміны з старонак}}", "echo-category-title-thank-you-edit": "{{PLURAL:$1|Дасягненьне|Дасягненьні}} рэдагаваньняў", - "echo-pref-tooltip-edit-user-talk": "Паведамляць, калі нехта пакідае паведамленьне або адказ на маёй старонцы гутарак.", + "echo-pref-tooltip-edit-user-talk": "Паведамляць, калі нехта пакідае рэдагуе маю старонку гутарак.", "echo-pref-tooltip-article-linked": "Паведамляць, калі нехта спасылаецца на створаную мной старонку зь іншай старонкі.", "echo-pref-tooltip-reverted": "Паведамляць, калі нехта адмяняе зробленую мной праўку з дапамогай функцыі адмены ці адкату.", "echo-pref-tooltip-mention": "Паведамляць, калі нехта спасылаецца на маю старонку ўдзельніка.", diff --git a/Echo/i18n/be.json b/Echo/i18n/be.json index ca7daabc..d56ad006 100644 --- a/Echo/i18n/be.json +++ b/Echo/i18n/be.json @@ -2,24 +2,35 @@ "@metadata": { "authors": [ "Artsiom91", + "Chadyka", "Macofe", "Matěj Suchánek", "Mikalai Udodau", + "No Sleep till Krupki", + "Tomato Cream", + "ZlyiLev", "Дзяніс Тутэйшы", "Чаховіч Уладзіслаў" ] }, "echo-desc": "Сістэма апавяшчэння ўдзельнікаў пра падзеі і паведамленні", "prefs-echo": "Паведамленні", - "prefs-emailsettings": "Настройкі эл. пошты", + "prefs-description-echo": "Выберыце, якія апавяшчэнні {{GENDER:|вы}} будзеце атрымліваць і як іх атрымліваць.", + "prefs-emailsettings": "Параметры эл. пошты", "prefs-echosubscriptions": "Паведамляць мне пра гэтыя падзеі", "prefs-echocrosswiki": "Паведамленні з некалькіх вікі-праектаў («крос-вікі»)", "prefs-blocknotificationslist": "Адключаныя ўдзельнікі", - "echo-pref-send-me": "Дасылаць мне:", + "prefs-mutedpageslist": "Старонкі з заглушанымі паведамленнямі пра спасылкі на старонкі", + "prefs-echopollupdates": "Жывыя апавяшчэнні", + "echo-mobile-notifications-filter-title": "Фільтр апавяшчэнняў", + "echo-pref-show-poll-updates": "Паказваць новыя апавяшчэнні па меры іх паступлення", + "echo-pref-show-poll-updates-help": "Паказваць колькасць не прачытаных апавяшчэнняў у радку загалоўка і фрагмент кожнага апавяшчэння адразу, калі яно прыходзіць.", + "echo-pref-send-me": "Даслаць мне:", "echo-pref-send-to": "Дасылаць да:", "echo-pref-email-format": "Фармат e-mail:", "echo-pref-web": "Праз сайт", "echo-pref-email": "Эл.пошта", + "echo-pref-push": "Дадаткі", "echo-pref-email-frequency-never": "Не дасылаць мне паведамленні па эл. пошце", "echo-pref-email-frequency-immediately": "Асобныя паведамленні па меры іх паступлення", "echo-pref-email-frequency-daily": "Штодзённы агляд паведамленняў", @@ -28,10 +39,12 @@ "echo-pref-email-format-plain-text": "Просты тэкст", "echo-pref-cross-wiki-notifications": "Паказваць паведамленні з іншых вікі-праектаў", "echo-pref-notifications-blacklist": "Не паказваць паведамленні ад гэтых удзельнікаў ([[mw:Special:MyLanguage/Help:Notifications#mute|даведацца больш]]):", + "echo-pref-notifications-page-linked-title-muted-list": "Не паказваць паведамленні «Спасылкі на старонку» для гэтых старонак ([[mw:Special:MyLanguage/Help:Notifications#mute|даведацца болей]]).", + "echo-pref-dont-email-read-notifications": "Не ўключаць прачытаныя апавяшчэнні ў зводкі па эл. пошце", "echo-learn-more": "Даведацца больш", "echo-log": "Агульнадаступны журнал", - "echo-new-messages": "У Вас ёсць новыя паведамленні", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|паведамленне|паведамленні}} на старонцы размоў", + "echo-new-messages": "У вас ёсць новае паведамленне на старонцы размовы", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|1=Змена|Змены}} на маёй старонцы размоў", "echo-category-title-article-linked": "{{PLURAL:$1|спасылка|спасылкі}} на старонкі", "echo-category-title-reverted": "{{PLURAL:$1|адмена|адмены}} правак", "echo-category-title-mention": "{{PLURAL:$1|Згадванне|Згадванні}}", @@ -40,11 +53,15 @@ "echo-category-title-other": "{{PLURAL:$1|Іншае|Іншыя}}", "echo-category-title-system": "{{PLURAL:$1|Сістэмнае|Сістэмныя}}", "echo-category-title-system-noemail": "{{PLURAL:$1|Сістэмныя}}", + "echo-category-title-system-emailonly": "{{PLURAL:$1|Сістэмнае|Сістэмныя}}", "echo-category-title-user-rights": "{{PLURAL:$1|Змяненне доступаў удзельніка|Змяненні доступаў удзельніка}}", "echo-category-title-emailuser": "{{PLURAL:$1|1=Ліст электроннай пошты ад іншага ўдзельніка|Лісты электроннай пошты ад іншых удзельнікаў}}", + "echo-category-title-article-reminder": "{{PLURAL:$1|Напамін з старонкі|Напаміны з старонак}}", "echo-category-title-thank-you-edit": "{{PLURAL:$1|Дасягненне|Дасягненні}} ў праўках", - "echo-pref-tooltip-edit-user-talk": "Паведамляць мне, калі хтосьці пакідае паведамленне ці адказвае на маёй старонцы размоў.", - "echo-pref-tooltip-article-linked": "Паведамляць мне, калі хтосьці спасылаецца ў артыкулах на створаную мной старонку", + "echo-category-title-watchlist": "Праўка на назіранай старонцы", + "echo-category-title-minor-watchlist": "Дробная праўка на назіранай старонцы", + "echo-pref-tooltip-edit-user-talk": "Паведамляць мне, калі хтосьці правіць маю старонку размоў.", + "echo-pref-tooltip-article-linked": "Паведамляць мне, калі хтосьці спасылаецца на створаную мной старонку з іншай старонкі", "echo-pref-tooltip-reverted": "Паведамляць мне, калі хтосьці адмяніў маю праўку, выкарыстаўшы функцыю адмены ці адкату.", "echo-pref-tooltip-mention": "Паведамляць мне, калі хтосьці высылаецца на маю старонку ўдзельніка.", "echo-pref-tooltip-mention-failure": "Паведамляць мне, калі я не магу адправіць камусьці згадванне.", @@ -53,54 +70,110 @@ "echo-pref-tooltip-emailuser": "Паведамляць мне, калі нехта шле мне ліст электроннай поштай.", "echo-pref-tooltip-article-reminder": "Паведаміць мне аб гэтай старонцы, калі я папрашу.", "echo-pref-tooltip-thank-you-edit": "Паведамляць пра дасягненне мной 1-й, 10-й, 100-й... праўкі.", + "echo-pref-tooltip-watchlist": "Паведамляйце мне, калі хтосьці робіць (нядробную) праўку на старонцы ў маім спісе назірання.", + "echo-pref-tooltip-minor-watchlist": "Паведамляйце мне, калі хтосьці робіць дробную праўку на старонцы ў маім спісе назірання.", "notifications": "Паведамленні", "tooltip-pt-notifications-alert": "{{GENDER:|Вашы}} апавяшчэнні", "tooltip-pt-notifications-notice": "{{GENDER:|Вашы}} апавяшчэнні", + "echo-displaynotificationsconfiguration": "Паказаць налады Апавяшчэнняў", + "echo-displaynotificationsconfiguration-summary": "Гэта агляд наладаў Апавяшчэнняў у гэтай вікі.", + "echo-displaynotificationsconfiguration-notifications-by-category-header": "Апавяшчэнні паводле катэгорыяў", + "echo-displaynotificationsconfiguration-sorting-by-section-header": "Сартаванне паводле тыпаў", + "echo-displaynotificationsconfiguration-sorting-by-section-legend": "У які раздзел сартуецца кожны тып апавяшчэння", + "echo-displaynotificationsconfiguration-available-notification-methods-header": "Дазволеныя спосабы апавяшчэнняў", + "echo-displaynotificationsconfiguration-available-notification-methods-by-category-legend": "Якія спосабы апавяшчэнняў падтрымліваюцца ў кожнай катэгорыі", + "echo-displaynotificationsconfiguration-enabled-default-header": "Уключана па змaўчанні", + "echo-displaynotificationsconfiguration-enabled-default-existing-users-legend": "Існыя ўдзельнікі", "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "Новыя ўдзельнікі", + "echo-displaynotificationsconfiguration-mandatory-notification-methods-header": "Абавязковыя спосабы апавяшчэнняў", + "echo-displaynotificationsconfiguration-mandatory-notification-methods-by-category-legend": "Якія спосабы апавяшчэнняў абавязковыя для кожнай катэгорыі", "echo-specialpage": "Паведамленні", "echo-specialpage-section-markread": "Пазначыць групу як прачытаную", + "echo-specialpage-markasread": "Апавяшчэнне: Пазначыць як прачытанае", + "echo-specialpage-markasread-invalid-id": "Няслушны ідэнтыфікатар падзеі", + "echo-specialpage-pagefilterwidget-aria-label": "Фільтраваць па вікі і назве старонкі", + "echo-specialpage-special-help-menu-widget-aria-label": "Дадатковыя параметры і налады Апавяшчэнняў.", "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|апавяшчэнне|апавяшчэнні|апавяшчэнняў}}", "echo-specialpage-pagefilters-title": "Нядаўняя актыўнасць", "echo-specialpage-pagefilters-subtitle": "Старонкі з непрагледжанымі апавяшчэннямі", "notificationsmarkread-legend": "Пазначыць апавяшчэнні як прачытаныя", "echo-none": "Вы не атрымлівалі паведамленняў.", - "echo-api-failure": "Немагчыма атрымаць апавяшчэнні. Калі ласка, паспрабуйце яшчэ раз. (Памылка $1)", + "echo-api-failure": "Немагчыма атрымаць апавяшчэнні.", "echo-api-failure-cross-wiki": "Доступ к аддаленаму дамену забаронены.", "echo-notification-placeholder": "Няма апавяшчэнняў.", "echo-notification-placeholder-filters": "Няма апавяшчэнняў, якія адпавядаюць уведзеным крытэрыям.", "echo-notification-loginrequired": "Вы павінны ўвайсці, каб пабачыць паведамленні.", + "echo-notification-popup-loginrequired": "Калі ласка, увайдзіце, каб пабачыць вашыя апавяшчэнні.", "echo-notification-markasread": "Адзначыць як прачытанае", "echo-notification-markasunread": "Адзначыць як нечытанае", "echo-notification-markasread-tooltip": "Адзначыць як прачытанае", + "echo-notification-more-options-tooltip": "Больш магчымасцей", + "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|Адключыць}} апавяшчэнні аб спасылках на старонку «$1»", + "notification-dynamic-actions-mute-page-linked-confirmation": "Апавяшчэнні пра «Спасылкі на старонкі» цяпер адключаны для старонкі «$1»", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|Вы}} можаце кіраваць вашымі прыглушанымі старонкамі [$1 ў вашых наладах] у любы час.", + "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2|Уключыць}} апавяшчэнні аб спасылках на старонку «$1»", + "notification-dynamic-actions-unmute-page-linked-confirmation": "Апавяшчэнні пра «Спасылкі на старонкі» цяпер уключаны для старонкі «$1»", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|Вы}} можаце кіраваць вашымі прыглушанымі старонкамі [$1 ў вашых наладах] у любы час.", + "notification-dynamic-actions-unwatch": "{{GENDER:$3|Не}} сачыць за новымі падзеямі на старонцы «$1»", + "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3|Вы}} больш не назіраеце за старонкай «$1»", + "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|Вы}} можаце пачаць назіраць за [$2 гэтай старонкай] у любы час.", + "notification-dynamic-actions-watch": "{{GENDER:$3|Сачыць}} за новымі падзеямі на старонцы «$1»", + "notification-dynamic-actions-watch-confirmation": "Цяпер {{GENDER:$3|вы}} назіраеце за старонкай «$1»", + "notification-dynamic-actions-watch-confirmation-description": "{{GENDER:$3|Вы}} можаце спыніць назіранне за [$2 гэтай старонкай] у любы час.", "notification-link-text-expand-all": "Разгарнуць", "notification-link-text-expand-alert-count": "Паказаць {{PLURAL:$1|$1 папярэджанне|$1 папярэджанні|$1 папярэджанняў}}", "notification-link-text-expand-notice-count": "Паказаць {{PLURAL:$1|$1 паведамленне|$1 паведамленні|$1 паведамленняў}}", - "notification-link-text-expand-all-count": "Разгарнуць {{PLURAL:$1|$1 апавяшчэнне|$1 апавяшчэнні|$1 апавяшчэнняў}}", + "notification-link-text-expand-all-count": "Паказаць {{PLURAL:$1|$1 апавяшчэнне|$1 апавяшчэнні|$1 апавяшчэнняў}}", "notification-link-text-collapse-all": "Згарнуць", "notification-link-text-view-message": "Прагляд паведамленняў", "notification-link-text-view-mention": "Прагляд згадкі", + "notification-link-text-view-mention-failure": "Праглядзець {{PLURAL:$1|1=згадку|згадкі}}", "notification-link-text-view-changes": "{{GENDER:$1|Прагляд}} змен", "notification-link-text-view-page": "Прагляд старонкі", "notification-header-edit-user-talk": "$1 {{GENDER:$2|пакінуў|пакінула}} паведамленне на <strong>{{GENDER:$3|вашай}} старонцы размоў</strong>.", "notification-header-edit-user-talk-with-section": "$1 {{GENDER:$2|пакінуў|пакінула}} паведамленне на <strong>{{GENDER:$3|вашай}} старонцы размоў</strong> у \"<strong>$4</strong>\".", + "notification-compact-header-edit-user-talk": "$1 {{GENDER:$2|пакінуў|пакінула}} {{GENDER:$3|вам}} паведамленне.", + "notification-compact-header-edit-user-talk-with-section": "$1 {{GENDER:$2|пакінуў|пакінула}} {{GENDER:$3|вам}} паведамленне ў раздзеле «<strong>$4</strong>».", "notification-header-page-linked": "Зроблена спасылка з <strong>$4</strong> на <strong>$3</strong>.", + "notification-compact-header-page-linked": "Спаслаліся з <strong>$1</strong>.", + "notification-bundle-header-page-linked": "Зробленыя спасылкі з {{PLURAL:$5|$5 старонкі|$5 старонак|100=99+ старонак}} на <strong>$3</strong>.", + "notification-header-article-reminder": "Старонка, пра якую {{GENDER:$2|вы}} прасілі нагадаць — <strong>$3</strong>", "notification-link-text-what-links-here": "Усе спасылкі на гэту старонку", "notification-header-mention-other": "$1 {{GENDER:$2|згадаў|згадала}} {{GENDER:$3|вас}} на старонцы <strong>$4</strong> у раздзеле «<strong>$5</strong>».", "notification-header-mention-other-nosection": "$1 {{GENDER:$2|згадаў|згадала}} {{GENDER:$3|Вас}} на старонцы <strong>$4</strong>.", - "notification-header-mention-user-talkpage-v2": "$1 {{GENDER:$2|згадаў|згадала}} {{GENDER:$3|Вас}} на <strong>старонцы размоў удзельніка $4</strong> у \"<strong>$6</strong>\".", + "notification-header-mention-user-talkpage-v2": "$1 {{GENDER:$2|згадаў|згадала}} {{GENDER:$3|Вас}} на <strong>старонцы размоў {{GENDER:$5|удзельніка|удзельніцы}} $4</strong> у «<strong>$6</strong>».", "notification-header-mention-user-talkpage-nosection": "$1 {{GENDER:$2|згадаў|згадала}} {{GENDER:$3|вас}} на <strong>старонцы размоў {{GENDER:$5|$4}}</strong>.", "notification-header-mention-agent-talkpage": "$1 {{GENDER:$2||згадаў|згадала}} {{GENDER:$3|Вас}} на <strong>сваёй старонцы размоў</strong> у \"<strong>$4</strong>\".", "notification-header-mention-agent-talkpage-nosection": "$1 {{GENDER:$2|згадаў|згадала}} {{GENDER:$3|Вас}} на <strong>сваёй старонцы размоў</strong>.", "notification-header-mention-article-talkpage": "$1 {{GENDER:$2|згадаў|згадала}} {{GENDER:$3|вас}} на старонцы размоў «<strong>$4</strong>» у раздзеле «<strong>$5</strong>».", "notification-header-mention-article-talkpage-nosection": "$1 {{GENDER:$2|згадаў|згадала}} {{GENDER:$3|вас}} на старонцы размоў «<strong>$4</strong>».", + "notification-header-mention-failure-user-unknown": "{{GENDER:$2|Вашая}} згадка <strong>$3</strong> не была дасланая, бо такі ўдзельнік не знойдзены.", + "notification-header-mention-failure-user-anonymous": "{{GENDER:$2|Вашая}} згадка <strong>$3</strong> не была дасланая, бо ўдзельнік — ананім.", + "notification-header-mention-failure-too-many": "{{GENDER:$2|Вы}} паспрабавалі згадаць больш чым $3 {{PLURAL:$3|удзельніка|удзельнікаў}}. Усе згадкі, якія перавышаюць гэты ліміт, не былі дасланыя.", "notification-header-mention-failure-bundle": "{{PLURAL:$3|Згадка|$3 згадкі|$3 згадак}} {{PLURAL:$3|зробленая|зробленыя|зробленых}} {{GENDER:$2|вамі}} на старонцы размоў <strong>$4</strong> не {{PLURAL:$3|можа|могуць}} быць адпраўлены.", + "notification-compact-header-mention-failure-user-unknown": "<strong>Імя ўдзельніка не існуе:</strong> $1", + "notification-compact-header-mention-failure-user-anonymous": "<strong>IP-адрасы не могуць быць згаданыя:</strong> $1", + "notification-header-mention-success": "{{GENDER:$2|Вашая}} згадка <strong>$3</strong> была дасланая.", "notification-header-mention-success-bundle": "{{PLURAL:$3|Згадка, зробленая|$3 згадкі, зробленыя|$3 згадак, зробленых}} {{GENDER:$2|вамі}} на старонцы размоў <strong>$4</strong>, адпраўлен{{PLURAL:$3|а|ы}}.", + "notification-compact-header-mention-success": "<strong>{{GENDER:$2|Вы згадалі}}:</strong> $3", "notification-header-mention-status-bundle": "{{PLURAL:$3|Абвестка|$3 абвесткі|$3 абвестак}} аб згадцы, {{PLURAL:$3|зробленая|зробленыя|зробленых}} {{GENDER:$2|вамі}} на старонцы размоў <strong>$4</strong>: {{PLURAL:$5|$5 не адпраўлена|$5 не адпраўлены}}, {{PLURAL:$6|$6 адпраўлена|$6 адпраўлены}}.", "notification-header-user-rights-add-only": "{{GENDER:$4|Вашы}} правы ўдзельніка былі {{GENDER:$1|зменены}}. Вы былі дададзены ў: $2.", "notification-header-user-rights-remove-only": "{{GENDER:$4|Вашы}} правы ўдзельніка былі {{GENDER:$1|зменены}}. Вы больш не ўваходзіце ў: $2.", "notification-header-user-rights-add-and-remove": "{{GENDER:$6|Вашы}} правы ўдзельніка былі {{GENDER:$1|зменены}}. Вы былі дададзены ў: $2. Вы больш не ўваходзіце ў: $4.", + "notification-header-user-rights-expiry-change": "Тэрмін сканчэння {{GENDER:$4|вашага}} членства ў {{PLURAL:$3|1=наступнай групе|наступных групах}} быў {{GENDER:$1|зменены}}: $2.", "notification-header-welcome": "{{GENDER:$2|Вітаем}} на сайце {{SITENAME}}, $1! Рады {{GENDER:$2|Вас}} тут бачыць.", "notification-header-mention-summary": "$1 {{GENDER:$2|згадаў|згадала}} {{GENDER:$3|Вас}} у кароткім апісанні змен старонкі <strong>$4</strong>.", + "notification-header-watchlist-changed": "$1 {{GENDER:$2|змяніў|змяніла}} <strong>$3</strong>, старонку ў {{GENDER:$4|вашым}} спісе назірання{{PLURAL:$5|$1 раз|, $5 разы|, $5 разоў|1=}}.", + "notification-header-watchlist-created": "$1 {{GENDER:$2|стварыў|стварыла}} <strong>$3</strong>, старонку ў {{GENDER:$4|вашым}} спісе назірання{{PLURAL:$5|$1 раз|, $5 разы|, $5 разоў|1=}}.", + "notification-header-watchlist-deleted": "$1 {{GENDER:$2|выдаліў|выдаліла}} <strong>$3</strong>, старонку ў {{GENDER:$4|вашым}} спісе назірання{{PLURAL:$5|$1 раз|, $5 разы|, $5 разоў|1=}}.", + "notification-header-watchlist-moved": "$1 {{GENDER:$2|перанёс|перанесла}} <strong>$3</strong>, старонку ў {{GENDER:$4|вашым}} спісе назірання{{PLURAL:$5|$1 раз|, $5 разы|, $5 разоў|1=}}.", + "notification-header-watchlist-restored": "$1 {{GENDER:$2|аднавіў|аднавіла}} <strong>$3</strong>, старонку ў {{GENDER:$4|вашым}} спісе назірання{{PLURAL:$5|$1 раз|, $5 разы|, $5 разоў|1=}}.", + "notification-header-watchlist-multiuser-changed": "<strong>$1</strong>, старонка ў {{GENDER:$2|вашым}} спісе назірання, была змененая $3 {{PLURAL:$3|раз|разы|разоў}}.", + "notification-header-watchlist-multiuser-created": "<strong>$1</strong>, старонка ў {{GENDER:$2|вашым}} спісе назірання, была створаная $3 {{PLURAL:$3|раз|разы|разоў}}.", + "notification-header-watchlist-multiuser-deleted": "<strong>$1</strong>, старонка ў {{GENDER:$2|вашым}} спісе назірання, была выдаленая $3 {{PLURAL:$3|раз|разы|разоў}}.", + "notification-header-watchlist-multiuser-moved": "<strong>$1</strong>, старонка ў {{GENDER:$2|вашым}} спісе назірання, была перанесеная $3 {{PLURAL:$3|раз|разы|разоў}}.", + "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>, старонка ў {{GENDER:$2|вашым}} спісе назірання, была адноўленая $3 {{PLURAL:$3|раз|разы|разоў}}.", + "notification-body-watchlist-once": "Іншых апавяшчэнняў на эл. пошту аб далейшай дзейнасці не будзе, калі вы не {{GENDER:$1|наведаеце}} гэтую старонку пасля ўваходу ў сістэму.", "notification-welcome-linktext": "Вітаем", "notification-header-thank-you-1-edit": "{{GENDER:$2|Вы}} толькі што зрабілі {{GENDER:$2|сваю}} першую праўку; дзякуй {{GENDER:$2|Вам}} за гэта, і вітаем!", "notification-header-thank-you-10-edit": "{{GENDER:$2|Вы}} толькі што зрабілі {{GENDER:$2|сваю}} дзясятую праўку; дзякуй {{GENDER:$2|Вам}} за гэта, працягвайце ў тым жа духу!", @@ -109,33 +182,56 @@ "notification-header-thank-you-10000-edit": "{{GENDER:$2|Вы}} толькі што зрабілі {{GENDER:$2|сваю}} дзесяцітысячную праўку; велізарны {{GENDER:$2|Вам}} дзякуй!", "notification-header-thank-you-100000-edit": "{{GENDER:$2|Вы}} толькі што зрабілі {{GENDER:$2|сваю}} статысячную праўку; дзякуй {{GENDER:$2|Вам}} за цудоўны ўнёсак!", "notification-header-thank-you-1000000-edit": "{{GENDER:$2|Вы}} толькі што зрабілі {{GENDER:$2|сваю}} мільённую праўку; дзякуй {{GENDER:$2|Вам}} за неверагодны ўнёсак!", + "notification-header-thank-you-10000000-edit": "{{GENDER:$2|Вы}} толькі што зрабілі {{GENDER:$2|сваю}} дзесяцімільённую праўку; дзякуй {{GENDER:$2|вам}} за цудоўны ўнёсак!", + "notification-link-thank-you-edit": "{{GENDER:$1|Ваша}} праўка", "notification-link-text-view-edit": "Прагляд праўкі", - "notification-header-reverted": "{{PLURAL:$4|1=Вашу праўку на старонцы $3|Вашы праўкі на старонцы $3}} {{GENDER:$2|скасаваў|скасавала}} $1.", - "notification-header-emailuser": "$1 {{GENDER:$1|даслаў|даслала}} Вам ліст.", - "notification-edit-talk-page-email-subject2": "{{GENDER:$2|Удзельнік|Удзельніца}} $1 {{GENDER:$2|пакінуў|пакінула}} вам паведамленне на пляцоўцы «{{SITENAME}}»", - "notification-page-linked-email-subject": "На сайце «{{SITENAME}}» з'явілася спасылка на вашу старонку ўдзельніка", + "notification-link-article-reminder": "Прагляд старонкі", + "notification-header-reverted": "{{PLURAL:$4|1=Вашу праўку на старонцы <strong>$3</strong>|Вашы праўкі на старонцы <strong>$3</strong>}} {{GENDER:$2|скасавалі}}.", + "notification-header-emailuser": "$1 {{GENDER:$2|даслаў|даслала}} вам ліст.", + "notification-edit-talk-page-email-subject2": "{{GENDER:$2|Удзельнік|Удзельніца}} $1 {{GENDER:$2|пакінуў|пакінула}} {{GENDER:$3|вам}} паведамленне на пляцоўцы «{{SITENAME}}»", + "notification-page-linked-email-subject": "На сайце «{{SITENAME}}» з’явілася спасылка на створаную {{GENDER:$3|вамі}} старонку", "notification-reverted-email-subject2": "{{GENDER:$2|Хтосьці}} адмяніў {{PLURAL:$4|вашу праўку|вашы праўкі}} на сайце «{{SITENAME}}»", - "notification-mention-email-subject": "{{GENDER:$2|Удзельнік|Удзельніца}} $1 {{GENDER:$2|згадаў|згадала}} вас на сайце «{{SITENAME}}»", - "notification-user-rights-email-subject": "Вашы правы на сайце «{{SITENAME}}» былі зменены", + "notification-mention-email-subject": "{{GENDER:$2|Удзельнік|Удзельніца}} $1 {{GENDER:$2|згадаў|згадала}} {{GENDER:$3|вас}} на сайце «{{SITENAME}}»", + "notification-user-rights-email-subject": "{{GENDER:$3|Вашы}} правы на сайце «{{SITENAME}}» былі зменены", + "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1 с}}", + "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1 хв}}", + "notification-timestamp-ago-hours": "{{PLURAL:$1|$1 гадз}}", + "notification-timestamp-ago-days": "{{PLURAL:$1|$1 д}}", + "notification-timestamp-ago-months": "{{PLURAL:$1|$1 мес}}", + "notification-timestamp-ago-years": "{{PLURAL:$1|$1 год|$1 гады|$1 гадоў}}", "notification-timestamp-today": "Сёння", "notification-timestamp-yesterday": "Учора", "notification-inbox-filter-read": "Чытаныя", "notification-inbox-filter-unread": "Непрачытаныя", "notification-inbox-filter-all": "Усе", - "echo-specialmute-label-mute-notifications": "Не паказваць апавяшчэнні ад гэтага ўдзельніка", + "echo-specialmute-label-mute-notifications": "Не паказваць апавяшчэнні ад {{GENDER:$1|гэтага ўдзельніка|гэтай ўдзельніцы}}", + "echo-email-plain-footer": "Для кантролю, якія лісты эл. пошты мы дасылаем {{GENDER:$1|вам}}, праверце {{GENDER:$1|вашыя}} налады:", + "echo-email-html-footer-preference-link-text": "праверце {{GENDER:$1|вашыя}} налады", + "echo-email-html-footer-with-link": "Для кантролю, якія лісты эл. пошты мы дасылаем {{GENDER:$2|вам}}, $1.", "echo-notification-alert": "{{PLURAL:$1|Абвестка ($1)|Абвесткі ($1)|100=Абвесткі (99+)}}", + "echo-notification-notice": "{{PLURAL:$1|1=Абвестка ($1)|Абвесткі ($1)|100=Абвесткі (99+)}}", "echo-notification-alert-text-only": "Паведамленні", "echo-notification-notice-text-only": "Абвесткі", "echo-overlay-link": "Усе паведамленні", "echo-overlay-title": "<b>Паведамленні</b>", "echo-mark-all-as-read": "Пазначыць усе як прачытаныя", + "echo-mark-all-as-read-confirmation": "$1 {{PLURAL:$1|апавяшчэнне пазначанае як прачытанае|апавяшчэнні пазначаныя як прачытаныя|апавяшчэнняў пазначаныя як прачытаныя}}", "echo-mark-wiki-as-read": "Пазначыць усе як прачытаныя ў выбранай вікі: $1", + "echo-displaysnippet-title": "Новае апавяшчэнне", "echo-date-today": "Сёння", "echo-date-yesterday": "Учора", + "notification-bundle-header-edit-user-talk-v2": "$1 {{PLURAL:$1|новае паведамленне|новыя паведамленні|новых паведамленняў|100=99+ новых паведамленняў}} на <strong>{{GENDER:$3|вашай}} старонцы размоў</strong>.", "echo-email-batch-subject-daily": "Вы атрымалі $2 {{PLURAL:$2|новае паведамленне ў|новых паведамлення ў|новых паведамленняў у}} праекце «{{SITENAME}}»", "echo-email-batch-subject-weekly": "На гэтым тыдні вы атрымалі $2 {{PLURAL:$2|новае паведамленне ў|новых паведамлення ў|новых паведамленняў у}} праекце «{{SITENAME}}»", "echo-email-batch-body-intro-daily": "Прывітанне, $1! Вось кароткі агляд сённяшняй дзейнасці ў {{SITENAME}} для вас.", "echo-email-batch-body-intro-weekly": "Прывітанне, $1! Вось кароткі тыднёвы агляд дзейнасці ў {{SITENAME}} для вас.", "echo-email-batch-link-text-view-all-notifications": "Праглядзець усе паведамленні", - "notification-header-foreign-notice": "Больш абвестак з {{PLURAL:$5|іншай вікі|$5 іншых вікі}}" + "notification-header-foreign-alert": "Больш абвестак з {{PLURAL:$5|$5 іншай вікі|$5 іншых вікі}}", + "notification-header-foreign-notice": "Больш абвестак з {{PLURAL:$5|іншай вікі|$5 іншых вікі}}", + "notification-header-foreign-all": "Больш апавяшчэнняў з {{PLURAL:$5|іншай вікі|$5 іншых вікі}}", + "right-manage-all-push-subscriptions": "Кіраванне ўсімі push-падпіскамі", + "action-manage-all-push-subscriptions": "кіраваць усімі push-падпіскамі", + "group-push-subscription-manager": "Кіраўнікі push-падпісак", + "group-push-subscription-manager-member": "{{GENDER:$1|кіраўнік|кіраўніца}} push-падпісак", + "grouppage-push-subscription-manager": "{{ns:project}}:Кіраўнікі push-падпісак" } diff --git a/Echo/i18n/bg.json b/Echo/i18n/bg.json index 416a5f74..42052d64 100644 --- a/Echo/i18n/bg.json +++ b/Echo/i18n/bg.json @@ -43,8 +43,8 @@ "echo-pref-notifications-page-linked-title-muted-list": "Да не се показват известия за връзки към страница за следните страници. ([[mw:Special:MyLanguage/Help:Notifications#mute|научете повече]])", "echo-learn-more": "Повече подробности", "echo-log": "Публичен дневник", - "echo-new-messages": "Имате нови съобщения", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Съобщение|Съобщения}} на беседата", + "echo-new-messages": "Имате нови съобщение на беседата си.", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Редакция|Редакции}} на беседата ми", "echo-category-title-article-linked": "{{PLURAL:$1|Препратка|Препратки}} към страници", "echo-category-title-reverted": "{{PLURAL:$1|Връщане|Връщания}} на редакция", "echo-category-title-mention": "{{PLURAL:$1|Споменаване|Споменавания}}", @@ -58,7 +58,7 @@ "echo-category-title-emailuser": "{{PLURAL:$1|Писмо от друг потребител|Писма от други потребители}}", "echo-category-title-article-reminder": "{{PLURAL:$1|напомняне|напомняния}} за страницата", "echo-category-title-thank-you-edit": "Редактиране на {{PLURAL:$1|основния етап|основните етапи}}", - "echo-pref-tooltip-edit-user-talk": "Известяване, когато някой остави съобщение или отговор на беседата ми.", + "echo-pref-tooltip-edit-user-talk": "Известяване, когато някой остави редактира беседата ми.", "echo-pref-tooltip-article-linked": "Известяване, когато някой постави препратка в страница към създадена от мен страница.", "echo-pref-tooltip-reverted": "Известяване, когато някой премахне или отмени моя редакция чрез инструмента за връщане.", "echo-pref-tooltip-mention": "Известяване, когато някой постави препратка към потребителската ми страница.", @@ -165,7 +165,6 @@ "notification-link-text-view-edit": "Преглед на редакцията", "notification-link-article-reminder": "Преглед на страницата", "notification-header-reverted": "{{PLURAL:$4|Ваша редакция|Ваши редакции}} на страницата <strong>$3</strong> {{GENDER:$2|{{PLURAL:$4|е върната|са върнати}}}}.", - "notification-body-reverted": "$1", "notification-header-emailuser": "$1 {{GENDER:$2|Ви изпрати}} имейл.", "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$3|Ви}} {{GENDER:$2|остави}} съобщение на {{SITENAME}}", "notification-page-linked-email-subject": "Страницата, създадена от {{GENDER:$3|вас}}, бе свързана с {{SITENAME}}", @@ -183,7 +182,7 @@ "notification-inbox-filter-read": "Прочетени", "notification-inbox-filter-unread": "Непрочетени", "notification-inbox-filter-all": "Всички", - "echo-specialmute-label-mute-notifications": "Спиране на известията от този потребител", + "echo-specialmute-label-mute-notifications": "Спиране на известията от този {{GENDER:$1|потребител}}", "echo-email-plain-footer": "За да изберете какви ел. писма да {{GENDER:$1|Ви}} изпращаме, проверете {{GENDER:$1|настройките си}}:", "echo-email-html-footer-preference-link-text": "проверете {{GENDER:$1|своите}} настройки", "echo-email-html-footer-with-link": "За да изберете какви имейли да {{GENDER:$2|ви}} изпращаме, $1.", diff --git a/Echo/i18n/bjn.json b/Echo/i18n/bjn.json index 3946bbc4..cfe07eaa 100644 --- a/Echo/i18n/bjn.json +++ b/Echo/i18n/bjn.json @@ -4,5 +4,54 @@ "Ezagren" ] }, - "tooltip-pt-notifications-alert": "Pamadahan {{GENDER:|Pian}}" + "echo-desc": "Sistim pamadahan ka pamakai pasal pasan wan paristiwa", + "prefs-echo": "Pamadahan", + "prefs-emailsettings": "Pilihan surél", + "prefs-echosubscriptions": "Padahi ulun pasal acara ngini", + "prefs-echocrosswiki": "Pamadahan lintas-wiki", + "prefs-blocknotificationslist": "Pamakai nang dihinipakan.", + "prefs-mutedpageslist": "Laman nang dihinipakan gasan pamadahan tautan laman", + "prefs-echopollupdates": "Pamadahan langsung", + "echo-pref-show-poll-updates": "Tampaiakan pamadahan hanyar damintu sampai", + "echo-pref-show-poll-updates-help": "Manampaiakan jumlah pamadahan balum tabaca pada bilah judul, wan manampaiakan cuplikan matan masing-masing pamadahan lakas imbah ditarima.", + "echo-pref-send-me": "Kirimi ulun:", + "echo-pref-send-to": "Kirimakan ka:", + "echo-pref-email-format": "Format surél:", + "echo-pref-email": "Surél", + "echo-pref-email-frequency-never": "Jangan kirimi ulun pamadahan surél apapun", + "echo-pref-email-frequency-immediately": "Pamadahan tunggal wayah suatu paristiwa datang", + "echo-pref-email-frequency-daily": "Ringkasan pamadahan harian", + "echo-pref-email-frequency-weekly": "Ringkasan mingguan matan babarapa pamadahan", + "echo-pref-email-format-plain-text": "Naskah biasa", + "echo-pref-cross-wiki-notifications": "Tampaiakan pamadahan matan wiki lain", + "echo-pref-notifications-blacklist": "Jangan tampaiakan pamadahan pamakai ngini. \n([[mw:Special:MyLanguage/Help:Notifications#mute|palajari salangkapnya]])", + "echo-pref-notifications-page-linked-title-muted-list": "Jangan tampaiakan pamadahan \"Tautan laman\" matan laman ngini. \n([[mw:Special:MyLanguage/Help:Notifications#mute|palajari salangkapnya]])", + "echo-pref-dont-email-read-notifications": "Jangan silipakan pamadahan tabaca dalam surél ringkasan", + "echo-learn-more": "Palajari salangkapnya", + "echo-new-messages": "Pian baisi pasan hanyar di laman Pamandiran", + "echo-category-title-article-linked": "{{PLURAL:$1|Tautan}} laman", + "echo-category-title-reverted": "{{PLURAL:$1|Pambulikan}} babakan", + "echo-category-title-mention": "{{PLURAL:$1|Sambatan}}", + "echo-category-title-mention-failure": "{{PLURAL:$1|Sambatan}} gagal", + "echo-category-title-mention-success": "{{PLURAL:$1|Sambatan}} bahasil", + "echo-category-title-system": "{{PLURAL:$1|Sistim}}", + "echo-category-title-system-emailonly": "{{PLURAL:$1|Sistim}}", + "echo-category-title-user-rights": "{{PLURAL:$1|Paubahan hak pamakai}}", + "echo-category-title-emailuser": "{{PLURAL:$1|Surél matan pamakai lain}}", + "echo-category-title-article-reminder": "Laman {{PLURAL:$1|pangingat}}", + "echo-category-title-thank-you-edit": "{{PLURAL:$1|riwayat}} babakan", + "echo-category-title-watchlist": "Babakan pada laman itihan", + "echo-category-title-minor-watchlist": "Babakan sapalih pada laman itihan", + "echo-pref-tooltip-edit-user-talk": "Padahi ulun wayah sasaurang mambabak laman pamandiran ulun.", + "echo-pref-tooltip-article-linked": "Padahi ulun wayah sasaurang maulah tautan di laman artikal ka sabuting laman nang suah ulun rintis.", + "echo-pref-tooltip-reverted": "Padahi ulun wayah sasaurang mambulikakan babakan nang suah ulun ulah, mamakai pakakas pasahakan atawa bulikakan.", + "echo-pref-tooltip-mention": "Padahi ulun wayah sasaurang manautakan ka laman pamakai ulun.", + "echo-pref-tooltip-mention-failure": "Padahi ulun amun kada kawa mangirim pasan ka pamakai lain.", + "echo-pref-tooltip-mention-success": "Padahi ulun wayah mangirimakan sambatan ka sasaurang.", + "echo-pref-tooltip-user-rights": "Padahi ulun wayah sasaurang maubah hak pamakai ulun.", + "echo-pref-tooltip-emailuser": "Padahi ulun amun sasaurang mangirim ulun surél.", + "echo-pref-tooltip-article-reminder": "Padahi ulun pasal laman ngini amun ulun minta.", + "tooltip-pt-notifications-alert": "Pamadahan {{GENDER:|Pian}}", + "tooltip-pt-notifications-notice": "Pamadahan {{GENDER:|Pian}}", + "group-push-subscription-manager": "Pangalula langganan tunjul" } diff --git a/Echo/i18n/blk.json b/Echo/i18n/blk.json new file mode 100644 index 00000000..4a5d4673 --- /dev/null +++ b/Echo/i18n/blk.json @@ -0,0 +1,32 @@ +{ + "@metadata": { + "authors": [ + "Khun Kt", + "咽頭べさ" + ] + }, + "prefs-echo": "ဖေႏသေချက်ဖိုင်ႏ", + "prefs-emailsettings": "အီးမေးတာႏ လွိုက်ရွေꩻခရာႏ", + "prefs-echocrosswiki": "ဝီခီ-စွောစ်ꩻစဲစ်ꩻ ဖေႏသေချက်ဖိုင်ႏ", + "echo-pref-send-me": "ပသာလွဉ်သွော့သြ-", + "echo-pref-send-to": "ပသာသာလွေꩻ-", + "echo-pref-email-format": "အီးမေးပုင်ႏစံႏ-", + "echo-pref-web": "ဝဲက်", + "echo-pref-email": "အီးမေး", + "echo-pref-push": "အဲပ်ဖိုင်ႏ", + "echo-pref-email-frequency-never": "ပသာမွုန်းတဝ်းဒုမ် အီးမေးဖေႏသေချက်ဖိုင်ႏမုဲင်ꩻမုဲင်ꩻ", + "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "ကေားသုင်ꩻသား လိုꩻတသာဖိုင်ႏ", + "echo-specialpage-markasread": "ဖေႏသေချက်: ဟော်ꩻထွူလဲဥ်းအကျောင်ꩻ ဒင်ႏမုဲင်တာႏ", + "notification-link-text-what-links-here": "ကဆွိုက်ခါꩻဒါႏ လိတ်မဲ့ငါယို လိဥ့်ဖုံႏကားကအဝ်ႏ", + "notification-header-welcome": "အဝ်ႏ{{SITENAME}}ယို{{GENDER:$2|ကျိုႏဆွုမ်ႏဒျာႏသြ}}၊ $1! နာꩻတွိုႏလွဥ်ဒါႏယိုကိုနဝ်ꩻ နီသွဥ်းသီး သꩻရေꩻငါႏသွူ။", + "notification-header-thank-you-1-edit": "{{GENDER:$2|အရီးသွတ်ꩻ}} {{GENDER:$2|နာꩻ}}နွို့တဲမ်းဖျင်မုꩻယို {{GENDER:$2|နာမာꩻ}}ဖေႏလဲဥ်းသွူ၊ ကျိုႏဆွုမ်ႏ ကေꩻဇူꩻတင်ႏငါႏသွူ!", + "notification-header-thank-you-10-edit": "{{GENDER:$2|နာꩻ}}ခြပ် {{GENDER:$2|ချော်}}ဖျင်ဆင်မုꩻ တွိုႏလဲဥ်း အလဲင်ႏ ၁၀သွူ၊ ကေꩻဇူꩻ{{GENDER:$2|တင်ႏငါႏသြ}}၊ မာꩻသွုပ်ယင်းဟုဲင်း။", + "notification-header-thank-you-100-edit": "{{GENDER:$2|နာꩻ}}ခြပ် {{GENDER:$2|ချော်}}ဖျင်ဆင်မုꩻ တွိုႏလဲဥ်း အလဲင်ႏ ၁၀၀ သွူ၊ ကေꩻဇူꩻ{{GENDER:$2|တင်ႏငါႏ မရေႏမရာႏသွူ}}။", + "notification-header-thank-you-1000-edit": "{{GENDER:$2|နာꩻ}}ခြပ်ချော် {{GENDER:$2|ဖျင်ဆင်မုꩻ}} တွိုႏလဲဥ်း အလဲင်ႏ၁၀၀၀သွူ၊ စွဲးကမ်းဖေႏအာဒါႏနုဲင်းယို ကေꩻဇူꩻ{{GENDER:$2|တင်ႏငါႏသြ}}။", + "notification-header-thank-you-10000-edit": "{{GENDER:$2|နာꩻ}}ခြပ် {{GENDER:$2|ချော်ꩻ}} ဖျင်ဆင်မုꩻ တွိုႏလဲဥ်း အလဲင်ႏ၁၀၀၀၀သွူ၊ ကေꩻဇူꩻ{{GENDER:$2|တင်ႏငါႏသြ}}။", + "notification-header-thank-you-100000-edit": "{{GENDER:$2|နာꩻ}}ခြပ် {{GENDER:$2|ချော်ꩻ}}ဖျင်ဆင်မုꩻ တွိုႏလဲဥ်း အလဲင်ႏ ၁၀၀၀၀၀ သွူ၊ အံႏဖြာႏခရာႏစွဲးကမ်းမုꩻအတာႏ ကေꩻဇူꩻ{{GENDER:$2|တင်ႏငါႏသြ}}။", + "notification-header-thank-you-1000000-edit": "{{GENDER:$2|နာꩻ}}ခြပ် {{GENDER:$2|ချော်}} ဖျင်ဆင်မုꩻ တွိုႏလဲဥ်း အလဲင်ႏတသိန်ႏသွူ၊ အံႏဖြာႏခရာႏ စွဲးကမ်းမုꩻယိုတာႏ ကေꩻဇူꩻ{{GENDER:$2|တင်ႏငါႏ မရေႏမရာႏသွူ}}။", + "echo-notification-alert": "{{PLURAL:$1|တမာချက် ($1)|တမာချက်ဖုံႏ ($1)|100=တမာချက်ဖုံႏ (99+)}}", + "echo-notification-notice-text-only": "ကျော်ႏညာႏခင်ႏလမ်း", + "echo-mark-all-as-read": "ဟော်ꩻထွားထွူလို့လဲဥ်းအကျောင်ꩻ ဒင်ႏမုဲင်တာႏ" +} diff --git a/Echo/i18n/bn.json b/Echo/i18n/bn.json index 95c7978f..5cfaa1b9 100644 --- a/Echo/i18n/bn.json +++ b/Echo/i18n/bn.json @@ -10,6 +10,7 @@ "Macofe", "Nasir8891", "Sayak Sarkar", + "Yahya", "আফতাবুজ্জামান" ] }, @@ -17,8 +18,9 @@ "prefs-echo": "বিজ্ঞপ্তি", "prefs-emailsettings": "ইমেইল বিকল্প", "prefs-echosubscriptions": "এই ঘটনা সম্পর্কে আমাকে অবহিত করুন", - "prefs-echocrosswiki": "আন্তঃ-উইকি বিজ্ঞপ্তি", + "prefs-echocrosswiki": "আন্তঃউইকি বিজ্ঞপ্তি", "prefs-blocknotificationslist": "নিঃশব্দকৃত ব্যবহারকারী", + "prefs-mutedpageslist": "পাতা সংযোগ বিজ্ঞপ্তি থেকে নিঃশব্দকৃত পাতা", "prefs-echopollupdates": "সরাসরি বিজ্ঞপ্তি", "echo-mobile-notifications-filter-title": "বিজ্ঞপ্তি ছাঁকুন", "echo-pref-show-poll-updates": "বিজ্ঞপ্তি আসা মাত্র সাথে সাথে তা প্রদর্শন", @@ -37,11 +39,12 @@ "echo-pref-email-format-plain-text": "সরল লেখা", "echo-pref-cross-wiki-notifications": "অন্যান্য উইকিগুলি থেকে বিজ্ঞপ্তি দেখান", "echo-pref-notifications-blacklist": "এই ব্যবহারকারীদের থেকে বিজ্ঞপ্তি প্রদর্শন করবেন না। ([[mw:Special:MyLanguage/Help:Notifications#mute|আরও জানুন]])", + "echo-pref-notifications-page-linked-title-muted-list": "এই পাতাগুলির জন্য \"পাতা সংযোগ\" বিজ্ঞপ্তি প্রদর্শন করবেন না। ([[mw:Special:MyLanguage/Help:Notifications#mute|আরও জানুন]])", "echo-pref-dont-email-read-notifications": "সারসংক্ষেপের ইমেলগুলিতে পঠিত বিজ্ঞপ্তিগুলি অন্তর্ভুক্ত করবেন না", "echo-learn-more": "আরও জানুন", "echo-log": "প্রকাশ্য লগ", "echo-new-messages": "আপনার নতুন বার্তা এসেছে", - "echo-category-title-edit-user-talk": "আলাপ পাতার {{PLURAL:$1|বার্তা|বার্তাসমূহ}}", + "echo-category-title-edit-user-talk": "আমার ব্যবহারকারী আলাপ পাতায় {{PLURAL:$1|সম্পাদনা|সম্পাদনাসমূহ}}", "echo-category-title-article-linked": "পাতা {{PLURAL:$1|সংযোগ|সংযোগসমূহ}}", "echo-category-title-reverted": "সম্পাদনা {{PLURAL:$1|ফেরত}}", "echo-category-title-mention": "{{PLURAL:$1|উল্লেখ|উল্লেখসমূহ}}", @@ -55,7 +58,7 @@ "echo-category-title-emailuser": "{{PLURAL:$1|অন্য ব্যবহারকারীর কাছ থেকে ইমেইল|অন্যান্য ব্যবহারকারীর কাছ থেকে ইমেইলসমূহ}}", "echo-category-title-article-reminder": "পাতা {{PLURAL:$1|স্মরণ}}", "echo-category-title-thank-you-edit": "সম্পাদনা {{PLURAL:$1|মাইলফলক|মাইলফলকগুলি}}", - "echo-pref-tooltip-edit-user-talk": "আমার আলাপ পাতায় কেউ বার্তা রাখলে বা উত্তর দিলে আমাকে বিজ্ঞপ্তি দিন।", + "echo-pref-tooltip-edit-user-talk": "আমার ব্যবহারকারী আলাপ পাতায় কেউ সম্পাদনা করলে আমাকে বিজ্ঞপ্তি দিন।", "echo-pref-tooltip-article-linked": "কেউ অন্য পাতায় আমার তৈরি কোনো পাতার লিঙ্ক প্রদান করলে আমাকে বিজ্ঞপ্তি দিন।", "echo-pref-tooltip-reverted": "পূর্বাবস্থা বা রোলব্যাক সরঞ্জাম দিয়ে কেউ আমার সম্পাদনা ফেরত নিলে আমাকে বিজ্ঞপ্তি দিন।", "echo-pref-tooltip-mention": "কেউ আমার ব্যবহারকারী পাতার লিঙ্ক প্রদান করলে আমাকে বিজ্ঞপ্তি দিন।", @@ -100,6 +103,7 @@ "echo-notification-markasunread": "অপঠিত হিসেবে চিহ্নিত করুন", "echo-notification-markasread-tooltip": "পঠিত হিসেবে চিহ্নিত করুন", "echo-notification-more-options-tooltip": "আরো বিকল্প", + "notification-dynamic-actions-mute-page-linked-confirmation": "\"পাতা সংযোগ\" বিজ্ঞপ্তি এখন \"$1\" পাতার জন্য নিষ্ক্রিয় করা হয়েছে", "notification-dynamic-actions-unwatch": "\"$1\"-এ নতুন কার্যকলাপ নজর রাখা {{GENDER:$3|বন্ধ করুন}}", "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3|আপনি}} আর \"$1\" পাতাটি নজরে রাখছেন না", "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|আপনি}} যেকোন সময় [$2 এই পাতায়] নজরে রাখতে পারেন।", @@ -156,12 +160,13 @@ "notification-header-thank-you-10000-edit": "{{GENDER:$2|আপনি}} এইমাত্র {{GENDER:$2|আপনার}} দশ হাজারতম সম্পাদনা করেছেন; {{GENDER:$2|আপনাকে}} অনেক ধন্যবাদ!", "notification-header-thank-you-100000-edit": "{{GENDER:$2|আপনি}} এইমাত্র {{GENDER:$2|আপনার}} এক লক্ষতম সম্পাদনা করেছেন; একজন অসাধারণ অবদানকারী হওয়ার জন্য {{GENDER:$2|আপনাকে}} ধন্যবাদ!", "notification-header-thank-you-1000000-edit": "{{GENDER:$2|আপনি}} এইমাত্র {{GENDER:$2|আপনার}} এক লক্ষতম সম্পাদনা করেছেন; একজন অসাধারণ অবদানকারী হওয়ার জন্য {{GENDER:$2|আপনাকে}} ধন্যবাদ!", + "notification-header-thank-you-10000000-edit": "{{GENDER:$2|আপনি}} এইমাত্র {{GENDER:$2|আপনার}} এক কোটিতম সম্পাদনা করেছেন; একজন অসাধারণ অবদানকারী হওয়ার জন্য {{GENDER:$2|আপনাকে}} ধন্যবাদ!", "notification-link-thank-you-edit": "{{GENDER:$1|আপনার}} সম্পাদনা", "notification-link-text-view-edit": "সম্পাদনা দেখুন", "notification-link-article-reminder": "পাতা দেখুন", "notification-header-reverted": "<strong>$3</strong>-এ আপনার করা {{PLURAL:$4|সম্পাদনা|সম্পাদনাগুলো}} {{GENDER:$2|পূর্বাবস্থায় নেয়া হয়েছে}}।", "notification-header-emailuser": "$1 আপনাকে একটি ইমেইল {{GENDER:$2|পাঠিয়েছেন}}।", - "notification-edit-talk-page-email-subject2": "$1 {{SITENAME}}-এ {{GENDER:$3|আপনাকে}} একটি বার্তা {{GENDER:$2|দিয়েছেন}}", + "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$3|আপনাকে}} {{SITENAME}}-এ একটি বার্তা {{GENDER:$2|দিয়েছেন}}", "notification-page-linked-email-subject": "{{GENDER:$3|আপনার}} তৈরিকৃত একটি পাতা {{SITENAME}} সাইটে সংযুক্ত হয়েছে।", "notification-reverted-email-subject2": "{{SITENAME}}-এ {{GENDER:$3|আপনার}} করা {{PLURAL:$4|সম্পাদনা|সম্পাদনাগুলি}} {{GENDER:$2|পূর্বাবস্থায়}} নেয়া হয়েছে", "notification-mention-email-subject": "$1 {{GENDER:$2|আপনাকে}} {{SITENAME}} সাইটে {{GENDER:$3|উল্লেখ করেছেন}}", @@ -193,7 +198,7 @@ "echo-displaysnippet-title": "নতুন বিজ্ঞপ্তি", "echo-date-today": "আজ", "echo-date-yesterday": "গতকাল", - "notification-bundle-header-edit-user-talk-v2": "আপনি <strong>{{GENDER:$3|আপনার}} আলাপ পাতায়</strong> {{PLURAL:$1|একটি|$1টি|100=৯৯+টি}} নতুন বার্তা পেয়েছেন।", + "notification-bundle-header-edit-user-talk-v2": "<strong>{{GENDER:$3|আপনার}} আলাপ পাতায়</strong> {{PLURAL:$1|একটি|$1টি|100=৯৯টি+}} নতুন বার্তা এসেছে।", "echo-email-batch-subject-daily": "আপনি {{SITENAME}}-এ {{PLURAL:$2|একটি নতুন বিজ্ঞপ্তি|একাধিক নতুন বিজ্ঞপ্তি}} পেয়েছেন", "echo-email-batch-subject-weekly": "এই সপ্তাহে আপনি {{SITENAME}}-এ {{PLURAL:$2|একটি নতুন বিজ্ঞপ্তি|একাধিক নতুন বিজ্ঞপ্তি}} পেয়েছেন", "echo-email-batch-body-intro-daily": "প্রিয় $1,\n{{SITENAME}} সাইটে আপনার জন্য আজকের দিনের কার্যক্রমের সারাংশ এখানে দেওয়া হল।", @@ -202,5 +207,5 @@ "notification-header-foreign-alert": "{{PLURAL:$5|আরেকটি উইকি থেকে|$5টি উইকি থেকে}} আরো অবহিতি", "notification-header-foreign-notice": "{{PLURAL:$5|আরেকটি উইকি|$5টি উইকি}} থেকে আরো বিজ্ঞপ্তি", "notification-header-foreign-all": "{{PLURAL:$5|আরেকটি উইকি|$5টি উইকি}} থেকে আরো বিজ্ঞপ্তি", - "echo-badge-count": "{{PLURAL:$1|$1|100=৯৯+}}" + "echo-badge-count": "{{PLURAL:$1|$1|100={{formatnum:99}}+}}" } diff --git a/Echo/i18n/bpy.json b/Echo/i18n/bpy.json new file mode 100644 index 00000000..fda78cc3 --- /dev/null +++ b/Echo/i18n/bpy.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Usingha" + ] + }, + "tooltip-pt-notifications-alert": "{{GENDER:|তর}} জানানি" +} diff --git a/Echo/i18n/br.json b/Echo/i18n/br.json index 9d142a92..6c799b9b 100644 --- a/Echo/i18n/br.json +++ b/Echo/i18n/br.json @@ -1,6 +1,7 @@ { "@metadata": { "authors": [ + "Adriendelucca", "Fohanno", "Fulup", "Gwenn-Ael", @@ -11,14 +12,21 @@ }, "echo-desc": "Reizhiad da gas keloù d'an implijerien diwar-benn darvoudoù ha kemennadennoù", "prefs-echo": "Kemennoù", + "prefs-description-echo": "Dibabit pe kemenadennoù e {{GENDER:|resevit}} ha penaos e vezont resevet ganeoc’h.", "prefs-emailsettings": "Dibarzhioù postel", "prefs-echosubscriptions": "Kas keloù din diwar-benn an darvoudoù-mañ", "prefs-echocrosswiki": "Kemennoù etrewiki", + "prefs-blocknotificationslist": "Implijerien stanket", + "prefs-mutedpageslist": "Pajennoù diwiredekaet kemennoù liammoù pajennoù evito", + "prefs-echopollupdates": "Kemennoù war eeun", + "echo-mobile-notifications-filter-title": "Silañ ar c'hemennoù", + "echo-pref-show-poll-updates": "Diskwel kemennoù nevez pa erruont", "echo-pref-send-me": "Kas din :", "echo-pref-send-to": "Kas da :", "echo-pref-email-format": "Furmad ar postel :", "echo-pref-web": "Web", "echo-pref-email": "Postel", + "echo-pref-push": "Arloadoù", "echo-pref-email-frequency-never": "Arabat kas kemennoù din dre bostel", "echo-pref-email-frequency-immediately": "Kemennoù hiniennel bep ma teuont", "echo-pref-email-frequency-daily": "Un diverrañ pemdeziek eus ar c'hemennoù", @@ -26,83 +34,187 @@ "echo-pref-email-format-html": "HTML", "echo-pref-email-format-plain-text": "Testenn blaen", "echo-pref-cross-wiki-notifications": "Diskouez kemennoù eus wikioù all", + "echo-pref-notifications-blacklist": "Chom hep diskwel kemennoù eus an implijerien-mañ. ([[mw:Special:MyLanguage/Help:Notifications#mute|gouzout hiroc’h]])", + "echo-pref-notifications-page-linked-title-muted-list": "Chom hep diskwel \"Liamm pajenn\" kemennoù evit ar pajennoù-mañ. ([[mw:Special:MyLanguage/Help:Notifications#mute|gouzout hiroc’h]])", + "echo-pref-dont-email-read-notifications": "Chom hep lakaat kemennoù lennet e posteloù diverrañ", "echo-learn-more": "Gouzout hiroc'h", - "echo-new-messages": "Kemennadennoù nevez hoc'h eus", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Ur gemennadenn|Kemennadennoù}} er bajenn gaozeal", + "echo-log": "Marilh foran", + "echo-new-messages": "Ur gemennadenn nevez ho peus", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Kemm}} d’am fajenn gaozeal", "echo-category-title-article-linked": "Pajenn {{PLURAL:$1|link}}", "echo-category-title-reverted": "{{PLURAL:$1|Kemm|Kemmoù}} nullet", "echo-category-title-mention": "{{PLURAL:$1|Meneg}}", - "echo-category-title-mention-failure": "Menegoù c’hwitet", - "echo-category-title-mention-success": "Menegoù deuet da benn", + "echo-category-title-mention-failure": "{{PLURAL:$1|Meneg|Menegoù}} c’hwitet", + "echo-category-title-mention-success": "{{PLURAL:$1|Meneg|Menegoù}} deuet a-benn", "echo-category-title-other": "{{PLURAL:$1|All}}", "echo-category-title-system": "{{PLURAL:$1|Sistem}}", + "echo-category-title-system-noemail": "{{PLURAL:$1|Sistem}}", + "echo-category-title-system-emailonly": "{{PLURAL:$1|Sistem}}", + "echo-category-title-user-rights": "{{PLURAL:$1|Kemm|Kemmoù}} gwirioù an implijerien", "echo-category-title-emailuser": "{{PLURAL:$1|Postel digant un implijer all|Posteloù digant implijerien all}}", + "echo-category-title-article-reminder": "Kounadur{{PLURAL:$1||ioù}} pajennoù", "echo-category-title-thank-you-edit": "{{PLURAL:$1|Maen-bonn|Vein-bonn}} kemmañ", - "echo-pref-tooltip-edit-user-talk": "Kemenn din pa vez postet ur gemennadenn pe pa vez respontet din gant unan bennak war ma fajenn gaozeal.", - "echo-pref-tooltip-article-linked": "Ma c'hemenn pa vez graet ul liamm war-du ur bajennn am eus krouet gant unan bennak adalek pajenn ur pennad.", + "echo-category-title-watchlist": "Kemm da bajenn evezhiet", + "echo-category-title-minor-watchlist": "Kemm dister da bajenn evezhiet", + "echo-pref-tooltip-edit-user-talk": "Kemenn din pa vez kemmet ma fajenn gaozeal.", + "echo-pref-tooltip-article-linked": "Kemenn din pa vez graet ul liamm war-du ur bajennn am eus krouet gant unan bennak adalek ur bajenn all.", "echo-pref-tooltip-reverted": "Kemenn din pa vez distaolet ur c'hemm graet ganin, en ur ober gant an ostilh disteurel pe distreiñ.", - "echo-pref-tooltip-mention": "Kelaouiñ ac'hanon pa vez menneget va fajenn implijer gant unan bennak.", - "echo-pref-tooltip-mention-failure": "Kemenn ac’hanon pa n’am eus ket gallet menegiñ unan bennak.", - "echo-pref-tooltip-user-rights": "Kelaouiñ ac'hanon pa vez kemmet va gwirioù implijer gant unan bennak.", + "echo-pref-tooltip-mention": "Kemenn din pa vez liammet war-du va fajenn implijer gant unan bennak.", + "echo-pref-tooltip-mention-failure": "Kemennit ac’hanon pa n’am eus ket gallet menegiñ unan bennak.", + "echo-pref-tooltip-mention-success": "Kemennit ac’hanon pa am eus kaset ur meneg da unan bennak.", + "echo-pref-tooltip-user-rights": "Kemenn din pa vez kemmet va gwirioù implijer gant unan bennak.", + "echo-pref-tooltip-emailuser": "Kemennit ac’hanon pa gas un den bennak ur postel din.", + "echo-pref-tooltip-article-reminder": "Kemennit ac’hanon a-zivout ar bajenn-mañ pa c’houlennan.", + "echo-pref-tooltip-thank-you-edit": "Kemennit ac’hanon pa dizhan ma 1añ, 10vet, 100vet… kemm.", + "echo-pref-tooltip-watchlist": "Kemenn ac’hanon pa zegas unan bennak ur c’hemm (n’eo ket dister) d’ur bajenn em roll evezhiañ.", + "echo-pref-tooltip-minor-watchlist": "Kemenn ac’hanon pa zegas unan bennak ur c’hemm dister d’ur bajenn em roll evezhiañ.", "notifications": "Kemennoù", "tooltip-pt-notifications-alert": "{{GENDER:|Ho}} kemennoù-diwall", "tooltip-pt-notifications-notice": "{{GENDER:|Ho}} kemennoù", "echo-displaynotificationsconfiguration": "Diskwel kefluniadur ar c'hemennoù", "echo-displaynotificationsconfiguration-summary": "Setu aze ur brassell war ar mod m'eo kefluniet ar c'hemennoù er wiki-mañ.", "echo-displaynotificationsconfiguration-notifications-by-category-header": "Kemennoù dre rummad", + "echo-displaynotificationsconfiguration-sorting-by-section-header": "Urzh ar seurtoù", "echo-displaynotificationsconfiguration-sorting-by-section-legend": "E pe rann emañ urzhiet kement doare kemenn zo", + "echo-displaynotificationsconfiguration-available-notification-methods-header": "Hentennoù kemenn aotreet", "echo-displaynotificationsconfiguration-available-notification-methods-by-category-legend": "Peseurt hentenn kemenn zo skoret evit pep rummad", + "echo-displaynotificationsconfiguration-enabled-default-header": "Gweredekaet dre ziouer", + "echo-displaynotificationsconfiguration-enabled-default-existing-users-legend": "Implijerien a zo anezho", "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "Implijerien nevez", "echo-displaynotificationsconfiguration-mandatory-notification-methods-header": "Rekis eo kaout hentennoù kemenn", + "echo-displaynotificationsconfiguration-mandatory-notification-methods-by-category-legend": "Peseurt hentenn kemenn zo dre ret evit pep rummad", "echo-specialpage": "Kemennoù", + "echo-specialpage-section-markread": "Merkañ strollad evel lennet", "echo-specialpage-markasread": "Kemenn : merket evel lennet", + "echo-specialpage-markasread-invalid-id": "Anaouder degouezhadenn faziek", "echo-specialpage-pagefilterwidget-aria-label": "Silañ dre wiki ha titloù pajennoù", + "echo-specialpage-special-help-menu-widget-aria-label": "Dibarzhioù ouzhpenn ha dibaboù kemennoù.", "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|c'hemenn|kemenn}}", + "echo-specialpage-pagefilters-title": "Oberiantiz nevez", "echo-specialpage-pagefilters-subtitle": "Pajennoù enno kemennoù n'int ket bet lennet", + "notificationsmarkread-legend": "Merkañ kemenn evel lennet", "echo-none": "N'ho peus resevet kemenn ebet.", "echo-api-failure": "N'eus ket bet gallet mont da gerc'hat ar c'hemennadennoù.", "echo-notification-placeholder": "N'eus kemenn ebet.", + "echo-notification-placeholder-filters": "N’eus kemenn ebet a glot gant ar c’hriterioù-mañ.", "echo-notification-loginrequired": "Ret eo deoc'h kevreañ evit gallout lenn ho kemennoù.", - "notification-link-text-expand-alert-count": "Diskouez $1 galv-diwall", + "echo-notification-popup-loginrequired": "Kevreit evit gwelout ho kemennoù mar plij.", + "echo-notification-markasread": "Merkañ evel lennet", + "echo-notification-markasunread": "Merkañ evel anlennet", + "echo-notification-markasread-tooltip": "Merkañ evel lennet", + "echo-notification-more-options-tooltip": "Muioc'h a zibarzhioù", + "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|Diweredekaat}} kemennoù liammoù evit \"$1\"", + "notification-dynamic-actions-mute-page-linked-confirmation": "Diweredekaet eo kemennoù « liammoù pajennoù » evit pajenn \"$1\"", + "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2|Gweredekaat}} kemennoù liammoù evit \"$1\"", + "notification-dynamic-actions-unmute-page-linked-confirmation": "Gweredekaet eo kemennoù « liammoù pajennoù » evit pajenn \"$1\"", + "notification-dynamic-actions-unwatch": "{{GENDER:$3|Paouez}} da evezhiañ oberiantiz nevez war \"$1\"", + "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3|N’emaoc’h ket}} oc’h evezhiañ pajenn \"$1\" ken", + "notification-dynamic-actions-unwatch-confirmation-description": "Gallout a {{GENDER:$3|rit}} evezhiañ [$2 ar bajenn-mañ] pa garit.", + "notification-dynamic-actions-watch": "{{GENDER:$3|Heuliañ}} oberiantiz nevez war \"$1\"", + "notification-dynamic-actions-watch-confirmation": "{{GENDER:$3|Emaoc’h}} oc’h evezhiañ ar bajenn \"$1\" bremañ", + "notification-dynamic-actions-watch-confirmation-description": "Gallout a {{GENDER:$3|rit}} paouez da evezhiañ [$2 ar bajenn-mañ] pa garit.", + "notification-link-text-expand-all": "Dispakañ", + "notification-link-text-expand-alert-count": "Diskouez {{PLURAL:$1|$1 galv-diwall|2=c'halv-diwall}}", + "notification-link-text-expand-notice-count": "Gwelet {{PLURAL:$1|$1 kemenn}}", "notification-link-text-expand-all-count": "Gwelet {{PLURAL:$1|$1 c'hemenn|$1 kemenn}}", "notification-link-text-collapse-all": "Pakañ", "notification-link-text-view-message": "Gwelet ar gemennadenn", "notification-link-text-view-mention": "Gwelet ar meneg", "notification-link-text-view-mention-failure": "Gweloat {{PLURAL:$1|menegoù|meneg}}", - "notification-link-text-view-changes": "Diskouez ar c'hemmoù", + "notification-link-text-view-changes": "{{GENDER:$1|Gwelet}} ar c'hemmoù", "notification-link-text-view-page": "Gwelet ar bajenn", + "notification-header-edit-user-talk": "$1 {{GENDER:$2|en|he}} deus lezet ur gemennadenn war <strong>{{GENDER:$3|ho}} pajenn gaozeal</strong>.", "notification-header-edit-user-talk-with-section": "$1 {{GENDER:$2|en deus|he deus}} skrivet ur gemennadenn war <strong>{{GENDER:$3|ho}} pajenn gaozeal</strong> er rann \"<strong>$4</strong>\".", - "notification-header-mention-other": "Meneget oc’h bet gant $1 war bajenn <strong>$4</strong> e \"<strong>$5</strong>\".", - "notification-header-mention-user-talkpage-v2": "Meneget oc’h bet gant $1 war <strong>bajenn gaozeal $4</strong> e \"<strong>$6</strong>\".", - "notification-header-mention-agent-talkpage": "Meneget oc’h bet gant $1 war <strong>{{GENDER:$2|e bajenn|he fajenn|ar bajenn}} kaozeal e rannbennad \"<strong>$4</strong>\".", - "notification-header-mention-article-talkpage": "Meneget oc’h bet gant $1 war ar bajenn gaozeaz <strong>$4</strong> e \"<strong>$5</strong>\".", + "notification-compact-header-edit-user-talk": "$1 {{GENDER:$2|en|he}} deus laosket ur gemennadenn {{GENDER:$3|ganeoc’h}}.", + "notification-compact-header-edit-user-talk-with-section": "$1 {{GENDER:$2|en|he}} deus lezet ur gemennadenn {{GENDER:$3|ganeoc’h}} e \"<strong>$4</strong>\".", + "notification-header-page-linked": "Graet ez eus bet ul liamm eus <strong>$4</strong> davet <strong>$3</strong>.", + "notification-compact-header-page-linked": "Liammet eus <strong>$1</strong>.", + "notification-bundle-header-page-linked": "Graet eo bet liammoù eus {{PLURAL:$5||$5 pajenn|100=99+ pajenn}} war-zu strong>$3</strong>.", + "notification-header-article-reminder": "Emañ ur bajenn {{GENDER:$2|ho}} peus goulennet bezañ adc’halvet diwar he fenn e <strong>$3</strong>", + "notification-link-text-what-links-here": "An holl liammoù war-zu ar bajenn-mañ", + "notification-header-mention-other": "{{GENDER:$2|Meneget}} {{GENDER:$3|oc’h}} bet gant $1 war bajenn <strong>$4</strong> e \"<strong>$5</strong>\".", + "notification-header-mention-other-nosection": "$1 {{GENDER:$2|en|he}} deus meneget {{GENDER:$3|ac’hanoc’h}} war <strong>$4</strong>.", + "notification-header-mention-user-talkpage-v2": "{{GENDER:$2|Meneget}} {{GENDER:$3|oc’h}} bet gant $1 war <strong>bajenn gaozeal $4</strong> {{GENDER:$5|$5}} e \"<strong>$6</strong>\".", + "notification-header-mention-user-talkpage-nosection": "$1 {{GENDER:$2|en|he}} deus meneget {{GENDER:$3|ac’hanoc’h}} war <strong>bajenn gaozeal {{GENDER:$5||}} $4</strong>.", + "notification-header-mention-agent-talkpage": "{{GENDER:$2|Meneget}} {{GENDER:$3|oc’h}} bet gant $1 war <strong>{{GENDER:$2|e bajenn|he fajenn|ar bajenn}} kaozeal e rannbennad \"<strong>$4</strong>\".", + "notification-header-mention-agent-talkpage-nosection": "$1 {{GENDER:$2|en|he}} deus meneget {{GENDER:$3|ac’hanoc’h}} war <strong>{{GENDER:$2|e bajenn|he fajenn}} gaozeal</strong>.", + "notification-header-mention-article-talkpage": "{{GENDER:$2|Meneget}} {{GENDER:$3|oc’h}} bet gant $1 war ar bajenn gaozeaz <strong>$4</strong> e \"<strong>$5</strong>\".", + "notification-header-mention-article-talkpage-nosection": "$1 {{GENDER:$2|en|he}} deus meneget {{GENDER:$3|ac’hanoc’h}} war bajenn gaozeal <strong>$4</strong>.", + "notification-header-mention-failure-user-unknown": "N’eo ket bet kavet {{GENDER:$2|ho}} meneg eus <strong>$3</strong>.", + "notification-header-mention-failure-user-anonymous": "N’eo ket bet kaset {{GENDER:$2|ho}} meneg eus <strong>$3</strong> peogwir eo dizanav an implijer.", + "notification-header-mention-failure-too-many": "Klasket {{GENDER:$2|ho peus}} menegiñ muioc’h evit $3 {{PLURAL:$3|implijer}}. N’eo ket bet kaset ar menegoù a-üs d’ar vevenn-mañ.", + "notification-header-mention-failure-bundle": "N’eo ket bet {{PLURAL:$3|posubl}} kas {{PLURAL:$3|Ur|$3}} meneg {{GENDER:$2|ho peus graet}} war bajenn gaozeal <strong>$4</strong>.", + "notification-compact-header-mention-failure-user-unknown": "<strong>N’eus ket eus an anv implijer-mañ:</strong> $1", "notification-compact-header-mention-failure-user-anonymous": "<strong>IPoù ne c’hell ket bezañ meneget:</strong> $1", - "notification-compact-header-mention-success": "<strong>Meneget ho peus:</strong> $3", + "notification-header-mention-success": "Kaset eo bet {{GENDER:$2|ho}} meneg eus <strong>$3</strong>.", + "notification-header-mention-success-bundle": "Kaset {{PLURAL:$3|eo bet}} {{PLURAL:$3|ur|$3}} meneg {{GENDER:$2|ho peus graet}} war bajenn gaozeal <strong>$4</strong>.", + "notification-compact-header-mention-success": "<strong>{{GENDER:$2|Meneget ho peus}}:</strong> $3", "notification-header-mention-status-bundle": "{{PLURAL:$3|Ur c'hemenn|$3 kemen}} diwar-benn menegoù {{GENDER:$2|graet ganeoc'h}} e bajenn gaozeal <strong>$4</strong> : $5 {{PLURAL:$5|n'eo ket bet kaset|n'int ket bet kaset}}, ha {{PLURAL:$6|$6 zo bet kaset}}.", - "notification-header-mention-summary": "Meneget oc’h bet gant $1 e diverradenn ur c’hemm war bajenn <strong>$4</strong>.", - "notification-header-thank-you-1-edit": "{{GENDER:$2|Da}} gemmadenn gentañ o paouez bezañ graet ganit; trugarez ha degemer mat!", - "notification-header-thank-you-10-edit": "{{GENDER:$2|Da}} dekvet gemmadenn o paouez bezañ graet ganit; trugarez ha bec'h dezhi!", - "notification-header-thank-you-100-edit": "{{GENDER:$2|Da}} kantvet gemmadenn o paouez bezañ graet ganit; mersi bras!", - "notification-header-thank-you-1000-edit": "{{GENDER:$2|Da}} milvet gemmadenn o paouez bezañ graet ganit; trugarez da vezañ ur {{GENDER:$2|c'henlabourer meur|genlabourerez veur}}!", + "notification-header-user-rights-add-only": "{{GENDER:$1|Kemmet}} eo bet {{GENDER:$4|ho}} kwirioù implijer. Ouzhpennet oc’h bet da: $2.", + "notification-header-user-rights-remove-only": "{{GENDER:$1|Kemmet}} eo bet {{GENDER:$4|ho}} kwirioù implijer. N’oc’h ket ezel ken eus: $2.", + "notification-header-user-rights-add-and-remove": "{{GENDER:$1|Kemmet}} eo bet {{GENDER:$6|ho}} kwirioù implijer. Ouzhpennet oc’h bet da: $2. N’oc’h ket ezel ken eus: $4.", + "notification-header-welcome": "{{GENDER:$2|Degemer mat}} da {{SITENAME}}, $1! Laouen omp {{GENDER:$2|oc’h}} amañ.", + "notification-header-mention-summary": "{{GENDER:$2|Meneget}} {{GENDER:$3|oc’h}} bet gant $1 e diverradenn ur c’hemm war bajenn <strong>$4</strong>.", + "notification-header-watchlist-changed": "$1 {{GENDER:$2|en|he}} deus kemmet <strong>$3</strong>, ur bajenn en {{GENDER:$4|ho}} roll ezehiañ{{PLURAL:$5||, $5 gwech}}.", + "notification-header-watchlist-created": "$1 {{GENDER:$2|en|he}} deus krouet <strong>$3</strong>, ur bajenn en {{GENDER:$4|ho}} roll ezehiañ{{PLURAL:$5||, $5 gwech}}.", + "notification-header-watchlist-deleted": "$1 {{GENDER:$2|en|he}} deus diverket <strong>$3</strong>, ur bajenn en {{GENDER:$4|ho}} roll ezehiañ{{PLURAL:$5||, $5 gwech}}.", + "notification-header-watchlist-moved": "$1 {{GENDER:$2|en|he}} deus dilec’hiet <strong>$3</strong>, ur bajenn en {{GENDER:$4|ho}} roll ezehiañ{{PLURAL:$5||, $5 gwech}}.", + "notification-header-watchlist-restored": "$1 {{GENDER:$2|en|he}} deus assavet <strong>$3</strong>, ur bajenn en {{GENDER:$4|ho}} roll ezehiañ{{PLURAL:$5||, $5 gwech}}.", + "notification-header-watchlist-multiuser-changed": "Kemmet eo bet <strong>$1</strong>, ur bajenn en {{GENDER:$2|ho}} roll ezehiañ, {{PLURAL:$3|gwech}}.", + "notification-header-watchlist-multiuser-created": "Krouet eo bet <strong>$1</strong>, ur bajenn en {{GENDER:$2|ho}} roll ezehiañ, {{PLURAL:$3|gwech}}.", + "notification-header-watchlist-multiuser-deleted": "Diverket eo bet <strong>$1</strong>, ur bajenn en {{GENDER:$2|ho}} roll ezehiañ, {{PLURAL:$3|gwech}}.", + "notification-header-watchlist-multiuser-moved": "Dilec’hiet eo bet <strong>$1</strong>, ur bajenn en {{GENDER:$2|ho}} roll ezehiañ, {{PLURAL:$3|gwech}}.", + "notification-header-watchlist-multiuser-restored": "Assavet eo bet <strong>$1</strong>, ur bajenn en {{GENDER:$2|ho}} roll ezehiañ, {{PLURAL:$3|gwech}}.", + "notification-welcome-linktext": "Degemer mat", + "notification-header-thank-you-1-edit": "Emaoc’h o paouez ober {{GENDER:$2|ho}} kemm kentañ; trugarez, ha degemer mat!", + "notification-header-thank-you-10-edit": "Emaoc’h o paouez ober {{GENDER:$2|ho}} tekvet kemm; trugarez, ha kendalc’hit mar plij!", + "notification-header-thank-you-100-edit": "Emaoc’h o paouez ober {{GENDER:$2|ho}} kantvet kemm; trugarez, trugarez vras deoc’h!", + "notification-header-thank-you-1000-edit": "Emaoc’h o paouez ober {{GENDER:$2|ho}} milvet kemm; trugarez deoc’h, c’hwi zo ur {{GENDER:$2|c'henlabourer|genlabourerez}} a-feson!", + "notification-header-thank-you-10000-edit": "Emaoc’h o paouez ober {{GENDER:|ho}} tek vilvet kemm, trugarez vras {{GENDER:$2|deoc’h}}!", + "notification-header-thank-you-100000-edit": "Emaoc’h o paouez ober {{GENDER:$2|ho}} kant milvet kemm; trugarez deoc’h evit un degasadenn dispar!", + "notification-header-thank-you-1000000-edit": "Emaoc’h o paouez ober {{GENDER:|ho}} milionvet kemm, trugarez vras {{GENDER:$2|deoc’h}}!", + "notification-link-thank-you-edit": "{{GENDER:$1|Ho}} kemm", "notification-link-text-view-edit": "Gwelet ar c'hemm", - "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$2|en|he}} deus laosket ur gemennadenn ganeoc’h war {{SITENAME}}", - "notification-page-linked-email-subject": "Liammet eo bet ho pajenn ouzh {{SITENAME}}", - "notification-mention-email-subject": "Meneget oc’h bet gant $1 war {{SITENAME}}", - "notification-user-rights-email-subject": "Cheñchet eo ho kwirioù implijer war {{SITENAME}}", + "notification-link-article-reminder": "Gwelet ar bajenn", + "notification-header-reverted": "{{GENDER:$2|Distaolet}} eo bet ho {{PLURAL:$4|kemm|kemmoù}} war <strong>$3</strong>.", + "notification-header-emailuser": "$1 {{GENDER:$2|en|he}} deus kaset ur postel deoc’h.", + "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$2|en|he}} deus laosket ur gemennadenn {{GENDER:$3|ganeoc’h}} war {{SITENAME}}", + "notification-page-linked-email-subject": "Liammet eo bet ouzh ur bajenn krouet {{GENDER:$3|ganeoc’h}} war {{SITENAME}}", + "notification-reverted-email-subject2": "{{GENDER:$2|Distaolet}} eo bet ho {{PLURAL:$4|kemm|kemmoù}} war <strong>$3</strong> war {{SITENAME}}.", + "notification-mention-email-subject": "{{GENDER:$2|Meneget}} {{GENDER:$3|oc’h}} bet gant $1 war {{SITENAME}}", + "notification-user-rights-email-subject": "Cheñchet eo {{GENDER:$3|ho}} kwirioù implijer war {{SITENAME}}", + "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1eil}}", + "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1m}}", + "notification-timestamp-ago-hours": "{{PLURAL:$1|$1e}}", + "notification-timestamp-ago-days": "{{PLURAL:$1|$1d}}", + "notification-timestamp-ago-months": "{{PLURAL:$1|$1miz}}", + "notification-timestamp-ago-years": "{{PLURAL:$1|$1bl}}", + "notification-timestamp-today": "Hiziv", + "notification-timestamp-yesterday": "Dec'h", "notification-inbox-filter-read": "Lennet", "notification-inbox-filter-unread": "Anlennet", + "notification-inbox-filter-all": "An holl", + "echo-specialmute-label-mute-notifications": "Diweredekaat kemennoù eus an implijer{{GENDER:$1||ez}}-mañ", + "echo-email-html-footer-preference-link-text": "mont d’{{GENDER:$1|ho}} tibaboù", + "echo-notification-alert": "{{PLURAL:$1|Kemenn ($1)|Kemennoù ($1)|100=Kemennoù (99+)}}", + "echo-notification-notice": "{{PLURAL:$1|Kemenn ($1)|100=Kemenn (99+)}}", "echo-notification-alert-text-only": "Kemennoù-diwall", + "echo-notification-notice-text-only": "Kemennoù", "echo-overlay-link": "An holl gemennoù", "echo-overlay-title": "<b>Kemennoù</b>", "echo-mark-all-as-read": "Merkañ an holl evel lennet", "echo-mark-all-as-read-confirmation": "$1 {{PLURAL:$1|c'hemenn|kemenn}} merket evel lennet", + "echo-mark-wiki-as-read": "Merkañ an holl evel lennet er wiki diuzet: $1", + "echo-displaysnippet-title": "Kemenn nevez", "echo-date-today": "Hiziv", "echo-date-yesterday": "Dec'h", + "notification-bundle-header-edit-user-talk-v2": "{{PLURAL:$1}} evezhiadenn nevez war <strong>{{GENDER:$3|ho}} pajenn gaozeal</strong>.", "echo-email-batch-subject-daily": "{{PLURAL:$2|Ur c'hemenn|Kemennoù}} nevez hoc'h eus war {{SITENAME}}", "echo-email-batch-subject-weekly": "{{PLURAL:$2|Ur c'hemenn|Kemennoù}} nevez hoc'h eus war {{SITENAME}} er sizhun-mañ", "echo-email-batch-body-intro-daily": "Demat deoc'h $1,\nSetu amañ un diverradur eus obererezh an deiz war {{SITENAME}} evidoc'h.", "echo-email-batch-body-intro-weekly": "Demat deoc'h $1,\nSetu amañ un diverradur eus obererezh ar sizhun-mañ war {{SITENAME}} evidoc'h.", "echo-email-batch-link-text-view-all-notifications": "Gwelet an holl gemennadennoù", "notification-header-foreign-alert": "Muioc'h a c'halvoù-diwall eus {{PLURAL:$5|ur wiki-all|$5 wiki-all}}", + "notification-header-foreign-notice": "Kemennoù all eus {{PLURAL:$5|ur|$5}} wiki all", "notification-header-foreign-all": "Kemennoù ouzhpenn war {{PLURAL:$5|ur wiki all|$5 wiki all}}" } diff --git a/Echo/i18n/bs.json b/Echo/i18n/bs.json index 8ea30304..7df84cb4 100644 --- a/Echo/i18n/bs.json +++ b/Echo/i18n/bs.json @@ -8,7 +8,8 @@ "Macofe", "Palapa", "Semso98", - "Srdjan m" + "Srdjan m", + "Srđan" ] }, "echo-desc": "Sistem za obavještavanje korisnika o dešavanjima i porukama", diff --git a/Echo/i18n/ca.json b/Echo/i18n/ca.json index cf0892eb..1d8d73dc 100644 --- a/Echo/i18n/ca.json +++ b/Echo/i18n/ca.json @@ -3,9 +3,12 @@ "authors": [ "Arnaugir", "Fitoschido", + "Galactic Thrasher", "Lluis tgn", + "Mguix", "Nemo bis", "Papapep", + "Paucabot", "Pitort", "QuimGil", "Ssola", @@ -20,6 +23,7 @@ "prefs-echosubscriptions": "Notifica'm sobre aquests esdeveniments", "prefs-echocrosswiki": "Notificacions interwiki", "prefs-blocknotificationslist": "Usuaris silenciats", + "prefs-mutedpageslist": "Pàgines silenciades de les notificacions d'enllaç a pàgines", "echo-pref-send-me": "Envia’m:", "echo-pref-send-to": "Envia a:", "echo-pref-email-format": "Format del missatge:", @@ -32,10 +36,12 @@ "echo-pref-email-format-html": "HTML", "echo-pref-email-format-plain-text": "Text net", "echo-pref-cross-wiki-notifications": "Mostra les notificacions d'altres wikis", + "echo-pref-notifications-blacklist": "No mostris notificacions d'aquests usuaris. ([[mw:Special:MyLanguage/Help:Notifications#mute|més informació]])", + "echo-pref-notifications-page-linked-title-muted-list": "No mostris notificacions «d'enllaç a pàgina» d'aquestes pàgines. ([[mw:Special:MyLanguage/Help:Notifications#mute|més informació]])", "echo-learn-more": "Més informació", "echo-log": "Registre públic", "echo-new-messages": "Teniu nous missatges", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Missatge|Missatges}} de discussió", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Modificació|Modificacions}} a la meva pàgina de discussió d'usuari", "echo-category-title-article-linked": "{{PLURAL:$1|Enllaç|Enllaços}} de pàgina", "echo-category-title-reverted": "{{PLURAL:$1|Reversió d'edició|Reversions d'edicions}}", "echo-category-title-mention": "{{PLURAL:$1|Menció|Mencions}}", @@ -46,7 +52,8 @@ "echo-category-title-user-rights": "{{PLURAL:$1|Canvi de drets d'usuari|Canvis de drets d'usuari}}", "echo-category-title-emailuser": "{{PLURAL:$1|Correu electrònic d'un altre usuari|Correus electrònics d'altres usuaris}}", "echo-category-title-article-reminder": "{{PLURAL:$1|Recordatori|Recordatoris}} de pàgina", - "echo-pref-tooltip-edit-user-talk": "Avisa'm quan algú envia un missatge o respon a la meva pàgina de discussió.", + "echo-category-title-thank-you-edit": "{{PLURAL:$1|Fita|Fites}} d'edició", + "echo-pref-tooltip-edit-user-talk": "Notifica'm quan algú modifiqui la meva pàgina de discussió d'usuari.", "echo-pref-tooltip-article-linked": "Avisa'm quan algú enllaça des d'un article a una pàgina que he creat.", "echo-pref-tooltip-reverted": "Avisa'm quan algú reverteix una modificació que he fet, emprant l'eina per a desfer o revocar.", "echo-pref-tooltip-mention": "Notifica'm quan algú enllaci a la meva pàgina d'usuari.", @@ -130,7 +137,7 @@ "notification-header-user-rights-add-only": "Els vostres drets d'usuari han estat {{GENDER:$1|modificats}}. Heu estat {{GENDER:$4|afegit|afegida}} a: $2.", "notification-header-user-rights-remove-only": "{{GENDER:$4|Els vostres}} drets d'usuari han estat {{GENDER:$1|modificats}}. Ja no sou membre de: $2.", "notification-header-user-rights-add-and-remove": "Els vostres drets d'usuari han estat {{GENDER:$1|modificats}}. Heu estat {{GENDER:$6|afegit|afegida}} a: $2. Ja no sou membre de: $4.", - "notification-header-welcome": "{{GENDER:$2|Benvingut|Benvinguda}} al projecte {{SITENAME}}, $1! Ens alegrem que {{GENDER:$2|estigueu}} aquí.", + "notification-header-welcome": "{{GENDER:$2|Benvingut|Benvinguda}} al projecte {{SITENAME}}, $1! Ens alegrem que {{GENDER:$2|sigueu}} aquí.", "notification-welcome-linktext": "Benvinguts", "notification-header-thank-you-1-edit": "{{GENDER:$2|Acabeu}} de fer {{GENDER:$2|la vostra}} primera modificació; {{GENDER:$2|us}} ho agraïm i us donem la benvinguda!", "notification-header-thank-you-10-edit": "{{GENDER:$2|Acabeu}} de fer {{GENDER:$2|la vostra}} desena modificació; gràcies i endavant!", @@ -144,11 +151,11 @@ "notification-link-article-reminder": "Mostra la pàgina", "notification-header-reverted": "{{PLURAL:$4|La vostra edició a <strong>$3</strong> ha estat revertida|Les vostres edicions a <strong>$3</strong> han estat revertides}}{{GENDER:$2|}}.", "notification-header-emailuser": "$1 us ha {{GENDER:$2|enviat}} un correu electrònic.", - "notification-edit-talk-page-email-subject2": "$1 us {{GENDER:$2|ha deixat}} un missatge al projecte {{SITENAME}}", - "notification-page-linked-email-subject": "Una pàgina que vau crear s'ha enllaçat en el projecte {{SITENAME}}", - "notification-reverted-email-subject2": "{{PLURAL:$4|S'ha revertit la vostra edició|S'han revertit les vostres edicions}} {{GENDER:$2|al projecte}} {{SITENAME}}", - "notification-mention-email-subject": "$1 {{GENDER:$3|us}} ha {{GENDER:$2|mencionat}} en el projecte {{SITENAME}}", - "notification-user-rights-email-subject": "Els vostres permisos d'usuari han canviat a {{SITENAME}}", + "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$3|t'}} ha {{GENDER:$2|deixat}} un missatge en {{SITENAME}}", + "notification-page-linked-email-subject": "Una pàgina que {{GENDER:$3|va crear}} està enllaçada a {{SITENAME}}", + "notification-reverted-email-subject2": "{{GENDER:$3 |}} {{PLURAL:$4 | El vostre canvi s'ha revertit | Els vostres canvis s'han revertit}} {{GENDER:$2 |}} a {{SITENAME}}", + "notification-mention-email-subject": "$1 {{GENDER:$2|us}} ha {{GENDER:$3|mencionat}} en el projecte {{SITENAME}}", + "notification-user-rights-email-subject": "{{GENDER:$3|}}Els vostres drets d'usuari han canviat a {{SITENAME}}", "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1 s}}", "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1m}}", "notification-timestamp-ago-hours": "{{PLURAL:$1|$1h}}", diff --git a/Echo/i18n/ce.json b/Echo/i18n/ce.json index daf21104..8ec9140a 100644 --- a/Echo/i18n/ce.json +++ b/Echo/i18n/ce.json @@ -12,40 +12,51 @@ "prefs-echosubscriptions": "ХӀокху хиларах лаьцна хаийта", "prefs-echocrosswiki": "Кросс-вики дӀахаийтарш", "prefs-blocknotificationslist": "Ӏаьржа могӀам", + "prefs-mutedpageslist": "Тергалцайо агӀонаш", + "prefs-echopollupdates": "ДӀахаийтарш хӀинца йолу ханнахь", + "echo-mobile-notifications-filter-title": "ДӀахаийтарийн литтарг", + "echo-pref-show-poll-updates": "Керла дӀахаийтарш гайта уьш йазмадийнехь", "echo-pref-send-me": "Баийта соьга:", "echo-pref-send-to": "Хаам баийта тӀе:", "echo-pref-email-format": "Хааман формат:", "echo-pref-web": "Веб", "echo-pref-email": "Электронан пошт", + "echo-pref-push": "Push (программаш тӀехь)", "echo-pref-email-frequency-never": "Сан эл. поште ма баийта хаамаш", "echo-pref-email-frequency-immediately": "Къаьстина хаамаш тӀедаре хьаьжжина", "echo-pref-email-frequency-daily": "ХӀор денна хаам", "echo-pref-email-frequency-weekly": "ХӀор кӀиранах хаам", "echo-pref-email-format-html": "HTML", "echo-pref-email-format-plain-text": "Цхьалхе йоза", - "echo-pref-cross-wiki-notifications": "Кхечу викиш чура хаамаш гайта", + "echo-pref-cross-wiki-notifications": "Кхечу викиш чуьра хаамаш гайта", "echo-pref-notifications-blacklist": "ХӀокху декъашхошкара хаамаш ма гайта. ([[mw:Special:MyLanguage/Help:Notifications#mute|мадарра]])", + "echo-pref-notifications-page-linked-title-muted-list": "Ма гайта дӀахаийтарш \"Хьажорг агӀонгахь\" хӀокху агӀонашна. ([[mw:Special:MyLanguage/Help:Notifications#mute|мадарра]])", "echo-learn-more": "Цул совнаха хаа", "echo-log": "Массо тӀекхочу тептар", "echo-new-messages": "Хьуна кхаьчна керла хаам", - "echo-category-title-edit-user-talk": "Дийцаре агӀонехь {{PLURAL:$1|хаам|хаамаш}}", - "echo-category-title-article-linked": "АгӀона тӀе {{PLURAL:$1|хьажорг}}", - "echo-category-title-reverted": "{{PLURAL:$1|нисдар юхадаккхар|нисдарш юхадаккхар}}", + "echo-category-title-edit-user-talk": "Дийцарийн агӀонехь {{PLURAL:$1|хаам}}", + "echo-category-title-article-linked": "АгӀонан тӀе {{PLURAL:$1|хьажорг}}", + "echo-category-title-reverted": "{{PLURAL:$1|нисдар йухадаккхар|нисдарш йухадаккхар}}", "echo-category-title-mention": "{{PLURAL:$1|хаам|хаамаш}}", "echo-category-title-mention-failure": "{{PLURAL:$1|Нисцадела хьахор|Нисцадела хьахорш}}", "echo-category-title-mention-success": "{{PLURAL:$1|Кхиамца хьахор|Кхиамца хьахорш}}", - "echo-category-title-other": "{{PLURAL:$1|кхин долу|кхин дерш}}", - "echo-category-title-system": "{{PLURAL:$1|Системан}}", + "echo-category-title-other": "{{PLURAL:$1|кхидерг|кхидерш}}", + "echo-category-title-system": "{{PLURAL:$1|Системин}}", + "echo-category-title-system-noemail": "{{PLURAL:$1|1=Системин}}", "echo-category-title-system-emailonly": "{{PLURAL:$1|Система}}", "echo-category-title-user-rights": "{{PLURAL:$1|Декъашхочун бакъо хийцар|Декъашхочун бакъонаш хийцар}}", "echo-category-title-emailuser": "Кхечу {{PLURAL:$1|декъашхочунгара|декъашхошкара}} электронан пошта", "echo-category-title-article-reminder": "{{PLURAL:$1|Дагадайтаран}} агӀо", - "echo-pref-tooltip-edit-user-talk": "Хаийта соьга, цхьам хаам баийтача я сан дийцаре агӀорахь жоп делча.", - "echo-pref-tooltip-article-linked": "Хаийта соьга, цхьам ас кхоьллина агӀона тӀе хьажорг цхьан агӀонашкахь йитича.", - "echo-pref-tooltip-reverted": "Хаийта соьга, цхьам сан нисдар юха даьккхича.", - "echo-pref-tooltip-mention": "Хаийта соьга, цхьам сан долара агӀона тӀе хьажорг цхьан дийцаре агӀорахь йитича.", + "echo-category-title-thank-you-edit": "{{PLURAL:$1|ДӀакхаьчна нисдар}}", + "echo-category-title-watchlist": "Тергамехь йолу агӀонгахь нисдар", + "echo-category-title-minor-watchlist": "Тергамехь йолу агӀонгахь сан нисдар", + "echo-pref-tooltip-edit-user-talk": "Хаийта соьга, цхьам хаам баийтача йа сан дийцарийн агӀорахь жоп делча.", + "echo-pref-tooltip-article-linked": "Хаийта соьга, цхьам ас кхоьллина агӀонан тӀе хьажорг цхьан агӀонашкахь йитича.", + "echo-pref-tooltip-reverted": "Хаийта соьга, цхьам сан нисдар йуха даьккхича.", + "echo-pref-tooltip-mention": "Хаийта соьга, цхьам сан долара агӀонан тӀе хьажорг цхьан дийцарийн агӀорахь йитича.", "echo-pref-tooltip-user-rights": "Сан бакъонаш цхьаммо хийцича хаам бе соьга.", - "echo-pref-tooltip-emailuser": "Хаийта соьга, цхьам сан электронан поште яздича.", + "echo-pref-tooltip-emailuser": "Хаийта соьга, цхьам сан электронан поште йаздича.", + "echo-pref-tooltip-thank-you-edit": "Соьга хаам бе аса 1, 10, 100... нисдар дича.", "notifications": "ДӀахаийтарш", "tooltip-pt-notifications-alert": "{{GENDER:|Хьан}} дӀахаийтарш", "tooltip-pt-notifications-notice": "{{GENDER:|Хьан}} хаамаш", @@ -54,17 +65,19 @@ "echo-displaynotificationsconfiguration-notifications-by-category-header": "ДӀахаийтарш категорешкахула", "echo-displaynotificationsconfiguration-sorting-by-section-header": "Тайпанаш къастор", "echo-displaynotificationsconfiguration-available-notification-methods-header": "Шуьйра дӀахаийтарш", - "echo-displaynotificationsconfiguration-available-notification-methods-by-category-legend": "ХӀора категори чура ловш йолу дӀахаийтаран таронаш", - "echo-displaynotificationsconfiguration-enabled-default-header": "Ӏадйитаран кепаца латина ю", + "echo-displaynotificationsconfiguration-available-notification-methods-by-category-legend": "ХӀора категори чуьра ловш йолу дӀахаийтаран таронаш", + "echo-displaynotificationsconfiguration-enabled-default-header": "Ӏадйитаран кепаца латина йу", "echo-displaynotificationsconfiguration-enabled-default-existing-users-legend": "Болуш болу декъашхой", "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "Керла декъашхой", "echo-displaynotificationsconfiguration-mandatory-notification-methods-header": "Оьшуш йолу хаамийн кепаш", - "echo-displaynotificationsconfiguration-mandatory-notification-methods-by-category-legend": "ХӀора категори хила езаш йолу таронаш", + "echo-displaynotificationsconfiguration-mandatory-notification-methods-by-category-legend": "ХӀора категори хила йезаш йолу таронаш", "echo-specialpage": "ДӀахаийтарш", - "echo-specialpage-section-markread": "Тоба ешна санна билгалъе", - "echo-specialpage-markasread": "ДӀахаийтар: билгалъе ешна санна", + "echo-specialpage-section-markread": "Тоба йешна санна билгалйе", + "echo-specialpage-markasread": "ДӀахаийтар: билгалйе йешна санна", "echo-specialpage-markasread-invalid-id": "Хиламийн нийса йоцу идентификатор", + "echo-specialpage-pagefilterwidget-aria-label": "Викин а, агӀонан цӀеран а литтарг", "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|дӀахаийтар}}", + "echo-specialpage-pagination-range": "$1 - $2", "echo-specialpage-pagefilters-title": "Дукха хан йоцуш дийнарг", "echo-specialpage-pagefilters-subtitle": "Дешна доцу дӀахаийтарш долу агӀонаш", "notificationsmarkread-legend": "Билгалде дӀахаийтар дешна санна", @@ -75,43 +88,59 @@ "echo-notification-placeholder-filters": "Цхьаа дӀахаийтар дац.", "echo-notification-loginrequired": "ДӀахаийтаршка хьажа системин чугӀо", "echo-notification-popup-loginrequired": "Дехар до, дӀахаийтаршка хьажа симтемин чугӀо.", - "echo-notification-markasread": "Билгалъе ешна сана", - "echo-notification-markasunread": "Билгалъе ца ешна сана", - "echo-notification-markasread-tooltip": "Билгалъе ешна сана", - "echo-notification-more-options-tooltip": "Дукха варианташ", - "notification-link-text-expand-all": "Хьажа массаьрга", + "echo-notification-markasread": "Билгалйе йешна санна", + "echo-notification-markasunread": "Билгалйе ца-йешна санна", + "echo-notification-markasread-tooltip": "Билгалйе йешна санна", + "echo-notification-more-options-tooltip": "Дукха таронаш", + "notification-link-text-expand-all": "Схьайаста", "notification-link-text-expand-alert-count": "Гайта {{PLURAL:$1|$1 дӀахьедар}}", "notification-link-text-expand-all-count": "Гайта {{PLURAL:$1|$1 дӀахаийтар}}", - "notification-link-text-collapse-all": "Къайлаяха массо", + "notification-link-text-collapse-all": "ДӀахьарчо", "notification-link-text-view-message": "Хааме хьажар", "notification-link-text-view-mention": "Хааме хьажар", - "notification-link-text-view-changes": "Хийцаме хьажар", + "notification-link-text-view-mention-failure": "{{PLURAL:$1|Хьажа хаам}}", + "notification-link-text-view-changes": "Хийцаме {{GENDER:$1|хьажар}}", "notification-link-text-view-page": "Хьажа агӀоне", - "notification-header-edit-user-talk": "$1 {{GENDER:$2|битина}} хаам {{GENDER:$3|хьан}} дийцаре агӀонгахь.", - "notification-header-edit-user-talk-with-section": "$1 {{GENDER:$2|хаам битина}} {{GENDER:$3|хьан}} дийцаре агӀонгара «$4» дакъа тӀехь.", + "notification-header-edit-user-talk": "$1 {{GENDER:$2|битина}} хаам {{GENDER:$3|хьан}} дийцарийн агӀонгахь.", + "notification-header-edit-user-talk-with-section": "$1 {{GENDER:$2|хаам битина}} {{GENDER:$3|хьан}} дийцарийн агӀонгара «$4» дакъа тӀехь.", + "notification-compact-header-edit-user-talk": "$1 {{GENDER:$2|битина}} {{GENDER:$3|хьуна}} хаам.", + "notification-compact-header-edit-user-talk-with-section": "$1 {{GENDER:$2|битина}} {{GENDER:$3|хьуна}} хаам «<strong>$4</strong>» декъа тӀехь.", + "notification-body-edit-user-talk-with-section": "$1", "notification-header-page-linked": "Хьажорг йина <strong>$4</strong> → <strong>$3</strong>.", - "notification-compact-header-page-linked": "Уьйр ю $1", + "notification-compact-header-page-linked": "Йихкина йу $1", "notification-bundle-header-page-linked": "$4 а, $5 а агӀонаш {{PLURAL:$6|кхечу агӀон тӀера|кхечу агӀонаш тӀера}} $3 тӀе хьажийна.", "notification-link-text-what-links-here": "ХӀокху агӀонна тӀе массо хьажоргаш", - "notification-header-mention-other": "$1 {{GENDER:$2|хьахийна}} {{GENDER:$3|хьо}} <strong>$4</strong> агӀона «$5» дакъа тӀехь.", + "notification-header-mention-other": "$1 {{GENDER:$2|хьахийна}} {{GENDER:$3|хьо}} <strong>$4</strong> агӀонан «$5» дакъа тӀехь.", "notification-header-mention-other-nosection": "$1 {{GENDER:$2|хьахийна}} {{GENDER:$3|хьо}} <strong>$4</strong> агӀонгахь.", - "notification-header-mention-user-talkpage-v2": "$1 {{GENDER:$2|хьахийна}} {{GENDER:$3|хьо}} '''{{GENDER:$5|$4}}''' дийцаре агӀонгахь «$6» дакъа тӀехь.", - "notification-header-mention-user-talkpage-nosection": "$1 {{GENDER:$2|хьахийна}} {{GENDER:$3|хьо}} '''{{GENDER:$5|$4}}''' дийцаре агӀонгахь.", - "notification-header-mention-agent-talkpage": "$1 {{GENDER:$2|хьахийна}} {{GENDER:$3|хьо}} {{GENDER:$2|шен}} «$4» дийцаре агӀонгахь.", - "notification-header-mention-agent-talkpage-nosection": "$1 {{GENDER:$2|хьахийна}} {{GENDER:$3|хьо}} {{GENDER:$2|шен}} дийцаре агӀонгахь.", - "notification-header-mention-article-talkpage": "$1 {{GENDER:$2|хьахийна}} {{GENDER:$3|хьо}} «$4» дийцаре агӀона «$5» дакъа тӀехь.", - "notification-header-mention-article-talkpage-nosection": "$1 {{GENDER:$2|хьахийна}} {{GENDER:$3|хьо}} «$4» дийцаре агӀонгахь.", - "notification-header-user-rights-add-only": "{{GENDER:$4|Хьан}} декъашхо санна йолу бакъонаш {{GENDER:$1|хийцина}}. Хьо юкъатоьхна тобанна: $2.", + "notification-header-mention-user-talkpage-v2": "$1 {{GENDER:$2|хьахийна}} {{GENDER:$3|хьо}} '''{{GENDER:$5|$4}}''' дийцарийн агӀонгахь «$6» дакъа тӀехь.", + "notification-header-mention-user-talkpage-nosection": "$1 {{GENDER:$2|хьахийна}} {{GENDER:$3|хьо}} '''{{GENDER:$5|$4}}''' дийцарийн агӀонгахь.", + "notification-header-mention-agent-talkpage": "$1 {{GENDER:$2|хьахийна}} {{GENDER:$3|хьо}} {{GENDER:$2|шен}} «$4» дийцарийн агӀонгахь.", + "notification-header-mention-agent-talkpage-nosection": "$1 {{GENDER:$2|хьахийна}} {{GENDER:$3|хьо}} {{GENDER:$2|шен}} дийцарийн агӀонгахь.", + "notification-header-mention-article-talkpage": "$1 {{GENDER:$2|хьахийна}} {{GENDER:$3|хьо}} «$4» дийцарийн агӀонан «$5» дакъа тӀехь.", + "notification-header-mention-article-talkpage-nosection": "$1 {{GENDER:$2|хьахийна}} {{GENDER:$3|хьо}} «$4» дийцарийн агӀонгахь.", + "notification-compact-header-mention-failure-user-unknown": "<strong>Декъашхочун цӀе йан а йац:</strong> $1", + "notification-compact-header-mention-failure-user-anonymous": "<strong>IP-адресаш хьахо аьтту бац:</strong> $1", + "notification-header-mention-success": "{{GENDER:$2|Ахьа}} {{GENDER:$3|декъашхо}} хьахор <strong>$3</strong> дӀадахьийтина.", + "notification-header-mention-success-bundle": "Кху <strong>$4</strong> дийцарийн агӀонгахь {{GENDER:$2|ахьа}} {{PLURAL:$3|хьахор}}, {{PLURAL:$3|дӀадахьийтина}}.", + "notification-compact-header-mention-success": "<strong>{{GENDER:$2|Ахьа хьахийна}}:</strong> $3", + "notification-header-user-rights-add-only": "{{GENDER:$4|Хьан}} декъашхо санна йолу бакъонаш {{GENDER:$1|хийцина}}. Хьо йукъатоьхна тобанна: $2.", + "notification-header-mention-summary": "$1 {{GENDER:$3|хьо}} {{GENDER:$2|хьахийна}} <strong>$4</strong> декъа тӀехь.", "notification-welcome-linktext": "Марша догӀийла", "notification-header-thank-you-1-edit": "Маршалла, {{GENDER:$2|ахьа}} хӀинца дина {{GENDER:$2|хьай}} духхьара нисдар. Баркалла {{GENDER:$2|хьуна}}!", + "notification-header-thank-you-10-edit": "{{GENDER:$2|Ахьа}} хӀинца дина {{GENDER:$2|хьайн}} итталгӀа нисдар. Баркалла!", + "notification-header-thank-you-100-edit": "{{GENDER:$2|Ахьа}} хӀинца дина {{GENDER:$2|хьайн}} бӀоалгӀа нисдар. Баркалла!", + "notification-header-thank-you-1000-edit": "{{GENDER:$2|Ахьа}} хӀинца дина {{GENDER:$2|хьайн}} эзарлагӀа нисдар. Баркалла!", + "notification-header-thank-you-10000-edit": "{{GENDER:$2|Ахьа}} хӀинца дина {{GENDER:$2|хьайн}} итт эзарлагӀа нисдар. Баркалла!", + "notification-header-thank-you-100000-edit": "{{GENDER:$2|Ахьа}} хӀинца дина {{GENDER:$2|хьайн}} бӀе эзарлагӀа нисдар. Баркалла!", + "notification-header-thank-you-1000000-edit": "{{GENDER:$2|Ахьа}} хӀинца дина {{GENDER:$2|хьайн}} миллионалгӀа нисдар. Баркалла!", "notification-link-thank-you-edit": "{{GENDER:$1|Хьан}} нисдар", "notification-link-text-view-edit": "Нисдаре хьажар", "notification-link-article-reminder": "АгӀоне хьажар", - "notification-header-reverted": "{{PLURAL:$4|АгӀонехь $3 хьан нисдар}} {{GENDER:$2|юхадаькхина}}.", + "notification-header-reverted": "{{PLURAL:$4|АгӀонехь $3 хьан нисдар}} {{GENDER:$2|йухадаькхина}}.", "notification-header-emailuser": "$1 {{GENDER:$2|баийтина}} хьога хаам.", "notification-edit-talk-page-email-subject2": "{{GENDER:$2|Декъашхочо}} $1 «{{SITENAME}}» сайтехь хьуна хаам {{GENDER:$2|биттина}}", "notification-page-linked-email-subject": "«{{SITENAME}}» сайтехь ахьа кхоьллина агӀона тӀе хьажорг хӀоттина", - "notification-reverted-email-subject2": "{{GENDER:$2|Цхьам}} «{{SITENAME}}» сайтехь хьан {{PLURAL:$4|нисдар юхадаькхина|нисдарш юхадаьхина}}", + "notification-reverted-email-subject2": "{{GENDER:$2|Цхьам}} «{{SITENAME}}» сайтехь хьан {{PLURAL:$4|нисдар йухадаькхина|нисдарш йухадаьхна}}", "notification-mention-email-subject": "$1 {{GENDER:$2|Декъашхочо}} «{{SITENAME}}» сайтехь {{GENDER:$3|хьо}} хьахийна", "notification-user-rights-email-subject": "Сайтехь «{{SITENAME}}» хьан бакъонаш хийцина", "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1 с}}", @@ -122,30 +151,38 @@ "notification-timestamp-ago-years": "{{PLURAL:$1|$1 ш.}}", "notification-timestamp-today": "Тахана", "notification-timestamp-yesterday": "Селхана", - "notification-inbox-filter-read": "Ешар", - "notification-inbox-filter-unread": "Ца ешнарш", + "notification-inbox-filter-read": "Йешнарш", + "notification-inbox-filter-unread": "Йешазайерш", "notification-inbox-filter-all": "Массо", "echo-specialmute-label-mute-notifications": "ХӀокху декъашхочунгара хаамаш дӀабайа", "echo-email-html-footer-preference-link-text": "хьажа {{GENDER:$1|хьайн}} нисдаран гӀирсе", - "echo-email-html-footer-with-link": "Оха {{GENDER:$2|хьайга}} кхоьхьуьйтуш болу хаамашна контроль ян $1.", + "echo-email-html-footer-with-link": "Оха {{GENDER:$2|хьайга}} кхоьхьуьйтуш болу хаамашна контроль йан $1.", "echo-notification-alert": "{{PLURAL:$1|ДӀахьедар ($1)|100=ДӀахьедар (99+)}}", "echo-notification-notice": "{{PLURAL:$1|Хаамаш ($1)|100=Хаамаш (99+)}}", "echo-notification-alert-text-only": "ДӀахаийтарш", "echo-notification-notice-text-only": "Хаамаш", "echo-overlay-link": "Массо хаамаш", "echo-overlay-title": "<b>Хаамаш</b>", - "echo-mark-all-as-read": "Массо билгалъе ешна сана", - "echo-mark-wiki-as-read": "Хаьржинчу вики чура ерриге ешна санна билгалъе: $1", + "echo-mark-all-as-read": "Йерриге билгалйе йешна санна", + "echo-mark-all-as-read-confirmation": "$1 {{PLURAL:$1|хаам бешна санна билгалбина}}", + "echo-mark-wiki-as-read": "Хаьржинчу вики чуьра йерриге йешна санна билгалйе: $1", "echo-displaysnippet-title": "Керла хаам", "echo-date-today": "Тахана", "echo-date-yesterday": "Селхана", - "notification-bundle-header-edit-user-talk-v2": "{{PLURAL:$1|керла хаам бу}} <strong>{{GENDER:$3|хьан}} дийцаре агӀонгахь</strong>.", + "notification-bundle-header-edit-user-talk-v2": "{{PLURAL:$1|керла хаам бу}} <strong>{{GENDER:$3|хьан}} дийцарийн агӀонгахь</strong>.", + "echo-email-batch-bullet": "•", "echo-email-batch-subject-daily": "Хьоьга кхаьчна $2 {{PLURAL:$2|керла хаам|керла хаамаш}} «{{SITENAME}}» проектехь", "echo-email-batch-subject-weekly": "ХӀокху кӀиран чохь хьоьга кхаьчна $2 {{PLURAL:$2|керла хаам|керла хаамаш}} «{{SITENAME}}» проектехь", "echo-email-batch-body-intro-daily": "Маршалла, $1!\nТахан хилларг {{SITENAME}}.", "echo-email-batch-body-intro-weekly": "Маршалла, $1!\nТахан хилларг {{SITENAME}}.", "echo-email-batch-link-text-view-all-notifications": "Массо хаамашка хьажар", - "notification-header-foreign-alert": "Дукха дӀахьедарш {{PLURAL:$5|кхечу вики чура|$5 кхечу викеш чура}}", - "notification-header-foreign-notice": "Дукха хаамаш {{PLURAL:$5|кхечу вики чура|$5 кхечу викеш чура}}", - "notification-header-foreign-all": "Дукха дӀахьедарш {{PLURAL:$5|кхечу вики чура|$5 кхечу викеш чура}}" + "notification-header-foreign-alert": "Дукха дӀахьедарш {{PLURAL:$5|кхечу вики чуьра|$5 кхечу викеш чуьра}}", + "notification-header-foreign-notice": "Дукха хаамаш {{PLURAL:$5|кхечу вики чуьра|$5 кхечу викеш чуьра}}", + "notification-header-foreign-all": "Дукха дӀахьедарш {{PLURAL:$5|кхечу вики чуьра|$5 кхечу викеш чуьра}}", + "echo-foreign-wiki-lang": "$1 - $2", + "right-manage-all-push-subscriptions": "Массо push-хаамийн урхалла", + "action-manage-all-push-subscriptions": "массо push-хаамийн урхалла", + "group-push-subscription-manager": "Push-хаамийн урхалча", + "group-push-subscription-manager-member": "{{GENDER:$1|push-хаамийн урхалча}}", + "grouppage-push-subscription-manager": "{{ns:project}}:push-хаамийн урхалча" } diff --git a/Echo/i18n/ckb.json b/Echo/i18n/ckb.json index 80c0d6e1..8d068703 100644 --- a/Echo/i18n/ckb.json +++ b/Echo/i18n/ckb.json @@ -1,6 +1,7 @@ { "@metadata": { "authors": [ + "Aram", "Asoxor", "Calak", "Lost Whispers", @@ -16,7 +17,7 @@ "prefs-emailsettings": "ھەڵبژاردەکانی ئیمەیل", "prefs-echosubscriptions": "سەبارەت بەم ڕووداوانە ئاگادارم بکە", "prefs-echocrosswiki": "ھۆشداری سەرانسەری", - "prefs-blocknotificationslist": "بەکارھێنەرە بێدەنگکراوەکان", + "prefs-blocknotificationslist": "بەکارھێنەرە کپکراوەکان", "prefs-echopollupdates": "ھۆشدارە ڕاستەوخۆکان", "echo-mobile-notifications-filter-title": "پاڵاوتنی ھۆشدارەکان", "echo-pref-send-me": "بۆم بنێرە:", @@ -24,6 +25,7 @@ "echo-pref-email-format": "جۆری ئیمەیل:", "echo-pref-web": "وێب", "echo-pref-email": "ئیمەیل", + "echo-pref-push": "ئەپلیکەیشنەکان", "echo-pref-email-frequency-never": "ھیچ ئاگاداراییەکم بە ئیمەیل بۆ مەنێرە", "echo-pref-email-frequency-immediately": "ھەر ئەو کاتەی کە تاکە ئاگادارییەکم بۆ دێت", "echo-pref-email-frequency-daily": "ڕۆژێک جارێک، پوختەیەکی ئاگادارییەکان", @@ -34,7 +36,7 @@ "echo-pref-notifications-blacklist": "ھۆشداری ئەم بەکارھێنەرانە پیشان مەدە.\n([[mw:Special:MyLanguage/Help:Notifications#mute|زیاتر بزانە]])", "echo-learn-more": "زۆرتر بزانە", "echo-log": "لۆگی گشتی", - "echo-new-messages": "پەیامی نوێت ھەیە", + "echo-new-messages": "پەیامێکی نوێی پەڕەی لێدوانت ھەیە", "echo-category-title-edit-user-talk": "{{PLURAL:$1|پەیام|پەیامەکان}}ی پەڕەی لێدوان", "echo-category-title-article-linked": "{{PLURAL:$1|بەستەر|بەستەرەکان}}ی پەڕە", "echo-category-title-reverted": "{{PLURAL:$1|گەڕاندنەوە|گەڕاندنەوەکان}}ی دەستکاری", @@ -49,7 +51,7 @@ "echo-category-title-emailuser": "{{PLURAL:$1|ئیمێل لە بەکارھێنەرێکی ترەوە|ئیمێلەکان لە بەکارھێنارانی ترەوە}}", "echo-category-title-article-reminder": "{{PLURAL:$1|بیرھێنانەوەی پەڕەکە|بیرھێنانەوەی پەڕەکان}}", "echo-category-title-thank-you-edit": "{{PLURAL:$1|ئاماژەدەر|ئاماژەدەرەکان}}ی دەستکاری", - "echo-pref-tooltip-edit-user-talk": "کاتێک کەسێک لە پەڕەی لێدوانمدا پەیامێکی نارد یان وەڵامی دامەوە، ئاگادارم بکە.", + "echo-pref-tooltip-edit-user-talk": "کاتێک کەسێک دەستکاریی پەڕەی لێدوانەکەم دەکات، ئاگادارم بکە.", "echo-pref-tooltip-article-linked": "ئاگادارم بکەرەوە کاتێک یەکێک لە پەڕەیەکەوە بەستەر دەدات بە پەڕەیەک کە من دروستم کردووە.", "echo-pref-tooltip-reverted": "کاتێک کەسێک دەستکارییەکی من کردوومە بە ئامرازی پووچەڵکردنەوە یان گەڕاندنەوە دەگەڕێنێتەوە، ئاگادارم بکە.", "echo-pref-tooltip-mention": "ئاگادارم بکەرەوە، ئەگەر کەسێک بۆ پەڕەی بەکارھێنەریی من بەستەری دانا.", @@ -70,34 +72,36 @@ "echo-specialpage": "ئاگادارییەکان", "echo-specialpage-section-markread": "کۆمەڵەکە وەک خوێندراوە نیشانی بکە", "echo-specialpage-markasread": "ھۆشدار: وەک خوێندراوە نیشانی بکە", - "echo-specialpage-pagination-numnotifications": "بینینی $1 ھۆشدار", + "echo-specialpage-pagination-numnotifications": "$1 ھۆشدار", "echo-specialpage-pagination-range": "$1 - $2", "echo-specialpage-pagefilters-title": "چالاکیی تازە", "echo-specialpage-pagefilters-subtitle": "پەڕەکانی ئاگادارییە نەخوێندراوەکان", "notificationsmarkread-legend": "دیاریکردنی ھۆشدار وەک خوێنراوە", "echo-none": "ھیچ ئاگادارییەکت نییە.", "echo-notification-placeholder": "ھیچ ئاگادارییەک نییە.", + "echo-notification-placeholder-filters": "ھیچ ھۆشدارێک نییە لەگەڵ ئەم پێوەرانەدا بگونجێت.", "echo-notification-loginrequired": "دەبێت بچیتە ژوورەوە بۆ بینینی ھۆشدارەکانت.", "echo-notification-popup-loginrequired": "تکایە بچۆ ژوورەوە بۆ بینینی ھۆشدارەکانت.", "echo-notification-markasread": "نیشانکردن وەکوو خوێنراو", "echo-notification-markasunread": "نیشانکردن وەکوو نەخوێنراوە", "echo-notification-markasread-tooltip": "نیشانکردن وەکوو خوێنراو", "echo-notification-more-options-tooltip": "ھەڵبژاردەی زیاتر", - "notification-dynamic-actions-unwatch": "ڕاگرتنی چاودێری لەسەر «$1»", - "notification-dynamic-actions-unwatch-confirmation": "پەڕەی «$1» لە پێڕستی چاودێریت دەرکرا", - "notification-dynamic-actions-watch-confirmation": "ئێستا چاودێری پەڕەی «$1» دەکەیت", + "notification-dynamic-actions-unwatch": "لە چاودێریکردنی چالاکیی نوێی «$1» {{GENDER:$3|بوەستە}}", + "notification-dynamic-actions-unwatch-confirmation": "پەڕەی «$1» لە {{GENDER:$3|پێڕستی چاودێریت}} دەرکرا", + "notification-dynamic-actions-watch-confirmation": "ئێستا چاودێریی پەڕەی «$1» {{GENDER:$3|دەکەیت}}", "notification-dynamic-actions-watch-confirmation-description": "دەتوانیت ھەر کاتێک ویستت [$2 ئەم پەڕەیە] لە پێڕستی چاودێریت دەربکەیت.", "notification-link-text-expand-all": "بڵاوکردنەوە", - "notification-link-text-expand-alert-count": "بینینی {{PLURAL:$1|$1 ئاگاداری|$1 ئاگاداری}}", + "notification-link-text-expand-alert-count": "بینینی $1 ئاگاداری", "notification-link-text-expand-notice-count": "بینینی $1 ھۆشدار", + "notification-link-text-expand-all-count": "بینینی $1 ھۆشدار", "notification-link-text-collapse-all": "کۆکردنەوە", "notification-link-text-view-message": "پەیام ببینە", "notification-link-text-view-mention": "ئاماژە ببینە", "notification-link-text-view-mention-failure": "{{PLURAL:$1|بینینی بانگکردن|بینینی بانگکردنەکان}}", "notification-link-text-view-changes": "{{GENDER:$1|دەستکارییەکانی ببینە}}", "notification-link-text-view-page": "پەڕە ببینە", - "notification-header-edit-user-talk": "$1 پەیامێکی لەسەر <strong>پەڕەی وتووێژەکەت</strong> دانا.", - "notification-header-edit-user-talk-with-section": "$1 پەیامێکی لەسەر <strong>پەڕەی وتووێژەکەت</strong> دانا لە «<strong>$4</strong>»", + "notification-header-edit-user-talk": "$1 پەیامێکی لەسەر <strong>{{GENDER:$3|پەڕەی لێدوانەکەت}} {{GENDER:$2|دانا}}</strong>.", + "notification-header-edit-user-talk-with-section": "$1 لە «<strong>$4</strong>» پەیامێکی لەسەر <strong>{{GENDER:$3|پەڕەی لێدوانەکەت}}</strong> {{GENDER:$2|دانا}}.", "notification-compact-header-edit-user-talk": "$1 پەیامێکی بۆ {{GENDER:$2|نارد}}{{GENDER:$3|یت}}.", "notification-compact-header-edit-user-talk-with-section": "$1 پەیامێکی لە «<strong>$4</strong>» بۆ ناردی.", "notification-header-page-linked": "بەستەرێک لە <strong>$4</strong>ەوە بۆ <strong>$3</strong> درا.", @@ -141,7 +145,7 @@ "notification-page-linked-email-subject": "پەڕەکەت لە {{SITENAME}}دا بەستەر درا.", "notification-reverted-email-subject2": "{{PLURAL:$4|دەستکارییەکەت|دەستکارییەکانت}} لە {{SITENAME}}دا {{GENDER:$2|گەڕێنرایەوە}}", "notification-mention-email-subject": "$1 لە {{SITENAME}}دا ئاماژەی پێکردی.", - "notification-user-rights-email-subject": "مافەکانی بەکارھێنەریت لە {{SITENAME}}دا گۆڕدرا.", + "notification-user-rights-email-subject": "{{GENDER:$3|مافەکانی بەکارھێنەریت}} لە {{SITENAME}}دا گۆڕدرا", "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1چ}}", "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1خ}}", "notification-timestamp-ago-hours": "{{PLURAL:$1|$1س}}", @@ -153,7 +157,7 @@ "notification-inbox-filter-read": "خوێندنەوە", "notification-inbox-filter-unread": "نەخوێنراوە", "notification-inbox-filter-all": "ھەموو", - "echo-specialmute-label-mute-notifications": "ھۆشدارەکان لەم بەکارھێنەرەوە کپ بکە", + "echo-specialmute-label-mute-notifications": "ھۆشدارەکان {{GENDER:$1|لەم بەکارھێنەرەوە}} کپ بکە", "echo-email-plain-footer": "بۆ کۆنترۆڵکردنی ئەو پۆستە ئەلیکترۆنییانەی بۆتی دەنێرین، سەیری ھەڵبژاردەکانت بکە:", "echo-email-html-footer-preference-link-text": "{{GENDER:$1|ھەڵبژاردەکانت}} ببینە", "echo-email-html-footer-with-link": "بۆ کۆنترۆڵکردنی ئەو پۆستە ئەلیکترۆنییانەی بۆتی دەنێرین، $1.", @@ -172,6 +176,8 @@ "echo-email-batch-body-intro-daily": "سڵاو $1،\nئەمە کۆرتەیەکە لە چالاکییەکانی ئەمرۆی {{SITENAME}} بۆ تۆ.", "echo-email-batch-body-intro-weekly": "سڵاو $1،\nئەمە کۆرتەیەکە لە چالاکییەکانی حەفتانەی {{SITENAME}} بۆ تۆ.", "echo-email-batch-link-text-view-all-notifications": "ھەموو ئاگادارییەکان ببینە", - "notification-header-foreign-alert": "ئاگاداری زیاتر لە ویکی تر", + "notification-header-foreign-alert": "ئاگاداریی زیاتر لە {{PLURAL:$5|ویکییەکی ترەوە|$5 ویکیی ترەوە}}", + "notification-header-foreign-notice": "ھۆشداری زیاتر لە {{PLURAL:$5|ویکییەکی ترەوە|$5 ویکیی ترەوە}}", + "notification-header-foreign-all": "ھۆشداری زیاتر لە {{PLURAL:$5|ویکییەکی ترەوە|$5 ویکیی ترەوە}}", "echo-foreign-wiki-lang": "$1 - $2" } diff --git a/Echo/i18n/cop.json b/Echo/i18n/cop.json new file mode 100644 index 00000000..21234de5 --- /dev/null +++ b/Echo/i18n/cop.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Bloomaround" + ] + }, + "tooltip-pt-notifications-alert": "{{GENDER:|ⲛⲉⲧⲉⲛ}}ϫⲓⲛϭⲓⲟⲩⲱ" +} diff --git a/Echo/i18n/crh-latn.json b/Echo/i18n/crh-latn.json new file mode 100644 index 00000000..eb148e2e --- /dev/null +++ b/Echo/i18n/crh-latn.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "TayfunEt." + ] + }, + "echo-new-messages": "Yañı bir beyanatıñız bar", + "notifications": "Bildirimler", + "notification-bundle-header-edit-user-talk-v2": "{{PLURAL:$1|Yañı bir beyanat|$1 yañı beyanat|100=99+ yañı beyanat}} <strong>{{GENDER:$3|sizin}} muzakere saifeñizde tapıla</strong>.", + "echo-email-batch-link-text-view-all-notifications": "Bütün bildirimlerge qarañız" +} diff --git a/Echo/i18n/cs.json b/Echo/i18n/cs.json index 938ca767..62c24847 100644 --- a/Echo/i18n/cs.json +++ b/Echo/i18n/cs.json @@ -14,6 +14,7 @@ "Mormegil", "MrJaroslavik", "Patriccck", + "Patrik L.", "Teslaton", "Vks" ] @@ -34,7 +35,7 @@ "echo-pref-email-format": "Formát e-mailu:", "echo-pref-web": "Web", "echo-pref-email": "E-mail", - "echo-pref-push": "Push (jen aplikace)", + "echo-pref-push": "Aplikace", "echo-pref-email-frequency-never": "Neposílejte mi žádná upozornění e-mailem", "echo-pref-email-frequency-immediately": "Jednotlivá upozornění, jakmile se objeví", "echo-pref-email-frequency-daily": "Denní souhrn upozornění", @@ -47,8 +48,8 @@ "echo-pref-dont-email-read-notifications": "V souhrnech neposílat přečtená upozornění", "echo-learn-more": "Další informace", "echo-log": "Veřejný záznam", - "echo-new-messages": "Máte nové zprávy", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|příspěvek|příspěvky}} na diskusní stránce", + "echo-new-messages": "Máte novou zprávu na diskusní stránce", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|editaci|editace}} mé diskusní stránky", "echo-category-title-article-linked": "{{PLURAL:$1|odkaz|odkazy}} na vytvořenou stránku", "echo-category-title-reverted": "{{PLURAL:$1|vrácenou úpravu|vrácené úpravy}}", "echo-category-title-mention": "{{PLURAL:$1|zmínku|zmínky}}", @@ -64,7 +65,7 @@ "echo-category-title-thank-you-edit": "editační {{PLURAL:$1|milník|milníky}}", "echo-category-title-watchlist": "editaci sledované stránky", "echo-category-title-minor-watchlist": "malou editaci sledované stránky", - "echo-pref-tooltip-edit-user-talk": "Upozorněte mě, když mi někdo na mé diskusní stránce napíše zprávu nebo odpoví.", + "echo-pref-tooltip-edit-user-talk": "Upozorněte mě, když někdo upraví moji uživatelskou diskusní stránku.", "echo-pref-tooltip-article-linked": "Upozorněte mě, když někdo na stránku, kterou jsem {{GENDER:|založil|založila}}, odkáže z jiné stránky.", "echo-pref-tooltip-reverted": "Upozorněte mě, když někdo úpravu, kterou jsem {{GENDER:|provedl|provedla}}, vrátí pomocí nástrojů pro zrušení editace nebo vrácení zpět.", "echo-pref-tooltip-mention": "Upozorněte mě, když někdo odkáže na mou uživatelskou stránku.", @@ -168,6 +169,16 @@ "notification-header-user-rights-expiry-change": "Čas vypršení {{GENDER:$4|vašeho}} členství v {{PLURAL:$3|následující skupině|následujících skupinách}} byl {{GENDER:$1|změněn}}: $2.", "notification-header-welcome": "Vítejte na {{GRAMMAR:6sg|{{SITENAME}}}}, {{GENDER:$2|uživateli|uživatelko}} $1! Jsme rádi, že jste zde.", "notification-header-mention-summary": "$1 {{GENDER:$3|vás}} {{GENDER:$2|zmínil|zmínila}} ve shrnutí editace stránky <strong>$4</strong>.", + "notification-header-watchlist-changed": "$1 {{GENDER:$2|změnil|změnila|změnil}} <strong>$3</strong>, stránku na {{GENDER:$4|vašem}} seznamu sledovaných stránek{{PLURAL:$5||, $5krát}}.", + "notification-header-watchlist-created": "$1 {{GENDER:$2|založil|založila|založil}} <strong>$3</strong>, stránku na {{GENDER:$4|vašem}} seznamu sledovaných stránek{{PLURAL:$5||, $5krát}}.", + "notification-header-watchlist-deleted": "$1 {{GENDER:$2|smazal|smazala|smazal}} <strong>$3</strong>, stránku na {{GENDER:$4|vašem}} seznamu sledovaných stránek{{PLURAL:$5||, $5krát}}.", + "notification-header-watchlist-moved": "$1 {{GENDER:$2|přesunul|přesunula|přesunul}} <strong>$3</strong>, stránku na {{GENDER:$4|vašem}} seznamu sledovaných stránek{{PLURAL:$5||, $5krát}}.", + "notification-header-watchlist-restored": "$1 {{GENDER:$2|obnovil|obnovila|obnovil}} <strong>$3</strong>, stránku na {{GENDER:$4|vašem}} seznamu sledovaných stránek{{PLURAL:$5||, $5krát}}.", + "notification-header-watchlist-multiuser-changed": "<strong>$1</strong>, stránka na {{GENDER:$2|vašem}} seznamu sledovaných stránek, byla {{PLURAL:$3|jednou|$3krát}} změněna.", + "notification-header-watchlist-multiuser-created": "<strong>$1</strong>, stránka na {{GENDER:$2|vašem}} seznamu sledovaných stránek, byla {{PLURAL:$3|jednou|$3krát}} založena.", + "notification-header-watchlist-multiuser-deleted": "<strong>$1</strong>, stránka na {{GENDER:$2|vašem}} seznamu sledovaných stránek, byla {{PLURAL:$3|jednou|$3krát}} smazána.", + "notification-header-watchlist-multiuser-moved": "<strong>$1</strong>, stránka na {{GENDER:$2|vašem}} seznamu sledovaných stránek, byla {{PLURAL:$3|jednou|$3krát}} přesunuta.", + "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>, stránka na {{GENDER:$2|vašem}} seznamu sledovaných stránek, byla {{PLURAL:$3|jednou|$3krát}} obnovena.", "notification-welcome-linktext": "Vítejte", "notification-header-thank-you-1-edit": "Právě jste {{GENDER:$2|provedl|provedla}} svou první editaci. Děkujeme a vítejte!", "notification-header-thank-you-10-edit": "Právě jste {{GENDER:$2|provedl|provedla}} svou desátou editaci. Díky a jen tak dál!", @@ -198,7 +209,7 @@ "notification-inbox-filter-read": "Přečtená", "notification-inbox-filter-unread": "Nepřečtená", "notification-inbox-filter-all": "Všechna", - "echo-specialmute-label-mute-notifications": "Ignorovat upozornění od tohoto uživatele", + "echo-specialmute-label-mute-notifications": "Ignorovat upozornění od {{GENDER:$1|tohoto uživatele|této uživatelky}}", "echo-email-plain-footer": "Posílání e-mailů si {{GENDER:$1|můžete}} přizpůsobit v nastavení:", "echo-email-html-footer-preference-link-text": "{{GENDER:$1|nastavení}}", "echo-email-html-footer-with-link": "Posílání e-mailů si {{GENDER:$2|můžete}} přizpůsobit v $1.", diff --git a/Echo/i18n/csb.json b/Echo/i18n/csb.json index a7266e5d..afcbc7ba 100644 --- a/Echo/i18n/csb.json +++ b/Echo/i18n/csb.json @@ -1,9 +1,11 @@ { "@metadata": { "authors": [ - "Kaszeba" + "Kaszeba", + "Kirsan" ] }, "tooltip-pt-notifications-alert": "Mòjé alarmë", + "tooltip-pt-notifications-notice": "Mòje kòmùnikatë", "notification-link-article-reminder": "Òbôczë starnã" } diff --git a/Echo/i18n/cu.json b/Echo/i18n/cu.json index 98778d0e..662715ba 100644 --- a/Echo/i18n/cu.json +++ b/Echo/i18n/cu.json @@ -1,12 +1,14 @@ { "@metadata": { "authors": [ + "NR Deblocked", "ОйЛ" ] }, "echo-learn-more": "поꙁнаи вѧщє", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|напьсаниѥ|напьсании|напьсаниꙗ}} бєсѣдꙑ страницѣ", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Комментарїй|Комментарїи}} на мое́й страни́цѣ ѻбсꙋжденїѧ пользователѧ", "echo-category-title-system": "{{PLURAL:$1|сѷстима}}", + "echo-pref-tooltip-edit-user-talk": "Оуведомлѧть менѧ когда̀ кто̀-то̀ пꙋбликꙋетъ соѻбще́нїе и҆лѝ ѻтвечаетъ на мое́й страни́цѣ ѻбсꙋжденїѧ пользователѧ.", "tooltip-pt-notifications-alert": "{{GENDER:|твоѩ}} повѣщєниꙗ", "notification-header-edit-user-talk-with-section": "$1 {{GENDER:$2|напьса}} на <strong>{{GENDER:$3|твоѥи}}</strong> бєсѣдꙑ страници въ чѧсти ⁖ <strong>$4</strong> ⁖", "echo-date-today": "дьньсь", diff --git a/Echo/i18n/da.json b/Echo/i18n/da.json index 52dfd0e4..d45a3afe 100644 --- a/Echo/i18n/da.json +++ b/Echo/i18n/da.json @@ -4,6 +4,7 @@ "Byrial", "Cgtdk", "Christian List", + "Dipsacus fullonum", "EeveeSylveon", "Macofe", "Palnatoke", @@ -22,6 +23,7 @@ "prefs-echosubscriptions": "Giv mig en meddelelse ved følgende hændelser", "prefs-echocrosswiki": "Interwiki-meddelelser", "prefs-blocknotificationslist": "Ignorerede brugere", + "prefs-mutedpageslist": "Ignorerede sider", "prefs-echopollupdates": "Live-notifikationer", "echo-mobile-notifications-filter-title": "Filtrér notifikationer", "echo-pref-show-poll-updates": "Vis nye notifikationer så snart de kommer", @@ -39,10 +41,11 @@ "echo-pref-email-format-plain-text": "Uformateret tekst", "echo-pref-cross-wiki-notifications": "Vis meddelelser fra andre wikier", "echo-pref-notifications-blacklist": "Vis ikke beskeder (notifikationer) fra disse brugere. ([[mw:Special:MyLanguage/Help:Notifications#mute|læs mere]])", + "echo-pref-notifications-page-linked-title-muted-list": "Vis ikke beskeder (notifikationer), når der linkes til disse sider, jeg har oprettet. ([[mw:Special:MyLanguage/Help:Notifications#mute|læs mere]])", "echo-learn-more": "Find ud af mere", "echo-log": "Offentlig log", "echo-new-messages": "Du har nye beskeder", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Besked|Beskeder}} på diskussionsside", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Besked|Beskeder}} på min brugerdiskussionsside", "echo-category-title-article-linked": "{{PLURAL:$1|Sidehenvisning|Sidehenvisninger}}", "echo-category-title-reverted": "Tilbagestilling af {{PLURAL:$1|redigering|redigeringer}}", "echo-category-title-mention": "{{PLURAL:$1|Omtale|Omtaler}}", @@ -55,7 +58,7 @@ "echo-category-title-user-rights": "{{PLURAL:$1|Ændring af brugerrettighed|Ændring af brugerrettigheder}}", "echo-category-title-emailuser": "{{PLURAL:$1|E-mail fra anden bruger|E-mails fra andre brugere}}", "echo-category-title-thank-you-edit": "{{PLURAL:$1|Milepæl|Milepæle}}", - "echo-pref-tooltip-edit-user-talk": "Giv mig besked, når nogen skriver en besked eller et svar på min diskussionsside.", + "echo-pref-tooltip-edit-user-talk": "Giv mig besked, når nogen skriver en besked eller et svar på min brugerdiskussionsside.", "echo-pref-tooltip-article-linked": "Giv mig besked, når nogen henviser til en side, som jeg har oprettet, fra en artikelside.", "echo-pref-tooltip-reverted": "Giv mig besked, når nogen tilbagestiller en redigering, som jeg lavet, ved at bruge \"fjern redigering\" eller \"rul tilbage\".", "echo-pref-tooltip-mention": "Giv mig besked når nogen henviser til min brugerside.", @@ -99,7 +102,7 @@ "notification-header-mention-other": "$1 {{GENDER:$2|nævnte}} {{GENDER:$3|dig}} på <strong>$4</strong> i \"<strong>$5</strong>\".", "notification-header-mention-other-nosection": "$1 {{GENDER:$2|nævnte}} {{GENDER:$3|dig}} på <strong>$4</strong>.", "notification-header-mention-user-talkpage-v2": "$1 {{GENDER:$2|nævnte}} {{GENDER:$3|dig}} på <strong>brugerdiskussionssiden {{GENDER:$5|for}} $4</strong> i \"<strong>$6</strong>\".", - "notification-header-mention-agent-talkpage": "$1 {{GENDER:$2|nævnte}} {{GENDER:$3|dig}} på <strong>{{GENDER:$2|sin|sin|deres}} diskussionsside</strong> under \"<strong>$4</strong>\".", + "notification-header-mention-agent-talkpage": "$1 {{GENDER:$2|nævnte}} {{GENDER:$3|dig}} på <strong>{{GENDER:$2|sin|sin|sin}} diskussionsside</strong> under \"<strong>$4</strong>\".", "notification-header-mention-agent-talkpage-nosection": "$1 {{GENDER:$2|nævnte}} {{GENDER:$3|dig}} på <strong>{{GENDER:$2|sin|sin|sin}} diskussionsside</strong>.", "notification-header-mention-article-talkpage": "$1 {{GENDER:$2|nævnte}} {{GENDER:$3|dig}} på <strong>$4</strong>s diskussionsside i \"<strong>$5</strong>\".", "notification-compact-header-mention-failure-user-unknown": "<strong>Brugernavnet findes ikke:</strong> $1", diff --git a/Echo/i18n/de-formal.json b/Echo/i18n/de-formal.json index ff5b7db9..0f78b2be 100644 --- a/Echo/i18n/de-formal.json +++ b/Echo/i18n/de-formal.json @@ -7,5 +7,6 @@ "echo-new-messages": "Sie haben neue Nachrichten", "tooltip-pt-notifications-alert": "{{GENDER:|Ihre}} Meldungen", "echo-none": "Sie haben in letzter Zeit keine Benachrichtigungen erhalten.", + "notification-header-welcome": "{{GENDER:$2|Willkommen}} bei {{SITENAME}}, $1! Wir freuen uns, dass {{GENDER:$2|Sie}} da sind.", "notification-user-rights-email-subject": "Ihre Benutzerrechte auf „{{SITENAME}}“ wurden geändert." } diff --git a/Echo/i18n/de.json b/Echo/i18n/de.json index afe3acf5..642a0684 100644 --- a/Echo/i18n/de.json +++ b/Echo/i18n/de.json @@ -1,12 +1,15 @@ { "@metadata": { "authors": [ + "Brettchenweber", "ChrisiPK", "DerHexer", "FriedhelmW", + "Inkowik", "Kghbln", "Lucas Werkmeister", "MGChecker", + "McDutchie", "Metalhead64", "PiefPafPier", "Predatorix", @@ -16,11 +19,14 @@ "TMg", "Tiin", "Tobi 406", - "Vogone" + "Umherirrender", + "Vogone", + "Wnme" ] }, "echo-desc": "Erweitert das Wiki um ein System zur Benachrichtigung von Benutzern zu Ereignissen und Nachrichten", "prefs-echo": "Benachrichtigungen", + "prefs-description-echo": "Wähle aus, welche Benachrichtigungen du erhältst und wie du sie erhältst.", "prefs-emailsettings": "E-Mail-Optionen", "prefs-echosubscriptions": "Bei diesen Ereignissen benachrichtigen", "prefs-echocrosswiki": "Wikiübergreifende Benachrichtigungen", @@ -48,8 +54,8 @@ "echo-pref-dont-email-read-notifications": "Gelesene Benachrichtigungen nicht in den Zusammenfassungmails einschließen", "echo-learn-more": "Mehr erfahren", "echo-log": "Öffentliches Logbuch", - "echo-new-messages": "Du hast neue Nachrichten", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Diskussionsseitennachricht|Diskussionsseitennachrichten}}", + "echo-new-messages": "Neue Nachricht auf deiner Diskussionsseite", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Bearbeitung|Bearbeitungen}} auf meiner Diskussionsseite", "echo-category-title-article-linked": "{{PLURAL:$1|Seitenverlinkung|Seitenverlinkungen}}", "echo-category-title-reverted": "{{PLURAL:$1|Rückgängigmachung einer Bearbeitung|Rückgängigmachungen von Bearbeitungen}}", "echo-category-title-mention": "{{PLURAL:$1|Erwähnung|Erwähnungen}}", @@ -65,7 +71,7 @@ "echo-category-title-thank-you-edit": "{{PLURAL:$1|Bearbeitungsmeilenstein|Bearbeitungsmeilensteine}}", "echo-category-title-watchlist": "Bearbeitung an beobachteter Seite", "echo-category-title-minor-watchlist": "Kleine Bearbeitung an beobachteter Seite", - "echo-pref-tooltip-edit-user-talk": "Benachrichtige mich, wenn jemand eine Nachricht oder eine Antwort auf meiner Diskussionsseite hinterlässt.", + "echo-pref-tooltip-edit-user-talk": "Benachrichtige mich, wenn jemand meine Diskussionsseite bearbeitet.", "echo-pref-tooltip-article-linked": "Benachrichtige mich, wenn jemand auf einer Seite auf eine andere von mir erstellte Seite verlinkt.", "echo-pref-tooltip-reverted": "Benachrichtige mich, wenn jemand eine von mir gemachte Bearbeitung rückgängig macht oder zurücksetzt.", "echo-pref-tooltip-mention": "Benachrichtige mich, wenn jemand auf meine Benutzerseite verlinkt.", @@ -74,7 +80,7 @@ "echo-pref-tooltip-user-rights": "Benachrichtige mich, wenn jemand meine Benutzerrechte ändert.", "echo-pref-tooltip-emailuser": "Benachrichtige mich, wenn mir jemand eine E-Mail sendet.", "echo-pref-tooltip-article-reminder": "Benachrichtige mich über diese Seite, wenn ich dies verlange.", - "echo-pref-tooltip-thank-you-edit": "Benachrichtige mich, wenn ich meine 1., 10., 100., … Bearbeitung erreiche.", + "echo-pref-tooltip-thank-you-edit": "Benachrichtige mich, wenn ich meine 1., 10., 100., … Bearbeitung erreiche.", "echo-pref-tooltip-watchlist": "Benachrichtige mich, wenn jemand eine (nicht-kleine) Bearbeitung an einer Seite auf meiner Beobachtungsliste macht.", "echo-pref-tooltip-minor-watchlist": "Benachrichtige mich, wenn jemand eine kleine Bearbeitung an einer Seite auf meiner Beobachtungsliste macht.", "notifications": "Benachrichtigungen", @@ -149,8 +155,8 @@ "notification-header-mention-other-nosection": "$1 {{GENDER:$2|erwähnte}} {{GENDER:$3|dich}} auf <strong>$4</strong>.", "notification-header-mention-user-talkpage-v2": "$1 {{GENDER:$2|erwähnte}} {{GENDER:$3|dich}} auf der <strong>Benutzerdiskussionsseite {{GENDER:$5|von}} $4</strong> in „<strong>$6</strong>“.", "notification-header-mention-user-talkpage-nosection": "$1 {{GENDER:$2|erwähnte}} {{GENDER:$3|dich}} auf der <strong>Benutzerdiskussionsseite {{GENDER:$5|von}} $4</strong>.", - "notification-header-mention-agent-talkpage": "$1 {{GENDER:$2|erwähnte}} {{GENDER:$3|dich}} auf <strong>{{GENDER:$2|seiner|ihrer|Benutzers}} Diskussionsseite</strong> in „<strong>$4</strong>“.", - "notification-header-mention-agent-talkpage-nosection": "$1 {{GENDER:$2|erwähnte}} {{GENDER:$3|dich}} auf <strong>{{GENDER:$2|seiner|ihrer|Benutzers}} Diskussionsseite</strong>.", + "notification-header-mention-agent-talkpage": "$1 {{GENDER:$2|erwähnte}} {{GENDER:$3|dich}} auf <strong>{{GENDER:$2|seiner|ihrer|der eigenen}} Diskussionsseite</strong> in „<strong>$4</strong>“.", + "notification-header-mention-agent-talkpage-nosection": "$1 {{GENDER:$2|erwähnte}} {{GENDER:$3|dich}} auf <strong>{{GENDER:$2|seiner|ihrer|der eigenen}} Diskussionsseite</strong>.", "notification-header-mention-article-talkpage": "$1 {{GENDER:$2|erwähnte}} {{GENDER:$3|dich}} auf der Diskussionsseite von <strong>$4</strong> in „<strong>$5</strong>“.", "notification-header-mention-article-talkpage-nosection": "$1 {{GENDER:$2|erwähnte}} {{GENDER:$3|dich}} auf der Diskussionsseite von <strong>$4</strong>.", "notification-header-mention-failure-user-unknown": "{{GENDER:$2|Deine}} Erwähnung von <strong>$3</strong> wurde nicht gesendet, da der Benutzer nicht gefunden wurde.", @@ -167,7 +173,7 @@ "notification-header-user-rights-remove-only": "{{GENDER:$4|Deine}} Benutzerrechte wurden {{GENDER:$1|geändert}}. Du bist kein Mitglied mehr von: $2.", "notification-header-user-rights-add-and-remove": "{{GENDER:$6|Deine}} Benutzerrechte wurden {{GENDER:$1|geändert}}. Du wurdest hinzugefügt zu: $2. Du bist kein Mitglied mehr von: $4.", "notification-header-user-rights-expiry-change": "Der Ablauf {{GENDER:$4|deiner}} Mitgliedschaft in {{PLURAL:$3|der folgenden Gruppe|den folgenden Gruppen}} wurde {{GENDER:$1|geändert}}: $2.", - "notification-header-welcome": "{{GENDER:$2|Willkommen}} bei {{SITENAME}}, $1! Wir sind froh, dass {{GENDER:$2|du}} da bist.", + "notification-header-welcome": "{{GENDER:$2|Willkommen}} bei {{SITENAME}}, $1! Wir freuen uns, dass {{GENDER:$2|du}} da bist.", "notification-header-mention-summary": "$1 {{GENDER:$2|erwähnte}} {{GENDER:$3|dich}} in einer Bearbeitungszusammenfassung auf <strong>$4</strong>.", "notification-header-watchlist-changed": "$1 {{GENDER:$2|änderte}} <strong>$3</strong>, eine Seite auf {{GENDER:$4|deiner}} Beobachtungsliste {{PLURAL:$5||, $5x}}.", "notification-header-watchlist-created": "$1 {{GENDER:$2|erstellte}} <strong>$3</strong>, eine Seite auf {{GENDER:$4|deiner}} Beobachtungsliste {{PLURAL:$5||, $5x}}.", @@ -179,6 +185,7 @@ "notification-header-watchlist-multiuser-deleted": "<strong>$1</strong>, eine Seite auf {{GENDER:$2|deiner}} Beobachtungsliste, wurde {{PLURAL:$3|einmal|$3x}} gelöscht.", "notification-header-watchlist-multiuser-moved": "<strong>$1</strong>, eine Seite auf {{GENDER:$2|deiner}} Beobachtungsliste, wurde {{PLURAL:$3||$3x}} verschoben.", "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>, eine Seite auf {{GENDER:$2|deiner}} Beobachtungsliste, wurde {{PLURAL:$3||$3x}} wiederhergestellt.", + "notification-body-watchlist-once": "Es wird keine weiteren E-Mail-Benachrichtigungen im Falle weiterer Aktivitäten geben, es sei denn, {{GENDER:$1|du besuchst}} diese Seite, während du angemeldet bist.", "notification-welcome-linktext": "Willkommen", "notification-header-thank-you-1-edit": "{{GENDER:$2|Du}} hast gerade {{GENDER:$2|deine}} erste Bearbeitung durchgeführt. {{GENDER:$2|Vielen}} Dank und willkommen!", "notification-header-thank-you-10-edit": "{{GENDER:$2|Du}} hast gerade {{GENDER:$2|deine}} zehnte Bearbeitung durchgeführt. {{GENDER:$2|Vielen}} Dank! Mach weiter so!", @@ -209,7 +216,7 @@ "notification-inbox-filter-read": "Gelesen", "notification-inbox-filter-unread": "Ungelesen", "notification-inbox-filter-all": "Alle", - "echo-specialmute-label-mute-notifications": "Benachrichtigungen {{GENDER:$1|dieses Benutzers|dieser Benutzerin}} stumm schalten", + "echo-specialmute-label-mute-notifications": "Benachrichtigungen {{GENDER:$1|dieses Benutzers|dieser Benutzerin}} stummschalten", "echo-email-plain-footer": "Um zu steuern, welche E-Mails wir {{GENDER:$1|dir}} senden, überprüfe {{GENDER:$1|deine}} Einstellungen:", "echo-email-html-footer-preference-link-text": "überprüfe {{GENDER:$1|deine}} Einstellungen", "echo-email-html-footer-with-link": "Um zu steuern, welche E-Mails wir {{GENDER:$2|dir}} senden, $1.", @@ -234,5 +241,10 @@ "notification-header-foreign-alert": "Weitere Meldungen von {{PLURAL:$5|einem anderen Wiki|$5 anderen Wikis}}", "notification-header-foreign-notice": "Weitere Mitteilungen von {{PLURAL:$5|einem anderen Wiki|$5 anderen Wikis}}", "notification-header-foreign-all": "Weitere Benachrichtigungen von {{PLURAL:$5|einem weiteren Wiki|$5 weiteren Wikis}}", - "echo-foreign-wiki-lang": "$1 – $2" + "echo-foreign-wiki-lang": "$1 – $2", + "right-manage-all-push-subscriptions": "Verwalten aller Push-Abonnements", + "action-manage-all-push-subscriptions": "verwalten aller Push-Abonnements", + "group-push-subscription-manager": "Push-Abonnementverwalter", + "group-push-subscription-manager-member": "{{GENDER:$1|Push-Abonnementverwalter|Push-Abonnementverwalterin}}", + "grouppage-push-subscription-manager": "{{ns:project}}:Push-Abonnementverwalter" } diff --git a/Echo/i18n/diq.json b/Echo/i18n/diq.json index 3c1a1759..35c2f72e 100644 --- a/Echo/i18n/diq.json +++ b/Echo/i18n/diq.json @@ -139,7 +139,7 @@ "echo-notification-notice-text-only": "Mengeney", "echo-overlay-link": "Tebliği pêro", "echo-overlay-title": "<b>Tebliği</b>", - "echo-mark-all-as-read": "Pêron waniyaye nışan bık", + "echo-mark-all-as-read": "Pêrıne wende nişan ke", "echo-mark-wiki-as-read": "Wiki dı pêron wanaye nışan bık:$1", "echo-displaysnippet-title": "Pêhesnayışê newey", "echo-date-today": "Ewro", diff --git a/Echo/i18n/el.json b/Echo/i18n/el.json index 485e4d93..324f9988 100644 --- a/Echo/i18n/el.json +++ b/Echo/i18n/el.json @@ -5,8 +5,10 @@ "Auslaender", "Dipa1965", "Geraki", + "Giannaras99", "Giorgos456", "Glavkos", + "NikosLikomitros", "Nikosgranturismogt", "Norhorn", "Protnet", @@ -16,15 +18,17 @@ "Ανώνυμος Βικιπαιδιστής" ] }, - "echo-desc": "Σύστημα για την ενημέρωση των χρηστών σχετικά με τα γεγονότα και τα μηνύματα", + "echo-desc": "Σύστημα για την ενημέρωση των χρηστών σχετικά με τα γεγονότα και μηνύματα", "prefs-echo": "Ενημερώσεις", "prefs-emailsettings": "Επιλογές ηλεκτρονικού ταχυδρομείου", "prefs-echosubscriptions": "Να ειδοποιούμαι σχετικά με αυτά τα γεγονότα", "prefs-echocrosswiki": "Cross-wiki ενημερώσεις", "prefs-blocknotificationslist": "Σιγασμένοι χρήστες", + "prefs-mutedpageslist": "Σιγασμένες σελίδες για ειδοποιήσεις σύνδεσης σελίδας", "prefs-echopollupdates": "Ζωντανές ενημερώσεις", "echo-mobile-notifications-filter-title": "Φιλτράρισμα ενημερώσεων", "echo-pref-show-poll-updates": "Εμφάνιση νέων ενημερώσεων καθώς έρχονται", + "echo-pref-show-poll-updates-help": "Εμφάνιση του αριθμού αδιάβαστων ενημερώσεων στην μπάρα τίτλου, και εμφάνιση αποσπάσματος κάθε ενημέρωσης αμέσως μόλις ληφθεί.", "echo-pref-send-me": "Στείλτε μου:", "echo-pref-send-to": "Αποστολή σε:", "echo-pref-email-format": "Μορφή ηλεκτρονικού ταχυδρομείου:", @@ -39,10 +43,12 @@ "echo-pref-email-format-plain-text": "Απλό κείμενο", "echo-pref-cross-wiki-notifications": "Εμφάνιση ενημερώσεων από άλλα wiki", "echo-pref-notifications-blacklist": "Να μην εμφανίζονται ειδοποιήσεις από αυτούς τους χρήστες.([[mw:Special:MyLanguage/Help:Notifications#mute|μάθετε περισσότερα]])", + "echo-pref-notifications-page-linked-title-muted-list": "Να μην εμφανίζονται ειδοποιήσεις «σύνδεσης σελίδας» για αυτές τις σελίδες.([[mw:Special:MyLanguage/Help:Notifications#mute|μάθετε περισσότερα]])", + "echo-pref-dont-email-read-notifications": "Να μην περιλαμβάνονται ενημερώσεις ανάγνωσης στα συνοπτικά email", "echo-learn-more": "Μάθετε περισσότερα", "echo-log": "Δημόσια καταγραφή", - "echo-new-messages": "Έχετε νέα μηνύματα", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Μήνυμα|Μηνύματα}} στη σελίδα συζήτησης", + "echo-new-messages": "Έχετε ένα νέο μήνυμα στη σελίδα συζήτησης", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Επεξεργασία|Επεξεργασίες}} στη σελίδα συζήτησής μου", "echo-category-title-article-linked": "{{PLURAL:$1|Σύνδεσμος|Σύνδεσμοι}} σελίδας", "echo-category-title-reverted": "{{PLURAL:$1|Επαναφορά|Επαναφορές}} επεξεργασίας", "echo-category-title-mention": "{{PLURAL:$1|Αναφορά|Αναφορές}}", @@ -58,7 +64,7 @@ "echo-category-title-thank-you-edit": "{{PLURAL:$1|Ορόσημο|Ορόσημα}} επεξεργασιών", "echo-category-title-watchlist": "Επεξεργασία σε παρακολουθούμενη σελίδα", "echo-category-title-minor-watchlist": "Μικρή επεξεργασία σε παρακολουθούμενη σελίδα", - "echo-pref-tooltip-edit-user-talk": "Να ενημερώνομαι όταν κάποιος δημοσιεύσει ένα μήνυμα ή απαντήσεις στη σελίδα συζήτησής μου.", + "echo-pref-tooltip-edit-user-talk": "Να ενημερώνομαι όταν κάποιος επεξεργαστεί τη σελίδα συζήτησής μου.", "echo-pref-tooltip-article-linked": "Να ενημερώνομαι όταν κάποιος συνδέει τη σελίδα που δημιούργησα σε μια σελίδα λήμματος.", "echo-pref-tooltip-reverted": "Να ενημερώνομαι όταν κάποιος αναστρέφει μια επεξεργασία που έκανα, χρησιμοποιώντας το εργαλείο αναίρεσης ή επαναφοράς.", "echo-pref-tooltip-mention": "Να ενημερώνομαι όταν κάποιος προσθέτει σύνδεσμο προς τη σελίδα χρήστη μου.", @@ -68,6 +74,8 @@ "echo-pref-tooltip-emailuser": "Να ενημερώνομαι όταν κάποιος μου στέλνει email.", "echo-pref-tooltip-article-reminder": "Να ειδοποιούμαι για αυτή τη σελίδα όταν το ζητάω.", "echo-pref-tooltip-thank-you-edit": "Ενημερώστε με όταν φτάσω στην 1η, 10η, 100η ... επεξεργασία.", + "echo-pref-tooltip-watchlist": "Να ενημερώνομαι όταν κάποιος κάνει μια (μη-μικρή) επεξεργασία σε μια σελίδα στη λίστα παρακολούθησής μου.", + "echo-pref-tooltip-minor-watchlist": "Να ενημερώνομαι όταν κάποιος κάνει μια μικρή επεξεργασία σε μια σελίδα στη λίστα παρακολούθησής μου.", "notifications": "Ενημερώσεις", "tooltip-pt-notifications-alert": "Οι ειδοποιήσεις {{GENDER:|σας}}", "tooltip-pt-notifications-notice": "Οι ενημερώσεις {{GENDER:|σας}}", @@ -86,6 +94,8 @@ "echo-specialpage": "Ενημερώσεις", "echo-specialpage-section-markread": "Σήμανση ομάδας ως αναγνωσμένης", "echo-specialpage-markasread": "Ενημέρωση: Σημείωση ως αναγνωσμένη", + "echo-specialpage-pagefilterwidget-aria-label": "Φιλτράρισμα κατά wiki και τίτλο σελίδας", + "echo-specialpage-special-help-menu-widget-aria-label": "Επιπλέον επιλογές και προτιμήσεις Ενημερώσεων.", "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|ενημέρωση|ενημερώσεις}}", "echo-specialpage-pagefilters-title": "Πρόσφατη δραστηριότητα", "echo-specialpage-pagefilters-subtitle": "Σελίδες με μη αναγνωσμένες ενημερώσεις", @@ -101,6 +111,16 @@ "echo-notification-markasunread": "Σήμανση ως αδιάβαστο", "echo-notification-markasread-tooltip": "Σήμανση ως διαβασμένο", "echo-notification-more-options-tooltip": "Περισσότερες επιλογές", + "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|Σίγαση}} ειδοποιήσεων συνδέσμων στη «$1»", + "notification-dynamic-actions-mute-page-linked-confirmation": "Οι ειδοποιήσεις «συνδέσμων σελίδας» είναι τώρα απενεργοποιημένες για τη σελίδα «$1»", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|Μπορείτε}} να διαχειριστείτε τις σελίδες σας σε σίγαση στις [$1 προτιμήσεις] σας ανά πάσα στιγμή.", + "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2|Μη σίγαση}} ειδοποιήσεων συνδέσμων στη «$1»", + "notification-dynamic-actions-unmute-page-linked-confirmation": "Οι ειδοποιήσεις «συνδέσμων σελίδας» είναι τώρα ενεργοποιημένες για τη σελίδα «$1»", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|Μπορείτε}} να διαχειριστείτε τις σελίδες σας σε σίγαση στις [$1 προτιμήσεις] σας ανά πάσα στιγμή.", + "notification-dynamic-actions-unwatch": "{{GENDER:$3|Διακοπή}} της παρακολούθησης νέας δραστηριότητας στη «$1»", + "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3|Δεν}} παρακολουθείτε πλέον τη σελίδα «$1»", + "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|Μπορείτε}} να παρακολουθήσετε [$2 αυτή τη σελίδα] οποιαδήποτε στιγμή.", + "notification-dynamic-actions-watch": "{{GENDER:$3|Ακολούθηση}} νέας δραστηριότητας στην «$1»", "notification-dynamic-actions-watch-confirmation": "{{GENDER:$3|Παρακολουθείς}} τώρα τη σελίδα «$1»", "notification-dynamic-actions-watch-confirmation-description": "{{GENDER:$3|Μπορείς}} να σταματήσεις να παρακολουθείς [$2 αυτή τη σελίδα] οποτεδήποτε.", "notification-link-text-expand-all": "Ανάπτυξη", @@ -132,14 +152,30 @@ "notification-header-mention-failure-user-unknown": "Η αναφορά {{GENDER:$2|σου}} στον <strong>$3</strong> δεν στάλθηκε επειδή δεν βρέθηκε ο χρήστης.", "notification-header-mention-failure-user-anonymous": "Η αναφορά {{GENDER:$2|σου}} στον <strong>$3</strong> δεν στάλθηκε επειδή ο χρήστης είναι ανώνυμος.", "notification-header-mention-failure-too-many": "{{GENDER:$2|Προσπάθησες}} να αναφέρεις περισσότερους από $3 {{PLURAL:$3|χρήστη|χρήστες}}. Όλες οι αναφορές πάνω από αυτό το όριο δεν στάλθηκαν.", + "notification-header-mention-failure-bundle": "{{PLURAL:$3|Μια αναφορά|$3 αναφορές}} {{GENDER:$2|που κάνατε}} στην σελίδα συζητήσεων <strong>$4</strong> δεν {{PLURAL:$3|μπόρεσε να σταλεί|δεν μπόρεσαν να σταλούν}}.", "notification-compact-header-mention-failure-user-unknown": "<strong>Το όνομα χρήστη δεν υπάρχει:</strong> $1", "notification-compact-header-mention-failure-user-anonymous": "<strong>Οι IP δεν μπορούν να αναφερθούν:</strong> $1", "notification-header-mention-success": "Η {{GENDER:$2|αναφορά}} σου {{GENDER:$3|στον|στην}} <strong>$3</strong> έχει σταλεί.", + "notification-header-mention-success-bundle": "{{PLURAL:$3|Μια αναφορά|$3 αναφορές}} {{GENDER:$2|που κάνατε}} στην σελίδα συζητήσεων <strong>$4</strong> δεν {{PLURAL:$3|στάλθηκε|στάλθηκαν}}.", "notification-compact-header-mention-success": "<strong>{{GENDER:$2|Αναφέρατε}}:</strong> $3", + "notification-header-mention-status-bundle": "{{PLURAL:$3|Μια ενημέρωση|$3 ενημερώσεις}} για αναφορές {{GENDER:$2|που κάνατε}} στην σελίδα συζήτηση <strong>$4</strong>: {{PLURAL:$5|$5 δεν στάλθηκαν}}, {{PLURAL:$6|$6 στάλθηκαν}}.", "notification-header-user-rights-add-only": "Τα δικαιώματα χρήστη {{GENDER:$4|σου}} {{GENDER:$1|άλλαξαν}}. Προστέθηκες σε: $2.", "notification-header-user-rights-remove-only": "Τα δικαιώματα χρήστη {{GENDER:$4|σου}} {{GENDER:$1|άλλαξαν}}. Δεν είσαι πλέον μέλος σε: $2.", + "notification-header-user-rights-add-and-remove": "Τα δικαιώματα χρήστη {{GENDER:$6|σου}} {{GENDER:$1|άλλαξαν}}. Έχεις προστεθεί σε: $2. Δεν είσαι πλέον μέλος σε: $4.", + "notification-header-user-rights-expiry-change": "Η λήξη της ιδιότητάς {{GENDER:$4|σου}} {{PLURAL:$3|στην ακόλουθη ομάδα|στις ακόλουθες ομάδες}} έχει {{GENDER:$1|αλλάξει}}: $2.", "notification-header-welcome": "{{GENDER:$2|Καλωσήρθατε}} στο {{SITENAME}}, $1! Είμαστε χαρούμενοι {{GENDER:$2|που είστε}} εδώ.", "notification-header-mention-summary": "{{GENDER:$2|Ο|Η}} $1 {{GENDER:$3|σας}} ανάφερε στη σύνοψη επεξεργασίας στην <strong>$4</strong>.", + "notification-header-watchlist-changed": "{{GENDER:$2|Ο|Η}} $1 άλλαξε την <strong>$3</strong>, μια σελίδα στην λίστα παρακολούθησής {{GENDER:$4|σας}}{{PLURAL:$5||, $5 φορές}}.", + "notification-header-watchlist-created": "{{GENDER:$2|Ο|Η}} $1 δημιούργησε την <strong>$3</strong>, μια σελίδα στην λίστα παρακολούθησής {{GENDER:$4|σας}}{{PLURAL:$5||, $5 φορές}}.", + "notification-header-watchlist-deleted": "{{GENDER:$2|Ο|Η}} $1 διέγραψε την <strong>$3</strong>, μια σελίδα στην λίστα παρακολούθησής {{GENDER:$4|σας}}{{PLURAL:$5||, $5 φορές}}.", + "notification-header-watchlist-moved": "{{GENDER:$2|Ο|Η}} $1 μετακίνησε την <strong>$3</strong>, μια σελίδα στην λίστα παρακολούθησής {{GENDER:$4|σας}}{{PLURAL:$5||, $5 φορές}}.", + "notification-header-watchlist-restored": "{{GENDER:$2|Ο|Η}} $1 ανάκτησε την <strong>$3</strong>, μια σελίδα στην λίστα παρακολούθησής {{GENDER:$4|σας}}{{PLURAL:$5||, $5 φορές}}.", + "notification-header-watchlist-multiuser-changed": "Η <strong>$1</strong>, μια σελίδα στην λίστα παρακολούθησής {{GENDER:$2|σας}}, έχει αλλάξει $3 {{PLURAL:$3|φορά|φορές}}.", + "notification-header-watchlist-multiuser-created": "Η <strong>$1</strong>, μια σελίδα στην λίστα παρακολούθησής {{GENDER:$2|σας}}, έχει δημιουργηθεί $3 {{PLURAL:$3|φορά|φορές}}.", + "notification-header-watchlist-multiuser-deleted": "Η <strong>$1</strong>, μια σελίδα στην λίστα παρακολούθησής {{GENDER:$2|σας}}, έχει διαγραφεί $3 {{PLURAL:$3|φορά|φορές}}.", + "notification-header-watchlist-multiuser-moved": "Η <strong>$1</strong>, μια σελίδα στην λίστα παρακολούθησής {{GENDER:$2|σας}}, μετακινήθηκε $3 {{PLURAL:$3|φορά|φορές}}.", + "notification-header-watchlist-multiuser-restored": "Η <strong>$1</strong>, μια σελίδα στην λίστα παρακολούθησής {{GENDER:$2|σας}}, ανακτήθηκε $3 {{PLURAL:$3|φορά|φορές}}.", + "notification-body-watchlist-once": "Δεν θα υπάρχουν άλλες ειδοποιήσεις μέσω ηλεκτρονικού ταχυδρομείου σε περίπτωση περαιτέρω δραστηριότητας, εκτός εάν επισκεφτείτε αυτήν τη σελίδα ενώ είστε {{GENDER:$1|συνδεδεμένος|συνδεδεμένη}}.", "notification-welcome-linktext": "Καλώς ήρθατε", "notification-header-thank-you-1-edit": "Μόλις {{GENDER:$2|έκανες}} την πρώτη σου επεξεργασία. Σε ευχαριστούμε, και καλώς ήρθες!", "notification-header-thank-you-10-edit": "Μόλις {{GENDER:$2|κάνατε}} την δέκατη επεξεργασία {{GENDER:$2|σας}}. {{GENDER:$2|Σας}} ευχαριστούμε, και παρακαλούμε συνεχίστε!", @@ -148,6 +184,7 @@ "notification-header-thank-you-10000-edit": "Μόλις {{GENDER:$2|κάνατε}} την δεκάκις χιλιοστή επεξεργασία {{GENDER:$2|σας}}. {{GENDER:$2|Σας}} ευχαριστούμε πάρα πολύ!", "notification-header-thank-you-100000-edit": "Μόλις {{GENDER:$2|κάνατε}} την εκατοστή χιλιοστή επεξεργασία {{GENDER:$2|σας}}. {{GENDER:$2|Σας}} ευχαριστούμε για την καταπληκτική συνεισφορά!", "notification-header-thank-you-1000000-edit": "Μόλις {{GENDER:$2|κάνατε}} την εκατομμυριοστή επεξεργασία {{GENDER:$2|σας}}. {{GENDER:$2|Σας}} ευχαριστούμε για την εκπληκτική συνεισφορά!", + "notification-header-thank-you-10000000-edit": "Μόλις {{GENDER:$2|κάνατε}} την δεκάκις εκατομμυριοστή επεξεργασία {{GENDER:$2|σας}}. {{GENDER:$2|Σας}} ευχαριστούμε για την εκπληκτική συνεισφορά!", "notification-link-thank-you-edit": "Η επεξεργασία {{GENDER:$1|σας}}", "notification-link-text-view-edit": "Προβολή επεξεργασίας", "notification-link-article-reminder": "Προβολή σελίδας", @@ -161,12 +198,15 @@ "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1δ}}", "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1λ}}", "notification-timestamp-ago-hours": "{{PLURAL:$1|$1ω}}", + "notification-timestamp-ago-days": "{{PLURAL:$1|$1 ημ.}}", + "notification-timestamp-ago-months": "{{PLURAL:$1|$1 μην.}}", + "notification-timestamp-ago-years": "{{PLURAL:$1|$1 ετ}}", "notification-timestamp-today": "Σήμερα", "notification-timestamp-yesterday": "Χθες", "notification-inbox-filter-read": "Αναγνωσμένες", "notification-inbox-filter-unread": "Μη αναγνωσμένες", "notification-inbox-filter-all": "Όλες", - "echo-specialmute-label-mute-notifications": "Σίγαση ειδοποιήσεων από αυτόν τον χρήστη", + "echo-specialmute-label-mute-notifications": "Σίγαση ειδοποιήσεων από {{GENDER:$1|αυτόν τον χρήστη|αυτή τη χρήστρια}}", "echo-email-plain-footer": "Για να ελέγξετε ποια email {{GENDER:$1|σας}} στέλνουμε, ελέγξτε τις προτιμήσεις {{GENDER:$1|σας}}.", "echo-email-html-footer-preference-link-text": "ελέγξτε τις προτιμήσεις {{GENDER:$1|σας}}", "echo-email-html-footer-with-link": "Για να ελέγξετε ποια email {{GENDER:$2|σας}} στέλνουμε, $1.", @@ -190,5 +230,10 @@ "echo-email-batch-link-text-view-all-notifications": "Δείτε όλες τις ενημερώσεις", "notification-header-foreign-alert": "Περισσότερες ειδοποιήσεις από {{PLURAL:$5|άλλο wiki|$5 άλλα wiki}}", "notification-header-foreign-notice": "Περισσότερες κοινοποιήσεις από {{PLURAL:$5|άλλο wiki|$5 άλλα wiki}}", - "notification-header-foreign-all": "Περισσότερες ενημερώσεις από {{PLURAL:$5|άλλο wiki|$5 άλλα wiki}}" + "notification-header-foreign-all": "Περισσότερες ενημερώσεις από {{PLURAL:$5|άλλο wiki|$5 άλλα wiki}}", + "right-manage-all-push-subscriptions": "Διαχείριση όλων των εγγραφών ενημερώσεων", + "action-manage-all-push-subscriptions": "διαχειριστείτε όλες τις εγγραφές ενημερώσεων", + "group-push-subscription-manager": "Διαχειριστές εγγραφών ενημερώσεων", + "group-push-subscription-manager-member": "{{GENDER:$1|διαχειριστής εγγραφών ενημερώσεων|διαχειρίστρια εγγραφών ενημερώσεων}}", + "grouppage-push-subscription-manager": "{{ns:project}}:Διαχειριστές εγγραφών ενημερώσεων" } diff --git a/Echo/i18n/en-gb.json b/Echo/i18n/en-gb.json deleted file mode 100644 index bb1b253c..00000000 --- a/Echo/i18n/en-gb.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Shirayuki", - "Mhutti1", - "Shahjad ansari" - ] - }, - "echo-pref-beta-feature-cross-wiki-message": "Enhanced notifications" -} diff --git a/Echo/i18n/en.json b/Echo/i18n/en.json index ca1290aa..3b1861b7 100644 --- a/Echo/i18n/en.json +++ b/Echo/i18n/en.json @@ -37,6 +37,7 @@ }, "echo-desc": "System for notifying users about events and messages", "prefs-echo": "Notifications", + "prefs-description-echo": "Select which notifications {{GENDER:|you}} get and how to receive them.", "prefs-emailsettings": "Email options", "prefs-echosubscriptions": "Notify me about these events", "prefs-echocrosswiki": "Cross-wiki notifications", @@ -64,8 +65,8 @@ "echo-pref-dont-email-read-notifications": "Don't include read notifications in summary emails", "echo-learn-more": "Learn more", "echo-log": "Public log", - "echo-new-messages": "You have new messages", - "echo-category-title-edit-user-talk": "Talk page {{PLURAL:$1|message|messages}}", + "echo-new-messages": "You have a new Talk page message", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Edit|Edits}} to my user talk page", "echo-category-title-article-linked": "Page {{PLURAL:$1|link|links}}", "echo-category-title-reverted": "Edit {{PLURAL:$1|revert|reverts}}", "echo-category-title-mention": "{{PLURAL:$1|Mention|Mentions}}", @@ -81,7 +82,7 @@ "echo-category-title-thank-you-edit": "Edit {{PLURAL:$1|milestone|milestones}}", "echo-category-title-watchlist": "Edit to watched page", "echo-category-title-minor-watchlist": "Minor edit to watched page", - "echo-pref-tooltip-edit-user-talk": "Notify me when someone posts a message or replies on my talk page.", + "echo-pref-tooltip-edit-user-talk": "Notify me when someone edits my user talk page.", "echo-pref-tooltip-article-linked": "Notify me when someone links to a page I created from another page.", "echo-pref-tooltip-reverted": "Notify me when someone reverts an edit I made, by using the undo or rollback tool.", "echo-pref-tooltip-mention": "Notify me when someone links to my user page.", @@ -197,6 +198,7 @@ "notification-header-watchlist-multiuser-deleted": "<strong>$1</strong>, a page on {{GENDER:$2|your}} watchlist, was deleted $3 {{PLURAL:$3|time|times}}.", "notification-header-watchlist-multiuser-moved": "<strong>$1</strong>, a page on {{GENDER:$2|your}} watchlist, was moved $3 {{PLURAL:$3|time|times}}.", "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>, a page on {{GENDER:$2|your}} watchlist, was restored $3 {{PLURAL:$3|time|times}}.", + "notification-body-watchlist-once": "There will be no other email notifications in case of further activity unless {{GENDER:$1|you visit}} this page while logged in.", "notification-welcome-link": "", "notification-welcome-linktext": "Welcome", "notification-header-thank-you-1-edit": "{{GENDER:$2|You}} just made {{GENDER:$2|your}} first edit; thank {{GENDER:$2|you}}, and welcome!", @@ -259,5 +261,10 @@ "notification-body-foreign": "$1", "echo-foreign-wiki-lang": "$1 - $2", "echo-badge-count": "{{PLURAL:$1|$1|100={{formatnum:99}}+}}", - "echo-blacklist": "" + "echo-blacklist": "", + "right-manage-all-push-subscriptions": "Manage all push subscriptions", + "action-manage-all-push-subscriptions": "manage all push subscriptions", + "group-push-subscription-manager": "Push subscription managers", + "group-push-subscription-manager-member": "{{GENDER:$1|push subscription manager}}", + "grouppage-push-subscription-manager": "{{ns:project}}:Push subscription managers" } diff --git a/Echo/i18n/eo.json b/Echo/i18n/eo.json index d2bd4121..babf229e 100644 --- a/Echo/i18n/eo.json +++ b/Echo/i18n/eo.json @@ -24,6 +24,7 @@ "echo-pref-email-format": "Formo de retpoŝto:", "echo-pref-web": "Reteje", "echo-pref-email": "Retpoŝte", + "echo-pref-push": "Aplikaĵoj", "echo-pref-email-frequency-never": "Ne sendadi al mi retpoŝtajn sciigojn", "echo-pref-email-frequency-immediately": "Unuopajn sciigojn tuj kiam ili alvenos", "echo-pref-email-frequency-daily": "Tagan resumon de sciigoj", @@ -33,8 +34,8 @@ "echo-pref-cross-wiki-notifications": "Montri sciigojn el aliaj vikioj", "echo-learn-more": "Lerni plu", "echo-log": "Publika protokolo", - "echo-new-messages": "Vi havas novajn mesaĝojn", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Mesaĝo|Mesaĝoj}} en diskutpaĝo", + "echo-new-messages": "Vi havas novan diskutpaĝan mesaĝon", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Komento|Komentoj}} en mia uzanto-diskutpaĝo", "echo-category-title-article-linked": "{{PLURAL:$1|Ligilo|Ligiloj}} al paĝo", "echo-category-title-reverted": "{{PLURAL:$1|Malfaro|Malfaroj}} de redakto", "echo-category-title-mention": "{{PLURAL:$1|Mencio|Mencioj}}", @@ -46,8 +47,8 @@ "echo-category-title-user-rights": "{{PLURAL:$1|Ŝanĝo de uzanto-rajto|Ŝanĝoj de uzanto-rajtoj}}", "echo-category-title-emailuser": "{{PLURAL:$1|Retpoŝta mesaĝo de alia uzanto|Retpoŝtaj mesaĝoj de aliaj uzantoj}}", "echo-category-title-thank-you-edit": "Redakti {{PLURAL:$1|mejloŝtonon|mejloŝtonojn}}", - "echo-pref-tooltip-edit-user-talk": "Sciigu min kiam iu komencas diskuton aŭ respondas en mia diskutpaĝo.", - "echo-pref-tooltip-article-linked": "Sciigu min kiam iu de artikolo ligas al paĝo kiun mi kreis.", + "echo-pref-tooltip-edit-user-talk": "Sciigu min kiam iu komencas diskuton aŭ respondas en mia uzanto-diskutpaĝo.", + "echo-pref-tooltip-article-linked": "Sciigu min kiam iu ligas al paĝo kiun mi kreis de alia paĝo.", "echo-pref-tooltip-reverted": "Sciigu min kiam iu malfaras mian redakton per ilo por malfari aŭ amasmalfari.", "echo-pref-tooltip-mention": "Sciigu min kiam iu ligas al mia uzantopaĝo.", "echo-pref-tooltip-mention-failure": "Sciigi al mi kiam mi ne sendis mencion al iu.", @@ -132,13 +133,13 @@ "notification-link-thank-you-edit": "{{GENDER:$1|Via}} redakto", "notification-link-text-view-edit": "Montri redakton", "notification-link-article-reminder": "Vidi paĝon", - "notification-header-reverted": "{{PLURAL:$4|Via redakto sur $3 estis {{GENDER:$2|malfarita}}|Viaj redaktoj sur $3 estis {{GENDER:$2|malfaritaj}}}}.", + "notification-header-reverted": "{{PLURAL:$4|Via redakto en $3 estis {{GENDER:$2|malfarita}}|Viaj redaktoj en $3 estis {{GENDER:$2|malfaritaj}}}}.", "notification-header-emailuser": "$1 {{GENDER:$2|sendis}} al vi retpoŝtan mesaĝon.", "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$2|lasis}} al vi mesaĝon sur {{SITENAME}}", - "notification-page-linked-email-subject": "Paĝo kiun vi kreis estas ligita en {{SITENAME}}", - "notification-reverted-email-subject2": "{{PLURAL:$4|Via redakto estis {{GENDER:$2|malfarita}}|Viaj redaktoj estis {{GENDER:$2|malfaritaj}}}} sur {{SITENAME}}", - "notification-mention-email-subject": "$1 {{GENDER:$2|menciis}} {{GENDER:$3|vin}} sur {{SITENAME}}", - "notification-user-rights-email-subject": "Viaj uzantorajtoj estis ŝanĝitaj sur {{SITENAME}}", + "notification-page-linked-email-subject": "Iu en {{SITENAME}} ligis al paĝo, kiun {{GENDER:$3|vi}} kreis", + "notification-reverted-email-subject2": "{{PLURAL:$4|{{GENDER:$3|Via}} redakto estis {{GENDER:$2|malfarita}}|{{GENDER:$3|Viaj}} redaktoj estis {{GENDER:$2|malfaritaj}}}} en {{SITENAME}}", + "notification-mention-email-subject": "$1 {{GENDER:$2|menciis}} {{GENDER:$3|vin}} en {{SITENAME}}", + "notification-user-rights-email-subject": "{{GENDER:$3|Viaj}} uzantorajtoj estis ŝanĝitaj en {{SITENAME}}", "notification-timestamp-ago-seconds": "{{PLURAL:$1|sekundo|$1 sekundoj}}", "notification-timestamp-ago-minutes": "{{PLURAL:$1|minuto|$1 minutoj}}", "notification-timestamp-ago-hours": "{{PLURAL:$1|horo|$1 horoj}}", @@ -150,7 +151,7 @@ "notification-inbox-filter-read": "Legita", "notification-inbox-filter-unread": "Nelegita", "notification-inbox-filter-all": "Ĉiuj", - "echo-specialmute-label-mute-notifications": "Silentigi sciigojn el ĉi tiu uzanto", + "echo-specialmute-label-mute-notifications": "Silentigi sciigojn de ĉi tiu {{GENDER:$1|uzanto|uzantino|uzanto}}", "echo-email-html-footer-preference-link-text": "kontroli {{GENDER:$1|viajn}} preferojn", "echo-notification-alert": "{{PLURAL:$1|Atentigo ($1)|Atentigoj ($1)|100=Atentigoj (99+)}}", "echo-notification-notice": "{{PLURAL:$1|Avizo ($1)|Avizoj ($1)|100=Avizoj (99+)}}", diff --git a/Echo/i18n/es.json b/Echo/i18n/es.json index 259bd990..d7d0f6ba 100644 --- a/Echo/i18n/es.json +++ b/Echo/i18n/es.json @@ -5,15 +5,19 @@ "2axterix2", "Allan Aguilar", "Amitie 10g", + "ArenaL5", "Armando-Martin", "Ciencia Al Poder", "DJ Nietzsche", "DannyS712", "Dgstranz", + "DiegoAmbrocio", + "Fewasser Traduce", "Fitoschido", "Hahc21", "Hamilton Abreu", "Invadinado", + "Jakeukalane", "Javiersanp", "Jduranboger", "Larjona", @@ -21,11 +25,14 @@ "Macofe", "MarcoAurelio", "Matiia", + "McDutchie", "Mgpena", "Miguel2706", "Peter Bowman", "PoLuX124", "Ralgis", + "Reverse88", + "Rodney Araujo", "Rubentl134", "Savh", "The Anonymouse", @@ -40,6 +47,11 @@ "prefs-echosubscriptions": "Notificarme sobre estos eventos", "prefs-echocrosswiki": "Notificaciones de varios wikis", "prefs-blocknotificationslist": "Usuarios silenciados", + "prefs-mutedpageslist": "Páginas silenciadas para notificaciones de enlaces de página", + "prefs-echopollupdates": "Notificaciones en vivo", + "echo-mobile-notifications-filter-title": "Filtrar notificaciones", + "echo-pref-show-poll-updates": "Mostrar las notificaciones nuevas en cuando llegan", + "echo-pref-show-poll-updates-help": "Muestra la cantidad de notificaciones no leídas en la barra de título junto con un fragmento de cada notificación inmediatamente cuando lleguen.", "echo-pref-send-me": "Enviarme:", "echo-pref-send-to": "Enviar a:", "echo-pref-email-format": "Formato del correo electrónico:", @@ -54,10 +66,12 @@ "echo-pref-email-format-plain-text": "Texto sin formato", "echo-pref-cross-wiki-notifications": "Mostrar notificaciones de otros wikis", "echo-pref-notifications-blacklist": "No mostrar notificaciones de estos usuarios. ([[mw:Special:MyLanguage/Help:Notifications#mute|más información]])", + "echo-pref-notifications-page-linked-title-muted-list": "No mostrar notificaciones de \"Enlace de página\" para estas páginas. ([[mw:Special:MyLanguage/Help:Notifications#mute|más información]])", + "echo-pref-dont-email-read-notifications": "No incluyas notificaciones leídas en los correos electrónicos de resumen", "echo-learn-more": "Más información", "echo-log": "Registro público", - "echo-new-messages": "Tienes mensajes nuevos", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Mensaje|Mensajes}} en la página de discusión", + "echo-new-messages": "Tienes un nuevo mensaje de discusión", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Edición|Ediciones}} en mi página de discusión", "echo-category-title-article-linked": "{{PLURAL:$1|Enlace|Enlaces}} de página", "echo-category-title-reverted": "{{PLURAL:$1|Reversión|Reversiones}} de edición", "echo-category-title-mention": "{{PLURAL:$1|Mención|Menciones}}", @@ -71,7 +85,9 @@ "echo-category-title-emailuser": "{{PLURAL:$1|Correo electrónico de otro usuario|Correos electrónicos de otros usuarios}}", "echo-category-title-article-reminder": "{{PLURAL:$1|Recordatorio de páginas|Recordatorios de páginas}}", "echo-category-title-thank-you-edit": "{{PLURAL:$1|Hito|Hitos}} de edición", - "echo-pref-tooltip-edit-user-talk": "Notificarme cuando alguien publique un mensaje o responda en mi página de discusión.", + "echo-category-title-watchlist": "Edición en página vigilada", + "echo-category-title-minor-watchlist": "Edición menor en página vigilada", + "echo-pref-tooltip-edit-user-talk": "Notifícame cuándo alguien edita mi página de charla del usuario.", "echo-pref-tooltip-article-linked": "Notificarme cuando alguien enlace a una página creada a partir de otra página.", "echo-pref-tooltip-reverted": "Notificarme cuando alguien revierta una edición mía mediante las herramientas de deshacer o revertir.", "echo-pref-tooltip-mention": "Notificarme cuando alguien enlace mi página de {{GENDER:|usuario|usuaria}}.", @@ -81,11 +97,13 @@ "echo-pref-tooltip-emailuser": "Notificarme cuando alguien me envíe un correo electrónico.", "echo-pref-tooltip-article-reminder": "Notificarme sobre esta página cuando lo solicite.", "echo-pref-tooltip-thank-you-edit": "Notifícame cuando alcance mi primera, décima, centésima... edición.", + "echo-pref-tooltip-watchlist": "Notifícame cuando alguien haga una edición (no menor) a una página en mi lista de seguimiento.", + "echo-pref-tooltip-minor-watchlist": "Notifícame cuándo alguien hace una edición menor a una página en mi lista de seguimiento.", "notifications": "Notificaciones", "tooltip-pt-notifications-alert": "{{GENDER:|Tus}} alertas", "tooltip-pt-notifications-notice": "{{GENDER:|Tus}} avisos", "echo-displaynotificationsconfiguration": "Configuración del exhibidor de notificaciones", - "echo-displaynotificationsconfiguration-summary": "Este es un resumen de cómo se configuran las notificaciones en este wiki.", + "echo-displaynotificationsconfiguration-summary": "Este es un resumen de cómo se configuran las notificaciones en esta wiki.", "echo-displaynotificationsconfiguration-notifications-by-category-header": "Notificaciones por categoría", "echo-displaynotificationsconfiguration-sorting-by-section-header": "Clasificación de tipos", "echo-displaynotificationsconfiguration-sorting-by-section-legend": "Sección en la que se clasificará cada tipo de notificación", @@ -101,6 +119,7 @@ "echo-specialpage-markasread": "Notificación: marcar como leída", "echo-specialpage-markasread-invalid-id": "Identificador de evento no válido", "echo-specialpage-pagefilterwidget-aria-label": "Filtrar por wiki y título de página", + "echo-specialpage-special-help-menu-widget-aria-label": "Opciones adicionales y preferencias de notificaciones.", "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|notificación|notificaciones}}", "echo-specialpage-pagefilters-title": "Actividad reciente", "echo-specialpage-pagefilters-subtitle": "Páginas con notificaciones sin leer", @@ -116,6 +135,16 @@ "echo-notification-markasunread": "Marcar como no leído", "echo-notification-markasread-tooltip": "Marcar como leída", "echo-notification-more-options-tooltip": "Más opciones", + "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|Silenciar}} notificaciones de enlace en \"$1\"", + "notification-dynamic-actions-mute-page-linked-confirmation": "Las notificaciones del \"enlace de la página\" están ahora desactivadas para la página \"$1\"", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|Puedes}} gestionar tus páginas silenciadas en [$1 tus preferencias] en cualquier momento.", + "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2|No silenciar}} notificaciones de enlaces para «$1»", + "notification-dynamic-actions-unmute-page-linked-confirmation": "Las notificaciones de \"enlace de página\" están ahora habilitadas para la página «$1»", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|Puedes}} gestionar las páginas silenciadas en cualquier momento a través de [$1 tus preferencias].", + "notification-dynamic-actions-unwatch": "{{GENDER:$3|Dejar}} de vigilar nueva actividad en «$1»", + "notification-dynamic-actions-unwatch-confirmation": "Ya no {{GENDER:$3|vigilas}} la página «$1»", + "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|Puedes}} vigilar [$2 este página] en cualquier momento.", + "notification-dynamic-actions-watch": "{{GENDER:$3|Seguir}} la actividad nueva en «$1»", "notification-dynamic-actions-watch-confirmation": "Ahora {{GENDER:$3|estás}} observando la página «$1»", "notification-dynamic-actions-watch-confirmation-description": "{{GENDER:$3|Puedes}} dejar de observar [$2 esta página] en cualquier momento.", "notification-link-text-expand-all": "Expandir", @@ -168,6 +197,7 @@ "notification-header-thank-you-10000-edit": "Acabas de hacer {{GENDER:$2|tu}} edición número diez mil. ¡Muchas gracias!", "notification-header-thank-you-100000-edit": "Acabas de hacer {{GENDER:$2|tu}} edición número cien mil. ¡Muchas gracias por tu increíble contribución!", "notification-header-thank-you-1000000-edit": "Acabas de hacer {{GENDER:$2|tu}} millonésima edición. ¡Gracias por tu asombrosa contribución!", + "notification-header-thank-you-10000000-edit": "{{GENDER:$2|Acabas de hacer}} tu diezmillonésima edición. ¡Gracias por tu brillante dedicación!", "notification-link-thank-you-edit": "{{GENDER:$1|Tu}} edición", "notification-link-text-view-edit": "Ver edición", "notification-link-article-reminder": "Ver página", @@ -189,7 +219,7 @@ "notification-inbox-filter-read": "Leídas", "notification-inbox-filter-unread": "No leídas", "notification-inbox-filter-all": "Todas", - "echo-specialmute-label-mute-notifications": "Silenciar notificaciones de este usuario", + "echo-specialmute-label-mute-notifications": "Silenciar notificaciones de {{GENDER:$1|este usuario|esta usuaria}}", "echo-email-plain-footer": "Para controlar cuáles correos electrónicos {{GENDER:$1|te}} enviamos, revisa {{GENDER:$1|tus}} preferencias:", "echo-email-html-footer-preference-link-text": "revisa {{GENDER:$1|tus}} preferencias", "echo-email-html-footer-with-link": "Para controlar qué correos electrónicos {{GENDER:$2|te}} enviamos, $1.", @@ -201,7 +231,7 @@ "echo-overlay-title": "<b>Notificaciones</b>", "echo-mark-all-as-read": "Marcar todo como leído", "echo-mark-all-as-read-confirmation": "$1 {{PLURAL:$1|notificación marcada como leída|notificaciones marcadas como leídas}}", - "echo-mark-wiki-as-read": "Marcar como leídas todas las notificaciones del wiki seleccionado: $1", + "echo-mark-wiki-as-read": "Marcar como leídas todas las notificaciones de la wiki seleccionada: $1", "echo-displaysnippet-title": "Notificación nueva", "echo-date-today": "Hoy", "echo-date-yesterday": "Ayer", @@ -213,5 +243,10 @@ "echo-email-batch-link-text-view-all-notifications": "Ver todas las notificaciones", "notification-header-foreign-alert": "Más alertas de {{PLURAL:$5|otra wiki|otras $5 wikis}}", "notification-header-foreign-notice": "Más avisos de {{PLURAL:$5|otra wiki|otras $5 wikis}}", - "notification-header-foreign-all": "Más notificaciones de {{PLURAL:$5|otra wiki|otras $5 wikis}}" + "notification-header-foreign-all": "Más notificaciones de {{PLURAL:$5|otra wiki|otras $5 wikis}}", + "right-manage-all-push-subscriptions": "Gestionar todas las suscripciones push", + "action-manage-all-push-subscriptions": "gestionar todas las suscripciones push", + "group-push-subscription-manager": "Gestores de notificaciones push", + "group-push-subscription-manager-member": "{{GENDER:$1|gestor|gestora}} de notificaciones push", + "grouppage-push-subscription-manager": "{{ns:project}}:Gestores de notificaciones push" } diff --git a/Echo/i18n/et.json b/Echo/i18n/et.json index e0a96472..eeb129bb 100644 --- a/Echo/i18n/et.json +++ b/Echo/i18n/et.json @@ -11,12 +11,14 @@ }, "echo-desc": "Süsteem, millega teavitatakse kasutajaid sündmustest ja sõnumitest", "prefs-echo": "Teavitused", + "prefs-description-echo": "Vali, milliseid teavitusi saad ja kuidas need sulle saadetakse.", "prefs-emailsettings": "E-posti suvandid", "prefs-echosubscriptions": "Teavita mind neist sündmustest", "prefs-echocrosswiki": "Vikideülesed teavitused", "prefs-blocknotificationslist": "Vaigistatud kasutajad", "prefs-mutedpageslist": "Vaigistatud linkimisteavitusega leheküljed", "prefs-echopollupdates": "Reaalajas teavitused", + "echo-mobile-notifications-filter-title": "Teavituste filtreerimine", "echo-pref-show-poll-updates": "Kuva teavitused nende saabumisel", "echo-pref-show-poll-updates-help": "Näita tiitliribal lugemata teavituste arvu ja näita lõigendit igast teavitusest kohe, kui see saabub.", "echo-pref-send-me": "Saada mulle:", @@ -36,8 +38,8 @@ "echo-pref-notifications-page-linked-title-muted-list": "Ära kuva tüübi \"Leheküljelink\" teavitusi nende lehekülgede kohta. ([[mw:Special:MyLanguage/Help:Notifications#mute|lisateave]])", "echo-learn-more": "Lisateave", "echo-log": "Avalik logi", - "echo-new-messages": "Sulle on uusi sõnumeid", - "echo-category-title-edit-user-talk": "Arutelulehekülje {{PLURAL:$1|sõnum|sõnumid}}", + "echo-new-messages": "Sulle on aruteluleheküljel uusi sõnumeid", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Muudatus|Muudatused}} minu aruteluleheküljel", "echo-category-title-article-linked": "{{PLURAL:$1|Leheküljelink|Leheküljelingid}}", "echo-category-title-reverted": "Tühistatud {{PLURAL:$1|muudatus|muudatused}}", "echo-category-title-mention": "{{PLURAL:$1|Mainimine|Mainimised}}", @@ -49,7 +51,7 @@ "echo-category-title-user-rights": "{{PLURAL:$1|Kasutajaõiguste muutmine|Kasutajaõiguste muutmised}}", "echo-category-title-emailuser": "{{PLURAL:$1|E-kiri teiselt kasutajalt|E-kiri teistelt kasutajatelt}}", "echo-category-title-thank-you-edit": "Kaastöö {{PLURAL:$1|verstapost|verstapostid}}", - "echo-pref-tooltip-edit-user-talk": "Teavita mind, kui keegi postitab või vastab minu aruteluleheküljel.", + "echo-pref-tooltip-edit-user-talk": "Teavita mind, kui keegi muudab minu kasutaja arutelulehekülge.", "echo-pref-tooltip-article-linked": "Teavita mind, kui keegi lingib teiselt leheküljelt minu alustatud leheküljele.", "echo-pref-tooltip-reverted": "Teavita mind, kui keegi tühistab minu muudatuse, kasutades eemaldus- või tühistusfunktsiooni.", "echo-pref-tooltip-mention": "Teavita mind, kui keegi lingib minu kasutajaleheküljele.", @@ -134,9 +136,9 @@ "notification-header-mention-success-bundle": "{{PLURAL:$3|Mainimine|$3 mainimist}}, mille {{GENDER:$2|lisasid}} aruteluleheküljele \"<strong>$4</strong>\", on saadetud.", "notification-compact-header-mention-success": "<strong>{{GENDER:$2|Mainisid}}:</strong> $3", "notification-header-mention-status-bundle": "{{PLURAL:$3|Teavitus|$3 teavitust}} mainimistest, mille {{GENDER:$2|lisasid}} aruteluleheküljele \"<strong>$4</strong>\": {{PLURAL:$5|$5 saatmata}}, {{PLURAL:$6|$6 saadetud}}.", - "notification-header-user-rights-add-only": "{{GENDER:$4|Sinu}} kasutajaõigusi {{GENDER:$1|muudeti}}. Sind lisati rühma: $2.", - "notification-header-user-rights-remove-only": "{{GENDER:$4|Sinu}} kasutajaõigusi {{GENDER:$1|muudeti}}. Sa ei kuulu enam rühma: $2.", - "notification-header-user-rights-add-and-remove": "{{GENDER:$6|Sinu}} kasutajaõigused {{GENDER:$1|muudeti}}. Kuulud nüüd järgmistesse rühmadesse: $2. Sa ei kuulu enam järgmistesse rühmadesse: $4.", + "notification-header-user-rights-add-only": "{{GENDER:$4|Sinu}} kasutajaõigusi {{GENDER:$1|muudeti}}. Sind lisati {{PLURAL:$3|järgmisesse rühma|järgmistesse rühmadesse}}: $2.", + "notification-header-user-rights-remove-only": "{{GENDER:$4|Sinu}} kasutajaõigusi {{GENDER:$1|muudeti}}. Sa ei kuulu enam {{PLURAL:$3|järgmisesse rühma|järgmistesse rühmadesse}}: $2.", + "notification-header-user-rights-add-and-remove": "{{GENDER:$6|Sinu}} kasutajaõigused {{GENDER:$1|muudeti}}. Kuulud nüüd {{PLURAL:$3|järgmisesse rühma|järgmistesse rühmadesse}}: $2. Sa ei kuulu enam {{PLURAL:$5|järgmisesse rühma|järgmistesse rühmadesse}}: $4.", "notification-header-user-rights-expiry-change": "{{GENDER:$4|Sinu}} liikmesuse aegumistähtaeg {{PLURAL:$3|järgmises rühmas|järgmistes rühmades}} on {{GENDER:$1|muudetud}}: $2.", "notification-header-welcome": "{{GENDER:$2|Tere}} tulemast saidile {{SITENAME}}, $1! Meil on hea meel, et siin oled.", "notification-header-mention-summary": "$1 {{GENDER:$2|mainis}} {{GENDER:$3|sind}} lehekülje \"<strong>$4</strong>\" muudatuse resümees.", @@ -194,5 +196,6 @@ "echo-email-batch-link-text-view-all-notifications": "Vaata kõiki teavitusi", "notification-header-foreign-alert": "Veel märguandeid {{PLURAL:$5|teisest|$5 teisest}} vikist", "notification-header-foreign-notice": "Veel märkusi {{PLURAL:$5|teisest|$5 teisest}} vikist", - "notification-header-foreign-all": "Veel teavitusi {{PLURAL:$5|teisest|$5 teisest}} vikist" + "notification-header-foreign-all": "Veel teavitusi {{PLURAL:$5|teisest|$5 teisest}} vikist", + "echo-foreign-wiki-lang": "$1 – $2" } diff --git a/Echo/i18n/eu.json b/Echo/i18n/eu.json index 18520003..ceb7bfd2 100644 --- a/Echo/i18n/eu.json +++ b/Echo/i18n/eu.json @@ -25,7 +25,7 @@ "echo-pref-email-format-plain-text": "Testu laua", "echo-pref-cross-wiki-notifications": "Erakutsi beste wikietako jakinarazpenak", "echo-learn-more": "Gehiago ikasi", - "echo-new-messages": "Mezu berriak dituzu", + "echo-new-messages": "Mezu berriak dituzu eztabaida orrian", "echo-category-title-edit-user-talk": "{{PLURAL:$1|mezu}} eztabaida orrian", "echo-category-title-mention": "{{PLURAL:$1|Aipamen|Aipamenak}}", "echo-category-title-other": "{{PLURAL:$1|Beste}}", @@ -35,7 +35,7 @@ "echo-pref-tooltip-edit-user-talk": "Jakinarazi norbaitek mezu bat nire eztabaida orrian jartzen edo erantzuten duenean.", "echo-pref-tooltip-article-linked": "Jakinarazi norbaitek egin dudan artikulu bati beste orri batetik loturen bat egiten duenean.", "echo-pref-tooltip-reverted": "Jakinaraz iezadazue inork nire ekarpenen bat atzera botatzen duenean, desegite edo lehengoratze tresnaren bidez.", - "echo-pref-tooltip-mention": "Jakinarazi norbaitek nire lankide orrira lotura egiten duenean.", + "echo-pref-tooltip-mention": "Jakinarazi niri, inork nire lankide orriranzko esteka ezartzen duenean.", "echo-pref-tooltip-user-rights": "Jakinarazi norbaitek nire lankide eskubideak aldatzean.", "echo-pref-tooltip-emailuser": "Jakinarazi norbaitek niri email bat bidaltzean.", "echo-pref-tooltip-article-reminder": "Artikulu honen inguruko mezuak jaso eskatzen ditudanean.", @@ -46,7 +46,7 @@ "echo-specialpage": "Jakinarazpenak", "echo-specialpage-section-markread": "Markatu taldea irakurritzat", "echo-specialpage-markasread": "Jakinarazpena: Markatu irakurritzat", - "echo-specialpage-pagination-numnotifications": "{{PLURAL:$1|jakinarazpen $1|$1 jakinarazpen}}", + "echo-specialpage-pagination-numnotifications": "{{PLURAL:$1|Jakinarazpen bat|$1 jakinarazpen}}", "echo-specialpage-pagefilters-title": "Azken jarduerak", "echo-specialpage-pagefilters-subtitle": "Irakurri gabeko jakinarazpenak dituzten orriak", "notificationsmarkread-legend": "Markatu jakinarazpena irakurritzat", @@ -94,22 +94,22 @@ "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1m}}", "notification-timestamp-ago-hours": "{{PLURAL:$1|$1 ord}}", "notification-timestamp-ago-days": "{{PLURAL:$1|$1 eg}}", - "notification-timestamp-ago-months": "{{PLURAL:$1|$1 hil}}", - "notification-timestamp-ago-years": "{{PLURAL:$1|$1 urt}}", + "notification-timestamp-ago-months": "{{PLURAL:$1|hilabete|$1 hilabete}}", + "notification-timestamp-ago-years": "{{PLURAL:$1|urtebete|$1 urte}}", "notification-timestamp-today": "Gaur", "notification-timestamp-yesterday": "Atzo", "notification-inbox-filter-read": "Irakurriak", "notification-inbox-filter-unread": "irakurri gabe", "notification-inbox-filter-all": "Denak", - "echo-notification-alert": "{{PLURAL:$1|Alerta ($1)|($1) Alerta|100=Alerta (99+)}}", - "echo-notification-notice": "{{PLURAL:$1|Mezu($1)|($1) mezu|100=Mezuak(99+)}}", + "echo-notification-alert": "{{PLURAL:$1|Alerta ($1)|Alertak ($1)|100=Alertak (99tik gora)}}", + "echo-notification-notice": "{{PLURAL:$1|Jakinarazpena ($1)|Jakinarazpenak ($1)|100=Jakinarazpenak (99tik gora)}}", "echo-notification-alert-text-only": "Alertak", "echo-notification-notice-text-only": "Abisuak", "echo-overlay-link": "Jakinarazpen guztiak", "echo-overlay-title": "<b>Jakinarazpenak</b>", "echo-mark-all-as-read": "Markatu denak irakurritzat", - "echo-mark-all-as-read-confirmation": "{{PLURAL:$1|Jakinarazpen $1|$1 jakinarazpen}} irakurriak bezala {{PLURAL:$1|markatua|markatuak}}", - "echo-mark-wiki-as-read": "Markatu denak irakurriak bezala aukeratutako wikian:$1", + "echo-mark-all-as-read-confirmation": "{{PLURAL:$1|Jakinarazpen bat|$1 jakinarazpen}} irakurritzat {{PLURAL:$1|markatu da|markatu dira}}", + "echo-mark-wiki-as-read": "Markatu denak irakurritzat, aukeratutako wikian: $1", "echo-date-today": "Gaur", "echo-date-yesterday": "Atzo", "echo-email-batch-link-text-view-all-notifications": "Jakinarazpen guztiak ikusi", diff --git a/Echo/i18n/fa.json b/Echo/i18n/fa.json index 81705359..bd8984f1 100644 --- a/Echo/i18n/fa.json +++ b/Echo/i18n/fa.json @@ -10,18 +10,22 @@ "Amjad Khan", "Arian Ar", "Baloch Khan", + "Beginneruser", "Bersam", "Calak", "Dalba", + "Darafsh", "Ebraminio", "FarsiNevis", "Hosseinblue", "Huji", + "Jeeputer", "Koroğlu", "Ladsgroup", "Macofe", "Mahdy Saffar", "Mjbmr", + "Mohammad ebz", "Omidh", "Reza1615", "Rtemis", @@ -31,31 +35,36 @@ ] }, "echo-desc": "سامانهٔ آگاهسازی کاربران از رویدادها و پیامها", - "prefs-echo": "اعلانها", + "prefs-echo": "آگاهسازیها", "prefs-emailsettings": "تنظیمات ایمیل", "prefs-echosubscriptions": "مرا از این رویدادها آگاه کن", - "prefs-echocrosswiki": "آگاهسازی همه ویکیها", + "prefs-echocrosswiki": "آگاهیسازیهای بین ویکی", "prefs-blocknotificationslist": "کاربران خاموششده", + "prefs-mutedpageslist": "صفحههای خاموششده برای آگاهسازیهای پیوند صفحه", "prefs-echopollupdates": "آگاهسازیهای زنده", "echo-mobile-notifications-filter-title": "پالایش آگاهسازیها", "echo-pref-show-poll-updates": "نمایش آگاهسازیهای جدید بهمحض رسیدن", + "echo-pref-show-poll-updates-help": "نمایش تعداد آگاهسازیهای خواندهنشده در نوار عنوان و نمایش مختصری از هر آگاهسازی بلافاصله پس از رسیدن آن.", "echo-pref-send-me": "برایم فرستاده شود:", "echo-pref-send-to": "فرستادهشود به:", "echo-pref-email-format": "قالب ایمیل:", "echo-pref-web": "وبگاه", "echo-pref-email": "ایمیل", - "echo-pref-email-frequency-never": "ایمیل اعلانها برایم فرستاده نشود", - "echo-pref-email-frequency-immediately": "اعلانهای جداگانه به محض دریافت", - "echo-pref-email-frequency-daily": "خلاصهٔ روزانهٔ اعلانها", - "echo-pref-email-frequency-weekly": "خلاصهٔ هفتگی اعلانها", + "echo-pref-push": "برنامهها", + "echo-pref-email-frequency-never": "هیج آگاهسازی ایمیلی برای من ارسال نشود", + "echo-pref-email-frequency-immediately": "آگاهسازیهای جداگانه به محض دریافت", + "echo-pref-email-frequency-daily": "یک خلاصهٔ روزانه از آگاهسازیها", + "echo-pref-email-frequency-weekly": "یک خلاصهٔ هفتگی از آگاهیسازیها", "echo-pref-email-format-html": "اچتیامال", "echo-pref-email-format-plain-text": "متن ساده", - "echo-pref-cross-wiki-notifications": "نمایش آگاهسازی از ویکیهای دیگر", - "echo-pref-notifications-blacklist": "عدم نمایش آگاهسازی برای این کاربران. [[mw:Special:MyLanguage/Help:Notifications#mute|برای اطلاعات بیشتر]]", + "echo-pref-cross-wiki-notifications": "نمایش آگاهسازیها از ویکیهای دیگر", + "echo-pref-notifications-blacklist": "عدم نمایش آگاهسازیها برای این کاربران. [[mw:Special:MyLanguage/Help:Notifications#mute|بیشتر یاد بگیرید]]", + "echo-pref-notifications-page-linked-title-muted-list": "عدم نمایش آگاهسازیهای «پیوند صفحه» برای این صفحات. [[mw:Special:MyLanguage/Help:Notifications#mute|بیشتر بدانید]]", + "echo-pref-dont-email-read-notifications": "آگاهسازیهای خواندهشده در ایمیلهای خلاصه آورده نشود", "echo-learn-more": "اطلاعات بیشتر", "echo-log": "سیاهه عمومی", - "echo-new-messages": "پیامهای جدیدی دارید", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|پیام|پیامهای}} صفحهٔ بحث", + "echo-new-messages": "در صفحهٔ بحثتان پیام جدیدی دارید", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|ویرایش|ویرایشها}} در صفحهٔ بحث من", "echo-category-title-article-linked": "{{PLURAL:$1|پیوند|پیوندهای}} صفحه", "echo-category-title-reverted": "{{PLURAL:$1|واگردانی|واگردانیهای}} ویرایش", "echo-category-title-mention": "{{PLURAL:$1|اشاره|اشارهها}}", @@ -64,26 +73,29 @@ "echo-category-title-other": "{{PLURAL:$1|سایر}}", "echo-category-title-system": "{{PLURAL:$1|سامانه}}", "echo-category-title-system-noemail": "{{PLURAL:$1|سامانه}}", - "echo-category-title-user-rights": "{{PLURAL:$1|تغییر دسترسیهای کاربری|تغییرات دسترسیهای کاربری}}", + "echo-category-title-system-emailonly": "{{PLURAL:$1|سامانه}}", + "echo-category-title-user-rights": "{{PLURAL:$1|تغییر اختیارات کاربر|تغییرات اختیارات کاربر}}", "echo-category-title-emailuser": "{{PLURAL:$1|ایمیل از کاربری دیگر|ایمیلهایی از دیگر کاربران}}", "echo-category-title-article-reminder": "صفحهٔ {{PLURAL:$1|یادآوری|یادآوری}}", "echo-category-title-thank-you-edit": "ویرایش {{PLURAL:$1|رویداد مهم|رویدادهای مهم}}", "echo-category-title-watchlist": "ویرایش در صفحهٔ محافظتشده", "echo-category-title-minor-watchlist": "ویرایش جزئی در صفحهٔ محافظتشده", - "echo-pref-tooltip-edit-user-talk": "وقتی کسی برایم پیام فرستاد یا جواب پیام مرا در صفحهٔ بحثم داد، مرا آگاه کن.", + "echo-pref-tooltip-edit-user-talk": "وقتی کسی صفحهٔ بحثم را ویرایش کرد، مرا آگاه کن.", "echo-pref-tooltip-article-linked": "وقتی کسی به صفحهای که ایجاد کردهام پیوند داد، مرا آگاه کن.", "echo-pref-tooltip-reverted": "وقتی کسی ویرایش مرا با ابزار خثنیسازی یا واگردانی، خثنی کرد، مرا آگاه کن.", "echo-pref-tooltip-mention": "وقتی کسی به صفحهٔ کاربریام پیوند داد، مرا آگاه کن.", "echo-pref-tooltip-mention-failure": "زمانی که اشارهکردن به سایر کاربران با خطا مواجه شد به من اطلاع بده.", "echo-pref-tooltip-mention-success": "زمانی که اشارهکردن به سایر کاربران با موفقیت انجام شد به من اطلاع بده.", - "echo-pref-tooltip-user-rights": "وقتی کسی دسترسیهای کاربری من را تغییر داد مرا آگاه کن.", + "echo-pref-tooltip-user-rights": "وقتی کسی اختیارات کاربری من را تغییر داد مرا آگاه کن.", "echo-pref-tooltip-emailuser": "وقتی کسی به من ایمیل فرستاد، مرا آگاه کن.", "echo-pref-tooltip-article-reminder": "زمانی که درخواست دادم، دربارهٔ این صفحه مرا آگاه کن.", "echo-pref-tooltip-thank-you-edit": "زمانی که به اولین، دهمین، صدمین و... ویرایش رسیدم من را مطلع کن.", - "notifications": "اعلانها", + "echo-pref-tooltip-watchlist": "هرگاه شخصی ویرایش (غیر جزئی) در هریک از صفحههای موجود در فهرست پیگیریام انجام داد، مرا آگاه کن.", + "echo-pref-tooltip-minor-watchlist": "هرگاه شخصی ویرایشی جزئی در هریک از صفحههای موجود در فهرست پیگیریام انجام داد، مرا آگاه کن.", + "notifications": "آگاهسازیها", "tooltip-pt-notifications-alert": "هشدارهای {{GENDER:|شما}}", "tooltip-pt-notifications-notice": "آگاهیهای {{GENDER:|شما}}", - "echo-displaynotificationsconfiguration": "نمایش تنظیمات آگاهسازیها", + "echo-displaynotificationsconfiguration": "نمایش پیکربندی آگاهیسازیها", "echo-displaynotificationsconfiguration-summary": "این نگاهی اجمالی است برای مشخص کردن اینکه چگونه آگاهسازیها برای این ویکی تنظیم میشوند.", "echo-displaynotificationsconfiguration-notifications-by-category-header": "آگاهسازیها بر پایه رده", "echo-displaynotificationsconfiguration-sorting-by-section-header": "مرتبکردن نوعها", @@ -100,27 +112,34 @@ "echo-specialpage-markasread": "آگاهسازی: انتخاب به عنوان خوانده شده", "echo-specialpage-markasread-invalid-id": "شناسهٔ رویداد نامعتبر", "echo-specialpage-pagefilterwidget-aria-label": "پالایش بر حسب ویکی و عنوان صفحه", - "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|آگاهسازی|آگاهسازی}}", + "echo-specialpage-special-help-menu-widget-aria-label": "گزینههای اضافی و ترجیحات آگاهیسازیها.", + "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|اعلان}}", "echo-specialpage-pagefilters-title": "فعالیتهای اخیر", - "echo-specialpage-pagefilters-subtitle": "صفحات دارای آگاهسازیهای خواندهنشده", + "echo-specialpage-pagefilters-subtitle": "صفحههای دارای اعلانهای خواندهنشده", "notificationsmarkread-legend": "علامت زدن آگاهسازی به عنوان خوانده شده", - "echo-none": "آگاهسازی ندارید.", - "echo-api-failure": "ناتوان از دریافت آگاهسازیها.", + "echo-none": "شما هیچ اعلانی ندارید.", + "echo-api-failure": "ناموفق در واکشی آگاهسازیها.", "echo-api-failure-cross-wiki": "اجازهٔ دسترسی به دامنه دور داده نشد.", - "echo-notification-placeholder": "آگاهسازی ندارید.", - "echo-notification-placeholder-filters": "آگاهسازیای در مطابقت با این شرایط وجود ندارد.", + "echo-notification-placeholder": "هیچ اعلانی وجود ندارد.", + "echo-notification-placeholder-filters": "هیچ آگاهسازی مطابقت با این شرایط وجود ندارد.", "echo-notification-loginrequired": "برای دیدن آگاهسازیهایتان باید به سامانه وارد شوید.", "echo-notification-popup-loginrequired": "لطفاً برای دیدن آگاهسازیهایتان به سامانه وارد شوید.", "echo-notification-markasread": "علامتگذاری به عنوان خواندهشده", "echo-notification-markasunread": "علامتگذاری به عنوان خواندهنشده", "echo-notification-markasread-tooltip": "علامتگذاری به عنوان خواندهشده", "echo-notification-more-options-tooltip": "گزینههای بیشتر", - "notification-dynamic-actions-unwatch": "فعالیتهای تازه در «$1» را پیگیری {{GENDER:$3|نکن}}", - "notification-dynamic-actions-unwatch-confirmation": "شما دیگر صفحهٔ «$1» را پیگیری {{GENDER:$3|نمیکنید}}", - "notification-dynamic-actions-unwatch-confirmation-description": "شما میتوانید هر زمان خواستید [$2 این صفحه] را پیگیری {{GENDER:$3|کنید}}", + "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|بیصدا کردن}} آگاهسازیهای پیونددهی در «$1»", + "notification-dynamic-actions-mute-page-linked-confirmation": "آگاهسازیهای «پیوند به صفحه» برای صفحهٔ «$1» اکنون غیرفعال شدهاند", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|شما}} در هر زمانی میتوانید صفحههای بیصدا شدهٔ خود را در [$1 ترجیحات خود] مدیریت کنید.", + "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2|صدادار کردن}} آگاهسازیهای پیونددهی در «$1»", + "notification-dynamic-actions-unmute-page-linked-confirmation": "آگاهسازیهای «پیوند به صفحه» برای صفحهٔ «$1» اکنون فعال شدهاند", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|شما}} در هر زمانی میتوانید صفحههای بیصدا شدهٔ خود را در [$1 ترجیحات خود] مدیریت کنید.", + "notification-dynamic-actions-unwatch": "فعالیتهای تازه در «$1» را پیگیری {{GENDER:$3|نکن}}", + "notification-dynamic-actions-unwatch-confirmation": "شما دیگر صفحهٔ «$1» را پیگیری {{GENDER:$3|نمیکنید}}", + "notification-dynamic-actions-unwatch-confirmation-description": "شما میتوانید هر زمان خواستید [$2 این صفحه] را پیگیری {{GENDER:$3|کنید}}", "notification-dynamic-actions-watch": "فعالیتهای تازه در «$1» را دنبال {{GENDER:$3|کن}}", - "notification-dynamic-actions-watch-confirmation": "شما حالا صفحهٔ «$1» پیگیری {{GENDER:$3|میکنید}}", - "notification-dynamic-actions-watch-confirmation-description": "شما میتوانید هر زمان خواستید پیگیری [$2 این صفحه] را متوقف {{GENDER:$3|کنید}}.", + "notification-dynamic-actions-watch-confirmation": "شما حالا صفحهٔ «$1» پیگیری {{GENDER:$3|میکنید}}", + "notification-dynamic-actions-watch-confirmation-description": "شما میتوانید هر زمان خواستید پیگیری [$2 این صفحه] را متوقف {{GENDER:$3|کنید}}.", "notification-link-text-expand-all": "گسترش", "notification-link-text-expand-alert-count": "دیدن {{PLURAL:$1|$1 هشدار|$1 هشدار}}", "notification-link-text-expand-notice-count": "دیدن {{PLURAL:$1|$1 آگاهسازی|$1 آگاهسازی}}", @@ -158,14 +177,23 @@ "notification-header-mention-success-bundle": "{{PLURAL:$3|اشارهای|$3 اشارهای}} که {{GENDER:$2|شما}} در بحث <strong>$4</strong> ایجاد کردید {{PLURAL:$3|ارسال}} شد.", "notification-compact-header-mention-success": "{{GENDER:$2|اشاره کردید به}}: $3", "notification-header-mention-status-bundle": "{{PLURAL:$3|یک آگاهسازی|$3 آگاهسازی}} دربارهٔ {{PLURAL:$3|اشارهای|اشارههایی}} که در صفحهٔ بحث <strong>$4</strong> {{GENDER:$2|انجام دادید}}: {{PLURAL:$5|$5 مورد فرستاده نشد}}، {{PLURAL:$6|$6 مورد فرستاده شد}}.", - "notification-header-user-rights-add-only": "دسترسی {{GENDER:$4|شما}} تغییر {{GENDER:$1|کردهاست}}. اضافه شدید به: $2.", - "notification-header-user-rights-remove-only": "دسترسی {{GENDER:$4|شما}} تغییر {{GENDER:$1|کردهاست}}. دیگر در $2 عضو نیستید.", - "notification-header-user-rights-add-and-remove": "دسترسی {{GENDER:$6|شما}} تغییر {{GENDER:$1|کردهاست}}. اضافه شدید به: $2. دیگر در $4 عضو نیستید.", + "notification-header-user-rights-add-only": "امتیاز {{GENDER:$4|شما}} تغییر {{GENDER:$1|کردهاست}}. اضافه شدید به: $2.", + "notification-header-user-rights-remove-only": "امتیاز {{GENDER:$4|شما}} تغییر {{GENDER:$1|کردهاست}}. دیگر در $2 عضو نیستید.", + "notification-header-user-rights-add-and-remove": "امتیاز {{GENDER:$6|شما}} تغییر {{GENDER:$1|کردهاست}}. اضافه شدید به: $2. دیگر در $4 عضو نیستید.", "notification-header-user-rights-expiry-change": "انقضای عضویت {{GENDER:$4|شما}} در این {{PLURAL:$3|گروه|گروهها}} تغییر {{GENDER:$1|یافتهاست}}: $2", "notification-header-welcome": "$1، به {{SITENAME}} {{GENDER:$2|خوش آمدید}}. خوشحالیم که {{GENDER:$2|شما}} اینجایید.", "notification-header-mention-summary": "$1 {{GENDER:$3|به شما}} در خلاصه ویرایش <strong>$4</strong> {{GENDER:$2|اشاره کرد}}.", - "notification-header-watchlist-multiuser-moved": "صفحهٔ <strong>$1</strong> که در فهرست پیگیریهای {{GENDER:$2|شما}} حضور دارد، $3 {{PLURAL:$3|بار|بار}} منتقل شده است.", - "notification-header-watchlist-multiuser-restored": "صفحهٔ <strong>$1</strong> که در فهرست پیگیریهای {{GENDER:$2|شما}} حضور دارد، $3 {{PLURAL:$3|بار|بار}} بازیابی شده است.", + "notification-header-watchlist-changed": "$1 صفحهٔ <strong>$3</strong> که در فهرست پیگیری {{GENDER:$4|شما}} موجود است را {{GENDER:$2|{{PLURAL:$5|تغییر داد|$5 دفعه تغییر داد}}}}.", + "notification-header-watchlist-created": "$1 صفحهٔ <strong>$3</strong> که در فهرست پیگیری {{GENDER:$4|شما}} موجود است را {{GENDER:$2|{{PLURAL:$5|ایجاد کرد|$5 دفعه ایجاد کرد}}}}.", + "notification-header-watchlist-deleted": "$1 صفحهٔ <strong>$3</strong> که در فهرست پیگیری {{GENDER:$4|شما}} موجود است را {{GENDER:$2|{{PLURAL:$5|حذف کرد|$5 دفعه حذف کرد}}}}.", + "notification-header-watchlist-moved": "$1 صفحهٔ <strong>$3</strong> که در فهرست پیگیری {{GENDER:$4|شما}} موجود است را {{GENDER:$2|{{PLURAL:$5|منتقل کرد|$5 دفعه منتقل کرد}}}}.", + "notification-header-watchlist-restored": "$1 صفحهٔ <strong>$3</strong> که در فهرست پیگیری {{GENDER:$4|شما}} موجود است را {{GENDER:$2|{{PLURAL:$5|احیا کرد|$5 دفعه احیا کرد}}}}.", + "notification-header-watchlist-multiuser-changed": "صفحهٔ <strong>$1</strong> که در فهرست پیگیریهای {{GENDER:$2|شما}} موجود است، $3{{PLURAL:$3|دفعه}} تغییر یافت.", + "notification-header-watchlist-multiuser-created": "صفحهٔ <strong>$1</strong> که در فهرست پیگیری {{GENDER:$2|شما}} موجود است، $3 {{PLURAL:$3|دفعه}} ایجاد شد.", + "notification-header-watchlist-multiuser-deleted": "صفحهٔ <strong>$1</strong> که در فهرست پیگیری {{GENDER:$2|شما}} موجود است، $3 {{PLURAL:$3|دفعه}} حذف شد.", + "notification-header-watchlist-multiuser-moved": "صفحهٔ <strong>$1</strong> که در فهرست پیگیری {{GENDER:$2|شما}} قرار دارد، $3 {{PLURAL:$3|بار}} منتقل شده است.", + "notification-header-watchlist-multiuser-restored": "صفحهٔ <strong>$1</strong> که در فهرست پیگیری {{GENDER:$2|شما}} حضور دارد، $3 {{PLURAL:$3|بار}} احیا شده است.", + "notification-body-watchlist-once": "در صورت فعالیتهای بیشتر، هیچ اعلانی از طریق ایمیل ارسال نخواهد شد؛ مگر آن که {{GENDER:$1|شما}} در حالی که به سامانه وارد شدهاید، از این صفحه بازدید کنید.", "notification-welcome-linktext": "خوش آمدید", "notification-header-thank-you-1-edit": "{{GENDER:$2|شما}} اولین ویرایشتان را {{GENDER:$2|انجام دادید}}. سپاس از {{GENDER:$2|شما}}، و خوش آمدید!", "notification-header-thank-you-10-edit": "{{GENDER:$2|شما}} دهمین ویرایشتان را {{GENDER:$2|انجام دادید}}؛ {{GENDER:$2|ممنون}}، لطفاً ادامه دهید!", @@ -174,6 +202,7 @@ "notification-header-thank-you-10000-edit": "{{GENDER:$2|شما}} دههزارمین ویرایشتان را {{GENDER:$2|انجام دادید}}؛ {{GENDER:$2|خیلی ممنون}}!", "notification-header-thank-you-100000-edit": "{{GENDER:$2|شما}} صد هزارمین ویرایشتان را {{GENDER:$2|انجام دادید}}؛ {{GENDER:$2|ممنون}} از بابت اینکه ویرایشگر بزرگی هستید!", "notification-header-thank-you-1000000-edit": "{{GENDER:$2|شما}} یک میلیونمین ویرایشتان را {{GENDER:$2|انجام دادید}}؛ {{GENDER:$2|ممنون}} از بابت اینکه ویرایشگر بزرگی هستید!", + "notification-header-thank-you-10000000-edit": "{{GENDER:$2|شما}} ده میلیونمین ویرایش {{GENDER:$2|خود}} را انجام دادید؛ از فداکاری درخشان {{GENDER:$2|شما}} ممنونیم!", "notification-link-thank-you-edit": "{{GENDER:$1|ویرایش}} شما", "notification-link-text-view-edit": "نمایش ویرایش", "notification-link-article-reminder": "مشاهدهٔ صفحه", @@ -183,7 +212,7 @@ "notification-page-linked-email-subject": "صفحهای که {{GENDER:$3|شما}} آغازگر آن بودید در {{SITENAME}} پیوند شد.", "notification-reverted-email-subject2": "{{PLURAL:$4|ویرایش|ویرایشهای}} {{GENDER:$3|شما}} در {{SITENAME}} {{GENDER:$2|واگردانی شدهاست}}", "notification-mention-email-subject": "$1 {{GENDER:$3|شما}} را در {{SITENAME}} {{GENDER:$2|ذکر کردهاست}}", - "notification-user-rights-email-subject": "دسترسیهای {{GENDER:$3|شما}} در {{SITENAME}} تغییر یافتهاست", + "notification-user-rights-email-subject": "اختیارات {{GENDER:$3|شما}} در {{SITENAME}} تغییر یافتهاست", "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1 ثانیه}}", "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1 دقیقه}}", "notification-timestamp-ago-hours": "{{PLURAL:$1|$1 ساعت}}", @@ -195,7 +224,7 @@ "notification-inbox-filter-read": "خواندهشده", "notification-inbox-filter-unread": "خواندهنشده", "notification-inbox-filter-all": "همه", - "echo-specialmute-label-mute-notifications": "بیصدا کردن آگاهسازیهای از سوی این کاربر", + "echo-specialmute-label-mute-notifications": "بیصدا کردن آگاهیسازیها از سوی این {{GENDER:$1|کاربر}}", "echo-email-plain-footer": "برای تنظیم ایمیلهایی که دریافت {{GENDER:$1|میکنید}}، تنظیماتتان را بررسی {{GENDER:$1|کنید}}:", "echo-email-html-footer-preference-link-text": "ترجیحاتتان را بررسی {{GENDER:$1|کنید}}", "echo-email-html-footer-with-link": "برای بررسی ایمیلهایی که برای شما ارسال {{GENDER:$2|کردیم}}، $1.", @@ -204,7 +233,7 @@ "echo-notification-alert-text-only": "هشدارها", "echo-notification-notice-text-only": "آگاهیها", "echo-overlay-link": "همهٔ آگاهسازیها", - "echo-overlay-title": "<b>آگاهسازیها</b>", + "echo-overlay-title": "<b>آگاهیسازیها</b>", "echo-mark-all-as-read": "نشانگذاری همه به عنوان خواندهشده", "echo-mark-all-as-read-confirmation": "$1 آگاهسازی به عنوان خواندهشده علامت {{PLURAL:$1|خورد|خوردند}}", "echo-mark-wiki-as-read": "انتخاب همهٔ موارد در ویکی انتخاب شده به عنوان خوانده شده:$1", @@ -216,8 +245,13 @@ "echo-email-batch-subject-weekly": "شما دارای {{PLURAL:$2|یک آگاهسازی تازه|آگاهسازیهای تازهای}} در {{SITENAME}} در این هفته هستید", "echo-email-batch-body-intro-daily": "سلام $1،\nدر اینجا خلاصهٔ فعالیت امروز شما در {{SITENAME}} وجود دارد.", "echo-email-batch-body-intro-weekly": "سلام $1،\nدر اینجا خلاصهٔ فعالیت این هفتهٔ شما در {{SITENAME}} وجود دارد.", - "echo-email-batch-link-text-view-all-notifications": "دیدن همهٔ آگاهسازیها", + "echo-email-batch-link-text-view-all-notifications": "مشاهدهٔ تمام آگاهسازیها", "notification-header-foreign-alert": "هشدارهای بیشتر از {{PLURAL:$5|و ویکی دیگر|و $5 ویکی دیگر}}", "notification-header-foreign-notice": "آگاهیهای بیشتر از {{PLURAL:$5|ویکی دیگر|$5 ویکی دیگر}}", - "notification-header-foreign-all": "آگاهسازیهای بیشتر از $5 ویکی دیگر" + "notification-header-foreign-all": "آگاهسازیهای بیشتر از $5 ویکی دیگر", + "right-manage-all-push-subscriptions": "مدیریت تمام اشتراکات فشاری", + "action-manage-all-push-subscriptions": "مدیریت تمام اشتراکات فشاری", + "group-push-subscription-manager": "مدیران اشتراک فشاری", + "group-push-subscription-manager-member": "{{GENDER:$1|مدیر اشتراک فشاری}}", + "grouppage-push-subscription-manager": "{{ns:project}}:مدیران اشتراک فشاری" } diff --git a/Echo/i18n/fat.json b/Echo/i18n/fat.json new file mode 100644 index 00000000..16f70337 --- /dev/null +++ b/Echo/i18n/fat.json @@ -0,0 +1,56 @@ +{ + "@metadata": { + "authors": [ + "Ebenoffen1", + "Georgecoleman", + "Suzieturkson" + ] + }, + "echo-desc": "Dza yɛdze bɔ dwumadzifo nkae fa dwumadzi na nkrato ho", + "prefs-echo": "Nkaebɔ", + "prefs-emailsettings": "Email horow", + "prefs-echosubscriptions": "Bɔ me nkae fa dwumadzi yinom ho", + "prefs-echocrosswiki": "Cross-wiki ho nkaabɔ", + "prefs-blocknotificationslist": "Dwumadzifo a wonntum nndzi dwuma", + "prefs-mutedpageslist": "Kratafa lenke nkaabɔ a ɔfa nkratafa a wɔato mu ho", + "prefs-echopollupdates": "Mprempren nkaabɔ", + "echo-mobile-notifications-filter-title": "Sɔn nkaabɔ do", + "echo-pref-show-poll-updates": "Bue nkaabɔ fofor ber a minyaa no ara.", + "echo-pref-show-poll-updates-help": "Kyerɛ nkaabɔ a ɔwɔ tsirasɛm bea a ennkenkanee na kyerɛ nkaabɔ ne fa kakra biara amonmu a ɔbɛbɛ", + "echo-pref-send-me": "Fa ma me", + "echo-pref-send-to": "Ma ɔnkɔ:", + "echo-pref-email-format": "Email ne tsebea", + "echo-pref-web": "Web", + "echo-pref-email": "Email", + "echo-pref-push": "Apps", + "echo-pref-email-frequency-never": "Mma mma me email nkaabɔ biara", + "echo-pref-email-frequency-immediately": "Ankorankor nkaebɔ na ber a ɔba", + "echo-pref-email-frequency-daily": "Daa daa nkaabɔ tɔfabɔ", + "echo-pref-email-frequency-weekly": "Dapɛn dapɛn nkaabɔ tɔfa", + "echo-pref-email-format-html": "HTML", + "echo-pref-email-format-plain-text": "Kratafa a hwee nnyi do", + "echo-pref-cross-wiki-notifications": "Kyerɛ nkaebɔ a ofir wiki binom", + "echo-pref-notifications-blacklist": "Mma nnkyerɛ nkaabɔ a ofi dwumadzifo yinom hɔ edzi.([[mw:Special:MyLanguage/Help:Notifications#mute|sua bi ka ka ho]])", + "echo-pref-notifications-page-linked-title-muted-list": "Mma nnda \"Page link\" nkaabɔ mma dɛm kratafa yinom. ([[mw:Special:MyLanguage/Help:Notifications#mute|sua bi ka ho]])", + "echo-pref-dont-email-read-notifications": "Mma mmfa nkaabɔ a wɔakenkan dadaw wɔ tɔfabɔ emails no mu", + "echo-learn-more": "Sua bi kaho", + "echo-log": "Amansuon lɔɔgo", + "echo-new-messages": "Enya nkɔmbɔdzibea nkrato fofor", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Edit|Edits}} kɔ mo nkɔmbɔdzibea", + "echo-category-title-article-linked": "Kratafa {{PLURAL:$1|lenke}}", + "echo-category-title-reverted": "Yɛ nsesa {{PLURAL:$1|san ekyir}}", + "echo-category-title-mention": "{{PLURAL:$1|Dza wɔabɔ dzin|Dza wɔabobɔ edzin}}", + "echo-category-title-mention-failure": "Annyɛ yie {{PLURAL:$1|Dza wɔabɔ dzin|Dza wɔabobɔ edzin}}", + "echo-category-title-mention-success": "Ɔayɛ yie {{PLURAL:$1|dza wɔabɔ dzin|dza wɔabobɔ edzin}}", + "echo-category-title-other": "{{PLURAL:$1|Afofor}}", + "echo-category-title-system": "{{PLURAL:$1|System}}", + "echo-category-title-system-noemail": "{{PLURAL:$1|System}}", + "echo-category-title-system-emailonly": "{{PLURAL:$1|System}}", + "echo-category-title-user-rights": "{{PLURAL:$1|Dwumadzinyi no tumdze nsesaa}}", + "echo-category-title-emailuser": "{{PLURAL:$1|Email a ofi dwumadzinyi fofor hɔ|Email a ofi dwumadzifo afofor hɔ}}", + "echo-category-title-article-reminder": "Page {{PLURAL:$1|nkaakaadze}}", + "echo-category-title-thank-you-edit": "Nsesa {{PLURAL:$1|milestone|milestones}}", + "echo-category-title-watchlist": "Yɛ nsesa kɔ kratafa a wɔahwɛ do", + "echo-category-title-minor-watchlist": "Yɛ nsesa kumaa kɔ kratafa a wɔahwɛ do", + "echo-pref-tooltip-edit-user-talk": "Bɔ me nkaa sɛ obi yɛ nsesa wɔ me mkɔmbɔdzibea hɔ" +} diff --git a/Echo/i18n/ff.json b/Echo/i18n/ff.json index 282d2ad8..2c0d1966 100644 --- a/Echo/i18n/ff.json +++ b/Echo/i18n/ff.json @@ -1,7 +1,8 @@ { "@metadata": { "authors": [ - "Ibrahima" + "Ibrahima", + "Ibrahima Malal Sarr" ] }, "tooltip-pt-notifications-alert": "Jeertine {{GENDER:|maa}}" diff --git a/Echo/i18n/fi.json b/Echo/i18n/fi.json index df010f37..6186b1a5 100644 --- a/Echo/i18n/fi.json +++ b/Echo/i18n/fi.json @@ -3,19 +3,25 @@ "authors": [ "01miki10", "Crt", + "Jack Phoenix", "Kyykaarme", + "MITO", "McSalama", "Mikahama", + "Moj", "Nedergard", "Nike", "Olli", "Pitke", "Pxos", "Pyscowicz", + "Rönttönen", "Samoasambia", "Silvonen", "Stryn", - "VezonThunder" + "Veikk0.ma", + "VezonThunder", + "Zzko" ] }, "echo-desc": "Järjestelmä jonka avulla käyttäjille voi lähettää ilmoituksia tapahtumista ja viesteistä", @@ -24,11 +30,17 @@ "prefs-echosubscriptions": "Ilmoita minulle näistä tapahtumista", "prefs-echocrosswiki": "Wikienväliset ilmoitukset", "prefs-blocknotificationslist": "Hiljennetyt käyttäjät", + "prefs-mutedpageslist": "Sivun linkki -ilmoituksilta hiljennetyt sivut", + "prefs-echopollupdates": "Reaaliaikaiset ilmoitukset", + "echo-mobile-notifications-filter-title": "Suodata ilmoituksia", + "echo-pref-show-poll-updates": "Näytä uudet ilmoitukset sitä mukaa kun niitä saapuu", + "echo-pref-show-poll-updates-help": "Näytä lukemattomien ilmoitusten määrä tilapalkissa ja näytä ote jokaisesta ilmoituksesta kun se saapuu.", "echo-pref-send-me": "Lähetä minulle:", "echo-pref-send-to": "Lähetä osoitteeseen:", "echo-pref-email-format": "Sähköpostin muoto:", "echo-pref-web": "Verkko", "echo-pref-email": "Sähköposti", + "echo-pref-push": "Sovellukset", "echo-pref-email-frequency-never": "Älä lähetä minulle sähköposti-ilmoituksia", "echo-pref-email-frequency-immediately": "Yksittäiset ilmoitukset sitä mukaa kun niitä tulee", "echo-pref-email-frequency-daily": "Päivittäinen yhteenveto ilmoituksista", @@ -37,10 +49,11 @@ "echo-pref-email-format-plain-text": "Pelkkä teksti", "echo-pref-cross-wiki-notifications": "Näytä ilmoituksia muista wikeistä", "echo-pref-notifications-blacklist": "Älä näytä ilmoituksia näiltä käyttäjiltä. ([[mw:Special:MyLanguage/Help:Notifications#mute|lisätietoja]])", + "echo-pref-notifications-page-linked-title-muted-list": "Älä näytä Sivun linkki -ilmoituksia näiltä sivuilta. ([[mw:Special:MyLanguage/Help:Notifications#mute|lisätietoja]])", "echo-learn-more": "Lue lisää aiheesta", "echo-log": "Julkinen loki", - "echo-new-messages": "Sinulle on uusia viestejä", - "echo-category-title-edit-user-talk": "Keskustelusivun {{PLURAL:$1|viesti|viestit}}", + "echo-new-messages": "Sinulle on uusi viesti keskustelusivulla", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Kommentti|Kommenttia}} omalla keskustelusivullani", "echo-category-title-article-linked": "{{PLURAL:$1|Sivun linkki|Sivujen linkit}}", "echo-category-title-reverted": "{{PLURAL:$1|Muokkauksen kumoaminen|Muokkausten kumoamiset}}", "echo-category-title-mention": "{{PLURAL:$1|Maininta|Maininnat}}", @@ -53,7 +66,7 @@ "echo-category-title-user-rights": "{{PLURAL:$1|Käyttöoikeusmuutos|Käyttöoikeusmuutokset}}", "echo-category-title-emailuser": "{{PLURAL:$1|Sähköposti toiselta käyttäjältä|Sähköpostia toisilta käyttäjiltä}}", "echo-category-title-thank-you-edit": "{{PLURAL:$1|Muokkausvirstanpylväs|Muokkausvirstanpylväät}}", - "echo-pref-tooltip-edit-user-talk": "Ilmoita, kun joku kirjoittaa viestin tai vastaa viestiini keskustelusivullani.", + "echo-pref-tooltip-edit-user-talk": "Ilmoita, kun joku muokkaa keskustelusivuani.", "echo-pref-tooltip-article-linked": "Ilmoita, kun joku linkittää luomaani sivuun toiselta sivulta.", "echo-pref-tooltip-reverted": "Ilmoita, kun joku kumoaa tekemäni muokkauksen käyttäen kumoa- tai palauta-työkalua.", "echo-pref-tooltip-mention": "Ilmoita, kun joku tekee linkin käyttäjäsivulleni.", @@ -61,6 +74,7 @@ "echo-pref-tooltip-mention-success": "Ilmoita minulle, kun maininnan lähettäminen toiselle käyttäjälle onnistui.", "echo-pref-tooltip-user-rights": "Ilmoita, kun joku muuttaa käyttöoikeuksiani.", "echo-pref-tooltip-emailuser": "Ilmoita, kun joku lähettää minulle sähköpostia.", + "echo-pref-tooltip-thank-you-edit": "Ilmoita, kun teen ensimmäisen, 10:nnen, 100:nnen jne. muokkaukseni.", "notifications": "Ilmoitukset", "tooltip-pt-notifications-alert": "{{GENDER:|Hälytyksesi}}", "tooltip-pt-notifications-notice": "{{GENDER:|Ilmoituksesi}}", @@ -141,6 +155,7 @@ "notification-header-thank-you-10000-edit": "{{GENDER:$2|Teit}} juuri kymmenennentuhannennen muokkauksesi. Kiitos erittäin paljon!", "notification-header-thank-you-100000-edit": "{{GENDER:$2|Teit}} juuri sadannentuhannennen muokkauksesi. Kiitos\nuskomattomasta työstä!", "notification-header-thank-you-1000000-edit": "{{GENDER:$2|Teit}} juuri miljoonannen muokkauksesi. Kiitos hämmästyttävästä työstä!", + "notification-header-thank-you-10000000-edit": "{{GENDER:$2|Teit}} juuri kymmenennen miljoonannen muokkauksesi. Kiitos upeasta omistautumisestasi!", "notification-link-thank-you-edit": "{{GENDER:$1|Muokkauksesi}}", "notification-link-text-view-edit": "Näytä muokkaus", "notification-link-article-reminder": "Näytä sivu", @@ -162,7 +177,7 @@ "notification-inbox-filter-read": "Luetut", "notification-inbox-filter-unread": "Lukemattomat", "notification-inbox-filter-all": "Kaikki", - "echo-specialmute-label-mute-notifications": "Vaimenna ilmoitukset tältä käyttäjältä", + "echo-specialmute-label-mute-notifications": "Vaimenna ilmoitukset tältä {{GENDER:$1|käyttäjältä}}", "echo-email-plain-footer": "Valitaksesi mitä sähköposteja lähetämme {{GENDER:$1|sinulle}}, tarkista asetuksesi:", "echo-email-html-footer-preference-link-text": "tarkista {{GENDER:$1|asetuksesi}}", "echo-email-html-footer-with-link": "Valitaksesi mitä sähköposteja lähetämme {{GENDER:$2|sinulle}}, $1.", diff --git a/Echo/i18n/fr.json b/Echo/i18n/fr.json index 9fce9e44..1eac7341 100644 --- a/Echo/i18n/fr.json +++ b/Echo/i18n/fr.json @@ -3,7 +3,9 @@ "authors": [ "Ash Crow", "Automatik", + "Ayack", "Cedric31", + "Cigaryno", "Crochet.david", "DavidL", "Eihel", @@ -20,6 +22,7 @@ "Macofe", "Mattflaschen", "Mattho69", + "McDutchie", "Metroitendo", "Momo50WM", "NemesisIII", @@ -49,6 +52,7 @@ }, "echo-desc": "Système pour avertir les utilisateurs des événements et messages", "prefs-echo": "Notifications", + "prefs-description-echo": "Sélectionnez les notifications que vous{{GENDER:|}} recevez et comment les recevoir.", "prefs-emailsettings": "Options de courriel", "prefs-echosubscriptions": "Me prévenir de ces événements", "prefs-echocrosswiki": "Notifications inter-wikis", @@ -58,12 +62,12 @@ "echo-mobile-notifications-filter-title": "Filtrer les notifications", "echo-pref-show-poll-updates": "Afficher les nouvelles notifications quand elles arrivent", "echo-pref-show-poll-updates-help": "Afficher le nombre de notifications non lues dans la barre de titre et afficher un extrait de chacune immédiatement quand elle arrive.", - "echo-pref-send-me": "M’envoyer :", - "echo-pref-send-to": "Envoyer à :", - "echo-pref-email-format": "Format des courriels :", + "echo-pref-send-me": "M’envoyer :", + "echo-pref-send-to": "Envoyer à :", + "echo-pref-email-format": "Format des courriels :", "echo-pref-web": "Web", "echo-pref-email": "Courriel", - "echo-pref-push": "Applications", + "echo-pref-push": "Applis", "echo-pref-email-frequency-never": "Ne pas m’envoyer de notification par courriel", "echo-pref-email-frequency-immediately": "Les notifications individuelles sans délai", "echo-pref-email-frequency-daily": "Un résumé quotidien des notifications", @@ -72,13 +76,13 @@ "echo-pref-email-format-plain-text": "Texte brut", "echo-pref-cross-wiki-notifications": "Afficher les notifications d’autres wikis", "echo-pref-notifications-blacklist": "Ne pas afficher les notifications de ces utilisateurs. ([[mw:Special:MyLanguage/Help:Notifications#mute|en savoir plus]])", - "echo-pref-notifications-page-linked-title-muted-list": "Ne pas afficher les notifications « Lien de page » pour ces pages. ([[mw:Special:MyLanguage/Help:Notifications#mute|en savoir plus]])", - "echo-pref-dont-email-read-notifications": "Ne pas inclure les notifications de lecture dans les courriels de résumé", + "echo-pref-notifications-page-linked-title-muted-list": "Ne pas afficher les notifications « Lien de page » pour ces pages. ([[mw:Special:MyLanguage/Help:Notifications#mute|en savoir plus]])", + "echo-pref-dont-email-read-notifications": "Ne pas inclure les notifications déjà lues dans les courriels de résumé", "echo-learn-more": "En savoir plus", "echo-log": "Journal public", - "echo-new-messages": "Vous avez de nouveaux messages", - "echo-category-title-edit-user-talk": "Message{{PLURAL:$1||s}} sur ma page de discussion", - "echo-category-title-article-linked": "Article{{PLURAL:$1||s}} lié{{PLURAL:$1||s}}", + "echo-new-messages": "Vous avez un nouveau message", + "echo-category-title-edit-user-talk": "Modification{{PLURAL:$1|s}} de ma page de discussion utilisateur", + "echo-category-title-article-linked": "Page{{PLURAL:$1||s}} liée{{PLURAL:$1||s}}", "echo-category-title-reverted": "Modification{{PLURAL:$1||s}} annulée{{PLURAL:$1||s}}", "echo-category-title-mention": "Mention{{PLURAL:$1||s}}", "echo-category-title-mention-failure": "Échec {{PLURAL:$1|de la mention d’un utilisateur|des mentions d’utilisateurs}}", @@ -93,8 +97,8 @@ "echo-category-title-thank-you-edit": "Jalon{{PLURAL:$1||s}} de modifications", "echo-category-title-watchlist": "Modification d’une page suivie", "echo-category-title-minor-watchlist": "Modification mineure d’une page suivie", - "echo-pref-tooltip-edit-user-talk": "Me prévenir quand quelqu’un publie un message ou répond sur ma page de discussion.", - "echo-pref-tooltip-article-linked": "Me prévenir quand quelqu’un depuis une autre page fait référence à une page que j’ai créée.", + "echo-pref-tooltip-edit-user-talk": "Me prévenir quand quelqu’un modifie ma page de discussion utilisateur.", + "echo-pref-tooltip-article-linked": "Me prévenir quand quelqu’un fait référence depuis une autre page à une page que j’ai créée.", "echo-pref-tooltip-reverted": "Me prévenir quand quelqu’un annule une modification que j’ai faite, en utilisant l’outil d’annulation ou de révocation.", "echo-pref-tooltip-mention": "Me prévenir quand quelqu’un fait référence à ma page utilisateur.", "echo-pref-tooltip-mention-failure": "M’avertir si quelqu’un n’est pas notifié alors que je l’ai mentionné.", @@ -102,7 +106,7 @@ "echo-pref-tooltip-user-rights": "Me notifier quand quelqu’un modifie mes droits utilisateur.", "echo-pref-tooltip-emailuser": "Me notifier quand quelqu’un m’envoie un courriel.", "echo-pref-tooltip-article-reminder": "Me prévenir de cette page quand je le demande.", - "echo-pref-tooltip-thank-you-edit": "Me notifier quand j’atteins ma première, dixième, centième, millième… modification.", + "echo-pref-tooltip-thank-you-edit": "Me notifier quand j’atteins ma première modification ou ma dixième, centième, millième, etc.", "echo-pref-tooltip-watchlist": "Me notifier quand quelqu’un effectue une modification (non mineure) d’une page sur ma liste de suivi.", "echo-pref-tooltip-minor-watchlist": "Me notifier quand quelqu’un effectue une modification mineure d’une page sur ma liste de suivi.", "notifications": "Notifications", @@ -122,11 +126,12 @@ "echo-displaynotificationsconfiguration-mandatory-notification-methods-by-category-legend": "Quelles méthodes de notification sont obligatoires pour chaque catégorie", "echo-specialpage": "Notifications", "echo-specialpage-section-markread": "Marquer la section comme lue", - "echo-specialpage-markasread": "Notification : marquer comme lue", + "echo-specialpage-markasread": "Notification : marquer comme lue", "echo-specialpage-markasread-invalid-id": "ID d’événement non valide", "echo-specialpage-pagefilterwidget-aria-label": "Filtrer par wiki et par titre de page", "echo-specialpage-special-help-menu-widget-aria-label": "Options supplémentaires et préférences de notification.", "echo-specialpage-pagination-numnotifications": "$1 notification{{PLURAL:$1||s}}", + "echo-specialpage-pagination-range": "$1 – $2", "echo-specialpage-pagefilters-title": "Activité récente", "echo-specialpage-pagefilters-subtitle": "Pages avec des notifications non lues", "notificationsmarkread-legend": "Marquer la notification comme lue", @@ -141,17 +146,17 @@ "echo-notification-markasunread": "Marquer comme non lue", "echo-notification-markasread-tooltip": "Marquer comme lue", "echo-notification-more-options-tooltip": "Plus d’options", - "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|Mettre en sourdine}} les notifications de lien sur « $1 ».", - "notification-dynamic-actions-mute-page-linked-confirmation": "Les notifications « Lien de page » sont désormais désactivées pour la page « $1 »", - "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|Vous}} pouvez gérer vos pages mises en sourdine dans [$1 vos préférences] à tout moment.", - "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2|Rétablir}} les notifications de lien sur « $1 ».", - "notification-dynamic-actions-unmute-page-linked-confirmation": "Les notifications « Lien de page » sont désormais activées pour la page « $1 »", - "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|Vous}} pouvez gérer vos pages mises en sourdine dans [$1 vos préférences] à tout moment.", - "notification-dynamic-actions-unwatch": "Arrêter{{GENDER:$3|}} de suivre les nouvelles activités sur « $1 »", - "notification-dynamic-actions-unwatch-confirmation": "Vous{{GENDER:$3|}} ne suivez plus la page « $1 »", + "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|}}Mettre en sourdine les notifications des liens dans « $1 ».", + "notification-dynamic-actions-mute-page-linked-confirmation": "Les notifications « Lien de page » sont désormais désactivées pour la page « $1 »", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|}}Vous pouvez gérer vos pages mises en sourdine dans [$1 vos préférences] à tout moment.", + "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2|}}Rétablir les notifications de liens dans « $1 ».", + "notification-dynamic-actions-unmute-page-linked-confirmation": "Les notifications de « Lien de page » sont désormais activées pour la page « $1 »", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|}}Vous pouvez gérer vos pages mises en sourdine dans [$1 vos préférences] à tout moment.", + "notification-dynamic-actions-unwatch": "{{GENDER:$3|}}Arrêter de suivre les nouvelles activités sur « $1 »", + "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3|}}Vous ne suivez plus la page « $1 »", "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|Vous}} pouvez suivre [$2 cette page] à nouveau à tout moment.", - "notification-dynamic-actions-watch": "Suivre{{GENDER:$3|}} l’évolution de « $1 »", - "notification-dynamic-actions-watch-confirmation": "Vous{{GENDER:$3|}} suivez désormais la page « $1 »", + "notification-dynamic-actions-watch": "{{GENDER:$3|}}Suivre l’évolution de « $1 »", + "notification-dynamic-actions-watch-confirmation": "{{GENDER:$3|}}Vous suivez désormais la page « $1 »", "notification-dynamic-actions-watch-confirmation-description": "Vous{{GENDER:$3|}} pouvez arrêter de suivre [$2 cette page] à tout moment.", "notification-link-text-expand-all": "Développer", "notification-link-text-expand-alert-count": "Afficher $1 alerte{{PLURAL:$1||s}}", @@ -164,81 +169,82 @@ "notification-link-text-view-changes": "Afficher{{GENDER:$1|}} les modifications", "notification-link-text-view-page": "Afficher la page", "notification-header-edit-user-talk": "{{GENDER:$2|}}$1 a laissé un message sur <strong>{{GENDER:$3|}}votre page de discussion</strong>.", - "notification-header-edit-user-talk-with-section": "{{GENDER:$2|}}$1 a laissé un message sur <strong>{{GENDER:$3|}}votre page de discussion</strong> dans la section « <strong>$4</strong> ».", + "notification-header-edit-user-talk-with-section": "{{GENDER:$2|}}$1 a laissé un message sur <strong>{{GENDER:$3|}}votre page de discussion</strong> dans la section « <strong>$4</strong> ».", "notification-compact-header-edit-user-talk": "{{GENDER:$2|}}$1 {{GENDER:$3|}}vous a laissé un message.", - "notification-compact-header-edit-user-talk-with-section": "{{GENDER:$2|}}$1 {{GENDER:$3|}}vous a laissé un message dans « <strong>$4</strong> ».", + "notification-compact-header-edit-user-talk-with-section": "{{GENDER:$2|}}$1 {{GENDER:$3|}}vous a laissé un message dans « <strong>$4</strong> ».", "notification-body-edit-user-talk-with-section": "$1", "notification-header-page-linked": "Un lien vers <strong>$3</strong> a été créé sur <strong>$4</strong>.", "notification-compact-header-page-linked": "Lié depuis <strong>$1</strong>.", - "notification-bundle-header-page-linked": "Des liens vers « <strong>$3</strong> » ont été insérés dans {{PLURAL:$5|$5 page|$5 pages|100=plus de 100 pages}}.", + "notification-bundle-header-page-linked": "Des liens vers « <strong>$3</strong> » ont été insérés dans {{PLURAL:$5|$5 page|$5 pages|100=au moins une centaine de pages}}.", "notification-header-article-reminder": "Une page dont {{GENDER:$2|}}vous avez demandé le rappel est disponible sur <strong>$3</strong>.", "notification-link-text-what-links-here": "Tous les liens vers cette page", - "notification-header-mention-other": "$1{{GENDER:$2|}} vous a mentionné{{GENDER:$3||e}} sur <strong>$4</strong> dans « <strong>$5</strong> ».", + "notification-header-mention-other": "$1{{GENDER:$2|}} vous a mentionné{{GENDER:$3||e}} sur <strong>$4</strong> dans « <strong>$5</strong> ».", "notification-header-mention-other-nosection": "$1{{GENDER:$2|}} vous a mentionné{{GENDER:$3||e}} sur <strong>$4</strong>.", - "notification-header-mention-user-talkpage-v2": "$1{{GENDER:$2|}} vous a mentionné{{GENDER:$3||e}} sur la <strong>page de discussion de l’utilisat{{GENDER:$5|eur|rice}} $4</strong> dans « <strong>$6</strong> ».", + "notification-header-mention-user-talkpage-v2": "{{GENDER:$2|}}$1 {{GENDER:$3|}}vous a mentionné{{GENDER:$3||e}} sur la <strong>page de discussion de l’utilisat{{GENDER:$5|eur|rice}} $4</strong> dans « <strong>$6</strong> ».", "notification-header-mention-user-talkpage-nosection": "$1{{GENDER:$2|}} vous a mentionné{{GENDER:$3||e}} sur la <strong>page de discussion de l’utilisat{{GENDER:$5|eur|rice}} $4</strong>.", "notification-header-mention-agent-talkpage": "$1{{GENDER:$2|}} vous a mentionné{{GENDER:$3||e}} sur <strong>{{GENDER:$2|}}sa page de discussion</strong> dans « <strong>$4</strong> ».", "notification-header-mention-agent-talkpage-nosection": "$1{{GENDER:$2|}} vous a mentionné{{GENDER:$3||e}} sur <strong>{{GENDER:$2|}}sa page de discussion</strong>", - "notification-header-mention-article-talkpage": "$1{{GENDER:$2|}} vous a mentionné{{GENDER:$3||e}} sur la page de discussion de <strong>$4</strong> dans « <strong> $5</strong> ».", + "notification-header-mention-article-talkpage": "{{GENDER:$2|}}$1 vous a mentionné{{GENDER:$3||e}} sur la page de discussion de <strong>$4</strong> dans « <strong>$5</strong> ».", "notification-header-mention-article-talkpage-nosection": "$1{{GENDER:$2|}} vous a mentionné{{GENDER:$3||e}} sur la page de discussion de <strong>$4</strong>.", - "notification-header-mention-failure-user-unknown": "Aucune notification n’a été envoyée lorsque vous avez {{GENDER:$2|mentionné}} <strong>$3</strong> car cet utilisateur n’a pas été trouvé.", - "notification-header-mention-failure-user-anonymous": "Aucune notification n’a été envoyée lorsque vous avez {{GENDER:$2|mentionné}} <strong>$3</strong> car cet utilisateur est anonyme.", - "notification-header-mention-failure-too-many": "{{GENDER:$2|}}Vous avez mentionné plus de $3 utilisateur{{PLURAL:$3||s}}. Tous les utilisateurs mentionnés au-delà de cette limite n’ont pas été notifiés.", + "notification-header-mention-failure-user-unknown": "Aucune notification n’a été envoyée lorsque {{GENDER:$2|}}vous avez mentionné <strong>$3</strong> car cet utilisateur n’a pas été trouvé.", + "notification-header-mention-failure-user-anonymous": "Aucune notification n’a été envoyée lorsque {{GENDER:$2|}}vous avez mentionné <strong>$3</strong> car cet utilisateur est anonyme.", + "notification-header-mention-failure-too-many": "{{GENDER:$2|}}Vous avez mentionné plus de $3 utilisateur{{PLURAL:$3||s}}. Aucun des utilisateurs mentionnés au-delà de cette limite n’a été notifié.", "notification-header-mention-failure-bundle": "Concernant {{PLURAL:$3|l’utilisat{{GENDER:$2|eur|rice}} que vous avez mentionné{{GENDER:$2||e}}|les $3 utilisateurs que vous avez mentionnés}} sur la page de discussion <strong>$4</strong>, {{PLURAL:$3|une notification n’a pas pu lui être envoyée|$3 notifications n’ont pas pu leur être envoyées}}.", - "notification-compact-header-mention-failure-user-unknown": "<strong>Utilisateur inconnu :</strong> « $1 »", + "notification-compact-header-mention-failure-user-unknown": "<strong>Utilisateur inexistant :</strong> « $1 »", "notification-compact-header-mention-failure-user-anonymous": "<strong>Les adresses IP ne peuvent pas être notifiées :</strong> $1", - "notification-header-mention-success": "L’utilisat{{GENDER:$3|eur|rice}} <strong>$3</strong> que {{GENDER:$2|vous}} avez mentionné{{GENDER:$3||e}} a été notifié{{GENDER:$3||e}}.", + "notification-header-mention-success": "L’utilisat{{GENDER:$3|eur|rice}} <strong>$3</strong> que {{GENDER:$2|}}vous avez mentionné{{GENDER:$3||e}} a été notifié{{GENDER:$3||e}}.", "notification-header-mention-success-bundle": "{{PLURAL:$3|Une mention|$3 mentions}} que {{GENDER:$2|}}vous avez faite{{PLURAL:$3||s}} sur la page de discussion de <strong>$4</strong> {{PLURAL:$3|a été envoyée|ont été envoyées}}.", - "notification-compact-header-mention-success": "<strong>{{GENDER:$2|}}Vous avez mentionné :</strong> $3", - "notification-header-mention-status-bundle": "{{PLURAL:$3|Une notification|$3 notifications}} concernant les mentions que {{GENDER:$2|}}vous avez faites sur la page de discussion <strong>$4</strong> : $5 non envoyée{{PLURAL:$5||s}}, $6 envoyée{{PLURAL:$6||s}}.", - "notification-header-user-rights-add-only": "Vos droits d’utilisat{{GENDER:$4|eur|rice}} ont été modifiés{{GENDER:$1|}}. Vous avez été ajouté{{GENDER:$4||e}} à : $2.", - "notification-header-user-rights-remove-only": "Vos droits d’utilisat{{GENDER:$4|eur|rice}} ont été modifiés{{GENDER:$1|}}. Vous n’êtes désormais plus membre de : $2.", - "notification-header-user-rights-add-and-remove": "{{GENDER:$6|}}Vos droits d’utilisat{{GENDER:$4|eur|rice}} ont été modifiés{{GENDER:$1|}}. Vous avez été ajouté{{GENDER:$6||e}} à : $2. Vous n’êtes désormais plus membre de : $4.", - "notification-header-user-rights-expiry-change": "L’expiration de {{GENDER:$4|votre}} appartenance {{PLURAL:$3|au groupe suivant|aux groupes suivants}} a été {{GENDER:$1|modifiée}} : $2.", - "notification-header-welcome": "{{GENDER:$2|Bienvenue}} sur {{SITENAME}}, $1 ! Nous sommes heureux que {{GENDER:$2|vous soyez}} ici.", - "notification-header-mention-summary": "$1 {{GENDER:$3|vous}} {{GENDER:$2|a mentionné}} dans un résumé de modification sur <strong>$4</strong>.", - "notification-header-watchlist-changed": "$1{{GENDER:$2|}} a modifié <strong>$3</strong>, une page sur votre{{GENDER:$4|}} liste de suivi{{PLURAL:$5||, $5 fois}}.", - "notification-header-watchlist-created": "$1{{GENDER:$2|}} a créé <strong>$3</strong>, une page sur votre{{GENDER:$4|}} liste de suivi{{PLURAL:$5||, $5 fois}}.", - "notification-header-watchlist-deleted": "$1{{GENDER:$2|}} a modifié <strong>$3</strong>, une page sur votre{{GENDER:$4|}} liste de suivi{{PLURAL:$5||, $5 fois}}.", - "notification-header-watchlist-moved": "$1{{GENDER:$2|}} a renommé <strong>$3</strong>, une page sur votre{{GENDER:$4|}} liste de suivi{{PLURAL:$5||, $5 fois}}.", - "notification-header-watchlist-restored": "$1{{GENDER:$2|}} a restauré <strong>$3</strong>, une page sur votre{{GENDER:$4|}} liste de suivi{{PLURAL:$5||, $5 fois}}.", - "notification-header-watchlist-multiuser-changed": "<strong>$1</strong>, une page sur {{GENDER:$2|}}votre liste de suivi, a été modifiée $3 fois{{PLURAL:$3|}}.", - "notification-header-watchlist-multiuser-created": "<strong>$1</strong>, une page sur {{GENDER:$2|}}votre liste de suivi, a été créée $3 fois{{PLURAL:$3|}}.", - "notification-header-watchlist-multiuser-deleted": "<strong>$1</strong>, une page sur {{GENDER:$2|}}votre liste de suivi, a été supprimée $3 fois{{PLURAL:$3|}}.", + "notification-compact-header-mention-success": "<strong>{{GENDER:$2|}}Vous avez mentionné :</strong> $3", + "notification-header-mention-status-bundle": "{{PLURAL:$3|Une notification|$3 notifications}} concernant les mentions que {{GENDER:$2|}}vous avez faites sur la page de discussion <strong>$4</strong> : $5 non envoyée{{PLURAL:$5||s}}, $6 envoyée{{PLURAL:$6||s}}.", + "notification-header-user-rights-add-only": "{{GENDER:$4|}}Vos droits d’utilisat{{GENDER:$4|eur|rice}} ont été modifiés{{GENDER:$1|}}. Vous avez été ajouté{{GENDER:$4||e}} comme membre {{PLURAL:$3|du groupe|des groupes}} : $2.", + "notification-header-user-rights-remove-only": "{{GENDER:$4|}}Vos droits d’utilisat{{GENDER:$4|eur|rice}} ont été modifiés{{GENDER:$1|}}. Vous n’êtes désormais plus membre {{PLURAL:$3|du groupe|des groupes}} : $2.", + "notification-header-user-rights-add-and-remove": "{{GENDER:$6|}}Vos droits d’utilisat{{GENDER:$4|eur|rice}} ont été modifiés{{GENDER:$1|}}. Vous avez été ajouté{{GENDER:$6||e}} comme membre{{PLURAL:$3|du groupe|des groupes}} : $2. Vous n’êtes désormais plus membre {{PLURAL:$5|du groupe|des groupes}} : $4.", + "notification-header-user-rights-expiry-change": "L’expiration de {{GENDER:$4|}}votre appartenance {{PLURAL:$3|au groupe suivant|aux groupes suivants}} a été modifiée{{GENDER:$1|}} : $2.", + "notification-header-welcome": "Bienvenue{{GENDER:$2|}} sur {{SITENAME}}, $1 ! Nous sommes heureux de {{GENDER:$2|}}vous voir ici.", + "notification-header-mention-summary": "{{GENDER:$2|}}$1 {{GENDER:$3|}}vous a mentionné{{GENDER:$3||e}} dans un résumé de modification sur <strong>$4</strong>.", + "notification-header-watchlist-changed": "{{GENDER:$2|}}$1 a modifié {{PLURAL:$5||$5 fois}} <strong>$3</strong>, une page sur {{GENDER:$4|}}votre liste de suivi.", + "notification-header-watchlist-created": "{{GENDER:$2|}}$1 a créé {{PLURAL:$5||pour la $5<sup>e</sup> fois}} <strong>$3</strong>, une page sur {{GENDER:$4|}}votre liste de suivi.", + "notification-header-watchlist-deleted": "{{GENDER:$2|}}$1 a supprimé {{PLURAL:$5||pour la $5<sup>e</sup> fois}} <strong>$3</strong>, une page sur {{GENDER:$4|}}votre liste de suivi.", + "notification-header-watchlist-moved": "{{GENDER:$2|}}$1 a renommé {{PLURAL:$5||pour la $5<sup>e</sup> fois}} <strong>$3</strong>, une page sur {{GENDER:$4|}}votre liste de suivi.", + "notification-header-watchlist-restored": "{{GENDER:$2|}}$1 a restauré {{PLURAL:$5||pour la $5<sup>e</sup> fois}} <strong>$3</strong>, une page sur {{GENDER:$4|}}votre liste de suivi.", + "notification-header-watchlist-multiuser-changed": "<strong>$1</strong>, une page sur {{GENDER:$2|}}votre liste de suivi, a été modifiée pour la $3<sup>e</sup> fois{{PLURAL:$3|}}.", + "notification-header-watchlist-multiuser-created": "<strong>$1</strong>, une page sur {{GENDER:$2|}}votre liste de suivi, a été créée pour la $3<sup>e</sup> fois{{PLURAL:$3|}}.", + "notification-header-watchlist-multiuser-deleted": "<strong>$1</strong>, une page sur {{GENDER:$2|}}votre liste de suivi, a été supprimée pour la $3<sup>e</sup> fois{{PLURAL:$3|}}.", "notification-header-watchlist-multiuser-moved": "<strong>$1</strong>, une page sur {{GENDER:$2|}}votre liste de suivi, a été renommée $3 fois{{PLURAL:$3|}}.", - "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>, une page sur {{GENDER:$2|}}votre liste de suivi, a été restaurée $3 fois{{PLURAL:$3|}}.", + "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>, une page sur {{GENDER:$2|}}votre liste de suivi, a été restaurée pour la $3<sup>e</sup> fois{{PLURAL:$3|}}.", + "notification-body-watchlist-once": "Il n’y aura pas d’autre notification par courriel en cas d’activité ultérieure à moins que {{GENDER:$1|}}vous visitiez cette page une fois connecté.", "notification-welcome-linktext": "Bienvenue", - "notification-header-thank-you-1-edit": "{{GENDER:$2|Vous}} venez de faire {{GENDER:$2|votre}} première modification, {{GENDER:$2|}} merci et bienvenue !", - "notification-header-thank-you-10-edit": "{{GENDER:$2|Vous}} venez de faire {{GENDER:$2|votre}} dixième modification, {{GENDER:$2|}} merci, continuez ainsi !", - "notification-header-thank-you-100-edit": "{{GENDER:$2|Vous}} venez de faire {{GENDER:$2|votre}} centième modification, {{GENDER:$2|}} merci beaucoup !", - "notification-header-thank-you-1000-edit": "{{GENDER:$2|Vous}} venez de faire {{GENDER:$2|votre}} millième modification ; nous {{GENDER:$2|vous}} remercions d’être {{GENDER:$2|un grand contributeur !|une grande contributrice !}}", - "notification-header-thank-you-10000-edit": "{{GENDER:$2|Vous}} venez de faire {{GENDER:$2|votre}} dix-millième modification, un très grand merci à {{GENDER:$2|vous}} !", - "notification-header-thank-you-100000-edit": "{{GENDER:$2|Vous}} venez de faire {{GENDER:$2|votre}} cent-millième modification, merci à {{GENDER:$2|vous}} pour votre participation incroyable !", - "notification-header-thank-you-1000000-edit": "{{GENDER:$2|Vous}} venez de faire {{GENDER:$2|votre}} millionième modification, merci à {{GENDER:$2|vous}} pour votre participation exceptionnelle !", - "notification-header-thank-you-10000000-edit": "{{GENDER:$2|Vous}} venez de faire {{GENDER:$2|votre}} dix millionième modification ; merci à {{GENDER:$2|vous}} pour votre engagement brillant !", + "notification-header-thank-you-1-edit": "{{GENDER:$2|}}Vous venez d’effectuer {{GENDER:$2|}}votre première modification. {{GENDER:$2|}}Merci et bienvenue !", + "notification-header-thank-you-10-edit": "{{GENDER:$2|}}Vous venez d’effectuer {{GENDER:$2|}}votre dixième modification. {{GENDER:$2|}}Merci, continuez ainsi !", + "notification-header-thank-you-100-edit": "{{GENDER:$2|}}Vous venez d’effectuer {{GENDER:$2|}}votre centième modification. {{GENDER:$2|}}Merci beaucoup !", + "notification-header-thank-you-1000-edit": "{{GENDER:$2|}}Vous venez d’effectuer {{GENDER:$2|}}votre millième modification. Nous {{GENDER:$2|}}vous remercions d’être {{GENDER:$2|un si grand contributeur|une si grande contributrice}} !", + "notification-header-thank-you-10000-edit": "{{GENDER:$2|}}Vous venez d’effectuer {{GENDER:$2|}}votre dix-millième modification. Un très grand merci à {{GENDER:$2|}}vous !", + "notification-header-thank-you-100000-edit": "{{GENDER:$2|}}Vous venez d’effectuer {{GENDER:$2|}}votre cent-millième modification. Merci à {{GENDER:$2|}}vous pour {{GENDER:$2|}}votre participation incroyable !", + "notification-header-thank-you-1000000-edit": "{{GENDER:$2|}}Vous venez d’effectuer {{GENDER:$2|}}votre millionième modification. Merci à {{GENDER:$2|}}vous pour {{GENDER:$2|}}votre participation exceptionnelle !", + "notification-header-thank-you-10000000-edit": "{{GENDER:$2|}}Vous venez d’effectuer {{GENDER:$2|}}votre dix-millionième modification. Merci à {{GENDER:$2|}}vous pour votre engagement brillant !", "notification-link-thank-you-edit": "{{GENDER:$1|}}Votre modification", "notification-link-text-view-edit": "Afficher la modification", "notification-link-article-reminder": "Afficher la page", "notification-header-reverted": "{{PLURAL:$4|Votre modification|Vos modifications}} sur <strong>$3</strong> {{PLURAL:$4|a été annulée|ont été annulées}}{{GENDER:$2|}}.", "notification-header-emailuser": "$1 {{GENDER:$2|}}vous a envoyé un courriel.", "notification-edit-talk-page-email-subject2": "$1{{GENDER:$2|}} a laissé un message sur {{GENDER:$3|}}votre page de discussion sur {{SITENAME}}.", - "notification-page-linked-email-subject": "Un lien vers une page que {{GENDER:$3|}}vous avez créée a été inséré sur {{SITENAME}}", + "notification-page-linked-email-subject": "Un lien vers une page que {{GENDER:$3|}}vous avez créée a été inséré sur {{SITENAME}}.", "notification-reverted-email-subject2": "{{GENDER:$3|}}{{PLURAL:$4|Votre modification a été annulée|Vos modifications ont été annulées}}{{GENDER:$2|}} sur {{SITENAME}}", "notification-mention-email-subject": "$1{{GENDER:$2|}} vous a mentionné{{GENDER:$3||e}} sur {{SITENAME}}", "notification-user-rights-email-subject": "{{GENDER:$3|}}Vos droits utilisateur ont été modifiés sur {{SITENAME}}", - "notification-timestamp-ago-seconds": "$1 s{{PLURAL:$1|}}", - "notification-timestamp-ago-minutes": "$1 min{{PLURAL:$1|}}", - "notification-timestamp-ago-hours": "$1 h{{PLURAL:$1|}}", - "notification-timestamp-ago-days": "$1 j{{PLURAL:$1|}}", - "notification-timestamp-ago-months": "$1 mois{{PLURAL:$1|}}", - "notification-timestamp-ago-years": "$1 an{{PLURAL:$1||s}}", + "notification-timestamp-ago-seconds": "$1 s{{PLURAL:$1|}}", + "notification-timestamp-ago-minutes": "$1 min{{PLURAL:$1|}}", + "notification-timestamp-ago-hours": "$1 h{{PLURAL:$1|}}", + "notification-timestamp-ago-days": "$1 j{{PLURAL:$1|}}", + "notification-timestamp-ago-months": "$1 mois{{PLURAL:$1|}}", + "notification-timestamp-ago-years": "$1 an{{PLURAL:$1||s}}", "notification-timestamp-today": "Aujourd’hui", "notification-timestamp-yesterday": "Hier", "notification-inbox-filter-read": "Lus", "notification-inbox-filter-unread": "Non lus", "notification-inbox-filter-all": "Tous", "echo-specialmute-label-mute-notifications": "Faire taire les notifications de {{GENDER:$1|cet utilisateur|cette utilisatrice}}", - "echo-email-plain-footer": "Pour choisir quels courriels nous {{GENDER:$1|}}vous envoyons, vérifiez {{GENDER:$1|}}vos préférences :", + "echo-email-plain-footer": "Pour choisir quels courriels nous {{GENDER:$1|}}vous envoyons, vérifiez {{GENDER:$1|}}vos préférences :", "echo-email-html-footer-preference-link-text": "vérifiez {{GENDER:$1|}}vos préférences", "echo-email-html-footer-with-link": "Pour contrôler quels courriels nous {{GENDER:$2|}}vous envoyons, $1.", "echo-notification-alert": "{{PLURAL:$1|Alerte ($1)|Alertes ($1)|100=Alertes (99+)}}", @@ -253,7 +259,8 @@ "echo-displaysnippet-title": "Nouvelle notification", "echo-date-today": "Aujourd’hui", "echo-date-yesterday": "Hier", - "notification-bundle-header-edit-user-talk-v2": "{{PLURAL:$1|Un nouveau message|$1 nouveaux messages|100=Plus de 99 nouveaux messages}} sur <strong>{{GENDER:$3|}}votre page de discussion</strong>.", + "notification-bundle-header-edit-user-talk-v2": "{{PLURAL:$1|Un nouveau message|$1 nouveaux messages|100=Au moins une centaine de nouveaux messages}} sur <strong>{{GENDER:$3|}}votre page de discussion</strong>.", + "echo-email-batch-bullet": "•", "echo-email-batch-subject-daily": "Vous avez {{PLURAL:$2|une nouvelle notification|de nouvelles notifications}} sur {{SITENAME}}", "echo-email-batch-subject-weekly": "Vous avez {{PLURAL:$2|une nouvelle notification|de nouvelles notifications}} sur {{SITENAME}} cette semaine", "echo-email-batch-body-intro-daily": "Bonjour $1,\nVoici pour vous un résumé de l’activité d’aujourd’hui sur {{SITENAME}}.", @@ -261,5 +268,12 @@ "echo-email-batch-link-text-view-all-notifications": "Voir toutes les notifications", "notification-header-foreign-alert": "Davantage d’alertes {{PLURAL:$5|d’un autre wiki|de $5 autres wikis}}", "notification-header-foreign-notice": "Davantage de notifications {{PLURAL:$5|d’un autre wiki|de $5 autres wikis}}", - "notification-header-foreign-all": "Davantage de notifications {{PLURAL:$5|d’un autre wiki|de $5 autres wikis}}" + "notification-header-foreign-all": "Davantage de notifications {{PLURAL:$5|d’un autre wiki|de $5 autres wikis}}", + "echo-foreign-wiki-lang": "$1 – $2", + "echo-badge-count": "{{PLURAL:$1|$1|100={{formatnum:99}}+}}", + "right-manage-all-push-subscriptions": "Gérer toutes les demandes de poussée", + "action-manage-all-push-subscriptions": "gérer toutes les demandes de poussée", + "group-push-subscription-manager": "Gestionnaires de demande de poussée", + "group-push-subscription-manager-member": "gestionnaire{{GENDER:$1|}} de demande de poussée", + "grouppage-push-subscription-manager": "{{ns:project}}:Push subscription managers" } diff --git a/Echo/i18n/frr.json b/Echo/i18n/frr.json index c52bc39d..86698f74 100644 --- a/Echo/i18n/frr.json +++ b/Echo/i18n/frr.json @@ -7,13 +7,13 @@ "echo-desc": "Bööd-süsteem för brükern auer neis", "prefs-echo": "Bööd", "prefs-emailsettings": "E-mail iinstelangen", - "prefs-echosubscriptions": "Schüür mi diar en bööd am", - "echo-pref-send-me": "Schüür mi:", - "echo-pref-send-to": "Schüür tu:", + "prefs-echosubscriptions": "Sjüür mi diar en bööd am", + "echo-pref-send-me": "Sjüür mi:", + "echo-pref-send-to": "Sjüür tu:", "echo-pref-email-format": "E-mail-formoot:", "echo-pref-web": "Wääb", "echo-pref-email": "E-mail", - "echo-pref-email-frequency-never": "Schüür mi nian bööd", + "echo-pref-email-frequency-never": "Sjüür mi nian e-mail bööd", "echo-pref-email-frequency-immediately": "Enkelt bööd tu arke föörgung", "echo-pref-email-frequency-daily": "Iansis a dai en bööd", "echo-pref-email-frequency-weekly": "Iansis a weg en bööd", @@ -21,7 +21,7 @@ "echo-pref-email-format-plain-text": "Normool tekst", "echo-learn-more": "Ik wal muar wed", "echo-new-messages": "Dü heest nei bööd", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|bööd|bööden}} üüb min diskuschuunssidj", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|bööd|bööden}} üüb min diskusioonsidj", "echo-category-title-article-linked": "$1 {{PLURAL:$1|ferwisang|ferwisangen}}", "echo-category-title-reverted": "{{PLURAL:$1|turagsaatang|turagsaatangen}} bewerke", "echo-category-title-mention": "{{PLURAL:$1|henwis|henwiser}}", @@ -37,8 +37,10 @@ "echo-pref-tooltip-emailuser": "Du mi bööd, wan mi hoker en e-mail schüürt.", "notifications": "Bööd", "tooltip-pt-notifications-alert": "{{GENDER:|Din}} wäärnangen", + "tooltip-pt-notifications-notice": "{{GENDER:|Din}} bööden", "echo-specialpage": "Bööd", "echo-none": "Dü heest nian bööd.", + "echo-notification-more-options-tooltip": "Muar ütjwool", "notification-link-text-view-message": "Bööd/en uunwise", "notification-link-text-view-mention": "Henwis/er uunwise", "notification-link-text-view-changes": "Feranrang/en uunwise", diff --git a/Echo/i18n/fy.json b/Echo/i18n/fy.json index 25bc6167..479340fa 100644 --- a/Echo/i18n/fy.json +++ b/Echo/i18n/fy.json @@ -8,11 +8,12 @@ }, "echo-desc": "Systeem om meidoggers barrens en berjochten te melden", "prefs-echo": "Meldingen", + "prefs-description-echo": "Selektearje hokker meldingen, en hoe't {{GENDER:|jo}} dy ûntfange sille.", "prefs-emailsettings": "E-mailopsjes", "prefs-echosubscriptions": "Meld oan my dizze barrens", "prefs-echocrosswiki": "Meldingen tusken wiki's", "prefs-blocknotificationslist": "Stilholden meidoggers", - "prefs-mutedpageslist": "Stilholden siden", + "prefs-mutedpageslist": "Stilholden siden foar meldingen oer sidekeppeling", "prefs-echopollupdates": "Fuort melden", "echo-mobile-notifications-filter-title": "Meldingen filterje", "echo-pref-show-poll-updates": "Nije meldingen daliks by ynkomst werjaan", @@ -22,6 +23,7 @@ "echo-pref-email-format": "E-mailyndieling:", "echo-pref-web": "Web", "echo-pref-email": "E-mail", + "echo-pref-push": "Apps", "echo-pref-email-frequency-never": "Gjin meldingen mei de e-mail", "echo-pref-email-frequency-immediately": "Aparte meldingen daliks by ynkomst", "echo-pref-email-frequency-daily": "Deis in oersjoch fan 'e meldingen", @@ -34,8 +36,8 @@ "echo-pref-dont-email-read-notifications": "Lêzen meldingen net opnimme yn 'e oersjochmails", "echo-learn-more": "Mear witte", "echo-log": "Iepenbier loch", - "echo-new-messages": "Jo hawwe nije berjochten", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Boadskip|Boadskippen}} op myn oerlisside", + "echo-new-messages": "Jo hawwe in nij oerlisberjocht", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Bewurking|Bewurkings}} op myn oerlisside", "echo-category-title-article-linked": "Keppele {{PLURAL:$1|side|siden}}", "echo-category-title-reverted": "Ungedien makke {{PLURAL:$1|wiziging|wizigings}}", "echo-category-title-mention": "{{PLURAL:$1|Neamd wurde}}", @@ -51,7 +53,7 @@ "echo-category-title-thank-you-edit": "Bewurkings{{PLURAL:$1|mylpeal|mylpeallen}}", "echo-category-title-watchlist": "Bewurking oan folchlistside", "echo-category-title-minor-watchlist": "Lytse feroaring oan folchlistside", - "echo-pref-tooltip-edit-user-talk": "Meld my wannear't immen in berjocht of antwurden pleatst op myn oerlisside.", + "echo-pref-tooltip-edit-user-talk": "Meld my wannear't immen myn oerlisside bewurket.", "echo-pref-tooltip-article-linked": "Meld my wannear't immen in keppeling makket, fan 'e iene nei in troch my oanmakke side.", "echo-pref-tooltip-reverted": "Meld my wannear't immen in wiziging fan my ûngedien makket mei it weromset- of weromdraaiark.", "echo-pref-tooltip-mention": "Meld my wannear't immen in keppeling nei myn meidoggerside makket.", @@ -83,6 +85,7 @@ "echo-specialpage-markasread": "Melding: As lêzen markearje", "echo-specialpage-markasread-invalid-id": "Barren hat ûnjildich nûmer", "echo-specialpage-pagefilterwidget-aria-label": "Wiki en sidetitel filterje", + "echo-specialpage-special-help-menu-widget-aria-label": "Oanfoljende opsjes en Meldingsfoarkarren.", "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|melding|meldingen}}", "echo-specialpage-pagefilters-title": "Warberens koartlyn", "echo-specialpage-pagefilters-subtitle": "Siden mei net-lêzen meldingen", @@ -98,6 +101,12 @@ "echo-notification-markasunread": "As net-lêzen markearje", "echo-notification-markasread-tooltip": "As lêzen markearje", "echo-notification-more-options-tooltip": "Mear opsjes", + "notification-dynamic-actions-mute-page-linked": "Keppelmeldingen op \"$1\" {{GENDER:$2|stilhâlde}}", + "notification-dynamic-actions-mute-page-linked-confirmation": "Meldingen oer \"sidekeppeling\" binne no útskeakele foar de side \"$1\"", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|Jo}} kinne jo stilholden siden op elk stuit beheare yn [$1 jo foarkarren].", + "notification-dynamic-actions-unmute-page-linked": "Keppelmeldingen op \"$1\" net {{GENDER:$2|stilhâlde}}", + "notification-dynamic-actions-unmute-page-linked-confirmation": "Meldingen oer \"sidekeppeling\" binne no ynskeakele foar de side \"$1\"", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|Jo}} kinne jo stilholden siden op elk stuit beheare yn [$1 jo foarkarren].", "notification-dynamic-actions-unwatch": "Nije warberens op \"$1\" {{GENDER:$3|ophâlde}} te folgjen", "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3|Jo}} folgje de side \"$1\" net mear", "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|Jo}} kinne [$2 de side] altyd wer folgje.", @@ -136,7 +145,7 @@ "notification-header-mention-failure-too-many": "{{GENDER:$2|Jo}} hawwe besocht mear as $3 {{PLURAL:$3|meidogger|meidoggers}} te neamen. Al it neamen boppe dy limyt is net ferstjoerd.", "notification-header-mention-failure-bundle": "{{PLURAL:$3|It neamen|$3 kear neamen}} troch {{GENDER:$2|jo}} op de oerlisside fan <strong>$4</strong> {{PLURAL:$3|koe}} net ferstjoerd wurde.", "notification-compact-header-mention-failure-user-unknown": "<strong>Meidochnamme bestiet net:</strong> $1", - "notification-compact-header-mention-failure-user-anonymous": "<strong>IP's kinne net neamd wurde:</strong> $1", + "notification-compact-header-mention-failure-user-anonymous": "<strong>YP's kinne net neamd wurde:</strong> $1", "notification-header-mention-success": "{{GENDER:$2|Jo}} neamen fan <strong>$3</strong> is ferstjoerd.", "notification-header-mention-success-bundle": "{{PLURAL:$3|It neamen|$3 kear neamen}} troch {{GENDER:$2|jo}} op de oerlisside fan <strong>$4</strong> {{PLURAL:$3|is}} ferstjoerd.", "notification-compact-header-mention-success": "<strong>{{GENDER:$2|Jo hawwe}} neamd:</strong> $3", @@ -157,6 +166,7 @@ "notification-header-watchlist-multiuser-deleted": "<strong>$1</strong>, in side op {{GENDER:$2|jo}} folchlist, is $3 {{PLURAL:$3|kear}} wiske.", "notification-header-watchlist-multiuser-moved": "<strong>$1</strong>, in side op {{GENDER:$2|jo}} folchlist, is $3 {{PLURAL:$3|kear}} omneamd.", "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>, in side op {{GENDER:$2|jo}} folchlist, is $3 {{PLURAL:$3|kear}} wer teplak set.", + "notification-body-watchlist-once": "Der komme gjin oare meldingen mear mei de e-mail yn gefal fan fierdere warberens, oant {{GENDER:$1|jo}} de side besykje at jo ynlogd binne.", "notification-welcome-linktext": "Wolkom", "notification-header-thank-you-1-edit": "{{GENDER:$2|Jo}} hawwe sakrekt {{GENDER:$2|jo}} earste bewurking dien; tankjewol, en wolkom!", "notification-header-thank-you-10-edit": "{{GENDER:$2|Jo}} hawwe sakrekt {{GENDER:$2|jo}} tsiende bewurking dien; tankjewol, en gean sa troch!", @@ -165,6 +175,7 @@ "notification-header-thank-you-10000-edit": "{{GENDER:$2|Jo}} hawwe sakrekt {{GENDER:$2|jo}} tsientûzenste bewurking dien; tige, tige tank!", "notification-header-thank-you-100000-edit": "{{GENDER:$2|Jo}} hawwe sakrekt {{GENDER:$2|jo}} hûnderttûzenste bewurking dien; tankjewol foar de grandioaze bydrage!", "notification-header-thank-you-1000000-edit": "{{GENDER:$2|Jo}} hawwe sakrekt {{GENDER:$2|jo}} miljoenste bewurking dien; tankjewol foar de bjusterbaarlike bydrage!", + "notification-header-thank-you-10000000-edit": "{{GENDER:$2|Jo}} hawwe sakrekt {{GENDER:$2|jo}} tsien miljoenste bewurking dien; tankjewol foar jo bûtenwenstige hoekhâlden!", "notification-link-thank-you-edit": "{{GENDER:$1|Jo}} bewurking", "notification-link-text-view-edit": "Bewurking besjen", "notification-link-article-reminder": "Side besjen", @@ -186,7 +197,7 @@ "notification-inbox-filter-read": "Lêzen", "notification-inbox-filter-unread": "Net-lêzen", "notification-inbox-filter-all": "Alles", - "echo-specialmute-label-mute-notifications": "Gjin meldingen sjen litte fan dizze meidogger", + "echo-specialmute-label-mute-notifications": "Gjin meldingen sjen litte fan dizze {{GENDER:$1|meidogger|meidochster}}", "echo-email-plain-footer": "Besjoch {{GENDER:$1|jo}} foarkarren en regelje hokker e-mails wy {{GENDER:$1|jo}} tastjoere:", "echo-email-html-footer-preference-link-text": "Besjoch {{GENDER:$1|jo}} foarkarren", "echo-email-html-footer-with-link": "$1 en regelje hokker e-mails wy {{GENDER:$2|jo}} tastjoere.", @@ -210,5 +221,10 @@ "echo-email-batch-link-text-view-all-notifications": "Alle meldingen besjen", "notification-header-foreign-alert": "Mear seintsjes fan {{PLURAL:$5|in oare wiki|$5 oare wiki's}}", "notification-header-foreign-notice": "Mear meidielings fan {{PLURAL:$5|in oare wiki|$5 oare wiki's}}", - "notification-header-foreign-all": "Mear meldingen fan {{PLURAL:$5|in oare wiki|$5 oare wiki's}}" + "notification-header-foreign-all": "Mear meldingen fan {{PLURAL:$5|in oare wiki|$5 oare wiki's}}", + "right-manage-all-push-subscriptions": "Behearen fan 'e trochsetabonneminten", + "action-manage-all-push-subscriptions": "de trochsetabonneminten te behearen", + "group-push-subscription-manager": "Behearders fan trochsetabonneminten", + "group-push-subscription-manager-member": "{{GENDER:$1|behearder trochsetabonneminten|behearster trochsetabonneminten}}", + "grouppage-push-subscription-manager": "{{ns:project}}:Behearders fan trochsetabonneminten" } diff --git a/Echo/i18n/gl.json b/Echo/i18n/gl.json index d0826685..665dfc9f 100644 --- a/Echo/i18n/gl.json +++ b/Echo/i18n/gl.json @@ -1,6 +1,7 @@ { "@metadata": { "authors": [ + "ArenaL5", "Banjo", "Elisardojm", "Iváns", @@ -162,8 +163,8 @@ "notification-link-article-reminder": "Ollar a páxina", "notification-header-reverted": "{{PLURAL:$4|A túa edición en <strong>$3</strong> foi revertida|As túas edicións en <strong>$3</strong> foron {{GENDER:$2|revertidas}}}}.", "notification-header-emailuser": "$1 {{GENDER:$2|envioulle}} un correo electrónico.", - "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$2|deixoulle}} unha mensaxe en {{SITENAME}}", - "notification-page-linked-email-subject": "Unha páxina creada por vostede foi ligada en {{SITENAME}}", + "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$2|deixou}}{{GENDER:$3|lle}} unha mensaxe en {{SITENAME}}", + "notification-page-linked-email-subject": "Unha páxina creada por {{GENDER:$3|vostede}} foi ligada en {{SITENAME}}", "notification-reverted-email-subject2": "{{PLURAL:$4|Reverteuse a súa edición|Revertéronse as súas edicións}} {{GENDER:$2|en}} {{SITENAME}}", "notification-mention-email-subject": "$1 {{GENDER:$2|fíxolle}} unha {{GENDER:$3|mención}} en {{SITENAME}}", "notification-user-rights-email-subject": "{{GENDER:$3|Os seus}} dereitos de usuario cambiaron en {{SITENAME}}", @@ -178,7 +179,7 @@ "notification-inbox-filter-read": "Lidas", "notification-inbox-filter-unread": "Non lidas", "notification-inbox-filter-all": "Todas", - "echo-specialmute-label-mute-notifications": "Silenciar notificacións deste usuario", + "echo-specialmute-label-mute-notifications": "Silenciar notificacións dest{{GENDER:$1|e usuario|a usuaria|a persoa}}", "echo-email-plain-footer": "Para controlar os emais que {{GENDER:$1|lle}} mandamos, {{GENDER:$1|revise}} as súas preferenciasː", "echo-email-html-footer-preference-link-text": "{{GENDER:$1|comprobe}} as súas preferencias", "echo-email-html-footer-with-link": "Para controlar que correos electrónicos {{GENDER:$2|lle}} enviamos, $1.", diff --git a/Echo/i18n/gld.json b/Echo/i18n/gld.json new file mode 100644 index 00000000..6fd5c068 --- /dev/null +++ b/Echo/i18n/gld.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "RFScott" + ] + }, + "tooltip-pt-notifications-alert": "Синду хайва-да нирухэн" +} diff --git a/Echo/i18n/gom-deva.json b/Echo/i18n/gom-deva.json index 951ad60e..61f1819f 100644 --- a/Echo/i18n/gom-deva.json +++ b/Echo/i18n/gom-deva.json @@ -6,10 +6,24 @@ "Vaishali Parab" ] }, + "prefs-echo": "कळोवण्यो", + "notifications": "कळोवण्यो", "tooltip-pt-notifications-alert": "{{GENDER:|तुज्यो}} चत्रायो", + "tooltip-pt-notifications-notice": "तुज्यो कळोवण्यो", + "echo-specialpage": "कळोवण्यो", + "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1सॅ}}", + "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1मि}}", + "notification-timestamp-ago-hours": "{{PLURAL:$1|$1वर}}", + "notification-timestamp-ago-days": "{{PLURAL:$1|$1दी}}", + "notification-timestamp-ago-months": "{{PLURAL:$1|$1म्ह}}", + "notification-timestamp-ago-years": "{{PLURAL:$1|$1वर्स}}", "notification-timestamp-today": "आयज", "notification-timestamp-yesterday": "काल", "notification-inbox-filter-read": "वाचचें", "notification-inbox-filter-unread": "वाचूंक नाशिल्ले", - "notification-inbox-filter-all": "सगळें" + "notification-inbox-filter-all": "सगळें", + "echo-notification-notice-text-only": "कळोवण्यो", + "echo-overlay-link": "सग्ळयो कळोवण्यो", + "echo-displaysnippet-title": "नवी कळोवणी", + "echo-email-batch-link-text-view-all-notifications": "सग्ळयो कळोवण्यो पळय" } diff --git a/Echo/i18n/gom-latn.json b/Echo/i18n/gom-latn.json index f2a34aef..8462c388 100644 --- a/Echo/i18n/gom-latn.json +++ b/Echo/i18n/gom-latn.json @@ -4,11 +4,29 @@ "The Discoverer" ] }, + "prefs-echo": "Kollovnnio", "echo-learn-more": "Odik xikun ghe", + "notifications": "Kollovnnio", "tooltip-pt-notifications-alert": "{{GENDER:|Tujeo}} chotraio", + "tooltip-pt-notifications-notice": "Tujeo kollovnnio", + "echo-specialpage": "Kollovnnio", + "echo-notification-placeholder": "Kaich kollovnnio nan", + "notification-link-text-expand-notice-count": "{{PLURAL:$1|$1 kollovnni|$1 kollovnnio}} polloi", + "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1s}}", + "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1mi}}", + "notification-timestamp-ago-hours": "{{PLURAL:$1|$1vr}}", + "notification-timestamp-ago-days": "{{PLURAL:$1|$1d}}", + "notification-timestamp-ago-months": "{{PLURAL:$1|$1mh}}", + "notification-timestamp-ago-years": "{{PLURAL:$1|$1vrs}}", "notification-timestamp-today": "Aiz", "notification-timestamp-yesterday": "Kal", "notification-inbox-filter-read": "Vach", "notification-inbox-filter-unread": "Vachunk naslele", - "notification-inbox-filter-all": "Sogllem" + "notification-inbox-filter-all": "Sogllem", + "echo-notification-notice": "{{PLURAL:$1|Kollovnni ($1)|Kollovnnio ($1)|100=Kollovnnio (99+)}}", + "echo-notification-alert-text-only": "Chotraio", + "echo-notification-notice-text-only": "Kollovnnio", + "echo-overlay-link": "Soglleo kollovnnio", + "echo-displaysnippet-title": "Novi kollovnni", + "echo-email-batch-link-text-view-all-notifications": "Soglleo kollovnnio polloi" } diff --git a/Echo/i18n/gu.json b/Echo/i18n/gu.json index 6de84536..f7950284 100644 --- a/Echo/i18n/gu.json +++ b/Echo/i18n/gu.json @@ -1,6 +1,7 @@ { "@metadata": { "authors": [ + "CptViraj", "Drashti4", "Dsvyas", "KartikMistry", @@ -27,8 +28,8 @@ "echo-pref-cross-wiki-notifications": "અન્ય વિકિ પરની સૂચનાઓ દર્શાવો", "echo-learn-more": "વધુ જાણો", "echo-log": "જાહેર નોંધ", - "echo-new-messages": "તમારા માટે નવા સંદેશાઓ છે", - "echo-category-title-edit-user-talk": "ચર્ચા પાનું {{PLURAL:$1|સંદેશ|સંદેશાઓ}}", + "echo-new-messages": "તમારા માટે નવો સંદેશો છે", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|ટીપ્પણી|ટીપ્પણીઓ}} મારા ચર્ચા પાના પર", "echo-category-title-article-linked": "પાનું {{PLURAL:$1|કડી|કડીઓ}}", "echo-category-title-reverted": "{{PLURAL:$1|ઉલટાવેલ|ઉલટાવેલા}} ફેરફાર", "echo-category-title-mention": "{{PLURAL:$1|ઉલ્લેખ|ઉલ્લેખો}}", diff --git a/Echo/i18n/guc.json b/Echo/i18n/guc.json new file mode 100644 index 00000000..8f303f0a --- /dev/null +++ b/Echo/i18n/guc.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Leonfd1992" + ] + }, + "tooltip-pt-notifications-alert": "{{GENDER:|Aapitka}} pia" +} diff --git a/Echo/i18n/he.json b/Echo/i18n/he.json index 674ee679..ecebc0fe 100644 --- a/Echo/i18n/he.json +++ b/Echo/i18n/he.json @@ -10,14 +10,17 @@ "Macofe", "Orsa", "Ypnypn", + "דגש", "דגש חזק", "דולב", "חיים", + "לואיקה", "ערן" ] }, "echo-desc": "מערכת לשליחת התראות למשתמשים על אירועים והודעות", "prefs-echo": "הודעות", + "prefs-description-echo": "{{GENDER:|בחר|בחרי}} אילו התראות {{GENDER:|תקבל|תקבלי}}, ואיך לקבל אותן.", "prefs-emailsettings": "אפשרויות דוא\"ל", "prefs-echosubscriptions": "להודיע לי על האירועים הבאים", "prefs-echocrosswiki": "הודעות מאתרי ויקי אחרים", @@ -45,8 +48,8 @@ "echo-pref-dont-email-read-notifications": "לא לכלול הודעות שנקראו במכתבים עם סיכומים", "echo-learn-more": "מידע נוסף", "echo-log": "יומן ציבורי", - "echo-new-messages": "יש לך הודעות חדשות", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|הודעה|הודעות}} בדף השיחה", + "echo-new-messages": "יש לך הודעה חדשה בדף השיחה", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|עריכה|עריכות}} בדף שיחת המשתמש שלי", "echo-category-title-article-linked": "{{PLURAL:$1|קישור לדף|קישורים לדפים}}", "echo-category-title-reverted": "{{PLURAL:$1|שחזור עריכה|שחזורי עריכות}}", "echo-category-title-mention": "{{PLURAL:$1|אזכור|אזכורים}}", @@ -62,7 +65,7 @@ "echo-category-title-thank-you-edit": "{{PLURAL:$1|אבן דרך|אבני דרך}} בעריכה", "echo-category-title-watchlist": "עריכה של דף ברשימת מעקב", "echo-category-title-minor-watchlist": "עריכה משנית של דף ברשימת מעקב", - "echo-pref-tooltip-edit-user-talk": "להודיע לי כשמישהו שולח הודעה או תגובה בדף השיחה שלי.", + "echo-pref-tooltip-edit-user-talk": "להודיע לי כשמישהו עורך את דף שיחת המשתמש שלי.", "echo-pref-tooltip-article-linked": "להודיע לי כשמישהו מקשר לדף שיצרתי מתוך דף אחר.", "echo-pref-tooltip-reverted": "להודיע לי כשמישהו משחזר עריכה שלי באמצעות כלי השחזור או הביטול.", "echo-pref-tooltip-mention": "להודיע לי כשמישהו מקשר לדף המשתמש שלי.", @@ -112,10 +115,10 @@ "echo-notification-more-options-tooltip": "אפשרויות נוספות", "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|להשתיק}} התראות על קישורים מהדף \"$1\"", "notification-dynamic-actions-mute-page-linked-confirmation": "התראות \"קישור מדף\" כבויות עכשיו עבור הדף \"$1\"", - "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|אתה יכול|את יכולה}} לנהל את הדפים המושתקים שלך ב[$1 העדפות שלך] בכל זמן.", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|אתה יכול|את יכולה|ביכולתך}} לנהל את הדפים המושתקים שלך דרך [$1 ההעדפות שלך] בכל עת.", "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2|להפעיל}} התראות על קישורים מהדף \"$1\"", "notification-dynamic-actions-unmute-page-linked-confirmation": "התראות \"קישור מדף\" מופעלות עכשיו עבור הדף \"$1\"", - "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|אתה יכול|את יכולה}} לנהל את הדפים המושתקים שלך ב[$1 העדפות שלך] בכל זמן.", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|אתה יכול|את יכולה|ביכולתך}} לנהל את הדפים המושתקים שלך ב[$1 העדפות שלך] בכל זמן.", "notification-dynamic-actions-unwatch": "{{GENDER:$3|הפסקת}} המעקב אחרי פעילות חדשה בדף \"$1\"", "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3|אתה כבר לא עוקב|את כבר לא עוקבת|אתם כבר לא עוקבים}} יותר אחרי הדף \"$1\"", "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|באפשרותך|באפשרותך|באפשרותכם}} לעקוב אחרי [$2 הדף הזה] בכל עת.", @@ -175,11 +178,12 @@ "notification-header-watchlist-multiuser-deleted": "<strong>$1</strong>, דף ברשימת המעקב {{GENDER:$2|שלך}}, נמחק {{PLURAL:$3|פעם אחת|פעמיים|$3 פעמים}}.", "notification-header-watchlist-multiuser-moved": "<strong>$1</strong>, דף ברשימת המעקב {{GENDER:$2|שלך}}, הועבר {{PLURAL:$3|פעם אחת|פעמיים|$3 פעמים}}.", "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>, דף ברשימת המעקב {{GENDER:$2|שלך}}, שוחזר ממחיקה {{PLURAL:$3|פעם אחת|פעמיים|$3 פעמים}}.", + "notification-body-watchlist-once": "לא יהיו הודעות דוא\"ל אחרות במקרה של פעילות נוספת אלא אם {{GENDER:$1|תבקר בדף בזמן שתהיה מחובר|תבקרי בדף בזמן שתהיי מחוברת}} לחשבון.", "notification-welcome-linktext": "ברוך בואך", "notification-header-thank-you-1-edit": "זה עתה {{GENDER:$2|עשית}} את העריכה הראשונה שלך; תודה ו{{GENDER:$2|ברוך הבא|ברוכה הבאה|ברוך בואך}}!", "notification-header-thank-you-10-edit": "זה עתה {{GENDER:$2|עשית}} את העריכה העשירית שלך; תודה, {{GENDER:$2|המשך|המשיכי}} כך!", "notification-header-thank-you-100-edit": "זה עתה {{GENDER:$2|עשית}} את העריכה המאה שלך; תודה רבה!", - "notification-header-thank-you-1000-edit": "זה עתה {{GENDER:$2|עשית}} את העריכה ה־1,000 שלך; תודה על כך {{GENDER:$2|שאתה תורם כה נפלא|שאת תורמת כה נפלאה}}!", + "notification-header-thank-you-1000-edit": "זה עתה {{GENDER:$2|עשית}} את העריכה ה־1,000 שלך; תודה {{GENDER:$2|שאתה תורם כה נפלא|שאת תורמת כה נפלאה|שתרמת כל־כך הרבה}}!", "notification-header-thank-you-10000-edit": "{{GENDER:$2|עשית}} את העריכה העשרת אלפים שלך; תודה רבה־רבה!", "notification-header-thank-you-100000-edit": "{{GENDER:$2|עשית}} את העריכה המאה אלף שלך; תודה על התרומה המדהימה הזאת!", "notification-header-thank-you-1000000-edit": "{{GENDER:$2|עשית}} את העריכה המיליון שלך; תודה על התרומה המדהימה הזאת!", @@ -209,8 +213,8 @@ "echo-email-plain-footer": "כדי לבחור אילו מכתבים נשלח {{GENDER:$1|אליך|אלייך|אליכם}}, אנא {{GENDER:$1|בדוק|בִדקי|בִדקו}} את ההעדפות {{GENDER:$1|שלך|שלך|שלכם}}:", "echo-email-html-footer-preference-link-text": "{{GENDER:$1|בדוק|בִדקי|בִדקו}} את ההעדפות {{GENDER:$1|שלך|שלך|שלכם}}", "echo-email-html-footer-with-link": "כדי לבחור אילו מכתבים נשלח {{GENDER:$2|אליך|אלייך|אליכם}}, אנא $1.", - "echo-notification-alert": "{{PLURAL:$1|התראות ($1)|100=התראות (99+)}}", - "echo-notification-notice": "{{PLURAL:$1|הודעה אחת|הודעות ($1)|100=הודעות (99+)}}", + "echo-notification-alert": "{{PLURAL:$1|התראה|התראות ($1)|100=התראות (99+)}}", + "echo-notification-notice": "{{PLURAL:$1|הודעה|הודעות ($1)|100=הודעות (99+)}}", "echo-notification-alert-text-only": "התראות", "echo-notification-notice-text-only": "הודעות", "echo-overlay-link": "כל ההודעות", @@ -230,5 +234,10 @@ "notification-header-foreign-alert": "עוד התראות {{PLURAL:$5|מאתר ויקי אחר|מ־$5 אתרי ויקי אחרים}}", "notification-header-foreign-notice": "עוד הודעות {{PLURAL:$5|מאתר ויקי אחר|מ־$5 אתרי ויקי אחרים}}", "notification-header-foreign-all": "עוד הודעות {{PLURAL:$5|מאתר ויקי אחר|מ־$5 אתרי ויקי אחרים}}", - "echo-foreign-wiki-lang": "$1 – $2" + "echo-foreign-wiki-lang": "$1 – $2", + "right-manage-all-push-subscriptions": "ניהול כל מינויי הדחיפה", + "action-manage-all-push-subscriptions": "לנהל את כל מינויי הדחיפה", + "group-push-subscription-manager": "מנהלי מינויי דחיפה", + "group-push-subscription-manager-member": "{{GENDER:$1|מנהל|מנהלת}} מינויי דחיפה", + "grouppage-push-subscription-manager": "{{ns:project}}:מנהל מינויי דחיפה" } diff --git a/Echo/i18n/hi.json b/Echo/i18n/hi.json index 51c27d58..0f0b885a 100644 --- a/Echo/i18n/hi.json +++ b/Echo/i18n/hi.json @@ -9,6 +9,7 @@ "Hindustanilanguage", "NehalDaveND", "Sachinkatiyar", + "Saurmandal", "Sfic", "Shahjad ansari", "Shubhamkanodia", @@ -19,140 +20,224 @@ "हिंदुस्थान वासी" ] }, - "echo-desc": "अधिसूचना प्रणाली", - "prefs-echo": "सूचनायें", + "echo-desc": "सदस्यों को घटनाओं और संदेशों के बारे में सूचित करने के लिए प्रणाली", + "prefs-echo": "अधिसूचनाएँ", "prefs-emailsettings": "ईमेल विकल्प", "prefs-echosubscriptions": "मुझे इन घटनाओं के बारे में सूचित करें", - "prefs-echocrosswiki": "क्रॉस-विकी नोटिफिकेशन", - "prefs-blocknotificationslist": "मूक उपयोगकर्ता", - "echo-pref-send-me": "मुझे भेजिए:", - "echo-pref-send-to": "यहाँ भेजिए:", - "echo-pref-email-format": "ईमेल प्रारूप:", + "prefs-echocrosswiki": "क्रॉस-विकि अधिसूचनाएँ", + "prefs-blocknotificationslist": "म्यूट किए गए सदस्य", + "prefs-mutedpageslist": "पृष्ठों की कड़ियों वाली अधिसूचनाओं के लिए म्यूट किए गए पृष्ठ", + "prefs-echopollupdates": "लाइव अधिसूचनाएँ", + "echo-mobile-notifications-filter-title": "अधिसूचनाएँ छानें", + "echo-pref-show-poll-updates": "नई सुचनाएँ आने पर उन्हें दिखाते जाएँ", + "echo-pref-show-poll-updates-help": "शीर्षक बार में अपठित अधिसूचनाओं की संख्या दिखाएँ, और हर अधिसूचना के आते ही उसका एक सारांश दिखाएँ।", + "echo-pref-send-me": "मुझे भेजें:", + "echo-pref-send-to": "यहाँ भेजें:", + "echo-pref-email-format": "ईमेल का प्रारूप:", "echo-pref-web": "वेब", "echo-pref-email": "ईमेल", - "echo-pref-email-frequency-never": "मुझे कोई भी ईमेल अधिसूचना मत भेजें", - "echo-pref-email-frequency-immediately": "सूचना आते साथ प्राप्त होती है।", - "echo-pref-email-frequency-daily": "अधिसूचनाओं का दैनिक सारांश", - "echo-pref-email-frequency-weekly": "अधिसूचनाओं का साप्ताहिक सारांश", - "echo-pref-email-format-html": "एच॰टी॰एम॰एल॰", - "echo-pref-email-format-plain-text": "सादा पाठ", - "echo-pref-cross-wiki-notifications": "दूसरे विकीज़ से नोटिफिकेशन दिखाएँ", - "echo-learn-more": "अधिक जानिए", + "echo-pref-push": "ऐप्स", + "echo-pref-email-frequency-never": "मुझे कोई भी ईमेल अधिसूचना न भेजें", + "echo-pref-email-frequency-immediately": "अधिसूचनाओं के आने पर तुरंत भेजें", + "echo-pref-email-frequency-daily": "अधिसूचनाओं का दैनिक सारांश भेजें", + "echo-pref-email-frequency-weekly": "अधिसूचनाओं का साप्ताहिक सारांश भेजें", + "echo-pref-email-format-html": "HTML", + "echo-pref-email-format-plain-text": "सादा टेक्स्ट", + "echo-pref-cross-wiki-notifications": "दूसरे विकियों से अधिसूचनाएँ दिखाएँ", + "echo-pref-notifications-blacklist": "इन सदस्यों से अधिसूचनाएँ न दिखाएँ। ([[mw:Special:MyLanguage/Help:Notifications#mute|अधिक जानें]])", + "echo-pref-notifications-page-linked-title-muted-list": "इन पृष्ठों से \"पृष्ठों की कड़ियों\" वाली अधिसूचनाएँ न दिखाएँ। ([[mw:Special:MyLanguage/Help:Notifications#mute|अधिक जानें]])", + "echo-pref-dont-email-read-notifications": "सारांश ईमेलों में पठित अधिसूचनाएँ शामिल न करें", + "echo-learn-more": "अधिक जानें", "echo-log": "सार्वजनिक लॉग", - "echo-new-messages": "आपके लिए नए संदेश हैं", - "echo-category-title-edit-user-talk": "वार्ता पृष्ठ {{PLURAL:$1| सन्देश}}", - "echo-category-title-article-linked": "पृष्ठ {{PLURAL:$1| कड़ी | कड़ियाँ}}", - "echo-category-title-reverted": "सम्पादन {{PLURAL:$1|पूर्ववत किये जाने की}}", + "echo-new-messages": "आपके वार्ता पृष्ठ पर एक नया संदेश है", + "echo-category-title-edit-user-talk": "मेरे वार्ता पृष्ठ पर {{PLURAL:$1|संपादन}}", + "echo-category-title-article-linked": "पृष्ठ {{PLURAL:$1|कड़ी|कड़ियाँ}}", + "echo-category-title-reverted": "{{PLURAL:$1|संपादन|संपादनों}} पर पूर्ववत क्रिया", "echo-category-title-mention": "{{PLURAL:$1|उल्लेख}}", - "echo-category-title-mention-failure": "{{PLURAL:$1|उल्लेख}} विफल रहा", - "echo-category-title-mention-success": "{{PLURAL:$1|उल्लेख}} सफल रहा", + "echo-category-title-mention-failure": "विफल {{PLURAL:$1|उल्लेख}}", + "echo-category-title-mention-success": "सफल {{PLURAL:$1|उल्लेख}}", "echo-category-title-other": "{{PLURAL:$1|अन्य}}", "echo-category-title-system": "{{PLURAL:$1|प्रणाली}}", - "echo-category-title-user-rights": "{{PLURAL:$1|सदस्य अधिकार बदला|सदस्य अधिकार बदले}}", - "echo-category-title-emailuser": "{{PLURAL:$1|अन्य सदस्य से ईमेल|अन्य सदस्यों से ईमेल}}", - "echo-pref-tooltip-edit-user-talk": "जब कोई मुझे संदेश भेजे या मेरे वार्ता पृष्ठ पर उत्तर दे तो मुझे सूचित करें।", - "echo-pref-tooltip-article-linked": "जब कोई मेरे द्वारा बनाए गए लेख की कड़ी कहीं जोड़े तो मुझे सूचित करें।", - "echo-pref-tooltip-reverted": "जब कोई मेरे किसी सम्पादन को पूर्ववत करे या वापस ले तो मुझे सूचित करें।", - "echo-pref-tooltip-mention": "जब कोई मेरे सदस्य पृष्ठ की कड़ी का किसी वार्ता पृष्ठ पर प्रयोग करे तो मुझे सूचित करें।", - "echo-pref-tooltip-mention-failure": "यदि किसी के नाम का उल्लेख न हो तो मुझे सूचित करें।", + "echo-category-title-system-noemail": "{{PLURAL:$1|प्रणाली}}", + "echo-category-title-system-emailonly": "{{PLURAL:$1|प्रणाली}}", + "echo-category-title-user-rights": "{{PLURAL:$1|सदस्य अधिकारों}} में बदलाव", + "echo-category-title-emailuser": "{{PLURAL:$1|दूसरे सदस्य से ईमेल|दूसरे सदस्यों से ईमेल}}", + "echo-category-title-article-reminder": "{{PLURAL:$1|पृष्ठ का|पृष्ठों के}} अनुस्मारक", + "echo-category-title-thank-you-edit": "संपादन की {{PLURAL:$1|उपलब्धि|उपलब्धियाँ}}", + "echo-category-title-watchlist": "ध्यान रखे हुए पृष्ठ पर संपादन", + "echo-category-title-minor-watchlist": "ध्यान रखे हुए पृष्ठ पर छोटा संपादन", + "echo-pref-tooltip-edit-user-talk": "जब कोई मेरे वार्ता पृष्ठ को संपादित करे तब मुझे सूचित करें।", + "echo-pref-tooltip-article-linked": "जब कोई मेरे बनाए पृष्ठ की कड़ी किसी दूसरे पृष्ठ पर जोड़े तब मुझे सूचित करें।", + "echo-pref-tooltip-reverted": "जब कोई मेरे संपादन को पूर्ववत या रोलबैक उपकरण की मदद से पूर्ववत करता है तब मुझे सूचित करें।", + "echo-pref-tooltip-mention": "जब कोई मेरे सदस्य पृष्ठ की कड़ी कहीं जोड़ता है तब मुझे सूचित करें।", + "echo-pref-tooltip-mention-failure": "अगर मैं किसी सदस्य का उल्लेख न कर पाऊँ तो मुझे सूचित करें।", "echo-pref-tooltip-mention-success": "किसी के नाम का उल्लेख करने पर मुझे सूचित करें।", - "echo-pref-tooltip-user-rights": "यदि कोई मेरे सदस्य अधिकार परिवर्तित करता है तो मुझे सूचित करें।", - "echo-pref-tooltip-emailuser": "जब मुझे कोई ईमेल करें तो मुझे सूचना दें।", - "notifications": "सूचनायें", - "tooltip-pt-notifications-alert": "{{GENDER:|आपका}} जागरूकता संदेश", - "tooltip-pt-notifications-notice": "{{GENDER:|आपकी}} सूचना", - "echo-displaynotificationsconfiguration": "प्रदर्शन सूचना पसंद", - "echo-displaynotificationsconfiguration-summary": "यह इस विकी पर सूचनाएँ कैसे कॉन्फ़िगर किया गया है, इसका अवलोकन है।", - "echo-displaynotificationsconfiguration-notifications-by-category-header": "श्रेणी अनुसार अधिसूचनाएं", - "echo-displaynotificationsconfiguration-sorting-by-section-header": "छंटनी के प्रकार", - "echo-displaynotificationsconfiguration-available-notification-methods-header": "अनुमति प्राप्त सूचना के तरीके", - "echo-displaynotificationsconfiguration-enabled-default-header": "मूल रूप से सक्रिय", - "echo-displaynotificationsconfiguration-enabled-default-existing-users-legend": "वर्तमान सदस्य", - "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "नये सदस्य", - "echo-displaynotificationsconfiguration-mandatory-notification-methods-header": "अनिवार्य सूचना पद्धति", - "echo-displaynotificationsconfiguration-mandatory-notification-methods-by-category-legend": "कौनसा सूचना पद्धति उन श्रेणियों में अनिवार्य है", - "echo-specialpage": "सूचनायें", - "echo-specialpage-section-markread": "समूह को पढ़ा हुआ चिह्नित करें", - "echo-specialpage-markasread": "सूचना: पढ़ा हुआ चिन्हित करें", - "echo-specialpage-markasread-invalid-id": "अमान्य आयोजन आईडी", - "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|सूचना}}", + "echo-pref-tooltip-user-rights": "जब कोई मेरे सदस्य अधिकार बदलता है तब मुझे सूचित करें।", + "echo-pref-tooltip-emailuser": "जब मुझे कोई ईमेल करे तो मुझे सूचित करें।", + "echo-pref-tooltip-article-reminder": "मेरे पूछने पर मुझे इस पृष्ठ के बारे में सूचित करें।", + "echo-pref-tooltip-thank-you-edit": "मेरे पहले, दसवें, सौवें संपादन पर मुझे सूचित करें।", + "echo-pref-tooltip-watchlist": "जब कोई मेरी ध्यानसूची में कोई (गैर-छोटा) संपादन करता है तो मुझे सूचित करें।", + "echo-pref-tooltip-minor-watchlist": "जब कोई मेरी ध्यानसूची में कोई छोटा संपादन करता है तो मुझे सूचित करें।", + "notifications": "अधिसूचनाएँ", + "tooltip-pt-notifications-alert": "आपकी चेतावनियाँ", + "tooltip-pt-notifications-notice": "आपकी अधिसूचनाएँ", + "echo-displaynotificationsconfiguration": "अधिसूचनाओं का कॉन्फ़िगरेशन देखें", + "echo-displaynotificationsconfiguration-summary": "यह इस विकि पर आपकी अधिसूचनाओं के कॉन्फ़िगरेशन का एक अवलोकन है।", + "echo-displaynotificationsconfiguration-notifications-by-category-header": "श्रेणी अनुसार अधिसूचनाएँ", + "echo-displaynotificationsconfiguration-sorting-by-section-header": "छँटनी के प्रकार", + "echo-displaynotificationsconfiguration-sorting-by-section-legend": "अधिसूचना के हर प्रकार को किस अनुभाग में दिखाया जाता है", + "echo-displaynotificationsconfiguration-available-notification-methods-header": "अधिसूचनाओं के अनुमोदित माध्यम", + "echo-displaynotificationsconfiguration-available-notification-methods-by-category-legend": "हर श्रेणी में अधिसूचनाओं के कौन-से प्रकार समर्थित हैं", + "echo-displaynotificationsconfiguration-enabled-default-header": "डिफ़ॉल्ट से सक्रिय", + "echo-displaynotificationsconfiguration-enabled-default-existing-users-legend": "मौजूदा सदस्य", + "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "नए सदस्य", + "echo-displaynotificationsconfiguration-mandatory-notification-methods-header": "अधिसूचनाओं के अनिवार्य माध्यम", + "echo-displaynotificationsconfiguration-mandatory-notification-methods-by-category-legend": "हर श्रेणी में अधिसूचनाओं के कौन-से प्रकार अनिवार्य हैं", + "echo-specialpage": "अधिसूचनाएँ", + "echo-specialpage-section-markread": "समूह को पठित चिह्नित करें", + "echo-specialpage-markasread": "अधिसूचना: पठित चिह्नित करें", + "echo-specialpage-markasread-invalid-id": "अमान्य घटना ID", + "echo-specialpage-pagefilterwidget-aria-label": "विकि और पृष्ठ शीर्षक के अनुसार छानें", + "echo-specialpage-special-help-menu-widget-aria-label": "अतिरिक्त विकल्प और अधिसूचनाओं की वरीयताएँ।", + "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|सूचना|सूचनाएँ}}", "echo-specialpage-pagefilters-title": "हाल की गतिविधि", - "echo-specialpage-pagefilters-subtitle": "न पढ़े सूचना के साथ पन्ने", - "notificationsmarkread-legend": "सूचना को पढ़ा हुआ चिन्हित करें", - "echo-none": "आपके लिये कोई अधिसूचना नहीं है।", - "echo-api-failure": "सूचना प्राप्त करने में विफल रहा।", - "echo-api-failure-cross-wiki": "रिमोट डोमैन ने जुड़ने से इंकार कर दिया।", - "echo-notification-placeholder": "कोई सूचना नहीं है।", - "echo-notification-placeholder-filters": "इस मापदंड पर कोई सूचना नहीं दिख रही", - "echo-notification-loginrequired": "सूचनाओं को देखने हेतु आपको प्रवेश करना होगा।", - "echo-notification-popup-loginrequired": "सूचना देखने हेतु खाते में प्रवेश करें।", - "echo-notification-markasread": "पढ़ा गया चिन्हित करें", - "echo-notification-markasunread": "न पढ़ा चिन्हित करें", - "echo-notification-markasread-tooltip": "पढ़ा गया चिन्हित करें", - "echo-notification-more-options-tooltip": "अन्य विकल्प", - "notification-dynamic-actions-unwatch": "\"$1\" में नई गतिविधि देखना {{GENDER:$3|बंद}} करें", - "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3|आप}} अब \"$1\" पन्ने को ध्यानसूची से हटा चुके हैं।", - "notification-dynamic-actions-watch": "\"$1\" में नई गतिविधि {{GENDER:$3|ध्यान में रखें}}", - "notification-dynamic-actions-watch-confirmation": "\"$1\" को {{GENDER:$3|आप}} ध्यान दे रहे हैं।", - "notification-dynamic-actions-watch-confirmation-description": "{{GENDER:$3|आप}} [$2 इस पृष्ठ] से कभी भी ध्यान देना बंद कर सकते हैं।", + "echo-specialpage-pagefilters-subtitle": "अपठित अधिसूचनाओं वाले पृष्ठ", + "notificationsmarkread-legend": "अधिसूचना को पठित चिह्नित करें", + "echo-none": "आपके लिए कोई अधिसूचना नहीं है।", + "echo-api-failure": "अधिसूचनाएँ प्राप्त न की जा सकीं।", + "echo-api-failure-cross-wiki": "रिमोट डोमेन तक पहुँचा न जा सका।", + "echo-notification-placeholder": "कोई अधिसूचना नहीं है।", + "echo-notification-placeholder-filters": "इन मानदंडों से कोई अधिसूचना मेल नहीं खाती।", + "echo-notification-loginrequired": "अधिसूचनाएँ देखने के लिए आपको लॉग-इन करना होगा।", + "echo-notification-popup-loginrequired": "अपनी अधिसूचनाएँ देखने के लिए कृपया लॉग-इन करें।", + "echo-notification-markasread": "पठित चिह्नित करें", + "echo-notification-markasunread": "अपठित चिह्नित करें", + "echo-notification-markasread-tooltip": "पठित चिह्नित करें", + "echo-notification-more-options-tooltip": "अधिक विकल्प", + "notification-dynamic-actions-mute-page-linked": "\"$1\" पर कड़ियों की अधिसूचनाएँ {{GENDER:$2|म्यूट करें}}", + "notification-dynamic-actions-mute-page-linked-confirmation": "\"पृष्ठ कड़ी\" अधिसूचनाएँ अब \"$1\" पृष्ठ के लिए अक्षम हैं", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|आप}} किसी भी समय [$1 अपनी वरीयताओं] में आपके म्यूट किए गए पृष्ठ प्रबंधित कर सकते हैं।", + "notification-dynamic-actions-unmute-page-linked": "\"$1\" पर कड़ियों की अधिसूचनाएँ {{GENDER:$2|अनम्यूट करें}}", + "notification-dynamic-actions-unmute-page-linked-confirmation": "\"पृष्ठ कड़ी\" अधिसूचनाएँ अब \"$1\" पृष्ठ के लिए सक्षम हैं", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|आप}} किसी भी समय [$1 अपनी वरीयताओं] में आपके म्यूट किए गए पृष्ठ प्रबंधित कर सकते हैं।", + "notification-dynamic-actions-unwatch": "\"$1\" में नई गतिविधि पर ध्यान रखना {{GENDER:$3|बंद करें}}", + "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3|आप}} अब \"$1\" पृष्ठ को ध्यानसूची से हटा चुके हैं", + "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|आप}} [$2 इस पृष्ठ] को कभी भी ध्यानसूची में डाल सकते हैं।", + "notification-dynamic-actions-watch": "\"$1\" में नई गतिविधि पर {{GENDER:$3|ध्यान रखें}}", + "notification-dynamic-actions-watch-confirmation": "{{GENDER:$3|आप}} अब \"$1\" पर ध्यान रख रहे हैं", + "notification-dynamic-actions-watch-confirmation-description": "{{GENDER:$3|आप}} [$2 इस पृष्ठ] को कभी भी ध्यानसूची से हटा सकते हैं।", "notification-link-text-expand-all": "विस्तार करें", - "notification-link-text-expand-alert-count": "{{PLURAL:$1|$1 सूचना|$1 सूचनाएँ}} देखें", - "notification-link-text-expand-notice-count": "{{PLURAL:$1|$1 सूचना|$1 सूचनाओं को}} देखें", - "notification-link-text-expand-all-count": "{{PLURAL:$1|$1 सूचना|$1 सूचनाओं को}} देखें", + "notification-link-text-expand-alert-count": "{{PLURAL:$1|$1 चेतावनी|$1 चेतावनियाँ}} देखें", + "notification-link-text-expand-notice-count": "{{PLURAL:$1|$1 अधिसूचना|$1 अधिसूचनाएँ}} देखें", + "notification-link-text-expand-all-count": "{{PLURAL:$1|$1 अधिसूचना|$1 अधिसूचनाएँ}} देखें", "notification-link-text-collapse-all": "छोटा करें", "notification-link-text-view-message": "संदेश देखें", "notification-link-text-view-mention": "उल्लेख देखें", "notification-link-text-view-mention-failure": "{{PLURAL:$1|उल्लेख देखें}}", "notification-link-text-view-changes": "बदलाव {{GENDER:$1|देखें}}", "notification-link-text-view-page": "पृष्ठ देखें", - "notification-header-edit-user-talk": "$1 ने <strong>{{GENDER:$3|आपके}} वार्ता पृष्ठ पर</strong> एक संदेश {{GENDER:$2|छोड़ा}} है।", - "notification-compact-header-page-linked": "<strong>$1</strong> से जुड़ा", - "notification-link-text-what-links-here": "इसी पृष्ठ से जुड़ी सभी कड़ियाँ", - "notification-header-mention-other": "<strong>$4</strong> पर \"<strong>$5</strong>\" अनुभाग में $1 जी ने {{GENDER:$3|आपका}} {{GENDER:$2|उल्लेख किया है}}।", - "notification-header-mention-other-nosection": "$1 जी ने {{GENDER:$3|आपका}} <strong>$4</strong> में {{GENDER:$2|उल्लेख किया है}}।", - "notification-header-mention-user-talkpage-v2": "<strong>$4 {{GENDER:$5|के}} वार्ता पृष्ठ</strong> के \"<strong>$6</strong>\" अनुभाग में $1 जी ने {{GENDER:$3|आपका}} {{GENDER:$2|उल्लेख किया है}}।", - "notification-header-mention-user-talkpage-nosection": "$1 जी ने {{GENDER:$3|आपका}} $4 {{GENDER:$5|के}} <strong>सदस्य वार्ता पृष्ठ पर</strong> {{GENDER:$2|उल्लेख किया है}}।", - "notification-compact-header-mention-failure-user-unknown": "<strong>सदस्य नाम उपस्थित नहीं है:</strong> $1", - "notification-compact-header-mention-failure-user-anonymous": "<strong>आईपी सदस्यों का उल्लेख नहीं किया जा सकता:</strong> $1", + "notification-header-edit-user-talk": "$1 ने <strong>{{GENDER:$3|आपके}} वार्ता पृष्ठ</strong> पर एक संदेश {{GENDER:$2|छोड़ा}} है।", + "notification-header-edit-user-talk-with-section": "$1 ने <strong>{{GENDER:$3|आपके}} वार्ता पृष्ठ</strong> के \"<strong>$4</strong>\" में एक संदेश {{GENDER:$2|छोड़ा}} है।", + "notification-compact-header-edit-user-talk": "$1 ने {{GENDER:$3|आपके}} लिए एक संदेश {{GENDER:$2|छोड़ा है}}।", + "notification-compact-header-edit-user-talk-with-section": "$1 ने \"<strong>$4</strong>\" में {{GENDER:$3|आपके}} लिए एक संदेश {{GENDER:$2|छोड़ा है}}।", + "notification-header-page-linked": "<strong>$4</strong> से <strong>$3</strong> तक एक कड़ी बनाई गई।", + "notification-compact-header-page-linked": "<strong>$1</strong> से जुड़ा।", + "notification-bundle-header-page-linked": "{{PLURAL:$5||$5 पृष्ठों|100=99 से अधिक पृष्ठों}} से <strong>$3</strong> तक कड़ियाँ बनाई गईं।", + "notification-header-article-reminder": "एक पृष्ठ <strong>$3</strong> पर है जिसके बारे में {{GENDER:$2|आपने}} अनुस्मारक प्राप्त करने का अनुरोध किया था", + "notification-link-text-what-links-here": "इस पृष्ठ की सारी कड़ियाँ", + "notification-header-mention-other": "$1 ने <strong>$4</strong> पर \"<strong>$5</strong>\" में {{GENDER:$3|आपका}} {{GENDER:$2|उल्लेख किया}} है।", + "notification-header-mention-other-nosection": "$1 ने <strong>$4</strong> पर {{GENDER:$3|आपका}} {{GENDER:$2|उल्लेख किया}} है।", + "notification-header-mention-user-talkpage-v2": "$1 ने <strong>$4 {{GENDER:$5|के}} सदस्य वार्ता पृष्ठ</strong> पर \"<strong>$6</strong>\" में {{GENDER:$3|आपका}} {{GENDER:$2|उल्लेख किया}} है।", + "notification-header-mention-user-talkpage-nosection": "$1 ने <strong>$4 {{GENDER:$5|के}} सदस्य वार्ता पृष्ठ</strong> पर {{GENDER:$3|आपका}} {{GENDER:$2|उल्लेख किया}} है।", + "notification-header-mention-agent-talkpage": "$1 ने <strong>{{GENDER:$2|अपने}} वार्ता पृष्ठ</strong> पर \"<strong>$4</strong>\" में {{GENDER:$3|आपका}} {{GENDER:$2|उल्लेख किया}} है।", + "notification-header-mention-agent-talkpage-nosection": "$1 ने <strong>{{GENDER:$2|अपने}} वार्ता पृष्ठ</strong> पर {{GENDER:$3|आपका}} {{GENDER:$2|उल्लेख किया}} है।", + "notification-header-mention-article-talkpage": "$1 ने <strong>$4</strong> वार्ता पृष्ठ पर \"<strong>$5</strong>\" में {{GENDER:$3|आपका}} {{GENDER:$2|उल्लेख किया}} है।", + "notification-header-mention-article-talkpage-nosection": "$1 ने <strong>$4</strong> वार्ता पृष्ठ पर {{GENDER:$3|आपका}} {{GENDER:$2|उल्लेख किया}} है।", + "notification-header-mention-failure-user-unknown": "<strong>$3</strong> का उल्लेख नहीं {{GENDER:$2|किया}} जा सका क्योंकि सदस्य नहीं मिला।", + "notification-header-mention-failure-user-anonymous": "<strong>$3</strong> का उल्लेख नहीं {{GENDER:$2|किया}} जा सका क्योंकि सदस्य गुमनाम है।", + "notification-header-mention-failure-too-many": "{{GENDER:$2|आपने}} $3 से अधिक {{PLURAL:$3|सदस्य|सदस्यों}} का उल्लेख करने का प्रयास किया। इस सीमा के बाहर के सारे उल्लेख असफल रहे।", + "notification-header-mention-failure-bundle": "<strong>$4</strong> वार्ता पृष्ठ पर {{GENDER:$2|आपके}} द्वारा {{PLURAL:$3|जोड़ा गया एक|जोड़े गए $3}} उल्लेख असफल {{PLURAL:$3|रहा|रहे}}।", + "notification-compact-header-mention-failure-user-unknown": "<strong>सदस्यनाम मौजूद नहीं है:</strong> $1", + "notification-compact-header-mention-failure-user-anonymous": "<strong>IP सदस्यों का उल्लेख नहीं किया जा सकता:</strong> $1", + "notification-header-mention-success": "<strong>$3</strong> का उल्लेख {{GENDER:$2|कर दिया}} गया है।", + "notification-header-mention-success-bundle": "<strong>$4</strong> वार्ता पृष्ठ पर {{GENDER:$2|आपके}} द्वारा {{PLURAL:$3|जोड़ा गया एक|जोड़े गए $3}} उल्लेख सफल {{PLURAL:$3|रहा|रहे}}।", "notification-compact-header-mention-success": "<strong>{{GENDER:$2|आपने उल्लेख किया}}:</strong> $3", - "notification-header-user-rights-add-only": "{{GENDER:$4|आपका}} अधिकार {{GENDER:$1|बदला}} गया। अब आपको इसमें जोड़ा गया है: $2", + "notification-header-mention-status-bundle": "<strong>$4</strong> वार्ता पृष्ठ पर {{GENDER:$2|आपके}} द्वारा जोड़े गए उल्लेखों के बारे में {{PLURAL:$3|एक अधिसूचना|$3 अधिसूचनाएँ}}: {{PLURAL:$5|$5 असफल}}, {{PLURAL:$6|$6 सफल}}।", + "notification-header-user-rights-add-only": "{{GENDER:$4|आपके}} सदस्य अधिकार {{GENDER:$1|बदले गए}} हैं। आपको $2 में जोड़ दिया गया है।", + "notification-header-user-rights-remove-only": "{{GENDER:$4|आपके}} सदस्य अधिकार {{GENDER:$1|बदले गए}} हैं। आप अब $2 के सदस्य नहीं रहे।", + "notification-header-user-rights-add-and-remove": "{{GENDER:$6|आपके}} सदस्य अधिकार {{GENDER:$1|बदले गए}} हैं। आपको $2 में जोड़ दिया गया है। आप अब $4 के सदस्य नहीं रहे।", + "notification-header-user-rights-expiry-change": "{{PLURAL:$3|इस समूह|इन समूहों}} में {{GENDER:$4|आपके}} सदस्यता की समाप्ति {{GENDER:$1|बदल दी गई}} है: $2।", + "notification-header-welcome": "{{SITENAME}} पर आपका {{GENDER:$2|स्वागत है}}, $1 जी! आपको यहाँ पाकर हमें बहुत खुशी हुई।", + "notification-header-mention-summary": "$1 ने <strong>$4</strong> पर एक संपादन सारांश में {{GENDER:$3|आपका}} {{GENDER:$2|उल्लेख किया}}।", + "notification-header-watchlist-changed": "$1 ने{{PLURAL:$5|| $5 बार}} {{GENDER:$4|आपकी}} ध्यानसूची में मौजूद एक पृष्ठ <strong>$3</strong> को {{GENDER:$2|बदला}}।", + "notification-header-watchlist-created": "$1 ने{{PLURAL:$5|| $5 बार}} {{GENDER:$4|आपकी}} ध्यानसूची में मौजूद एक पृष्ठ <strong>$3</strong> को {{GENDER:$2|बनाया}}।", + "notification-header-watchlist-deleted": "$1 ने{{PLURAL:$5|| $5 बार}} {{GENDER:$4|आपकी}} ध्यानसूची में मौजूद एक पृष्ठ <strong>$3</strong> को {{GENDER:$2|हटाया}}।", + "notification-header-watchlist-moved": "$1 ने{{PLURAL:$5|| $5 बार}} {{GENDER:$4|आपकी}} ध्यानसूची में मौजूद एक पृष्ठ <strong>$3</strong> को {{GENDER:$2|स्थानांतरित किया}}।", + "notification-header-watchlist-restored": "$1 ने{{PLURAL:$5|| $5 बार}} {{GENDER:$4|आपकी}} ध्यानसूची में मौजूद एक पृष्ठ <strong>$3</strong> को {{GENDER:$2|पुनर्स्थापित किया}}।", + "notification-header-watchlist-multiuser-changed": "<strong>$1</strong>, {{GENDER:$2|आपकी}} ध्यानसूची में मौजूद एक पृष्ठ, को $3 {{PLURAL:$3|बार}} बदला गया।", + "notification-header-watchlist-multiuser-created": "<strong>$1</strong>, {{GENDER:$2|आपकी}} ध्यानसूची में मौजूद एक पृष्ठ, को $3 {{PLURAL:$3|बार}} बनाया गया।", + "notification-header-watchlist-multiuser-deleted": "<strong>$1</strong>, {{GENDER:$2|आपकी}} ध्यानसूची में मौजूद एक पृष्ठ, को $3 {{PLURAL:$3|बार}} हटाया गया।", + "notification-header-watchlist-multiuser-moved": "<strong>$1</strong>, {{GENDER:$2|आपकी}} ध्यानसूची में मौजूद एक पृष्ठ, को $3 {{PLURAL:$3|बार}} स्थानांतरित किया गया।", + "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>, {{GENDER:$2|आपकी}} ध्यानसूची में मौजूद एक पृष्ठ, को $3 {{PLURAL:$3|बार}} पुनर्स्थापित गया।", + "notification-body-watchlist-once": "जब तक {{GENDER:$1|आप}} लॉग-इन करके इस पृष्ठ पर वापस नहीं आते, गतिविधि की अधिसूचनाएँ आपको ईमेल से भेजी नहीं जाएँगी।", "notification-welcome-linktext": "सुस्वागतम्!", - "notification-header-thank-you-1-edit": "{{GENDER:$2|आपने}} अभी अभी {{GENDER:$2|अपना}} पहला सम्पादन किया है; {{GENDER:$2|आपका}} धन्यवाद, और स्वागत है!", - "notification-link-thank-you-edit": "{{GENDER:$1|आपके}} सम्पादन", - "notification-link-text-view-edit": "सम्पादन देखें", - "notification-link-article-reminder": "लेख देखें", - "notification-header-reverted": "$3 पर आपके {{PLURAL:$4|सम्पादन|सम्पादनों}} को $1 द्वारा {{GENDER:$2|पूर्ववत}} कर दिया गया है।", + "notification-header-thank-you-1-edit": "{{GENDER:$2|आपने}} अभी-अभी {{GENDER:$2|अपना}} पहला संपादन किया है; {{GENDER:$2|आपका}} धन्यवाद, और स्वागत है!", + "notification-header-thank-you-10-edit": "{{GENDER:$2|आपने}} अभी-अभी {{GENDER:$2|अपना}} दसवाँ संपादन किया है; {{GENDER:$2|आपका}} धन्यवाद, और कृपया आगे बढ़ते जाएँ!", + "notification-header-thank-you-100-edit": "{{GENDER:$2|आपने}} अभी-अभी {{GENDER:$2|अपना}} सौवाँ संपादन किया है; {{GENDER:$2|आपका}} दिल से धन्यवाद!", + "notification-header-thank-you-1000-edit": "{{GENDER:$2|आपने}} अभी-अभी {{GENDER:$2|अपना}} सौवाँ संपादन किया है; एक श्रेष्ठ योगदानकर्ता होने के लिए {{GENDER:$2|आपका}} धन्यवाद!", + "notification-header-thank-you-10000-edit": "{{GENDER:$2|आपने}} अभी-अभी {{GENDER:$2|अपना}} हज़ारवाँ संपादन किया है; {{GENDER:$2|आपका}} बहुत-बहुत धन्यवाद!", + "notification-header-thank-you-100000-edit": "{{GENDER:$2|आपने}} अभी-अभी {{GENDER:$2|अपना}} एक लाखवाँ संपादन किया है; इस खूबसूरत योगदान के लिए {{GENDER:$2|आपका}} धन्यवाद!", + "notification-header-thank-you-1000000-edit": "{{GENDER:$2|आपने}} अभी-अभी {{GENDER:$2|अपना}} दस लाखवाँ संपादन किया है; इस चमकते योगदान के लिए {{GENDER:$2|आपका}} धन्यवाद!", + "notification-header-thank-you-10000000-edit": "{{GENDER:$2|आपने}} अभी-अभी {{GENDER:$2|अपना}} एक करोड़वाँ संपादन किया है; इस समर्पण के लिए {{GENDER:$2|आपका}} धन्यवाद!", + "notification-link-thank-you-edit": "{{GENDER:$1|आपका}} सम्पादन", + "notification-link-text-view-edit": "संपादन देखें", + "notification-link-article-reminder": "पृष्ठ देखें", + "notification-header-reverted": "<strong>$3</strong> पर आपके {{PLURAL:$4|संपादन|संपादनों}} को {{GENDER:$2|पूर्ववत कर दिया गया}} है।", "notification-header-emailuser": "$1 ने आपको ईमेल {{GENDER:$2|भेजा}} है।", - "notification-edit-talk-page-email-subject2": "$1 ने आपके लिए {{SITENAME}} पर संदेश {{GENDER:$2|छोड़ा है}}", - "notification-page-linked-email-subject": "आपका पृष्ठ {{SITENAME}} पर लिंक किया गया", - "notification-reverted-email-subject2": "{{SITENAME}} पर आपके {{PLURAL:$4|सम्पादन|सम्पादनों}} को {{GENDER:$2|पूर्ववत}} किया गया।", - "notification-mention-email-subject": "$1 ने {{SITENAME}} पर आपका {{GENDER:$2|उल्लेख}} किया", - "notification-user-rights-email-subject": "{{SITENAME}} पर आपके सदस्य अधिकार बदले गए हैं", - "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1से}}", + "notification-edit-talk-page-email-subject2": "$1 ने {{GENDER:$3|आपके}} लिए {{SITENAME}} पर संदेश {{GENDER:$2|छोड़ा है}}", + "notification-page-linked-email-subject": "{{SITENAME}} पर {{GENDER:$3|आपके}} द्वारा बनाए गए एक पृष्ठ की कड़ी कहीं जोड़ी गई है", + "notification-reverted-email-subject2": "{{SITENAME}} पर {{GENDER:$3|आपके}} {{PLURAL:$4|सम्पादन|सम्पादनों}} को {{GENDER:$2|पूर्ववत}} कर दिया गया है", + "notification-mention-email-subject": "$1 ने {{SITENAME}} पर {{GENDER:$3|आपका}} {{GENDER:$2|उल्लेख}} किया है", + "notification-user-rights-email-subject": "{{SITENAME}} पर {{GENDER:$3|आपके}} सदस्य अधिकार बदले गए हैं", + "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1 सेकंड}}", "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1 मि}}", - "notification-timestamp-ago-hours": "{{PLURAL:$1|$1 घ}}", + "notification-timestamp-ago-hours": "{{PLURAL:$1|$1 घं}}", "notification-timestamp-ago-days": "{{PLURAL:$1|$1 दि}}", "notification-timestamp-ago-months": "{{PLURAL:$1|$1 मा}}", "notification-timestamp-ago-years": "{{PLURAL:$1|$1 व}}", "notification-timestamp-today": "आज", "notification-timestamp-yesterday": "कल", - "notification-inbox-filter-read": "पढ़ें", - "notification-inbox-filter-unread": "बिना पढ़े", + "notification-inbox-filter-read": "पठित", + "notification-inbox-filter-unread": "अपठित", "notification-inbox-filter-all": "सभी", - "echo-email-html-footer-preference-link-text": "{{GENDER:$1|अपनी}} पसंद देखें", - "echo-notification-alert": "{{PLURAL:$1|सूचना ($1)|सूचना ($1)|100=सूचना (99+)}}", - "echo-notification-alert-text-only": "सूचना", - "echo-notification-notice-text-only": "सूचना", - "echo-overlay-link": "सभी सूचनायें", - "echo-overlay-title": "<b>सूचनायें</b>", - "echo-mark-all-as-read": "सभी पढ़ी गयी चिन्हित करें", - "echo-mark-wiki-as-read": "चुने विकियों के सभी को पढ़ा चिन्हित करें: $1", + "echo-specialmute-label-mute-notifications": "इस {{GENDER:$1|सदस्य}} से अधिसूचनाएँ म्यूट करें", + "echo-email-plain-footer": "{{GENDER:$1|आपको}} भेजे जाने वाले ईमेलों को नियंत्रित करने के लिए अपनी वरीयताएँ देखें:", + "echo-email-html-footer-preference-link-text": "{{GENDER:$1|अपनी}} वरीयताएँ देखें", + "echo-email-html-footer-with-link": "{{GENDER:$2|आपको}} भेजे जाने वाले ईमेलों को नियंत्रित करने के लिए $1।", + "echo-notification-alert": "{{PLURAL:$1|चेतावनी ($1)|चेतावनियाँ ($1)|100=चेतावनियाँ (99 से अधिक)}}", + "echo-notification-notice": "{{PLURAL:$1|सूचना ($1)|सूचनाएँ ($1)|100=सूचनाएँ (99 से अधिक)}}", + "echo-notification-alert-text-only": "चेतावनियाँ", + "echo-notification-notice-text-only": "अधिसूचनाएँ", + "echo-overlay-link": "सभी अधिसूचनाएँ", + "echo-overlay-title": "<b>सूचनाएँ</b>", + "echo-mark-all-as-read": "सभी को पठित चिह्नित करे", + "echo-mark-all-as-read-confirmation": "$1 {{PLURAL:$1|सूचना|सूचनाओं}} को पठित चिह्नित किया गया", + "echo-mark-wiki-as-read": "चयनित विकि पर सभी को पठित चिह्नित करें: $1", + "echo-displaysnippet-title": "नई अधिसूचना", "echo-date-today": "आज", "echo-date-yesterday": "कल", - "notification-bundle-header-edit-user-talk-v2": "<strong>{{GENDER:$3|आपके}} वार्ता पृष्ठ</strong> पर {{PLURAL:$1|एक नया संदेश आया है।|$1 नये संदेश आये हैं।|100=99+ नये संदेश आये हैं।}}", - "echo-email-batch-subject-daily": "आपके लिये {{SITENAME}} पर नई {{PLURAL:$2|अधिसूचना है|अधिसूचनाएँ हैं}}।", - "echo-email-batch-subject-weekly": "आपके लिये {{SITENAME}} पर इस सप्ताह नई {{PLURAL:$2|अधिसूचना है|अधिसूचनाएँ हैं}}।", - "echo-email-batch-body-intro-daily": "नमस्कार $1,\n{{SITENAME}} पर आज की गतिविधि का सारांश निम्न है।", - "echo-email-batch-body-intro-weekly": "नमस्कार $1,\n{{SITENAME}} पर इस सप्ताह की गतिविधि का सारांश निम्न है।", - "echo-email-batch-link-text-view-all-notifications": "सभी सूचनायें देखें" + "notification-bundle-header-edit-user-talk-v2": "<strong>{{GENDER:$3|आपके}} वार्ता पृष्ठ</strong> पर {{PLURAL:$1|एक नया संदेश आया है|$1 नए संदेश आए हैं|100=99 से अधिक संदेश आए हैं}}।", + "echo-email-batch-subject-daily": "आपके लिए {{SITENAME}} पर नई {{PLURAL:$2|सूचना है|सूचनाएँ हैं}}", + "echo-email-batch-subject-weekly": "आपके लिए {{SITENAME}} पर इस हफ़्ते नई {{PLURAL:$2|सूचना है|सूचनाएँ हैं}}", + "echo-email-batch-body-intro-daily": "नमस्कार $1,\nयह रहा {{SITENAME}} पर आज की गतिविधि का सारांश।", + "echo-email-batch-body-intro-weekly": "नमस्कार $1,\nयह रहा {{SITENAME}} पर इस हफ़्ते की गतिविधि का सारांश।", + "echo-email-batch-link-text-view-all-notifications": "सभी अधिसूचनाएँ देखें", + "notification-header-foreign-alert": "{{PLURAL:$5|एक दूसरे विकि|$5 दूसरे विकियों}} से अधिक चेतावनियाँ", + "notification-header-foreign-notice": "{{PLURAL:$5|एक दूसरे विकि|$5 दूसरे विकियों}} से अधिक अधिसूचनाएँ", + "notification-header-foreign-all": "{{PLURAL:$5|एक दूसरे विकि|$5 दूसरे विकियों}} से अधिक अधिसूचनाएँ", + "right-manage-all-push-subscriptions": "सभी पुश सदस्यताएँ प्रबंधित करें", + "action-manage-all-push-subscriptions": "सभी पुश सदस्यताएँ प्रबंधित करने", + "group-push-subscription-manager": "पुश सदस्यता प्रबंधक", + "group-push-subscription-manager-member": "{{GENDER:$1|पुश सदस्यता प्रबंधक}}", + "grouppage-push-subscription-manager": "{{ns:project}}:पुश सदस्यता प्रबंधक" } diff --git a/Echo/i18n/hr.json b/Echo/i18n/hr.json index dd37f828..6f4e9ab5 100644 --- a/Echo/i18n/hr.json +++ b/Echo/i18n/hr.json @@ -2,9 +2,12 @@ "@metadata": { "authors": [ "Amire80", + "BadDog", "Bugoslav", "Ex13", "MaGa", + "Neptune, the Mystic", + "Ponor", "Roberta F.", "Wumbolo" ] @@ -37,8 +40,8 @@ "echo-pref-notifications-page-linked-title-muted-list": "Ne prikazuj obavijesti »Stavljanja poveznica na stranicu« za ove stranice. ([[mw:Special:MyLanguage/Help:Notifications#mute|saznaj više]])", "echo-learn-more": "Saznajte više", "echo-log": "Javna evidencija", - "echo-new-messages": "Imate nove poruke", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Poruka|Poruke|Poruka}} na stranici za razgovor", + "echo-new-messages": "Imate nove poruke na stranici za razgovor", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Izmjena|Izmjene}} na mojoj stranici za razgovor", "echo-category-title-article-linked": "Stavljanja {{PLURAL:$1|poveznica|poveznice|poveznica}} na stranicu", "echo-category-title-reverted": "Uklanjanje {{PLURAL:$1|uređivanja}}", "echo-category-title-mention": "{{PLURAL:$1|Spominjanje|Spominjanja}}", @@ -54,7 +57,7 @@ "echo-category-title-thank-you-edit": "{{PLURAL:$1|Miljokaz|Miljokazi}} uređivanja", "echo-category-title-watchlist": "Uređivanje praćene stranice", "echo-category-title-minor-watchlist": "Manje uređivanje praćene stranice", - "echo-pref-tooltip-edit-user-talk": "Obavijesti me kad netko snimi poruku ili odgovori na mojoj stranici za razgovor.", + "echo-pref-tooltip-edit-user-talk": "Obavijesti me kad netko napravi uređivanje na mojoj stranici za razgovor.", "echo-pref-tooltip-article-linked": "Obavijesti me kad netko doda poveznicu na stranicu koju sam započeo s druge stranice.", "echo-pref-tooltip-reverted": "Obavijesti me kad netko ukloni moje uređivanje.", "echo-pref-tooltip-mention": "Obavijesti me kad netko doda poveznicu prema mojoj suradničkoj stranici.", @@ -85,6 +88,7 @@ "echo-specialpage-section-markread": "Označi grupu kao pročitanu", "echo-specialpage-markasread": "Obavijest: označi kao pročitano", "echo-specialpage-markasread-invalid-id": "Neispravan ID događaja", + "echo-specialpage-special-help-menu-widget-aria-label": "Dodatne mogućnosti i postavke obavijesti.", "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|obavijest|obavijesti}}", "echo-specialpage-pagination-range": "$1 - $2", "echo-specialpage-pagefilters-title": "Nedavna aktivnost", @@ -96,11 +100,17 @@ "echo-notification-placeholder": "Nema obavijesti.", "echo-notification-placeholder-filters": "Nema obavijesti prema zadanim kriterijima.", "echo-notification-loginrequired": "Morate biti prijavljeni da biste vidjeli Vaše obavijesti.", - "echo-notification-popup-loginrequired": "Da biste vidjeli vaše obavijesti, molimo prijavite se.", + "echo-notification-popup-loginrequired": "Prijavite se da biste vidjeli svoje obavijesti.", "echo-notification-markasread": "Označi kao pročitano", "echo-notification-markasunread": "Označi kao nepročitano", "echo-notification-markasread-tooltip": "Označi kao pročitano", "echo-notification-more-options-tooltip": "Više mogućnosti", + "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|Utišaj}} obavijesti o povezivanju sa stranicom \"$1\"", + "notification-dynamic-actions-mute-page-linked-confirmation": "Obavijesti o \"povezivanju stranice\" onemogućene su za stranicu \"$1\"", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|Možete}} upravljati utišanim stranicama bilo kada u [$1 postavkama].", + "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2|Isključi utišavanje}} obavijesti o povezivanju sa stranicom \"$1\"", + "notification-dynamic-actions-unmute-page-linked-confirmation": "Obavijesti o \"povezivanju stranice\" omogućene su za stranicu \"$1\"", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|Možete}} upravljati utišanim stranicama bilo kada u [$1 postavkama].", "notification-dynamic-actions-unwatch": "{{GENDER:$3|Prestani}} pratiti nove aktivnosti na \"$1\"", "notification-dynamic-actions-unwatch-confirmation": "Više {{GENDER:$3|ne pratite}} stranicu \"$1\"", "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|Možete}} bilo kada pratiti [$2 ovu stranicu].", @@ -126,14 +136,14 @@ "notification-bundle-header-page-linked": "Stranica <strong>$3</strong> povezana je s/sa {{PLURAL:$5|1=jednom stranicom|$5 stranicom|$5 stranice|$5 stranica|100=preko 99 stranica}}.", "notification-header-article-reminder": "Stranica za koju {{GENDER:$2|ste}} tražili podsjetnik nalazi se na <strong>$3</strong>", "notification-link-text-what-links-here": "Sve poveznice na ovu stranicu", - "notification-header-mention-other": "$1 Vas je {{GENDER:$2|spomenuo|spomenula}} {{GENDER:$3|na}} <strong>$4</strong> u „<strong>$5</strong>”.", - "notification-header-mention-other-nosection": "$1 {{GENDER:$3|Vas}} je {{GENDER:$2|spomenuo|spomenula}} na <strong>$4</strong>.", - "notification-header-mention-user-talkpage-v2": "$1 {{GENDER:$3|Vas}} je {{GENDER:$2|spomenuo|spomenula}} na <strong>razgovornoj stranici {{GENDER:$5|suradnika|suradnice}} $4</strong> u odlomku »<strong>$6</strong>«.", + "notification-header-mention-other": "$1 {{GENDER:$3|Vas}} je {{GENDER:$2|spomenuo|spomenula}} na stranici <strong>$4</strong> u odlomku <strong>$5</strong>.", + "notification-header-mention-other-nosection": "$1 {{GENDER:$3|Vas}} je {{GENDER:$2|spomenuo|spomenula}} na stranici <strong>$4</strong>.", + "notification-header-mention-user-talkpage-v2": "$1 {{GENDER:$3|Vas}} je {{GENDER:$2|spomenuo|spomenula}} na <strong>razgovornoj stranici {{GENDER:$5|suradnika|suradnice}} $4</strong> u odlomku <strong>$6</strong>.", "notification-header-mention-user-talkpage-nosection": "$1 {{GENDER:$3|Vas}} je {{GENDER:$2|spomenuo|spomenula}} na <strong>razgovornoj stranici {{GENDER:$5|suradnika|suradnice}} $4</strong>.", - "notification-header-mention-agent-talkpage": "$1 {{GENDER:$3|Vas}} je {{GENDER:$2|spomenuo|spomenula}} na <strong>{{GENDER:$2|svojoj}} razgovornoj stranici</strong> u odlomku »<strong>$4</strong>«.", - "notification-header-mention-agent-talkpage-nosection": "$1 {{GENDER:$3|Vas}} je {{GENDER:$2|spomenuo|spomenula}} na <strong>{{GENDER:$2|njegovoj|njenoj}} stranici za razgovor</strong>.", - "notification-header-mention-article-talkpage": "$1 {{GENDER:$3|Vas}} je {{GENDER:$2|spomenuo|spomenula}} na razgovornoj stranici <strong>$4</strong> u temi \"<strong>$5</strong>\".", - "notification-header-mention-article-talkpage-nosection": "$1 {{GENDER:$3|Vas}} je {{GENDER:$2|spomenuo|spomenula}} na <strong>$4</strong> stranici za razgovor.", + "notification-header-mention-agent-talkpage": "$1 {{GENDER:$3|Vas}} je {{GENDER:$2|spomenuo|spomenula}} na <strong>{{GENDER:$2|svojoj}} razgovornoj stranici</strong> u odlomku <strong>$4</strong>.", + "notification-header-mention-agent-talkpage-nosection": "$1 {{GENDER:$3|Vas}} je {{GENDER:$2|spomenuo|spomenula}} na <strong>svojoj stranici za razgovor</strong>.", + "notification-header-mention-article-talkpage": "$1 {{GENDER:$3|Vas}} je {{GENDER:$2|spomenuo|spomenula}} na razgovornoj stranici <strong>$4</strong> u temi <strong>$5</strong>.", + "notification-header-mention-article-talkpage-nosection": "$1 {{GENDER:$3|Vas}} je {{GENDER:$2|spomenuo|spomenula}} na stranici za razgovor članka <strong>$4</strong>.", "notification-header-mention-failure-user-unknown": "{{GENDER:$2|Vaše}} spominjanje suradnika <strong>$3</strong> nije bilo poslano, jer suradničko ime nije bilo moguće pronaći.", "notification-header-mention-failure-user-anonymous": "{{GENDER:$2|Vaše}} spominjanje suradnika <strong>$3</strong> nije poslano, jer je neprijavljeni suradnik anoniman.", "notification-header-mention-failure-too-many": "Pokušali {{GENDER:$2|ste}} spomenuti više od $3 {{PLURAL:$3|suradnik|suradnika}}. Spominjanja iznad tog ograničenja nisu poslana.", @@ -142,7 +152,7 @@ "notification-compact-header-mention-failure-user-anonymous": "<strong>Neprijavljeni suradnici ne mogu biti spomenuti:</strong> $1", "notification-header-mention-success": "<strong>$3</strong> je {{GENDER:$3|obaviješten|obaviještena}} da {{GENDER:$2|ste}} {{GENDER:$3|ga|je}} spomenuli.", "notification-header-mention-success-bundle": "{{PLURAL:$3|Spominjanje koje|$3 spominjanja koja}} ste Vi {{GENDER:$2|poslali|poslala}}, a putem razgovorne stranice <strong>$4</strong>, {{PLURAL:$3|bilo je isporučeno|bila su isporučena}}.", - "notification-compact-header-mention-success": "<strong>{{GENDER:$2|Spomenuo si suradnika|Spomenula si suradnika|Spomenuli ste suradnika}}:</strong> $3", + "notification-compact-header-mention-success": "<strong>{{GENDER:$2|Spomenuli ste}}:</strong> $3", "notification-header-mention-status-bundle": "{{PLURAL:$3|Obavijest|$3 obavijesti}} o spominjanju koja {{GENDER:$2|ste učinili}} na <strong>$4</strong> stranici za razgovor: {{PLURAL:$5|$5 nije poslano|$5 nisu poslana|$5 nije poslano}}, {{PLURAL:$6|$6 je poslano|$6 su poslana|$6 je poslano}}.", "notification-header-user-rights-add-only": "{{GENDER:$4|Vašu}} pripadnost suradničkim skupinama {{GENDER:$1|promijenio|promijenila}} je {{GENDER:$1|suradnik|suradnica}} $1. Sad ste {{GENDER:$4|pripadnikom|pripadnicom}} suradničke skupine: $2.", "notification-header-user-rights-remove-only": "{{GENDER:$4|Vaša}} suradnička prava su {{GENDER:$1|promijenjena}}. Niste više član sljedećih grupa: $2.", @@ -156,12 +166,13 @@ "notification-header-thank-you-100-edit": "Upravo {{GENDER:$2|ste}} načinili {{GENDER:$2|Vaše}} stoto uređivanje, zahvaljujemo {{GENDER:$2|Vam}} i očekujemo da ćete nastaviti tako i dalje!", "notification-header-thank-you-1000-edit": "{{GENDER:$2|Poštovani|Poštovana}}, upravo {{GENDER:$2|ste}} načinili {{GENDER:$2|Vaše}} tisućito uređivanje, zahvaljujemo {{GENDER:$2|Vam}} i molimo Vas da nastavite biti {{GENDER:$2|odličnim doprinositeljem|odličnom doprinositeljicom}}!", "notification-header-thank-you-10000-edit": "{{GENDER:$2|Poštovani|Poštovana}}, upravo {{GENDER:$2|ste}} načinili {{GENDER:$2|Vaše}} desettisućito uređivanje, neizmjerno {{GENDER:$2|Vam}} zahvaljujemo i molimo Vas da nastavite biti {{GENDER:$2|izvrsnim doprinositeljem|izvrsnom doprinositeljicom}}!", - "notification-header-thank-you-100000-edit": "{{GENDER:$2|Poštovani|Poštovana}}, upravo {{GENDER:$2|ste}} načinili {{GENDER:$2|Vaše}} stotisućito uređivanje, zahvaljujemo {{GENDER:$2|Vam}} na iznimnom doprinosu te Vas molimo da nastavite biti {{GENDER:$2|izvanrednim doprinositeljom|izvanrednom doprinositeljicom}}!", + "notification-header-thank-you-100000-edit": "{{GENDER:$2|Poštovani|Poštovana}}, upravo {{GENDER:$2|ste}} načinili {{GENDER:$2|Vaše}} stotisućito uređivanje, zahvaljujemo {{GENDER:$2|Vam}} na iznimnom doprinosu te Vas molimo da nastavite biti {{GENDER:$2|izvanrednim doprinositeljem|izvanrednom doprinositeljicom}}!", "notification-header-thank-you-1000000-edit": "{{GENDER:$2|Poštovani|Poštovana}}, upravo {{GENDER:$2|ste}} načinili {{GENDER:$2|Vaše}} milijunto uređivanje, zahvaljujemo {{GENDER:$2|Vam}} na tom nevjerojatno zadivljujućem doprinosu!", + "notification-header-thank-you-10000000-edit": "{{GENDER:$2|Poštovani|Poštovana}}, upravo {{GENDER:$2|ste}} načinili deset milijuntno uređivanje; hvala {{GENDER:$2|Vam}} na izvrsnoj predanosti!", "notification-link-thank-you-edit": "{{GENDER:$1|Vaše}} uređivanje", "notification-link-text-view-edit": "Prikaži promjene", "notification-link-article-reminder": "Vidi stranicu", - "notification-header-reverted": "{{PLURAL:$4|Vaše uređivanje na stranici $3|Vaša uređivanja na stranici $3}} {{GENDER:$2|uklonio je suradnik|uklonila je suradnica}} $2.", + "notification-header-reverted": "$2 je {{GENDER:$2|uklonio|uklonila}} {{PLURAL:$4|Vaše uređivanje na stranici <strong>$3</strong>|Vaša uređivanja na stranici <strong>$3</strong>}}.", "notification-header-emailuser": "$1 Vam je {{GENDER:$2|poslao|poslala}} e-poštu.", "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$3|Vam}} je {{GENDER:$2|ostavio|ostavila}} poruku na projektu {{SITENAME}}", "notification-page-linked-email-subject": "Na projektu {{SITENAME}} dodana je poveznica na stranicu koju {{GENDER:$3|ste}} stvorili", diff --git a/Echo/i18n/hrx.json b/Echo/i18n/hrx.json new file mode 100644 index 00000000..d679f16a --- /dev/null +++ b/Echo/i18n/hrx.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Iohanen" + ] + }, + "tooltip-pt-notifications-alert": "{{GENDER:|Dein}} Alertas" +} diff --git a/Echo/i18n/ht.json b/Echo/i18n/ht.json index 8f104252..78bf2dc3 100644 --- a/Echo/i18n/ht.json +++ b/Echo/i18n/ht.json @@ -1,7 +1,8 @@ { "@metadata": { "authors": [ - "Tisave" + "Amire80" ] - } + }, + "prefs-echo": "Notifikasyon" } diff --git a/Echo/i18n/hu.json b/Echo/i18n/hu.json index 6ef457c5..c7d07525 100644 --- a/Echo/i18n/hu.json +++ b/Echo/i18n/hu.json @@ -21,14 +21,18 @@ "prefs-echosubscriptions": "Értesítést kérek ezekről az eseményekről", "prefs-echocrosswiki": "Wikiközi értesítések", "prefs-blocknotificationslist": "Lenémított felhasználók", + "prefs-mutedpageslist": "Hivatkozásértesítéseknél elnémított lapok", "prefs-echopollupdates": "Élő értesítések", + "echo-mobile-notifications-filter-title": "Értesítések szűrése", "echo-pref-show-poll-updates": "Új értesítések azonnali megjelenítése", + "echo-pref-show-poll-updates-help": "Az olvasatlan értesítések számának megjelenítése a címsorban, valamint egy rövid részlet megjelenítése minden értesítésből, amint megérkezik.", "echo-pref-send-me": "Gyakoriság:", "echo-pref-send-to": "Erre a címre:", "echo-pref-email-format": "A levél formátuma:", "echo-pref-web": "Web", "echo-pref-email": "E-mail", - "echo-pref-email-frequency-never": "Egyáltalán ne küldjön e-mail értesítést", + "echo-pref-push": "Mobilalkalmazások", + "echo-pref-email-frequency-never": "Egyáltalán ne küldjön e-mailes értesítést", "echo-pref-email-frequency-immediately": "Küldjön külön értesítést minden eseményről", "echo-pref-email-frequency-daily": "Küldjön napi összefoglalót az értesítésekről", "echo-pref-email-frequency-weekly": "Küldjön heti összefoglalót az értesítésekről", @@ -36,11 +40,12 @@ "echo-pref-email-format-plain-text": "Sima szöveg", "echo-pref-cross-wiki-notifications": "Értesítések megjelenítése más wikikről", "echo-pref-notifications-blacklist": "Értesítések megjelenítésének letiltása ezektől a felhasználóktól. ([[mw:Help:Notifications/hu#mute|további információk]])", + "echo-pref-notifications-page-linked-title-muted-list": "„Hivatkozott lap” értesítések letiltása ezekről a lapokról. ([[mw:Help:Notifications/hu#mute|további információk]])", "echo-pref-dont-email-read-notifications": "Az összefoglaló e-mailek ne tartalmazzák a már olvasott értesítéseket", "echo-learn-more": "Tudj meg többet", "echo-log": "Nyilvános napló", - "echo-new-messages": "Új üzeneted van", - "echo-category-title-edit-user-talk": "vitalapi {{PLURAL:$1|üzenet|üzenetek}}", + "echo-new-messages": "Új vitalapi üzeneted van", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Üzenet|Üzenetek}} a saját vitalapomon", "echo-category-title-article-linked": "hivatkozott {{PLURAL:$1|lap|lapok}}", "echo-category-title-reverted": "visszaállított {{PLURAL:$1|szerkesztés|szerkesztések}}", "echo-category-title-mention": "{{PLURAL:$1|említés|említések}}", @@ -49,13 +54,14 @@ "echo-category-title-other": "{{PLURAL:$1|Más}}", "echo-category-title-system": "{{PLURAL:$1|rendszerüzenet|rendszerüzenetek}}", "echo-category-title-system-noemail": "{{PLURAL:$1|Rendszerüzenet}}", + "echo-category-title-system-emailonly": "{{PLURAL:$1|Rendszer}}", "echo-category-title-user-rights": "{{PLURAL:$1|Felhasználói jogok változása|Felhasználói jogok változásai}}", "echo-category-title-emailuser": "{{PLURAL:$1|E-mail másik szerkesztőtől|E-mailek más szerkesztőktől}}", "echo-category-title-article-reminder": "{{PLURAL:$1|lapértesítés|lapértesítések}}", "echo-category-title-thank-you-edit": "Szerkesztési {{PLURAL:$1|mérföldkő|mérföldkövek}}", "echo-category-title-watchlist": "Szerkesztés egy általam figyelt lapon", "echo-category-title-minor-watchlist": "Apró szerkesztés egy általam figyelt lapon", - "echo-pref-tooltip-edit-user-talk": "Értesítést kérek, ha valaki üzen vagy válaszol a vitalapomon.", + "echo-pref-tooltip-edit-user-talk": "Értesítést kérek, ha valaki üzen vagy válaszol az én szerkesztővita-lapomon.", "echo-pref-tooltip-article-linked": "Értesítést kérek, ha valaki hivatkozik egy általam írt szócikkre egy másik cikkben.", "echo-pref-tooltip-reverted": "Értesítést kérek, ha valaki visszaállítja egy szerkesztésemet a visszavonás vagy a visszaállítás eszközzel.", "echo-pref-tooltip-mention": "Értesítést kérek, ha valaki hivatkozik a felhasználói lapomra.", @@ -80,10 +86,14 @@ "echo-displaynotificationsconfiguration-enabled-default-header": "Alapértelmezetten bekapcsolva", "echo-displaynotificationsconfiguration-enabled-default-existing-users-legend": "Létező felhasználóknak", "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "Új felhasználóknak", + "echo-displaynotificationsconfiguration-mandatory-notification-methods-header": "Kötelező értesítési módok", + "echo-displaynotificationsconfiguration-mandatory-notification-methods-by-category-legend": "Melyik értesítési módok kötelezők az egyes kategóriákban", "echo-specialpage": "Értesítések", "echo-specialpage-section-markread": "Csoport megjelölése olvasottként", "echo-specialpage-markasread": "Értesítés: Megjelölés olvasottként", "echo-specialpage-markasread-invalid-id": "Érvénytelen eseményazonosító", + "echo-specialpage-pagefilterwidget-aria-label": "Wiki és lapcím szerinti szűrés", + "echo-specialpage-special-help-menu-widget-aria-label": "További lehetőségek és az értesítések beállításai.", "echo-specialpage-pagination-numnotifications": "$1 értesítés", "echo-specialpage-pagefilters-title": "Friss tevékenység", "echo-specialpage-pagefilters-subtitle": "Lapok olvasatlan értesítésekkel", @@ -99,6 +109,12 @@ "echo-notification-markasunread": "Megjelölés olvasatlanként", "echo-notification-markasread-tooltip": "Megjelölés olvasottként", "echo-notification-more-options-tooltip": "További lehetőségek", + "notification-dynamic-actions-mute-page-linked": "A(z) „$1” lapra készített hivatkozások értesítéseinek {{GENDER:$2|némítása}}", + "notification-dynamic-actions-mute-page-linked-confirmation": "A(z) „$1” lapra mutató hivatkozásokról szóló értesítések mostantól le vannak tiltva", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "A [$1 beállításaidban] bármikor {{GENDER:$2|kezelheted}} a lenémított lapokat.", + "notification-dynamic-actions-unmute-page-linked": "A(z) „$1” lapra készített hivatkozások értesítéseinek némításának {{GENDER:$2|feloldása}}", + "notification-dynamic-actions-unmute-page-linked-confirmation": "A(z) „$1” lapra mutató hivatkozásokról szóló értesítések mostantól engedélyezve vannak", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "A [$1 beállításaidban] bármikor {{GENDER:$2|kezelheted}} a lenémított lapokat.", "notification-dynamic-actions-unwatch": "Új tevékenységek figyelésének {{GENDER:$3|leállítása}} a(z) „$1” lapon", "notification-dynamic-actions-unwatch-confirmation": "Már nem {{GENDER:$3|figyeled}} a(z) „$1” lapot", "notification-dynamic-actions-unwatch-confirmation-description": "Bármikor újra {{GENDER:$3|figyelheted}} [$2 ezt a lapot].", @@ -147,6 +163,16 @@ "notification-header-user-rights-expiry-change": "Ideiglenes {{GENDER:$4|tagságod}} határideje a következő {{PLURAL:$3|csoportban|csoportokban}} {{GENDER:$1|megváltozott}}: $2.", "notification-header-welcome": "{{GENDER:$2|Üdvözlünk}} a(z) {{SITENAME}} wikin, $1! Örülünk, hogy itt {{GENDER:$2|vagy}}.", "notification-header-mention-summary": "$1 {{GENDER:$2|megemlített}} {{GENDER:$3|téged}} egy szerkesztési összefoglalóban a(z) <strong>$4</strong> lapon.", + "notification-header-watchlist-changed": "$1 {{PLURAL:$5||$5 alkalommal}} {{GENDER:$2|megváltoztatta}} a {{GENDER:$4|figyelőlistádon}} szereplő <strong>$3</strong> lapot.", + "notification-header-watchlist-created": "$1 {{GENDER:$2|létrehozta}} {{PLURAL:$5||$5 alkalommal}} a {{GENDER:$4|figyelőlistádon}} szereplő <strong>$3</strong> lapot.", + "notification-header-watchlist-deleted": "$1 {{GENDER:$2|törölte}} {{PLURAL:$5||$5 alkalommal}} a {{GENDER:$4|figyelőlistádon}} szereplő <strong>$3</strong> lapot.", + "notification-header-watchlist-moved": "$1 {{GENDER:$2|átnevezte}} {{PLURAL:$5||$5 alkalommal}} a {{GENDER:$4|figyelőlistádon}} szereplő <strong>$3</strong> lapot.", + "notification-header-watchlist-restored": "$1 {{GENDER:$2|helyreállította}} {{PLURAL:$5||$5 alkalommal}} a {{GENDER:$4|figyelőlistádon}} szereplő <strong>$3</strong> lapot.", + "notification-header-watchlist-multiuser-changed": "A {{GENDER:$2|figyelőlistádon}} szereplő <strong>$1</strong> lapot $3 alkalommal szerkesztették.", + "notification-header-watchlist-multiuser-created": "A {{GENDER:$2|figyelőlistádon}} szereplő <strong>$1</strong> lapot létrehozták $3 alkalommal.", + "notification-header-watchlist-multiuser-deleted": "A {{GENDER:$2|figyelőlistádon}} szereplő <strong>$1</strong> lapot törölték $3 alkalommal.", + "notification-header-watchlist-multiuser-moved": "A {{GENDER:$2|figyelőlistádon}} szereplő <strong>$1</strong> lapot átnevezték $3 alkalommal.", + "notification-header-watchlist-multiuser-restored": "A {{GENDER:$2|figyelőlistádon}} szereplő <strong>$1</strong> lapot törölték $3 alkalommal.", "notification-welcome-linktext": "Üdvözlet", "notification-header-thank-you-1-edit": "{{GENDER:$2|Elkészítetted}} az első szerkesztésedet; köszönjük és üdvözlünk!", "notification-header-thank-you-10-edit": "{{GENDER:$2|Elkészítetted}} a tizedik szerkesztésedet; köszönjük és csak így tovább!", @@ -155,6 +181,7 @@ "notification-header-thank-you-10000-edit": "{{GENDER:$2|Elkészítetted}} a tízezredik szerkesztésedet; nagyon-nagyon köszönjük!", "notification-header-thank-you-100000-edit": "{{GENDER:$2|Elkészítetted}} a százezredik szerkesztésedet; köszönjük ezt az elképesztő hozzájárulást!", "notification-header-thank-you-1000000-edit": "{{GENDER:$2|Elkészítetted}} a milliomodik szerkesztésedet; köszönjük a megdöbbentő hozzájárulásodat!", + "notification-header-thank-you-10000000-edit": "{{GENDER:$2|Elkészítetted}} a tízmilliomodik szerkesztésedet; köszönjük a zseniális közreműködésedet!", "notification-link-thank-you-edit": "A {{GENDER:$1|szerkesztésed}}", "notification-link-text-view-edit": "Szerkesztés mutatása", "notification-link-article-reminder": "Oldal megtekintése", @@ -176,7 +203,7 @@ "notification-inbox-filter-read": "Olvasott", "notification-inbox-filter-unread": "Olvasatlan", "notification-inbox-filter-all": "Mind", - "echo-specialmute-label-mute-notifications": "Értesítések némítása ettől a felhasználótól", + "echo-specialmute-label-mute-notifications": "Értesítések némítása ettől a {{GENDER:$1|felhasználótól}}", "echo-email-plain-footer": "A {{GENDER:$1|beállításaidnál}} módosíthatod, mikor küldjünk e-mailt:", "echo-email-html-footer-preference-link-text": "{{GENDER:$1|beállításaidnál}}", "echo-email-html-footer-with-link": "A $1 {{GENDER:$2|módosíthatod}}, mikor küldjünk e-mailt.", @@ -200,5 +227,10 @@ "echo-email-batch-link-text-view-all-notifications": "Nézd meg az összes értesítést", "notification-header-foreign-alert": "További figyelmeztetések {{PLURAL:$5|egy|$5}} másik wikiről", "notification-header-foreign-notice": "További értesítések {{PLURAL:$5|egy|$5}} másik wikiről", - "notification-header-foreign-all": "További értesítések {{PLURAL:$5|egy|$5}} másik wikiről" + "notification-header-foreign-all": "További értesítések {{PLURAL:$5|egy|$5}} másik wikiről", + "right-manage-all-push-subscriptions": "összes leküldéses feliratkozás kezelése", + "action-manage-all-push-subscriptions": "összes leküldéses feliratkozás kezelése", + "group-push-subscription-manager": "leküldésesfeliratkozás-kezelők", + "group-push-subscription-manager-member": "{{GENDER:$1|leküldésesfeliratkozás-kezelő}}", + "grouppage-push-subscription-manager": "{{ns:project}}:Leküldésesfeliratkozás-kezelők" } diff --git a/Echo/i18n/hy.json b/Echo/i18n/hy.json index d36ce804..1f5490db 100644 --- a/Echo/i18n/hy.json +++ b/Echo/i18n/hy.json @@ -32,7 +32,7 @@ "echo-pref-notifications-blacklist": "Հետևյալ մասնակիցներից ծանուցումներ ցույց չտալ․\n([[mw:Special:MyLanguage/Help:Notifications#mute|իմանալ ավելին]])", "echo-learn-more": "Իմանալ ավելին", "echo-log": "Հանրամատչելի գրանցամատյան", - "echo-new-messages": "Դուք նոր ուղերձներ ունեք", + "echo-new-messages": "Դուք նոր ուղերձներ ունեք քննարկման էջում", "echo-category-title-edit-user-talk": "{{PLURAL:$1|Ուղերձ|ուղերձներ}} քննարկման էջում", "echo-category-title-article-linked": "Էջի {{PLURAL:$1|հղում|հղումներ}}", "echo-category-title-reverted": "{{PLURAL:$1|1=Խմբագրման|Խմբագրումների}} հետ շրջում", @@ -128,7 +128,7 @@ "notification-link-text-view-edit": "Դիտել խմբագրումը", "notification-link-article-reminder": "Դիտել էջը", "notification-header-reverted": "Քո {{PLURAL:$4|խմբագրումը <strong>$3</strong> էջում|խմբագրումները <strong>$3</strong> էջում}} {{PLURAL:$2|հետ է շրջվել|հետ են շրջվել}}:", - "notification-header-emailuser": "$1-ը քեզ {{GENDER:$2|ուղարկել է}} էլ. փոստ:", + "notification-header-emailuser": "$1-ը քեզ էլփոստով նամակ {{GENDER:$2|է ուղարկել}}:", "notification-edit-talk-page-email-subject2": "$1-ը հաղորդագրություն է {{GENDER:$2|թողել}} {{SITENAME}}-ում:", "notification-page-linked-email-subject": "Ձեր ստեղծած էջը հղվում է դեպի {{SITENAME}} կայքը", "notification-mention-email-subject": "$1 մասնակիցը հիշատակել է {{GENDER:$3|Ձեզ}} {{SITENAME}} էջում", diff --git a/Echo/i18n/hyw.json b/Echo/i18n/hyw.json index eee6abbb..8219e034 100644 --- a/Echo/i18n/hyw.json +++ b/Echo/i18n/hyw.json @@ -75,7 +75,6 @@ "notification-link-thank-you-edit": "{{GENDER:$1|Ձեր}} խմբագրումը", "notification-link-text-view-edit": "Խմբագրումը կարդալ", "notification-link-article-reminder": "Էջը ցոյց տալ", - "notification-body-reverted": "$1", "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1 երկվյրկ․}}", "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1 վյրկ․}}", "notification-timestamp-ago-hours": "{{PLURAL:$1|$1 ժամ}}", diff --git a/Echo/i18n/ia.json b/Echo/i18n/ia.json index c3b2ec48..f24a9ab3 100644 --- a/Echo/i18n/ia.json +++ b/Echo/i18n/ia.json @@ -7,10 +7,12 @@ }, "echo-desc": "Systema pro notificar usatores super eventos e messages", "prefs-echo": "Notificationes", + "prefs-description-echo": "Selige le notificationes que tu vole reciper e como reciper los.", "prefs-emailsettings": "Optiones de e-mail", "prefs-echosubscriptions": "Notificar me de iste eventos", "prefs-echocrosswiki": "Notificationes inter wikis", "prefs-blocknotificationslist": "Usatores silentiate", + "prefs-mutedpageslist": "Paginas silentiate pro notificationes de ligamines al pagina", "prefs-echopollupdates": "Notificationes in directo", "echo-mobile-notifications-filter-title": "Filtrar notificationes", "echo-pref-show-poll-updates": "Monstrar nove notificationes al momento que illos arriva", @@ -20,6 +22,7 @@ "echo-pref-email-format": "Formato de e-mail:", "echo-pref-web": "Web", "echo-pref-email": "E-mail", + "echo-pref-push": "Apps", "echo-pref-email-frequency-never": "Non inviar me notificationes in e-mail", "echo-pref-email-frequency-immediately": "Notificationes individual al momento de cata occurrentia", "echo-pref-email-frequency-daily": "Un summario quotidian de notificationes", @@ -28,10 +31,12 @@ "echo-pref-email-format-plain-text": "Texto simple", "echo-pref-cross-wiki-notifications": "Monstrar notificationes de altere wikis", "echo-pref-notifications-blacklist": "Non monstrar notificationes ab iste usatores. ([[mw:Special:MyLanguage/Help:Notifications#mute|leger plus]])", + "echo-pref-notifications-page-linked-title-muted-list": "Non monstrar notificationes \"Ligamine al pagina\" pro iste paginas. ([[mw:Special:MyLanguage/Help:Notifications#mute|leger plus]])", + "echo-pref-dont-email-read-notifications": "Non includer notificationes jam legite in e-mails de summario", "echo-learn-more": "Leger plus", "echo-log": "Registro public", - "echo-new-messages": "Tu ha nove messages", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Message|Messages}} del pagina de discussion", + "echo-new-messages": "Tu ha un nove message de discussion", + "echo-category-title-edit-user-talk": "Modification{{PLURAL:$1||es}} de mi proprie pagina de discussion", "echo-category-title-article-linked": "{{PLURAL:$1|Ligamine|Ligamines}} a un pagina", "echo-category-title-reverted": "{{PLURAL:$1|Modification|Modificationes}} revertite", "echo-category-title-mention": "{{PLURAL:$1|Mention|Mentiones}}", @@ -45,16 +50,20 @@ "echo-category-title-emailuser": "Message{{PLURAL:$1||s}} de e-mail ab {{PLURAL:$1|un altere usator|altere usatores}}", "echo-category-title-article-reminder": "Rememoration{{PLURAL:$1||es}} de pagina", "echo-category-title-thank-you-edit": "Petra{{PLURAL:$1||s}} milliari de modification", - "echo-pref-tooltip-edit-user-talk": "Notificar me quando alcuno scribe un message o responsa in mi pagina de discussion", + "echo-category-title-watchlist": "Modification de un pagina sub observation", + "echo-category-title-minor-watchlist": "Modification minor de un pagina sub observation", + "echo-pref-tooltip-edit-user-talk": "Notificar me quando alcuno modifica mi proprie pagina de discussion.", "echo-pref-tooltip-article-linked": "Notificar me quando alcuno insere in un altere pagina un ligamine a un pagina que io ha create.", "echo-pref-tooltip-reverted": "Notificar me quando alcuno reverte, per medio de \"disfacer\" o \"revocar\", un modification que io ha facite.", "echo-pref-tooltip-mention": "Notificar me quando alcuno insere un ligamine a mi pagina de usator.", "echo-pref-tooltip-mention-failure": "Notificar me quando io non ha potite inviar un mention a un persona.", "echo-pref-tooltip-mention-success": "Notificar me quando io invia un mention a un persona.", "echo-pref-tooltip-user-rights": "Notificar me quando alcuno modifica mi derectos de usator.", - "echo-pref-tooltip-emailuser": "Notificar me quando alcuno invia me un message de e-mail.", + "echo-pref-tooltip-emailuser": "Notificar me quando alcuno me invia un message de e-mail.", "echo-pref-tooltip-article-reminder": "Notificar me sur iste pagina quando io lo demanda.", "echo-pref-tooltip-thank-you-edit": "Notificar me quando io attinge mi 1me, 10me, 100me... modification.", + "echo-pref-tooltip-watchlist": "Notificar me quando alcuno apporta un modification (non minor) a un pagina sur mi observatorio.", + "echo-pref-tooltip-minor-watchlist": "Notificar me quando alcuno apporta un modification minor a un pagina sur mi observatorio.", "notifications": "Notificationes", "tooltip-pt-notifications-alert": "Tu alertas", "tooltip-pt-notifications-notice": "{{GENDER:|Tu}} avisos", @@ -75,6 +84,7 @@ "echo-specialpage-markasread": "Notification: Marcar como legite", "echo-specialpage-markasread-invalid-id": "ID de evento non valide", "echo-specialpage-pagefilterwidget-aria-label": "Filtrar per wiki e titulo de pagina", + "echo-specialpage-special-help-menu-widget-aria-label": "Optiones additional e preferentias de notification.", "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|notification|notificationes}}", "echo-specialpage-pagefilters-title": "Activitate recente", "echo-specialpage-pagefilters-subtitle": "Paginas con notificationes non legite", @@ -90,6 +100,12 @@ "echo-notification-markasunread": "Marcar como non legite", "echo-notification-markasread-tooltip": "Marcar como legite", "echo-notification-more-options-tooltip": "Plus optiones", + "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|Silentiar}} notificationes de ligamine sur \"$1\"", + "notification-dynamic-actions-mute-page-linked-confirmation": "Le notificationes \"Ligamine al pagina\" es ora disactivate pro le pagina \"$1\".", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|Tu}} pote gerer tu paginas silentiate in [$1 tu preferentias] a omne momento.", + "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2|Non plus silentiar}} notificationes de ligamine sur \"$1\"", + "notification-dynamic-actions-unmute-page-linked-confirmation": "Le notificationes \"Ligamine al pagina\" es ora activate pro le pagina \"$1\".", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|Tu}} pote gerer tu paginas silentiate in [$1 tu preferentias] a omne momento.", "notification-dynamic-actions-unwatch": "{{GENDER:$3|Cessar}} de observar le nove activitate sur \"$1\"", "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3|Tu}} non plus observa le pagina \"$1\"", "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|Tu}} pote observar [$2 iste pagina] a qualcunque momento.", @@ -106,7 +122,7 @@ "notification-link-text-view-mention-failure": "Vider {{PLURAL:$1|mention|mentiones}}", "notification-link-text-view-changes": "{{GENDER:$1|Vider}} modificationes", "notification-link-text-view-page": "Vider pagina", - "notification-header-edit-user-talk": "$1 {{GENDER:$2|ha lassate}} un message osurn <strong>{{GENDER:$3|tu}} pagina de discussion</strong>.", + "notification-header-edit-user-talk": "$1 {{GENDER:$2|ha lassate}} un message sur <strong>{{GENDER:$3|tu}} pagina de discussion</strong>.", "notification-header-edit-user-talk-with-section": "$1 {{GENDER:$2|ha lassate}} un message sur <strong>{{GENDER:$3|tu}} pagina de discussion</strong> in le section \"<strong>$4</strong>\".", "notification-compact-header-edit-user-talk": "$1 {{GENDER:$3|te}} {{GENDER:$2|ha lassate}} un message.", "notification-compact-header-edit-user-talk-with-section": "$1 {{GENDER:$3|te}} {{GENDER:$2|ha lassate}} un message in le section \"<strong>$4</strong>\".", @@ -139,6 +155,17 @@ "notification-header-user-rights-expiry-change": "Le expiration de {{GENDER:$4|tu}} appertinentia al sequente {{PLURAL:$3|gruppo|gruppos}} ha {{GENDER:$1|cambiate}}: $2.", "notification-header-welcome": "{{GENDER:$2|Benvenite}} a {{SITENAME}}, $1! Nos es felice que {{GENDER:$2|tu es}} hic.", "notification-header-mention-summary": "$1 {{GENDER:$3|te}} {{GENDER:$2|ha mentionate}} in un summario de modification sur <strong>$4</strong>.", + "notification-header-watchlist-changed": "$1 {{GENDER:$2|ha cambiate}} <strong>$3</strong>, un pagina sur {{GENDER:$4|tu}} observatorio{{PLURAL:$5||, $5 vices}}.", + "notification-header-watchlist-created": "$1 {{GENDER:$2|ha create}} <strong>$3</strong>, un pagina sur {{GENDER:$4|tu}} observatorio{{PLURAL:$5||, $5 vices}}.", + "notification-header-watchlist-deleted": "$1 {{GENDER:$2|ha delite}} <strong>$3</strong>, un pagina sur {{GENDER:$4|tu}} observatorio{{PLURAL:$5||, $5 vices}}.", + "notification-header-watchlist-moved": "$1 {{GENDER:$2|ha renominate}} <strong>$3</strong>, un pagina sur {{GENDER:$4|tu}} observatorio{{PLURAL:$5||, $5 vices}}.", + "notification-header-watchlist-restored": "$1 {{GENDER:$2|ha restaurate}} <strong>$3</strong>, un pagina sur {{GENDER:$4|tu}} observatorio{{PLURAL:$5||, $5 vices}}.", + "notification-header-watchlist-multiuser-changed": "<strong>$1</strong>, un pagina sur {{GENDER:$2|tu}} observatorio, ha essite cambiate $3 vice{{PLURAL:$3||s}}.", + "notification-header-watchlist-multiuser-created": "<strong>$1</strong>, un pagina sur {{GENDER:$2|tu}} observatorio, ha essite create $3 vice{{PLURAL:$3||s}}.", + "notification-header-watchlist-multiuser-deleted": "<strong>$1</strong>, un pagina sur {{GENDER:$2|tu}} observatorio, ha essite delite $3 vice{{PLURAL:$3||s}}.", + "notification-header-watchlist-multiuser-moved": "<strong>$1</strong>, un pagina sur {{GENDER:$2|tu}} observatorio, ha essite renominate $3 vice{{PLURAL:$3||s}}.", + "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>, un pagina sur {{GENDER:$2|tu}} observatorio, ha essite restaurate $3 vice{{PLURAL:$3||s}}.", + "notification-body-watchlist-once": "Il non habera altere notification de e-mail in caso de ulterior activitate, a minus que tu {{GENDER:$1|visita}} iste pagina con session aperte.", "notification-welcome-linktext": "Benvenite", "notification-header-thank-you-1-edit": "{{GENDER:$2|Tu}} ha justo ora facite tu prime modification; gratias, e benvenite!", "notification-header-thank-you-10-edit": "{{GENDER:$2|Tu}} ha justo ora facite tu decime modification; gratias, e per favor continua!", @@ -147,6 +174,7 @@ "notification-header-thank-you-10000-edit": "{{GENDER:$2|Tu}} ha justo ora facite tu dece-millesime modification; multissime gratias!", "notification-header-thank-you-100000-edit": "{{GENDER:$2|Tu}} ha justo ora facite tu cento-millesime modification; gratias a te pro un contribution incredibile!", "notification-header-thank-you-1000000-edit": "{{GENDER:$2|Tu}} ha justo ora facite tu millionesime modification; gratias pro un contribution phenomenal!", + "notification-header-thank-you-10000000-edit": "{{GENDER:$2|Tu}} ha justo ora facite tu dece-millionesime modification; gratias pro tu dedication brillante!", "notification-link-thank-you-edit": "{{GENDER:$1|Tu}} modification", "notification-link-text-view-edit": "Vider modification", "notification-link-article-reminder": "Vider pagina", @@ -168,7 +196,7 @@ "notification-inbox-filter-read": "Legite", "notification-inbox-filter-unread": "Non legite", "notification-inbox-filter-all": "Totes", - "echo-specialmute-label-mute-notifications": "Silentiar le notificationes de iste usator", + "echo-specialmute-label-mute-notifications": "Silentiar le notificationes de iste {{GENDER:$1|usator}}", "echo-email-plain-footer": "Pro eliger qual messages nos {{GENDER:$1|te}} invia, revide {{GENDER:$1|tu}} preferentias:", "echo-email-html-footer-preference-link-text": "revide {{GENDER:$1|tu}} preferentias", "echo-email-html-footer-with-link": "Pro eliger qual messages nos {{GENDER:$2|te}} invia, $1.", @@ -192,5 +220,10 @@ "echo-email-batch-link-text-view-all-notifications": "Vider tote le notificationes", "notification-header-foreign-alert": "Plus alertas ab {{PLURAL:$5|un altere wiki|$5 altere wikis}}", "notification-header-foreign-notice": "Plus avisos ab {{PLURAL:$5|un altere wiki|$5 altere wikis}}", - "notification-header-foreign-all": "Plus notificationes ab {{PLURAL:$5|un altere wiki|$5 altere wikis}}" + "notification-header-foreign-all": "Plus notificationes ab {{PLURAL:$5|un altere wiki|$5 altere wikis}}", + "right-manage-all-push-subscriptions": "Gerer tote le subscriptiones push", + "action-manage-all-push-subscriptions": "gerer tote le subscriptiones push", + "group-push-subscription-manager": "Gestores de subscriptiones push", + "group-push-subscription-manager-member": "{{GENDER:$1|gestor de subscriptiones push}}", + "grouppage-push-subscription-manager": "{{ns:project}}:Gestores de subscriptiones push" } diff --git a/Echo/i18n/id.json b/Echo/i18n/id.json index 4f91fc28..397293d4 100644 --- a/Echo/i18n/id.json +++ b/Echo/i18n/id.json @@ -3,6 +3,8 @@ "authors": [ "Amire80", "Bennylin", + "Daud I.F. Argana", + "Ezagren", "Farras", "Gombang", "Iwan Novirion", @@ -10,6 +12,7 @@ "Mbrt", "Rachmat.Wahidi", "Rachmat04", + "Veracious", "William Surya Permana", "WongKentir", "පසිඳු කාවින්ද" @@ -18,27 +21,34 @@ "echo-desc": "Sistem pemberitahuan ke pengguna tentang pesan dan peristiwa", "prefs-echo": "Pemberitahuan", "prefs-emailsettings": "Opsi surel", - "prefs-echosubscriptions": "Beritahu saya mengenai peristiwa berikut", - "prefs-echocrosswiki": "Pemberitahuan antar-wiki", - "prefs-blocknotificationslist": "Pengguna yang dibisukan.", + "prefs-echosubscriptions": "Beri tahu saya mengenai peristiwa berikut", + "prefs-echocrosswiki": "Pemberitahuan lintas-wiki", + "prefs-blocknotificationslist": "Pengguna yang dibisukan", + "prefs-mutedpageslist": "Halaman yang dibisukan untuk pemberitahuan pranala halaman", + "prefs-echopollupdates": "Pemberitahuan langsung", + "echo-mobile-notifications-filter-title": "Saring pemberitahuan", "echo-pref-show-poll-updates": "Tampilkan pemberitahuan baru begitu sampai", + "echo-pref-show-poll-updates-help": "Menampilkan jumlah pemberitahuan belum terbaca pada bilah judul, dan menampilkan cuplikan dari masing-masing pemberitahuan segera setelah diterima.", "echo-pref-send-me": "Kirimi saya:", "echo-pref-send-to": "Kirimkan ke:", "echo-pref-email-format": "Format surel:", "echo-pref-web": "Web", "echo-pref-email": "Surel", + "echo-pref-push": "Aplikasi", "echo-pref-email-frequency-never": "Jangan kirimi saya pemberitahuan surel apapun", "echo-pref-email-frequency-immediately": "Pemberitahuan tunggal setiap suatu peristiwa terjadi", - "echo-pref-email-frequency-daily": "Ringkasan harian dari beberapa pemberitahuan", + "echo-pref-email-frequency-daily": "Ringkasan pemberitahuan harian", "echo-pref-email-frequency-weekly": "Ringkasan mingguan dari beberapa pemberitahuan", "echo-pref-email-format-html": "HTML", "echo-pref-email-format-plain-text": "Teks polos", - "echo-pref-cross-wiki-notifications": "Perlihatkan pemberitahuan dari wiki lain", - "echo-pref-notifications-blacklist": "Jangan tampilkan pemberitahuan dari pengguna ini. \n([[mw:Special:MyLanguage/Help:Notifications#mute|pelajari lebih lanjut]])", + "echo-pref-cross-wiki-notifications": "Tampilkan pemberitahuan dari wiki lain", + "echo-pref-notifications-blacklist": "Jangan tampilkan pemberitahuan dari pengguna berikut. \n([[mw:Special:MyLanguage/Help:Notifications#mute|pelajari selengkapnya]])", + "echo-pref-notifications-page-linked-title-muted-list": "Jangan tampilkan pemberitahuan \"Pranala halaman\" dari halaman berikut. \n([[mw:Special:MyLanguage/Help:Notifications#mute|pelajari selengkapnya]])", + "echo-pref-dont-email-read-notifications": "Jangan sertakan pemberitahuan terbaca dalam surel ringkasan", "echo-learn-more": "Pelajari selengkapnya", "echo-log": "Catatan publik", - "echo-new-messages": "Anda memiliki pesan baru", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Pesan}} halaman pembicaraan", + "echo-new-messages": "Anda memiliki pesan baru di halaman Pembicaraan", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Suntingan}} di halaman pembicaraan saya", "echo-category-title-article-linked": "{{PLURAL:$1|Pranala}} halaman", "echo-category-title-reverted": "{{PLURAL:$1|Pengembalian}} suntingan", "echo-category-title-mention": "{{PLURAL:$1|Sebutan}}", @@ -47,27 +57,33 @@ "echo-category-title-other": "{{PLURAL:$1|Lainnya}}", "echo-category-title-system": "{{PLURAL:$1|Sistem}}", "echo-category-title-system-noemail": "{{PLURAL:$1|Sistem}}", + "echo-category-title-system-emailonly": "{{PLURAL:$1|Sistem}}", "echo-category-title-user-rights": "{{PLURAL:$1|Perubahan hak pengguna}}", - "echo-category-title-emailuser": "{{PLURAL:$1|Surel dari pengguna lain|Surel dari pengguna lain}}", - "echo-category-title-article-reminder": "Halaman {{PLURAL:$1|pengingat|pengingat}}", + "echo-category-title-emailuser": "{{PLURAL:$1|Surel dari pengguna lain|Surel dari para pengguna lain}}", + "echo-category-title-article-reminder": "Halaman {{PLURAL:$1|pengingat}}", "echo-category-title-thank-you-edit": "{{PLURAL:$1|sejarah}} suntingan", - "echo-pref-tooltip-edit-user-talk": "Beritahu saya saat seseorang mengirimkan pesan atau balasan pada halaman pembicaraan saya.", + "echo-category-title-watchlist": "Suntingan pada halaman pantauan", + "echo-category-title-minor-watchlist": "Suntingan kecil pada halaman pantauan", + "echo-pref-tooltip-edit-user-talk": "Beri tahu saya saat seseorang menyunting halaman pembicaraan saya.", "echo-pref-tooltip-article-linked": "Beritahu saya saat seseorang membuat pranala di halaman artikel ke sebuah halaman yang pernah saya rintis.", - "echo-pref-tooltip-reverted": "Beritahu saya saat seseorang membalikkan suntingan yang pernah saya buat, dengan menggunakan alat batalkan atau balikkan.", + "echo-pref-tooltip-reverted": "Beri tahu saya saat seseorang membalikkan suntingan yang pernah saya buat, dengan menggunakan alat batalkan atau balikkan.", "echo-pref-tooltip-mention": "Beritahu saya saat seseorang menautkan ke halaman pengguna saya.", "echo-pref-tooltip-mention-failure": "Beri tahu saya bila tidak dapat mengirim pesan ke pengguna lain.", "echo-pref-tooltip-mention-success": "Beri tahu saya ketika mengirimkan sebutan ke seseorang.", - "echo-pref-tooltip-user-rights": "Beritahu saya saat seseorang mengubah hak pengguna saya.", + "echo-pref-tooltip-user-rights": "Beri tahu saya saat seseorang mengubah hak pengguna saya.", "echo-pref-tooltip-emailuser": "Beri tahu saya bila seseorang mengirim saya surel.", "echo-pref-tooltip-article-reminder": "Beri tahu saya tentang halaman ini bila saya minta.", + "echo-pref-tooltip-thank-you-edit": "Beri tahu saya ketika saya mencapai suntingan ke-1, ke-10, ke-100...", + "echo-pref-tooltip-watchlist": "Beri tahu saya saat seseorang membuat sebuah suntingan (non-kecil) pada halaman dalam daftar pantauan saya.", + "echo-pref-tooltip-minor-watchlist": "Beri tahu saya saat seseorang membuat sebuah suntingan kecil pada halaman dalam daftar pantauan saya.", "notifications": "Pemberitahuan", - "tooltip-pt-notifications-alert": "Pemberitahuan {{GENDER:|Anda}}", - "tooltip-pt-notifications-notice": "Pemberitahuan {{GENDER:|Anda}}", + "tooltip-pt-notifications-alert": "Peringatan {{GENDER:|Anda}}", + "tooltip-pt-notifications-notice": "Perhatian {{GENDER:|Anda}}", "echo-displaynotificationsconfiguration": "Konfigurasi tampilan Pemberitahuan", "echo-displaynotificationsconfiguration-summary": "Ini adalah ikhtisar konfigurasi pemberitahuan pada wiki ini.", "echo-displaynotificationsconfiguration-notifications-by-category-header": "Pemberitahuan berdasarkan kategori", "echo-displaynotificationsconfiguration-sorting-by-section-header": "Menyortir jenis", - "echo-displaynotificationsconfiguration-sorting-by-section-legend": "Bagian manakah masing-masing jenis pemberitahuan diurutkan ke dalamnya", + "echo-displaynotificationsconfiguration-sorting-by-section-legend": "Bagian yang mengelompokkan masing-masing jenis pemberitahuan", "echo-displaynotificationsconfiguration-available-notification-methods-header": "Cara pemberitahuan yang diizinkan", "echo-displaynotificationsconfiguration-available-notification-methods-by-category-legend": "Metode pemberitahuan manakah yang didukung untuk masing-masing kategori", "echo-displaynotificationsconfiguration-enabled-default-header": "Diaktifkan secara baku", @@ -79,6 +95,8 @@ "echo-specialpage-section-markread": "Tandai grup telah dibaca", "echo-specialpage-markasread": "Pemberitahuan: Tandai sudah dibaca", "echo-specialpage-markasread-invalid-id": "ID event tidak sah", + "echo-specialpage-pagefilterwidget-aria-label": "Saring menurut wiki dan judul halaman", + "echo-specialpage-special-help-menu-widget-aria-label": "Pilihan tambahan dan preferensi Pemberitahuan.", "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|pemberitahuan|pemberitahuan}}", "echo-specialpage-pagefilters-title": "Aktivitas terkini", "echo-specialpage-pagefilters-subtitle": "Halaman dengan pemberitahuan yang belum dibaca", @@ -94,6 +112,12 @@ "echo-notification-markasunread": "Tandai belum dibaca", "echo-notification-markasread-tooltip": "Tandai sudah dibaca", "echo-notification-more-options-tooltip": "Opsi lainnya", + "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|Bisukan}} pemberitahuan pranala di \"$1\"", + "notification-dynamic-actions-mute-page-linked-confirmation": "Pemberitahuan \"pranala halaman\" kini dinonaktifkan untuk halaman \"$1\"", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|Anda}} dapat mengelola halaman yang dibisukan Anda dalam [$1 preferensi Anda] kapan pun.", + "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2|Suarakan}} pemberitahuan pranala di \"$1\"", + "notification-dynamic-actions-unmute-page-linked-confirmation": "Pemberitahuan \"pranala halaman\" kini diaktifkan untuk halaman \"$1\"", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|Anda}} dapat mengelola halaman yang dibisukan Anda dalam [$1 preferensi Anda] kapan pun.", "notification-dynamic-actions-unwatch": "{{GENDER:$3|Berhenti}} memantau aktivitas baru pada \"$1\"", "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3|Anda}} tidak lagi memantau halaman \"$1\"", "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|Anda}} dapat memantau [$2 halaman ini] kapan saja.", @@ -101,8 +125,8 @@ "notification-dynamic-actions-watch-confirmation": "{{GENDER:$3|Anda}} sekarang memantau halaman \"$1\"", "notification-dynamic-actions-watch-confirmation-description": "{{GENDER:$3|Anda}} dapat berhenti memantau [$2 halaman ini] kapan saja.", "notification-link-text-expand-all": "Kembangkan", - "notification-link-text-expand-alert-count": "Lihat {{PLURAL:$1|$1 pemberitahuan|$1 pemberitahuan}}", - "notification-link-text-expand-notice-count": "Lihat {{PLURAL:$1|$1 pemberitahuan|$1 pemberitahuan}}", + "notification-link-text-expand-alert-count": "Lihat {{PLURAL:$1|$1 peringatan}}", + "notification-link-text-expand-notice-count": "Lihat {{PLURAL:$1|$1 perhatian}}", "notification-link-text-expand-all-count": "Lihat {{PLURAL:$1|$1 pemberitahuan}}", "notification-link-text-collapse-all": "Ciutkan", "notification-link-text-view-message": "Lihat pesan", @@ -142,6 +166,18 @@ "notification-header-user-rights-add-and-remove": "Kelompok pengguna {{GENDER:$6|Anda}} telah {{GENDER:$1|diubah}}. Anda telah ditambahkan ke: $2. Anda tidak lagi menjadi anggota dari: $4.", "notification-header-user-rights-expiry-change": "Kedaluwarsa dari keanggotaan {{GENDER:$4|Anda}} dalam {{PLURAL:$3|kelompok|kelompok}} telah {{GENDER:$1|diubah}}: $2.", "notification-header-welcome": "{{GENDER:$2|Selamat datang}} di {{SITENAME}}, $1! Kami senang {{GENDER:$2|Anda}} bergabung.", + "notification-header-mention-summary": "$1 {{GENDER:$2|menyebut}} {{GENDER:$3|Anda}} di keterangan suntingan di \"<strong>$4</strong>\".", + "notification-header-watchlist-changed": "$1 {{GENDER:$2|mengubah}} <strong>$3</strong>, halaman pada daftar pantauan {{GENDER:$4|Anda}}{{PLURAL:$5||, $5 kali}}.", + "notification-header-watchlist-created": "$1 {{GENDER:$2|membuat}} <strong>$3</strong>, halaman pada daftar pantauan {{GENDER:$4|Anda}}{{PLURAL:$5||, $5 kali}}.", + "notification-header-watchlist-deleted": "$1 {{GENDER:$2|menghapus}} <strong>$3</strong>, halaman pada daftar pantauan {{GENDER:$4|Anda}}{{PLURAL:$5||, $5 kali}}.", + "notification-header-watchlist-moved": "$1 {{GENDER:$2|memindahkan}} <strong>$3</strong>, halaman pada daftar pantauan {{GENDER:$4|Anda}}{{PLURAL:$5||, $5 kali}}.", + "notification-header-watchlist-restored": "$1 {{GENDER:$2|memulihkan}} <strong>$3</strong>, halaman pada daftar pantauan {{GENDER:$4|Anda}}{{PLURAL:$5||, $5 kali}}.", + "notification-header-watchlist-multiuser-changed": "<strong>$1</strong>, halaman pada daftar pantauan {{GENDER:$2|Anda}}, diubah $3 {{PLURAL:$3|kali}}.", + "notification-header-watchlist-multiuser-created": "<strong>$1</strong>,halaman pada daftar pantauan {{GENDER:$2|Anda}}, dibuat $3 {{PLURAL:$3|kali}}.", + "notification-header-watchlist-multiuser-deleted": "<strong>$1</strong>,halaman pada daftar pantauan {{GENDER:$2|Anda}}, dihapus $3 {{PLURAL:$3|kali}}.", + "notification-header-watchlist-multiuser-moved": "<strong>$1</strong>,halaman pada daftar pantauan {{GENDER:$2|Anda}}, dipindahkan $3 {{PLURAL:$3|kali}}.", + "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>,halaman pada daftar pantauan {{GENDER:$2|Anda}}, dipulihkan $3 {{PLURAL:$3|kali}}.", + "notification-body-watchlist-once": "Tidak akan ada lagi pemberitahuan surel ketika terjadi aktivitas lebih lanjut kecuali {{GENDER:$1|Anda mengunjungi}} halaman ini saat masuk log.", "notification-welcome-linktext": "Selamat datang", "notification-header-thank-you-1-edit": "{{GENDER:$2|Anda}} baru saja melakukan suntingan pertama; terima kasih, dan selamat datang!", "notification-header-thank-you-10-edit": "{{GENDER:$2|Anda}} baru saja melakukan suntingan ke-10; terima kasih, dan teruslah menyunting!", @@ -150,6 +186,7 @@ "notification-header-thank-you-10000-edit": "{{GENDER:$2|Anda}} baru saja melakukan suntingan ke-10.000; terima kasih banyak!", "notification-header-thank-you-100000-edit": "{{GENDER:$2|Anda}} baru saja melakukan suntingan ke-100.000; terima kasih atas segala kontribusi Anda!", "notification-header-thank-you-1000000-edit": "{{GENDER:$2|Anda}} baru saja melakukan suntingan ke-1.000.000; terima kasih atas kontribusi Anda yang menakjubkan!", + "notification-header-thank-you-10000000-edit": "{{GENDER:$2|Anda}} baru saja melakukan suntingan ke-10.000.000; terima kasih atas kontribusi Anda yang menakjubkan!", "notification-link-thank-you-edit": "Suntingan {{GENDER:$1|Anda}}", "notification-link-text-view-edit": "Lihat suntingan", "notification-link-article-reminder": "Lihat halaman", @@ -171,14 +208,14 @@ "notification-inbox-filter-read": "Sudah dibaca", "notification-inbox-filter-unread": "Belum dibaca", "notification-inbox-filter-all": "Semua", - "echo-specialmute-label-mute-notifications": "Bisukan pemberitahuan dari pengguna ini", + "echo-specialmute-label-mute-notifications": "Bisukan pemberitahuan dari {{GENDER:$1|pengguna}} ini", "echo-email-plain-footer": "Untuk mengendalikan surel mana saja yang akan kami kirimkan kepada {{GENDER:$1|Anda}}, periksa preferensi {{GENDER:$1|Anda}}:", "echo-email-html-footer-preference-link-text": "periksa preferensi {{GENDER:$1|Anda}}", "echo-email-html-footer-with-link": "Untuk mengendalikan surel mana saja yang akan kami kirimkan kepada {{GENDER:$2|Anda}}, $1.", - "echo-notification-alert": "{{PLURAL:$1|Penanda ($1)|100=Penanda (99+)}}", - "echo-notification-notice": "{{PLURAL:$1|Pemberitahuan ($1)|Pemberitahuan ($1)|100=Pemberitahuan (99+)}}", - "echo-notification-alert-text-only": "Penanda", - "echo-notification-notice-text-only": "Pemberitahuan", + "echo-notification-alert": "{{PLURAL:$1|Peringatan ($1)|100=Peringatan (99+)}}", + "echo-notification-notice": "{{PLURAL:$1|Perhatian ($1)|100=Perhatian (99+)}}", + "echo-notification-alert-text-only": "Peringatan", + "echo-notification-notice-text-only": "Perhatian", "echo-overlay-link": "Semua pemberitahuan", "echo-overlay-title": "<b>Pemberitahuan</b>", "echo-mark-all-as-read": "Tandai semua sebagai telah dibaca", @@ -193,7 +230,12 @@ "echo-email-batch-body-intro-daily": "Hai $1,\nIni adalah ringkasan aktivitas kegiatan hari ini di {{SITENAME}} untuk Anda.", "echo-email-batch-body-intro-weekly": "Hai $1,\nIni adalah ringkasan aktivitas kegiatan pekan ini di {{SITENAME}} untuk Anda.", "echo-email-batch-link-text-view-all-notifications": "Tampilkan semua pemberitahuan", - "notification-header-foreign-alert": "Pemberitahuan lainnya dari {{PLURAL:$5|wiki lainnya|$5 wiki lainnya}}", - "notification-header-foreign-notice": "Pemberitahuan lainnya dari {{PLURAL:$5|wiki lainnya|$5 wiki lainnya}}.", - "notification-header-foreign-all": "Pemberitahuan lainnya dari {{PLURAL:$5|wiki lainnya|$5 wiki lainnya}}." + "notification-header-foreign-alert": "Peringatan lainnya dari {{PLURAL:$5|wiki lainnya|$5 wiki lainnya}}", + "notification-header-foreign-notice": "Perhatian lainnya dari {{PLURAL:$5|wiki lainnya|$5 wiki lainnya}}.", + "notification-header-foreign-all": "Pemberitahuan lainnya dari {{PLURAL:$5|wiki lainnya|$5 wiki lainnya}}.", + "right-manage-all-push-subscriptions": "Mengelola semua langganan dorong", + "action-manage-all-push-subscriptions": "mengelola semua langganan dorong", + "group-push-subscription-manager": "Pengelola langganan dorong", + "group-push-subscription-manager-member": "{{GENDER:$1|pengelola langganan dorong}}", + "grouppage-push-subscription-manager": "{{ns:project}}:Pengelola langganan dorong" } diff --git a/Echo/i18n/ie.json b/Echo/i18n/ie.json index 6cbd12cb..99843a73 100644 --- a/Echo/i18n/ie.json +++ b/Echo/i18n/ie.json @@ -1,8 +1,10 @@ { "@metadata": { "authors": [ + "Renan", "Stavanger7" ] }, - "tooltip-pt-notifications-alert": "Tui notificationes" + "tooltip-pt-notifications-alert": "Tui notificationes", + "tooltip-pt-notifications-notice": "{{GENDER:|Tui}} notificationes" } diff --git a/Echo/i18n/inh.json b/Echo/i18n/inh.json index 047075de..f3e01c64 100644 --- a/Echo/i18n/inh.json +++ b/Echo/i18n/inh.json @@ -22,6 +22,6 @@ "echo-pref-notifications-blacklist": "Ма гойта хоамаш укх доакъашхошкара ([[mw:Special:MyLanguage/Help:Notifications#mute|дукхагIа хá]])", "notifications": "Хоамбар", "tooltip-pt-notifications-alert": "{{GENDER:|Хьога}} дéна дӀахайтар", - "echo-specialmute-label-mute-notifications": "Хьа ма гойта укх доакъашхочунгара хоамаш", + "echo-specialmute-label-mute-notifications": "Ма гойта хоамаш {{GENDER:$1|укх доакъашхочунгара}}", "echo-notification-alert-text-only": "Хабар дáр" } diff --git a/Echo/i18n/io.json b/Echo/i18n/io.json index e294c96f..5a66a5a5 100644 --- a/Echo/i18n/io.json +++ b/Echo/i18n/io.json @@ -2,6 +2,7 @@ "@metadata": { "authors": [ "Algentem", + "JSantos", "Joao Xavier" ] }, @@ -20,16 +21,27 @@ "echo-pref-email-frequency-daily": "Diala rezumo pri avizi", "echo-pref-email-frequency-weekly": "Semanala rezumo pri avizi", "echo-pref-email-format-plain-text": "Nur texto sen formato", - "echo-pref-cross-wiki-notifications": "Montrez notifiki de altra Wiki", + "echo-pref-cross-wiki-notifications": "Montrez avizi de altra Wiki", "echo-pref-notifications-blacklist": "Ne montrez avizi pri ca uzeri. ([[mw:Special:MyLanguage/Help:Notifications#mute|lernez pluse]])", "echo-learn-more": "Lernez pluse", "echo-new-messages": "Vu havas nova mesaji", "echo-category-title-edit-user-talk": "{{PLURAL:$1|Mesajo|Mesaji}} en la diskuto-pagino", "echo-category-title-article-linked": "{{PLURAL:$1|Ligilo|Ligili}} di la pagino", "echo-category-title-mention": "{{PLURAL:$1|Menciono|Mencioni}}", + "echo-category-title-mention-failure": "Faliita {{PLURAL:$1|menciono|mencioni}}", "echo-category-title-mention-success": "{{PLURAL:$1|Menciono|Mencioni}} sucesoza", + "echo-category-title-other": "{{PLURAL:$1|Altra}}", + "echo-category-title-user-rights": "{{PLURAL:$1|Modifikuro|Modifikuri}} en l'autoroyuro", "echo-category-title-emailuser": "{{PLURAL:$1|E-posto de altra uzero|E-posti de altra uzeri}}", "echo-category-title-article-reminder": "{{PLURAL:$1|Memorohelpilo|Memorohelpili}} di la pagino", + "echo-pref-tooltip-edit-user-talk": "Informez me kande ulu redaktos en mea uzero-pagino.", + "echo-pref-tooltip-article-linked": "Informez me se ulu kreos ligilo ad ula pagino quan me kreis de altra pagino.", + "echo-pref-tooltip-mention": "Informez me kande ulu kreos ligilo a mea uzero-pagino.", + "echo-pref-tooltip-mention-failure": "Informez me kande me ne povos sendar ula menciono ad ula persono.", + "echo-pref-tooltip-mention-success": "Informez me kande me sendos menciono ad ulu.", + "echo-pref-tooltip-user-rights": "Informez me, se ulu modifikus mea uzero-yuri.", + "echo-pref-tooltip-emailuser": "Informez me kande ulu sendos me e-posto.", + "echo-pref-tooltip-article-reminder": "Informez me pri ca pagino kande me questionos.", "notifications": "Avizi", "tooltip-pt-notifications-alert": "{{GENDER:|Vua}} informi", "tooltip-pt-notifications-notice": "{{GENDER:|Vua}} informi", @@ -38,13 +50,20 @@ "echo-specialpage-pagefilters-title": "Recenta agadi", "echo-specialpage-pagefilters-subtitle": "Pagini kun nelektita avizi", "notificationsmarkread-legend": "Markizar l'informo quale \"lektita\"", + "echo-none": "Vu havas nula avizi.", + "echo-api-failure": "Faliis pri adportar avizi.", "echo-notification-placeholder": "Ne existas avizi.", "echo-notification-placeholder-filters": "Ne existas avizi segun ica kriterii.", + "echo-notification-loginrequired": "Vu mustas facar ''log in'' por lektar vua avizi.", + "echo-notification-popup-loginrequired": "Facez ''log in'' por vidar l'avizi por vu.", "echo-notification-markasread": "Indikez \"lektita\"", "echo-notification-markasunread": "Indikez quale \"ne lektita\"", "echo-notification-more-options-tooltip": "Plusa selekti", "notification-link-text-expand-alert-count": "Vidar {{PLURAL:$1|$1 avizo|$1 avizi}}", + "notification-link-text-expand-notice-count": "Videz {{PLURAL:$1|$1 avizo|$1 avizi}}", + "notification-link-text-expand-all-count": "Vidar {{PLURAL:$1|$1 avizi|$1 avizi}}", "notification-link-text-collapse-all": "Celez", + "notification-link-text-view-message": "Montrez mesajo", "notification-link-text-view-changes": "{{GENDER:$1|Vidar}} modifiki", "notification-link-text-view-page": "Montrez pagino", "notification-header-edit-user-talk": "$1 {{GENDER:$2|lasis}} mesajo en <strong>{{GENDER:$3|vua}} debato-pagino</strong>.", @@ -57,6 +76,7 @@ "notification-header-user-rights-remove-only": "{{GENDER:$4|Vua}} uzero-yuri {{GENDER:$1|modifikesis}}. Vu ne pluse esas membro de: $2.", "notification-header-user-rights-add-and-remove": "{{GENDER:$6|Vua}} uzero-yuri {{GENDER:$1|modifikesis}}. Vu nun esas $2. Vu ne pluse esas membro de $4.", "notification-header-welcome": "{{GENDER:$2|Bonveno}} a {{SITENAME}}, $1! Ni prizas havar {{GENDER:$2|vu}} hike!", + "notification-welcome-linktext": "Bonveno", "notification-header-thank-you-1-edit": "{{GENDER:$2|Vu}} jus facis {{GENDER:$2|vua}} unesma redakto; ni dankas {{GENDER:$2|vu}}, e bonveno!", "notification-header-thank-you-10-edit": "{{GENDER:$2|Vu}} jus facis {{GENDER:$2|vua}} dekesma redakto; ni dankas {{GENDER:$2|vu}}, e voluntez durar!", "notification-header-thank-you-100-edit": "{{GENDER:$2|Vu}} jus facis {{GENDER:$2|vua}} centesma redakto; ni dankas {{GENDER:$2|vu}} tre multe!", @@ -70,11 +90,13 @@ "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$2|skriptis}} mesajo a vu en {{SITENAME}}", "notification-reverted-email-subject2": "Vua {{PLURAL:$4|redakto|redakti}} {{GENDER:$2|desfacesis}} en {{SITENAME}}", "notification-mention-email-subject": "$1 {{GENDER:$2|mencionis}} {{GENDER:$3|vu}} en {{SITENAME}}", + "notification-user-rights-email-subject": "{{GENDER:$3|Vua}} uzero-yuri chanjesis che {{SITENAME}}", "notification-timestamp-ago-hours": "{{PLURAL:$1|horo|$1 hori}}", "notification-timestamp-ago-days": "{{PLURAL:$1|$1d}}", "notification-timestamp-ago-months": "{{PLURAL:$1|1 monato|$1 monati}}", "notification-timestamp-today": "Hodie", "notification-inbox-filter-all": "Omna", + "echo-specialmute-label-mute-notifications": "Silencigez avizi de ca {{GENDER:$1|uzero}}", "echo-notification-alert": "{{PLURAL:$1|($1) avizo|($1) avizi|100=(99+) avizi}}", "echo-notification-notice": "{{PLURAL:$1|($1) avizo|($1) avizi|100= Avizi (99+)}}", "echo-notification-alert-text-only": "Avizi", @@ -84,6 +106,9 @@ "echo-mark-all-as-read": "Indikez omna mesaji quale \"lektita\"", "echo-date-today": "Hodie", "notification-bundle-header-edit-user-talk-v2": "Existas {{PLURAL:$1|1 nova mesajo|$1 nova mesaji|100=plu kam 99 nova mesaji}} en <strong>{{GENDER:$3|vua}} diskuto-pagino</strong>.", + "echo-email-batch-subject-daily": "Vu havas {{PLURAL:$2|nova avizo|nova avizi}} che {{SITENAME}}", + "echo-email-batch-subject-weekly": "Vu havas {{PLURAL:$2|nova avizo|nova avizi}} de {{SITENAME}} ca semano", + "echo-email-batch-link-text-view-all-notifications": "Montrez omna avizi", "notification-header-foreign-alert": "Plusa avizi de {{PLURAL:$5|altra Wiki|$5 altra Wiki}}", "notification-header-foreign-notice": "Altra avizi de {{PLURAL:$5|altra Wiki|$5 altra Wiki}}" } diff --git a/Echo/i18n/is.json b/Echo/i18n/is.json index 9978e58c..2f2be281 100644 --- a/Echo/i18n/is.json +++ b/Echo/i18n/is.json @@ -2,6 +2,7 @@ "@metadata": { "authors": [ "Hjalmtyr", + "LoveIceLang", "Macofe", "Snævar", "Sveinki", @@ -11,9 +12,9 @@ }, "echo-desc": "Kerfi til að tilkynna notendum um viðburði og skilaboð", "prefs-echo": "Tilkynningar", - "prefs-emailsettings": "Tölvupósts stillingar", + "prefs-emailsettings": "Tölvupóststillingar", "prefs-echosubscriptions": "Gefðu mér tilkynningar fyrir eftirfarandi viðburði", - "echo-pref-send-me": "Sentu mér:", + "echo-pref-send-me": "Senda mér:", "echo-pref-send-to": "Senda til:", "echo-pref-email-format": "Stílviðmið tölvupósts:", "echo-pref-web": "Á netinu", @@ -26,19 +27,20 @@ "echo-pref-email-format-plain-text": "óstílfærður texti", "echo-pref-cross-wiki-notifications": "Sýna tilkynningar frá öðrum wiki", "echo-learn-more": "Vita meira", - "echo-new-messages": "Þú hefur ný skilaboð", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Skilaboð}} á spjallsíðu", + "echo-new-messages": "Þú hefur ný spjallsíðu skilaboð", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Skilaboð}} á spjallsíðu minni", "echo-category-title-article-linked": "{{PLURAL:$1|Tengil|Tengla}} á síðum", "echo-category-title-reverted": "{{PLURAL:$1|Breyting tekin|Breytingar teknar}} aftur", "echo-category-title-mention": "{{PLURAL:$1|Minnst á þig}}", "echo-category-title-other": "{{PLURAL:$1|Annað}}", "echo-category-title-system": "{{PLURAL:$1|Kerfi}}", - "echo-category-title-user-rights": "{{PLURAL:$1|Réttinda breyting|Réttinda breytingar}}", + "echo-category-title-user-rights": "{{PLURAL:$1|Breyting á réttindum|Breytingar á réttindum}}", "echo-category-title-emailuser": "{{PLURAL:$1|Tölvupóstur frá öðrum notanda|Tölvupóstar frá öðrum notendum}}", - "echo-pref-tooltip-edit-user-talk": "Tilkynntu mér um þegar einhver skilur eftir skilaboð eða svarar skilaboðum á spjallsíðunni minni.", + "echo-category-title-thank-you-edit": "Breytinga{{PLURAL:$1|áfangi|áfangar}}", + "echo-pref-tooltip-edit-user-talk": "Tilkynntu mér um þegar einhver breytir spjallsíðunni minni.", "echo-pref-tooltip-article-linked": "Gefðu mér tilkynningu þegar einhver tengir í síðu sem ég bjó til úr annari síðu.", "echo-pref-tooltip-reverted": "Gefðu mér tilkynningu þegar einhver tekur aftur breytingu sem ég gerði.", - "echo-pref-tooltip-mention": "Tilkynntu mér þegar einhver tengir í notendasíðuna mína.", + "echo-pref-tooltip-mention": "Tilkynntu mér þegar einhver tengir í notandasíðuna mína.", "echo-pref-tooltip-user-rights": "Tilkynntu mér þegar einhver breytir notendaréttendum mínum.", "echo-pref-tooltip-emailuser": "Tilkynntu mér um þegar einhver sendir mér tölvupóst.", "notifications": "Tilkynningar", @@ -77,13 +79,12 @@ "notification-link-text-view-edit": "Skoða breytingu", "notification-link-article-reminder": "Skoða síðu", "notification-header-reverted": "{{PLURAL:$4|Breyting þín|Breytingar þínar}} á <strong>$3</strong> {{PLURAL:$4|var tekin|voru teknar}} {{GENDER:$2|aftur}}.", - "notification-body-reverted": "$1", "notification-header-emailuser": "$1 {{GENDER:$2|sendi}} þér tölvupóst.", "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$2|skildi}} eftir skilaboð handa þér á {{SITENAME}}", - "notification-page-linked-email-subject": "Tengt var í síðu sem þú bjóst til á {{SITENAME}}", - "notification-reverted-email-subject2": "{{PLURAL:$4|Breytingin þín var tekin aftur|Breytingarnar þínar voru teknar}} {{GENDER:$2|aftur}} á {{SITENAME}}", + "notification-page-linked-email-subject": "Tengt var í síðu sem {{GENDER:$3|þú}} bjóst til á {{SITENAME}}", + "notification-reverted-email-subject2": "{{PLURAL:$4|Breytingin {{GENDER:$3|þín}} var tekin aftur|Breytingarnar {{GENDER:$3|þínar}} voru teknar}} {{GENDER:$2|aftur}} á {{SITENAME}} $3", "notification-mention-email-subject": "$1 {{GENDER:$2|minntist}} á {{GENDER:$3|þig}} á {{SITENAME}}", - "notification-user-rights-email-subject": "Notandaréttindi þín hafa breyst á {{SITENAME}}", + "notification-user-rights-email-subject": "Notandaréttindi {{GENDER:$3|þín}} hafa breyst á {{SITENAME}}", "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1sek}}", "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1 m}}", "notification-timestamp-ago-hours": "{{PLURAL:$1|$1 klst}}", diff --git a/Echo/i18n/it.json b/Echo/i18n/it.json index d8bf382e..f6cc2e8b 100644 --- a/Echo/i18n/it.json +++ b/Echo/i18n/it.json @@ -13,6 +13,7 @@ "Gianfranco", "Horcrux92", "Macofe", + "Mannivu", "Matteocng", "Nemo bis", "Pequod76", @@ -29,6 +30,10 @@ "prefs-echocrosswiki": "Notifiche cross-wiki", "prefs-blocknotificationslist": "Utenti silenziati", "prefs-mutedpageslist": "Pagine silenziate per le notifiche di collegamento pagina", + "prefs-echopollupdates": "Notifiche dal vivo", + "echo-mobile-notifications-filter-title": "Filtra notifiche", + "echo-pref-show-poll-updates": "Mostra le nuove notifiche appena arrivano", + "echo-pref-show-poll-updates-help": "Mostra il numero di notifiche non lette nella barra del titolo e mostra un'anteprima di ciascuna notifica appena arriva.", "echo-pref-send-me": "Inviami:", "echo-pref-send-to": "Invia a:", "echo-pref-email-format": "Formato email:", @@ -44,10 +49,11 @@ "echo-pref-cross-wiki-notifications": "Mostra notifiche da altri wiki", "echo-pref-notifications-blacklist": "Non mostrare notifiche di questi utenti ([[mw:Special:MyLanguage/Help:Notifications#mute|ulteriori informazioni]])", "echo-pref-notifications-page-linked-title-muted-list": "Non mostrare le notifiche \"Collegamento a una pagina\" per queste pagine ([[mw:Special:MyLanguage/Help:Notifications#mute|ulteriori informazioni]])", + "echo-pref-dont-email-read-notifications": "Non includere le notifiche lette nei resoconti via mail", "echo-learn-more": "Ulteriori informazioni", "echo-log": "Registro pubblico", - "echo-new-messages": "Hai nuovi messaggi", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Messaggio|Messaggi}} sulla pagina di discussione", + "echo-new-messages": "Hai un nuovo messaggio", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Modifica|Modifiche}} alla mia pagina di discussione utente", "echo-category-title-article-linked": "{{PLURAL:$1|Collegamento|Collegamenti}} a una pagina", "echo-category-title-reverted": "{{PLURAL:$1|Modifica annullata|Modifiche annullate}}", "echo-category-title-mention": "{{PLURAL:$1|Menzione|Menzioni}}", @@ -60,7 +66,7 @@ "echo-category-title-user-rights": "{{PLURAL:$1|Modifica diritto|Modifiche diritti}} utente", "echo-category-title-emailuser": "{{PLURAL:$1|Email da un altro utente|Email da altri utenti}}", "echo-category-title-thank-you-edit": "{{PLURAL:$1|Traguardo|Traguardi}} modifiche", - "echo-pref-tooltip-edit-user-talk": "Avvisami quando qualcuno mi scrive un messaggio o risponde nella mia pagina di discussione.", + "echo-pref-tooltip-edit-user-talk": "Avvisami quando qualcuno modifica la mia pagina di discussione utente.", "echo-pref-tooltip-article-linked": "Avvisami quando qualcuno collega una pagina che ho creato da un'altra pagina.", "echo-pref-tooltip-reverted": "Avvisami quando qualcuno annulla una modifica che ho fatto, usando le funzioni annulla o rollback.", "echo-pref-tooltip-mention": "Avvisami quando qualcuno collega la mia pagina utente.", diff --git a/Echo/i18n/ja.json b/Echo/i18n/ja.json index e2a53b95..2977a170 100644 --- a/Echo/i18n/ja.json +++ b/Echo/i18n/ja.json @@ -4,12 +4,15 @@ "2nd-player", "Afaz", "Fryed-peach", + "Fumi37s", "Kkairri", + "LaMagiaaa", "Marine-Blue", "Ochaochaocha3", "Omotecho", "Otokoume", "Penn Station", + "RYOUMA1117", "Shirayuki", "Suchichi02", "Sujiniku", @@ -18,8 +21,11 @@ "Tmv", "Translatealcd", "Vigorous action", + "W.CC", "Whym", - "Yusuke1109" + "Yusuke1109", + "おはぐろ蜻蛉", + "ネイ" ] }, "echo-desc": "イベントおよびメッセージについて、利用者に通知するシステム", @@ -37,6 +43,7 @@ "echo-pref-email-format": "メールの形式:", "echo-pref-web": "ウェブ", "echo-pref-email": "メール", + "echo-pref-push": "アプリ", "echo-pref-email-frequency-never": "通知メールを何も受け取らない", "echo-pref-email-frequency-immediately": "個別の通知が来るたび", "echo-pref-email-frequency-daily": "通知を1日ごとに要約", @@ -48,8 +55,8 @@ "echo-pref-notifications-page-linked-title-muted-list": "以下のページからのページリンク通知は表示されません ([[mw:Special:MyLanguage/Help:Notifications#mute|詳細]])。", "echo-learn-more": "詳細", "echo-log": "公開記録", - "echo-new-messages": "新着メッセージがあります", - "echo-category-title-edit-user-talk": "トークページヘの{{PLURAL:$1|メッセージ}}", + "echo-new-messages": "あなたの会話ページに新着メッセージがあります", + "echo-category-title-edit-user-talk": "利用者トークページでの{{PLURAL:$1|編集}}", "echo-category-title-article-linked": "ページへの{{PLURAL:$1|リンク}}", "echo-category-title-reverted": "編集の{{PLURAL:$1|差し戻し}}", "echo-category-title-mention": "{{PLURAL:$1|言及}}", @@ -65,7 +72,7 @@ "echo-category-title-thank-you-edit": "編集{{PLURAL:$1|マイルストーン}}", "echo-category-title-watchlist": "ウォッチページへの編集", "echo-category-title-minor-watchlist": "ウォッチページの細部の編集", - "echo-pref-tooltip-edit-user-talk": "誰かが私のトークページでメッセージの投稿または返信をしたときに通知する。", + "echo-pref-tooltip-edit-user-talk": "誰かが私の利用者トークページを編集したときに通知する。", "echo-pref-tooltip-article-linked": "誰かが自分の作成したページに記事からリンクしたときに通知する。", "echo-pref-tooltip-reverted": "誰かが取り消しや巻き戻しの機能で私の編集を差し戻したときに通知する。", "echo-pref-tooltip-mention": "誰かが私の利用者ページにリンクしたときに通知する。", @@ -115,10 +122,10 @@ "echo-notification-more-options-tooltip": "その他の操作", "notification-dynamic-actions-mute-page-linked": "「$1」のリンク通知を{{GENDER:$2|ミュートする}}", "notification-dynamic-actions-mute-page-linked-confirmation": "ページ「$1」に対する「ページリンク」通知は無効になりました", - "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|あなた}}は、[$1 設定]からいつでもミュートしたページを管理することができます。", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|あなた}}は、[$1 設定]からいつでもミュートしたページを管理できます。", "notification-dynamic-actions-unmute-page-linked": "「$1」のリンク通知の{{GENDER:$2|ミュートを解除する}}", "notification-dynamic-actions-unmute-page-linked-confirmation": "ページ「$1」に対する「ページリンク」通知は有効になりました", - "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|あなた}}は、[$1 設定]からいつでもミュートしたページを管理することができます。", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|あなた}}は、[$1 設定]からいつでもミュートしたページを管理できます。", "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|あなた}}はいつでも[$2 このページ]を閲覧できます。", "notification-link-text-expand-all": "展開", "notification-link-text-expand-alert-count": "{{PLURAL:$1|$1件のアラート}}を表示", @@ -161,6 +168,7 @@ "notification-header-user-rights-add-and-remove": "{{GENDER:$6|あなたの}}利用者権限が{{GENDER:$1|変更されました}}: $2へ追加され、$4から除外されました。", "notification-header-welcome": "$1 さん、{{SITENAME}} へ{{GENDER:$2|ようこそ}}!{{GENDER:$2|あなた}}の参加を歓迎します。", "notification-header-mention-summary": "$1 が <strong>$4</strong> の「編集の要約欄」で{{GENDER:$3|あなた}}に{{GENDER:$2|言及しました}} 。", + "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>、{{GENDER:$2|あなた}}のウォッチリストを$3{{PLURAL:$3|time|times}}のものに復元しました。", "notification-welcome-linktext": "ようこそ", "notification-header-thank-you-1-edit": "{{GENDER:$2|あなた}}は初めて編集を行いました。寄稿をありがとうございます。そして、ようこそ!", "notification-header-thank-you-10-edit": "{{GENDER:$2|あなた}}は10回の編集を行いました。これからも頑張りましょう!", @@ -190,10 +198,10 @@ "notification-inbox-filter-read": "既読", "notification-inbox-filter-unread": "未読", "notification-inbox-filter-all": "すべて", - "echo-specialmute-label-mute-notifications": "この利用者からの通知をミュートする", + "echo-specialmute-label-mute-notifications": "この{{GENDER:$1|利用者}}からの通知をミュートする", "echo-email-plain-footer": "{{GENDER:$1|あなた}}が受け取るメールの設定を変更するには、個人設定をご確認ください:", "echo-email-html-footer-preference-link-text": "{{GENDER:$1|個人設定}}をご確認ください", - "echo-email-html-footer-with-link": "{{{{GENDER:$2|皆さん}}}}にお届けするメールを変更するには、$1。", + "echo-email-html-footer-with-link": "{{GENDER:$2|}}お届けするメールを変更するには、$1。", "echo-notification-alert": "{{PLURAL:$1|アラート ($1)|100=アラート (99件以上)}}", "echo-notification-notice": "{{PLURAL:$1|通知 ($1件)|100=通知 (99件以上)}}", "echo-notification-alert-text-only": "アラート", @@ -214,5 +222,10 @@ "echo-email-batch-link-text-view-all-notifications": "すべての通知を閲覧", "notification-header-foreign-alert": "{{PLURAL:$5|他のウィキ|他の$5個のウィキ}}からのアラートがあります", "notification-header-foreign-notice": "{{PLURAL:$5|他のウィキ|他の$5個のウィキ}}からの通知があります", - "notification-header-foreign-all": "{{PLURAL:$5|他のウィキ|他の$5個のウィキ}}からの通知があります" + "notification-header-foreign-all": "{{PLURAL:$5|他のウィキ|他の$5個のウィキ}}からの通知があります", + "right-manage-all-push-subscriptions": "すべてのプッシュ・サブスクリプションを操作する", + "action-manage-all-push-subscriptions": "すべてのプッシュ・サブスクリプションを操作する", + "group-push-subscription-manager": "プッシュ・サブスクリプション取扱者", + "group-push-subscription-manager-member": "{{GENDER:$1|プッシュ・サブスクリプション取扱者}}", + "grouppage-push-subscription-manager": "{{ns:project}}:プッシュ・サブスクリプション取扱者" } diff --git a/Echo/i18n/jv.json b/Echo/i18n/jv.json index 06c70744..a5d72b93 100644 --- a/Echo/i18n/jv.json +++ b/Echo/i18n/jv.json @@ -138,7 +138,6 @@ "notification-link-text-view-edit": "Tuduhaké besutan", "notification-link-article-reminder": "Deleng kaca", "notification-header-reverted": "{{PLURAL:$4|Besutané panjenengan ing <strong>$3</strong>}} {{GENDER:$2|dibalèkaké}}.", - "notification-body-reverted": "$1", "notification-header-emailuser": "$1 {{GENDER:$2|ngirimi}} panjenengan layang.", "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$2|ngirimi}} panjenengan layang ing {{SITENAME}}", "notification-page-linked-email-subject": "Kaca kang {{GENDER:$3|ko}}gawé kagayut marang {{SITENAME}}", diff --git a/Echo/i18n/ka.json b/Echo/i18n/ka.json index c8fdcc1c..19e98cc6 100644 --- a/Echo/i18n/ka.json +++ b/Echo/i18n/ka.json @@ -9,7 +9,8 @@ "Nodar Kherkheulidze", "Otogi", "Sopopruidze", - "Tokoko" + "Tokoko", + "Გიო ოქრო" ] }, "echo-desc": "შეტყობინებებისა და მოვლენების სისტემა", @@ -45,7 +46,7 @@ "echo-category-title-system": "{{PLURAL:$1|სისტემა}}", "echo-category-title-user-rights": "{{PLURAL:$1|მომხმარებლის უფლებების ცვლილება|მომხმარებლის უფლებების ცვლილებები}}", "echo-category-title-emailuser": "{{PLURAL:$1|იმეილი სხვა მომხმარებლისაგან|იმეილი სხვა მომხმარებლებისაგან}}", - "echo-category-title-thank-you-edit": "{{PLURAL:$1|საფეხურის|საფეხურის}} რედაქტირება", + "echo-category-title-thank-you-edit": "რედაქტირებების მრგვალი რიცხვი", "echo-pref-tooltip-edit-user-talk": "შემატყობინე, როდესაც ვინმე დაარედაქტირებს ჩემს განხილვის გვერდს.", "echo-pref-tooltip-article-linked": "შემატყობინე, როდესაც ვინმე უკავშირდება სტატიებს ჩემ მიერ შექმნილ გვერდზე", "echo-pref-tooltip-reverted": "შემატყობინე, როდესაც ვინმე ჩემს რედაქტირებას გააუქმებს.", @@ -54,6 +55,7 @@ "echo-pref-tooltip-mention-success": "შემატყობინე, როდესაც მე ვუგზავნი ვინმეს მოხსენებას", "echo-pref-tooltip-user-rights": "შემატყობინე, როდესაც ვინმე შეცვლის ჩემს მომხმარებლის უფლებებს.", "echo-pref-tooltip-emailuser": "შემატყობინე, როდესაც ვინმე მომწერს ელექტრონულ მეილს.", + "echo-pref-tooltip-thank-you-edit": "შემატყობინე, როდესაც მივაღწევ ჩემ 1-ელ, მე-10, მე-100... რედაქტირებას.", "notifications": "შეტყობინებები", "tooltip-pt-notifications-alert": "{{GENDER:|თქვენი}} მოხსენებები", "tooltip-pt-notifications-notice": "თქვენი შეტყობინებები", @@ -73,7 +75,7 @@ "echo-notification-markasread": "მონიშნეთ როგორც წაკითხული", "echo-notification-markasunread": "მონიშნეთ როგორც წაუკითხავი", "echo-notification-markasread-tooltip": "მონიშნეთ როგორც წაკითხული", - "echo-notification-more-options-tooltip": "მეტი პარამეტრები", + "echo-notification-more-options-tooltip": "მეტი შესაძლებლობა", "notification-link-text-expand-all": "განვრცობა", "notification-link-text-expand-all-count": "იხილე {{PLURAL:$1|$1 შეტყობინება|$1 შეტყობინებები}}", "notification-link-text-collapse-all": "ჩაკეცვა", @@ -121,5 +123,8 @@ "echo-date-today": "დღეს", "echo-date-yesterday": "გუშინ", "echo-email-batch-bullet": "•", - "echo-email-batch-link-text-view-all-notifications": "ყველა შეტყობინების ნახვა" + "echo-email-batch-link-text-view-all-notifications": "ყველა შეტყობინების ნახვა", + "group-push-subscription-manager": "push-შეტყობინების მმართველები", + "group-push-subscription-manager-member": "{{GENDER:$1|push-შეტყობინების მმართველი}}", + "grouppage-push-subscription-manager": "{{ns:project}}:push-შეტყობინების მმართველები" } diff --git a/Echo/i18n/kaa.json b/Echo/i18n/kaa.json new file mode 100644 index 00000000..62824f07 --- /dev/null +++ b/Echo/i18n/kaa.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Ajiniyaz Nurniyazov", + "Nurlan" + ] + }, + "prefs-description-echo": "Qaysı bildiriw xatlardı {{GENDER:| siz}} alıwdı hám olardı qalay qabıllawdı saylań.", + "notification-welcome-linktext": "Xosh keldińiz" +} diff --git a/Echo/i18n/kcg.json b/Echo/i18n/kcg.json new file mode 100644 index 00000000..8d77eca6 --- /dev/null +++ b/Echo/i18n/kcg.json @@ -0,0 +1,69 @@ +{ + "@metadata": { + "authors": [ + "Amire80", + "Kambai Akau" + ] + }, + "prefs-echo": "Shei li̱lak", + "prefs-emailsettings": "A̱vwuokhai tá̱m-i", + "prefs-echosubscriptions": "Shei ma̱ng a̱nung tazwa nyiá̱ jini", + "prefs-echocrosswiki": "Shei li̱lak a̱yaawuki ma̱ a̱adi̱di̱t nvwuon", + "prefs-blocknotificationslist": "Á̱nietnta̱m nang á̱ ku tyia̱ ma̱ma̱m a̱ni", + "prefs-mutedpageslist": "Ngwat na nang á̱ ku tyia̱ ma̱ma̱m mat shei li̱lak a̱fwuop wat", + "prefs-echopollupdates": "Shei li̱lak ma̱ninika", + "echo-pref-send-me": "Ta̱m ma̱ng a̱nung:", + "echo-pref-send-to": "Ta̱m da̱ a̱vwuo:", + "echo-pref-email-format": "Vak lyuut ta̱m-i:", + "echo-pref-web": "A̱ma̱ntei", + "echo-pref-email": "Ta̱m-i", + "echo-pref-push": "A̱yaa-ap", + "echo-pref-email-frequency-never": "Yok ta̱m ma̱ng a̱nung ku shei li̱lak ta̱m-i bah", + "echo-pref-email-frequency-immediately": "Shei li̱lak konyan ma̱nang ku nwuai a̱ni", + "echo-pref-email-format-html": "HTML", + "echo-learn-more": "Myiam nkyang njhyang", + "echo-log": "Ri̱jista konyan ma̱ng konyan", + "echo-new-messages": "A byia̱ ta̱m wat A̱lyiat swai", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Edit|Njhyuk}} ma̱ wat a̱lyiat a̱tyunta̱m nung hu", + "echo-category-title-article-linked": "Page {{PLURAL:$1|a̱fwuop|a̱ka̱fwuop}}", + "echo-category-title-other": "{{PLURAL:$1|A̱ghyang}}", + "tooltip-pt-notifications-alert": "A̱yaalama {{GENDER:|ang ba}}", + "echo-displaynotificationsconfiguration-enabled-default-existing-users-legend": "Á̱nietnta̱m ba̱ ka̱n nshyia̱ a̱ni", + "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "Á̱nietnta̱m á̱fai", + "echo-specialpage": "Shei li̱lak", + "echo-specialpage-section-markread": "Cak sot ji nang si̱ hu nang á̱ ka̱n fang a̱ni", + "echo-notification-placeholder": "Shei li̱lak nshyia̱ bah.", + "echo-notification-markasread": "Cak nang si̱ hu nang á̱ ka̱n fang a̱ni", + "echo-notification-markasunread": "Cak nang si̱ hu nang á̱ ka̱n fang a̱ni bah", + "echo-notification-markasread-tooltip": "Cak nang si̱ hu nang á̱ ka̱n fang a̱ni", + "notification-link-text-expand-all": "Ngaat", + "notification-link-text-collapse-all": "Kwa", + "notification-link-text-view-message": "Li ta̱m ji", + "notification-link-text-view-mention": "Li ta̱m ji", + "notification-link-text-view-page": "Li wat hu", + "notification-link-text-what-links-here": "A̱mgba̱m a̱ka̱fwuop ma̱ wat huni", + "notification-compact-header-mention-failure-user-unknown": "<strong>A̱lyoot-a̱tyunta̱m nshyia̱ bah:</strong> $1", + "notification-welcome-linktext": "Aba̱n/a̱la̱baa", + "notification-link-thank-you-edit": "Jhyuk {{GENDER:$1|ang}} hu", + "notification-link-text-view-edit": "Li jhyuk hu", + "notification-link-article-reminder": "Li wat hu", + "notification-header-emailuser": "$1 ku {{GENDER:$2|ta̱m}} ma̱ng a̱nwan ta̱m-i.", + "notification-user-rights-email-subject": "A̱ka̱wat a̱tyunta̱m {{GENDER:$3|ang}} na ku shai ma̱ {{SITENAME}}", + "notification-timestamp-ago-seconds": "{{PLURAL:$1|a̱b$1}}", + "notification-timestamp-ago-minutes": "{{PLURAL:$1|mi$1}}", + "notification-timestamp-ago-hours": "{{PLURAL:$1|a̱w$1}}", + "notification-timestamp-ago-days": "{{PLURAL:$1|ma$1}}", + "notification-timestamp-ago-months": "{{PLURAL:$1|zw$1}}", + "notification-timestamp-ago-years": "{{PLURAL:$1|a̱l$1}}", + "notification-timestamp-today": "A̱fwun", + "notification-timestamp-yesterday": "Lyuo", + "notification-inbox-filter-read": "Á̱ ka̱n fang", + "notification-inbox-filter-unread": "Á̱ ka̱n fang bah", + "notification-inbox-filter-all": "A̱mgba̱m", + "echo-notification-alert-text-only": "A̱yaalama", + "echo-mark-wiki-as-read": "Cak a̱mgba̱m nang á̱si̱ nang á̱ ka̱n fang a̱ni mi̱ wuki nang á̱ khai a̱ni: $1", + "echo-displaysnippet-title": "Shei li̱lak fai", + "echo-date-today": "A̱fwun", + "echo-date-yesterday": "Lyuo", + "echo-email-batch-link-text-view-all-notifications": "Li a̱mgba̱m shei li̱lak" +} diff --git a/Echo/i18n/kk-cyrl.json b/Echo/i18n/kk-cyrl.json index 0582a6a1..f61173fe 100644 --- a/Echo/i18n/kk-cyrl.json +++ b/Echo/i18n/kk-cyrl.json @@ -2,7 +2,8 @@ "@metadata": { "authors": [ "Arystanbek", - "Macofe" + "Macofe", + "СеніңШешең" ] }, "echo-desc": "Оқиғалар мен хабарламалар туралы қатысушыларға ескерту \nжүйесі", @@ -58,7 +59,7 @@ "notification-link-text-expand-alert-count": "{{PLURAL:$1|$1 Дабылды|$1 Дабылды}} көру", "notification-link-text-expand-all-count": "{{PLURAL:$1|$1 ескертпені|$1 ескертпені}} көру", "notification-link-text-collapse-all": "Жиыру", - "notification-link-text-view-message": "Хабарламаны көру", + "notification-link-text-view-message": "Хабарды көру", "notification-link-text-view-mention": "Еске салуды көру", "notification-link-text-view-changes": "Өзгерістерді {{GENDER:$1|көру}}", "notification-link-text-view-page": "Бетті көру", diff --git a/Echo/i18n/kn.json b/Echo/i18n/kn.json index 30ccc16c..44c20938 100644 --- a/Echo/i18n/kn.json +++ b/Echo/i18n/kn.json @@ -3,7 +3,8 @@ "authors": [ "Pavanaja", "Shubha", - "Vikashegde" + "Vikashegde", + "ಮಲ್ನಾಡಾಚ್ ಕೊಂಕ್ಣೊ" ] }, "echo-desc": "ಸೂಚನಾ ವ್ಯವಸ್ಥೆ", @@ -29,23 +30,46 @@ "echo-category-title-mention": "{{PLURAL:$1|Mention|Mentions}}", "echo-category-title-other": "{{PLURAL:$1|Other}}", "echo-category-title-system": "{{PLURAL:$1|System}}", - "echo-pref-tooltip-edit-user-talk": "ಯಾರಾದರೂ ನನಗೆ ಸಂದೇಶ ಪೋಸ್ಟ್ ಮಾಡಿದರೆ ಅಥವಾ ನನ್ನ ಚರ್ಚಾಪುಟದಲ್ಲಿ ಉತ್ತರಿಸಿದರೆ ತಿಳಿಸಿ", - "echo-pref-tooltip-article-linked": "ನಾನು ತಯಾರಿಸಿದ ಲೇಖನಪುಟಕ್ಕೆ ಯಾರಾದರೂ ಕೊಂಡಿ ನೀಡಿದರೆ ನನಗೆ ತಿಳಿಸಿ", + "echo-pref-tooltip-edit-user-talk": "ಯಾರಾದರೂ ನನಗೆ ಸಂದೇಶ ಪೋಸ್ಟ್ ಮಾಡಿದರೆ ಅಥವಾ ನನ್ನ ಚರ್ಚಾಪುಟದಲ್ಲಿ ಉತ್ತರಿಸಿದರೆ ತಿಳಿಸಿ.", + "echo-pref-tooltip-article-linked": "ನಾನು ತಯಾರಿಸಿದ ಪುಟಕ್ಕೆ ಯಾರಾದರೂ ಬೇರೆ ಪುಟದಿಂದ ಕೊಂಡಿ ನೀಡಿದರೆ ನನಗೆ ತಿಳಿಸಿ.", "echo-pref-tooltip-reverted": "ನಾನು ಮಾಡಿದ ಸಂಪಾದನೆಯನ್ನು ಯಾರಾದರು ಹಿಂದಿನಂತೆ ಮಾಡಿದರೆ ನನಗೆ ತಿಳಿಸಿ", "echo-pref-tooltip-mention": "ನನ್ನ ಸದಸ್ಯ ಪುಟಕ್ಕೆ ಯಾರಾದರು ಯಾವುದಾದರು ಚರ್ಚಾಪುಟದಿಂದ ಕೊಂಡಿ ನೀಡಿದರೆ ನನಗೆ ತಿಳಿಸಿ", "notifications": "ಸೂಚನೆಗಳು", + "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "ಹೊಸ ಬಳಕೆದಾರರು", "echo-specialpage": "ಸೂಚನೆಗಳು", + "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|ಅಧಿಸೂಚನೆ|ಅಧಿಸೂಚನೆಗಳು}}", + "echo-specialpage-pagefilters-title": "ಇತ್ತೀಚೆಗಿನ ಚಟುವಟಿಕೆ", "echo-none": "ನಿಮಗೆ ಯಾವುದೇ ಸೂಚನೆಗಳಿಲ್ಲ", + "echo-notification-placeholder": "ಯಾವುದೇ ಅಧಿಸೂಚನೆಗಳು ಇಲ್ಲ.", + "echo-notification-placeholder-filters": "ಈ ಮಾನದಂಡಗಳನ್ನು ಹೋಲುವ ಯಾವುದೇ ಅಧಿಸೂಚನೆಗಳು ಇಲ್ಲ.", + "echo-notification-loginrequired": "ನಿಮ್ಮ ಅಧಿಸೂಚನೆಗಳನ್ನು ನೋಡಲು ನೀವು ಲಾಗಿನ್ ಆಗಬೇಕು.", + "echo-notification-popup-loginrequired": "ನಿಮ್ಮ ಅಧಿಸೂಚನೆಗಳನ್ನು ನೋಡಲು ದಯವಿಟ್ಟು ಲಾಗಿನ್ ಆಗಿ.", + "echo-notification-markasread": "ಓದಿರುವುದಾಗಿ ಗುರುತು ಮಾಡಿ", + "echo-notification-markasunread": "ಓದಿಲ್ಲವೆಂದು ಗುರುತು ಮಾಡಿ", + "echo-notification-markasread-tooltip": "ಓದಿರುವುದಾಗಿ ಗುರುತು ಮಾಡಿ", + "echo-notification-more-options-tooltip": "ಹೆಚ್ಚಿನ ಆಯ್ಕೆಗಳು", "notification-link-text-view-message": "ಸಂದೇಶ ನೋಡಿ", "notification-link-text-view-mention": "ಸಂಬೋಧನೆ ನೋಡಿ", - "notification-link-text-view-changes": "ಬದಲಾವಣೆ ನೋಡಿ", + "notification-link-text-view-changes": "ಬದಲಾವಣೆಗಳನ್ನು {{GENDER:$1|ನೋಡಿ}}", "notification-link-text-view-page": "ಪುಟ ನೋಡಿ", "notification-link-text-view-edit": "ಸಂಪಾದನೆ ನೋಡಿ", "notification-page-linked-email-subject": "ನಿಮ್ಮ ಪುಟವು {{SITENAME}} ಜಾಲತಾಣಕ್ಕೆ ಸಂಪರ್ಕಿಸಲ್ಪಟ್ಟಿದೆ", "notification-user-rights-email-subject": "{{SITENAME}} ಜಾಲತಾಣದಲ್ಲಿ ನಿಮ್ಮ ಬಳಕೆದಾರ ಹಕ್ಕುಗಳನ್ನು ಬದಲಿಸಲಾಗಿದೆ", + "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1ಸೆ}}", + "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1ನಿ}}", + "notification-timestamp-ago-hours": "{{PLURAL:$1|$1ಗಂ}}", + "notification-timestamp-ago-days": "{{PLURAL:$1|$1ದಿ}}", + "notification-timestamp-ago-months": "{{PLURAL:$1|$1ತಿಂ}}", + "notification-timestamp-ago-years": "{{PLURAL:$1|$1ವ}}", + "notification-timestamp-today": "ಇಂದು", + "notification-timestamp-yesterday": "ನಿನ್ನೆ", + "notification-inbox-filter-read": "ಓದಿದ", + "notification-inbox-filter-unread": "ಓದದ", + "notification-inbox-filter-all": "ಎಲ್ಲಾ", "echo-overlay-link": "ಎಲ್ಲ ಸೂಚನೆಗಳು", "echo-overlay-title": "<b>ಸೂಚನೆಗಳು</b>", "echo-mark-all-as-read": "ಎಲ್ಲವನ್ನೂ ಓದಿದೆ ಎಂದು ಆಯ್ಕೆ ಮಾಡಿ", + "echo-displaysnippet-title": "ಹೊಸ ಅಧಿಸೂಚನೆ", "echo-date-today": "ಇಂದು", "echo-date-yesterday": "ನಿನ್ನೆ", "echo-email-batch-body-intro-daily": "ನಮಸ್ಕಾರ $1,\n{{SITENAME}} ಜಾಲತಾಣದಲ್ಲಿ ಇಂದು ನಡೆದ ಎಲ್ಲ ಪ್ರಕ್ರಿಯೆಗಳ ಸಾರಾಂಶ ನಿಮಗಾಗಿ ಇಲ್ಲಿದೆ.", diff --git a/Echo/i18n/ko.json b/Echo/i18n/ko.json index d83ae241..09007082 100644 --- a/Echo/i18n/ko.json +++ b/Echo/i18n/ko.json @@ -1,6 +1,7 @@ { "@metadata": { "authors": [ + "Bluehill", "Bluemersen", "Daisy2002", "Ellif", @@ -30,7 +31,9 @@ "prefs-echocrosswiki": "여러 위키의 알림", "prefs-blocknotificationslist": "알림에서 제외된 사용자", "prefs-mutedpageslist": "문서 링크 알림 표시를 하지 않는 문서", + "prefs-echopollupdates": "실시간 알림", "echo-mobile-notifications-filter-title": "필터 알림", + "echo-pref-show-poll-updates": "새 알림이 오면 표시합니다", "echo-pref-send-me": "다음 방식으로 보내기:", "echo-pref-send-to": "다음 주소로 보내기:", "echo-pref-email-format": "이메일 형식:", @@ -46,10 +49,11 @@ "echo-pref-cross-wiki-notifications": "다른 위키의 알림을 보기", "echo-pref-notifications-blacklist": "이 사용자의 알림을 표시하지 않습니다. ([[mw:Special:MyLanguage/Help:Notifications#mute|더 알아보기]])", "echo-pref-notifications-page-linked-title-muted-list": "이 문서에 대한 '문서 링크' 알림을 표시하지 않습니다. ([[mw:Special:MyLanguage/Help:Notifications#mute|더 알아보기]])", + "echo-pref-dont-email-read-notifications": "요약 이메일에 읽음 알림을 포함하지 않습니다", "echo-learn-more": "더 알아보기", "echo-log": "공개 기록", - "echo-new-messages": "새 메시지가 있습니다", - "echo-category-title-edit-user-talk": "토론 문서 {{PLURAL:$1|메시지}}", + "echo-new-messages": "새 토론 문서 메시지가 있습니다", + "echo-category-title-edit-user-talk": "내 사용자 토론 문서의 {{PLURAL:$1|편집}}", "echo-category-title-article-linked": "문서 {{PLURAL:$1|링크}}", "echo-category-title-reverted": "편집이 {{PLURAL:$1|되돌려짐}}", "echo-category-title-mention": "{{PLURAL:$1|언급}}", @@ -65,7 +69,7 @@ "echo-category-title-thank-you-edit": "편집 {{PLURAL:$1|이정표}}", "echo-category-title-watchlist": "주시 중인 문서의 편집", "echo-category-title-minor-watchlist": "주시 중인 문서의 사소한 편집", - "echo-pref-tooltip-edit-user-talk": "내 토론 문서에 누군가가 글이나 답글을 남길 때 내게 알립니다.", + "echo-pref-tooltip-edit-user-talk": "누군가가 내 사용자 토론 문서를 편집할 때 내게 알립니다.", "echo-pref-tooltip-article-linked": "누군가가 다른 문서에서 내가 만든 문서를 링크할 때 내게 알립니다.", "echo-pref-tooltip-reverted": "누군가가 편집 취소나 되돌리기 도구를 사용하여 내 편집을 되돌릴 때 내게 알립니다.", "echo-pref-tooltip-mention": "누군가가 내 사용자 문서를 링크할 때 내게 알립니다.", @@ -83,6 +87,7 @@ "echo-displaynotificationsconfiguration": "알림 표시 설정", "echo-displaynotificationsconfiguration-summary": "이 위키에서 알림이 어떻게 설정되었는지에 관한 개요입니다.", "echo-displaynotificationsconfiguration-notifications-by-category-header": "분류별 알림", + "echo-displaynotificationsconfiguration-sorting-by-section-header": "유형 정렬", "echo-displaynotificationsconfiguration-available-notification-methods-header": "허용된 알림 방식", "echo-displaynotificationsconfiguration-enabled-default-header": "기본적으로 활성화됨", "echo-displaynotificationsconfiguration-enabled-default-existing-users-legend": "기존 사용자", @@ -92,6 +97,7 @@ "echo-specialpage-section-markread": "그룹을 읽은 것으로 표시", "echo-specialpage-markasread": "알림: 읽은 것으로 표시", "echo-specialpage-markasread-invalid-id": "유효하지 않은 이벤트 ID", + "echo-specialpage-pagefilterwidget-aria-label": "위키와 문서 제목별 필터", "echo-specialpage-special-help-menu-widget-aria-label": "추가 옵션과 알림 환경 설정입니다.", "echo-specialpage-pagination-numnotifications": "{{PLURAL:$1|알림}} $1개", "echo-specialpage-pagefilters-title": "최근 활동", @@ -176,7 +182,7 @@ "notification-page-linked-email-subject": "{{SITENAME}}에서 {{GENDER:$3|당신}}이 만든 문서가 링크되었습니다", "notification-reverted-email-subject2": "{{SITENAME}}의 {{GENDER:$3|당신}}의 {{PLURAL:$4|편집}}이 {{GENDER:$2|되돌려졌습니다}}", "notification-mention-email-subject": "$1님이 {{SITENAME}}에서 {{GENDER:$3|나를}} {{GENDER:$2|언급했습니다}}", - "notification-user-rights-email-subject": "{{SITENAME}}에서 당신의 사용자 권한이 바뀌었습니다", + "notification-user-rights-email-subject": "{{SITENAME}}에서 {{GENDER:$3|당신}}의 사용자 권한이 바뀌었습니다", "notification-timestamp-ago-seconds": "$1초 전", "notification-timestamp-ago-minutes": "$1분 전", "notification-timestamp-ago-hours": "$1시간 전", @@ -212,5 +218,10 @@ "echo-email-batch-link-text-view-all-notifications": "모든 알림 보기", "notification-header-foreign-alert": "{{PLURAL:$5|다른 위키|$5개의 다른 위키}}의 중요 알림 더 보기", "notification-header-foreign-notice": "{{PLURAL:$5|다른 위키|$5개의 다른 위키}}의 더 많은 알림", - "notification-header-foreign-all": "$5개의 다른 위키로부터 알림 더 보기" + "notification-header-foreign-all": "$5개의 다른 위키로부터 알림 더 보기", + "right-manage-all-push-subscriptions": "모든 푸시 구독 관리", + "action-manage-all-push-subscriptions": "모든 푸시 구독을 관리할", + "group-push-subscription-manager": "푸시 구독 관리자", + "group-push-subscription-manager-member": "{{GENDER:$1|푸시 구독 관리자}}", + "grouppage-push-subscription-manager": "{{ns:project}}:푸시 구독 관리자" } diff --git a/Echo/i18n/ks-arab.json b/Echo/i18n/ks-arab.json index dabc4767..6d4ab799 100644 --- a/Echo/i18n/ks-arab.json +++ b/Echo/i18n/ks-arab.json @@ -1,8 +1,26 @@ { "@metadata": { "authors": [ - "Shahwaqar" + "Iflaq", + "Rishabhbhat", + "Shahwaqar", + "Tajamul9" ] }, - "echo-displaynotificationsconfiguration-sorting-by-section-header": "اَلَگ اَلَگ قٕسٕمن چھانٛٹ دِنۍ" + "prefs-echo": "اِطلا", + "prefs-description-echo": "اطلاع کَمہٕ چُنِیوٚ {{GENDER:|تُہہ}} حأصل کرنہٕ کھٲترٕ تہٕ تِمہٕ رٹنہٕ کھأترٕ.", + "echo-pref-web": "ویب", + "echo-pref-email": "برقی خط", + "echo-pref-push": "ایپلِیکیشَن", + "echo-pref-email-format-html": "ایچ ٹی ایم ایل", + "echo-pref-email-format-plain-text": "سادٕ مَتَن", + "echo-log": "عَوٲمی لاگ", + "echo-new-messages": "تۄہہِ چھُوٕ بَحَث صَفَس پؠٹھ اَکھ نۆو پٲغام", + "echo-displaynotificationsconfiguration-sorting-by-section-header": "اَلَگ اَلَگ قٕسٕمن چھانٛٹ دِنؠ", + "notification-timestamp-today": "اَز", + "notification-timestamp-yesterday": "راتھ", + "notification-inbox-filter-read": "پَرُن", + "notification-inbox-filter-all": "سٲری", + "echo-date-today": "اَز", + "echo-date-yesterday": "راتھ" } diff --git a/Echo/i18n/ksw.json b/Echo/i18n/ksw.json index a53ad270..0364cd75 100644 --- a/Echo/i18n/ksw.json +++ b/Echo/i18n/ksw.json @@ -4,5 +4,9 @@ "SawJaemin" ] }, - "tooltip-pt-notifications-alert": "{{GENDER:|န}} ဟ့ၣ်ပလီၢ်" + "echo-new-messages": "နအိၣ်ဒီး တၢ်ကတိၤကဘျံးပၤ မဲစ့းအသီတခါ", + "tooltip-pt-notifications-alert": "{{GENDER:|န}} ဟ့ၣ်ပလီၢ်", + "notification-link-text-collapse-all": "မၤလီၤပှီၢ်", + "notification-inbox-filter-all": "ခဲလၢာ်", + "echo-overlay-link": "တၢ်ဘိးဘၣ်သ့ၣ်ညါခဲလၢာ်" } diff --git a/Echo/i18n/ku-latn.json b/Echo/i18n/ku-latn.json index 7d2b9511..6c591913 100644 --- a/Echo/i18n/ku-latn.json +++ b/Echo/i18n/ku-latn.json @@ -1,9 +1,11 @@ { "@metadata": { "authors": [ + "Balyozxane", "Bikarhêner", "George Animal", - "Ghybu" + "Ghybu", + "Guherto" ] }, "prefs-emailsettings": "Vebijarkên e-nameyê", @@ -11,9 +13,9 @@ "echo-pref-email": "E-name", "echo-pref-email-format-html": "HTML", "echo-learn-more": "Bêhtir hîn bibe", - "echo-new-messages": "Peyamên nû ji te re hene", + "echo-new-messages": "Peyamên te yên nû hene li ser rûpela te ya gotûbêjê", "echo-category-title-system": "{{PLURAL:$1|Pergal}}", - "echo-category-title-user-rights": "{{PLURAL:$1|Guherandina mafên bikarhêran|Guherandinan mafên bikarhêneran}}", + "echo-category-title-user-rights": "{{PLURAL:$1|Guhartina mafên bikarhêran|Guhartinên mafên bikarhêneran}}", "tooltip-pt-notifications-alert": "{{GENDER:|Agahdariyên}} te", "echo-displaynotificationsconfiguration-enabled-default-existing-users-legend": "Bikarhênerên hene", "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "Bikarhênerên nû", @@ -22,14 +24,19 @@ "echo-notification-markasread": "Wek xwendî nîşan bide", "echo-notification-markasunread": "Wek nexwendî nîşan bide", "echo-notification-markasread-tooltip": "Wek xwendî nîşan bide", - "notification-link-text-view-changes": "Guherandinan {{GENDER:$1|bibîne}}", + "notification-link-text-view-changes": "Guhartinan {{GENDER:$1|bibîne}}", "notification-link-text-view-page": "Rûpelê bibîne", "notification-link-text-what-links-here": "Hemû girêdanên ber bi vê rûpelê ve", "notification-header-mention-other-nosection": "$1 li ser <strong>$4</strong> {{GENDER:$2|qala}} {{GENDER:$3|te}} kir.", "notification-compact-header-mention-failure-user-unknown": "<strong>Navê bikarhêner tune ye:</strong> $1", "notification-welcome-linktext": "Tu bi xêr hatî", + "notification-header-thank-you-1-edit": "{{GENDER:$2|Te}} guhartina {{GENDER:$2|xwe}} ya yekem kiriye; mala {{GENDER:$2|te}} ava û bi xêr hatî!", + "notification-header-thank-you-10-edit": "{{GENDER:$2|Te}} guhartina {{GENDER:$2|xwe}} ya dehem kiriye; mala {{GENDER:$2|te}} ava, xêra xwe dest jê bernede!", + "notification-header-thank-you-100-edit": "{{GENDER:$2|Te}} guhartina {{GENDER:$2|xwe}} ya sedem kiriye; mala {{GENDER:$2|te}} sed caran ava!", + "notification-header-thank-you-1000-edit": "{{GENDER:$2|Te}} guhartina {{GENDER:$2|xwe}} ya hezarem kiriye; mala {{GENDER:$2|te}} hezar caran ava!", + "notification-header-thank-you-10000-edit": "{{GENDER:$2|Te}} guhartina {{GENDER:$2|xwe}} ya dehhezarem kiriye; mala {{GENDER:$2|te}} deh hezar caran ava!", "notification-header-emailuser": "$1 peyamek ji te re {{GENDER:$2|şand.}}", - "notification-user-rights-email-subject": "Mafên te yên bikarhêneriyê li ser {{SITENAME}} hatin guherandin.", + "notification-user-rights-email-subject": "Mafên {{GENDER:$3|te}} yên bikarhêneriyê li ser {{SITENAME}} hatin guherandin", "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1s}}", "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1d}}", "notification-timestamp-ago-hours": "{{PLURAL:$1|$1st}}", diff --git a/Echo/i18n/ky.json b/Echo/i18n/ky.json deleted file mode 100644 index bcaa4b00..00000000 --- a/Echo/i18n/ky.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Janatkg" - ] - } -} diff --git a/Echo/i18n/lb.json b/Echo/i18n/lb.json index 5d8a5520..7bba09c4 100644 --- a/Echo/i18n/lb.json +++ b/Echo/i18n/lb.json @@ -13,6 +13,10 @@ "prefs-echosubscriptions": "Mech iwwer dës Evenementer informéieren", "prefs-echocrosswiki": "Cross-Wiki Notifikatiounen", "prefs-blocknotificationslist": "Verstoppt Benotzer", + "prefs-mutedpageslist": "Säite fir déi d'Notifikatioune fir Säite-Verlinkungen ausgeschalt sinn", + "prefs-echopollupdates": "Direkt mellen", + "echo-mobile-notifications-filter-title": "Notifikatioune filteren", + "echo-pref-show-poll-updates": "Nei Notifikatioune weisen esoubal wéi se ukommen", "echo-pref-send-me": "Mir schécken:", "echo-pref-send-to": "Schécken un:", "echo-pref-email-format": "E-Mail-Format:", @@ -27,10 +31,11 @@ "echo-pref-email-format-plain-text": "Kloertext", "echo-pref-cross-wiki-notifications": "Notifikatioune vun anere Wikie weisen", "echo-pref-notifications-blacklist": "Notifikatioune vun dëse Benotzer net weisen.\n([[mw:Special:MyLanguage/Help:Notifications#mute|méi gewuer ginn]])", + "echo-pref-notifications-page-linked-title-muted-list": "Weis keng Notifikatioune fir 'Säite-Verlinkungen' fir dës Säiten. ([[mw:Special:MyLanguage/Help:Notifications#mute|méi gewuer ginn]])", "echo-learn-more": "Fir méi ze wëssen", "echo-log": "Ëffentlecht Logbuch", - "echo-new-messages": "Dir hutt nei Messagen", - "echo-category-title-edit-user-talk": "Diskussiounssäit {{PLURAL:$1|Message|Messagen}}", + "echo-new-messages": "Dir hutt en neie Message op Ärer Diskussiounssäit", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Ännerung|Ännerungen}} op menger Diskussiounssäit", "echo-category-title-article-linked": "{{PLURAL:$1|Säitelink|Säitelinken}}", "echo-category-title-reverted": "{{PLURAL:$1|Zrécksetzung|Zrécksetzungen}} änneren", "echo-category-title-mention": "{{PLURAL:$1|Mentioun|Mentiounen}}", @@ -43,7 +48,10 @@ "echo-category-title-user-rights": "{{PLURAL:$1|Ännerung vu Benotzerrechter|Ännerunge vu Benotzerrechter}}", "echo-category-title-emailuser": "{{PLURAL:$1|E-Mail vun engem anere Benotzer|E-Maile vun anere Benotzer}}", "echo-category-title-article-reminder": "Säit {{PLURAL:$1|Erënnerung|Erënnerungen}}", - "echo-pref-tooltip-edit-user-talk": "Mech informéiere wann een eppes op meng Diskussiounssäit schreift oder do äntwert.", + "echo-category-title-thank-you-edit": "{{PLURAL:$1|Kilometersteen|Kilometersteng}} vun den Ännerungen", + "echo-category-title-watchlist": "Ännerung op enger iwwerwaachter Säit", + "echo-category-title-minor-watchlist": "Kleng Ännerung op enger iwwerwaachter Säit", + "echo-pref-tooltip-edit-user-talk": "Mech informéiere wann een eppes op meng Benotzer-Diskussiounssäit setzt.", "echo-pref-tooltip-article-linked": "Mech informéiere wann een an engem Artikel op eng aner Säit verlinkt, déi ech kreéiert hunn.", "echo-pref-tooltip-reverted": "Mech informéiere wann ee meng Ännerung zerécksetzt oder wann de 'Rollback'-Tool benotzt gëtt.", "echo-pref-tooltip-mention": "Mech informéiere wann een e Link op meng Benotzersäit setzt.", @@ -52,6 +60,7 @@ "echo-pref-tooltip-user-rights": "Mech informéiere wann ee meng Benotzerrechter ännert.", "echo-pref-tooltip-emailuser": "Mech informéiere wann ee mir en E-Mail schéckt.", "echo-pref-tooltip-article-reminder": "Mech iwwer dës Säit notifiéieren wann ech froen.", + "echo-pref-tooltip-thank-you-edit": "Mech informéieren wann ech meng éischt, zéngt, honnerst... Ännerung gemaach hunn.", "notifications": "Notifikatiounen", "tooltip-pt-notifications-alert": "{{GENDER:|Är}} Meldungen", "tooltip-pt-notifications-notice": "{{GENDER:|Är}} Notifikatiounen", @@ -72,10 +81,11 @@ "echo-specialpage-markasread": "Notifikatioun: Als gelies markéieren", "echo-specialpage-markasread-invalid-id": "Net valabel ID vun engem Evenement", "echo-specialpage-pagefilterwidget-aria-label": "No Wiki a Säitentitel filteren", + "echo-specialpage-special-help-menu-widget-aria-label": "Zousätzlech Optiounen an Astellunge fir Notifikatiounen.", "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|Notifikatioun|Notifikatiounen}}", "echo-specialpage-pagination-range": "$1 bis $2", "echo-specialpage-pagefilters-title": "Rezent Aktivitéit", - "echo-specialpage-pagefilters-subtitle": "Säite mat net geliesten Notifikatiounen", + "echo-specialpage-pagefilters-subtitle": "Säite mat net geliesen Notifikatiounen", "notificationsmarkread-legend": "Notifikatioun als gelies markéieren", "echo-none": "Dir hutt keng Notifikatiounen.", "echo-api-failure": "D'Notifikatioune konnten net ofgeruff ginn.", @@ -134,6 +144,8 @@ "notification-header-user-rights-remove-only": "{{GENDER:$4|Är}} Benotzerrechter goufe {{GENDER:$1|geännert}}. Dir sidd net méi Member vun: $2.", "notification-header-user-rights-add-and-remove": "{{GENDER:$6|Är}} Benotzerrechter goufe {{GENDER:$1|geännert}}. Dir sidd elo Member vun: $2. Dir sidd net méi Member vun: $4.", "notification-header-welcome": "{{GENDER:$2|Wëllkomm}} op {{SITENAME}}, $1! Mir si frou, datt {{GENDER:$2|Dir}} do sidd.", + "notification-header-watchlist-multiuser-changed": "<strong>$1</strong>, eng Säit vun {{GENDER:$2|Ärer}} Iwwerwaachungslëscht, gouf $3 {{PLURAL:$3|eemol|$3 mol}} geännert.", + "notification-body-watchlist-once": "Et gëtt keng weider e-mail-Notifikatiounen am Fall vu spéiderer Aktivitéit et sief {{GENDER:$1|Dir besicht}} dës Säit wärend deem Dir ageloggt sidd.", "notification-welcome-linktext": "Wëllkomm", "notification-header-thank-you-1-edit": "{{GENDER:$2|Dir}} hutt elo grad {{GENDER:$2|Är}} éischt Ännerung op {{SITENAME}} gemaach; Villmools {{GENDER:$2|Merci}}, a wëllkomm!", "notification-header-thank-you-10-edit": "{{GENDER:$2|Dir}} hutt elo grad {{GENDER:$2|Är}} zéngt Ännerung gemaach; Villmools {{GENDER:$2|Merci}}, a maacht esou weider!", @@ -163,7 +175,7 @@ "notification-inbox-filter-read": "Gelies", "notification-inbox-filter-unread": "Net gelies", "notification-inbox-filter-all": "All", - "echo-specialmute-label-mute-notifications": "Notifikatioune vun dësem Benotzer net méi weisen", + "echo-specialmute-label-mute-notifications": "Notifikatioune vun {{GENDER:$1|dësem Benotzer|dëser Bemnotzerin}} net méi weisen", "echo-email-plain-footer": "Fir ze kontrolléiere wat fir eng E-Mailen mir {{GENDER:$1|Iech}} schécken, kuckt an {{GENDER:$1|Ären}} Astellungen:", "echo-email-html-footer-preference-link-text": "kuckt {{GENDER:$1|Är}} Astellungen no", "echo-email-html-footer-with-link": "Fir ze kontrolléiere wat fir eng E-Mailen mir {{GENDER:$2|Iech}} schécken, $1.", diff --git a/Echo/i18n/lez.json b/Echo/i18n/lez.json new file mode 100644 index 00000000..abe011af --- /dev/null +++ b/Echo/i18n/lez.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Mugerganets" + ] + }, + "tooltip-pt-notifications-alert": "{{GENDER:|Ви}} хабар гунар" +} diff --git a/Echo/i18n/lij.json b/Echo/i18n/lij.json index defe51a0..bf20cbd4 100644 --- a/Echo/i18n/lij.json +++ b/Echo/i18n/lij.json @@ -156,12 +156,12 @@ "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>, 'na paggina inta {{GENDER:$2|to}} lista d'oservassion, a l'è stæta ripristinâ $3 {{PLURAL:$3|votta|votte}}.", "notification-welcome-linktext": "Benvegnuo", "notification-header-thank-you-1-edit": "T'hæ apen-a fæto a to primma modiffica; grassie e {{GENDER:$2|benvegnuo|benvegnua|benvegnuo/a}}!", - "notification-header-thank-you-10-edit": "{{GENDER:$2|}} T'hæ apen-a fæto a to dexima modiffica; grassie e continnoa coscie!", - "notification-header-thank-you-100-edit": "{{GENDER:$2|}} T'hæ apen-a fæto a to sentexima modiffica; grassie mille!", + "notification-header-thank-you-10-edit": "T'hæ apen-a fæto a to dexima modiffica; grassie e {{GENDER:$2|continnoa}} coscie!", + "notification-header-thank-you-100-edit": "T'hæ apen-a fæto a to sentexima modiffica; {{GENDER:$2|grassie mille}}!", "notification-header-thank-you-1000-edit": "T'hæ apen-a fæto a to milexima modiffica; grassie pe ese {{GENDER:$2|un gran contributô|una gran contributoa}}!", - "notification-header-thank-you-10000-edit": "{{GENDER:$2|}} T'hæ apen-a fæto a to dexemilexima modiffica; grassie mille!", - "notification-header-thank-you-100000-edit": "T'hæ apen-a fæto a to sentomilexima modiffica; grassie pe-o {{GENDER:$2|}} to incredibbile contributo!", - "notification-header-thank-you-1000000-edit": "T'hæ apen-a fæto a to milionexima modiffica; grassie pe-o {{GENDER:$2|}} to abarlugante contributo!", + "notification-header-thank-you-10000-edit": "T'hæ apen-a fæto a to dexemilexima modiffica; {{GENDER:$2|grassie mille}}!", + "notification-header-thank-you-100000-edit": "T'hæ apen-a fæto a to sentomilexima modiffica; grassie pe-o {{GENDER:$2|to}} incredibbile contributo!", + "notification-header-thank-you-1000000-edit": "T'hæ apen-a fæto a to milionexima modiffica; grassie pe-o {{GENDER:$2|to}} abarlugante contributo!", "notification-link-thank-you-edit": "A {{GENDER:$1|to}} modiffica", "notification-link-text-view-edit": "Amia a modiffica", "notification-link-article-reminder": "Amia a paggina", diff --git a/Echo/i18n/lki.json b/Echo/i18n/lki.json index 781911c5..26534222 100644 --- a/Echo/i18n/lki.json +++ b/Echo/i18n/lki.json @@ -1,13 +1,14 @@ { "@metadata": { "authors": [ + "Beginneruser", "Hosseinblue", "Lakzon", "Reza1615" ] }, "echo-desc": "سامانهٔ آگاهسازی کاربران از رویدادها و پیامها", - "prefs-echo": "اعلانها", + "prefs-echo": "آگاهسازیها", "prefs-emailsettings": "تنظیمات ایمیل", "prefs-echosubscriptions": "مرا از این رویدادها آگاه کن", "echo-pref-send-me": "برایم فرستاده شود:", diff --git a/Echo/i18n/lld.json b/Echo/i18n/lld.json index b1a4f6ce..3ebd9f02 100644 --- a/Echo/i18n/lld.json +++ b/Echo/i18n/lld.json @@ -4,5 +4,6 @@ "Starladin" ] }, + "notifications": "Notificaziuns", "tooltip-pt-notifications-alert": "{{GENDER:|Tü}}avisc" } diff --git a/Echo/i18n/lmo.json b/Echo/i18n/lmo.json new file mode 100644 index 00000000..352d111e --- /dev/null +++ b/Echo/i18n/lmo.json @@ -0,0 +1,227 @@ +{ + "@metadata": { + "authors": [ + "Salvemm el lombard" + ] + }, + "echo-desc": "Sistema de notificà ai utent i messagg e i aveniment", + "prefs-echo": "Notifiche", + "prefs-emailsettings": "Opzion de la posta eletronica", + "prefs-echosubscriptions": "Mandom una notifica sora 'sti aveniment chì", + "prefs-echocrosswiki": "Notifiche intra 'na wiki e l'altra", + "prefs-blocknotificationslist": "Utent che fann citto", + "prefs-mutedpageslist": "Pagine che fann citto quant ai notifiche de conligament tra i pagine", + "prefs-echopollupdates": "Notifiche del viv", + "echo-mobile-notifications-filter-title": "Filtra i notifiche", + "echo-pref-show-poll-updates": "Mostra i notifiche noeuve ntanta che riven", + "echo-pref-show-poll-updates-help": "Mostra el numero de notifiche minga lesgiude in la sbara del titol e mostra subit un tochell de ciascheduna notifica apena pe la riva.", + "echo-pref-send-me": "Mandomː", + "echo-pref-send-to": "Manda aː", + "echo-pref-email-format": "Formad di messagg de la posta eletronicaː", + "echo-pref-web": "Red", + "echo-pref-email": "Posta eletronica", + "echo-pref-push": "Aplicazzion", + "echo-pref-email-frequency-never": "Mandom minga di notifiche con la posta eletronica", + "echo-pref-email-frequency-immediately": "Notifiche in deperlore meneman che riven", + "echo-pref-email-frequency-daily": "Un sunt giornader di notifiche", + "echo-pref-email-frequency-weekly": "Un sunt setimanal di notifiche", + "echo-pref-email-format-html": "HTML", + "echo-pref-email-format-plain-text": "Test normal", + "echo-pref-cross-wiki-notifications": "Mostra i notifiche de alter wiki", + "echo-pref-notifications-blacklist": "Mostra no i notifiche che chi utent chì. ([[mw:Special:MyLanguage/Help:Notifications#mute|per savenn pussee]])", + "echo-pref-notifications-page-linked-title-muted-list": "Mostra no i notifiche \"Conligament a una pagina\" per queste pagine chì ([[mw:Special:MyLanguage/Help:Notifications#mute|ulteriori informazioni]])", + "echo-pref-dont-email-read-notifications": "Includ minga i notifiche de letura in di messagg de posta eletrica de riassont", + "echo-learn-more": "Per savenn pussee", + "echo-log": "Register publich", + "echo-new-messages": "Te gh'hee di messagg noeuv in la pagina de ciciarada.", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Coment}} in de la mia pagina de ciciarada", + "echo-category-title-article-linked": "{{PLURAL:$1|Conligament}} a 'na pagina", + "echo-category-title-reverted": "{{PLURAL:$1|Modifega anulada|Modifeghe annulade}}", + "echo-category-title-mention": "{{PLURAL:$1|Menzion}}", + "echo-category-title-mention-failure": "{{PLURAL:$1|Menzion}} in eror", + "echo-category-title-mention-success": "{{PLURAL:$1|Menzion riessida|Menzion riesside}}", + "echo-category-title-other": "{{PLURAL:$1|Alter}}", + "echo-category-title-system": "{{PLURAL:$1|Sistema}}", + "echo-category-title-system-noemail": "{{PLURAL:$1|Sistema}}", + "echo-category-title-system-emailonly": "{{PLURAL:$1|Sistema}}", + "echo-category-title-user-rights": "{{PLURAL:$1|Modifega ai dirit|Modifeghe ai dirit}} de l'utente", + "echo-category-title-emailuser": "{{PLURAL:$1|messagg de posta eletronica d'un alter utent|messagg de posta eletronica da alter utent}}", + "echo-category-title-article-reminder": "{{PLURAL:$1|promemoria}} de la pagina", + "echo-category-title-thank-you-edit": "{{PLURAL:$1|mreja milIara|preje miliare}} de modifeghe", + "echo-category-title-watchlist": "Modifega a la pagina vardada", + "echo-category-title-minor-watchlist": "Modifega piscinina a la pagina vardada", + "echo-pref-tooltip-edit-user-talk": "Avisom quand che 'n quaivun el fà di cambiament a la mia pagina de ciciarada.", + "echo-pref-tooltip-article-linked": "Avisom quand che un quaivun el conliga una pagina che hoo cread a un'altra pagina.", + "echo-pref-tooltip-reverted": "Avisom quand che un quaivun l'inversa una modifega che hoo fad, cont el drovà i istrument \"anula\" o \" torna indree\".", + "echo-pref-tooltip-mention": "Avisom quand che un quaivun el conliga la pagina de la mia utenza.", + "echo-pref-tooltip-mention-failure": "Avisom quand che hoo podùu minga mandà una menzion a 'n quadun", + "echo-pref-tooltip-mention-success": "Avisom quand che mandi una menzion a 'n quaidun", + "echo-pref-tooltip-user-rights": "Avisom quand che 'n quaivun el cambia i me dirit de utent.", + "echo-pref-tooltip-emailuser": "Avisom quand che un quaivun el me manda di messagg de posta eletronica.", + "echo-pref-tooltip-article-reminder": "Mandom di avis sora questa pagina chi quand che 'l domandi.", + "echo-pref-tooltip-thank-you-edit": "Avisom quand che hoo rasgiont la mia prima modifega, decima modifega la motifega quella di cent...", + "echo-pref-tooltip-watchlist": "Avisom quand che un quaivun el fà una modifega (minga piscinina) a 'na pagina che tegni d'oeugg", + "echo-pref-tooltip-minor-watchlist": "Avisom quand che 'n quaidun el fà una modifega piscinina a una pagina che tegni d'oeugg", + "notifications": "Notifiche", + "tooltip-pt-notifications-alert": "{{GENDER:|I to}} avis", + "tooltip-pt-notifications-notice": "{{GENDER:|I to}} notizzi", + "echo-displaynotificationsconfiguration": "Mostra l'impostazzion di notifiche", + "echo-displaynotificationsconfiguration-summary": "Questa chì a l'è una veduda di come i notifiche a inn impostade in quel wiki chì.", + "echo-displaynotificationsconfiguration-notifications-by-category-header": "Notifiche per categoria", + "echo-displaynotificationsconfiguration-sorting-by-section-header": "Ordinament di tipi", + "echo-displaynotificationsconfiguration-sorting-by-section-legend": "In qual sezzion l'è ordinad ciaschedun tipo de notifica", + "echo-displaynotificationsconfiguration-available-notification-methods-header": "Metod de notifica permetud", + "echo-displaynotificationsconfiguration-available-notification-methods-by-category-legend": "Quai metod de notifica a inn suportad per ciascheduna categoria", + "echo-displaynotificationsconfiguration-enabled-default-header": "Ativad per impostazzion predefinida", + "echo-displaynotificationsconfiguration-enabled-default-existing-users-legend": "Utent esistent", + "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "Utent noeuv", + "echo-displaynotificationsconfiguration-mandatory-notification-methods-header": "Metod de notifica obligatori", + "echo-displaynotificationsconfiguration-mandatory-notification-methods-by-category-legend": "Quai metod de notifica a inn obligatori per ogni categoria", + "echo-specialpage": "Notifiche", + "echo-specialpage-section-markread": "Marca el grup come lesgiud", + "echo-specialpage-markasread": "Notificheː Marca come lesgiuda", + "echo-specialpage-markasread-invalid-id": "ID de l'aveniment minga valid", + "echo-specialpage-pagefilterwidget-aria-label": "Fitra a segonda del wiki e del titol de la pagina", + "echo-specialpage-special-help-menu-widget-aria-label": "Opzion adizzionai e preferenze de notifica.", + "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|notifica|notifiche}}", + "echo-specialpage-pagefilters-title": "Atività recente", + "echo-specialpage-pagefilters-subtitle": "Pagine con di notifiche nananmò lesgiude", + "notificationsmarkread-legend": "Marca i notifiche come lesgiude", + "echo-none": "Te gh'hee nissuna notifica.", + "echo-api-failure": "A l'è stad no possibil recuperà i modifighe.", + "echo-api-failure-cross-wiki": "L'entrada in del domini distant l'è stada negada.", + "echo-notification-placeholder": "A gh'è minga de notifiche", + "echo-notification-placeholder-filters": "A ghe 'n è minga de notifiche che corisponden a 'sti criteri chì.", + "echo-notification-loginrequired": "Te gh'hee de andà dent per vedè i to notifiche.", + "echo-notification-popup-loginrequired": "Và dent per vardà i to notifiche.", + "echo-notification-markasread": "Marca come sgiamò lesgiud", + "echo-notification-markasunread": "Marca come nananmò lesgiud", + "echo-notification-markasread-tooltip": "Marca come sgiamò lesgiud", + "echo-notification-more-options-tooltip": "Alter opzion", + "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|Impon de fà citto}} ai notifiche de conligament a la pagina \"$1\"", + "notification-dynamic-actions-mute-page-linked-confirmation": "I notifiche sora el \"conligament a la pagina\" adess a inn disativade per \"$1\"", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|Te}} manesget i pagine che te voeret che i faghen citto in di [$1 to preferenze] quand che te voeuret.", + "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2|Fagh desmet de fà citto}} ai notifiche de conligament a la pagina \"$1\"", + "notification-dynamic-actions-unmute-page-linked-confirmation": "I notifiche sora el \"conligament a la pagina\" adess a inn ativade per la pagina \"$1\"", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|Te}} podet gestì i pagine mute in di [$1 to preferenze] quand che te voeuret.", + "notification-dynamic-actions-unwatch": "{{GENDER:$3|Desmet}} de tegnì d'oeugg i atività noeuve \"$1\"", + "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3|Te}} seet pu adree a tegnì d'oeugg la pagina \"$1\"", + "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|Te podet}} tacà a tegnì d'oeugg [$2 questa pagina chì] quand che te voeuret.", + "notification-dynamic-actions-watch": "{{GENDER:$3|Segui}} i atività noeuve in su \"$1\"", + "notification-dynamic-actions-watch-confirmation": "{{GENDER:$3|Te}} see 'dree a tegnì d'oeugg la pagina \"$1\"", + "notification-dynamic-actions-watch-confirmation-description": "{{GENDER:$3|Te podet}} toeu via [$2 questa pagina chì] di osservad speciai quand che te voeuret.", + "notification-link-text-expand-all": "Slarga", + "notification-link-text-expand-alert-count": "Varda {{PLURAL:$1|$1 avis}}", + "notification-link-text-expand-notice-count": "Varda {{PLURAL:$1|$1 notizzi|$1 notizzie}}", + "notification-link-text-expand-all-count": "Varda {{PLURAL:$1|$1 notifica|$1 notifiche}}", + "notification-link-text-collapse-all": "Comprimm", + "notification-link-text-view-message": "Varda el messagg", + "notification-link-text-view-mention": "Varda la menzion", + "notification-link-text-view-mention-failure": "{{PLURAL:$1|Varda la menzion|Varda i menzion}}", + "notification-link-text-view-changes": "{{GENDER:$1|Varda}} i modifiche", + "notification-link-text-view-page": "Varda la pagina", + "notification-header-edit-user-talk": "{{GENDER:$2|El $1|La $1| $1 el/la}} l'ha lassad sgiò un messagg in su la <strong>{{GENDER:$3|toa}} pagina de discussion</strong>.", + "notification-header-edit-user-talk-with-section": "{{GENDER:$2|El $1|La $1| $1}} l'hà lassad sgiò un messagg in su la <strong>{{GENDER:$3|toa}} pagina de discussion </strong> in \"<strong>$4</strong>\".", + "notification-compact-header-edit-user-talk": "{{GENDER:$2|El $1|La $1| $1}} l'hà lassad un messagg per {{GENDER:$3|ti}}", + "notification-compact-header-edit-user-talk-with-section": "{{GENDER:$2|El $1|La $1| $1 el/la}} l'hà lassad un messagg {{GENDER:$3|ti}} in \"<strong>$4</strong>\".", + "notification-header-page-linked": "A l'è stad cread un conligament de <strong>$4</strong> a <strong>$3</strong>.", + "notification-compact-header-page-linked": "Coligada de <strong>$1</strong>.", + "notification-bundle-header-page-linked": "A in stad cread i conligament de {{PLURAL:$5||$5 pagine|100=pussee de 99 pagine}} a <strong>$3</strong>.", + "notification-header-article-reminder": "Una pagina che {{GENDER:$2|}} t'hee domandad che la te vegna ricordada a l'è in <strong>$3</strong>", + "notification-link-text-what-links-here": "Tucc i conligament a questa pagina chì", + "notification-header-mention-other": "{{GENDER:$2|El $1 el|La $1 la|$1 el/la}} t'ha {{GENDER:$3|menzionad|menzionada|menzionad/da}} in su <strong>$4</strong> in \"<strong>$5</strong>\".", + "notification-header-mention-other-nosection": "{{GENDER:$2|El $1 el|La $1 la|$1 el/la}} t'ha {{GENDER:$3|menzionad|menzionada|menzionad/da}} in su <strong>$4</strong>", + "notification-header-mention-user-talkpage-v2": "{{GENDER:$2|El $1 el|La $1 la|$1 el/la}} t'ha {{GENDER:$3|menzionad|menzionada|menzionad/da}} in la <strong>pagina de discussion de l'utenza {{GENDER:$5|del|de la}} $4</strong> in \"<strong>$6</strong>\".", + "notification-header-mention-user-talkpage-nosection": "{{GENDER:$2|El $1 el|La $1 la|$1 el/la}} t'ha {{GENDER:$3|menzionad|menzionada|menzionad/da}} in la <strong>pagina de discussion de l'utenza {{GENDER:$5|del|de la}} $4.", + "notification-header-mention-agent-talkpage": "{{GENDER:$2|El $1 el|La $1 la|̩$1 el/la}} t'ha {{GENDER:$3|menzionad|menzionada|menzionad/da}} in la <strong>{{GENDER:$2|soa}} pagina de discussion in \"<strong>$4</strong>\".", + "notification-header-mention-agent-talkpage-nosection": "{{GENDER:$2|El $1 el|La $1 la|̩$1 el/la}} t'ha {{GENDER:$3|menzionad|menzionada|menzionad/da}} in de la <strong>{{GENDER:$2|soa}} pagina de discussion.", + "notification-header-mention-article-talkpage": "{{GENDER:$2|El $1 el|La $1 la|̩$1 el/la}} t'ha {{GENDER:$3|menzionad|menzionada|menzionad/da}} in la pagina de discussion <strong>$4</strong> in \"<strong>$5</strong>\".", + "notification-header-mention-article-talkpage-nosection": "{{GENDER:$2|El $1 el|La $1 la|̩$1 el/la}} t'ha {{GENDER:$3|menzionad|menzionada|menzionad/da}} in la pagina de discussion <strong>$4</strong>.", + "notification-header-mention-failure-user-unknown": "{{GENDER:$2|La toa}} menzion de <strong>$3</strong> l'è stada minga spedida perchè l'utent l'è stad minga trovad.", + "notification-header-mention-failure-user-anonymous": "{{GENDER:$2|La tua}} menzion de <strong>$3</strong> l'è stada minga spedida perchè <strong>$3</strong> a l'è un utent anonim.", + "notification-header-mention-failure-too-many": "{{GENDER:$2|T'hee provà a menzionà}} pussée de $3 {{PLURAL:$3|utent}}. Tute i menzion sora quell limit chì a inn stada spedide.", + "notification-header-mention-failure-bundle": "{{PLURAL:$3|Una menzion|$3 menzion}} che {{GENDER:$2|t'hee fad}} in la pagina de discussion <strong>$4</strong> {{PLURAL:$3|la po vesser minmga spedida|i poden minga vesser spedide}}.", + "notification-compact-header-mention-failure-user-unknown": "<strong>El nom de utent a l'esist minga:</strong> $1", + "notification-compact-header-mention-failure-user-anonymous": "<strong>A poden minga vesser inviade i menzion ai IP:</strong> $1", + "notification-header-mention-success": "{{GENDER:$2|La toa}} menzion de <strong>$3</strong> l'è stada spedida.", + "notification-header-mention-success-bundle": "{{PLURAL:$3|Una menzion|$3 menzion}} che {{GENDER:$2|t'hee fad}} in la pagina de discussion <strong>$4</strong> {{PLURAL:$3|l'è stada inviada|a inn stade inviade}}.", + "notification-compact-header-mention-success": "<strong>{{GENDER:$2|T'hee minzionad}}:</strong> $3", + "notification-header-mention-status-bundle": "{{PLURAL:$3|Una notifica|$3 notifiche}} quant ai menzion che {{GENDER:$2|t'hee fad}} in la pagina de discussion <strong>$4</strong>: $5 minga {{PLURAL:$5|inviada|inviade}}, $6 {{PLURAL:$6|inviada|inviade}}.", + "notification-header-user-rights-add-only": "I to dirit de utente a inn stad {{GENDER:$1|modifegad}}. Te see {{GENDER:$4|stad sgiontad|stada sgiontada}} a: $2.", + "notification-header-user-rights-remove-only": "I {{GENDER:$4|to}} dirit de utent a inn stad {{GENDER:$1|modifegad}}. te see pu un member de: $2.", + "notification-header-user-rights-add-and-remove": "I to dirit de utent a inn stad {{GENDER:$1|modifegad}}. Te see {{GENDER:$6|stad sgiontad|stada sgiontada}} a: $2. Te see pu un member de: $4.", + "notification-header-user-rights-expiry-change": "La scadenza de la {{GENDER:$4|toa}} aderenza {{PLURAL:$3|a quell grup chì|a sti grup chì}} l'è stada {{GENDER:$1|modifegada}}: $2.", + "notification-header-welcome": "{{GENDER:$2|Benvegnud|Benvesgnuda|Benvenud/da}} in su {{SITENAME}}, $1! Semm content che {{GENDER:$2|te see}} chì.", + "notification-header-mention-summary": "{{GENDER:$2|El $1 el|La $1 la|$1 el/la}} t'ha {{GENDER:$3|menzionad|menzionada|menzionad/da}} in del sunt de la modifega in su <strong>$4</strong>.", + "notification-header-watchlist-changed": "{{GENDER:$2|El $1 l'|La $1 l'|$1 l'}}hà cambiad <strong>$3</strong>, una pagina che {{GENDER:$4|te}} tegnet d'oeugg{{PLURAL:$5||, $5 volte}}.", + "notification-header-watchlist-created": "{{GENDER:$2|El $1 l'|La $1 l'|$1 l'}}ha cread <strong>$3</strong>, una pagina che {{GENDER:$4|te}} tegnet d'oeugg{{PLURAL:$5||, $5 volte}}.", + "notification-header-watchlist-deleted": "{{GENDER:$2|El $1 l'|La $1 l'|$1 l'}}ha scancelad <strong>$3</strong>, una pagina che {{GENDER:$4|te}} tegnet d'oeugg{{PLURAL:$5||, $5 volte}}.", + "notification-header-watchlist-moved": "{{GENDER:$2|El $1 l'|La $1 l'|$1 l'}}ha spostad <strong>$3</strong>, una pagina che {{GENDER:$4|te}} tegnet d'oeugg{{PLURAL:$5||, $5 volte}}.", + "notification-header-watchlist-restored": "{{GENDER:$2|El $1 l'|La $1 l'|$1 l'}}ha miss a post de noeuv <strong>$3</strong>, una pagina che {{GENDER:$4|te}} tegnet d'oeugg{{PLURAL:$5||, $5 volte}}.", + "notification-header-watchlist-multiuser-changed": "<strong>$1</strong>, voeuna di pagine che {{GENDER:$2|te}} tegned d'oeugg, l'è stada modifegada $3 {{PLURAL:$3|volta|volte}}.", + "notification-header-watchlist-multiuser-created": "<strong>$1</strong>, voeuna di pagine che {{GENDER:$2|te}} tegned d'oeugg, l'è stada creada $3 {{PLURAL:$3|volta|volte}}.", + "notification-header-watchlist-multiuser-deleted": "<strong>$1</strong>, voeuna di pagine che {{GENDER:$2|te}} tegned d'oeugg, l'è stada scancelada $3 {{PLURAL:$3|volta|volte}}.", + "notification-header-watchlist-multiuser-moved": "<strong>$1</strong>, voeuna di pagine che {{GENDER:$2|te}} tegned d'oeugg, l'è stada spostada $3 {{PLURAL:$3|volta|volte}}.", + "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>, voeuna di pagine che {{GENDER:$2|te}} tegned d'oeugg, l'è stada metuda a post 'me che l'era $3 {{PLURAL:$3|volta|volte}}.", + "notification-body-watchlist-once": "A ghe sarànn minga di alter messagg de notifega in cas de altra atività condamanch che {{GENDER:$1|te passaet dent}} in questa pagina chì intanta che te see coness.", + "notification-welcome-linktext": "Benvegnud", + "notification-header-thank-you-1-edit": "T'hee apena fad la toa prima modifega; grazie e {{GENDER:$2|benvenud|benvenuda|benvenud/da}}!", + "notification-header-thank-you-10-edit": "T'hee apena fad la toa decima modifega; grazzie e {{GENDER:$2|và adree}} inscì!", + "notification-header-thank-you-100-edit": "T'hee apena fad la toa modifega quella di cent; grazzie {{GENDER:$2|devera}}!", + "notification-header-thank-you-1000-edit": "T'hee apena fad la toa modifega quella di mila; grazzie de vesser {{GENDER:$2|un gran contributor|una granda contributora}}!", + "notification-header-thank-you-10000-edit": "T'heet apena fad la toa modifega quella di desmila; a {{GENDER:$2|te}} ringrazziom tant!", + "notification-header-thank-you-100000-edit": "T'hee apena fad la toa modifega quella di centmila; grazzie de la {{GENDER:$2|la toa contrbuzzion sorprendenta}}!", + "notification-header-thank-you-1000000-edit": "T'hee apena fad la toa modifega quella del milion; grazzie de la {{GENDER:$2|la toa contribuzzion de strasecolà}}!", + "notification-header-thank-you-10000000-edit": "T'hee apena fad la toa modifega quella di centmila; grazzie de la {{GENDER:$2|de vesser stad adree con granda generosità}}!", + "notification-link-thank-you-edit": "La {{GENDER:$1|toa}} modifega", + "notification-link-text-view-edit": "Varda la modifega", + "notification-link-article-reminder": "Varda la pagina", + "notification-header-reverted": "{{PLURAL:$4|La toa modifega|I to modifeghe}} in su <strong>$3</strong> {{PLURAL:$4|l'è stada anulada|a inn stade anulade}}{{GENDER:$2|}}", + "notification-header-emailuser": "{{GENDER:$2|El $1 el|La $1 la|$1}} t'hà mandad un messagg de posta eletronica.", + "notification-edit-talk-page-email-subject2": "{{GENDER:$2|El $1 el|La $1 la|$1 el}} {{GENDER:$3|t'}}ha lassad sgiò un messagg in su {{SITENAME}}", + "notification-page-linked-email-subject": "'Na pagina che {{GENDER:$3|t'hee cread}} a l'è stada conligada a {{SITENAME}}", + "notification-reverted-email-subject2": "{{PLURAL:$4|La {{GENDER:$3|toa}} modifega l'è stada inversada|I toe modifeghe a inn stade reversade}} {{GENDER:$2|in su}} {{SITENAME}}", + "notification-mention-email-subject": "{{GENDER:$2|El $1 el|La $1 la|$1 el}} {{GENDER:$3|t'}}ha menzionad in su {{SITENAME}}", + "notification-user-rights-email-subject": "I {{GENDER:$3|to}} dirit de utent a inn stad modifegad in su {{SITENAME}}", + "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1 s}}", + "notification-timestamp-ago-minutes": "$1 {{PLURAL:$1|min}}", + "notification-timestamp-ago-hours": "$1 {{PLURAL:$1|ora|ore}}", + "notification-timestamp-ago-days": "$1 {{PLURAL:$1|dì}}", + "notification-timestamp-ago-months": "$1 {{PLURAL:$1|mes}}", + "notification-timestamp-ago-years": "$1 {{PLURAL:$1|ann|agn}}", + "notification-timestamp-today": "Incoeu", + "notification-timestamp-yesterday": "Ier", + "notification-inbox-filter-read": "Lesgiude", + "notification-inbox-filter-unread": "Nananmò lesgiude", + "notification-inbox-filter-all": "Tusscoss", + "echo-specialmute-label-mute-notifications": "Fà che i notifiche de {{GENDER:$1|quell}} utent chì i faghen citto", + "echo-email-plain-footer": "Per controlà quai messagg de posta eletronica {{GENDER:$1|te}} vegnen mandad, verifica i {{GENDER:$1|to}} preferenze:", + "echo-email-html-footer-preference-link-text": "verifica i {{GENDER:$1|to}} preferenze", + "echo-email-html-footer-with-link": "Per controlà quai messagg de posta eletronica {{GENDER:$2|te}} vegnen mandad, $1.", + "echo-notification-alert": "{{PLURAL:$1|Avis ($1)|Avis ($1)|100=Avis (99+)}}", + "echo-notification-notice": "{{PLURAL:$1|Notizzia ($1)|Notizzi ($1)|100=Notizzi (99+)}}", + "echo-notification-alert-text-only": "Avis", + "echo-notification-notice-text-only": "Notizzi", + "echo-overlay-link": "Tute i notifiche", + "echo-overlay-title": "<b>Notifiche</b>", + "echo-mark-all-as-read": "Marcai tucce come sgiamò lesgiude", + "echo-mark-all-as-read-confirmation": "$1 {{PLURAL:$1|notifica marcada come sgiamò lesgiuda|notifiche marcade come sgiamò lesgiude}}", + "echo-mark-wiki-as-read": "Marcai tucce come sgiamò lesgiude in del wiki scernid foeura: $1", + "echo-displaysnippet-title": "Notifica noeuva", + "echo-date-today": "Incoeu", + "echo-date-yesterday": "Ier", + "notification-bundle-header-edit-user-talk-v2": "{{PLURAL:$1|Un messagg noeuv|$1 messagg noeuv|100=Pussee de 99 messagg noeuv}} in la <strong>{{GENDER:$3|toa}} pagina de discussion</strong>.", + "echo-email-batch-subject-daily": "Te gh'heet {{PLURAL:$2|una notifica noeuva|notifiche noeuve}} in {{SITENAME}} in su wikipedia", + "echo-email-batch-subject-weekly": "Te gh'heet {{PLURAL:$2|una notifica noeuva|notifiche noeuve}} in su {{SITENAME}} in questa setimana chì", + "echo-email-batch-body-intro-daily": "Ciao $1,\nL'è scià un riassont di atuività d'incoeu in su {{SITENAME}}.", + "echo-email-batch-body-intro-weekly": "Ciao $1,\nL'è scià un risassont di atività d'incoeu in su {{SITENAME}}.", + "echo-email-batch-link-text-view-all-notifications": "Varda tute i notifiche", + "notification-header-foreign-alert": "Alter avis de {{PLURAL:$5|un alter wiki|alter $5 wiki}}", + "notification-header-foreign-notice": "Alter notizzi de {{PLURAL:$5|un alterwiki|alter $5 wiki}}", + "notification-header-foreign-all": "Alter notifiche de {{PLURAL:$5|un alter wiki|$5 wiki anmò}}", + "right-manage-all-push-subscriptions": "Manesgia tucc i abonament push", + "action-manage-all-push-subscriptions": "el manesgia tut i abonament push", + "group-push-subscription-manager": "Manesgioni de abonament push", + "group-push-subscription-manager-member": "{{GENDER:$1|i manesgion de abonament push}}", + "grouppage-push-subscription-manager": "{{ns:project}}:Manesgioni di abonament push" +} diff --git a/Echo/i18n/lrc.json b/Echo/i18n/lrc.json index 42b19b8c..f30a6d16 100644 --- a/Echo/i18n/lrc.json +++ b/Echo/i18n/lrc.json @@ -44,7 +44,7 @@ "notification-link-text-view-page": "بلگه بوینیت", "notification-link-text-view-edit": "ویرایشت نه بوینیت", "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$2|یه گل پیغوم}} د {{SITENAME}} نیائه.", - "notification-page-linked-email-subject": "بلگه شما د {{نوم مالگه}} هوم پیوند بیه", + "notification-page-linked-email-subject": "بلگه شما د {{SITENAME}} هوم پیوند بیه", "notification-mention-email-subject": "$1 {{GENDER:$2|گوته}} د {{SITENAME}} شما", "notification-user-rights-email-subject": "هوقۊق کاریاری شاٛما د {{SITENAME}} آلشت دٱئٱ بیٱ", "echo-notification-alert-text-only": "زئناریا", diff --git a/Echo/i18n/lt.json b/Echo/i18n/lt.json index c23bd151..acb90896 100644 --- a/Echo/i18n/lt.json +++ b/Echo/i18n/lt.json @@ -34,8 +34,8 @@ "echo-pref-notifications-blacklist": "Nerodyti pranešimų iš šių naudotojų. ([[mw:Special:MyLanguage/Help:Notifications#mute|sužinoti daugiau]])", "echo-learn-more": "Sužinokite daugiau", "echo-log": "Viešas žurnalas", - "echo-new-messages": "Turite naujų žinučių", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Pranešimas|Pranešimai}} aptarimų puslapyje", + "echo-new-messages": "Turite naujų žinučių Aptarimo puslapyje", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Pranešimas|Pranešimai}} mano aptarimų puslapyje", "echo-category-title-article-linked": "Puslapio {{PLURAL:$1|nuoroda|nuorodos}}", "echo-category-title-reverted": "Pakeitimų {{PLURAL:$1|atmetimas|atmetimai}}", "echo-category-title-mention": "{{PLURAL:$1|Paminėjimas|Paminėjimai}}", @@ -46,7 +46,7 @@ "echo-category-title-user-rights": "{{PLURAL:$1|Naudotojo teisių pakeitimas|Naudotojo teisių pakeitimai}}", "echo-category-title-emailuser": "{{PLURAL:$1|El. laiškas iš kito naudotojo|El. laiškai iš kitų naudotojų}}", "echo-category-title-article-reminder": "Puslapio {{PLURAL:$1|priminimas|priminimai|priminimų}}", - "echo-pref-tooltip-edit-user-talk": "Pranešti man, kai kas nors parašo žinutę ar atsako mano aptarimo puslapyje.", + "echo-pref-tooltip-edit-user-talk": "Pranešti man, kai kas nors redaguoja mano aptarimo puslapį.", "echo-pref-tooltip-article-linked": "Pranešti man, kai kas nors sukuria nuorodą iš kito puslapio į mano sukurtą puslapį.", "echo-pref-tooltip-reverted": "Pranešti man, kai kas nors atmeta mano pakeitimus, naudodamasis atmetimo ar atšaukimo įrankiais.", "echo-pref-tooltip-mention": "Pranešti man, kai kas nors sukuria nuorodą į mano naudotojo puslapį.", @@ -145,13 +145,12 @@ "notification-link-text-view-edit": "Peržiūrėti redagavimą", "notification-link-article-reminder": "Žiūrėti puslapį", "notification-header-reverted": "Jūsų {{PLURAL:$4|keitimas <strong>$3</strong>|keitimai <strong>$3</strong>}} puslapyje buvo {{PLURAL:$4|atmestas|atmesti}}.", - "notification-body-reverted": "$1", "notification-header-emailuser": "$1 {{GENDER:$2|atsiuntė}} jums el. laišką.", - "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$2|paliko}} žinutę jums svetainėje {{SITENAME}}", - "notification-page-linked-email-subject": "Puslapis, kurį sukūrėte buvo susietas {{SITENAME}} tinklapyje", + "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$2|paliko}} {{GENDER:$3|Jums}} {{SITENAME}} svetainėje žinutę", + "notification-page-linked-email-subject": "Puslapis, kurį {{GENDER:$3|Jūs}} sukūrėte, buvo susietas {{SITENAME}} svetainėje", "notification-reverted-email-subject2": "Jūsų {{PLURAL:$4|pakeitimas buvo|pakeitimai buvo}} {{GENDER:$2|atšaukti}} {{SITENAME}} tinklapyje", - "notification-mention-email-subject": "$1 {{GENDER:$2|paminėjo}} {{GENDER:$3|jus}} {{SITENAME}}", - "notification-user-rights-email-subject": "Jūsų naudotojo teisės buvo pakeistos {{SITENAME}} tinklapyje", + "notification-mention-email-subject": "$1 {{GENDER:$2|paminėjo}} {{GENDER:$3|Jus}} {{SITENAME}} svetainėje", + "notification-user-rights-email-subject": "{{GENDER:$3|Jūsų}} naudotojo teisės buvo pakeistos {{SITENAME}} svetainėje", "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1s}}", "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1m}}", "notification-timestamp-ago-hours": "{{PLURAL:$1|$1h}}", @@ -163,7 +162,7 @@ "notification-inbox-filter-read": "Skaitytas", "notification-inbox-filter-unread": "Neskaitytas", "notification-inbox-filter-all": "Visi", - "echo-email-plain-footer": "Kontroliuoti, kuriuos el. laiškus Jums siunčiame, galite savo nustatymuose:", + "echo-email-plain-footer": "{{GENDER:$1|Jums}} siunčiamų el. laiškų parinktis galite valdyti {{GENDER:$1|savo}} nustatymuose:", "echo-email-html-footer-preference-link-text": "patikrinkite {{GENDER:$1|savo}} nustatymus", "echo-email-html-footer-with-link": "Kontroliuoti, kuriuos el. laiškus jums {{GENDER:$2|siunčiame}}, $1.", "echo-notification-alert": "{{PLURAL:$1|Įspėjimas ($1)|Įspėjimai ($1)|100=Įspėjimų (99+)}}", diff --git a/Echo/i18n/luz.json b/Echo/i18n/luz.json index 5cbf26ed..57b1d7af 100644 --- a/Echo/i18n/luz.json +++ b/Echo/i18n/luz.json @@ -1,7 +1,9 @@ { "@metadata": { "authors": [ + "Bluehamed", "علی ساکی لرستانی" ] - } + }, + "tooltip-pt-notifications-alert": "اٛختارٱل {{GENDER:|ایشا}}" } diff --git a/Echo/i18n/lv.json b/Echo/i18n/lv.json index 6aa111ba..bfdbf41b 100644 --- a/Echo/i18n/lv.json +++ b/Echo/i18n/lv.json @@ -22,6 +22,7 @@ "echo-pref-email-format": "E-pasta formāts:", "echo-pref-web": "Vietnē", "echo-pref-email": "E-pastā", + "echo-pref-push": "Lietotnes", "echo-pref-email-frequency-never": "Nesūtīt man e-pasta paziņojumus", "echo-pref-email-frequency-immediately": "Individuāli paziņojumi, tiklīdz tie ienāk", "echo-pref-email-frequency-daily": "Ikdienas paziņojumu kopsavilkums", @@ -33,7 +34,7 @@ "echo-pref-dont-email-read-notifications": "Neiekļaut izlasītos paziņojumus kopsavilkuma e-pastos", "echo-learn-more": "Uzzināt vairāk", "echo-log": "Publiskais žurnāls", - "echo-new-messages": "tev ir jauni paziņojumi", + "echo-new-messages": "Tev ir jauns diskusiju lapas paziņojums", "echo-category-title-edit-user-talk": "Diskusiju lapas {{PLURAL:$1|paziņojumi|paziņojums|paziņojumi}}", "echo-category-title-article-linked": "Lapas {{PLURAL:$1|saites|saite|saites}}", "echo-category-title-reverted": "{{PLURAL:$1|Atcelti labojumi|Atcelts labojums|Atcelti labojumi}}", @@ -53,6 +54,7 @@ "echo-pref-tooltip-mention": "Paziņot man, kad kāds izveido saiti uz manu dalībnieka lapu.", "echo-pref-tooltip-user-rights": "Paziņot man, kad kāds izmaina manas dalībnieka tiesības.", "echo-pref-tooltip-emailuser": "Paziņot man, kad kāds nosūta man e-pastu.", + "echo-pref-tooltip-thank-you-edit": "Paziņot man, kad es veicu 1., 10., 100., ... labojumu.", "notifications": "Paziņojumi", "tooltip-pt-notifications-alert": "{{GENDER:|Tavi}} brīdinājumi", "tooltip-pt-notifications-notice": "{{GENDER:|Tavi}} paziņojumi", @@ -68,6 +70,7 @@ "echo-specialpage-section-markread": "Atzīmēt grupu kā izlasītu", "echo-specialpage-markasread": "Paziņojums: Atzīmēt kā izlasītu", "echo-specialpage-markasread-invalid-id": "Nederīgs notikuma ID", + "echo-specialpage-pagefilterwidget-aria-label": "Filtrēt pēc vikivietnes un lapas nosaukuma", "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|paziņojumi|paziņojums|paziņojumi}}", "echo-specialpage-pagefilters-title": "Nesena aktivitāte", "echo-specialpage-pagefilters-subtitle": "Lapas ar nelasītiem paziņojumiem", @@ -80,6 +83,7 @@ "echo-notification-markasunread": "Atzīmēt kā nelasītu", "echo-notification-markasread-tooltip": "Atzīmēt kā lasītu", "echo-notification-more-options-tooltip": "Vairāk iespēju", + "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|Apklusināt}} saišu paziņojumus par \"$1\"", "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|Tu}} vari jebkurā brīdī sākt uzraudzīt [$2 šo lapu].", "notification-dynamic-actions-watch-confirmation": "{{GENDER:$3|Tu}} tagad uzraugi lapu \"$1\"", "notification-dynamic-actions-watch-confirmation-description": "{{GENDER:$3|Tu}} vari jebkurā brīdī pārtraukt uzraudzīt [$2 šo lapu].", @@ -133,7 +137,7 @@ "notification-page-linked-email-subject": "Uz {{GENDER:$3|tevis}} veidotu lapu vietnē {{SITENAME}} tika izveidota saite", "notification-reverted-email-subject2": "Jūsu {{PLURAL:$4|atcelts|labojums tika {{GENDER:$2|atcelts}}|labojumi tika {{GENDER:$2|atcelti}}}} {{SITENAME}}", "notification-mention-email-subject": "$1 {{GENDER:$2|pieminēja}} {{GENDER:$3|tevi}} vietnē {{SITENAME}}", - "notification-user-rights-email-subject": "Jūsu dalībnieka tiesības tika izmainītas {{SITENAME}}", + "notification-user-rights-email-subject": "{{GENDER:$3|Tavas}} dalībnieka tiesības tika izmainītas vietnē \"{{SITENAME}}\"", "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1 s}}", "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1 m}}", "notification-timestamp-ago-hours": "{{PLURAL:$1|$1 h}}", @@ -145,7 +149,7 @@ "notification-inbox-filter-read": "Izlasītie", "notification-inbox-filter-unread": "Nelasītie", "notification-inbox-filter-all": "Visi", - "echo-specialmute-label-mute-notifications": "Apklusināt paziņojumus no šī dalībnieka", + "echo-specialmute-label-mute-notifications": "Apklusināt paziņojumus no šī {{GENDER:$1|dalībnieka|dalībnieces}}", "echo-email-plain-footer": "Lai kontrolētu, kādus e-pastus mēs {{GENDER:$1|tev}} sūtām, pārbaudi {{GENDER:$1|savas}} izvēles:", "echo-email-html-footer-preference-link-text": "pārbaudi {{GENDER:$1|savas}} izvēles", "echo-email-html-footer-with-link": "Lai kontrolētu, kādus e-pastus mēs {{GENDER:$1|tev}} sūtām, $1.", diff --git a/Echo/i18n/mad.json b/Echo/i18n/mad.json new file mode 100644 index 00000000..deae2b5f --- /dev/null +++ b/Echo/i18n/mad.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Boesenbergia" + ] + }, + "tooltip-pt-notifications-alert": "Paèlènganna {{GENDER:|bâ'na}}" +} diff --git a/Echo/i18n/mk.json b/Echo/i18n/mk.json index be8422c8..076c3ce0 100644 --- a/Echo/i18n/mk.json +++ b/Echo/i18n/mk.json @@ -7,6 +7,7 @@ }, "echo-desc": "Систем за известување на корисници во врска со настани и пораки", "prefs-echo": "Известувања", + "prefs-description-echo": "Изберете кои објави да ги {{GENDER:|добивате}} и како ќе ги добивате.", "prefs-emailsettings": "Можности за е-пошта", "prefs-echosubscriptions": "Известувај ме за следниве настани", "prefs-echocrosswiki": "Известувања од други викија", @@ -16,12 +17,12 @@ "echo-mobile-notifications-filter-title": "Филтрирање на известувања", "echo-pref-show-poll-updates": "Прикажува нови известувања како што пристигаат", "echo-pref-show-poll-updates-help": "Прикажи број на непрочитани известувања во насловната лента, како и извадок од секое известување веднаш штом ќе пристигне.", - "echo-pref-send-me": "Испрати ми:", + "echo-pref-send-me": "Испраќај ми:", "echo-pref-send-to": "Испрати на:", "echo-pref-email-format": "Формат на е-поштата:", "echo-pref-web": "На вики", "echo-pref-email": "Е-пошта", - "echo-pref-push": "Наметни (само прилози)", + "echo-pref-push": "Прилози", "echo-pref-email-frequency-never": "Не ми праќај известувања на е-пошта", "echo-pref-email-frequency-immediately": "Поединечни известувања, едно по едно", "echo-pref-email-frequency-daily": "Дневен преглед на известувањата", @@ -34,8 +35,8 @@ "echo-pref-dont-email-read-notifications": "Не вклучувај прочитани известувања во резимираната е-пошта", "echo-learn-more": "Дознајте повеќе", "echo-log": "Јавен дневник", - "echo-new-messages": "Имате нови пораки", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Порака|Пораки}} во разговорот", + "echo-new-messages": "Имате нова порака во разговорната страница", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Уредување|Уредувања}} на мојата разговорна страница", "echo-category-title-article-linked": "{{PLURAL:$1|Врска|Врски}} до стран.", "echo-category-title-reverted": "{{PLURAL:$1|Вратено уредување|Вратени уредувања}}", "echo-category-title-mention": "{{PLURAL:$1|Споменување|Споменувања}}", @@ -51,7 +52,7 @@ "echo-category-title-thank-you-edit": "{{PLURAL:$1|Уредувачко достигнување|Уредувачки достигнувања}}", "echo-category-title-watchlist": "Уредување на набљудувана страница", "echo-category-title-minor-watchlist": "Ситно уредување на набљудувана страница", - "echo-pref-tooltip-edit-user-talk": "Извести ме кога некој ќе остави порака или ќе одговори на мојата разговорна страница.", + "echo-pref-tooltip-edit-user-talk": "Извести ме кога некој ќе ја уреди мојата разговорна страница.", "echo-pref-tooltip-article-linked": "Извести ме кога некој ќе се повика на страница што ја имам создадено од друга страница.", "echo-pref-tooltip-reverted": "Извести ме кога некој ќе откаже уредување што го имам направено користејќи ја алатката за отповикување или враќање.", "echo-pref-tooltip-mention": "Извести ме кога некој ќе се повика на мојата корисничка страница.", @@ -166,6 +167,7 @@ "notification-header-watchlist-multiuser-deleted": "<strong>$1</strong>, страница од {{GENDER:$2|вашите}} набљудувања, е избришана {{PLURAL:$3|еднаш|$3 пати}}.", "notification-header-watchlist-multiuser-moved": "<strong>$1</strong>, страница од {{GENDER:$2|вашите}} набљудувања, е преместена {{PLURAL:$3|еднаш|$3 пати}}.", "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>, страница од {{GENDER:$2|вашите}} набљудувања, е повратена {{PLURAL:$3|еднаш|$3 пати}}.", + "notification-body-watchlist-once": "Повеќе нема да има известувања по е-пошта во случај на понатамошни активности освен {{GENDER:$1|ако не ја посетите}} страницава додека сте најавени.", "notification-welcome-linktext": "Добре дојдовте", "notification-header-thank-you-1-edit": "Штотуку го {{GENDER:$2|направивте}} {{GENDER:$2|вашето}} прво уредување. {{GENDER:$2|Ви}} благодариме, и добре дојдовте!", "notification-header-thank-you-10-edit": "Штотуку го {{GENDER:$2|направивте}} {{GENDER:$2|вашето}} десетто уредување. {{GENDER:$2|Ви}} благодариме, и продолжете така!", @@ -196,7 +198,7 @@ "notification-inbox-filter-read": "Прочитани", "notification-inbox-filter-unread": "Непрочитани", "notification-inbox-filter-all": "Сите", - "echo-specialmute-label-mute-notifications": "Исклучи известувања од корисников", + "echo-specialmute-label-mute-notifications": "Исклучи известувања од {{GENDER:$1|корисников}}", "echo-email-plain-footer": "За да одберете каква е-пошта да {{GENDER:$1|ви}} праќаме, проверете {{GENDER:$1|си}} ги поставките:", "echo-email-html-footer-preference-link-text": "проверете {{GENDER:$1|си}} ги поставките", "echo-email-html-footer-with-link": "За да одберете каква е-пошта да {{GENDER:$2|ви}} праќаме, $1.", @@ -221,5 +223,10 @@ "notification-header-foreign-alert": "Повеќе напомени од {{PLURAL:$5|друго вики|$5 други викија}}", "notification-header-foreign-notice": "Уште напомени од {{PLURAL:$5|друго вики|$5 други викија}}", "notification-header-foreign-all": "Уште известувања од {{PLURAL:$5|друго вики|$5 други викија}}", - "echo-foreign-wiki-lang": "$1 — $2" + "echo-foreign-wiki-lang": "$1 — $2", + "right-manage-all-push-subscriptions": "Раководење со сите претплати на наметнувања", + "action-manage-all-push-subscriptions": "раководење со сите претлати на наметнувања", + "group-push-subscription-manager": "Ракводители на претплати на наметнувања", + "group-push-subscription-manager-member": "{{GENDER:$1|раководител на претплати на наметнувања}}", + "grouppage-push-subscription-manager": "{{ns:project}}:Раководители на претплати на наметнувања" } diff --git a/Echo/i18n/mnc.json b/Echo/i18n/mnc.json new file mode 100644 index 00000000..574d256c --- /dev/null +++ b/Echo/i18n/mnc.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Chulsu463" + ] + }, + "tooltip-pt-notifications-alert": "{{GENDER:|sini}} mejige" +} diff --git a/Echo/i18n/mni.json b/Echo/i18n/mni.json index 626193f1..e02f24b9 100644 --- a/Echo/i18n/mni.json +++ b/Echo/i18n/mni.json @@ -19,5 +19,8 @@ "notification-link-text-expand-all": "ꯄꯥꯛꯊꯣꯛꯄ", "notification-link-text-collapse-all": "ꯁꯨꯞꯆꯤꯟꯕꯥ", "notification-link-text-view-message": "ꯄꯥꯎꯖꯦꯜ ꯎꯠꯂꯨ", - "notification-link-text-view-mention": "ꯃꯤꯡ ꯄꯟꯕꯗꯨ ꯎꯠꯂꯨ" + "notification-link-text-view-mention": "ꯃꯤꯡ ꯄꯟꯕꯗꯨ ꯎꯠꯂꯨ", + "notification-header-thank-you-1-edit": "{{GENDER:$2|ꯅꯪꯅ}} ꯍꯧꯖꯤꯛꯇ {{GENDER:$2|ꯅꯍꯥꯛꯀꯤ}} ꯑꯍꯥꯟꯕ ꯏꯗꯤꯠ ꯁꯦꯝꯒꯠꯈꯔꯦ; ꯊꯥꯒꯠꯆꯔꯤ {{GENDER:$2|ꯑꯗꯣꯝꯕꯨ}}, ꯑꯃꯁꯨꯡ ꯂꯦꯡꯁꯤꯟꯕꯤꯔꯛꯁꯤ!", + "notification-header-thank-you-10-edit": "{{GENDER:$2|ꯅꯪꯅ}} ꯍꯧꯖꯤꯛꯇ {{GENDER:$2|ꯅꯍꯥꯛꯀꯤ}} ꯱꯰ꯁꯨꯕ ꯁꯦꯝꯒꯠꯄ ꯃꯁꯤꯡ ꯁꯨꯔꯦ; ꯊꯥꯒꯠꯆꯔꯤ {{GENDER:$2|ꯑꯗꯣꯝꯕꯨ}}, ꯑꯃꯁꯨꯡ ꯆꯥꯟꯕꯤꯗꯨꯅ ꯃꯈꯥ ꯆꯠꯊꯕꯤꯌꯨ!", + "notification-header-thank-you-100-edit": "{{GENDER:$2|ꯅꯪꯅ}} ꯍꯧꯖꯤꯛꯇ {{GENDER:$2|ꯅꯍꯥꯛꯀꯤ}} ꯁꯦꯝꯒꯠꯄꯁꯤ ꯱꯰꯰ ꯁꯨꯔꯩ;{{GENDER:$2|ꯑꯗꯣꯝꯕꯨ}} ꯍꯥꯏꯅꯤꯉꯥꯏ ꯂꯩꯇꯅ ꯊꯥꯒꯠꯆꯔꯤ!" } diff --git a/Echo/i18n/mnw.json b/Echo/i18n/mnw.json index 1a1be15c..548e37a2 100644 --- a/Echo/i18n/mnw.json +++ b/Echo/i18n/mnw.json @@ -1,8 +1,10 @@ { "@metadata": { "authors": [ - "Htawmonzel" + "Htawmonzel", + "咽頭べさ" ] }, - "tooltip-pt-notifications-alert": "{{GENDER:|မၞး}} မကဵုသတိဂမၠိုင်" + "tooltip-pt-notifications-alert": "{{GENDER:|မၞး}} မကဵုသတိဂမၠိုင်", + "echo-notification-alert": "{{PLURAL:$1|ကဵုသတိ ($1)|ကဵုသတိဂမၠိုင် ($1)|100=ကဵုသတိဂမၠိုင် (99+)}}" } diff --git a/Echo/i18n/ms-arab.json b/Echo/i18n/ms-arab.json new file mode 100644 index 00000000..c02423d6 --- /dev/null +++ b/Echo/i18n/ms-arab.json @@ -0,0 +1,63 @@ +{ + "@metadata": { + "authors": [ + "Tofeiku" + ] + }, + "prefs-echo": "ڤمبريتاهوان", + "echo-pref-send-me": "هانتر ساي:", + "echo-pref-email": "إي-ميل", + "echo-log": "لوݢ عوام", + "echo-new-messages": "اندا اد ڤسنن بارو", + "echo-category-title-system": "{{PLURAL:$1|سيستم}}", + "echo-category-title-system-noemail": "{{PLURAL:$1|سيستم}}", + "echo-category-title-system-emailonly": "{{PLURAL:$1|سيستم}}", + "echo-category-title-user-rights": "{{PLURAL:$1|ڤروبهن حق ڤڠݢونا}}", + "notifications": "ڤمبريتاهوان", + "tooltip-pt-notifications-alert": "نوتيس {{GENDER:|اندا}}", + "tooltip-pt-notifications-notice": "ڤمبريتاهوان {{GENDER:|اندا}}", + "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "ڤڠݢونا بارو", + "echo-specialpage": "ڤمبريتاهوان", + "echo-specialpage-pagefilters-title": "کݢياتن ترکيني", + "echo-none": "اندا تياد ڤمبريتاهوان.", + "echo-notification-markasread": "تنداءي سباݢاي دباچ", + "echo-notification-markasread-tooltip": "تنداءي سباݢاي دباچ", + "notification-link-text-expand-all": "کمبڠکن", + "notification-link-text-expand-notice-count": "ليهت {{PLURAL:$1|$1 ڤمبريتاهوان}}", + "notification-link-text-view-message": "ليهت ڤسنن", + "notification-link-text-view-mention": "ليهت سبوتن", + "notification-link-text-view-mention-failure": "{{PLURAL:$1|ليهت سبوتن}}", + "notification-link-text-view-changes": "{{GENDER:$1|ليهت}} ڤروبهن", + "notification-link-text-view-page": "ليهت لامن", + "notification-header-page-linked": "سبواه ڤاءوتن تله دبوات دري <strong>$4</strong> ک<strong>$3</strong>.", + "notification-bundle-header-page-linked": "ڤاءوتن تله دبوات دري {{PLURAL:$5||$5 لامن|100=99+ لامن}} ک<strong>$3</strong>.", + "notification-link-text-what-links-here": "سموا ڤاءوتن کلامن اين", + "notification-compact-header-mention-failure-user-unknown": "<strong>نام ڤڠݢونا تيدق وجود:</strong> $1", + "notification-welcome-linktext": "سلامت داتڠ", + "notification-link-thank-you-edit": "سونتيڠن {{GENDER:$1|اندا}}", + "notification-link-text-view-edit": "ليهت سونتيڠن", + "notification-link-article-reminder": "ليهت لامن", + "notification-header-emailuser": "$1 {{GENDER:$2|مڠهانتر}} اندا سبواه إي-ميل.", + "notification-page-linked-email-subject": "لامن يڠ {{GENDER:$3|اندا}} چيڤتا تله دڤاءوتکن ڤد {{SITENAME}}", + "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1 ساعت}}", + "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1 مينيت}}", + "notification-timestamp-ago-hours": "{{PLURAL:$1|$1 جم}}", + "notification-timestamp-ago-days": "{{PLURAL:$1|$1 هاري}}", + "notification-timestamp-ago-months": "{{PLURAL:$1|$1 بولن}}", + "notification-timestamp-ago-years": "{{PLURAL:$1|$1 تاهون}}", + "notification-timestamp-today": "هاري اين", + "notification-timestamp-yesterday": "کلمارين", + "notification-inbox-filter-read": "باچ", + "notification-inbox-filter-all": "سموا", + "echo-notification-notice": "{{PLURAL:$1|ڤمبريتاهوان ($1)|100=ڤمبريتاهوان (99+)}}", + "echo-notification-notice-text-only": "ڤمبريتاهوان", + "echo-overlay-link": "سموا ڤمبريتاهوان", + "echo-overlay-title": "<b>ڤمبريتاهوان</b>", + "echo-mark-all-as-read": "تنداءي سموا سباݢاي دباچ", + "echo-displaysnippet-title": "ڤمبريتاهوان بارو", + "echo-date-today": "هاري اين", + "echo-date-yesterday": "کلمارين", + "notification-bundle-header-edit-user-talk-v2": "{{PLURAL:$1|ساتو ڤسنن بارو|$1 ڤسنن بارو|100=99+ ڤسنن بارو}} دلامن ڤربينچڠن <strong>{{GENDER:$3|اندا}}</strong>.", + "echo-email-batch-link-text-view-all-notifications": "ليهت سموا ڤمبريتاهوان", + "notification-header-foreign-notice": "لبيه باڽق ڤمبريتاهوان درڤد {{PLURAL:$5|ويکي لاءين|$5 ويکي لاءين}}" +} diff --git a/Echo/i18n/ms.json b/Echo/i18n/ms.json index 9643a60b..1cc2d3b4 100644 --- a/Echo/i18n/ms.json +++ b/Echo/i18n/ms.json @@ -9,10 +9,12 @@ "Tofeiku" ] }, - "echo-desc": "Sistem pemberitahuan", + "echo-desc": "Sistem untuk memberitahu pengguna tentang peristiwa dan pesanan", "prefs-echo": "Pemberitahuan", "prefs-emailsettings": "Pilihan e-mel", "prefs-echosubscriptions": "Beritahu saya tentang peristiwa-peristiwa ini", + "prefs-echopollupdates": "Pemberitahuan langsung", + "echo-mobile-notifications-filter-title": "Tapis pemberitahuan", "echo-pref-send-me": "Hantarkan saya:", "echo-pref-send-to": "Hantar ke:", "echo-pref-email-format": "Format e-mel:", @@ -24,15 +26,22 @@ "echo-pref-email-frequency-weekly": "Ringkasan pemberitahuan mingguan", "echo-pref-email-format-html": "HTML", "echo-pref-email-format-plain-text": "Teks biasa", + "echo-pref-cross-wiki-notifications": "Tunjuk pemberitahuan daripada wiki lain", "echo-learn-more": "Ketahui lebih lanjut", + "echo-log": "Log awam", "echo-new-messages": "Anda mempunyai pesanan baru", "echo-category-title-edit-user-talk": "{{PLURAL:$1|Pesanan|Pesanan-pesanan}} laman perbincangan", "echo-category-title-article-linked": "{{PLURAL:$1|Pautan}} halaman", "echo-category-title-reverted": "{{PLURAL:$1|Pembalikan}} suntingan", "echo-category-title-mention": "{{PLURAL:$1|Sebutan}}", + "echo-category-title-mention-failure": "{{PLURAL:$1|Sebutan}} gagal", + "echo-category-title-mention-success": "{{PLURAL:$1|Sebutan}} berjaya", "echo-category-title-other": "{{PLURAL:$1|Lain-lain}}", "echo-category-title-system": "{{PLURAL:$1|Sistem}}", + "echo-category-title-system-noemail": "{{PLURAL:$1|Sistem}}", + "echo-category-title-system-emailonly": "{{PLURAL:$1|Sistem}}", "echo-category-title-user-rights": "{{PLURAL:$1|Perubahan hak pengguna|Perubahan-perubahan hak pengguna}}", + "echo-category-title-article-reminder": "{{PLURAL:$1|Peringatan}} laman", "echo-pref-tooltip-edit-user-talk": "Beritahu saya apabila seseorang mengirim pesanan atau membalas di laman perbincangan saya.", "echo-pref-tooltip-article-linked": "Beritahu saya apabila seseorang membuat pautan ke suatu halaman yang pernah saya wujudkan dari halaman rencana.", "echo-pref-tooltip-reverted": "Beritahu saya apabila seseorang mengundurkan suntingan saya dengan menggunakan alat 'batalkan' atau 'undur'.", @@ -40,19 +49,50 @@ "echo-pref-tooltip-user-rights": "Beritahu saya apabila seseorang mengubah hak-hak pengguna saya.", "notifications": "Pemberitahuan", "tooltip-pt-notifications-alert": "Notis {{GENDER:|anda}}", + "tooltip-pt-notifications-notice": "Notis {{GENDER:|anda}}", + "echo-displaynotificationsconfiguration-notifications-by-category-header": "Pemberitahuan mengikut kategori", + "echo-displaynotificationsconfiguration-enabled-default-existing-users-legend": "Pengguna sedia ada", + "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "Pengguna baru", + "echo-displaynotificationsconfiguration-mandatory-notification-methods-header": "Kaedah pemberitahuan yang diperlukan", "echo-specialpage": "Pemberitahuan", + "echo-specialpage-section-markread": "Tandai kumpulan sebagai dibaca", + "echo-specialpage-markasread-invalid-id": "ID peristiwa tidak sah", + "echo-specialpage-pagefilterwidget-aria-label": "Tapis mengikut wiki dan tajuk laman", + "echo-specialpage-pagefilters-title": "Kegiatan terkini", + "notificationsmarkread-legend": "Tandai pemberitahuan ini sebagai dibaca", "echo-none": "Tiada pemberitahuan untuk anda.", + "echo-notification-markasread": "Tanda sebagai sudah dibaca", + "echo-notification-markasunread": "Tanda sebagai belum dibaca", + "echo-notification-markasread-tooltip": "Tanda sebagai sudah dibaca", + "notification-link-text-expand-all": "Kembangkan", "notification-link-text-view-message": "Lihat pesanan", "notification-link-text-view-mention": "Lihat sebutan", - "notification-link-text-view-changes": "Lihat perubahan", + "notification-link-text-view-changes": "{{GENDER:$1|Lihat}} perubahan", "notification-link-text-view-page": "Lihat laman", + "notification-link-text-what-links-here": "Semua pautan ke laman ini", + "notification-compact-header-mention-failure-user-unknown": "<strong>Nama pengguna tidak wujud:</strong> $1", + "notification-compact-header-mention-failure-user-anonymous": "<strong>IP tidak boleh disebut:</strong> $1", + "notification-welcome-linktext": "Selamat datang", + "notification-header-thank-you-1-edit": "{{GENDER:$2|Anda}} baru membuat suntingan pertama {{GENDER:$2|anda}}; terima kasih, dan selamat datang!", + "notification-link-thank-you-edit": "Suntingan {{GENDER:$1|anda}}", "notification-link-text-view-edit": "Lihat suntingan", + "notification-link-article-reminder": "Lihat laman", "notification-header-reverted": "{{PLURAL:$4|Suntingan|Suntingan-suntingan}} anda di $3 telah {{GENDER:$2|dibalikkan}} oleh $1", "notification-edit-talk-page-email-subject2": "$1 telah {{GENDER:$2|meninggalkan}} pesanan untuk anda di {{SITENAME}}", "notification-page-linked-email-subject": "Laman ciptaan anda telah dipautkan dengan {{SITENAME}}", "notification-reverted-email-subject2": "{{PLURAL:$4|Suntingan|Suntingan-suntingan}} telah {{GENDER:$2|diundurkan}} di {{SITENAME}}", "notification-mention-email-subject": "$1 {{GENDER:$2|menyebut}} anda di {{SITENAME}}", "notification-user-rights-email-subject": "Hak-hak pengguna anda telah berubah di {{SITENAME}}", + "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1s}}", + "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1m}}", + "notification-timestamp-ago-hours": "{{PLURAL:$1|$1j}}", + "notification-timestamp-ago-days": "{{PLURAL:$1|$1h}}", + "notification-timestamp-ago-months": "{{PLURAL:$1|$1b}}", + "notification-timestamp-ago-years": "{{PLURAL:$1|$1t}}", + "notification-timestamp-today": "Hari ini", + "notification-timestamp-yesterday": "Kelmarin", + "notification-inbox-filter-read": "Baca", + "notification-inbox-filter-all": "Semua", "echo-notification-alert": "{{PLURAL:$1|Pesanan ($1)|100=Pesanan (99+)}}", "echo-notification-alert-text-only": "Peringatan", "echo-overlay-link": "Semua pemberitahuan", @@ -61,9 +101,11 @@ "echo-displaysnippet-title": "Pemberitahuan baru", "echo-date-today": "Hari ini", "echo-date-yesterday": "Semalam", + "notification-bundle-header-edit-user-talk-v2": "{{PLURAL:$1|Satu pesanan baru|$1 pesanan baru|100=99+ pesanan baru}} di laman perbincangan <strong>{{GENDER:$3|anda}}</strong>.", "echo-email-batch-subject-daily": "Anda ada {{PLURAL:$2|satu|beberapa}} pemberitahuan baru di {{SITENAME}}", "echo-email-batch-subject-weekly": "Anda ada {{PLURAL:$2|satu|beberapa}} pemberitahuan baru di {{SITENAME}} minggu ini", "echo-email-batch-body-intro-daily": "$1,\nYang berikut ialah ringkasan kegiatan hari ini di {{SITENAME}} untuk rujukan anda.", "echo-email-batch-body-intro-weekly": "$1,\nYang berikut ialah ringkasan kegiatan minggu ini di {{SITENAME}} untuk rujukan anda.", - "echo-email-batch-link-text-view-all-notifications": "Baca semua pemberitahuan" + "echo-email-batch-link-text-view-all-notifications": "Baca semua pemberitahuan", + "notification-header-foreign-all": "Lebih pemberitahuan daripada {{PLURAL:$5|wiki lain|$5 wiki lain}}" } diff --git a/Echo/i18n/mt.json b/Echo/i18n/mt.json index 74e2c93c..d6130494 100644 --- a/Echo/i18n/mt.json +++ b/Echo/i18n/mt.json @@ -4,7 +4,8 @@ "Amire80", "Chrisportelli", "Leli Forte", - "MTSap" + "MTSap", + "ToniSant" ] }, "echo-desc": "Sistema ta' notifika", @@ -38,6 +39,7 @@ "tooltip-pt-notifications-alert": "L-avviżi tiegħek", "echo-specialpage": "Notifiki", "echo-none": "M'għandek l-ebda notifika", + "notification-link-text-expand-alert-count": "Ara {{PLURAL:$1|$1 avviż|$1 avviżi}}", "notification-link-text-view-message": "Ara l-messaġġ", "notification-link-text-view-mention": "Ara fejn issemmejt", "notification-link-text-view-changes": "Ara l-bidliet", @@ -49,6 +51,8 @@ "notification-reverted-email-subject2": "Il-{{PLURAL:$4|modifika tiegħek ġiet annullata|modifiki tiegħek ġew annullati}} {{GENDER:$2|fuq}} {{SITENAME}}", "notification-mention-email-subject": "$1 {{GENDER:$2|semmiek|semmietek}} fuq {{SITENAME}}$1", "notification-user-rights-email-subject": "Id-drittijiet tiegħek ta' utent fuq {{SITENAME}} inbidlu.", + "echo-notification-alert": "{{PLURAL:$1|Avviż ($1)|Avviżi ($1)|100=Avviżi (99+)}}", + "echo-notification-alert-text-only": "Avviżi", "echo-overlay-link": "In-notifiki kollha", "echo-overlay-title": "<b>Notifiki</b>", "echo-mark-all-as-read": "Immarkahom kollha bħala li nqraw", @@ -58,5 +62,6 @@ "echo-email-batch-subject-weekly": "Għandek {{PLURAL:$2|notifika ġdida|notifiki ġodda}} fuq {{SITENAME}} dil-Ġimgħa", "echo-email-batch-body-intro-daily": "X'hemm $1,\nDan hu s-sommarju tal-attività tal-lum fuq {{SITENAME}} biex tista' tarah.", "echo-email-batch-body-intro-weekly": "X'hemm $1,\nDan hu s-sommarju tal-attività ta' din il-ġimgħa fuq {{SITENAME}} biex tista' tarah.", - "echo-email-batch-link-text-view-all-notifications": "Ara n-notifiki kollha" + "echo-email-batch-link-text-view-all-notifications": "Ara n-notifiki kollha", + "notification-header-foreign-alert": "Aktar avviżi minn {{PLURAL:$5|wiki ieħor$5 wikis oħra}}" } diff --git a/Echo/i18n/my.json b/Echo/i18n/my.json index defb19a7..311ad8fc 100644 --- a/Echo/i18n/my.json +++ b/Echo/i18n/my.json @@ -33,8 +33,8 @@ "echo-pref-notifications-page-linked-title-muted-list": "ဤစာမျက်နှာများအတွက် \"စာမျက်နှာလင့်ခ်ချိတ်မှု\" အသိပေးချက်များကို မဖော်ပြပါနှင့်။\n([[mw:Special:MyLanguage/Help:Notifications#mute|ပိုမိုလေ့လာရန်]])", "echo-learn-more": "ပို၍ လေ့လာရန်", "echo-log": "အများကြည့် မှတ်တမ်း", - "echo-new-messages": "မက်ဆေ့အသစ်များ ရောက်နေသည်", - "echo-category-title-edit-user-talk": "ဆွေးနွေးချက်စာမျက်နှာ {{PLURAL:$1|မက်ဆေ့|မက်ဆေ့များ}}", + "echo-new-messages": "ဆွေးနွေးချက်စာမျက်နှာမက်ဆေ့အသစ်များ ရောက်နေသည်", + "echo-category-title-edit-user-talk": "ကျွန်ုပ်၏ ဆွေးနွေးချက်စာမျက်နှာရှိ {{PLURAL:$1|တည်းဖြတ်မှု|တည်းဖြတ်မှုများ}}", "echo-category-title-article-linked": "စာမျက်နှာ {{PLURAL:$1|လင့်ခ်|လင့်ခ်များ}}", "echo-category-title-reverted": "{{PLURAL:$1|နောက်ပြန်ပြင်ဆင်မှု|နောက်ပြန်ပြင်ဆင်မှုများ}}ကို တည်းဖြတ်ရန်", "echo-category-title-mention": "{{PLURAL:$1|ရည်ညွန်းပြောဆိုချက်|ရည်ညွန်းပြောဆိုချက်များ}}", @@ -47,7 +47,10 @@ "echo-category-title-user-rights": "{{PLURAL:$1|အသုံးပြုသူအခွင့်ရေး ပြောင်းလဲမှု|အသုံးပြုသူအခွင့်ရေး ပြောင်းလဲမှုများ}}", "echo-category-title-emailuser": "{{PLURAL:$1|အခြားအသုံးပြုသူမှ အီးမေးလ်|အခြားအသုံးပြုသူမှ အီးမေးလ်များ}}", "echo-category-title-thank-you-edit": "{{PLURAL:$1|မိုင်တိုင်|မိုင်တိုင်များ}} ပြင်ဆင်ရန်", - "echo-pref-tooltip-edit-user-talk": "တစ်ယောက်ယောက်က မိမိ၏ဆွေးနွေးစာမျက်နှာတွင် မက်ဆေ့တစ်စောင်ပို့ပါက သို့မဟုတ် အကြောင်းပြန်ပါက အသိပေးရန်။", + "echo-category-title-watchlist": "စောင့်ကြည့်စာမျက်နှာအား တည်းဖြတ်ရန်", + "echo-category-title-minor-watchlist": "စောင့်ကြည့်စာမျက်နှာအား အသေးစား တည်းဖြတ်ရန်", + "echo-pref-tooltip-edit-user-talk": "တစ်ယောက်ယောက်က မိမိ၏အသုံးပြုသူဆွေးနွေးစာမျက်နှာအား တည်းဖြတ်ပါက အသိပေးပါ။", + "echo-pref-tooltip-mention": "တစ်ယောက်ယောက်က ကျွန်ုပ်၏အသုံးပြုသူစာမျက်နှာသို့ လင့်ခ်လာချိတ်ပါက အသိပေးပါ။", "echo-pref-tooltip-user-rights": "မိမိ၏အသုံးပြုသူအခွင့်ရေးကို တစ်ယောက်ယောက်မှ ပြောင်းလဲလိုက်ပါက အသိပေးရန်။", "echo-pref-tooltip-emailuser": "တစ်ယောက်ယောက်က ကျွန်ုပ်အား အီးမေးလ်ပို့ပါက အသိပေးရန်။", "notifications": "အသိပေးချက်များ", @@ -104,8 +107,8 @@ "notification-header-thank-you-10-edit": "{{GENDER:$2|သင်}}သည် {{GENDER:$2|သင်၏}} ၁၀ ခုမြောက်တည်းဖြတ်မှုကို လုပ်ဆောင်ခဲ့သည်၊ ကျေးဇူး{{GENDER:$2|တင်ပါသည်}}၊ ဆက်လုပ်ပါ။", "notification-header-thank-you-100-edit": "{{GENDER:$2|သင်}}သည် {{GENDER:$2|သင်၏}} ၁၀၀ ခုမြောက်တည်းဖြတ်မှုကို လုပ်ဆောင်ခဲ့သည်၊ ကျေးဇူးအများကြီး{{GENDER:$2|တင်ပါသည်}}။", "notification-header-thank-you-1000-edit": "{{GENDER:$2|သင်}}သည် {{GENDER:$2|သင်၏}} ၁၀၀၀ ခုမြောက်တည်းဖြတ်မှုကို လုပ်ဆောင်ခဲ့သည်၊ ကြီးကျယ်သော\nပံ့ပိုးသူတစ်ဦးဖြစ်သည့်အတွက် ကျေးဇူး{{GENDER:$2|တင်ပါသည်}}။", - "notification-header-thank-you-10000-edit": "{{GENDER:$2|သင်}}သည် {{GENDER:$2|သင်၏}} တစ်သောင်းပြည့်မြောက် တည်းဖြတ်မှုကို လုပ်ဆေင်ခဲ့ပါပြီ၊ ကျေးဇူး{{GENDER:$2|တင်ပါသည်}}", - "notification-header-thank-you-100000-edit": "{{GENDER:$2|သင်}}သည် {{GENDER:$2|သင်၏}} ၁၀၀ ခုမြောက်တည်းဖြတ်မှုကို လုပ်ဆောင်ခဲ့သည်၊ အံ့ဩဖွယ်ပံ့ပိုးမှုအတွက်ကျေးဇူး{{GENDER:$2|တင်ပါသည်}}။", + "notification-header-thank-you-10000-edit": "{{GENDER:$2|သင်}}သည် {{GENDER:$2|သင်၏}} တစ်သောင်းပြည့်မြောက် တည်းဖြတ်မှုကို လုပ်ဆောင်ခဲ့ပါပြီ၊ ကျေးဇူး{{GENDER:$2|တင်ပါသည်}}", + "notification-header-thank-you-100000-edit": "{{GENDER:$2|သင်}}သည် {{GENDER:$2|သင်၏}} တစ်သိန်းခုမြောက်တည်းဖြတ်မှုကို လုပ်ဆောင်ခဲ့သည်၊ အံ့ဩဖွယ်ပံ့ပိုးမှုအတွက် {{GENDER:$2|သင့်}}အား ကျေးဇူးတင်ပါသည်။", "notification-header-thank-you-1000000-edit": "{{GENDER:$2|သင်}}သည် {{GENDER:$2|သင်၏}} တစ်သိန်းမြောက်တည်းဖြတ်မှုကို လုပ်ဆောင်ခဲ့သည်၊ အံ့အားသင့်စရာ\nပံပိုးမှုအတွက် ကျေးဇူး{{GENDER:$2|တင်ပါသည်}}။", "notification-link-thank-you-edit": "{{GENDER:$1|သင်၏}} တည်းဖြတ်မှု", "notification-link-text-view-edit": "တည်းဖြတ်မှုကို ကြည့်ရန်", @@ -127,7 +130,7 @@ "notification-inbox-filter-read": "ဖတ်ပြီး", "notification-inbox-filter-unread": "မဖတ်ရသေး", "notification-inbox-filter-all": "အားလုံး", - "echo-specialmute-label-mute-notifications": "ဤ {{GENDER:$1|user}}မှ သတိပေးချက်ကို ရပ်ဆိုင်းပါ", + "echo-specialmute-label-mute-notifications": "ဤ {{GENDER:$1|အသုံးပြုသူ}}မှ သတိပေးချက်များကို ရပ်ဆိုင်းပါ", "echo-email-plain-footer": "{{GENDER:$1|သင့်အား}} ကျွန်ုပ်တို့ မည်သည့်အီးမေးလ်များပို့ပေးသည်ကို ထိန်းချုပ်ရန်အတွက် {{GENDER:$1|သင်၏}} အပြင်အဆင်များကို စစ်ဆေးပါ။", "echo-email-html-footer-preference-link-text": "{{GENDER:$1|သင်၏}} ရွေးချယ်စရာများကို စစ်ဆေးရန်", "echo-email-html-footer-with-link": "ကျွန်ုပ်တို့ {{GENDER:$2|သင့်ကို}} အီးမေးလ်ပို့ပေးခြင်းအား ထိန်းချုပ်ရန်အတွက် $1။", diff --git a/Echo/i18n/mzn.json b/Echo/i18n/mzn.json index eb12f954..5c9271aa 100644 --- a/Echo/i18n/mzn.json +++ b/Echo/i18n/mzn.json @@ -4,5 +4,6 @@ "محک" ] }, + "echo-new-messages": "شمه وسه نو پغوم بییشتنه", "tooltip-pt-notifications-alert": "{{GENDER:|شمه}} هشدارون" } diff --git a/Echo/i18n/nap.json b/Echo/i18n/nap.json index bf43db45..bf6415ed 100644 --- a/Echo/i18n/nap.json +++ b/Echo/i18n/nap.json @@ -41,7 +41,7 @@ "echo-category-title-emailuser": "{{PLURAL:$1|Masciata mail 'a n'at'utente|Mmasciate mail 'a ll'at'utente}}", "echo-pref-tooltip-edit-user-talk": "Famme nu tuzzuleo si coccheruno mannasse na mmasciata o rispunnesse ncopp' 'a paggena 'e chiacchiera mia.", "echo-pref-tooltip-article-linked": "Famme nu tuzzuleo si quaccheruno se cullegasse a na paggena ca avesse criato ij 'a n'ata voce.", - "echo-pref-tooltip-reverted": "Famme nu tuzzuleo si coccheruno annullasse nu cagnamiento ca io stesso aggio fatto, ausanno 'o strumiento 'e annulla.", + "echo-pref-tooltip-reverted": "Famme nu tuzzuleo si coccheruno annullasse nu cagnamiento ca je stesso aggio fatto, ausanno 'o strumiento 'e annulla.", "echo-pref-tooltip-mention": "Famme nu tuzzuleo si coccheruno se cullegasse 'a paggena utente mia.", "echo-pref-tooltip-mention-failure": "Fà 'a notifica si nun putesse mannà fòre na menziona a coccheruno.", "echo-pref-tooltip-mention-success": "Famme 'a notifica si mannasse fòre na menziona a coccheruno.", diff --git a/Echo/i18n/nb.json b/Echo/i18n/nb.json index d51370b5..56498155 100644 --- a/Echo/i18n/nb.json +++ b/Echo/i18n/nb.json @@ -1,6 +1,7 @@ { "@metadata": { "authors": [ + "Abuluntu", "Chameleon222", "Danmichaelo", "Jeblad", @@ -14,19 +15,22 @@ }, "echo-desc": "System for å gi brukere beskjed om hendelser og meldinger", "prefs-echo": "Beskjeder", + "prefs-description-echo": "Velg hvilke varsler {{GENDER:|du}} får og hvordan du får dem.", "prefs-emailsettings": "E-postinnstillinger", "prefs-echosubscriptions": "Gi meg beskjed om disse hendelsene", "prefs-echocrosswiki": "Interwikivarsler", "prefs-blocknotificationslist": "Ignorerte brukere", + "prefs-mutedpageslist": "Sider sidelenkevarsling er slått av for", "prefs-echopollupdates": "Direkte varsler", "echo-mobile-notifications-filter-title": "Filtrer varsler", "echo-pref-show-poll-updates": "Vis nye varsler når de kommer", "echo-pref-show-poll-updates-help": "Vis antall uleste varsler i tittellinja, og vis et utdrag av hvert varsel med én gang det kommer.", "echo-pref-send-me": "Send meg:", "echo-pref-send-to": "Send til:", - "echo-pref-email-format": "Epost-format:", + "echo-pref-email-format": "E-postformat:", "echo-pref-web": "Web", "echo-pref-email": "E-post", + "echo-pref-push": "Apper", "echo-pref-email-frequency-never": "Ikke send meg beskjed på e-post", "echo-pref-email-frequency-immediately": "Individuelle beskjeder etterhvert som de kommer inn", "echo-pref-email-frequency-daily": "Daglige sammendrag av beskjeder", @@ -35,11 +39,12 @@ "echo-pref-email-format-plain-text": "Ren tekst", "echo-pref-cross-wiki-notifications": "Vis beskjeder fra andre wikier", "echo-pref-notifications-blacklist": "Ikke vis varsler fra disse brukerne. ([[mw:Special:MyLanguage/Help:Notifications#mute|lær mer]])", + "echo-pref-notifications-page-linked-title-muted-list": "Ikke vis sidelenkevarsler for disse sidene. ([[mw:Special:MyLanguage/Help:Notifications#mute|lær mer]])", "echo-pref-dont-email-read-notifications": "Ikke inkluder lesevarsler i sammendragseposter", "echo-learn-more": "Lær mer", "echo-log": "Offentlig logg", - "echo-new-messages": "Du har nye meldinger", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Melding|Meldinger}} på diskusjonsside", + "echo-new-messages": "Du har en ny melding på diskusjonssiden", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Redigering|Redigeringer}} på min brukerdiskusjonsside", "echo-category-title-article-linked": "{{PLURAL:$1|Sidelenke|Sidelenker}}", "echo-category-title-reverted": "Tilbakestilling av {{PLURAL:$1|redigering|redigeringer}}", "echo-category-title-mention": "{{PLURAL:$1|Nevning|Nevninger}}", @@ -50,12 +55,12 @@ "echo-category-title-system-noemail": "{{PLURAL:$1|System}}", "echo-category-title-system-emailonly": "{{PLURAL:$1|System}}", "echo-category-title-user-rights": "{{PLURAL:$1|Endring|Endringer}} i brukerrettigheter", - "echo-category-title-emailuser": "Epost fra {{PLURAL:$1|annen bruker|andre brukere}}", + "echo-category-title-emailuser": "E-post fra {{PLURAL:$1|annen bruker|andre brukere}}", "echo-category-title-article-reminder": "{{PLURAL:$1|Sidepåminnelse|Sidepåminnelser}}", "echo-category-title-thank-you-edit": "Rediger {{PLURAL:$1|milepæl|milepæler}}", "echo-category-title-watchlist": "Redigering av overvåket side", "echo-category-title-minor-watchlist": "Mindre redigering av overvåket side", - "echo-pref-tooltip-edit-user-talk": "Gi meg beskjed når noen skriver en melding eller svarer på diskusjonssiden min.", + "echo-pref-tooltip-edit-user-talk": "Gi meg beskjed når noen redigerer brukerdiskusjonssiden min.", "echo-pref-tooltip-article-linked": "Gi meg beskjed når noen lenker til en side jeg har opprettet fra en annen side.", "echo-pref-tooltip-reverted": "Gi meg beskjed når noen tilbakestiller en av redigeringene mine.", "echo-pref-tooltip-mention": "Gi meg beskjed når noen lenker til brukersiden min.", @@ -81,12 +86,13 @@ "echo-displaynotificationsconfiguration-enabled-default-existing-users-legend": "Eksisterende brukere", "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "Nye brukere", "echo-displaynotificationsconfiguration-mandatory-notification-methods-header": "Obligatoriske beskjedmetoder", - "echo-displaynotificationsconfiguration-mandatory-notification-methods-by-category-legend": "Hvilken beskjedmetoder er nødvendige for hver kategori", + "echo-displaynotificationsconfiguration-mandatory-notification-methods-by-category-legend": "Hvilken beskjedmetoder er obligatoriske for hver kategori", "echo-specialpage": "Beskjeder", "echo-specialpage-section-markread": "Merk gruppen som lest", "echo-specialpage-markasread": "Beskjed: Merk som lest", "echo-specialpage-markasread-invalid-id": "Ugyldig hendelses-ID", "echo-specialpage-pagefilterwidget-aria-label": "Filtrer etter wiki og sidetittel", + "echo-specialpage-special-help-menu-widget-aria-label": "Ytterligere alternativer og varslingsinnstillinger.", "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|beskjed|beskjeder}}", "echo-specialpage-pagination-range": "$1–$2", "echo-specialpage-pagefilters-title": "Nylig aktivitet", @@ -102,7 +108,13 @@ "echo-notification-markasread": "Merk som lest", "echo-notification-markasunread": "Merk som ulest", "echo-notification-markasread-tooltip": "Merk som lest", - "echo-notification-more-options-tooltip": "Flere valg", + "echo-notification-more-options-tooltip": "Flere alternativer", + "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|Slå}} av lenkevarsler for «$1»", + "notification-dynamic-actions-mute-page-linked-confirmation": "Sidelenkevarsler er nå slått av for siden «$1»", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|Du}} kan når som helst behandle avslåtte sider i [$1 innstillingene dine].", + "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2|Slå}} på lenkevarsler for «$1»", + "notification-dynamic-actions-unmute-page-linked-confirmation": "Sidelenkevarsler for siden «$1» er nå slått på", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|Du}} kan når som helst behandle avslåtte sider i [$1 innstillingene dine].", "notification-dynamic-actions-unwatch": "{{GENDER:$3|Slutt}} å følge med på ny aktivitet på «$1»", "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3|Du}} overvåker ikke lenger siden «$1»", "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|Du}} kan når som helst begynne å overvåke [$2 denne siden] igjen.", @@ -111,12 +123,12 @@ "notification-dynamic-actions-watch-confirmation-description": "{{GENDER:$3|Du}} kan når som helst slutte å overvåke [$2 denne siden].", "notification-link-text-expand-all": "Utvid", "notification-link-text-expand-alert-count": "Vis {{PLURAL:$1|varsel|$1 varsler}}", - "notification-link-text-expand-notice-count": "Vis {{PLURAL:$1|En notis|$1 notiser}}", - "notification-link-text-expand-all-count": "Vis {{PLURAL:$1|beskjeden|$1 beskjedene}}", + "notification-link-text-expand-notice-count": "Vis {{PLURAL:$1|notis|$1 notiser}}", + "notification-link-text-expand-all-count": "Vis {{PLURAL:$1|beskjeden|$1 beskjeder}}", "notification-link-text-collapse-all": "Skjul", - "notification-link-text-view-message": "Vis melding", + "notification-link-text-view-message": "Vis beskjed", "notification-link-text-view-mention": "Vis hvor jeg ble nevnt", - "notification-link-text-view-mention-failure": "{{PLURAL:$1|Vis nevning|Vis nevninger}}", + "notification-link-text-view-mention-failure": "Vis {{PLURAL:$1|nevning|nevninger}}", "notification-link-text-view-changes": "{{GENDER:$1|Vis}} endringer", "notification-link-text-view-page": "Vis side", "notification-header-edit-user-talk": "$1 {{GENDER:$2|skrev}} en melding på <strong>diskusjonssiden {{GENDER:$3|din}}</strong>.", @@ -125,7 +137,7 @@ "notification-compact-header-edit-user-talk-with-section": "$1 {{GENDER:$2|la}} igjen en beskjed til {{GENDER:$3|deg}} under «<strong>$4</strong>».", "notification-header-page-linked": "<strong>$3</strong> ble lenket til fra <strong>$4</strong>.", "notification-compact-header-page-linked": "Lenket fra <strong>$1</strong>.", - "notification-bundle-header-page-linked": "<strong>$3</strong> ble lenket til fra {{PLURAL:$5||$5 sider|100=99+ andre sider}}.", + "notification-bundle-header-page-linked": "<strong>$3</strong> ble lenket til fra {{PLURAL:$5|$5 side|$5 sider|100=99+ andre sider}}.", "notification-header-article-reminder": "En side {{GENDER:$2|du}} har bedt om varsler for finnes på <strong>$3</strong>", "notification-link-text-what-links-here": "Alle lenker til denne siden", "notification-header-mention-other": "$1 {{GENDER:$2|nevnte}} {{GENDER:$3|deg}} i «<strong>$5</strong>» på <strong>$4</strong>.", @@ -136,13 +148,13 @@ "notification-header-mention-agent-talkpage-nosection": "$1 {{GENDER:$2|nevnte}} {{GENDER:$3|deg}} på <strong>diskusjonssiden {{GENDER:$2|sin}}</strong>.", "notification-header-mention-article-talkpage": "$1 {{GENDER:$2|nevnte}} {{GENDER:$3|deg}} i «<strong>$5</strong>» på diskusjonssiden til <strong>$4</strong>.", "notification-header-mention-article-talkpage-nosection": "$1 {{GENDER:$2|nevnte}} {{GENDER:$3|deg}} på diskusjonssiden til <strong>$4</strong>.", - "notification-header-mention-failure-user-unknown": "Brukeren <strong>$3</strong>, som du {{GENDER:$2|du}} prøvde å nevne, ble ikke funnet.", + "notification-header-mention-failure-user-unknown": "Brukeren <strong>$3</strong>, som {{GENDER:$2|du}} prøvde å nevne, ble ikke funnet.", "notification-header-mention-failure-user-anonymous": "Brukeren <strong>$3</strong>, som {{GENDER:$2|du}} prøvde å nevne, er anonym.", "notification-header-mention-failure-too-many": "{{GENDER:$2|Du}} prøvde å nevne mer enn $3 {{PLURAL:$3|bruker|brukere}}. Overskytende nevninger ble ikke sendt.", "notification-header-mention-failure-bundle": "{{PLURAL:$3|Kunne}} ikke sende {{PLURAL:$3|en nevning|$3 nevninger}} {{GENDER:$2|du prøvde å gjøre}} på diskusjonssiden <strong>$4</strong>.", "notification-compact-header-mention-failure-user-unknown": "<strong>Brukernavnet eksisterer ikke:</strong> $1", "notification-compact-header-mention-failure-user-anonymous": "<strong>Kan ikke nevne IP-adresser:</strong> $1", - "notification-header-mention-success": "<strong>$3</strong> har fått beskjed om at {{GENDER:$2|du}} nevnte vedkommende.", + "notification-header-mention-success": "<strong>$3</strong> har fått beskjed om at {{GENDER:$2|du}} nevnte {{GENDER:$3|ham|henne|vedkommende}}.", "notification-header-mention-success-bundle": "{{GENDER:$2|Du}} {{PLURAL:$3|nevnte}} {{PLURAL:$3|en bruker|$3 brukere}} på diskusjonssiden <strong>$4</strong>.", "notification-compact-header-mention-success": "<strong>{{GENDER:$2|Du nevnte}}:</strong> $3", "notification-header-mention-status-bundle": "{{PLURAL:$3|En beskjed|$3 beskjeder}} om nevninger {{GENDER:$2|du gjorde}} på diskusjonssiden <strong>$4</strong>: {{PLURAL:$5|$5 ble ikke sendt}}, {{PLURAL:$6|$6 ble sendt}}.", @@ -162,6 +174,7 @@ "notification-header-watchlist-multiuser-deleted": "<strong>$1</strong>, ei side på overvåkningslista {{GENDER:$2|di}}, ble slettet $3 {{PLURAL:$3|gang|ganger}}.", "notification-header-watchlist-multiuser-moved": "<strong>$1</strong>, ei side på overvåkningslista {{GENDER:$2|di}}, ble flyttet $3 {{PLURAL:$3|gang|ganger}}.", "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>, ei side på overvåkningslista {{GENDER:$2|di}}, ble gjenopprettet $3 {{PLURAL:$3|gang|ganger}}.", + "notification-body-watchlist-once": "Du vil ikke få flere epostvarsler med mindre {{GENDER:$1|du}} besøker siden mens du er logget inn.", "notification-welcome-linktext": "Velkommen", "notification-header-thank-you-1-edit": "{{GENDER:$2|Du}} har gjort {{GENDER:$2|din}} første redigering. {{GENDER:$2|Takk}} – og velkommen hit!", "notification-header-thank-you-10-edit": "{{GENDER:$2|Du}} har gjort {{GENDER:$2|din}} tiende redigering. {{GENDER:$2|Takk}}, fortsett gjerne!", @@ -170,11 +183,12 @@ "notification-header-thank-you-10000-edit": "{{GENDER:$2|Du}} har gjort {{GENDER:$2|din}} titusende redigering – {{GENDER:$2|tusen takk}}!", "notification-header-thank-you-100000-edit": "{{GENDER:$2|Du}} gjorde akkurat {{GENDER:$2|din}} hundretusende redigering – {{GENDER:$2|tusen takk}} for utrolig innsats!", "notification-header-thank-you-1000000-edit": "{{GENDER:$2|Du}} gjorde akkurat {{GENDER:$2|din}} millionte redigering – {{GENDER:$2|tusen takk}} for forbløffende innsats!", + "notification-header-thank-you-10000000-edit": "{{GENDER:$2|Du}} gjorde akkurat din ti-millionte redigering – tusen takk for fantastisk innsats!", "notification-link-thank-you-edit": "Redigeringen {{GENDER:$1|din}}", "notification-link-text-view-edit": "Vis redigering", "notification-link-article-reminder": "Vis siden", "notification-header-reverted": "{{PLURAL:$4|Redigeringen din|Redigeringene dine}} på <strong>$3</strong> har blitt {{GENDER:$2|tilbakestilt}}.", - "notification-header-emailuser": "$1 {{GENDER:$2|sendte}} deg en epost.", + "notification-header-emailuser": "$1 {{GENDER:$2|sendte}} deg en e-post.", "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$2|skrev}} en melding til deg på {{SITENAME}}", "notification-page-linked-email-subject": "En side {{GENDER:$3|du}} opprettet ble lenket til på {{SITENAME}}", "notification-reverted-email-subject2": "{{PLURAL:$4|Redigeringen din|Redigeringene dine}} på {{SITENAME}} ble {{GENDER:$2|tilbakestilt}}", @@ -191,8 +205,8 @@ "notification-inbox-filter-read": "Leste", "notification-inbox-filter-unread": "Uleste", "notification-inbox-filter-all": "Alle", - "echo-specialmute-label-mute-notifications": "Demp varsler fra denne brukeren", - "echo-email-plain-footer": "For å styre hvilke eposter vi sender {{GENDER:$1|deg}}, sjekk innstillingene dine:", + "echo-specialmute-label-mute-notifications": "Slå av varsler fra denne {{GENDER:$1|brukeren}}", + "echo-email-plain-footer": "Sjekk innstillingene {{GENDER:$1|dine}} for å styre hvilke e-poster vi sender deg:", "echo-email-html-footer-preference-link-text": "sjekk innstillingene {{GENDER:$1|dine}}", "echo-email-html-footer-with-link": "For å styre hvilke eposter vi sender {{GENDER:$2|deg}}, $1.", "echo-notification-alert": "{{PLURAL:$1|Varsel ($1)|Varsler ($1)|100=Varsler (99+)}}", @@ -208,13 +222,18 @@ "echo-date-today": "I dag", "echo-date-yesterday": "I går", "notification-bundle-header-edit-user-talk-v2": "{{PLURAL:$1|Én ny melding|$1 nye meldinger|100=99+ nye meldinger}} på <strong>diskusjonssiden {{GENDER:$3|din}}</strong>.", - "echo-email-batch-subject-daily": "Du har {{PLURAL:$2|en ny beskjed|nye beskjeder}} på {{SITENAME}} i dag", + "echo-email-batch-subject-daily": "Du har {{PLURAL:$2|en ny beskjed|nye beskjeder}} på {{SITENAME}}", "echo-email-batch-subject-weekly": "Du har {{PLURAL:$2|en ny beskjed|nye beskjeder}} på {{SITENAME}} denne uka", - "echo-email-batch-body-intro-daily": "Hei $1\nHer er et sammendrag av dagens aktivitet på {{SITENAME}} for deg.", + "echo-email-batch-body-intro-daily": "Hei, $1\nHer er et sammendrag av dagens aktivitet på {{SITENAME}} for deg.", "echo-email-batch-body-intro-weekly": "Hei $1\nHer er et sammendrag av ukas aktivitet på {{SITENAME}} for deg.", "echo-email-batch-link-text-view-all-notifications": "Vis alle beskjeder", "notification-header-foreign-alert": "Flere varsler fra {{PLURAL:$5|én annen wiki|$5 andre wikier}}", "notification-header-foreign-notice": "Flere notiser fra {{PLURAL:$5|en annen wiki|$5 andre wikier}}", - "notification-header-foreign-all": "Flere beskjeder fra {{PLURAL:$5|én annen wiki|$5 andre wikier}}", - "echo-foreign-wiki-lang": "$1 – $2" + "notification-header-foreign-all": "Flere beskjeder fra {{PLURAL:$5|en annen wiki|$5 andre wikier}}", + "echo-foreign-wiki-lang": "$1 – $2", + "right-manage-all-push-subscriptions": "Behandle alle push-abonnementer", + "action-manage-all-push-subscriptions": "behandle alle push-aboennementer", + "group-push-subscription-manager": "Push-abonnementsbehandlere", + "group-push-subscription-manager-member": "{{GENDER:$1|push-abonnementsbehandler}}", + "grouppage-push-subscription-manager": "{{ns:project}}:Push-abonnementsbehandlere" } diff --git a/Echo/i18n/nds-nl.json b/Echo/i18n/nds-nl.json index 7a6c820e..46480b72 100644 --- a/Echo/i18n/nds-nl.json +++ b/Echo/i18n/nds-nl.json @@ -58,10 +58,11 @@ "notification-link-text-view-changes": "Wysigingen {{GENDER:$1|bekyken}}", "notification-link-text-view-page": "Zied bekieken", "notification-header-edit-user-talk": "$1 hevt een bericht up <strong>{{GENDER:$3|juw}} oaverlegsyde</strong> {{GENDER:$2|achterlåten}}.", + "notification-header-edit-user-talk-with-section": "$1 {{GENDER:$2|hevt}} en bericht achterlåten up <strong>{{GENDER:$3|juw}} oaverlegsyde</strong> under \"<strong>$4</strong>\".", "notification-welcome-linktext": "Welkom", "notification-link-text-view-edit": "Bewarking bekieken", "notification-header-reverted": "Joew {{PLURAL:$4|bewarking op $3 is|bewarkingen op $3 bin}} {{GENDER:$2|weerummedreid}} deur $1", - "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$2|hevt}} een bericht vöär {{GENDER:$3|ju}} achterlåten up {{SITENAME}}", + "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$2|hevt}} en bericht vöär {{GENDER:$3|juw}} achterlåten up {{SITENAME}}", "notification-page-linked-email-subject": "n Zied die'j an-emaakt hebbe is ekoppeld op {{SITENAME}}", "notification-reverted-email-subject2": "Joew {{PLURAL:$4|bewarking op {{SITENAME}} is|bewarkingen op {{SITENAME}} bin}} {{GENDER:$2|weerummedreid}}", "notification-mention-email-subject": "$1 {{GENDER:$2|hef}} joe eneumd op {{SITENAME}}", @@ -77,9 +78,9 @@ "notification-inbox-filter-read": "Elezen", "notification-inbox-filter-unread": "Niet elezen", "notification-inbox-filter-all": "Alles", - "echo-email-plain-footer": "Kontroleer {{GENDER:$1|juw}} instellingen üm te bepålen welke netberichten wy {{GENDER:$1|ju}} stüren:", + "echo-email-plain-footer": "Kontroleer {{GENDER:$1|juw}} instellingen üm te bepålen welke netberichten wy {{GENDER:$1|juw}} stüren:", "echo-email-html-footer-preference-link-text": "kontroleer {{GENDER:$1|juw}} instellingen", - "echo-email-html-footer-with-link": "Üm te bepålen welke netberichten wy {{GENDER:$2|ju}} stüren, $1.", + "echo-email-html-footer-with-link": "Üm te bepålen welke netberichten wy {{GENDER:$2|juw}} stüren, $1.", "echo-notification-alert-text-only": "Meldingen", "echo-notification-notice-text-only": "Mededelingen", "echo-overlay-link": "Alle meldingen", diff --git a/Echo/i18n/ne.json b/Echo/i18n/ne.json index a02c64a5..7d5ecaee 100644 --- a/Echo/i18n/ne.json +++ b/Echo/i18n/ne.json @@ -1,10 +1,13 @@ { "@metadata": { "authors": [ + "Bada Kaji", "NehalDaveND", + "Nirajan pant", "Nirjal stha", "जनक राज भट्ट", "पर्वत सुबेदी", + "बडा काजी", "बिप्लब आनन्द", "राम प्रसाद जोशी", "सरोज कुमार ढकाल", @@ -16,23 +19,31 @@ "prefs-emailsettings": "इमेल विकल्पहरू", "prefs-echosubscriptions": "निम्न घटनाहरूबारे मलाई जानकारी गराउने", "prefs-echocrosswiki": "बहु-विकि जानकारीहरू", + "prefs-blocknotificationslist": "म्यूट गरिएका प्रयोगकर्ताहरू", + "prefs-mutedpageslist": "पृष्ठ लिङ्क सुचनाहरू म्यूट गरिएका पृष्ठहरू", "prefs-echopollupdates": "प्रत्यक्ष जानकारीहरू", "echo-mobile-notifications-filter-title": "सूचनाहरू छनाेट गर्नुहाेस्", "echo-pref-show-poll-updates": "नयाँ जानकरीहरू देखा परे पछि तिनलाई प्रदर्शन गर्नुहोस्", + "echo-pref-show-poll-updates-help": "नपढिएका अधिसूचनाहरूको सङ्ख्या शीर्षकपट्टिमा देखाउनुहोस्, र अधिसूचना आइपुग्ने बित्तिकै हरेक अधिसूचनाको एउटा झल्को देखाउनुहोस्।", "echo-pref-send-me": "मलाई पठाउने:", - "echo-pref-send-to": "पठाउने:", - "echo-pref-email-format": "इमेल ढाँचा :", + "echo-pref-send-to": "लाई पठाउने:", + "echo-pref-email-format": "इमेल ढाँचा:", "echo-pref-web": "वेब", "echo-pref-email": "इमेल", - "echo-pref-email-frequency-never": "मलाई कुनै पनि इमेल जानकारी नपठाउने", + "echo-pref-push": "एपहरू", + "echo-pref-email-frequency-never": "मलाई कुनै पनि इमेल अधिसूचनाहरू नपठाउनू", "echo-pref-email-frequency-immediately": "जानकारीहरू जस्ताको तस्तै जसै हुन्छन्", - "echo-pref-email-frequency-daily": "दैनिक जानकारीको सारांश", - "echo-pref-email-frequency-weekly": "साप्ताहिक जानकारीको सारांश", - "echo-pref-email-format-html": "HTML", - "echo-pref-email-format-plain-text": "साधारण पाठ", - "echo-learn-more": "थप जानकारी", - "echo-new-messages": "तपाईंको लागि नयाँ सन्देशहरू छन्", - "echo-category-title-edit-user-talk": "वार्तालाप पृष्ठ {{PLURAL:$1|सन्देश|सन्देशहरू}}", + "echo-pref-email-frequency-daily": "अधिसूचनाहरूको दैनिक सारांश", + "echo-pref-email-frequency-weekly": "अधिसूचनाहरूको साप्ताहिक सारांश", + "echo-pref-email-format-html": "एचटीएमएल", + "echo-pref-email-format-plain-text": "सादा पाठ", + "echo-pref-cross-wiki-notifications": "अन्य विकिहरूबाट प्राप्त अधिसूचनाहरू देखाउनुहोस्", + "echo-pref-notifications-blacklist": "यी प्रयोगकर्ताहरूबाट आउने अधिसूचनाहरू नदेखाउनू।\n([[mw:Special:MyLanguage/Help:Notifications#mute|थप जान्नुहोस्]])", + "echo-pref-dont-email-read-notifications": "सारांश इमेलहरूमा पढिएका सूचनाहरू समावेश नगर्नुहोस्", + "echo-learn-more": "थप जान्नुहोस्", + "echo-log": "सार्वजनिक अभिलेखहरू", + "echo-new-messages": "तपाईंसँग नयाँ वार्ता पृष्ठ सन्देश छ", + "echo-category-title-edit-user-talk": "मेरो प्रयोगकर्ता वार्ता पृष्ठमा {{PLURAL:$1|सम्पादन|सम्पादनहरू}}", "echo-category-title-article-linked": "पृष्ठ {{PLURAL:$1|लिङ्क|लिङ्कहरू}}", "echo-category-title-reverted": "सम्पादन {{PLURAL:$1|रिभर्ट|रिभर्टहरू}}", "echo-category-title-mention": "{{PLURAL:$1|नाम लिइयो|नामहरू लिइयो}}", @@ -42,13 +53,13 @@ "echo-category-title-system": "{{PLURAL:$1|प्रणाली}}", "echo-category-title-system-noemail": "{{PLURAL:$1|प्रणाली}}", "echo-category-title-system-emailonly": "{{PLURAL:$1|प्रणाली}}", - "echo-category-title-user-rights": "{{PLURAL:$1|प्रयोगकर्ता अधिकार परिवर्तन|प्रयोगकर्ता अधिकारहरू परिवर्तन}}", + "echo-category-title-user-rights": "{{PLURAL:$1|प्रयोगकर्ताको अधिकार परिवर्तन|प्रयोगकर्ताको अधिकारहरू परिवर्तन}}", "echo-category-title-emailuser": "{{PLURAL:$1|अन्य प्रयोगकर्ताबाट इमेल|अन्य प्रयोगकर्ताहरूबाट इमेल}}", "echo-category-title-article-reminder": "{{PLURAL:$1|अनुस्मारक|अनुस्मारकहरू}} पृष्ठ", "echo-category-title-thank-you-edit": "{{PLURAL:$1|काेशेढुङ्गा|काेशेढुङ्गाहरू}} सम्पादन", "echo-category-title-watchlist": "अवलाेकन पृष्ठमा सम्पादन गर्नुहोस्", "echo-category-title-minor-watchlist": "अवलाेकन पृष्ठमा सामान्य सम्पादन गर्नुहोस्", - "echo-pref-tooltip-edit-user-talk": "कसैले मेरो वार्तालाप पृष्ठमा सन्देश छोडेमा वा उत्तर दिएमा मलाई जानकारी गराउनुहोस्।", + "echo-pref-tooltip-edit-user-talk": "कसैले मेरो प्रयोगकर्ता वार्ता पृष्ठ सम्पादन गर्दा मलाई सूचित गर्नुहोस्।", "echo-pref-tooltip-article-linked": "कसैले मैले सृजना गरेको पृष्ठमा सूत्रहरू जोडेमा मलाई जानकारी गराउनुहोस।", "echo-pref-tooltip-reverted": "जब कसैले मैले गरेकाे सम्पादन पूर्ववत उपकरण प्रयाेग गरि उल्ट्याउँछ भने मलाई सूचित गर्नुहोस्।", "echo-pref-tooltip-mention": "जब कसैले मेरो प्रयोगकर्ता पृष्ठलाई सूत्रबद्ध गर्छ भने मलाई जानकारी गराउनुहोस्।", @@ -56,10 +67,18 @@ "echo-pref-tooltip-mention-success": "जब मैले कसैलाई उल्लेख पढाएँ भने मलाई सूचित गर्नुहोस्", "echo-pref-tooltip-user-rights": "जब कसैले मेरो प्रयोगकर्ता अधिकार परिवर्तन गर्दछ भने मलाई सूचित गर्नुहोस्।", "echo-pref-tooltip-emailuser": "जब कसैले मलाई डाँक पठाउँदछ भने मलाई सूचित गर्नुहोस्", + "echo-pref-tooltip-article-reminder": "मैले सोध्दा यो पृष्ठको बारेमा मलाई सूचित गर्नुहोस्।", + "echo-pref-tooltip-thank-you-edit": "म मेरो पहिलो, १० औं, १०० औं... सम्पादन गर्दा मलाई सूचित गर्नुहोस्।", + "echo-pref-tooltip-watchlist": "कसैले मेरो अवलोकनसूचीको पृष्ठमा सानो सम्पादन गर्दा मलाई सूचित गर्नुहोस्।", + "echo-pref-tooltip-minor-watchlist": "कसैले मेरो अवलोकनसूचीको पृष्ठमा सानो सम्पादन गर्दा मलाई सूचित गर्नुहोस्।", "notifications": "जानकारीहरू", "tooltip-pt-notifications-alert": "{{GENDER:|तपाईंको}} जानकारीहरू", "tooltip-pt-notifications-notice": "{{GENDER:|तपाईको}} जानकारीहरू", + "echo-displaynotificationsconfiguration": "सूचना अभिरुचिहरू प्रदर्शन गर्नुहोस्", + "echo-displaynotificationsconfiguration-summary": "यो विकिमा सूचनाहरू कसरी कन्फिगर गरिएको छ भन्ने बारे एक सिंहावलोकन हो।", "echo-displaynotificationsconfiguration-notifications-by-category-header": "श्रेणीद्वारा जानकारीहरू", + "echo-displaynotificationsconfiguration-sorting-by-section-header": "प्रकार को क्रमबद्ध", + "echo-displaynotificationsconfiguration-available-notification-methods-header": "अनुमति दिइएको सूचना विधिहरू", "echo-displaynotificationsconfiguration-enabled-default-header": "पुनर्निर्धारितद्वारा सक्षम गरिएकाे", "echo-displaynotificationsconfiguration-enabled-default-existing-users-legend": "अवस्थित प्रयोगकर्ताहरू", "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "नयाँ प्रयोगकर्ताहरू", @@ -70,17 +89,19 @@ "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|$1 जानकारी|$1 जानकारीहरू}}", "echo-specialpage-pagination-range": "$1 - $2", "echo-specialpage-pagefilters-title": "हालको गतिविधि", - "echo-specialpage-pagefilters-subtitle": "नपठिएका सूचनाहरूको साथ पृष्ठहरू", + "echo-specialpage-pagefilters-subtitle": "नपढिएका सूचनाहरूको साथ पृष्ठहरू", "notificationsmarkread-legend": "जानकारीलाई पढिएकाे रूपमा चिनाे लगाउनुहाेस्", "echo-none": "तपाईंको लागि कुनै नयाँ जानकारी छैन ।", "echo-notification-placeholder": "तपाईंको लागि कुनै सूचना छैन ।", "echo-notification-placeholder-filters": "यी मापदण्डसँग मेल खाने यहाँ कुनै सूचनाहरू छैनन्।", - "echo-notification-loginrequired": "तपाईका सूचनाहरू हेर्नका लागि तपाईले प्रवेश गर्नुपर्छ।", + "echo-notification-loginrequired": "तपाईंले आफ्नो सूचनाहरू हेर्न प्रवेश गर्नुपर्छ।", + "echo-notification-popup-loginrequired": "कृपया आफ्नो सूचनाहरू हेर्न प्रवेश गर्नुहोस्।", "echo-notification-markasread": "पढेकोमा चिह्नित गर्ने", "echo-notification-markasunread": "नपढिएको रूपमा चिनो लगाउनुहोस्", "echo-notification-markasread-tooltip": "पढिएको रूपमा चिनो लगाउनुहोस्", "echo-notification-more-options-tooltip": "थप विकल्पहरू", - "notification-link-text-expand-all": "फैलाउनुहोस्", + "notification-dynamic-actions-watch": "\"$1\"मा नयाँ गतिविधिलाई {{GENDER:$3|पछ्याउनुहोस्}}", + "notification-link-text-expand-all": "देखाउनुहोस्", "notification-link-text-expand-alert-count": "{{PLURAL:$1|$1 सूचना|$1 सूचनाहरू}} हेर्नुहाेस्", "notification-link-text-expand-notice-count": "{{PLURAL:$1|$1 सूचना|$1 सूचनाहरू}} हेर्नुहाेस्", "notification-link-text-expand-all-count": "{{PLURAL:$1|$1 जानकारी|$1 जानकारीहरू}} हेर्नुहाेस्", @@ -91,11 +112,16 @@ "notification-link-text-view-changes": "परिवर्तनहरू {{GENDER:$1|हेर्नुहाेस्}}", "notification-link-text-view-page": "पृष्ठ हेर्ने", "notification-header-edit-user-talk": "$1 {{GENDER:$2|छाेडिएकाे छ}} सन्देश <strong>{{GENDER:$3|तपाईकाे}} वार्तालाप पृष्ठमा </strong>", + "notification-compact-header-edit-user-talk": "$1ले {{GENDER:$3|तपाईं}}लाई सन्देश {{GENDER:$2|छोड्नुभएको छ}}।", "notification-compact-header-edit-user-talk-with-section": "{{GENDER:$3|तपाईलाई}} एक सन्देश $1 {{GENDER:$2|छाेड्नुभएकाे छ}} \"<strong>$4</strong>\".", "notification-body-edit-user-talk-with-section": "$1", "notification-compact-header-page-linked": "<strong>$1</strong> बाट सूत्रबद्ध", "notification-link-text-what-links-here": "यस पृष्ठका सबै सूत्रहरू", "notification-compact-header-mention-failure-user-unknown": "<strong>प्रयाेगकर्ता नाम हाल अस्तित्वमा छैन:</strong> $1", + "notification-compact-header-mention-failure-user-anonymous": "<strong>आईपीहरू उल्लेख गर्न सकिँदैन:</strong> $1", + "notification-header-mention-success": "{{GENDER:$2|तपाईंको}} <strong>$3</strong>को उल्लेख पठाइएको थियो।", + "notification-compact-header-mention-success": "<strong>{{GENDER:$2|तपाईंले उल्लेख गर्नुभयो}}:</strong> $3", + "notification-header-welcome": "{{SITENAME}}मा {{GENDER:$2|स्वागत}} छ, $1! {{GENDER:$2|तपाईं}} यहाँ हुनु भएकोमा हामी खुसी छौं।", "notification-welcome-linktext": "स्वागतम्", "notification-header-thank-you-1-edit": "{{GENDER:$2|तपाई}}ले भर्खरै {{GENDER:$2|आफ्नाे}} पहिलाे सम्पादन गर्नु भएकाे छ; {{GENDER:$2|तपाई}}लाई धन्यवाद र स्वागत् छ!", "notification-header-thank-you-10-edit": "{{GENDER:$2|तपाई}}ले भर्खरै {{GENDER:$2|आफ्नाे}} दशाैँ सम्पादन गर्नु भएकाे छ; {{GENDER:$2|तपाई}}लाई धन्यवाद छ!", @@ -107,7 +133,6 @@ "notification-link-text-view-edit": "सम्पादन हेर्ने", "notification-link-article-reminder": "पृष्ठ हेर्नुहाेस्", "notification-header-reverted": "तपाईंको {{PLURAL:$4|सम्पादन $3 मा |सम्पादनहरू $3}} द्वारा {{GENDER:$2|उल्ट्याइएको छ}}।", - "notification-body-reverted": "$1", "notification-header-emailuser": "$1 {{GENDER:$2|ले}} डाँक पठाउनुभएको छ", "notification-edit-talk-page-email-subject2": "$1 ले {{GENDER:$3|तपाईलाई}} {{SITENAME}}मा एउटा सन्देश {{GENDER:$2|छोड्नुभएको छ}}", "notification-page-linked-email-subject": "{{GENDER:$3|तपाईद्वारा}} निर्माण गरिएको पृष्ठ {{SITENAME}}मा जोडियो", @@ -125,14 +150,16 @@ "notification-inbox-filter-read": "पढिएका", "notification-inbox-filter-unread": "नपढिएका", "notification-inbox-filter-all": "सबै", + "echo-specialmute-label-mute-notifications": "यस {{GENDER:$1|प्रयोगकर्ता}}बाट सूचनाहरू मौन गर्नुहोस्", "echo-email-html-footer-preference-link-text": "{{GENDER:$1|तपाईका}} अभिरुचिहरू जाँच गर्नुहाेस्", "echo-notification-alert": "{{PLURAL:$1|सूचना ($1)|सूचनाहरू ($1)|100=सूचनाहरू (९९+)}}", "echo-notification-notice": "{{PLURAL:$1|सूचना ($1)|सूचनाहरू ($1)|100=सूचनाहरू (९९+)}}", "echo-notification-alert-text-only": "सुचनाहरू", "echo-notification-notice-text-only": "सूचनाहरू", - "echo-overlay-link": "सबै जानकारीहरू", + "echo-overlay-link": "सबै सूचनाहरू", "echo-overlay-title": "<b>जानकारीहरू</b>", "echo-mark-all-as-read": "सबै पढिएको भनि चिनो लगाउने", + "echo-mark-wiki-as-read": "सबैलाई चयन गरिएको विकिमा पढिएको रूपमा चिन्ह लगाउनुहोस्: $1", "echo-displaysnippet-title": "नयाँ जानकारी", "echo-date-today": "आज", "echo-date-yesterday": "हिजो", @@ -142,5 +169,10 @@ "echo-email-batch-body-intro-daily": "नमस्ते $1,\nयहाँ तपाईंको लागि {{SITENAME}}मा आजको गतिविधिको एउटा सारांश छ।", "echo-email-batch-body-intro-weekly": "नमस्ते $1,\nयहाँ तपाईंको लागि {{SITENAME}} मा यो हप्ताको गतिविधिको निम्नानुशार सारांश छ।", "echo-email-batch-link-text-view-all-notifications": "सबै सूचनाहरू हेर्नुहोस्", - "echo-foreign-wiki-lang": "$1 - $2" + "echo-foreign-wiki-lang": "$1 - $2", + "right-manage-all-push-subscriptions": "सबै पुश सदस्यताहरू प्रबन्ध गर्नुहोस्", + "action-manage-all-push-subscriptions": "सबै पुश सदस्यताहरू प्रबन्ध गर्नुहोस्", + "group-push-subscription-manager": "सदस्यता प्रबन्धकहरू पुश गर्नुहोस्", + "group-push-subscription-manager-member": "{{GENDER:$1|पुश सदस्यता प्रबन्धक}}", + "grouppage-push-subscription-manager": "{{ns:project}}: पुश सदस्यता प्रबन्धकहरू" } diff --git a/Echo/i18n/nia.json b/Echo/i18n/nia.json new file mode 100644 index 00000000..df66a7e3 --- /dev/null +++ b/Echo/i18n/nia.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Slaia" + ] + }, + "tooltip-pt-notifications-alert": "Fangombakha {{GENDER:|khöu}}" +} diff --git a/Echo/i18n/nl-informal.json b/Echo/i18n/nl-informal.json index 90dd7f41..d59d4572 100644 --- a/Echo/i18n/nl-informal.json +++ b/Echo/i18n/nl-informal.json @@ -1,10 +1,13 @@ { "@metadata": { "authors": [ + "Kars", + "McDutchie", "Siebrand" ] }, + "tooltip-pt-notifications-alert": "{{GENDER:|Jouw}} meldingen", "echo-none": "Je hebt geen meldingen.", - "echo-email-batch-subject-daily": "Je hebt vandaag {{PLURAL:$2|0=geen meldingen|één melding|$1 meldingen}}", - "echo-email-batch-subject-weekly": "Je hebt deze week {{PLURAL:$2|0=geen meldingen|één melding|$1 meldingen}}" + "echo-email-batch-subject-daily": "Je hebt {{PLURAL:$2|een nieuwe melding|nieuwe meldingen}} op {{SITENAME}}", + "echo-email-batch-subject-weekly": "Je hebt deze week {{PLURAL:$2|een nieuwe melding|nieuwe meldingen}} op {{SITENAME}}" } diff --git a/Echo/i18n/nl.json b/Echo/i18n/nl.json index 29ae3bad..5f25ec4b 100644 --- a/Echo/i18n/nl.json +++ b/Echo/i18n/nl.json @@ -3,6 +3,7 @@ "authors": [ "Catrope", "Dinosaur918", + "Dutchy45", "Edokter", "Encycloon", "Esketti", @@ -33,9 +34,10 @@ "echo-desc": "Systeem om gebruikers gebeurtenissen en berichten te melden", "prefs-echo": "Meldingen", "prefs-emailsettings": "E-mailinstellingen", - "prefs-echosubscriptions": "Meld aan mij deze gebeurtenissen", + "prefs-echosubscriptions": "Meld deze gebeurtenissen aan mij", "prefs-echocrosswiki": "Meldingen van andere wiki's", "prefs-blocknotificationslist": "Genegeerde gebruikers", + "prefs-mutedpageslist": "Gedempte pagina's voor meldingen over paginakoppelingen", "prefs-echopollupdates": "Direct melden", "echo-mobile-notifications-filter-title": "Meldingen filteren", "echo-pref-show-poll-updates": "Nieuwe meldingen weergeven op het moment dat ze binnen komen", @@ -45,6 +47,7 @@ "echo-pref-email-format": "E-mailopmaak:", "echo-pref-web": "Web", "echo-pref-email": "E-mail", + "echo-pref-push": "Apps", "echo-pref-email-frequency-never": "Stuur mij geen meldingen per e-mail", "echo-pref-email-frequency-immediately": "Individuele meldingen wanneer ze binnenkomen", "echo-pref-email-frequency-daily": "Een dagelijkse samenvatting van meldingen", @@ -53,11 +56,12 @@ "echo-pref-email-format-plain-text": "Tekst zonder opmaak", "echo-pref-cross-wiki-notifications": "Meldingen van andere wiki's weergeven", "echo-pref-notifications-blacklist": "Toon geen meldingen van deze gebruikers. ([[mw:Special:MyLanguage/Help:Notifications#mute|Meer lezen]])", + "echo-pref-notifications-page-linked-title-muted-list": "Geef geen meldingen voor \"paginakoppelingen\" weer voor deze pagina's. ([[mw:Special:MyLanguage/Help:Notifications#mute|Meer lezen]])", "echo-pref-dont-email-read-notifications": "Gelezen meldingen niet opnemen in overzichtsmails", "echo-learn-more": "Meer lezen", "echo-log": "Openbaar logboek", - "echo-new-messages": "U hebt nieuwe berichten", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Bericht|Berichten}} op mijn overlegpagina", + "echo-new-messages": "Nieuw bericht op uw overlegpagina", + "echo-category-title-edit-user-talk": "Bewerking{{PLURAL:$1||en}} op mijn eigen overlegpagina", "echo-category-title-article-linked": "Paginakoppeling{{PLURAL:$1||en}}", "echo-category-title-reverted": "Teruggedraaide {{PLURAL:$1|bewerking|bewerkingen}}", "echo-category-title-mention": "{{PLURAL:$1|Vermelding|Vermeldingen}}", @@ -73,7 +77,7 @@ "echo-category-title-thank-you-edit": "Bewerkings{{PLURAL:$1|mijlpaal|mijlpalen}}", "echo-category-title-watchlist": "Bewerking aan volglijstpagina", "echo-category-title-minor-watchlist": "Kleine bewerking aan volglijstpagina", - "echo-pref-tooltip-edit-user-talk": "Meld mij wanneer iemand een bericht of antwoord op mijn overlegpagina plaatst.", + "echo-pref-tooltip-edit-user-talk": "Meld het mij wanneer iemand mijn eigen overlegpagina bewerkt.", "echo-pref-tooltip-article-linked": "Meld mij wanneer iemand een koppeling aanbrengt naar een pagina die ik heb aangemaakt.", "echo-pref-tooltip-reverted": "Meld mij wanneer iemand een bewerking van mij terugdraait met behulp van \"ongedaan maken\" of \"terugdraaien\".", "echo-pref-tooltip-mention": "Meld mij wanneer iemand een koppeling naar mijn gebruikerspagina plaatst.", @@ -209,7 +213,7 @@ "notification-inbox-filter-read": "Gelezen", "notification-inbox-filter-unread": "Ongelezen", "notification-inbox-filter-all": "Alle", - "echo-specialmute-label-mute-notifications": "Verberg meldingen van deze gebruiker", + "echo-specialmute-label-mute-notifications": "Verberg meldingen van deze {{GENDER:$1|gebruiker}}", "echo-email-plain-footer": "Controleer {{GENDER:$1|uw}} voorkeuren om te bepalen welke e-mails wij {{GENDER:$1|u}} sturen:", "echo-email-html-footer-preference-link-text": "controleer {{GENDER:$1|uw}} voorkeuren", "echo-email-html-footer-with-link": "Om te bepalen welke e-mails wij {{GENDER:$2|u}} sturen, $1.", diff --git a/Echo/i18n/nn.json b/Echo/i18n/nn.json index b9ad0931..7ac48d26 100644 --- a/Echo/i18n/nn.json +++ b/Echo/i18n/nn.json @@ -47,6 +47,7 @@ "notifications": "Meldingar og varsel", "tooltip-pt-notifications-alert": "Varsla {{GENDER:|dine}}", "tooltip-pt-notifications-notice": "Notisane {{GENDER:|dine}}", + "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "Nye brukarar", "echo-specialpage": "Meldingar og varsel", "echo-specialpage-section-markread": "Merk gruppa som lesen", "echo-specialpage-pagination-numnotifications": "{{PLURAL:$1|éin notis eller eitt varsel|$1 notisar og varsel}}", @@ -60,6 +61,8 @@ "echo-notification-more-options-tooltip": "Fleire val", "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|Slå av}} lenkjenotisar for «$1»", "notification-dynamic-actions-mute-page-linked-confirmation": "Notisar for sidelenkjer er no avslegne for sida «$1»", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|Du}} kan styra avslegne lenkjenotisar i [$1 innstillingane dine] kva tid som helst.", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|Du}} kan styra avslegne lenkjenotisar i [$1 innstillingane dine] kva tid som helst.", "notification-dynamic-actions-unwatch": "{{GENDER:$3|Slutt}} å fylgja med på ny aktivitet på «$1»", "notification-link-text-expand-all": "Vis", "notification-link-text-expand-alert-count": "Sjå {{PLURAL:$1|varsel|$1 varsel}}", @@ -71,6 +74,7 @@ "notification-link-text-view-page": "Sjå side", "notification-header-edit-user-talk": "$1 {{GENDER:$2|la att}} ei melding på <strong>diskusjonssida</strong> {{GENDER:$3|di}}.", "notification-header-edit-user-talk-with-section": "$1 {{GENDER:$2|la att}} ei melding på <strong>diskusjonssida</strong> {{GENDER:$3|di}} under «<strong>$4</strong>».", + "notification-compact-header-edit-user-talk": "$1 {{GENDER:$2|la}} att ei melding til {{GENDER:$3|deg}}.", "notification-header-page-linked": "Ei lenkje vart oppretta frå <strong>$4</strong> til <strong>$3</strong>.", "notification-compact-header-page-linked": "Lenkja frå <strong>$1</strong>.", "notification-bundle-header-page-linked": "Det vart oppretta lenkjer frå {{PLURAL:$5||$5 sider|100=meir enn 99 sider}} til <strong>$3</strong>.", @@ -117,6 +121,7 @@ "notification-inbox-filter-read": "Lesne", "notification-inbox-filter-unread": "Ulesne", "notification-inbox-filter-all": "Alle", + "echo-specialmute-label-mute-notifications": "Demp varsel frå denne {{GENDER:$1|brukaren}}", "echo-email-plain-footer": "For å styra kva e-postar me sender {{GENDER:$2|deg}}, sjekk innstillingane dine:", "echo-email-html-footer-preference-link-text": "sjekk innstillingane {{GENDER:$1|dine}}", "echo-email-html-footer-with-link": "For å styra kva e-postar me sender {{GENDER:$2|deg}}, $1.", diff --git a/Echo/i18n/nqo.json b/Echo/i18n/nqo.json index 1bc6afd4..0ebfaa50 100644 --- a/Echo/i18n/nqo.json +++ b/Echo/i18n/nqo.json @@ -6,5 +6,220 @@ "Youssoufkadialy" ] }, - "tooltip-pt-notifications-alert": "{{GENDER:|ߌ ߟߊ߫}} ߟߊ߬ߛߏ߬ߓߌ߬ߟߌ ߟߎ߬" + "echo-desc": "ߞߊ߲ߞߋ ߡߍ߲ ߦߋ߫ ߦߋ߲߬ ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߟߎ߬ ߖߊ߲߬ߓߌ߬ߟߊ߬ ߞߊ߲ ߡߊ߬ ߖߊ߲߬ߖߏ߲ ߠߎ߬ ߣߌ߫ ߗߋߛߓߍ ߟߎ߬ ߟߊ߫", + "prefs-echo": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߟߎ߬", + "prefs-emailsettings": "ߢ:ߞߏ߲ߘߏ ߢߣߊߕߊߟߌ", + "prefs-echosubscriptions": "ߒ ߖߊ߲߭ߓߌ߬ߟߊ߫ ߞߊ߬ ߓߍ߲߬ ߖߊ߲߬ߖߏ߲ ߏ߬ ߡߊ߬", + "prefs-echocrosswiki": "ߥߞߌ-ߓߊ߬ߛߊ߲߬ߣߍ߲ ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߟߎ߬", + "prefs-blocknotificationslist": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ߫ ߓߊ߬ߟߌ߬ߣߍ߲ ߠߎ߬", + "prefs-mutedpageslist": "ߞߐߜߍ߫ ߓߏߓߏߦߊߣߍ߲ ߠߎ߬ ߞߐߜߍ ߛߘߌ߬ߜߋ߲ ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ߫ ߞߏ ߘߐ߫", + "prefs-echopollupdates": "ߞߍߕߎߡߊ ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߟߎ߬", + "echo-mobile-notifications-filter-title": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߟߎ߬ ߛߍ߲ߛߍ߲߫", + "echo-pref-show-poll-updates": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ߫ ߞߎߘߊ ߟߎ߬ ߦߌ߬ߘߴߊ߬ߟߎ߫ ߣߊ߬ ߢߊ ߡߊ߬", + "echo-pref-show-poll-updates-help": "ߘߐ߬ߞߊ߬ߙߊ߲߬ߓߊߟߌ ߟߎ߬ ߦߙߌߞߊ ߦߌ߬ߘߊ߬ ߞߎ߲߬ߕߐ߰ ߝߙߊߕߌ ߟߊ߫߸ ߊ߬ ߣߌ߫ ߞߊ߬ ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߟߎ߬ ߞߋ߬ߟߋ߲߬ߞߋ߬ߟߋ߲߬ߠߊ ߟߎ߬ ߓߊߕߐߡߐ߲ ߝߣߊ߫ ߦߌ߬ߘߊ߬ ߞߊߟߌߦߊ߫ ߘߐ߫ ߣߴߊ߬ߟߎ߫ ߛߋ߫ ߘߊ߫.", + "echo-pref-send-me": "ߊ߬ ߗߋ߫ ߒ ߡߊ߬:", + "echo-pref-send-to": "ߊ߬ ߗߋ߫ ߕߐ߫:", + "echo-pref-email-format": "ߢ:ߞߏ߲ߘߏ ߖߙߎߡߎ߲:", + "echo-pref-web": "ߓߟߐߟߐ", + "echo-pref-email": "ߢߎߡߍߙߋ߲ߞߏ߲ߘߏ", + "echo-pref-push": "ߟߥߊ߬ߟߌ߬ߟߊ߲", + "echo-pref-email-frequency-never": "ߢߎߡߍߙߋ߲ߞߏ߲ߘߏ ߟߊ߬ߛߙߋ߬ߦߊ߬ߟߌ ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ߫ ߝߏߦߌ߬ ߞߊ߫ ߗߋ߫ ߒ ߡߊ߬", + "echo-pref-email-frequency-immediately": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ߫ ߞߎߕߎߙߎ߲ ߠߎ߬߸ ߊ߬ߟߎ߫ ߣߊ߬ ߕߎߡߊ ߟߊ߫", + "echo-pref-email-frequency-daily": "ߕߋ߬ߟߋ߲ ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߟߊ߬ߘߛߏ߬ߟߌ ߟߎ߬", + "echo-pref-email-frequency-weekly": "ߞߎ߲߬ߢߐ߰ߟߊ߬ߞߊ ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߟߊ߬ߘߛߏ߬ߟߌ ߟߎ߬", + "echo-pref-email-format-html": "HTML", + "echo-pref-email-format-plain-text": "ߛߓߍߟߌ߫ ߘߝߊߣߍ߲", + "echo-pref-cross-wiki-notifications": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߟߎ߬ ߦߌ߬ߘߊ߬ ߞߊ߬ ߝߘߊ߫ ߥߞߌ߫ ߜߘߍ ߟߎ߬ ߟߊ߫", + "echo-pref-notifications-blacklist": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߣߌ߲߬ ߕߊ߫ ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߟߎ߬ ߞߊߣߊ߬ ߟߊߓߊ߯ߙߊ߫ ߘߋ߬. ([[mw:Special:MyLanguage/Help:Notifications#mute|learn more]])", + "echo-pref-notifications-page-linked-title-muted-list": "ߞߐߜߍ ߛߘߌ߬ߜߋ߲ ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߞߊߣߊ߬ ߟߊߓߊ߯ߙߊ߫ ߞߐߜߍ ߢߌ߲߬ ߠߎ߫ ߢߍ߫. ([[mw:Special:MyLanguage/Help:Notifications#mute|ߘߏ߫ ߜߘߍ߫ ߟߎ߫ ߞߊ߬ߙߊ߲߫]])", + "echo-pref-dont-email-read-notifications": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ߫ ߘߐߞߊ߬ߙߊ߲߬ߣߍ߲ ߠߎ߬ ߛߋ߲߬ ߞߊ߫ ߕߘߍ߬ ߢߎߡߍߙߋ߲ ߟߊ߬ߘߛߏ߬ߣߍ߲ ߠߎ߬ ߘߐ߫", + "echo-learn-more": "ߘߏߜߘߍ߫ ߟߎ߫ ߘߐߞߊ߬ߙߊ߲߬", + "echo-log": "ߖߊ߬ߡߊ ߕߋ߬ߟߋ߲", + "echo-new-messages": "ߌ ߓߘߊ߫ ߗߋߛߓߍ߫ ߞߎߘߊ߫ ߛߐ߬ߘߐ߲߬ ߌ ߟߊ߫ ߞߎߡߊ߫ ߞߐߜߍ ߟߊ߫", + "echo-category-title-edit-user-talk": "ߞߎߡߊ߫ ߞߐߜߍ {{PLURAL:|ߡߙߌߣߊ߲|ߡߙߌߣߊ߲ $1 ߟߎ߬}} ߟߋ߬ ߦߋ߫ ߒ ߠߊ߫ ߟߊ߬ߓߊ߰ߙߊ߬ߟߌ߬ ߞߎߡߊ߫ ߞߐߜߍ ߘߐ߫", + "echo-category-title-article-linked": "{{PLURAL:|ߛߘߌ߬ߜߋ߲ $1|ߛߘߌ߬ߜߋ߲ ߠߎ߬}}", + "echo-category-title-reverted": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲߬ {{PLURAL:|ߘߐߛߊ߬ߣߍ߲|ߘߐߛߊ߬ߣߍ߲ $1 ߠߎ߬}}", + "echo-category-title-mention": "{{PLURAL:|ߕߐ߯ߘߐߕߍ߮|ߕߐ߯ߘߐߕߍ߮ $1 ߟߎ߬}}", + "echo-category-title-mention-failure": "{{PLURAL:|ߞߏߝߐߟߌ|ߞߏߝߐߟߌ $1 ߗߌߙߏ߲ߣߍ߲}} ߠߎ߬", + "echo-category-title-mention-success": "{{PLURAL:|ߞߏߝߐߟߌ߫|ߞߏߝߐߟߌ $1 ߛߎߘߊ߲ߣߍ߲}} ߠߎ߬", + "echo-category-title-other": "{{PLURAL:|ߘߏߜߘߍ߫ $1}}", + "echo-category-title-system": "{{PLURAL:|ߞߊ߲ߞߋ $1}}", + "echo-category-title-system-noemail": "{{PLURAL:|ߞߊ߲ߞߋ $1}}", + "echo-category-title-system-emailonly": "{{PLURAL:|ߞߊ߲ߞߋ $1}}", + "echo-category-title-user-rights": "{{PLURAL:|ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߤߊߞߍ ߡߊߦߟߍ߬ߡߊ߲|ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߟߎ߬ ߡߊߞߍ߫ ߡߊߦߟߍߡߊ߲ $1}}", + "echo-category-title-emailuser": "{{PLURAL:|ߢߎߡߍߙߋ߲߫ $1 ߞߊ߬ ߝߘߊ߫ ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ߫ ߜߘߍ߫ ߟߊ߫|ߢߎߡߍߙߋ߲ ߡߍ߲ ߠߎ߬ ߝߘߊߣߍ߲߫ ߦߋ߫ ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ߫ ߜߘߍ ߟߎ߬ ߟߊ߫}}", + "echo-category-title-article-reminder": "{{PLURAL:|ߦߟߌߓߌߟߊߟߌ|ߦߟߌߓߌߟߊߟߌ߫ $1}} ߞߐߜߍ ߟߎ߬", + "echo-category-title-thank-you-edit": "{{PLURAL:|ߘߊ߲߬ߓߟߐ|ߘߊ߲߬ߓߟߐ $1 ߟߎ߫}} ߡߊߦߟߍ߬ߡߊ߲߫", + "echo-category-title-watchlist": "ߞߐߜߍ߫߫ ߜߋ߬ߟߎ߲߬ߣߍ߲ ߘߏ߫ ߡߊߦߟߍ߬ߡߊ߲߬ߠߌ߲", + "echo-category-title-minor-watchlist": "ߞߐߜߍ߫߫ ߜߋ߬ߟߎ߲߬ߣߍ߲ ߘߏ߫ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲߬ ߘߋ߬ߣߍ߲", + "echo-pref-tooltip-edit-user-talk": "ߒ ߖߊ߲߬ߓߌ߬ߟߊ߬ ߣߌ߫ ߡߐ߰ ߘߏ߫ ߞߊ߬ ߒ ߠߊ߫ ߞߎߡߊ߫ ߞߐߜߍ ߡߊߦߟߍ߬ߡߊ߲߫.", + "echo-pref-tooltip-article-linked": "ߞߊ߬ ߒ ߖߊ߲߬ߓߌ߬ߟߊ߬ ߣߌ߫ ߘߏߕߌ߰ ߞߊ߬ ߦߟߌߡߊߛߙߋ ߓߌ߬ߟߊ߬ ߞߐߜߍ߫ ߟߊ߫ ߒߠߋ ߣߊ߬ ߡߍ߲ ߛߌ߲ߘߌ߫ ߟߊ߫ ߞߐߜߍ߫ ߜߘߍ߫ ߡߊ߬.", + "echo-pref-tooltip-reverted": "ߞߊ߬ ߒ ߖߊ߲߬ߓߌ߬ߟߊ߬ ߣߌ߫ ߘߏߕߌ߰ ߞߊ߬ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߘߏ߫ ߘߐߛߊ߬ ߒ ߣߐ߬ ߡߍ߲ ߛߌ߲ߘߌ߫ ߟߊ߫߸ ߞߵߏ߬ ߞߍ߫ ߘߐ߬ߛߊ߬ߟߌ߫ ߖߐ߯ߙߊ߲ ߠߊߓߊ߯ߙߊ ߟߊ߫ ߥߟߊ߫ ߟߊ߬ߕߊ߲߬ߞߌ߬ߟߌ߫ ߖߐ߯ߙߊ߲ ߠߊ߫.", + "echo-pref-tooltip-mention": "ߒ ߖߊ߲߬ߓߌ߬ߟߊ߬ ߣߌ߫ ߡߐ߱ ߘߏ߫ ߞߵߊ߬ ߜߋ߲߬ߞߘߎ߬ ߒ ߠߊ߫ ߟߊ߬ߓߊ߰ߙߊ߬ߟߌ߬ ߞߐߜߍ ߟߊ߫.", + "echo-pref-tooltip-mention-failure": "ߞߊ߬ ߒ ߖߊ߲߭ߓߌ߬ߟߊ߫ ߣߌ߫ ߒ ߕߍߣߊ߬ ߛߋ߫ ߟߊ߫ ߕߐ߯ߘߐߕߍ ߗߋ߫ ߟߊ߫ ߡߐ߱ ߘߏ߫ ߡߊ߬", + "echo-pref-tooltip-mention-success": "ߞߊ߬ ߒ ߖߊ߲߭ߓߌ߬ߟߊ߫ ߣߌ߫ ߒ ߞߊ߬ ߕߐ߯ߘߐߕߍ ߗߋ߫ ߡߐ߱ ߘߏ߫ ߡߊ߬.", + "echo-pref-tooltip-user-rights": "ߞߊ߬ ߒ ߖߊ߲߭ߓߌ߬ߟߊ߫ ߣߌ߫ ߘߏߕߌ߰ ߞߊ߬ ߒ ߠߊ߫ ߟߊ߬ߓߊ߰ߙߊ߬ߟߌ߬ ߤߊߞߍ ߡߊߝߊ߬ߟߋ߲߫.", + "echo-pref-tooltip-emailuser": "ߞߊ߬ ߒ ߖߊ߲߭ߓߌ߬ߟߊ߫ ߣߌ߫ ߘߏߕߌ߰ ߞߊ߬ ߢߎߡߍߙߋ߲߫ ߗߋߛߓߍ ߗߋ߫ ߒ ߡߊ߬.", + "echo-pref-tooltip-article-reminder": "ߞߊ߬ ߒ ߖߊ߲߭ߓߌ߬ߟߊ߫ ߞߐߜߍ ߣߌ߲߬ ߠߊ߫ ߞߏ߫ ߟߊ߫ ߣߌ߫ ߒ ߞߊ߬ ߢߌ߬ߣߌ߲߬ߞߊ߬ߟߌ ߞߍ߫.", + "echo-pref-tooltip-thank-you-edit": "ߞߊ߬ ߒ ߖߊ߲߭ߓߌ߬ߟߊ߫ ߣߌ߫ ߒ ߛߋ߫ ߘߊ߫ ߒ ߠߊ߫ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲߬ ߝߟߐߡߊ߸ ߕߊ߲ߣߊ߸ ߗߡߍ߬ߣߊ߲... ߠߎ߬ ߘߐ߫.", + "echo-pref-tooltip-watchlist": "ߞߊ߬ ߒ ߖߊ߲߭ߓߌ߬ߟߊ߫ ߣߌ߫ ߘߏߕߌ߰ ߞߊ߬ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲߬ (ߘߋ߬ߣߍ߲߫-ߓߊߟߌ) ߘߏ߫ ߞߍ߫ ߞߐߜߍ ߘߏ߫ ߘߐ߫ ߒ ߠߊ߫ ߜߋ߬ߟߎ߲߬ߠߌ߲߬ ߛߙߍߘߍ ߘߐ߫.", + "echo-pref-tooltip-minor-watchlist": "ߞߊ߬ ߒ ߖߊ߲߭ߓߌ߬ߟߊ߫ ߣߌ߫ ߘߏߕߌ߰ ߞߊ߬ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲߬ ߘߋ߬ߣߍ߲ ߘߏ߫ ߞߍ߫ ߒ ߠߊ߫ ߜߋ߬ߟߎ߲߬ߠߌ߲߬ ߛߙߍߘߍ ߞߐߜߍ ߘߏ߫ ߘߐ߫.", + "notifications": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߟߎ߬", + "tooltip-pt-notifications-alert": "{{GENDER:|ߌ ߟߊ߫}} ߟߊ߬ߛߏ߬ߓߌ߬ߟߌ ߟߎ߬", + "tooltip-pt-notifications-notice": "{{GENDER:|ߌ ߟߊ߫}} ߟߊ߬ߛߏ߬ߓߌ߬ߟߌ ߟߎ߬", + "echo-displaynotificationsconfiguration": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߟߎ߬ ߦߌ߬ߘߊ߬ߟߌ ߘߊߘߐߓߍ߲߬", + "echo-displaynotificationsconfiguration-summary": "ߣߌ߲߬ ߦߋ߫ ߢߊߦߌߘߊߟߌ ߟߋ߬ ߘߌ߫ ߞߊ߬ ߟߐ߬ ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߦߋ߫ ߢߊߓߐ߫ (Configurée) ߟߊ߫ ߢߊ ߡߍ߲ ߡߊ߬ ߥߞߌ ߣߌ߲߬ ߞߊ߲߬.", + "echo-displaynotificationsconfiguration-notifications-by-category-header": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߞߊ߬ ߝߘߊ߫ ߦߌߟߡߊ ߟߊ߫", + "echo-displaynotificationsconfiguration-sorting-by-section-header": "ߛߎ߯ߦߊ ߟߎ߬ ߛߙߊߛߌ߯ߟߌ ߟߎ߬", + "echo-displaynotificationsconfiguration-sorting-by-section-legend": "ߕߍߕߍ߮ ߢߎ߬ߡߊ߲߫ ߠߋ߬ ߘߐ߫ ߣߌ߫ ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߛߎ߯ߦߊ ߓߍ߯ ߛߙߊߛߌ߰ ߟߴߊ߬ ߘߐ߫", + "echo-displaynotificationsconfiguration-available-notification-methods-header": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߞߍߞߌߦߊ ߓߍ߯ ߟߊߘߤߊ߬ߣߍ߲߫", + "echo-displaynotificationsconfiguration-available-notification-methods-by-category-legend": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߞߍߞߌߦߊ ߢߎ߬ߡߊ߲߫ ߠߋ߬ ߦߋ߫ ߟߊߘߤߊ߬ߣߍ߲߫ ߦߋ߫ ߦߌߟߡߊ ߞߋ߬ߟߋ߲߬ߞߋ߬ߟߋ߲߬ߠߊ ߢߍ߫", + "echo-displaynotificationsconfiguration-enabled-default-header": "ߊ߬ ߓߌ߬ߟߴߊ߬ ߟߊ߫ ߞߐߓߊ߯ߦߊ ߘߐ߫", + "echo-displaynotificationsconfiguration-enabled-default-existing-users-legend": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߡߍ߲ ߦߋ߫ ߦߋ߲߬ ߞߘߐ߬ߡߊ߲߫", + "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ߫ ߞߎߘߊ ߟߎ߬", + "echo-displaynotificationsconfiguration-mandatory-notification-methods-header": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߞߍߞߌߦߊ ߟߎ߬ ߦߋ߫ ߘߌߦߊߜߏߦߊ ߟߋ߬ ߘߌ߫", + "echo-displaynotificationsconfiguration-mandatory-notification-methods-by-category-legend": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߞߍߞߌߦߊ ߢߎ߬ߡߊ߲߫ ߠߋ߬ ߦߋ߫ ߘߌߦߊߜߏߦߊߣߍ߲߫ ߦߋ߫ ߦߌߟߡߊ ߞߋ߬ߟߋ߲߬ߞߋ߬ߟߋ߲߬ߠߊ ߢߍ߫", + "echo-specialpage": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߟߎ߬", + "echo-specialpage-section-markread": "ߞߙߎ ߣߐ߬ߣߐ߬ ߘߐ߬ߞߊ߬ߙߊ߲߬ߣߍ߲ ߘߌ߫", + "echo-specialpage-markasread": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ: ߖߊ߬ߕߋ߫ ߘߐ߬ߞߊ߬ߙߊ߲߬ߣߍ߲ ߘߌ߫", + "echo-specialpage-markasread-invalid-id": "ߖߊ߲߬ߖߏ߲ ID ߓߍ߲߬ߣߍ߲߫ ߕߍ߫", + "echo-specialpage-pagefilterwidget-aria-label": "ߞߵߊ߬ ߛߍ߲ߛߍ߲߫ ߥߞߌ ߣߌ߫ ߞߐߜߍ ߞߎ߲߬ߕߐ߮ ߡߊ߬", + "echo-specialpage-special-help-menu-widget-aria-label": "ߢߣߊߕߊߟߌ ߣߌ߫ ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߡߞߊ߬ߝߏ߬ߟߌ ߝߌ߬ߡߊ߲߬ߕߋ߬ ߜߘߍ߫ ߟߎ߫", + "echo-specialpage-pagination-numnotifications": "{{PLURAL:|ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ߫ $1|ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ߫ $1 ߟߎ߬}}", + "echo-specialpage-pagefilters-title": "ߞߏ߫ ߞߍߛߊ߲߫ ߞߎߘߊ", + "echo-specialpage-pagefilters-subtitle": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ߫ ߘߐߞߊ߬ߙߊ߲߬ߓߊߟߊ ߟߎ߬ ߦߋ߫ ߞߐߜߍ ߡߍ߲ ߠߎ߬ ߟߊ߫", + "notificationsmarkread-legend": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߖߊ߬ߕߋ߫ ߘߐ߬ߞߊ߬ߙߊ߲߬ߣߍ߲ ߘߌ߫", + "echo-none": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ߫ ߘߐߞߊ߬ߙߊ߲߬ߓߊߟߌ ߝߋ߲߫ ߕߴߌ ߓߟߏ߫", + "echo-api-failure": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߟߊߛߐ߬ߘߐ߲߬ߠߌ߲ ߓߘߊ߫ ߗߌߙߏ߲߫.", + "echo-api-failure-cross-wiki": "ߓߊ߲߬ ߓߘߊ߫ ߞߍ߫ ߥߎߟߊ߫ ߟߊ߫ ߡߊߘߎ߮ ߟߎ߬ ߟߊߛߐ߬ߘߐ߲ ߡߊ߬.", + "echo-notification-placeholder": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ߫ ߛߌ߫ ߕߍ߫ ߦߋ߲߬.", + "echo-notification-placeholder-filters": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ߫ ߛߌ߫ ߓߍ߲߬ߣߍ߲߫ ߕߍ߫ ߦߋ߲߬ ߛߙߊߕߌ ߣߌ߲߬ ߡߊ߬.", + "echo-notification-loginrequired": "ߌ ߦߴߌ ߜߊ߲߬ߞߎ߲߫ ߞߵߌ ߟߊ߫ ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߟߎ߬ ߦߋ߫.", + "echo-notification-popup-loginrequired": "ߌ ߜߊ߲߬ߞߎ߲߫ ߖߊ߰ߣߌ߲߫ ߞߵߌ ߟߊ߫ ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߟߎ߬ ߦߋ߫.", + "echo-notification-markasread": "ߊ߬ ߣߐ߬ߣߐ߫ ߘߐ߬ߞߊ߬ߙߊ߲߬ߣߍ߲ ߘߌ߫", + "echo-notification-markasunread": "ߊ߬ ߣߐ߬ߣߐ߫ ߘߐ߬ߞߊ߬ߙߊ߲߬ߣߍ߲ ߘߌ߫", + "echo-notification-markasread-tooltip": "ߊ߬ ߣߐ߬ߣߐ߫ ߘߐ߬ߞߊ߬ߙߊ߲߬ߣߍ߲ ߘߌ߫", + "echo-notification-more-options-tooltip": "ߢߣߊߕߊߟߌ߫ ߜߘߍ߫ ߟߎ߫", + "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|}}ߓߘߊ߫ ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߓߌ߬ߟߊ߬ ߡߊ߬ߞߎ߲ ߠߊ߫ \"$1\" ߟߊ߫", + "notification-dynamic-actions-mute-page-linked-confirmation": "\"ߞߐߜߍ ߛߘߌ߬ߜߋ߲\" ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߓߘߊ߫ ߓߐ߫ ߞߐߜߍ \"$1\" ߟߊ߫", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|ߌ߫}} ߘߌ߫ ߛߴߌ ߟߊ߫ ߞߐߜߍ߫ ߡߊߞߎ߲߬ߣߍ߲ ߠߎ߬ ߘߐߓߍ߲߬ ߠߊ߫ [$1 ߟߴߌ ߟߊ߫ ߦߟߌߡߊߛߙߋ ߟߎ߬] ߘߐ߫ ߥߊ߯ߕߌ ߓߍ߯.", + "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2|}}ߓߘߊ߫ ߛߘߌ߬ߜߋ߲ ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߟߎ߬ ߡߊߞߎ߲߬ߣߍ߲ ߓߐ߫ \"$1\" ߟߊ߫", + "notification-dynamic-actions-unmute-page-linked-confirmation": "\"ߞߐߜߍ ߛߘߌ߬ߜߋ߲\" ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߓߘߊ߫ ߟߊߞߎߣߎ߲߫ ߞߐߜߍ \"$1\" ߟߊ߫", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|ߌ߫}} ߘߌ߫ ߛߴߌ ߟߊ߫ ߞߐߜߍ߫ ߡߊߞߎ߲߬ߣߍ߲ ߠߎ߬ ߘߐߓߍ߲߬ ߠߊ߫ [$1 ߟߴߌ ߟߊ߫ ߦߟߌߡߊߛߙߋ ߟߎ߬] ߘߐ߫ ߥߊ߯ߕߌ ߓߍ߯.", + "notification-dynamic-actions-unwatch": "{{GENDER:$3|}}ߓߘߊ߫ ߓߊ߯ߙߊ߫ ߞߎߘߊ߫ ߟߎ߫ ߜߋ߬ߟߎ߲߬ߠߌ߲ ߠߊߟߐ߬ \"$1\" ߟߊ߫", + "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3|ߌ߫}} ߕߍߣߊ߬ ߡߍ߲߫ ߠߊ߫ ߞߐߜߍ \"$1\" ߜߋ߬ߟߎ߲߬ߠߌ߲ ߘߴߏ߬ ߞߐ߫", + "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|ߌ߫}} ߘߌ߫ ߛߋ߫ [ߞߐߜߍ ߣߌ߲߬ $2] ߜߋ߬ߟߎ߲߬ ߠߊ߫ ߕߎ߬ߡߊ߬ ߓߍ߯.", + "notification-dynamic-actions-watch": "{{GENDER:$3|}} \"$1\" ߕߎ߬ߜߍ߬ߕߎ߬ߜߍ߬ߟߌ ߟߊߓߊ߬ߕߏ߬", + "notification-dynamic-actions-watch-confirmation": "{{GENDER:$3|ߌ߫}} ߓߘߊ߫ ߞߐߜߍ \"$1\" ߜߋ߬ߟߎ߲ ߘߊߡߌ߬ߣߊ߬ ߌߞߐߕߎ߲߯", + "notification-dynamic-actions-watch-confirmation-description": "{{GENDER:$3|ߌ߫}}ߘߌ߫ ߛߋ߫ [ߞߐߜߍ ߣߌ߲߬ $2] ߜߋ߬ߟߎ߲߬ߠߌ߲ ߠߊߟߐ߬ ߟߊ߫ ߕߎ߬ߡߊ߬ ߓߍ߯.", + "notification-link-text-expand-all": "ߊ߬ ߘߐߥߛߊ߬", + "notification-link-text-expand-alert-count": "{{PLURAL:|ߟߊ߬ߛߏ߬ߓߌ߬ߟߌ $1|ߟߊ߬ߛߏ߬ߓߌ߬ߟߌ $1 ߟߎ߫}} ߦߋ߫", + "notification-link-text-expand-notice-count": "{{PLURAL:|ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ $1|ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ $1 ߟߎ߫}} ߘߐߜߍ߫", + "notification-link-text-expand-all-count": "{{PLURAL:|ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ $1|ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ $1 ߟߎ߫}} ߘߐߜߍ߫", + "notification-link-text-collapse-all": "ߊ߬ ߘߐߘߏ߲߬", + "notification-link-text-view-message": "ߗߋߛߓߍ ߦߋ߫", + "notification-link-text-view-mention": "ߞߏߝߐߟߌ ߦߋ߫", + "notification-link-text-view-mention-failure": "{{PLURAL:|ߞߏߝߐߟߌ $1 ߦߋ߫|ߞߏߝߐߟߌ $1 ߟߎ߬ ߦߋ߫}}", + "notification-link-text-view-changes": "{{GENDER:$1|ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߠߎ߬}} ߦߋ߫", + "notification-link-text-view-page": "ߞߐߜߍ ߘߐߜߍ߫", + "notification-header-edit-user-talk": "$1 {{GENDER:$2|ߓߘߊ߫}} ߗߋߛߓߍ ߘߏ߫ ߓߌ߬ߟߊ߬ <strong>{{GENDER:$3|ߌ ߟߊ߫}} ߞߎߡߊ߫ ߞߐߜߍ ߟߊ߫</strong>", + "notification-header-edit-user-talk-with-section": "$1 {{GENDER:$2|ߓߘߊ߫}} ߗߋߛߓߍ ߘߏ߫ ߓߌ߬ߟߊ߬ <strong>{{GENDER:$3|ߌ ߟߊ߫}} ߞߎߡߊ߫ ߞߐߜߍ ߟߊ߫</strong> ߕߍߕߍ߮ \"<strong>$4</strong>\" ߘߐ߫", + "notification-compact-header-edit-user-talk": "$1 {{GENDER:$2|ߓߘߊ߫}} ߗߋߛߓߍ ߘߏ߫ ߓߌ߬ߟߊ߬ {{GENDER:|ߌ߫}} $3 ߡߊ߬.", + "notification-compact-header-edit-user-talk-with-section": "$1 {{GENDER:$2|ߓߘߊ߫}} ߗߋߛߓߍ ߘߏ߫ ߓߌ߬ߟߊ߬ {{GENDER:|ߌ߫}}$3 ߡߊ߬ \"<strong>$4</strong>\" ߟߊ߫.", + "notification-header-page-linked": "ߛߘߌ߬ߜߋ߲ ߘߏ߫ ߓߘߊ߫ ߛߌ߲ߘߌ߫ ߞߊ߬ ߝߘߊ߫ <strong>$4</strong> ߟߊ߫ ߞߵߊ߬ ߟߊߘߊ߲߫ <strong>$3</strong> ߘߐ߫.", + "notification-compact-header-page-linked": "ߜߋ߲߬ߞߘߎ߬ߣߍ߲߫ ߦߋ߫ <strong>$1</strong> ߟߋ߬ ߟߊ߫", + "notification-bundle-header-page-linked": "ߛߘߌ߬ߜߋ߲ ߡߍ߲ ߓߌ߬ߟߊ߬ߣߍ߲߫ ߦߋ߫ <strong>$3</strong> ߡߊ߬߸ ߏ߬ ߜߙߋ߬ߡߊߕߍ߰ߣߍ߲߫ ߦߋ߫ ߞߊ߬ ߝߘߊ߫ {{PLURAL:|ߞߐߜߍ $5|ߞߐߜߍ ߁߀߀=߉߉+ ߟߎ߬}}", + "notification-header-article-reminder": "{{GENDER:$2|ߌ}} ߣߴߊ߬ ߢߌߣߌ߲߫ ߠߊ߫ ߞߏ߫ ߞߵߌ ߖߊ߲߬ߓߌ߬ߟߊ߬ ߞߐߜߍ ߡߍ߲ ߠߊ߫߸ ߏ߬ ߦߋ߫ <strong>$3</strong> ߟߋ߬ ߘߐ߫", + "notification-link-text-what-links-here": "ߛߘߌ߬ߜߋ߲ ߡߍ߲ ߓߍ߯ ߦߋ߫ ߞߐߜߍ ߣߌ߲߬ ߘߐ߫", + "notification-header-mention-other": "$1 ߓߘߊ߫ {{GENDER:$2|ߌ}} {{GENDER:$3|ߕߐ߯ߘߐߕߍ߰}} <strong>$4</strong> ߘߐ߫ <strong>$5</strong> ߞߊ߲߬", + "notification-header-mention-other-nosection": "$1 ߓߘߊ߫ {{GENDER:$2|ߌ}} {{GENDER:$3|ߕߐ߯ߘߐߕߍ߰}} <strong>$4</strong> ߘߐ߫.", + "notification-header-mention-user-talkpage-v2": "$1 {{GENDER:$2|}} ߓߘߴߌ {{GENDER:$3|}} ߞߏߝߐ߫ <strong>{{GENDER:$5|ߟߊ߫}} ߞߎߡߊ߫ ߞߐߜߍ $4 ߘߐ߫ </strong> <strong>$6</strong> ߘߐ߫.", + "notification-header-mention-user-talkpage-nosection": "$1 {{GENDER:$2|}} ߓߘߊ߫ {{GENDER:$3|ߌ}}ߞߏߝߐ߫ <strong>{{GENDER:$5|ߟߊ߫}} ߞߎߡߊ߫ ߞߐߜߍ $4</strong> ߘߐ߫.", + "notification-header-mention-agent-talkpage": "$1 {{GENDER:$2|ߓߘߊ߫}} {{GENDER:$3|ߌ}}ߞߏߝߐ߫ <strong>{{GENDER:$2|ߊ߬ ߟߊ߫|ߊ߬ ߟߊ߫|ߊ߬ߟߎ߫ ߟߊ߫}} ߞߎߡߊ߫ ߞߐߜߍ ߘߐ߫</strong> <strong>$4</strong> ߘߐ߫.", + "notification-header-mention-agent-talkpage-nosection": "$1 {{GENDER:$2|ߓߘߊ߫}} {{GENDER:$3|ߌ}}ߞߏߝߐ߫ <strong>{{GENDER:$2|ߊ߬ ߟߊ߫|ߊ߬ ߟߊ߫|ߊ߬ߟߎ߫ ߟߊ߫}} ߞߎߡߊ߫ ߞߐߜߍ ߘߐ߫</strong>", + "notification-header-mention-article-talkpage": "$1 ߓߘߊ߫ {{GENDER:$2|ߌ}} {{GENDER:$3|ߕߐ߯ߘߐߕߍ߰}} <strong>$4</strong> ߘߐ߫ <strong>$5</strong> ߞߊ߲߬.", + "notification-header-mention-article-talkpage-nosection": "$1 ߓߘߊ߫ {{GENDER:$2|ߌ}} {{GENDER:$3|ߕߐ߯ߘߐߕߍ߰}} ߞߎߡߊ߫ ߞߐߜߍ <strong>$4</strong> ߘߐ߫.", + "notification-header-mention-failure-user-unknown": "{{GENDER:$2|ߌ ߟߊ߫}}<strong>$3</strong> ߞߏߝߐߟߌ ߡߊ߫ ߗߋ߫ ߓߊߏ߬ ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߏ߬ ߡߊ߫ ߛߐ߬ߘߐ߲߫.", + "notification-header-mention-failure-user-anonymous": "{{GENDER:$2|ߌ ߟߊ߫}} <strong>$3</strong> ߞߏߝߐߟߌ ߡߊ߫ ߗߋ߫ ߓߊߏ߬ ߕߐ߯ ߕߍ߫ ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߟߊ߫.", + "notification-header-mention-failure-too-many": "{{GENDER:$2|ߌ}} ߞߏߝߐߟߌ ߞߍ߫ ߞߊ߬ ߕߊ߬ߡߌ߲߫ ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ߫{{PLURAL:$3|ߟߎ߬}} ߟߊ߫. ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ߫ ߞߏߝߐߣߍ߲ ߡߍ߲ ߓߍ߯ ߦߋ߫ ߛߊ߲ߘߐ߫ ߣߌ߲߬߸ ߏ߬ ߟߎ߫ ߡߊ߫ ߙߋ߫.", + "notification-header-mention-failure-bundle": "ߡߍ߲ ߟߐ߬ ߕߐ߫ ߦߋ߫ {{GENDER:$2|ߌ ߟߊ߫}} ߞߏߝߐߟߌ߫{{PLURAL:$3|ߟߎ߫}} ߡߊ߬ ߞߎߡߊ߫ ߞߐߜߍ <strong>$4</strong> ߘߐ߫ {{PLURAL:$3|ߟߎ߫}} ߕߍߣߊ߬ ߗߋ߫ ߟߊ߫.", + "notification-compact-header-mention-failure-user-unknown": "<strong>ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ: $1 ߕߍ߫ ߦߋ߲߬</strong>", + "notification-compact-header-mention-failure-user-anonymous": "<strong>IP $1 ߕߍ߫ ߣߊ߬ ߛߐ߲߬ ߠߊ߫ ߞߏߝߐ߫ ߟߊ߫</strong>", + "notification-header-mention-success": "{{GENDER:$2|ߌ ߟߊ߫}} <strong>$3</strong> ߟߎ߫ ߕߐ߯ߘߐߕߍߟߌ ߓߘߊ߫ ߗߋ߫.", + "notification-header-mention-success-bundle": "ߞߏߝߐߟߌ߫{{PLURAL:$3|ߡߍ߲ ߠߎ߬}} ߞߍߣߍ߲߫ ߦߋ߫ {{GENDER:$2|ߌ}} ߓߟߏ߫ ߞߎߡߊ߫ ߞߐߜߍ <strong>$4</strong> ߘߐ߫ {{PLURAL:$3|ߟߎ߫}} ߓߘߊ߫ ߗߋ߫.", + "notification-compact-header-mention-success": "<strong>{{GENDER:$2|ߌ ߓߘߊ߫}}$3 ߞߏߝߐ߫</strong>", + "notification-header-mention-status-bundle": "{{PLURAL:|ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߘߏ߫ $3|ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ $3 ߟߎ߬}} ߞߊ߬ ߓߍ߲߬ ߞߏߝߐߟߌ ߡߊ߬ {{GENDER:$2|ߌ ߣߐ߬ ߡߍ߲ ߛߌ߲ߘߌ߫}} ߟߊ߫ <strong>$4</strong> ߞߎߡߊ߫ ߞߐߜߍ ߘߐ߫: {{PLURAL:$5|$5}} ߟߎ߫ ߡߊ߬ ߗߋ߫߸ {{PLURAL:| ߗߋߣߍ߲ $6}}", + "notification-header-user-rights-add-only": "{{GENDER:$4|ߌ}} ߤߊߞߍ ߓߘߊ߫ ߡߊߝߊ߬ߟߋ߲߫ {{GENDER:$1|ߓߟߏ߫}} ߌ ߓߘߊ߫ ߓߌ߬ߟߊ߬: $2 ߘߐ߫.", + "notification-header-user-rights-remove-only": "{{GENDER:$4|ߌ ߟߊ߫}} ߟߊ߬ߓߊ߰ߙߊ߬ߟߌ߫ ߤߊߞߍ ߓߘߊ߫ ߡߊߝߊ߬ߟߋ߲߫ {{GENDER:$1|ߓߟߏ߫}}. ߌ ߕߍ߫ $2 ߛߌ߲߬ߝߏ߲ ߝߋ߲߫ ߘߴߏ߬ ߞߐ߫.", + "notification-header-user-rights-add-and-remove": "{{GENDER:$6|ߌ ߟߊ߫}} ߟߊ߬ߓߊ߰ߙߊ߬ߟߌ߫ ߤߊߞߍ ߓߘߊ߫ ߡߊߝߊ߬ߟߋ߲߫ {{GENDER:$1|ߓߟߏ߫}}. ߌ ߓߘߊ߫ ߝߊ߬ߙߊ߫: $2 ߟߊ߫. ߌ ߕߍ߫ $4 ߛߌ߲߬ߝߏ߲߬ ߘߴߏ߬ ߞߐ߫.", + "notification-header-user-rights-expiry-change": "{{GENDER:$4|ߌ ߟߊ߫}} {{PLURAL:|ߞߙߎ $3|ߞߙߎ $3 ߟߎ߬}} ߛߌ߲߬ߝߏ߲߬ߦߊ ߛߕߊ ߘߌ߫ ߝߊ߫ ߕߎߡߊ ߓߘߊ߫ ߡߊߝߊ߬ߟߋ߲߫ {{GENDER:$1|ߓߟߏ߫}}: $2.", + "notification-header-welcome": "{{GENDER:$2|ߌ ߣߌ߫ ߛߣߍ߫}} {{SITENAME}} ߞߊ߲߬߸ $1߹ ߊ߲ ߓߘߊ߫ ߛߍߥߊ߫ {{GENDER:$2|ߌ}} ߦߋߟߌ ߟߊ߫ ߦߊ߲߬.", + "notification-header-mention-summary": "$1 ߓߘߊ߫ {{GENDER:$2|ߌ}} {{GENDER:$3|ߕߐ߯ߘߐߕߍ߰}} ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߟߊ߬ߘߛߏ߬ߟߌ ߘߏ߫ ߘߐ߫ ߦߊ߲߬ <strong>$4</strong>", + "notification-header-watchlist-changed": "$1 {{GENDER:$2|}}ߓߘߊ߫ <strong>$3</strong> ߡߊߦߟߍ߬ߡߊ߲߫߸ ߞߐߜߍ ߡߍ߲ ߦߋ߫ {{GENDER:$4|ߌ ߟߊ߫}} ߜߋ߬ߟߎ߲߬ߠߌ߲߬ߛߙߍߘߍ{{PLURAL:|ߛߋ߲߬ߧߊ߫ $5|ߛߋ߲߬ߧߊ߬ $5}}.", + "notification-header-watchlist-created": "$1 {{GENDER:$2|}} ߓߘߊ߫ <strong>$3</strong> ߛߌ߲ߘߌ߫ ߸ߞߐߜߍ ߏ߬ ߘߏ߲߬ ߦߋ߫ {{GENDER:$4|ߌ ߟߊ߫}} ߜߋ߬ߟߎ߲߬ߠߌ߲߬ ߛߙߍߘߍ ߘߐ߫{{PLURAL:|ߛߋ߲߬ߧߊ߫ $5|ߛߋ߲߬ߢߊ߬ $5}}.", + "notification-header-watchlist-deleted": "$1 {{GENDER:$2|}} ߓߘߊ߫ <strong>$3</strong> ߖߏ߰ߛߌ߫ ߸ߞߐߜߍ ߏ߬ ߘߏ߲߬ ߦߋ߫ {{GENDER:$4|ߌ ߟߊ߫}} ߜߋ߬ߟߎ߲߬ߠߌ߲߬ ߛߙߍߘߍ ߘߐ߫{{PLURAL:|ߛߋ߲߬ߧߊ߫ $5|ߛߋ߲߬ߢߊ߬ $5}}.", + "notification-header-watchlist-moved": "$1 {{GENDER:$2|}}ߓߘߊ߫ <strong>$3</strong> ߕߐ߮ ߦߟߍ߬ߡߊ߲߫߸ ߞߐߜߍ ߏ߬ ߘߏ߲߬ ߦߋ߫ {{GENDER:$4|ߌ ߟߊ߫}} ߜߋ߬ߟߎ߲߬ߠߌ߲߬ߛߙߍߘߍ ߟߋ߬ ߘߐ߫{{PLURAL:|ߛߋ߲߬ߧߊ߫ $5|ߛߋ߲߬ߧߊ߬ $5}}.", + "notification-header-watchlist-restored": "$1 {{GENDER:$2|}} ߓߘߊ߫ <strong>$3</strong> ߟߊߞߎߣߎ߲߫߸ ߞߐߜߍ ߏ߬ ߘߏ߲߬ ߦߋ߫ {{GENDER:$4|ߌ ߟߊ߫}} ߜߋ߬ߟߎ߲߬ߠߌ߲߬ ߛߙߍߘߍ ߘߐ߫{{PLURAL:|ߛߋ߲߬ߧߊ߫ $5|ߛߋ߲߬ߢߊ߬ $5}}.", + "notification-header-watchlist-multiuser-changed": "ߞߐߜߍ <strong>$1</strong> ߡߍ߲ ߦߋ߫ {{GENDER:$2|ߌ ߟߊ߫}} ߜߋ߬ߟߎ߲߬ߠߌ߲߬ ߛߙߍߘߍ ߘߐ߫߸ ߓߘߊ߫ ߡߊߦߟߍ߬ߡߊ߲߫ ߛߋ߲߬ߧߊ߫ {{PLURAL:$3|}} ߛߋ߲߬ߧߊ߫ $3 ߟߎ߫.", + "notification-header-watchlist-multiuser-created": "ߞߐߜߍ <strong>$1</strong> ߡߍ߲ ߦߋ߫ {{GENDER:$2|ߌ ߟߊ߫}} ߜߋ߬ߟߎ߲߬ߠߌ߲߬ ߛߙߍߘߍ ߘߐ߫߸ ߏ߬ ߓߘߊ߫ ߛߌ߲ߘߌ߫ ߛߋ߲߬ߧߊ߫ {{PLURAL:$3|ߛߋ߲߬ߧߊ߫ $3}}ߟߎ߫.", + "notification-header-watchlist-multiuser-deleted": "ߞߐߜߍ ߘߏ߫ <strong>$1</strong>߸ ߡߍ߲ ߦߋ߫ {{GENDER:$2|ߌ ߟߊ߫}} ߜߋ߬ߟߎ߲߬ߠߌ߲߬ ߛߙߍߘߍ ߘߐ߫߸ ߓߘߊ߫ ߖߏ߰ߛߌ߫ ߛߋ߲߫ߧߊ߫ {{PLURAL:$3|}} $3 ߠߎ߫.", + "notification-header-watchlist-multiuser-moved": "ߞߐߜߍ ߘߏ߫ <strong>$1</strong>߸ ߡߍ߲ ߦߴ{{GENDER:$2|ߌ ߟߊ߫}} ߜߋ߬ߟߎ߲߬ߠߌ߲߬ ߛߙߍߘߍ ߘߐ߫߸ ߕߐ߮ ߓߘߊ߫ ߦߟߍ߬ߡߊ߲߫ ߛߋ߲߬ߧߊ߬ {{PLURAL:$3|}} $3 ߟߎ߫.", + "notification-header-watchlist-multiuser-restored": "ߞߐߜߍ <strong>$1</strong> ߡߍ߲ ߦߋ߫ {{GENDER:$2|ߌ ߟߊ߫}} ߜߋ߬ߟߎ߲߬ߠߌ߲߬ ߛߙߍߘߍ ߘߐ߫߸ ߏ߬ ߓߘߊ߫ ߟߊߛߊ߬ߦߌ߫ ߛߋ߲߬ߧߊ߬{{PLURAL:$3|ߛߋ߲߬ߧߊ߫ $3}}ߟߎ߫.", + "notification-body-watchlist-once": "ߢߎߡߍߙߋ߲ߞߏ߲ߘߏ߫ ߟߊ߫ ߖߊ߲ߓߌߟߊߟߌ߫ ߜߘߍ߫ ߟߎ߫ ߕߍ߫ ߣߊ߬ ߞߍ߫ ߟߴߏ߬ ߘߐ߫ ߞߏߟߊߞߏߕߍ߫ ߣߴߊ߬ ߓߍ߲߬ ߘߊ߫ ߞߏ ߘߏ߫ ߟߎ߫ ߞߍߟߌ ߡߊ߬ ߝߏߣߴ{{GENDER:$1|ߌ}}ߓߐ߫ ߘߊ߫ ߞߐߜߍ ߣߌ߲߬ ߡߊ߬ ߌ ߜߊ߲߬ߞߎ߲߬ߣߍ߲ ߞߐ߫.", + "notification-welcome-linktext": "ߊߟߎ߫ ߣߌ߫ ߛߣߍ߫", + "notification-header-thank-you-1-edit": "{{GENDER:$2|ߌ}} ߓߘߴ{{GENDER:$2|ߌ ߟߊ߫}} ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲߫ ߝߟߐ ߞߍ߫: {{GENDER:$2|ߌ}} ߣߌ߫ ߗߋ߫߸ ߊ߬ ߣߴߌ ߣߌ߫ ߛߣߍ߫߹", + "notification-header-thank-you-10-edit": "{{GENDER:$2|ߌ}} ߓߘߴ{{GENDER:$2|ߌ ߟߊ߫}} ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߕߊ߲ߣߊ߲ ߞߍ߫: {{GENDER:$2|ߌ}} ߣߌ߫ ߗߋ߫: ߗߍ߬ ߌ߫ ߘߐߖߊ߬ ߏ߬ ߞߊ߲߬ ߤߊ߲߫߹", + "notification-header-thank-you-100-edit": "{{GENDER:$2|ߌ}} ߓߘߴ{{GENDER:$2|ߌ ߟߊ߫}} ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߗߡߍ߬ߣߊ߲ ߞߍ߫: {{GENDER:$2|ߌ}} ߣߌ߫ ߗߋ߫ ߞߏߛߓߍ߫߹", + "notification-header-thank-you-1000-edit": "{{GENDER:$2|ߌ}} ߓߘߴ{{GENDER:$2|ߌ ߟߊ߫}} ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߥߊ߯ߣߊ߲ ߞߍ߫: {{GENDER:$2|ߌ}} ߣߌ߫ ߗߋ߫ ߌ ߞߍ ߟߊ߫ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߊ߫ ߓߟߋߓߟߋ ߘߏ߫ ߘߌ߫߹", + "notification-header-thank-you-10000-edit": "{{GENDER:$2|ߌ}} ߓߘߴ{{GENDER:$2|ߌ ߟߊ߫}} ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲߫ ߥߊ߯-ߕߊ߲ߣߊ߲ ߞߍ߫: {{GENDER:$2|ߌ}} ߣߌ߫ ߗߋ߫ ߞߏߟߌߞߏߟߌ߫߹", + "notification-header-thank-you-100000-edit": "{{GENDER:$2|ߌ}} ߓߘߴ{{GENDER:$2|ߌ ߟߊ߫}} ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߥߊ߯-ߗߡߍߣߊ߲ ߞߍ߫: {{GENDER:$2|ߌ}} ߣߌ߫ ߗߋ߫ {{GENDER:$2|ߌ ߟߊ߫}} ߝߓߊ߬ߘߋ߲߬ ߓߟߏߡߊߜߍ߲߫ ߛߎ߮ ߣߌ߲߬ ߠߊ߫ ߡߌ߬ߙߌ߲߬ߘߌ ߢߍ߫߹", + "notification-header-thank-you-1000000-edit": "{{GENDER:$2|ߌ}} ߓߘߴ{{GENDER:$2|ߌ ߟߊ߫}} ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߞߋ߲߬ߥߟߎ߬ߣߊ߲ ߞߍ߫: {{GENDER:$2|ߌ}} ߣߌ߫ ߗߋ߫ ߌ ߞߍ ߟߊ߫ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߊ߫ ߞߙߍߞߙߍߣߍ߲ ߘߏ߫ ߘߌ߫߹", + "notification-header-thank-you-10000000-edit": "{{GENDER:$2|ߌ}} ߓߘߴ{{GENDER:$2|ߌ ߟߊ߫}} ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߞߋ߲߬ߥߟߎ߬-ߕߊ߲߬ߣߊ߲ ߞߍ߫; {{GENDER:$2|ߌ}} ߣߌ߫ ߗߋ߫ {{GENDER:$2|ߌ ߟߊ߫}} ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲߫ ߡߊߦߋߙߋ߲ߣߍ߲ ߏ߬ ߟߊ߫߹", + "notification-link-thank-you-edit": "{{GENDER:$1|ߌ ߟߊ߫}} ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲", + "notification-link-text-view-edit": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߦߋ߫", + "notification-link-article-reminder": "ߞߐߜߍ ߘߐߜߍ߫", + "notification-header-reverted": "ߌ ߟߊ߫ {{PLURAL:|ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲߫ $4 ߡߍ߲ ߦߋ߫ <strong>$3</strong> ߘߐ߫߸ ߓߘߊ߫|ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲߫ <strong>$3</strong> ߘߐ߫߸ ߓߘߊ߫}}{{GENDER:|ߟߊߕߊ߲߬ߞߌ߫ $2}}.", + "notification-header-emailuser": "$1 {{GENDER:$2|}}ߓߘߊ߫ ߢߎߡߍߙߋ߲ ߘߏ߫ ߗߋ߫ ߌ ߡߊ߬.", + "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$2|ߓߘߊ߫}} ߗߋߛߓߍ ߘߏ߫ ߓߌ߬ߟߊ߬ {{GENDER:|ߌ߫}} $3 ߡߊ߬ {{SITENAME}} ߞߊ߲߬", + "notification-page-linked-email-subject": "{{GENDER:$3|ߌ}} ߣߊ߬ ߞߐߜߍ ߡߍ߲ ߛߌ߲ߘߌ߫ ߟߊ߫ ߏ߬ ߛߘߌ߬ߜߋ߲ ߓߘߊ߫ ߛߘߌ߬ {{SITENAME}} ߟߊ߫", + "notification-reverted-email-subject2": "{{GENDER:$3|ߌ ߟߊ߫}} {{PLURAL:|ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ $4 ߓߘߊ߫|ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ $4 ߟߎ߬ ߓߘߊ߫}} {{GENDER:$2|ߘߐߛߊ߬}} {{SITENAME}} ߞߊ߲߬", + "notification-mention-email-subject": "$1 {{GENDER:$2|ߓߘߊ߫}} {{GENDER:$3|ߌ}} ߕߐ߯ߘߐߕߍ߰ {{SITENAME}} ߞߊ߲߬", + "notification-user-rights-email-subject": "{{GENDER:$3|ߌ ߟߊ߫}} ߟߊ߬ߓߊ߰ߙߊ߬ߟߌ߫ ߤߊߞߍ ߓߘߊ߫ ߡߊߝߊ߬ߟߋ߲߫ {{SITENAME}} ߞߊ߲߬", + "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1s|}}", + "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1m}}", + "notification-timestamp-ago-hours": "{{PLURAL:$1|$1h}}", + "notification-timestamp-ago-days": "{{PLURAL:$1|$1d}}", + "notification-timestamp-ago-months": "{{PLURAL:$1|$1mo}}", + "notification-timestamp-ago-years": "{{PLURAL:$1|$1yr}}", + "notification-timestamp-today": "ߓߌ߬", + "notification-timestamp-yesterday": "ߞߎߣߎ߲߬", + "notification-inbox-filter-read": "ߘߐ߬ߞߊ߬ߙߊ߲߬ߣߍ߲", + "notification-inbox-filter-unread": "ߘߐ߬ߞߊ߬ߙߊ߲߬ߓߊߟߌ", + "notification-inbox-filter-all": "ߊ߬ ߓߍ߯", + "echo-specialmute-label-mute-notifications": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߟߎ߬ ߡߊߞߎ߲߬ ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߣߌ߲߬{{GENDER:$1|}} ߡߊ߬", + "echo-email-plain-footer": "ߖߐ߲߬ߛߊ߫ ߞߵߊ߬ ߛߎߥߊ߲ߘߌ߫ ߊ߲ ߞߊ߬ ߢߎߡߍߙߋ߲ ߡߍ߲ ߗߋ߫ {{GENDER:$1|ߌ}}ߡߊ߬߸ {{GENDER:$1|ߌ ߟߊ߫}} ߦߟߌߡߊߛߙߋ ߟߎ߬ ߝߛߍ߬ߝߛߍ߫:", + "echo-email-html-footer-preference-link-text": "{{GENDER:$1|ߌ ߟߊ߫}} ߤߣߍߕߊ ߟߎ߬ ߝߛߍ߬ߝߛߍ߫", + "echo-email-html-footer-with-link": "ߖߐ߲߬ߛߊ߫ ߞߊ߬ ߊ߬ ߡߊߝߟߍ߫ ߊ߲ ߞߊ߬ ߢߎߡߍߙߋ߲߫ ߗߋߛߓߍ ߡߍ߲ ߗߋ߫ {{GENDER:$2|ߌ}} ߡߊ߬߸ $1", + "echo-notification-alert": "{{PLURAL:|ߟߊ߬ߛߏ߬ߓߌ߬ߟߌ߫ ($1)|ߟߊ߬ߛߏ߬ߓߌ߬ߟߌ߫ ($1) ߟߎ߬|ߟߊ߬ߛߏ߬ߓߌ߬ߟߌ߫ 100= (99+)}}", + "echo-notification-alert-text-only": "ߟߊ߬ߛߏ߬ߓߌ߬ߟߌ ߟߎ߬", + "echo-notification-notice-text-only": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߟߎ߬", + "echo-overlay-link": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߟߎ߬ ߓߍ߯", + "echo-overlay-title": "<b>ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߟߎ߬</b>", + "echo-mark-all-as-read": "ߊ߬ ߓߍ߯ ߣߐ߬ߣߐ߫ ߘߐ߬ߞߊ߬ߙߊ߲߬ߣߍ߲ ߘߌ߫", + "echo-mark-all-as-read-confirmation": "{{PLURAL:|ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ $1|ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ $1 ߟߎ߬}} ߓߘߊ߫ ߣߐ߬ߣߐ߬ ߘߐ߬ߞߊ߬ߙߊ߲߬ߣߍ߲ ߘߌ߫.", + "echo-mark-wiki-as-read": "ߊ߬ ߓߍ߯ ߣߐ߬ߣߐ߬ ߘߐ߬ߞߊ߬ߙߊ߲߬ߣߍ߲ ߘߌ߫ ߥߞߌ߫ ߓߊߕߐ߬ߡߐ߲߬ߣߍ߲: $1 ߠߊ߫", + "echo-displaysnippet-title": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ߫ ߞߎߘߊ", + "echo-date-today": "ߓߌ߬", + "echo-date-yesterday": "ߞߎߣߎ߲߬", + "echo-email-batch-subject-daily": "ߌ ߓߘߊ߫ {{PLURAL:|ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ߫ ߞߎߘߊ ߘߏ߫|ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ߫ ߞߎߘߊ߫ $2 ߟߎ߫}} ߛߐ߬ߘߐ߲߬ {{SITENAME}} ߛߌߟߊ ߝߍ߬", + "echo-email-batch-subject-weekly": "ߌ ߓߘߊ߫ {{PLURAL:|ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ߫ ߞߎߘߊ ߘߏ߫|ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ߫ ߞߎߘߊ $2 ߟߎ߫}} ߛߐ߬ߘߐ߲߬ {{SITENAME}} ߛߌߟߊ ߝߍ߬ ߞߎ߲߬ߢߐ߮ ߣߌ߲߬ ߞߘߐ߫", + "echo-email-batch-body-intro-daily": "ߌ ߣߌ߫ ߕߎ߬ߡߊ߫ $1߸\nߓߌ߬ ߓߊ߯ߙߊ߫ ߣߐ ߟߎ߬ ߟߊߘߛߏߣߍ߲ ߠߋ߬ ߦߋ߫ ߌߟߋ ߢߍ߫ ߣߌ߲߬ {{SITENAME}} ߞߊ߲߬", + "echo-email-batch-body-intro-weekly": "ߌ ߣߌ߫ ߕߎ߬ߡߊ߬ $1߸ \nߣߌ߲߬ ߦߴߌ ߟߊ߫ ߞߎ߲߬ߢߐ߮ ߣߌ߲߬ ߓߊ߯ߙߊߣߐ ߟߎ߬ ߟߊߘߛߏߣߍ߲ ߠߎ߬ ߟߋ߬ ߘߌ߫ {{SITENAME}} ߞߊ߲߬.", + "echo-email-batch-link-text-view-all-notifications": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ ߟߎ߬ ߓߍ߯ ߦߋ߫", + "notification-header-foreign-alert": "ߟߊ߬ߛߏ߬ߓߌ߬ߟߌ߫ ߜߘߍ ߟߎ߬ ߟߎ߫ ߞߊ߬ ߝߘߊ߫ {{PLURAL:|ߥߞߌ߫ ߜߘߍ߫ $5|ߜߘߍ߫ ߟߎ߫ $5}} ߟߊ߫", + "notification-header-foreign-notice": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ߫ ߜߘߍ߫ ߟߎ߫ ߞߊ߬ ߝߘߊ߫ {{PLURAL:|ߥߞߌ߫ ߜߘߍ߫ $5|ߥߞߌ߫ ߜߘߍ ߟߎ߬ $5}} ߟߊ߫", + "notification-header-foreign-all": "ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ߫ ߜߘߍ߫ ߟߎ߫ ߞߊ߬ ߝߘߊ߫ {{PLURAL:|ߥߞߌ߫ ߜߘߍ߫ $5|ߥߞߌ߫ ߜߘߍ ߟߎ߬ $5}} ߟߊ߫", + "right-manage-all-push-subscriptions": "ߘߌ߯ߟߌ ߡߊ߬ߢߌ߬ߣߌ߲߬ߞߊ߬ߟߌ ߟߎ߫ ߓߍ߯ ߢߊߓߐ߫", + "action-manage-all-push-subscriptions": "ߕߎ߲߬ߕߎ߲߬ߠߌ߲ ߡߊ߬ߢߌ߬ߣߌ߲߬ߞߊ߬ߟߌ ߟߎ߬ ߓߍ߯ ߢߊߓߐ߫", + "group-push-subscription-manager": "ߕߎ߲߬ߕߎ߲߬ߠߌ߲ ߡߊ߬ߢߌ߬ߣߌ߲߬ߞߊ߬ߟߌ ߢߊߓߐߟߊ߲" } diff --git a/Echo/i18n/ojb.json b/Echo/i18n/ojb.json new file mode 100644 index 00000000..2a395b6f --- /dev/null +++ b/Echo/i18n/ojb.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Aandeginini" + ] + }, + "tooltip-pt-notifications-alert": "{{GENDER:|Giin}} zegim" +} diff --git a/Echo/i18n/om.json b/Echo/i18n/om.json new file mode 100644 index 00000000..07eb393b --- /dev/null +++ b/Echo/i18n/om.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Maammee" + ] + }, + "tooltip-pt-notifications-alert": "Yaadachiisota {{GENDER:|kee}}" +} diff --git a/Echo/i18n/pfl.json b/Echo/i18n/pfl.json deleted file mode 100644 index 2e41e363..00000000 --- a/Echo/i18n/pfl.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Manuae" - ] - } -} diff --git a/Echo/i18n/pl.json b/Echo/i18n/pl.json index 3f5c30c3..29eac24a 100644 --- a/Echo/i18n/pl.json +++ b/Echo/i18n/pl.json @@ -16,6 +16,7 @@ "Rail", "Railfail536", "Rzuwig", + "SemanticPioneer", "Sethakill", "Tar Lócesilion", "The Polish", @@ -41,7 +42,7 @@ "echo-pref-email-format": "Format e-maila:", "echo-pref-web": "Na stronie", "echo-pref-email": "Przez e‐mail", - "echo-pref-push": "W telefonie (tylko aplikacje)", + "echo-pref-push": "W aplikacji", "echo-pref-email-frequency-never": "Nie wysyłaj powiadomień e-mailem", "echo-pref-email-frequency-immediately": "Każde powiadomienie osobno", "echo-pref-email-frequency-daily": "Podsumowanie dzienne", @@ -49,13 +50,13 @@ "echo-pref-email-format-html": "HTML", "echo-pref-email-format-plain-text": "Zwykły tekst", "echo-pref-cross-wiki-notifications": "Pokazuj powiadomienia z innych wiki", - "echo-pref-notifications-blacklist": "Nie wyświetlaj powiadomień od tych użytkowników. ([[mw:Special:MyLanguage/Help:Notifications#mute|dowiedz się więcej]])", - "echo-pref-notifications-page-linked-title-muted-list": "Nie wyświetlaj powiadomień „Link do moich artykułów” dla tych stron. ([[mw:Special:MyLanguage/Help:Notifications#mute|dowiedz się więcej]])", + "echo-pref-notifications-blacklist": "Nie wyświetlaj powiadomień od tych użytkowników ([[mw:Special:MyLanguage/Help:Notifications#mute|dowiedz się więcej]]).", + "echo-pref-notifications-page-linked-title-muted-list": "Nie wyświetlaj powiadomień „Link do moich artykułów” dla tych stron ([[mw:Special:MyLanguage/Help:Notifications#mute|dowiedz się więcej]]).", "echo-pref-dont-email-read-notifications": "Nie uwzględniaj przeczytanych powiadomień w mailach podsumowujących", "echo-learn-more": "Dowiedz się więcej", "echo-log": "Rejestr publiczny", - "echo-new-messages": "Masz nowe wiadomości", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Wpis|Wpisy}} w dyskusji", + "echo-new-messages": "Masz nową wiadomość na stronie dyskusji", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Edycja|Edycje}} na mojej stronie dyskusji", "echo-category-title-article-linked": "{{PLURAL:$1|Link|Linki}} do moich artykułów", "echo-category-title-reverted": "{{PLURAL:$1|Rewert|Rewerty}} edycji", "echo-category-title-mention": "{{PLURAL:$1|Wzmianka|Wzmianki}}", @@ -71,7 +72,7 @@ "echo-category-title-thank-you-edit": "{{PLURAL:$1|Kamień milowy|Kamienie milowe}} edycji", "echo-category-title-watchlist": "Edycja w obserwowanej stronie", "echo-category-title-minor-watchlist": "Drobna zmiana w obserwowanej stronie", - "echo-pref-tooltip-edit-user-talk": "Powiadom mnie, kiedy ktoś napisze nową wiadomość albo odpowie na mojej stronie dyskusji.", + "echo-pref-tooltip-edit-user-talk": "Powiadom mnie, kiedy ktoś dokona zmian na mojej stronie dyskusji użytkownika.", "echo-pref-tooltip-article-linked": "Powiadom mnie, kiedy ktoś umieści na innej stronie link do strony utworzonej przeze mnie.", "echo-pref-tooltip-reverted": "Powiadom mnie, kiedy ktoś cofnie moją edycję korzystając z narzędzia „cofnij” albo „wycofaj”.", "echo-pref-tooltip-mention": "Powiadom mnie, kiedy ktoś umieści link do mojej strony użytkownika.", @@ -125,15 +126,15 @@ "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2|Ponownie włącz}} powiadomienia o linkach na „$1”", "notification-dynamic-actions-unmute-page-linked-confirmation": "Powiadomienia o linkach do strony „$1” są teraz włączone", "notification-dynamic-actions-unmute-page-linked-confirmation-description": "W każdej chwili {{GENDER:$2|możesz}} zarządzać swoimi wyciszonymi stronami w [$1 preferencjach].", - "notification-dynamic-actions-unwatch": "{{GENDER:$3|Zatrzymaj}} obserwowanie nowej aktywności na \"$1\"", + "notification-dynamic-actions-unwatch": "{{GENDER:$3|Zatrzymaj}} obserwowanie nowej aktywności na „$1”", "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3|Przestałeś|Przestałaś}} obserwować stronę „$1”", "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|Możesz}} wznowić obserwowanie [$2 tej strony] w dowolnym momencie.", - "notification-dynamic-actions-watch": "{{GENDER:$3|Śledź}} nową aktywność na \"$1\"", + "notification-dynamic-actions-watch": "{{GENDER:$3|Śledź}} nową aktywność na „$1”", "notification-dynamic-actions-watch-confirmation": "{{GENDER:$3|Zacząłeś|Zaczęłaś}} obserwować stronę „$1”", "notification-dynamic-actions-watch-confirmation-description": "{{GENDER:$3|Możesz}} przestać obserwować [$2 tę stronę] w dowolnym momencie.", "notification-link-text-expand-all": "Rozwiń", "notification-link-text-expand-alert-count": "Pokaż {{PLURAL:$1|$1 powiadomienie|$1 powiadomienia|$1 powiadomień}}", - "notification-link-text-expand-notice-count": "Zobacz {{PLURAL:$1|$1 powiadomienie|$1 powiadomień}}", + "notification-link-text-expand-notice-count": "Zobacz {{PLURAL:$1|$1 powiadomienie|$1 powiadomienia|$1 powiadomień}}", "notification-link-text-expand-all-count": "Pokaż {{PLURAL:$1|$1 powiadomienie|$1 powiadomienia|$1 powiadomień}}", "notification-link-text-collapse-all": "Zwiń", "notification-link-text-view-message": "Zobacz wiadomość", @@ -141,22 +142,22 @@ "notification-link-text-view-mention-failure": "Zobacz {{PLURAL:$1|wzmiankę|wzmianki}}", "notification-link-text-view-changes": "{{GENDER:$1|Zobacz}} zmiany", "notification-link-text-view-page": "Zobacz stronę", - "notification-header-edit-user-talk": "$1 {{GENDER:$2|zostawił|zostawiła|zostawił(a)}} wiadomość na <strong>{{GENDER:$3|twojej}} stronie dyskusji</strong>.", - "notification-header-edit-user-talk-with-section": "$1 {{GENDER:$2|zostawił|zostawiła|zostawił(a)}} wiadomość na <strong>{{GENDER:$3|twojej}} stronie dyskusji</strong> w „<strong>$4</strong>”.", + "notification-header-edit-user-talk": "$1 {{GENDER:$2|zostawił|zostawiła|zostawił(a)}} wiadomość na <strong>{{GENDER:$3|Twojej}} stronie dyskusji</strong>.", + "notification-header-edit-user-talk-with-section": "$1 {{GENDER:$2|zostawił|zostawiła|zostawił(a)}} wiadomość na <strong>{{GENDER:$3|Twojej}} stronie dyskusji</strong> w wątku „<strong>$4</strong>”.", "notification-compact-header-edit-user-talk": "$1 {{GENDER:$2|pozostawił|pozostawił}} {{GENDER:$3|Ci}} wiadomość.", - "notification-compact-header-edit-user-talk-with-section": "$1 {{GENDER:$2|pozostawił|pozostawiła}} {{GENDER:$3|Ci}} wiadomość w „<strong>$4</strong>”.", + "notification-compact-header-edit-user-talk-with-section": "$1 {{GENDER:$2|pozostawił|pozostawiła}} {{GENDER:$3|Ci}} wiadomość w wątku „<strong>$4</strong>”.", "notification-body-edit-user-talk-with-section": "$1", "notification-header-page-linked": "Utworzono link z <strong>$4</strong> do <strong>$3</strong>.", "notification-compact-header-page-linked": "Linkowana z <strong>$1</strong>.", "notification-bundle-header-page-linked": "Utworzono linki z {{PLURAL:$5||$5 stron|100=99+ stron}} do <strong>$3</strong>.", "notification-link-text-what-links-here": "Wszystkie linki do tej strony", - "notification-header-mention-other": "$1 {{GENDER:$2|wspomniał|wspomniała|wspomniał(a)}} o {{GENDER:$3|tobie}} na stronie <strong>$4</strong> w wątku „<strong>$5</strong>”.", + "notification-header-mention-other": "$1 {{GENDER:$2|wspomniał|wspomniała|wspomniał(a)}} o {{GENDER:$3|Tobie}} na stronie <strong>$4</strong> w wątku „<strong>$5</strong>”.", "notification-header-mention-other-nosection": "$1 {{GENDER:$2|wspomniał|wspomniała|wspomniał(a)}} o {{GENDER:$3|Tobie}} na stronie <strong>$4</strong>.", - "notification-header-mention-user-talkpage-v2": "$1 {{GENDER:$2|wspomniał|wspomniała|wspomniał(a)}} o {{GENDER:$3|tobie}} na <strong>stronie dyskusji {{GENDER:$5|użytkownika|użytkowniczki}} $4</strong> w wątku „<strong>$6</strong>”.", - "notification-header-mention-user-talkpage-nosection": "$1 {{GENDER:$2|wspomniał|wspomniała|wspomniał(a)}} o {{GENDER:$3|tobie}} na <strong>stronie dyskusji {{GENDER:$5|użytkownika|użytkowniczki}} $4</strong>.", - "notification-header-mention-agent-talkpage": "$1 {{GENDER:$2|wspomniał|wspomniała|wspomniał(a)}} o {{GENDER:$3|tobie}} na <strong>{{GENDER:$2|swojej}} stronie dyskusji</strong> w wątku „<strong>$4</strong>”.", - "notification-header-mention-agent-talkpage-nosection": "$1 {{GENDER:$2|wspomniał|wspomniała|wspomniał(a)}} o {{GENDER:$3|tobie}} na <strong>{{GENDER:$2|swojej}} stronie dyskusji</strong>.", - "notification-header-mention-article-talkpage": "$1 {{GENDER:$2|wspomniał|wspomniała|wspomniał(a)}} o {{GENDER:$3|tobie}} na stronie dyskusji strony <strong>$4</strong> w wątku „<strong>$5</strong>”.", + "notification-header-mention-user-talkpage-v2": "$1 {{GENDER:$2|wspomniał|wspomniała|wspomniał(a)}} o {{GENDER:$3|Tobie}} na <strong>stronie dyskusji {{GENDER:$5|użytkownika|użytkowniczki}} $4</strong> w wątku „<strong>$6</strong>”.", + "notification-header-mention-user-talkpage-nosection": "$1 {{GENDER:$2|wspomniał|wspomniała|wspomniał(a)}} o {{GENDER:$3|Tobie}} na <strong>stronie dyskusji {{GENDER:$5|użytkownika|użytkowniczki}} $4</strong>.", + "notification-header-mention-agent-talkpage": "$1 {{GENDER:$2|wspomniał|wspomniała|wspomniał(a)}} o {{GENDER:$3|Tobie}} na <strong>{{GENDER:$2|swojej}} stronie dyskusji</strong> w wątku „<strong>$4</strong>”.", + "notification-header-mention-agent-talkpage-nosection": "$1 {{GENDER:$2|wspomniał|wspomniała|wspomniał(a)}} o {{GENDER:$3|Tobie}} na <strong>{{GENDER:$2|swojej}} stronie dyskusji</strong>.", + "notification-header-mention-article-talkpage": "$1 {{GENDER:$2|wspomniał|wspomniała|wspomniał(a)}} o {{GENDER:$3|Tobie}} na stronie dyskusji strony <strong>$4</strong> w wątku „<strong>$5</strong>”.", "notification-header-mention-article-talkpage-nosection": "$1 {{GENDER:$2|wspomniał|wspomniała|wspomniał(a)}} o {{GENDER:$3|Tobie}} na stronie dyskusji strony <strong>$4</strong>.", "notification-header-mention-failure-user-unknown": "{{GENDER:$2|Twoja}} wzmianka o <strong>$3</strong> nie została wysłana, ponieważ ten użytkownik nie został znaleziony.", "notification-header-mention-failure-user-anonymous": "{{GENDER:$2|Twoja}} wzmianka o <strong>$3</strong> nie została wysłana, ponieważ jest to użytkownik anonimowy.", @@ -183,6 +184,7 @@ "notification-header-watchlist-multiuser-deleted": "Strona <strong>$1</strong> na {{GENDER:$2|twojej}} liście obserwowanych została usunięta $3 {{PLURAL:$3|raz|razy}}", "notification-header-watchlist-multiuser-moved": "Strona <strong>$1</strong> na {{GENDER:$2|twojej}} liście obserwowanych została przeniesiona $3 {{PLURAL:$3|raz|razy}}", "notification-header-watchlist-multiuser-restored": "Strona <strong>$1</strong> na {{GENDER:$2|twojej}} liście obserwowanych została przywrócona $3 {{PLURAL:$3|raz|razy}}", + "notification-body-watchlist-once": "W przypadku dalszej aktywności nie będzie żadnych innych powiadomień e-mail, chyba że {{GENDER:$1| odwiedzasz}} tę stronę będąc zalogowanym.", "notification-welcome-linktext": "Witaj", "notification-header-thank-you-1-edit": "Właśnie {{GENDER:$2|dokonałeś|dokonałaś}} swojej pierwszej edycji; dziękujemy Ci i zapraszamy!", "notification-header-thank-you-10-edit": "Właśnie {{GENDER:$2|dokonałeś|dokonałaś}} swojej dziesiątej edycji; dziękujemy Ci i tak trzymaj!", @@ -195,7 +197,7 @@ "notification-link-thank-you-edit": "{{GENDER:$1|Twoja}} edycja", "notification-link-text-view-edit": "Zobacz edycję", "notification-link-article-reminder": "Zobacz stronę", - "notification-header-reverted": "{{GENDER:$2|Wycofano}} {{PLURAL:$4|twoją edycję|twoje edycje}} na stronie <strong>$3</strong>.", + "notification-header-reverted": "{{GENDER:$2|Wycofano}} {{PLURAL:$4|Twoją edycję|Twoje edycje}} na stronie <strong>$3</strong>.", "notification-header-emailuser": "$1 {{GENDER:$2|wysłał|wysłała|wysłał(a)}} Ci e-mail.", "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$2|napisał|napisała}} do {{GENDER:$3|Ciebie}} w projekcie {{SITENAME}}", "notification-page-linked-email-subject": "Na stronie {{SITENAME}} pojawił się link do utworzonej przez {{GENDER:$3|Ciebie}} strony", @@ -213,7 +215,7 @@ "notification-inbox-filter-read": "Przeczytane", "notification-inbox-filter-unread": "Nieprzeczytane", "notification-inbox-filter-all": "Wszystkie", - "echo-specialmute-label-mute-notifications": "Wycisz powiadomienia od tego użytkownika", + "echo-specialmute-label-mute-notifications": "Wycisz powiadomienia od {{GENDER:$1|tego użytkownika|tej użytkowniczki}}", "echo-email-plain-footer": "Aby kontrolować e-maile, które wysyłamy do {{GENDER:$1|Ciebie}}, sprawdź swoje ustawienia:", "echo-email-html-footer-preference-link-text": "sprawdź {{GENDER:$1|swoje}} preferencje", "echo-email-html-footer-with-link": "Aby kontrolować, jakie e-maile wysyłamy do {{GENDER:$2|Ciebie}}, $1.", @@ -229,7 +231,7 @@ "echo-displaysnippet-title": "Nowe powiadomienie", "echo-date-today": "Dzisiaj", "echo-date-yesterday": "Wczoraj", - "notification-bundle-header-edit-user-talk-v2": "{{PLURAL:$1|Jedna nowa wiadomość|$1 nowe wiadomości|$1 nowych wiadomości|100=99+ nowych wiadomości}} na <strong>{{GENDER:$3|twojej}} stronie dyskusji</strong>.", + "notification-bundle-header-edit-user-talk-v2": "{{PLURAL:$1|Jedna nowa wiadomość|$1 nowe wiadomości|$1 nowych wiadomości|100=99+ nowych wiadomości}} na <strong>{{GENDER:$3|Twojej}} stronie dyskusji</strong>.", "echo-email-batch-subject-daily": "Masz {{PLURAL:$2|nowe powiadomienie|nowe powiadomienia}} w {{grammar:MS.lp|{{SITENAME}}}}", "echo-email-batch-subject-weekly": "Masz {{PLURAL:$2|nowe powiadomienie|nowe powiadomienia}} w {{grammar:MS.lp|{{SITENAME}}}} z tego tygodnia", "echo-email-batch-body-intro-daily": "Cześć, $1!\nW {{grammar:MS.lp|{{SITENAME}}}} czeka na ciebie dzisiejsze podsumowanie powiadomień.", @@ -237,5 +239,10 @@ "echo-email-batch-link-text-view-all-notifications": "Zobacz wszystkie powiadomienia", "notification-header-foreign-alert": "Więcej powiadomień z {{PLURAL:$5|innej wiki|$5 innych wiki}}", "notification-header-foreign-notice": "Więcej powiadomień z {{PLURAL:$5|innej wiki|$5 innych wiki}}", - "notification-header-foreign-all": "Więcej powiadomień z {{PLURAL:$5|innej wiki|$5 innych wiki}}" + "notification-header-foreign-all": "Więcej powiadomień z {{PLURAL:$5|innej wiki|$5 innych wiki}}", + "right-manage-all-push-subscriptions": "Zarządzanie subskrypcjami push", + "action-manage-all-push-subscriptions": "zarządzania subskrypcjami push", + "group-push-subscription-manager": "Menedżerowie subskrypcji push", + "group-push-subscription-manager-member": "{{GENDER:$1|menedżer|menedżerka}} subskrypcji push", + "grouppage-push-subscription-manager": "{{ns:project}}:Menedżerowie subskrypcji push" } diff --git a/Echo/i18n/pnb.json b/Echo/i18n/pnb.json index c697e103..9f4a4fe5 100644 --- a/Echo/i18n/pnb.json +++ b/Echo/i18n/pnb.json @@ -2,11 +2,35 @@ "@metadata": { "authors": [ "Abbas dhothar", + "Bgo eiu", "BukhariSaeed", "Khalid Mahmood", "Saanvel" ] }, - "notifications": "اطلاعات", - "tooltip-pt-notifications-alert": "{{GENDER:|Your}} الرٹس" + "prefs-echo": "اطلاعواں", + "prefs-echosubscriptions": "مینوں اِس ترھاں دے سبباں بارے نوٹیفائی کرو", + "echo-pref-email-format": "ای میل ارمیٹ:", + "echo-pref-web": "ویب", + "echo-pref-email": "ای میل", + "echo-pref-email-format-html": "ایچ ٹی ایم ایل", + "echo-learn-more": "ہور سکھو", + "echo-category-title-article-linked": "صفحہ {{PLURAL:$1|لنک}}", + "echo-category-title-reverted": "سودھ {{PLURAL:$1|رد کیتا|رد کیتے}}", + "echo-category-title-mention": "{{PLURAL:$1|زکر}}", + "echo-category-title-user-rights": "{{PLURAL:$1|اختیارات ورتنوالے دی تبدیلی|اختیارات ورتنوالے دیاں تبدیلیاں}}", + "notifications": "اطلاعواں", + "tooltip-pt-notifications-alert": "{{GENDER:|تواڈیاں}} اطلاعواں", + "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "نویَں ورتنوالے", + "echo-specialpage": "اطلاعواں", + "echo-none": "تہاڈے کئی کوئی سوچنا نہیں ہے۔", + "echo-notification-more-options-tooltip": "ہور اختیار", + "notification-link-text-expand-notice-count": "{{PLURAL:$1|$1 اطلاع|$1 اطلاعواں}} دیکھو", + "notification-link-text-view-changes": "{{GENDER:$1|دیکھو}} تبدیلیاں", + "notification-link-text-view-page": "صفحہ دیکھو", + "notification-welcome-linktext": "جی آیاں نوں", + "notification-link-text-view-edit": "سودھ دیکھو", + "notification-link-article-reminder": "صفحہ دیکھو", + "echo-notification-notice-text-only": "اطلاعواں", + "echo-overlay-link": "ساریاں اطلاعواں" } diff --git a/Echo/i18n/prg.json b/Echo/i18n/prg.json new file mode 100644 index 00000000..bd022c7c --- /dev/null +++ b/Echo/i18n/prg.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Nertiks", + "Tīgelika" + ] + }, + "prefs-echo": "Pawakīsenei", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Redigisnā|Redigīsnas}} na majjan diskusiōnis pāusan" +} diff --git a/Echo/i18n/pt-br.json b/Echo/i18n/pt-br.json index 1259fa0e..7be61060 100644 --- a/Echo/i18n/pt-br.json +++ b/Echo/i18n/pt-br.json @@ -1,6 +1,7 @@ { "@metadata": { "authors": [ + "Albertoleoncio", "Almondega", "Anderson Costa", "Cainamarques", @@ -8,6 +9,7 @@ "Cristofer Alves", "Dianakc", "Eduardo Addad de Oliveira", + "Eduardoaddad", "Felipe L. Ewald", "Hamilton Abreu", "He7d3r", @@ -23,11 +25,14 @@ "Raylton P. Sousa", "Rodrigo codignoli", "TheEduGobi", - "TheGabrielZaum" + "TheGabrielZaum", + "Vonil55", + "YuriNikolai" ] }, "echo-desc": "Sistema para notificar usuários sobre eventos e mensagens", "prefs-echo": "Notificações", + "prefs-description-echo": "Selecione as notificações que recebe e como recebê-las.", "prefs-emailsettings": "Opções de e-mail", "prefs-echosubscriptions": "Notificar-me sobre estes eventos", "prefs-echocrosswiki": "Notificações entre-wikis", @@ -52,11 +57,11 @@ "echo-pref-cross-wiki-notifications": "Mostrar notificações de outras wikis", "echo-pref-notifications-blacklist": "Não apresentar notificações destes usuários. ([[mw:Special:MyLanguage/Help:Notifications#mute|mais informações]])", "echo-pref-notifications-page-linked-title-muted-list": "Não exibir notificações \"Link da página\" para essas páginas. ([[mw:Special:MyLanguage/Help:Notifications#mute|Saber mais]])", - "echo-pref-dont-email-read-notifications": "Não inclua notificações de leitura em emails de resumo", + "echo-pref-dont-email-read-notifications": "Não inclua notificações já lidas em emails de resumo", "echo-learn-more": "Saiba mais", - "echo-log": "Registro Público", + "echo-log": "Registo público", "echo-new-messages": "Você tem novas mensagens", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Mensagem|Mensagens}} na página de discussão", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Edição|Edições}} na minha página de discussão do usuário", "echo-category-title-article-linked": "{{PLURAL:$1|Ligação|Ligações}} para a página", "echo-category-title-reverted": "{{PLURAL:$1|Edição revertida|Edições revertidas}}", "echo-category-title-mention": "{{PLURAL:$1|Menção|Menções}}", @@ -72,7 +77,7 @@ "echo-category-title-thank-you-edit": "{{PLURAL:$1|marco|marcos}} de edição", "echo-category-title-watchlist": "Editar na página vigiadas", "echo-category-title-minor-watchlist": "Edição menores na página vigiadas", - "echo-pref-tooltip-edit-user-talk": "Notifique-me quando alguém publicar uma mensagem ou respostas na minha página de discussão.", + "echo-pref-tooltip-edit-user-talk": "Notifique-me quando alguém editar a minha página de discussão de usuário.", "echo-pref-tooltip-article-linked": "Notifique-me quando alguém criar um link para uma página que criei a partir de uma página de artigo.", "echo-pref-tooltip-reverted": "Notifique-me quando alguém reverter uma edição que fiz usando desfazer ou a ferramenta de reversão.", "echo-pref-tooltip-mention": "Notificar-me quando alguém criar links para a minha página de usuário.", @@ -188,19 +193,18 @@ "notification-header-watchlist-multiuser-moved": "<strong>$1</strong>, uma página na {{GENDER:$2|sua}} lista de páginas vigiadas, foi movida em $3 {{PLURAL:$3|veze|vezes}}.", "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>, uma página na {{GENDER:$2|sua}} lista de páginas vigiadas, foi restaurada em $3 {{PLURAL:$3|veze|vezes}}.", "notification-welcome-linktext": "Bem-vindo(a)", - "notification-header-thank-you-1-edit": "{{GENDER:$2|Você}} acaba de fez {{GENDER:$2|sua}} primeira edição; {{GENDER:$2|Obrigado e seja bem-vindo!|Obrigada e seja bem-vinda!}}", - "notification-header-thank-you-10-edit": "{{GENDER:$2|Você}} acaba de fez {{GENDER:$2|sua}} décima edição; {{GENDER:$2|Obrigado|Obrigada}} e continue por aí!", + "notification-header-thank-you-1-edit": "Você acaba de fazer sua primeira edição. Muito obrigado, e seja {{GENDER:$2|bem-vindo|bem-vinda}}!", + "notification-header-thank-you-10-edit": "{{GENDER:$2|Você}} acaba de fazer sua décima edição; obrigado e continue por aí!", "notification-header-thank-you-100-edit": "{{GENDER:$2|Você}} acabou de fazer {{GENDER:$2|sua}} centésima edição. {{GENDER:$2|Muito obrigado!}}", - "notification-header-thank-you-1000-edit": "{{GENDER:$2|Você}} acaba de fez {{GENDER:$2|sua}} milésima edição; {{GENDER:$2|Muito obrigado por ser um grande contribuidor!|Muito obrigada por ser uma grande contribuidora!}}", - "notification-header-thank-you-10000-edit": "{{GENDER:$2|Você}} acaba de fez {{GENDER:$2|sua}} décima milésima edição; {{GENDER:$2|Muito obrigado!|Muito obrigada!}}", - "notification-header-thank-you-100000-edit": "{{GENDER:$2|Você}} acaba de fez {{GENDER:$2|sua}} centésima milésima edição; {{GENDER:$2|Muito obrigado|Muito obrigada}} por uma incrível contribuição!", - "notification-header-thank-you-1000000-edit": "{{GENDER:$2|Você}} acaba de fez {{GENDER:$2|sua}} milionésima edição; {{GENDER:$2|Muito obrigado|Muito obrigada}} por uma contribuição surpreendente!", + "notification-header-thank-you-1000-edit": "Você acaba de fazer sua milésima edição. Muito obrigado por ser {{GENDER:$2|um colaborador|uma colaboradora}} tão especial!", + "notification-header-thank-you-10000-edit": "{{GENDER:$2|Você}} acaba de fazer sua décima milésima edição; Muito obrigado!", + "notification-header-thank-you-100000-edit": "{{GENDER:$2|Você}} acaba de fazer sua centésima milésima edição; muito obrigado por suas incríveis contribuições!", + "notification-header-thank-you-1000000-edit": "Você acaba de fazer sua milionésima edição. Muito obrigado por continuar a ser {{GENDER:$2|um|uma}} excelente {{GENDER:$2|colaborador|colaboradora}}!", "notification-header-thank-you-10000000-edit": "{{GENDER:$2|Você}} acabou de fazer {{GENDER:$2|sua}} décima milionésima edição; {{GENDER:$2|Muito obrigado|Muito}} por sua dedicação brilhante!", "notification-link-thank-you-edit": "{{GENDER:$1|Sua}} edição", "notification-link-text-view-edit": "Ver edição", "notification-link-article-reminder": "Ver página", "notification-header-reverted": "{{PLURAL:$4|Sua edição em <strong>$3</strong> foi {{GENDER:$2|revertida}}|Suas edições em <strong>$3</strong> foram {{GENDER:$2|revertidas}}}}.", - "notification-body-reverted": "$1", "notification-header-emailuser": "$1 {{GENDER:$2|enviou}} um e-mail para você.", "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$2|deixou}} uma mensagem para você em {{SITENAME}}", "notification-page-linked-email-subject": "A pagina que {{GENDER:$3|você}} criou foi lincada em {{SITENAME}}", @@ -245,5 +249,10 @@ "notification-header-foreign-notice": "Mais notificações de {{PLURAL:$5|outra wiki|$5 outras wikis}}", "notification-header-foreign-all": "Mais notificações de {{PLURAL:$5|outra wiki|$5 outras wikis}}", "echo-foreign-wiki-lang": "$1 - $2", - "echo-badge-count": "{{PLURAL:$1|$1|100={{formatnum:99}}+}}" + "echo-badge-count": "{{PLURAL:$1|$1|100={{formatnum:99}}+}}", + "right-manage-all-push-subscriptions": "Gerenciar todas as inscrições push", + "action-manage-all-push-subscriptions": "gerenciar todas as inscrições push", + "group-push-subscription-manager": "Gerenciar inscrições push", + "group-push-subscription-manager-member": "{{GENDER:$1|gerente de inscrições push}}", + "grouppage-push-subscription-manager": "{{ns:project}}:Gerenciar inscrições push" } diff --git a/Echo/i18n/pt.json b/Echo/i18n/pt.json index 2365c3e2..1f5690e8 100644 --- a/Echo/i18n/pt.json +++ b/Echo/i18n/pt.json @@ -27,10 +27,12 @@ }, "echo-desc": "Sistema de notificações a utilizadores sobre eventos e mensagens", "prefs-echo": "Notificações", + "prefs-description-echo": "Selecione as notificações que recebe e como recebê-las.", "prefs-emailsettings": "Opções de correio eletrónico", "prefs-echosubscriptions": "Notificar-me sobre estes eventos", "prefs-echocrosswiki": "Notificações interwikis", "prefs-blocknotificationslist": "Utilizadores silenciados", + "prefs-mutedpageslist": "Páginas silenciadas para notificações de hiperligações para a página", "prefs-echopollupdates": "Notificações ao vivo", "echo-mobile-notifications-filter-title": "Filtrar notificações", "echo-pref-show-poll-updates": "Apresentar notificações novas à medida que chegam", @@ -40,6 +42,7 @@ "echo-pref-email-format": "Formato de correio:", "echo-pref-web": "Internet", "echo-pref-email": "Correio eletrónico", + "echo-pref-push": "Aplicações", "echo-pref-email-frequency-never": "Não me enviar notificações por correio", "echo-pref-email-frequency-immediately": "Notificações individuais conforme cheguem", "echo-pref-email-frequency-daily": "Um resumo diário de notificações", @@ -48,11 +51,12 @@ "echo-pref-email-format-plain-text": "Texto simples", "echo-pref-cross-wiki-notifications": "Mostrar notificações de outras wikis", "echo-pref-notifications-blacklist": "Não apresentar notificações destes utilizadores. ([[mw:Special:MyLanguage/Help:Notifications#mute|mais informações]])", + "echo-pref-notifications-page-linked-title-muted-list": "Não apresentar notificações \"Hiperligação para a página\" para estas páginas. ([[mw:Special:MyLanguage/Help:Notifications#mute|saber mais]])", "echo-pref-dont-email-read-notifications": "Não incluir as notificações já lidas nas mensagens de resumo", - "echo-learn-more": "Saiba mais", + "echo-learn-more": "Saber mais", "echo-log": "Registo público", "echo-new-messages": "Tem novas mensagens", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Mensagem|Mensagens}} na página de discussão", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Edição|Edições}} da minha página de discussão", "echo-category-title-article-linked": "{{PLURAL:$1|Hiperligação|Hiperligações}} para uma página", "echo-category-title-reverted": "Reversão de {{PLURAL:$1|edição|edições}}", "echo-category-title-mention": "{{PLURAL:$1|Menção|Menções}}", @@ -68,7 +72,7 @@ "echo-category-title-thank-you-edit": "{{PLURAL:$1|Marco|Marcos}} de edição", "echo-category-title-watchlist": "Edição de página vigiada", "echo-category-title-minor-watchlist": "Edição menor de uma página vigiada", - "echo-pref-tooltip-edit-user-talk": "Notificar-me quando alguém publicar na minha página de discussão.", + "echo-pref-tooltip-edit-user-talk": "Notificar-me quando alguém editar a minha página de discussão do utilizador.", "echo-pref-tooltip-article-linked": "Notificar-me quando alguém criar uma hiperligação para uma página criada por mim, a partir de outra página.", "echo-pref-tooltip-reverted": "Notificar-me quando alguém reverter uma edição minha, ao utilizar a função desfazer ou a ferramenta de reversão.", "echo-pref-tooltip-mention": "Notificar-me quando alguém criar uma hiperligação para a minha página de utilizador.", @@ -78,6 +82,8 @@ "echo-pref-tooltip-emailuser": "Notificar-me quando alguém me enviar um correio.", "echo-pref-tooltip-article-reminder": "Notificar-me acerca desta página a meu pedido.", "echo-pref-tooltip-thank-you-edit": "Notificar-me quando eu atingir a primeira, décima, centésima... edição.", + "echo-pref-tooltip-watchlist": "Notificar-me quando alguém fizer uma edição (não menor) a uma das minhas páginas vigiadas.", + "echo-pref-tooltip-minor-watchlist": "Notificar-me quando alguém fizer uma edição menor a uma das minhas páginas vigiadas.", "notifications": "Notificações", "tooltip-pt-notifications-alert": "Os {{GENDER:|seus}} alertas", "tooltip-pt-notifications-notice": "As {{GENDER:|suas}} notificações", @@ -97,6 +103,8 @@ "echo-specialpage-section-markread": "Marcar grupo como lido", "echo-specialpage-markasread": "Notificação: Marcar como lida", "echo-specialpage-markasread-invalid-id": "ID de evento inválido", + "echo-specialpage-pagefilterwidget-aria-label": "Filtrar por wiki e título de página", + "echo-specialpage-special-help-menu-widget-aria-label": "Opções adicionais e preferências de notificações.", "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|notificação|notificações}}", "echo-specialpage-pagination-range": "$1 - $2", "echo-specialpage-pagefilters-title": "Atividade recente", @@ -113,6 +121,12 @@ "echo-notification-markasunread": "Marcar como não lida", "echo-notification-markasread-tooltip": "Marcar como lida", "echo-notification-more-options-tooltip": "Mais opções", + "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|Silenciar}} notificações de hiperligações para \"$1\"", + "notification-dynamic-actions-mute-page-linked-confirmation": "As notificações \"hiperligação para a página\" estão agora desativadas para a página \"$1\"", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|Pode}} gerir as páginas silenciadas nas [$1 suas preferências] a qualquer altura.", + "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2|Remover o silenciamento}} das notificações de hiperligações para \"$1\"", + "notification-dynamic-actions-unmute-page-linked-confirmation": "As notificações \"hiperligação para a página\" estão agora ativadas para a página \"$1\"", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|Pode}} gerir as páginas silenciadas nas [$1 suas preferências] a qualquer altura.", "notification-dynamic-actions-unwatch": "{{GENDER:$3|Parar}} de vigiar a nova atividade em \"$1\"", "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3|Parou}} de vigiar a página \"$1\"", "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|Pode}} vigiar [$2 esta página] a qualquer momento.", @@ -162,6 +176,17 @@ "notification-header-user-rights-expiry-change": "A expiração da {{GENDER:$4|sua}} associação {{PLURAL:$3|ao seguinte grupo|aos seguintes grupos}} foi {{GENDER:$1|alterada}}: $2", "notification-header-welcome": "{{GENDER:$2|Bem-vindo|Bem-vinda|Bem-vindo(a)}} à wiki {{SITENAME}}, $1! Ficamos satisfeitos por {{GENDER:$2|tê-lo|tê-la|tê-lo(a)}} aqui.", "notification-header-mention-summary": "$1 {{GENDER:$2|mencionou-}}{{GENDER:$3|o|a}} num resumo de edição em <strong>$4</strong>.", + "notification-header-watchlist-changed": "$1 {{GENDER:$2|mudou}} <strong>$3</strong>, umas das {{GENDER:$4|suas}} páginas vigiadas{{PLURAL:$5||, $5 vezes}}.", + "notification-header-watchlist-created": "$1 {{GENDER:$2|criou}} <strong>$3</strong>, uma das {{GENDER:$4|suas}} páginas vigiadas{{PLURAL:$5||, $5 vezes}}.", + "notification-header-watchlist-deleted": "$1 {{GENDER:$2|eliminou}} <strong>$3</strong>, umas das {{GENDER:$4|suas}} páginas vigiadas{{PLURAL:$5||, $5 vezes}}.", + "notification-header-watchlist-moved": "$1 {{GENDER:$2|moveu}} <strong>$3</strong>, uma das {{GENDER:$4|suas}} páginas vigiadas{{PLURAL:$5||, $5 vezes}}.", + "notification-header-watchlist-restored": "$1 {{GENDER:$2|restaurou}} <strong>$3</strong>, uma das {{GENDER:$4|suas}} páginas vigiadas{{PLURAL:$5||, $5 vezes}}.", + "notification-header-watchlist-multiuser-changed": "<strong>$1</strong>, uma das {{GENDER:$2|suas}} páginas vigiadas, foi mudada $3 {{PLURAL:$3|vez|vezes}}.", + "notification-header-watchlist-multiuser-created": "<strong>$1</strong>, uma das {{GENDER:$2|suas}} páginas vigiadas, foi criada $3 {{PLURAL:$3|vez|vezes}}.", + "notification-header-watchlist-multiuser-deleted": "<strong>$1</strong>, uma das {{GENDER:$2|suas}} páginas vigiadas, foi eliminada $3 {{PLURAL:$3|vez|vezes}}.", + "notification-header-watchlist-multiuser-moved": "<strong>$1</strong>, uma das {{GENDER:$2|suas}} páginas vigiadas, foi movida $3 {{PLURAL:$3|vez|vezes}}.", + "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>, uma das {{GENDER:$2|suas}} páginas vigiadas, foi restaurada $3 {{PLURAL:$3|vez|vezes}}.", + "notification-body-watchlist-once": "Não será feita mais nenhuma notificação por correio eletrónico no caso de atividade futura, a menos que visite esta página com uma sessão iniciada.{{GENDER:$1|}}", "notification-welcome-linktext": "Bem-vindo(a)!", "notification-header-thank-you-1-edit": "{{GENDER:$2|Acabou}} de fazer a {{GENDER:$2|sua}} primeira edição; obrigado, e seja {{GENDER:$2|bem-vindo|bem-vinda|bem-vindo(a)}}!", "notification-header-thank-you-10-edit": "{{GENDER:$2|Acabou}} de fazer a {{GENDER:$2|sua}} décima edição; obrigado e, por favor, continue!", @@ -170,6 +195,7 @@ "notification-header-thank-you-10000-edit": "{{GENDER:$2|Acabou}} de fazer a {{GENDER:$2|sua}} décima milésima edição; muito obrigado!", "notification-header-thank-you-100000-edit": "{{GENDER:$2|Acabou}} de fazer a {{GENDER:$2|sua}} edição número cem mil; obrigado por colaborar tão arduamente!", "notification-header-thank-you-1000000-edit": "{{GENDER:$2|Acabou}} de fazer a {{GENDER:$2|sua}} milionésima edição; obrigado pela sua surpreendente contribuição!", + "notification-header-thank-you-10000000-edit": "{{GENDER:$2|Acabou}} de realizar {{GENDER:$2|a sua}} décima milionésima edição; {{GENDER:$2|agradecemos}} a sua dedicação impressionante!", "notification-link-thank-you-edit": "{{GENDER:$1|A sua}} edição", "notification-link-text-view-edit": "Ver edição", "notification-link-article-reminder": "Ver página", @@ -191,7 +217,7 @@ "notification-inbox-filter-read": "Lidas", "notification-inbox-filter-unread": "Não lidas", "notification-inbox-filter-all": "Todas", - "echo-specialmute-label-mute-notifications": "Silenciar notificações deste utilizador", + "echo-specialmute-label-mute-notifications": "Silenciar notificações {{GENDER:$1|deste utilizador|desta utilizadora}}", "echo-email-plain-footer": "Para controlar as mensagens eletrónicas que {{GENDER:$1|lhe}} são enviadas, verifique as {{GENDER:$1|suas}} preferências:", "echo-email-html-footer-preference-link-text": "verifique as {{GENDER:$1|suas}} preferências", "echo-email-html-footer-with-link": "Para controlar as mensagens eletrónicas que {{GENDER:$2|lhe}} são enviadas, $1.", @@ -215,5 +241,10 @@ "echo-email-batch-link-text-view-all-notifications": "Ver todas as notificações", "notification-header-foreign-alert": "Mais alertas de {{PLURAL:$5|uma outra wiki|$5 outras wikis}}", "notification-header-foreign-notice": "Mais notificações de {{PLURAL:$5|outra wiki|$5 outras wikis}}", - "notification-header-foreign-all": "Mais notificações de {{PLURAL:$5|uma outra wiki|$5 outras wikis}}" + "notification-header-foreign-all": "Mais notificações de {{PLURAL:$5|uma outra wiki|$5 outras wikis}}", + "right-manage-all-push-subscriptions": "Gerir todas as subscrições de notificações imediatas", + "action-manage-all-push-subscriptions": "gerir todas as subscrições de notificações imediatas", + "group-push-subscription-manager": "Gestores de subscrições de notificações imediatas", + "group-push-subscription-manager-member": "{{GENDER:$1|gestor|gestora}} de subscrições de notificações imediatas", + "grouppage-push-subscription-manager": "{{ns:project}}:Gestores de subscrições de notificações imediatas" } diff --git a/Echo/i18n/pwn.json b/Echo/i18n/pwn.json new file mode 100644 index 00000000..e9e36aa7 --- /dev/null +++ b/Echo/i18n/pwn.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Akamycoco" + ] + }, + "notification-inbox-filter-read": "semupu", + "notification-inbox-filter-all": "pipenuljatan" +} diff --git a/Echo/i18n/qqq.json b/Echo/i18n/qqq.json index 7a9e0edf..7756b334 100644 --- a/Echo/i18n/qqq.json +++ b/Echo/i18n/qqq.json @@ -1,6 +1,7 @@ { "@metadata": { "authors": [ + "Ajeje Brazorf", "Amire80", "Ans", "Beta16", @@ -25,6 +26,7 @@ "Purodha", "Pxos", "Raymond", + "Rodney Araujo", "Shirayuki", "Siebrand", "Tacsipacsi", @@ -37,8 +39,9 @@ "రహ్మానుద్దీన్" ] }, - "echo-desc": "{{desc|name=Echo|url=https://www.mediawiki.org/wiki/Extension:Echo}} The [https://www.mediawiki.org/wiki/Help:Notifications Mediawiki help] page gives notes on the terminology in this extension.", + "echo-desc": "{{desc|name=Echo|url=https://www.mediawiki.org/wiki/Extension:Echo}} The [https://www.mediawiki.org/wiki/Help:Notifications MediaWiki help] page gives notes on the terminology in this extension.", "prefs-echo": "Name of preferences section for Echo notifications.\n{{Identical|Notification}}", + "prefs-description-echo": "Used in [[Special:Preferences]] for mobile to describe the Notifications section.", "prefs-emailsettings": "Header for the section of preferences that deals with how often notification emails are sent out and what address they are sent to.\n{{Identical|E-mail option}}", "prefs-echosubscriptions": "Header for the section of preferences that deals with which notifications the user receives", "prefs-echocrosswiki": "Header for the section of preferences that deals with notifications from other wikis", @@ -51,7 +54,7 @@ "echo-pref-send-me": "Label for the following email delivery options:\n* {{msg-mw|Echo-pref-email-frequency-never}}\n* {{msg-mw|Echo-pref-email-frequency-immediately}} (default)\n* {{msg-mw|Echo-pref-email-frequency-daily}}\n* {{msg-mw|Echo-pref-email-frequency-weekly}}", "echo-pref-send-to": "Label for the address to send email notifications to.", "echo-pref-email-format": "Label for individual email notification format, the label will be updated once HTML email is ready for email digest.\n\nUsed as label for the select box which has the following options:\n* {{msg-mw|Echo-pref-email-format-html}}\n* {{msg-mw|Echo-pref-email-format-plain-text}}", - "echo-pref-web": "Label for list of notifications which are delivered on the web. In other words, on the wiki itself rather by email or another method. This should be kept very short.", + "echo-pref-web": "Label for list of notifications which are delivered on the web. In other words, on the wiki itself rather by email or another method. This should be kept very short.\n\n{{Identical|Web}}", "echo-pref-email": "Label for list of notifications which are delivered via email. This should be kept very short.\n{{Identical|E-mail}}", "echo-pref-push": "Label for the notification preferences column controlling which notifications should be delivered by push notification to Wikipedia mobile app installations for which the user has registered a push notification subscription.", "echo-pref-email-frequency-never": "Option for users who don't want to receive any email notifications\n\nSee also:\n* {{msg-mw|Echo-pref-email-frequency-immediately}}\n* {{msg-mw|Echo-pref-email-frequency-daily}}\n* {{msg-mw|Echo-pref-email-frequency-weekly}}", @@ -67,7 +70,7 @@ "echo-learn-more": "Text for link to more information about a topic.\n{{Identical|Learn more}}", "echo-log": "Text for link to go to Special:Log", "echo-new-messages": "Message to let the user know that they have new talk page messages, displayed in the personal menu (top-right corner on Vector and Monobook).\n\nKeep this message short. It '''should not''' end in a full stop.", - "echo-category-title-edit-user-talk": "{{doc-echo-category-title|tooltip=Echo-pref-tooltip-edit-user-talk}}", + "echo-category-title-edit-user-talk": "'''When translating, please emphasize the distinction between “my user talk page” and “other talk pages”, to avoid confusion with {{msg-mw|echo-category-title-dt-subscription}}.'''\n\n{{doc-echo-category-title|tooltip=Echo-pref-tooltip-edit-user-talk}}", "echo-category-title-article-linked": "{{doc-echo-category-title|tooltip=Echo-pref-tooltip-article-linked}}", "echo-category-title-reverted": "{{doc-echo-category-title|tooltip=Echo-pref-tooltip-reverted}}", "echo-category-title-mention": "{{doc-echo-category-title|tooltip=Echo-pref-tooltip-mention}}\n{{Identical|Mention}}", @@ -117,7 +120,7 @@ "echo-specialpage-pagefilterwidget-aria-label": "Screen readers use this name to identify the recent activities (pages with unread notifications) wiki and pages grouped lists.", "echo-specialpage-special-help-menu-widget-aria-label": "Screen readers use this label to identify the special help menu widget including the Notifications preferences.", "echo-specialpage-pagination-numnotifications": "Label noting the number of notifications displayed in the page. This only appears if there is a single page of results.\n\nParameters:\n* $1 - Number of notifications in the page.\n{{Identical|Notification}}", - "echo-specialpage-pagination-range": "Label noting the range of the notifications displayed in the page. This only appears if there are multiple pages of results available.\n\nParameters:\n* $1 - Number of the first item.\n* $2 - Number of the last item.", + "echo-specialpage-pagination-range": "{{optional}}\nLabel noting the range of the notifications displayed in the page. This only appears if there are multiple pages of results available.\n\nParameters:\n* $1 - Number of the first item.\n* $2 - Number of the last item.", "echo-specialpage-pagefilters-title": "Title of the page filter box in Special:Notifications page.", "echo-specialpage-pagefilters-subtitle": "Subtitle of the page filter box in Special:Notifications page.", "notificationsmarkread-legend": "Title for the form that marks a notification as read in [[Special:NotificationsMarkRead]]", @@ -132,18 +135,18 @@ "echo-notification-markasunread": "Label for the button to mark the notification as unread.", "echo-notification-markasread-tooltip": "Tooltip for the button to mark the notification as read.", "echo-notification-more-options-tooltip": "Tooltip for the button to show the hidden secondary actions.", - "notification-dynamic-actions-mute-page-linked": "Text for the action offering the user to mute link notifications for a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Current user name for gender purposes\n\n{{related|Notification-dynamic}}", - "notification-dynamic-actions-mute-page-linked-confirmation": "Title for the confirmation text for muting link notifications for a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Current user name for gender purposes\n\n{{related|Notification-dynamic}}", - "notification-dynamic-actions-mute-page-linked-confirmation-description": "Description for the confirmation text for muting link notifications for a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Current user name for gender purposes\n\n{{related|Notification-dynamic}}", - "notification-dynamic-actions-unmute-page-linked": "Text for the action offering the user to unmute link notifications for a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Current user name for gender purposes\n\n{{related|Notification-dynamic}}", - "notification-dynamic-actions-unmute-page-linked-confirmation": "Title for the confirmation text for unmuting link notifications for a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Current user name for gender purposes\n\n{{related|Notification-dynamic}}", - "notification-dynamic-actions-unmute-page-linked-confirmation-description": "Description for the confirmation text for unmuting link notifications for a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Current user name for gender purposes\n\n{{related|Notification-dynamic}}", - "notification-dynamic-actions-unwatch": "Text for the action offering the user to unwatch a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Page URL\n* $3 - Current user name for gender purposes\n\n{{related|Notification-dynamic}}", - "notification-dynamic-actions-unwatch-confirmation": "Title for the confirmation text for unwatching a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Page URL\n* $3 - Current user name for gender purposes\n\n{{related|Notification-dynamic}}", - "notification-dynamic-actions-unwatch-confirmation-description": "Description for the confirmation text for unwatching a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Page URL\n* $3 - Current user name for gender purposes\n\n{{related|Notification-dynamic}}", - "notification-dynamic-actions-watch": "Text for the action offering the user to watch a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Page URL\n* $3 - Current user name for gender purposes\n\n{{related|Notification-dynamic}}", - "notification-dynamic-actions-watch-confirmation": "Title for the confirmation text for watching a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Page URL\n* $3 - Current user name for gender purposes\n\n{{related|Notification-dynamic}}", - "notification-dynamic-actions-watch-confirmation-description": "Description for the confirmation text for watching a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Page URL\n* $3 - Current user name for gender purposes\n\n{{related|Notification-dynamic}}", + "notification-dynamic-actions-mute-page-linked": "Text for the action that offers the user to mute link notifications for a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Current username for gender purposes\n\n{{related|Notification-dynamic}}", + "notification-dynamic-actions-mute-page-linked-confirmation": "Title for the confirmation text for muting link notifications for a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Current username for gender purposes\n\n{{related|Notification-dynamic}}", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "Description for the confirmation text for muting link notifications for a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Current username for gender purposes\n\n{{related|Notification-dynamic}}", + "notification-dynamic-actions-unmute-page-linked": "Text for the action offering the user to unmute link notifications for a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Current username for gender purposes\n\n{{related|Notification-dynamic}}", + "notification-dynamic-actions-unmute-page-linked-confirmation": "Title for the confirmation text for unmuting link notifications for a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Current username for gender purposes\n\n{{related|Notification-dynamic}}", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "Description for the confirmation text for unmuting link notifications for a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Current username for gender purposes\n\n{{related|Notification-dynamic}}", + "notification-dynamic-actions-unwatch": "Text for the action that offers the user to unwatch a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Page URL\n* $3 - Current username for gender purposes\n\n{{related|Notification-dynamic}}", + "notification-dynamic-actions-unwatch-confirmation": "Title for the confirmation text for unwatching a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Page URL\n* $3 - Current username for gender purposes\n\n{{related|Notification-dynamic}}", + "notification-dynamic-actions-unwatch-confirmation-description": "Description for the confirmation text for unwatching a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Page URL\n* $3 - Current username for gender purposes\n\n{{related|Notification-dynamic}}", + "notification-dynamic-actions-watch": "Text for the action that offers the user to watch a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Page URL\n* $3 - Current username for gender purposes\n\n{{related|Notification-dynamic}}", + "notification-dynamic-actions-watch-confirmation": "Title for the confirmation text for watching a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Page URL\n* $3 - Current username for gender purposes\n\n{{related|Notification-dynamic}}", + "notification-dynamic-actions-watch-confirmation-description": "Description for the confirmation text for watching a page from within a notification.\n\nParameters:\n* $1 - Page name\n* $2 - Page URL\n* $3 - Current username for gender purposes\n\n{{related|Notification-dynamic}}", "notification-link-text-expand-all": "Label for the button that expands a bundled notification.\n{{Identical|Expand}}", "notification-link-text-expand-alert-count": "Label for the button that expands a bundled alert notification.\n\nParameters:\n* $1 - The count of messages that the bundle holds.\n{{Identical|View alert}}", "notification-link-text-expand-notice-count": "Label for the button that expands a bundled notice notification.\n\nParameters:\n* $1 - The count of messages that the bundle holds.", @@ -199,6 +202,7 @@ "notification-header-watchlist-multiuser-deleted": "Text of a notification when multiple different users delete pages on your watchlist.\n* $1 - name of the page that was deleted (with namespace) \n* $2 - name of the user viewing the notification, can be used for GENDER \n* $3 - Number of times the page has been deleted. (Always greater than one)", "notification-header-watchlist-multiuser-moved": "Text of a notification when multiple different users move pages on your watchlist.\n* $1 - name of the page that was moved (with namespace) \n* $2 - name of the user viewing the notification, can be used for GENDER \n* $3 - Number of times the page has been moved. (Always greater than one)", "notification-header-watchlist-multiuser-restored": "Text of a notification when multiple different users restore pages on your watchlist.\n* $1 - name of the page that was restored (with namespace) \n* $2 - name of the user viewing the notification, can be used for GENDER \n* $3 - Number of times the page has been restored. (Always greater than one)", + "notification-body-watchlist-once": "Text added to email notifications of watchlist changes to specify that no further emails will be sent for that page until it is visited. \n* $1 - user's name for use in GENDER", "notification-welcome-link": "{{notranslate}}", "notification-welcome-linktext": "Link text for link to the wiki's welcome or introduction page.\n{{Identical|Welcome}}", "notification-header-thank-you-1-edit": "Text of the editor welcome notification for their first edit.\nParameters:\n* $1 - the formatted username of the new user\n* $2 - the username for gender purposes", @@ -212,12 +216,12 @@ "notification-link-thank-you-edit": "Label for the link to the user's edit which triggered a threshold congratulations message.\nParameters:\n* $1 - the username for gender purposes", "notification-link-text-view-edit": "Label for button that links to a \"diff\" view showing an edit made to a page. This is an alternative to the wording in {{msg-mw|notification-link-text-view-changes}}, which serves essentially the same function.", "notification-link-article-reminder": "Label for the link to the article the user requested to be reminded about", - "notification-header-reverted": "Notification header of a user's edit being reverted.\n\nParameters:\n* $1 - the formatted username of the person who reverted the edit (not suitable for GENDER).\n* $2 - the username for GENDER\n* $3 - the page that was reverted, formatted\n* $4 - the number of edits that were reverted\n{{Related|Notification-reverted}}", + "notification-header-reverted": "Notification header of a user's edit has being reverted by other user.\nParameters:\n* $1 - the formatted username of the person who reverted the edit, using the undo or rollback features (not suitable for GENDER).\n* $2 - the username for GENDER\n* $3 - the page that was reverted, formatted\n* $4 - the number of edits that were reverted\n\nWhen the notified user clicks on the notification message, this appoint to a diff page.\n{{Related|Notification-reverted}}", "notification-body-reverted": "{{notranslate}}", "notification-header-emailuser": "Flyout-specific format for displaying notifications of user has sent an email to another user.\n\nParameters:\n* $1 - the formatted username of the person who sent the email.\n* $2 - the username for GENDER.", "notification-body-emailuser": "{{notranslate}}", "notification-edit-talk-page-email-subject2": "Email subject. Parameters:\n* $1 - the formatted username of the person who edited (not suitable for GENDER).\n* $2 - the username for GENDER.\n* $3 - username of the current user, can be used for GENDER.", - "notification-page-linked-email-subject": "E-mail subject Parameters:\n * $1 - the formatted username of the person who edited (not suitable for GENDER).\n* $2 - the username for GENDER.\n* $3 - username of the current user, can be used for GENDER.", + "notification-page-linked-email-subject": "E-mail subject Parameters:\n* $1 - the formatted username of the person who edited (not suitable for GENDER).\n* $2 - the username for GENDER.\n* $3 - username of the current user, can be used for GENDER.", "notification-reverted-email-subject2": "Email subject. Parameters:\n* $1 - the formatted username of the person who reverted the edit (not suitable for GENDER).\n* $2 - the username for GENDER.\n* $3 - username of the current user, can be used for GENDER.\n* $4 - the number of reverts\n{{Related|Notification-reverted}}", "notification-mention-email-subject": "Email subject. Parameters:\n* $1 - the formatted username of the person who edited (not suitable for GENDER).\n* $2 - the username for GENDER.\n* $3 - username of the current user, can be used for GENDER.", "notification-user-rights-email-subject": "E-mail subject for user rights notification. Parameters:\n* $1 - the formatted username of the person who made the user rights change (not suitable for GENDER).\n* $2 - the username for GENDER.\n* $3 - username of the current user, can be used for GENDER.", @@ -259,7 +263,12 @@ "notification-header-foreign-notice": "Flyout-specific format for displaying notification header of having notice notifications on foreign wikis.\n\nParameters:\n* $1 - the formatted username of the current user.\n* $2 - the username for GENDER\n* $3 (deprecated) - 1 of the foreign wikis you have notifications on\n* $4 (deprecated) - the number of remaining other wikis you have notifications on\n*$5 - the number of other wikis you have notifications on", "notification-header-foreign-all": "Flyout-specific format for displaying notification header of having notifications (combined alerts and messages) on foreign wikis.\n\nParameters:\n* $1 - the formatted username of the current user.\n* $2 - the username for GENDER\n* $3 (deprecated) - 1 of the foreign wikis you have notifications on\n* $4 (deprecated) - the number of remaining other wikis you have notifications on\n*$5 - the number of other wikis you have notifications on", "notification-body-foreign": "{{notranslate}}", - "echo-foreign-wiki-lang": "Title of the wiki for which you're seeing foreign notifications:\n\nParameters:\n* $1 - the name of the site (e.g. 'Wikipedia', 'Wikiversity', ...)\n* $2 - the language of the website (e.g. 'English', 'Deutsch', ...)", - "echo-badge-count": "Used only for the two Echo badges shown on the personal toolbar.\nParameters:\n* $1 - Formatted notification count. However, for 100 or greater, 100 will be passed.", - "echo-blacklist": "{{ignored}} Site-wide list of accounts that cannot trigger notifications. Can be overridden by users at [[Special:MyPage/Echo-whitelist]]." + "echo-foreign-wiki-lang": "{{optional}}\nTitle of the wiki for which you're seeing foreign notifications:\n\nParameters:\n* $1 - the name of the site (e.g. 'Wikipedia', 'Wikiversity', ...)\n* $2 - the language of the website (e.g. 'English', 'Deutsch', ...)", + "echo-badge-count": "{{optional}}\nUsed only for the two Echo badges shown on the personal toolbar.\nParameters:\n* $1 - Formatted notification count. However, for 100 or greater, 100 will be passed.", + "echo-blacklist": "{{ignored}} Site-wide list of accounts that cannot trigger notifications. Can be overridden by users at [[Special:MyPage/Echo-whitelist]].", + "right-manage-all-push-subscriptions": "{{doc-right|manage-all-push-subscriptions}}", + "action-manage-all-push-subscriptions": "{{doc-action|manage-all-push-subscriptions}}", + "group-push-subscription-manager": "{{doc-group|push-subscription-manager}}", + "group-push-subscription-manager-member": "{{doc-group|push-subscription-manager|member}}", + "grouppage-push-subscription-manager": "{{doc-group|push-subscription-manager|page}}" } diff --git a/Echo/i18n/rki.json b/Echo/i18n/rki.json new file mode 100644 index 00000000..b8a05e44 --- /dev/null +++ b/Echo/i18n/rki.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "ReyLon Mrat" + ] + }, + "prefs-description-echo": "ဇာသတိပီးချက်ကိုရွီး {{GENDER:|you}}ယင်းချင့်တိကိုဇာပိုင်လက်ခံဖို့လဲ။" +} diff --git a/Echo/i18n/rmc.json b/Echo/i18n/rmc.json new file mode 100644 index 00000000..e53e567e --- /dev/null +++ b/Echo/i18n/rmc.json @@ -0,0 +1,12 @@ +{ + "@metadata": { + "authors": [ + "Adehertogh" + ] + }, + "notification-timestamp-today": "Adaďives", + "notification-timestamp-yesterday": "Idž", + "notification-inbox-filter-read": "Te genel", + "echo-date-today": "Adaďives", + "echo-date-yesterday": "Idž" +} diff --git a/Echo/i18n/ro.json b/Echo/i18n/ro.json index e8094fe9..7c0787e6 100644 --- a/Echo/i18n/ro.json +++ b/Echo/i18n/ro.json @@ -2,13 +2,18 @@ "@metadata": { "authors": [ "Andrei Stroe", + "Andreyyshore", + "Cezar", "Firilacroco", "ImGelu", "Macofe", "Minisarm", + "NGC 54", "Reception123", + "Rsocol", "Stelistcristi", "Strainu", + "WebSourceContentRO", "Wintereu" ] }, @@ -17,24 +22,30 @@ "prefs-emailsettings": "Setări pentru e-mail", "prefs-echosubscriptions": "Notifică-mă despre aceste evenimente", "prefs-echocrosswiki": "Notificări inter-wiki", - "prefs-blocknotificationslist": "Utilizatori blocați", + "prefs-blocknotificationslist": "Utilizatori ignorați de notificări", + "prefs-mutedpageslist": "Pagini ignorate de notificările de legare ale paginilor", + "prefs-echopollupdates": "Notificări în timp real", + "echo-mobile-notifications-filter-title": "Filtrează notificările", + "echo-pref-show-poll-updates": "Afișează notificări noi pe măsură ce sosesc", "echo-pref-send-me": "Trimite-mi:", "echo-pref-send-to": "Trimite la:", "echo-pref-email-format": "Formatul e-mailului:", "echo-pref-web": "Web", "echo-pref-email": "E-mail", + "echo-pref-push": "Aplicații", "echo-pref-email-frequency-never": "Nu-mi trimite nicio notificare prin e-mail", "echo-pref-email-frequency-immediately": "Notificări individuale pe măsură ce sosesc", "echo-pref-email-frequency-daily": "Un rezumat zilnic al notificărilor", "echo-pref-email-frequency-weekly": "Un rezumat săptămânal al notificărilor", "echo-pref-email-format-html": "HTML", "echo-pref-email-format-plain-text": "Text brut", - "echo-pref-cross-wiki-notifications": "Arată notificări de la alte wikiuri", - "echo-pref-notifications-blacklist": "Nu arăta notificări de la acești utilizatori. ([[mw:Special:MyLanguage/Help:Notifications#mute|Află mai multe]])", + "echo-pref-cross-wiki-notifications": "Arată notificări de la alte wiki-uri", + "echo-pref-notifications-blacklist": "Nu arăta notificări de la acești utilizatori. ([[mw:Special:MyLanguage/Help:Notifications#mute|află mai multe]])", + "echo-pref-notifications-page-linked-title-muted-list": "Nu arăta notificări de „legare ale paginilor” pentru aceste pagini. ([[mw:Special:MyLanguage/Help:Notifications#mute|află mai multe]])", "echo-learn-more": "Aflați mai multe", "echo-log": "Jurnal public", - "echo-new-messages": "Aveți mesaje noi", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Mesaj|Mesaje}} în pagina de discuții", + "echo-new-messages": "Aveți un mesaj nou în pagina de discuții", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Modificare|Modificări}} pe pagina mea de discuții", "echo-category-title-article-linked": "{{PLURAL:$1|Legătură|Legături}} către pagină", "echo-category-title-reverted": "{{PLURAL:$1|Revenire|Reveniri}} asupra modificărilor", "echo-category-title-mention": "{{PLURAL:$1|Menționare|Menționări}}", @@ -44,12 +55,20 @@ "echo-category-title-system": "{{PLURAL:$1|Sistem}}", "echo-category-title-user-rights": "{{PLURAL:$1|Schimbare a drepturilor de utilizator|Schimbări ale drepturilor de utilizator}}", "echo-category-title-emailuser": "{{PLURAL:$1|E-mail de la un alt utilizator|E-mailuri de la alți utilizatori}}", - "echo-pref-tooltip-edit-user-talk": "Notifică-mă când cineva publică un mesaj sau răspunde pe pagina mea de discuții.", + "echo-category-title-thank-you-edit": "Atingere {{PLURAL:$1|număr fix}} de editări", + "echo-category-title-watchlist": "Editare la o pagină urmărită", + "echo-category-title-minor-watchlist": "Editare minoră la o pagină urmărită", + "echo-pref-tooltip-edit-user-talk": "Notifică-mă când cineva modifică pagina mea de discuții.", "echo-pref-tooltip-article-linked": "Notifică-mă atunci când cineva introduce într-un articol o legătură către una din paginile pe care le-am creat.", "echo-pref-tooltip-reverted": "Notifică-mă atunci când cineva, folosind uneltele de anulare sau revenire, revine asupra unei modificări făcută de mine.", "echo-pref-tooltip-mention": "Notifică-mă când cineva face referire la pagina mea de utilizator.", - "echo-pref-tooltip-user-rights": "Anunță-mă când cineva îmi schimbă drepturile de utilizator.", - "echo-pref-tooltip-emailuser": "Anunță-mă când cineva îmi trimite un e-mail.", + "echo-pref-tooltip-mention-failure": "Notifică-mă când nu am reușit să trimit cuiva o menționare.", + "echo-pref-tooltip-mention-success": "Notifică-mă când am reușit să trimit cuiva o menționare.", + "echo-pref-tooltip-user-rights": "Notifică-mă când cineva îmi schimbă drepturile de utilizator.", + "echo-pref-tooltip-emailuser": "Notifică-mă când cineva îmi trimite un e-mail.", + "echo-pref-tooltip-thank-you-edit": "Notifică-mă când ajung la prima, a zecea, a o suta... modificare.", + "echo-pref-tooltip-watchlist": "Notifică-mă când cineva face o editare (non-minoră) la o pagină din lista mea de pagini urmărite.", + "echo-pref-tooltip-minor-watchlist": "Notifică-mă când cineva face o editare minoră la o pagină din lista mea de pagini urmărite.", "notifications": "Notificări", "tooltip-pt-notifications-alert": "Alertele {{GENDER:|dumneavoastră}}", "tooltip-pt-notifications-notice": "Înștiințările {{GENDER:|dumneavoastră}}", @@ -62,10 +81,12 @@ "echo-displaynotificationsconfiguration-enabled-default-existing-users-legend": "Utilizatori existenți", "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "Utilizatori noi", "echo-displaynotificationsconfiguration-mandatory-notification-methods-header": "Metode obligatorii de notificare", + "echo-displaynotificationsconfiguration-mandatory-notification-methods-by-category-legend": "Care metode de notificare sunt obligatorii pentru fiecare categorie", "echo-specialpage": "Notificări", "echo-specialpage-section-markread": "Marchează grupul ca citit", "echo-specialpage-markasread": "Notificare: Marcare ca citită", "echo-specialpage-markasread-invalid-id": "ID de eveniment nevalid", + "echo-specialpage-pagefilterwidget-aria-label": "Filtrează după wiki și titlul paginii", "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|notificare|notificări|de notificări}}", "echo-specialpage-pagefilters-title": "Activitate recentă", "echo-specialpage-pagefilters-subtitle": "Pagini cu notificări necitite", @@ -79,6 +100,12 @@ "echo-notification-markasunread": "Marchează ca necitită", "echo-notification-markasread-tooltip": "Marchează ca citită", "echo-notification-more-options-tooltip": "Mai multe opțiuni", + "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|Oprește}} notificările de legare pentru „$1”", + "notification-dynamic-actions-mute-page-linked-confirmation": "Notificările de „legare ale paginilor” sunt acum dezactivate pentru pagina „$1”", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|Puteți}} oricând să administrați paginile a căror notificările le ignorați în [$1 preferințele dvs.]", + "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2|Anulează}} ignorarea notificărilor de legare pentru „$1”", + "notification-dynamic-actions-unmute-page-linked-confirmation": "Notificările de „legare ale paginilor” sunt acum activate pentru pagina „$1”", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|Puteți}} oricând să administrați paginile a căror notificările le ignorați în [$1 preferințele dvs.]", "notification-link-text-expand-all": "Extinde", "notification-link-text-expand-alert-count": "Arată {{PLURAL:$1|$1 alertă|$1 alerte|$1 de alerte}}", "notification-link-text-expand-notice-count": "Arată {{PLURAL:$1|$1 înștiințare|$1 înștiințări|$1 de înștiințări}}", @@ -86,23 +113,56 @@ "notification-link-text-collapse-all": "Restrânge", "notification-link-text-view-message": "Vezi mesajul", "notification-link-text-view-mention": "Vezi menționarea", + "notification-link-text-view-mention-failure": "{{PLURAL:$1|Vezi menționarea|Vezi menționările}}", "notification-link-text-view-changes": "{{GENDER:$1|Vezi}} schimbările", "notification-link-text-view-page": "Vezi pagina", "notification-header-edit-user-talk": "$1 {{GENDER:$2|a lăsat}} un mesaj pe <strong>pagina {{GENDER:$3|dumnevoastră}} de discuții</strong>.", "notification-header-edit-user-talk-with-section": "$1 {{GENDER:$2|a lăsat}} un mesaj pe <strong>pagina {{GENDER:$3|dumneavoastră}} de discuții</strong>, în cadrul secțiunii „<strong>$4</strong>”.", + "notification-compact-header-edit-user-talk": "$1 {{GENDER:$3|v-}}a {{GENDER:$2|lăsat}} un mesaj.", + "notification-compact-header-edit-user-talk-with-section": "$1 {{GENDER:$3|v-}}a {{GENDER:$2|lăsat}} un a mesaj în cadrul secțiunii „<strong>$4</strong>”.", "notification-header-page-linked": "A fost creată o legătură de la <strong>$4</strong> către <strong>$3</strong>.", + "notification-compact-header-page-linked": "Legată de la <strong>$1</strong>.", "notification-bundle-header-page-linked": "Au fost create legături de la {{PLURAL:$5|o pagină|alte $5 pagini|alte $5 de pagini|100=alte 99+ pagini}} către <strong>$3</strong>.", "notification-link-text-what-links-here": "Toate legăturile către această pagină", + "notification-header-mention-other": "$1 {{GENDER:$3|v-}}{{GENDER:$2|a menționat}} pe <strong>$4</strong>, în cadrul secțiunii „<strong>$5</strong>”.", + "notification-header-mention-other-nosection": "$1 {{GENDER:$3|v-}}{{GENDER:$2|a menționat}} pe <strong>$4</strong>.", + "notification-header-mention-user-talkpage-v2": "$1 {{GENDER:$3|v-}}{{GENDER:$2|a menționat}} pe <strong>pagina de discuție a {{GENDER:$5|utilizatorului|utilizatoarei|utilizatorului}} $4</strong>, în cadrul secțiunii „<strong>$6</strong>”.", + "notification-header-mention-user-talkpage-nosection": "$1 {{GENDER:$3|v-}}{{GENDER:$2|a menționat}} pe <strong>pagina de discuție a {{GENDER:$5|utilizatorului|utilizatoarei|utilizatorului}} $4</strong>.", + "notification-header-mention-agent-talkpage": "$1 {{GENDER:$3|v-}}{{GENDER:$2|a menționat}} pe <strong>pagina {{GENDER:$2|lui|ei|sa}} de discuție</strong>, în cadrul secțiunii „<strong>$4</strong>”.", + "notification-header-mention-agent-talkpage-nosection": "$1 {{GENDER:$2|v-}}{{GENDER:$3|a menționat}} pe <strong>pagina {{GENDER:$2|lui|ei|sa}} de discuție</strong>.", + "notification-header-mention-article-talkpage": "$1 {{GENDER:$3|v-}}{{GENDER:$2|a menționat}} pe pagina de discuție a paginii <strong>$4</strong>, în cadrul secțiunii „<strong>$5</strong>”.", + "notification-header-mention-article-talkpage-nosection": "$1 {{GENDER:$3|v-}}{{GENDER:$2|a menționat}} pe pagina de discuție <strong>$4</strong>.", + "notification-header-mention-failure-user-unknown": "Menționarea {{GENDER:$2|dvs.}} a lui <strong>$3</strong> nu a fost trimisă deoarece utilizatorul nu a fost găsit.", + "notification-header-mention-failure-user-anonymous": "Menționarea {{GENDER:$2|dvs.}} a lui <strong>$3</strong> nu a fost trimisă deoarece utilizatorul este anonim.", + "notification-header-mention-failure-too-many": "{{GENDER:$2|Ați}} încercat să menționați mai mult de $3 {{PLURAL:$3|utilizator|utilizatori}}. Toate menționările peste această limită nu au fost trimise.", + "notification-header-mention-failure-bundle": "{{PLURAL:$3|O menționare|$3 menționări}} pe care {{PLURAL:$2|ați făcut-o|le-ați făcut}} pe pagina de discuție <strong>$4</strong> nu {{PLURAL:$3|a putut fi trimisă|au putut fi trimise}}.", "notification-compact-header-mention-failure-user-unknown": "<strong>Numele de utilizator nu există:</strong> $1", "notification-compact-header-mention-failure-user-anonymous": "<strong>Adresele IP nu pot fi menționate:</strong> $1", + "notification-header-mention-success": "Menționarea {{GENDER:$2|dvs.}} a lui <strong>$3</strong> a fost trimisă.", + "notification-header-mention-success-bundle": "{{PLURAL:$3|O menționare|$3 menționări}} pe care {{PLURAL:$2|ați făcut-o|le-ați făcut}} pe pagina de discuție <strong>$4</strong> {{PLURAL:$3|a fost trimisă|au fost trimise}}.", + "notification-compact-header-mention-success": "<strong>{{GENDER:$2|Ați menționat pe}}:</strong> $3", + "notification-header-mention-status-bundle": "{{PLURAL:$3|O notificare|$3 notificări}} despre menționări {{GENDER:$2|pe care le-ați făcut}} pe pagina de discuție <strong>$4</strong>: {{PLURAL:$5|$5 netrimisă|$5 netrimise}}, {{PLURAL:$6|$6 trimisă|$6 trimise}}.", + "notification-header-user-rights-add-only": "Drepturile {{GENDER:$4|dumneavoastră}} de utilizator au fost {{GENDER:$1|schimbate}}. Ați fost {{GENDER:$4|adăugat|adăugată|adăugat}} la: $2.", + "notification-header-user-rights-remove-only": "Drepturile {{GENDER:$4|dumneavoastră}} de utilizator au fost {{GENDER:$1|schimbate}}. Nu mai sunteți {{GENDER:$4|un membru|o membră|un membru}} al: $2.", + "notification-header-user-rights-add-and-remove": "Drepturile {{GENDER:$6|dumneavoastră}} de utilizator au fost {{GENDER:$1|schimbate}}. Ați fost {{GENDER:$4|adăugat|adăugată|adăugat}} la: $2. Nu mai sunteți {{GENDER:$4|un membru|o membră|un membru}} al: $4.", + "notification-header-user-rights-expiry-change": "Termenul de expirare a apartenenței {{GENDER:$4|dvs.}} în {{PLURAL:$3|următorul grup|următoarele grupuri}} a fost {{GENDER:$1|schimbat}}: $2.", "notification-header-welcome": "{{GENDER:$2|Bun venit}} la {{SITENAME}}, $1! Ne bucurăm să {{GENDER:$2|vă avem}} printre noi.", + "notification-header-mention-summary": "$1 {{GENDER:$3|v-a}}{{GENDER:$2|menționat}} într-o descriere a modificării la <strong>$4</strong>.", "notification-welcome-linktext": "Bun venit", + "notification-header-thank-you-1-edit": "Tocmai {{GENDER:$2|ați}} făcut prima {{GENDER:$2|dumneavoastră}} modificare; {{GENDER:$2|vă}} mulțumim și bine ați venit!", + "notification-header-thank-you-10-edit": "Tocmai {{GENDER:$2|ați}} făcut a zecea {{GENDER:$2|dumneavoastră}} modificare; {{GENDER:$2|vă}} mulțumim și vă rugăm să continuați!", + "notification-header-thank-you-100-edit": "Tocmai {{GENDER:$2|ați}} făcut a o suta {{GENDER:$2|modificare}}; {{GENDER:$2|vă}} mulțumim foarte mult!", + "notification-header-thank-you-1000-edit": "Tocmai {{GENDER:$2|ați}} făcut a o mia {{GENDER:$2|dumneavoastră modificare}}; {{GENDER:$2|vă}} mulțumim pentru că sunteți un mare contribuitor!", + "notification-header-thank-you-10000-edit": "Tocmai {{GENDER:$2|ați}} făcut a zece mia {{GENDER:$2|voastră}} modificare; {{GENDER:$2|vă}} mulțumim mult!", + "notification-header-thank-you-100000-edit": "Tocmai {{GENDER:$2|ați}} făcut a o sută mia {{GENDER:$2|dumneavoastră}} modificare; {{GENDER:$2|vă}} mulțumim pentru contribuția dvs. uimitoare!", + "notification-header-thank-you-1000000-edit": "Tocmai {{GENDER:$2|ați}} făcut a milioana {{GENDER:$2|dumneavoastră}} modificare; {{GENDER:$2|vă}} mulțumim pentru contribuțiile dvs. extraordinare!", + "notification-header-thank-you-10000000-edit": "Tocmai {{GENDER:$2|ați}} făcut a zece milioana {{GENDER:$2|dumneavoastră}} modificare; {{GENDER:$2|vă}} mulțumim pentru devotamentul dvs. extraordinar!", "notification-link-thank-you-edit": "Modificarea {{GENDER:$1|dumnevoastră}}", "notification-link-text-view-edit": "Vezi modificarea", "notification-link-article-reminder": "Vezi pagina", "notification-header-reverted": "{{PLURAL:$4|Modificarea dumneavoastră asupra paginii <strong>$3</strong> a|Modificările dumneavoastră asupra paginii <strong>$3</strong> au}} fost {{GENDER:$2|înlăturat}}{{PLURAL:$4|ă|e}}.", "notification-header-emailuser": "$1 {{GENDER:$2|v-a trimis}} un e-mail.", - "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$2|v-a lăsat}} un mesaj la {{SITENAME}}", + "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$3|v-a}} {{GENDER:$2|lăsat}} un mesaj la {{SITENAME}}", "notification-page-linked-email-subject": "O pagină creată de {{GENDER:$3|dumnevoastră}} a fost menționată la {{SITENAME}}", "notification-reverted-email-subject2": "{{PLURAL:$4|Modificarea|Modificările}} {{GENDER:$3|dumneavoastră}} {{PLURAL:$4|a fost|au fost}} {{GENDER:$2|înlăturat}}{{PLURAL:$4|ă|e}} la {{SITENAME}}", "notification-mention-email-subject": "$1 {{GENDER:$3|v}}-{{GENDER:$2|a menționat}} la {{SITENAME}}", @@ -118,9 +178,10 @@ "notification-inbox-filter-read": "Citite", "notification-inbox-filter-unread": "Necitite", "notification-inbox-filter-all": "Toate", - "echo-email-plain-footer": "Pentru a avea controlul asupra e-mailurilor pe care vi le trimitem, verificați-vă preferințele:", - "echo-email-html-footer-preference-link-text": "verificați-vă preferințele", - "echo-email-html-footer-with-link": "Pentru a avea controlul asupra e-mailurilor pe care vi le trimitem, $1.", + "echo-specialmute-label-mute-notifications": "Nu arăta notificări de la {{GENDER:$1|acest utilizator|această utilizatoare}}", + "echo-email-plain-footer": "Pentru a avea controlul asupra e-mailurilor pe care {{GENDER:$1|vi}} le trimitem, {{GENDER:$1|verificați-vă}} preferințele:", + "echo-email-html-footer-preference-link-text": "{{GENDER:$1verificați-vă}} preferințele", + "echo-email-html-footer-with-link": "Pentru a avea controlul asupra e-mailurilor pe care {{GENDER:$2vi}} le trimitem, $1.", "echo-notification-alert": "{{PLURAL:$1|Alertă ($1)|Alerte ($1)|100=Alerte (99+)}}", "echo-notification-notice": "{{PLURAL:$1|Înștiințare ($1)|Înștiințări ($1)|100=Înștiințări (99+)}}", "echo-notification-alert-text-only": "Alerte", @@ -130,6 +191,7 @@ "echo-mark-all-as-read": "Marchează toate ca citite", "echo-mark-all-as-read-confirmation": "$1 {{PLURAL:$1|notificare marcată ca citită|notificări marcate ca citite|de notificări marcate ca citite}}", "echo-mark-wiki-as-read": "Marchează ca citită în wikiul selectat: $1", + "echo-displaysnippet-title": "Notificare nouă", "echo-date-today": "Astăzi", "echo-date-yesterday": "Ieri", "notification-bundle-header-edit-user-talk-v2": "{{PLURAL:$1|Un mesaj noi|$1 mesaje noi|$1 de mesaje noi|100=99+ mesaje noi}} pe <strong>pagina {{GENDER:$3|dumneavoastră}} de discuții</strong>.", @@ -138,7 +200,7 @@ "echo-email-batch-body-intro-daily": "Bună ziua $1,\nAveți aici un rezumat al activității de astăzi la {{SITENAME}}.", "echo-email-batch-body-intro-weekly": "Bună ziua $1,\nAveți aici un rezumat al activității din această săptămână la {{SITENAME}}.", "echo-email-batch-link-text-view-all-notifications": "Vezi toate notificările", - "notification-header-foreign-alert": "Mai multe alerte de pe {{PLURAL:$5|alt wiki|$5 alte wikiuri|$5 de alte wikiuri}}", + "notification-header-foreign-alert": "Mai multe alerte {{PLURAL:$5|de pe alt wiki|$5 alte wikiuri|$5 de alte wikiuri}}", "notification-header-foreign-notice": "Mai multe înștiințări de pe {{PLURAL:$5|alt wiki|$5 alte wikiuri|$5 de alte wikiuri}}", "notification-header-foreign-all": "Mai multe notificări de pe {{PLURAL:$5|alt wiki|$5 alte wikiuri|$5 de alte wikiuri}}" } diff --git a/Echo/i18n/roa-tara.json b/Echo/i18n/roa-tara.json index e5d40166..5b340018 100644 --- a/Echo/i18n/roa-tara.json +++ b/Echo/i18n/roa-tara.json @@ -6,11 +6,12 @@ ] }, "echo-desc": "Sisteme de notifiche a l'utinde sus a avveneminde e messàgge", - "prefs-echo": "Notificaziune", + "prefs-echo": "Notifeche", "prefs-emailsettings": "'Mbostaziune de l'email", "prefs-echosubscriptions": "Notificame sus a ste avveneminde", "prefs-echocrosswiki": "Notifeche cross-uicchi", "prefs-blocknotificationslist": "Utinde citte da sotte", + "prefs-mutedpageslist": "Pàggene silenziate pe le notifeche de collegamende 'a pàgene", "prefs-echopollupdates": "Notifeche in dirette", "echo-mobile-notifications-filter-title": "Notifeche d'u filtre", "echo-pref-show-poll-updates": "Fà 'ndrucà le notifeche nove cumme arrivane", @@ -20,6 +21,7 @@ "echo-pref-email-format": "Formate de l'email:", "echo-pref-web": "Web", "echo-pref-email": "E-mail", + "echo-pref-push": "App", "echo-pref-email-frequency-never": "No sce mannanne nisciuna mail de notifiche", "echo-pref-email-frequency-immediately": "Le notifiche individuale a cumme trasene", "echo-pref-email-frequency-daily": "'Nu riepiloghe sciurnaliere de le notifiche", @@ -28,10 +30,12 @@ "echo-pref-email-format-plain-text": "Teste semblice", "echo-pref-cross-wiki-notifications": "Fà 'ndrucà le notifeche da otre uicchi", "echo-pref-notifications-blacklist": "Nò ffà 'ndrucà le notifeche da ste utinde. ([[mw:Special:MyLanguage/Help:Notifications#mute|'mbare de cchiù]])", + "echo-pref-notifications-page-linked-title-muted-list": "Nò ffà 'ndrucà le notifeche d'a \"Pàgene de collegamende\" pè ste pàggene. ([[mw:Special:MyLanguage/Help:Notifications#mute|'mbare de cchiù]])", + "echo-pref-dont-email-read-notifications": "No 'ngludere le notifeche lette jndr'à le email de riepiloghe", "echo-learn-more": "'Mbare de cchiù", "echo-log": "Archivije pubbleche", - "echo-new-messages": "Tu è messàgge nuève", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Messàgge}} d'a pàgene de le 'ngazzaminde", + "echo-new-messages": "Tu è 'nu messàgge nuève jndr'à pàgene de le 'ngazzaminde", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Cangiamende|Cangiaminde}} d'a pàgene de le 'ngazzaminde meje", "echo-category-title-article-linked": "{{PLURAL:$1|Collegamende|Collegaminde}} d'a pàgene", "echo-category-title-reverted": "Annulle {{PLURAL:$1|'u cangiamende|le cangiaminde}}", "echo-category-title-mention": "{{PLURAL:$1|Menzione}}", @@ -46,7 +50,8 @@ "echo-category-title-article-reminder": "{{PLURAL:$1|Pàgene|Pàggene}} de promemorie", "echo-category-title-thank-you-edit": "Cange {{PLURAL:$1|'a petra miliare|le petre miliare}}", "echo-category-title-watchlist": "Cange 'a pàgene condrollate", - "echo-pref-tooltip-edit-user-talk": "Avvisame quacche quacchedune manne 'nu messàgge o responne sus 'a pàgene de le 'ngazzaminde meje.", + "echo-category-title-minor-watchlist": "Cangiamende stuèdeche jndr'à le pàggene condrollate", + "echo-pref-tooltip-edit-user-talk": "Avvisame quacche quacchedune cange 'a pàgene de le 'ngazzaminde meje.", "echo-pref-tooltip-article-linked": "Avvisame quacche quacchedune se colleghe a 'na pàgene ca ije agghie ccrejate da 'n'otra vôsce.", "echo-pref-tooltip-reverted": "Avvisame quanne quacchedune annulle 'nu cangiamende ca agghie fatte ije, ausanne 'u strumende de annullamende.", "echo-pref-tooltip-mention": "Avvisame quanne quacchedune se colleghe a pàgena utende meje.", @@ -56,7 +61,9 @@ "echo-pref-tooltip-emailuser": "Avvisame quanne quacchedune manne 'na mail.", "echo-pref-tooltip-article-reminder": "Avvisame sus a sta pàgene quanne ije cerche.", "echo-pref-tooltip-thank-you-edit": "Avvisame quanne agghie raggiunde 'u prime, decime, cendesime... cangiamende.", - "notifications": "Notificaziune", + "echo-pref-tooltip-watchlist": "Notifecame quanne quacchedune face 'nu cangiamende (none stuedeche) sus a 'na pàgene ca ste jndr'à l'elenghe de le pàggene condrollate mie.", + "echo-pref-tooltip-minor-watchlist": "Notifecame quanne quacchedune face 'nu cangiamende stuedeche sus a 'na pàgene ca ste jndr'à l'elenghe de le pàggene condrollate mie.", + "notifications": "Notifeche", "tooltip-pt-notifications-alert": "Avvise {{GENDER:|tune}}", "tooltip-pt-notifications-notice": "Le notizie {{GENDER:|tune}}", "echo-displaynotificationsconfiguration": "Fà 'ndrucà 'a configurazione de le notifeche", @@ -71,10 +78,12 @@ "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "Utinde nuève", "echo-displaynotificationsconfiguration-mandatory-notification-methods-header": "Metode de notifeche obbligatorije", "echo-displaynotificationsconfiguration-mandatory-notification-methods-by-category-legend": "Ce metode de notifeche sò obbligatorije pe ogne categorije", - "echo-specialpage": "Notificaziune", + "echo-specialpage": "Notifeche", "echo-specialpage-section-markread": "Signe 'u gruppe cumme lette", "echo-specialpage-markasread": "Notifeche: Signe cumme lette", "echo-specialpage-markasread-invalid-id": "ID evende invalide", + "echo-specialpage-pagefilterwidget-aria-label": "Filtre pe uicchi e titole d'a pàgene", + "echo-specialpage-special-help-menu-widget-aria-label": "Opziune aggiundive e preferenze de le notifeche.", "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|notifeche}}", "echo-specialpage-pagefilters-title": "Urteme attivitate", "echo-specialpage-pagefilters-subtitle": "Pàggene cu notifeche non lette", @@ -90,6 +99,12 @@ "echo-notification-markasunread": "Signe cumme non lette", "echo-notification-markasread-tooltip": "Signe cumme lette", "echo-notification-more-options-tooltip": "Cchiù opziune", + "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|Fà sta citte}} 'u collegamende a le notifeche sus a \"$1\"", + "notification-dynamic-actions-mute-page-linked-confirmation": "Le notifeche \"Collegamende d'a pàgene\" mò sò disabbilitate pa pàgene \"$1\"", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|Tu}} puè gestì le pàggene silenziate tune jndr'à [$1 le preferenze tune] quanne vuè.", + "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2|Attive}} 'u collegamende a le notifeche sus a \"$1\"", + "notification-dynamic-actions-unmute-page-linked-confirmation": "Le notifeche \"Collegamende d'a pàgene\" mò sò abbilitate pa pàgene \"$1\"", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|Tu}} puè gestì le pàggene silenziate tune jndr'à [$1 le preferenze tune] quanne vuè.", "notification-dynamic-actions-unwatch": "{{GENDER:$3|Live}} le attività nove sus a \"$1\" da le osservate speciale", "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3|Tu}} non g3e ste cchiù condrolle 'a pàgene \"$1\"", "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|Puè}} condrollà [$2 sta pàgene] quanne vuè.", @@ -139,6 +154,16 @@ "notification-header-user-rights-expiry-change": "'A scadenze de l'appartenenza {{GENDER:$4|toje}} {{PLURAL:$3|a stu|a ste}} gruppe ha state {{GENDER:$1|cangiate}}: $2.", "notification-header-welcome": "{{GENDER:$2|Bovègne}} sus a {{SITENAME}}, $1! Sime cundende ca {{GENDER:$2|tu}} ste aqquà.", "notification-header-mention-summary": "$1 {{GENDER:$3|te}} {{GENDER:$2|ave menzionate}} jndr'à 'nu riepiloghe de cangiamende sus a <strong>$4</strong>.", + "notification-header-watchlist-changed": "$1 {{GENDER:$2|ave cangiate}} <strong>$3</strong>, 'na pàgene jndr'à l'elenghe de le pàggene condrollate {{GENDER:$4|tune}} {{PLURAL:$5||, $5 vote}}.", + "notification-header-watchlist-created": "$1 {{GENDER:$2|ave ccrejate}} <strong>$3</strong>, 'na pàgene jndr'à l'elenghe de le pàggene condrollate {{GENDER:$4|tune}} {{PLURAL:$5||, $5 vote}}.", + "notification-header-watchlist-deleted": "$1 {{GENDER:$2|ave scangellate}} <strong>$3</strong>, 'na pàgene jndr'à l'elenghe de le pàggene condrollate {{GENDER:$4|tune}} {{PLURAL:$5||, $5 vote}}.", + "notification-header-watchlist-moved": "$1 {{GENDER:$2|ave spustate}} <strong>$3</strong>, 'na pàgene jndr'à l'elenghe de le pàggene condrollate {{GENDER:$4|tune}} {{PLURAL:$5||, $5 vote}}.", + "notification-header-watchlist-restored": "$1 {{GENDER:$2|ave repristinate}} <strong>$3</strong>, 'na pàgene jndr'à l'elenghe de le pàggene condrollate {{GENDER:$4|tune}} {{PLURAL:$5||, $5 vote}}.", + "notification-header-watchlist-multiuser-changed": "<strong>$1</strong>, 'na pàgene sus a l'elenghe de le pàggene condrollate {{GENDER:$2|tune}}, ha state cangiate $3 {{PLURAL:$3|vote}}.", + "notification-header-watchlist-multiuser-created": "<strong>$1</strong>, 'na pàgene sus a l'elenghe de le pàggene condrollate {{GENDER:$2|tune}}, ha state ccrejate $3 {{PLURAL:$3|vote}}.", + "notification-header-watchlist-multiuser-deleted": "<strong>$1</strong>, 'na pàgene sus a l'elenghe de le pàggene condrollate {{GENDER:$2|tune}}, ha state scangellate $3 {{PLURAL:$3|vote}}.", + "notification-header-watchlist-multiuser-moved": "<strong>$1</strong>, 'na pàgene sus a l'elenghe de le pàggene condrollate {{GENDER:$2|tune}}, ha state spustate $3 {{PLURAL:$3|vote}}.", + "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>, 'na pàgene sus a l'elenghe de le pàggene condrollate {{GENDER:$2|tune}}, ha state repristinate $3 {{PLURAL:$3|vote}}.", "notification-welcome-linktext": "Bovègne", "notification-header-thank-you-1-edit": "E' fatte mo mo 'u prima cangiamende tune; grazie e {{GENDER:$2|bovègne}}!", "notification-header-thank-you-10-edit": "E' fatte mo mo 'u decime cangiamende {{GENDER:$2|tune}}; {{GENDER:$2|te}} rengraziame, e condinue accussì!", @@ -147,6 +172,7 @@ "notification-header-thank-you-10000-edit": "E' fatte mo mo 'u decimillesime cangiamende {{GENDER:$2|tune}}; {{GENDER:$2|te}} rengraziame assai avveramende!", "notification-header-thank-you-100000-edit": "E' fatte mo mo 'u cindemillesime cangiamende {{GENDER:$2|tune}}; {{GENDER:$2|te}} pu condrebbute 'mbortande ca ne dèje!", "notification-header-thank-you-1000000-edit": "E' fatte mo mo 'u miglionesime cangiamende {{GENDER:$2|tune}}; {{GENDER:$2|te}} pu condrebbute 'mbressionande ca ne dèje!", + "notification-header-thank-you-10000000-edit": "{{GENDER:$2|E'}} fatte mò mò 'u {{GENDER:$2|tue}} decemiglionesime cangiamende; {{GENDER:$2|te}} rengraziame pa brillande dediziona toje!", "notification-link-thank-you-edit": "'U {{GENDER:$1|cangiamende}} tune", "notification-link-text-view-edit": "'Ndruche 'u cangiamende", "notification-link-article-reminder": "'Ndruche 'a vôsce", @@ -168,7 +194,7 @@ "notification-inbox-filter-read": "Lette", "notification-inbox-filter-unread": "None lette", "notification-inbox-filter-all": "Tutte", - "echo-specialmute-label-mute-notifications": "Silenzie le notifeche da stu utende", + "echo-specialmute-label-mute-notifications": "Silenzie le notifeche da stu {{GENDER:$1|utende}}", "echo-email-plain-footer": "Pe condrollà ce email {{GENDER:$1|t'}}avènene mannate, condrolle le preferenze {{GENDER:$1|tune}}:", "echo-email-html-footer-preference-link-text": "condrolle le preferenze {{GENDER:$1|tune}}", "echo-email-html-footer-with-link": "Pe condrollà ce email {{GENDER:$2|t'}}avènene mannate, $1.", @@ -192,5 +218,10 @@ "echo-email-batch-link-text-view-all-notifications": "'Ndruche tutte le notifiche", "notification-header-foreign-alert": "Otre avvise da {{PLURAL:$5|'n'otra uicchi|otre $5 uicchi}}", "notification-header-foreign-notice": "Otre notizie da {{PLURAL:$5|'n'otra uicchi|otre $5 uicchi}}", - "notification-header-foreign-all": "Otre notifeche da {{PLURAL:$5|'n'otra uicchi|otre $5 uicchi}}" + "notification-header-foreign-all": "Otre notifeche da {{PLURAL:$5|'n'otra uicchi|otre $5 uicchi}}", + "right-manage-all-push-subscriptions": "Gestisce tutte le sottoscreziune push", + "action-manage-all-push-subscriptions": "gestisce tutte le sottoscreziune push", + "group-push-subscription-manager": "Gestore de le sottoscreziune push", + "group-push-subscription-manager-member": "{{GENDER:$1|gestore de le sottoscreziune push}}", + "grouppage-push-subscription-manager": "{{ns:project}}:Gestore de le sottoscreziune push" } diff --git a/Echo/i18n/ru.json b/Echo/i18n/ru.json index 2f56709c..942e7aa4 100644 --- a/Echo/i18n/ru.json +++ b/Echo/i18n/ru.json @@ -26,11 +26,14 @@ "Mailman", "Marina Melik-Adamyan", "MaxBioHazard", + "Megakott", + "MirandaBlack", "Mouse21", "Movses", "Okras", "Ole Yves", "Orsa", + "Pacha Tchernof", "Putnik", "Sealle", "ShinePhantom", @@ -39,6 +42,7 @@ "Stjn", "Sunpriat", "Trizek (WMF)", + "Wolterhon", "Исмаил Садуев", "Лилиә", "ЛосЯш", @@ -62,7 +66,7 @@ "echo-pref-email-format": "Формат писем:", "echo-pref-web": "Веб", "echo-pref-email": "Эл. почта", - "echo-pref-push": "Push (только в приложениях)", + "echo-pref-push": "Приложения", "echo-pref-email-frequency-never": "Не присылать мне уведомления по эл. почте", "echo-pref-email-frequency-immediately": "Отдельные уведомления по мере их поступления", "echo-pref-email-frequency-daily": "Ежедневная сводка уведомлений", @@ -71,12 +75,12 @@ "echo-pref-email-format-plain-text": "Простой текст", "echo-pref-cross-wiki-notifications": "Показывать уведомления с других вики", "echo-pref-notifications-blacklist": "Не показывать уведомления от этих участников ([[mw:Special:MyLanguage/Help:Notifications#mute|узнать больше]]):", - "echo-pref-notifications-page-linked-title-muted-list": "Не показывать уведомления \"Ссылка на странице\" для этих страниц. ([[mw:Special:MyLanguage/Help:Notifications#mute|узнать больше]])", - "echo-pref-dont-email-read-notifications": "Не включать чтение уведомлений в сводки по эл. почте", + "echo-pref-notifications-page-linked-title-muted-list": "Не показывать уведомления «Ссылка на странице» для следующих страниц. ([[mw:Special:MyLanguage/Help:Notifications#mute|узнать больше]])", + "echo-pref-dont-email-read-notifications": "Не включать в рассылку сводок уведомления, отмеченные как прочитанные", "echo-learn-more": "Узнать больше", "echo-log": "Общедоступный журнал", - "echo-new-messages": "У вас есть новые сообщения", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|1=Сообщение|Сообщения}} на странице обсуждения", + "echo-new-messages": "Новые сообщения", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|1=Правка|Правки}} на странице обсуждения", "echo-category-title-article-linked": "{{PLURAL:$1|1=Ссылка на странице|Ссылки на страницах}}", "echo-category-title-reverted": "{{PLURAL:$1|1=Отмена|Отмены}} правок", "echo-category-title-mention": "{{PLURAL:$1|1=Упоминание|Упоминания}}", @@ -89,10 +93,10 @@ "echo-category-title-user-rights": "{{PLURAL:$1|Изменение|Изменения}} прав участника", "echo-category-title-emailuser": "Электронная почта от {{PLURAL:$1|другого участника|других участников}}", "echo-category-title-article-reminder": "Страница {{PLURAL:$1|напоминание|напоминания}}", - "echo-category-title-thank-you-edit": "{{PLURAL:$1|Достигнутая правка|достигнутые правки}}", + "echo-category-title-thank-you-edit": "{{PLURAL:$1|Веха|Вехи}} в редактировании", "echo-category-title-watchlist": "Правка в наблюдаемой странице", "echo-category-title-minor-watchlist": "Малая правка в наблюдаемой странице", - "echo-pref-tooltip-edit-user-talk": "Сообщать мне, когда кто-то посылает сообщение или отвечает на моей странице обсуждения.", + "echo-pref-tooltip-edit-user-talk": "Сообщать мне, когда кто-то редактирует мою страницу обсуждения.", "echo-pref-tooltip-article-linked": "Сообщать мне, когда на созданную мной страницу кто-то ссылается с другой страницы.", "echo-pref-tooltip-reverted": "Сообщать мне, когда кто-то отменил мою правку, используя функцию отмены или отката.", "echo-pref-tooltip-mention": "Сообщать мне, когда кто-то ссылается на мою страницу участника.", @@ -100,7 +104,7 @@ "echo-pref-tooltip-mention-success": "Уведомлять меня, когда я отправляю упоминание кому-либо.", "echo-pref-tooltip-user-rights": "Сообщать мне, когда кто-то изменяет мои права участника.", "echo-pref-tooltip-emailuser": "Сообщать мне, когда кто-то присылает мне письмо по электронной почте.", - "echo-pref-tooltip-article-reminder": "Сообщите мне об этой странице, когда я попрошу.", + "echo-pref-tooltip-article-reminder": "Сообщать мне об этой странице, когда я попрошу.", "echo-pref-tooltip-thank-you-edit": "Уведомлять меня когда я достигаю моих 1-й, 10-й, 100-й... правок.", "echo-pref-tooltip-watchlist": "Уведомлять меня когда кто-либо совершает (не малую) правку на странице из моего списка наблюдения.", "echo-pref-tooltip-minor-watchlist": "Уведомлять меня когда кто-либо совершает малую правку на странице из моего списка наблюдения.", @@ -112,7 +116,7 @@ "echo-displaynotificationsconfiguration-notifications-by-category-header": "Уведомления по категориям", "echo-displaynotificationsconfiguration-sorting-by-section-header": "Сортировка по типам", "echo-displaynotificationsconfiguration-sorting-by-section-legend": "В какие секции отсортирован каждый тип уведомлений", - "echo-displaynotificationsconfiguration-available-notification-methods-header": "Разрешенные способы уведомления", + "echo-displaynotificationsconfiguration-available-notification-methods-header": "Разрешённые способы уведомления", "echo-displaynotificationsconfiguration-available-notification-methods-by-category-legend": "Какие способы уведомления поддерживаются в каждой категории", "echo-displaynotificationsconfiguration-enabled-default-header": "Включено по умолчанию", "echo-displaynotificationsconfiguration-enabled-default-existing-users-legend": "Существующие участники", @@ -131,7 +135,7 @@ "notificationsmarkread-legend": "Пометить уведомление как прочитанное", "echo-none": "Вы не получали уведомлений.", "echo-api-failure": "Не удалось получить уведомления.", - "echo-api-failure-cross-wiki": "В доступе к удаленному домену было отказано.", + "echo-api-failure-cross-wiki": "Было отказано в доступе к удалённому домену.", "echo-notification-placeholder": "Уведомлений нет.", "echo-notification-placeholder-filters": "Нет уведомлений, соответствующих заданным критериям.", "echo-notification-loginrequired": "Вы должны войти, чтобы посмотреть уведомления.", @@ -140,11 +144,11 @@ "echo-notification-markasunread": "Пометить как непрочитанное", "echo-notification-markasread-tooltip": "Отметить как прочитанное", "echo-notification-more-options-tooltip": "Больше возможностей", - "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|Игнорировать}} уведомления о ссылке на \"$1\"", - "notification-dynamic-actions-mute-page-linked-confirmation": "Уведомления \"ссылка на странице\" теперь отключены для страницы \"$1\"", + "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|Игнорировать}} уведомления о ссылке на «$1»", + "notification-dynamic-actions-mute-page-linked-confirmation": "Уведомления «ссылка на странице» теперь отключены для страницы «$1»", "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|Вы}} можете управлять вашими игнорируемыми страницами в [$1 ваших настройках] в любое время.", - "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2|Убрать из игнорируемых}} уведомления о ссылке на \"$1\"", - "notification-dynamic-actions-unmute-page-linked-confirmation": "Уведомления \"ссылка на странице\" теперь включены для страницы \"$1\"", + "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2|Убрать из игнорируемых}} уведомления о ссылке на «$1»", + "notification-dynamic-actions-unmute-page-linked-confirmation": "Уведомления «ссылка на странице» теперь включены для страницы «$1»", "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|Вы}} можете управлять вашими игнорируемыми страницами в [$1 ваших настройках] в любое время.", "notification-dynamic-actions-unwatch": "{{GENDER:$3|Прекратить}} отслеживание новых изменений страницы «$1»", "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3|Вы}} больше не следите за изменениями страницы «$1»", @@ -177,16 +181,16 @@ "notification-header-mention-user-talkpage-v2": "$1 упомянул{{GENDER:$2||а}} {{GENDER:$3|вас}} на <strong>странице обсуждения {{GENDER:$5|$4}}</strong> в разделе «<strong>$6</strong>».", "notification-header-mention-user-talkpage-nosection": "$1 упомянул{{GENDER:$2||а}} {{GENDER:$3|вас}} на <strong>странице обсуждения {{GENDER:$5|$4}}</strong>.", "notification-header-mention-agent-talkpage": "$1 упомянул{{GENDER:$2||а}} {{GENDER:$3|вас}} на <strong>{{GENDER:$2|своей}} странице обсуждения</strong> в разделе «<strong>$4</strong>».", - "notification-header-mention-agent-talkpage-nosection": "$1 упомянул{{GENDER:$2||а}} {{GENDER:$3|вас}} на <strong>{{GENDER:$2|своей}} странице обсуждения</strong>.", + "notification-header-mention-agent-talkpage-nosection": "$1 упомянул{{GENDER:$2||а}} {{GENDER:$3|вас}} на <strong>{{GENDER:$2|его|её|своей}} странице обсуждения</strong>.", "notification-header-mention-article-talkpage": "$1 упомянул{{GENDER:$2||а}} {{GENDER:$3|вас}} на странице обсуждения «<strong>$4</strong>» в разделе «<strong>$5</strong>».", "notification-header-mention-article-talkpage-nosection": "$1 упомянул{{GENDER:$2||а}} {{GENDER:$3|вас}} на странице обсуждения «$4».", - "notification-header-mention-failure-user-unknown": "{{GENDER:$2|Ваше}} упоминание <strong>$3</strong> не было отправлено, поскольку этот участник не найден.", - "notification-header-mention-failure-user-anonymous": "{{GENDER:$2|Ваше}} упоминание <strong>$3</strong> не было отправлено, поскольку этот участник аноним.", + "notification-header-mention-failure-user-unknown": "{{GENDER:$2|Ваше}} упоминание <strong>$3</strong> не было отправлено, так как эта учётная запись не найдена.", + "notification-header-mention-failure-user-anonymous": "{{GENDER:$2|Ваше}} упоминание <strong>$3</strong> не было отправлено, так как эта учётная запись анонимна.", "notification-header-mention-failure-too-many": "{{GENDER:$2|Вы}} попытались упомянуть более $3 {{PLURAL:$3|участника|участников}}. Все упоминания выше этого лимита не были разосланы.", "notification-header-mention-failure-bundle": "{{PLURAL:$3|Упоминание|$3 упоминания|$3 упоминаний}} {{PLURAL:$3|сделанное|сделанные|сделанных}} {{GENDER:$2|вами}} на странице обсуждений <strong>$4</strong> не {{PLURAL:$3|может|могут}} быть отправлены.", "notification-compact-header-mention-failure-user-unknown": "<strong>Имя участника не существует:</strong> $1", "notification-compact-header-mention-failure-user-anonymous": "<strong>IP-адреса не могут быть упомянуты:</strong> $1", - "notification-header-mention-success": "{{GENDER:$2|Ваше}} упоминание участника <strong>$3</strong> было отправлено.", + "notification-header-mention-success": "{{GENDER:$2|Ваше}} упоминание {{GENDER:$3|участника|участницы}} <strong>$3</strong> было отправлено.", "notification-header-mention-success-bundle": "{{PLURAL:$3|Упоминание, сделанное|$3 упоминания, сделанные|$3 упоминаний, сделанных}} {{GENDER:$2|вами}} на странице обсуждения <strong>$4</strong>, отправлен{{PLURAL:$3|о|ы}}.", "notification-compact-header-mention-success": "<strong>{{GENDER:$2|Вы упомянули}}:</strong> $3", "notification-header-mention-status-bundle": "{{PLURAL:$3|Уведомление|$3 уведомления|$3 уведомлений}} об упоминании {{PLURAL:$3|сделанное|сделанные|сделанных}} {{GENDER:$2|вами}} на странице обсуждений <strong>$4</strong>: {{PLURAL:$5|$5 не отправлено|$5 не отправлены}}, {{PLURAL:$6|$6 отправлено|$6 отправлены}}.", @@ -194,7 +198,7 @@ "notification-header-user-rights-remove-only": "{{GENDER:$4|Ваши}} права пользователя были {{GENDER:$1|изменены}}. Вы больше не входите в группу: $2.", "notification-header-user-rights-add-and-remove": "{{GENDER:$6|Ваши}} права участника были {{GENDER:$1|изменены}}. Вы были добавлены в: $2. Вы больше не входите в: $4.", "notification-header-user-rights-expiry-change": "Время истечения {{GENDER:$4|вашего}} членства в {{PLURAL:$3|следующей группе|следующих группах}} {{GENDER:$1|изменено}}: $2.", - "notification-header-welcome": "{{GENDER:$2|Добро пожаловать}} на сайт {{SITENAME}}, $1! Мы рады приветствовать {{GENDER:$2|вас}} здесь.", + "notification-header-welcome": "{{GENDER:$2|Добро пожаловать}} на сайт {{SITENAME}}, $1! Рады {{GENDER:$2|вас}} здесь видеть.", "notification-header-mention-summary": "$1 упомянул{{GENDER:$2||а}} {{GENDER:$3|вас}} в описании <strong>$4</strong>.", "notification-header-watchlist-changed": "$1 {{GENDER:$2|изменил|изменила}} <strong>$3</strong>, страницу из {{GENDER:$4|вашего}} списка наблюдени{{PLURAL:$5|й $5 раз|й $5 раза|й $5 раз|1=}}.", "notification-header-watchlist-created": "$1 {{GENDER:$2|создал|создала}} <strong>$3</strong>, страницу из {{GENDER:$4|вашего}} списка наблюдени{{PLURAL:$5|й $5 раз|й $5 раза|й $5 раз|1=}}.", @@ -206,6 +210,7 @@ "notification-header-watchlist-multiuser-deleted": "<strong>$1</strong>, страница из {{GENDER:$2|вашего}} списка наблюдения, была удалена {{PLURAL:$3|$3 раз|$3 раза|$3 раз}}.", "notification-header-watchlist-multiuser-moved": "<strong>$1</strong>, страница из {{GENDER:$2|вашего}} списка наблюдения, была переименована {{PLURAL:$3|$3 раз|$3 раза|$3 раз}}.", "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>, страница из {{GENDER:$2|вашего}} списка наблюдения, была восстановлена {{PLURAL:$3|$3 раз|$3 раза|$3 раз}}.", + "notification-body-watchlist-once": "Уведомлений по электронной почте по поводу дальнейшей активности больше не будет, если только вы не {{GENDER:$1|посетите}} эту страницу, будучи авторизованным на сайте.", "notification-welcome-linktext": "Добро пожаловать!", "notification-header-thank-you-1-edit": "{{GENDER:$2|Вы}} только что сделали {{GENDER:$2|вашу}} первую правку. Благодарим {{GENDER:$2|вас}} за это, и добро пожаловать!", "notification-header-thank-you-10-edit": "{{GENDER:$2|Вы}} только что сделали {{GENDER:$2|вашу}} десятую правку. Благодарим {{GENDER:$2|вас}} за это, продолжайте в том же духе!", @@ -261,5 +266,10 @@ "echo-email-batch-link-text-view-all-notifications": "Посмотреть все уведомления", "notification-header-foreign-alert": "Больше уведомлений из {{PLURAL:$5|другой вики|$5 других вики}}", "notification-header-foreign-notice": "Больше уведомлений из {{PLURAL:$5|другой вики|$5 других вики}}", - "notification-header-foreign-all": "Больше уведомлений из {{PLURAL:$5|другой вики|$5 других вики}}" + "notification-header-foreign-all": "Больше уведомлений из {{PLURAL:$5|другой вики|$5 других вики}}", + "right-manage-all-push-subscriptions": "Управление всеми подписками push-уведомлений", + "action-manage-all-push-subscriptions": "управление всеми подписками push-уведомлений", + "group-push-subscription-manager": "Управляющие подписками push-уведомлений", + "group-push-subscription-manager-member": "{{GENDER:$1|управляющий подписками push-уведомлений|управляющая подписками push-уведомлений}}", + "grouppage-push-subscription-manager": "{{ns:project}}:Управляющие подписками push-уведомлений" } diff --git a/Echo/i18n/rue.json b/Echo/i18n/rue.json deleted file mode 100644 index 43cb98aa..00000000 --- a/Echo/i18n/rue.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "@metadata": { - "authors": [ - "Dicto23456" - ] - } -} diff --git a/Echo/i18n/sat.json b/Echo/i18n/sat.json index 56cb7ce1..7a57f5ba 100644 --- a/Echo/i18n/sat.json +++ b/Echo/i18n/sat.json @@ -4,7 +4,8 @@ "Albinus", "Fagunkoyel Hansdah", "Manik Soren", - "Ramjit Tudu" + "Ramjit Tudu", + "ᱥᱟᱹᱜᱩᱱ ᱗" ] }, "echo-pref-web": "ᱣᱮᱵᱽ", @@ -13,7 +14,18 @@ "tooltip-pt-notifications-alert": "{{GENDER:|ᱟᱢᱟᱜ}} ᱵᱟᱰᱟᱭᱡᱚᱝ", "tooltip-pt-notifications-notice": "{{GENDER:|ᱟᱢᱟᱜ}} ᱧᱮᱛᱮᱞᱠᱚ", "notification-link-text-expand-notice-count": "ᱧᱮᱞᱢᱮ {{PLURAL:$1|$1 ᱧᱮᱛᱮᱞ|$1 ᱧᱮᱛᱮᱞᱠᱚ}}", + "notification-link-text-view-message": "ᱠᱷᱚᱵᱚᱨ ᱧᱮᱞᱢᱮ", + "notification-link-text-view-page": "ᱥᱟᱦᱴᱟ ᱧᱮᱞᱢᱮ", + "notification-welcome-linktext": "ᱥᱟᱹᱜᱩᱱ ᱫᱟᱨᱟᱢ", + "notification-link-text-view-edit": "ᱟᱹᱨᱩ ᱧᱮᱞ", + "notification-link-article-reminder": "ᱥᱟᱦᱴᱟ ᱧᱮᱞ", + "notification-timestamp-today": "ᱛᱤᱦᱤᱧ", + "notification-timestamp-yesterday": "ᱦᱚᱞᱟ", + "notification-inbox-filter-read": "ᱯᱟᱲᱦᱟᱣᱢᱮ", + "notification-inbox-filter-all": "ᱥᱟᱱᱟᱢ", "echo-notification-notice": "{{PLURAL:$1|ᱧᱮᱛᱮᱞ ($1)|ᱧᱮᱛᱮᱞᱠᱚ ($1)|100=ᱧᱮᱛᱮᱞᱠᱚ (᱙᱙+)}}", "echo-notification-notice-text-only": "ᱧᱮᱛᱮᱞᱠᱚ", + "echo-date-today": "ᱛᱤᱦᱤᱧ", + "echo-date-yesterday": "ᱦᱚᱞᱟ", "notification-header-foreign-notice": "{{PLURAL:$5|ᱟᱨᱢᱤᱫ ᱣᱤᱠᱤ|$5 ᱮᱴᱟᱜ ᱣᱤᱠᱤ ᱠᱚᱨᱮ}} ᱠᱷᱚᱱ ᱵᱟᱹᱲᱛᱤ ᱧᱮᱛᱮᱞᱠᱚ" } diff --git a/Echo/i18n/sc.json b/Echo/i18n/sc.json new file mode 100644 index 00000000..c51bcf43 --- /dev/null +++ b/Echo/i18n/sc.json @@ -0,0 +1,17 @@ +{ + "@metadata": { + "authors": [ + "L2212" + ] + }, + "echo-desc": "Sistema pro notificare a sos impitadores subra de eventos e messàgios", + "prefs-echo": "Notìficas", + "prefs-echosubscriptions": "Notìfica·mi subra de custos eventos", + "prefs-echocrosswiki": "Notìficas inter-wiki", + "prefs-blocknotificationslist": "Impitadores postos a sa muda", + "notification-timestamp-today": "Oe", + "notification-timestamp-yesterday": "Eris", + "notification-inbox-filter-read": "Lèghidas", + "notification-inbox-filter-unread": "Non lèghidas", + "notification-inbox-filter-all": "Totus" +} diff --git a/Echo/i18n/scn.json b/Echo/i18n/scn.json index 6afd882b..bb8a08fc 100644 --- a/Echo/i18n/scn.json +++ b/Echo/i18n/scn.json @@ -1,6 +1,7 @@ { "@metadata": { "authors": [ + "Ajeje Brazorf", "Gmelfi", "Pippinu", "Sarvaturi" @@ -23,31 +24,50 @@ "echo-pref-email-format-plain-text": "Testu nurmali", "echo-learn-more": "Pi sapìrinni cchiossai", "echo-new-messages": "Vossìa havi missaggi novi", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Missaggiu|Missaggi}} supra la pàggina di discussioni", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Canciamentu|Canciamenti}} supra la mè pàggina di discussioni", "echo-category-title-article-linked": "{{PLURAL:$1|Liami|Liama}} a na pàggina", "echo-category-title-reverted": "{{PLURAL:$1|Canciamentu annullatu|Canciamenti annullati}}", "echo-category-title-mention": "{{PLURAL:$1|Minzioni}}", "echo-category-title-other": "{{PLURAL:$1|Àutru}}", "echo-category-title-system": "{{PLURAL:$1|Sistema}}", - "echo-pref-tooltip-edit-user-talk": "Abbìsami quannu quarcunu mi scrivi nu missaggiu o arrispunni ntâ mè pàggina di discussioni.", + "echo-category-title-system-noemail": "{{PLURAL:$1|Sistema}}", + "echo-category-title-system-emailonly": "{{PLURAL:$1|Sistema}}", + "echo-category-title-watchlist": "Canciamentu a na pàggina taliata", + "echo-category-title-minor-watchlist": "Canciamentu nicu a na pàggina taliata", + "echo-pref-tooltip-edit-user-talk": "Abbìsami quannu quarcunu cancia la mè pàggina di discussioni.", "echo-pref-tooltip-article-linked": "Abbìsami quannu quarcunu cullèga, di na vuci, na pàggina ca criai.", "echo-pref-tooltip-reverted": "Abbìsami quannu quarcunu annulla nu canciamentu ca fici, usannu li funzioni annulla o rollback.", "echo-pref-tooltip-mention": "Avvìsami quannu quarchidunu crea un culligamentu â mè pàggina d'utenti.", "notifications": "Nutìfichi", "tooltip-pt-notifications-alert": "Li {{GENDER:|tò}} avvisi", + "tooltip-pt-notifications-notice": "Li {{GENDER:|tò}} avvisi", + "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "Utenti novi", "echo-specialpage": "Nutìfichi", "echo-none": "Nun arricivistru nutìfichi", "notification-link-text-view-message": "Talìa lu missaggiu", "notification-link-text-view-mention": "Talìa la minzioni", "notification-link-text-view-changes": "Talìa li canciamenti", "notification-link-text-view-page": "Talìa la pàggina", + "notification-compact-header-mention-failure-user-unknown": "<strong>Lu nomu utenti nun esisti:</strong> $1", + "notification-welcome-linktext": "Bimminutu", + "notification-link-thank-you-edit": "Lu {{GENDER:$1|tò}} canciamentu", "notification-link-text-view-edit": "Talìa lu canciamentu", - "notification-header-reverted": "{{PLURAL:$4|Lu tò canciamentu|Li tò canciamenti}} supra $3 {{PLURAL:$4|fu annullatu|foru annullati}} {{GENDER:$2|di}} $1", + "notification-link-article-reminder": "Talìa la pàggina", + "notification-header-reverted": "{{PLURAL:$4|Lu tò canciamentu|Li tò canciamenti}} supra <strong>$3</strong> {{PLURAL:$2|fu annullatu|foru annullati}}.", "notification-edit-talk-page-email-subject2": "$1 ti {{GENDER:$2|lassau}} nu missaggiu n {{SITENAME}}", "notification-page-linked-email-subject": "Na pàggina chi criasti fu liata nta {{SITENAME}}", "notification-reverted-email-subject2": "{{PLURAL:$4|Lu tò canciamentu fu annullatu|Li tò canciamenti foru annullati}} {{GENDER:$2|supra}} {{SITENAME}}", "notification-mention-email-subject": "$1 ti {{GENDER:$2|mintuviau}} supra {{SITENAME}}", "notification-user-rights-email-subject": "Li tò diritti utenti foru canciati supra {{SITENAME}}", + "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1 s}}", + "notification-timestamp-ago-minutes": "$1 {{PLURAL:$1|min}}", + "notification-timestamp-ago-hours": "$1 {{PLURAL:$1|ura|uri}}", + "notification-timestamp-ago-days": "$1 {{PLURAL:$1|j|jj}}", + "notification-timestamp-ago-months": "$1 {{PLURAL:$1|misi}}", + "notification-timestamp-ago-years": "$1 {{PLURAL:$1|annu|anni}}", + "notification-timestamp-today": "Oi", + "notification-timestamp-yesterday": "Aieri", + "notification-inbox-filter-all": "Tutti", "echo-overlay-link": "Tutti li nutìfichi", "echo-overlay-title": "<b>Nutìfichi</b>", "echo-mark-all-as-read": "Sinna tutti comu ligghiuti", diff --git a/Echo/i18n/sco.json b/Echo/i18n/sco.json index b258fe0e..b7fd05bf 100644 --- a/Echo/i18n/sco.json +++ b/Echo/i18n/sco.json @@ -1,9 +1,11 @@ { "@metadata": { "authors": [ - "AmaryllisGardener" + "AmaryllisGardener", + "MJL" ] }, "tooltip-pt-notifications-alert": "{{GENDER:|Yer}} alerts", - "echo-specialpage-pagefilters-subtitle": "Pages wi unread notifications" + "echo-specialpage-pagefilters-subtitle": "Pages wi unread notifications", + "notification-header-thank-you-1-edit": "{{GENDER:$2|Ye'v}} juist duin {{GENDER:$2|yer}} first edit; cheers, an walcome!" } diff --git a/Echo/i18n/sd.json b/Echo/i18n/sd.json index 9ab1148e..62da2497 100644 --- a/Echo/i18n/sd.json +++ b/Echo/i18n/sd.json @@ -9,103 +9,156 @@ }, "echo-desc": "واپرائيندڙن کي واقعن ۽ پيغامن جو اطلاع ڏيڻ لاءِ سرشتو", "prefs-echo": "اطلاع", - "prefs-emailsettings": "برقٽپال چارا", + "prefs-emailsettings": "ايميل چارا", "prefs-echosubscriptions": "مونکي ھنن واقعن بابت اطلاع ڏيو", "prefs-echocrosswiki": "بين-الوڪي اطلاع", "prefs-blocknotificationslist": "بند واپرائيندڙ", + "prefs-mutedpageslist": "صفحن جي ڳنڍڻن جي اطلاعن لاءِ روڪيل صفحا", + "prefs-echopollupdates": "سڌاسنوان اطلاع", + "echo-mobile-notifications-filter-title": "اطلاع ڇاڻيو", "echo-pref-send-me": "مون ڏي موڪليو:", "echo-pref-send-to": "ڏانھن موڪليو:", - "echo-pref-email-format": "برقٽپال حليو:", + "echo-pref-email-format": "ايميل فارميٽ:", "echo-pref-web": "ويب", - "echo-pref-email": "برقٽپال", - "echo-pref-email-frequency-never": "مونکي اطلاع برقٽپال تي نہ موڪليو", + "echo-pref-email": "ايميل", + "echo-pref-push": "ايپس", + "echo-pref-email-frequency-never": "مون ڏانھن ڪي بہ ايميل اطلاع نہ موڪليو", "echo-pref-email-frequency-immediately": "جيئن ئي اچن، الڳ الڳ موڪليو", - "echo-pref-email-frequency-daily": "هر روز اطلاعن جو تت موڪليو", - "echo-pref-email-frequency-weekly": "هر هفتي اطلاعن جو تت موڪليو", - "echo-pref-email-format-html": "ايڇ ٽي ايم ايل", - "echo-pref-email-format-plain-text": "سادا اکر", - "echo-pref-cross-wiki-notifications": "ٻين وڪيز جا اطلاع ڏيکاريو", - "echo-pref-notifications-blacklist": "هنن واپرائيندڙ جا اطلاع نه ڏيو. ([[mw:Special:MyLanguage/Help:Notifications#mute|وڌيڪ معلومات]])", - "echo-learn-more": "وڌيڪ ڄاڻو", - "echo-new-messages": "توھان لاءِ نوان نياپا آھن", - "echo-category-title-edit-user-talk": "بحث صفحي {{PLURAL:$1|جو پيغام|جا پيغام}}", - "echo-category-title-article-linked": "صفحو {{PLURAL:$1|ڳنڍڻو|ڳنڍڻا}}", - "echo-category-title-reverted": "سنوار {{PLURAL:$1|اڻڪريل|اڻڪئي وئي}}", - "echo-category-title-mention": "{{PLURAL:$1|ذڪر|ياد}}", - "echo-category-title-mention-failure": "نامڪمل {{PLURAL:$1|ذڪر|ياد}}", - "echo-category-title-mention-success": "ڪامياب {{PLURAL:$1|ياد|يادگري}}", + "echo-pref-email-frequency-daily": "روزانو جي اطلاعن جو تَتُ", + "echo-pref-email-frequency-weekly": "ھفتيوار اطلاعن جو تَتُ", + "echo-pref-email-format-html": "ايڇ.ٽي.ايم.ايل", + "echo-pref-email-format-plain-text": "سادو متن", + "echo-pref-cross-wiki-notifications": "ٻين وڪين جا اطلاع ڏيکاريو", + "echo-pref-notifications-blacklist": "هنن واپرائيندڙ جا اطلاع نہ ڏيو. ([[mw:Special:MyLanguage/Help:Notifications#mute|وڌيڪ ڄاڻيو]])", + "echo-pref-notifications-page-linked-title-muted-list": "ھنن صفحن لاءِ \"صفحي ڳنڍڻي\" جا اطلاع نہ ڏيکاريو. ([[mw:Special:MyLanguage/Help:Notifications#mute|وڌيڪ ڄاڻيو]])", + "echo-learn-more": "وڌيڪ ڄاڻيو", + "echo-log": "عوامي لاگ", + "echo-new-messages": "توھان لاءِ بحث صفحي تي ھڪ نئون نياپا آھي", + "echo-category-title-edit-user-talk": "منھنجي بحث صفحي ۾ {{PLURAL:$1|سنوار|سنوارون}}", + "echo-category-title-article-linked": "صفحي {{PLURAL:$1|ڳنڍڻو|ڳنڍڻا}}", + "echo-category-title-reverted": "{{PLURAL:$1|سنوار موٽائي|سنوارون موٽايون}}", + "echo-category-title-mention": "{{PLURAL:$1|ذڪر|ذڪرَ}}", + "echo-category-title-mention-failure": "نامڪمل {{PLURAL:$1|ذڪر|ذڪرَ}}", + "echo-category-title-mention-success": "ڪامياب {{PLURAL:$1|ذڪر|ذڪرَ}}", "echo-category-title-other": "{{PLURAL:$1|ٻي}}", - "echo-category-title-system": "{{PLURAL:$1|سسٽم}}", + "echo-category-title-system": "{{PLURAL:$1|سرشتو}}", "echo-category-title-system-noemail": "{{PLURAL:$1|سرشتو}}", "echo-category-title-system-emailonly": "{{PLURAL:$1|سرشتو}}", - "echo-category-title-user-rights": "{{PLURAL:$1|واپرائيندڙ حق ۾ تبديليون|واپرائيندڙ حقن ۾ تبديلون}}", - "echo-category-title-emailuser": "{{PLURAL:$1|ٻي واپرائيندڙ وٽان برقٽپال|ٻين واپرائيندڙ طرفان برقٽپالون}}", - "echo-category-title-article-reminder": "صفحو {{PLURAL:$1|يادگير|ياگيريون}}", + "echo-category-title-user-rights": "{{PLURAL:$1|واپرائيندڙ حقن ۾ بدلاء}}", + "echo-category-title-emailuser": "{{PLURAL:$1|ٻي واپرائيندڙ وٽان ايميل|ٻين واپرائيندڙ طرفان ايميلون}}", + "echo-category-title-article-reminder": "صفحي {{PLURAL:$1|يادگيري|يادگيريون}}", "echo-category-title-thank-you-edit": "{{PLURAL:$1|سنگ-ميل|سنگ-ميلَ}} سنواريو", - "echo-pref-tooltip-edit-user-talk": "مونکي اطلاع ڏيو، جڏهن ڪير منھنجي بحث صفحي تي پيغام ڇڏي يا جواب ڏي.", + "echo-category-title-watchlist": "نظر۾رکيل صفحي ۾ سنوار", + "echo-category-title-minor-watchlist": "نظر۾رکيل صفحي ۾ معمولي سنوار", + "echo-pref-tooltip-edit-user-talk": "مونکي اطلاع ڏيو، جڏهن ڪير منھنجي بحث صفحي کي سنواري.", "echo-pref-tooltip-article-linked": "مونکي اطلاع ڏيو، جڏهن ڪير ان صفحي سان ڳنڍڻو جوڙي جيڪو مون ٻي صفحي تان جوڙيو آهي.", - "echo-pref-tooltip-reverted": "مونکي اطلاع ڏيو، جڏهن منھنجي ڪيل سنوار کي اڻڪريو يا واپس-ورايو اوزار سان واپس ڪيو وڃي.", + "echo-pref-tooltip-reverted": "مونکي اطلاع ڏيو، جڏهن منھنجي ڪيل سنوار کي ختم يا واپس-ورايو اوزار سان واپس ڪيو وڃي.", "echo-pref-tooltip-mention": "مونکي اطلاع ڏيو جڏهن ڪير منھنجي واپرائيندڙ صفحي سان ڳنڍڻو جوڙي.", + "echo-pref-tooltip-mention-failure": "جڏھن مان ڪنھن کي مينشن نہ موڪلي سگهان تہ مون کي اطلاع ڏيو.", + "echo-pref-tooltip-mention-success": "جڏھن مان ڪنھن کي مينشن ڪيان تہ مون کي اطلاع ڏيو.", "echo-pref-tooltip-user-rights": "مونکي اطلاع ڏيو جڏهن ڪو منھنجا واپرائيندڙ حق بدلائي.", - "echo-pref-tooltip-emailuser": "مونکي اطلاع ڏيو جڏهن ڪير مونکي برقٽپال موڪلي.", - "echo-pref-tooltip-article-reminder": "جڏهن هن صفحي بابت آئون پڇان ته مونکي اطلاع ڏيو.", + "echo-pref-tooltip-emailuser": "مونکي اطلاع ڏيو جڏهن ڪير مونکي ايميل موڪلي.", + "echo-pref-tooltip-article-reminder": "هن صفحي بابت جڏهن آئون پڇان تہ مونکي اطلاع ڏيو.", + "echo-pref-tooltip-thank-you-edit": "جڏھن مان 1ئين، 10ھين، 100ئين... سنوار ڪيان تہ مون کي اطلاع ڏيو.", + "echo-pref-tooltip-watchlist": "جڏھن منھنجي نظر۾فھرست ۾ رکيل صفحي ۾ (غير معمولي) سنوار ڪري تہ مون کي اطلاع ڏيو.", + "echo-pref-tooltip-minor-watchlist": "جڏھن منھنجي نظر۾فھرست رکيل صفحي ۾ معمولي سنوار ڪري تہ مقن کي اطلاع ڏيو.", "notifications": "اطلاع", "tooltip-pt-notifications-alert": "{{GENDER:|توهانجون}} خبرون", "tooltip-pt-notifications-notice": "{{GENDER:|توھان جا}} اطلاع", "echo-displaynotificationsconfiguration-notifications-by-category-header": "اطلاع بلحاظ زمرو", - "echo-displaynotificationsconfiguration-sorting-by-section-header": "تربيت جا قسم", - "echo-displaynotificationsconfiguration-enabled-default-header": "شروع کان ڪارگر آهي", - "echo-displaynotificationsconfiguration-enabled-default-existing-users-legend": "موجوده واپرائيندڙ", - "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "نئون واپرائيندڙ", + "echo-displaynotificationsconfiguration-sorting-by-section-header": "قسمن کي مرتب ڪرڻ", + "echo-displaynotificationsconfiguration-available-notification-methods-header": "اطلاع جا اجازت ڏنل طريقا", + "echo-displaynotificationsconfiguration-available-notification-methods-by-category-legend": "ھر زمري لاءِ اطلاع جا ڪھڙا طريقا سپورٽ ڪيل آھن", + "echo-displaynotificationsconfiguration-enabled-default-header": "پاڻمرادو ئي ڪارگر ڪيل آھي", + "echo-displaynotificationsconfiguration-enabled-default-existing-users-legend": "موجوده واپرائيندڙَ", + "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "نوان واپرائيندڙَ", + "echo-displaynotificationsconfiguration-mandatory-notification-methods-header": "گهربل اطلاع جا طريقا", + "echo-displaynotificationsconfiguration-mandatory-notification-methods-by-category-legend": "ھر زمري لاءِ اطلاع جا ڪھڙا طريقا لازمي آھن", "echo-specialpage": "اطلاع", "echo-specialpage-section-markread": "گروھ کي پڙھيل طور نشان لڳايو", "echo-specialpage-markasread": "اطلاع:پڙھيل طور نشان لڳايو", - "echo-specialpage-pagefilters-title": "تازي سرگرمي", + "echo-specialpage-markasread-invalid-id": "موقعي جي ناقابلِڪار آئڊي", + "echo-specialpage-pagefilterwidget-aria-label": "وڪي ۽ صفحي جي عنوان سان ڇاڻيو", + "echo-specialpage-special-help-menu-widget-aria-label": "واڌو چارا ۽ اطلاعن جو ترجيحون.", + "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|اطلاع|اطلاعَ}}", + "echo-specialpage-pagefilters-title": "ھاڻوڪي سرگرمي", + "echo-specialpage-pagefilters-subtitle": "نہ-پڙھيل اطلاعن وارا صفحا", "notificationsmarkread-legend": "اطلاع کي پڙھيل طور نشان لڳايو", - "echo-none": "اوهان لاءِ ڪي به اطلاع ناهن.", + "echo-none": "اوهان لاءِ ڪي بہ اطلاع ناهن.", + "echo-api-failure": "اطلاع حاصل ڪرڻ ۾ ناڪام.", "echo-notification-placeholder": "ڪي بہ اطلاع ناھن.", - "echo-notification-loginrequired": "اطلاع ڏسڻ لاءِ داخل ٿيو.", + "echo-notification-placeholder-filters": "ھن ڪسوٽيءَ تي ڪي بہ اطلاع نٿا ملن.", + "echo-notification-loginrequired": "پنھنجا اطلاع ڏسڻ لاءِ توھان کي لازماً داخل ٿيڻو پوندو.", "echo-notification-popup-loginrequired": "پنھنجي اطلاعن کي ڏسڻ لاءِ داخل ٿيو.", "echo-notification-markasread": "پڙھيل طور نشان لڳايو", - "echo-notification-markasunread": "نه-پڙھيل طور نشان لڳايو", + "echo-notification-markasunread": "نہ-پڙھيل طور نشان لڳايو", "echo-notification-markasread-tooltip": "پڙھيل طور نشان لڳايو", - "echo-notification-more-options-tooltip": "وڌيڪ عمل", + "echo-notification-more-options-tooltip": "وڌيڪ چارا", + "notification-dynamic-actions-unwatch": "\"$1\" تي نين سرگرميءَ کي نظر۾رکڻ {{GENDER:$3|بند ڪريو}}", + "notification-dynamic-actions-unwatch-confirmation": "صفحو \"$1\" ھاڻي وڌيڪ {{GENDER:$3|توھان}} جي نظر۾رکيل نہ آھي", + "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|توھان}} [$2 ھن صفحي] کي ڪنھن بہ وقت نظر۾رکي سگهو ٿا.", + "notification-dynamic-actions-watch": "\"$1\" تي نئين سرگرميءَ جي {{GENDER:$3|پيروي ڪريو}}", + "notification-dynamic-actions-watch-confirmation": "{{GENDER:$3|توھان}} صفحي \"$1\" کي نظر۾رکيو ويٺا آھيو", + "notification-dynamic-actions-watch-confirmation-description": "{{GENDER:$3|توھان}} ڪنھن بہ وقت [$2 ھن صفحي] کي نظر مان ڪڍي سگهو ٿا.", "notification-link-text-expand-all": "کوليو", "notification-link-text-expand-notice-count": "{{PLURAL:$1|$1 اطلاع|$1 اطلاعَ}} ڏسو", + "notification-link-text-expand-all-count": "{{PLURAL:$1|اطلاع|اطلاعَ}} ڏسو", "notification-link-text-collapse-all": "بند ڪريو", - "notification-link-text-view-message": "پيغام ڏسو", + "notification-link-text-view-message": "نياپو ڏسو", + "notification-link-text-view-mention": "مينشن ڏسو", + "notification-link-text-view-mention-failure": "{{PLURAL:$1|مينشن ڏسو|مينشنس ڏسو}}", "notification-link-text-view-changes": "تبديليون {{GENDER:$1|ڏيکاريو}}", "notification-link-text-view-page": "صفحو ڏسو", - "notification-header-edit-user-talk": "$1 <strong>{{GENDER:$3|توھان جي}} بحث صفحي</strong> تي ھڪ پيغام {{GENDER:$2|ڇڏيو}}.", - "notification-header-edit-user-talk-with-section": "$1 <strong>{{GENDER:$3|توھان جي}} بحث صفحي</strong> تي ھڪ پيغام \"<strong>$4</strong>\" ۾ {{GENDER:$2|ڇڏيو}}.", + "notification-header-edit-user-talk": "$1 <strong>{{GENDER:$3|توھان جي}} بحث صفحي</strong> تي ھڪ نياپو {{GENDER:$2|ڇڏيو}}.", + "notification-header-edit-user-talk-with-section": "$1 <strong>{{GENDER:$3|توھان جي}} بحث صفحي</strong> تي ھڪ نياپو \"<strong>$4</strong>\" ۾ {{GENDER:$2|ڇڏيو}}.", + "notification-compact-header-edit-user-talk": "$1 {{GENDER:$3|توھان}} لاءِ ھڪ نياپو {{GENDER:$2|ڇڏيو}}.", + "notification-compact-header-edit-user-talk-with-section": "$1 {{GENDER:$3|توھان}} لاءِ \"<strong>$4</strong>\" ۾ ھڪ نياپو {{GENDER:$2|ڇڏيو}} آھي.", "notification-body-edit-user-talk-with-section": "$1", "notification-header-page-linked": "<strong>$4</strong> کان ھڪ ڳنڍڻو <strong>$3</strong> ڏانھن ٺاھيو ويو.", - "notification-compact-header-page-linked": "<strong>$1</strong> تان ڳنڍڻو.", + "notification-compact-header-page-linked": "<strong>$1</strong> تان ڳنڍيل.", + "notification-bundle-header-page-linked": "{{PLURAL:$5|$5 صفحن|100=99+ صفحن}} کان <strong>$3</strong> ڏانھن ڳنڍڻا ٺاھيا ويا.", "notification-link-text-what-links-here": "ھن صفحي ڏانھن سڀ ڳنڍڻا", + "notification-header-mention-other": "$1 {{GENDER:$3|توھان کي}} <strong>$4</strong> تي \"<strong>$5</strong>\" ۾ {{GENDER:$2|مينشن ڪيو}}.", + "notification-header-mention-other-nosection": "$1 {{GENDER:$3|توھان کي}} <strong>$4</strong> تي {{GENDER:$2|مينشن ڪيو}}.", "notification-header-mention-article-talkpage-nosection": "$1 {{GENDER:$3|توھان کي}} <strong>$4</strong> بحث صفحي تي {{GENDER:$2|بيان ڪيو}}.", - "notification-compact-header-mention-failure-user-unknown": "<strong>واپرائيندڙ نانءُ نه لڌو:</strong> $1", - "notification-compact-header-mention-failure-user-anonymous": "<strong>آئي پي پتا ڄاڻيل ناهن:</strong> $1", + "notification-compact-header-mention-failure-user-unknown": "<strong>واپرائيندڙنانءُ وجود نٿو رکي:</strong> $1", + "notification-compact-header-mention-failure-user-anonymous": "<strong>آئپي پتن جو ذڪر نٿو ڪري سگهجي:</strong> $1", + "notification-header-mention-success": "<strong>$3</strong> وارو {{GENDER:$2|توھان جو}} موڪليو ويو.", + "notification-compact-header-mention-success": "<strong>{{GENDER:$2|توھان مينشن ڪيو}}:</strong> $3", "notification-welcome-linktext": "ڀليڪار", - "notification-header-thank-you-10000-edit": "{{GENDER:$2|توھان}} {{GENDER:$2|پنهنجون}} ڏھ هزار تبديليون مڪمل ڪري ڇڏيون آھن. هن تعاون جي تمام گهڻي مهرباني!", + "notification-header-thank-you-10000-edit": "{{GENDER:$2|توھان}} ھاڻي ھاڻي {{GENDER:$2|پنھنجي}} ڏھين هزاري تبديلي ڪئي؛ {{GENDER:$2|توھان}} جي تمام گهڻي مھرباني!", "notification-link-thank-you-edit": "{{GENDER:$1|توهان جي}} سنوار", "notification-link-text-view-edit": "سنوار ڏسو", "notification-link-article-reminder": "صفحو ڏسو", - "notification-body-reverted": "$1", - "notification-header-emailuser": "$1 توھان ڏانھن ھڪ برقٽپال {{GENDER:$2|موڪلي}}.", + "notification-header-emailuser": "$1 توھان ڏانھن ھڪ ايميل {{GENDER:$2|موڪلي}}.", + "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$3|توھان لاءِ}} {{SITENAME}} تي ھڪ نياپو {{GENDER:$2|ڇڏيو}}", + "notification-mention-email-subject": "$1 {{GENDER:$3|توھان کي}} {{SITENAME}} تي {{GENDER:$2|مينشن ڪيو}}", + "notification-user-rights-email-subject": "{{GENDER:$3|توھان جا}} حق بطور واپرائيندڙ {{SITENAME}} تي بدلجي چڪا آھن", + "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1s}}", + "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1m}}", + "notification-timestamp-ago-hours": "{{PLURAL:$1|$1h}}", + "notification-timestamp-ago-days": "{{PLURAL:$1|$1d}}", + "notification-timestamp-ago-months": "{{PLURAL:$1|$1mo}}", + "notification-timestamp-ago-years": "{{PLURAL:$1|$1yr}}", "notification-timestamp-today": "اڄ", - "notification-timestamp-yesterday": "ڪلھ", + "notification-timestamp-yesterday": "ڪالھ", "notification-inbox-filter-read": "پڙھيل", "notification-inbox-filter-unread": "اڻپڙھيل", "notification-inbox-filter-all": "سڀ", + "echo-specialmute-label-mute-notifications": "ھن {{GENDER:$1|واپرائيندڙ}} پاران اطلاع مِيُوٽِ ڪريو", + "echo-email-html-footer-preference-link-text": "{{GENDER:$1|پنھنجون}} ترجيحون چڪاسيو", "echo-notification-alert-text-only": "پيغام", "echo-notification-notice-text-only": "اطلاع", "echo-overlay-link": "سڀ اطلاع", - "echo-overlay-title": "<b>اطلاع</b>", + "echo-overlay-title": "<b>اطلاعَ</b>", "echo-mark-all-as-read": "سڀ پڙھيل طور نشان لڳايو", + "echo-mark-all-as-read-confirmation": "$1 {{PLURAL:$1|اطلاع|اطلاعن}} کي پڙھيل طور نشان لڳايو ويو", + "echo-displaysnippet-title": "نوان اطلاع", "echo-date-today": "اڄ", - "echo-date-yesterday": "ڪلھ", + "echo-date-yesterday": "ڪالھ", "echo-email-batch-bullet": "•", - "echo-email-batch-link-text-view-all-notifications": "سڀ اطلاع ڏسو", + "echo-email-batch-link-text-view-all-notifications": "سڀ اطلاعَ ڏسو", + "notification-header-foreign-notice": "وڌيڪ {{PLURAL:$5|ھڪ وکي|$5 ٻين کان}} اطلاع", "echo-foreign-wiki-lang": "$1 - $2", - "echo-badge-count": "{{PLURAL:$1|$1|100=99+}}" + "echo-badge-count": "{{PLURAL:$1|$1|100={{formatnum:99}}+}}" } diff --git a/Echo/i18n/sdc.json b/Echo/i18n/sdc.json index 503f18aa..15e5e7d5 100644 --- a/Echo/i18n/sdc.json +++ b/Echo/i18n/sdc.json @@ -1,8 +1,27 @@ { "@metadata": { "authors": [ + "F Samaritani", "Jun Misugi" ] }, - "tooltip-pt-notifications-alert": "{{GENDER:|Li tó}} avvisi" + "prefs-emailsettings": "Isciùbari e-postha", + "echo-mobile-notifications-filter-title": "Modìfica di filthru", + "echo-pref-web": "Web", + "echo-pref-email": "Indirizzu di postha erettrònica", + "echo-pref-push": "App", + "echo-pref-email-format-html": "HTML", + "echo-pref-email-format-plain-text": "Testhu noimmali", + "echo-category-title-article-linked": "Pàgina {{PLURAL:$1|cullegamentu|cullegamenti}}", + "tooltip-pt-notifications-alert": "{{GENDER:|Li tó}} avvisi", + "tooltip-pt-notifications-notice": "{{GENDER:|Li tó}} avvisi", + "notification-link-text-expand-all": "Ammusthrà", + "notification-link-text-collapse-all": "Cuà", + "notification-link-text-view-message": "Viddi imbasciaddi", + "notification-link-text-view-page": "Viddi pàgina", + "notification-link-article-reminder": "Viddi pàgina", + "notification-timestamp-today": "Oggi", + "notification-inbox-filter-read": "Liggì", + "notification-inbox-filter-all": "Tutti", + "echo-date-today": "Oggi" } diff --git a/Echo/i18n/se.json b/Echo/i18n/se.json new file mode 100644 index 00000000..87c6d46f --- /dev/null +++ b/Echo/i18n/se.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Yupik" + ] + }, + "notification-link-text-expand-all": "Čájet", + "notification-inbox-filter-all": "Buot" +} diff --git a/Echo/i18n/sh.json b/Echo/i18n/sh.json index d62d6e91..bb334194 100644 --- a/Echo/i18n/sh.json +++ b/Echo/i18n/sh.json @@ -13,6 +13,7 @@ "prefs-echocrosswiki": "Obavještenja s drugih wikija", "prefs-blocknotificationslist": "Ignorisani korisnici", "prefs-echopollupdates": "Obavještenja uživo", + "echo-mobile-notifications-filter-title": "Filtriraj obavijesti", "echo-pref-show-poll-updates": "Prikazuje nova obavještenja čim stignu", "echo-pref-show-poll-updates-help": "Prikaži broj nepročitanih obavijesti u naslovnoj traci, kao i izvadak svake obavijesti čim stigne.", "echo-pref-send-me": "Pošalji mi:", @@ -20,6 +21,7 @@ "echo-pref-email-format": "Format e-pošte:", "echo-pref-web": "Web", "echo-pref-email": "E-pošta", + "echo-pref-push": "Prilozi", "echo-pref-email-frequency-never": "Ne šalji mi obavještenja preko e-pošte", "echo-pref-email-frequency-immediately": "Lična obavještenja kako dolaze u", "echo-pref-email-frequency-daily": "Dnevni sažetak obavještenja", @@ -28,10 +30,11 @@ "echo-pref-email-format-plain-text": "Obični tekst", "echo-pref-cross-wiki-notifications": "Prikazivaj obavještenja s drugih wikija", "echo-pref-notifications-blacklist": "Ne prikazuj obavještenja ovih korisnika. ([[mw:Special:MyLanguage/Help:Notifications#mute|saznajte više]])", + "echo-pref-notifications-page-linked-title-muted-list": "Ne prikazuj obavijesti \"Link na stranicu\" za ove stranice. ([[mw:Special:MyLanguage/Help:Notifications#mute|saznaj više]])", "echo-learn-more": "Saznajte više", "echo-log": "Javna evidencija", - "echo-new-messages": "Imate nove poruke.", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Poruke}} na stranici za razgovor", + "echo-new-messages": "Imate nove poruke u stranici za razgovor", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Izmjena|Izmjene}} na mojoj stranici za razgovor", "echo-category-title-article-linked": "{{PLURAL:$1|Linkovi na stranicu}}", "echo-category-title-reverted": "{{PLURAL:$1|Vraćanje izmjena}}", "echo-category-title-mention": "{{PLURAL:$1|Spominjanje|Spominjanja}}", @@ -40,11 +43,14 @@ "echo-category-title-other": "{{PLURAL:$1|Ostalo}}", "echo-category-title-system": "{{PLURAL:$1|Sistem}}", "echo-category-title-system-noemail": "{{PLURAL:$1|Sistem}}", + "echo-category-title-system-emailonly": "{{PLURAL:$1|Sistem}}", "echo-category-title-user-rights": "{{PLURAL:$1|Promjena u korisničkim pravima|Promjene u korisničkim pravima}}", "echo-category-title-emailuser": "{{PLURAL:$1|E-pošta od drugog korisnika|E-pošta od drugih korisnika}}", "echo-category-title-article-reminder": "{{PLURAL:$1|Podsjetnik o stranici|Podsjetnici o stranicama}}", "echo-category-title-thank-you-edit": "{{PLURAL:$1|Miljokaz|Miljokazi}} uređivanja", - "echo-pref-tooltip-edit-user-talk": "Obavijesti me kada neko ostavi poruku ili odgovor na mojoj razgovornoj stranici.", + "echo-category-title-watchlist": "Uređivanje praćene stranice", + "echo-category-title-minor-watchlist": "Manje uređivanje praćene stranice", + "echo-pref-tooltip-edit-user-talk": "Obavijesti me kad netko napravi izmjenu na mojoj stranici za razgovor.", "echo-pref-tooltip-article-linked": "Obavijesti me kad netko pozove na stranicu što sam stvorio s druge stranice.", "echo-pref-tooltip-reverted": "Obavijesti me kada netko otkazati uređivanje što sam napravio/la pomoću alata za opoziv ili vraćanje.", "echo-pref-tooltip-mention": "Obavijesti me kad netko pozove na moju korisničku stranicu.", @@ -155,7 +161,7 @@ "notification-inbox-filter-read": "Pročitane", "notification-inbox-filter-unread": "Nepročitane", "notification-inbox-filter-all": "Sve", - "echo-specialmute-label-mute-notifications": "Isključi obavještenja od ovog korisnika", + "echo-specialmute-label-mute-notifications": "Isključi obavještenja od {{GENDER:$1|ovog korisnika|ove korisnice}}", "echo-email-plain-footer": "Da biste odabrali koje {{GENDER:$1|Vam}} e-poruke šaljemo, provjerite {{GENDER:$1|sebi}} postavke:", "echo-email-html-footer-preference-link-text": "provjerite {{GENDER:$1|svoje}} postavke", "echo-email-html-footer-with-link": "Da biste odabrali koje {{GENDER:$2|Vam}} e-poruke šaljemo, $1.", @@ -179,5 +185,10 @@ "echo-email-batch-link-text-view-all-notifications": "Vidi sve notifikacije", "notification-header-foreign-alert": "Više obavještenja {{PLURAL:$5|s druge wiki|sa $5 druga wikija|sa $5 drugih wikija}}", "notification-header-foreign-notice": "Još obavještenja {{PLURAL:$5|s drugog wikija|sa $5 druga wikija|sa $5 drugih wikija}}", - "notification-header-foreign-all": "Još obavještenja {{PLURAL:$5|s druge wiki|sa $5 druga wikija|sa $5 drugih wikija}}" + "notification-header-foreign-all": "Još obavještenja {{PLURAL:$5|s druge wiki|sa $5 druga wikija|sa $5 drugih wikija}}", + "right-manage-all-push-subscriptions": "Upravljanje svim push pretplatama", + "action-manage-all-push-subscriptions": "upravljanje svim push pretplatama", + "group-push-subscription-manager": "Upravitelji push pretplatama", + "group-push-subscription-manager-member": "{{GENDER:$1|upravitelj push pretplatama|upraviteljica push pretplatama}}", + "grouppage-push-subscription-manager": "{{ns:project}}:Upravitelji push pretplatama" } diff --git a/Echo/i18n/shi.json b/Echo/i18n/shi.json new file mode 100644 index 00000000..e1c9fe8a --- /dev/null +++ b/Echo/i18n/shi.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Ayour2002" + ] + }, + "tooltip-pt-notifications-alert": "Tuzinin {{GENDER:|nnk|nnm}}" +} diff --git a/Echo/i18n/shn.json b/Echo/i18n/shn.json index 50eb96ca..9f6b3375 100644 --- a/Echo/i18n/shn.json +++ b/Echo/i18n/shn.json @@ -7,5 +7,6 @@ }, "echo-pref-tooltip-user-rights": "သင်ၸိူဝ်ႉဝႃႈ သေၵေႃႉၵေႃႉ မႄးသုၼ်ႇလႆႈၽူႈၸႂ်ႉတိုဝ်းၵဝ်ၶႃႈၼႆ ပၼ်ၶေႃႈၽၢင်ႉသေၵမ်း။", "tooltip-pt-notifications-alert": "{{GENDER:|ၸဝ်ႈၵဝ်ႇ}} ဢၼ်ၽၢင်ႉ", - "notification-link-text-view-changes": "{{GENDER:$1|တူၺ်း}} လွင်ႈၸိူဝ်းလႅၵ်ႈလၢႆႈ" + "notification-link-text-view-changes": "{{GENDER:$1|တူၺ်း}} လွင်ႈၸိူဝ်းလႅၵ်ႈလၢႆႈ", + "notification-bundle-header-edit-user-talk-v2": "{{PLURAL:$1|ၶေႃႈၵႂၢမ်းလိၵ်ႈမႂ်ႇ ၽိုၼ်ၼိုင်ႈ|ၶေႃႈၵႂၢမ်းလိၵ်ႈမႂ်ႇ $1 ၽိုၼ်|100=ၶေႃႈၵႂၢမ်းလိၵ်ႈမႂ်ႇ 99+ ၽိုၼ်}} တီႈ <strong>ၼႃႈလိၵ်ႈဢုပ်ႇဢူဝ်း {{GENDER:$3|ၸဝ်ႈၵဝ်ႇ}} </strong>။" } diff --git a/Echo/i18n/sl.json b/Echo/i18n/sl.json index c819e1aa..1fcc488d 100644 --- a/Echo/i18n/sl.json +++ b/Echo/i18n/sl.json @@ -11,41 +11,53 @@ ] }, "echo-desc": "Sistem za obveščanje uporabnikov o dogodkih in sporočilih", - "prefs-echo": "Obvestila", + "prefs-echo": "Obveščanje", + "prefs-description-echo": "Izberite, katera obvestila {{GENDER:|želite}} prejemati in kako jih prejemati.", "prefs-emailsettings": "Možnosti e-pošte", - "prefs-echosubscriptions": "Obvesti me o naslednjih dogodkih", - "prefs-echocrosswiki": "Obveščanje med wikiji", + "prefs-echosubscriptions": "Obvesti me ob naslednjih dogodkih", + "prefs-echocrosswiki": "Obveščanje med vikiji", "prefs-blocknotificationslist": "Utišani uporabniki", - "echo-pref-send-me": "Pošlji mi:", - "echo-pref-send-to": "Pošlji:", - "echo-pref-email-format": "Format e-pošte:", + "prefs-mutedpageslist": "Strani z utišanim obveščanjem o povezavah na stran", + "prefs-echopollupdates": "Sprotna obvestila", + "echo-mobile-notifications-filter-title": "Filtriraj obvestila", + "echo-pref-show-poll-updates": "Prikaži nova obvestila, ko prispejo", + "echo-pref-show-poll-updates-help": "Prikaži število neprebranih obvestil v naslovni vrstici in prikaži izrezek vsakega obvestila takoj, ko prispe.", + "echo-pref-send-me": "Pošiljaj mi:", + "echo-pref-send-to": "Pošiljaj na:", + "echo-pref-email-format": "Oblika e-pošte:", "echo-pref-web": "Splet", "echo-pref-email": "E-pošta", + "echo-pref-push": "Api", "echo-pref-email-frequency-never": "Ne pošiljaj mi nobenih e-poštnih obvestil", "echo-pref-email-frequency-immediately": "Posamezna obvestila, kot prihajajo", "echo-pref-email-frequency-daily": "Dnevni povzetek obvestil", "echo-pref-email-frequency-weekly": "Tedenski povzetek obvestil", "echo-pref-email-format-html": "HTML", "echo-pref-email-format-plain-text": "Neoblikovano besedilo", - "echo-pref-cross-wiki-notifications": "Prikaži obvestila iz drugih wikijev", - "echo-pref-notifications-blacklist": "Ne prikazuj obvestil naslednjih uporabnikov. ([[mw:Special:MyLanguage/Help:Notifications#mute|več]])", + "echo-pref-cross-wiki-notifications": "Prikaži obvestila iz drugih vikijev", + "echo-pref-notifications-blacklist": "Ne prikazuj obvestil naslednjih uporabnikov ([[mw:Special:MyLanguage/Help:Notifications#mute|več]]):", + "echo-pref-notifications-page-linked-title-muted-list": "Za te strani ne prikazuj obvestil »Povezava na stran« ([[mw:Special:MyLanguage/Help:Notifications#mute|več]]):", + "echo-pref-dont-email-read-notifications": "V povzetke obvestil ne vključi prebranih obvestil", "echo-learn-more": "Več o tem", "echo-log": "Dnevnik", - "echo-new-messages": "Prejel si nova sporočila", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Sporočilo|Sporočili|Sporočila}} na pogovornih straneh", - "echo-category-title-article-linked": "{{PLURAL:$1|Povezava|Povezavi|Povezave}} na pogovornih straneh", - "echo-category-title-reverted": "{{PLURAL:$1|Vračanje urejanja|Vračanje urejanj}}", + "echo-new-messages": "Imaš novo sporočilo na pogovorni strani", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Urejanje|Urejanji|Urejanja}} moje uporabniške pogovorne strani", + "echo-category-title-article-linked": "{{PLURAL:$1|Povezava|Povezavi|Povezave}} na strani", + "echo-category-title-reverted": "{{PLURAL:$1|Vrnitev urejanja|Vrnitev urejanj}}", "echo-category-title-mention": "{{PLURAL:$1|Omemba|Omembi|Omembe|Omemb}}", - "echo-category-title-mention-failure": "{{PLURAL:$1|neuspela omemba|neuspeli omembi|neuspele omembe|neuspelih omemb}}", - "echo-category-title-mention-success": "{{PLURAL:$1|uspela omemba|uspeli omembi|uspele omembe|uspelih omemb}}", + "echo-category-title-mention-failure": "{{PLURAL:$1|Neuspela omemba|Neuspeli omembi|Neuspele omembe}}", + "echo-category-title-mention-success": "{{PLURAL:$1|Uspela omemba|Uspeli omembi|Uspele omembe}}", "echo-category-title-other": "{{PLURAL:$1|Drugo}}", "echo-category-title-system": "{{PLURAL:$1|Sistem}}", "echo-category-title-system-noemail": "{{PLURAL:$1|Sistem}}", + "echo-category-title-system-emailonly": "{{PLURAL:$1|Sistem|Sistema|Sistemi}}", "echo-category-title-user-rights": "{{PLURAL:$1|Sprememba|Spremembi|Spremembe}} uporabniških pravic", - "echo-category-title-emailuser": "{{PLURAL:$1|e-pošta od drugega uporabnika|e-pošti od drugih uporabnikov|e-pošte od drugih uporabnikov|e-pošt od drugih uporabnikov}}", + "echo-category-title-emailuser": "{{PLURAL:$1|E-pismo od drugega uporabnika|E-pošta od drugih uporabnikov}}", "echo-category-title-article-reminder": "{{PLURAL:$1|opomnik|opomnika|opomniki|opomnikov}} strani", - "echo-category-title-thank-you-edit": "Uredi {{PLURAL:$1|mejnik|mejnika|mejnike|mejnikov}}", - "echo-pref-tooltip-edit-user-talk": "Obvesti me, ko nekdo na moji pogovorni strani objavi sporočilo ali odgovori.", + "echo-category-title-thank-you-edit": "{{PLURAL:$1|Mejnik|Mejnika|Mejniki}} urejanja", + "echo-category-title-watchlist": "Urejanje spremljane strani", + "echo-category-title-minor-watchlist": "Manjše urejanje spremljane strani", + "echo-pref-tooltip-edit-user-talk": "Obvesti me, ko nekdo uredi mojo uporabniško pogovorno stran.", "echo-pref-tooltip-article-linked": "Obvesti me, ko nekdo doda povezavo na stran, ki sem jo ustvaril.", "echo-pref-tooltip-reverted": "Obvesti me, ko nekdo z orodjem za razveljavitev ali vrnitev vrne urejanje, ki sem ga napravil.", "echo-pref-tooltip-mention": "Obvesti me, ko nekdo doda povezavo na mojo uporabniško stran.", @@ -55,11 +67,13 @@ "echo-pref-tooltip-emailuser": "Obvesti me ob prejemu e-pošte.", "echo-pref-tooltip-article-reminder": "Obvesti me o tej strani, kadar povprašam.", "echo-pref-tooltip-thank-you-edit": "Obvesti me, ko dosežem svoje 1., 10., 100. ... urejanje.", + "echo-pref-tooltip-watchlist": "Obvesti me, ko nekdo (ne-manjše) uredi stran na mojem spisku nadzorov.", + "echo-pref-tooltip-minor-watchlist": "Obvesti me, ko nekdo manjše uredi stran na mojem spisku nadzorov.", "notifications": "Obvestila", - "tooltip-pt-notifications-alert": "{{GENDER:|Tvoji}} opomniki", - "tooltip-pt-notifications-notice": "{{GENDER:|Tvoja}} obvestila", + "tooltip-pt-notifications-alert": "{{GENDER:|Vaša}} obvestila", + "tooltip-pt-notifications-notice": "{{GENDER:|Vaša}} obvestila", "echo-displaynotificationsconfiguration": "Prikaži nastavitve za obvestila", - "echo-displaynotificationsconfiguration-summary": "To je pregled nastavitev tvojih obvestil na tem wikiju.", + "echo-displaynotificationsconfiguration-summary": "To je pregled nastavitev obvestil v tem vikiju.", "echo-displaynotificationsconfiguration-notifications-by-category-header": "Obvestila po kategoriji", "echo-displaynotificationsconfiguration-sorting-by-section-header": "Sortiranje tipov", "echo-displaynotificationsconfiguration-sorting-by-section-legend": "v kateri del je uvrščena vrsta obvestila", @@ -74,7 +88,10 @@ "echo-specialpage-section-markread": "Označi skupino kot prebrano", "echo-specialpage-markasread": "Obvestilo: Označi kot prebrano", "echo-specialpage-markasread-invalid-id": "Neuspešna določitev dejanja", + "echo-specialpage-pagefilterwidget-aria-label": "Filtriranje po vikiju in naslovu strani", + "echo-specialpage-special-help-menu-widget-aria-label": "Dodatne možnosti in nastavitve obvestil.", "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|obvestilo|obvestili|obvestila|obvestil}}", + "echo-specialpage-pagination-range": "$1 – $2", "echo-specialpage-pagefilters-title": "Trenutna dejavnost", "echo-specialpage-pagefilters-subtitle": "Strani z neprebranimi obvestili", "notificationsmarkread-legend": "Označi obvestilo kot prebrano", @@ -82,13 +99,19 @@ "echo-api-failure": "Pri izpisu obvestil je prišlo do napake.", "echo-api-failure-cross-wiki": "Dostop do oddaljene domene je bil zavrnjen.", "echo-notification-placeholder": "Ni obvestil.", - "echo-notification-placeholder-filters": "Ni obvestil, ki bi se ujemale s temi kriteriji.", - "echo-notification-loginrequired": "Za pregled sporočil se moraš prijaviti.", - "echo-notification-popup-loginrequired": "Za ogled svojih obvestil se prosim prijavi.", + "echo-notification-placeholder-filters": "Ni obvestil, ki bi se ujemala s temi merili.", + "echo-notification-loginrequired": "Za ogled sporočil se morate prijaviti.", + "echo-notification-popup-loginrequired": "Za ogled svojih obvestil se prijavite.", "echo-notification-markasread": "Označi kot prebrano", "echo-notification-markasunread": "Označi kot neprebrano", "echo-notification-markasread-tooltip": "Označi kot prebrano", "echo-notification-more-options-tooltip": "Dodatne možnosti", + "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|Utišaj}} obvestila o povezavah za stran »$1«", + "notification-dynamic-actions-mute-page-linked-confirmation": "Obvestila »Povezava na stran« so zdaj za stran »$1« izklopljena", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "Utišane strani lahko kadar koli {{GENDER:$2|urejate}} v [$1 svojih nastavitvah].", + "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2|Izklop utišanja}} obvestil o povezavah za stran »$1«", + "notification-dynamic-actions-unmute-page-linked-confirmation": "Obvestila »Povezava na stran« so zdaj za stran »$1« vklopljena", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "Utišane strani lahko kadar koli {{GENDER:$2|urejate}} v [$1 svojih nastavitvah].", "notification-dynamic-actions-unwatch": "{{GENDER:$3|Ne glej}} več novih dejavnosti na \"$1\"", "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3|Ne gledaš}} več strani \"$1\"", "notification-dynamic-actions-unwatch-confirmation-description": "Kadarkoli lahko {{GENDER:$3|pogledaš}} [$2 to stran].", @@ -96,32 +119,33 @@ "notification-dynamic-actions-watch-confirmation": "Trenutno {{GENDER:$3|gledaš}} stran \"$1\"", "notification-dynamic-actions-watch-confirmation-description": "Kadarkoli lahko {{GENDER:$3|prenehaš}} z ogledom [$2 te strani].", "notification-link-text-expand-all": "Odpri", - "notification-link-text-expand-alert-count": "Poglej {{PLURAL:$1|$1 opomnik|$1 opomnika|$1 opomnike|$1 opomnikov}}", - "notification-link-text-expand-notice-count": "Poglej {{PLURAL:$1|$1 obvestilo|$1 obvestili|$1 obvestila|$1 obvestil}}", - "notification-link-text-expand-all-count": "Poglej {{PLURAL:$1|$1 obvestilo|$1 obvestili|$1 obvestila|$1 obvestil}}", - "notification-link-text-collapse-all": "Zapri", + "notification-link-text-expand-alert-count": "Prikaži {{PLURAL:$1|$1 opomnik|$1 opomnika|$1 opomnike|$1 opomnikov}}", + "notification-link-text-expand-notice-count": "Prikaži {{PLURAL:$1|$1 obvestilo|$1 obvestili|$1 obvestila|$1 obvestil}}", + "notification-link-text-expand-all-count": "Prikaži {{PLURAL:$1|$1 obvestilo|$1 obvestili|$1 obvestila|$1 obvestil}}", + "notification-link-text-collapse-all": "Strni", "notification-link-text-view-message": "Ogled sporočila", "notification-link-text-view-mention": "Ogled omembe", - "notification-link-text-view-mention-failure": "{{PLURAL:$1|Poglej obvestilo|Poglej obvestili|Poglej obvestila}}", + "notification-link-text-view-mention-failure": "{{PLURAL:$1|Prikaz obvestila|Prikaz obvestil}}", "notification-link-text-view-changes": "{{GENDER:$1|Ogled}} sprememb", "notification-link-text-view-page": "Ogled strani", - "notification-header-edit-user-talk": "$1 je na <strong>{{GENDER:$3|tvoji}} pogovorni strani</strong> {{GENDER:$2|pustil|pustila}} sporočilo.", - "notification-header-edit-user-talk-with-section": "$1 ti je {{GENDER:$2|pustil|pustila}} sporočilo na <strong>{{GENDER:$3|tvoji}} pogovorni strani</strong> v razdelku »<strong>$4</strong>«.", - "notification-compact-header-edit-user-talk": "$1 {{GENDER:$3|ti}} {{GENDER:$2|je pustil}} sporočilo.", - "notification-compact-header-edit-user-talk-with-section": "$1 {{GENDER:$3|ti}} {{GENDER:$2|je pustil}} sporočilo v razdelku \"<strong>$4</strong>\".", - "notification-header-page-linked": "V članku <strong>$4</strong> je bila narejena notranja povezava na članek <strong>$3</strong>.", - "notification-compact-header-page-linked": "Povezava narejena iz <strong>$1</strong>.", - "notification-bundle-header-page-linked": "Narejene so bile povezave iz {{PLURAL:$5|$5 stran|$5 strani|100=99+ strani}} na <strong>$3</strong>.", + "notification-header-edit-user-talk": "$1 je na <strong>{{GENDER:$3|vaši}} pogovorni strani</strong> {{GENDER:$2|pustil|pustila}} sporočilo.", + "notification-header-edit-user-talk-with-section": "$1 vam je na <strong>{{GENDER:$3|vaši}} pogovorni strani</strong> v razdelku »<strong>$4</strong>« {{GENDER:$2|pustil|pustila}} sporočilo.", + "notification-compact-header-edit-user-talk": "$1 {{GENDER:$3|vam}} {{GENDER:$2|je pustil}} sporočilo.", + "notification-compact-header-edit-user-talk-with-section": "$1 {{GENDER:$3|vam}} {{GENDER:$2|je pustil}} sporočilo v razdelku \"<strong>$4</strong>\".", + "notification-body-edit-user-talk-with-section": "$1", + "notification-header-page-linked": "V članku <strong>$4</strong> je bila ustvarjena povezava na članek <strong>$3</strong>.", + "notification-compact-header-page-linked": "Povezava s strani <strong>$1</strong>.", + "notification-bundle-header-page-linked": "{{PLURAL:$5|Z $5 strani je bila ustvarjena povezava na <strong>$3</strong>|Z $5 strani sta bili ustvarjeni povezavi na <strong>$3</strong>|S $5 strani so bile ustvarjene povezave na <strong>$3</strong>|Z $5 strani so bile ustvarjene povezave na <strong>$3</strong>|100=S 100 ali več strani so bile ustvarjene povezave na <strong>$3</strong>}}.", "notification-header-article-reminder": "Stran, o kateri {{GENDER:$2|si}} si želel biti opomnjen, ima naslov <strong>$3</strong>", "notification-link-text-what-links-here": "Vse povezave na to stran", - "notification-header-mention-other": "$1 {{GENDER:$3|te}} je {{GENDER:$2|omenil|omenila}} na strani <strong>$4</strong> v razdelku »<strong>$5</strong>«.", - "notification-header-mention-other-nosection": "$1 {{GENDER:$3|te}} je {{GENDER:$2|omenil|omenila}} na strani <strong>$4</strong>.", - "notification-header-mention-user-talkpage-v2": "$1 {{GENDER:$3|te}} je {{GENDER:$2|omenil|omenila}} na <strong>pogovorni strani {{GENDER:$5|uporabnika|uporabnice}} $4</strong> v razdelku »<strong>$6</strong>«.", - "notification-header-mention-user-talkpage-nosection": "$1 {{GENDER:$3|te}} je {{GENDER:$2|omenil|omenila}} na <strong>pogovorni strani {{GENDER:$5|uporabnika|uporabnice}} $4</strong>.", - "notification-header-mention-agent-talkpage": "$1 {{GENDER:$3|te}} {{GENDER:$2|je omenil}} na <strong>{{GENDER:$2|svoji}} pogovorni strani</strong> v razdelku \"<strong>$4</strong>\".", - "notification-header-mention-agent-talkpage-nosection": "$1 {{GENDER:$3|te}} je {{GENDER:$2|omenil|omenila}} na <strong>{{GENDER:$2|svoji}} pogovorni strani</strong>.", - "notification-header-mention-article-talkpage": "$1 {{GENDER:$3|te}} je {{GENDER:$2|omenil|omenila}} na pogovorni strani članka <strong>$4</strong> v razdelku »<strong>$5</strong>«.", - "notification-header-mention-article-talkpage-nosection": "$1 {{GENDER:$3|te}} je {{GENDER:$2|omenil|omenila}} na pogovorni strani članka <strong>$4</strong>.", + "notification-header-mention-other": "$1 {{GENDER:$3|vas}} je {{GENDER:$2|omenil|omenila}} na strani <strong>$4</strong> v razdelku »<strong>$5</strong>«.", + "notification-header-mention-other-nosection": "$1 {{GENDER:$3|vas}} je {{GENDER:$2|omenil|omenila}} na strani <strong>$4</strong>.", + "notification-header-mention-user-talkpage-v2": "$1 {{GENDER:$3|vas}} je {{GENDER:$2|omenil|omenila}} na <strong>pogovorni strani {{GENDER:$5|uporabnika|uporabnice}} $4</strong> v razdelku »<strong>$6</strong>«.", + "notification-header-mention-user-talkpage-nosection": "$1 {{GENDER:$3|vas}} je {{GENDER:$2|omenil|omenila}} na <strong>pogovorni strani {{GENDER:$5|uporabnika|uporabnice}} $4</strong>.", + "notification-header-mention-agent-talkpage": "$1 {{GENDER:$3|vas}} {{GENDER:$2|je omenil|je omenila|je omenil}} na <strong>{{GENDER:$2|svoji}} pogovorni strani</strong> v razdelku \"<strong>$4</strong>\".", + "notification-header-mention-agent-talkpage-nosection": "$1 {{GENDER:$3|vas}} je {{GENDER:$2|omenil|omenila}} na <strong>{{GENDER:$2|svoji}} pogovorni strani</strong>.", + "notification-header-mention-article-talkpage": "$1 {{GENDER:$3|vas}} je {{GENDER:$2|omenil|omenila}} na pogovorni strani članka <strong>$4</strong> v razdelku »<strong>$5</strong>«.", + "notification-header-mention-article-talkpage-nosection": "$1 {{GENDER:$3|vas}} je {{GENDER:$2|omenil|omenila}} na pogovorni strani članka <strong>$4</strong>.", "notification-header-mention-failure-user-unknown": "{{GENDER:$2|Tvoja}} omemba uporabnika <strong>$3</strong> ni bila poslana, saj uporabnik ni bil najden.", "notification-header-mention-failure-user-anonymous": "{{GENDER:$2|Tvoja}} omemba uporabnika <strong>$3</strong> ni bila poslana, saj je uporabnik anonimen.", "notification-header-mention-failure-too-many": "{{GENDER:$2|Poskusil si|Poskusila si|Poskusili ste}} omeniti več kot $3 {{PLURAL:$3|uporabnika|uporabnika|uporabnike|uporabnikov}}. Vseh omemb nad to mejo nismo poslali.", @@ -130,31 +154,43 @@ "notification-compact-header-mention-failure-user-anonymous": "<strong>IP-je ni mogoče omenjati:</strong> $1", "notification-header-mention-success": "{{GENDER:$2|Tvoja}} omemba uporabnika <strong>$3</strong> je bila poslana.", "notification-header-mention-success-bundle": "{{PLURAL:$3|Omemba|$3 omembi|$3 omembe|$3 omemb}}, ki si jih {{GENDER:$2|naredil}} na uporabniškem pogovoru <strong>$4</strong> {{PLURAL:$3|je bila poslana|sta bili poslani|so bile poslane|je bilo poslanih}}.", - "notification-compact-header-mention-success": "<strong>{{GENDER:$2|Omenil si}}:</strong> $3", + "notification-compact-header-mention-success": "<strong>{{GENDER:$2|Omenili ste}}:</strong> $3", "notification-header-mention-status-bundle": "{{PLURAL:$3|Obvestilo|$3 obvestili|$3 obvestila|$3 obvestil}} o omembah, ki si jih {{GENDER:$2|naredil}} na uporabniškem pogovoru <strong>$4</strong>: {{PLURAL:$5|$5 neposlano|$5 neposlani|$5 neposlana|$5 neposlanih}}, {{PLURAL:$6|$6 poslano|$6 poslani|$6 poslana|$6 poslanih}}.", "notification-header-user-rights-add-only": "{{GENDER:$4|Tvoje}} uporabniške pravice so bile {{GENDER:$1|spremenjene}}. Dodan si bil k skupini: $2.", "notification-header-user-rights-remove-only": "{{GENDER:$4|Tvoje}} Uporabniške pravice {{GENDER:$1|so bile spremenjene}}. Odslej nisi več v skupini: $2.", "notification-header-user-rights-add-and-remove": "{{GENDER:$6|Tvoje}} uporabniške pravice {{GENDER:$1|so bile spremenjene}}. Postal si del skupine: $2. Nisi več v skupini: $4.", "notification-header-user-rights-expiry-change": "Čas poteka {{GENDER:$4|tvojega}} tvojega članstva v naslednjih {{PLURAL:$3|skupini|skupinama|skupinah}} je bil {{GENDER:$1|spremenjen}}: $2.", - "notification-header-welcome": "{{GENDER:$2|Dobrodošel|Dobrodošla}} na {{SITENAME}}, $1! Veseli smo, da si se {{GENDER:$2|oglasil|oglasila}}.", - "notification-header-mention-summary": "$1 {{GENDER:$3|te}} {{GENDER:$2|je omenil}} v povzetku urejanja strani <strong>$4</strong>.", - "notification-welcome-linktext": "{{GENDER:|Dobrodošel|Dobrodošla}}", - "notification-header-thank-you-1-edit": "Pravkar si {{GENDER:$2|naredil|naredila}} svoje prvo urejanje. Hvala {{GENDER:$2|ti}} in {{GENDER:$2|dobrodošel|dobrodošla}} še naprej!", + "notification-header-welcome": "{{GENDER:$2|Pozdravljeni}} v projektu {{SITENAME}}, $1! Veseli nas, da {{GENDER:$2|ste}} tu.", + "notification-header-mention-summary": "$1 {{GENDER:$3|vas}} {{GENDER:$2|je omenil}} v povzetku urejanja strani <strong>$4</strong>.", + "notification-header-watchlist-changed": "$1 je {{GENDER:$2|spremenil|spremenila|spremenil/a}} <strong>$3</strong>, stran na {{GENDER:$4|vašem}} spisku nadzorov{{PLURAL:$5||, $5-krat}}.", + "notification-header-watchlist-created": "$1 je {{GENDER:$2|ustvaril|ustvarila|ustvaril/a}} <strong>$3</strong>, stran na {{GENDER:$4|vašem}} spisku nadzorov {{PLURAL:$5||, $5-krat}}.", + "notification-header-watchlist-deleted": "$1 je {{GENDER:$2|izbrisal|izbrisala|izbrisal/a}} <strong>$3</strong>, stran na {{GENDER:$4|vašem}} spisku nadzorov {{PLURAL:$5||, $5-krat}}.", + "notification-header-watchlist-moved": "$1 je {{GENDER:$2|spremenil|spremenila|spremenil/a}} <strong>$3</strong>, stran na {{GENDER:$4|vašem}} spisku nadzorov{{PLURAL:$5||, $5-krat}}.", + "notification-header-watchlist-restored": "$1 je {{GENDER:$2|obnovil|obnovila|obnovill/a}} <strong>$3</strong>, stran na {{GENDER:$4|vašem}} spisku nadzorov {{PLURAL:$5||, $5-krat}}.", + "notification-header-watchlist-multiuser-changed": "<strong>$1</strong>, stran na {{GENDER:$2|vašem}} spisku nadzorov, je bila spremenjena $3-{{PLURAL:$3|krat}}.", + "notification-header-watchlist-multiuser-created": "<strong>$1</strong>, stran na {{GENDER:$2|vašem}} spisku nadzorov, je bila ustvarjena $3-{{PLURAL:$3|krat}}.", + "notification-header-watchlist-multiuser-deleted": "<strong>$1</strong>, stran na {{GENDER:$2|vašem}} spisku nadzorov, je bila izbrisana $3-{{PLURAL:$3|krat}}.", + "notification-header-watchlist-multiuser-moved": "<strong>$1</strong>, stran na {{GENDER:$2|vašem}} spisku nadzorov, je bila spremenjena $3-{{PLURAL:$3|krat}}.", + "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>, stran na {{GENDER:$2|vašem}} spisku nadzorov, je bila obnovljena $3-{{PLURAL:$3|krat}}.", + "notification-body-watchlist-once": "V primeru nadaljnje dejavnosti ne bo drugih e-poštnih obvestil, razen če {{GENDER:$1|boste to stran obiskali}}, medtem ko ste prijavljeni.", + "notification-welcome-linktext": "{{GENDER: Pozdravljen|Pozdravljena|Pozdravljeni}}", + "notification-header-thank-you-1-edit": "Pravkar ste {{GENDER:$2|opravili}} svoje prvo urejanje. Hvala{{GENDER:$2|}} in kar tako naprej!", "notification-header-thank-you-10-edit": "Pravkar si {{GENDER:$2|naredil|naredila}} {{GENDER:$2|svoje}} deseto urejanje. Hvala {{GENDER:$2|ti}} in le tako naprej!", "notification-header-thank-you-100-edit": "Pravkar si {{GENDER:$2|naredil|naredila}} {{GENDER:$2|svoje}} stoto urejanje. Hvala ti za {{GENDER:$2|tvoj}} doprinos!", "notification-header-thank-you-1000-edit": "Pravkar si {{GENDER:$2|naredil|naredila}} {{GENDER:$2|svoje}} tisoče urejanje. Hvala ti za {{GENDER:$2|tvojo}} vztrajnost pri tem velikem delu!", - "notification-header-thank-you-10000-edit": "Pravkar si {{GENDER:$2|naredil|naredila}} {{GENDER:$2|svoje}} desettisoče urejanje. Hvala ti za {{GENDER:$2|tvojo}} veliko prostovoljsko vnemo!", + "notification-header-thank-you-10000-edit": "Pravkar {{GENDER:$2|ste}} opravili svoje desettisoče urejanje. Hvala za vaš velik prostovoljski doprinos!", "notification-header-thank-you-100000-edit": "Pravkar si {{GENDER:$2|naredil|naredila}} {{GENDER:$2|svoje}} stotisoče urejanje. Hvala ti za {{GENDER:$2|tvoj}} neverjetni doprinos!", "notification-header-thank-you-1000000-edit": "Pravkar si {{GENDER:$2|naredil|naredila}} {{GENDER:$2|svoje}} milijonto urejanje. Hvala ti za {{GENDER:$2|tvoj}} naravnost osupljiv doprinos!", + "notification-header-thank-you-10000000-edit": "Pravkar ste {{GENDER:$2|opravili}} {{GENDER:$2|svoje}} milijonto urejanje. Hvala vam za {{GENDER:$2|vaš}} naravnost osupljiv doprinos!", "notification-link-thank-you-edit": "{{GENDER:$1|Vaše}} urejanje", "notification-link-text-view-edit": "Ogled urejanja", "notification-link-article-reminder": "Ogled strani", - "notification-header-reverted": "{{PLURAL:$4|Tvoje urejanje strani <strong>$3</strong> je bilo {{GENDER:$2|vrnjeno}}|Tvoji urejanji strani <strong>$3</strong> sta bili vrnjeni|Tvoja urejanja strani <strong>$3</strong> so bila vrnjena}}.", - "notification-header-emailuser": "$1 ti {{GENDER:$2|je poslal|je poslala}} e-pošto.", - "notification-edit-talk-page-email-subject2": "V projektu {{SITENAME}} ti je {{GENDER:$2|uporabnik|uporabnica}} {{GENDER:$2|pustil|pustila}} sporočilo.", - "notification-page-linked-email-subject": "Stran, ki si jo {{GENDER:$3|ustvaril|ustvarila}}, je dobila povezavo na projektu {{SITENAME}}", + "notification-header-reverted": "{{PLURAL:$4|Vaše urejanje strani <strong>$3</strong> je bilo {{GENDER:$2|vrnjeno}}|Vaši urejanji strani <strong>$3</strong> sta bili vrnjeni|Vaša urejanja strani <strong>$3</strong> so bila vrnjena}}.", + "notification-header-emailuser": "$1 vam {{GENDER:$2|je poslal|je poslala}} e-pošto.", + "notification-edit-talk-page-email-subject2": "V projektu {{SITENAME}} {{GENDER:$3|vam}} je {{GENDER:$1|uporabnik|uporabnica}} {{GENDER:$2|pustil|pustila}} sporočilo.", + "notification-page-linked-email-subject": "Za stran, ki ste jo {{GENDER:$3|ustvarili}}, je bila dodana povezava v projektu {{SITENAME}}", "notification-reverted-email-subject2": "V {{GRAMMAR:dajalnik|{{SITENAME}}}} {{PLURAL:$4|je bilo|sta bili|so bila}} {{PLURAL:$4|vaše urejanje|vaši urejanji|vaša urejanja}} {{GENDER:$2|{{PLURAL:$4|vrnjeno|vrnjeni|vrnjena}}}}.", - "notification-mention-email-subject": "V projektu {{SITENAME}} {{GENDER:$3|te}} je {{GENDER:$2|omenil|omenila}} $1.", + "notification-mention-email-subject": "V projektu {{SITENAME}} {{GENDER:$3|vas}} je {{GENDER:$2|omenil|omenila}} $1.", "notification-user-rights-email-subject": "V {{GRAMMAR:dajalnik|{{SITENAME}}}} so bile spremenjene {{GENDER:$3|tvoje}} uporabniške pravice.", "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1 sekunda|$1 sekundi|$1 sekunde|$1 sekund}}", "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1 minuta|$1 minuti|$1 minute|$1 minut}}", @@ -167,6 +203,7 @@ "notification-inbox-filter-read": "Prebrana", "notification-inbox-filter-unread": "Neprebrana", "notification-inbox-filter-all": "Vsa", + "echo-specialmute-label-mute-notifications": "Utišaj obvestila {{GENDER:$1|tega uporabnika|te uporabnice}}", "echo-email-plain-footer": "Za določite vrste e-pošte, ki naj {{GENDER:$1|vam}} jih pošiljamo, preverite svoje nastavitve:", "echo-email-html-footer-preference-link-text": "preverite {{GENDER:$1|svoje}} nastavitve", "echo-email-html-footer-with-link": "Za določitev vrste e-pošte, ki naj {{GENDER:$2|vam}} jo pošiljamo, $1.", @@ -176,18 +213,27 @@ "echo-notification-notice-text-only": "Obvestila", "echo-overlay-link": "Vsa obvestila", "echo-overlay-title": "<b>Obvestila</b>", - "echo-mark-all-as-read": "Označi vsa sporočila kot prebrana", - "echo-mark-all-as-read-confirmation": "$1 {{PLURAL:$1|obvestilo označeno za prebrano|obvestili označeni za prebrani|obvestila označena za prebrana|obvestil označenih za prebrane}}", - "echo-mark-wiki-as-read": "Označi vsa kot prebrana v izbranem wikiju: $1", + "echo-mark-all-as-read": "Označi vse kot prebrano", + "echo-mark-all-as-read-confirmation": "$1 {{PLURAL:$1|obvestilo označeno kot prebrano|obvestili označeni kot prebrani|obvestila označena kot prebrana|obvestil označenih kot prebranih}}", + "echo-mark-wiki-as-read": "Označi vsa kot prebrana v izbranem vikiju: $1", + "echo-displaysnippet-title": "Novo obvestilo", "echo-date-today": "Danes", "echo-date-yesterday": "Včeraj", - "notification-bundle-header-edit-user-talk-v2": "{{PLURAL:$1|Eno novo sporočilo|$1 novi sporočili|$1 nova sporočila|$1 novih sporočil|100=99+ novih sporočil}} na <strong>{{GENDER:$3|tvoji}} pogovorni strani</strong>.", + "notification-bundle-header-edit-user-talk-v2": "{{PLURAL:$1|Eno novo sporočilo|$1 novi sporočili|$1 nova sporočila|$1 novih sporočil|100=99+ novih sporočil}} na <strong>{{GENDER:$3|vaši}} pogovorni strani</strong>.", + "echo-email-batch-bullet": "•", "echo-email-batch-subject-daily": "V {{GRAMMAR:dajalnik|{{SITENAME}}}} te {{PLURAL:$2|čaka novo sporočilo|čakata novi sporočili|čakajo nova sporočila}}.", "echo-email-batch-subject-weekly": "V {{GRAMMAR:dajalnik|{{SITENAME}}}} te ta teden čaka {{PLURAL:$2|eno novo sporočilo|dve novi sporočili|nova sporočila}}.", - "echo-email-batch-body-intro-daily": "{{GENDER:|Pozdravljen|Pozdravljena}}, $1.\n\nTu je povzetek tvoje današnje dejavnosti v {{GRAMMAR:dajalnik|{{SITENAME}}}}.", + "echo-email-batch-body-intro-daily": "Pozdravljeni, $1.\n\nTu je povzetek vaše današnje dejavnosti v {{GRAMMAR:dajalnik|{{SITENAME}}}}.", "echo-email-batch-body-intro-weekly": "{{GENDER:|Pozdravljen|Pozdravljena}}, $1.\n\nTu je povzetek tvojih dejavnosti v preteklem tednu v {{GRAMMAR:dajalnik|{{SITENAME}}}}.", "echo-email-batch-link-text-view-all-notifications": "Ogled vseh obvestil", "notification-header-foreign-alert": "Novi opomniki iz {{PLURAL:$5|drugega wikija|$5 drugih wikijev}}", - "notification-header-foreign-notice": "Več obvestil iz {{PLURAL:$5|drugega wikija|$5 drugih wikijev}}", - "notification-header-foreign-all": "Več obvestil iz {{PLURAL:$5|drugega wikija|$5 drugih wikijev}}" + "notification-header-foreign-notice": "Več obvestil iz {{PLURAL:$5|drugega vikija|$5 drugih vikijev}}", + "notification-header-foreign-all": "Več obvestil iz {{PLURAL:$5|drugega vikija|$5 drugih vikijev}}", + "echo-foreign-wiki-lang": "$1 – $2", + "echo-badge-count": "{{PLURAL:$1|$1|100={{formatnum:99}}+}}", + "right-manage-all-push-subscriptions": "Upravljanje vseh naročil potisnih obvestil", + "action-manage-all-push-subscriptions": "upravljanje vseh potisnih naročil", + "group-push-subscription-manager": "Upravljavci potisnih naročil", + "group-push-subscription-manager-member": "{{GENDER:$1|upravljavec potisnih naročil|upravljavka potisnih naročil/upravljavec/ka potisnih naročil}}", + "grouppage-push-subscription-manager": "{{ns:project}}:Upravljavci potisnih naročil" } diff --git a/Echo/i18n/sli.json b/Echo/i18n/sli.json new file mode 100644 index 00000000..3f1ca60c --- /dev/null +++ b/Echo/i18n/sli.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Äberlausitzer" + ] + }, + "tooltip-pt-notifications-alert": "{{GENDER:|Denne}} Meldunga" +} diff --git a/Echo/i18n/smn.json b/Echo/i18n/smn.json index e3d5620f..95d3fe89 100644 --- a/Echo/i18n/smn.json +++ b/Echo/i18n/smn.json @@ -1,8 +1,28 @@ { "@metadata": { "authors": [ - "Trondtr" + "Seipinne", + "Trondtr", + "Yupik" ] }, - "tooltip-pt-notifications-alert": "{{GENDER:|Tuu larmâdâsah}}" + "prefs-echo": "Almottâsah", + "prefs-emailsettings": "Šleđgâpostâasâttâsah", + "notifications": "Almottâsah", + "tooltip-pt-notifications-alert": "{{GENDER:|Tuu larmâdâsah}}", + "tooltip-pt-notifications-notice": "{{GENDER:|Tuu almottâsah}}", + "echo-specialpage": "Almottâsah", + "notification-link-text-expand-all": "Čääiti", + "notification-link-text-collapse-all": "Čievâ", + "notification-link-text-view-changes": "{{GENDER:$1|Čääiti}} nubástusâid", + "notification-welcome-linktext": "Tiervâpuáttim", + "notification-timestamp-today": "Onne", + "notification-inbox-filter-all": "Puoh", + "echo-specialmute-label-mute-notifications": "Jávuttut almottâsâid taan {{GENDER:$1|kevttest}}", + "echo-email-html-footer-preference-link-text": "täärhist {{GENDER:$1|asâttâsâidâd}}", + "echo-notification-alert-text-only": "Larmâdâsah", + "echo-overlay-link": "Puoh almottâsah", + "echo-overlay-title": "<b>Almottâsah</b>", + "echo-date-today": "Onne", + "echo-email-batch-link-text-view-all-notifications": "Čääiti puoh almottâsâid" } diff --git a/Echo/i18n/sms.json b/Echo/i18n/sms.json new file mode 100644 index 00000000..df722aad --- /dev/null +++ b/Echo/i18n/sms.json @@ -0,0 +1,30 @@ +{ + "@metadata": { + "authors": [ + "Yupik" + ] + }, + "prefs-emailsettings": "E-pååʹštasetõõzz", + "echo-pref-send-me": "Vuõlttâd muʹnne:", + "echo-pref-send-to": "Vuõlttâd addrõʹsse:", + "echo-pref-email": "E-pååʹšt", + "echo-pref-email-frequency-never": "Jeäʹl vuõlttâd muʹnne iʹlmmtõõzzi neʹttpooʹštin", + "echo-learn-more": "Lââʹssteâđ teeʹmest", + "echo-category-title-other": "{{PLURAL:$1|Jeeʹres}}", + "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "Ođđ õõʹnni", + "notification-link-text-expand-all": "Čuäʹjet", + "notification-link-text-collapse-all": "Čiõǥǥ", + "notification-link-text-view-message": "Čuäʹjet saaǥǥ", + "notification-link-text-view-page": "Čuäʹjet seeid", + "notification-welcome-linktext": "Tiõrvpueʹttem", + "notification-link-article-reminder": "Čuäʹjet seeid", + "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1 s}}", + "notification-timestamp-ago-hours": "{{PLURAL:$1|$1 č.}}", + "notification-timestamp-ago-days": "{{PLURAL:$1|$1 pv}}", + "notification-timestamp-ago-months": "{{PLURAL:$1|$1 mp}}", + "notification-timestamp-today": "Täʹbbe", + "notification-timestamp-yesterday": "Jåhtta", + "notification-inbox-filter-all": "Puk", + "echo-date-today": "Täʹbbe", + "echo-date-yesterday": "Jåhtta" +} diff --git a/Echo/i18n/sq.json b/Echo/i18n/sq.json index 2c2375e7..a406ce69 100644 --- a/Echo/i18n/sq.json +++ b/Echo/i18n/sq.json @@ -2,6 +2,7 @@ "@metadata": { "authors": [ "Euriditi", + "Klein Muçi", "Kosovastar", "Liridon", "Olsi" @@ -9,55 +10,55 @@ }, "echo-desc": "Sistemi i njoftimeve", "prefs-echo": "Njoftimet", - "prefs-emailsettings": "Opsionet e emailit", + "prefs-emailsettings": "Opsionet për mesazhet elektronike", "prefs-echosubscriptions": "Më njofto për këto raste", "echo-pref-send-me": "Më dërgo:", - "echo-pref-send-to": "Dërgo në:", - "echo-pref-email-format": "Formati i e-mailit:", - "echo-pref-web": "Web", - "echo-pref-email": "E-mail", - "echo-pref-email-frequency-never": "Mos më dërgo më njoftime me email", - "echo-pref-email-frequency-immediately": "Njoftimet individuale për çdo rast", - "echo-pref-email-frequency-daily": "Përmbledhje e përditshme e njoftimeve", - "echo-pref-email-frequency-weekly": "Përmbledhje javore e njoftimeve", + "echo-pref-send-to": "Dërgo te:", + "echo-pref-email-format": "Formati i adresës elektronike:", + "echo-pref-web": "Brenda projektit", + "echo-pref-email": "Në mesazhe elektronike", + "echo-pref-email-frequency-never": "Mos më dërgo njoftime me mesazhe elektronike", + "echo-pref-email-frequency-immediately": "Njoftime të veçanta për çdo rast", + "echo-pref-email-frequency-daily": "Përmbledhje ditore njoftimesh", + "echo-pref-email-frequency-weekly": "Përmbledhje javore njoftimesh", "echo-pref-email-format-html": "HTML", "echo-pref-email-format-plain-text": "Tekst normal", "echo-learn-more": "Mëso më tepër", - "echo-new-messages": "Keni mesazhe të reja", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|mesazh|mesazhe}} në faqen e diskutimeve", - "echo-category-title-article-linked": "{{PLURAL:$1|lidhje|lidhje}} në një faqe", + "echo-new-messages": "Ke mesazhe të reja", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Mesazh|Mesazhe}} në faqen vetjake të diskutimeve", + "echo-category-title-article-linked": "{{PLURAL:$1|Lidhje|Lidhje}} në një faqe", "echo-category-title-reverted": "{{PLURAL:$1|Redaktim i kthyer|Redaktime të kthyera}}", "echo-category-title-mention": "{{PLURAL:$1|Përmëndje|Përmëndje}}", "echo-category-title-other": "{{PLURAL:$1|Të tjera}}", "echo-category-title-system": "{{PLURAL:$1|Sistemi}}", - "echo-pref-tooltip-edit-user-talk": "Më njofto kur dikush poston një mesazh të ri ose përgjigjet në faqet time të diskutimit.", - "echo-pref-tooltip-article-linked": "Më njofto kur dikush lidh, një faqe, me një faqe që kam krijuar unë.", - "echo-pref-tooltip-reverted": "Më njofto kur dikush kthen një ndryshim që kam bërë unë, duke përdorur funksionet zhbëj ose riktheje.", - "echo-pref-tooltip-mention": "Më njofto kur dikush lidh faqen time të përdoruesit me cilëndo faqe diskutimi.", + "echo-pref-tooltip-edit-user-talk": "Më njofto kur dikush redakton faqen time të diskutimit.", + "echo-pref-tooltip-article-linked": "Më njofto kur dikush lidh një faqe me një faqe që kam krijuar unë.", + "echo-pref-tooltip-reverted": "Më njofto kur dikush kthen një ndryshim që kam bërë unë duke përdorur butonat e zhbërjes ose të rikthimit.", + "echo-pref-tooltip-mention": "Më njofto kur dikush lidh një faqe me faqen time të përdoruesit.", "notifications": "Njoftimet", "tooltip-pt-notifications-alert": "Njoftimet e tua", "echo-specialpage": "Njoftimet", - "echo-none": "Nuk keni njoftime.", + "echo-none": "Nuk ke njoftime.", "notification-link-text-view-message": "Shiko mesazhin", "notification-link-text-view-mention": "Shiko përmëndjen", "notification-link-text-view-changes": "Shiko ndryshimet", "notification-link-text-view-page": "Shiko faqen", - "notification-header-welcome": "{{GENDER:$2|Mirë se erdhët}} në {{SITENAME}}, $1! Jemi të lumtur që {{GENDER:$2|ju}} kemi këtu.", + "notification-header-welcome": "Mirë se erdhe në {{SITENAME}}, $1! Jemi të lumtur që të kemi këtu.", "notification-link-text-view-edit": "Shiko redaktimin", - "notification-header-reverted": "{{PLURAL:$4|Redaktimi i juaj|Redaktimet e tua}} në $3 {{PLURAL:$4|u kthye|u kthyen}} {{GENDER:$2|nga}} $1.", - "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$2|iu la}} një mesazh në {{SITENAME}}", - "notification-page-linked-email-subject": "Një faqe që keni krijuar u lidh në {{SITENAME}}", - "notification-reverted-email-subject2": "{{PLURAL:$4|Redaktimi juaj|Redaktimet tuaja}} {{GENDER:$2|u kthyen}} në {{SITENAME}}", - "notification-mention-email-subject": "$1 të {{GENDER:$2|përmëndi}} në {{SITENAME}}", - "notification-user-rights-email-subject": "Të drejtat e tua të përdoruesit u ndryshuan në {{SITENAME}}", + "notification-header-reverted": "{{PLURAL:$4|Redaktimi yt|Redaktimet e tua}} në $3 {{PLURAL:$4|u kthye|u kthyen}} nga $1.", + "notification-edit-talk-page-email-subject2": "$1 të la një mesazh në {{SITENAME}}", + "notification-page-linked-email-subject": "Një faqe që ke krijuar u lidh në {{SITENAME}}", + "notification-reverted-email-subject2": "{{PLURAL:$4|Redaktimi yt|Redaktimet e tua}} u {{PLURAL:$4|kthye|kthyen}} në {{SITENAME}}", + "notification-mention-email-subject": "$1 të përmendi në {{SITENAME}}", + "notification-user-rights-email-subject": "Privilegjet e tua të përdoruesit u ndryshuan në {{SITENAME}}", "echo-overlay-link": "Të gjitha njoftimet", "echo-overlay-title": "<b>Njoftimet</b>", "echo-mark-all-as-read": "Shënoji të gjitha si të lexuara", "echo-date-today": "Sot", "echo-date-yesterday": "Dje", - "echo-email-batch-subject-daily": "Keni {{PLURAL:$2|një njoftim të ri|njoftime të reja}} në {{SITENAME}}", - "echo-email-batch-subject-weekly": "Keni {{PLURAL:$2|një njoftim të ri|njoftime të reja}} në {{SITENAME}} gjatë kësaj jave.", - "echo-email-batch-body-intro-daily": "Përshëndetje $1,\nkëtu është përmbledhja e aktivitetit të sotëm në {{SITENAME}} për ju.", - "echo-email-batch-body-intro-weekly": "Përshëndetje $1,\nkëtu është përmbledhja e aktivitetit javor në {{SITENAME}} për ju.", + "echo-email-batch-subject-daily": "Ke {{PLURAL:$2|një njoftim të ri|njoftime të reja}} në {{SITENAME}}", + "echo-email-batch-subject-weekly": "Ke {{PLURAL:$2|një njoftim të ri|njoftime të reja}} për këtë javë në {{SITENAME}}.", + "echo-email-batch-body-intro-daily": "Përshëndetje, $1!\n\nMë poshtë gjendet përmbledhja e aktivitetit të sotëm në {{SITENAME}}.", + "echo-email-batch-body-intro-weekly": "Përshëndetje, $1!\n\nMë poshtë gjendet përmbledhja e aktivitetit javor në {{SITENAME}}.", "echo-email-batch-link-text-view-all-notifications": "Shfaq të gjitha njoftimet" } diff --git a/Echo/i18n/sr-ec.json b/Echo/i18n/sr-ec.json index aabd891e..9bb2b17a 100644 --- a/Echo/i18n/sr-ec.json +++ b/Echo/i18n/sr-ec.json @@ -4,6 +4,7 @@ "Acamicamacaraca", "BadDog", "Dungodung", + "Kizule", "Macofe", "Matěj Suchánek", "Milicevic01", @@ -18,19 +19,22 @@ }, "echo-desc": "Систем за обавештавање корисника о догађајима и порукама", "prefs-echo": "Обавештења", + "prefs-description-echo": "Одређујете која обавештења {{GENDER:|желите}} да примате и како.", "prefs-emailsettings": "Опције е-поште", - "prefs-echosubscriptions": "Обавештавај ме о следећим догађајима", + "prefs-echosubscriptions": "Обавештавај ме о:", "prefs-echocrosswiki": "Међувики обавештења", "prefs-blocknotificationslist": "Пригушени корисници", + "prefs-mutedpageslist": "Пригушене странице", "prefs-echopollupdates": "Обавештења уживо", "echo-mobile-notifications-filter-title": "Филтрирање обавештења", "echo-pref-show-poll-updates": "Приказује нова обавештења чим стигну", "echo-pref-show-poll-updates-help": "Прикажи број непрочитаних обавештења у насловној траци и исечак сваког од њих чим стигну.", "echo-pref-send-me": "Шаљи ми:", "echo-pref-send-to": "Шаљи на:", - "echo-pref-email-format": "Формат е-поруке:", + "echo-pref-email-format": "Формат имејла:", "echo-pref-web": "Веб", "echo-pref-email": "Е-пошта", + "echo-pref-push": "Апликације", "echo-pref-email-frequency-never": "не шаљи ми никаква обавештења путем е-поште", "echo-pref-email-frequency-immediately": "појединачна обавештења чим се појаве", "echo-pref-email-frequency-daily": "дневни резиме обавештења", @@ -38,12 +42,13 @@ "echo-pref-email-format-html": "HTML", "echo-pref-email-format-plain-text": "чист текст", "echo-pref-cross-wiki-notifications": "Приказуј обавештења са других викија", - "echo-pref-notifications-blacklist": "Не приказуј обавештења од следећих корисника: ([[mw:Special:MyLanguage/Help:Notifications#mute|сазнајте више]])", + "echo-pref-notifications-blacklist": "Не приказуј обавештења од следећих корисника: ([[mw:Special:MyLanguage/Help:Notifications#mute|детаљније]])", + "echo-pref-notifications-page-linked-title-muted-list": "Не приказуј обавештења о повезивању следећих страница. ([[mw:Special:MyLanguage/Help:Notifications#mute|детаљније]])", "echo-pref-dont-email-read-notifications": "Не укључуј прочитана обавештења у е-порукама са резимеом", "echo-learn-more": "Сазнајте више", "echo-log": "Јаван дневник", "echo-new-messages": "Имате нове поруке", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Порука|Поруке}} на страници за разговор", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Измена|Измене}} на мојој страници за разговор", "echo-category-title-article-linked": "{{PLURAL:$1|Веза|Везе}} ка страници", "echo-category-title-reverted": "{{PLURAL:$1|Враћање измене|Враћање измена}}", "echo-category-title-mention": "{{PLURAL:$1|Помињање|Помињања}}", @@ -54,12 +59,12 @@ "echo-category-title-system-noemail": "{{PLURAL:$1|Систем}}", "echo-category-title-system-emailonly": "{{PLURAL:$1|Систем}}", "echo-category-title-user-rights": "{{PLURAL:$1|Промена корисничких права|Промене корисничких права}}", - "echo-category-title-emailuser": "{{PLURAL:$1|Е-порука од другог корисника|Е-поруке од других корисника}}", + "echo-category-title-emailuser": "{{PLURAL:$1|Имејл од другог корисника|Имејлови од других корисника}}", "echo-category-title-article-reminder": "{{PLURAL:$1|Подсетник о страници|Подсетници о страницама}}", "echo-category-title-thank-you-edit": "{{PLURAL:$1|Прекретница|Прекретнице}} измена", "echo-category-title-watchlist": "Измена надгледане странице", "echo-category-title-minor-watchlist": "Мања измена надгледане странице", - "echo-pref-tooltip-edit-user-talk": "Обавештава вас када неко постави поруку или одговори на вашој страници за разговор.", + "echo-pref-tooltip-edit-user-talk": "Обавештава вас када неко измени вашу страницу за разговор.", "echo-pref-tooltip-article-linked": "Обавештава вас када неко повеже страницу који сте направили са неком другом страницом.", "echo-pref-tooltip-reverted": "Обавештава вас када неко врати измену коју сте направили помоћу алатке за поништавање или враћање измена.", "echo-pref-tooltip-mention": "Обавештава вас када неко дода везу ка вашој корисничкој страници.", @@ -77,7 +82,7 @@ "echo-displaynotificationsconfiguration": "Конфигурација приказа обавештења", "echo-displaynotificationsconfiguration-summary": "Ово је преглед о томе како су обавештења конфигурисана на овом викију.", "echo-displaynotificationsconfiguration-notifications-by-category-header": "Обавештења по категоријама", - "echo-displaynotificationsconfiguration-sorting-by-section-header": "Сортирање по типовима", + "echo-displaynotificationsconfiguration-sorting-by-section-header": "Ређање по типовима", "echo-displaynotificationsconfiguration-sorting-by-section-legend": "У којем ће се одељку сваки тип обавештења сортирати", "echo-displaynotificationsconfiguration-available-notification-methods-header": "Дозвољени начини за обавештавање", "echo-displaynotificationsconfiguration-available-notification-methods-by-category-legend": "Који начини за обавештавање су подржани за сваку категорију", @@ -90,6 +95,7 @@ "echo-specialpage-section-markread": "Означи групу прочитаном", "echo-specialpage-markasread": "Обавештење: Означавање прочитаним", "echo-specialpage-markasread-invalid-id": "Неважећи ID догађаја", + "echo-specialpage-special-help-menu-widget-aria-label": "Додатне опције и подешавања за обавештења.", "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|обавeштење|обавештења}}", "echo-specialpage-pagination-range": "$1—$2.", "echo-specialpage-pagefilters-title": "Недавна активност", @@ -104,8 +110,9 @@ "echo-notification-popup-loginrequired": "Пријавите се да бисте видите обавештења.", "echo-notification-markasread": "Означи прочитаним", "echo-notification-markasunread": "Означи непрочитаним", - "echo-notification-markasread-tooltip": "Означите прочитаним", + "echo-notification-markasread-tooltip": "Означите као прочитано", "echo-notification-more-options-tooltip": "Још опција", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|У}} сваком тренутку можете променити пригушене странице у [$1 подешавањима].", "notification-dynamic-actions-unwatch": "{{GENDER:$3|Престани}} да надгледаш нову активност на страници „$1”", "notification-dynamic-actions-unwatch-confirmation": "Више {{GENDER:$3|не надгледате}} страницу „$1”", "notification-dynamic-actions-unwatch-confirmation-description": "У било ком тренутку {{GENDER:$3|можете}} да надгледате [$2 ову страницу].", @@ -122,23 +129,23 @@ "notification-link-text-view-mention-failure": "Прикажи {{PLURAL:$1|помињање|помињања}}", "notification-link-text-view-changes": "{{GENDER:$1|Прикажи}} промене", "notification-link-text-view-page": "Прикажи страницу", - "notification-header-edit-user-talk": "$1 је {{GENDER:$2|оставио|оставила}} поруку на <strong>{{GENDER:$3|вашој}} страници за разговор</strong>.", - "notification-header-edit-user-talk-with-section": "$1 је {{GENDER:$2|оставио|оставила}} поруку на <strong>{{GENDER:$3|вашој}} страници за разговор</strong> у одељку „<strong>$4</strong>”.", + "notification-header-edit-user-talk": "$1 је {{GENDER:$2|оставио|оставила}} поруку на <strong>{{GENDER:$3|Вашој}} страници за разговор</strong>.", + "notification-header-edit-user-talk-with-section": "$1 је {{GENDER:$2|оставио|оставила}} поруку на <strong>{{GENDER:$3|Вашој}} страници за разговор</strong> у одељку „<strong>$4</strong>”.", "notification-compact-header-edit-user-talk": "$1 {{GENDER:$3|вам}} је {{GENDER:$2|оставио|оставила}} поруку.", - "notification-compact-header-edit-user-talk-with-section": "$1 вам је {{GENDER:$2|оставио|оставила}} {{GENDER:$3|поруку}} у одељку „<strong>$4</strong>”.", + "notification-compact-header-edit-user-talk-with-section": "$1 Вам је {{GENDER:$2|оставио|оставила}} {{GENDER:$3|поруку}} у одељку „<strong>$4</strong>”.", "notification-header-page-linked": "Страница <strong>$3</strong> повезана је са <strong>$4</strong>.", "notification-compact-header-page-linked": "Повезана са странице <strong>$1</strong>.", "notification-bundle-header-page-linked": "Страница <strong>$3</strong> повезана је {{PLURAL:$5|1=с једном страницом|са $5 страницом|са $5 странице|са $5 страница|100=с преко 99 страница}}.", "notification-header-article-reminder": "Страница о којој {{GENDER:$2|сте}} тражили да будете подсећени се зове <strong>$3</strong>", "notification-link-text-what-links-here": "Све везе ка овој страници", - "notification-header-mention-other": "$1 {{GENDER:$3|вас}} је {{GENDER:$2|поменуо|поменула}} на страници <strong>$4</strong> у одељку „<strong>$5</strong>”.", - "notification-header-mention-other-nosection": "$1 {{GENDER:$3|вас}} је {{GENDER:$2|поменуо|поменула}} на страници strong>$4</strong>.", - "notification-header-mention-user-talkpage-v2": "$1 {{GENDER:$3|вас}} је {{GENDER:$2|поменуо|поменула}} на <strong>страници за разговор {{GENDER:$5|корисника|кориснице}} $4</strong> у одељку „<strong>$6</strong>”.", - "notification-header-mention-user-talkpage-nosection": "$1 {{GENDER:$3|вас}} је {{GENDER:$2|поменуо|поменула}} на <strong>страници за разговор {{GENDER:$5|корисника|кориснице}} $4</strong>.", - "notification-header-mention-agent-talkpage": "$1 {{GENDER:$3|вас}} је {{GENDER:$2|поменуо|поменула}} на <strong>својој страници за разговор</strong> у одељку „<strong>$4</strong>”.", - "notification-header-mention-agent-talkpage-nosection": "$1 {{GENDER:$3|вас}} је {{GENDER:$2|поменуо|поменула}} на <strong>својој страници за разговор</strong>.", - "notification-header-mention-article-talkpage": "$1 {{GENDER:$3|вас}} је {{GENDER:$2|поменуо|поменула}} на страници за разговор странице <strong>$4</strong> у одељку „<strong>$5</strong>”.", - "notification-header-mention-article-talkpage-nosection": "$1 {{GENDER:$3|вас}} је {{GENDER:$2|поменуо|поменула}} на страници за разговор странице „<strong>$4</strong>”.", + "notification-header-mention-other": "$1 {{GENDER:$3|Вас}} је {{GENDER:$2|поменуо|поменула}} на страници <strong>$4</strong> у одељку „<strong>$5</strong>”.", + "notification-header-mention-other-nosection": "$1 {{GENDER:$3|Вас}} је {{GENDER:$2|поменуо|поменула}} на страници <strong>$4</strong>.", + "notification-header-mention-user-talkpage-v2": "$1 {{GENDER:$3|Вас}} је {{GENDER:$2|поменуо|поменула}} на <strong>страници за разговор {{GENDER:$5|корисника|кориснице}} $4</strong> у одељку „<strong>$6</strong>”.", + "notification-header-mention-user-talkpage-nosection": "$1 {{GENDER:$3|Вас}} је {{GENDER:$2|поменуо|поменула}} на <strong>страници за разговор {{GENDER:$5|корисника|кориснице}} $4</strong>.", + "notification-header-mention-agent-talkpage": "$1 {{GENDER:$3|Вас}} је {{GENDER:$2|поменуо|поменула}} на <strong>својој страници за разговор</strong> у одељку „<strong>$4</strong>”.", + "notification-header-mention-agent-talkpage-nosection": "$1 {{GENDER:$3|Вас}} је {{GENDER:$2|поменуо|поменула}} на <strong>својој страници за разговор</strong>.", + "notification-header-mention-article-talkpage": "$1 {{GENDER:$3|Вас}} је {{GENDER:$2|поменуо|поменула}} на страници за разговор странице <strong>$4</strong> у одељку „<strong>$5</strong>”.", + "notification-header-mention-article-talkpage-nosection": "$1 {{GENDER:$3|Вас}} је {{GENDER:$2|поменуо|поменула}} на страници за разговор странице „<strong>$4</strong>”.", "notification-header-mention-failure-user-unknown": "{{GENDER:$2|Ваше}} помињање корисника <strong>$3</strong> није послато, јер корисничко име није пронађено.", "notification-header-mention-failure-user-anonymous": "{{GENDER:$2|Ваше}} помињање корисника <strong>$3</strong> није послато, јер је корисник анониман.", "notification-header-mention-failure-too-many": "Покушали {{GENDER:$2|сте}} да поменете више од $3 {{PLURAL:$3|корисника}}. Сва помињања изнад тог ограничења нису послата.", @@ -151,20 +158,21 @@ "notification-header-mention-status-bundle": "{{PLURAL:$3|Обавештење|$3 обавештења}} о помињањима која {{GENDER:$2|сте направили}} на страници за разговор <strong>$4</strong>: {{PLURAL:$5|$5 није послато|$5 нису послата}}, {{PLURAL:$6|$6 је послато|$6 су послата}}.", "notification-header-user-rights-add-only": "{{GENDER:$4|Ваша}} корисничка права су {{GENDER:$1|промењена}}. Додати сте у следеће групе: $2.", "notification-header-user-rights-remove-only": "{{GENDER:$4|Ваша}} корисничка права су {{GENDER:$1|промењена}}. Више нисте члан следећих група: $2.", - "notification-header-user-rights-add-and-remove": "{{GENDER:$6|Ваша}} корисничка права су {{GENDER:$1|промењена}}. Додати сте у следеће групе: $2. Више нисте члан следећи група: $4.", + "notification-header-user-rights-add-and-remove": "{{GENDER:$6|Ваша}} корисничка права су {{GENDER:$1|промењена}}. Додати сте у следеће групе: $2. Више нисте члан следећих група: $4.", "notification-header-user-rights-expiry-change": "Истек {{GENDER:$4|вашег}} чланства у {{PLURAL:$3|следећој групи|следећим групама}} је {{GENDER:$1|промењен}}: $2.", "notification-header-welcome": "{{GENDER:$2|Добро дошли}} на {{GRAMMAR:акузатив|{{SITENAME}}}}, $1! Драго нам што {{GENDER:$2|сте}} овде.", - "notification-header-mention-summary": "$1 {{GENDER:$3|вас}} је {{GENDER:$2|поменуо|поменула}} у резимеу измене на страници <strong>$4</strong>.", + "notification-header-mention-summary": "$1 {{GENDER:$3|Вас}} је {{GENDER:$2|поменуо|поменула}} у опису измене на страници <strong>$4</strong>.", "notification-header-watchlist-changed": "$1 је {{GENDER:$2|променио|променила}} страницу <strong>$3</strong>, страницу на {{GENDER:$4|вашем}} списку надгледања{{PLURAL:$5||, $5 пута}}.", - "notification-header-watchlist-created": "$1 је {{GENDER:$2|направио|направила}} страницу <strong>$3</strong>, страницу на {{GENDER:$4|вашем}} списку надгледања{{PLURAL:$5||, $5 пута}}.", + "notification-header-watchlist-created": "$1 је {{GENDER:$2|направио|направила}} страницу <strong>$3</strong>, страницу на {{GENDER:$4|Вашем}} списку надгледања{{PLURAL:$5||, $5 пута}}.", "notification-header-watchlist-deleted": "$1 је {{GENDER:$2|избрисао|избрисала}} страницу <strong>$3</strong>, страницу на {{GENDER:$4|вашем}} списку надгледања{{PLURAL:$5||, $5 пута}}.", - "notification-header-watchlist-moved": "$1 је {{GENDER:$2|преместио|преместила}} страницу <strong>$3</strong>, страницу на {{GENDER:$4|вашем}} списку надгледања{{PLURAL:$5||, $5 пута}}.", + "notification-header-watchlist-moved": "$1 је {{GENDER:$2|преместио|преместила}} страницу <strong>$3</strong>, страницу на {{GENDER:$4|Вашем}} списку надгледања{{PLURAL:$5||, $5 пута}}.", "notification-header-watchlist-restored": "$1 је {{GENDER:$2|вратио|вратила}} страницу <strong>$3</strong>, страницу на {{GENDER:$4|вашем}} списку надгледања{{PLURAL:$5||, $5 пута}}.", "notification-header-watchlist-multiuser-changed": "<strong>$1</strong>, страница на {{GENDER:$2|списку}} надгледања, промењена је $3 {{PLURAL:$3|пут|пута}}.", "notification-header-watchlist-multiuser-created": "<strong>$1</strong>, страница на {{GENDER:$2|списку}} надгледања, направљена је $3 {{PLURAL:$3|пут|пута}}.", "notification-header-watchlist-multiuser-deleted": "<strong>$1</strong>, страница на {{GENDER:$2|списку}} надгледања, избрисана је $3 {{PLURAL:$3|пут|пута}}.", "notification-header-watchlist-multiuser-moved": "<strong>$1</strong>, страница на {{GENDER:$2|списку}} надгледања, премештена је $3 {{PLURAL:$3|пут|пута}}.", "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>, страница на {{GENDER:$2|списку}} надгледања, враћена је $3 {{PLURAL:$3|пут|пута}}.", + "notification-body-watchlist-once": "Неће бити даљих имејл обавештења у случају активности осим ако {{GENDER:$1|посетите}} ову страницу пријављени.", "notification-welcome-linktext": "Добро дошли", "notification-header-thank-you-1-edit": "Управо {{GENDER:$2|сте}} направили прву измену. Хвала {{GENDER:$2|вам}} и добро дошли.", "notification-header-thank-you-10-edit": "Управо {{GENDER:$2|сте}} направили десету измену. Хвала {{GENDER:$2|вам}} и само тако наставите!", @@ -173,15 +181,16 @@ "notification-header-thank-you-10000-edit": "Управо {{GENDER:$2|сте}} направили десет-хиљадиту измену. Хвала {{GENDER:$2|вам}} пуно.", "notification-header-thank-you-100000-edit": "Управо {{GENDER:$2|сте}} направили сто-хиљадиту измену. Хвала {{GENDER:$2|вам}} на феноменалном доприносу.", "notification-header-thank-you-1000000-edit": "Управо {{GENDER:$2|сте}} направили милиониту измену. Хвала {{GENDER:$2|вам}} на задивљујућем доприносу.", + "notification-header-thank-you-10000000-edit": "Управо {{GENDER:$2|сте}} направили 10-милиониту измену. Хвала {{GENDER:$2|вам}} на невероватној посвећености.", "notification-link-thank-you-edit": "{{GENDER:$1|Ваша}} измена", "notification-link-text-view-edit": "Прикажи измену", "notification-link-article-reminder": "Прикажи страницу", - "notification-header-reverted": "{{PLURAL:$4|Ваша измена на страници <strong>$3</strong> је враћена|Ваше измене на {{GENDER:$2|страници}} <strong>$3</strong> су враћене}}.", - "notification-header-emailuser": "$1 вам је {{GENDER:$2|послао|послала}} е-поруку.", + "notification-header-reverted": "$2 je {{GENDER:$2|опозвао|опозвала}} {{PLURAL:$4|Вашу измену странице <strong>$3</strong>|Ваше измене странице <strong>$3</strong>}}.", + "notification-header-emailuser": "$1 Вам {{GENDER:$2|шаље}} имејл.", "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$3|вам}} је {{GENDER:$2|оставио|оставила}} поруку на пројекту {{SITENAME}}", "notification-page-linked-email-subject": "Страница коју {{GENDER:$3|сте}} направили је повезана на пројекту {{SITENAME}}", - "notification-reverted-email-subject2": "{{GENDER:$3|Ваша|Ваше}} {{PLURAL:$4|измена је|измене су}} {{GENDER:$2|враћена|враћене}} на пројекту {{SITENAME}}.", - "notification-mention-email-subject": "$1 {{GENDER:$3|вас}} је {{GENDER:$2|поменуо|поменула}} на пројекту {{SITENAME}}", + "notification-reverted-email-subject2": "{{PLURAL:$4|{{GENDER:$3|Ваша}} измена је {{GENDER:$2|враћена}}|Ваше измене су враћене}} на пројекту {{SITENAME}}.", + "notification-mention-email-subject": "$1 {{GENDER:$3|Вас}} је {{GENDER:$2|поменуо|поменула}} на пројекту {{SITENAME}}", "notification-user-rights-email-subject": "{{GENDER:$3|Ваша}} корисничка права су промењена на пројекту {{SITENAME}}.", "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1 сек.}}", "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1 мин.}}", @@ -194,8 +203,8 @@ "notification-inbox-filter-read": "Прочитана", "notification-inbox-filter-unread": "Непрочитана", "notification-inbox-filter-all": "Сва", - "echo-specialmute-label-mute-notifications": "Пригуши обавештења од {{GENDER:$1|овог корисника|ове кориснице}}", - "echo-email-plain-footer": "Да бисте контролисали које е-поруке {{GENDER:$1|вам}} шаљемо, проверите подешавања.", + "echo-specialmute-label-mute-notifications": "Утишај обавештења од {{GENDER:$1|корисника|кориснице}}", + "echo-email-plain-footer": "Да бисте управљали имејловима које {{GENDER:$1|вам}} шаљемо, посетите подешавања.", "echo-email-html-footer-preference-link-text": "{{GENDER:$1|проверите}} подешавања", "echo-email-html-footer-with-link": "Да бисте контролисали које е-поруке {{GENDER:$2|вам}} шаљемо, $1.", "echo-notification-alert": "{{PLURAL:$1|Обавештење ($1)|Обавештења ($1)|100=Обавештења (99+)}}", diff --git a/Echo/i18n/sr-el.json b/Echo/i18n/sr-el.json index 008d195f..c5f01136 100644 --- a/Echo/i18n/sr-el.json +++ b/Echo/i18n/sr-el.json @@ -6,6 +6,7 @@ "Obsuser", "Prevodim", "Srdjan m", + "Srđan", "Сербијана" ] }, diff --git a/Echo/i18n/sv.json b/Echo/i18n/sv.json index 3715729e..8b77b142 100644 --- a/Echo/i18n/sv.json +++ b/Echo/i18n/sv.json @@ -4,6 +4,7 @@ "Ainali", "Dcastor", "Edvinw", + "Felba", "Frisko", "Hangsna", "JohanahoJ", @@ -16,6 +17,7 @@ "Nemo bis", "Paracel63", "Pipetricker", + "Sabelöga", "Skalman", "Tobulos1", "Umeaboy", @@ -24,10 +26,11 @@ }, "echo-desc": "System för att meddela användare om händelser och meddelanden", "prefs-echo": "Aviseringar", + "prefs-description-echo": "Välj vilka aviseringar som {{GENDER:|du}} får och hur du får dem.", "prefs-emailsettings": "E-postinställningar", "prefs-echosubscriptions": "Meddela mig om dessa händelser", "prefs-echocrosswiki": "Interwikiaviseringar", - "prefs-blocknotificationslist": "Ignorerade användare", + "prefs-blocknotificationslist": "Tysta användare", "prefs-mutedpageslist": "Sidor undantagna från sidlänkningsavisering", "prefs-echopollupdates": "Direktaviseringar", "echo-mobile-notifications-filter-title": "Filtrera aviseringar", @@ -45,14 +48,14 @@ "echo-pref-email-frequency-weekly": "En veckovis sammanställning av aviseringar", "echo-pref-email-format-html": "HTML", "echo-pref-email-format-plain-text": "Oformaterad text", - "echo-pref-cross-wiki-notifications": "Visa aviseringar från andra wikis", + "echo-pref-cross-wiki-notifications": "Visa aviseringar från andra wikier", "echo-pref-notifications-blacklist": "Visa inte aviseringar från dessa användare. ([[mw:Special:MyLanguage/Help:Notifications#mute|läs mer]])", "echo-pref-notifications-page-linked-title-muted-list": "Visa inte sidlänkningsaviseringar för dessa sidor. ([[mw:Special:MyLanguage/Help:Notifications#mute|läs mer]])", "echo-pref-dont-email-read-notifications": "Inkludera inte lästa aviseringar i sammanfattningsmeddelanden", "echo-learn-more": "Läs mer", "echo-log": "Offentlig logg", - "echo-new-messages": "Du har nya meddelanden", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Diskussionssidemeddelande|Diskussionssidemeddelanden}}", + "echo-new-messages": "Du har ett nytt meddelande på diskussionssidan", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Redigering|Redigeringar}} till min användardiskussionsida", "echo-category-title-article-linked": "Sid{{PLURAL:$1|länkning|länkningar}}", "echo-category-title-reverted": "Redigerings{{PLURAL:$1|återställning|återställningar}}", "echo-category-title-mention": "{{PLURAL:$1|Omnämnande|Omnämnanden}}", @@ -68,7 +71,7 @@ "echo-category-title-thank-you-edit": "Redigerings{{PLURAL:$1|milsten|milstenar}}", "echo-category-title-watchlist": "Redigering på bevakad sida", "echo-category-title-minor-watchlist": "Mindre redigering på bevakad sida", - "echo-pref-tooltip-edit-user-talk": "Meddela mig när någon lämnar ett meddelande eller svarar på min diskussionssida.", + "echo-pref-tooltip-edit-user-talk": "Meddela mig när någon redigerar min användardiskussionssida.", "echo-pref-tooltip-article-linked": "Meddela mig när någon sida länkas till en sida som jag skapat.", "echo-pref-tooltip-reverted": "Meddela mig när någon återställer en ändring som jag gjort, med hjälp av verktygen \"gör ogjord\" eller \"rulla tillbaka\".", "echo-pref-tooltip-mention": "Meddela mig när någon länkar till min användarsida.", @@ -118,10 +121,10 @@ "echo-notification-more-options-tooltip": "Fler alternativ", "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|Visa inte}} länkningsaviseringar för \"$1\"", "notification-dynamic-actions-mute-page-linked-confirmation": "Sidlänkningsavisering är nu inaktiverad för sidan \"$1\"", - "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|Du}} kan hantera dina tystade sidor i [$1 dina inställningar] när som helst.", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|Du}} kan hantera sidorna du har tystat i [$1 dina inställningar] när som helst.", "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2|Visa}} sidlänkningsaviseringar för \"$1\"", "notification-dynamic-actions-unmute-page-linked-confirmation": "Sidlänkningsmeddelanden är nu aktiverade för sidan \"$1\"", - "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|Du}} kan hantera dina tystade sidor i [$1 dina inställningar] när som helst.", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|Du}} kan hantera sidorna du har tystat i [$1 dina inställningar] när som helst.", "notification-dynamic-actions-unwatch": "{{GENDER:$3|Sluta}} bevaka ny aktivitet på \"$1\"", "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3|Du}} bevakar inte längre sidan \"$1\"", "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|Du}} kan bevaka [$2 denna sida] när som helst.", @@ -181,6 +184,7 @@ "notification-header-watchlist-multiuser-deleted": "<strong>$1</strong>, en sida i {{GENDER:$2|din}} bevakningslista, raderades $3 {{PLURAL:$3|gång|gånger}}.", "notification-header-watchlist-multiuser-moved": "<strong>$1</strong>, en sida i {{GENDER:$2|din}} bevakningslista, flyttades $3 {{PLURAL:$3|gång|gånger}}.", "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>, en sida i {{GENDER:$2|din}} bevakningslista, återställdes $3 {{PLURAL:$3|gång|gånger}}.", + "notification-body-watchlist-once": "Inga e-postaviseringar kommer att skickas vid aktivitet såvida {{GENDER:$1|du inte besöker}} denna sida när du är inloggad.", "notification-welcome-linktext": "Välkommen", "notification-header-thank-you-1-edit": "{{GENDER:$2|Du}} gjorde precis {{GENDER:$2|din}} första redigering; {{GENDER:$2|tack}} och välkommen!", "notification-header-thank-you-10-edit": "{{GENDER:$2|Du}} gjorde precis {{GENDER:$2|din}} tionde redigering; {{GENDER:$2|tack}} och fortsätt i samma takt!", @@ -233,7 +237,12 @@ "echo-email-batch-body-intro-daily": "Hej $1,\nHär är en sammanfattning av dagens aktivitet på {{SITENAME}} för dig.", "echo-email-batch-body-intro-weekly": "Hej $1,\nHär är en sammanfattning av veckans aktivitet på {{SITENAME}} för dig.", "echo-email-batch-link-text-view-all-notifications": "Visa alla aviseringar", - "notification-header-foreign-alert": "Fler systemmeddelanden från {{PLURAL:$5|en annan wiki|$5 andra wikis|0=}}", - "notification-header-foreign-notice": "Flera notiser från {{PLURAL:$5|en annan wiki|$5 andra wikis}}", - "notification-header-foreign-all": "Fler aviseringar från {{PLURAL:$5|en annan wiki|$5 andra wikis}}" + "notification-header-foreign-alert": "Fler systemmeddelanden från {{PLURAL:$5|en annan wiki|$5 andra wikier|0=}}", + "notification-header-foreign-notice": "Flera notiser från {{PLURAL:$5|en annan wiki|$5 andra wikier}}", + "notification-header-foreign-all": "Fler aviseringar från {{PLURAL:$5|en annan wiki|$5 andra wikier}}", + "right-manage-all-push-subscriptions": "Hantera alla push-prenumerationer", + "action-manage-all-push-subscriptions": "hantera alla push-prenumerationer", + "group-push-subscription-manager": "Push-prenumerationshanterare", + "group-push-subscription-manager-member": "{{GENDER:$1|push-prenumerationshanterare}}", + "grouppage-push-subscription-manager": "{{ns:project}}:Push-prenumerationshanterare" } diff --git a/Echo/i18n/syl.json b/Echo/i18n/syl.json new file mode 100644 index 00000000..8e087a70 --- /dev/null +++ b/Echo/i18n/syl.json @@ -0,0 +1,28 @@ +{ + "@metadata": { + "authors": [ + "ꠢꠣꠍꠘ ꠞꠣꠎꠣ" + ] + }, + "prefs-blocknotificationslist": "ꠎꠦꠔꠣ ꠛꠦꠛꠀꠞꠇꠞ꠆ꠞꠣꠞ ꠝꠥꠈ ꠛꠘ", + "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "ꠘꠄꠀ ꠛꠦꠛꠀꠞꠇꠞ꠆ꠞꠣꠅꠇꠟ", + "echo-specialpage": "ꠎꠣꠘꠣꠅꠞꠣꠁꠘ", + "echo-specialpage-markasread-invalid-id": "ꠛꠦꠎꠣꠔ ꠇꠥꠞ ꠀꠁꠒꠤ", + "echo-specialpage-pagefilters-title": "ꠅꠁꠖ꠆ꠖꠇꠥꠞ ꠟꠣꠞꠣꠌꠣꠞꠣ", + "echo-specialpage-pagefilters-subtitle": "ꠙꠣꠔꠣꠁꠘ ꠎꠦꠔꠣꠔ ꠀꠛꠧ ꠘꠣꠙꠠꠣ ꠎꠣꠘꠣꠅꠞꠣꠁꠘ ꠞꠁꠌꠦ", + "notificationsmarkread-legend": "ꠙꠠꠤꠟꠤꠌꠂꠘ ꠛꠟꠤꠀ ꠎꠣꠘꠣꠅꠞꠣꠁꠘ꠆ꠔ ꠖꠣꠉ ꠝꠣꠞꠂꠇ꠆ꠇꠣ", + "echo-none": "ꠀꠙꠘꠣꠞ ꠀꠞꠇꠥꠘꠥ ꠎꠣꠘꠣꠅꠞꠣꠁꠘ ꠘꠣꠁ", + "echo-notification-placeholder": "ꠁꠇꠣꠘꠧ ꠀꠞ ꠇꠥꠘꠥ ꠎꠣꠘꠣꠅꠞꠣꠁꠘ ꠘꠣꠁ", + "echo-notification-markasread": "ꠙꠠꠤꠟꠤꠌꠂꠘ ꠇꠞꠤ ꠖꠣꠉ ꠖꠦꠃꠇ꠆ꠇꠣ", + "echo-notification-markasunread": "ꠙꠠꠌꠂꠘ꠆ꠘꠣ ꠇꠞꠤ ꠖꠣꠉ ꠖꠦꠃꠇ꠆ꠇꠣ", + "echo-notification-markasread-tooltip": "ꠙꠠꠤꠟꠤꠌꠂꠘ ꠇꠞꠤ ꠖꠣꠉ ꠖꠦꠃꠇ꠆ꠇꠣ", + "echo-notification-more-options-tooltip": "ꠀꠞ ꠎꠦꠔꠣ ꠎꠦꠔꠣ", + "notification-link-text-expand-all": "ꠛꠟꠣꠃꠇ꠆ꠇꠣ", + "notification-link-text-collapse-all": "ꠙꠣꠟꠣꠃꠇ꠆ꠇꠣ", + "notification-link-text-view-message": "ꠈꠛꠞ ꠖꠈꠂꠇ꠆ꠇꠣ", + "notification-link-text-view-mention": "ꠀꠙꠘꠣꠞꠦ ꠟꠃꠀ ꠝꠣꠔ ꠖꠦꠈꠂꠘ", + "notification-link-text-view-mention-failure": "{{PLURAL:$1|ꠀꠙꠘꠣꠞꠦ ꠔꠥꠟꠤ ꠝꠣꠔ ꠖꠦꠈꠂꠘ|ꠀꠙꠘꠣꠞꠦ ꠔꠥꠟꠤ ꠝꠣꠔꠣꠁꠘ ꠖꠦꠈꠂꠘ}}", + "notification-link-text-view-changes": "{{GENDER:$1|ꠖꠦꠈꠂꠘ}} ꠛꠖꠟꠣꠁꠟꠉꠥꠘ", + "notification-link-text-view-page": "ꠙꠣꠔꠣ ꠖꠦꠈꠂꠘ", + "notification-link-text-what-links-here": "ꠢꠇꠟꠔꠣ ꠅꠃ ꠙꠣꠔꠣꠔ ꠀꠁꠘ ꠟꠣꠉꠌꠦ" +} diff --git a/Echo/i18n/te.json b/Echo/i18n/te.json index 3a0c22ed..240a6a62 100644 --- a/Echo/i18n/te.json +++ b/Echo/i18n/te.json @@ -14,7 +14,8 @@ "prefs-emailsettings": "ఈ-మెయిల్ ఐచ్ఛికాలు", "prefs-echosubscriptions": "ఈ సంఘటనల గురించి నాకు తెలియజేయి", "prefs-echocrosswiki": "క్రాస్-వికీ గమనింపులు", - "prefs-blocknotificationslist": "సద్దుమణిగిన వాడుకరులు", + "prefs-blocknotificationslist": "గమనింపులు నిలిపివేసిన వాడుకరులు", + "prefs-mutedpageslist": "పేజీ లింకు సూచనలు వర్తించని పేజీలు", "echo-pref-send-me": "నాకు పంపు:", "echo-pref-send-to": "పంపించు:", "echo-pref-email-format": "ఇమెయిల్ ఫార్మాట్:", @@ -24,10 +25,12 @@ "echo-pref-email-frequency-immediately": "ఒక్కో సూచన వచ్చినది వచ్చినట్టుగా పంపు", "echo-pref-email-frequency-daily": "రోజువారి సూచనల సారాంశం", "echo-pref-email-frequency-weekly": "వారం మొత్తం మీద సూచనల సారాంశం", - "echo-pref-email-format-html": "హెచ్.టి.ఎం.ఎల్", + "echo-pref-email-format-html": "HTML", "echo-pref-email-format-plain-text": "సాదా పాఠ్యం", "echo-pref-cross-wiki-notifications": "ఇతర వికీల నుండి గమనింపులు చూపించు", "echo-pref-notifications-blacklist": "కింది వాడుకరుల నుండి వచ్చే గమనింపులను చూపవద్దు.\n([[mw:Special:MyLanguage/Help:Notifications#mute|మరింత సమాచారం]])", + "echo-pref-notifications-page-linked-title-muted-list": "ఈ పేజీలకు \"Page link\" సూచనలు చూపించవద్దు. ([[mw:Special:MyLanguage/Help:Notifications#mute|మరింత సమాచారం]])", + "echo-pref-dont-email-read-notifications": "సారాంశపు ఈ మెయిళ్లలో చదువు సూచనలు చేర్చవద్దు.", "echo-learn-more": "మరింత తెలుసుకోండి", "echo-log": "బహిరంగ లాగ్", "echo-new-messages": "మీకు కొత్త సందేశాలు ఉన్నాయి", @@ -150,7 +153,6 @@ "notification-link-text-view-edit": "మార్పును చూడు", "notification-link-article-reminder": "పేజీని చూడు", "notification-header-reverted": "మీరు {{PLURAL:$4|<strong>$3</strong> లో చేసిన దిద్దుబాటును|<strong>$3</strong> లో చేసిన దిద్దుబాట్లను}} {{GENDER:$2|వెనక్కి తిప్పారు}}.", - "notification-body-reverted": "$1", "notification-header-emailuser": "$1 మీకో ఈమెయిలు {{GENDER:$2|పంపించారు}}.", "notification-edit-talk-page-email-subject2": "{{SITENAME}}లో $1 {{GENDER:$3|మీ}}కొక సందేశం {{GENDER:$2|పెట్టారు}}.", "notification-page-linked-email-subject": "{{SITENAME}}లో {{GENDER:$3|మీరు}} సృష్టించిన ఒక పేజీకి లింకు చేసారు", diff --git a/Echo/i18n/th.json b/Echo/i18n/th.json index 2a89cec6..7da8f59c 100644 --- a/Echo/i18n/th.json +++ b/Echo/i18n/th.json @@ -17,7 +17,9 @@ "prefs-echosubscriptions": "แจ้งเตือนฉันเกี่ยวกับเหตุการณ์เหล่านี้", "prefs-echocrosswiki": "การแจ้งเตือนข้ามวิกิ", "prefs-blocknotificationslist": "ทำให้ผู้ใช้เงียบ", + "prefs-mutedpageslist": "ปิดการแจ้งเตือนเมื่อหน้าถูกลิงก์ในหน้าอื่น", "prefs-echopollupdates": "การแจ้งเตือนสด", + "echo-mobile-notifications-filter-title": "กรองการแจ้งเตือน", "echo-pref-show-poll-updates": "แสดงการแจ้งเตือนทันทีที่เข้ามา", "echo-pref-show-poll-updates-help": "แสดงจำนวนการแจ้งเตือนที่ยังไม่ได้อ่านในแถบชื่อเรื่อง และแสดงการแจ้งเตือนส่วนเล็ก ๆ ทันทีที่เข้ามา", "echo-pref-send-me": "ส่งถึงฉัน:", @@ -25,6 +27,7 @@ "echo-pref-email-format": "รูปแบบอีเมล:", "echo-pref-web": "เว็บ", "echo-pref-email": "อีเมล", + "echo-pref-push": "แอป", "echo-pref-email-frequency-never": "ไม่ต้องส่งการแจ้งเตือนทางอีเมลถึงฉัน", "echo-pref-email-frequency-immediately": "การแจ้งเตือนแบบต่างหากสำหรับทุกเหตุการณ์ทันทีที่เกิดขึ้น", "echo-pref-email-frequency-daily": "การแจ้งเตือนแบบสรุปรายวัน", @@ -33,6 +36,8 @@ "echo-pref-email-format-plain-text": "ข้อความธรรมดา", "echo-pref-cross-wiki-notifications": "แสดงการแจ้งเตือนจากวิกิอื่น", "echo-pref-notifications-blacklist": "ไม่ต้องแสดงการแจ้งเตือนจากผู้ใช้เหล่านี้\n([[mw:Special:MyLanguage/Help:Notifications#mute|เรียนรู้เพิ่มเติม]])", + "echo-pref-notifications-page-linked-title-muted-list": "ไม่ต้องแสดงการแจ้งเตือน \"การลิงก์หน้า\" สำหรับหน้าเปล่านี้ ([[mw:Special:MyLanguage/Help:Notifications#mute|เรียนรู้เพิ่มเติม]])", + "echo-pref-dont-email-read-notifications": "ไม่ต้องรวมการแจ้งเตือนที่อ่านแล้วในอีเมลสรุป", "echo-learn-more": "เรียนรู้เพิ่มเติม", "echo-log": "ปูมสาธารณะ", "echo-new-messages": "คุณมีสารใหม่", @@ -45,10 +50,12 @@ "echo-category-title-other": "{{PLURAL:$1|อื่น ๆ}}", "echo-category-title-system": "{{PLURAL:$1|ระบบ}}", "echo-category-title-system-noemail": "{{PLURAL:$1|ระบบ}}", + "echo-category-title-system-emailonly": "{{PLURAL:$1|ระบบ}}", "echo-category-title-user-rights": "{{PLURAL:$1|การเปลี่ยนแปลงสิทธิผู้ใช้}}", "echo-category-title-emailuser": "{{PLURAL:$1|อีเมลจากผู้ใช้อื่น}}", "echo-category-title-article-reminder": "{{PLURAL:$1|ตัวแจ้งเตือน}}หน้า", "echo-category-title-thank-you-edit": "{{PLURAL:$1|หลักไมล์}}การแก้ไข", + "echo-category-title-watchlist": "แก้ไขรายการเฝ้าดู", "echo-pref-tooltip-edit-user-talk": "แจ้งเตือนฉันเมื่อมีคนโพสต์ข้อความหรือการตอบกลับในหน้าพูดคุยของฉัน", "echo-pref-tooltip-article-linked": "แจ้งเตือนฉันเมื่อมีคนเชื่อมโยงจากหน้าบทความถึงหน้าที่ฉันสร้าง", "echo-pref-tooltip-reverted": "แจ้งเตือนฉันเมื่อมีคนแปลงกลับการแก้ไขของฉัน โดยใช้เครื่องมือเลิกทำหรือย้อนรวดเดียว", @@ -121,13 +128,13 @@ "notification-header-mention-other": "$1 {{GENDER:$2|กล่าวถึง}}{{GENDER:$3|คุณ}}ในหน้า <strong>$4</strong> ส่วน \"<strong>$5</strong>\"", "notification-header-mention-other-nosection": "$1 {{GENDER:$2|กล่าวถึง}}{{GENDER:$3|คุณ}}ในหน้า <strong>$4</strong>", "notification-header-mention-user-talkpage-v2": "$1 {{GENDER:$2|กล่าวถึง}}{{GENDER:$3|คุณ}}ในหน้า<strong>คุยกับผู้ใช้{{GENDER:$5|ของ}} $4</strong> ส่วน \"<strong>$6</strong>\"", - "notification-header-mention-user-talkpage-nosection": "$1 กล่าวถึงคุณในหน้า<strong>คุยกับผู้ใช้ของ $4</strong>", + "notification-header-mention-user-talkpage-nosection": "$1 ได้{{GENDER:$2|กล่าวถึง}}{{GENDER:$3|คุณ}}ในหน้า<strong>คุยกับผู้ใช้{{GENDER:$5|ของ}} $4</strong>", "notification-header-mention-agent-talkpage": "$1 {{GENDER:$2|กล่าวถึง}}{{GENDER:$3|คุณ}}ในหน้า<strong>คุยกับผู้ใช้ของ{{GENDER:$2|เขา|เธอ|พวกเขา}}</strong> ส่วน\"<strong>$4</strong>\"", "notification-header-mention-agent-talkpage-nosection": "$1 {{GENDER:$2|กล่าวถึง}}{{GENDER:$3|คุณ}}ในหน้า<strong>คุยกับผู้ใช้ของ{{GENDER:$2|เขา|เธอ|พวกเขา}}</strong>", "notification-header-mention-article-talkpage": "$1 {{GENDER:$2|กล่าวถึง}}{{GENDER:$3|คุณ}}ในหน้าคุย <strong>$4</strong> ส่วน \"<strong>$5</strong>\"", - "notification-header-mention-article-talkpage-nosection": "$1 กล่าวถึงคุณในหน้าคุย <strong>$4</strong>", - "notification-header-mention-failure-user-unknown": "ไม่ส่งการกล่าวถึง <strong>$3</strong> ของคุณเพราะหาผู้ใช้ไม่พบ", - "notification-header-mention-failure-user-anonymous": "ไม่ส่งการกล่าวถึง <strong>$3</strong> ของคุณเพราะผู้ใช้นั้นเป็นผู้ใช้นิรนาม", + "notification-header-mention-article-talkpage-nosection": "$1 {{GENDER:$2|กล่าวถึง}}{{GENDER:$3|คุณ}}ในหน้าพูดคุย <strong>$4</strong>", + "notification-header-mention-failure-user-unknown": "ไม่ได้ส่งการกล่าวถึง <strong>$3</strong> {{GENDER:$2|ของคุณ}}เพราะไม่พบชื่อผู้ใช้นี้", + "notification-header-mention-failure-user-anonymous": "ไม่ได้ส่งการกล่าวถึง <strong>$3</strong> ของคุณเพราะผู้ใช้นั้นเป็นผู้ใช้นิรนาม", "notification-header-mention-failure-too-many": "คุณพยายามกล่าวถึงผู้ใช้มากกว่า $3 คน จะไม่ส่งการกล่าวถึงทั้งหมดที่เกินขีดจำกัดนั้น", "notification-header-mention-failure-bundle": "ส่ง $3 การกล่าวถึงของคุณในหน้าคุย <strong>$4</strong> ไม่ได้", "notification-compact-header-mention-failure-user-unknown": "<strong>ไม่มีชื่อผู้ใช้:</strong> $1", diff --git a/Echo/i18n/ti.json b/Echo/i18n/ti.json index c441c13b..2f02a802 100644 --- a/Echo/i18n/ti.json +++ b/Echo/i18n/ti.json @@ -5,21 +5,82 @@ ] }, "prefs-echo": "መፍለጢታት", - "echo-pref-email": "ኢሜይል", + "prefs-emailsettings": "ኣማራጽታት ኢመይል", + "prefs-echosubscriptions": "ብዛዕባ እዞም ፍጻሜታት እዚኣቶም ኣፍልጠኒ", + "echo-mobile-notifications-filter-title": "መፍለጢታት ኣጻርይ", + "echo-pref-email-format": "ቅርጺ ኢመይል፦", + "echo-pref-web": "መርበብ", + "echo-pref-email": "ኢመይል", + "echo-pref-push": "መተግበሪታት", + "echo-pref-cross-wiki-notifications": "ካብ ካልኦት ዊኪታት መፍለጢታት ኣርእይ", "echo-learn-more": "ተወሳኺ ፍለጥ", + "echo-category-title-other": "{{PLURAL:$1|ካልእ|ካልኦት}}", + "echo-category-title-system": "{{PLURAL:$1|ስርዓት}}", + "echo-category-title-system-noemail": "{{PLURAL:$1|ስርዓት}}", + "echo-category-title-system-emailonly": "{{PLURAL:$1|ስርዓት}}", "notifications": "መፍለጢታት", + "tooltip-pt-notifications-alert": "{{GENDER:|መጠንቀቕታታትካ|መጠንቀቕታታትኪ}}", + "tooltip-pt-notifications-notice": "{{GENDER:|ምልክታታትካ|ምልክታታትኪ}}", + "echo-displaynotificationsconfiguration-notifications-by-category-header": "መፍለጢታት ብመደብ", + "echo-displaynotificationsconfiguration-enabled-default-existing-users-legend": "ነባራት ተጠቀምቲ", + "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "ሓደሽቲ ተጠቀምቲ", "echo-specialpage": "መፍለጢታት", + "echo-specialpage-section-markread": "ክፋል ከም ዘይተነበበ ኣመልክት", + "echo-specialpage-markasread": "መፍለጢ፦ ከም ዘይተነበበ ኣመልክት", + "echo-specialpage-pagefilterwidget-aria-label": "ብዊኪን ኣርእስቲ ገጽን ኣጻርይ", "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|መፍለጢ|መፍለጢታት}}", + "echo-specialpage-pagefilters-title": "ናይ ቀረባ ግዜ ንጥፈት", + "notificationsmarkread-legend": "መፍለጢ ከም ዘይተነበበ ኣመልክት", + "echo-none": "መፍለጢታት የብልካን።", + "echo-notification-placeholder": "መፍለጢታት የለዉን።", + "echo-notification-markasread": "ከም እተነበበ ኣመልክት", + "echo-notification-markasunread": "ከም ዘይተነበበ ኣመልክት", + "echo-notification-markasread-tooltip": "ከም ዘይተነበበ ኣመልክት", + "echo-notification-more-options-tooltip": "ተወሳኺ ኣማራጽታት", "notification-link-text-expand-all": "ዘርግሕ", + "notification-link-text-expand-alert-count": "{{PLURAL:$1|$1 መጠንቀቕታ|$1 መጠንቀቕታታት}} ርኣይ", + "notification-link-text-expand-notice-count": "{{PLURAL:$1|$1 ምልክታ|$1 ምልክታታት}} ርኣይ", + "notification-link-text-expand-all-count": "{{PLURAL:$1|$1 መፍለጢ|$1 መፍለጢታት}} ርኣይ", "notification-link-text-collapse-all": "ኣክብ", - "notification-welcome-linktext": "እንኳዕ ብደሓን መጻኻ", + "notification-link-text-view-message": "መልእኽቲ ርኣይ", + "notification-link-text-view-mention": "ምስማይ ርኣይ", + "notification-link-text-view-changes": "ለውጥታት {{GENDER:$1|ርኣይ|ርኣዪ}}", + "notification-link-text-view-page": "ገጽ ርኣይ", + "notification-header-edit-user-talk": "$1 ኣብ <strong>ገጽ {{GENDER:$3|ምይይጥካ|ምይይጥኪ}}</strong> መልእኽቲ {{GENDER:$2|ገዲፉ|ገዲፋ}}።", + "notification-compact-header-edit-user-talk": "$1 መልእኽቲ {{GENDER:$2|ገዲፉል|ገዲፋትል}}{{GENDER:$3|ካ|ኪ}}።", + "notification-compact-header-edit-user-talk-with-section": "$1 ኣብ «<strong>$4</strong>» መልእኽቲ {{GENDER:$2|ገዲፉል|ገዲፋትል}}{{GENDER:$3|ካ|ኪ}}።", + "notification-header-welcome": "{{GENDER:$2|እንቋዕ ብደሓን መጻእካ|እንቋዕ ብደሓን መጻእኪ}} ናብ {{SITENAME}}፣ $1! ኣብዚ {{GENDER:$2|ብምምጻእካ|ብምምጻእኪ}} ደስ ኢሉና።", + "notification-welcome-linktext": "እንቋዕ ብደሓን መጻእካ", + "notification-header-thank-you-1-edit": "ቀዳማይ {{GENDER:$2|ኣርትዖትካ ጥራይ ኢኻ ጌርካዮ|ኣርትዖትኪ ጥራይ ኢኺ ጌርክዮ}}። የቀንየልናን {{GENDER:$2|እንቋዕ ብደሓን መጻእካ|እንቋዕ ብደሓን መጻእኪ}}ን!", + "notification-header-thank-you-10-edit": "ዓስራይ {{GENDER:$2|ኣርትዖትካ ጥራይ ኢኻ ጌርካዮ|ኣርትዖትኪ ጥራይ ኢኺ ጌርክዮ}}። የቀንየልናን ቀጽልን!", + "notification-link-thank-you-edit": "{{GENDER:$1|ኣርትዖትካ|ኣርትዖትኪ}}", + "notification-link-text-view-edit": "ኣርትዖት ርኣይ", + "notification-link-article-reminder": "ገጽ ርኣይ", + "notification-header-emailuser": "$1 ኢመይል {{GENDER:$2|ሰዲዱልካ ኣሎ|ሰዲዳትልካ ኣላ}}።", + "notification-edit-talk-page-email-subject2": "$1 ኣብ {{SITENAME}} መልእኽቲ {{GENDER:$2|ገዲፉል|ገዲፋትል}}{{GENDER:$3|ካ|ኪ}}", + "notification-reverted-email-subject2": "{{PLURAL:$4|ኣርትዖት|ኣርትዖታት}}{{GENDER:$3|ካ|ኪ}} ኣብ {{SITENAME}} {{GENDER:$2|ተመሊሱ|ተመሊሶም}}", + "notification-mention-email-subject": "$1 ኣብ {{SITENAME}} {{GENDER:$2|ጠቒሱ|ጠቒሳ}}{{GENDER:$3|ካ|ኪ}}", + "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1ካ}}", + "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1 ደቒቓ|$1 ደቓይቕ}}", + "notification-timestamp-ago-hours": "{{PLURAL:$1|$1 ሰዓት|$1 ሰዓታት}}", + "notification-timestamp-ago-days": "{{PLURAL:$1|$1 መዓልቲ|$1 መዓልታት}}", + "notification-timestamp-ago-months": "{{PLURAL:$1|$1 ወርሒ|$1 ኣዋርሕ}}", + "notification-timestamp-ago-years": "{{PLURAL:$1|$1 ዓመት|$1 ዓመታት}}", "notification-timestamp-today": "ሎሚ", "notification-timestamp-yesterday": "ትማሊ", - "notification-inbox-filter-all": "ኩሉ", - "echo-overlay-link": "ኩሉ መፍለጢታት", + "notification-inbox-filter-read": "ተነቢቡ", + "notification-inbox-filter-unread": "ዘይተነበቡ", + "notification-inbox-filter-all": "ኩሎም", + "echo-notification-alert": "{{PLURAL:$1|መጠንቀቕታ ($1)|መጠቀቕታታት ($1)|100=መጠቀቕታታት (99+)}}", + "echo-notification-notice": "{{PLURAL:$1|ምልክታ ($1)|ምልክታታት ($1)|100=ምልክታታት (99+)}}", + "echo-notification-alert-text-only": "መጠቐቕታታት", + "echo-notification-notice-text-only": "ምልክታታት", + "echo-overlay-link": "ኩሎም መፍለጢታት", "echo-overlay-title": "<b>መፍለጢታት</b>", + "echo-mark-all-as-read": "ኩሉ ከም ዝተነበብ ኣመልክት", "echo-displaysnippet-title": "ሓድሽ መፍለጢ", "echo-date-today": "ሎሚ", "echo-date-yesterday": "ትማሊ", - "echo-email-batch-link-text-view-all-notifications": "ኩሉ መፍለጢታት ርኣይ" + "echo-email-batch-subject-daily": "ኣብ {{SITENAME}} {{PLURAL:$2|ሓድሽ መፍለጢ|ሓደሽቲ መፍለጢታት}} ኣሎካ", + "echo-email-batch-link-text-view-all-notifications": "ኩሎም መፍለጢታት ርኣይ" } diff --git a/Echo/i18n/tk.json b/Echo/i18n/tk.json new file mode 100644 index 00000000..026531d7 --- /dev/null +++ b/Echo/i18n/tk.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Hanberke" + ] + }, + "tooltip-pt-notifications-alert": "{{GENDER:|Duýduryşlaryňyz}}" +} diff --git a/Echo/i18n/tl.json b/Echo/i18n/tl.json index 1fab9941..6b19b28b 100644 --- a/Echo/i18n/tl.json +++ b/Echo/i18n/tl.json @@ -4,10 +4,12 @@ "AnakngAraw", "Brazal.dang", "Emem.calist", + "GinawaSaHapon", "Jojit fb", "Leeheonjin", "Sky Harbor", - "TheSleepyhollow02" + "TheSleepyhollow02", + "Yivan000" ] }, "echo-desc": "Sistema ng pagpapabatid", @@ -18,7 +20,7 @@ "echo-pref-send-to": "Ipadala kay:", "echo-pref-email-format": "Kaanyuan ng e-liham:", "echo-pref-web": "Web", - "echo-pref-email": "E-liham", + "echo-pref-email": "Email", "echo-pref-email-frequency-never": "Huwag magpadala sa akin ng anumang pabatid sa e-liham", "echo-pref-email-frequency-immediately": "Mga indibiduwal na pabatid nang papasok ito", "echo-pref-email-frequency-daily": "Isang arawang buod ng mga pabatid", @@ -37,7 +39,7 @@ "echo-pref-tooltip-mention": "Ipabatid sa aking kung may kumawing sa aking pahina ng tagagamit mula sa anumang pahinang usapan.", "echo-pref-tooltip-article-reminder": "PakiTawag-Pansin mo ako kapag ito ay naitanong.", "notifications": "Mga pagpapabatid", - "tooltip-pt-notifications-alert": "{{GENDER:|Iyong}} mga babala", + "tooltip-pt-notifications-alert": "Mga alerto mo", "echo-specialpage": "Mga pabatid", "echo-none": "Wala kang mga pabatid.", "echo-notification-loginrequired": "Kailangan mong mag-login upang makita ang iyong mga pabatid.", diff --git a/Echo/i18n/tly.json b/Echo/i18n/tly.json index a580afce..45340f26 100644 --- a/Echo/i18n/tly.json +++ b/Echo/i18n/tly.json @@ -1,9 +1,14 @@ { "@metadata": { "authors": [ - "Patriot Kur" + "Patriot Kur", + "Гусейн" ] }, "echo-pref-email": "Enomə", - "notification-inbox-filter-read": "Bahand" + "tooltip-pt-notifications-alert": "{{GENDER:|Şımə}} xəbədon", + "notification-timestamp-today": "Imrüj", + "notification-inbox-filter-read": "Bahand", + "notification-inbox-filter-all": "Həmə", + "echo-date-today": "Imrüj" } diff --git a/Echo/i18n/tok.json b/Echo/i18n/tok.json new file mode 100644 index 00000000..85c0d9a2 --- /dev/null +++ b/Echo/i18n/tok.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Robin van der Vliet" + ] + }, + "notification-welcome-linktext": "kama pona" +} diff --git a/Echo/i18n/tr.json b/Echo/i18n/tr.json index 920b4ecc..6c60e846 100644 --- a/Echo/i18n/tr.json +++ b/Echo/i18n/tr.json @@ -8,6 +8,7 @@ "Ece Alpdeniz", "Emperyan", "HakanIST", + "Hedda", "Incelemeelemani", "Joseph", "KorkmazO", @@ -16,15 +17,21 @@ "McAang", "Meelo", "MrSchipunov", + "MuratTheTurkish", "Nemo bis", "Rapsar", "Sadrettin", + "SaldırganSincap", "Sayginer", "Serkanland", + "Sezgin İbiş", "Stultiwikia", "Superyetkin", "ToprakM", - "Violetanka" + "Uncitoyen", + "Victor Trevor", + "Violetanka", + "Vito Genovese" ] }, "echo-desc": "Kullanıcıları olaylar ve mesajlar hakkında bilgilendiren sistem", @@ -56,12 +63,12 @@ "echo-pref-dont-email-read-notifications": "Özet e-postalara okundu bildirimleri eklemeyin", "echo-learn-more": "Daha fazla bilgi", "echo-log": "Genel günlük", - "echo-new-messages": "Yeni mesajınız var", - "echo-category-title-edit-user-talk": "Tartışma sayfası {{PLURAL:$1|mesajı|mesajları}}", + "echo-new-messages": "Yeni bir mesajınız var", + "echo-category-title-edit-user-talk": "Mesaj sayfama {{PLURAL:$1|düzenleme|düzenlemeler}}", "echo-category-title-article-linked": "Sayfa {{PLURAL:$1|bağlantısı|bağlantıları}}", "echo-category-title-reverted": "Değişiklik {{PLURAL:$1|iptali|iptalleri}}", "echo-category-title-mention": "{{PLURAL:$1|Bahsetme|Bahsetmeler}}", - "echo-category-title-mention-failure": "Başarısız {{PLURAL:$1|bahsetme|bahsetme}}", + "echo-category-title-mention-failure": "Başarısız {{PLURAL:$1|bahsetme|bahsetmeler}}", "echo-category-title-mention-success": "Başarılı {{PLURAL:$1|bahsetme|bahsetmeler}}", "echo-category-title-other": "{{PLURAL:$1|Diğer}}", "echo-category-title-system": "{{PLURAL:$1|Sistem}}", @@ -69,11 +76,11 @@ "echo-category-title-system-emailonly": "{{PLURAL:$1|Sistem}}", "echo-category-title-user-rights": "{{PLURAL:$1|Kullanıcı hakları değişikliği|Kullanıcı hakları değişiklikleri}}", "echo-category-title-emailuser": "{{PLURAL:$1|Diğer kullanıcıdan gelen e-posta|Diğer kullanıcılardan gelen e-postalar}}", - "echo-category-title-article-reminder": "Sayfa {{PLURAL:$1|hatırlatıcı|hatırlatıcı}}", - "echo-category-title-thank-you-edit": "{{PLURAL:$1|Kilometre taşlarını}} düzenle", + "echo-category-title-article-reminder": "Sayfa {{PLURAL:$1|hatırlatıcısı|hatırlatıcıları}}", + "echo-category-title-thank-you-edit": "{{PLURAL:$1|Kilometre taşı|Kilometre taşları}} düzenlemesi", "echo-category-title-watchlist": "İzlenen sayfada düzenleme", "echo-category-title-minor-watchlist": "İzlenen sayfada küçük düzenleme", - "echo-pref-tooltip-edit-user-talk": "Bir kullanıcı mesaj sayfamı değiştirdiğinde bana bildirim gönder.", + "echo-pref-tooltip-edit-user-talk": "Birisi kullanıcı mesaj sayfamı düzenlediğinde bana bildir.", "echo-pref-tooltip-article-linked": "Bir kullanıcı, bir sayfadan benim oluşturduğum bir sayfaya bağlantı verdiğinde bana bildirim gönder.", "echo-pref-tooltip-reverted": "Yaptığım bir değişiklik geri alındığı takdirde bana bildirim gönder.", "echo-pref-tooltip-mention": "Kullanıcı sayfama bağlantı verildiğinde bana bildirim gönder.", @@ -102,12 +109,12 @@ "echo-displaynotificationsconfiguration-mandatory-notification-methods-by-category-legend": "Hangi bildirim yöntemleri ilgili kategori için zorunlu olacak", "echo-specialpage": "Bildirimler", "echo-specialpage-section-markread": "Grubu okunmuş olarak işaretle", - "echo-specialpage-markasread": "Bildirim: Okundu olarak İşaretle", + "echo-specialpage-markasread": "Bildirim: Okundu olarak işaretle", "echo-specialpage-markasread-invalid-id": "Geçersiz olay kimliği", "echo-specialpage-pagefilterwidget-aria-label": "Viki ve sayfa başlığına göre filtrele", "echo-specialpage-special-help-menu-widget-aria-label": "Ek seçenekler ve Bildirim tercihleri.", - "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|bildirim|bildirim}}", - "echo-specialpage-pagefilters-title": "Son hareketler", + "echo-specialpage-pagination-numnotifications": "$1 bildirim", + "echo-specialpage-pagefilters-title": "Son etkinlik", "echo-specialpage-pagefilters-subtitle": "Okunmamış bildirim bulunan sayfalar", "notificationsmarkread-legend": "Bilidirimi okunmuş olarak işaretle", "echo-none": "Bildiriminiz bulunmuyor.", @@ -115,32 +122,32 @@ "echo-api-failure-cross-wiki": "Uzak etki alanı için erişim engellendi.", "echo-notification-placeholder": "Hiçbir bildirim yok.", "echo-notification-placeholder-filters": "Bu kriterlere uyan herhangi bir bildirim yok.", - "echo-notification-loginrequired": "Bildirimlerinizi görmek için giriş yapmalısınız.", + "echo-notification-loginrequired": "Bildirimlerinizi görmek için oturum açmalısınız.", "echo-notification-popup-loginrequired": "Bildirimlerinizi görmek için lütfen oturum açın.", "echo-notification-markasread": "Okundu olarak işaretle", "echo-notification-markasunread": "Okunmamış olarak işaretle", - "echo-notification-markasread-tooltip": "Okunmuş olarak işaretle", + "echo-notification-markasread-tooltip": "Okundu olarak işaretle", "echo-notification-more-options-tooltip": "Daha fazla seçenek", "notification-dynamic-actions-mute-page-linked": "\"$1\" sayfasındaki bağlantı bildirimlerini {{GENDER:$2|sessize al}}", "notification-dynamic-actions-mute-page-linked-confirmation": "\"$1\" sayfası için \"Sayfa bağlantısı\" bildirimleri artık devre dışı", "notification-dynamic-actions-mute-page-linked-confirmation-description": "Sessiz sayfalarınızı istediğiniz zaman [$1 tercihlerinizden] {{GENDER:$2|yönetebilirsiniz}}.", - "notification-dynamic-actions-unmute-page-linked": "\"$1\" sayfasındaki bağlantı bildirimlerini {{GENDER:$2|sesi aç}}", + "notification-dynamic-actions-unmute-page-linked": "\"$1\" sayfasındaki bağlantı bildirimlerini {{GENDER:$2|sesi açın}}", "notification-dynamic-actions-unmute-page-linked-confirmation": "\"$1\" sayfası için \"Sayfa bağlantısı\" bildirimleri artık etkin", "notification-dynamic-actions-unmute-page-linked-confirmation-description": "Sesli sayfalarınızı istediğiniz zaman [$1 tercihlerinizden] {{GENDER:$2|yönetebilirsiniz}}.", - "notification-dynamic-actions-unwatch": "\"$1\" üzerindeki yeni etkinliği izlemeyi {{GENDER:$3|bırakın}}", + "notification-dynamic-actions-unwatch": "\"$1\" sayfasındaki yeni etkinliği izlemeyi {{GENDER:$3|bırakın}}", "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3|Siz}} artık \"$1\" sayfasını izlemiyorsunuz", "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|Siz}}, istediğiniz zaman [$2 bu sayfayı] izleyebilirsiniz.", - "notification-dynamic-actions-watch": "\"$1\" üzerindeki yeni etkinlik {{GENDER:$3|izleyin}}", - "notification-dynamic-actions-watch-confirmation": "{{GENDER:$3|Siz}} şimdi \"$1\" sayfasını izliyorsunuz", + "notification-dynamic-actions-watch": "\"$1\" sayfasındaki yeni etkinlik {{GENDER:$3|izleyin}}", + "notification-dynamic-actions-watch-confirmation": "{{GENDER:$3|Siz}} artık \"$1\" sayfasını izliyorsunuz", "notification-dynamic-actions-watch-confirmation-description": "{{GENDER:$3|Siz}}, [$2 bu sayfada] izlemeyi her zaman durdurabilirsiniz.", "notification-link-text-expand-all": "Genişlet", - "notification-link-text-expand-alert-count": "{{PLURAL:$1|$1 uyarı|$1 uyarı}} göster", - "notification-link-text-expand-notice-count": "{{PLURAL:$1|$1 bildirim|$1 bildirim}} göster", + "notification-link-text-expand-alert-count": "{{PLURAL:$1|$1 uyarıyı|$1 uyarıyı}} görüntüle", + "notification-link-text-expand-notice-count": "{{PLURAL:$1|$1 bildirimi|$1 bildirimi}} görüntüle", "notification-link-text-expand-all-count": "{{PLURAL:$1|$1 bildirimi|$1 bildirimi}} görüntüle", "notification-link-text-collapse-all": "Daralt", "notification-link-text-view-message": "Mesajı görüntüle", - "notification-link-text-view-mention": "Bahsi görüntüle", - "notification-link-text-view-mention-failure": "{{PLURAL:$1|Bahsetmeyi göster|Bahsetmeleri göster}}", + "notification-link-text-view-mention": "Bahsetmeyi görüntüle", + "notification-link-text-view-mention-failure": "{{PLURAL:$1|Bahsetmeyi görüntüle|Bahsetmeleri görüntüle}}", "notification-link-text-view-changes": "Değişiklikleri {{GENDER:$1|görüntüle}}", "notification-link-text-view-page": "Sayfayı görüntüle", "notification-header-edit-user-talk": "$1, <strong>mesaj {{GENDER:$3|sayfanıza}}</strong> bir mesaj {{GENDER:$2|bıraktı}}.", @@ -149,8 +156,8 @@ "notification-compact-header-edit-user-talk-with-section": "$1 {{GENDER:$3|size}} \"<strong>$4</strong>\" mesajını {{GENDER:$2|bıraktı}}.", "notification-header-page-linked": "<strong>$4</strong> sayfasından <strong>$3</strong> sayfasına bağlantı verildi.", "notification-compact-header-page-linked": "<strong>$1</strong> bağlantılı.", - "notification-bundle-header-page-linked": "{{PLURAL:$5|$5 sayfadan|100=99+ sayfadan}}, <strong>$3</strong> sayfasına bağlantı verildi.", - "notification-header-article-reminder": "{{GENDER:$2|Size}} hatırlatılmasını istediğiniz bir sayfası <strong>$3</strong>", + "notification-bundle-header-page-linked": "{{PLURAL:$5|$5 sayfadan|100=99+ sayfadan}}, <strong>$3</strong> sayfasına bağlantı verildi.", + "notification-header-article-reminder": "{{GENDER:$2|Size}} hatırlatılmasını istediğiniz bir sayfası <strong>$3</strong> altındadır", "notification-link-text-what-links-here": "Bu sayfaya verilen tüm bağlantılar", "notification-header-mention-other": "$1, <strong>$4</strong> sayfasının \"<strong>$5</strong>\" başlığında {{GENDER:$3|sizden}} {{GENDER:$2|bahsetti}}.", "notification-header-mention-other-nosection": "$1, <strong>$4</strong> sayfasında {{GENDER:$3|sizden}} {{GENDER:$2|bahsetti}}.", @@ -168,14 +175,14 @@ "notification-compact-header-mention-failure-user-anonymous": "<strong>IP'lerden bahsedilemez:</strong> $1", "notification-header-mention-success": "<strong>$3</strong> kullanıcısına başarılı bir şekilde {{GENDER:$2|seslendiniz}}.", "notification-header-mention-success-bundle": "<strong>$4</strong> sayfasında $3 kullanıcıya {{GENDER:$2|seslendiniz}}.", - "notification-compact-header-mention-success": "<strong>{{GENDER:$2|Şununla bahsettiniz}}:</strong> $3", + "notification-compact-header-mention-success": "<strong>{{GENDER:$2|Seslendiğiniz kullanıcı}}:</strong> $3", "notification-header-mention-status-bundle": "<strong>$4</strong> tartışma sayfasında {{GENDER:$2|yaptınız}} ile ilgili {{PLURAL:$3|bir bildirim|$3 bildirim}}: {{PLURAL:$5|$5 gönderilmedi}}, {{PLURAL:$6|$6 gönderildi}}.", "notification-header-user-rights-add-only": "{{GENDER:$4|Kullanıcı}} haklarınız {{GENDER:$1|değiştirildi}}. Eklendiğiniz yer: $2.", "notification-header-user-rights-remove-only": "{{GENDER:$4|Kullanıcı}} haklarınız {{GENDER:$1|değiştirildi}}. Çıkarıldığınız yer: $2.", "notification-header-user-rights-add-and-remove": "{{GENDER:$6|Kullanıcı}} haklarınız {{GENDER:$1|değiştirildi}}. Eklendiğiniz yer: $2. Çıkarıldığınız yer: $4.", "notification-header-user-rights-expiry-change": "Aşağıdaki {{PLURAL:$3|grup|grup}} için {{GENDER:$4|sizin}} üyeliğinin sona ermesi {{GENDER:$1|değiştirildi}}: $2.", "notification-header-welcome": "{{SITENAME}}'ye {{GENDER:$2|hoş geldin}} $1! Burada olmandan çok memnunuz.", - "notification-header-mention-summary": "<strong>$4</strong> bir düzenleme özetinde {{GENDER:$3|size}} $1 {{GENDER:$2|bahsetti}}.", + "notification-header-mention-summary": "$1, <strong>$4</strong> sayfasının değişiklik özetinde {{GENDER:$3|sizden}} {{GENDER:$2|bahsetti}}.", "notification-header-watchlist-changed": "$1, <strong>$3</strong> {{GENDER:$2|değiştirdi}}, {{GENDER:$4|sizin}} izleme listesindeki {{PLURAL:$5|$5 kere}} bir sayfa.", "notification-header-watchlist-created": "$1, <strong>$3</strong> {{GENDER:$2|oluşturdu}}, {{GENDER:$4|sizin}} izleme listesindeki {{PLURAL:$5|$5 kere}} bir sayfa.", "notification-header-watchlist-deleted": "$1, <strong>$3</strong> {{GENDER:$2|sildi}}, {{GENDER:$4|sizin}} izleme listesindeki {{PLURAL:$5|$5 kere}} bir sayfa.", @@ -189,31 +196,31 @@ "notification-welcome-linktext": "Hoş geldiniz", "notification-header-thank-you-1-edit": "İlk {{GENDER:$2|değişikliğinizi}} {{GENDER:$2|yaptınız}}; teşekkürler ve hoş geldiniz!", "notification-header-thank-you-10-edit": "Onuncu {{GENDER:$2|değişikliğinizi}} {{GENDER:$2|yaptınız}}; teşekkürler, lütfen devam edin!", - "notification-header-thank-you-100-edit": "Yüzüncü {{GENDER:$2|değişikliğinizi}} {{GENDER:$2|yaptınız}}; çok teşekkürler!", - "notification-header-thank-you-1000-edit": "Bininci {{GENDER:$2|değişikliğinizi}} {{GENDER:$2|yaptınız}}; büyük katkınız için çok teşekkürler!", - "notification-header-thank-you-10000-edit": "On bininci {{GENDER:$2|değişikliğinizi}} {{GENDER:$2|yaptınız}}; çok çok teşekkürler!", - "notification-header-thank-you-100000-edit": "Yüz bininci {{GENDER:$2|değişikliğinizi}} {{GENDER:$2|yaptınız}}; inanılmaz katkınız için teşekkürler!", - "notification-header-thank-you-1000000-edit": "Bir milyonuncu {{GENDER:$2|değişikliğinizi}} {{GENDER:$2|yaptınız}}; ağızları açık bırakan katkınız için teşekkürler!", + "notification-header-thank-you-100-edit": "Yüzüncü {{GENDER:$2|değişikliğinizi}} {{GENDER:$2|yaptınız}}; teşekkürler!", + "notification-header-thank-you-1000-edit": "Bininci {{GENDER:$2|değişikliğinizi}} {{GENDER:$2|yaptınız}}; katkılarınız için teşekkürler!", + "notification-header-thank-you-10000-edit": "On bininci {{GENDER:$2|değişikliğinizi}} {{GENDER:$2|yaptınız}}; inanılmaz katkılarınız için çok teşekkürler!", + "notification-header-thank-you-100000-edit": "Yüz bininci {{GENDER:$2|değişikliğinizi}} {{GENDER:$2|yaptınız}}; Vikipedi, olağanüstü çalışmalarınızdan dolayı size müteşekkirdir.", + "notification-header-thank-you-1000000-edit": "Bir milyonuncu {{GENDER:$2|değişikliğinizi}} {{GENDER:$2|yaptınız}}; Vikipedi'yi benimsediğiniz ve burayı daha iyi bir hâle getirdiğiniz için sonsuz teşekkürler!", "notification-header-thank-you-10000000-edit": "On milyonuncu {{GENDER:$2|değişikliğinizi}} {{GENDER:$2|yaptınız}}; parlak özveri bırakan katkınız için teşekkürler!", "notification-link-thank-you-edit": "{{GENDER:$1|Sizin}} düzenleme", "notification-link-text-view-edit": "Değişikliği görüntüle", "notification-link-article-reminder": "Sayfayı görüntüle", "notification-header-reverted": "{{PLURAL:$4|$3 sayfasındaki değişikliğiniz|$3 sayfasındaki değişiklikleriniz}} {{GENDER:$2|geri alındı}}.", "notification-header-emailuser": "$1 size bir e-posta {{GENDER:$2|gönderdi}}.", - "notification-edit-talk-page-email-subject2": "$1, {{SITENAME}} sayfasında {{GENDER:$3|size}} bir mesaj {{GENDER:$2|bıraktı}}", + "notification-edit-talk-page-email-subject2": "$1, {{SITENAME}} üzerinde {{GENDER:$3|size}} bir mesaj {{GENDER:$2|bıraktı}}", "notification-page-linked-email-subject": "{{SITENAME}} {{GENDER:$3|siz}} sayfasında oluşturulan bir sayfası bağlandı", "notification-reverted-email-subject2": "{{GENDER:$3|Sizin}} {{GENDER:$4|düzenlemeniz|düzenlememiz}} \n{{SITENAME}} üzerinde {{GENDER:$2|geri alındı}}", "notification-mention-email-subject": "$1, {{SITENAME}} sitesinde {{GENDER:$3|sizden}} {{GENDER:$2|bahsetti}}", - "notification-user-rights-email-subject": "{{SITENAME}} adresinimzde kullanıcı {{GENDER:$3|haklarınız}} değişti", - "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1 s}}", - "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1d}}", + "notification-user-rights-email-subject": "{{SITENAME}} üzerinde kullanıcı {{GENDER:$3|haklarınız}} değişti", + "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1sn}}", + "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1dk}}", "notification-timestamp-ago-hours": "{{PLURAL:$1|$1sa}}", "notification-timestamp-ago-days": "{{PLURAL:$1|$1g}}", "notification-timestamp-ago-months": "{{PLURAL:$1|$1ay}}", "notification-timestamp-ago-years": "{{PLURAL:$1|$1yıl}}", "notification-timestamp-today": "Bugün", "notification-timestamp-yesterday": "Dün", - "notification-inbox-filter-read": "Oku", + "notification-inbox-filter-read": "Okunmuş", "notification-inbox-filter-unread": "Okunmamış", "notification-inbox-filter-all": "Hepsi", "echo-specialmute-label-mute-notifications": "Bu {{GENDER:$1|kullanıcıdan}} gelen bildirimleri yoksay", @@ -228,7 +235,7 @@ "echo-overlay-title": "<b>Bildirimler</b>", "echo-mark-all-as-read": "Tümünü okundu olarak işaretle", "echo-mark-all-as-read-confirmation": "$1 {{PLURAL:$1|bildirim|bildirim}} okunmuş olarak işaretlendi", - "echo-mark-wiki-as-read": "Tümünü seçilen wikide okundu olarak işaretle: $1", + "echo-mark-wiki-as-read": "Tümünü seçilen vikide okundu olarak işaretle: $1", "echo-displaysnippet-title": "Yeni bildirim", "echo-date-today": "Bugün", "echo-date-yesterday": "Dün", @@ -238,7 +245,12 @@ "echo-email-batch-body-intro-daily": "Merhaba $1,\nBurada {{SITENAME}} için bu günün etkinlik özetini bulabilirsiniz.", "echo-email-batch-body-intro-weekly": "Merhaba $1,\nBurada {{SITENAME}} için bu haftaki etkinlik özetini bulabilirsiniz.", "echo-email-batch-link-text-view-all-notifications": "Tüm bildirimleri göster", - "notification-header-foreign-alert": "{{PLURAL:$5|$5 diğer Viki projesinden}} uyarınız var", + "notification-header-foreign-alert": "{{PLURAL:$5|$5 diğer viki projesinden}} uyarınız var", "notification-header-foreign-notice": "{{PLURAL:$5|Diğer viki|$5 diğer viki}}den daha fazla bildirim", - "notification-header-foreign-all": "{{PLURAL:$5|Başka bir viki|$5 diğer vikiler}} tarafından gönderilen diğer bildirimler" + "notification-header-foreign-all": "{{PLURAL:$5|Başka bir viki|$5 diğer vikiler}} tarafından gönderilen diğer bildirimler", + "right-manage-all-push-subscriptions": "Tüm push aboneliklerini yönet", + "action-manage-all-push-subscriptions": "tüm push aboneliklerini yönet", + "group-push-subscription-manager": "Push abonelik yöneticileri", + "group-push-subscription-manager-member": "{{GENDER:$1|push abonelik yöneticisi}}", + "grouppage-push-subscription-manager": "{{ns:project}}:Push abonelik yöneticileri" } diff --git a/Echo/i18n/tw.json b/Echo/i18n/tw.json new file mode 100644 index 00000000..b5bce5ad --- /dev/null +++ b/Echo/i18n/tw.json @@ -0,0 +1,23 @@ +{ + "@metadata": { + "authors": [ + "Robertjamal12", + "TAMAKNARAD" + ] + }, + "echo-desc": "System for notifying users about events and messages", + "prefs-echo": "Nkaebɔ", + "prefs-echosubscriptions": "Bɔ me enkae ɛfa ndwumade no ho", + "prefs-echocrosswiki": "Cross-wiki hon nkaebɔ", + "prefs-blocknotificationslist": "Kan na ano tum", + "prefs-mutedpageslist": "Muted pages for page link notifications", + "prefs-echopollupdates": "Mprenprem nkaebɔ", + "echo-mobile-notifications-filter-title": "Sɔne nkaebɔ yi so", + "echo-pref-show-poll-updates": "Bue nkaebɔ foforɔ bere a me nya naa", + "echo-pref-send-me": "Fa mane me:", + "echo-pref-send-to": "Mane kɔ:", + "echo-pref-web": "Web", + "echo-pref-email-frequency-never": "Ɛmanae me ɛnsem yi hon nkaebɔ beaa", + "echo-pref-email-frequency-daily": "Da bea nkaebɔ tɔfa", + "echo-pref-email-frequency-weekly": "Nawɔtwen nkaebɔ tɔfa" +} diff --git a/Echo/i18n/udm.json b/Echo/i18n/udm.json index 3cba93c6..43c2883d 100644 --- a/Echo/i18n/udm.json +++ b/Echo/i18n/udm.json @@ -3,9 +3,11 @@ "authors": [ "AlnashPiyash2", "Kaganer", + "Kotwys", "Wadorgurt" ] }, + "echo-category-title-edit-user-talk": "Вераськон бамме {{PLURAL:$1|тупатэм|тупатэмъёс}}", "tooltip-pt-notifications-alert": "{{GENDER:|Тӥляд}} ивортонъёсты", "notification-inbox-filter-all": "Ваньзэ" } diff --git a/Echo/i18n/uk.json b/Echo/i18n/uk.json index 9cf464d2..0fa14168 100644 --- a/Echo/i18n/uk.json +++ b/Echo/i18n/uk.json @@ -6,7 +6,9 @@ "Amire80", "Andriykopanytsia", "Base", + "DDPAT", "Green Zero", + "Ice bulldog", "Lxlalexlxl", "Macofe", "Movses", @@ -37,7 +39,7 @@ "echo-pref-email-format": "Формат листів:", "echo-pref-web": "Веб", "echo-pref-email": "Ел. пошта", - "echo-pref-push": "Пуш (лише програмки)", + "echo-pref-push": "Програмки", "echo-pref-email-frequency-never": "Не надсилати мені жодних сповіщень електронною поштою", "echo-pref-email-frequency-immediately": "Сповіщати про кожну подію одразу", "echo-pref-email-frequency-daily": "Щоденна збірка сповіщень", @@ -51,7 +53,7 @@ "echo-learn-more": "Дізнатися більше", "echo-log": "Публічний журнал", "echo-new-messages": "У Вас є нові повідомлення", - "echo-category-title-edit-user-talk": "{{PLURAL:$1|Повідомлення}} на сторінці обговорення", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Зміна|Змін}} на моїй сторінці обговорення користувача", "echo-category-title-article-linked": "{{PLURAL:$1|Посилання}} на сторінку", "echo-category-title-reverted": "Скасування {{PLURAL:$1|редагування|редагувань}}", "echo-category-title-mention": "{{PLURAL:$1|Згадування}}", @@ -67,7 +69,7 @@ "echo-category-title-thank-you-edit": "{{PLURAL:$1|Віхи}} редагування", "echo-category-title-watchlist": "Редагування сторінки зі списку спостереження", "echo-category-title-minor-watchlist": "Незначне редагування сторінки зі списку спостереження", - "echo-pref-tooltip-edit-user-talk": "Повідомляти мене, коли хтось надсилає повідомлення або відповідає на моїй сторінці обговорення.", + "echo-pref-tooltip-edit-user-talk": "Повідомляти мене, коли хтось редагуватиме мою сторінку обговорення користувача.", "echo-pref-tooltip-article-linked": "Повідомляти мене, коли хтось додає посилання на створену мною сторінку.", "echo-pref-tooltip-reverted": "Повідомляти мене, коли хтось відхиляє моє редагування за допомогою скасування чи відкату.", "echo-pref-tooltip-mention": "Повідомляти мене, коли хтось посилається на мою сторінку користувача.", @@ -101,6 +103,7 @@ "echo-specialpage-pagefilterwidget-aria-label": "Фільтрувати за вікі та назвою сторінки", "echo-specialpage-special-help-menu-widget-aria-label": "Додаткові опції та налаштування Сповіщень.", "echo-specialpage-pagination-numnotifications": "$1 {{PLURAL:$1|сповіщення|сповіщення|сповіщень}}", + "echo-specialpage-pagination-range": "$1 - $2", "echo-specialpage-pagefilters-title": "Нещодавня активність", "echo-specialpage-pagefilters-subtitle": "Сторінки з непрочитаними сповіщеннями", "notificationsmarkread-legend": "Позначити сповіщення прочитаним", @@ -140,7 +143,7 @@ "notification-header-edit-user-talk": "$1 {{GENDER:$2|залишив|залишила}} повідомлення на <strong>{{GENDER:$3|Вашій}} сторінці обговорення</strong>.", "notification-header-edit-user-talk-with-section": "$1 {{GENDER:$2|залишив|залишила}} повідомлення на <strong>{{GENDER:$3|Вашій}} сторінці обговорення</strong> у «<strong>$4</strong>».", "notification-compact-header-edit-user-talk": "$1 {{GENDER:$2|залишив|залишила}} {{GENDER:$3|Вам}} повідомлення.", - "notification-compact-header-edit-user-talk-with-section": "$1 {{GENDER:$2|залишив|залишила}} {{GENDER:$3|Вам}} повідомленя в «<strong>$4</strong>».", + "notification-compact-header-edit-user-talk-with-section": "$1 {{GENDER:$2|залишив|залишила}} {{GENDER:$3|Вам}} повідомлення в «<strong>$4</strong>».", "notification-body-edit-user-talk-with-section": "$1", "notification-header-page-linked": "На сторінці <strong>$4</strong> додано посилання на <strong>$3</strong>.", "notification-compact-header-page-linked": "Посилання з <strong>$1</strong>.", @@ -181,6 +184,7 @@ "notification-header-watchlist-multiuser-deleted": "<strong>$1</strong>, сторінку з {{GENDER:$2|Вашого}} списку спостереження, вилучено $3 {{PLURAL:$3|раз|рази|раз}}.", "notification-header-watchlist-multiuser-moved": "<strong>$1</strong>, сторінку з {{GENDER:$2|Вашого}} списку спостереження, перейменовано $3 {{PLURAL:$3|раз|рази|раз}}.", "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>, сторінку з {{GENDER:$2|Вашого}} списку спостереження, відновлено $3 {{PLURAL:$3|раз|рази|раз}}.", + "notification-body-watchlist-once": "Інших сповіщень електронною поштою за майбутньої активності не буде, якщо тільки ви не {{GENDER:$1|не відвідаєте}} цю сторінку, увійшовши в систему.", "notification-welcome-linktext": "Ласкаво просимо!", "notification-header-thank-you-1-edit": "{{GENDER:$2|Ви}} щойно зробили {{GENDER:$2|своє}} перше редагування; дякуємо {{GENDER:$2|Вам}} і ласкаво просимо!", "notification-header-thank-you-10-edit": "{{GENDER:$2|Ви}} щойно зробили {{GENDER:$2|своє}} десяте редагування; дякуємо {{GENDER:$2|Вам}}, продовжуйте!", @@ -200,18 +204,18 @@ "notification-reverted-email-subject2": "{{GENDER:$3|{{PLURAL:$4|1=Ваше редагування|Ваші редагування}}}} на сайті {{SITENAME}} було {{GENDER:$2|скасовано}}", "notification-mention-email-subject": "$1 {{GENDER:$2|згадав|згадала}} {{GENDER:$3|Вас}} на сайті {{SITENAME}}", "notification-user-rights-email-subject": "{{GENDER:$3|Ваші}} права користувача на веб-сайті {{SITENAME}} було змінено", - "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1с}}", - "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1хв}}", - "notification-timestamp-ago-hours": "{{PLURAL:$1|$1год}}", - "notification-timestamp-ago-days": "{{PLURAL:$1|$1д.}}", - "notification-timestamp-ago-months": "{{PLURAL:$1|$1міс.}}", - "notification-timestamp-ago-years": "{{PLURAL:$1|$1р.|$1рр.}}", + "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1 с}}", + "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1 хв}}", + "notification-timestamp-ago-hours": "{{PLURAL:$1|$1 год}}", + "notification-timestamp-ago-days": "{{PLURAL:$1|$1 д.}}", + "notification-timestamp-ago-months": "{{PLURAL:$1|$1 міс.}}", + "notification-timestamp-ago-years": "{{PLURAL:$1|$1 р.|$1 рр.}}", "notification-timestamp-today": "Сьогодні", "notification-timestamp-yesterday": "Вчора", "notification-inbox-filter-read": "Прочитане", "notification-inbox-filter-unread": "Непрочитане", "notification-inbox-filter-all": "Усе", - "echo-specialmute-label-mute-notifications": "Вимкнути сповіщення від цього користувача", + "echo-specialmute-label-mute-notifications": "Вимкнути сповіщення від {{GENDER:$1|цього користувача|цієї користувачки}}", "echo-email-plain-footer": "Щоб визначити, які повідомлення ми {{GENDER:$1|Вам}} надсилаємо, перевірте свої налаштування:", "echo-email-html-footer-preference-link-text": "перевірте {{GENDER:$1|свої}} налаштування", "echo-email-html-footer-with-link": "Щоб контролювати, які листи ми {{GENDER:$2|Вам}} надсилаємо, $1.", @@ -228,6 +232,7 @@ "echo-date-today": "Сьогодні", "echo-date-yesterday": "Вчора", "notification-bundle-header-edit-user-talk-v2": "{{PLURAL:$1|Одне нове повідомлення|$1 нові повідомлення|$1 нових повідомлень|100=99+ нових повідомлень}} на <strong>{{GENDER:$3|Вашій}} сторінці обговорення</strong>.", + "echo-email-batch-bullet": "•", "echo-email-batch-subject-daily": "У Вас {{PLURAL:$2|нове сповіщення|нові сповіщення|нових сповіщень}} на сайті {{SITENAME}}", "echo-email-batch-subject-weekly": "У Вас {{PLURAL:$2|нове сповіщення|нові сповіщення|нових сповіщень}} на сайті {{SITENAME}} цього тижня", "echo-email-batch-body-intro-daily": "Привіт $1!\nОсь підсумок денної активності на сайті {{SITENAME}} для вас.", @@ -235,5 +240,12 @@ "echo-email-batch-link-text-view-all-notifications": "Переглянути усі сповіщення", "notification-header-foreign-alert": "Більше звісток з {{PLURAL:$5|$5 іншої вікі|$5 інших вікі}}", "notification-header-foreign-notice": "Більше сповіщень з {{PLURAL:$5|іншої вікі|$5 інших вікі}}", - "notification-header-foreign-all": "Більше сповіщень з {{PLURAL:$5|іншої вікі|$5 інших вікі}}" + "notification-header-foreign-all": "Більше сповіщень з {{PLURAL:$5|іншої вікі|$5 інших вікі}}", + "echo-foreign-wiki-lang": "$1 - $2", + "echo-badge-count": "{{PLURAL:$1|$1|100={{formatnum:99}}+}}", + "right-manage-all-push-subscriptions": "Керувати всіма push-підписками", + "action-manage-all-push-subscriptions": "керувати всіма push-підписками", + "group-push-subscription-manager": "Керівники push-підписками", + "group-push-subscription-manager-member": "{{GENDER:$1|керівник|керівниця}} push-підписками", + "grouppage-push-subscription-manager": "{{ns:project}}:Керівники push-підписками" } diff --git a/Echo/i18n/ur.json b/Echo/i18n/ur.json index 99b60e48..43c9e5ec 100644 --- a/Echo/i18n/ur.json +++ b/Echo/i18n/ur.json @@ -14,7 +14,7 @@ "පසිඳු කාවින්ද" ] }, - "echo-desc": "نظام برائے اطلاع صارفین دربارہ تقریبات و پیغامات", + "echo-desc": "صارفین کو پیغام اور دیگر احوال و وقائع کی اطلاع رسانی کا نظام", "prefs-echo": "اطلاعات", "prefs-emailsettings": "برقی خط کے اختیارات", "prefs-echosubscriptions": "ان احوال کے متعلق مجھے آگاہ کریں", @@ -37,8 +37,8 @@ "echo-pref-notifications-blacklist": "ان صارفین کے اطلاع نامے نہ دکھائیں۔ [[mw:Special:MyLanguage/Help:Notifications#mute|مزید تفصیلات]]", "echo-learn-more": "مزید معلومات حاصل کریں", "echo-log": "عوامی نوشتہ", - "echo-new-messages": "آپ کے لیے نئے پیغامات", - "echo-category-title-edit-user-talk": "تبادلۂ خیال صفحہ {{PLURAL:$1|کا پیغام|کے پیغامات}}", + "echo-new-messages": "آپ کے لیے نئے پیغام", + "echo-category-title-edit-user-talk": "تبادلۂ خیال صفحہ {{PLURAL:$1|کا پیغام|کے پیغام}}", "echo-category-title-article-linked": "صفحہ {{PLURAL:$1|کا ربط|کے روابط}}", "echo-category-title-reverted": "رد {{PLURAL:$1|ترمیم|ترامیم}}", "echo-category-title-mention": "{{PLURAL:$1|تذکرہ|تذکرے}}", @@ -175,7 +175,7 @@ "echo-displaysnippet-title": "نیا اطلاع نامہ", "echo-date-today": "آج", "echo-date-yesterday": "گذشتہ کل", - "notification-bundle-header-edit-user-talk-v2": "<strong>{{GENDER:$3|آپ کے}} تبادلہ خیال صفحہ</strong> پر\n{{PLURAL:$1|ایک نیا پیغام|$1 نئے پیغامات|100=99+ نئے پیغامات}}۔", + "notification-bundle-header-edit-user-talk-v2": "<strong>{{GENDER:$3|آپ کے}} تبادلہ خیال صفحہ</strong> پر\n{{PLURAL:$1|ایک نیا پیغام|$1 نئے پیغام|100=99+ نئے پیغام}}۔", "echo-email-batch-subject-daily": "{{SITENAME}} پر آپ کے لیے {{PLURAL:$2|ایک نیا اطلاع نامہ|نئے اطلاع نامے}}", "echo-email-batch-subject-weekly": "اس ہفتہ {{SITENAME}} پر آپ کے لیے {{PLURAL:$2|ایک نیا اطلاع نامہ|نئے اطلاع نامے}}", "echo-email-batch-body-intro-daily": "سلام $1،\n{{SITENAME}} پر آپ کی آج کی سرگرمیوں کی کارگزاری پیش خدمت ہے۔", diff --git a/Echo/i18n/uz.json b/Echo/i18n/uz.json index 8e49d7f4..38614a87 100644 --- a/Echo/i18n/uz.json +++ b/Echo/i18n/uz.json @@ -2,6 +2,7 @@ "@metadata": { "authors": [ "CoderSI", + "Malikxan", "Nataev", "Sociologist" ] @@ -10,52 +11,166 @@ "prefs-echo": "Xabarlar", "prefs-emailsettings": "Elektron pochta moslamalari", "prefs-echosubscriptions": "Quyidagi hodisalar haqida menga xabar berilsin", + "prefs-echocrosswiki": "Cross-wiki bildirishnomalari", + "prefs-blocknotificationslist": "Ishonchli ishtirokchilar", + "prefs-mutedpageslist": "Sahifa havolasi bildirishnomalari uchun sukut qilingan sahifalar", + "prefs-echopollupdates": "Jonli bildirishnomalar", + "echo-mobile-notifications-filter-title": "Bildirishnomalar filtri", "echo-pref-send-me": "Menga joʻnatilsin:", "echo-pref-send-to": "Joʻnatilsin:", "echo-pref-email-format": "Xatlar formati:", "echo-pref-web": "Veb", "echo-pref-email": "Elektron pochta", + "echo-pref-push": "Ilovalar", "echo-pref-email-frequency-never": "Menga elektron pochta orqali xabarlar joʻnatilmasin", "echo-pref-email-frequency-immediately": "Alohida xabarlar kelgani sayin", "echo-pref-email-frequency-daily": "Xabarlar haqida kundalik maʼlumot", "echo-pref-email-frequency-weekly": "Xabarlar haqida haftalik maʼlumot", "echo-pref-email-format-html": "HTML", "echo-pref-email-format-plain-text": "Quruq matn", + "echo-pref-cross-wiki-notifications": "Boshqa vikilardan bildirishnomalarni koʻrish", "echo-learn-more": "Batafsil maʼlumot", + "echo-log": "Umumiy jurnal", "echo-new-messages": "Sizda yangi xabarlar bor", "echo-category-title-edit-user-talk": "Munozaramda {{PLURAL:$1|1=xabar|xabar}}", "echo-category-title-article-linked": "Sahifalarimga {{PLURAL:$1|1=ishora|ishoralar}}", "echo-category-title-reverted": "{{PLURAL:$1|Tahririm|Tahrirlarim}} qaytarildi", "echo-category-title-mention": "{{PLURAL:$1|1=Tilga olish|Tilga olishlar}}", + "echo-category-title-mention-failure": "Muvaffaqiyatsiz {{PLURAL:$1|tilga olish}}", + "echo-category-title-mention-success": "Muvaffaqiyatli {{PLURAL:$1|tilga olish}}", "echo-category-title-other": "{{PLURAL:$1|1=boshqa|boshqalar}}", "echo-category-title-system": "{{PLURAL:$1|Tuzum}}", + "echo-category-title-system-noemail": "{{PLURAL:$1|Tizim}}", + "echo-category-title-system-emailonly": "{{PLURAL:$1|Tizim}}", "echo-category-title-user-rights": "{{PLURAL:$1|Foydalanuvchi huquqlarim oʻzgartirildi}}", - "echo-pref-tooltip-edit-user-talk": "Kimdur menga xat yuborsa yoki munozara sahifamda javob yozsa xabar berilsin", - "echo-pref-tooltip-article-linked": "Maqolalarda men yaratgan biror-bir sahifaga link qoldirilsa xabar berilsin", + "echo-category-title-emailuser": "{{PLURAL:$1|Boshqa foydalanuvchidan kelgan e-pochta|Boshqa foydalanuvchilardan kelgan e-pochtalar}}", + "echo-pref-tooltip-edit-user-talk": "Kimdir menga xat yuborsa yoki munozara sahifamda javob yozsa xabar berilsin.", + "echo-pref-tooltip-article-linked": "Maqolalarda men yaratgan biror-bir sahifaga link qoldirilsa xabar berilsin.", "echo-pref-tooltip-reverted": "Kimdir men qilgan tahrirni bekor qilsa, menga xabar berilsin.", - "echo-pref-tooltip-mention": "Biror foydalanuvchi har qanday munozarada sahifamga havola bergani haqida xabar qilinsin", - "notifications": "Xabarlar", - "echo-specialpage": "Xabarlar", + "echo-pref-tooltip-mention": "Biror foydalanuvchi har qanday munozarada sahifamga havola bergani haqida xabar qilinsin.", + "notifications": "Bildirishnomalar", + "tooltip-pt-notifications-alert": "{{GENDER:|Xabarnomalaringiz}}", + "tooltip-pt-notifications-notice": "{{GENDER:|Bildirishnomalaringiz}}", + "echo-displaynotificationsconfiguration-notifications-by-category-header": "Turkum boʻyicha bildirishnomalar", + "echo-displaynotificationsconfiguration-sorting-by-section-header": "Turlarga koʻra saralash", + "echo-displaynotificationsconfiguration-enabled-default-header": "Sukut boʻyicha yoqilgan", + "echo-displaynotificationsconfiguration-enabled-default-existing-users-legend": "Mavjud foydalanuvchilar", + "echo-displaynotificationsconfiguration-enabled-default-new-users-legend": "Yangi foydalanuvchilar", + "echo-specialpage": "Bildirishnomalar", + "echo-specialpage-section-markread": "Guruhni oʻqilgan deb belgilash", + "echo-specialpage-markasread": "Bildirishnoma: Oʻqilgan deb belgilash", + "echo-specialpage-pagefilterwidget-aria-label": "Viki va sahifa nomi boʻyicha filtr", + "echo-specialpage-special-help-menu-widget-aria-label": "Qoʻshimcha opsiyalar va Bildirishnomalar moslamalari", + "echo-specialpage-pagination-numnotifications": "$1 ta {{PLURAL:$1|xabar}}", + "echo-specialpage-pagination-range": "$1 - $2", + "echo-specialpage-pagefilters-title": "Soʻnggi faoliyat", + "echo-specialpage-pagefilters-subtitle": "Oʻqilmagan bildirishnomalar boʻyicha sahifalar", + "notificationsmarkread-legend": "Bildirishnomani oʻqilgan deb belgilash", "echo-none": "Siz xabar olmadingiz.", + "echo-notification-placeholder": "Bildirishnomalar mavjud emas.", + "echo-notification-placeholder-filters": "Bu mezonlarga mos keladigan bildirishnomalar yoʻq.", + "echo-notification-loginrequired": "Bildirishnomalaringizni koʻrish uchun tizimga kirishingiz kerkak.", + "echo-notification-popup-loginrequired": "Bildirishnomalaringizni koʻrish uchun iltimos kiring", + "echo-notification-markasread": "Oʻqilgan deb belgilash", + "echo-notification-markasunread": "Oʻqilmagan deb belgilash", + "echo-notification-markasread-tooltip": "Oʻqilgan deb belgilash", + "echo-notification-more-options-tooltip": "Koʻproq opsiyalar", + "notification-dynamic-actions-mute-page-linked": "„$1“ sahifasidagi havola bildirishnomalari {{GENDER:$2|sukut qilinsin}}", + "notification-dynamic-actions-mute-page-linked-confirmation": "\"Page link\" bildirishnomalari hozirda \"$1\" sahifasi uchun yoqilmagan", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|Siz}} istagan vaqtingizda [$1 moslamalaringiz] orqali sukut qilgan sahifalaringizni boshqarishingiz mumkin.", + "notification-dynamic-actions-unmute-page-linked": "„$1“ sahifasidagi havola bildirishnomalari {{GENDER:$2|sukut qilinmasin}}", + "notification-dynamic-actions-unmute-page-linked-confirmation": "\"Page link\" bildirishnomalari hozirda \"$1\" sahifasi uchun yoqilgan", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|Siz}} istagan vaqtingizda [$1 moslamalaringiz] orqali sukut qilgan sahifalaringizni boshqarishingiz mumkin.", + "notification-link-text-expand-all": "Yoyish", + "notification-link-text-expand-alert-count": "{{PLURAL:$1|$1 ta xabar}}ga razm solish", + "notification-link-text-expand-notice-count": "{{PLURAL:$1|$1 ta bildirishnoma}}ga razm solish", + "notification-link-text-expand-all-count": "{{PLURAL:$1|$1 ta xabar}}ga razm solish", + "notification-link-text-collapse-all": "Yigʻish", "notification-link-text-view-message": "Xabarni koʻrib chiqish", "notification-link-text-view-mention": "Eslatib oʻtishni koʻrib chiqish", - "notification-link-text-view-changes": "Oʻzgarishlarni koʻrish", + "notification-link-text-view-mention-failure": "{{PLURAL:$1|Tilga olishga razm solish|Tilga olishlarga razm solish}}", + "notification-link-text-view-changes": "Oʻzgarishlarni {{GENDER:$1|koʻrish}}", "notification-link-text-view-page": "Sahifani koʻrish", + "notification-header-edit-user-talk": "$1 <strong>{{GENDER:$3|sizning}} munozara sahifangizda</strong> xabar {{GENDER:$2|qoldirdi}}.", + "notification-header-edit-user-talk-with-section": "$1 „<strong>$4</strong>“ mavzusida {{GENDER:$3|sizning}} munozara sahifangizda</strong> xabar {{GENDER:$2|qoldirdi}}.", + "notification-compact-header-edit-user-talk": "$1 {{GENDER:$3|sizga}} xabar {{GENDER:$2|qoldirdi}}.", + "notification-compact-header-edit-user-talk-with-section": "$1 {{GENDER:$3|sizga}} \"<strong>$4</strong>\"da xabar{{GENDER:$2|qoldirdi}}.", + "notification-body-edit-user-talk-with-section": "$1", + "notification-header-page-linked": "<strong>$4</strong>dan <strong>$3</strong>ga havola qilindi.", + "notification-compact-header-page-linked": "<strong>$1</strong>ga havola paydo boʻldi", + "notification-bundle-header-page-linked": "{{PLURAL:$5||$5 sahifa|100=99+ sahifa}}dan <strong>$3</strong>ga havola qilingan.", + "notification-link-text-what-links-here": "Bu sahifaga barcha havolalar", + "notification-header-mention-other": "$1 {{GENDER:$3|sizni}} \"<strong>$5</strong>\"dagi <strong>$4</strong>da {{GENDER:$2|tilga oldi}}.", + "notification-header-mention-other-nosection": "$1 {{GENDER:$3|sizni}} <strong>$4</strong>da {{GENDER:$2|tilga oldi}}.", + "notification-header-mention-user-talkpage-v2": "$1 {{GENDER:$3|sizni}} \"<strong>$6</strong>\"dagi <strong>$4 {{GENDER:$5|munozara}} sahifasida</strong> {{GENDER:$2|tilga oldi}}.", + "notification-header-mention-user-talkpage-nosection": "$1 {{GENDER:$3|sizni}} <strong>$4 {{GENDER:$5|munozara}} sahifasida</strong> {{GENDER:$2|tilga oldi}}.", + "notification-header-mention-agent-talkpage": "$1 <strong>$2 nomli foydalanuvchining munozara sahifasidagi</strong> „<strong>$4</strong>“ boʻlimida {{GENDER:$3|sizni}} {{GENDER:$2|tilga oldi}}.", + "notification-header-mention-agent-talkpage-nosection": "$1 <strong>{{GENDER:$2|oʻzining}} munozara sahifasida</strong> {{GENDER:$3|sizni}} {{GENDER:$2|tilga oldi}}.", + "notification-header-mention-article-talkpage": "$1 <strong>$4</strong> munozara sahifasining „<strong>$5</strong>“ boʻlimida {{GENDER:$3|sizni}} {{GENDER:$2|tilga oldi}}.", + "notification-header-mention-article-talkpage-nosection": "$1 <strong>$4</strong> munozara sahifasida {{GENDER:$3|sizni}} {{GENDER:$2|tilga oldi}}.", + "notification-header-mention-failure-user-unknown": "<strong>$3</strong> nomli foydalanuvchini {{GENDER:$2|tilga olganligingiz}} yuborilmadi, chunki bunday nomli foydalanuvchi topilmadi.", + "notification-header-mention-failure-user-anonymous": "Foydalanuvchi anonim boʻlganligi uchun <strong>$3</strong>ni {{GENDER:$2|tilga olganligingiz}} yuborilmadi.", + "notification-compact-header-mention-failure-user-unknown": "<strong>Foydalanuvchi nomi mavjud emas:</strong> $1", + "notification-header-mention-success": "<strong>$3</strong> nomli foydalanuvchini {{GENDER:$2|tilga olganingiz}} yuborildi.", + "notification-compact-header-mention-success": "<strong>{{GENDER:$2|Siz tilga oldingiz}}:</strong> $3", + "notification-header-user-rights-add-only": "{{GENDER:$4|Foydalanuvchi}} huquqlaringiz {{GENDER:$1|oʻzgartirildi}}. Qoʻshilgan guruhingiz: $2.", + "notification-header-user-rights-remove-only": "{{GENDER:$4|Foydalanuvchi}} huquqlaringiz {{GENDER:$1|oʻzgartirildi}}. Chiqarilgan guruhingiz: $2.", + "notification-header-user-rights-add-and-remove": "{{GENDER:$6|Foydalanuvchi}} huquqlaringiz {{GENDER:$1|oʻzgartirildi}}. Qoʻshilgan guruhingiz: $2. Chiqarilgan guruhingiz: $4.", + "notification-header-welcome": "{{SITENAME}}ga {{GENDER:$2|xush kelibsiz}}, $1! Bu yerda ekanligingizdan bagʻoyatda mamnunmiz!", + "notification-header-mention-summary": "$1 <strong>$4</strong> sahifasining tahrir izohida {{GENDER:$3|sizni}} {{GENDER:$2|tilga oldi}}.", + "notification-welcome-linktext": "Xush kelibsiz", + "notification-header-thank-you-1-edit": "{{GENDER:$2|Siz}} {{GENDER:$2|ilk}} tahriringizni qildingiz; {{GENDER:$2|tashakkur}} va xush kelibsiz!", + "notification-header-thank-you-10-edit": "{{GENDER:$2|Siz}} oʻninchi {{GENDER:$2|tahriringizni}} qildingiz; {{GENDER:$2|tashakkur}} va shunday davom eting!", + "notification-header-thank-you-100-edit": "{{GENDER:$2|Siz}} yuzinchi {{GENDER:$2|tahriringizni}} qildingiz; katta {{GENDER:$2|rahmat}}!", + "notification-header-thank-you-1000-edit": "{{GENDER:$2|Siz}} minginchi {{GENDER:$2|tahriringizni}} qildingiz; ulkan hissangiz uchun katta {{GENDER:$2|rahmat}}!", + "notification-header-thank-you-10000-edit": "{{GENDER:$2|Siz}} oʻn minginchi {{GENDER:$2|tahriringizni}} qildingiz; katta {{GENDER:$2|rahmat}}!", + "notification-header-thank-you-100000-edit": "{{GENDER:$2|Siz}} yuz minginchi {{GENDER:$2|tahriringizni}} qildingiz; ajoyib hissangiz uchun {{GENDER:$2|tashakkur}}!", + "notification-header-thank-you-1000000-edit": "{{GENDER:$2|Siz}} millionchi {{GENDER:$2|tahriringizni}} qildingiz; hayratda qoldiradigan hissangiz uchun {{GENDER:$2|tashakkur}}!", + "notification-header-thank-you-10000000-edit": "{{GENDER:$2|Siz}} oʻn millionchi {{GENDER:$2|tahriringizni}} qildingiz; fidokorligingiz uchun {{GENDER:$2|tashakkur}}!", + "notification-link-thank-you-edit": "{{GENDER:$1|Sizning}} tahriringiz", "notification-link-text-view-edit": "Tahrirni koʻrish", - "notification-header-reverted": "$3 sahifasidagi {{PLURAL:$4|1=tahriringizni|tahrirlaringizni}} $1 {{GENDER:$2|bekor qildi}}.", - "notification-edit-talk-page-email-subject2": "$1 {{SITENAME}}da sizga xabar {{GENDER:$2|qoldirdi}}.", - "notification-page-linked-email-subject": "{{SITENAME}} saytida siz yaratgan sahifaga havola paydo boʻldi.", - "notification-reverted-email-subject2": "{{GENDER:$2|Кimdir}} {{SITENAME}} saytida sizning {{PLURAL:$4|1=tahriringizni|tahrirlaringizni}} bekor qildi.", - "notification-mention-email-subject": "$1 sizni {{SITENAME}} saytida {{GENDER:$2|tilga oldi}}.", - "notification-user-rights-email-subject": "{{SITENAME}} saytidagi huquqlaringiz oʻzgartirildi.", + "notification-link-article-reminder": "Sahifani koʻrish", + "notification-header-reverted": "Sizning {{PLURAL:$4|<strong>$3</strong>dagi tahriringiz|<strong>$3</strong>dagi tahrirlaringiz}} {{GENDER:$2|qaytarildi}}.", + "notification-header-emailuser": "$1 sizga email xabarini {{GENDER:$2|yubordi}}.", + "notification-edit-talk-page-email-subject2": "$1 {{SITENAME}}da {{GENDER:$3|sizga}} xabar {{GENDER:$2|qoldirdi}}", + "notification-page-linked-email-subject": "{{SITENAME}} saytida {{GENDER:$3|siz}} yaratgan sahifaga havola paydo boʻldi.", + "notification-reverted-email-subject2": "{{GENDER:$3|Sizning}} {{PLURAL:$4|1=tahriringiz|tahrirlaringiz}} {{SITENAME}} saytida {{GENDER:$2|bekor qilindi}}.", + "notification-mention-email-subject": "$1 {{GENDER:$3|sizni}} {{SITENAME}} saytida {{GENDER:$2|tilga oldi}}.", + "notification-user-rights-email-subject": "{{SITENAME}} saytidagi {{GENDER:$3|huquqlaringiz}} oʻzgartirildi.", + "notification-timestamp-ago-seconds": "{{PLURAL:$1|$1soniya}}", + "notification-timestamp-ago-minutes": "{{PLURAL:$1|$1daq}}", + "notification-timestamp-ago-hours": "{{PLURAL:$1|$1soat}}", + "notification-timestamp-ago-days": "{{PLURAL:$1|$1kun}}", + "notification-timestamp-ago-months": "{{PLURAL:$1|$1oy}}", + "notification-timestamp-ago-years": "{{PLURAL:$1|$1yil}}", + "notification-timestamp-today": "Bugun", + "notification-timestamp-yesterday": "Kecha", + "notification-inbox-filter-read": "Mutolaa", + "notification-inbox-filter-unread": "Oʻqilmagan", + "notification-inbox-filter-all": "Barchasi", + "echo-specialmute-label-mute-notifications": "Bu {{GENDER:$1|foydalanuvchi}}dan kelgan sukut qilingan bildirishnomalar", + "echo-email-html-footer-preference-link-text": "{{GENDER:$1|moslamalaringizni}} tekshiring", + "echo-notification-alert": "{{PLURAL:$1|Xabarnoma ($1)|Xabarnomalar ($1)|100=Xabarnomalar (99+)}}", + "echo-notification-notice": "{{PLURAL:$1|Bildirishnoma ($1)|Bildirishnomalar ($1)|100=Bildirishnomalar (99+)}}", + "echo-notification-alert-text-only": "Xabarnomalar", + "echo-notification-notice-text-only": "Bildirishnomalar", "echo-overlay-link": "Barcha xabarlar", "echo-overlay-title": "<b>Xabarlar</b>", "echo-mark-all-as-read": "Barchasini oʻqilgan deb belgilash", + "echo-mark-all-as-read-confirmation": "$1 ta {{PLURAL:$1|xabar}} oʻqilgan sifatida belgilandi", + "echo-displaysnippet-title": "Yangi bildirishnoma", "echo-date-today": "Bugun", "echo-date-yesterday": "Kecha", - "echo-email-batch-subject-daily": "{{SITENAME}} saytida sizda {{PLURAL:$2|yangi xabar|yangi xabar}} bor.", - "echo-email-batch-subject-weekly": "Bu hafta {{SITENAME}} saytida sizda {{PLURAL:$2|yangi xabar|yangi xabar}} bor.", + "notification-bundle-header-edit-user-talk-v2": "Munozara {{GENDER:$3|sahifangizda}} {{PLURAL:$1|bitta yangi xabar|$1 ta yangi xabar|100=99 tadan ortiq yangi xabar}} bor.", + "echo-email-batch-bullet": "•", + "echo-email-batch-subject-daily": "{{SITENAME}} saytida sizda {{PLURAL:$2|yangi xabar}} bor.", + "echo-email-batch-subject-weekly": "Bu hafta {{SITENAME}} saytida sizda {{PLURAL:$2|yangi xabar}} bor.", "echo-email-batch-body-intro-daily": "Salom $1,\nMana siz uchun {{SITENAME}} saytidagi bugungi faoliyat haʻqida qisqa maʼlumot.", "echo-email-batch-body-intro-weekly": "Salom $1,\nMana siz uchun {{SITENAME}} saytidagi bir haftalik faoliyat haʻqida qisqa maʼlumot.", - "echo-email-batch-link-text-view-all-notifications": "Barcha xabarlarni koʻrib chiqish" + "echo-email-batch-link-text-view-all-notifications": "Barcha xabarlarni koʻrib chiqish", + "notification-header-foreign-alert": "{{PLURAL:$5|Boshqa viki|$5 ta boshqa viki}}dan xabarlar", + "notification-header-foreign-notice": "{{PLURAL:$5|Boshqa viki|$5 ta boshqa viki}}dan bildirishnomalar", + "notification-header-foreign-all": "{{PLURAL:$5|Boshqa viki|$5 ta boshqa viki}}dan bildirishnomalar", + "echo-foreign-wiki-lang": "$1 - $2", + "echo-badge-count": "{{PLURAL:$1|$1|100={{formatnum:99}}+}}" } diff --git a/Echo/i18n/vec.json b/Echo/i18n/vec.json index 1db6e43b..c6fe38d2 100644 --- a/Echo/i18n/vec.json +++ b/Echo/i18n/vec.json @@ -13,6 +13,7 @@ "prefs-echosubscriptions": "Màndame on avixo so sti eventi", "prefs-echocrosswiki": "Avixi intrà na Wiki e cheł'altra", "prefs-blocknotificationslist": "Utenti siłensiai", + "prefs-mutedpageslist": "Pàjine siłensiae par łe notìfeghe de linganbo pàjina", "prefs-echopollupdates": "Notifeghe dal vivo", "echo-mobile-notifications-filter-title": "Filtro notifeghe", "echo-pref-show-poll-updates": "Motrare łe nove notifeghe pena che łe riva", @@ -30,6 +31,7 @@ "echo-pref-email-format-plain-text": "Testo normal", "echo-pref-cross-wiki-notifications": "Fa védare anca i avixi de chełe altre wiki", "echo-pref-notifications-blacklist": "No sta mostrare notifeghe de sti utenti ([[mw:Special:MyLanguage/Help:Notifications#mute|pì informasion]])", + "echo-pref-notifications-page-linked-title-muted-list": "No sta mostrar łe notìfeghe \"linganbo a na pàjina\" par ste pàjine.([[mw:Special:MyLanguage/Help:Notifications#mute|Pì informasion]])", "echo-pref-dont-email-read-notifications": "No sta ciapar drento łe notifeghe de letura in te łe e-mail de resunto", "echo-learn-more": "Par saverghine de pì", "echo-log": "Rejistro pùblico", @@ -88,7 +90,7 @@ "echo-notification-placeholder": "No ghe xé notìfeghe", "echo-notification-placeholder-filters": "No ghe xé notìfeghe che łe corisponda a sti criteri", "echo-notification-loginrequired": "Te ghè da ndar drento par vardare łe to notìfeghe.", - "echo-notification-popup-loginrequired": "Va drento par vardar łe notìfeghe", + "echo-notification-popup-loginrequired": "Lòghite par vardar łe notìfeghe", "echo-notification-markasread": "Ségnelo come zà lèto", "echo-notification-markasunread": "Ségnelo come gnancora lèto", "echo-notification-markasread-tooltip": "Ségnelo come zà lèto", diff --git a/Echo/i18n/vi.json b/Echo/i18n/vi.json index 24e69162..dd7f5a57 100644 --- a/Echo/i18n/vi.json +++ b/Echo/i18n/vi.json @@ -7,60 +7,70 @@ "Nguyên Lê", "Quenhitran", "Thienhau2003", - "Trần Nguyễn Minh Huy" + "Trần Nguyễn Minh Huy", + "Vinhtantran" ] }, "echo-desc": "Hệ thống thông báo cho người dùng về các sự kiện và thay đổi quan trọng", "prefs-echo": "Thông báo", "prefs-emailsettings": "Tùy chọn thư điện tử", - "prefs-echosubscriptions": "Báo cho tôi biết về những sự kiện này", + "prefs-echosubscriptions": "Báo cho tôi về những sự kiện này", "prefs-echocrosswiki": "Thông báo liên wiki", - "prefs-blocknotificationslist": "Tắt tiếng người dùng", + "prefs-blocknotificationslist": "Tắt thông báo từ người dùng", + "prefs-mutedpageslist": "Trang được tắt thông báo liên kết", + "prefs-echopollupdates": "Thông báo trực tiếp", + "echo-mobile-notifications-filter-title": "Lọc thông báo", + "echo-pref-show-poll-updates": "Nhận các thông báo ngay", + "echo-pref-show-poll-updates-help": "Hiển thị số thông báo chưa đọc trong thanh tiêu đề và hiển thị thông báo ngay với lời tóm lược.", "echo-pref-send-me": "Gửi thư cho tôi:", "echo-pref-send-to": "Gửi đến:", "echo-pref-email-format": "Định dạng thư điện tử:", "echo-pref-web": "Web", "echo-pref-email": "Thư điện tử", - "echo-pref-email-frequency-never": "Không gửi cho tôi bất kỳ thông báo qua thư điện tử", - "echo-pref-email-frequency-immediately": "Gửi các thông báo từng cái một vào đúng lúc xảy ra", - "echo-pref-email-frequency-daily": "Tóm lược các thông báo hàng ngày", - "echo-pref-email-frequency-weekly": "Tóm lược các thông báo hàng tuần", + "echo-pref-push": "Ứng dụng", + "echo-pref-email-frequency-never": "Đừng gửi thông báo qua thư điện tử", + "echo-pref-email-frequency-immediately": "Gửi từng thông báo riêng lẻ khi có", + "echo-pref-email-frequency-daily": "Tóm tắt thông báo theo ngày", + "echo-pref-email-frequency-weekly": "Tóm tắt thông báo theo tuần", "echo-pref-email-format-html": "HTML", "echo-pref-email-format-plain-text": "Văn bản thuần", - "echo-pref-cross-wiki-notifications": "Hiển thị thông báo từ wiki khác", + "echo-pref-cross-wiki-notifications": "Hiện thông báo từ wiki khác", "echo-pref-notifications-blacklist": "Ẩn thông báo từ những người dùng này. ([[mw:Special:MyLanguage/Help:Notifications#mute|Tìm hiểu thêm]])", + "echo-pref-notifications-page-linked-title-muted-list": "Ẩn thông báo “Liên kết đến trang” về các trang này. ([[mw:Special:MyLanguage/Help:Notifications#mute|Tìm hiểu thêm]])", "echo-pref-dont-email-read-notifications": "Bỏ qua các thông báo đã đọc trong thư điện tử tóm tắt", "echo-learn-more": "Tìm hiểu thêm", "echo-log": "Nhật trình công khai", "echo-new-messages": "Bạn có tin nhắn mới", - "echo-category-title-edit-user-talk": "{{PLURAL:$1}}Lời tin nhắn", + "echo-category-title-edit-user-talk": "{{PLURAL:$1}}Tin nhắn thảo luận", "echo-category-title-article-linked": "{{PLURAL:$1}}Liên kết đến trang", - "echo-category-title-reverted": "{{PLURAL:$1}}Lùi sửa", - "echo-category-title-mention": "{{PLURAL:$1}}Lời nói đến", - "echo-category-title-mention-failure": "{{PLURAL:$1|Lời nhắc đến|Các lời nhắc đến}} thất bại", - "echo-category-title-mention-success": "{{PLURAL:$1|Lời nhắc đến|Các lời nhắc đến}} thành công", + "echo-category-title-reverted": "{{PLURAL:$1}}Bị lùi sửa", + "echo-category-title-mention": "{{PLURAL:$1}}Được nhắc đến", + "echo-category-title-mention-failure": "{{PLURAL:$1}}Lời nhắc đến thất bại", + "echo-category-title-mention-success": "{{PLURAL:$1}}Lời nhắc đến thành công", "echo-category-title-other": "{{PLURAL:$1}}Khác", "echo-category-title-system": "{{PLURAL:$1}}Hệ thống", - "echo-category-title-user-rights": "{{PLURAL:$1|Các thay đổi|Thay đổi}} về quyền người dùng", - "echo-category-title-emailuser": "Thư điện tử nhận từ {{PLURAL:$1|người dùng|những người dùng}} khác", + "echo-category-title-system-noemail": "{{PLURAL:$1}}Hệ thống", + "echo-category-title-system-emailonly": "{{PLURAL:$1}}Hệ thống", + "echo-category-title-user-rights": "{{PLURAL:$1}}Có thay đổi về quyền người dùng", + "echo-category-title-emailuser": "Có thư điện tử từ {{PLURAL:$1}}người dùng khác", "echo-category-title-article-reminder": "{{PLURAL:$1}}Nhắc nhở về trang", - "echo-category-title-thank-you-edit": "Sửa {{PLURAL:$1}}cột mốc", - "echo-category-title-watchlist": "Sửa đổi trang đang theo dõi", - "echo-category-title-minor-watchlist": "Sửa đổi nhỏ trang đang theo dõi", - "echo-pref-tooltip-edit-user-talk": "Báo cho tôi biết khi nào người ta nhắn tin hoặc trả lời trên trang thảo luận của tôi.", - "echo-pref-tooltip-article-linked": "Báo cho tôi biết khi nào người ta đặt liên kết từ một trang đến một trang khác do tôi tạo ra.", - "echo-pref-tooltip-reverted": "Báo cho tôi khi nào người ta lùi lại một sửa đổi của tôi dùng chức năng Lùi sửa hoặc Lùi tất cả.", - "echo-pref-tooltip-mention": "Báo cho tôi biết khi có người đặt liên kết đến trang thành viên của tôi.", - "echo-pref-tooltip-mention-failure": "Báo cho tôi biết khi tôi không thể nhắc đến người khác.", + "echo-category-title-thank-you-edit": "{{PLURAL:$1}}Đạt cột mốc sửa đổi", + "echo-category-title-watchlist": "Có sửa đổi tại trang đang theo dõi", + "echo-category-title-minor-watchlist": "Có sửa đổi nhỏ tại trang đang theo dõi", + "echo-pref-tooltip-edit-user-talk": "Báo cho tôi khi có người nhắn tin hoặc trả lời trên trang thảo luận của tôi.", + "echo-pref-tooltip-article-linked": "Báo cho tôi khi có người đặt liên kết đến trang do tôi tạo ra.", + "echo-pref-tooltip-reverted": "Báo cho tôi khi có người lùi lại một sửa đổi của tôi bằng chức năng Lùi sửa hoặc Lùi tất cả.", + "echo-pref-tooltip-mention": "Báo cho tôi khi có người đặt liên kết đến trang thành viên của tôi.", + "echo-pref-tooltip-mention-failure": "Báo cho tôi khi tôi không thể nhắc đến người khác.", "echo-pref-tooltip-mention-success": "Báo cho tôi khi tôi nhắc đến người khác.", - "echo-pref-tooltip-user-rights": "Báo cho tôi biết khi có người thay đổi quyền người dùng của tôi.", - "echo-pref-tooltip-emailuser": "Báo cho tôi biết khi có người gửi thư cho tôi.", - "echo-pref-tooltip-article-reminder": "Báo cho tôi biết về trang này khi tôi yêu cầu lời nhắc nhở.", - "echo-pref-tooltip-thank-you-edit": "Thông báo cho tôi khi tôi sửa đổi lần thứ 1, 10, 100…", - "echo-pref-tooltip-watchlist": "Thông báo cho tôi khi ai đó thực hiện sửa đổi (không phải là nhỏ) vào một trang trong danh sách theo dõi của tôi.", - "echo-pref-tooltip-minor-watchlist": "Thông báo cho tôi khi ai đó thực hiện sửa đổi nhỏ vào một trang trong danh sách theo dõi của tôi.", + "echo-pref-tooltip-user-rights": "Báo cho tôi khi có người thay đổi quyền người dùng của tôi.", + "echo-pref-tooltip-emailuser": "Báo cho tôi khi có người gửi thư cho tôi.", + "echo-pref-tooltip-article-reminder": "Báo cho tôi về trang này khi tôi yêu cầu.", + "echo-pref-tooltip-thank-you-edit": "Thông báo cho tôi khi tôi đạt tới sửa đổi thứ 1, 10, 100…", + "echo-pref-tooltip-watchlist": "Báo cho tôi khi có người thực hiện sửa đổi (không phải là nhỏ) vào một trang trong danh sách theo dõi của tôi.", + "echo-pref-tooltip-minor-watchlist": "Thông báo cho tôi khi có người thực hiện sửa đổi nhỏ vào một trang trong danh sách theo dõi của tôi.", "notifications": "Thông báo", - "tooltip-pt-notifications-alert": "Tin nhắn cho bạn", + "tooltip-pt-notifications-alert": "Cảnh báo cho bạn", "tooltip-pt-notifications-notice": "Thông báo cho bạn", "echo-displaynotificationsconfiguration": "Cấu hình hiển thị thông báo", "echo-displaynotificationsconfiguration-summary": "Đây là cấu hình hiển thị thông báo trên wiki này.", @@ -78,6 +88,8 @@ "echo-specialpage-section-markread": "Đánh dấu cả phần là đã đọc", "echo-specialpage-markasread": "Thông báo: Đánh dấu là đã đọc", "echo-specialpage-markasread-invalid-id": "ID sự kiện không hợp lệ", + "echo-specialpage-pagefilterwidget-aria-label": "Lọc theo wiki và tên trang", + "echo-specialpage-special-help-menu-widget-aria-label": "Tùy chọn bổ sung và thông báo.", "echo-specialpage-pagination-numnotifications": "$1 thông báo", "echo-specialpage-pagination-range": "$1 – $2", "echo-specialpage-pagefilters-title": "Hoạt động gần đây", @@ -94,6 +106,12 @@ "echo-notification-markasunread": "Đánh dấu là chưa đọc", "echo-notification-markasread-tooltip": "Đánh dấu là đã đọc", "echo-notification-more-options-tooltip": "Thêm tùy chọn", + "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2}}Tắt các thông báo liên kết về “$1”", + "notification-dynamic-actions-mute-page-linked-confirmation": "Đã tắt các thông báo “Liên kết đến trang” về trang “$1”", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2}}Bạn có thể lúc nào quản lý các trang được tắt thông báo trong [$1 tùy chọn].", + "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2}}Bật thông báo liên kết về “$1”", + "notification-dynamic-actions-unmute-page-linked-confirmation": "Đã bật các thông báo “Liên kết đến trang” về trang “$1”", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2}}Bạn có thể lúc nào quản lý các trang được tắt thông báo trong [$1 tùy chọn].", "notification-dynamic-actions-unwatch": "{{GENDER:$3}}Ngừng theo dõi hoạt động mới tại “$1”", "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3}}Bạn không còn theo dõi trang “$1”", "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3}}Bạn có thể theo dõi [$2 trang này] bất cứ lúc nào.", @@ -114,8 +132,9 @@ "notification-header-edit-user-talk-with-section": "$1 {{GENDER:$2}}đã để lại một tin nhắn trên <strong>trang thảo luận {{GENDER:$3}}của bạn</strong> trong “<strong>$4</strong>”.", "notification-compact-header-edit-user-talk": "$1 {{GENDER:$2}}đã nhắn tin cho {{GENDER:$3}}bạn.", "notification-compact-header-edit-user-talk-with-section": "$1 {{GENDER:$2}}đã nhắn tin cho {{GENDER:$3}}bạn trong “<strong>$4</strong>”.", + "notification-body-edit-user-talk-with-section": "$1", "notification-header-page-linked": "Một liên kết đã được tạo từ <strong>$4</strong> tới <strong>$3</strong>.", - "notification-compact-header-page-linked": "Liên kết từ <strong>$1</strong>.", + "notification-compact-header-page-linked": "Được liên kết tại <strong>$1</strong>.", "notification-bundle-header-page-linked": "Các liên kết đã được tạo từ {{PLURAL:$5|một trang|$5 trang|100=99+ trang}} tới <strong>$3</strong>.", "notification-header-article-reminder": "Trước đây {{GENDER:$2}}bạn xin được nhắc nhở về trang <strong>$3</strong>", "notification-link-text-what-links-here": "Mọi liên kết đến trang này", @@ -143,6 +162,16 @@ "notification-header-user-rights-expiry-change": "Ngày hạn của {{GENDER:$4}}bạn trong {{PLURAL:$3|nhóm|các nhóm}} sau đã được {{GENDER:$1}}thay đổi: $2.", "notification-header-welcome": "{{GENDER:$2}}Chào mừng $1 đã đến với {{SITENAME}}! Chúng tôi rất vui vì bạn đã tham gia.", "notification-header-mention-summary": "$1 {{GENDER:$2}}đã nhắc đến {{GENDER:$3}}bạn trong lời tóm lược sửa đổi tại <strong>$4</strong>.", + "notification-header-watchlist-changed": "$1 đã {{GENDER:$2}}thay đổi trang <strong>$3</strong> trong danh sách theo dõi của {{GENDER:$4}}bạn{{PLURAL:$5|| $5 lần}}.", + "notification-header-watchlist-created": "$1 đã {{GENDER:$2}}tạo trang <strong>$3</strong> trong danh sách theo dõi của {{GENDER:$4}}bạn{{PLURAL:$5|| $5 lần}}.", + "notification-header-watchlist-deleted": "$1 đã {{GENDER:$2}}xóa trang <strong>$3</strong> trong danh sách theo dõi của {{GENDER:$4}}bạn{{PLURAL:$5|| $5 lần}}.", + "notification-header-watchlist-moved": "$1 đã {{GENDER:$2}}di chuyển trang <strong>$3</strong> trong danh sách theo dõi của {{GENDER:$4}}bạn{{PLURAL:$5|| $5 lần}}.", + "notification-header-watchlist-restored": "$1 đã {{GENDER:$2}}phục hồi trang <strong>$3</strong> trong danh sách theo dõi của {{GENDER:$4}}bạn{{PLURAL:$5|| $5 lần}}.", + "notification-header-watchlist-multiuser-changed": "Trang <strong>$1</strong> trong danh sách theo dõi của {{GENDER:$2}}bạn đã được thay đổi $3 lần.", + "notification-header-watchlist-multiuser-created": "Trang <strong>$1</strong> trong danh sách theo dõi của {{GENDER:$2}}bạn đã được tạo $3 lần.", + "notification-header-watchlist-multiuser-deleted": "Trang <strong>$1</strong> trong danh sách theo dõi của {{GENDER:$2}} bạn đã bị xóa $3 lần.", + "notification-header-watchlist-multiuser-moved": "Trang <strong>$1</strong> trong danh sách theo dõi của {{GENDER:$2}}bạn đã được di chuyển $3 lần.", + "notification-header-watchlist-multiuser-restored": "Trang <strong>$1</strong> trong danh sách theo dõi của {{GENDER:$2}}bạn đã được phục hồi $3 lần.", "notification-welcome-linktext": "Chào mừng", "notification-header-thank-you-1-edit": "{{GENDER:$2}}Bạn vừa thực hiện sửa đổi đầu tiên; cảm ơn và chào mừng!", "notification-header-thank-you-10-edit": "{{GENDER:$2}}Bạn vừa thực hiện sửa đổi lần thứ 10; cảm ơn và xin hãy tiếp tục!", @@ -151,16 +180,17 @@ "notification-header-thank-you-10000-edit": "{{GENDER:$2}}Bạn đã thực hiện sửa đổi lần thứ 10.000; chân thành cảm ơn bạn!", "notification-header-thank-you-100000-edit": "{{GENDER:$2}}Bạn vừa thực hiện sửa đổi lần thứ 100.000; cảm ơn bạn vì lượng đóng góp đáng khen!", "notification-header-thank-you-1000000-edit": "{{GENDER:$2}}Bạn vừa thực hiện sửa đổi lần thứ một triệu; cảm ơn bạn vì lượng đóng góp anh hùng!", + "notification-header-thank-you-10000000-edit": "{{GENDER:$2}}Bạn vừa thực hiện sửa đổi lần thứ mười triệu; cảm ơn bạn vì sự công hiến rực rỡ của bạn!", "notification-link-thank-you-edit": "{{GENDER:$1}}Sửa đổi của bạn", "notification-link-text-view-edit": "Xem sửa đổi", "notification-link-article-reminder": "Xem trang", "notification-header-reverted": "{{PLURAL:$4|Sửa đổi|Các sửa đổi}} của bạn tại <strong>$3</strong> đã bị {{GENDER:$2}}lùi lại.", "notification-header-emailuser": "$1 {{GENDER:$2}}đã gửi bạn bức thư điện tử.", "notification-edit-talk-page-email-subject2": "$1 đã {{GENDER:$2}}nhắn tin cho bạn trên {{SITENAME}}", - "notification-page-linked-email-subject": "Có liên kết mới đến một trang do bạn tạo ra tại {{SITENAME}}", - "notification-reverted-email-subject2": "{{PLURAL:$4|Sửa đổi|Các sửa đổi}} của bạn đã bị {{GENDER:$2}}lùi lại trên {{SITENAME}}", - "notification-mention-email-subject": "$1 đã nói đến {{GENDER:$3}}bạn tại {{SITENAME}}", - "notification-user-rights-email-subject": "Các quyền người dùng của bạn đã thay đổi tại {{SITENAME}}", + "notification-page-linked-email-subject": "Có liên kết mới đến một trang do {{GENDER:$3}}bạn tạo ra tại {{SITENAME}}", + "notification-reverted-email-subject2": "{{PLURAL:$4|Sửa đổi|Các sửa đổi}} của {{GENDER:$3}}bạn đã bị {{GENDER:$2}}lùi lại trên {{SITENAME}}", + "notification-mention-email-subject": "$1 đã {{GENDER:$2}}nói đến {{GENDER:$3}}bạn tại {{SITENAME}}", + "notification-user-rights-email-subject": "Các quyền người dùng của {{GENDER:$3}}bạn đã thay đổi tại {{SITENAME}}", "notification-timestamp-ago-seconds": "$1gi", "notification-timestamp-ago-minutes": "$1ph́", "notification-timestamp-ago-hours": "$1g̀", @@ -172,7 +202,7 @@ "notification-inbox-filter-read": "Đọc", "notification-inbox-filter-unread": "Chưa đọc", "notification-inbox-filter-all": "Tất cả", - "echo-specialmute-label-mute-notifications": "Làm im thông báo từ người dùng này", + "echo-specialmute-label-mute-notifications": "Làm im thông báo từ {{GENDER:$1}}người dùng này", "echo-email-plain-footer": "Để kiểm soát các thư điện tử mà chúng tôi gửi cho {{GENDER:$1}}bạn, hãy kiểm tra tùy chọn của {{GENDER:$1}}bạn:", "echo-email-html-footer-preference-link-text": "kiểm tra tùy chọn của {{GENDER:$1}}bạn", "echo-email-html-footer-with-link": "Để kiểm soát các thư điện tử mà chúng tôi gửi cho {{GENDER:$2}}bạn, hãy $1.", @@ -189,6 +219,7 @@ "echo-date-today": "Hôm nay", "echo-date-yesterday": "Hôm qua", "notification-bundle-header-edit-user-talk-v2": "{{PLURAL:$1|Một tin nhắn|$1 tin nhắn|100=99+ tin nhắn}} mới tại <strong>trang thảo luận của {{GENDER:$3}}bạn</strong>.", + "echo-email-batch-bullet": "•", "echo-email-batch-subject-daily": "Bạn có {{PLURAL:$2|một tin nhắn|các tin nhắn}} mới hôm nay trên {{SITENAME}}", "echo-email-batch-subject-weekly": "Bạn có {{PLURAL:$2|thông báo|các thông báo}} mới trên {{SITENAME}} tuần này", "echo-email-batch-body-intro-daily": "Chào $1,\nĐây là bản tóm tắt các chuyện xảy ra hôm nay trên {{SITENAME}}.", @@ -197,5 +228,6 @@ "notification-header-foreign-alert": "Thêm thông báo từ {{PLURAL:$5|một wiki|$5 wiki}} khác", "notification-header-foreign-notice": "Thêm thông báo từ {{PLURAL:$5|một wiki nữa|$5 wiki nữa}}", "notification-header-foreign-all": "Thêm thông báo từ {{PLURAL:$5|một wiki|$5 wiki}} khác", - "echo-foreign-wiki-lang": "$1 – $2" + "echo-foreign-wiki-lang": "$1 – $2", + "echo-badge-count": "{{PLURAL:$1|$1|100={{formatnum:99}}+}}" } diff --git a/Echo/i18n/yi.json b/Echo/i18n/yi.json index 0a99b805..9e2c913b 100644 --- a/Echo/i18n/yi.json +++ b/Echo/i18n/yi.json @@ -110,7 +110,6 @@ "notification-link-text-view-edit": "באקוקן רעדאקטירונג", "notification-link-article-reminder": "באַקוקן בלאַט", "notification-header-reverted": " {{PLURAL:$4|אייער רעדאקטירונג אויף <strong>$3</strong> איז|אייערע רעדאקטירונגען אויף <strong>$3</strong> זענען}} געווארן {{GENDER:$2|צוריקגעשטעלט}}.", - "notification-body-reverted": "$1", "notification-header-emailuser": "$1 {{GENDER:$2|האט אייך געשיקט}} א בליצבריוו.", "notification-edit-talk-page-email-subject2": "$1 {{GENDER:$2|האט}} {{GENDER:$3|אייך}} געשריבן א נייע מעלדונג אינעם {{SITENAME}} וועבזייטל", "notification-page-linked-email-subject": "א בלאט {{GENDER:$3|איר}} האט געשאפן איז געווארן פֿאַרלינקט אויף {{SITENAME}}", diff --git a/Echo/i18n/yrl.json b/Echo/i18n/yrl.json new file mode 100644 index 00000000..ed4282e9 --- /dev/null +++ b/Echo/i18n/yrl.json @@ -0,0 +1,71 @@ +{ + "@metadata": { + "authors": [ + "Karapananguasú Kururú Teremembé", + "Maracajá Teremembé" + ] + }, + "echo-desc": "Yũrepawa umbeu arã puruçara’etá mereçeçawa açui patuá mirapura reçé", + "prefs-echo": "Mbeuçawa'etá", + "prefs-emailsettings": "Emayu purawakaçawa'etá", + "prefs-echosubscriptions": "Erembeu xe kuá mereçeçawa’etá reçé", + "prefs-echocrosswiki": "Mbeuçawa’etá siya wiki reçé", + "prefs-blocknotificationslist": "Puruçara’etá kurukaĩma", + "prefs-mutedpageslist": "Sowa’etá kurukaĩma sowa rituya mbeuçawa’etá reçé", + "prefs-echopollupdates": "Mbeuçawa’etá pãnhé yepé arã", + "echo-mobile-notifications-filter-title": "Usikári mbeuçawa’etá", + "echo-pref-show-poll-updates": "Umukameẽ mbeuçawa’etá aĩtá yepé pãnhé tausika ramẽ waá", + "echo-pref-show-poll-updates-help": "Umukameẽ mbeuçawa paparipawa ĩdé te remunheẽ ã waá kuatiarawaçú rupí açui umukameẽ kutara rupí yuí yepé piçawera yawá reçé yawá usika ĩdé arã aramẽ.", + "echo-pref-send-me": "E-meẽ xe arã:", + "echo-pref-send-to": "Umeẽ aé çupé:", + "echo-pref-email-format": "Emayu murupiawa:", + "echo-pref-web": "Web", + "echo-pref-email": "Emayu", + "echo-pref-push": "Mburipawa’etá", + "echo-pref-email-frequency-never": "Te remeẽ mbeuçawa’etá emayu rupí xe arã", + "echo-pref-email-frequency-immediately": "Mbeuçawa mirapura mayé yawá yepé usika ramẽ", + "echo-pref-email-frequency-daily": "Mbeuçawa mumirĩgawa arawara reçé", + "echo-pref-email-frequency-weekly": "Mbeuçawa mumirĩgawa çẽmanawa reçé", + "echo-pref-email-format-html": "HTML", + "echo-pref-email-format-plain-text": "Kuatiara pupuya", + "echo-pref-cross-wiki-notifications": "Umukameẽ mbeuçawa amũ wiki yuí aramẽ", + "echo-pref-notifications-blacklist": "Te remukameẽ mbeuçawa’etá tauyuri waá kuá puruçara’etá reçé. ([[mw:Special:MyLanguage/Help:Notifications#mute|kuauçawa píri]])", + "echo-pref-notifications-page-linked-title-muted-list": "Te remukameẽ \"sowa tupaçá\" kuá sowa’etá kití. ([[mw:Special:MyLanguage/Help:Notifications#mute|Ukuau píri yawá reçé]])", + "echo-pref-dont-email-read-notifications": "Te remburí mbeuçawa’etá xe amunheẽ wã waá emayu mumirĩgawa rupí", + "echo-learn-more": "Ukuau píri", + "echo-log": "Mukatiuruçawa pãnhé yepé arã", + "echo-new-messages": "Aikué patuá mirapura piçaçú ĩdé arã", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|Murupiawa|Murupiawa’etá}} çe murũgetaçawa puruçara mainãgá kití", + "echo-category-title-article-linked": "Sowa {{PLURAL:$1|tupaçá|tupaça’etá}}", + "echo-category-title-reverted": "Murupiawa {{PLURAL:$1|amũmunhãgawa|amũmunhãgawa’etá}}", + "echo-category-title-mention": "{{PLURAL:$1|Mĩduariçawa|Mĩduariçawa’etá}}", + "echo-category-title-mention-failure": "{{PLURAL:$1|Mĩduariçawa ĩti uyũré ã|Mĩduariçawa’etá ĩti tauyũré ã}}", + "echo-category-title-mention-success": "{{PLURAL:$1|Mĩduariçawa uyũré ã, ikatú reté.|Mĩduariçawa’etá tauyũré ã, ikatú reté.}}", + "echo-category-title-other": "{{PLURAL:$1|Amũ yepé}}", + "echo-category-title-system": "{{PLURAL:$1|Yũrepawa}}", + "echo-category-title-system-noemail": "{{PLURAL:$1|Yũrepawa}}", + "echo-category-title-system-emailonly": "{{PLURAL:$1|Yũrepawa}}", + "echo-category-title-user-rights": "{{PLURAL:$1|Puruçara sinimuka çatãbika|Puruçara sinimuka çatãbika’etá}}", + "echo-category-title-emailuser": "{{PLURAL:$1|Emayu amũ puruçara çuí|Emayu amũ puruçara’etá çuí}}", + "echo-category-title-article-reminder": "Sowa {{PLURAL:$1|mumãduariçara|mumãduariçara’etá}}", + "echo-category-title-thank-you-edit": "Murupiawa {{PLURAL:$1|sikaçawa|sikaçawa’etá}}", + "echo-category-title-watchlist": "Umurupiawa sowa’etá xipiana", + "echo-category-title-minor-watchlist": "Murupiawa’i sowa’etá xipiana rupí", + "echo-pref-tooltip-edit-user-talk": "E-mukameẽ xe arã yepé mira umurupiawa ramẽ çe puruçara mainãgawa murũgetaçawa sowa.", + "echo-pref-tooltip-article-linked": "E-nheẽ xe arã yepé mira umunhã ramẽ yepé tupaçá yepé sowa kití xe amunhã ã waá yepé kuatiara sowa rupí.", + "echo-pref-tooltip-reverted": "Erembeu xe arã yepé mira wamũmunhã ramẽ yepé murupiawa xe amunhã ã waá upurú rupí amũmunhãgawa murakimaé yara.", + "echo-pref-tooltip-mention": "Erembeu xe arã yepé mira umunhã ramẽ tupaçá çe puruçara mainãgawa sowa kití.", + "echo-pref-tooltip-mention-failure": "Erembeu xe arã xe ti amurú amumĩduari yepé mira ramẽ.", + "echo-pref-tooltip-mention-success": "Erembeu xe arã xe ameẽ ramẽ yepé mĩduariçawa yepé mira çupé.", + "echo-pref-tooltip-user-rights": "Erembeu xe arã yepé mira umuterie ramẽ çe puruçara mainãgawa xiariçawa’etá.", + "echo-pref-tooltip-emailuser": "Erembeu xe yepé mira umeẽ ramẽ yepé emayu.", + "echo-pref-tooltip-article-reminder": "Erembeu xe kuá sowa reçé xe apurãdú ramẽ.", + "echo-pref-tooltip-thank-you-edit": "Erembeu ixé asika ramẽ yepewara, opaĩpowara, yepewera ... murupiawa.", + "notification-link-text-what-links-here": "Pãnhé tupaçá kuá sowa kití", + "notification-timestamp-today": "Uye", + "notification-timestamp-yesterday": "Kueçé", + "notification-inbox-filter-read": "Umũgetá", + "notification-inbox-filter-unread": "Mũgetaĩma", + "notification-inbox-filter-all": "Pãnhé", + "echo-specialmute-label-mute-notifications": "Umutipuĩma pãnhé mbeuçawa’etá kuá {{GENDER:$1|puruçara}} çuiwara" +} diff --git a/Echo/i18n/yua.json b/Echo/i18n/yua.json index 4602d73e..2e532a48 100644 --- a/Echo/i18n/yua.json +++ b/Echo/i18n/yua.json @@ -1,16 +1,17 @@ { "@metadata": { "authors": [ + "Languaeditor", "Lorenzoitza" ] }, "echo-category-title-mention-failure": "K'aschaji {{PLURAL:$1|mention|mentions}}", - "echo-pref-tooltip-mention-failure": "A'aten le ken k'exa'ak a'alakten men maax ma' patal tin k'exi'", + "echo-pref-tooltip-mention-failure": "Aꞌaten le ken kꞌexaꞌak aꞌalakten men maax maꞌ patal tin kꞌexiꞌ", "notification-link-text-view-mention-failure": "{{PLURAL:$1|Il maax ku t'aan yóolal|Il maax t'anik}}", - "notification-header-mention-failure-user-unknown": "{{GENDER:$2|Your}} a tuxt'aan \"$3\" ma' ta tuuxtabi' tumene le maaxo' ma' kaxta'abi'.", - "notification-header-mention-failure-user-anonymous": "{{GENDER:$2|Your}} t'aana'ab tumen \"$3\" ma' tuuxta'ab tumen ma' oojletan máax tuuxtik.", - "notification-header-mention-failure-too-many": "{{GENDER:$2|Your}} a tuuxt'an ma'tuuxtabi' tumen maan u $3.", - "notification-header-mention-failure-bundle": "$3 t'aano'ob {{GENDER:$2|you made}} ichil <strong>$4</strong> u waalil t'aan tu'ux ma' tuuxtabi'.", - "notification-compact-header-mention-failure-user-unknown": "<strong>Ma' ojeeltáan maaxi':</strong> \"$1\"", - "notification-compact-header-mention-failure-user-anonymous": "<strong>Ma' ojeelta'an maaxi':</strong> \"$1\"" + "notification-header-mention-failure-user-unknown": "{{GENDER:$2|Your}} a tuxtꞌaan \"$3\" maꞌ ta tuuxtabiꞌ tumene le maaxoꞌ maꞌ kaxtaꞌabiꞌ.", + "notification-header-mention-failure-user-anonymous": "{{GENDER:$2|Your}} tꞌaanaꞌab tumen \"$3\" maꞌ tuuxtaꞌab tumen maꞌ oojletan máax tuuxtik.", + "notification-header-mention-failure-too-many": "A tuuxtꞌan maꞌtuuxtabiꞌ tumen maan u $3.", + "notification-header-mention-failure-bundle": "Tꞌaanoꞌob ichil <strong>$4</strong> u waalil tꞌaan tuꞌux maꞌ tuuxtabiꞌ.", + "notification-compact-header-mention-failure-user-unknown": "<strong>Maꞌ ojeeltáan maaxiꞌ:</strong> \"$1\"", + "notification-compact-header-mention-failure-user-anonymous": "<strong>Maꞌ ojeeltaꞌan maaxiꞌ:</strong> \"$1\"" } diff --git a/Echo/i18n/yue.json b/Echo/i18n/yue.json index 59ce4649..19de05a1 100644 --- a/Echo/i18n/yue.json +++ b/Echo/i18n/yue.json @@ -2,7 +2,10 @@ "@metadata": { "authors": [ "Deryck Chan", + "Hello903hello", "Ktchankt", + "Moon0319", + "Roy17", "Suzukaze-c", "William915", "Wong128hk" @@ -44,10 +47,11 @@ "notification-link-text-view-mention": "去睇下講啲咩", "notification-link-text-view-changes": "去睇改咗啲乜", "notification-link-text-view-page": "去睇嗰頁", + "notification-header-mention-success": "發出咗{{GENDER:$2|你}}對<strong>$3</strong>嘅提及。", "notification-link-text-view-edit": "去睇改咗啲乜", "echo-notification-alert-text-only": "提示", "echo-notification-notice-text-only": "通知", - "echo-overlay-link": "所有通知", + "echo-overlay-link": "全部通知", "echo-overlay-title": "<b>通知</b>", "echo-mark-all-as-read": "全部標做讀過", "echo-date-today": "今日", diff --git a/Echo/i18n/zh-hans.json b/Echo/i18n/zh-hans.json index 3124c7b4..3bad712a 100644 --- a/Echo/i18n/zh-hans.json +++ b/Echo/i18n/zh-hans.json @@ -11,34 +11,43 @@ "Cosine02", "Cwek", "Dimension", + "Diskdance", "EagerLin", "Fantasticfears", "GeneralNFS", + "GuoPC", "Hydra", "Hzy980512", "Impersonator 1", "Kuailong", "LNDDYL", + "LaMagiaaa", "Li3939108", "Liangent", "Linforest", "Liuxinyu970226", "Looong", + "MangoFanFanw", "Mywood", "Qiyue2001", "Shirayuki", "Shizhao", "SomeyaMako", + "Stang", "StephDC", "Suchichi02", + "SunAfterRain", + "Sunny00217", "TianyinLee", "Tiger", + "Tranve", "Viztor", "WhitePhosphorus", "Xiaomingyan", "Xingzhe", "Xiplus", "Yfdyh000", + "Zhang8569", "乌拉跨氪", "予弦", "佛壁灯", @@ -52,11 +61,12 @@ }, "echo-desc": "用于通知用户有关活动和消息的系统", "prefs-echo": "通知", + "prefs-description-echo": "选择 {{GENDER:|you}} 接收哪些通知以及如何接收它们。", "prefs-emailsettings": "电子邮件选项", "prefs-echosubscriptions": "通知我这些事件", "prefs-echocrosswiki": "跨wiki通知", "prefs-blocknotificationslist": "屏蔽用户", - "prefs-mutedpageslist": "页面链接通知的页面已静音", + "prefs-mutedpageslist": "屏蔽来自页面的通知", "prefs-echopollupdates": "实时通知", "echo-mobile-notifications-filter-title": "过滤通知", "echo-pref-show-poll-updates": "当他们达到是显示新通知", @@ -75,12 +85,12 @@ "echo-pref-email-format-plain-text": "纯文本", "echo-pref-cross-wiki-notifications": "显示来自其他wiki的通知", "echo-pref-notifications-blacklist": "不显示来自这些用户的通知([[mw:Special:MyLanguage/Help:Notifications#mute|了解更多]])", - "echo-pref-notifications-page-linked-title-muted-list": "不要为这些页面显示“页面链接”提醒。([[mw:Special:MyLanguage/Help:Notifications#mute|了解更多]])", + "echo-pref-notifications-page-linked-title-muted-list": "不显示来自这些页面的链接提醒。([[mw:Special:MyLanguage/Help:Notifications#mute|了解更多]])", "echo-pref-dont-email-read-notifications": "不要在通知摘要邮件中包含已读通知", "echo-learn-more": "了解详情", - "echo-log": "公共日志", - "echo-new-messages": "您有新消息", - "echo-category-title-edit-user-talk": "讨论页{{PLURAL:$1|留言}}", + "echo-log": "日志", + "echo-new-messages": "您有新的讨论页消息", + "echo-category-title-edit-user-talk": "讨论页{{PLURAL:$1|编辑}}", "echo-category-title-article-linked": "页面{{PLURAL:$1|链接}}", "echo-category-title-reverted": "编辑{{PLURAL:$1|还原}}", "echo-category-title-mention": "{{PLURAL:$1|提及}}", @@ -96,7 +106,7 @@ "echo-category-title-thank-you-edit": "编辑{{PLURAL:$1|里程碑}}", "echo-category-title-watchlist": "监视列表的页面编辑", "echo-category-title-minor-watchlist": "监视列表的页面小编辑", - "echo-pref-tooltip-edit-user-talk": "当有人在我的讨论页上留言或回复时通知我。", + "echo-pref-tooltip-edit-user-talk": "当有人编辑我的用户讨论页时通知我。", "echo-pref-tooltip-article-linked": "当有人链接到我从另一页面创建的页面时通知我。", "echo-pref-tooltip-reverted": "当有人用撤销或回退工具来还原我的编辑时通知我。", "echo-pref-tooltip-mention": "当有人链接我的用户页时通知我。", @@ -127,13 +137,14 @@ "echo-specialpage-section-markread": "将组标记为已读", "echo-specialpage-markasread": "通知:标记为已读", "echo-specialpage-markasread-invalid-id": "无效的活动ID", + "echo-specialpage-pagefilterwidget-aria-label": "按wiki和页面标题筛选", "echo-specialpage-special-help-menu-widget-aria-label": "附加设置和消息通知偏好", "echo-specialpage-pagination-numnotifications": "$1条{{PLURAL:$1|通知}}", "echo-specialpage-pagination-range": "$1 - $2", "echo-specialpage-pagefilters-title": "最近活动", "echo-specialpage-pagefilters-subtitle": "有未读通知的页面", "notificationsmarkread-legend": "标记通知为已读", - "echo-none": "您没有通知。", + "echo-none": "您目前没有通知。", "echo-api-failure": "检索通知失败。", "echo-api-failure-cross-wiki": "对远程域名的访问已拒绝。", "echo-notification-placeholder": "这里没有通知。", @@ -144,6 +155,12 @@ "echo-notification-markasunread": "标记为未读", "echo-notification-markasread-tooltip": "标记为已读", "echo-notification-more-options-tooltip": "更多选项", + "notification-dynamic-actions-mute-page-linked": "{{GENDER:$2|停止}}在“$1”的链接通知", + "notification-dynamic-actions-mute-page-linked-confirmation": "现在页面“$1”的链接通知已停用", + "notification-dynamic-actions-mute-page-linked-confirmation-description": "{{GENDER:$2|您}}可以随时在[$1 您的参数设置]里管理停用通知的页面。", + "notification-dynamic-actions-unmute-page-linked": "{{GENDER:$2|启用}}在“$1”的链接通知", + "notification-dynamic-actions-unmute-page-linked-confirmation": "现在页面“$1”的链接通知已启用", + "notification-dynamic-actions-unmute-page-linked-confirmation-description": "{{GENDER:$2|您}}可以随时在[$1 您的参数设置]里管理停用通知的页面。", "notification-dynamic-actions-unwatch": "{{GENDER:$3|停止}}关注“$1”上的新活动", "notification-dynamic-actions-unwatch-confirmation": "{{GENDER:$3|您}}已不再监视页面“$1”", "notification-dynamic-actions-unwatch-confirmation-description": "{{GENDER:$3|您}}可以随时监视[$2 此页面]。", @@ -174,8 +191,8 @@ "notification-header-mention-other-nosection": "$1在<strong>$4</strong>{{GENDER:$2|提到}}了{{GENDER:$3|您}}。", "notification-header-mention-user-talkpage-v2": "$1在<strong>$4{{GENDER:$5|的}}用户讨论页</strong>的“<strong>$6</strong>”中{{GENDER:$2|提到}}了{{GENDER:$3|您}}。", "notification-header-mention-user-talkpage-nosection": "$1在<strong>$4{{GENDER:$5|的}}用户讨论页</strong>{{GENDER:$2|提到}}了{{GENDER:$3|您}}。", - "notification-header-mention-agent-talkpage": "$1在<strong>{{GENDER:$2|他|她|他}}的讨论页</strong>的“<strong>$4</strong>”里{{GENDER:$2|提到}}了{{GENDER:$3|您}}。", - "notification-header-mention-agent-talkpage-nosection": "$1在<strong>{{GENDER:$2|他|她|他}}的讨论页</strong>{{GENDER:$2|提到}}了{{GENDER:$3|您}}。", + "notification-header-mention-agent-talkpage": "$1在<strong>{{GENDER:$2|其}}讨论页</strong>的“<strong>$4</strong>”里{{GENDER:$2|提到}}了{{GENDER:$3|您}}。", + "notification-header-mention-agent-talkpage-nosection": "$1在<strong>{{GENDER:$2|其}}讨论页</strong>{{GENDER:$2|提到}}了{{GENDER:$3|您}}。", "notification-header-mention-article-talkpage": "$1在<strong>$4</strong>的讨论页的“<strong>$5</strong>”段落{{GENDER:$2|提到}}了{{GENDER:$3|您}}。", "notification-header-mention-article-talkpage-nosection": "$1在<strong>$4</strong>的讨论页{{GENDER:$2|提到}}了{{GENDER:$3|您}}。", "notification-header-mention-failure-user-unknown": "{{GENDER:$2|您}}对<strong>$3</strong>的提及未被发送,因为找不到用户。", @@ -204,20 +221,20 @@ "notification-header-watchlist-multiuser-deleted": "{{GENDER:$2|您的}}监视列表里的页面 <strong>$1</strong> 被删除了$3{{PLURAL:$3|次}}。", "notification-header-watchlist-multiuser-moved": "{{GENDER:$2|您的}}监视列表里的页面 <strong>$1</strong> 被移动了$3{{PLURAL:$3|次}}。", "notification-header-watchlist-multiuser-restored": "{{GENDER:$2|您的}}监视列表里的页面 <strong>$1</strong> 被恢复了$3{{PLURAL:$3|次}}。", + "notification-body-watchlist-once": "如果有进一步的活动,除非您在登录的状态下{{GENDER:$1|访问}}这个页面,f否则您将不会收到其他电子邮件通知。", "notification-welcome-linktext": "欢迎", - "notification-header-thank-you-1-edit": "{{GENDER:$2|您}}刚刚作出了{{GENDER:$2|您}}的第一次编辑;感谢{{GENDER:$2|您}},并欢迎您!", - "notification-header-thank-you-10-edit": "{{GENDER:$2|您}}刚刚作出了{{GENDER:$2|您}}的第10次编辑;感谢{{GENDER:$2|您}},请继续保持!", - "notification-header-thank-you-100-edit": "{{GENDER:$2|您}}刚刚作出了{{GENDER:$2|您}}的第100次编辑;非常感谢{{GENDER:$2|您}}!", - "notification-header-thank-you-1000-edit": "{{GENDER:$2|您}}刚刚作出了{{GENDER:$2|您}}的第1000次编辑;感谢{{GENDER:$2|您}}成为一个伟大的编辑者!", - "notification-header-thank-you-10000-edit": "{{GENDER:$2|您}}刚刚作出了{{GENDER:$2|您}}的第1万次编辑;非常非常感谢{{GENDER:$2|您}}!", - "notification-header-thank-you-100000-edit": "{{GENDER:$2|您}}刚刚作出了{{GENDER:$2|您}}的第10万次编辑;感谢{{GENDER:$2|您}}惊人的贡献!", - "notification-header-thank-you-1000000-edit": "{{GENDER:$2|您}}刚刚作出了{{GENDER:$2|您}}的第100万次编辑;感谢{{GENDER:$2|您}}令人惊讶的贡献!", - "notification-header-thank-you-10000000-edit": "{{GENDER:$2|您}}刚刚作出了{{GENDER:$2|您}}的第1000万次编辑;感谢{{GENDER:$2|您}}令人惊讶的贡献!", + "notification-header-thank-you-1-edit": "{{GENDER:$2|您}}刚刚完成了第一笔编辑。谢谢,我们欢迎{{GENDER:$2|您}}!", + "notification-header-thank-you-10-edit": "{{GENDER:$2|您}}刚刚完成了第十笔编辑。感谢{{GENDER:$2|您}},请继续保持!", + "notification-header-thank-you-100-edit": "{{GENDER:$2|您}}刚刚完成了第一百笔编辑。非常感谢{{GENDER:$2|您}}!", + "notification-header-thank-you-1000-edit": "{{GENDER:$2|您}}刚刚完成了第一千笔编辑。感谢{{GENDER:$2|您}},伟大的贡献者!", + "notification-header-thank-you-10000-edit": "{{GENDER:$2|您}}刚刚完成了第一万笔编辑。我们感激不尽!", + "notification-header-thank-you-100000-edit": "{{GENDER:$2|您}}刚刚完成了第十万笔编辑。感谢{{GENDER:$2|您}}惊人的贡献!", + "notification-header-thank-you-1000000-edit": "{{GENDER:$2|您}}刚刚完成了第一百万笔编辑。感谢{{GENDER:$2|您}}的贡献,您真了不起!", + "notification-header-thank-you-10000000-edit": "{{GENDER:$2|您}}刚刚完成了第一千万笔编辑。感谢{{GENDER:$2|您}}的杰出奉献!", "notification-link-thank-you-edit": "{{GENDER:$1|您}}的编辑", "notification-link-text-view-edit": "查看编辑", "notification-link-article-reminder": "查看页面", "notification-header-reverted": "有人{{GENDER:$2|回退}}了您{{PLURAL:$4|对<strong>$3</strong>所作出的编辑}}。", - "notification-body-reverted": "$1", "notification-header-emailuser": "$1向您{{GENDER:$2|发送}}了电子邮件。", "notification-edit-talk-page-email-subject2": "$1在{{SITENAME}}给您{{GENDER:$2|留言}}了", "notification-page-linked-email-subject": "{{GENDER:$3|您}}创建的一个页面在{{SITENAME}}上被链接", @@ -262,5 +279,10 @@ "notification-header-foreign-notice": "来自{{PLURAL:$5|另一个wiki|另外$5个wiki}}上的更多一般通知", "notification-header-foreign-all": "来自{{PLURAL:$5|其他wiki|$5个其他wiki}}的更多通知", "echo-foreign-wiki-lang": "$1 - $2", - "echo-badge-count": "{{PLURAL:$1|$1|100=99+}}" + "echo-badge-count": "{{PLURAL:$1|$1|100={{formatnum:99}}+}}", + "right-manage-all-push-subscriptions": "管理所有推送订阅", + "action-manage-all-push-subscriptions": "管理所有推送订阅", + "group-push-subscription-manager": "推送订阅管理器", + "group-push-subscription-manager-member": "{{GENDER:$1|推送订阅管理器}}", + "grouppage-push-subscription-manager": "{{ns:project}}:推送订阅管理器" } diff --git a/Echo/i18n/zh-hant.json b/Echo/i18n/zh-hant.json index bad10ce8..823846c5 100644 --- a/Echo/i18n/zh-hant.json +++ b/Echo/i18n/zh-hant.json @@ -20,12 +20,15 @@ "Shirayuki", "Shizhao", "Simon Shek", + "SunAfterRain", + "Sunny00217", "Waihorace", "Wehwei", "Winstonyin", "Wong128hk", "Xiplus", "一個正常人", + "列维劳德", "沈澄心", "逆襲的天邪鬼" ] @@ -58,9 +61,9 @@ "echo-pref-notifications-page-linked-title-muted-list": "不要顯示這些頁面的「頁面連結」通知。\n([[mw:Special:MyLanguage/Help:Notifications#mute|了解更多]])", "echo-pref-dont-email-read-notifications": "不要在摘要電子郵件裡包含已讀通知", "echo-learn-more": "瞭解更多", - "echo-log": "公共日誌", - "echo-new-messages": "您有新訊息", - "echo-category-title-edit-user-talk": "對話頁面{{PLURAL:$1|訊息}}", + "echo-log": "日誌", + "echo-new-messages": "您有新的討論頁訊息", + "echo-category-title-edit-user-talk": "{{PLURAL:$1|編輯}}我的使用者討論頁", "echo-category-title-article-linked": "頁面{{PLURAL:$1|連結}}", "echo-category-title-reverted": "編輯{{PLURAL:$1|還原}}", "echo-category-title-mention": "{{PLURAL:$1|提及}}", @@ -76,7 +79,7 @@ "echo-category-title-thank-you-edit": "編輯{{PLURAL:$1|里程碑}}", "echo-category-title-watchlist": "監視頁面的編輯", "echo-category-title-minor-watchlist": "監視頁面的小修改", - "echo-pref-tooltip-edit-user-talk": "當有人在我的對話頁面上留下訊息或是回覆留言時通知我。", + "echo-pref-tooltip-edit-user-talk": "當有人編輯我的使用者討論頁時通知我。", "echo-pref-tooltip-article-linked": "當有人從另一頁面連結到我建立的頁面時通知我。", "echo-pref-tooltip-reverted": "當有人使用還原或取消功能來還原我的編輯時通知我。", "echo-pref-tooltip-mention": "當有人連結我的使用者頁面時通知我。", @@ -159,7 +162,7 @@ "notification-header-mention-other-nosection": "$1在「<strong>$4</strong>」中{{GENDER:$2|提到}}了{{GENDER:$3|您}}。", "notification-header-mention-user-talkpage-v2": "$1在<strong>$4{{GENDER:$5|的}}使用者對話頁</strong>上的「<strong>$6</strong>」{{GENDER:$2|提到}}了{{GENDER:$3|您}}。", "notification-header-mention-user-talkpage-nosection": "$1在<strong>$4{{GENDER:$5|的}}使用者對話頁</strong>上{{GENDER:$2|提到}}了{{GENDER:$3|您}}。", - "notification-header-mention-agent-talkpage": "$1在<strong>{{GENDER:$2|他|她|他}}對話頁</strong>上的「<strong>$4</strong>」{{GENDER:$2|提到}}了{{GENDER:$3|您}}。", + "notification-header-mention-agent-talkpage": "$1在<strong>{{GENDER:$2|他|她|他}}的對話頁</strong>上的「<strong>$4</strong>」{{GENDER:$2|提到}}了{{GENDER:$3|您}}。", "notification-header-mention-agent-talkpage-nosection": "$1在<strong>{{GENDER:$2|他|她|他}}的對話頁</strong>上{{GENDER:$2|提到}}了{{GENDER:$3|您}}。", "notification-header-mention-article-talkpage": "$1在<strong>$4</strong>討論頁上的「<strong>$5</strong>」{{GENDER:$2|提到}}了{{GENDER:$3|您}}。", "notification-header-mention-article-talkpage-nosection": "$1在<strong>$4</strong>的討論頁上{{GENDER:$2|提到}}了{{GENDER:$3|您}}。", @@ -189,6 +192,7 @@ "notification-header-watchlist-multiuser-deleted": "<strong>$1</strong>,一個在{{GENDER:$2|您的}}監視清單上的頁面已被刪除了 $3 {{PLURAL:$3|次}}。", "notification-header-watchlist-multiuser-moved": "<strong>$1</strong>,一個在{{GENDER:$2|您的}}監視清單上的頁面已被移動了 $3 {{PLURAL:$3|次}}。", "notification-header-watchlist-multiuser-restored": "<strong>$1</strong>,一個在{{GENDER:$2|您的}}監視清單上的頁面已被恢復了 $3 {{PLURAL:$3|次}}。", + "notification-body-watchlist-once": "除非在登入時{{GENDER:$1|您有訪問}}此頁面,否則在往後進一步活動時不會有其他電子郵件通知您。", "notification-welcome-linktext": "歡迎", "notification-header-thank-you-1-edit": "{{GENDER:$2|您}}剛剛作出了{{GENDER:$2|您的}}第一次編輯。謝謝您並歡迎{{GENDER:$2|您}}!", "notification-header-thank-you-10-edit": "{{GENDER:$2|您}}剛剛作出了{{GENDER:$2|您的}}第十次編輯。謝謝您,請繼續努力!", @@ -243,5 +247,10 @@ "echo-email-batch-link-text-view-all-notifications": "檢視所有通知", "notification-header-foreign-alert": "來自{{PLURAL:$5|另一個 wiki|其他 $5 個 wiki}} 的更多通知", "notification-header-foreign-notice": "來自{{PLURAL:$5|另一個 wiki|其他 $5 個 wiki}} 的更多一般通知", - "notification-header-foreign-all": "來自 {{PLURAL:$5|其他 wiki| $5 個其他 wiki}} 的更多通知" + "notification-header-foreign-all": "來自 {{PLURAL:$5|其他 wiki| $5 個其他 wiki}} 的更多通知", + "right-manage-all-push-subscriptions": "管理所有推送訂閱", + "action-manage-all-push-subscriptions": "管理所有推送訂閱", + "group-push-subscription-manager": "推送訂閱管理", + "group-push-subscription-manager-member": "{{GENDER:$1|推送訂閱管理員}}", + "grouppage-push-subscription-manager": "{{ns:project}}:推送訂閱管理員" } diff --git a/Echo/i18n/zh-hk.json b/Echo/i18n/zh-hk.json index a8f92b8e..91090c13 100644 --- a/Echo/i18n/zh-hk.json +++ b/Echo/i18n/zh-hk.json @@ -2,8 +2,9 @@ "@metadata": { "authors": [ "A2093064", + "LuciferianThomas", "Xiplus" ] }, - "prefs-blocknotificationslist": "禁言用戶" + "prefs-blocknotificationslist": "黑名單" } diff --git a/Echo/includes/api/ApiCrossWiki.php b/Echo/includes/Api/ApiCrossWiki.php index b3f75b7e..51b20b2b 100644 --- a/Echo/includes/api/ApiCrossWiki.php +++ b/Echo/includes/Api/ApiCrossWiki.php @@ -1,5 +1,14 @@ <?php + +namespace MediaWiki\Extension\Notifications\Api; + // @phan-file-suppress PhanUndeclaredMethod This is a trait, and phan is confused by $this +use EchoForeignNotifications; +use EchoForeignWikiRequest; +use Exception; +use WikiMap; +use Wikimedia\ParamValidator\ParamValidator; + /** * Trait that adds cross-wiki functionality to an API module. For mixing into ApiBase subclasses. * @@ -36,7 +45,7 @@ trait ApiCrossWiki { $this->getModulePrefix() . 'wikis', $tokenType !== false ? $tokenType : null ); - return $foreignReq->execute(); + return $foreignReq->execute( $this->getRequest() ); } /** @@ -69,19 +78,19 @@ trait ApiCrossWiki { // if wiki is omitted from params, that's because crosswiki is/was not // available, and it'll default to current wiki - $wikis = $params['wikis'] ?? [ wfWikiID() ]; + $wikis = $params['wikis'] ?? [ WikiMap::getCurrentWikiId() ]; - if ( array_search( '*', $wikis ) !== false ) { + if ( in_array( '*', $wikis ) ) { // expand `*` to all foreign wikis with unread notifications + local $wikis = array_merge( - [ wfWikiID() ], + [ WikiMap::getCurrentWikiId() ], $this->getForeignWikisWithUnreadNotifications() ); } if ( !$this->allowCrossWikiNotifications() ) { // exclude foreign wikis if x-wiki is not enabled - $wikis = array_intersect_key( [ wfWikiID() ], $wikis ); + $wikis = array_intersect_key( [ WikiMap::getCurrentWikiId() ], $wikis ); } return $wikis; @@ -91,7 +100,7 @@ trait ApiCrossWiki { * @return string[] Wiki names */ protected function getRequestedForeignWikis() { - return array_diff( $this->getRequestedWikis(), [ wfWikiID() ] ); + return array_diff( $this->getRequestedWikis(), [ WikiMap::getCurrentWikiId() ] ); } /** @@ -123,11 +132,16 @@ trait ApiCrossWiki { $params += [ // fetch notifications from multiple wikis 'wikis' => [ - ApiBase::PARAM_ISMULTI => true, - ApiBase::PARAM_DFLT => wfWikiID(), + ParamValidator::PARAM_ISMULTI => true, + ParamValidator::PARAM_DEFAULT => WikiMap::getCurrentWikiId(), // `*` will let you immediately fetch from all wikis that have // unread notifications, without having to look them up first - ApiBase::PARAM_TYPE => array_unique( array_merge( $wgConf->wikis, [ wfWikiID(), '*' ] ) ), + ParamValidator::PARAM_TYPE => array_unique( + array_merge( + $wgConf->wikis, + [ WikiMap::getCurrentWikiId(), '*' ] + ) + ), ], ]; } diff --git a/Echo/includes/api/ApiEchoArticleReminder.php b/Echo/includes/Api/ApiEchoArticleReminder.php index 6c8c4363..60bf0247 100644 --- a/Echo/includes/api/ApiEchoArticleReminder.php +++ b/Echo/includes/Api/ApiEchoArticleReminder.php @@ -1,11 +1,20 @@ <?php +namespace MediaWiki\Extension\Notifications\Api; + +use ApiBase; +use DateInterval; +use DateTime; +use EchoEvent; +use MWTimestamp; +use Wikimedia\ParamValidator\ParamValidator; + class ApiEchoArticleReminder extends ApiBase { public function execute() { $this->getMain()->setCacheMode( 'private' ); $user = $this->getUser(); - if ( $user->isAnon() ) { + if ( !$user->isRegistered() ) { $this->dieWithError( 'apierror-mustbeloggedin-generic', 'login-required' ); } @@ -44,7 +53,7 @@ class ApiEchoArticleReminder extends ApiBase { [ 'removeDuplicates' => true ], Title::newFromID( $params['pageid'] ) ); - JobQueueGroup::singleton()->push( $job );*/ + MediaWikiServices::getInstance()->getJobQueueGroup()->push( $job );*/ $result += [ 'result' => 'success' ]; @@ -54,20 +63,20 @@ class ApiEchoArticleReminder extends ApiBase { public function getAllowedParams() { return [ 'pageid' => [ - ApiBase::PARAM_TYPE => 'integer', + ParamValidator::PARAM_TYPE => 'integer', ], 'title' => [ - ApiBase::PARAM_TYPE => 'string', + ParamValidator::PARAM_TYPE => 'string', ], 'comment' => [ - ApiBase::PARAM_TYPE => 'string', + ParamValidator::PARAM_TYPE => 'string', ], 'timestamp' => [ - ApiBase::PARAM_REQUIRED => true, - ApiBase::PARAM_TYPE => 'timestamp', + ParamValidator::PARAM_REQUIRED => true, + ParamValidator::PARAM_TYPE => 'timestamp', ], 'token' => [ - ApiBase::PARAM_REQUIRED => true, + ParamValidator::PARAM_REQUIRED => true, ], ]; } @@ -76,10 +85,6 @@ class ApiEchoArticleReminder extends ApiBase { return 'csrf'; } - public function getTokenSalt() { - return ''; - } - public function mustBePosted() { return true; } diff --git a/Echo/includes/api/ApiEchoMarkRead.php b/Echo/includes/Api/ApiEchoMarkRead.php index 93021715..f192fd50 100644 --- a/Echo/includes/api/ApiEchoMarkRead.php +++ b/Echo/includes/Api/ApiEchoMarkRead.php @@ -1,5 +1,15 @@ <?php +namespace MediaWiki\Extension\Notifications\Api; + +use ApiBase; +use EchoAttributeManager; +use EchoNotificationController; +use MWEchoDbFactory; +use MWEchoNotifUser; +use WikiMap; +use Wikimedia\ParamValidator\ParamValidator; + class ApiEchoMarkRead extends ApiBase { use ApiCrossWiki; @@ -8,7 +18,7 @@ class ApiEchoMarkRead extends ApiBase { $this->getMain()->getVal( '_' ); $user = $this->getUser(); - if ( $user->isAnon() ) { + if ( !$user->isRegistered() ) { $this->dieWithError( 'apierror-mustbeloggedin-generic', 'login-required' ); } elseif ( MWEchoDbFactory::newFromDefault()->isReadOnly() ) { $this->dieReadOnly(); @@ -19,7 +29,7 @@ class ApiEchoMarkRead extends ApiBase { $params = $this->extractRequestParams(); // Mark as read/unread locally, if requested - if ( in_array( wfWikiID(), $this->getRequestedWikis() ) ) { + if ( in_array( WikiMap::getCurrentWikiId(), $this->getRequestedWikis() ) ) { // There is no need to trigger markRead if all notifications are read if ( $notifUser->getLocalNotificationCount() > 0 ) { if ( $params['list'] ) { @@ -72,21 +82,21 @@ class ApiEchoMarkRead extends ApiBase { public function getAllowedParams() { return $this->getCrossWikiParams() + [ 'list' => [ - ApiBase::PARAM_ISMULTI => true, + ParamValidator::PARAM_ISMULTI => true, ], 'unreadlist' => [ - ApiBase::PARAM_ISMULTI => true, + ParamValidator::PARAM_ISMULTI => true, ], 'all' => [ - ApiBase::PARAM_REQUIRED => false, - ApiBase::PARAM_TYPE => 'boolean' + ParamValidator::PARAM_REQUIRED => false, + ParamValidator::PARAM_TYPE => 'boolean' ], 'sections' => [ - ApiBase::PARAM_TYPE => EchoAttributeManager::$sections, - ApiBase::PARAM_ISMULTI => true, + ParamValidator::PARAM_TYPE => EchoAttributeManager::$sections, + ParamValidator::PARAM_ISMULTI => true, ], 'token' => [ - ApiBase::PARAM_REQUIRED => true, + ParamValidator::PARAM_REQUIRED => true, ] ]; } @@ -95,10 +105,6 @@ class ApiEchoMarkRead extends ApiBase { return 'csrf'; } - public function getTokenSalt() { - return ''; - } - public function mustBePosted() { return true; } diff --git a/Echo/includes/api/ApiEchoMarkSeen.php b/Echo/includes/Api/ApiEchoMarkSeen.php index 50eeccd9..8fc16fa5 100644 --- a/Echo/includes/api/ApiEchoMarkSeen.php +++ b/Echo/includes/Api/ApiEchoMarkSeen.php @@ -1,7 +1,13 @@ <?php +namespace MediaWiki\Extension\Notifications\Api; + // This is a GET module, not a POST module, for multi-DC support. See T222851. // Note that this module doesn't write to the database, only to the seentime cache. +use ApiBase; +use EchoSeenTime; +use Wikimedia\ParamValidator\ParamValidator; + class ApiEchoMarkSeen extends ApiBase { public function execute() { @@ -9,7 +15,7 @@ class ApiEchoMarkSeen extends ApiBase { $this->getMain()->getVal( '_' ); $user = $this->getUser(); - if ( $user->isAnon() ) { + if ( !$user->isRegistered() ) { $this->dieWithError( 'apierror-mustbeloggedin-generic', 'login-required' ); } @@ -39,13 +45,13 @@ class ApiEchoMarkSeen extends ApiBase { public function getAllowedParams() { return [ 'type' => [ - ApiBase::PARAM_REQUIRED => true, - ApiBase::PARAM_TYPE => [ 'alert', 'message', 'all' ], + ParamValidator::PARAM_REQUIRED => true, + ParamValidator::PARAM_TYPE => [ 'alert', 'message', 'all' ], ], 'timestampFormat' => [ // Not using the TS constants, since clients can't. - ApiBase::PARAM_DFLT => 'MW', - ApiBase::PARAM_TYPE => [ 'ISO_8601', 'MW' ], + ParamValidator::PARAM_DEFAULT => 'MW', + ParamValidator::PARAM_TYPE => [ 'ISO_8601', 'MW' ], ], ]; } diff --git a/Echo/includes/api/ApiEchoMute.php b/Echo/includes/Api/ApiEchoMute.php index e050e3bd..9f08a712 100644 --- a/Echo/includes/api/ApiEchoMute.php +++ b/Echo/includes/Api/ApiEchoMute.php @@ -1,11 +1,24 @@ <?php +namespace MediaWiki\Extension\Notifications\Api; + +use ApiBase; +use ApiMain; +use CentralIdLookup; use MediaWiki\MediaWikiServices; +use MediaWiki\User\UserOptionsManager; +use Title; +use Wikimedia\ParamValidator\ParamValidator; class ApiEchoMute extends ApiBase { - private $centralIdLookup = null; + /** @var CentralIdLookup */ + private $centralIdLookup; + + /** @var UserOptionsManager */ + private $userOptionsManager; + /** @var string[][] */ private static $muteLists = [ 'user' => [ 'pref' => 'echo-notifications-blacklist', @@ -17,9 +30,27 @@ class ApiEchoMute extends ApiBase { ], ]; + /** + * @param ApiMain $main + * @param string $action + * @param CentralIdLookup $centralIdLookup + * @param UserOptionsManager $userOptionsManager + */ + public function __construct( + ApiMain $main, + $action, + CentralIdLookup $centralIdLookup, + UserOptionsManager $userOptionsManager + ) { + parent::__construct( $main, $action ); + + $this->centralIdLookup = $centralIdLookup; + $this->userOptionsManager = $userOptionsManager; + } + public function execute() { $user = $this->getUser()->getInstanceForUpdate(); - if ( !$user || $user->isAnon() ) { + if ( !$user || !$user->isRegistered() ) { $this->dieWithError( [ 'apierror-mustbeloggedin', $this->msg( 'action-editmyoptions' ) ], 'notloggedin' @@ -30,8 +61,8 @@ class ApiEchoMute extends ApiBase { $params = $this->extractRequestParams(); $mutelistInfo = self::$muteLists[ $params['type'] ]; - $prefValue = $user->getOption( $mutelistInfo['pref'] ); - $ids = $this->parsePref( $prefValue, $mutelistInfo['type'] ); + $prefValue = $this->userOptionsManager->getOption( $user, $mutelistInfo['pref'] ); + $ids = $this->parsePref( $prefValue ); $targetsToMute = $params['mute'] ?? []; $targetsToUnmute = $params['unmute'] ?? []; @@ -53,20 +84,17 @@ class ApiEchoMute extends ApiBase { } if ( $changed ) { - $user->setOption( $mutelistInfo['pref'], $this->serializePref( $ids, $mutelistInfo['type'] ) ); + $this->userOptionsManager->setOption( + $user, + $mutelistInfo['pref'], + $this->serializePref( $ids ) + ); $user->saveSettings(); } $this->getResult()->addValue( null, $this->getModuleName(), 'success' ); } - private function getCentralIdLookup() { - if ( $this->centralIdLookup === null ) { - $this->centralIdLookup = CentralIdLookup::factory(); - } - return $this->centralIdLookup; - } - private function lookupIds( $names, $type ) { if ( $type === 'title' ) { $linkBatch = MediaWikiServices::getInstance()->getLinkBatchFactory()->newLinkBatch(); @@ -84,29 +112,29 @@ class ApiEchoMute extends ApiBase { } return $ids; } elseif ( $type === 'user' ) { - return $this->getCentralIdLookup()->centralIdsFromNames( $names, CentralIdLookup::AUDIENCE_PUBLIC ); + return $this->centralIdLookup->centralIdsFromNames( $names, CentralIdLookup::AUDIENCE_PUBLIC ); } } - private function parsePref( $prefValue, $type ) { + private function parsePref( $prefValue ) { return preg_split( '/\n/', $prefValue, -1, PREG_SPLIT_NO_EMPTY ); } - private function serializePref( $ids, $type ) { + private function serializePref( $ids ) { return implode( "\n", $ids ); } public function getAllowedParams( $flags = 0 ) { return [ 'type' => [ - ApiBase::PARAM_REQUIRED => true, - ApiBase::PARAM_TYPE => array_keys( self::$muteLists ), + ParamValidator::PARAM_REQUIRED => true, + ParamValidator::PARAM_TYPE => array_keys( self::$muteLists ), ], 'mute' => [ - ApiBase::PARAM_ISMULTI => true, + ParamValidator::PARAM_ISMULTI => true, ], 'unmute' => [ - ApiBase::PARAM_ISMULTI => true, + ParamValidator::PARAM_ISMULTI => true, ] ]; } @@ -115,10 +143,6 @@ class ApiEchoMute extends ApiBase { return 'csrf'; } - public function getTokenSalt() { - return ''; - } - public function mustBePosted() { return true; } diff --git a/Echo/includes/api/ApiEchoNotifications.php b/Echo/includes/Api/ApiEchoNotifications.php index 3d4736c4..ad7093e5 100644 --- a/Echo/includes/api/ApiEchoNotifications.php +++ b/Echo/includes/Api/ApiEchoNotifications.php @@ -1,5 +1,27 @@ <?php +namespace MediaWiki\Extension\Notifications\Api; + +use ApiBase; +use ApiQuery; +use ApiQueryBase; +use Bundler; +use Config; +use EchoAttributeManager; +use EchoDataOutputFormatter; +use EchoForeignNotifications; +use EchoNotification; +use EchoNotificationController; +use EchoNotificationMapper; +use EchoSeenTime; +use EchoServices; +use MWEchoNotifUser; +use Title; +use User; +use WikiMap; +use Wikimedia\ParamValidator\ParamValidator; +use Wikimedia\ParamValidator\TypeDef\IntegerDef; + class ApiEchoNotifications extends ApiQueryBase { use ApiCrossWiki; @@ -8,15 +30,19 @@ class ApiEchoNotifications extends ApiQueryBase { */ protected $crossWikiSummary = false; - public function __construct( $query, $moduleName ) { + /** @var string[] */ + private $allowedNotifierTypes; + + public function __construct( ApiQuery $query, string $moduleName, Config $mainConfig ) { parent::__construct( $query, $moduleName, 'not' ); + $this->allowedNotifierTypes = array_keys( $mainConfig->get( 'EchoNotifiers' ) ); } public function execute() { // To avoid API warning, register the parameter used to bust browser cache $this->getMain()->getVal( '_' ); - if ( $this->getUser()->isAnon() ) { + if ( !$this->getUser()->isRegistered() ) { $this->dieWithError( 'apierror-mustbeloggedin-generic', 'login-required' ); } @@ -36,8 +62,8 @@ class ApiEchoNotifications extends ApiQueryBase { } $results = []; - if ( in_array( wfWikiID(), $this->getRequestedWikis() ) ) { - $results[wfWikiID()] = $this->getLocalNotifications( $params ); + if ( in_array( WikiMap::getCurrentWikiId(), $this->getRequestedWikis() ) ) { + $results[WikiMap::getCurrentWikiId()] = $this->getLocalNotifications( $params ); } if ( $this->getRequestedForeignWikis() ) { @@ -88,7 +114,8 @@ class ApiEchoNotifications extends ApiQueryBase { $result[$section] = $this->getSectionPropList( $user, $section, $params['filter'], $params['limit'], $params[$section . 'continue'], $params['format'], - $titles, $params[$section . 'unreadfirst'], $params['bundle'] + $titles, $params[$section . 'unreadfirst'], $params['bundle'], + $params['notifiertypes'] ); if ( $this->crossWikiSummary ) { @@ -100,10 +127,11 @@ class ApiEchoNotifications extends ApiQueryBase { } } } else { - $attributeManager = EchoAttributeManager::newFromGlobalVars(); + $attributeManager = EchoServices::getInstance()->getAttributeManager(); $result = $this->getPropList( $user, - $attributeManager->getUserEnabledEventsbySections( $user, 'web', $params['sections'] ), + $attributeManager->getUserEnabledEventsBySections( $user, $params['notifiertypes'], + $params['sections'] ), $params['filter'], $params['limit'], $params['continue'], $params['format'], $titles, $params['unreadfirst'], $params['bundle'] ); @@ -150,6 +178,7 @@ class ApiEchoNotifications extends ApiQueryBase { * @param Title[]|null $titles * @param bool $unreadFirst * @param bool $bundle + * @param string[] $notifierTypes * @return array */ protected function getSectionPropList( @@ -161,10 +190,11 @@ class ApiEchoNotifications extends ApiQueryBase { $format, array $titles = null, $unreadFirst = false, - $bundle = false + $bundle = false, + array $notifierTypes = [ 'web' ] ) { - $attributeManager = EchoAttributeManager::newFromGlobalVars(); - $sectionEvents = $attributeManager->getUserEnabledEventsbySections( $user, 'web', [ $section ] ); + $attributeManager = EchoServices::getInstance()->getAttributeManager(); + $sectionEvents = $attributeManager->getUserEnabledEventsBySections( $user, $notifierTypes, [ $section ] ); if ( !$sectionEvents ) { $result = [ @@ -387,29 +417,30 @@ class ApiEchoNotifications extends ApiQueryBase { } // Sort wikis by timestamp, in descending order (newest first) - usort( $wikis, function ( $a, $b ) use ( $section, $timestampsByWiki ) { + usort( $wikis, static function ( $a, $b ) use ( $section, $timestampsByWiki ) { return (int)$timestampsByWiki[$b]->getTimestamp( TS_UNIX ) - (int)$timestampsByWiki[$a]->getTimestamp( TS_UNIX ); } ); - $row = new stdClass; - $row->event_id = -1; - $row->event_type = 'foreign'; - $row->event_variant = null; - $row->event_agent_id = $user->getId(); - $row->event_agent_ip = null; - $row->event_page_id = null; - $row->event_extra = serialize( [ - 'section' => $section ?: 'all', - 'wikis' => $wikis, - 'count' => $count - ] ); - $row->event_deleted = 0; - - $row->notification_user = $user->getId(); - $row->notification_timestamp = $maxTimestamp; - $row->notification_read_timestamp = null; - $row->notification_bundle_hash = md5( 'bogus' ); + $row = (object)[ + 'event_id' => -1, + 'event_type' => 'foreign', + 'event_variant' => null, + 'event_agent_id' => $user->getId(), + 'event_agent_ip' => null, + 'event_page_id' => null, + 'event_extra' => serialize( [ + 'section' => $section ?: 'all', + 'wikis' => $wikis, + 'count' => $count + ] ), + 'event_deleted' => 0, + + 'notification_user' => $user->getId(), + 'notification_timestamp' => $maxTimestamp, + 'notification_read_timestamp' => null, + 'notification_bundle_hash' => md5( 'bogus' ), + ]; // Format output like any other notification $notif = EchoNotification::newFromRow( $row ); @@ -441,90 +472,90 @@ class ApiEchoNotifications extends ApiQueryBase { * @return array */ protected function mergeResults( array $results, array $params ) { - $master = array_shift( $results ); - if ( !$master ) { - $master = []; + $primary = array_shift( $results ); + if ( !$primary ) { + $primary = []; } if ( in_array( 'list', $params['prop'] ) ) { - $master = $this->mergeList( $master, $results, $params['groupbysection'] ); + $primary = $this->mergeList( $primary, $results, $params['groupbysection'] ); } if ( in_array( 'count', $params['prop'] ) && !$this->crossWikiSummary ) { - // if crosswiki data was requested, the count in $master + // if crosswiki data was requested, the count in $primary // is accurate already // otherwise, we'll want to combine counts for all wikis - $master = $this->mergeCount( $master, $results, $params['groupbysection'] ); + $primary = $this->mergeCount( $primary, $results, $params['groupbysection'] ); } - return $master; + return $primary; } /** - * @param array $master + * @param array $primary * @param array[] $results * @param bool $groupBySection * @return array */ - protected function mergeList( array $master, array $results, $groupBySection ) { + protected function mergeList( array $primary, array $results, $groupBySection ) { // sort all notifications by timestamp: most recent first - $sort = function ( $a, $b ) { + $sort = static function ( $a, $b ) { return $a['timestamp']['utcunix'] - $b['timestamp']['utcunix']; }; if ( $groupBySection ) { foreach ( EchoAttributeManager::$sections as $section ) { - if ( !isset( $master[$section]['list'] ) ) { - $master[$section]['list'] = []; + if ( !isset( $primary[$section]['list'] ) ) { + $primary[$section]['list'] = []; } foreach ( $results as $result ) { - $master[$section]['list'] = array_merge( $master[$section]['list'], $result[$section]['list'] ); + $primary[$section]['list'] = array_merge( $primary[$section]['list'], $result[$section]['list'] ); } - usort( $master[$section]['list'], $sort ); + usort( $primary[$section]['list'], $sort ); } } else { - if ( !isset( $master['list'] ) || !is_array( $master['list'] ) ) { - $master['list'] = []; + if ( !isset( $primary['list'] ) || !is_array( $primary['list'] ) ) { + $primary['list'] = []; } foreach ( $results as $result ) { - $master['list'] = array_merge( $master['list'], $result['list'] ); + $primary['list'] = array_merge( $primary['list'], $result['list'] ); } - usort( $master['list'], $sort ); + usort( $primary['list'], $sort ); } - return $master; + return $primary; } /** - * @param array $master + * @param array $primary * @param array[] $results * @param bool $groupBySection * @return array */ - protected function mergeCount( array $master, array $results, $groupBySection ) { + protected function mergeCount( array $primary, array $results, $groupBySection ) { if ( $groupBySection ) { foreach ( EchoAttributeManager::$sections as $section ) { - if ( !isset( $master[$section]['rawcount'] ) ) { - $master[$section]['rawcount'] = 0; + if ( !isset( $primary[$section]['rawcount'] ) ) { + $primary[$section]['rawcount'] = 0; } foreach ( $results as $result ) { - $master[$section]['rawcount'] += $result[$section]['rawcount']; + $primary[$section]['rawcount'] += $result[$section]['rawcount']; } - $master[$section]['count'] = EchoNotificationController::formatNotificationCount( - $master[$section]['rawcount'] ); + $primary[$section]['count'] = EchoNotificationController::formatNotificationCount( + $primary[$section]['rawcount'] ); } } - if ( !isset( $master['rawcount'] ) ) { - $master['rawcount'] = 0; + if ( !isset( $primary['rawcount'] ) ) { + $primary['rawcount'] = 0; } foreach ( $results as $result ) { // regardless of groupbysection, totals are always included - $master['rawcount'] += $result['rawcount']; + $primary['rawcount'] += $result['rawcount']; } - $master['count'] = EchoNotificationController::formatNotificationCount( $master['rawcount'] ); + $primary['count'] = EchoNotificationController::formatNotificationCount( $primary['rawcount'] ); - return $master; + return $primary; } public function getAllowedParams() { @@ -532,33 +563,33 @@ class ApiEchoNotifications extends ApiQueryBase { $params = $this->getCrossWikiParams() + [ 'filter' => [ - ApiBase::PARAM_ISMULTI => true, - ApiBase::PARAM_DFLT => 'read|!read', - ApiBase::PARAM_TYPE => [ + ParamValidator::PARAM_ISMULTI => true, + ParamValidator::PARAM_DEFAULT => 'read|!read', + ParamValidator::PARAM_TYPE => [ 'read', '!read', ], ], 'prop' => [ - ApiBase::PARAM_ISMULTI => true, - ApiBase::PARAM_TYPE => [ + ParamValidator::PARAM_ISMULTI => true, + ParamValidator::PARAM_TYPE => [ 'list', 'count', 'seenTime', ], - ApiBase::PARAM_DFLT => 'list', + ParamValidator::PARAM_DEFAULT => 'list', ], 'sections' => [ - ApiBase::PARAM_DFLT => implode( '|', $sections ), - ApiBase::PARAM_TYPE => $sections, - ApiBase::PARAM_ISMULTI => true, + ParamValidator::PARAM_DEFAULT => implode( '|', $sections ), + ParamValidator::PARAM_TYPE => $sections, + ParamValidator::PARAM_ISMULTI => true, ], 'groupbysection' => [ - ApiBase::PARAM_TYPE => 'boolean', - ApiBase::PARAM_DFLT => false, + ParamValidator::PARAM_TYPE => 'boolean', + ParamValidator::PARAM_DEFAULT => false, ], 'format' => [ - ApiBase::PARAM_TYPE => [ + ParamValidator::PARAM_TYPE => [ 'model', 'special', 'flyout', /* @deprecated */ @@ -567,32 +598,37 @@ class ApiEchoNotifications extends ApiQueryBase { ApiBase::PARAM_HELP_MSG_PER_VALUE => [], ], 'limit' => [ - ApiBase::PARAM_TYPE => 'limit', - ApiBase::PARAM_DFLT => 20, - ApiBase::PARAM_MIN => 1, - ApiBase::PARAM_MAX => ApiBase::LIMIT_SML1, - ApiBase::PARAM_MAX2 => ApiBase::LIMIT_SML2, + ParamValidator::PARAM_TYPE => 'limit', + ParamValidator::PARAM_DEFAULT => 20, + IntegerDef::PARAM_MIN => 1, + IntegerDef::PARAM_MAX => ApiBase::LIMIT_SML1, + IntegerDef::PARAM_MAX2 => ApiBase::LIMIT_SML2, ], 'continue' => [ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue', ], 'unreadfirst' => [ - ApiBase::PARAM_TYPE => 'boolean', - ApiBase::PARAM_DFLT => false, + ParamValidator::PARAM_TYPE => 'boolean', + ParamValidator::PARAM_DEFAULT => false, ], 'titles' => [ - ApiBase::PARAM_ISMULTI => true, + ParamValidator::PARAM_ISMULTI => true, ], 'bundle' => [ - ApiBase::PARAM_TYPE => 'boolean', - ApiBase::PARAM_DFLT => false, + ParamValidator::PARAM_TYPE => 'boolean', + ParamValidator::PARAM_DEFAULT => false, + ], + 'notifiertypes' => [ + ParamValidator::PARAM_TYPE => $this->allowedNotifierTypes, + ParamValidator::PARAM_ISMULTI => true, + ParamValidator::PARAM_DEFAULT => 'web', ], ]; foreach ( $sections as $section ) { $params[$section . 'continue'] = null; $params[$section . 'unreadfirst'] = [ - ApiBase::PARAM_TYPE => 'boolean', - ApiBase::PARAM_DFLT => false, + ParamValidator::PARAM_TYPE => 'boolean', + ParamValidator::PARAM_DEFAULT => false, ]; } @@ -601,8 +637,8 @@ class ApiEchoNotifications extends ApiQueryBase { // create "x notifications from y wikis" notification bundle & // include unread counts from other wikis in prop=count results 'crosswikisummary' => [ - ApiBase::PARAM_TYPE => 'boolean', - ApiBase::PARAM_DFLT => false, + ParamValidator::PARAM_TYPE => 'boolean', + ParamValidator::PARAM_DEFAULT => false, ], ]; } @@ -620,6 +656,8 @@ class ApiEchoNotifications extends ApiQueryBase { => 'apihelp-query+notifications-example-1', 'action=query&meta=notifications¬prop=count¬sections=alert|message¬groupbysection=1' => 'apihelp-query+notifications-example-2', + 'action=query&meta=notifications¬notifiertypes=email' + => 'apihelp-query+notifications-example-3', ]; } diff --git a/Echo/includes/api/ApiEchoUnreadNotificationPages.php b/Echo/includes/Api/ApiEchoUnreadNotificationPages.php index 95f9b5df..6dd4676d 100644 --- a/Echo/includes/api/ApiEchoUnreadNotificationPages.php +++ b/Echo/includes/Api/ApiEchoUnreadNotificationPages.php @@ -1,5 +1,22 @@ <?php +namespace MediaWiki\Extension\Notifications\Api; + +use ApiQuery; +use ApiQueryBase; +use ApiUsageException; +use EchoServices; +use MediaWiki\Logger\LoggerFactory; +use MediaWiki\Page\PageRecord; +use MediaWiki\Page\PageStore; +use MWEchoDbFactory; +use MWEchoNotifUser; +use Title; +use TitleFactory; +use WikiMap; +use Wikimedia\ParamValidator\ParamValidator; +use Wikimedia\ParamValidator\TypeDef\IntegerDef; + class ApiEchoUnreadNotificationPages extends ApiQueryBase { use ApiCrossWiki; @@ -9,11 +26,25 @@ class ApiEchoUnreadNotificationPages extends ApiQueryBase { protected $crossWikiSummary = false; /** + * @var PageStore + */ + private $pageStore; + + /** + * @var TitleFactory + */ + private $titleFactory; + + /** * @param ApiQuery $query * @param string $moduleName + * @param PageStore $pageStore + * @param TitleFactory $titleFactory */ - public function __construct( $query, $moduleName ) { + public function __construct( $query, $moduleName, PageStore $pageStore, TitleFactory $titleFactory ) { parent::__construct( $query, $moduleName, 'unp' ); + $this->pageStore = $pageStore; + $this->titleFactory = $titleFactory; } /** @@ -23,15 +54,15 @@ class ApiEchoUnreadNotificationPages extends ApiQueryBase { // To avoid API warning, register the parameter used to bust browser cache $this->getMain()->getVal( '_' ); - if ( $this->getUser()->isAnon() ) { + if ( !$this->getUser()->isRegistered() ) { $this->dieWithError( 'apierror-mustbeloggedin-generic', 'login-required' ); } $params = $this->extractRequestParams(); $result = []; - if ( in_array( wfWikiID(), $this->getRequestedWikis() ) ) { - $result[wfWikiID()] = $this->getFromLocal( $params['limit'], $params['grouppages'] ); + if ( in_array( WikiMap::getCurrentWikiId(), $this->getRequestedWikis() ) ) { + $result[WikiMap::getCurrentWikiId()] = $this->getFromLocal( $params['limit'], $params['grouppages'] ); } if ( $this->getRequestedForeignWikis() ) { @@ -54,7 +85,7 @@ class ApiEchoUnreadNotificationPages extends ApiQueryBase { * @phan-return array{pages:array[],totalCount:int} */ protected function getFromLocal( $limit, $groupPages ) { - $attributeManager = EchoAttributeManager::newFromGlobalVars(); + $attributeManager = EchoServices::getInstance()->getAttributeManager(); $enabledTypes = $attributeManager->getUserEnabledEvents( $this->getUser(), 'web' ); $dbr = MWEchoDbFactory::newFromDefault()->getEchoDb( DB_REPLICA ); @@ -88,18 +119,22 @@ class ApiEchoUnreadNotificationPages extends ApiQueryBase { $pageCounts = []; foreach ( $rows as $row ) { if ( $row->event_page_id !== null ) { - // @phan-suppress-next-line PhanTypeMismatchDimAssignment - $pageCounts[$row->event_page_id] = intval( $row->count ); + $pageCounts[(int)$row->event_page_id] = intval( $row->count ); } else { $nullCount = intval( $row->count ); } } - // @phan-suppress-next-line PhanTypeMismatchArgument - $titles = Title::newFromIDs( array_keys( $pageCounts ) ); + $titles = $this->pageStore + ->newSelectQueryBuilder() + ->wherePageIds( array_keys( $pageCounts ) ) + ->caller( __METHOD__ ) + ->fetchPageRecords(); $groupCounts = []; + /** @var PageRecord $title */ foreach ( $titles as $title ) { + $title = $this->titleFactory->castFromPageIdentity( $title ); if ( $groupPages ) { // If $title is a talk page, add its count to its subject page's count $pageName = $title->getSubjectPage()->getPrefixedText(); @@ -107,8 +142,7 @@ class ApiEchoUnreadNotificationPages extends ApiQueryBase { $pageName = $title->getPrefixedText(); } - // @phan-suppress-next-line PhanTypeMismatchDimFetch - $count = $pageCounts[$title->getArticleID()]; + $count = $pageCounts[$title->getArticleID()] ?? 0; if ( isset( $groupCounts[$pageName] ) ) { $groupCounts[$pageName] += $count; } else { @@ -174,7 +208,19 @@ class ApiEchoUnreadNotificationPages extends ApiQueryBase { protected function getUnreadNotificationPagesFromForeign() { $result = []; foreach ( $this->getFromForeign() as $wiki => $data ) { - $result[$wiki] = $data['query'][$this->getModuleName()][$wiki]; + if ( isset( $data['query'][$this->getModuleName()][$wiki] ) ) { + $result[$wiki] = $data['query'][$this->getModuleName()][$wiki]; + } else { + # Usually an error or it is some malformed response + # T273479 + LoggerFactory::getInstance( 'Echo' )->warning( + __METHOD__ . ': Unexpected API response from {wiki}', + [ + 'wiki' => $wiki, + 'data' => $data, + ] + ); + } } return $result; @@ -184,19 +230,19 @@ class ApiEchoUnreadNotificationPages extends ApiQueryBase { * @return array[] */ public function getAllowedParams() { - global $wgEchoMaxUpdateCount; + $maxUpdateCount = $this->getConfig()->get( 'EchoMaxUpdateCount' ); return $this->getCrossWikiParams() + [ 'grouppages' => [ - ApiBase::PARAM_TYPE => 'boolean', - ApiBase::PARAM_DFLT => false, + ParamValidator::PARAM_TYPE => 'boolean', + ParamValidator::PARAM_DEFAULT => false, ], 'limit' => [ - ApiBase::PARAM_TYPE => 'limit', - ApiBase::PARAM_DFLT => 10, - ApiBase::PARAM_MIN => 1, - ApiBase::PARAM_MAX => $wgEchoMaxUpdateCount, - ApiBase::PARAM_MAX2 => $wgEchoMaxUpdateCount, + ParamValidator::PARAM_TYPE => 'limit', + ParamValidator::PARAM_DEFAULT => 10, + IntegerDef::PARAM_MIN => 1, + IntegerDef::PARAM_MAX => $maxUpdateCount, + IntegerDef::PARAM_MAX2 => $maxUpdateCount, ], // there is no `offset` or `continue` value: the set of possible // notifications is small enough to allow fetching all of them at diff --git a/Echo/includes/AttributeManager.php b/Echo/includes/AttributeManager.php index 9851c8b3..aa4df06a 100644 --- a/Echo/includes/AttributeManager.php +++ b/Echo/includes/AttributeManager.php @@ -1,10 +1,21 @@ <?php +use MediaWiki\User\UserGroupManager; +use MediaWiki\User\UserIdentity; +use MediaWiki\User\UserOptionsLookup; + /** - * An object that manages attributes of echo notifications: category, elegibility, + * An object that manages attributes of echo notifications: category, eligibility, * group, section etc. */ class EchoAttributeManager { + /** + * @var UserGroupManager + */ + private $userGroupManager; + + /** @var UserOptionsLookup */ + private $userOptionsLookup; /** * @var array[] @@ -29,11 +40,12 @@ class EchoAttributeManager { /** * Notification section constant */ - const ALERT = 'alert'; - const MESSAGE = 'message'; - const ALL = 'all'; + public const ALERT = 'alert'; + public const MESSAGE = 'message'; + public const ALL = 'all'; - protected static $DEFAULT_SECTION = self::ALERT; + /** @var string */ + protected const DEFAULT_SECTION = self::ALERT; /** * Notifications are broken down to two sections, default is alert @@ -47,14 +59,8 @@ class EchoAttributeManager { /** * Names for keys in $wgEchoNotifications notification config */ - const ATTR_LOCATORS = 'user-locators'; - const ATTR_FILTERS = 'user-filters'; - - /** - * An EchoAttributeManager instance created from global variables - * @var self - */ - protected static $globalVarInstance; + public const ATTR_LOCATORS = 'user-locators'; + public const ATTR_FILTERS = 'user-filters'; /** * @param array[] $notifications Notification attributes @@ -64,12 +70,16 @@ class EchoAttributeManager { * @param array[] $notifyTypeAvailabilityByCategory Associative array with * categories as keys and value an associative array as with * $defaultNotifyTypeAvailability. + * @param UserGroupManager $userGroupManager + * @param UserOptionsLookup $userOptionsLookup */ public function __construct( array $notifications, array $categories, array $defaultNotifyTypeAvailability, - array $notifyTypeAvailabilityByCategory + array $notifyTypeAvailabilityByCategory, + UserGroupManager $userGroupManager, + UserOptionsLookup $userOptionsLookup ) { // Extensions can define their own notifications and categories $this->notifications = $notifications; @@ -77,36 +87,8 @@ class EchoAttributeManager { $this->defaultNotifyTypeAvailability = $defaultNotifyTypeAvailability; $this->notifyTypeAvailabilityByCategory = $notifyTypeAvailabilityByCategory; - } - - /** - * Create an instance from global variables - * @return EchoAttributeManager - */ - public static function newFromGlobalVars() { - global $wgEchoNotifications, $wgEchoNotificationCategories, - $wgDefaultNotifyTypeAvailability, $wgNotifyTypeAvailabilityByCategory; - - // Unit test may alter the global data for test purpose - if ( defined( 'MW_PHPUNIT_TEST' ) ) { - return new self( - $wgEchoNotifications, - $wgEchoNotificationCategories, - $wgDefaultNotifyTypeAvailability, - $wgNotifyTypeAvailabilityByCategory - ); - } - - if ( self::$globalVarInstance === null ) { - self::$globalVarInstance = new self( - $wgEchoNotifications, - $wgEchoNotificationCategories, - $wgDefaultNotifyTypeAvailability, - $wgNotifyTypeAvailabilityByCategory - ); - } - - return self::$globalVarInstance; + $this->userGroupManager = $userGroupManager; + $this->userOptionsLookup = $userOptionsLookup; } /** @@ -127,30 +109,47 @@ class EchoAttributeManager { /** * Get the enabled events for a user, which excludes user-dismissed events * from the general enabled events - * @param User $user - * @param string $notifyType Either "web" or "email". + * @param UserIdentity $userIdentity + * @param string|string[] $notifierTypes a defined notifier type, or an array containing one + * or more defined notifier types * @return string[] */ - public function getUserEnabledEvents( User $user, $notifyType ) { + public function getUserEnabledEvents( UserIdentity $userIdentity, $notifierTypes ) { + if ( is_string( $notifierTypes ) ) { + $notifierTypes = [ $notifierTypes ]; + } return array_values( array_filter( array_keys( $this->notifications ), - function ( $eventType ) use ( $user, $notifyType ) { + function ( $eventType ) use ( $userIdentity, $notifierTypes ) { $category = $this->getNotificationCategory( $eventType ); - return $this->isNotifyTypeAvailableForCategory( $category, $notifyType ) && - $this->getCategoryEligibility( $user, $category ) && - $user->getOption( "echo-subscriptions-$notifyType-$category" ); + return $this->getCategoryEligibility( $userIdentity, $category ) && + array_reduce( $notifierTypes, function ( $prev, $type ) use ( $userIdentity, $category ) { + return $prev || + ( + $this->isNotifyTypeAvailableForCategory( $category, $type ) && + $this->userOptionsLookup->getOption( + $userIdentity, + "echo-subscriptions-$type-$category" + ) + ); + }, false ); } ) ); } /** * Get the user enabled events for the specified sections - * @param User $user - * @param string $notifyType Either "web" or "email". + * @param UserIdentity $userIdentity + * @param string|string[] $notifierTypes a defined notifier type, or an array containing one + * or more defined notifier types * @param string[] $sections * @return string[] */ - public function getUserEnabledEventsbySections( User $user, $notifyType, array $sections ) { + public function getUserEnabledEventsBySections( + UserIdentity $userIdentity, + $notifierTypes, + array $sections + ) { $events = []; foreach ( $sections as $section ) { $events = array_merge( @@ -160,7 +159,7 @@ class EchoAttributeManager { } return array_intersect( - $this->getUserEnabledEvents( $user, $notifyType ), + $this->getUserEnabledEvents( $userIdentity, $notifierTypes ), $events ); } @@ -175,7 +174,7 @@ class EchoAttributeManager { public function getEventsForSection( $section ) { $events = []; - $isDefault = ( $section === self::$DEFAULT_SECTION ); + $isDefault = ( $section === self::DEFAULT_SECTION ); foreach ( $this->notifications as $event => $attribs ) { if ( @@ -214,12 +213,12 @@ class EchoAttributeManager { * See if a user is eligible to receive a certain type of notification * (based on user groups, not user preferences) * - * @param User $user + * @param UserIdentity $userIdentity * @param string $category A notification category defined in $wgEchoNotificationCategories * @return bool */ - public function getCategoryEligibility( $user, $category ) { - $usersGroups = $user->getGroups(); + public function getCategoryEligibility( UserIdentity $userIdentity, $category ) { + $usersGroups = $this->userGroupManager->getUserGroups( $userIdentity ); if ( isset( $this->categories[$category]['usergroups'] ) ) { $allowedGroups = $this->categories[$category]['usergroups']; if ( !array_intersect( $usersGroups, $allowedGroups ) ) { @@ -369,12 +368,11 @@ class EchoAttributeManager { /** * Get notification section for a notification type - * @todo add a unit test case * @param string $notificationType * @return string */ public function getNotificationSection( $notificationType ) { - return $this->notifications[$notificationType]['section'] ?? 'alert'; + return $this->notifications[$notificationType]['section'] ?? self::DEFAULT_SECTION; } /** @@ -392,4 +390,12 @@ class EchoAttributeManager { return $events; } + /** + * @param string $type + * @return bool Whether a notification type can be an expandable bundle + */ + public function isBundleExpandable( $type ) { + return $this->notifications[$type]['bundle']['expandable'] ?? false; + } + } diff --git a/Echo/includes/Bundler.php b/Echo/includes/Bundler.php index f91bece5..ad9ad7b1 100644 --- a/Echo/includes/Bundler.php +++ b/Echo/includes/Bundler.php @@ -3,15 +3,9 @@ class Bundler { private function sort( &$array ) { - // We have to ignore the error here (use @usort) - // otherwise this code fails when executed by unit tests - // See: https://bugs.php.net/bug.php?id=50688 - - // @codingStandardsIgnoreStart - @usort( $array, function( Bundleable $a, Bundleable $b ) { + usort( $array, static function ( Bundleable $a, Bundleable $b ) { return strcmp( $b->getSortingKey(), $a->getSortingKey() ); } ); - // @codingStandardsIgnoreEnd } /** diff --git a/Echo/includes/DataOutputFormatter.php b/Echo/includes/DataOutputFormatter.php index 1b4abfd9..2e22adbd 100644 --- a/Echo/includes/DataOutputFormatter.php +++ b/Echo/includes/DataOutputFormatter.php @@ -1,9 +1,13 @@ <?php +use MediaWiki\Extension\Notifications\Formatters\EchoFlyoutFormatter; +use MediaWiki\Extension\Notifications\Formatters\EchoModelFormatter; +use MediaWiki\Extension\Notifications\Formatters\SpecialNotificationsFormatter; use MediaWiki\Revision\RevisionRecord; /** * Utility class that formats a notification in the format specified + * @todo Make this a service with DI */ class EchoDataOutputFormatter { @@ -46,12 +50,12 @@ class EchoDataOutputFormatter { $bundledNotifs = $notification->getBundledNotifications(); if ( $bundledNotifs ) { - $bundledEvents = array_map( function ( EchoNotification $notif ) { + $bundledEvents = array_map( static function ( EchoNotification $notif ) { return $notif->getEvent(); }, $bundledNotifs ); $event->setBundledEvents( $bundledEvents ); - $bundledIds = array_map( function ( $event ) { + $bundledIds = array_map( static function ( $event ) { return (int)$event->getId(); }, $bundledEvents ); } @@ -78,7 +82,7 @@ class EchoDataOutputFormatter { // End creating date section header $output = [ - 'wiki' => wfWikiID(), + 'wiki' => WikiMap::getCurrentWikiId(), 'id' => $event->getId(), 'type' => $event->getType(), 'category' => $event->getCategory(), @@ -155,7 +159,7 @@ class EchoDataOutputFormatter { $output['*'] = $formatted; if ( $notification->getBundledNotifications() && - self::isBundleExpandable( $event->getType() ) + EchoServices::getInstance()->getAttributeManager()->isBundleExpandable( $event->getType() ) ) { $output['bundledNotifications'] = array_values( array_filter( array_map( function ( EchoNotification $notification ) use ( $format, $user, $lang ) { @@ -222,14 +226,4 @@ class EchoDataOutputFormatter { return $timestamp->getTimestamp( $format ); } - /** - * @param string $type - * @return bool Whether a notification type can be an expandable bundle - */ - public static function isBundleExpandable( $type ) { - global $wgEchoNotifications; - return isset( $wgEchoNotifications[$type]['bundle']['expandable'] ) - && $wgEchoNotifications[$type]['bundle']['expandable']; - } - } diff --git a/Echo/includes/DeferredMarkAsDeletedUpdate.php b/Echo/includes/DeferredMarkAsDeletedUpdate.php index ffd584d8..9d5ec505 100644 --- a/Echo/includes/DeferredMarkAsDeletedUpdate.php +++ b/Echo/includes/DeferredMarkAsDeletedUpdate.php @@ -34,14 +34,14 @@ class EchoDeferredMarkAsDeletedUpdate implements DeferrableUpdate { private function filterEventsWithTitleDbLag() { return array_filter( $this->events, - function ( EchoEvent $event ) { + static function ( EchoEvent $event ) { if ( !$event->getTitle() && $event->getTitle( true ) ) { // It is very likely this event was found - // unreaderable because of replica lag. + // unrenderable because of replica lag. // Do not moderate it at this time. LoggerFactory::getInstance( 'Echo' )->debug( - 'EchoDeferredMarkAsDeletedUpdate: Event {eventId} was found unrenderable ' . - ' but its associated title exists on Master. Skipping.', + 'EchoDeferredMarkAsDeletedUpdate: Event {eventId} was found unrenderable' . + ' but its associated title exists on primary database. Skipping.', [ 'eventId' => $event->getId(), 'title' => $event->getTitle()->getPrefixedText(), @@ -62,7 +62,7 @@ class EchoDeferredMarkAsDeletedUpdate implements DeferrableUpdate { $events = $this->filterEventsWithTitleDbLag(); $eventIds = array_map( - function ( EchoEvent $event ) { + static function ( EchoEvent $event ) { return $event->getId(); }, $events diff --git a/Echo/includes/DiscussionParser.php b/Echo/includes/DiscussionParser.php index 4a98b277..ef40b18f 100644 --- a/Echo/includes/DiscussionParser.php +++ b/Echo/includes/DiscussionParser.php @@ -3,12 +3,18 @@ use MediaWiki\MediaWikiServices; use MediaWiki\Revision\RevisionRecord; use MediaWiki\Revision\SlotRecord; +use MediaWiki\User\UserNameUtils; abstract class EchoDiscussionParser { - const HEADER_REGEX = '^(==+)\h*([^=].*)\h*\1$'; + private const HEADER_REGEX = '^(==+)\h*([^=].*)\h*\1$'; + public const DEFAULT_SNIPPET_LENGTH = 150; + + /** @var string|null */ protected static $timestampRegex; + /** @var array[][] */ protected static $revisionInterpretationCache = []; + /** @var EchoDiffParser|null */ protected static $diffParser; /** @@ -17,7 +23,6 @@ abstract class EchoDiscussionParser { * * @param RevisionRecord $revision * @param bool $isRevert - * @return null */ public static function generateEventsForRevision( RevisionRecord $revision, $isRevert ) { global $wgEchoMentionsOnMultipleSectionEdits; @@ -27,7 +32,7 @@ abstract class EchoDiscussionParser { // use replica database if there is a previous revision if ( $store->getPreviousRevision( $revision ) ) { $title = Title::newFromID( $revision->getPageId() ); - // use master database for new page + // use primary database for new page } else { $title = Title::newFromID( $revision->getPageId(), Title::GAID_FOR_UPDATE ); } @@ -37,28 +42,39 @@ abstract class EchoDiscussionParser { return; } + $events = []; + $interpretation = self::getChangeInterpretationForRevision( $revision ); $userID = $revision->getUser()->getId(); $userName = $revision->getUser()->getName(); - $user = $userID != 0 ? User::newFromId( $userID ) : User::newFromName( $userName, false ); + $user = $userID !== 0 ? User::newFromId( $userID ) : User::newFromName( $userName, false ); foreach ( $interpretation as $action ) { - if ( $action['type'] == 'add-comment' ) { + if ( $action['type'] === 'add-comment' ) { $fullSection = $action['full-section']; $header = self::extractHeader( $fullSection ); $userLinks = self::getUserLinks( $action['content'], $title ); - self::generateMentionEvents( $header, $userLinks, $action['content'], $revision, $user ); - } elseif ( $action['type'] == 'new-section-with-comment' ) { + $events = array_merge( + $events, + self::collectMentionEvents( $header, $userLinks, $action['content'], $revision, $user ) + ); + } elseif ( $action['type'] === 'new-section-with-comment' ) { $content = $action['content']; $header = self::extractHeader( $content ); $userLinks = self::getUserLinks( $content, $title ); - self::generateMentionEvents( $header, $userLinks, $content, $revision, $user ); - } elseif ( $action['type'] == 'add-section-multiple' && $wgEchoMentionsOnMultipleSectionEdits ) { + $events = array_merge( + $events, + self::collectMentionEvents( $header, $userLinks, $content, $revision, $user ) + ); + } elseif ( $action['type'] === 'add-section-multiple' && $wgEchoMentionsOnMultipleSectionEdits ) { $content = self::stripHeader( $action['content'] ); $content = self::stripSignature( $content ); $userLinks = self::getUserLinks( $content, $title ); - self::generateMentionEvents( $action['header'], $userLinks, $content, $revision, $user ); + $events = array_merge( + $events, + self::collectMentionEvents( $action['header'], $userLinks, $content, $revision, $user ) + ); } elseif ( $action['type'] === 'unknown-signed-change' ) { $userLinks = array_diff_key( self::getUserLinks( $action['new_content'], $title ), @@ -67,12 +83,15 @@ abstract class EchoDiscussionParser { $header = self::extractHeader( $action['full-section'] ); if ( $wgEchoMentionOnChanges ) { - self::generateMentionEvents( $header, $userLinks, $action['new_content'], $revision, $user ); + $events = array_merge( + $events, + self::collectMentionEvents( $header, $userLinks, $action['new_content'], $revision, $user ) + ); } } } - if ( $title->getNamespace() == NS_USER_TALK ) { + if ( $title->getNamespace() === NS_USER_TALK ) { $notifyUser = User::newFromName( $title->getText() ); // If the recipient is a valid non-anonymous user and hasn't turned // off their notifications, generate a talk page post Echo notification. @@ -88,7 +107,7 @@ abstract class EchoDiscussionParser { $section['section-text'] = $comment->text; } } - EchoEvent::create( [ + $events[] = [ 'type' => 'edit-user-talk', 'title' => $title, 'extra' => [ @@ -99,7 +118,7 @@ abstract class EchoDiscussionParser { 'target-page' => $title->getArticleID(), ], 'agent' => $user, - ] ); + ]; } } } @@ -129,7 +148,7 @@ abstract class EchoDiscussionParser { } if ( $mentionedUsers ) { - $info = [ + $events[] = [ 'type' => 'mention-summary', 'title' => $title, 'extra' => [ @@ -138,9 +157,17 @@ abstract class EchoDiscussionParser { ], 'agent' => $user, ]; - EchoEvent::create( $info ); } } + + // Allow extensions to generate more events for a revision, and de-duplicate + // against the standard events created above. + Hooks::run( 'EchoGetEventsForRevision', [ &$events, $revision, $isRevert ] ); + + // Create events + foreach ( $events as $event ) { + EchoEvent::create( $event ); + } } /** @@ -161,7 +188,7 @@ abstract class EchoDiscussionParser { $snippet = self::getTextSnippet( self::stripSignature( self::stripHeader( $action['content'] ), $title ), RequestContext::getMain()->getLanguage(), - 150, + self::DEFAULT_SNIPPET_LENGTH, $title ); break; case 'new-section-with-comment': @@ -169,7 +196,7 @@ abstract class EchoDiscussionParser { $snippet = self::getTextSnippet( self::stripSignature( self::stripHeader( $action['content'] ), $title ), RequestContext::getMain()->getLanguage(), - 150, + self::DEFAULT_SNIPPET_LENGTH, $title ); break; } @@ -183,7 +210,7 @@ abstract class EchoDiscussionParser { $found = true; } } - if ( $found === false ) { + if ( !$found ) { return [ 'section-title' => '', 'section-text' => '' ]; } @@ -206,17 +233,39 @@ abstract class EchoDiscussionParser { RevisionRecord $revision, User $agent ) { + $events = self::collectMentionEvents( $header, $userLinks, $content, $revision, $agent ); + foreach ( $events as $event ) { + EchoEvent::create( $event ); + } + } + + /** + * Generate mention event data for a talk page action + * @param string $header The subject line for the discussion. + * @param int[] $userLinks + * @param string $content The content of the post, as a wikitext string. + * @param RevisionRecord $revision + * @param User $agent The user who made the comment. + * @return array List of event info arrays + */ + protected static function collectMentionEvents( + $header, + array $userLinks, + $content, + RevisionRecord $revision, + User $agent + ) { global $wgEchoMaxMentionsCount, $wgEchoMentionStatusNotifications; $title = Title::newFromLinkTarget( $revision->getPageAsLinkTarget() ); if ( !$title ) { - return; + return []; } $content = self::stripHeader( $content ); $content = self::stripSignature( $content, $title ); if ( !$userLinks ) { - return; + return []; } $userMentions = self::getUserMentions( @@ -224,14 +273,15 @@ abstract class EchoDiscussionParser { ); $overallMentionsCount = self::getOverallUserMentionsCount( $userMentions ); if ( $overallMentionsCount === 0 ) { - return; + return []; } + $events = []; $stats = MediaWikiServices::getInstance()->getStatsdDataFactory(); if ( $overallMentionsCount > $wgEchoMaxMentionsCount ) { if ( $wgEchoMentionStatusNotifications ) { - EchoEvent::create( [ + $events[] = [ 'type' => 'mention-failure-too-many', 'title' => $title, 'extra' => [ @@ -239,14 +289,14 @@ abstract class EchoDiscussionParser { 'section-title' => $header, ], 'agent' => $agent, - ] ); + ]; $stats->increment( 'echo.event.mention.notification.failure-too-many' ); } - return; + return $events; } if ( $userMentions['validMentions'] ) { - EchoEvent::create( [ + $events[] = [ 'type' => 'mention', 'title' => $title, 'extra' => [ @@ -256,13 +306,13 @@ abstract class EchoDiscussionParser { 'mentioned-users' => $userMentions['validMentions'], ], 'agent' => $agent, - ] ); + ]; } if ( $wgEchoMentionStatusNotifications ) { // TODO batch? foreach ( $userMentions['validMentions'] as $mentionedUserId ) { - EchoEvent::create( [ + $events[] = [ 'type' => 'mention-success', 'title' => $title, 'extra' => [ @@ -271,13 +321,13 @@ abstract class EchoDiscussionParser { 'revid' => $revision->getId(), ], 'agent' => $agent, - ] ); + ]; $stats->increment( 'echo.event.mention.notification.success' ); } // TODO batch? foreach ( $userMentions['anonymousUsers'] as $anonymousUser ) { - EchoEvent::create( [ + $events[] = [ 'type' => 'mention-failure', 'title' => $title, 'extra' => [ @@ -287,13 +337,13 @@ abstract class EchoDiscussionParser { 'revid' => $revision->getId(), ], 'agent' => $agent, - ] ); + ]; $stats->increment( 'echo.event.mention.notification.failure-user-anonymous' ); } // TODO batch? foreach ( $userMentions['unknownUsers'] as $unknownUser ) { - EchoEvent::create( [ + $events[] = [ 'type' => 'mention-failure', 'title' => $title, 'extra' => [ @@ -303,10 +353,12 @@ abstract class EchoDiscussionParser { 'revid' => $revision->getId(), ], 'agent' => $agent, - ] ); + ]; $stats->increment( 'echo.event.mention.notification.failure-user-unknown' ); } } + + return $events; } private static function getOverallUserMentionsCount( array $userMentions ) { @@ -323,8 +375,9 @@ abstract class EchoDiscussionParser { * - [unknownUsers]: An array of DBKey strings representing unknown users. * - [anonymousUsers]: An array of DBKey strings representing anonymous IP users. */ - private static function getUserMentions( Title $title, $revisionUserId, array $userLinks ) { + public static function getUserMentions( Title $title, $revisionUserId, array $userLinks ) { global $wgEchoMaxMentionsCount; + $userMentions = [ 'validMentions' => [], 'unknownUsers' => [], @@ -333,6 +386,7 @@ abstract class EchoDiscussionParser { $count = 0; $stats = MediaWikiServices::getInstance()->getStatsdDataFactory(); + $userNameUtils = MediaWikiServices::getInstance()->getUserNameUtils(); foreach ( $userLinks as $dbk => $page_id ) { // If more users are being pinged this is likely a spam/attack vector @@ -349,7 +403,7 @@ abstract class EchoDiscussionParser { } // 2. user is an anonymous IP - if ( User::isIP( $dbk ) ) { + if ( $userNameUtils->isIP( $dbk ) ) { $userMentions['anonymousUsers'][] = $dbk; $count++; $stats->increment( 'echo.event.mention.error.anonUser' ); @@ -398,7 +452,7 @@ abstract class EchoDiscussionParser { * @return int[] * Array of links in the user namespace with DBKey => ID. */ - private static function getUserLinks( $content, Title $title ) { + public static function getUserLinks( $content, Title $title ) { $output = self::parseNonEditWikitext( $content, new Article( $title ) ); $links = $output->getLinks(); @@ -416,14 +470,14 @@ abstract class EchoDiscussionParser { /** * It's like Article::prepareTextForEdit, * but not for editing (old wikitext usually) - * Stolen from AbuseFilterVariableHolder + * Stolen from AbuseFilter's VariableHolder * * @param string $wikitext * @param Article $article * * @return ParserOutput */ - private static function parseNonEditWikitext( $wikitext, Article $article ) { + public static function parseNonEditWikitext( $wikitext, Article $article ) { static $cache = []; $cacheKey = md5( $wikitext ) . ':' . $article->getTitle()->getPrefixedText(); @@ -435,7 +489,6 @@ abstract class EchoDiscussionParser { $parser = MediaWikiServices::getInstance()->getParser(); $options = new ParserOptions( $article->getContext()->getUser() ); - $options->setTidy( true ); $output = $parser->parse( $wikitext, $article->getTitle(), $options ); $cache[$cacheKey] = $output; @@ -458,20 +511,22 @@ abstract class EchoDiscussionParser { $userIdentity = $revision->getUser(); $userID = $userIdentity ? $userIdentity->getId() : 0; $userName = $userIdentity ? $userIdentity->getName() : ''; - $user = $userID != 0 ? User::newFromId( $userID ) : User::newFromName( $userName, false ); + $user = $userID !== 0 ? User::newFromId( $userID ) : User::newFromName( $userName, false ); $prevText = ''; if ( $revision->getParentId() ) { $store = MediaWikiServices::getInstance()->getRevisionStore(); $prevRevision = $store->getRevisionById( $revision->getParentId() ); if ( $prevRevision ) { - $prevText = ContentHandler::getContentText( $prevRevision->getContent( SlotRecord::MAIN ) ) ?: ''; + $prevContent = $prevRevision->getContent( SlotRecord::MAIN ); + $prevText = ( $prevContent instanceof TextContent ) ? $prevContent->getText() : ''; } } + $content = $revision->getContent( SlotRecord::MAIN ); $changes = self::getMachineReadableDiff( $prevText, - ContentHandler::getContentText( $revision->getContent( SlotRecord::MAIN ) ) + ( $content instanceof TextContent ) ? $content->getText() : '' ); $output = self::interpretDiff( $changes, @@ -533,7 +588,7 @@ abstract class EchoDiscussionParser { continue; } - if ( $change['action'] == 'add' ) { + if ( $change['action'] === 'add' ) { $content = trim( $change['content'] ); // The \A means the regex must match at the beginning of the string. // This is slightly different than ^ which matches beginning of each @@ -600,12 +655,12 @@ abstract class EchoDiscussionParser { 'content' => $content, ]; } - } elseif ( $change['action'] == 'subtract' ) { + } elseif ( $change['action'] === 'subtract' ) { $actions[] = [ 'type' => 'unknown-subtraction', 'content' => $change['content'], ]; - } elseif ( $change['action'] == 'change' ) { + } elseif ( $change['action'] === 'change' ) { $actions[] = [ 'type' => 'unknown-change', 'old_content' => $change['old_content'], @@ -753,7 +808,7 @@ abstract class EchoDiscussionParser { /** * Gets the number of section headers in a string. * - * @param string $text The text. + * @param string $text * @return int Number of section headers found. */ public static function getSectionCount( $text ) { @@ -877,8 +932,10 @@ abstract class EchoDiscussionParser { } list( , $foundUser ) = $userData; + $userNameUtils = MediaWikiServices::getInstance()->getUserNameUtils(); - return User::getCanonicalName( $foundUser, false ) === User::getCanonicalName( $user, false ); + return $userNameUtils->getCanonical( $foundUser, UserNameUtils::RIGOR_NONE ) === + $userNameUtils->getCanonical( $user, UserNameUtils::RIGOR_NONE ); } /** @@ -1016,7 +1073,7 @@ abstract class EchoDiscussionParser { * From a line in a wiki page, determine which user, if any, * has signed it. * - * @param string $line The line. + * @param string $line * @param Title|null $title * @return array|false False for none, array for success. * - First element is the position of the signature. @@ -1028,7 +1085,7 @@ abstract class EchoDiscussionParser { /* * First we call extractUsersFromLine to get all the potential usernames * from the line. Then, we loop backwards through them, figure out which - * match to a user, regenera the signature based on that user, and + * match to a user, regenerate the signature based on that user, and * see if it matches! */ $usernames = self::extractUsersFromLine( $line ); @@ -1118,16 +1175,16 @@ abstract class EchoDiscussionParser { } $user = $userMatches[0]; - + $userNameUtils = MediaWikiServices::getInstance()->getUserNameUtils(); if ( - !User::isIP( $user ) && - User::getCanonicalName( $user ) === false + !$userNameUtils->isIP( $user ) && + $userNameUtils->getCanonical( $user ) === false ) { // Not a real username return false; } - return User::getCanonicalName( $userMatches[0], false ); + return $userNameUtils->getCanonical( $userMatches[0], UserNameUtils::RIGOR_NONE ); } /** @@ -1154,7 +1211,7 @@ abstract class EchoDiscussionParser { // Step 2: Generalise it // Trim off the timezone to replace at the end $output = $exemplarTimestamp; - $tzRegex = '/\h*\(\w+\)\h*$/'; + $tzRegex = '/\h*\(\w+\)\h*$/u'; $tzMatches = []; if ( preg_match( $tzRegex, $output, $tzMatches, PREG_OFFSET_CAPTURE ) ) { $output = substr( $output, 0, $tzMatches[0][1] ); @@ -1180,13 +1237,16 @@ abstract class EchoDiscussionParser { * Parse wikitext into truncated plain text. * @param string $text * @param Language $lang - * @param int $length Length in characters (not bytes); default 150 + * @param int $length Length in characters (not bytes); default DEFAULT_SNIPPET_LENGTH * @param Title|null $title Page from which the text snippet is being extracted + * @param bool $linestart Whether or not this is at the start of a line * @return string */ - public static function getTextSnippet( $text, Language $lang, $length = 150, $title = null ) { + public static function getTextSnippet( + $text, Language $lang, $length = self::DEFAULT_SNIPPET_LENGTH, $title = null, $linestart = true + ) { // Parse wikitext - $html = MediaWikiServices::getInstance()->getMessageCache()->parse( $text, $title )->getText( [ + $html = MediaWikiServices::getInstance()->getMessageCache()->parse( $text, $title, $linestart )->getText( [ 'enableSectionEditLinks' => false ] ); $plaintext = trim( Sanitizer::stripAllTags( $html ) ); @@ -1197,10 +1257,10 @@ abstract class EchoDiscussionParser { * Parse an edit summary into truncated plain text. * @param string $text * @param Language $lang - * @param int $length Length in characters (not bytes); default 150 + * @param int $length Length in characters (not bytes); default DEFAULT_SNIPPET_LENGTH * @return string */ - public static function getTextSnippetFromSummary( $text, Language $lang, $length = 150 ) { + public static function getTextSnippetFromSummary( $text, Language $lang, $length = self::DEFAULT_SNIPPET_LENGTH ) { // Parse wikitext with summary parser $html = Linker::formatLinksInComment( Sanitizer::escapeHtmlAllowEntities( $text ) ); $plaintext = trim( Sanitizer::stripAllTags( $html ) ); @@ -1212,10 +1272,12 @@ abstract class EchoDiscussionParser { * * @param RevisionRecord $revision * @param Language $lang - * @param int $length Length in characters (not bytes); default 150 + * @param int $length Length in characters (not bytes); default DEFAULT_SNIPPET_LENGTH * @return string */ - public static function getEditExcerpt( RevisionRecord $revision, Language $lang, $length = 150 ) { + public static function getEditExcerpt( + RevisionRecord $revision, Language $lang, $length = self::DEFAULT_SNIPPET_LENGTH + ) { $interpretation = self::getChangeInterpretationForRevision( $revision ); $section = self::detectSectionTitleAndText( $interpretation ); return $lang->truncateForVisual( $section['section-title'] . ' ' . $section['section-text'], $length ); diff --git a/Echo/includes/EchoCachedList.php b/Echo/includes/EchoCachedList.php index fc4c159f..697c2612 100644 --- a/Echo/includes/EchoCachedList.php +++ b/Echo/includes/EchoCachedList.php @@ -5,8 +5,7 @@ * to load the nested list from a potentially slow source (mysql, etc). */ class EchoCachedList implements EchoContainmentList { - const ONE_WEEK = 4233600; - const ONE_DAY = 86400; + private const ONE_WEEK = 4233600; /** @var WANObjectCache */ protected $cache; diff --git a/Echo/includes/EchoContainmentSet.php b/Echo/includes/EchoContainmentSet.php index 2f79634e..f9d5d8fe 100644 --- a/Echo/includes/EchoContainmentSet.php +++ b/Echo/includes/EchoContainmentSet.php @@ -1,5 +1,6 @@ <?php +use MediaWiki\MediaWikiServices; use MediaWiki\Preferences\MultiUsernameFilter; /** @@ -7,7 +8,7 @@ use MediaWiki\Preferences\MultiUsernameFilter; * from multiple sources like global variables, wiki pages, etc. * * Initialize: - * $cache = ObjectCache::getLocalClusterIntance(); + * $cache = ObjectCache::getLocalClusterInstance(); * $set = new EchoContainmentSet; * $set->addArray( $wgSomeGlobalParameter ); * $set->addOnWiki( NS_USER, 'Foo/bar-baz', $cache, 'some_user_specific_cache_key' ); @@ -28,6 +29,9 @@ class EchoContainmentSet { */ protected $recipient; + /** + * @param User $recipient + */ public function __construct( User $recipient ) { $this->recipient = $recipient; } @@ -55,13 +59,14 @@ class EchoContainmentSet { * * @param string $preferenceName */ - public function addFromUserOption( $preferenceName ) { - $preference = $this->recipient->getOption( $preferenceName, [] ); - + public function addFromUserOption( string $preferenceName ) { + $userOptionsLookup = MediaWikiServices::getInstance()->getUserOptionsLookup(); + $preference = $userOptionsLookup->getOption( $this->recipient, $preferenceName, [] ); if ( $preference ) { $ids = MultiUsernameFilter::splitIds( $preference ); - $lookup = CentralIdLookup::factory(); - $names = $lookup->namesFromCentralIds( $ids, $this->recipient ); + $names = MediaWikiServices::getInstance() + ->getCentralIdLookup() + ->namesFromCentralIds( $ids, $this->recipient ); $this->addArray( $names ); } } @@ -72,8 +77,9 @@ class EchoContainmentSet { * * @param string $preferenceName */ - public function addTitleIDsFromUserOption( string $preferenceName ) :void { - $preference = $this->recipient->getOption( $preferenceName, [] ); + public function addTitleIDsFromUserOption( string $preferenceName ): void { + $userOptionsLookup = MediaWikiServices::getInstance()->getUserOptionsLookup(); + $preference = $userOptionsLookup->getOption( $this->recipient, $preferenceName, [] ); if ( !is_string( $preference ) ) { // We expect the preference data to be saved as a string via the // preferences form; if the user modified their data so it's no @@ -118,7 +124,7 @@ class EchoContainmentSet { public function contains( $value ) { foreach ( $this->lists as $list ) { // Use strict comparison to prevent the number 0 from matching all strings (T177825) - if ( array_search( $value, $list->getValues(), true ) !== false ) { + if ( in_array( $value, $list->getValues(), true ) ) { return true; } } diff --git a/Echo/includes/EchoDbFactory.php b/Echo/includes/EchoDbFactory.php index 831b9b54..5c12bc94 100644 --- a/Echo/includes/EchoDbFactory.php +++ b/Echo/includes/EchoDbFactory.php @@ -1,7 +1,7 @@ <?php use MediaWiki\MediaWikiServices; -use Wikimedia\Rdbms\LoadBalancer; +use Wikimedia\Rdbms\ILoadBalancer; /** * Database factory class, this will determine whether to use the main database @@ -15,8 +15,10 @@ class MWEchoDbFactory { */ private $cluster; + /** @var string|false */ private $shared; + /** @var string|false */ private $sharedCluster; /** @@ -52,7 +54,7 @@ class MWEchoDbFactory { /** * Get the database load balancer - * @return LoadBalancer + * @return ILoadBalancer */ protected function getLB() { // Use the external db defined for Echo @@ -66,7 +68,7 @@ class MWEchoDbFactory { } /** - * @return LoadBalancer + * @return ILoadBalancer */ protected function getSharedLB() { if ( $this->sharedCluster ) { @@ -136,29 +138,29 @@ class MWEchoDbFactory { * Wait for the replicas of the database */ public function waitForReplicas() { - $this->waitFor( $this->getMasterPosition() ); + $this->waitFor( $this->getPrimaryPosition() ); } /** - * Get the current master position for the wiki and echo + * Get the current primary database position for the wiki and echo * db when they have at least one replica in their cluster. * * @return array */ - public function getMasterPosition() { + public function getPrimaryPosition() { $position = [ 'wikiDb' => false, 'echoDb' => false, ]; $lb = MediaWikiServices::getInstance()->getDBLoadBalancer(); if ( $lb->getServerCount() > 1 ) { - $position['wikiDb'] = $lb->getMasterPos(); + $position['wikiDb'] = $lb->getPrimaryPos(); } if ( $this->cluster ) { $lb = $this->getLB(); if ( $lb->getServerCount() > 1 ) { - $position['echoDb'] = $lb->getMasterPos(); + $position['echoDb'] = $lb->getPrimaryPos(); } } @@ -166,8 +168,8 @@ class MWEchoDbFactory { } /** - * Receives the output of self::getMasterPosition. Waits - * for replicas to catch up to the master position at that + * Receives the output of self::getPrimaryPosition. Waits + * for replicas to catch up to the primary database position at that * point. * * @param array $position @@ -182,10 +184,10 @@ class MWEchoDbFactory { } /** - * Check whether it makes sense to retry a failed lookup on the master. + * Check whether it makes sense to retry a failed lookup on the primary database. * @return bool True if there are multiple servers and changes were made in this request; false otherwise */ - public function canRetryMaster() { - return $this->getLB()->getServerCount() > 1 && $this->getLB()->hasOrMadeRecentMasterChanges(); + public function canRetryPrimary() { + return $this->getLB()->getServerCount() > 1 && $this->getLB()->hasOrMadeRecentPrimaryChanges(); } } diff --git a/Echo/includes/EchoDiffGroup.php b/Echo/includes/EchoDiffGroup.php index bc6a14a4..9abbcfd9 100644 --- a/Echo/includes/EchoDiffGroup.php +++ b/Echo/includes/EchoDiffGroup.php @@ -45,7 +45,7 @@ class EchoDiffGroup { * @param int $rightPos The starting line number in the right text */ public function __construct( $leftPos, $rightPos ) { - // +1 due to the origional code use 1 indexing for this result + // +1 due to the original code use 1 indexing for this result $this->position = [ 'right-pos' => $rightPos + 1, 'left-pos' => $leftPos + 1, diff --git a/Echo/includes/EchoDiffParser.php b/Echo/includes/EchoDiffParser.php index 7f9a8aa6..084f6e59 100644 --- a/Echo/includes/EchoDiffParser.php +++ b/Echo/includes/EchoDiffParser.php @@ -31,32 +31,32 @@ class EchoDiffParser { /** - * @var int $prefixLength The number of characters the diff prefixes a line with + * @var int The number of characters the diff prefixes a line with */ protected $prefixLength = 1; /** - * @var string[] $left The text of the left side of the diff operation + * @var string[] The text of the left side of the diff operation */ protected $left; /** - * @var int $leftPos The current position within the left text + * @var int The current position within the left text */ protected $leftPos; /** - * @var string[] $right The text of the right side of the diff operation + * @var string[] The text of the right side of the diff operation */ protected $right; /** - * @var int $rightPos The current position within the right text + * @var int The current position within the right text */ protected $rightPos; /** - * @var array[] $changeSet Set of add, subtract, or change operations within the diff + * @var array[] Set of add, subtract, or change operations within the diff */ protected $changeSet; diff --git a/Echo/includes/EchoOnWikiList.php b/Echo/includes/EchoOnWikiList.php index 43cbab49..adfbb8f2 100644 --- a/Echo/includes/EchoOnWikiList.php +++ b/Echo/includes/EchoOnWikiList.php @@ -1,5 +1,7 @@ <?php +use MediaWiki\MediaWikiServices; + /** * Implements EchoContainmentList interface for sourcing a list of items from a wiki * page. Uses the pages latest revision ID as cache key. @@ -30,11 +32,13 @@ class EchoOnWikiList implements EchoContainmentList { return []; } - $article = WikiPage::newFromID( $this->title->getArticleID() ); - if ( $article === null || !$article->exists() ) { + $article = MediaWikiServices::getInstance()->getWikiPageFactory()->newFromTitle( $this->title ); + if ( !$article->exists() ) { return []; } - $text = ContentHandler::getContentText( $article->getContent() ); + + $content = $article->getContent(); + $text = ( $content instanceof TextContent ) ? $content->getText() : null; if ( $text === null ) { return []; } diff --git a/Echo/includes/EchoServices.php b/Echo/includes/EchoServices.php index 7633d07b..be674478 100644 --- a/Echo/includes/EchoServices.php +++ b/Echo/includes/EchoServices.php @@ -1,7 +1,7 @@ <?php -use EchoPush\NotificationServiceClient; -use EchoPush\SubscriptionManager; +use MediaWiki\Extension\Notifications\Push\NotificationServiceClient; +use MediaWiki\Extension\Notifications\Push\SubscriptionManager; use MediaWiki\MediaWikiServices; class EchoServices { @@ -37,4 +37,9 @@ class EchoServices { return $this->services->getService( 'EchoPushSubscriptionManager' ); } + /** @return EchoAttributeManager */ + public function getAttributeManager(): EchoAttributeManager { + return $this->services->getService( 'EchoAttributeManager' ); + } + } diff --git a/Echo/includes/EchoSummaryParser.php b/Echo/includes/EchoSummaryParser.php index ab738a8c..410c875a 100644 --- a/Echo/includes/EchoSummaryParser.php +++ b/Echo/includes/EchoSummaryParser.php @@ -12,7 +12,7 @@ class EchoSummaryParser { public function __construct( callable $userLookup = null ) { $this->userLookup = $userLookup; if ( !$this->userLookup ) { - $this->userLookup = function ( User $user ) { + $this->userLookup = static function ( User $user ) { return $user->getId(); }; } diff --git a/Echo/includes/EmailBatch.php b/Echo/includes/EmailBatch.php index 320f2aa4..8440a712 100644 --- a/Echo/includes/EmailBatch.php +++ b/Echo/includes/EmailBatch.php @@ -1,6 +1,9 @@ <?php +use MediaWiki\Extension\Notifications\Formatters\EchoHtmlDigestEmailFormatter; +use MediaWiki\Extension\Notifications\Formatters\EchoPlainTextDigestEmailFormatter; use MediaWiki\MediaWikiServices; +use MediaWiki\User\UserOptionsManager; use Wikimedia\Rdbms\IResultWrapper; /** @@ -19,6 +22,11 @@ class MWEchoEmailBatch { protected $language; /** + * @var UserOptionsManager + */ + protected $userOptionsManager; + + /** * @var EchoEvent[] events included in this email */ protected $events = []; @@ -41,10 +49,14 @@ class MWEchoEmailBatch { /** * @param User $user + * @param UserOptionsManager $userOptionsManager */ - public function __construct( User $user ) { + public function __construct( User $user, UserOptionsManager $userOptionsManager ) { $this->mUser = $user; - $this->language = Language::factory( $this->mUser->getOption( 'language' ) ); + $this->language = Language::factory( + $userOptionsManager->getOption( $user, 'language' ) + ); + $this->userOptionsManager = $userOptionsManager; } /** @@ -67,12 +79,13 @@ class MWEchoEmailBatch { */ public static function newFromUserId( $userId, $enforceFrequency = true ) { $user = User::newFromId( (int)$userId ); + $userOptionsManager = MediaWikiServices::getInstance()->getUserOptionsManager(); - $userEmailSetting = (int)$user->getOption( 'echo-email-frequency' ); + $userEmailSetting = (int)$userOptionsManager->getOption( $user, 'echo-email-frequency' ); // clear all existing events if user decides not to receive emails if ( $userEmailSetting == -1 ) { - $emailBatch = new self( $user ); + $emailBatch = new self( $user, $userOptionsManager ); $emailBatch->clearProcessedEvent(); return false; @@ -89,7 +102,7 @@ class MWEchoEmailBatch { return false; } - $userLastBatch = $user->getOption( 'echo-email-last-batch' ); + $userLastBatch = $userOptionsManager->getOption( $user, 'echo-email-last-batch' ); // send email batch, if // 1. it has been long enough since last email batch based on frequency @@ -103,7 +116,7 @@ class MWEchoEmailBatch { } } - return new self( $user ); + return new self( $user, $userOptionsManager ); } /** @@ -170,14 +183,18 @@ class MWEchoEmailBatch { * Update the user's last batch timestamp after a successful batch */ protected function updateUserLastBatchTimestamp() { - $this->mUser->setOption( 'echo-email-last-batch', wfTimestampNow() ); + $this->userOptionsManager->setOption( + $this->mUser, + 'echo-email-last-batch', + wfTimestampNow() + ); $this->mUser->saveSettings(); $this->mUser->invalidateCache(); } /** * Get the events queued for the current user - * @return \stdClass[] + * @return stdClass[] */ protected function getEvents() { global $wgEchoNotifications; @@ -200,13 +217,17 @@ class MWEchoEmailBatch { ]; $tables = [ 'echo_email_batch', 'echo_event' ]; - - if ( $this->mUser->getOption( 'echo-dont-email-read-notifications' ) ) { - $conds += [ - 'notification_event = event_id', - 'notification_read_timestamp' => null - ]; - array_push( $tables, 'echo_notification' ); + if ( $this->userOptionsManager->getOption( + $this->mUser, 'echo-dont-email-read-notifications' + ) ) { + $conds = array_merge( + $conds, + [ + 'notification_event = event_id', + 'notification_read_timestamp IS NULL', + ] + ); + $tables[] = 'echo_notification'; } // See setLastEvent() for more detail for this variable @@ -252,7 +273,7 @@ class MWEchoEmailBatch { global $wgUpdateRowsPerQuery; $eventMapper = new EchoEventMapper(); $dbFactory = MWEchoDbFactory::newFromDefault(); - $dbw = $dbFactory->getEchoDb( DB_MASTER ); + $dbw = $dbFactory->getEchoDb( DB_PRIMARY ); $dbr = $dbFactory->getEchoDb( DB_REPLICA ); $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory(); $ticket = $lbFactory->getEmptyTransactionTicket( __METHOD__ ); @@ -264,6 +285,8 @@ class MWEchoEmailBatch { // There is a processed cutoff point $iterator->addConditions( [ 'eeb_event_id <= ' . (int)$this->lastEvent ] ); } + $iterator->setCaller( __METHOD__ ); + foreach ( $iterator as $batch ) { $eventIds = []; foreach ( $batch as $row ) { @@ -289,7 +312,9 @@ class MWEchoEmailBatch { public function sendEmail() { global $wgPasswordSender, $wgNoReplyAddress; - if ( $this->mUser->getOption( 'echo-email-frequency' ) == EchoEmailFrequency::WEEKLY_DIGEST ) { + if ( $this->userOptionsManager->getOption( $this->mUser, 'echo-email-frequency' ) + == EchoEmailFrequency::WEEKLY_DIGEST + ) { $frequency = 'weekly'; $emailDeliveryMode = 'weekly_digest'; } else { @@ -341,7 +366,7 @@ class MWEchoEmailBatch { return; } - $dbw = MWEchoDbFactory::newFromDefault()->getEchoDb( DB_MASTER ); + $dbw = MWEchoDbFactory::newFromDefault()->getEchoDb( DB_PRIMARY ); $row = [ 'eeb_user_id' => $userId, diff --git a/Echo/includes/EmailFormat.php b/Echo/includes/EmailFormat.php index 582ece97..608d0504 100644 --- a/Echo/includes/EmailFormat.php +++ b/Echo/includes/EmailFormat.php @@ -1,6 +1,6 @@ <?php class EchoEmailFormat { - const HTML = 'html'; - const PLAIN_TEXT = 'plain-text'; + public const HTML = 'html'; + public const PLAIN_TEXT = 'plain-text'; } diff --git a/Echo/includes/EmailFrequency.php b/Echo/includes/EmailFrequency.php index 1dd1ba8b..a3e57546 100644 --- a/Echo/includes/EmailFrequency.php +++ b/Echo/includes/EmailFrequency.php @@ -1,8 +1,8 @@ <?php class EchoEmailFrequency { - const NEVER = -1; // Never send email notifications - const IMMEDIATELY = 0; // Send email notifications immediately as they come in - const DAILY_DIGEST = 1; // Send daily email digests - const WEEKLY_DIGEST = 7; // Send weekly email digests + public const NEVER = -1; // Never send email notifications + public const IMMEDIATELY = 0; // Send email notifications immediately as they come in + public const DAILY_DIGEST = 1; // Send daily email digests + public const WEEKLY_DIGEST = 7; // Send weekly email digests } diff --git a/Echo/includes/EventLogging.php b/Echo/includes/EventLogging.php index 5db4771f..f928a44d 100644 --- a/Echo/includes/EventLogging.php +++ b/Echo/includes/EventLogging.php @@ -1,18 +1,16 @@ <?php +use MediaWiki\Extension\EventLogging\EventLogging; +use MediaWiki\MediaWikiServices; +use MediaWiki\User\UserIdentity; + /** * Static class for handling all kinds of event logging + * + * TODO: consider making this a service with dependencies injected */ class MWEchoEventLogging { - private static $revisionIds = [ - 'Echo' => 7731316, - 'EchoMail' => 5467650, - // Keep in sync with client-side revision - // in extension.json - 'EchoInteraction' => 15823738 - ]; - /** * This is the only function that interacts with EventLogging * @@ -32,74 +30,22 @@ class MWEchoEventLogging { return; } - $revision = self::$revisionIds[$schema]; $data['version'] = $wgEchoEventLoggingVersion; - EventLogging::logEvent( $schema, $revision, $data ); - } - - /** - * Function for logging the event for Schema:Echo - * @param User $user User being notified. - * @param EchoEvent $event Event to log detail about. - * @param string $deliveryMethod 'web' or 'email' - */ - public static function logSchemaEcho( User $user, EchoEvent $event, $deliveryMethod ) { - global $wgEchoNotifications; - - // Notifications under system category should have -1 as sender id - if ( $event->getCategory() === 'system' ) { - $sender = -1; - } else { - $agent = $event->getAgent(); - if ( $agent ) { - $sender = $agent->isAnon() ? $agent->getName() : $agent->getId(); - } else { - $sender = -1; - } - } - - if ( isset( $wgEchoNotifications[$event->getType()]['group'] ) ) { - $group = $wgEchoNotifications[$event->getType()]['group']; - } else { - $group = 'neutral'; - } - $data = [ - 'eventId' => (int)$event->getId(), - 'notificationType' => $event->getType(), - 'notificationGroup' => $group, - 'sender' => (string)$sender, - 'recipientUserId' => $user->getId(), - 'recipientEditCount' => (int)$user->getEditCount() - ]; - // Add the source if it exists. (This is mostly for the Thanks extension.) - $extra = $event->getExtra(); - if ( isset( $extra['source'] ) ) { - $data['eventSource'] = (string)$extra['source']; - } - if ( $deliveryMethod === 'email' ) { - $data['deliveryMethod'] = 'email'; - } else { - // whitelist valid delivery methods so it is always valid - $data['deliveryMethod'] = 'web'; - } - // Add revision ID if it exists - $rev = $event->getRevision(); - if ( $rev ) { - $data['revisionId'] = $rev->getId(); - } - - self::logEvent( 'Echo', $data ); + // NOTE: The 'EchoMail' and 'EchoInteraction' events were migrated to the Event Platform + // and are no longer using the legacy EventLogging schema from metawiki. $revId is actually + // overridden by the EventLoggingSchemas extension attribute in extension.json. + EventLogging::logEvent( $schema, -1, $data ); } /** * Function for logging the event for Schema:EchoEmail - * @param User $user + * @param UserIdentity $userIdentity * @param string $emailDeliveryMode 'single' (default), 'daily_digest', or 'weekly_digest' */ - public static function logSchemaEchoMail( User $user, $emailDeliveryMode = 'single' ) { + public static function logSchemaEchoMail( UserIdentity $userIdentity, $emailDeliveryMode = 'single' ) { $data = [ - 'recipientUserId' => $user->getId(), + 'recipientUserId' => $userIdentity->getId(), 'emailDeliveryMode' => $emailDeliveryMode ]; @@ -107,18 +53,21 @@ class MWEchoEventLogging { } /** - * @param User $user + * @param UserIdentity $userIdentity * @param string $skinName */ - public static function logSpecialPageVisit( User $user, $skinName ) { + public static function logSpecialPageVisit( UserIdentity $userIdentity, $skinName ) { + $userEditCount = (int)MediaWikiServices::getInstance() + ->getUserEditTracker() + ->getUserEditCount( $userIdentity ); self::logEvent( 'EchoInteraction', [ 'context' => 'archive', 'action' => 'special-page-visit', - 'userId' => (int)$user->getId(), - 'editCount' => (int)$user->getEditCount(), - 'notifWiki' => wfWikiID(), + 'userId' => $userIdentity->getId(), + 'editCount' => $userEditCount, + 'notifWiki' => WikiMap::getCurrentWikiId(), // Hack: Figure out if we are in the mobile skin 'mobile' => $skinName === 'minerva', ] diff --git a/Echo/includes/ForeignNotifications.php b/Echo/includes/ForeignNotifications.php index 301c09ab..92a09457 100644 --- a/Echo/includes/ForeignNotifications.php +++ b/Echo/includes/ForeignNotifications.php @@ -1,5 +1,8 @@ <?php +use MediaWiki\MediaWikiServices; +use MediaWiki\User\UserIdentity; + /** * Caches the result of EchoUnreadWikis::getUnreadCounts() and interprets the results in various useful ways. * @@ -11,7 +14,7 @@ */ class EchoForeignNotifications { /** - * @var User + * @var UserIdentity */ protected $user; @@ -46,10 +49,10 @@ class EchoForeignNotifications { protected $populated = false; /** - * @param User $user + * @param UserIdentity $user * @param bool $forceEnable Ignore the user's preferences and act as if they've enabled cross-wiki notifications */ - public function __construct( User $user, $forceEnable = false ) { + public function __construct( UserIdentity $user, $forceEnable = false ) { $this->user = $user; $this->enabled = $forceEnable || $this->isEnabledByUser(); } @@ -59,7 +62,8 @@ class EchoForeignNotifications { * @return bool */ public function isEnabledByUser() { - return (bool)$this->user->getOption( 'echo-cross-wiki-notifications' ); + $userOptionsLookup = MediaWikiServices::getInstance()->getUserOptionsLookup(); + return (bool)$userOptionsLookup->getOption( $this->user, 'echo-cross-wiki-notifications' ); } /** @@ -160,7 +164,7 @@ class EchoForeignNotifications { foreach ( $unreadCounts as $wiki => $sections ) { // exclude current wiki - if ( $wiki === wfWikiID() ) { + if ( $wiki === WikiMap::getCurrentWikiId() ) { continue; } diff --git a/Echo/includes/ForeignWikiRequest.php b/Echo/includes/ForeignWikiRequest.php index 6a7f35b3..475f86ff 100644 --- a/Echo/includes/ForeignWikiRequest.php +++ b/Echo/includes/ForeignWikiRequest.php @@ -3,6 +3,7 @@ use MediaWiki\Logger\LoggerFactory; use MediaWiki\MediaWikiServices; use MediaWiki\Session\SessionManager; +use MediaWiki\User\UserIdentity; class EchoForeignWikiRequest { @@ -15,7 +16,7 @@ class EchoForeignWikiRequest { /** @var array */ protected $wikis; - /** @varstring|null */ + /** @var string|null */ protected $wikiParam; /** @var string */ @@ -48,28 +49,39 @@ class EchoForeignWikiRequest { /** * Execute the request + * @param WebRequest|null $originalRequest Original request data to be sent with these requests * @return array[] [ wiki => result ] */ - public function execute() { + public function execute( ?WebRequest $originalRequest = null ) { if ( !$this->canUseCentralAuth() ) { return []; } - $reqs = $this->getRequestParams( $this->method, [ $this, 'getQueryParams' ] ); + $reqs = $this->getRequestParams( + $this->method, + function ( string $wiki ) use ( $originalRequest ) { + return $this->getQueryParams( $wiki, $originalRequest ); + }, + $originalRequest + ); return $this->doRequests( $reqs ); } + /** + * @param UserIdentity $user + * @return int + */ protected function getCentralId( $user ) { - $lookup = CentralIdLookup::factory(); - $id = $lookup->centralIdFromLocalUser( $user, CentralIdLookup::AUDIENCE_RAW ); - return $id; + return MediaWikiServices::getInstance() + ->getCentralIdLookup() + ->centralIdFromLocalUser( $user, CentralIdLookup::AUDIENCE_RAW ); } protected function canUseCentralAuth() { - global $wgFullyInitialised, $wgUser; + global $wgFullyInitialised; return $wgFullyInitialised && - $wgUser->isSafeToLoad() && + RequestContext::getMain()->getUser()->isSafeToLoad() && $this->user->isSafeToLoad() && SessionManager::getGlobalSession()->getProvider() instanceof CentralAuthSessionProvider && $this->getCentralId( $this->user ) !== 0; @@ -97,7 +109,7 @@ class EchoForeignWikiRequest { 'Exception when fetching CentralAuth token: wiki: {wiki}, userName: {userName}, ' . 'userId: {userId}, centralId: {centralId}, exception: {exception}', [ - 'wiki' => wfWikiID(), + 'wiki' => WikiMap::getCurrentWikiId(), 'userName' => $user->getName(), 'userId' => $user->getId(), 'centralId' => $this->getCentralId( $user ), @@ -116,10 +128,11 @@ class EchoForeignWikiRequest { * This method fetches the tokens for all requested wikis at once and caches the result. * * @param string $wiki Name of the wiki to get a token for + * @param WebRequest|null $originalRequest Original request data to be sent with these requests * @suppress PhanTypeInvalidCallableArraySize getRequestParams can take an array, too (phan bug) - * @return string Token + * @return string Token, or empty string if an unable to retrieve the token. */ - protected function getCsrfToken( $wiki ) { + protected function getCsrfToken( $wiki, ?WebRequest $originalRequest ) { if ( $this->csrfTokens === null ) { $this->csrfTokens = []; $reqs = $this->getRequestParams( 'GET', [ @@ -128,22 +141,33 @@ class EchoForeignWikiRequest { 'type' => $this->tokenType, 'format' => 'json', 'centralauthtoken' => $this->getCentralAuthToken( $this->user ), - ] ); + ], $originalRequest ); $responses = $this->doRequests( $reqs ); foreach ( $responses as $w => $response ) { - $this->csrfTokens[$w] = $response['query']['tokens']['csrftoken']; + if ( isset( $response['query']['tokens']['csrftoken'] ) ) { + $this->csrfTokens[$w] = $response['query']['tokens']['csrftoken']; + } else { + LoggerFactory::getInstance( 'Echo' )->warning( + __METHOD__ . ': Unexpected CSRF token API response from {wiki}', + [ + 'wiki' => $wiki, + 'response' => $response, + ] + ); + } } } - return $this->csrfTokens[$wiki]; + return $this->csrfTokens[$wiki] ?? ''; } /** * @param string $method 'GET' or 'POST' * @param array|callable $params Associative array of query string / POST parameters, * or a callback that takes a wiki name and returns such an array + * @param WebRequest|null $originalRequest Original request data to be sent with these requests * @return array[] Array of request parameters to pass to doRequests(), keyed by wiki name */ - protected function getRequestParams( $method, $params ) { + protected function getRequestParams( $method, $params, ?WebRequest $originalRequest ) { $apis = EchoForeignNotifications::getApiEndpoints( $this->wikis ); if ( !$apis ) { return []; @@ -157,6 +181,16 @@ class EchoForeignWikiRequest { 'url' => $api['url'], $queryKey => is_callable( $params ) ? $params( $wiki ) : $params ]; + + if ( $originalRequest ) { + $reqs[$wiki]['headers'] = [ + 'X-Forwarded-For' => $originalRequest->getIP(), + 'User-Agent' => ( + $originalRequest->getHeader( 'User-Agent' ) + . ' (via EchoForeignWikiRequest MediaWiki/' . MW_VERSION . ')' + ), + ]; + } } return $reqs; @@ -164,9 +198,10 @@ class EchoForeignWikiRequest { /** * @param string $wiki Wiki name + * @param WebRequest|null $originalRequest Original request data to be sent with these requests * @return array */ - protected function getQueryParams( $wiki ) { + protected function getQueryParams( $wiki, ?WebRequest $originalRequest ) { $extraParams = []; if ( $this->wikiParam ) { // Only request data from that specific wiki, or they'd all spawn @@ -174,7 +209,7 @@ class EchoForeignWikiRequest { $extraParams[$this->wikiParam] = $wiki; } if ( $this->method === 'POST' ) { - $extraParams['token'] = $this->getCsrfToken( $wiki ); + $extraParams['token'] = $this->getCsrfToken( $wiki, $originalRequest ); } return [ @@ -213,8 +248,7 @@ class EchoForeignWikiRequest { 'Failed to fetch API response from {wiki}. Error code {code}', [ 'wiki' => $wiki, - 'code' => $response['response']['code'], - 'response' => $response['response']['body'], + 'response' => $response['response'], 'request' => $reqs[$wiki], ] ); diff --git a/Echo/includes/formatters/ArticleReminderPresentationModel.php b/Echo/includes/Formatters/EchoArticleReminderPresentationModel.php index 06fa7646..b645c286 100644 --- a/Echo/includes/formatters/ArticleReminderPresentationModel.php +++ b/Echo/includes/Formatters/EchoArticleReminderPresentationModel.php @@ -1,4 +1,7 @@ <?php + +namespace MediaWiki\Extension\Notifications\Formatters; + /** * Presenter for 'article-reminder' notification * diff --git a/Echo/includes/formatters/EditThresholdPresentationModel.php b/Echo/includes/Formatters/EchoEditThresholdPresentationModel.php index 6a01cb5f..0d4bd2fe 100644 --- a/Echo/includes/formatters/EditThresholdPresentationModel.php +++ b/Echo/includes/Formatters/EchoEditThresholdPresentationModel.php @@ -1,5 +1,7 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + class EchoEditThresholdPresentationModel extends EchoEventPresentationModel { public function getIconType() { diff --git a/Echo/includes/formatters/EditUserTalkPresentationModel.php b/Echo/includes/Formatters/EchoEditUserTalkPresentationModel.php index 3e6974d1..5291e485 100644 --- a/Echo/includes/formatters/EditUserTalkPresentationModel.php +++ b/Echo/includes/Formatters/EchoEditUserTalkPresentationModel.php @@ -1,11 +1,18 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + +use EchoEvent; +use Language; +use MediaWiki\MediaWikiServices; +use User; + class EchoEditUserTalkPresentationModel extends EchoEventPresentationModel { /** * @var EchoPresentationModelSection */ - private $section; + protected $section; /** * @inheritDoc @@ -106,10 +113,15 @@ class EchoEditUserTalkPresentationModel extends EchoEventPresentationModel { private function getRevBeforeFirstNotification() { $events = $this->getBundledEvents(); $firstNotificationRevId = end( $events )->getExtraParam( 'revid' ); - return $this->event->getTitle()->getPreviousRevisionID( $firstNotificationRevId ); + $revisionLookup = MediaWikiServices::getInstance()->getRevisionLookup(); + $revisionRecord = $revisionLookup->getRevisionById( $firstNotificationRevId ); + $previousRevision = $revisionRecord ? $revisionLookup->getPreviousRevision( $revisionRecord ) : null; + return $previousRevision ? $previousRevision->getId() : 0; } protected function getSubjectMessageKey() { return 'notification-edit-talk-page-email-subject2'; } } + +class_alias( EchoEditUserTalkPresentationModel::class, 'EchoEditUserTalkPresentationModel' ); diff --git a/Echo/includes/formatters/EmailUserPresentationModel.php b/Echo/includes/Formatters/EchoEmailUserPresentationModel.php index da30d7ed..a12b823b 100644 --- a/Echo/includes/formatters/EmailUserPresentationModel.php +++ b/Echo/includes/Formatters/EchoEmailUserPresentationModel.php @@ -1,5 +1,7 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + class EchoEmailUserPresentationModel extends EchoEventPresentationModel { public function getIconType() { diff --git a/Echo/includes/formatters/EchoEventDigestFormatter.php b/Echo/includes/Formatters/EchoEventDigestFormatter.php index 85c9e927..98134dce 100644 --- a/Echo/includes/formatters/EchoEventDigestFormatter.php +++ b/Echo/includes/Formatters/EchoEventDigestFormatter.php @@ -1,5 +1,12 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + +use EchoEvent; +use Language; +use Message; +use User; + /** * Abstract class for formatters that process multiple events. * @@ -23,14 +30,12 @@ abstract class EchoEventDigestFormatter { * Equivalent to IContextSource::msg for the current * language * - * @param string ...$args + * @param string $key + * @param mixed ...$params * @return Message */ - protected function msg( ...$args ) { - /** - * @var Message $msg - */ - $msg = wfMessage( ...$args ); + protected function msg( string $key, ...$params ) { + $msg = wfMessage( $key, ...$params ); $msg->inLanguage( $this->language ); return $msg; diff --git a/Echo/includes/formatters/EchoEventFormatter.php b/Echo/includes/Formatters/EchoEventFormatter.php index 0e81b3c4..914081f2 100644 --- a/Echo/includes/formatters/EchoEventFormatter.php +++ b/Echo/includes/Formatters/EchoEventFormatter.php @@ -1,6 +1,12 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + +use EchoEvent; +use Language; use MediaWiki\Logger\LoggerFactory; +use Message; +use User; /** * Abstract class that each "formatter" should implement. @@ -30,14 +36,12 @@ abstract class EchoEventFormatter { * Equivalent to IContextSource::msg for the current * language * - * @param string ...$args + * @param string $key + * @param mixed ...$params * @return Message */ - protected function msg( ...$args ) { - /** - * @var Message $msg - */ - $msg = wfMessage( ...$args ); + protected function msg( string $key, ...$params ) { + $msg = wfMessage( $key, ...$params ); $msg->inLanguage( $this->language ); return $msg; @@ -45,9 +49,10 @@ abstract class EchoEventFormatter { /** * @param EchoEvent $event + * @param string $distributionType 'web' or 'email' * @return string[]|string|false Output format depends on implementation, false if it cannot be formatted */ - final public function format( EchoEvent $event ) { + final public function format( EchoEvent $event, string $distributionType = "web" ) { // Deleted events should have been filtered out before getting there. // This is just to be sure. if ( $event->isDeleted() ) { @@ -64,7 +69,7 @@ abstract class EchoEventFormatter { return false; } - $model = EchoEventPresentationModel::factory( $event, $this->language, $this->user ); + $model = EchoEventPresentationModel::factory( $event, $this->language, $this->user, $distributionType ); if ( !$model->canRender() ) { return false; } diff --git a/Echo/includes/formatters/EventPresentationModel.php b/Echo/includes/Formatters/EchoEventPresentationModel.php index 59a9bfef..0a74f1d4 100644 --- a/Echo/includes/formatters/EventPresentationModel.php +++ b/Echo/includes/Formatters/EchoEventPresentationModel.php @@ -1,43 +1,58 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + +use EchoEvent; +use EchoNotificationController; +use InvalidArgumentException; +use JsonSerializable; +use Language; +use MediaWiki\MediaWikiServices; use MediaWiki\Revision\RevisionRecord; +use Message; +use MessageLocalizer; +use MessageSpecifier; +use SpecialPage; +use Title; +use User; +use WikiMap; use Wikimedia\Timestamp\TimestampException; /** * Class that returns structured data based * on the provided event. */ -abstract class EchoEventPresentationModel implements JsonSerializable { +abstract class EchoEventPresentationModel implements JsonSerializable, MessageLocalizer { /** * Recommended length of usernames included in messages, in * characters (not bytes). */ - const USERNAME_RECOMMENDED_LENGTH = 20; + private const USERNAME_RECOMMENDED_LENGTH = 20; /** * Recommended length of usernames used as link label, in * characters (not bytes). */ - const USERNAME_AS_LABEL_RECOMMENDED_LENGTH = 15; + private const USERNAME_AS_LABEL_RECOMMENDED_LENGTH = 15; /** * Recommended length of page names included in messages, in * characters (not bytes). */ - const PAGE_NAME_RECOMMENDED_LENGTH = 50; + protected const PAGE_NAME_RECOMMENDED_LENGTH = 50; /** * Recommended length of page names used as link label, in * characters (not bytes). */ - const PAGE_NAME_AS_LABEL_RECOMMENDED_LENGTH = 15; + private const PAGE_NAME_AS_LABEL_RECOMMENDED_LENGTH = 15; /** * Recommended length of section titles included in messages, in * characters (not bytes). */ - const SECTION_TITLE_RECOMMENDED_LENGTH = 50; + public const SECTION_TITLE_RECOMMENDED_LENGTH = 50; /** * @var EchoEvent @@ -144,8 +159,6 @@ abstract class EchoEventPresentationModel implements JsonSerializable { } /** - * Get the distribution type - * * @return string 'web' or 'email' */ final public function getDistributionType() { @@ -156,14 +169,16 @@ abstract class EchoEventPresentationModel implements JsonSerializable { * Equivalent to IContextSource::msg for the current * language * - * @param string ...$args + * @param string|string[]|MessageSpecifier $key Message key, or array of keys, + * or a MessageSpecifier. + * @param mixed ...$params Normal message parameters * @return Message */ - protected function msg( ...$args ) { + public function msg( $key, ...$params ) { /** * @var Message $msg */ - $msg = wfMessage( ...$args ); + $msg = wfMessage( $key, ...$params ); $msg->inLanguage( $this->language ); // Notifications are considered UI (and should be in UI language, not @@ -187,7 +202,7 @@ abstract class EchoEventPresentationModel implements JsonSerializable { */ public function getBundledIds() { if ( $this->isBundled() ) { - return array_map( function ( EchoEvent $event ) { + return array_map( static function ( EchoEvent $event ) { return $event->getId(); }, $this->getBundledEvents() ); } @@ -249,8 +264,7 @@ abstract class EchoEventPresentationModel implements JsonSerializable { */ final protected function getNotificationCountForOutput( $includeCurrent = true, $groupCallback = null ) { $count = $this->getBundleCount( $includeCurrent, $groupCallback ); - $cappedCount = EchoNotificationController::getCappedNotificationCount( $count ); - return $cappedCount; + return EchoNotificationController::getCappedNotificationCount( $count ); } /** @@ -467,7 +481,7 @@ abstract class EchoEventPresentationModel implements JsonSerializable { $queryParams = [ 'markasread' => implode( '|', $eventIds ) ]; if ( $wgEchoCrossWikiNotifications ) { - $queryParams['markasreadwiki'] = wfWikiID(); + $queryParams['markasreadwiki'] = WikiMap::getCurrentWikiId(); } $primaryLink['url'] = wfAppendQuery( $primaryLink['url'], $queryParams ); @@ -532,7 +546,7 @@ abstract class EchoEventPresentationModel implements JsonSerializable { * @return array * @throws TimestampException */ - public function jsonSerialize() { + public function jsonSerialize(): array { $body = $this->getBodyMessage(); return [ @@ -580,7 +594,7 @@ abstract class EchoEventPresentationModel implements JsonSerializable { return null; } - $url = $user->isAnon() + $url = !$user->isRegistered() ? SpecialPage::getTitleFor( 'Contributions', $user->getName() )->getFullURL() : $user->getUserPage()->getFullURL(); @@ -673,7 +687,8 @@ abstract class EchoEventPresentationModel implements JsonSerializable { * @return array Array compatible with dynamic action link */ final protected function getWatchActionLink( Title $title ) { - $isTitleWatched = $this->getUser()->isWatched( $title ); + $isTitleWatched = MediaWikiServices::getInstance()->getWatchlistManager() + ->isWatched( $this->getUser(), $title ); $availableAction = $isTitleWatched ? 'unwatch' : 'watch'; $data = [ @@ -726,10 +741,12 @@ abstract class EchoEventPresentationModel implements JsonSerializable { $this->getTruncatedTitleText( $title ), $title->getFullURL( [ 'action' => $availableAction ] ), $this->getUser()->getName() - )->escaped(), + )->text(), null, $data, [ 'action' => $availableAction ] ); } } + +class_alias( EchoEventPresentationModel::class, 'EchoEventPresentationModel' ); diff --git a/Echo/includes/formatters/EchoFlyoutFormatter.php b/Echo/includes/Formatters/EchoFlyoutFormatter.php index f0235089..f12e889c 100644 --- a/Echo/includes/formatters/EchoFlyoutFormatter.php +++ b/Echo/includes/Formatters/EchoFlyoutFormatter.php @@ -1,9 +1,15 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + +use Html; +use MWTimestamp; +use Xml; + /** * A formatter for the notification flyout popup * - * Ideally we wouldn't need this and we'd just pass the + * Ideally we wouldn't need this, and we'd just pass the * presentation model to the client, but we need to continue * sending HTML for backwards compatibility. */ @@ -18,18 +24,18 @@ class EchoFlyoutFormatter extends EchoEventFormatter { ); $html = Xml::tags( - 'div', - [ 'class' => 'mw-echo-title' ], - $model->getHeaderMessage()->parse() - ) . "\n"; + 'div', + [ 'class' => 'mw-echo-title' ], + $model->getHeaderMessage()->parse() + ) . "\n"; $body = $model->getBodyMessage(); if ( $body ) { $html .= Xml::tags( - 'div', - [ 'class' => 'mw-echo-payload' ], - $body->parse() - ) . "\n"; + 'div', + [ 'class' => 'mw-echo-payload' ], + $body->parse() + ) . "\n"; } $ts = $this->language->getHumanTimestamp( @@ -63,15 +69,13 @@ class EchoFlyoutFormatter extends EchoEventFormatter { $html = Xml::tags( 'div', [ 'class' => 'mw-echo-content' ], $html ); // And then add the icon in front and wrap with mw-echo-state class. - $html = Xml::tags( 'div', [ 'class' => 'mw-echo-state' ], $icon . $html ); - - return $html; + return Xml::tags( 'div', [ 'class' => 'mw-echo-state' ], $icon . $html ); } private function getIconURL( EchoEventPresentationModel $model ) { return EchoIcon::getUrl( - $model->getIconType(), - $this->language->getDir() + $model->getIconType(), + $this->language->getDir() ); } diff --git a/Echo/includes/formatters/EchoForeignPresentationModel.php b/Echo/includes/Formatters/EchoForeignPresentationModel.php index 42e56f81..3476526e 100644 --- a/Echo/includes/formatters/EchoForeignPresentationModel.php +++ b/Echo/includes/Formatters/EchoForeignPresentationModel.php @@ -1,5 +1,9 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + +use EchoForeignNotifications; + class EchoForeignPresentationModel extends EchoEventPresentationModel { public function getIconType() { return 'global'; @@ -34,7 +38,7 @@ class EchoForeignPresentationModel extends EchoEventPresentationModel { public function getBodyMessage() { $data = $this->event->getExtra(); - $msg = wfMessage( 'notification-body-foreign' ); + $msg = $this->msg( 'notification-body-foreign' ); $msg->params( $this->language->listToText( $this->getWikiNames( $data['wikis'] ) ) ); return $msg; } diff --git a/Echo/includes/formatters/EchoHtmlDigestEmailFormatter.php b/Echo/includes/Formatters/EchoHtmlDigestEmailFormatter.php index fe59aaa3..e0c53425 100644 --- a/Echo/includes/formatters/EchoHtmlDigestEmailFormatter.php +++ b/Echo/includes/Formatters/EchoHtmlDigestEmailFormatter.php @@ -1,5 +1,13 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + +use Html; +use Language; +use Sanitizer; +use SpecialPage; +use User; + class EchoHtmlDigestEmailFormatter extends EchoEventDigestFormatter { /** @@ -61,7 +69,7 @@ class EchoHtmlDigestEmailFormatter extends EchoEventDigestFormatter { return <<< EOF <html><head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <style> @media only screen and (max-width: 480px){ table[id="email-container"]{max-width:600px !important; width:100% !important;} diff --git a/Echo/includes/formatters/EchoHtmlEmailFormatter.php b/Echo/includes/Formatters/EchoHtmlEmailFormatter.php index 9d5c65e3..aaf084e2 100644 --- a/Echo/includes/formatters/EchoHtmlEmailFormatter.php +++ b/Echo/includes/Formatters/EchoHtmlEmailFormatter.php @@ -1,11 +1,31 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + +use Html; +use Language; +use Sanitizer; +use SpecialPage; + class EchoHtmlEmailFormatter extends EchoEventFormatter { - // phpcs:disable Generic.Files.LineLength - const PRIMARY_LINK_STYLE = 'cursor:pointer; text-align:center; text-decoration:none; padding:.45em 0.6em .45em; color:#FFF; background:#36C; font-family: Arial, Helvetica, sans-serif;font-size: 13px;'; - const SECONDARY_LINK_STYLE = 'text-decoration: none;font-size: 10px;font-family: Arial, Helvetica, sans-serif; color: #72777D;'; - // phpcs:enable Generic.Files.LineLength + public const PRIMARY_LINK_STYLE = + 'cursor: pointer;' . + 'text-align: center;' . + 'text-decoration: none;' . + 'padding: 6px 10px;' . + 'border-radius: 2px;' . + 'color: #FFF;' . + 'background: #36C;' . + 'font-family: Arial, Helvetica, sans-serif;' . + 'font-weight: bold;' . + 'font-size: 13px;'; + + public const SECONDARY_LINK_STYLE = + 'text-decoration: none;' . + 'font-size: 10px;' . + 'font-family: Arial, Helvetica, sans-serif;' . + 'color: #72777D;'; protected function formatModel( EchoEventPresentationModel $model ) { $subject = $model->getSubjectMessage()->parse(); @@ -58,7 +78,7 @@ class EchoHtmlEmailFormatter extends EchoEventFormatter { return <<< EOF <html><head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <style> @media only screen and (max-width: 480px){ table[id="email-container"]{max-width:600px !important; width:100% !important;} diff --git a/Echo/includes/formatters/EchoIcon.php b/Echo/includes/Formatters/EchoIcon.php index b7ccbde4..d4166b17 100644 --- a/Echo/includes/formatters/EchoIcon.php +++ b/Echo/includes/Formatters/EchoIcon.php @@ -1,5 +1,10 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + +use InvalidArgumentException; +use UnexpectedValueException; + class EchoIcon { /** @@ -70,11 +75,11 @@ class EchoIcon { // rasterizing module if ( $url === false || $url === null ) { $iconUrl = wfScript( 'load' ) . '?' . wfArrayToCgi( [ - 'modules' => 'ext.echo.emailicons', - 'image' => $icon, - 'lang' => $lang, - 'format' => 'rasterized' - ] ); + 'modules' => 'ext.echo.emailicons', + 'image' => $icon, + 'lang' => $lang, + 'format' => 'rasterized' + ] ); } else { // For icons that are defined by URL $iconUrl = $wgEchoNotificationIcons[ $icon ][ 'url' ]; diff --git a/Echo/includes/formatters/MentionInSummaryPresentationModel.php b/Echo/includes/Formatters/EchoMentionInSummaryPresentationModel.php index 74f17603..52bf83e1 100644 --- a/Echo/includes/formatters/MentionInSummaryPresentationModel.php +++ b/Echo/includes/Formatters/EchoMentionInSummaryPresentationModel.php @@ -1,6 +1,10 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + +use Linker; use MediaWiki\Revision\RevisionRecord; +use Sanitizer; class EchoMentionInSummaryPresentationModel extends EchoEventPresentationModel { @@ -27,9 +31,8 @@ class EchoMentionInSummaryPresentationModel extends EchoEventPresentationModel { $summary = Linker::formatComment( $summary ); $summary = Sanitizer::stripAllTags( $summary ); - $msg = $this->msg( 'notification-body-mention' ) + return $this->msg( 'notification-body-mention' ) ->plaintextParams( $summary ); - return $msg; } else { return false; } @@ -51,9 +54,7 @@ class EchoMentionInSummaryPresentationModel extends EchoEventPresentationModel { } private function getDiffURL() { - $title = $this->event->getTitle(); - - return $title->getLocalURL( [ + return $this->event->getTitle()->getLocalURL( [ 'oldid' => 'prev', 'diff' => $this->event->getExtraParam( 'revid' ) ] ); diff --git a/Echo/includes/formatters/MentionPresentationModel.php b/Echo/includes/Formatters/EchoMentionPresentationModel.php index c407b350..b99ce6bc 100644 --- a/Echo/includes/formatters/MentionPresentationModel.php +++ b/Echo/includes/Formatters/EchoMentionPresentationModel.php @@ -1,13 +1,19 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + +use EchoDiscussionParser; +use EchoEvent; +use Language; use MediaWiki\Revision\RevisionRecord; +use User; class EchoMentionPresentationModel extends EchoEventPresentationModel { /** * @var EchoPresentationModelSection */ - private $section; + protected $section; /** * @inheritDoc @@ -79,7 +85,7 @@ class EchoMentionPresentationModel extends EchoEventPresentationModel { EchoDiscussionParser::getTextSnippet( $content, $this->language, - 150, + EchoDiscussionParser::DEFAULT_SNIPPET_LENGTH, $this->event->getTitle() ) ); @@ -98,9 +104,7 @@ class EchoMentionPresentationModel extends EchoEventPresentationModel { } public function getSecondaryLinks() { - $title = $this->event->getTitle(); - - $url = $title->getLocalURL( [ + $url = $this->event->getTitle()->getLocalURL( [ 'oldid' => 'prev', 'diff' => $this->event->getExtraParam( 'revid' ) ] ); @@ -132,3 +136,5 @@ class EchoMentionPresentationModel extends EchoEventPresentationModel { return 'notification-mention-email-subject'; } } + +class_alias( EchoMentionPresentationModel::class, 'EchoMentionPresentationModel' ); diff --git a/Echo/includes/formatters/MentionStatusPresentationModel.php b/Echo/includes/Formatters/EchoMentionStatusPresentationModel.php index 083d2c84..a00248ae 100644 --- a/Echo/includes/formatters/MentionStatusPresentationModel.php +++ b/Echo/includes/Formatters/EchoMentionStatusPresentationModel.php @@ -1,5 +1,11 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + +use EchoEvent; +use Language; +use User; + /** * Presenter for 'mention-failure' and 'mention-success' notifications * @@ -12,7 +18,7 @@ class EchoMentionStatusPresentationModel extends EchoEventPresentationModel { /** * @var EchoPresentationModelSection */ - private $section; + protected $section; /** * @inheritDoc @@ -152,3 +158,5 @@ class EchoMentionStatusPresentationModel extends EchoEventPresentationModel { return $successCount > 0 && $failCount > 0; } } + +class_alias( EchoMentionStatusPresentationModel::class, 'EchoMentionStatusPresentationModel' ); diff --git a/Echo/includes/formatters/EchoModelFormatter.php b/Echo/includes/Formatters/EchoModelFormatter.php index cff2abe5..9d899cdf 100644 --- a/Echo/includes/formatters/EchoModelFormatter.php +++ b/Echo/includes/Formatters/EchoModelFormatter.php @@ -1,5 +1,7 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + /** * A formatter for the notification flyout popup. Just the bare data needed to * render everything client-side. @@ -8,7 +10,6 @@ class EchoModelFormatter extends EchoEventFormatter { /** * @param EchoEventPresentationModel $model * @return array - * @suppress SecurityCheck-DoubleEscaped */ protected function formatModel( EchoEventPresentationModel $model ) { $data = $model->jsonSerialize(); diff --git a/Echo/includes/formatters/PageLinkedPresentationModel.php b/Echo/includes/Formatters/EchoPageLinkedPresentationModel.php index 3e34c6d2..a012ce92 100644 --- a/Echo/includes/formatters/PageLinkedPresentationModel.php +++ b/Echo/includes/Formatters/EchoPageLinkedPresentationModel.php @@ -1,9 +1,16 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + +use EchoEvent; +use EchoNotificationController; use MediaWiki\MediaWikiServices; +use SpecialPage; +use Title; class EchoPageLinkedPresentationModel extends EchoEventPresentationModel { + /** @var Title|null */ private $pageFrom; public function getIconType() { diff --git a/Echo/includes/formatters/EchoPlainTextDigestEmailFormatter.php b/Echo/includes/Formatters/EchoPlainTextDigestEmailFormatter.php index 55906b43..71c0e709 100644 --- a/Echo/includes/formatters/EchoPlainTextDigestEmailFormatter.php +++ b/Echo/includes/Formatters/EchoPlainTextDigestEmailFormatter.php @@ -1,5 +1,12 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + +use Language; +use Sanitizer; +use SpecialPage; +use User; + class EchoPlainTextDigestEmailFormatter extends EchoEventDigestFormatter { /** diff --git a/Echo/includes/formatters/EchoPlainTextEmailFormatter.php b/Echo/includes/Formatters/EchoPlainTextEmailFormatter.php index 33825136..4299ebb4 100644 --- a/Echo/includes/formatters/EchoPlainTextEmailFormatter.php +++ b/Echo/includes/Formatters/EchoPlainTextEmailFormatter.php @@ -1,5 +1,10 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + +use Sanitizer; +use SpecialPage; + class EchoPlainTextEmailFormatter extends EchoEventFormatter { protected function formatModel( EchoEventPresentationModel $model ) { $subject = Sanitizer::stripAllTags( $model->getSubjectMessage()->parse() ); @@ -14,10 +19,12 @@ class EchoPlainTextEmailFormatter extends EchoEventFormatter { } $primaryLink = $model->getPrimaryLinkWithMarkAsRead(); - - $primaryUrl = wfExpandUrl( $primaryLink['url'], PROTO_CANONICAL ); $colon = $this->msg( 'colon-separator' )->text(); - $text .= "\n\n{$primaryLink['label']}$colon <$primaryUrl>"; + + if ( $primaryLink ) { + $primaryUrl = wfExpandUrl( $primaryLink['url'], PROTO_CANONICAL ); + $text .= "\n\n{$primaryLink['label']}$colon <$primaryUrl>"; + } foreach ( array_filter( $model->getSecondaryLinks() ) as $secondaryLink ) { $url = wfExpandUrl( $secondaryLink['url'], PROTO_CANONICAL ); diff --git a/Echo/includes/formatters/PresentationModelSection.php b/Echo/includes/Formatters/EchoPresentationModelSection.php index 0a93bc53..2ca46a83 100644 --- a/Echo/includes/formatters/PresentationModelSection.php +++ b/Echo/includes/Formatters/EchoPresentationModelSection.php @@ -1,6 +1,15 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + +use EchoDiscussionParser; +use EchoEvent; +use Language; use MediaWiki\Revision\RevisionRecord; +use MWException; +use Parser; +use Title; +use User; /** * Component that represents a section of a page to be used from EchoEventPresentationModel subclass. @@ -20,17 +29,17 @@ class EchoPresentationModelSection { /** * @var EchoEvent */ - private $event; + protected $event; /** * @var User */ - private $user; + protected $user; /** * @var Language */ - private $language; + protected $language; /** * @param EchoEvent $event @@ -47,7 +56,7 @@ class EchoPresentationModelSection { * Get the raw (unparsed) section title * @return string|false Section title */ - private function getRawSectionTitle() { + protected function getRawSectionTitle() { if ( $this->rawSectionTitle !== null ) { return $this->rawSectionTitle; } @@ -70,7 +79,7 @@ class EchoPresentationModelSection { * Get the section title parsed to plain text * @return string|false Section title (plain text) */ - private function getParsedSectionTitle() { + protected function getParsedSectionTitle() { if ( $this->parsedSectionTitle !== null ) { return $this->parsedSectionTitle; } @@ -82,8 +91,11 @@ class EchoPresentationModelSection { $this->parsedSectionTitle = EchoDiscussionParser::getTextSnippet( $rawSectionTitle, $this->language, - 150, - $this->event->getTitle() + EchoDiscussionParser::DEFAULT_SNIPPET_LENGTH, + $this->event->getTitle(), + // linestart=false, because this wikitext was inside a heading like `== … ==`, + // so start-of-line markup like `*` should not be parsed (T299572) + false ); return $this->parsedSectionTitle; } @@ -131,3 +143,5 @@ class EchoPresentationModelSection { ) ); } } + +class_alias( EchoPresentationModelSection::class, 'EchoPresentationModelSection' ); diff --git a/Echo/includes/formatters/RevertedPresentationModel.php b/Echo/includes/Formatters/EchoRevertedPresentationModel.php index 46ce1db0..c690b51c 100644 --- a/Echo/includes/formatters/RevertedPresentationModel.php +++ b/Echo/includes/Formatters/EchoRevertedPresentationModel.php @@ -1,5 +1,8 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + +use EchoDiscussionParser; use MediaWiki\Revision\RevisionRecord; class EchoRevertedPresentationModel extends EchoEventPresentationModel { @@ -76,7 +79,7 @@ class EchoRevertedPresentationModel extends EchoEventPresentationModel { } private function isAutomaticSummary( $summary ) { - $autoSummaryMsg = wfMessage( 'undo-summary' )->inContentLanguage(); + $autoSummaryMsg = $this->msg( 'undo-summary' )->inContentLanguage(); $autoSummaryMsg->params( $this->event->getExtraParam( 'reverted-revision-id' ) ); $autoSummaryMsg->params( $this->getViewingUserForGender() ); $autoSummary = $autoSummaryMsg->text(); diff --git a/Echo/includes/formatters/UserRightsPresentationModel.php b/Echo/includes/Formatters/EchoUserRightsPresentationModel.php index 62213e67..27317de9 100644 --- a/Echo/includes/formatters/UserRightsPresentationModel.php +++ b/Echo/includes/Formatters/EchoUserRightsPresentationModel.php @@ -1,5 +1,12 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + +use EchoDiscussionParser; +use RawMessage; +use SpecialPage; +use User; + /** * Formatter for 'user-rights' notifications */ diff --git a/Echo/includes/formatters/WatchlistChangePresentationModel.php b/Echo/includes/Formatters/EchoWatchlistChangePresentationModel.php index cf09e187..b0d6857a 100644 --- a/Echo/includes/formatters/WatchlistChangePresentationModel.php +++ b/Echo/includes/Formatters/EchoWatchlistChangePresentationModel.php @@ -1,10 +1,13 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + +use SpecialPage; + class EchoWatchlistChangePresentationModel extends EchoEventPresentationModel { public function getIconType() { - // @todo create an icon to use here - return 'placeholder'; + return 'watchlist-progressive'; } public function getHeaderMessage() { @@ -28,7 +31,7 @@ class EchoWatchlistChangePresentationModel extends EchoEventPresentationModel { // notification-header-watchlist-restored $msg = $this->getMessageWithAgent( "notification-header-watchlist-" . $status ); } - $msg->params( $this->getTruncatedTitleText( $this->event->getTitle() ) ); + $msg->params( $this->getTruncatedTitleText( $this->event->getTitle(), true ) ); $msg->params( $this->getViewingUserForGender() ); $msg->numParams( $this->getBundleCount() ); return $msg; @@ -68,6 +71,13 @@ class EchoWatchlistChangePresentationModel extends EchoEventPresentationModel { } } + public function getBodyMessage() { + if ( $this->event->getExtraParam( 'emailonce' ) && $this->getDistributionType() == 'email' ) { + return $this->msg( 'notification-body-watchlist-once', $this->getViewingUserForGender() ); + } + return false; + } + private function isMultiUserBundle() { foreach ( $this->getBundledEvents() as $bundled ) { if ( !$bundled->getAgent()->equals( $this->event->getAgent() ) ) { diff --git a/Echo/includes/formatters/WelcomePresentationModel.php b/Echo/includes/Formatters/EchoWelcomePresentationModel.php index ca14f17b..aadef7c3 100644 --- a/Echo/includes/formatters/WelcomePresentationModel.php +++ b/Echo/includes/Formatters/EchoWelcomePresentationModel.php @@ -1,5 +1,9 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + +use Title; + class EchoWelcomePresentationModel extends EchoEventPresentationModel { public function getIconType() { diff --git a/Echo/includes/formatters/SpecialNotificationsFormatter.php b/Echo/includes/Formatters/SpecialNotificationsFormatter.php index c5b4caf0..e20130ea 100644 --- a/Echo/includes/formatters/SpecialNotificationsFormatter.php +++ b/Echo/includes/Formatters/SpecialNotificationsFormatter.php @@ -1,5 +1,14 @@ <?php +namespace MediaWiki\Extension\Notifications\Formatters; + +use Html; +use MWTimestamp; +use OOUI\IconWidget; +use OutputPage; +use SpecialNotificationsMarkRead; +use Xml; + /** * A formatter for Special:Notifications * @@ -21,7 +30,7 @@ class SpecialNotificationsFormatter extends EchoEventFormatter { OutputPage::setupOOUI(); - $markAsReadIcon = new OOUI\IconWidget( [ + $markAsReadIcon = new IconWidget( [ 'icon' => 'close', 'title' => wfMessage( 'echo-notification-markasread' )->text(), ] ); @@ -40,18 +49,18 @@ class SpecialNotificationsFormatter extends EchoEventFormatter { ); $html = Xml::tags( - 'div', - [ 'class' => 'mw-echo-title' ], - $model->getHeaderMessage()->parse() - ) . "\n"; + 'div', + [ 'class' => 'mw-echo-title' ], + $model->getHeaderMessage()->parse() + ) . "\n"; $body = $model->getBodyMessage(); if ( $body ) { $html .= Xml::tags( - 'div', - [ 'class' => 'mw-echo-payload' ], - $body->escaped() - ) . "\n"; + 'div', + [ 'class' => 'mw-echo-payload' ], + $body->escaped() + ) . "\n"; } $ts = $this->language->getHumanTimestamp( @@ -102,15 +111,13 @@ class SpecialNotificationsFormatter extends EchoEventFormatter { // And then add the mark as read button // and the icon in front and wrap with // mw-echo-state class. - $html = Xml::tags( 'div', [ 'class' => 'mw-echo-state' ], $markAsReadButton . $icon . $html ); - - return $html; + return Xml::tags( 'div', [ 'class' => 'mw-echo-state' ], $markAsReadButton . $icon . $html ); } private function getIconURL( EchoEventPresentationModel $model ) { return EchoIcon::getUrl( - $model->getIconType(), - $this->language->getDir() + $model->getIconType(), + $this->language->getDir() ); } } diff --git a/Echo/includes/EchoHooks.php b/Echo/includes/Hooks.php index 284933f4..1eb5812c 100644 --- a/Echo/includes/EchoHooks.php +++ b/Echo/includes/Hooks.php @@ -1,24 +1,119 @@ <?php +namespace MediaWiki\Extension\Notifications; + +use ApiModuleManager; +use Config; +use Content; +use DatabaseUpdater; +use DeferredUpdates; +use EchoAttributeManager; +use EchoDiscussionParser; +use EchoEmailFormat; +use EchoEmailFrequency; +use EchoEvent; +use EchoEventMapper; +use EchoModerationController; +use EchoNotification; +use EchoNotificationController; +use EchoNotificationMapper; +use EchoSeenTime; +use EchoServices; +use EmailNotification; +use ExtensionRegistry; +use Hooks as MWHooks; +use HTMLCheckMatrix; +use LinksUpdate; +use LogEntry; +use MailAddress; +use MediaWiki\Api\Hook\ApiMain__moduleManagerHook; +use MediaWiki\Auth\Hook\LocalUserCreatedHook; +use MediaWiki\DAO\WikiAwareEntity; +use MediaWiki\Extension\Notifications\Formatters\EchoEventPresentationModel; +use MediaWiki\Extension\Notifications\Push\Api\ApiEchoPushSubscriptions; +use MediaWiki\Hook\AbortTalkPageEmailNotificationHook; +use MediaWiki\Hook\BeforePageDisplayHook; +use MediaWiki\Hook\EmailUserCompleteHook; +use MediaWiki\Hook\GetNewMessagesAlertHook; +use MediaWiki\Hook\LinksUpdateCompleteHook; +use MediaWiki\Hook\LoginFormValidErrorMessagesHook; +use MediaWiki\Hook\OutputPageCheckLastModifiedHook; +use MediaWiki\Hook\PreferencesGetIconHook; use MediaWiki\Hook\RecentChange_saveHook; +use MediaWiki\Hook\SendWatchlistEmailNotificationHook; +use MediaWiki\Hook\SkinTemplateNavigation__UniversalHook; use MediaWiki\Logger\LoggerFactory; use MediaWiki\MediaWikiServices; +use MediaWiki\Page\Hook\ArticleDeleteCompleteHook; +use MediaWiki\Page\Hook\ArticleUndeleteHook; +use MediaWiki\Page\Hook\RollbackCompleteHook; +use MediaWiki\Preferences\Hook\GetPreferencesHook; use MediaWiki\Preferences\MultiTitleFilter; use MediaWiki\Preferences\MultiUsernameFilter; +use MediaWiki\ResourceLoader as RL; +use MediaWiki\ResourceLoader\Hook\ResourceLoaderRegisterModulesHook; +use MediaWiki\ResourceLoader\ResourceLoader; use MediaWiki\Revision\RevisionRecord; use MediaWiki\Storage\EditResult; +use MediaWiki\Storage\Hook\PageSaveCompleteHook; +use MediaWiki\User\Hook\UserClearNewTalkNotificationHook; +use MediaWiki\User\Hook\UserGetDefaultOptionsHook; +use MediaWiki\User\Hook\UserGroupsChangedHook; +use MediaWiki\User\Hook\UserSaveSettingsHook; +use MediaWiki\User\Options\Hook\LoadUserOptionsHook; +use MediaWiki\User\Options\Hook\SaveUserOptionsHook; use MediaWiki\User\UserIdentity; - -class EchoHooks implements RecentChange_saveHook { - /** - * @var RevisionRecord - */ - private static $lastRevertedRevision = null; +use MWEchoDbFactory; +use MWEchoNotifUser; +use MWException; +use OutputPage; +use RecentChange; +use ResourceLoaderEchoImageModule; +use Skin; +use SkinTemplate; +use SpecialPage; +use Title; +use UpdateEchoSchemaForSuppression; +use User; +use WebRequest; +use WikiMap; +use WikiPage; + +class Hooks implements + AbortTalkPageEmailNotificationHook, + ApiMain__moduleManagerHook, + ArticleDeleteCompleteHook, + ArticleUndeleteHook, + BeforePageDisplayHook, + EmailUserCompleteHook, + GetNewMessagesAlertHook, + GetPreferencesHook, + LinksUpdateCompleteHook, + LoadUserOptionsHook, + LocalUserCreatedHook, + LoginFormValidErrorMessagesHook, + OutputPageCheckLastModifiedHook, + PageSaveCompleteHook, + PreferencesGetIconHook, + RecentChange_saveHook, + ResourceLoaderRegisterModulesHook, + RollbackCompleteHook, + SaveUserOptionsHook, + SendWatchlistEmailNotificationHook, + SkinTemplateNavigation__UniversalHook, + UserClearNewTalkNotificationHook, + UserGetDefaultOptionsHook, + UserGroupsChangedHook, + UserSaveSettingsHook +{ /** * @var Config */ private $config; + /** @var array */ + private static $revertedRevIds = []; + public function __construct( Config $config ) { $this->config = $config; } @@ -26,8 +121,8 @@ class EchoHooks implements RecentChange_saveHook { /** * @param array &$defaults */ - public static function onUserGetDefaultOptions( array &$defaults ) { - global $wgAllowHTMLEmail, $wgEchoNotificationCategories; + public function onUserGetDefaultOptions( &$defaults ) { + global $wgAllowHTMLEmail, $wgEchoNotificationCategories, $wgEchoEnablePush; if ( $wgAllowHTMLEmail ) { $defaults['echo-email-format'] = 'html'; /*EchoHooks::EMAIL_FORMAT_HTML*/ @@ -65,6 +160,14 @@ class EchoHooks implements RecentChange_saveHook { 'web' => false, ], ]; + if ( $wgEchoEnablePush ) { + $presets['default']['push'] = true; + $presets['article-linked']['push'] = false; + $presets['mention-failure']['push'] = false; + $presets['mention-success']['push'] = false; + $presets['watchlist']['push'] = false; + $presets['minor-watchlist']['push'] = false; + } foreach ( $wgEchoNotificationCategories as $category => $categoryData ) { if ( !isset( $defaults["echo-subscriptions-email-{$category}"] ) ) { @@ -75,6 +178,11 @@ class EchoHooks implements RecentChange_saveHook { $defaults["echo-subscriptions-web-{$category}"] = $presets[$category]['web'] ?? $presets['default']['web']; } + if ( $wgEchoEnablePush && !isset( $defaults["echo-subscriptions-push-{$category}"] ) ) { + $defaults["echo-subscriptions-push-{$category}"] = $presets[$category]['push'] + // @phan-suppress-next-line PhanTypePossiblyInvalidDimOffset + ?? $presets['default']['push']; + } } } @@ -85,10 +193,11 @@ class EchoHooks implements RecentChange_saveHook { public static function initEchoExtension() { global $wgEchoNotifications, $wgEchoNotificationCategories, $wgEchoNotificationIcons, $wgEchoMentionStatusNotifications, $wgAllowArticleReminderNotification, $wgAPIModules, - $wgEchoWatchlistNotifications, $wgEchoSeenTimeCacheType, $wgMainStash; + $wgEchoWatchlistNotifications, $wgEchoSeenTimeCacheType, $wgMainStash, $wgEnableEmail, + $wgEnableUserEmail; // allow extensions to define their own event - Hooks::run( 'BeforeCreateEchoEvent', + MWHooks::run( 'BeforeCreateEchoEvent', [ &$wgEchoNotifications, &$wgEchoNotificationCategories, &$wgEchoNotificationIcons ] ); // Only allow mention status notifications when enabled @@ -109,6 +218,11 @@ class EchoHooks implements RecentChange_saveHook { unset( $wgEchoNotificationCategories['minor-watchlist'] ); } + // Only allow user email notifications when enabled + if ( !$wgEnableEmail || !$wgEnableUserEmail ) { + unset( $wgEchoNotificationCategories['emailuser'] ); + } + // Default $wgEchoSeenTimeCacheType to $wgMainStash if ( $wgEchoSeenTimeCacheType === null ) { $wgEchoSeenTimeCacheType = $wgMainStash; @@ -116,60 +230,20 @@ class EchoHooks implements RecentChange_saveHook { } /** - * ResourceLoaderTestModules hook handler - * @see https://www.mediawiki.org/wiki/Manual:Hooks/ResourceLoaderTestModules - * - * @param array &$testModules - * @param ResourceLoader $resourceLoader - */ - public static function onResourceLoaderTestModules( array &$testModules, - ResourceLoader $resourceLoader - ) { - global $wgResourceModules; - - $testModuleBoilerplate = [ - 'localBasePath' => dirname( __DIR__ ), - 'remoteExtPath' => 'Echo', - ]; - - // find test files for every RL module - $prefix = 'ext.echo'; - foreach ( $wgResourceModules as $key => $module ) { - if ( substr( $key, 0, strlen( $prefix ) ) === $prefix && isset( $module['scripts'] ) ) { - $testFiles = []; - foreach ( $module['scripts'] as $script ) { - $testFile = 'tests/qunit/' . dirname( $script ) . '/test_' . basename( $script ); - // if a test file exists for a given JS file, add it - if ( file_exists( $testModuleBoilerplate['localBasePath'] . '/' . $testFile ) ) { - $testFiles[] = $testFile; - } - } - // if test files exist for given module, create a corresponding test module - if ( $testFiles !== [] ) { - $testModules['qunit']["$key.tests"] = $testModuleBoilerplate + [ - 'dependencies' => [ $key ], - 'scripts' => $testFiles, - ]; - } - } - } - } - - /** * Handler for ResourceLoaderRegisterModules hook * @param ResourceLoader $resourceLoader */ - public static function onResourceLoaderRegisterModules( ResourceLoader $resourceLoader ) { + public function onResourceLoaderRegisterModules( ResourceLoader $resourceLoader ): void { global $wgExtensionDirectory, $wgEchoNotificationIcons, $wgEchoSecondaryIcons; $resourceLoader->register( 'ext.echo.emailicons', [ - 'class' => 'ResourceLoaderEchoImageModule', + 'class' => ResourceLoaderEchoImageModule::class, 'icons' => $wgEchoNotificationIcons, 'selector' => '.mw-echo-icon-{name}', 'localBasePath' => $wgExtensionDirectory, 'remoteExtPath' => 'Echo/modules' ] ); $resourceLoader->register( 'ext.echo.secondaryicons', [ - 'class' => 'ResourceLoaderEchoImageModule', + 'class' => ResourceLoaderEchoImageModule::class, 'icons' => $wgEchoSecondaryIcons, 'selector' => '.mw-echo-icon-{name}', 'localBasePath' => $wgExtensionDirectory, @@ -180,102 +254,63 @@ class EchoHooks implements RecentChange_saveHook { /** * @param DatabaseUpdater $updater */ - public static function onLoadExtensionSchemaUpdates( DatabaseUpdater $updater ) { + public static function onLoadExtensionSchemaUpdates( $updater ) { global $wgEchoCluster; if ( $wgEchoCluster ) { // DatabaseUpdater does not support other databases, so skip return; } - $dir = dirname( __DIR__ ); - $baseSQLFile = "$dir/echo.sql"; - $updater->addExtensionTable( 'echo_event', $baseSQLFile ); - $updater->addExtensionTable( 'echo_email_batch', "$dir/db_patches/echo_email_batch.sql" ); - $updater->addExtensionTable( 'echo_target_page', "$dir/db_patches/echo_target_page.sql" ); - - if ( $updater->getDB()->getType() === 'sqlite' ) { - $updater->modifyExtensionField( 'echo_event', 'event_agent', - "$dir/db_patches/patch-event_agent-split.sqlite.sql" ); - $updater->modifyExtensionField( 'echo_event', 'event_variant', - "$dir/db_patches/patch-event_variant_nullability.sqlite.sql" ); - $updater->addExtensionField( 'echo_target_page', 'etp_id', - "$dir/db_patches/patch-multiple_target_pages.sqlite.sql" ); - $updater->dropExtensionField( 'echo_target_page', 'etp_user', - "$dir/db_patches/patch-drop-echo_target_page-etp_user.sqlite.sql" ); - // There is no need to run the patch-event_extra-size or patch-event_agent_ip-size because - // sqlite ignores numeric arguments in parentheses that follow the type name (ex: VARCHAR(255)) - // see http://www.sqlite.org/datatype3.html Section 2.2 for more info - } else { - $updater->modifyExtensionField( 'echo_event', 'event_agent', - "$dir/db_patches/patch-event_agent-split.sql" ); - $updater->modifyExtensionField( 'echo_event', 'event_variant', - "$dir/db_patches/patch-event_variant_nullability.sql" ); - $updater->modifyExtensionField( 'echo_event', 'event_extra', - "$dir/db_patches/patch-event_extra-size.sql" ); - $updater->modifyExtensionField( 'echo_event', 'event_agent_ip', - "$dir/db_patches/patch-event_agent_ip-size.sql" ); - $updater->addExtensionField( 'echo_target_page', 'etp_id', - "$dir/db_patches/patch-multiple_target_pages.sql" ); - $updater->dropExtensionField( 'echo_target_page', 'etp_user', - "$dir/db_patches/patch-drop-echo_target_page-etp_user.sql" ); - } - - $updater->addExtensionField( 'echo_notification', 'notification_bundle_hash', - "$dir/db_patches/patch-notification-bundling-field.sql" ); - // This index was renamed twice, first from type_page to event_type and - // later from event_type to echo_event_type - if ( $updater->getDB()->indexExists( 'echo_event', 'type_page', __METHOD__ ) ) { - $updater->addExtensionIndex( 'echo_event', 'event_type', - "$dir/db_patches/patch-alter-type_page-index.sql" ); - } - $updater->dropExtensionTable( 'echo_subscription', - "$dir/db_patches/patch-drop-echo_subscription.sql" ); - if ( $updater->getDB()->getType() !== 'sqlite' ) { - $updater->dropExtensionField( 'echo_event', 'event_timestamp', - "$dir/db_patches/patch-drop-echo_event-event_timestamp.sql" ); - } - $updater->addExtensionField( 'echo_email_batch', 'eeb_event_hash', - "$dir/db_patches/patch-email_batch-new-field.sql" ); - $updater->addExtensionField( 'echo_event', 'event_page_id', - "$dir/db_patches/patch-add-echo_event-event_page_id.sql" ); - $updater->addExtensionIndex( 'echo_event', 'echo_event_type', - "$dir/db_patches/patch-alter-event_type-index.sql" ); - $updater->addExtensionIndex( 'echo_notification', 'echo_user_timestamp', - "$dir/db_patches/patch-alter-user_timestamp-index.sql" ); - $updater->addExtensionIndex( 'echo_notification', 'echo_notification_event', - "$dir/db_patches/patch-add-notification_event-index.sql" ); - $updater->addPostDatabaseUpdateMaintenance( RemoveOrphanedEvents::class ); - $updater->addExtensionField( 'echo_event', 'event_deleted', - "$dir/db_patches/patch-add-echo_event-event_deleted.sql" ); - $updater->addExtensionIndex( 'echo_notification', 'echo_notification_user_read_timestamp', - "$dir/db_patches/patch-add-user_read_timestamp-index.sql" ); - $updater->addExtensionIndex( 'echo_target_page', 'echo_target_page_page_event', - "$dir/db_patches/patch-add-page_event-index.sql" ); - $updater->addExtensionIndex( 'echo_event', 'echo_event_page_id', - "$dir/db_patches/patch-add-event_page_id-index.sql" ); - $updater->dropExtensionIndex( 'echo_notification', 'user_event', - "$dir/db_patches/patch-notification-pk.sql" ); + + $dbType = $updater->getDB()->getType(); + + $dir = dirname( __DIR__ ) . '/sql'; + + $updater->addExtensionTable( 'echo_event', "$dir/$dbType/tables-generated.sql" ); + + // 1.33 // Can't use addPostDatabaseUpdateMaintenance() here because that would // run the migration script after dropping the fields $updater->addExtensionUpdate( [ 'runMaintenance', UpdateEchoSchemaForSuppression::class, 'extensions/Echo/maintenance/updateEchoSchemaForSuppression.php' ] ); $updater->dropExtensionField( 'echo_event', 'event_page_namespace', - "$dir/db_patches/patch-drop-echo_event-event_page_namespace.sql" ); + "$dir/patch-drop-echo_event-event_page_namespace.sql" ); $updater->dropExtensionField( 'echo_event', 'event_page_title', - "$dir/db_patches/patch-drop-echo_event-event_page_title.sql" ); - if ( $updater->getDB()->getType() !== 'sqlite' ) { + "$dir/patch-drop-echo_event-event_page_title.sql" ); + if ( $dbType === 'mysql' ) { $updater->dropExtensionField( 'echo_notification', 'notification_bundle_base', - "$dir/db_patches/patch-drop-notification_bundle_base.sql" ); + "$dir/mysql/patch-drop-notification_bundle_base.sql" ); $updater->dropExtensionField( 'echo_notification', 'notification_bundle_display_hash', - "$dir/db_patches/patch-drop-notification_bundle_display_hash.sql" ); + "$dir/mysql/patch-drop-notification_bundle_display_hash.sql" ); } $updater->dropExtensionIndex( 'echo_notification', 'echo_notification_user_hash_timestamp', - "$dir/db_patches/patch-drop-user-hash-timestamp-index.sql" ); + "$dir/patch-drop-user-hash-timestamp-index.sql" ); + + // 1.35 + $updater->addExtensionTable( 'echo_push_provider', "$dir/echo_push_provider.sql" ); + $updater->addExtensionTable( 'echo_push_subscription', "$dir/echo_push_subscription.sql" ); + + // 1.36 + $updater->addExtensionTable( 'echo_push_topic', "$dir/echo_push_topic.sql" ); + + // 1.39 + if ( $dbType === 'mysql' || $dbType === 'sqlite' ) { + $updater->addExtensionIndex( 'echo_push_subscription', 'eps_user', + "$dir/$dbType/patch-cleanup-push_subscription-foreign-keys-indexes.sql" ); + } - $updater->addExtensionTable( 'echo_push_provider', "$dir/db_patches/echo_push_provider.sql" ); - $updater->addExtensionTable( 'echo_push_subscription', "$dir/db_patches/echo_push_subscription.sql" ); + global $wgEchoSharedTrackingCluster, $wgEchoSharedTrackingDB; + // Following tables should only be created if both cluster and database are false. + // Otherwise they are not created in the place they are accesses, because + // DatabaseUpdater does not support other databases other than main wiki schema. + if ( $wgEchoSharedTrackingCluster === false && $wgEchoSharedTrackingDB === false ) { + $updater->addExtensionTable( 'echo_unread_wikis', "$dir/$dbType/tables-sharedtracking-generated.sql" ); - $updater->modifyExtensionField( 'echo_unread_wikis', 'euw_wiki', - "$dir/db_patches/patch-increase-varchar-echo_unread_wikis-euw_wiki.sql" ); + // 1.34 (backported) - not for sqlite, the used data type supports the new length + if ( $updater->getDB()->getType() === 'mysql' ) { + $updater->modifyExtensionField( 'echo_unread_wikis', 'euw_wiki', + "$dir/mysql/patch-increase-varchar-echo_unread_wikis-euw_wiki.sql" ); + } + } } /** @@ -291,14 +326,8 @@ class EchoHooks implements RecentChange_saveHook { public static function onEchoGetBundleRules( $event, &$bundleString ) { switch ( $event->getType() ) { case 'edit-user-talk': - $bundleString = 'edit-user-talk'; - if ( $event->getTitle() ) { - $bundleString .= '-' . $event->getTitle()->getNamespace() - . '-' . $event->getTitle()->getDBkey(); - } - break; case 'page-linked': - $bundleString = 'page-linked'; + $bundleString = $event->getType(); if ( $event->getTitle() ) { $bundleString .= '-' . $event->getTitle()->getNamespace() . '-' . $event->getTitle()->getDBkey(); @@ -328,14 +357,14 @@ class EchoHooks implements RecentChange_saveHook { * * @throws MWException */ - public static function getPreferences( $user, &$preferences ) { + public function onGetPreferences( $user, &$preferences ) { global $wgEchoEnableEmailBatch, $wgEchoNotifiers, $wgEchoNotificationCategories, $wgEchoNotifications, $wgAllowHTMLEmail, $wgEchoPollForUpdates, $wgEchoCrossWikiNotifications, $wgEchoPerUserBlacklist, $wgEchoWatchlistNotifications; - $attributeManager = EchoAttributeManager::newFromGlobalVars(); + $attributeManager = EchoServices::getInstance()->getAttributeManager(); // Show email frequency options $freqOptions = [ @@ -423,7 +452,7 @@ class EchoHooks implements RecentChange_saveHook { // Show subscription options. IMPORTANT: 'echo-subscriptions-email-edit-user-talk', // 'echo-subscriptions-email-watchlist', and 'echo-subscriptions-email-minor-watchlist' are // virtual options, their values are saved to existing notification options 'enotifusertalkpages', - // 'enotifwatchlistpages', and 'enotifminoredits', see onUserLoadOptions() and onUserSaveOptions() + // 'enotifwatchlistpages', and 'enotifminoredits', see onLoadUserOptions() and onSaveUserOptions() // for more information on how it is handled. Doing it in this way, we can avoid keeping running // massive data migration script to keep these two options synced when echo is enabled on // new wikis or Echo is disabled and re-enabled for some reason. We can update the name @@ -470,7 +499,7 @@ class EchoHooks implements RecentChange_saveHook { ) ); } $preferences['echo-subscriptions'] = [ - 'class' => 'HTMLCheckMatrix', + 'class' => HTMLCheckMatrix::class, 'section' => 'echo/echosubscriptions', 'rows' => $rows, 'columns' => $columns, @@ -527,12 +556,22 @@ class EchoHooks implements RecentChange_saveHook { 'label-message' => 'echo-pref-notifications-page-linked-title-muted-list', 'section' => 'echo/mutedpageslist', 'showMissing' => false, - 'filter' => ( new MultiTitleFilter( new TitleFactory() ) ) + 'excludeDynamicNamespaces' => true, + 'filter' => new MultiTitleFilter() ]; } } /** + * Add icon for Special:Preferences mobile layout + * + * @param array &$iconNames Array of icon names for their respective sections. + */ + public function onPreferencesGetIcon( &$iconNames ) { + $iconNames[ 'echo' ] = 'bell'; + } + + /** * Test whether email address change is supposed to be allowed * @return bool */ @@ -552,51 +591,49 @@ class EchoHooks implements RecentChange_saveHook { * @param RevisionRecord $revisionRecord RevisionRecord for the revision that was created * @param EditResult $editResult */ - public static function onPageSaveComplete( - WikiPage $wikiPage, - UserIdentity $userIdentity, - string $summary, - int $flags, - RevisionRecord $revisionRecord, - EditResult $editResult + public function onPageSaveComplete( + $wikiPage, + $userIdentity, + $summary, + $flags, + $revisionRecord, + $editResult ) { - global $wgEchoNotifications; - if ( $editResult->isNullEdit() ) { return; } $title = $wikiPage->getTitle(); - $undidRevId = $editResult->getUndidRevId(); + $isRevert = $editResult->getRevertMethod() === EditResult::REVERT_UNDO || + $editResult->getRevertMethod() === EditResult::REVERT_ROLLBACK; + + // Save the revert status for the LinksUpdateComplete hook + if ( $isRevert ) { + self::$revertedRevIds[$revisionRecord->getId()] = true; + } // Try to do this after the HTTP response - DeferredUpdates::addCallableUpdate( function () use ( $revisionRecord, $undidRevId ) { - // This check has to happen during deferred processing, otherwise $lastRevertedRevision - // will not be initialized. - $isRevert = $undidRevId > 0 || - ( self::$lastRevertedRevision && - self::$lastRevertedRevision->getId() === $revisionRecord->getId() ); + DeferredUpdates::addCallableUpdate( static function () use ( $revisionRecord, $isRevert ) { EchoDiscussionParser::generateEventsForRevision( $revisionRecord, $isRevert ); } ); - $user = User::newFromIdentity( $userIdentity ); // If the user is not an IP and this is not a null edit, // test for them reaching a congratulatory threshold $thresholds = [ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000 ]; - if ( $user->isLoggedIn() ) { - $thresholdCount = self::getEditCount( $user ); + if ( $userIdentity->isRegistered() ) { + $thresholdCount = self::getEditCount( $userIdentity ); if ( in_array( $thresholdCount, $thresholds ) ) { - DeferredUpdates::addCallableUpdate( function () use ( $user, $title, $thresholdCount ) { + DeferredUpdates::addCallableUpdate( static function () use ( $userIdentity, $title, $thresholdCount ) { $notificationMapper = new EchoNotificationMapper(); - $notifications = $notificationMapper->fetchByUser( $user, 10, null, [ 'thank-you-edit' ] ); + $notifications = $notificationMapper->fetchByUser( $userIdentity, 10, null, [ 'thank-you-edit' ] ); /** @var EchoNotification $notification */ foreach ( $notifications as $notification ) { if ( $notification->getEvent()->getExtraParam( 'editCount' ) === $thresholdCount ) { LoggerFactory::getInstance( 'Echo' )->debug( '{user} (id: {id}) has already been thanked for their {count} edit', [ - 'user' => $user->getName(), - 'id' => $user->getId(), + 'user' => $userIdentity->getName(), + 'id' => $userIdentity->getId(), 'count' => $thresholdCount, ] ); @@ -605,41 +642,44 @@ class EchoHooks implements RecentChange_saveHook { } EchoEvent::create( [ - 'type' => 'thank-you-edit', - 'title' => $title, - 'agent' => $user, - // Edit threshold notifications are sent to the agent - 'extra' => [ - 'editCount' => $thresholdCount, - ] + 'type' => 'thank-you-edit', + 'title' => $title, + 'agent' => $userIdentity, + // Edit threshold notifications are sent to the agent + 'extra' => [ + 'editCount' => $thresholdCount, ] - ); + ] ); } ); } } // Handle the case of someone undoing an edit, either through the // 'undo' link in the article history or via the API. - if ( isset( $wgEchoNotifications['reverted'] ) && $undidRevId ) { + // Reverts through the 'rollback' link (EditResult::REVERT_ROLLBACK) + // are handled in ::onRollbackComplete(). + if ( $editResult->getRevertMethod() === EditResult::REVERT_UNDO ) { $store = MediaWikiServices::getInstance()->getRevisionStore(); + $undidRevId = $editResult->getUndidRevId(); $undidRevision = $store->getRevisionById( $undidRevId ); if ( $undidRevision && Title::newFromLinkTarget( $undidRevision->getPageAsLinkTarget() )->equals( $title ) ) { - $victimId = $undidRevision->getUser(); - if ( $victimId ) { // No notifications for anonymous users + $revertedUser = $undidRevision->getUser(); + // No notifications for anonymous users + if ( $revertedUser && $revertedUser->getId() ) { EchoEvent::create( [ 'type' => 'reverted', 'title' => $title, 'extra' => [ 'revid' => $revisionRecord->getId(), - 'reverted-user-id' => $victimId, + 'reverted-user-id' => $revertedUser->getId(), 'reverted-revision-id' => $undidRevId, 'method' => 'undo', 'summary' => $summary, ], - 'agent' => $user, + 'agent' => $userIdentity, ] ); } } @@ -647,17 +687,19 @@ class EchoHooks implements RecentChange_saveHook { } /** - * @param User $user + * @param UserIdentity $user * @return int */ - private static function getEditCount( User $user ) { + private static function getEditCount( UserIdentity $user ) { + $editCount = MediaWikiServices::getInstance()->getUserEditTracker() + ->getUserEditCount( $user ) ?: 0; // When this code runs from a maintenance script or unit tests // the deferred update incrementing edit count runs right away // so the edit count is right. Otherwise it lags by one. if ( wfIsCLI() ) { - return $user->getEditCount(); + return $editCount; } - return $user->getEditCount() + 1; + return $editCount + 1; } /** @@ -673,7 +715,8 @@ class EchoHooks implements RecentChange_saveHook { $extra = $event->getExtra(); if ( !empty( $extra['minoredit'] ) ) { global $wgEnotifMinorEdits; - if ( !$wgEnotifMinorEdits || !$user->getOption( 'enotifminoredits' ) ) { + $userOptionsLookup = MediaWikiServices::getInstance()->getUserOptionsLookup(); + if ( !$wgEnotifMinorEdits || !$userOptionsLookup->getOption( $user, 'enotifminoredits' ) ) { // Do not send talk page notification email return false; } @@ -720,13 +763,13 @@ class EchoHooks implements RecentChange_saveHook { * @param User $user User object that was created. * @param bool $autocreated True when account was auto-created */ - public static function onLocalUserCreated( $user, $autocreated ) { + public function onLocalUserCreated( $user, $autocreated ) { if ( !$autocreated ) { $overrides = self::getNewUserPreferenceOverrides(); + $userOptionsManager = MediaWikiServices::getInstance()->getUserOptionsManager(); foreach ( $overrides as $prefKey => $value ) { - $user->setOption( $prefKey, $value ); + $userOptionsManager->setOption( $user, $prefKey, $value ); } - $user->saveSettings(); EchoEvent::create( [ 'type' => 'welcome', 'agent' => $user, @@ -743,7 +786,7 @@ class EchoHooks implements RecentChange_saveHook { * Handler for UserGroupsChanged hook. * @see https://www.mediawiki.org/wiki/Manual:Hooks/UserGroupsChanged * - * @param User $user user that was changed + * @param UserIdentity $userId user that was changed * @param string[] $add strings corresponding to groups added * @param string[] $remove strings corresponding to groups removed * @param User|bool $performer @@ -751,18 +794,20 @@ class EchoHooks implements RecentChange_saveHook { * @param array $oldUGMs * @param array $newUGMs */ - public static function onUserGroupsChanged( $user, $add, $remove, $performer, - $reason = false, array $oldUGMs = [], array $newUGMs = [] ) { + public function onUserGroupsChanged( $userId, $add, $remove, $performer, + $reason, $oldUGMs, $newUGMs ) { if ( !$performer ) { // TODO: Implement support for autopromotion return; } - if ( !$user instanceof User ) { - // TODO: Support UserRightsProxy + if ( $userId->getWikiId() !== WikiAwareEntity::LOCAL ) { + // TODO: Support external users return; } + $user = MediaWikiServices::getInstance()->getUserFactory()->newFromUserIdentity( $userId ); + if ( $user->equals( $performer ) ) { // Don't notify for self changes return; @@ -813,30 +858,28 @@ class EchoHooks implements RecentChange_saveHook { } /** - * Handler for LinksUpdateAfterInsert hook. - * @see https://www.mediawiki.org/wiki/Manual:Hooks/LinksUpdateAfterInsert + * Handler for LinksUpdateComplete hook. + * @see https://www.mediawiki.org/wiki/Manual:Hooks/LinksUpdateComplete * @param LinksUpdate $linksUpdate - * @param string $table - * @param array[] $insertions + * @param mixed $ticket */ - public static function onLinksUpdateAfterInsert( $linksUpdate, $table, $insertions ) { - global $wgRequest; - - // FIXME: This doesn't work in 1.27+ + public function onLinksUpdateComplete( $linksUpdate, $ticket ) { // Rollback or undo should not trigger link notification - // @Todo Implement a better solution so it doesn't depend on the checking of - // a specific set of request variables - if ( $wgRequest->getVal( 'wpUndidRevision' ) || $wgRequest->getVal( 'action' ) == 'rollback' ) { - return; + if ( $linksUpdate->getRevisionRecord() ) { + $revId = $linksUpdate->getRevisionRecord()->getId(); + if ( isset( self::$revertedRevIds[$revId] ) ) { + return; + } } + $namespaceInfo = MediaWikiServices::getInstance()->getNamespaceInfo(); + // Handle only - // 1. inserts to pagelinks table && - // 2. content namespace pages && - // 3. non-transcluding pages && - // 4. non-redirect pages - if ( $table !== 'pagelinks' || !MWNamespace::isContent( $linksUpdate->mTitle->getNamespace() ) - || !$linksUpdate->mRecursive || $linksUpdate->mTitle->isRedirect() + // 1. content namespace pages && + // 2. non-transcluding pages && + // 3. non-redirect pages + if ( !$namespaceInfo->isContent( $linksUpdate->getTitle()->getNamespace() ) + || !$linksUpdate->isRecursive() || $linksUpdate->getTitle()->isRedirect() ) { return; } @@ -851,14 +894,13 @@ class EchoHooks implements RecentChange_saveHook { $max = 10; // Only create notifications for links to content namespace pages // @Todo - use one big insert instead of individual insert inside foreach loop - foreach ( $insertions as $page ) { - if ( MWNamespace::isContent( $page['pl_namespace'] ) ) { - $title = Title::makeTitle( $page['pl_namespace'], $page['pl_title'] ); + foreach ( $linksUpdate->getAddedLinks() as $title ) { + if ( $namespaceInfo->isContent( $title->getNamespace() ) ) { if ( $title->isRedirect() ) { continue; } - $linkFromPageId = $linksUpdate->mTitle->getArticleID(); + $linkFromPageId = $linksUpdate->getTitle()->getArticleID(); EchoEvent::create( [ 'type' => 'page-linked', 'title' => $title, @@ -883,16 +925,25 @@ class EchoHooks implements RecentChange_saveHook { * @param OutputPage $out * @param Skin $skin Skin being used. */ - public static function beforePageDisplay( $out, $skin ) { - if ( $out->getUser()->isLoggedIn() ) { - // Load the module for the Notifications flyout - $out->addModules( [ 'ext.echo.init' ] ); - // Load the styles for the Notifications badge - $out->addModuleStyles( [ - 'ext.echo.styles.badge', - 'oojs-ui.styles.icons-alerts' - ] ); + public function onBeforePageDisplay( $out, $skin ): void { + $user = $out->getUser(); + + if ( !$user->isRegistered() ) { + return; } + + if ( self::shouldDisplayTalkAlert( $user, $out->getTitle() ) ) { + // Load the module for the Orange alert + $out->addModuleStyles( 'ext.echo.styles.alert' ); + } + + // Load the module for the Notifications flyout + $out->addModules( [ 'ext.echo.init' ] ); + // Load the styles for the Notifications badge + $out->addModuleStyles( [ + 'ext.echo.styles.badge', + 'oojs-ui.styles.icons-alerts' + ] ); } private static function processMarkAsRead( User $user, WebRequest $request, Title $title ) { @@ -915,9 +966,9 @@ class EchoHooks implements RecentChange_saveHook { } // Attempt to mark as read the event IDs in the ?markasread= parameter, if present - $markAsReadIds = explode( '|', $request->getText( 'markasread' ) ); - $markAsReadWiki = $request->getText( 'markasreadwiki', wfWikiID() ); - $markAsReadLocal = !$wgEchoCrossWikiNotifications || $markAsReadWiki === wfWikiID(); + $markAsReadIds = array_filter( explode( '|', $request->getText( 'markasread' ) ) ); + $markAsReadWiki = $request->getText( 'markasreadwiki', WikiMap::getCurrentWikiId() ); + $markAsReadLocal = !$wgEchoCrossWikiNotifications || $markAsReadWiki === WikiMap::getCurrentWikiId(); if ( $markAsReadIds ) { if ( $markAsReadLocal ) { // gather the IDs that we didn't already find with target_pages @@ -945,22 +996,24 @@ class EchoHooks implements RecentChange_saveHook { $markAsReadIds = array_map( 'intval', $markAsReadIds ); // Look up the notifications on the foreign wiki $notifUser = MWEchoNotifUser::newFromUser( $user ); - $notifInfo = $notifUser->getForeignNotificationInfo( $markAsReadIds, $markAsReadWiki ); + $notifInfo = $notifUser->getForeignNotificationInfo( $markAsReadIds, $markAsReadWiki, $request ); foreach ( $notifInfo as $id => $info ) { $subtractions[$info['section']]++; } // Schedule a deferred update to mark these notifications as read on the foreign wiki - DeferredUpdates::addCallableUpdate( function () use ( $user, $markAsReadIds, $markAsReadWiki ) { - $notifUser = MWEchoNotifUser::newFromUser( $user ); - $notifUser->markReadForeign( $markAsReadIds, $markAsReadWiki ); - } ); + DeferredUpdates::addCallableUpdate( + static function () use ( $user, $markAsReadIds, $markAsReadWiki, $request ) { + $notifUser = MWEchoNotifUser::newFromUser( $user ); + $notifUser->markReadForeign( $markAsReadIds, $markAsReadWiki, $request ); + } + ); } } // Schedule a deferred update to mark local target_page and ?markasread= notifications as read if ( $eventIds ) { - DeferredUpdates::addCallableUpdate( function () use ( $user, $eventIds ) { + DeferredUpdates::addCallableUpdate( static function () use ( $user, $eventIds ) { $notifUser = MWEchoNotifUser::newFromUser( $user ); $notifUser->markRead( $eventIds ); } ); @@ -970,87 +1023,42 @@ class EchoHooks implements RecentChange_saveHook { } /** - * Handler for SkinMinervaReplaceNotificationsBadge hook. - * @param User $user who needs notifications - * @param Title $title of current page - * @param string &$badge to replace + * Determine if a talk page alert should be displayed. + * We need to check: + * - User actually has new messages + * - User is not viewing their user talk page, as user_newtalk will not have been cleared yet. + * (bug T107655). + * + * @param User $user + * @param Title $title + * @return bool */ - public static function onSkinMinervaReplaceNotificationsBadge( $user, $title, &$badge ) { - $notificationsTitle = SpecialPage::getTitleFor( 'Notifications' ); - $count = 0; - $countLabel = ''; - $isZero = true; - $hasUnseen = false; - - if ( $title->equals( $notificationsTitle ) ) { - // On Special:Notifications show no icon - $badge = ''; - return; - } - - // Note: `mw-ui-icon-wikimedia-bellOutline-base20` class is provided by Minerva. - // In future we'll likely want to rethink how this works and possibly consolidate this with the desktop badge. - // For now, we avoid loading two bells in the same place by reusing the class already defined in Minerva. - $notificationIconClass = 'mw-ui-icon mw-ui-icon-wikimedia-bellOutline-base20 mw-ui-icon-element user-button'; - $url = $notificationsTitle->getLocalURL( - [ 'returnto' => $title->getPrefixedText() ] ); - - $notifUser = MWEchoNotifUser::newFromUser( $user ); - $count = $notifUser->getNotificationCount(); - - $echoSeenTime = EchoSeenTime::newFromUser( $user ); - $seenAlertTime = $echoSeenTime->getTime( 'alert', TS_ISO_8601 ); - $seenMsgTime = $echoSeenTime->getTime( 'message', TS_ISO_8601 ); - - $alertNotificationTimestamp = $notifUser->getLastUnreadAlertTime(); - $msgNotificationTimestamp = $notifUser->getLastUnreadMessageTime(); - - $isZero = $count === 0; - $hasUnseen = $count > 0 && - ( - $seenMsgTime !== false && $msgNotificationTimestamp !== false && - $seenMsgTime < $msgNotificationTimestamp->getTimestamp( TS_ISO_8601 ) - ) || - ( - $seenAlertTime !== false && $alertNotificationTimestamp !== false && - $seenAlertTime < $alertNotificationTimestamp->getTimestamp( TS_ISO_8601 ) - ); + private static function shouldDisplayTalkAlert( $user, $title ) { + $userHasNewMessages = MediaWikiServices::getInstance() + ->getTalkPageNotificationManager() + ->userHasNewMessages( $user ); - $countLabel = EchoNotificationController::formatNotificationCount( $count ); - $data = [ - 'notificationIconClass' => $notificationIconClass, - 'title' => $hasUnseen ? - wfMessage( 'echo-overlay-link' ) : - wfMessage( 'echo-none' ), - 'url' => $url, - 'notificationCountRaw' => $count, - 'notificationCountString' => $countLabel, - 'isNotificationCountZero' => $isZero, - 'hasNotifications' => $hasUnseen, - // this variable is used inside the client side which has different handling - // for when notifications have been dismissed. Instead of a bell it shows `(0)`. - 'hasUnseenNotifications' => $hasUnseen, - ]; - $parser = new TemplateParser( __DIR__ . '/../modules/mobile' ); - // substitute the badge - $badge = $parser->processTemplate( 'NotificationBadge', $data ); + return $userHasNewMessages && !$user->getTalkPage()->equals( $title ); } /** - * Handler for PersonalUrls hook. - * Add a "Notifications" item to the user toolbar ('personal URLs'). - * @see https://www.mediawiki.org/wiki/Manual:Hooks/PersonalUrls - * @param array &$personal_urls Array of URLs to append to. - * @param Title &$title Title of page being visited. - * @param SkinTemplate $sk + * Handler for SkinTemplateNavigation::Universal hook. + * Adds "Notifications" items to the notifications content navigation. + * SkinTemplate automatically merges these into the personal tools for older skins. + * @see https://www.mediawiki.org/wiki/Manual:Hooks/SkinTemplateNavigation::Universal + * @param SkinTemplate $skinTemplate + * @param array &$links Array of URLs to append to. */ - public static function onPersonalUrls( &$personal_urls, &$title, $sk ) { - $user = $sk->getUser(); - if ( $user->isAnon() ) { + public function onSkinTemplateNavigation__Universal( $skinTemplate, &$links ): void { + $user = $skinTemplate->getUser(); + if ( !$user->isRegistered() ) { return; } - $subtractions = self::processMarkAsRead( $user, $sk->getOutput()->getRequest(), $title ); + $title = $skinTemplate->getTitle(); + $out = $skinTemplate->getOutput(); + + $subtractions = self::processMarkAsRead( $user, $out->getRequest(), $title ); // Add a "My notifications" item to personal URLs $notifUser = MWEchoNotifUser::newFromUser( $user ); @@ -1071,7 +1079,7 @@ class EchoHooks implements RecentChange_saveHook { $seenAlertTime = $seenTime->getTime( 'alert', TS_ISO_8601 ); $seenMsgTime = $seenTime->getTime( 'message', TS_ISO_8601 ); - $sk->getOutput()->addJsConfigVars( 'wgEchoSeenTime', [ + $out->addJsConfigVars( 'wgEchoSeenTime', [ 'alert' => $seenAlertTime, 'notice' => $seenMsgTime, ] ); @@ -1079,19 +1087,17 @@ class EchoHooks implements RecentChange_saveHook { $msgFormattedCount = EchoNotificationController::formatNotificationCount( $msgCount ); $alertFormattedCount = EchoNotificationController::formatNotificationCount( $alertCount ); - $msgText = wfMessage( 'echo-notification-notice', $msgCount ); - $alertText = wfMessage( 'echo-notification-alert', $alertCount ); - $url = SpecialPage::getTitleFor( 'Notifications' )->getLocalURL(); + $skinName = strtolower( $skinTemplate->getSkinName() ); + $isMinervaSkin = $skinName === 'minerva'; // HACK: inverted icons only work in the "MediaWiki" OOUI theme // Avoid flashes in skins that don't use it (T111821) - $sk->getOutput()->setupOOUI( - strtolower( $sk->getSkinName() ), $sk->getOutput()->getLanguage()->getDir() ); - - $msgLinkClasses = [ "mw-echo-notifications-badge", "mw-echo-notification-badge-nojs","oo-ui-iconElement-icon","oo-ui-icon-tray", "oo-ui-image-invert" ]; - $alertLinkClasses = [ "mw-echo-notifications-badge", "mw-echo-notification-badge-nojs","oo-ui-iconElement-icon", "oo-ui-icon-bell", "oo-ui-image-invert" ]; + $out::setupOOUI( $skinName, $out->getLanguage()->getDir() ); + $bellIconClass = $isMinervaSkin ? 'oo-ui-icon-bellOutline' : 'oo-ui-icon-bell'; + $msgLinkClasses = [ "mw-echo-notifications-badge", "mw-echo-notification-badge-nojs", "oo-ui-iconElement-icon", "oo-ui-icon-tray", "oo-ui-image-invert" ]; + $alertLinkClasses = [ "mw-echo-notifications-badge", "mw-echo-notification-badge-nojs", "oo-ui-iconElement-icon", $bellIconClass, "oo-ui-image-invert" ]; $hasUnseen = false; if ( $msgCount != 0 && // no unread notifications @@ -1127,57 +1133,77 @@ class EchoHooks implements RecentChange_saveHook { $alertLinkClasses[] = 'mw-echo-notifications-badge-long-label'; } - $alertLink = [ + $mytalk = $links['user-menu']['mytalk'] ?? false; + if ( + $mytalk && + self::shouldDisplayTalkAlert( $user, $title ) && + MediaWikiServices::getInstance() + ->getHookContainer()->run( 'BeforeDisplayOrangeAlert', [ $user, $title ] ) + ) { + // Create new talk alert inheriting from the talk link data. + $links['notifications']['talk-alert'] = array_merge( + $links['user-menu']['mytalk'], + [ + // Hardcode id, which is needed to dismiss the talk alert notification + 'id' => 'pt-talk-alert', + // If Vector hook ran anicon will have been copied to the link class. + // We must reset it. + 'link-class' => [], + 'text' => $skinTemplate->msg( 'echo-new-messages' )->text(), + 'class' => [ 'mw-echo-alert' ], + // unset icon + 'icon' => '', + ] + ); + + // If there's exactly one new user talk message, then link directly to it from the alert. + $notificationMapper = new EchoNotificationMapper(); + $notifications = $notificationMapper->fetchUnreadByUser( $user, 2, null, [ 'edit-user-talk' ] ); + if ( count( $notifications ) === 1 ) { + $presModel = EchoEventPresentationModel::factory( + current( $notifications )->getEvent(), + $out->getLanguage(), + $user + ); + $links['notifications']['talk-alert']['href'] = $presModel->getPrimaryLink()['url']; + } + } + + $links['notifications']['notifications-alert'] = [ 'href' => $url, - 'text' => $alertText, + 'text' => $skinTemplate->msg( 'echo-notification-alert', $alertCount )->text(), 'active' => ( $url == $title->getLocalURL() ), - 'class' => $alertLinkClasses, + 'link-class' => $alertLinkClasses, + 'icon' => 'bell', 'data' => [ + 'event-name' => 'ui.notifications', 'counter-num' => $alertCount, 'counter-text' => $alertFormattedCount, ], + // This item used to be part of personal tools, and much CSS relies on it using this id. + 'id' => 'pt-notifications-alert', ]; - $insertUrls = [ - 'notifications-alert' => $alertLink, - ]; - - $msgLink = [ + $links['notifications']['notifications-notice'] = [ 'href' => $url, - 'text' => $msgText, + 'text' => $skinTemplate->msg( 'echo-notification-notice', $msgCount )->text(), 'active' => ( $url == $title->getLocalURL() ), - 'class' => $msgLinkClasses, + 'link-class' => $msgLinkClasses, + 'icon' => 'tray', 'data' => [ 'counter-num' => $msgCount, 'counter-text' => $msgFormattedCount, ], + // This item used to be part of personal tools, and much CSS relies on it using this id. + 'id' => 'pt-notifications-notice', ]; - $insertUrls['notifications-notice'] = $msgLink; - - $personal_urls = wfArrayInsertAfter( $personal_urls, $insertUrls, 'userpage' ); - if ( $hasUnseen ) { // Record that the user is going to see an indicator that they have unseen notifications // This is part of tracking how likely users are to click a badge with unseen notifications. // The other part is the 'echo.unseen.click' counter, see ext.echo.init.js. MediaWikiServices::getInstance()->getStatsdDataFactory()->increment( 'echo.unseen' ); } - - // If the user has new messages, display a talk page alert - // We need to check: - // * User actually has new messages - // * User is not viewing their user talk page, as user_newtalk - // will not have been cleared yet. (bug T107655). - $userHasNewMessages = MediaWikiServices::getInstance() - ->getTalkPageNotificationManager()->userHasNewMessages( $user ); - if ( $userHasNewMessages && !$user->getTalkPage()->equals( $title ) ) { - if ( Hooks::run( 'BeforeDisplayOrangeAlert', [ $user, $title ] ) ) { - $personal_urls['mytalk']['text'] = $sk->msg( 'echo-new-messages' )->text(); - $personal_urls['mytalk']['class'] = [ 'mw-echo-alert' ]; - $sk->getOutput()->addModuleStyles( 'ext.echo.styles.alert' ); - } - } } /** @@ -1187,7 +1213,7 @@ class EchoHooks implements RecentChange_saveHook { * @param Title $title * @return bool */ - public static function onAbortTalkPageEmailNotification( $targetUser, $title ) { + public function onAbortTalkPageEmailNotification( $targetUser, $title ) { global $wgEchoNotifications; // Send legacy talk page email notification if @@ -1210,7 +1236,7 @@ class EchoHooks implements RecentChange_saveHook { * @param EmailNotification $emailNotification The email notification object that sends non-echo notifications * @return bool */ - public static function onSendWatchlistEmailNotification( $targetUser, $title, $emailNotification ) { + public function onSendWatchlistEmailNotification( $targetUser, $title, $emailNotification ) { global $wgEchoNotifications, $wgEchoWatchlistNotifications; if ( $wgEchoWatchlistNotifications && isset( $wgEchoNotifications["watchlist-change"] ) ) { // Let echo handle watchlist notifications entirely @@ -1219,7 +1245,7 @@ class EchoHooks implements RecentChange_saveHook { // If a user is watching his/her own talk page, do not send talk page watchlist // email notification if the user is receiving Echo talk page notification if ( $title->isTalkPage() && $targetUser->getTalkPage()->equals( $title ) ) { - $attributeManager = EchoAttributeManager::newFromGlobalVars(); + $attributeManager = EchoServices::getInstance()->getAttributeManager(); $events = $attributeManager->getUserEnabledEvents( $targetUser, 'email' ); if ( in_array( 'edit-user-talk', $events ) ) { // Do not send watchlist email notification, the user will receive an Echo notification @@ -1231,9 +1257,19 @@ class EchoHooks implements RecentChange_saveHook { return true; } - public static function onOutputPageCheckLastModified( array &$modifiedTimes, OutputPage $out ) { + /** + * @param array &$modifiedTimes + * @param OutputPage $out + */ + public function onOutputPageCheckLastModified( &$modifiedTimes, $out ) { + $req = $out->getRequest(); + if ( $req->getRawVal( 'action' ) === 'raw' || $req->getRawVal( 'action' ) === 'render' ) { + // Optimisation: Avoid expensive EchoSeenTime compute on non-skin responses (T279213) + return; + } + $user = $out->getUser(); - if ( $user->isLoggedIn() ) { + if ( $user->isRegistered() ) { $notifUser = MWEchoNotifUser::newFromUser( $user ); $lastUpdate = $notifUser->getGlobalUpdateTime(); if ( $lastUpdate !== false ) { @@ -1260,14 +1296,14 @@ class EchoHooks implements RecentChange_saveHook { * @return bool Should return false to prevent the new messages alert (OBOD) * or true to allow the new messages alert */ - public static function abortNewMessagesAlert( &$newMessagesAlert, $newtalks, $user, $out ) { + public function onGetNewMessagesAlert( &$newMessagesAlert, $newtalks, $user, $out ) { global $wgEchoNotifications; // If the user has the notifications flyout turned on and is receiving // notifications for talk page messages, disable the new messages alert. - if ( $user->isLoggedIn() + if ( $user->isRegistered() && isset( $wgEchoNotifications['edit-user-talk'] ) - && Hooks::run( 'EchoCanAbortNewMessagesAlert' ) + && MWHooks::run( 'EchoCanAbortNewMessagesAlert' ) ) { // hide new messages alert return false; @@ -1286,18 +1322,18 @@ class EchoHooks implements RecentChange_saveHook { * @param RevisionRecord $newRevision The revision the page was reverted back to * @param RevisionRecord $oldRevision The revision of the top edit that was reverted */ - public static function onRollbackComplete( - WikiPage $wikiPage, - UserIdentity $agent, - RevisionRecord $newRevision, - RevisionRecord $oldRevision + public function onRollbackComplete( + $wikiPage, + $agent, + $newRevision, + $oldRevision ) { - $victimId = $oldRevision->getUser(); + $revertedUser = $oldRevision->getUser(); $latestRevision = $wikiPage->getRevisionRecord(); - self::$lastRevertedRevision = $latestRevision; if ( - $victimId && // No notifications for anonymous users + $revertedUser && + $revertedUser->getId() && // No notifications for anonymous users !$oldRevision->hasSameContent( $newRevision ) // No notifications for null rollbacks ) { EchoEvent::create( [ @@ -1305,11 +1341,11 @@ class EchoHooks implements RecentChange_saveHook { 'title' => $wikiPage->getTitle(), 'extra' => [ 'revid' => $latestRevision->getId(), - 'reverted-user-id' => $victimId, + 'reverted-user-id' => $revertedUser->getId(), 'reverted-revision-id' => $oldRevision->getId(), 'method' => 'rollback', ], - 'agent' => User::newFromIdentity( $agent ), + 'agent' => $agent, ] ); } } @@ -1319,66 +1355,64 @@ class EchoHooks implements RecentChange_saveHook { * @see https://www.mediawiki.org/wiki/Manual:Hooks/UserSaveSettings * @param User $user whose settings were saved */ - public static function onUserSaveSettings( $user ) { + public function onUserSaveSettings( $user ) { // Extensions like AbuseFilter might create an account, but // the tables we need might not exist. Bug 57335 if ( !defined( 'MW_UPDATER' ) ) { // Reset the notification count since it may have changed due to user // option changes. This covers both explicit changes in the preferences // and changes made through the options API (since both call this hook). - DeferredUpdates::addCallableUpdate( function () use ( $user ) { + DeferredUpdates::addCallableUpdate( static function () use ( $user ) { MWEchoNotifUser::newFromUser( $user )->resetNotificationCount(); } ); } } /** - * Handler for UserLoadOptions hook. - * @see https://www.mediawiki.org/wiki/Manual:Hooks/UserLoadOptions - * @param User $user User whose options were loaded - * @param array &$options Options can be modified + * Some of Echo's subscription user preferences are mapped to existing user preferences defined in + * core MediaWiki. This returns the map of Echo preference names to core preference names. + * + * @return array */ - public static function onUserLoadOptions( $user, &$options ) { + public static function getVirtualUserOptions() { global $wgEchoWatchlistNotifications; - // Use existing enotifusertalkpages option for echo-subscriptions-email-edit-user-talk - if ( isset( $options['enotifusertalkpages'] ) ) { - $options['echo-subscriptions-email-edit-user-talk'] = $options['enotifusertalkpages']; - } - + $options = []; + $options['echo-subscriptions-email-edit-user-talk'] = 'enotifusertalkpages'; if ( $wgEchoWatchlistNotifications ) { - // Use existing enotifwatchlistpages option for echo-subscriptions-email-watchlist - if ( isset( $options['enotifwatchlistpages'] ) ) { - $options['echo-subscriptions-email-watchlist'] = $options['enotifwatchlistpages']; - } - - // Use existing enotifminoredits option for echo-subscriptions-email-minor-watchlist - if ( isset( $options['enotifminoredits'] ) ) { - $options['echo-subscriptions-email-minor-watchlist'] = $options['enotifminoredits']; - } + $options['echo-subscriptions-email-watchlist'] = 'enotifwatchlistpages'; + $options['echo-subscriptions-email-minor-watchlist'] = 'enotifminoredits'; } + return $options; } /** - * Handler for UserSaveOptions hook. - * @see https://www.mediawiki.org/wiki/Manual:Hooks/UserSaveOptions - * @param User $user User whose options are being saved + * Handler for LoadUserOptions hook. + * @see https://www.mediawiki.org/wiki/Manual:Hooks/LoadUserOptions + * @param UserIdentity $user User whose options were loaded * @param array &$options Options can be modified */ - public static function onUserSaveOptions( $user, &$options ) { - global $wgEchoWatchlistNotifications; - // save virtual option values in corresponding real option values - if ( isset( $options['echo-subscriptions-email-edit-user-talk'] ) ) { - $options['enotifusertalkpages'] = $options['echo-subscriptions-email-edit-user-talk']; - unset( $options['echo-subscriptions-email-edit-user-talk'] ); - } - if ( $wgEchoWatchlistNotifications ) { - if ( isset( $options['echo-subscriptions-email-watchlist'] ) ) { - $options['enotifwatchlistpages'] = $options['echo-subscriptions-email-watchlist']; - unset( $options['echo-subscriptions-email-watchlist'] ); + public function onLoadUserOptions( UserIdentity $user, &$options ): void { + foreach ( self::getVirtualUserOptions() as $echoPref => $mwPref ) { + // Use the existing core option's value for the Echo option + if ( isset( $options[ $mwPref ] ) ) { + $options[ $echoPref ] = $options[ $mwPref ]; } - if ( isset( $options['echo-subscriptions-email-minor-watchlist'] ) ) { - $options['enotifminoredits'] = $options['echo-subscriptions-email-minor-watchlist']; - unset( $options['echo-subscriptions-email-minor-watchlist'] ); + } + } + + /** + * Handler for SaveUserOptions hook. + * @see https://www.mediawiki.org/wiki/Manual:Hooks/SaveUserOptions + * @param UserIdentity $user User whose options are being saved + * @param array &$modifiedOptions Options can be modified + * @param array $originalOptions + */ + public function onSaveUserOptions( UserIdentity $user, array &$modifiedOptions, array $originalOptions ) { + foreach ( self::getVirtualUserOptions() as $echoPref => $mwPref ) { + // Save virtual option values in corresponding real option values + if ( isset( $modifiedOptions[ $echoPref ] ) ) { + $modifiedOptions[ $mwPref ] = $modifiedOptions[ $echoPref ]; + unset( $modifiedOptions[ $echoPref ] ); } } } @@ -1408,28 +1442,17 @@ class EchoHooks implements RecentChange_saveHook { * Handler for UserClearNewTalkNotification hook. * @see https://www.mediawiki.org/wiki/Manual:Hooks/UserClearNewTalkNotification * @param UserIdentity $user User whose talk page notification should be marked as read + * @param int $oldid */ - public static function onUserClearNewTalkNotification( UserIdentity $user ) { + public function onUserClearNewTalkNotification( $user, $oldid ) { if ( $user->isRegistered() ) { - $userObj = User::newFromIdentity( $user ); - DeferredUpdates::addCallableUpdate( function () use ( $userObj ) { - MWEchoNotifUser::newFromUser( $userObj )->clearUserTalkNotifications(); + DeferredUpdates::addCallableUpdate( static function () use ( $user ) { + MWEchoNotifUser::newFromUser( $user )->clearUserTalkNotifications(); } ); } } /** - * Handler for ParserTestTables hook, makes sure that Echo's tables are present during tests - * @see https://www.mediawiki.org/wiki/Manual:Hooks/ParserTestTables - * @param array &$tables List of DB tables to be used for parser tests - */ - public static function onParserTestTables( &$tables ) { - $tables[] = 'echo_event'; - $tables[] = 'echo_notification'; - $tables[] = 'echo_email_batch'; - } - - /** * Handler for EmailUserComplete hook. * @see https://www.mediawiki.org/wiki/Manual:Hooks/EmailUserComplete * @param MailAddress $address Adress of receiving user @@ -1437,7 +1460,7 @@ class EchoHooks implements RecentChange_saveHook { * @param string $subject Subject of the mail * @param string $text Text of the mail */ - public static function onEmailUserComplete( $address, $from, $subject, $text ) { + public function onEmailUserComplete( $address, $from, $subject, $text ) { if ( $from->name === $address->name ) { // nothing to notify return; @@ -1473,7 +1496,7 @@ class EchoHooks implements RecentChange_saveHook { */ public static function onUserMergeAccountFields( &$updateFields ) { // array( tableName, idField, textField ) - $dbw = MWEchoDbFactory::newFromDefault()->getEchoDb( DB_MASTER ); + $dbw = MWEchoDbFactory::newFromDefault()->getEchoDb( DB_PRIMARY ); $updateFields[] = [ 'echo_event', 'event_agent_id', 'db' => $dbw ]; $updateFields[] = [ 'echo_notification', 'notification_user', 'db' => $dbw, 'options' => [ 'IGNORE' ] ]; $updateFields[] = [ 'echo_email_batch', 'eeb_user_id', 'db' => $dbw, 'options' => [ 'IGNORE' ] ]; @@ -1481,11 +1504,11 @@ class EchoHooks implements RecentChange_saveHook { public static function onMergeAccountFromTo( User &$oldUser, User &$newUser ) { $method = __METHOD__; - DeferredUpdates::addCallableUpdate( function () use ( $oldUser, $newUser, $method ) { - if ( !$newUser->isAnon() ) { + DeferredUpdates::addCallableUpdate( static function () use ( $oldUser, $newUser, $method ) { + if ( $newUser->isRegistered() ) { // Select notifications that are now sent to the same user - $dbw = MWEchoDbFactory::newFromDefault()->getEchoDb( DB_MASTER ); - $attributeManager = EchoAttributeManager::newFromGlobalVars(); + $dbw = MWEchoDbFactory::newFromDefault()->getEchoDb( DB_PRIMARY ); + $attributeManager = EchoServices::getInstance()->getAttributeManager(); $selfIds = $dbw->selectFieldValues( [ 'echo_notification', 'echo_event' ], 'event_id', @@ -1542,7 +1565,6 @@ class EchoHooks implements RecentChange_saveHook { // Delete notifications $ids = array_merge( $selfIds, $welcomeIds, $thankYouIds ); - // @phan-suppress-next-line PhanImpossibleTypeComparison Each array in the merge may be empty if ( $ids !== [] ) { $dbw->delete( 'echo_notification', @@ -1556,14 +1578,14 @@ class EchoHooks implements RecentChange_saveHook { } MWEchoNotifUser::newFromUser( $oldUser )->resetNotificationCount(); - if ( !$newUser->isAnon() ) { + if ( $newUser->isRegistered() ) { MWEchoNotifUser::newFromUser( $newUser )->resetNotificationCount(); } } ); } public static function onUserMergeAccountDeleteTables( &$tables ) { - $dbw = MWEchoDbFactory::newFromDefault()->getEchoDb( DB_MASTER ); + $dbw = MWEchoDbFactory::newFromDefault()->getEchoDb( DB_PRIMARY ); $tables['echo_notification'] = [ 'notification_user', 'db' => $dbw ]; $tables['echo_email_batch'] = [ 'eeb_user_id', 'db' => $dbw ]; } @@ -1573,18 +1595,18 @@ class EchoHooks implements RecentChange_saveHook { * * @param array &$messages */ - public static function onLoginFormValidErrorMessages( &$messages ) { + public function onLoginFormValidErrorMessages( array &$messages ) { $messages[] = 'echo-notification-loginrequired'; } - public static function getConfigVars( ResourceLoaderContext $context, Config $config ) { + public static function getConfigVars( RL\Context $context, Config $config ) { return [ 'EchoMaxNotificationCount' => MWEchoNotifUser::MAX_BADGE_COUNT, 'EchoPollForUpdates' => $config->get( 'EchoPollForUpdates' ) ]; } - public static function getLoggerConfigVars( ResourceLoaderContext $context, Config $config ) { + public static function getLoggerConfigVars( RL\Context $context, Config $config ) { $schemas = $config->get( 'EchoEventLoggingSchemas' ); return [ 'EchoInteractionLogging' => $schemas['EchoInteraction']['enabled'] && @@ -1594,31 +1616,40 @@ class EchoHooks implements RecentChange_saveHook { } /** - * @param WikiPage &$article - * @param User &$user + * @param WikiPage $article + * @param User $user * @param string $reason * @param int $articleId * @param Content|null $content * @param LogEntry $logEntry + * @param int $archivedRevisionCount */ - public static function onArticleDeleteComplete( - WikiPage &$article, - User &$user, + public function onArticleDeleteComplete( + $article, + $user, $reason, $articleId, - ?Content $content, - LogEntry $logEntry + $content, + $logEntry, + $archivedRevisionCount ) { - \DeferredUpdates::addCallableUpdate( function () use ( $articleId ) { + DeferredUpdates::addCallableUpdate( static function () use ( $articleId ) { $eventMapper = new EchoEventMapper(); $eventIds = $eventMapper->fetchIdsByPage( $articleId ); EchoModerationController::moderate( $eventIds, true ); } ); } - public static function onArticleUndelete( Title $title, $create, $comment, $oldPageId ) { + /** + * @param Title $title + * @param bool $create + * @param string $comment + * @param int $oldPageId + * @param array $restoredPages + */ + public function onArticleUndelete( $title, $create, $comment, $oldPageId, $restoredPages ) { if ( $create ) { - \DeferredUpdates::addCallableUpdate( function () use ( $oldPageId ) { + DeferredUpdates::addCallableUpdate( static function () use ( $oldPageId ) { $eventMapper = new EchoEventMapper(); $eventIds = $eventMapper->fetchIdsByPage( $oldPageId ); EchoModerationController::moderate( $eventIds, false ); @@ -1629,20 +1660,25 @@ class EchoHooks implements RecentChange_saveHook { /** * Handler for SpecialMuteModifyFormFields hook * - * @param SpecialMute $specialMute + * @param UserIdentity|null $target + * @param User $user * @param array &$fields */ - public static function onSpecialMuteModifyFormFields( SpecialMute $specialMute, &$fields ) { - $echoPerUserBlacklist = MediaWikiServices::getInstance()->getMainConfig()->get( 'EchoPerUserBlacklist' ); + public static function onSpecialMuteModifyFormFields( $target, $user, &$fields ) { + $services = MediaWikiServices::getInstance(); + $echoPerUserBlacklist = $services->getMainConfig()->get( 'EchoPerUserBlacklist' ); if ( $echoPerUserBlacklist ) { - $target = $specialMute->getTarget(); + $id = $target ? $services->getCentralIdLookup()->centralIdFromLocalUser( $target ) : 0; + $list = MultiUsernameFilter::splitIds( + $services->getUserOptionsLookup()->getOption( $user, 'echo-notifications-blacklist' ) + ); $fields[ 'echo-notifications-blacklist'] = [ 'type' => 'check', 'label-message' => [ 'echo-specialmute-label-mute-notifications', $target ? $target->getName() : '' ], - 'default' => $specialMute->isTargetBlacklisted( 'echo-notifications-blacklist' ), + 'default' => in_array( $id, $list, true ), ]; } } @@ -1665,12 +1701,15 @@ class EchoHooks implements RecentChange_saveHook { 'type' => $type, 'title' => $change->getTitle(), 'extra' => [ + 'page_title' => $change->getPage()->getDBkey(), + 'page_namespace' => $change->getPage()->getNamespace(), 'revid' => $change->getAttribute( "rc_this_oldid" ), 'logid' => $change->getAttribute( "rc_logid" ), 'status' => $change->mExtra["pageStatus"], - 'timestamp' => $change->getAttribute( "rc_timestamp" ) + 'timestamp' => $change->getAttribute( "rc_timestamp" ), + 'emailonce' => $this->config->get( 'EchoWatchlistEmailOncePerPage' ) ], - 'agent' => $change->getPerformer() + 'agent' => $change->getPerformerIdentity(), ] ); } @@ -1681,7 +1720,7 @@ class EchoHooks implements RecentChange_saveHook { * anymore. * @param ApiModuleManager $moduleManager */ - public static function onApiMainModuleManager( ApiModuleManager $moduleManager ) { + public function onApiMain__ModuleManager( $moduleManager ) { $services = MediaWikiServices::getInstance(); $echoConfig = $services->getConfigFactory()->makeConfig( 'Echo' ); $pushEnabled = $echoConfig->get( 'EchoEnablePush' ); @@ -1689,7 +1728,7 @@ class EchoHooks implements RecentChange_saveHook { $moduleManager->addModule( 'echopushsubscriptions', 'action', - 'EchoPush\\Api\\ApiEchoPushSubscriptions' + ApiEchoPushSubscriptions::class ); } } diff --git a/Echo/includes/NotifUser.php b/Echo/includes/NotifUser.php index 8f965cd5..5f8d0018 100644 --- a/Echo/includes/NotifUser.php +++ b/Echo/includes/NotifUser.php @@ -1,6 +1,9 @@ <?php use MediaWiki\MediaWikiServices; +use MediaWiki\User\UserFactory; +use MediaWiki\User\UserIdentity; +use MediaWiki\User\UserOptionsLookup; use Wikimedia\Rdbms\Database; /** @@ -10,7 +13,7 @@ class MWEchoNotifUser { /** * Notification target user - * @var User + * @var UserIdentity */ private $mUser; @@ -54,9 +57,19 @@ class MWEchoNotifUser { private $globalCountsAndTimestamps; /** - * @var array[]|null + * @var UserOptionsLookup + */ + private $userOptionsLookup; + + /** + * @var UserFactory + */ + private $userFactory; + + /** + * @var ReadOnlyMode */ - private $mForeignData; + private $readOnlyMode; // The max notification count shown in badge @@ -65,56 +78,68 @@ class MWEchoNotifUser { // WARNING: If you change this, you should also change all references in the // i18n messages (100 and 99) in all repositories using Echo. - const MAX_BADGE_COUNT = 99; + public const MAX_BADGE_COUNT = 99; - const CACHE_TTL = 86400; - const CACHE_KEY = 'echo-notification-counts'; - const CHECK_KEY = 'echo-notification-updated'; + private const CACHE_TTL = 86400; + private const CACHE_KEY = 'echo-notification-counts'; + private const CHECK_KEY = 'echo-notification-updated'; /** * Usually client code doesn't need to initialize the object directly * because it could be obtained from factory method newFromUser() - * @param User $user + * @param UserIdentity $user * @param WANObjectCache $cache * @param EchoUserNotificationGateway $userNotifGateway * @param EchoNotificationMapper $notifMapper * @param EchoTargetPageMapper $targetPageMapper + * @param UserOptionsLookup $userOptionsLookup + * @param UserFactory $userFactory + * @param ReadOnlyMode $readOnlyMode */ public function __construct( - User $user, + UserIdentity $user, WANObjectCache $cache, EchoUserNotificationGateway $userNotifGateway, EchoNotificationMapper $notifMapper, - EchoTargetPageMapper $targetPageMapper + EchoTargetPageMapper $targetPageMapper, + UserOptionsLookup $userOptionsLookup, + UserFactory $userFactory, + ReadOnlyMode $readOnlyMode ) { $this->mUser = $user; $this->userNotifGateway = $userNotifGateway; $this->cache = $cache; $this->notifMapper = $notifMapper; $this->targetPageMapper = $targetPageMapper; + $this->userOptionsLookup = $userOptionsLookup; + $this->userFactory = $userFactory; + $this->readOnlyMode = $readOnlyMode; } /** * Factory method - * @param User $user + * @param UserIdentity $user * @throws MWException * @return MWEchoNotifUser */ - public static function newFromUser( User $user ) { - if ( $user->isAnon() ) { + public static function newFromUser( UserIdentity $user ) { + if ( !$user->isRegistered() ) { throw new MWException( 'User must be logged in to view notification!' ); } - + $services = MediaWikiServices::getInstance(); return new MWEchoNotifUser( $user, - MediaWikiServices::getInstance()->getMainWANObjectCache(), + $services->getMainWANObjectCache(), new EchoUserNotificationGateway( $user, MWEchoDbFactory::newFromDefault(), - MediaWikiServices::getInstance()->getMainConfig() + $services->getMainConfig() ), new EchoNotificationMapper(), - new EchoTargetPageMapper() + new EchoTargetPageMapper(), + $services->getUserOptionsLookup(), + $services->getUserFactory(), + $services->getReadOnlyMode() ); } @@ -170,7 +195,7 @@ class MWEchoNotifUser { * @return int */ public function getNotificationCount( $section = EchoAttributeManager::ALL, $global = 'preference' ) { - if ( $this->mUser->isAnon() ) { + if ( !$this->mUser->isRegistered() ) { return 0; } @@ -185,6 +210,10 @@ class MWEchoNotifUser { } $data = $this->getCountsAndTimestamps( $global ); + if ( $global && $data['global'] === null ) { + // No global user exists, no data. Use only local count + $global = false; + } $count = $data[$global ? 'global' : 'local'][$section]['count']; return (int)$count; } @@ -218,7 +247,7 @@ class MWEchoNotifUser { * @return bool|MWTimestamp Timestamp of latest unread message, or false if there are no unread messages. */ public function getLastUnreadNotificationTime( $section = EchoAttributeManager::ALL, $global = 'preference' ) { - if ( $this->mUser->isAnon() ) { + if ( !$this->mUser->isRegistered() ) { return false; } @@ -233,6 +262,10 @@ class MWEchoNotifUser { } $data = $this->getCountsAndTimestamps( $global ); + if ( $global && $data['global'] === null ) { + // No global user exists, no data. Use only local count + $global = false; + } $timestamp = $data[$global ? 'global' : 'local'][$section]['timestamp']; return $timestamp === -1 ? false : new MWTimestamp( $timestamp ); } @@ -245,7 +278,7 @@ class MWEchoNotifUser { */ public function markRead( $eventIds ) { $eventIds = array_filter( (array)$eventIds, 'is_numeric' ); - if ( !$eventIds || wfReadOnly() ) { + if ( !$eventIds || $this->readOnlyMode->isReadOnly() ) { return false; } @@ -259,7 +292,7 @@ class MWEchoNotifUser { $talkPageNotificationManager = MediaWikiServices::getInstance() ->getTalkPageNotificationManager(); if ( $talkPageNotificationManager->userHasNewMessages( $this->mUser ) ) { - $attributeManager = EchoAttributeManager::newFromGlobalVars(); + $attributeManager = EchoServices::getInstance()->getAttributeManager(); $categoryMap = $attributeManager->getEventsByCategory(); $usertalkTypes = $categoryMap['edit-user-talk']; $unreadEditUserTalk = $this->notifMapper->fetchUnreadByUser( @@ -268,7 +301,7 @@ class MWEchoNotifUser { null, $usertalkTypes, null, - DB_MASTER + DB_PRIMARY ); if ( $unreadEditUserTalk === [] ) { $talkPageNotificationManager->removeUserHasNewMessages( $this->mUser ); @@ -287,7 +320,7 @@ class MWEchoNotifUser { */ public function markUnRead( $eventIds ) { $eventIds = array_filter( (array)$eventIds, 'is_numeric' ); - if ( !$eventIds || wfReadOnly() ) { + if ( !$eventIds || $this->readOnlyMode->isReadOnly() ) { return false; } @@ -301,7 +334,7 @@ class MWEchoNotifUser { $talkPageNotificationManager = MediaWikiServices::getInstance() ->getTalkPageNotificationManager(); if ( !$talkPageNotificationManager->userHasNewMessages( $this->mUser ) ) { - $attributeManager = EchoAttributeManager::newFromGlobalVars(); + $attributeManager = EchoServices::getInstance()->getAttributeManager(); $categoryMap = $attributeManager->getEventsByCategory(); $usertalkTypes = $categoryMap['edit-user-talk']; $unreadEditUserTalk = $this->notifMapper->fetchUnreadByUser( @@ -310,7 +343,7 @@ class MWEchoNotifUser { null, $usertalkTypes, null, - DB_MASTER + DB_PRIMARY ); if ( $unreadEditUserTalk !== [] ) { $talkPageNotificationManager->setUserHasNewMessages( $this->mUser ); @@ -332,7 +365,7 @@ class MWEchoNotifUser { * @return bool */ public function markAllRead( array $sections = [ EchoAttributeManager::ALL ] ) { - if ( wfReadOnly() ) { + if ( $this->readOnlyMode->isReadOnly() ) { return false; } @@ -343,13 +376,13 @@ class MWEchoNotifUser { $sections = EchoAttributeManager::$sections; } - $attributeManager = EchoAttributeManager::newFromGlobalVars(); - $eventTypes = $attributeManager->getUserEnabledEventsbySections( $this->mUser, 'web', $sections ); + $attributeManager = EchoServices::getInstance()->getAttributeManager(); + $eventTypes = $attributeManager->getUserEnabledEventsBySections( $this->mUser, 'web', $sections ); $notifs = $this->notifMapper->fetchUnreadByUser( $this->mUser, $wgEchoMaxUpdateCount, null, $eventTypes ); $eventIds = array_filter( - array_map( function ( EchoNotification $notif ) { + array_map( static function ( EchoNotification $notif ) { // This should not happen at all, but use 0 in // such case so to keep the code running if ( $notif->getEvent() ) { @@ -376,10 +409,11 @@ class MWEchoNotifUser { * * @param int[] $eventIds Event IDs to mark as read * @param string $wiki Wiki name + * @param WebRequest|null $originalRequest Original request data to be sent with these requests */ - public function markReadForeign( array $eventIds, $wiki ) { + public function markReadForeign( array $eventIds, $wiki, ?WebRequest $originalRequest = null ) { $foreignReq = new EchoForeignWikiRequest( - $this->mUser, + $this->userFactory->newFromUserIdentity( $this->mUser ), [ 'action' => 'echomarkread', 'list' => implode( '|', $eventIds ), @@ -388,7 +422,7 @@ class MWEchoNotifUser { 'wikis', 'csrf' ); - $foreignReq->execute(); + $foreignReq->execute( $originalRequest ); } /** @@ -396,11 +430,12 @@ class MWEchoNotifUser { * * @param int[] $eventIds Event IDs to look up. Only unread notifications can be found. * @param string $wiki Wiki name + * @param WebRequest|null $originalRequest Original request data to be sent with these requests * @return array[] Array of notification data as returned by api.php, keyed by event ID */ - public function getForeignNotificationInfo( array $eventIds, $wiki ) { + public function getForeignNotificationInfo( array $eventIds, $wiki, ?WebRequest $originalRequest = null ) { $foreignReq = new EchoForeignWikiRequest( - $this->mUser, + $this->userFactory->newFromUserIdentity( $this->mUser ), [ 'action' => 'query', 'meta' => 'notifications', @@ -411,7 +446,7 @@ class MWEchoNotifUser { [ $wiki ], 'notwikis' ); - $foreignResults = $foreignReq->execute(); + $foreignResults = $foreignReq->execute( $originalRequest ); $list = $foreignResults[$wiki]['query']['notifications']['list'] ?? []; $result = []; @@ -429,7 +464,7 @@ class MWEchoNotifUser { * This updates the user's touched timestamp, as well as the value returned by getGlobalUpdateTime(). * * NOTE: Consider calling this function from a deferred update, since it will read from and write to - * the master DB if cross-wiki notifications are enabled. + * the primary DB if cross-wiki notifications are enabled. */ public function resetNotificationCount() { global $wgEchoCrossWikiNotifications; @@ -439,7 +474,7 @@ class MWEchoNotifUser { $this->cache->delete( $localMemcKey ); // Update the user touched timestamp for the local user - $this->mUser->invalidateCache(); + $this->userFactory->newFromUserIdentity( $this->mUser )->invalidateCache(); if ( $wgEchoCrossWikiNotifications ) { // Delete cached global counts and timestamps @@ -451,12 +486,12 @@ class MWEchoNotifUser { $uw = EchoUnreadWikis::newFromUser( $this->mUser ); if ( $uw ) { // Immediately compute new local counts and timestamps - $newLocalData = $this->computeLocalCountsAndTimestamps( DB_MASTER ); + $newLocalData = $this->computeLocalCountsAndTimestamps( DB_PRIMARY ); // Write the new values to the echo_unread_wikis table $alertTs = $newLocalData[EchoAttributeManager::ALERT]['timestamp']; $messageTs = $newLocalData[EchoAttributeManager::MESSAGE]['timestamp']; $uw->updateCount( - wfWikiID(), + WikiMap::getCurrentWikiId(), $newLocalData[EchoAttributeManager::ALERT]['count'], $alertTs === -1 ? false : new MWTimestamp( $alertTs ), $newLocalData[EchoAttributeManager::MESSAGE]['count'], @@ -510,10 +545,10 @@ class MWEchoNotifUser { * ], * ] * Where N is a number and TS is a timestamp in TS_MW format or -1. If $includeGlobal is false, - * the 'global' key will not be present. + * the 'global' key will not be present. It could be null, if no global user exists. * * @param bool $includeGlobal Whether to include cross-wiki notifications as well - * @return array[] + * @return array */ public function getCountsAndTimestamps( $includeGlobal = false ) { if ( $this->localCountsAndTimestamps === null ) { @@ -553,22 +588,22 @@ class MWEchoNotifUser { /** * Compute the counts and timestamps for the local notifications in each section. - * @param int $dbSource DB_REPLICA or DB_MASTER + * @param int $dbSource DB_REPLICA or DB_PRIMARY * @return array[] [ 'alert' => [ 'count' => N, 'timestamp' => TS ], ... ] */ protected function computeLocalCountsAndTimestamps( $dbSource = DB_REPLICA ) { - $attributeManager = EchoAttributeManager::newFromGlobalVars(); + $attributeManager = EchoServices::getInstance()->getAttributeManager(); $result = []; $totals = [ 'count' => 0, 'timestamp' => -1 ]; foreach ( EchoAttributeManager::$sections as $section ) { - $eventTypesToLoad = $attributeManager->getUserEnabledEventsbySections( + $eventTypesToLoad = $attributeManager->getUserEnabledEventsBySections( $this->mUser, 'web', [ $section ] ); - $count = (int)$this->userNotifGateway->getCappedNotificationCount( + $count = $this->userNotifGateway->getCappedNotificationCount( $dbSource, $eventTypesToLoad, self::MAX_BADGE_COUNT + 1 @@ -637,7 +672,7 @@ class MWEchoNotifUser { global $wgAllowHTMLEmail; if ( $wgAllowHTMLEmail ) { - return $this->mUser->getOption( 'echo-email-format' ); + return $this->userOptionsLookup->getOption( $this->mUser, 'echo-email-format' ); } return EchoEmailFormat::PLAIN_TEXT; @@ -662,8 +697,9 @@ class MWEchoNotifUser { */ protected function getGlobalMemcKey( $key ) { global $wgEchoCacheVersion; - $lookup = CentralIdLookup::factory(); - $globalId = $lookup->centralIdFromLocalUser( $this->mUser, CentralIdLookup::AUDIENCE_RAW ); + $globalId = MediaWikiServices::getInstance() + ->getCentralIdLookup() + ->centralIdFromLocalUser( $this->mUser, CentralIdLookup::AUDIENCE_RAW ); if ( !$globalId ) { return false; } diff --git a/Echo/includes/Notifier.php b/Echo/includes/Notifier.php index c2a6a72e..88bcd404 100644 --- a/Echo/includes/Notifier.php +++ b/Echo/includes/Notifier.php @@ -1,5 +1,9 @@ <?php +use MediaWiki\Extension\Notifications\Formatters\EchoHtmlEmailFormatter; +use MediaWiki\Extension\Notifications\Formatters\EchoPlainTextEmailFormatter; +use MediaWiki\MediaWikiServices; + // @todo Fill in class EchoNotifier { /** @@ -12,15 +16,13 @@ class EchoNotifier { public static function notifyWithNotification( $user, $event ) { // Only create the notification if the user wants to receive that type // of notification and they are eligible to receive it. See bug 47664. - $attributeManager = EchoAttributeManager::newFromGlobalVars(); + $attributeManager = EchoServices::getInstance()->getAttributeManager(); $userWebNotifications = $attributeManager->getUserEnabledEvents( $user, 'web' ); if ( !in_array( $event->getType(), $userWebNotifications ) ) { return; } EchoNotification::create( [ 'user' => $user, 'event' => $event ] ); - - MWEchoEventLogging::logSchemaEcho( $user, $event, 'web' ); } /** @@ -32,6 +34,7 @@ class EchoNotifier { */ public static function notifyWithEmail( $user, $event ) { global $wgEnableEmail, $wgBlockDisablesLogin; + $userOptionsLookup = MediaWikiServices::getInstance()->getUserOptionsLookup(); if ( // Email is globally disabled @@ -39,9 +42,9 @@ class EchoNotifier { // User does not have a valid and confirmed email address !$user->isEmailConfirmed() || // User has disabled Echo emails - $user->getOption( 'echo-email-frequency' ) < 0 || + $userOptionsLookup->getOption( $user, 'echo-email-frequency' ) < 0 || // User is blocked and cannot log in (T199993) - ( $wgBlockDisablesLogin && $user->isBlocked() ) + ( $wgBlockDisablesLogin && $user->getBlock() ) ) { return false; } @@ -51,7 +54,7 @@ class EchoNotifier { return false; } - $attributeManager = EchoAttributeManager::newFromGlobalVars(); + $attributeManager = EchoServices::getInstance()->getAttributeManager(); $userEmailNotifications = $attributeManager->getUserEnabledEvents( $user, 'email' ); // See if the user wants to receive emails for this category or the user is eligible to receive this email if ( in_array( $event->getType(), $userEmailNotifications ) ) { @@ -74,10 +77,8 @@ class EchoNotifier { $bundleHash = md5( $bundleString ); } - MWEchoEventLogging::logSchemaEcho( $user, $event, 'email' ); - // email digest notification ( weekly or daily ) - if ( $wgEchoEnableEmailBatch && $user->getOption( 'echo-email-frequency' ) > 0 ) { + if ( $wgEchoEnableEmailBatch && $userOptionsLookup->getOption( $user, 'echo-email-frequency' ) > 0 ) { // always create a unique event hash for those events don't support bundling // this is mainly for group by if ( !$bundleHash ) { @@ -120,16 +121,17 @@ class EchoNotifier { */ private static function generateEmail( EchoEvent $event, User $user ) { $emailFormat = MWEchoNotifUser::newFromUser( $user )->getEmailFormat(); - $lang = Language::factory( $user->getOption( 'language' ) ); + $userOptionsLookup = MediaWikiServices::getInstance()->getUserOptionsLookup(); + $lang = Language::factory( $userOptionsLookup->getOption( $user, 'language' ) ); $formatter = new EchoPlainTextEmailFormatter( $user, $lang ); - $content = $formatter->format( $event ); + $content = $formatter->format( $event, 'email' ); if ( !$content ) { return false; } if ( $emailFormat === EchoEmailFormat::HTML ) { $htmlEmailFormatter = new EchoHtmlEmailFormatter( $user, $lang ); - $htmlContent = $htmlEmailFormatter->format( $event ); + $htmlContent = $htmlEmailFormatter->format( $event, 'email' ); $multipartBody = [ 'text' => $content['body'], 'html' => $htmlContent['body'] diff --git a/Echo/includes/ooui/LabelIconWidget.php b/Echo/includes/OOUI/LabelIconWidget.php index 940b1721..04888857 100644 --- a/Echo/includes/ooui/LabelIconWidget.php +++ b/Echo/includes/OOUI/LabelIconWidget.php @@ -1,6 +1,6 @@ <?php -namespace EchoOOUI; +namespace MediaWiki\Extension\Notifications\OOUI; use OOUI\IconElement; use OOUI\LabelElement; diff --git a/Echo/includes/api/Push/ApiEchoPushSubscriptions.php b/Echo/includes/Push/Api/ApiEchoPushSubscriptions.php index ac067294..f0f46e5f 100644 --- a/Echo/includes/api/Push/ApiEchoPushSubscriptions.php +++ b/Echo/includes/Push/Api/ApiEchoPushSubscriptions.php @@ -1,6 +1,6 @@ <?php -namespace EchoPush\Api; +namespace MediaWiki\Extension\Notifications\Push\Api; use ApiBase; use ApiModuleManager; @@ -41,7 +41,7 @@ class ApiEchoPushSubscriptions extends ApiBase { /** @inheritDoc */ public function getModuleManager(): ApiModuleManager { if ( !$this->moduleManager ) { - $submodules = array_map( function ( $class ) { + $submodules = array_map( static function ( $class ) { return [ 'class' => $class, 'factory' => "$class::factory", @@ -71,7 +71,7 @@ class ApiEchoPushSubscriptions extends ApiBase { * @throws ApiUsageException */ private function checkLoginState(): void { - if ( $this->getUser()->isAnon() ) { + if ( !$this->getUser()->isRegistered() ) { $this->dieWithError( [ 'apierror-mustbeloggedin', $this->msg( 'action-editmyprivateinfo' ) ], 'notloggedin' diff --git a/Echo/includes/api/Push/ApiEchoPushSubscriptionsCreate.php b/Echo/includes/Push/Api/ApiEchoPushSubscriptionsCreate.php index db8009ec..31b34a97 100644 --- a/Echo/includes/api/Push/ApiEchoPushSubscriptionsCreate.php +++ b/Echo/includes/Push/Api/ApiEchoPushSubscriptionsCreate.php @@ -1,11 +1,12 @@ <?php -namespace EchoPush\Api; +namespace MediaWiki\Extension\Notifications\Push\Api; use ApiBase; use ApiMain; -use EchoPush\SubscriptionManager; use EchoServices; +use MediaWiki\Extension\Notifications\Push\SubscriptionManager; +use MediaWiki\Extension\Notifications\Push\Utils; use Wikimedia\ParamValidator\ParamValidator; class ApiEchoPushSubscriptionsCreate extends ApiBase { @@ -29,8 +30,7 @@ class ApiEchoPushSubscriptionsCreate extends ApiBase { * @param string $name Module name * @return ApiEchoPushSubscriptionsCreate */ - public static function factory( ApiBase $parent, string $name ): - ApiEchoPushSubscriptionsCreate { + public static function factory( ApiBase $parent, string $name ): ApiEchoPushSubscriptionsCreate { $subscriptionManger = EchoServices::getInstance()->getPushSubscriptionManager(); $module = new self( $parent->getMain(), $name, $subscriptionManger ); $module->parent = $parent; @@ -58,7 +58,16 @@ class ApiEchoPushSubscriptionsCreate extends ApiBase { public function execute(): void { $provider = $this->getParameter( 'provider' ); $token = $this->getParameter( 'providertoken' ); - $success = $this->subscriptionManager->create( $this->getUser(), $provider, $token ); + $topic = null; + // check if metadata is a JSON string correctly encoded + if ( $provider === 'apns' ) { + $topic = $this->getParameter( 'topic' ); + if ( !$topic ) { + $this->dieWithError( 'apierror-echo-push-topic-required' ); + } + } + $userId = Utils::getPushUserId( $this->getUser() ); + $success = $this->subscriptionManager->create( $provider, $token, $userId, $topic ); if ( !$success ) { $this->dieWithError( 'apierror-echo-push-token-exists' ); } @@ -83,6 +92,10 @@ class ApiEchoPushSubscriptionsCreate extends ApiBase { ParamValidator::PARAM_TYPE => 'string', ParamValidator::PARAM_REQUIRED => true, ], + 'topic' => [ + ParamValidator::PARAM_TYPE => 'string', + ParamValidator::PARAM_REQUIRED => false, + ], ]; } diff --git a/Echo/includes/api/Push/ApiEchoPushSubscriptionsDelete.php b/Echo/includes/Push/Api/ApiEchoPushSubscriptionsDelete.php index e6331d23..05181a33 100644 --- a/Echo/includes/api/Push/ApiEchoPushSubscriptionsDelete.php +++ b/Echo/includes/Push/Api/ApiEchoPushSubscriptionsDelete.php @@ -1,11 +1,13 @@ <?php -namespace EchoPush\Api; +namespace MediaWiki\Extension\Notifications\Push\Api; use ApiBase; use ApiMain; -use EchoPush\SubscriptionManager; +use ApiUsageException; use EchoServices; +use MediaWiki\Extension\Notifications\Push\SubscriptionManager; +use MediaWiki\Extension\Notifications\Push\Utils; use Wikimedia\ParamValidator\ParamValidator; class ApiEchoPushSubscriptionsDelete extends ApiBase { @@ -22,8 +24,7 @@ class ApiEchoPushSubscriptionsDelete extends ApiBase { * @param string $name Module name * @return ApiEchoPushSubscriptionsDelete */ - public static function factory( ApiBase $parent, string $name ): - ApiEchoPushSubscriptionsDelete { + public static function factory( ApiBase $parent, string $name ): ApiEchoPushSubscriptionsDelete { $subscriptionManager = EchoServices::getInstance()->getPushSubscriptionManager(); $module = new self( $parent->getMain(), $name, $subscriptionManager ); $module->parent = $parent; @@ -49,8 +50,20 @@ class ApiEchoPushSubscriptionsDelete extends ApiBase { * @inheritDoc */ public function execute(): void { - $token = $this->getParameter( 'providertoken' ); - $numRowsDeleted = $this->subscriptionManager->delete( $this->getUser(), $token ); + $tokens = $this->getParameter( 'providertoken' ); + $userId = null; + + if ( !$tokens ) { + $this->dieWithError( [ 'apierror-paramempty', 'providertoken' ], 'paramempty_providertoken' ); + } + // Restrict deletion to the user's own token(s) if not a push subscription manager + try { + $this->checkUserRightsAny( 'manage-all-push-subscriptions' ); + } catch ( ApiUsageException $e ) { + $userId = Utils::getPushUserId( $this->getUser() ); + } + + $numRowsDeleted = $this->subscriptionManager->delete( $tokens, $userId ); if ( $numRowsDeleted == 0 ) { $this->dieWithError( 'apierror-echo-push-token-not-found' ); } @@ -70,6 +83,7 @@ class ApiEchoPushSubscriptionsDelete extends ApiBase { 'providertoken' => [ ParamValidator::PARAM_TYPE => 'string', ParamValidator::PARAM_REQUIRED => true, + ParamValidator::PARAM_ISMULTI => true, ], ]; } diff --git a/Echo/includes/Push/NotificationRequestJob.php b/Echo/includes/Push/NotificationRequestJob.php index e228584d..bf70b13b 100644 --- a/Echo/includes/Push/NotificationRequestJob.php +++ b/Echo/includes/Push/NotificationRequestJob.php @@ -1,6 +1,6 @@ <?php -namespace EchoPush; +namespace MediaWiki\Extension\Notifications\Push; use EchoServices; use Job; diff --git a/Echo/includes/Push/NotificationServiceClient.php b/Echo/includes/Push/NotificationServiceClient.php index 39d1ab43..f2fcfe37 100644 --- a/Echo/includes/Push/NotificationServiceClient.php +++ b/Echo/includes/Push/NotificationServiceClient.php @@ -1,6 +1,6 @@ <?php -namespace EchoPush; +namespace MediaWiki\Extension\Notifications\Push; use MediaWiki\Http\HttpRequestFactory; use MWHttpRequest; @@ -33,18 +33,28 @@ class NotificationServiceClient implements LoggerAwareInterface { * @param array $subscriptions Subscriptions for which to send the message */ public function sendCheckEchoRequests( array $subscriptions ): void { - $tokensByProvider = []; + $tokenMap = []; foreach ( $subscriptions as $subscription ) { $provider = $subscription->getProvider(); - if ( !isset( $tokensByProvider[$provider] ) ) { - $tokensByProvider[$provider] = []; + $topic = $subscription->getTopic() ?? 0; + if ( !isset( $tokenMap[$topic][$provider] ) ) { + $tokenMap[$topic][$provider] = []; } - $tokensByProvider[$provider][] = $subscription->getToken(); + + $tokenMap[$topic][$provider][] = $subscription->getToken(); } - foreach ( array_keys( $tokensByProvider ) as $provider ) { - $tokens = $tokensByProvider[$provider]; - $payload = [ 'deviceTokens' => $tokens, 'messageType' => 'checkEchoV1' ]; - $this->sendRequest( $provider, $payload ); + foreach ( array_keys( $tokenMap ) as $topic ) { + foreach ( array_keys( $tokenMap[$topic] ) as $provider ) { + $tokens = $tokenMap[$topic][$provider]; + $payload = [ + 'deviceTokens' => $tokens, + 'messageType' => 'checkEchoV1' + ]; + if ( $topic !== 0 ) { + $payload['topic'] = $topic; + } + $this->sendRequest( $provider, $payload ); + } } } @@ -53,7 +63,7 @@ class NotificationServiceClient implements LoggerAwareInterface { * @param string $provider Provider endpoint to which to send the message * @param array $payload message payload */ - private function sendRequest( string $provider, array $payload ): void { + protected function sendRequest( string $provider, array $payload ): void { $request = $this->constructRequest( $provider, $payload ); $status = $request->execute(); if ( !$status->isOK() ) { diff --git a/Echo/includes/Push/PushNotifier.php b/Echo/includes/Push/PushNotifier.php index 93c7126c..c401454f 100644 --- a/Echo/includes/Push/PushNotifier.php +++ b/Echo/includes/Push/PushNotifier.php @@ -1,11 +1,10 @@ <?php -namespace EchoPush; +namespace MediaWiki\Extension\Notifications\Push; -use CentralIdLookup; -use EchoAttributeManager; use EchoEvent; -use JobQueueGroup; +use EchoServices; +use MediaWiki\MediaWikiServices; use User; class PushNotifier { @@ -17,10 +16,10 @@ class PushNotifier { * @param EchoEvent $event */ public static function notifyWithPush( User $user, EchoEvent $event ): void { - $attributeManager = EchoAttributeManager::newFromGlobalVars(); + $attributeManager = EchoServices::getInstance()->getAttributeManager(); $userEnabledEvents = $attributeManager->getUserEnabledEvents( $user, 'push' ); if ( in_array( $event->getType(), $userEnabledEvents ) ) { - JobQueueGroup::singleton()->push( self::createJob( $user, $event ) ); + MediaWikiServices::getInstance()->getJobQueueGroup()->push( self::createJob( $user, $event ) ); } } @@ -29,9 +28,8 @@ class PushNotifier { * @param EchoEvent|null $event * @return NotificationRequestJob */ - private static function createJob( User $user, EchoEvent $event = null ): - NotificationRequestJob { - $centralId = CentralIdLookup::factory()->centralIdFromLocalUser( $user ); + private static function createJob( User $user, EchoEvent $event = null ): NotificationRequestJob { + $centralId = Utils::getPushUserId( $user ); $params = [ 'centralId' => $centralId ]; // below params are only needed for debug logging (T255068) if ( $event !== null ) { @@ -45,3 +43,5 @@ class PushNotifier { } } + +class_alias( PushNotifier::class, 'EchoPush\\PushNotifier' ); diff --git a/Echo/includes/Push/Subscription.php b/Echo/includes/Push/Subscription.php index 92c7b904..4d875ebc 100644 --- a/Echo/includes/Push/Subscription.php +++ b/Echo/includes/Push/Subscription.php @@ -1,6 +1,6 @@ <?php -namespace EchoPush; +namespace MediaWiki\Extension\Notifications\Push; use Wikimedia\Timestamp\ConvertibleTimestamp; @@ -15,15 +15,19 @@ class Subscription { /** @var ConvertibleTimestamp */ private $updated; + /** @var string|null */ + private $topic; + /** * Construct a subscription from a DB result row. - * @param object $row echo_push_subscription row from IResultWrapper::fetchRow + * @param \stdClass $row echo_push_subscription row from IResultWrapper::fetchRow * @return Subscription */ public static function newFromRow( object $row ) { return new self( $row->epp_name, $row->eps_token, + $row->ept_text, new ConvertibleTimestamp( $row->eps_updated ) ); } @@ -31,11 +35,13 @@ class Subscription { /** * @param string $provider * @param string $token + * @param string|null $topic * @param ConvertibleTimestamp $updated */ - public function __construct( string $provider, string $token, ConvertibleTimestamp $updated ) { + public function __construct( string $provider, string $token, ?string $topic, ConvertibleTimestamp $updated ) { $this->provider = $provider; $this->token = $token; + $this->topic = $topic; $this->updated = $updated; } @@ -49,6 +55,11 @@ class Subscription { return $this->token; } + /** @return string|null topic */ + public function getTopic(): ?string { + return $this->topic; + } + /** @return ConvertibleTimestamp last updated timestamp */ public function getUpdated(): ConvertibleTimestamp { return $this->updated; diff --git a/Echo/includes/Push/SubscriptionManager.php b/Echo/includes/Push/SubscriptionManager.php index 312186c2..359b7d58 100644 --- a/Echo/includes/Push/SubscriptionManager.php +++ b/Echo/includes/Push/SubscriptionManager.php @@ -1,13 +1,11 @@ <?php -namespace EchoPush; +namespace MediaWiki\Extension\Notifications\Push; -use CentralIdLookup; use EchoAbstractMapper; -use IDatabase; use MediaWiki\Storage\NameTableStore; -use User; use Wikimedia\Rdbms\DBError; +use Wikimedia\Rdbms\IDatabase; class SubscriptionManager extends EchoAbstractMapper { @@ -17,46 +15,69 @@ class SubscriptionManager extends EchoAbstractMapper { /** @var IDatabase */ private $dbr; - /** @var CentralIdLookup */ - private $centralIdLookup; - /** @var NameTableStore */ private $pushProviderStore; + /** @var NameTableStore */ + private $pushTopicStore; + + /** @var int */ + private $maxSubscriptionsPerUser; + /** * @param IDatabase $dbw primary DB connection (for writes) * @param IDatabase $dbr replica DB connection (for reads) - * @param CentralIdLookup $centralIdLookup * @param NameTableStore $pushProviderStore + * @param NameTableStore $pushTopicStore + * @param int $maxSubscriptionsPerUser */ public function __construct( IDatabase $dbw, IDatabase $dbr, - CentralIdLookup $centralIdLookup, - NameTableStore $pushProviderStore + NameTableStore $pushProviderStore, + NameTableStore $pushTopicStore, + int $maxSubscriptionsPerUser ) { parent::__construct(); $this->dbw = $dbw; $this->dbr = $dbr; - $this->centralIdLookup = $centralIdLookup; $this->pushProviderStore = $pushProviderStore; + $this->pushTopicStore = $pushTopicStore; + $this->maxSubscriptionsPerUser = $maxSubscriptionsPerUser; } /** - * Store push subscription information for a user. - * @param User $user + * Store push subscription information for a central user ID. * @param string $provider Provider name string (validated by presence in the PARAM_TYPE array) * @param string $token Subscriber token provided by the push provider + * @param int $centralId + * @param string|null $topic APNS topic string * @return bool true if the subscription was created; false if the token already exists */ - public function create( User $user, string $provider, string $token ): bool { + public function create( string $provider, string $token, int $centralId, ?string $topic = null ): bool { + $subscriptions = $this->getSubscriptionsForUser( $centralId ); + if ( count( $subscriptions ) >= $this->maxSubscriptionsPerUser ) { + // If we exceed the number of subscriptions for this user, then delete the oldest subscription + // before inserting the new one, making it behave like a circular buffer. + // (Find the oldest subscription by iterating, since their order in the DB is not guaranteed.) + $oldest = $subscriptions[0]; + foreach ( $subscriptions as $subscription ) { + if ( $subscription->getUpdated() < $oldest->getUpdated() ) { + $oldest = $subscription; + } + } + $this->delete( [ $oldest->getToken() ], $centralId ); + } + $topicId = $topic ? $this->pushTopicStore->acquireId( $topic ) : null; $this->dbw->insert( 'echo_push_subscription', [ - 'eps_user' => $this->getCentralId( $user ), + 'eps_user' => $centralId, 'eps_provider' => $this->pushProviderStore->acquireId( $provider ), 'eps_token' => $token, 'eps_token_sha256' => hash( 'sha256', $token ), + 'eps_data' => null, + 'eps_topic' => $topicId, 'eps_updated' => $this->dbw->timestamp() ], __METHOD__, @@ -66,18 +87,21 @@ class SubscriptionManager extends EchoAbstractMapper { } /** - * Get all registered subscriptions for a user (by central ID). + * Get full data for all registered subscriptions for a user (by central ID). * @param int $centralId * @return array array of Subscription objects */ public function getSubscriptionsForUser( int $centralId ) { $res = $this->dbr->select( - [ 'echo_push_subscription', 'echo_push_provider' ], + [ 'echo_push_subscription', 'echo_push_provider', 'echo_push_topic' ], '*', [ 'eps_user' => $centralId ], __METHOD__, [], - [ 'echo_push_provider' => [ 'INNER JOIN', [ 'eps_provider = epp_id' ] ] ] + [ + 'echo_push_provider' => [ 'INNER JOIN', [ 'eps_provider = epp_id' ] ], + 'echo_push_topic' => [ 'LEFT JOIN', [ 'eps_topic = ept_id' ] ], + ] ); $result = []; foreach ( $res as $row ) { @@ -87,37 +111,24 @@ class SubscriptionManager extends EchoAbstractMapper { } /** - * Delete a push subscription for a user. - * Note: Selecting for the user in addition to the token should be redundant, since tokens - * are globally unique and user-specific, but it's probably safest to keep it as a sanity check. - * Also, currently the eps_user column is indexed but eps_token is not. - * @param User $user - * @param string $token Delete the subscription with this token + * Delete one or more push subscriptions by token. Unless the current user is a push + * subscription manager, the query will also include the current central user ID as a condition. + * @param array $tokens Delete the subscription with these tokens + * @param int|null $centralId * @return int number of rows deleted * @throws DBError */ - public function delete( User $user, string $token ): int { + public function delete( array $tokens, int $centralId = null ): int { + $cond = [ 'eps_token' => $tokens ]; + if ( $centralId ) { + $cond['eps_user'] = $centralId; + } $this->dbw->delete( 'echo_push_subscription', - [ - 'eps_user' => $this->getCentralId( $user ), - 'eps_token' => $token, - ], + $cond, __METHOD__ ); return $this->dbw->affectedRows(); } - /** - * Get the user's central ID. - * @param User $user - * @return int - */ - private function getCentralId( User $user ): int { - return $this->centralIdLookup->centralIdFromLocalUser( - $user, - CentralIdLookup::AUDIENCE_RAW - ); - } - } diff --git a/Echo/includes/Push/Utils.php b/Echo/includes/Push/Utils.php new file mode 100644 index 00000000..a3cd833a --- /dev/null +++ b/Echo/includes/Push/Utils.php @@ -0,0 +1,28 @@ +<?php + +namespace MediaWiki\Extension\Notifications\Push; + +use CentralIdLookup; +use MediaWiki\MediaWikiServices; +use MediaWiki\User\UserIdentity; + +class Utils { + + /** + * Attempt to get a unique ID for the specified user, accounting for installations both with + * and without CentralAuth: Return the user's central ID, if available. If there is no central + * user associated with the local user (i.e., centralIdFromLocalUser returns 0), fall back to + * returning the local user ID. + * @param UserIdentity $user + * @return int + */ + public static function getPushUserId( UserIdentity $user ): int { + return MediaWikiServices::getInstance() + ->getCentralIdLookup() + ->centralIdFromLocalUser( + $user, + CentralIdLookup::AUDIENCE_RAW + ) ?: $user->getId(); + } + +} diff --git a/Echo/includes/ResourceLoaderEchoImageModule.php b/Echo/includes/ResourceLoaderEchoImageModule.php index 5cb6f955..69eceabd 100644 --- a/Echo/includes/ResourceLoaderEchoImageModule.php +++ b/Echo/includes/ResourceLoaderEchoImageModule.php @@ -18,11 +18,13 @@ * @file */ +use MediaWiki\ResourceLoader as RL; + /** * A sibling of secret special sauce. - * @see ResourceLoaderOOUIImageModule for familial resemblence + * @see RL\OOUIImageModule for familial resemblence */ -class ResourceLoaderEchoImageModule extends ResourceLoaderImageModule { +class ResourceLoaderEchoImageModule extends RL\ImageModule { protected function loadFromDefinition() { if ( $this->definition === null ) { return; diff --git a/Echo/includes/SeenTime.php b/Echo/includes/SeenTime.php index bec18ef7..f2dfa17a 100644 --- a/Echo/includes/SeenTime.php +++ b/Echo/includes/SeenTime.php @@ -84,8 +84,9 @@ class EchoSeenTime { $data = self::cache()->get( $this->getMemcKey( $type ) ); if ( $data === false ) { + $userOptionsLookup = MediaWikiServices::getInstance()->getUserOptionsLookup(); // Check if the user still has it set in their preferences - $data = $this->user->getOption( 'echo-seen-time', false ); + $data = $userOptionsLookup->getOption( $this->user, 'echo-seen-time', false ); } if ( $data === false ) { @@ -119,7 +120,7 @@ class EchoSeenTime { $key = $this->getMemcKey( $type ); $cache = self::cache(); $cache->set( $key, $time, $cache::TTL_YEAR, BagOStuff::WRITE_CACHE_ONLY ); - DeferredUpdates::addCallableUpdate( function () use ( $key, $time, $cache ) { + DeferredUpdates::addCallableUpdate( static function () use ( $key, $time, $cache ) { $cache->set( $key, $time, $cache::TTL_YEAR ); } ); } @@ -144,13 +145,15 @@ class EchoSeenTime { $localKey = self::cache()->makeKey( 'echo', 'seen', $type, 'time', $this->user->getId() ); + $userOptionsLookup = MediaWikiServices::getInstance()->getUserOptionsLookup(); - if ( !$this->user->getOption( 'echo-cross-wiki-notifications' ) ) { + if ( !$userOptionsLookup->getOption( $this->user, 'echo-cross-wiki-notifications' ) ) { return $localKey; } - $lookup = CentralIdLookup::factory(); - $globalId = $lookup->centralIdFromLocalUser( $this->user, CentralIdLookup::AUDIENCE_RAW ); + $globalId = MediaWikiServices::getInstance() + ->getCentralIdLookup() + ->centralIdFromLocalUser( $this->user, CentralIdLookup::AUDIENCE_RAW ); if ( !$globalId ) { return $localKey; diff --git a/Echo/includes/UnreadWikis.php b/Echo/includes/UnreadWikis.php index ef02df64..44a0b1ba 100644 --- a/Echo/includes/UnreadWikis.php +++ b/Echo/includes/UnreadWikis.php @@ -1,11 +1,15 @@ <?php +use MediaWiki\MediaWikiServices; +use MediaWiki\User\UserIdentity; + /** * Manages what wikis a user has unread notifications on */ class EchoUnreadWikis { - const DEFAULT_TS = '00000000000000'; + private const DEFAULT_TS = '00000000000000'; + private const DEFAULT_TS_DB = '00010101010101'; /** * @var int @@ -28,12 +32,13 @@ class EchoUnreadWikis { /** * Use the user id provided by the CentralIdLookup * - * @param User $user + * @param UserIdentity $user * @return EchoUnreadWikis|false */ - public static function newFromUser( User $user ) { - $lookup = CentralIdLookup::factory(); - $id = $lookup->centralIdFromLocalUser( $user, CentralIdLookup::AUDIENCE_RAW ); + public static function newFromUser( UserIdentity $user ) { + $id = MediaWikiServices::getInstance() + ->getCentralIdLookup() + ->centralIdFromLocalUser( $user, CentralIdLookup::AUDIENCE_RAW ); if ( !$id ) { return false; } @@ -78,11 +83,13 @@ class EchoUnreadWikis { $wikis[$row->euw_wiki] = [ EchoAttributeManager::ALERT => [ 'count' => $row->euw_alerts, - 'ts' => $row->euw_alerts_ts, + 'ts' => wfTimestamp( TS_MW, $row->euw_alerts_ts ) === static::DEFAULT_TS_DB ? + static::DEFAULT_TS : wfTimestamp( TS_MW, $row->euw_alerts_ts ), ], EchoAttributeManager::MESSAGE => [ 'count' => $row->euw_messages, - 'ts' => $row->euw_messages_ts, + 'ts' => wfTimestamp( TS_MW, $row->euw_messages_ts ) === static::DEFAULT_TS_DB ? + static::DEFAULT_TS : wfTimestamp( TS_MW, $row->euw_messages_ts ), ], ]; } @@ -100,7 +107,7 @@ class EchoUnreadWikis { * false meaning no timestamp because there are no unread messages. */ public function updateCount( $wiki, $alertCount, $alertTime, $msgCount, $msgTime ) { - $dbw = $this->getDB( DB_MASTER ); + $dbw = $this->getDB( DB_PRIMARY ); if ( $dbw === false || $dbw->isReadOnly() ) { return; } @@ -113,13 +120,17 @@ class EchoUnreadWikis { if ( $alertCount || $msgCount ) { $values = [ 'euw_alerts' => $alertCount, - 'euw_alerts_ts' => $alertTime - ? $alertTime->getTimestamp( TS_MW ) - : static::DEFAULT_TS, + 'euw_alerts_ts' => $dbw->timestamp( + $alertTime + ? $alertTime->getTimestamp( TS_MW ) + : static::DEFAULT_TS_DB + ), 'euw_messages' => $msgCount, - 'euw_messages_ts' => $msgTime - ? $msgTime->getTimestamp( TS_MW ) - : static::DEFAULT_TS, + 'euw_messages_ts' => $dbw->timestamp( + $msgTime + ? $msgTime->getTimestamp( TS_MW ) + : static::DEFAULT_TS_DB + ), ]; // when there is unread alert(s) and/or message(s), upsert the row diff --git a/Echo/includes/UserLocator.php b/Echo/includes/UserLocator.php index 85cbecfc..0de9bec1 100644 --- a/Echo/includes/UserLocator.php +++ b/Echo/includes/UserLocator.php @@ -19,26 +19,27 @@ class EchoUserLocator { return []; } - $it = new BatchRowIterator( + $batchRowIt = new BatchRowIterator( wfGetDB( DB_REPLICA, 'watchlist' ), /* $table = */ 'watchlist', /* $primaryKeys = */ [ 'wl_user' ], $batchSize ); - $it->addConditions( [ + $batchRowIt->addConditions( [ 'wl_namespace' => $title->getNamespace(), 'wl_title' => $title->getDBkey(), ] ); + $batchRowIt->setCaller( __METHOD__ ); // flatten the result into a stream of rows - $it = new RecursiveIteratorIterator( $it ); + $recursiveIt = new RecursiveIteratorIterator( $batchRowIt ); // add callback to convert user id to user objects - $it = new EchoCallbackIterator( $it, function ( $row ) { + $echoCallbackIt = new EchoCallbackIterator( $recursiveIt, static function ( $row ) { return User::newFromId( $row->wl_user ); } ); - return $it; + return $echoCallbackIt; } /** @@ -55,7 +56,7 @@ class EchoUserLocator { } $user = User::newFromName( $title->getDBkey() ); - if ( $user && !$user->isAnon() ) { + if ( $user && $user->isRegistered() ) { return [ $user->getId() => $user ]; } @@ -70,7 +71,7 @@ class EchoUserLocator { */ public static function locateEventAgent( EchoEvent $event ) { $agent = $event->getAgent(); - if ( $agent && !$agent->isAnon() ) { + if ( $agent && $agent->isRegistered() ) { return [ $agent->getId() => $agent ]; } @@ -141,7 +142,7 @@ class EchoUserLocator { // we shouldn't receive User instances, but allow // it for backward compatability if ( $userId instanceof User ) { - if ( $userId->isAnon() ) { + if ( !$userId->isRegistered() ) { continue; } $user = $userId; diff --git a/Echo/includes/cache/LocalCache.php b/Echo/includes/cache/LocalCache.php index cebe8621..0cc709e6 100644 --- a/Echo/includes/cache/LocalCache.php +++ b/Echo/includes/cache/LocalCache.php @@ -9,9 +9,9 @@ abstract class EchoLocalCache { * Max number of objects to hold in $targets. In theory, 1000 * is very hard to reach in a normal web request. We need to * put cap so it doesn't reach memory limit when running email - * digest against large amount of notications + * digest against large amount of notifications */ - const TARGET_MAX_NUM = 1000; + private const TARGET_MAX_NUM = 1000; /** * Target object cache diff --git a/Echo/includes/cache/TitleLocalCache.php b/Echo/includes/cache/TitleLocalCache.php index b756b0f7..5a995f97 100644 --- a/Echo/includes/cache/TitleLocalCache.php +++ b/Echo/includes/cache/TitleLocalCache.php @@ -1,5 +1,8 @@ <?php +use MediaWiki\MediaWikiServices; +use MediaWiki\Page\PageRecord; + /** * Cache class that maps article id to Title object */ @@ -26,8 +29,16 @@ class EchoTitleLocalCache extends EchoLocalCache { */ protected function resolve( array $lookups ) { if ( $lookups ) { - $titles = Title::newFromIDs( $lookups ); + $titles = MediaWikiServices::getInstance() + ->getPageStore() + ->newSelectQueryBuilder() + ->wherePageIds( $lookups ) + ->caller( __METHOD__ ) + ->fetchPageRecords(); + + /** @var PageRecord $title */ foreach ( $titles as $title ) { + $title = MediaWikiServices::getInstance()->getTitleFactory()->castFromPageIdentity( $title ); yield $title->getArticleID() => $title; } } diff --git a/Echo/includes/controller/ModerationController.php b/Echo/includes/controller/ModerationController.php index 1c2c6884..5f790203 100644 --- a/Echo/includes/controller/ModerationController.php +++ b/Echo/includes/controller/ModerationController.php @@ -27,7 +27,7 @@ class EchoModerationController { $fname = __METHOD__; - DeferredUpdates::addCallableUpdate( function () use ( $affectedUserIds, $fname ) { + DeferredUpdates::addCallableUpdate( static function () use ( $affectedUserIds, $fname ) { // This update runs after the main transaction round commits. // Wait for the event deletions to be propagated to replica DBs $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory(); diff --git a/Echo/includes/controller/NotificationController.php b/Echo/includes/controller/NotificationController.php index b22773d1..ee7a3a6f 100644 --- a/Echo/includes/controller/NotificationController.php +++ b/Echo/includes/controller/NotificationController.php @@ -3,6 +3,7 @@ use MediaWiki\Logger\LoggerFactory; use MediaWiki\MediaWikiServices; use MediaWiki\Revision\RevisionStore; +use MediaWiki\User\UserIdentity; /** * This class represents the controller for notifications @@ -12,7 +13,7 @@ class EchoNotificationController { /** * Echo maximum number of users to cache * - * @var int $maxRecipientCacheSize + * @var int */ protected static $maxRecipientCacheSize = 200; @@ -58,12 +59,8 @@ class EchoNotificationController { * @param int $count * @return int Notification count, with ceiling applied */ - public static function getCappedNotificationCount( $count ) { - if ( $count <= MWEchoNotifUser::MAX_BADGE_COUNT ) { - return $count; - } else { - return MWEchoNotifUser::MAX_BADGE_COUNT + 1; - } + public static function getCappedNotificationCount( int $count ): int { + return min( $count, MWEchoNotifUser::MAX_BADGE_COUNT + 1 ); } /** @@ -111,16 +108,23 @@ class EchoNotificationController { $notifyTypes = self::getEventNotifyTypes( $type ); $userIds = []; $userIdsCount = 0; + $userOptionsLookup = MediaWikiServices::getInstance()->getUserOptionsLookup(); + /** @var bool|null $hasMinorRevision */ + $hasMinorRevision = null; + /** @var User $user */ foreach ( self::getUsersToNotifyForEvent( $event ) as $user ) { $userIds[$user->getId()] = $user->getId(); $userNotifyTypes = $notifyTypes; // Respect the enotifminoredits preference // @todo should this be checked somewhere else? - if ( - !$user->getOption( 'enotifminoredits' ) && - self::hasMinorRevision( $event ) - ) { - $notifyTypes = array_diff( $notifyTypes, [ 'email' ] ); + if ( !$userOptionsLookup->getOption( $user, 'enotifminoredits' ) ) { + if ( $hasMinorRevision === null ) { + // Do this only once per event + $hasMinorRevision = self::hasMinorRevision( $event ); + } + if ( $hasMinorRevision ) { + $userNotifyTypes = array_diff( $userNotifyTypes, [ 'email' ] ); + } } Hooks::run( 'EchoGetNotificationTypes', [ $user, $event, &$userNotifyTypes ] ); @@ -136,6 +140,10 @@ class EchoNotificationController { $userIds = []; $userIdsCount = 0; } + + $stats = MediaWikiServices::getInstance()->getStatsdDataFactory(); + $stats->increment( 'echo.notification.all' ); + $stats->increment( "echo.notification.$type" ); } // process the userIds left in the array @@ -191,7 +199,7 @@ class EchoNotificationController { 'userIds' => $userIds ] ); - JobQueueGroup::singleton()->push( $job ); + MediaWikiServices::getInstance()->getJobQueueGroup()->push( $job ); } /** @@ -202,7 +210,7 @@ class EchoNotificationController { * this event type */ public static function getEventNotifyTypes( $eventType ) { - $attributeManager = EchoAttributeManager::newFromGlobalVars(); + $attributeManager = EchoServices::getInstance()->getAttributeManager(); $category = $attributeManager->getNotificationCategory( $eventType ); @@ -212,18 +220,47 @@ class EchoNotificationController { } /** + * Helper function to extract event task params + * @param EchoEvent $event + * @return array Event params + */ + public static function getEventParams( EchoEvent $event ) { + $delay = $event->getExtraParam( 'delay' ); + $rootJobSignature = $event->getExtraParam( 'rootJobSignature' ); + $rootJobTimestamp = $event->getExtraParam( 'rootJobTimestamp' ); + + return [ 'eventId' => $event->getId() ] + + ( $delay ? [ 'jobReleaseTimestamp' => (int)wfTimestamp() + $delay ] : [] ) + + ( $rootJobSignature ? [ 'rootJobSignature' => $rootJobSignature ] : [] ) + + ( $rootJobTimestamp ? [ 'rootJobTimestamp' => $rootJobTimestamp ] : [] ); + } + + /** * Push $event onto the mediawiki job queue * * @param EchoEvent $event */ public static function enqueueEvent( EchoEvent $event ) { + $queue = MediaWikiServices::getInstance()->getJobQueueGroup(); + $params = self::getEventParams( $event ); + $job = new EchoNotificationJob( - $event->getTitle() ?: Title::newMainPage(), - [ - 'eventId' => $event->getId(), - ] + $event->getTitle() ?: Title::newMainPage(), $params ); - JobQueueGroup::singleton()->push( $job ); + + if ( isset( $params[ 'jobReleaseTimestamp' ] ) && !$queue->get( $job->getType() )->delayedJobsEnabled() ) { + $logger = LoggerFactory::getInstance( 'Echo' ); + $logger->warning( + 'Delayed jobs are not enabled. Skipping enqueuing event {id} of type {type}.', + [ + 'id' => $event->getId(), + 'type' => $event->getType() + ] + ); + return; + } + + $queue->push( $job ); } /** @@ -377,7 +414,7 @@ class EchoNotificationController { } // Don't send any notifications to anonymous users - if ( $user->isAnon() ) { + if ( !$user->isRegistered() ) { throw new MWException( "Cannot notify anonymous user: {$user->getName()}" ); } @@ -393,7 +430,7 @@ class EchoNotificationController { * @return array */ public static function evaluateUserCallable( EchoEvent $event, $locator = EchoAttributeManager::ATTR_LOCATORS ) { - $attributeManager = EchoAttributeManager::newFromGlobalVars(); + $attributeManager = EchoServices::getInstance()->getAttributeManager(); $type = $event->getType(); $result = []; foreach ( $attributeManager->getUserCallable( $type, $locator ) as $callable ) { @@ -441,11 +478,11 @@ class EchoNotificationController { foreach ( self::evaluateUserCallable( $event, EchoAttributeManager::ATTR_FILTERS ) as $users ) { // the result of the callback can be both an iterator or array $users = is_array( $users ) ? $users : iterator_to_array( $users ); - $notify->addFilter( function ( User $user ) use ( $users ) { + $notify->addFilter( static function ( UserIdentity $user ) use ( $users ) { // we need to check if $user is in $users, but they're not // guaranteed to be the same object, so I'll compare ids. $userId = $user->getId(); - $userIds = array_map( function ( User $user ) { + $userIds = array_map( static function ( UserIdentity $user ) { return $user->getId(); }, $users ); return !in_array( $userId, $userIds ); @@ -455,15 +492,15 @@ class EchoNotificationController { // Filter non-User, anon and duplicate users $seen = []; $fname = __METHOD__; - $notify->addFilter( function ( $user ) use ( &$seen, $fname ) { + $notify->addFilter( static function ( $user ) use ( &$seen, $fname ) { if ( !$user instanceof User ) { - wfDebugLog( $fname, 'Expected all User instances, received:' . + wfDebugLog( $fname, 'Expected all User instances, received: ' . ( is_object( $user ) ? get_class( $user ) : gettype( $user ) ) ); return false; } - if ( $user->isAnon() || isset( $seen[$user->getId()] ) ) { + if ( !$user->isRegistered() || isset( $seen[$user->getId()] ) ) { return false; } $seen[$user->getId()] = true; @@ -474,7 +511,7 @@ class EchoNotificationController { // Don't notify the person who initiated the event unless the event allows it if ( !$event->canNotifyAgent() && $event->getAgent() ) { $agentId = $event->getAgent()->getId(); - $notify->addFilter( function ( $user ) use ( $agentId ) { + $notify->addFilter( static function ( $user ) use ( $agentId ) { return $user->getId() != $agentId; } ); } @@ -487,9 +524,9 @@ class EchoNotificationController { ( $title === null || !( - // Still notify for posts anywhere in - // user's talk space - $title->getRootText() === $user->getName() && + // Still notify for posts on the user's talk page + // (but not subpages, T288112) + $title->getText() === $user->getName() && $title->getNamespace() === NS_USER_TALK ) ) diff --git a/Echo/includes/gateway/UserNotificationGateway.php b/Echo/includes/gateway/UserNotificationGateway.php index d8087715..6685a84d 100644 --- a/Echo/includes/gateway/UserNotificationGateway.php +++ b/Echo/includes/gateway/UserNotificationGateway.php @@ -1,5 +1,7 @@ <?php +use MediaWiki\User\UserIdentity; + /** * Database gateway which handles direct database interaction with the * echo_notification & echo_event for a user, that wouldn't require @@ -13,7 +15,7 @@ class EchoUserNotificationGateway { protected $dbFactory; /** - * @var User + * @var UserIdentity */ protected $user; @@ -36,11 +38,11 @@ class EchoUserNotificationGateway { private $config; /** - * @param User $user + * @param UserIdentity $user * @param MWEchoDbFactory $dbFactory * @param Config $config */ - public function __construct( User $user, MWEchoDbFactory $dbFactory, Config $config ) { + public function __construct( UserIdentity $user, MWEchoDbFactory $dbFactory, Config $config ) { $this->user = $user; $this->dbFactory = $dbFactory; $this->config = $config; @@ -61,7 +63,7 @@ class EchoUserNotificationGateway { return false; } - $dbw = $this->getDB( DB_MASTER ); + $dbw = $this->getDB( DB_PRIMARY ); if ( $dbw->isReadOnly() ) { return false; } @@ -96,7 +98,7 @@ class EchoUserNotificationGateway { return false; } - $dbw = $this->getDB( DB_MASTER ); + $dbw = $this->getDB( DB_PRIMARY ); if ( $dbw->isReadOnly() ) { return false; } @@ -125,7 +127,7 @@ class EchoUserNotificationGateway { * have updateJoin() */ public function markAllRead() { - $dbw = $this->getDB( DB_MASTER ); + $dbw = $this->getDB( DB_PRIMARY ); if ( $dbw->isReadOnly() ) { return false; } @@ -145,7 +147,7 @@ class EchoUserNotificationGateway { /** * Get notification count for the types specified - * @param int $dbSource use master or replica storage to pull count + * @param int $dbSource use primary database or replica storage to pull count * @param array $eventTypesToLoad event types to retrieve * @param int $cap Max count * @return int @@ -156,7 +158,7 @@ class EchoUserNotificationGateway { $cap = MWEchoNotifUser::MAX_BADGE_COUNT ) { // double check - if ( !in_array( $dbSource, [ DB_REPLICA, DB_MASTER ] ) ) { + if ( !in_array( $dbSource, [ DB_REPLICA, DB_PRIMARY ] ) ) { $dbSource = DB_REPLICA; } diff --git a/Echo/includes/iterator/CallbackIterator.php b/Echo/includes/iterator/CallbackIterator.php index c4b7926b..fe47e0ff 100644 --- a/Echo/includes/iterator/CallbackIterator.php +++ b/Echo/includes/iterator/CallbackIterator.php @@ -3,7 +3,8 @@ /** * Applies a callback to all values returned from the iterator */ -class EchoCallbackIterator extends EchoIteratorDecorator { +class EchoCallbackIterator extends IteratorDecorator { + /** @var callable */ protected $callable; public function __construct( Iterator $iterator, $callable ) { diff --git a/Echo/includes/iterator/FilteredSequentialIterator.php b/Echo/includes/iterator/FilteredSequentialIterator.php index 8ed5b2b1..67c67c25 100644 --- a/Echo/includes/iterator/FilteredSequentialIterator.php +++ b/Echo/includes/iterator/FilteredSequentialIterator.php @@ -75,7 +75,7 @@ class EchoFilteredSequentialIterator implements IteratorAggregate { * * @return Iterator */ - public function getIterator() { + public function getIterator(): Iterator { $it = $this->createIterator(); if ( $this->filters ) { $it = new CallbackFilterIterator( $it, $this->createFilter() ); @@ -106,7 +106,7 @@ class EchoFilteredSequentialIterator implements IteratorAggregate { protected function createFilter() { switch ( count( $this->filters ) ) { case 0: - return function () { + return static function () { return true; }; @@ -116,7 +116,7 @@ class EchoFilteredSequentialIterator implements IteratorAggregate { default: $filters = $this->filters; - return function ( $user ) use ( $filters ) { + return static function ( $user ) use ( $filters ) { foreach ( $filters as $filter ) { if ( !call_user_func( $filter, $user ) ) { return false; diff --git a/Echo/includes/iterator/IteratorDecorator.php b/Echo/includes/iterator/IteratorDecorator.php deleted file mode 100644 index 825575da..00000000 --- a/Echo/includes/iterator/IteratorDecorator.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php - -/** - * Allows extending classes to decorate an Iterator with - * reduced boilerplate. - */ -abstract class EchoIteratorDecorator implements Iterator { - protected $iterator; - - public function __construct( Iterator $iterator ) { - $this->iterator = $iterator; - } - - public function current() { - return $this->iterator->current(); - } - - public function key() { - return $this->iterator->key(); - } - - public function next() { - return $this->iterator->next(); - } - - public function rewind() { - return $this->iterator->rewind(); - } - - public function valid() { - return $this->iterator->valid(); - } -} diff --git a/Echo/includes/iterator/MultipleIterator.php b/Echo/includes/iterator/MultipleIterator.php index 02d55d41..2c77a795 100644 --- a/Echo/includes/iterator/MultipleIterator.php +++ b/Echo/includes/iterator/MultipleIterator.php @@ -10,15 +10,18 @@ * * Lots less features(e.g. simple!) */ class EchoMultipleIterator implements RecursiveIterator { + /** @var Iterator[] */ protected $active = []; + /** @var array */ protected $children; + /** @var int */ protected $key = 0; public function __construct( array $children ) { $this->children = $children; } - public function rewind() { + public function rewind(): void { $this->active = $this->children; $this->key = 0; foreach ( $this->active as $key => $it ) { @@ -29,11 +32,11 @@ class EchoMultipleIterator implements RecursiveIterator { } } - public function valid() { + public function valid(): bool { return (bool)$this->active; } - public function next() { + public function next(): void { $this->key++; foreach ( $this->active as $key => $it ) { $it->next(); @@ -43,6 +46,7 @@ class EchoMultipleIterator implements RecursiveIterator { } } + #[\ReturnTypeWillChange] public function current() { $result = []; foreach ( $this->active as $it ) { @@ -52,15 +56,15 @@ class EchoMultipleIterator implements RecursiveIterator { return $result; } - public function key() { + public function key(): int { return $this->key; } - public function hasChildren() { + public function hasChildren(): bool { return (bool)$this->active; } - public function getChildren() { + public function getChildren(): ?RecursiveIterator { // The NotRecursiveIterator is used rather than a RecursiveArrayIterator // so that nested arrays dont get recursed. return new EchoNotRecursiveIterator( new ArrayIterator( $this->current() ) ); diff --git a/Echo/includes/iterator/NotRecursiveIterator.php b/Echo/includes/iterator/NotRecursiveIterator.php index 39b67ae1..4c0ee84a 100644 --- a/Echo/includes/iterator/NotRecursiveIterator.php +++ b/Echo/includes/iterator/NotRecursiveIterator.php @@ -7,13 +7,13 @@ * Alternatively wraps a recursive iterator to prevent recursing deeper * than the wrapped iterator. */ -class EchoNotRecursiveIterator extends EchoIteratorDecorator implements RecursiveIterator { - public function hasChildren() { +class EchoNotRecursiveIterator extends IteratorDecorator implements RecursiveIterator { + public function hasChildren(): bool { return false; } - public function getChildren() { - // @phan-suppress-next-line PhanTypeMismatchReturn Never called + public function getChildren(): ?RecursiveIterator { + // @phan-suppress-next-line PhanTypeMismatchReturnProbablyReal Never called return null; } } diff --git a/Echo/includes/jobs/NotificationDeleteJob.php b/Echo/includes/jobs/NotificationDeleteJob.php index d1ec0c0a..a0aac348 100644 --- a/Echo/includes/jobs/NotificationDeleteJob.php +++ b/Echo/includes/jobs/NotificationDeleteJob.php @@ -1,5 +1,7 @@ <?php +use MediaWiki\MediaWikiServices; + /** * This job is created when sending notifications to the target users. The purpose * of this job is to delete older notifications when the number of notifications a @@ -33,7 +35,7 @@ class EchoNotificationDeleteJob extends Job { foreach ( $this->params['userIds'] as $userId ) { $jobs[] = new EchoNotificationDeleteJob( $this->title, [ 'userIds' => [ $userId ] ] ); } - JobQueueGroup::singleton()->push( $jobs ); + MediaWikiServices::getInstance()->getJobQueueGroup()->push( $jobs ); return true; } diff --git a/Echo/includes/jobs/NotificationJob.php b/Echo/includes/jobs/NotificationJob.php index 06fe226b..d323e29a 100644 --- a/Echo/includes/jobs/NotificationJob.php +++ b/Echo/includes/jobs/NotificationJob.php @@ -3,7 +3,8 @@ class EchoNotificationJob extends Job { public function __construct( Title $title, array $params ) { - parent::__construct( 'EchoNotificationJob', $title, $params ); + $command = isset( $params['jobReleaseTimestamp'] ) ? 'DelayedEchoNotificationJob' : 'EchoNotificationJob'; + parent::__construct( $command, $title, $params ); } public function run() { diff --git a/Echo/includes/mapper/EventMapper.php b/Echo/includes/mapper/EventMapper.php index d1e58919..0a8e3e92 100644 --- a/Echo/includes/mapper/EventMapper.php +++ b/Echo/includes/mapper/EventMapper.php @@ -1,7 +1,5 @@ <?php -use Wikimedia\Rdbms\IResultWrapper; - /** * Database mapper for EchoEvent model, which is an immutable class, there should * not be any update to it @@ -12,10 +10,10 @@ class EchoEventMapper extends EchoAbstractMapper { * Insert an event record * * @param EchoEvent $event - * @return int|false + * @return int */ public function insert( EchoEvent $event ) { - $dbw = $this->dbFactory->getEchoDb( DB_MASTER ); + $dbw = $this->dbFactory->getEchoDb( DB_PRIMARY ); $row = $event->toDbArray(); @@ -35,17 +33,17 @@ class EchoEventMapper extends EchoAbstractMapper { * Create an EchoEvent by id * * @param int $id - * @param bool $fromMaster + * @param bool $fromPrimary * @return EchoEvent|false False if it wouldn't load/unserialize * @throws MWException */ - public function fetchById( $id, $fromMaster = false ) { - $db = $fromMaster ? $this->dbFactory->getEchoDb( DB_MASTER ) : $this->dbFactory->getEchoDb( DB_REPLICA ); + public function fetchById( $id, $fromPrimary = false ) { + $db = $fromPrimary ? $this->dbFactory->getEchoDb( DB_PRIMARY ) : $this->dbFactory->getEchoDb( DB_REPLICA ); $row = $db->selectRow( 'echo_event', EchoEvent::selectFields(), [ 'event_id' => $id ], __METHOD__ ); - // If the row was not found, fall back on the master if it makes sense to do so - if ( !$row && !$fromMaster && $this->dbFactory->canRetryMaster() ) { + // If the row was not found, fall back on the primary database if it makes sense to do so + if ( !$row && !$fromPrimary && $this->dbFactory->canRetryPrimary() ) { return $this->fetchById( $id, true ); } elseif ( !$row ) { throw new MWException( "No EchoEvent found with ID: $id" ); @@ -57,10 +55,9 @@ class EchoEventMapper extends EchoAbstractMapper { /** * @param int[] $eventIds * @param bool $deleted - * @return bool|IResultWrapper */ public function toggleDeleted( array $eventIds, $deleted ) { - $dbw = $this->dbFactory->getEchoDb( DB_MASTER ); + $dbw = $this->dbFactory->getEchoDb( DB_PRIMARY ); $selectDeleted = $deleted ? 0 : 1; $setDeleted = $deleted ? 1 : 0; @@ -75,8 +72,6 @@ class EchoEventMapper extends EchoAbstractMapper { ], __METHOD__ ); - - return true; } /** @@ -117,7 +112,7 @@ class EchoEventMapper extends EchoAbstractMapper { EchoEvent::selectFields(), $conds, __METHOD__, - [ 'GROUP BY' => 'etp_event' ], + [ 'DISTINCT' ], [ 'echo_target_page' => [ 'INNER JOIN', 'event_id=etp_event' ] ] ); if ( $res ) { @@ -138,7 +133,7 @@ class EchoEventMapper extends EchoAbstractMapper { public function fetchIdsByPage( $pageId ) { $events = $this->fetchByPage( $pageId ); $eventIds = array_map( - function ( EchoEvent $event ) { + static function ( EchoEvent $event ) { return $event->getId(); }, $events @@ -188,7 +183,7 @@ class EchoEventMapper extends EchoAbstractMapper { * An event is orphaned if it is not referred to by any rows in the echo_notification or * echo_email_batch tables. If $ignoreUserId is set, rows for that user are not considered when * determining orphanhood; if $ignoreUserTable is set, this only applies to that table. - * Use this when you've just recently deleted rows related to this user on the master, so that + * Use this when you've just recently deleted rows related to this user on the primary database, so that * this function won't refuse to delete recently-orphaned events because it still sees the * recently-deleted rows on the replica. * @@ -199,7 +194,7 @@ class EchoEventMapper extends EchoAbstractMapper { * ('echo_notification' or 'echo_email_batch') */ public function deleteOrphanedEvents( array $eventIds, $ignoreUserId = null, $ignoreUserTable = null ) { - $dbw = $this->dbFactory->getEchoDb( DB_MASTER ); + $dbw = $this->dbFactory->getEchoDb( DB_PRIMARY ); $dbr = $this->dbFactory->getEchoDb( DB_REPLICA ); $notifJoinConds = []; diff --git a/Echo/includes/mapper/NotificationMapper.php b/Echo/includes/mapper/NotificationMapper.php index 4e572a78..37b4c620 100644 --- a/Echo/includes/mapper/NotificationMapper.php +++ b/Echo/includes/mapper/NotificationMapper.php @@ -1,6 +1,7 @@ <?php use MediaWiki\MediaWikiServices; +use MediaWiki\User\UserIdentity; use Wikimedia\Rdbms\IDatabase; /** @@ -11,10 +12,9 @@ class EchoNotificationMapper extends EchoAbstractMapper { /** * Insert a notification record * @param EchoNotification $notification - * @return null */ public function insert( EchoNotification $notification ) { - $dbw = $this->dbFactory->getEchoDb( DB_MASTER ); + $dbw = $this->dbFactory->getEchoDb( DB_PRIMARY ); $listeners = $this->getMethodListeners( __FUNCTION__ ); @@ -22,9 +22,11 @@ class EchoNotificationMapper extends EchoAbstractMapper { DeferredUpdates::addUpdate( new AtomicSectionUpdate( $dbw, __METHOD__, - function ( IDatabase $dbw, $fname ) use ( $row, $listeners ) { + static function ( IDatabase $dbw, $fname ) use ( $row, $listeners ) { $row['notification_timestamp'] = $dbw->timestamp( $row['notification_timestamp'] ); + $row['notification_read_timestamp'] = + $dbw->timestampOrNull( $row['notification_read_timestamp'] ); $dbw->insert( 'echo_notification', $row, $fname ); foreach ( $listeners as $listener ) { $dbw->onTransactionCommitOrIdle( $listener, $fname ); @@ -62,17 +64,17 @@ class EchoNotificationMapper extends EchoAbstractMapper { * unread notifications but it's not optimized for ordering by timestamp. The * descending order is only allowed if we keep the notification in low volume, * which is done via a deleteJob - * @param User $user + * @param UserIdentity $userIdentity * @param int $limit * @param string|null $continue Used for offset * @param string[] $eventTypes * @param Title[]|null $titles If set, only return notifications for these pages. * To find notifications not associated with any page, add null as an element to this array. - * @param int $dbSource Use master or replica database + * @param int $dbSource Use primary database or replica database * @return EchoNotification[] */ public function fetchUnreadByUser( - User $user, + UserIdentity $userIdentity, $limit, $continue, array $eventTypes = [], @@ -86,7 +88,14 @@ class EchoNotificationMapper extends EchoAbstractMapper { return []; } } - return $this->fetchByUserInternal( $user, $limit, $continue, $eventTypes, $conds, $dbSource ); + return $this->fetchByUserInternal( + $userIdentity, + $limit, + $continue, + $eventTypes, + $conds, + $dbSource + ); } /** @@ -95,17 +104,17 @@ class EchoNotificationMapper extends EchoAbstractMapper { * unread notifications but it's not optimized for ordering by timestamp. The * descending order is only allowed if we keep the notification in low volume, * which is done via a deleteJob - * @param User $user + * @param UserIdentity $userIdentity * @param int $limit * @param string|null $continue Used for offset * @param string[] $eventTypes * @param Title[]|null $titles If set, only return notifications for these pages. * To find notifications not associated with any page, add null as an element to this array. - * @param int $dbSource Use master or replica database + * @param int $dbSource Use primary database or replica database * @return EchoNotification[] */ public function fetchReadByUser( - User $user, + UserIdentity $userIdentity, $limit, $continue, array $eventTypes = [], @@ -119,13 +128,20 @@ class EchoNotificationMapper extends EchoAbstractMapper { return []; } } - return $this->fetchByUserInternal( $user, $limit, $continue, $eventTypes, $conds, $dbSource ); + return $this->fetchByUserInternal( + $userIdentity, + $limit, + $continue, + $eventTypes, + $conds, + $dbSource + ); } /** * Get Notification by user in batch along with limit, offset etc * - * @param User $user the user to get notifications for + * @param UserIdentity $userIdentity the user to get notifications for * @param int $limit The maximum number of notifications to return * @param string|null $continue Used for offset * @param array $eventTypes Event types to load @@ -135,7 +151,7 @@ class EchoNotificationMapper extends EchoAbstractMapper { * @return EchoNotification[] */ public function fetchByUser( - User $user, + UserIdentity $userIdentity, $limit, $continue, array $eventTypes = [], @@ -155,7 +171,13 @@ class EchoNotificationMapper extends EchoAbstractMapper { } } - return $this->fetchByUserInternal( $user, $limit, $continue, $eventTypes, $conds ); + return $this->fetchByUserInternal( + $userIdentity, + $limit, + $continue, + $eventTypes, + $conds + ); } protected function getIdsForTitles( array $titles ) { @@ -171,16 +193,16 @@ class EchoNotificationMapper extends EchoAbstractMapper { } /** - * @param User $user the user to get notifications for + * @param UserIdentity $userIdentity the user to get notifications for * @param int $limit The maximum number of notifications to return * @param string|null $continue Used for offset * @param array $eventTypes Event types to load * @param array $conds Additional query conditions. - * @param int $dbSource Use master or replica database + * @param int $dbSource Use primary database or replica database * @return EchoNotification[] */ protected function fetchByUserInternal( - User $user, + UserIdentity $userIdentity, $limit, $continue, array $eventTypes = [], @@ -200,7 +222,7 @@ class EchoNotificationMapper extends EchoAbstractMapper { // the notification volume is in a reasonable amount for such case. The other option // is to denormalize notification table with event_type and lookup index. $conds = [ - 'notification_user' => $user->getId(), + 'notification_user' => $userIdentity->getId(), 'event_type' => $eventTypes, 'event_deleted' => 0, ] + $conds; @@ -260,18 +282,18 @@ class EchoNotificationMapper extends EchoAbstractMapper { /** * Fetch EchoNotifications by user and event IDs. * - * @param User $user + * @param UserIdentity $userIdentity * @param int[] $eventIds * @return EchoNotification[]|false */ - public function fetchByUserEvents( User $user, array $eventIds ) { + public function fetchByUserEvents( UserIdentity $userIdentity, array $eventIds ) { $dbr = $this->dbFactory->getEchoDb( DB_REPLICA ); $result = $dbr->select( [ 'echo_notification', 'echo_event' ], EchoNotification::selectFields(), [ - 'notification_user' => $user->getId(), + 'notification_user' => $userIdentity->getId(), 'notification_event' => $eventIds ], __METHOD__, @@ -295,17 +317,17 @@ class EchoNotificationMapper extends EchoAbstractMapper { /** * Fetch a notification by user in the specified offset. The caller should * know that passing a big number for offset is NOT going to work - * @param User $user + * @param UserIdentity $userIdentity * @param int $offset * @return EchoNotification|false */ - public function fetchByUserOffset( User $user, $offset ) { + public function fetchByUserOffset( UserIdentity $userIdentity, $offset ) { $dbr = $this->dbFactory->getEchoDb( DB_REPLICA ); $row = $dbr->selectRow( [ 'echo_notification', 'echo_event' ], EchoNotification::selectFields(), [ - 'notification_user' => $user->getId(), + 'notification_user' => $userIdentity->getId(), 'event_deleted' => 0, ], __METHOD__, @@ -328,15 +350,15 @@ class EchoNotificationMapper extends EchoAbstractMapper { /** * Batch delete notifications by user and eventId offset - * @param User $user + * @param UserIdentity $userIdentity * @param int $eventId * @return bool */ - public function deleteByUserEventOffset( User $user, $eventId ) { + public function deleteByUserEventOffset( UserIdentity $userIdentity, $eventId ) { global $wgUpdateRowsPerQuery; $eventMapper = new EchoEventMapper( $this->dbFactory ); - $userId = $user->getId(); - $dbw = $this->dbFactory->getEchoDb( DB_MASTER ); + $userId = $userIdentity->getId(); + $dbw = $this->dbFactory->getEchoDb( DB_PRIMARY ); $dbr = $this->dbFactory->getEchoDb( DB_REPLICA ); $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory(); $ticket = $lbFactory->getEmptyTransactionTicket( __METHOD__ ); @@ -352,6 +374,7 @@ class EchoNotificationMapper extends EchoAbstractMapper { 'notification_user' => $userId, 'notification_event < ' . (int)$eventId ] ); + $iterator->setCaller( __METHOD__ ); foreach ( $iterator as $batch ) { $eventIds = []; diff --git a/Echo/includes/mapper/TargetPageMapper.php b/Echo/includes/mapper/TargetPageMapper.php index 91699722..698940fb 100644 --- a/Echo/includes/mapper/TargetPageMapper.php +++ b/Echo/includes/mapper/TargetPageMapper.php @@ -21,7 +21,7 @@ class EchoTargetPageMapper extends EchoAbstractMapper { * @return bool */ public function insert( EchoTargetPage $targetPage ) { - $dbw = $this->dbFactory->getEchoDb( DB_MASTER ); + $dbw = $this->dbFactory->getEchoDb( DB_PRIMARY ); $row = $targetPage->toDbArray(); diff --git a/Echo/includes/model/Event.php b/Echo/includes/model/Event.php index 87dcffae..42a007f6 100644 --- a/Echo/includes/model/Event.php +++ b/Echo/includes/model/Event.php @@ -3,6 +3,7 @@ use MediaWiki\Logger\LoggerFactory; use MediaWiki\MediaWikiServices; use MediaWiki\Revision\RevisionRecord; +use MediaWiki\User\UserIdentity; /** * Immutable class to represent an event. @@ -101,7 +102,19 @@ class EchoEvent extends EchoAbstractEntity implements Bundleable { * variant: A variant of the type; * agent: The user who caused the event; * title: The page on which the event was triggered; - * extra: Event-specific extra information (e.g. post content) + * extra: Event-specific extra information (e.g. post content, delay time, root job params). + * + * Delayed jobs extra params: + * delay: Amount of time in seconds for the notification to be delayed + * + * Job deduplication extra params: + * rootJobSignature: The sha1 signature of the job + * rootJobTimestamp: The timestamp when the job gets submitted + * + * For example to enqueue a new `example` root job or make a parent job + * no-op when submitting a new notification you need to pass this extra params: + * + * [ 'extra' => Job::newRootJobParams('example') ] * * @throws MWException * @return EchoEvent|false False if aborted via hook or Echo DB is read-only @@ -110,8 +123,8 @@ class EchoEvent extends EchoAbstractEntity implements Bundleable { global $wgEchoNotifications; // Do not create event and notifications if write access is locked - if ( wfReadOnly() - || MWEchoDbFactory::newFromDefault()->getEchoDb( DB_MASTER )->isReadOnly() + if ( MediaWikiServices::getInstance()->getReadOnlyMode()->isReadOnly() + || MWEchoDbFactory::newFromDefault()->getEchoDb( DB_PRIMARY )->isReadOnly() ) { return false; } @@ -128,12 +141,7 @@ class EchoEvent extends EchoAbstractEntity implements Bundleable { } $obj->id = false; - if ( isset( $info['timestamp'] ) && $info[ 'timestamp' ] !== null ) { - $obj->timestamp = $info['timestamp']; - } else { - $obj->timestamp = wfTimestampNow(); - } - + $obj->timestamp = $info['timestamp'] ?? wfTimestampNow(); foreach ( $validFields as $field ) { if ( isset( $info[$field] ) ) { $obj->$field = $info[$field]; @@ -157,8 +165,15 @@ class EchoEvent extends EchoAbstractEntity implements Bundleable { $obj->setTitle( $obj->title ); } - if ( $obj->agent && !$obj->agent instanceof User ) { - throw new InvalidArgumentException( "Invalid user parameter" ); + if ( $obj->agent ) { + if ( !$obj->agent instanceof UserIdentity ) { + throw new InvalidArgumentException( "Invalid user parameter" ); + } + + // RevisionStore returns UserIdentityValue now, convert to User for passing to hooks. + if ( !$obj->agent instanceof User ) { + $obj->agent = MediaWikiServices::getInstance()->getUserFactory()->newFromUserIdentity( $obj->agent ); + } } if ( !Hooks::run( 'BeforeEchoEventInsert', [ $obj ] ) ) { @@ -174,6 +189,11 @@ class EchoEvent extends EchoAbstractEntity implements Bundleable { EchoNotificationController::notify( $obj, $wgEchoUseJobQueue ); + $stats = MediaWikiServices::getInstance()->getStatsdDataFactory(); + $type = $info['type']; + $stats->increment( 'echo.event.all' ); + $stats->increment( "echo.event.$type" ); + return $obj; } @@ -192,7 +212,7 @@ class EchoEvent extends EchoAbstractEntity implements Bundleable { $data['event_id'] = $this->id; } if ( $this->agent ) { - if ( $this->agent->isAnon() ) { + if ( !$this->agent->isRegistered() ) { $data['event_agent_ip'] = $this->agent->getName(); } else { $data['event_agent_id'] = $this->agent->getId(); @@ -217,13 +237,9 @@ class EchoEvent extends EchoAbstractEntity implements Bundleable { * Check whether the echo event is an enabled event * @return bool */ - public function isEnabledEvent() { + public function isEnabledEvent(): bool { global $wgEchoNotifications; - if ( isset( $wgEchoNotifications[$this->getType()] ) ) { - return true; - } else { - return false; - } + return isset( $wgEchoNotifications[$this->getType()] ); } /** @@ -260,7 +276,7 @@ class EchoEvent extends EchoAbstractEntity implements Bundleable { foreach ( $targetPageIds as $targetPageId ) { // Make sure the target-page id is a valid id $title = Title::newFromID( $targetPageId ); - // Try master if there is no match + // Try primary database if there is no match if ( !$title ) { $title = Title::newFromID( $targetPageId, Title::GAID_FOR_UPDATE ); } @@ -308,10 +324,9 @@ class EchoEvent extends EchoAbstractEntity implements Bundleable { $this->deleted = $row->event_deleted; if ( $row->event_agent_id ) { - $this->agent = User::newFromId( $row->event_agent_id ); + $this->agent = User::newFromId( (int)$row->event_agent_id ); } elseif ( $row->event_agent_ip ) { - // @phan-suppress-next-line PhanTypeMismatchArgument Not null here - $this->agent = User::newFromName( $row->event_agent_ip, false ); + $this->agent = User::newFromName( (string)$row->event_agent_ip, false ); } // Lazy load the title from getTitle() so that we can do a batch-load @@ -326,8 +341,7 @@ class EchoEvent extends EchoAbstractEntity implements Bundleable { } if ( $row->event_page_id ) { $titleCache = EchoTitleLocalCache::create(); - // @phan-suppress-next-line PhanTypeMismatchArgument Not null here - $titleCache->add( $row->event_page_id ); + $titleCache->add( (int)$row->event_page_id ); } if ( isset( $this->extra['revid'] ) && $this->extra['revid'] ) { $revisionCache = EchoRevisionLocalCache::create(); @@ -340,12 +354,12 @@ class EchoEvent extends EchoAbstractEntity implements Bundleable { /** * Loads data from the database into this object, given the event ID. * @param int $id Event ID - * @param bool $fromMaster + * @param bool $fromPrimary * @return bool Whether it loaded successfully */ - public function loadFromID( $id, $fromMaster = false ) { + public function loadFromID( $id, $fromPrimary = false ) { $eventMapper = new EchoEventMapper(); - $event = $eventMapper->fetchById( $id, $fromMaster ); + $event = $eventMapper->fetchById( $id, $fromPrimary ); if ( !$event ) { return false; } @@ -439,7 +453,8 @@ class EchoEvent extends EchoAbstractEntity implements Bundleable { } else { // Use User::isHidden() $permManager = MediaWikiServices::getInstance()->getPermissionManager(); - return $permManager->userHasAnyRight( $user, 'viewsuppressed', 'hideuser' ) || !$agent->isHidden(); + return $permManager->userHasAnyRight( $user, 'viewsuppressed', 'hideuser' ) + || !$agent->isHidden(); } } elseif ( $revision ) { // A revision is set, use rev_deleted @@ -487,6 +502,11 @@ class EchoEvent extends EchoAbstractEntity implements Bundleable { return $this->extra; } + /** + * @param string $key + * @param mixed|null $default + * @return mixed|null + */ public function getExtraParam( $key, $default = null ) { return $this->extra[$key] ?? $default; } @@ -502,7 +522,7 @@ class EchoEvent extends EchoAbstractEntity implements Bundleable { * Check whether this event allows its agent to be notified. * * Notifying the agent is only allowed if the event's type allows it, or if the event extra - * explicity specifies 'notifyAgent' => true. + * explicitly specifies 'notifyAgent' => true. * * @return bool */ @@ -514,30 +534,32 @@ class EchoEvent extends EchoAbstractEntity implements Bundleable { } /** - * @param bool $fromMaster + * @param bool $fromPrimary * @return null|Title */ - public function getTitle( $fromMaster = false ) { + public function getTitle( $fromPrimary = false ) { if ( $this->title ) { return $this->title; - } elseif ( $this->pageId ) { + } + if ( $this->pageId ) { $titleCache = EchoTitleLocalCache::create(); $title = $titleCache->get( $this->pageId ); if ( $title ) { $this->title = $title; return $this->title; } - - $this->title = Title::newFromID( $this->pageId, $fromMaster ? Title::GAID_FOR_UPDATE : 0 ); - return $this->title; - } elseif ( isset( $this->extra['page_title'] ) && isset( $this->extra['page_namespace'] ) ) { + $this->title = Title::newFromID( $this->pageId, $fromPrimary ? Title::GAID_FOR_UPDATE : 0 ); + if ( $this->title ) { + return $this->title; + } + } + if ( isset( $this->extra['page_title'] ) && isset( $this->extra['page_namespace'] ) ) { $this->title = Title::makeTitleSafe( $this->extra['page_namespace'], $this->extra['page_title'] ); return $this->title; } - return null; } @@ -570,7 +592,7 @@ class EchoEvent extends EchoAbstractEntity implements Bundleable { * @return string */ public function getCategory() { - $attributeManager = EchoAttributeManager::newFromGlobalVars(); + $attributeManager = EchoServices::getInstance()->getAttributeManager(); return $attributeManager->getNotificationCategory( $this->type ); } @@ -580,7 +602,7 @@ class EchoEvent extends EchoAbstractEntity implements Bundleable { * @return string */ public function getSection() { - $attributeManager = EchoAttributeManager::newFromGlobalVars(); + $attributeManager = EchoServices::getInstance()->getAttributeManager(); return $attributeManager->getNotificationSection( $this->type ); } diff --git a/Echo/includes/model/Notification.php b/Echo/includes/model/Notification.php index 5ace7154..f4684ee4 100644 --- a/Echo/includes/model/Notification.php +++ b/Echo/includes/model/Notification.php @@ -28,7 +28,7 @@ class EchoNotification extends EchoAbstractEntity implements Bundleable { protected $timestamp; /** - * @var string + * @var string|null */ protected $readTimestamp; @@ -114,7 +114,7 @@ class EchoNotification extends EchoAbstractEntity implements Bundleable { // Add listener to refresh notification count upon insert $notifMapper->attachListener( 'insert', 'refresh-notif-count', - function () use ( $notifUser ) { + static function () use ( $notifUser ) { $notifUser->resetNotificationCount(); } ); @@ -152,11 +152,7 @@ class EchoNotification extends EchoAbstractEntity implements Bundleable { $notification->user = User::newFromId( $row->notification_user ); // Notification timestamp should never be empty $notification->timestamp = wfTimestamp( TS_MW, $row->notification_timestamp ); - // Only convert to MW format if it is not empty, otherwise - // wfTimestamp would use current timestamp for empty cases - if ( $row->notification_read_timestamp ) { - $notification->readTimestamp = wfTimestamp( TS_MW, $row->notification_read_timestamp ); - } + $notification->readTimestamp = wfTimestampOrNull( TS_MW, $row->notification_read_timestamp ); $notification->bundleHash = $row->notification_bundle_hash; return $notification; diff --git a/Echo/includes/schemaUpdate.php b/Echo/includes/schemaUpdate.php index 4ca3a8ae..7184c07c 100644 --- a/Echo/includes/schemaUpdate.php +++ b/Echo/includes/schemaUpdate.php @@ -102,7 +102,7 @@ class EchoSuppressionRowUpdateGenerator implements RowUpdateGenerator { /** * Return the extra data for a row, if an update wants to change the - * extra data returns that updated data rather than the origional. If + * extra data returns that updated data rather than the original. If * no extra data exists returns array() * * @param stdClass $row The database row being updated diff --git a/Echo/includes/special/NotificationPager.php b/Echo/includes/special/NotificationPager.php index 2dfc1238..cfa4b75f 100644 --- a/Echo/includes/special/NotificationPager.php +++ b/Echo/includes/special/NotificationPager.php @@ -17,12 +17,13 @@ class NotificationPager extends ReverseChronologicalPager { } public function formatRow( $row ) { + // @phan-suppress-previous-line PhanPluginNeverReturnMethod LSP violation throw new Exception( "This pager does not support row formatting. " . "Use 'getNotifications()' to get a list of EchoNotification objects." ); } public function getQueryInfo() { - $attributeManager = EchoAttributeManager::newFromGlobalVars(); + $attributeManager = EchoServices::getInstance()->getAttributeManager(); $eventTypes = $attributeManager->getUserEnabledEvents( $this->getUser(), 'web' ); return [ diff --git a/Echo/includes/special/SpecialDisplayNotificationsConfiguration.php b/Echo/includes/special/SpecialDisplayNotificationsConfiguration.php index c644c043..00bc01da 100644 --- a/Echo/includes/special/SpecialDisplayNotificationsConfiguration.php +++ b/Echo/includes/special/SpecialDisplayNotificationsConfiguration.php @@ -1,24 +1,20 @@ <?php +use MediaWiki\Extension\Notifications\Hooks as EchoHooks; +use MediaWiki\User\UserOptionsManager; + class SpecialDisplayNotificationsConfiguration extends UnlistedSpecialPage { /** * EchoAttributeManager to access notification configuration * - * @var EchoAttributeManager $attributeManager; + * @var EchoAttributeManager */ protected $attributeManager; /** - * Notification controller - * - * @var EchoNotificationController $notificationController; - */ - protected $notificationController; - - /** * Category names, mapping internal name to HTML-formatted name * - * @var string[] $categoryNames + * @var string[] */ protected $categoryNames; @@ -27,14 +23,14 @@ class SpecialDisplayNotificationsConfiguration extends UnlistedSpecialPage { /** * Notification type names. Mapping HTML-formatted internal name to internal name * - * @var string[] $notificationTypeNames + * @var string[] */ protected $notificationTypeNames; /** * Notify types, mapping internal name to HTML-formatted name * - * @var string[] $notifyTypes + * @var string[] */ protected $notifyTypes; @@ -42,22 +38,34 @@ class SpecialDisplayNotificationsConfiguration extends UnlistedSpecialPage { /** * Category names, mapping HTML-formatted name to internal name * - * @var string[] $flippedCategoryNames + * @var string[] */ protected $flippedCategoryNames; /** * Notify types, mapping HTML-formatted name to internal name * - * @var string[] $flippedNotifyTypes + * @var string[] */ protected $flippedNotifyTypes; - public function __construct() { + /** + * @var UserOptionsManager + */ + private $userOptionsManager; + + /** + * @param EchoAttributeManager $attributeManager + * @param UserOptionsManager $userOptionsManager + */ + public function __construct( + EchoAttributeManager $attributeManager, + UserOptionsManager $userOptionsManager + ) { parent::__construct( 'DisplayNotificationsConfiguration' ); - $this->attributeManager = EchoAttributeManager::newFromGlobalVars(); - $this->notificationController = new EchoNotificationController(); + $this->attributeManager = $attributeManager; + $this->userOptionsManager = $userOptionsManager; } public function execute( $subPage ) { @@ -136,7 +144,7 @@ class SpecialDisplayNotificationsConfiguration extends UnlistedSpecialPage { array $columnLabelMapping, array $value ) { - $form = new HTMLForm( + $form = new OOUIHTMLForm( [ $id => [ 'type' => 'checkmatrix', @@ -262,14 +270,20 @@ class SpecialDisplayNotificationsConfiguration extends UnlistedSpecialPage { $this->msg( 'echo-displaynotificationsconfiguration-enabled-default-header' )->text() ) ); + // Some of the preferences are mapped to existing ones defined in core MediaWiki + $virtualOptions = EchoHooks::getVirtualUserOptions(); + // In reality, anon users are not relevant to Echo, but this lets us easily query default options. $anonUser = new User; $byCategoryValueExisting = []; foreach ( $this->notifyTypes as $notifyType => $displayNotifyType ) { foreach ( $this->categoryNames as $category => $displayCategory ) { - $tag = "$notifyType-$category"; - if ( $anonUser->getOption( "echo-subscriptions-$tag" ) ) { + $prefKey = "echo-subscriptions-$notifyType-$category"; + if ( isset( $virtualOptions[ $prefKey ] ) ) { + $prefKey = $virtualOptions[ $prefKey ]; + } + if ( $this->userOptionsManager->getOption( $anonUser, $prefKey ) ) { $byCategoryValueExisting[] = "$notifyType-$category"; } } @@ -288,14 +302,17 @@ class SpecialDisplayNotificationsConfiguration extends UnlistedSpecialPage { // We can't run the actual hook, to avoid side effects. $overrides = EchoHooks::getNewUserPreferenceOverrides(); foreach ( $overrides as $prefKey => $value ) { - $loggedInUser->setOption( $prefKey, $value ); + $this->userOptionsManager->setOption( $loggedInUser, $prefKey, $value ); } $byCategoryValueNew = []; foreach ( $this->notifyTypes as $notifyType => $displayNotifyType ) { foreach ( $this->categoryNames as $category => $displayCategory ) { - $tag = "$notifyType-$category"; - if ( $loggedInUser->getOption( "echo-subscriptions-$tag" ) ) { + $prefKey = "echo-subscriptions-$notifyType-$category"; + if ( isset( $virtualOptions[ $prefKey ] ) ) { + $prefKey = $virtualOptions[ $prefKey ]; + } + if ( $this->userOptionsManager->getOption( $loggedInUser, $prefKey ) ) { $byCategoryValueNew[] = "$notifyType-$category"; } } diff --git a/Echo/includes/special/SpecialNotifications.php b/Echo/includes/special/SpecialNotifications.php index 3c775628..4ae78a62 100644 --- a/Echo/includes/special/SpecialNotifications.php +++ b/Echo/includes/special/SpecialNotifications.php @@ -1,11 +1,13 @@ <?php +use MediaWiki\Extension\Notifications\OOUI\LabelIconWidget; + class SpecialNotifications extends SpecialPage { /** * Number of notification records to display per page/load */ - const DISPLAY_NUM = 20; + private const DISPLAY_NUM = 20; public function __construct() { parent::__construct( 'Notifications' ); @@ -23,11 +25,11 @@ class SpecialNotifications extends SpecialPage { $this->addHelpLink( 'Help:Notifications/Special:Notifications' ); $out->addJsConfigVars( 'wgNotificationsSpecialPageLinks', [ - 'preferences' => SpecialPage::getTitleFor( 'Preferences' )->getLinkURL() . '#mw-prefsection-echo', + 'preferences' => SpecialPage::getTitleFor( 'Preferences', false, 'mw-prefsection-echo' )->getLinkURL(), ] ); $user = $this->getUser(); - if ( $user->isAnon() ) { + if ( !$user->isRegistered() ) { // Redirect to login page and inform user of the need to login $this->requireLogin( 'echo-notification-loginrequired' ); return; @@ -66,7 +68,6 @@ class SpecialNotifications extends SpecialPage { // Add the notifications to the page (interspersed with date headers) $dateHeader = ''; - $unread = []; $anyUnread = false; $echoSeenTime = EchoSeenTime::newFromUser( $user ); $seenTime = $echoSeenTime->getTime(); @@ -78,13 +79,6 @@ class SpecialNotifications extends SpecialPage { $classes = [ 'mw-echo-notification' ]; - if ( !isset( $row['read'] ) ) { - $classes[] = 'mw-echo-notification-unread'; - if ( !$row['targetpages'] ) { - $unread[] = $row['id']; - } - } - if ( $seenTime !== null && $row['timestamp']['mw'] > $seenTime ) { $classes[] = 'mw-echo-notification-unseen'; } @@ -92,14 +86,15 @@ class SpecialNotifications extends SpecialPage { // Output the date header if it has not been displayed if ( $dateHeader !== $row['timestamp']['date'] ) { $dateHeader = $row['timestamp']['date']; - $notifArray[ $dateHeader ] = [ - 'unread' => [], - 'notices' => [] - ]; } + $notifArray[ $dateHeader ] = [ + 'unread' => [], + 'notices' => [] + ]; // Collect unread IDs if ( !isset( $row['read'] ) ) { + $classes[] = 'mw-echo-notification-unread'; $anyUnread = true; $notifArray[ $dateHeader ][ 'unread' ][] = $row['id']; } @@ -125,7 +120,7 @@ class SpecialNotifications extends SpecialPage { $markReadSpecialPage->setContext( $this->getContext() ); $markAllAsReadText = $this->msg( 'echo-mark-all-as-read' )->text(); - $markAllAsReadLabelIcon = new EchoOOUI\LabelIconWidget( [ + $markAllAsReadLabelIcon = new LabelIconWidget( [ 'label' => $markAllAsReadText, 'icon' => 'checkAll', ] ); @@ -167,7 +162,7 @@ class SpecialNotifications extends SpecialPage { $out->addJsConfigVars( 'wgEchoReadState', 'unread' ); $markReadSectionText = $this->msg( 'echo-specialpage-section-markread' )->text(); - $markAsReadLabelIcon = new EchoOOUI\LabelIconWidget( [ + $markAsReadLabelIcon = new LabelIconWidget( [ 'label' => $markReadSectionText, 'icon' => 'checkAll', ] ); @@ -194,6 +189,7 @@ class SpecialNotifications extends SpecialPage { // is an array $notices ->appendContent( $heading ) + // @phan-suppress-next-line PhanTypePossiblyInvalidDimOffset https://github.com/phan/phan/issues/4735 ->appendContent( $data[ 'notices' ] ); } @@ -231,8 +227,8 @@ class SpecialNotifications extends SpecialPage { $out->addModuleStyles( [ 'ext.echo.styles.notifications', 'ext.echo.styles.special', - // We already load OOUI icons in the BeforePageDisplay hook, but not for minerva - 'oojs-ui.styles.icons-alerts' + 'oojs-ui.styles.icons-alerts', + 'oojs-ui.styles.icons-interactions', ] ); // Log visit @@ -250,7 +246,7 @@ class SpecialNotifications extends SpecialPage { $subtitleLinks[] = Html::element( 'a', [ - 'href' => SpecialPage::getTitleFor( 'Preferences' )->getLinkURL() . '#mw-prefsection-echo', + 'href' => SpecialPage::getTitleFor( 'Preferences', false, 'mw-prefsection-echo' )->getLinkURL(), 'id' => 'mw-echo-pref-link', 'class' => 'mw-echo-special-header-link', 'title' => $this->msg( 'preferences' )->text() diff --git a/Echo/includes/special/SpecialNotificationsMarkRead.php b/Echo/includes/special/SpecialNotificationsMarkRead.php index bac4d8a8..ad501677 100644 --- a/Echo/includes/special/SpecialNotificationsMarkRead.php +++ b/Echo/includes/special/SpecialNotificationsMarkRead.php @@ -9,8 +9,6 @@ * page should normally not need to be visited directly. */ class SpecialNotificationsMarkRead extends FormSpecialPage { - protected $eventId; - public function __construct() { parent::__construct( 'NotificationsMarkRead' ); } @@ -47,7 +45,7 @@ class SpecialNotificationsMarkRead extends FormSpecialPage { 'type' => 'hidden', 'required' => true, 'default' => $this->par, - 'filter-callback' => function ( $value, $alldata ) { + 'filter-callback' => static function ( $value, $alldata ) { // Allow for a single value or a set of values $result = explode( ',', $value ); return $result; @@ -102,10 +100,7 @@ class SpecialNotificationsMarkRead extends FormSpecialPage { // places on the page, it has to be neutral, so we make the button // manually. $form->suppressDefaultSubmit(); - - $pageTitle = $this->getPageTitle(); - $form->setTitle( $pageTitle ); - $form->setAction( $pageTitle->getLocalURL() ); + $form->setTitle( $this->getPageTitle() ); $form->addButton( [ 'name' => 'submit', diff --git a/Echo/maintenance/backfillUnreadWikis.php b/Echo/maintenance/backfillUnreadWikis.php index dd8044a7..4877b12e 100644 --- a/Echo/maintenance/backfillUnreadWikis.php +++ b/Echo/maintenance/backfillUnreadWikis.php @@ -1,5 +1,7 @@ <?php +use MediaWiki\MediaWikiServices; + $IP = getenv( 'MW_INSTALL_PATH' ); if ( $IP === false ) { $IP = __DIR__ . '/../../..'; @@ -18,7 +20,7 @@ class BackfillUnreadWikis extends Maintenance { public function execute() { $dbFactory = MWEchoDbFactory::newFromDefault(); - $lookup = CentralIdLookup::factory(); + $lookup = MediaWikiServices::getInstance()->getCentralIdLookup(); $rebuild = $this->hasOption( 'rebuild' ); if ( $rebuild ) { @@ -26,29 +28,34 @@ class BackfillUnreadWikis extends Maintenance { $dbFactory->getSharedDb( DB_REPLICA ), 'echo_unread_wikis', 'euw_user', - $this->mBatchSize + $this->getBatchSize() ); - $iterator->addConditions( [ 'euw_wiki' => wfWikiID() ] ); + $iterator->addConditions( [ 'euw_wiki' => WikiMap::getCurrentWikiId() ] ); } else { $userQuery = User::getQueryInfo(); $iterator = new BatchRowIterator( - wfGetDB( DB_REPLICA ), $userQuery['tables'], 'user_id', $this->mBatchSize + wfGetDB( DB_REPLICA ), $userQuery['tables'], 'user_id', $this->getBatchSize() ); $iterator->setFetchColumns( $userQuery['fields'] ); $iterator->addJoinConditions( $userQuery['joins'] ); } + $iterator->setCaller( __METHOD__ ); + $processed = 0; foreach ( $iterator as $batch ) { foreach ( $batch as $row ) { if ( $rebuild ) { - $user = $lookup->localUserFromCentralId( $row->euw_user, CentralIdLookup::AUDIENCE_RAW ); + $user = $lookup->localUserFromCentralId( + $row->euw_user, + CentralIdLookup::AUDIENCE_RAW + ); + if ( !$user ) { + continue; + } } else { $user = User::newFromRow( $row ); } - if ( !$user ) { - continue; - } $notifUser = MWEchoNotifUser::newFromUser( $user ); $uw = EchoUnreadWikis::newFromUser( $user ); @@ -69,7 +76,7 @@ class BackfillUnreadWikis extends Maintenance { continue; } - $uw->updateCount( wfWikiID(), $alertCount, $alertUnread, $msgCount, $msgUnread ); + $uw->updateCount( WikiMap::getCurrentWikiId(), $alertCount, $alertUnread, $msgCount, $msgUnread ); } } diff --git a/Echo/maintenance/generateSampleNotifications.php b/Echo/maintenance/generateSampleNotifications.php index ef3a711e..94c83b0a 100644 --- a/Echo/maintenance/generateSampleNotifications.php +++ b/Echo/maintenance/generateSampleNotifications.php @@ -5,7 +5,6 @@ use MediaWiki\MediaWikiServices; use MediaWiki\Revision\RevisionRecord; use MediaWiki\Revision\SlotRecord; -use Wikibase\Client\Hooks\EchoNotificationsHandlers; $IP = getenv( 'MW_INSTALL_PATH' ); if ( $IP === false ) { @@ -18,6 +17,7 @@ require_once "$IP/maintenance/Maintenance.php"; */ class GenerateSampleNotifications extends Maintenance { + /** @var string[] */ private $supportedNotificationTypes = [ 'welcome', 'edit-user-talk', @@ -33,6 +33,7 @@ class GenerateSampleNotifications extends Maintenance { 'page-connection', ]; + /** @var int */ private $timestampCounter = 5; public function __construct() { @@ -182,8 +183,8 @@ class GenerateSampleNotifications extends Maintenance { private function getOptionUser( $optionName ) { $username = $this->getOption( $optionName ); $user = User::newFromName( $username ); - if ( $user->isAnon() ) { - $this->error( "User $username does not seem to exist in this wiki", 1 ); + if ( !$user->isRegistered() ) { + $this->fatalError( "User $username does not seem to exist in this wiki" ); } return $user; } @@ -203,7 +204,7 @@ class GenerateSampleNotifications extends Maintenance { $this->output( "Enter 'yes' if you wish to continue or any other key to exit\n" ); $confirm = $this->readconsole(); if ( $confirm !== 'yes' ) { - $this->error( 'Safe decision', 1 ); + $this->fatalError( 'Safe decision' ); } } @@ -212,7 +213,7 @@ class GenerateSampleNotifications extends Maintenance { } private function addToPageContent( Title $title, User $agent, $contentText ) { - $page = WikiPage::factory( $title ); + $page = MediaWikiServices::getInstance()->getWikiPageFactory()->newFromTitle( $title ); $previousContent = ""; $page->loadPageData( WikiPage::READ_LATEST ); $revision = $page->getRevisionRecord(); @@ -222,12 +223,10 @@ class GenerateSampleNotifications extends Maintenance { $previousContent = $content->getText(); } } - $status = $page->doEditContent( + $status = $page->doUserEditContent( new WikitextContent( $contentText . $previousContent ), - 'generating sample notifications', - 0, - false, - $agent + $agent, + 'generating sample notifications' ); if ( !$status->isGood() ) { @@ -244,7 +243,7 @@ class GenerateSampleNotifications extends Maintenance { $this->output( "{$agent->getName()} is mentioning {$user->getName()} on {$title->getTalkPage()->getPrefixedText()}\n" ); $this->addToPageContent( $title->getTalkPage(), $agent, $mention ); - // agent tak + // agent talk $this->output( "{$agent->getName()} is mentioning {$user->getName()} on {$agent->getTalkPage()->getPrefixedText()}\n" ); $this->addToPageContent( $agent->getTalkPage(), $agent, $mention ); @@ -267,22 +266,21 @@ class GenerateSampleNotifications extends Maintenance { } private function generateReverted( User $user, User $agent ) { - $agent->addGroup( 'sysop' ); + $services = MediaWikiServices::getInstance(); + $services->getUserGroupManager()->addUserToGroup( $agent, 'sysop' ); // revert (undo) $moai = Title::newFromText( 'Moai' ); - $page = WikiPage::factory( $moai ); + $page = $services->getWikiPageFactory()->newFromTitle( $moai ); $this->output( "{$agent->getName()} is reverting {$user->getName()}'s edit on {$moai->getPrefixedText()}\n" ); $this->addToPageContent( $moai, $agent, "\ncreating a good revision here\n" ); $this->addToPageContent( $moai, $user, "\nadding a line here\n" ); $undoRev = $page->getRevisionRecord(); - $previous = MediaWikiServices::getInstance() - ->getRevisionLookup() + $previous = $services->getRevisionLookup() ->getPreviousRevision( $undoRev ); - $handler = MediaWikiServices::getInstance() - ->getContentHandlerFactory() + $handler = $services->getContentHandlerFactory() ->getContentHandler( $undoRev->getSlot( SlotRecord::MAIN, RevisionRecord::RAW ) ->getModel() @@ -290,6 +288,16 @@ class GenerateSampleNotifications extends Maintenance { $undoContent = $undoRev->getContent( SlotRecord::MAIN ); $previousContent = $previous->getContent( SlotRecord::MAIN ); + if ( !$undoContent ) { + $this->error( "Failed to undo {$moai->getPrefixedText()}: undoContent is null." ); + return; + } + + if ( !$previousContent ) { + $this->error( "Failed to undo {$moai->getPrefixedText()}: previousContent is null." ); + return; + } + $content = $handler->getUndoContent( $undoContent, $undoContent, @@ -297,7 +305,16 @@ class GenerateSampleNotifications extends Maintenance { true // undoIsLatest ); - $status = $page->doEditContent( $content, 'undo', 0, false, $agent, null, [], $undoRev->getId() ); + $status = $page->doUserEditContent( + $content, + $agent, + 'undo', + 0, // $flags + false, // $originalRevId + [], // $tags + $undoRev->getId() + ); + if ( !$status->isGood() ) { $this->error( "Failed to undo {$moai->getPrefixedText()}: {$status->getMessage()->text()}" ); } @@ -397,7 +414,9 @@ class GenerateSampleNotifications extends Maintenance { $content = "checkout [[{$pageBeingLinked->getPrefixedText()}]]!"; $this->output( "{$agent->getName()} is linking to {$pageBeingLinked->getPrefixedText()} from multiple pages\n" ); $this->addToPageContent( $this->generateNewPageTitle(), $agent, $content ); + // @phan-suppress-next-line PhanPluginDuplicateAdjacentStatement $this->addToPageContent( $this->generateNewPageTitle(), $agent, $content ); + // @phan-suppress-next-line PhanPluginDuplicateAdjacentStatement $this->addToPageContent( $this->generateNewPageTitle(), $agent, $content ); } @@ -432,7 +451,7 @@ class GenerateSampleNotifications extends Maintenance { } private function shouldGenerate( $type, array $types ) { - return array_search( $type, $types ) !== false; + return in_array( $type, $types ); } private function generateEditThanks( User $user, User $agent, User $otherUser ) { @@ -533,8 +552,7 @@ class GenerateSampleNotifications extends Maintenance { } private function generateWikibase( User $user, User $agent ) { - if ( !class_exists( EchoNotificationsHandlers::class ) ) { - // should use !ExtensionRegistry::getInstance()->isLoaded( 'Wikibase' ) when possible + if ( !ExtensionRegistry::getInstance()->isLoaded( 'WikibaseClient' ) ) { $this->output( "Skipping Wikibase. Extension not installed.\n" ); return; } diff --git a/Echo/maintenance/processEchoEmailBatch.php b/Echo/maintenance/processEchoEmailBatch.php index 401145a4..911d4039 100644 --- a/Echo/maintenance/processEchoEmailBatch.php +++ b/Echo/maintenance/processEchoEmailBatch.php @@ -11,12 +11,6 @@ require_once "$IP/maintenance/Maintenance.php"; */ class ProcessEchoEmailBatch extends Maintenance { - /** - * Max number of records to process at a time - * @var int - */ - protected $batchSize = 300; - public function __construct() { parent::__construct(); $this->addDescription( "Process email digest" ); @@ -26,6 +20,7 @@ class ProcessEchoEmailBatch extends Maintenance { "Send all pending notifications immediately even if configured to be weekly or daily.", false, false, "i" ); + $this->setBatchSize( 300 ); $this->requireExtension( 'Echo' ); } @@ -36,12 +31,13 @@ class ProcessEchoEmailBatch extends Maintenance { $this->output( "Started processing... \n" ); $startUserId = 0; - $count = $this->batchSize; + $batchSize = $this->getBatchSize(); + $count = $batchSize; - while ( $count === $this->batchSize ) { + while ( $count === $batchSize ) { $count = 0; - $res = MWEchoEmailBatch::getUsersToNotify( $startUserId, $this->batchSize ); + $res = MWEchoEmailBatch::getUsersToNotify( $startUserId, $batchSize ); $updated = false; foreach ( $res as $row ) { diff --git a/Echo/maintenance/recomputeNotifCounts.php b/Echo/maintenance/recomputeNotifCounts.php index 23560772..8b83a10b 100644 --- a/Echo/maintenance/recomputeNotifCounts.php +++ b/Echo/maintenance/recomputeNotifCounts.php @@ -32,7 +32,7 @@ class RecomputeNotifCounts extends Maintenance { public function execute() { $dbFactory = MWEchoDbFactory::newFromDefault(); - $dbwEcho = $dbFactory->getEchoDb( DB_MASTER ); + $dbwEcho = $dbFactory->getEchoDb( DB_PRIMARY ); $dbrEcho = $dbFactory->getEchoDb( DB_REPLICA ); $dbr = wfGetDB( DB_REPLICA ); @@ -60,11 +60,13 @@ class RecomputeNotifCounts extends Maintenance { $userIterator->addOptions( [ 'GROUP BY' => 'notification_user' ] ); + $userIterator->setCaller( __METHOD__ ); } else { $userQuery = User::getQueryInfo(); $userIterator = new BatchRowIterator( $dbr, $userQuery['tables'], 'user_id', $this->getBatchSize() ); $userIterator->setFetchColumns( $userQuery['fields'] ); $userIterator->addJoinConditions( $userQuery['joins'] ); + $userIterator->setCaller( __METHOD__ ); } $count = 0; diff --git a/Echo/maintenance/removeInvalidNotification.php b/Echo/maintenance/removeInvalidNotification.php index 43ab102f..5280cedd 100644 --- a/Echo/maintenance/removeInvalidNotification.php +++ b/Echo/maintenance/removeInvalidNotification.php @@ -16,13 +16,14 @@ require_once getenv( 'MW_INSTALL_PATH' ) !== false */ class RemoveInvalidNotification extends Maintenance { - protected $batchSize = 500; + /** @var string[] */ protected $invalidEventType = [ 'article-linked' ]; public function __construct() { parent::__construct(); $this->addDescription( "Removes invalid notifications from the database." ); + $this->setBatchSize( 500 ); $this->requireExtension( 'Echo' ); } @@ -34,12 +35,13 @@ class RemoveInvalidNotification extends Maintenance { return; } - $dbw = $lbFactory->getEchoDb( DB_MASTER ); + $dbw = $lbFactory->getEchoDb( DB_PRIMARY ); $dbr = $lbFactory->getEchoDb( DB_REPLICA ); - $count = $this->batchSize; + $batchSize = $this->getBatchSize(); + $count = $batchSize; - while ( $count == $this->batchSize ) { + while ( $count == $batchSize ) { $res = $dbr->select( [ 'echo_event' ], [ 'event_id' ], @@ -47,12 +49,13 @@ class RemoveInvalidNotification extends Maintenance { 'event_type' => $this->invalidEventType, ], __METHOD__, - [ 'LIMIT' => $this->batchSize ] + [ 'LIMIT' => $batchSize ] ); $event = []; $count = 0; foreach ( $res as $row ) { + // @phan-suppress-next-line PhanPossiblyUndeclaredVariable if ( !in_array( $row->event_id, $event ) ) { $event[] = $row->event_id; } diff --git a/Echo/maintenance/removeOrphanedEvents.php b/Echo/maintenance/removeOrphanedEvents.php index 7cb61b45..1351b1d9 100644 --- a/Echo/maintenance/removeOrphanedEvents.php +++ b/Echo/maintenance/removeOrphanedEvents.php @@ -31,14 +31,36 @@ class RemoveOrphanedEvents extends LoggedUpdateMaintenance { } public function doDBUpdates() { + $startId = 0; $dbFactory = MWEchoDbFactory::newFromDefault(); - $dbw = $dbFactory->getEchoDb( DB_MASTER ); + $dbr = $dbFactory->getEchoDb( DB_REPLICA ); + $maxId = (int)$dbr->newSelectQueryBuilder() + ->select( 'MAX(event_id)' ) + ->from( 'echo_event' ) + ->fetchField(); + $eventsProcessedTotal = 0; + $targetsProcessedTotal = 0; + while ( $startId < $maxId ) { + $startId += $this->getBatchSize() * 1000; + list( $eventsProcessed, $targetsProcessed ) = $this->doMajorBatch( $startId ); + $eventsProcessedTotal += $eventsProcessed; + $targetsProcessedTotal += $targetsProcessed; + } + $this->output( "In total, deleted $eventsProcessedTotal orphaned events and " . + "$targetsProcessedTotal target_page rows.\n" ); + + return true; + } + + private function doMajorBatch( $maxId ) { + $dbFactory = MWEchoDbFactory::newFromDefault(); + $dbw = $dbFactory->getEchoDb( DB_PRIMARY ); $dbr = $dbFactory->getEchoDb( DB_REPLICA ); $iterator = new BatchRowIterator( $dbr, [ 'echo_event', 'echo_notification', 'echo_email_batch' ], 'event_id', - $this->mBatchSize + $this->getBatchSize() ); $iterator->addJoinConditions( [ 'echo_notification' => [ 'LEFT JOIN', 'notification_event=event_id' ], @@ -47,9 +69,11 @@ class RemoveOrphanedEvents extends LoggedUpdateMaintenance { $iterator->addConditions( [ 'notification_user' => null, 'eeb_user_id' => null, + 'event_id < ' . $maxId ] ); + $iterator->setCaller( __METHOD__ ); - $this->output( "Removing orphaned echo_event rows...\n" ); + $this->output( "Removing orphaned echo_event rows with max event_id of $maxId...\n" ); $eventsProcessed = 0; $targetsProcessed = 0; @@ -66,16 +90,22 @@ class RemoveOrphanedEvents extends LoggedUpdateMaintenance { $dbFactory->waitForReplicas(); } - $this->output( "Removing any remaining orphaned echo_target_page rows...\n" ); + $this->output( "Removing any remaining orphaned echo_target_page rows with max etp_event of $maxId...\n" ); $iterator = new BatchRowIterator( $dbr, [ 'echo_target_page', 'echo_event' ], 'etp_event', - $this->mBatchSize + $this->getBatchSize() ); $iterator->addJoinConditions( [ 'echo_event' => [ 'LEFT JOIN', 'event_id=etp_event' ] ] ); - $iterator->addConditions( [ 'event_type' => null ] ); + $iterator->addConditions( + [ + 'event_type' => null, + 'etp_event < ' . $maxId + ] + ); $iterator->addOptions( [ 'DISTINCT' ] ); + $iterator->setCaller( __METHOD__ ); $processed = 0; foreach ( $iterator as $batch ) { @@ -89,7 +119,7 @@ class RemoveOrphanedEvents extends LoggedUpdateMaintenance { $dbFactory->waitForReplicas(); } - return true; + return [ $eventsProcessed, $targetsProcessed + $processed ]; } } diff --git a/Echo/maintenance/updateEchoSchemaForSuppression.php b/Echo/maintenance/updateEchoSchemaForSuppression.php index 62b1ff96..3079c76f 100644 --- a/Echo/maintenance/updateEchoSchemaForSuppression.php +++ b/Echo/maintenance/updateEchoSchemaForSuppression.php @@ -41,23 +41,28 @@ class UpdateEchoSchemaForSuppression extends LoggedUpdateMaintenance { $lbFactory = MWEchoDbFactory::newFromDefault(); $dbr = $lbFactory->getEchoDb( DB_REPLICA ); - $dbw = $lbFactory->getEchoDb( DB_MASTER ); + $dbw = $lbFactory->getEchoDb( DB_PRIMARY ); + '@phan-var \Wikimedia\Rdbms\IMaintainableDatabase $dbw'; if ( !$dbw->fieldExists( 'echo_event', 'event_page_title', __METHOD__ ) ) { $this->output( "No event_page_title field, skipping migration from event_page_title to event_page_id\n" ); return true; } - $reader = new BatchRowIterator( $dbr, $this->table, $this->idField, $this->mBatchSize ); + $reader = new BatchRowIterator( $dbr, $this->table, $this->idField, $this->getBatchSize() ); $reader->addConditions( [ "event_page_title IS NOT NULL", "event_page_id" => null, ] ); $reader->setFetchColumns( [ 'event_page_namespace', 'event_page_title', 'event_extra', 'event_type' ] ); + $reader->setCaller( __METHOD__ ); + + $writer = new BatchRowWriter( $dbw, $this->table, $wgEchoCluster ); + $writer->setCaller( __METHOD__ ); $updater = new BatchRowUpdate( $reader, - new BatchRowWriter( $dbw, $this->table, $wgEchoCluster ), + $writer, new EchoSuppressionRowUpdateGenerator ); $updater->setOutput( function ( $text ) { diff --git a/Echo/maintenance/updatePerUserBlacklist.php b/Echo/maintenance/updatePerUserBlacklist.php index 218654dc..296e3d3c 100644 --- a/Echo/maintenance/updatePerUserBlacklist.php +++ b/Echo/maintenance/updatePerUserBlacklist.php @@ -32,13 +32,13 @@ class EchoUpdatePerUserBlacklist extends LoggedUpdateMaintenance { public function doDBUpdates() { $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory(); - $dbw = $this->getDB( DB_MASTER ); + $dbw = $this->getDB( DB_PRIMARY ); $dbr = $this->getDB( DB_REPLICA ); $iterator = new BatchRowIterator( $dbr, 'user_properties', [ 'up_user', 'up_property' ], - $this->mBatchSize + $this->getBatchSize() ); $iterator->setFetchColumns( [ 'up_user', @@ -48,9 +48,11 @@ class EchoUpdatePerUserBlacklist extends LoggedUpdateMaintenance { 'up_property' => 'echo-notifications-blacklist' ] ); + $iterator->setCaller( __METHOD__ ); + $this->output( "Updating Echo Notification Blacklist...\n" ); - $lookup = CentralIdLookup::factory(); + $centralIdLookup = MediaWikiServices::getInstance()->getCentralIdLookup(); $processed = 0; foreach ( $iterator as $batch ) { foreach ( $batch as $row ) { @@ -59,7 +61,7 @@ class EchoUpdatePerUserBlacklist extends LoggedUpdateMaintenance { } $value = explode( "\n", $row->up_value ); - $names = array_filter( $value, function ( $item ) { + $names = array_filter( $value, static function ( $item ) { return !is_numeric( $item ); } ); @@ -70,7 +72,7 @@ class EchoUpdatePerUserBlacklist extends LoggedUpdateMaintenance { } $user = User::newFromId( $row->up_user ); - $ids = $lookup->centralIdsFromNames( $names, $user ); + $ids = $centralIdLookup->centralIdsFromNames( $names, $user ); $dbw->update( 'user_properties', diff --git a/Echo/modules/.eslintrc.json b/Echo/modules/.eslintrc.json new file mode 100644 index 00000000..3ac28f16 --- /dev/null +++ b/Echo/modules/.eslintrc.json @@ -0,0 +1,15 @@ +{ + "root": true, + "extends": [ + "wikimedia/client-es5", + "wikimedia/jquery", + "wikimedia/mediawiki", + "wikimedia/jsduck" + ], + "env": { + "commonjs": true + }, + "rules": { + "max-len": "off" + } +} diff --git a/Echo/modules/api/mw.echo.api.LocalAPIHandler.js b/Echo/modules/api/mw.echo.api.LocalAPIHandler.js index c00ce740..f437f5b2 100644 --- a/Echo/modules/api/mw.echo.api.LocalAPIHandler.js +++ b/Echo/modules/api/mw.echo.api.LocalAPIHandler.js @@ -55,12 +55,18 @@ * @inheritdoc */ mw.echo.api.LocalAPIHandler.prototype.markAllRead = function ( source, type ) { - var data; - type = Array.isArray( type ) ? type : [ type ]; - data = { - action: 'echomarkread', - sections: type.join( '|' ) + var data = { + action: 'echomarkread' }; + type = Array.isArray( type ) ? type : [ type ]; + if ( type.indexOf( 'all' ) !== -1 ) { + // As specified in the documentation of the parent function, the type parameter can be + // 'all'. We especially handle that case here to match the PHP API. Note: Other values + // of the array will be ignored. + data.all = true; + } else { + data.sections = type.join( '|' ); + } if ( !this.isSourceLocal( source ) ) { data.wikis = source; } diff --git a/Echo/modules/ext.echo.init.js b/Echo/modules/ext.echo.init.js index 407bfd41..66ccbe79 100644 --- a/Echo/modules/ext.echo.init.js +++ b/Echo/modules/ext.echo.init.js @@ -9,13 +9,19 @@ mw.echo.config.maxPrioritizedActions = 2; */ function initDesktop() { 'use strict'; + var uri; // Remove ?markasread=XYZ from the URL - var uri = new mw.Uri(); - if ( uri.query.markasread !== undefined ) { - delete uri.query.markasread; - delete uri.query.markasreadwiki; - window.history.replaceState( null, document.title, uri ); + try { + uri = new mw.Uri(); + if ( uri.query.markasread !== undefined ) { + delete uri.query.markasread; + delete uri.query.markasreadwiki; + window.history.replaceState( null, document.title, uri ); + } + } catch ( e ) { + // Catch problems when the URI is malformed (T261799) + // e.g. #/media/Fitxer:Campbells_Soup_Cans_MOMA_reduced_80%.jpg } // Activate ooui @@ -163,9 +169,7 @@ function initDesktop() { alertModelManager.on( 'allTalkRead', function () { // If there was a talk page notification, get rid of it - $( '#pt-mytalk a' ) - .removeClass( 'mw-echo-alert' ) - .text( mw.msg( 'mytalk' ) ); + $( '#pt-talk-alert' ).remove(); } ); // listen to event countChange and change title only if polling rate is non-zero @@ -230,7 +234,9 @@ function initDesktop() { $badge = $( this ), clickedSection = $badge.parent().prop( 'id' ) === 'pt-notifications-alert' ? 'alert' : 'message'; if ( e.which !== 1 || $badge.data( 'clicked' ) ) { - return false; + // Do not return false (as that calls stopPropagation) + e.preventDefault(); + return; } $badge.data( 'clicked', true ); @@ -259,15 +265,15 @@ function initDesktop() { if ( hasUnseenAlerts || hasUnseenMessages ) { // Clicked on the flyout due to having unread notifications // This is part of tracking how likely users are to click a badge with unseen notifications. - // The other part is the 'echo.unseen' counter, see EchoHooks::onPersonalUrls(). + // The other part is the 'echo.unseen' counter, see EchoHooks::onSkinTemplateNavigationUniversal(). mw.track( 'counter.MediaWiki.echo.unseen.click' ); } }, function () { // Un-dim badge if loading failed $badge.removeClass( 'mw-echo-notifications-badge-dimmed' ); } ); - // Prevent default - return false; + // Prevent default. Do not return false (as that calls stopPropagation) + e.preventDefault(); } ); function pollForNotificationCountUpdates() { @@ -296,7 +302,7 @@ function initDesktop() { function initMobile() { if ( !mw.user.isAnon() ) { mw.loader.using( [ 'ext.echo.mobile', 'mobile.startup' ] ).then( function ( require ) { - require( 'ext.echo.mobile' )(); + require( 'ext.echo.mobile' ).init(); } ); } } diff --git a/Echo/modules/hooks.txt b/Echo/modules/hooks.txt index db115fca..e85bd28d 100644 --- a/Echo/modules/hooks.txt +++ b/Echo/modules/hooks.txt @@ -19,6 +19,9 @@ were fetched from the API. * types: Notifications type that the badge represents. Can be 'message', 'alert' or 'all' * controller: The instance of the controller responsible for the specific popup operations +'ext.echo.NotificationBadgeWidget.onInitialize': Fired when the badge is initialized +* badge: Instance of mw.echo.ui.NotificationBadgeWidget + 'ext.echo.special.onInitialize': Fired when the special page is initialized. Note that this is also fired whenever the special page notification display is changed, like when clicking a filter, changing pagination, or viewing notifications for a remote wiki or page. diff --git a/Echo/modules/icons/articleCheck-progressive.svg b/Echo/modules/icons/articleCheck-progressive.svg index 7fecf3f3..b007084e 100644 --- a/Echo/modules/icons/articleCheck-progressive.svg +++ b/Echo/modules/icons/articleCheck-progressive.svg @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> +<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 20 20"> <title> article check </title> - <path fill="#36c" d="M9 17l-4.59-4.59L5.83 11 9 14.17l8-8V3a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V9z"/> + <path fill="#36c" d="m9 17-4.59-4.59L5.83 11 9 14.17l8-8V3a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V9z"/> </svg> diff --git a/Echo/modules/icons/changes.svg b/Echo/modules/icons/changes.svg index d90876f7..e4ce7b2d 100644 --- a/Echo/modules/icons/changes.svg +++ b/Echo/modules/icons/changes.svg @@ -4,5 +4,5 @@ changes </title> <path d="M16 0H5v2h11v14h2V2a2 2 0 0 0-2-2"/> - <path d="M13 9.41l-.98.99L9.6 7.98l.99-.98a.51.51 0 0 1 .72 0L13 8.7a.51.51 0 0 1 0 .72M6.41 16H4v-2.42l5.06-5.06 2.42 2.42zM13 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2"/> + <path d="m13 9.41-.98.99L9.6 7.98l.99-.98a.51.51 0 0 1 .72 0L13 8.7a.51.51 0 0 1 0 .72M6.41 16H4v-2.42l5.06-5.06 2.42 2.42zM13 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2"/> </svg> diff --git a/Echo/modules/icons/edit-progressive.svg b/Echo/modules/icons/edit-progressive.svg index 8d30517b..13d6355e 100644 --- a/Echo/modules/icons/edit-progressive.svg +++ b/Echo/modules/icons/edit-progressive.svg @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> +<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 20 20"> <title> edit </title> - <path fill="#36c" d="M16.77 8l1.94-2a1 1 0 0 0 0-1.41l-3.34-3.3a1 1 0 0 0-1.41 0L12 3.23zm-5.81-3.71L1 14.25V19h4.75l9.96-9.96-4.75-4.75z"/> + <path fill="#36c" d="m16.77 8 1.94-2a1 1 0 0 0 0-1.41l-3.34-3.3a1 1 0 0 0-1.41 0L12 3.23zm-5.81-3.71L1 14.25V19h4.75l9.96-9.96-4.75-4.75z"/> </svg> diff --git a/Echo/modules/icons/edit-user-talk-progressive.svg b/Echo/modules/icons/edit-user-talk-progressive.svg index eaa03de2..0c7c005e 100644 --- a/Echo/modules/icons/edit-user-talk-progressive.svg +++ b/Echo/modules/icons/edit-user-talk-progressive.svg @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> +<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 20 20"> <title> edit user talk </title> diff --git a/Echo/modules/icons/feedback-progressive.svg b/Echo/modules/icons/feedback-progressive.svg index fd0b90f1..fcb75fcb 100644 --- a/Echo/modules/icons/feedback-progressive.svg +++ b/Echo/modules/icons/feedback-progressive.svg @@ -4,7 +4,7 @@ feedback </title> <g fill="#36c"> - <path d="M19 16L2 12a3.83 3.83 0 0 1-1-2.5A3.83 3.83 0 0 1 2 7l17-4z"/> + <path d="M19 16 2 12a3.83 3.83 0 0 1-1-2.5A3.83 3.83 0 0 1 2 7l17-4z"/> <rect width="4" height="8" x="4" y="9" rx="2" ry="2"/> </g> </svg> diff --git a/Echo/modules/icons/global-progressive.svg b/Echo/modules/icons/global-progressive.svg index 5619ee3c..a3e29233 100644 --- a/Echo/modules/icons/global-progressive.svg +++ b/Echo/modules/icons/global-progressive.svg @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> +<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 20 20"> <title> global </title> diff --git a/Echo/modules/icons/helpNotice-ltr.svg b/Echo/modules/icons/helpNotice-ltr.svg index 8f0c3dc8..4ed50722 100644 --- a/Echo/modules/icons/helpNotice-ltr.svg +++ b/Echo/modules/icons/helpNotice-ltr.svg @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> +<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 20 20"> <title> help </title> diff --git a/Echo/modules/icons/helpNotice-rtl.svg b/Echo/modules/icons/helpNotice-rtl.svg index 5a3122ab..b565dc2c 100644 --- a/Echo/modules/icons/helpNotice-rtl.svg +++ b/Echo/modules/icons/helpNotice-rtl.svg @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> +<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 20 20"> <title> help </title> diff --git a/Echo/modules/icons/link-progressive.svg b/Echo/modules/icons/link-progressive.svg index 065bca1f..17f06862 100644 --- a/Echo/modules/icons/link-progressive.svg +++ b/Echo/modules/icons/link-progressive.svg @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> +<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 20 20"> <title> link </title> diff --git a/Echo/modules/icons/mention-failure.svg b/Echo/modules/icons/mention-failure.svg index 0dc4250a..f4d3f3c7 100644 --- a/Echo/modules/icons/mention-failure.svg +++ b/Echo/modules/icons/mention-failure.svg @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> +<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 20 20"> <title> mention failure </title> diff --git a/Echo/modules/icons/mention-progressive.svg b/Echo/modules/icons/mention-progressive.svg index c69b0df4..2ba6afed 100644 --- a/Echo/modules/icons/mention-progressive.svg +++ b/Echo/modules/icons/mention-progressive.svg @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> +<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 20 20"> <title> mention </title> diff --git a/Echo/modules/icons/mention-status-bundle-progressive.svg b/Echo/modules/icons/mention-status-bundle-progressive.svg index 0fb0b461..737b481b 100644 --- a/Echo/modules/icons/mention-status-bundle-progressive.svg +++ b/Echo/modules/icons/mention-status-bundle-progressive.svg @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> +<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 20 20"> <title> mention status bundle </title> diff --git a/Echo/modules/icons/mention-success-constructive.svg b/Echo/modules/icons/mention-success-constructive.svg index c0702929..e8ef19ea 100644 --- a/Echo/modules/icons/mention-success-constructive.svg +++ b/Echo/modules/icons/mention-success-constructive.svg @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> +<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 20 20"> <title> mention success </title> - <path fill="#00af89" d="M2 0a2 2 0 0 0-2 2v18l4-4h14a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm14.049 3l1.05 1.059L8.16 13 4 8.834l1.05-1.05 3.108 3.107L16.048 3z"/> + <path fill="#00af89" d="M2 0a2 2 0 0 0-2 2v18l4-4h14a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm14.049 3 1.05 1.059L8.16 13 4 8.834l1.05-1.05 3.108 3.107L16.048 3z"/> </svg> diff --git a/Echo/modules/icons/message-constructive.svg b/Echo/modules/icons/message-constructive.svg index c58a7af5..2bd96e0a 100644 --- a/Echo/modules/icons/message-constructive.svg +++ b/Echo/modules/icons/message-constructive.svg @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> +<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 20 20"> <title> message </title> diff --git a/Echo/modules/icons/notice.svg b/Echo/modules/icons/notice.svg index 06a7f5ec..7e560f6c 100644 --- a/Echo/modules/icons/notice.svg +++ b/Echo/modules/icons/notice.svg @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> +<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 20 20"> <title> notice </title> diff --git a/Echo/modules/icons/revert.svg b/Echo/modules/icons/revert.svg index d3914bc9..fc39a945 100644 --- a/Echo/modules/icons/revert.svg +++ b/Echo/modules/icons/revert.svg @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> +<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 20 20"> <title> revert </title> - <path fill="#54595d" d="M8.806 6.444L1 14.25V19h4.75l8.334-8.334zm4.908-3.515H13V.072L8 4l5 3.929V5.072h.714c2.286 0 4 1.428 4 4.285h2.143c0-4.285-3.857-6.428-6.143-6.428"/> + <path fill="#54595d" d="M8.806 6.444 1 14.25V19h4.75l8.334-8.334zm4.908-3.515H13V.072L8 4l5 3.929V5.072h.714c2.286 0 4 1.428 4 4.285h2.143c0-4.285-3.857-6.428-6.143-6.428"/> </svg> diff --git a/Echo/modules/icons/speechBubbles-ltr-progressive.svg b/Echo/modules/icons/speechBubbles-ltr-progressive.svg index de97021f..f0bfb593 100644 --- a/Echo/modules/icons/speechBubbles-ltr-progressive.svg +++ b/Echo/modules/icons/speechBubbles-ltr-progressive.svg @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> +<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 20 20"> <title> speech bubbles </title> diff --git a/Echo/modules/icons/speechBubbles-rtl-progressive.svg b/Echo/modules/icons/speechBubbles-rtl-progressive.svg index 05421380..a0631e97 100644 --- a/Echo/modules/icons/speechBubbles-rtl-progressive.svg +++ b/Echo/modules/icons/speechBubbles-rtl-progressive.svg @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> +<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 20 20"> <title> speech bubbles </title> diff --git a/Echo/modules/icons/unbell.svg b/Echo/modules/icons/unbell.svg index 8cb3e266..8f044fa2 100644 --- a/Echo/modules/icons/unbell.svg +++ b/Echo/modules/icons/unbell.svg @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> -<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewbox="0 0 20 20"> +<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20"> <title> unbell </title> - <path d="M1.22 0L0 1.22l4.334 4.335A5.38 5.38 0 004 7v6l-2 2v1h12.78l4 4L20 18.78 17.22 16 5.23 4.01 1.22 0zM10 0C8.47 0 8.4 1.46 8.46 2.15a5.38 5.38 0 00-1.92.729l9.46 9.46V7a5.38 5.38 0 00-4.46-4.85C11.6 1.46 11.53 0 10 0zM7 17a3 3 0 003 3 3 3 0 003-3H7z"/> + <path d="M1.22 0 0 1.22l4.334 4.335A5.38 5.38 0 0 0 4 7v6l-2 2v1h12.78l4 4L20 18.78 17.22 16 5.23 4.01 1.22 0zM10 0C8.47 0 8.4 1.46 8.46 2.15a5.38 5.38 0 0 0-1.92.729l9.46 9.46V7a5.38 5.38 0 0 0-4.46-4.85C11.6 1.46 11.53 0 10 0zM7 17a3 3 0 0 0 3 3 3 3 0 0 0 3-3H7z"/> </svg> diff --git a/Echo/modules/icons/user-rights-progressive.svg b/Echo/modules/icons/user-rights-progressive.svg index 0f5708b2..56a0d4a9 100644 --- a/Echo/modules/icons/user-rights-progressive.svg +++ b/Echo/modules/icons/user-rights-progressive.svg @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> +<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 20 20"> <title> user rights </title> diff --git a/Echo/modules/icons/user-speech-bubble.svg b/Echo/modules/icons/user-speech-bubble.svg index ddf3d551..1e0e06a3 100644 --- a/Echo/modules/icons/user-speech-bubble.svg +++ b/Echo/modules/icons/user-speech-bubble.svg @@ -3,6 +3,6 @@ <title> user speech bubble </title> - <path d="M12.4 9.3l-1.8 2.9H22V2.4h-9.6v6.9zM6 13c-5.9 0-8 3-8 5v3h16v-3c0-2-2.1-5-8-5z"/> + <path d="m12.4 9.3-1.8 2.9H22V2.4h-9.6v6.9zM6 13c-5.9 0-8 3-8 5v3h16v-3c0-2-2.1-5-8-5z"/> <circle cx="6" cy="7.5" r="4.5"/> </svg> diff --git a/Echo/modules/icons/watchlist-ltr-progressive.svg b/Echo/modules/icons/watchlist-ltr-progressive.svg new file mode 100644 index 00000000..2c9a3b16 --- /dev/null +++ b/Echo/modules/icons/watchlist-ltr-progressive.svg @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> + <title> + watchlist + </title><g fill="#36c"> + <path d="M1 3h16v2H1V3Zm0 6h6v2H1V9Zm0 6h8v2H1v-2Zm8-4.24h3.85L14.5 7l1.65 3.76H20l-3 3.17.9 4.05-3.4-2.14L11.1 18l.9-4.05-3-3.19Z"/> +</g></svg> diff --git a/Echo/modules/icons/watchlist-rtl-progressive.svg b/Echo/modules/icons/watchlist-rtl-progressive.svg new file mode 100644 index 00000000..3091a8a8 --- /dev/null +++ b/Echo/modules/icons/watchlist-rtl-progressive.svg @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> + <title> + watchlist + </title><g fill="#36c"> + <path d="M19 3H3v2h16zm0 6h-6v2h6zm0 6h-8v2h8zm-8-4.24H7.15L5.5 7l-1.65 3.76H0l3 3.17-.9 4.05 3.4-2.14L8.9 18 8 13.95Z"/> +</g></svg> diff --git a/Echo/modules/mobile/NotificationBadge.js b/Echo/modules/mobile/NotificationBadge.js index fdffb010..0a55196d 100644 --- a/Echo/modules/mobile/NotificationBadge.js +++ b/Echo/modules/mobile/NotificationBadge.js @@ -36,8 +36,9 @@ function NotificationBadge( options ) { $notificationAnchor = $el.find( 'a' ); options.title = $notificationAnchor.attr( 'title' ); options.url = $notificationAnchor.attr( 'href' ); - count = Number( $el.find( 'span' ).data( 'notification-count' ) ); + count = Number( $el.find( '[data-notification-count]' ).data( 'notification-count' ) ); } + View.call( this, $.extend( { notificationIconClass: notificationIcon.getClassName(), @@ -74,7 +75,6 @@ NotificationBadge.prototype.setCount = function ( count ) { this.options.notificationCountString = mw.message( 'echo-badge-count', mw.language.convertNumber( count ) ).text(); - this.options.isNotificationCountZero = count === 0; this.render(); }; diff --git a/Echo/modules/mobile/NotificationBadge.mustache b/Echo/modules/mobile/NotificationBadge.mustache index 18045e2c..cc0d5f55 100644 --- a/Echo/modules/mobile/NotificationBadge.mustache +++ b/Echo/modules/mobile/NotificationBadge.mustache @@ -8,8 +8,7 @@ <a href="{{url}}" title="{{title}}" id="user-notifications" data-event-name="ui.notifications" - class="mw-echo-notification-badge-nojs mw-echo-unseen-notifications notification-count user-button {{#hasUnseenNotifications}}notification-unseen{{/hasUnseenNotifications}} - {{#isNotificationCountZero}}zero{{/isNotificationCountZero}}"> + class="mw-echo-notification-badge-nojs mw-echo-unseen-notifications notification-count user-button {{#hasUnseenNotifications}}notification-unseen{{/hasUnseenNotifications}}"> <div class="circle"> <span data-notification-count="{{notificationCountRaw}}"> {{notificationCountString}} diff --git a/Echo/modules/mobile/list.js b/Echo/modules/mobile/list.js index 4660c0d8..9ad4fe9b 100644 --- a/Echo/modules/mobile/list.js +++ b/Echo/modules/mobile/list.js @@ -23,7 +23,7 @@ var mobile = mw.mobileFrontend.require( 'mobile.startup' ), */ function notificationsList( echo, markAllReadButton, onCountChange, onNotificationListRendered ) { var wrapperWidget, - maxNotificationCount = mw.config.get( 'wgEchoMaxNotificationCount' ), + maxNotificationCount = require( './config.json' ).EchoMaxNotificationCount, echoApi = new echo.api.EchoApi(), unreadCounter = new echo.dm.UnreadNotificationCounter( echoApi, 'all', maxNotificationCount ), modelManager = new echo.dm.ModelManager( unreadCounter, { type: [ 'message', 'alert' ] } ), diff --git a/Echo/modules/mobile/notifications.js b/Echo/modules/mobile/notifications.js index 9feaf9fb..5182366c 100644 --- a/Echo/modules/mobile/notifications.js +++ b/Echo/modules/mobile/notifications.js @@ -1,3 +1,5 @@ +var NotificationBadge = require( './NotificationBadge.js' ); + var NOTIFICATIONS_PATH = '/notifications'; /** @@ -14,17 +16,16 @@ function onCloseNotificationsOverlay() { mw.hook( 'echo.mobile' ).fire( false ); } -/* +/** * This code loads the necessary modules for the notifications overlay, not to be confused * with the Toast notifications defined by common/toast.js. */ -module.exports = function () { +function init() { var badge, notificationsFilterOverlay = require( './notificationsFilterOverlay.js' ), notificationsOverlay = require( './overlay.js' ), router = require( 'mediawiki.router' ), overlayManager = mw.mobileFrontend.require( 'mobile.startup' ).OverlayManager.getSingleton(), - NotificationBadge = require( './NotificationBadge.js' ), initialized = false; function showNotificationOverlay() { @@ -49,7 +50,7 @@ module.exports = function () { ev.preventDefault(); }, // eslint-disable-next-line no-jquery/no-global-selector - el: $( '#user-notifications.user-button' ).parent() + el: $( '.minerva-user-notifications ul' ).parent() } ); overlayManager.add( /^\/notifications$/, showNotificationOverlay ); @@ -114,4 +115,7 @@ module.exports = function () { } ); } ); -}; +} + +module.exports.init = init; +module.exports.NotificationBadge = NotificationBadge; diff --git a/Echo/modules/mobile/notificationsFilterOverlay.js b/Echo/modules/mobile/notificationsFilterOverlay.js index 20167bd9..3d7685b7 100644 --- a/Echo/modules/mobile/notificationsFilterOverlay.js +++ b/Echo/modules/mobile/notificationsFilterOverlay.js @@ -12,14 +12,16 @@ var Overlay = mw.mobileFrontend.require( 'mobile.startup' ).Overlay; */ function notificationsFilterOverlay( options ) { var $content, overlay; - // Initialize - options.$crossWikiUnreadFilter.on( 'click', function () { - overlay.hide(); - } ); - options.$notifReadState.find( '.oo-ui-buttonElement' ).on( 'click', function () { - overlay.hide(); - } ); + // Don't call overlay.hide(), because that doesn't invoke the onBeforeExit callback (T258954) + // Instead, change the hash, so that the OverlayManager hides the overlay for us + function hideOverlay() { + location.hash = '#'; + } + + // Close overlay when a selection is made + options.$crossWikiUnreadFilter.on( 'click', hideOverlay ); + options.$notifReadState.find( '.oo-ui-buttonElement' ).on( 'click', hideOverlay ); $content = $( '<div>' ).append( $( '<div>' ) diff --git a/Echo/modules/mobile/notificationsFilterOverlay.less b/Echo/modules/mobile/notificationsFilterOverlay.less index ae06d254..1cdd4b25 100644 --- a/Echo/modules/mobile/notificationsFilterOverlay.less +++ b/Echo/modules/mobile/notificationsFilterOverlay.less @@ -1,6 +1,6 @@ @import 'mediawiki.ui/variables.less'; -@import 'mediawiki.mixins.less'; +/* stylelint-disable-next-line selector-class-pattern */ .notifications-filter-overlay { padding-top: 0; @@ -10,6 +10,7 @@ text-align: center; } + /* stylelint-disable-next-line selector-class-pattern */ .overlay-content { // this is needed not only on iOS, that's why we repeat it here even though // it's in Overlay.less too @@ -19,7 +20,7 @@ padding-bottom: 0; .mw-echo-ui-pageNotificationsOptionWidget { - .box-sizing( border-box ); + box-sizing: border-box; border: 1px solid @colorGray12; padding: 0.7em 1.5em 1em 1em; width: 100%; diff --git a/Echo/modules/mobile/overlay.less b/Echo/modules/mobile/overlay.less index 264583b9..0a5c75cb 100644 --- a/Echo/modules/mobile/overlay.less +++ b/Echo/modules/mobile/overlay.less @@ -2,6 +2,9 @@ @import 'mediawiki.ui/variables.less'; @import 'mediawiki.mixins.less'; +@overlayHeaderHeight: 3em; + +/* stylelint-disable-next-line selector-class-pattern */ .notifications-overlay { // position: fixed + sliding drawer causes weird rendering bugs in Android // Browser (tested on 4.0.4 and 4.2.1) @@ -13,16 +16,16 @@ &-overlay { position: absolute; - bottom: 3em; + bottom: @overlayHeaderHeight; right: 0; left: 0; z-index: 1; .mw-echo-ui-actionMenuPopupWidget-menu { padding: 0.5em; - font-size: 1.5em; box-shadow: none; - border: 1px solid @colorGray10; + border: 1px solid @colorGray12; + border-width: 1px 0 0 0; // Override the positioning of the menu // so it is "stuck" on the bottom of the // notification overlay panel @@ -35,6 +38,7 @@ } } + /* stylelint-disable-next-line selector-class-pattern */ .overlay-content { // this is needed not only on iOS, that's why we repeat it here even though // it's in Overlay.less too @@ -44,12 +48,21 @@ padding-top: 0; padding-bottom: 0; max-width: none; // T219320 + top: @overlayHeaderHeight; + bottom: @overlayHeaderHeight; .mw-echo-ui-notificationsWidget { + top: @overlayHeaderHeight; height: 100%; } + + .mw-echo-ui-notificationsListWidget > .mw-echo-ui-notificationItemWidget { + border-left: 0; + border-right: 0; + } } + /* stylelint-disable-next-line selector-class-pattern */ .user-button { position: absolute; right: 0; diff --git a/Echo/modules/model/mw.echo.dm.ModelManager.js b/Echo/modules/model/mw.echo.dm.ModelManager.js index 32cccf65..35349c10 100644 --- a/Echo/modules/model/mw.echo.dm.ModelManager.js +++ b/Echo/modules/model/mw.echo.dm.ModelManager.js @@ -2,19 +2,19 @@ /** * A container that manages all models that are involved in creating * the notification list. There are currently two types of models: - * * mw.echo.dm.SortedList - This currently includes the local model + * - mw.echo.dm.SortedList - This currently includes the local model * or any model that has individual messages. - * * mw.echo.dm.CrossWikiNotificationItem - This is a model for the + * - mw.echo.dm.CrossWikiNotificationItem - This is a model for the * cross wiki notification, which acts as an item but itself contains * a list. * * All notification models that are managed by the manager must implement the * following methods: - * * getName - This should retrieve the model's name for the manager to fetch - * * isGroup - This should be true for xwiki model and local bundles - * * hasUnseen - This should iterate in the model's items and check whether + * - getName - This should retrieve the model's name for the manager to fetch + * - isGroup - This should be true for xwiki model and local bundles + * - hasUnseen - This should iterate in the model's items and check whether * there are any unseen notifications within them. - * * getCount - Get a total count of available notifications currently in the model + * - getCount - Get a total count of available notifications currently in the model * * @class * @mixins OO.EventEmitter diff --git a/Echo/modules/nojs/mw.echo.alert.monobook.less b/Echo/modules/nojs/mw.echo.alert.monobook.less index 95db1c0f..b3a1d4fd 100644 --- a/Echo/modules/nojs/mw.echo.alert.monobook.less +++ b/Echo/modules/nojs/mw.echo.alert.monobook.less @@ -1,3 +1,4 @@ -#pt-mytalk a.mw-echo-alert:hover { +// The id selector is required to increase specificity. +#pt-talk-alert a.mw-echo-alert:hover { background-color: #fab951; } diff --git a/Echo/modules/nojs/mw.echo.badge.less b/Echo/modules/nojs/mw.echo.badge.less index 87a8b507..55ecdc40 100644 --- a/Echo/modules/nojs/mw.echo.badge.less +++ b/Echo/modules/nojs/mw.echo.badge.less @@ -1,5 +1,4 @@ @import '../echo.variables.less'; -@import 'mediawiki.mixins.less'; /* stylelint-disable no-descending-specificity */ /* We have to include the #pt-notifications selector due to monobook */ @@ -8,18 +7,18 @@ #pt-notifications-notice & { position: relative; display: block; + box-sizing: border-box; width: 20px; height: 20px; margin: 0 2px; // Hide the text, but keep accessible for screen-readers // Later we put the counter back onscreen with a zero text-indent - top: -5px; + top: 0; text-indent: -9999px; border-radius: @border-radius-base; cursor: pointer; text-decoration: none; line-height: normal; - .box-sizing( border-box ); opacity: 0.87; color: transparent; @@ -30,7 +29,7 @@ } &:focus { - .box-shadow( ~'0 0 0 1px #fff, 0 0 0 3px #36c' ); + box-shadow: 0 0 0 1px #fff, 0 0 0 3px #36c; opacity: 1; &:after { diff --git a/Echo/modules/nojs/mw.echo.badge.minerva.less b/Echo/modules/nojs/mw.echo.badge.minerva.less index b95fd810..47cb2c90 100644 --- a/Echo/modules/nojs/mw.echo.badge.minerva.less +++ b/Echo/modules/nojs/mw.echo.badge.minerva.less @@ -4,6 +4,10 @@ top: 0; margin: 0; } + + a.mw-ui-icon-wikimedia-bellOutline-base20 { + color: transparent; + } } #pt-notifications-alert.oo-ui-widget { diff --git a/Echo/modules/nojs/mw.echo.badge.vector.less b/Echo/modules/nojs/mw.echo.badge.vector.less deleted file mode 100644 index 90c7d23c..00000000 --- a/Echo/modules/nojs/mw.echo.badge.vector.less +++ /dev/null @@ -1,6 +0,0 @@ -@import '../echo.variables.less'; - -#p-personal #pt-notifications-alert, -#p-personal #pt-notifications-notice { - margin-right: 0.4em; -} diff --git a/Echo/modules/nojs/mw.echo.notifications.less b/Echo/modules/nojs/mw.echo.notifications.less index 8defd104..6996b6df 100644 --- a/Echo/modules/nojs/mw.echo.notifications.less +++ b/Echo/modules/nojs/mw.echo.notifications.less @@ -6,8 +6,8 @@ // where the formatting of the notifications include the following structure .mw-echo-state { display: block; + box-sizing: border-box; width: 100%; - .box-sizing( border-box ); .mw-echo-notification-primary-link { display: none; @@ -35,6 +35,7 @@ /* Force container to expand to height of floated contents */ overflow: hidden; + /* stylelint-disable-next-line selector-class-pattern */ span.autocomment { color: inherit; font-style: normal; @@ -64,6 +65,7 @@ font-size: 1em; line-height: 1.4em; + /* stylelint-disable-next-line selector-class-pattern */ .plainlinks { max-width: 100%; display: inline-block; diff --git a/Echo/modules/nojs/mw.echo.special.less b/Echo/modules/nojs/mw.echo.special.less index 641060c4..1ac4bee5 100644 --- a/Echo/modules/nojs/mw.echo.special.less +++ b/Echo/modules/nojs/mw.echo.special.less @@ -60,13 +60,14 @@ } ul.mw-echo-special-notifications { - div.mw-htmlform-submit-buttons { - margin: 0; - } - list-style: none none; + list-style: none; padding: 0; margin: 0; width: 100%; + + div.mw-htmlform-submit-buttons { + margin: 0; + } } .mw-echo-special-navbar-top { @@ -147,6 +148,7 @@ div.mw-htmlform-ooui-wrapper { } @media all and ( max-width: ( @specialpage-hd-width - 1 ) ) { + /* stylelint-disable-next-line selector-class-pattern */ .pre-content.heading-holder { // Center 'preferences' in mobile special page text-align: center; diff --git a/Echo/modules/styles/mw.echo.ui.ActionMenuPopupWidget.less b/Echo/modules/styles/mw.echo.ui.ActionMenuPopupWidget.less index f1734ae5..e82bad94 100644 --- a/Echo/modules/styles/mw.echo.ui.ActionMenuPopupWidget.less +++ b/Echo/modules/styles/mw.echo.ui.ActionMenuPopupWidget.less @@ -3,4 +3,18 @@ // Override width: 100%; rule from OOUI width: auto; } + + // We put MenutItemWidgets in the popup menu, as we reuse the same widgets when they appear outside the popup. + // Re-style them to look more like DecoratedOptionWidgets instead of ButtonOptionWidgets + .mw-echo-ui-menuItemWidget { + display: block; + + .oo-ui-buttonElement-button { + display: block; + } + + &.oo-ui-labelElement:first-child { + margin-left: 0; + } + } } diff --git a/Echo/modules/styles/mw.echo.ui.CrossWikiNotificationItemWidget.less b/Echo/modules/styles/mw.echo.ui.CrossWikiNotificationItemWidget.less index b0b04fc2..d6ef42fb 100644 --- a/Echo/modules/styles/mw.echo.ui.CrossWikiNotificationItemWidget.less +++ b/Echo/modules/styles/mw.echo.ui.CrossWikiNotificationItemWidget.less @@ -20,7 +20,7 @@ &-content { // The icon is 30px margin-left: 30px; - padding-bottom: 1em; + padding-bottom: 0.5em; // 0.8em from ItemWidget, plus 0.8em padding-left: 1.6em; padding-right: 0.8em; @@ -37,25 +37,11 @@ } } - &-separator { - display: block; - position: absolute; - bottom: 0.4em; - width: 100%; - border-bottom: 1px solid #eaecf0; - - .mw-echo-ui-crossWikiNotificationItemWidget-expanded &, - .mw-echo-ui-bundleNotificationItemWidget-expanded & { - display: none; - } - } - &-group { cursor: default; padding: @bundle-group-padding; background-color: #f8f9fa; - .box-shadow( inset 0 -2px 0 0 rgba( 0, 0, 0, 0.05 ), inset 0 2px 0 0 rgba( 0, 0, 0, 0.05 ); ); - margin-bottom: 0.4em; + box-shadow: inset 0 2px 0 0 rgba( 0, 0, 0, 0.05 ); } .mw-echo-ui-subGroupListWidget-header { diff --git a/Echo/modules/styles/mw.echo.ui.MenuItemWidget.less b/Echo/modules/styles/mw.echo.ui.MenuItemWidget.less index 60da86f9..c15f4c17 100644 --- a/Echo/modules/styles/mw.echo.ui.MenuItemWidget.less +++ b/Echo/modules/styles/mw.echo.ui.MenuItemWidget.less @@ -7,39 +7,34 @@ text-decoration: none; } - > .oo-ui-labelElement-label { + > .oo-ui-buttonElement-button > .oo-ui-labelElement-label { // Override link colour color: @color-base; // Set max-width so buttons are truncated max-width: 25em; + font-weight: normal; } &-prioritized { .mw-echo-ui-mixin-hover-opacity(); display: inline-block; - // Remove left padding up to icon, 11/14 - margin-left: -0.78571429em; } &-dynamic-action { - &:hover { - background-color: @background-color-base; - } - - > .oo-ui-labelElement-label { + > .oo-ui-buttonElement-button > .oo-ui-labelElement-label { white-space: normal; overflow: visible; } - &.oo-ui-iconElement > .oo-ui-iconElement-icon { - // Limit to single line height, 32/14 - height: 2.28571em; + &.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon { + // Limit to single line height + max-height: 28px; } .mw-echo-ui-menuItemWidget-description { color: #54595d; display: block; - padding-top: 1em; + cursor: inherit; } } diff --git a/Echo/modules/styles/mw.echo.ui.NotificationBadgeWidget.less b/Echo/modules/styles/mw.echo.ui.NotificationBadgeWidget.less index 65320518..2bd899e5 100644 --- a/Echo/modules/styles/mw.echo.ui.NotificationBadgeWidget.less +++ b/Echo/modules/styles/mw.echo.ui.NotificationBadgeWidget.less @@ -7,9 +7,10 @@ &-popup { > .oo-ui-popupWidget-popup { > .oo-ui-popupWidget-head { - .box-sizing( border-box ); + box-sizing: border-box; height: 3.1428571em; // = 44px as result of 44 / 16 (font-size browser) / 0.875 (OOUI WikimediaUI theme font-size) border-bottom: 1px solid #c8ccd1; + margin: 0; > .oo-ui-iconWidget { float: left; @@ -22,16 +23,12 @@ margin: 0 0 0 0.4761905em; // = 8px as result of ≈0.5714286 / 1.2 (element's font-size) font-size: 1.2em; font-weight: bold; - line-height: 2.6190476em; // = 44px as result of ≈3.1428571 / 1.2 (element's font-size) + line-height: 2.5595238em; // = 43px as result of 43 (44 - 1 because of the border-box) / 16 / 0.875 / 1.2 (element's font-size) } .mw-echo-ui-notificationsWidget-markAllReadButton { margin-top: 0.4285714em; // = 6px as result of 6 / 16 / 0.875 margin-right: 0.5714286em; // = 8px as result of 8 / 16 / 0.875 - - .oo-ui-buttonElement-button { - padding-right: 0; - } } } @@ -70,7 +67,7 @@ display: table-cell; white-space: normal; width: @notification-popup-width / 2; - .box-sizing( border-box ); + box-sizing: border-box; &:last-child { border-left: 1px solid #c8ccd1; diff --git a/Echo/modules/styles/mw.echo.ui.NotificationItemWidget.less b/Echo/modules/styles/mw.echo.ui.NotificationItemWidget.less index b5f1838e..d836e047 100644 --- a/Echo/modules/styles/mw.echo.ui.NotificationItemWidget.less +++ b/Echo/modules/styles/mw.echo.ui.NotificationItemWidget.less @@ -3,18 +3,36 @@ @import '../echo.mixins.less'; .mw-echo-ui-notificationItemWidget { + display: block; background-color: @notification-item-background-read; position: relative; white-space: normal; padding: 0.8em 1em 0.5em 1em; - .box-sizing( border-box ); + box-sizing: border-box; border: 1px solid #c8ccd1; border-bottom: 0; + &:not( [ href ] ) { + // Items without a primary URL are not clickable + cursor: default; + } + + label { + // Reset browser default of cursor:default; + cursor: inherit; + } + &:hover { + text-decoration: none; background-color: #ececec; } + &:focus { + text-decoration: none; + box-shadow: inset 0 0 0 2px @color-primary; + outline: 0; + } + &:last-child { border-bottom: 1px solid #c8ccd1; } @@ -36,12 +54,6 @@ &-notify { &-title { font-weight: bold; - font-size: 1.2em; - } - - &-description { - font-size: 1em; - color: @grey-medium; } } @@ -56,10 +68,10 @@ &-content { display: block; + box-sizing: border-box; // The icon is 30px margin-left: 30px; padding-left: 0.8em; - .box-sizing( border-box ); &-message { line-height: 1.3em; @@ -91,20 +103,26 @@ } } - &-table { - display: table; - width: 100%; - margin-top: 0.8em; - } - &-actions { - display: table-row; + display: flex; + align-items: flex-end; font-size: 0.9em; + margin-top: 0.8em; & > &-buttons.oo-ui-buttonSelectWidget { - display: table-cell; - white-space: nowrap; - vertical-align: bottom; + display: flex; + overflow: hidden; + + > .oo-ui-buttonOptionWidget { + min-width: 7em; + overflow: hidden; + + .oo-ui-labelElement-label { + text-overflow: ellipsis; + overflow: hidden; + display: inline-block; + } + } } &-button { @@ -118,19 +136,17 @@ &-menu { .mw-echo-ui-mixin-hover-opacity(); - display: table-cell; vertical-align: bottom; padding: 0; } &-timestamp { - display: table-cell; - vertical-align: bottom; + flex-grow: 1; text-align: right; + vertical-align: bottom; color: @color-base--emphasized; opacity: @opacity-low; white-space: nowrap; - width: 100%; } } } @@ -174,8 +190,8 @@ padding-right: 0.5em; img { - height: 1.5em; - width: 1.5em; + height: 20px; + width: 20px; } } diff --git a/Echo/modules/styles/mw.echo.ui.NotificationsInboxWidget.less b/Echo/modules/styles/mw.echo.ui.NotificationsInboxWidget.less index 19219710..70cdd1cd 100644 --- a/Echo/modules/styles/mw.echo.ui.NotificationsInboxWidget.less +++ b/Echo/modules/styles/mw.echo.ui.NotificationsInboxWidget.less @@ -13,7 +13,9 @@ &-toolbarWrapper { height: 3.5em; + /* stylelint-disable-next-line plugin/no-unsupported-browser-features */ position: -webkit-sticky; + /* stylelint-disable-next-line plugin/no-unsupported-browser-features */ position: sticky; padding-top: 0.5em; margin-top: -0.5em; @@ -37,11 +39,6 @@ width: @specialpage-sidebar-width; padding-right: 1em; vertical-align: top; - - @media all and ( max-width: ( @specialpage-hd-width - 1 ) ) { - // Hide the sidebar for small screens - display: none; - } } &-main { @@ -82,8 +79,10 @@ } } - &-readState { - display: inline-block; + // Nav filter is the mobile version of readState + &-readState, + &-nav-filter { + display: block; } &-settings, @@ -100,6 +99,14 @@ } } + &-cell-placeholder { + display: block; + } + + &-sidebar { + display: none; + } + &-toolbarWrapper { height: 7em; } diff --git a/Echo/modules/styles/mw.echo.ui.NotificationsInboxWidget.minerva.less b/Echo/modules/styles/mw.echo.ui.NotificationsInboxWidget.minerva.less new file mode 100644 index 00000000..1343ba4a --- /dev/null +++ b/Echo/modules/styles/mw.echo.ui.NotificationsInboxWidget.minerva.less @@ -0,0 +1,31 @@ +// TODO: These should be mobile customizations done in JS + +.mw-echo-ui-notificationsInboxWidget { + &-sidebar { + // echo notificationsInboxWidget cell + // in the desktop version is hidden + // in the mobile version. + &.mw-echo-ui-notificationsInboxWidget-cell { + display: none; + } + } + + &-main { + &-toolbar { + &-readState { + // echo notificationsInboxWidget cell for readState + // in the desktop version is hidden + // in the mobile version. + &.mw-echo-ui-notificationsInboxWidget-cell { + display: none; + } + } + } + } + + & &-toolbarWrapper { + height: auto; + position: static; + padding-bottom: 0.5em; + } +} diff --git a/Echo/modules/styles/mw.echo.ui.NotificationsListWidget.less b/Echo/modules/styles/mw.echo.ui.NotificationsListWidget.less index 3a79558f..56a65e41 100644 --- a/Echo/modules/styles/mw.echo.ui.NotificationsListWidget.less +++ b/Echo/modules/styles/mw.echo.ui.NotificationsListWidget.less @@ -9,14 +9,8 @@ border-top: 0; } - > a, - &:hover > a { - text-decoration: none; - color: @grey-medium; - } - &:not( :hover ) a, - #p-personal &:not( :hover ) a.new { + #p-personal &:not( :hover ) a.new { /* stylelint-disable-line selector-class-pattern */ color: @grey-medium; } } diff --git a/Echo/modules/styles/mw.echo.ui.PageNotificationsOptionWidget.less b/Echo/modules/styles/mw.echo.ui.PageNotificationsOptionWidget.less index 44d51b45..056551b5 100644 --- a/Echo/modules/styles/mw.echo.ui.PageNotificationsOptionWidget.less +++ b/Echo/modules/styles/mw.echo.ui.PageNotificationsOptionWidget.less @@ -3,8 +3,8 @@ .mw-echo-ui-pageNotificationsOptionWidget { clear: both; + box-sizing: border-box; width: 100%; - .box-sizing( border-box ); &.oo-ui-optionWidget { .transition( ~'background-color 100ms, color 100ms' ); @@ -75,7 +75,7 @@ white-space: nowrap; .oo-ui-optionWidget-selected & { - background: none; // `background-color: transparent` would be the goto value, but IE 8-9 introduces a bug + background-color: transparent; color: @color-primary; } } diff --git a/Echo/modules/styles/mw.echo.ui.ToggleReadCircleButtonWidget.less b/Echo/modules/styles/mw.echo.ui.ToggleReadCircleButtonWidget.less index 96582329..b6451577 100644 --- a/Echo/modules/styles/mw.echo.ui.ToggleReadCircleButtonWidget.less +++ b/Echo/modules/styles/mw.echo.ui.ToggleReadCircleButtonWidget.less @@ -1,15 +1,14 @@ -@import 'mediawiki.mixins.less'; @import '../echo.variables.less'; .mw-echo-ui-toggleReadCircleButtonWidget { &-circle { border-radius: 50%; + box-sizing: border-box; min-width: 10px; width: @bundle-group-padding; min-height: 10px; height: @bundle-group-padding; margin: @bundle-group-padding; - .box-sizing( border-box ); // Mark as read background-color: #36c; @@ -25,6 +24,13 @@ // Override OOUI specific rule for frameless buttons that adds a ~2.5em padding-top &.oo-ui-widget.oo-ui-widget-enabled.oo-ui-buttonElement.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button { padding-top: 0; + // Remove padding for dummy icon + padding-left: 0; + } + + &.oo-ui-buttonElement-frameless.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon { + // Hide dummy icon + display: none; } &:hover .mw-echo-ui-toggleReadCircleButtonWidget-circle { diff --git a/Echo/modules/styles/mw.echo.ui.mobile.less b/Echo/modules/styles/mw.echo.ui.mobile.less index 54b9562f..ca86a150 100644 --- a/Echo/modules/styles/mw.echo.ui.mobile.less +++ b/Echo/modules/styles/mw.echo.ui.mobile.less @@ -2,11 +2,15 @@ // `!important` rules override the inline styles provides by clippable. @media all and ( max-width: @width-breakpoint-tablet ) { - .mw-echo-ui-overlay { + .skin-minerva .mw-echo-ui-overlay { .oo-ui-clippableElement-clippable { width: 100% !important; } + .mw-echo-ui-specialHelpMenuWidget-menu { + max-width: 70% !important; + } + .oo-ui-popupWidget-popup { width: 100% !important; } diff --git a/Echo/modules/styles/mw.echo.ui.overlay.minerva.less b/Echo/modules/styles/mw.echo.ui.overlay.minerva.less index 95d1817a..fa77ffc0 100644 --- a/Echo/modules/styles/mw.echo.ui.overlay.minerva.less +++ b/Echo/modules/styles/mw.echo.ui.overlay.minerva.less @@ -19,13 +19,14 @@ .mw-echo-ui-actionMenuPopupWidget-menu { padding: 0.5em; - font-size: 1.5em; + font-size: 16 / 14em; box-shadow: none; - border: 1px solid #54595d; + border: 1px solid @colorGray12; + border-width: 1px 0 0 0; // Override the positioning of the menu // so it is "stuck" on the bottom of the // notification overlay panel - position: static !important; + position: fixed !important; bottom: 0 !important; left: 0 !important; width: 100% !important; diff --git a/Echo/modules/styles/mw.echo.ui.overlay.monobook.less b/Echo/modules/styles/mw.echo.ui.overlay.monobook.less index 280a2250..349b8cfb 100644 --- a/Echo/modules/styles/mw.echo.ui.overlay.monobook.less +++ b/Echo/modules/styles/mw.echo.ui.overlay.monobook.less @@ -1,7 +1,4 @@ .mw-echo-ui-overlay { - // We need the overlay to be adjusted for: - // #globalWrapper 127% - // .pBody 95% - // .mw-echo-ui-notificationBadgeButtonPopupWidget > .oo-ui-popupWidget 0.875/0.75em - font-size: 1.27 * 0.95 * 0.875 / 0.75em; + // Match #globalWrapper + font-size: 127%; } diff --git a/Echo/modules/styles/mw.echo.ui.overlay.wikimediaapiportal.less b/Echo/modules/styles/mw.echo.ui.overlay.wikimediaapiportal.less new file mode 100644 index 00000000..a67b1bbe --- /dev/null +++ b/Echo/modules/styles/mw.echo.ui.overlay.wikimediaapiportal.less @@ -0,0 +1,3 @@ +.mw-echo-ui-overlay { + z-index: 101; +} diff --git a/Echo/modules/ui/mw.echo.ui.ActionMenuPopupWidget.js b/Echo/modules/ui/mw.echo.ui.ActionMenuPopupWidget.js index c3e287a5..e9d13cf4 100644 --- a/Echo/modules/ui/mw.echo.ui.ActionMenuPopupWidget.js +++ b/Echo/modules/ui/mw.echo.ui.ActionMenuPopupWidget.js @@ -31,12 +31,12 @@ // Menu this.customMenuPosition = ( config.horizontalPosition || 'auto' ) !== 'auto'; - this.menu = new OO.ui.MenuSelectWidget( $.extend( { + this.menu = new OO.ui.MenuSelectWidget( { $floatableContainer: this.$element, horizontalPosition: this.customMenuPosition ? config.horizontalPosition : 'start', classes: [ 'mw-echo-ui-actionMenuPopupWidget-menu' ], widget: this - } ) ); + } ); this.$overlay.append( this.menu.$element ); // Events diff --git a/Echo/modules/ui/mw.echo.ui.BadgeLinkWidget.js b/Echo/modules/ui/mw.echo.ui.BadgeLinkWidget.js index ed1cf4c5..df7af5ed 100644 --- a/Echo/modules/ui/mw.echo.ui.BadgeLinkWidget.js +++ b/Echo/modules/ui/mw.echo.ui.BadgeLinkWidget.js @@ -53,6 +53,18 @@ mw.echo.ui.BadgeLinkWidget.static.tagName = 'a'; /** + * Overrides ButtonElement.prototype.onClick so that it doesn't call ev.stopPropagation. + * This ensures the dialog dismisses other open overlays e.g. ULS (See T295796 for more + * information). + * + * @inheritDoc + */ + mw.echo.ui.BadgeLinkWidget.prototype.onClick = function ( ev ) { + ev.preventDefault(); + this.emit( 'click' ); + }; + + /** * Set the count labels for this button. * * @param {number} numItems Number of items diff --git a/Echo/modules/ui/mw.echo.ui.BundleNotificationItemWidget.js b/Echo/modules/ui/mw.echo.ui.BundleNotificationItemWidget.js index b3c4c9af..e998f290 100644 --- a/Echo/modules/ui/mw.echo.ui.BundleNotificationItemWidget.js +++ b/Echo/modules/ui/mw.echo.ui.BundleNotificationItemWidget.js @@ -212,6 +212,8 @@ 'collapse' : 'expand' ); + // T258706 + this.toggleExpandButton.setActive( false ); }; /** diff --git a/Echo/modules/ui/mw.echo.ui.MenuItemWidget.js b/Echo/modules/ui/mw.echo.ui.MenuItemWidget.js index 810d8ce4..4a446244 100644 --- a/Echo/modules/ui/mw.echo.ui.MenuItemWidget.js +++ b/Echo/modules/ui/mw.echo.ui.MenuItemWidget.js @@ -3,7 +3,7 @@ * Secondary menu item * * @class - * @extends OO.ui.DecoratedOptionWidget + * @extends OO.ui.ButtonOptionWidget * @mixins OO.ui.mixin.PendingElement * * @constructor @@ -25,7 +25,7 @@ this.isLink = config.url && !this.isDynamicAction(); // Parent constructor - mw.echo.ui.MenuItemWidget.super.call( this, config ); + mw.echo.ui.MenuItemWidget.super.call( this, $.extend( { framed: false }, config ) ); // Mixin constructors OO.ui.mixin.PendingElement.call( this, config ); @@ -62,7 +62,7 @@ /* Initialization */ - OO.inheritClass( mw.echo.ui.MenuItemWidget, OO.ui.DecoratedOptionWidget ); + OO.inheritClass( mw.echo.ui.MenuItemWidget, OO.ui.ButtonOptionWidget ); OO.mixinClass( mw.echo.ui.MenuItemWidget, OO.ui.mixin.PendingElement ); /* Static Properties */ @@ -76,6 +76,21 @@ return this.isLink ? 'a' : 'div'; }; + mw.echo.ui.MenuItemWidget.prototype.onClick = function ( e ) { + // Stop propagation, so that the default dynamic action of the notification isn't triggered + // (e.g. expanding a bundled notification). + e.stopPropagation(); + + // If this is a dynamic action, also prevent default to disable the native browser behavior, + // the default link of the notification won't be followed. + // (If this is a link, default link of the notification is ignored as native browser behavior.) + if ( !this.isLink ) { + e.preventDefault(); + } + + return mw.echo.ui.MenuItemWidget.super.prototype.onClick.apply( this, arguments ); + }; + mw.echo.ui.MenuItemWidget.prototype.isSelectable = function () { // If we have a link force selectability to false, otherwise defer to parent method // Without a link (for dynamic actions or specific internal actions) we need this widget diff --git a/Echo/modules/ui/mw.echo.ui.NotificationBadgeWidget.js b/Echo/modules/ui/mw.echo.ui.NotificationBadgeWidget.js index 50067145..308f2f52 100644 --- a/Echo/modules/ui/mw.echo.ui.NotificationBadgeWidget.js +++ b/Echo/modules/ui/mw.echo.ui.NotificationBadgeWidget.js @@ -174,6 +174,7 @@ 'mw-echo-ui-notificationBadgeButtonPopupWidget-' + adjustedTypeString ) .append( this.badgeButton.$element ); + mw.hook( 'ext.echo.NotificationBadgeWidget.onInitialize' ).fire( this ); }; /* Initialization */ diff --git a/Echo/modules/ui/mw.echo.ui.NotificationItemWidget.js b/Echo/modules/ui/mw.echo.ui.NotificationItemWidget.js index a31f3d46..b362dbaa 100644 --- a/Echo/modules/ui/mw.echo.ui.NotificationItemWidget.js +++ b/Echo/modules/ui/mw.echo.ui.NotificationItemWidget.js @@ -38,7 +38,6 @@ // Mark as read this.markAsReadButton = new mw.echo.ui.ToggleReadCircleButtonWidget( { framed: false, - title: mw.msg( 'echo-notification-markasread-tooltip' ), classes: [ 'mw-echo-ui-notificationItemWidget-markAsReadButton' ], markAsRead: !this.model.isRead() } ); @@ -136,17 +135,17 @@ // (where all actions are inside the menu) or there are more than // two prioritized actions (all others go into the menu) isOutsideMenu = !this.bundle && + ( ( - ( - // Make sure we don't have too many prioritized items - urlObj.prioritized && - outsideMenuItemCounter < mw.echo.config.maxPrioritizedActions - ) || - // If the number of total items are equal to or less than the - // maximum allowed, they all go outside the menu - // mw.echo.config.maxPrioritizedActions is 2 on desktop and 1 on mobile. - secondaryUrls.length <= mw.echo.config.maxPrioritizedActions - ); + // Make sure we don't have too many prioritized items + urlObj.prioritized && + outsideMenuItemCounter < mw.echo.config.maxPrioritizedActions + ) || + // If the number of total items are equal to or less than the + // maximum allowed, they all go outside the menu + // mw.echo.config.maxPrioritizedActions is 2 on desktop and 1 on mobile. + secondaryUrls.length <= mw.echo.config.maxPrioritizedActions + ); linkButton = new mw.echo.ui.MenuItemWidget( { type: urlObj.type, @@ -184,14 +183,13 @@ this.$content.append( this.markAsReadButton.$element, $message, - $( '<div>' ) - .addClass( 'mw-echo-ui-notificationItemWidget-content-table' ) - .append( this.$actions ) + this.$actions ); this.$element.append( $icon, this.$content ); } // Events + this.actionsButtonSelectWidget.connect( this, { choose: 'onPopupButtonWidgetChoose' } ); this.menuPopupButtonWidget.getMenu().connect( this, { choose: 'onPopupButtonWidgetChoose' } ); this.markAsReadButton.connect( this, { click: 'onMarkAsReadButtonClick' } ); @@ -200,25 +198,18 @@ .toggleClass( 'mw-echo-ui-notificationItemWidget-initiallyUnseen', !this.model.isSeen() && !this.bundle ) .toggleClass( 'mw-echo-ui-notificationItemWidget-bundled', this.bundle ); - // Wrap the entire item with primary url if ( this.model.getPrimaryUrl() ) { - this.$element.contents() - .wrapAll( - // HACK: Wrap the entire item with a link that takes - // the user to the primary url. This is not perfect, - // but it makes the behavior native to the browser rather - // than us listening to click events and opening new - // windows. - $( '<a>' ) - .addClass( 'mw-echo-ui-notificationItemWidget-linkWrapper' ) - .attr( 'href', this.model.getPrimaryUrl() ) - .on( 'click', this.onPrimaryLinkClick.bind( this ) ) - ); + this.$element + .attr( 'href', this.model.getPrimaryUrl() ) + .on( 'click', this.onPrimaryLinkClick.bind( this ) ); } }; OO.inheritClass( mw.echo.ui.NotificationItemWidget, OO.ui.Widget ); + // Make the whole item a link to get native link behaviour + mw.echo.ui.NotificationItemWidget.static.tagName = 'a'; + /** * Respond to primary link click. * Override this in the descendents. @@ -238,10 +229,14 @@ * NOTE: The messages are parsed as HTML. If user-input is expected * please make sure to properly escape it. * - * @param {mw.echo.ui.MenuItemWidget} item The selected item - * @return {boolean} False to prevent the native event + * @param {OO.ui.ButtonOptionWidget} item The selected item */ mw.echo.ui.NotificationItemWidget.prototype.onPopupButtonWidgetChoose = function ( item ) { + if ( !( item instanceof mw.echo.ui.MenuItemWidget ) ) { + // Other kinds of items may be added by subclasses + return; + } + var actionData = item && item.getActionData(), messages = item && item.getConfirmationMessages(), widget = this; @@ -278,24 +273,16 @@ // Send to mw.notify mw.notify( $confirmation ); } ); - - // Prevent the click propagation - return false; }; /** * Respond to mark as read button click - * - * @return {boolean} False to prevent the native event */ mw.echo.ui.NotificationItemWidget.prototype.onMarkAsReadButtonClick = function () { // If we're marking read or unread, the notification was already seen. // Remove the animation class this.$element.removeClass( 'mw-echo-ui-notificationItemWidget-initiallyUnseen' ); this.markRead( !this.model.isRead() ); - // Prevent propogation in case there's a link wrapping the content - // and the mark as read/unread button - return false; }; /** diff --git a/Echo/modules/ui/mw.echo.ui.NotificationsInboxWidget.js b/Echo/modules/ui/mw.echo.ui.NotificationsInboxWidget.js index 57e08328..6c53a10b 100644 --- a/Echo/modules/ui/mw.echo.ui.NotificationsInboxWidget.js +++ b/Echo/modules/ui/mw.echo.ui.NotificationsInboxWidget.js @@ -105,11 +105,13 @@ .addClass( 'mw-echo-ui-notificationsInboxWidget-row' ) .append( $( '<div>' ) - .addClass( 'mw-echo-ui-notificationsInboxWidget-main-toolbar-readState' ) - .addClass( 'mw-echo-ui-notificationsInboxWidget-cell' ) - .append( this.readStateSelectWidget.$element ), - $( '<div>' ) - .addClass( 'mw-echo-ui-notificationsInboxWidget-cell-placeholder' ), + .addClass( 'mw-echo-ui-notificationsInboxWidget-cell-placeholder' ) + .append( + $( '<div>' ) + .addClass( 'mw-echo-ui-notificationsInboxWidget-main-toolbar-readState' ) + .addClass( 'mw-echo-ui-notificationsInboxWidget-cell' ) + .append( this.readStateSelectWidget.$element ) + ), $( '<div>' ) .addClass( 'mw-echo-ui-notificationsInboxWidget-main-toolbar-pagination' ) .addClass( 'mw-echo-ui-notificationsInboxWidget-cell' ) diff --git a/Echo/modules/ui/mw.echo.ui.ToggleReadCircleButtonWidget.js b/Echo/modules/ui/mw.echo.ui.ToggleReadCircleButtonWidget.js index 9d32a10c..aaa20591 100644 --- a/Echo/modules/ui/mw.echo.ui.ToggleReadCircleButtonWidget.js +++ b/Echo/modules/ui/mw.echo.ui.ToggleReadCircleButtonWidget.js @@ -14,7 +14,11 @@ config = config || {}; // Parent constructor - mw.echo.ui.ToggleReadCircleButtonWidget.super.call( this, config ); + mw.echo.ui.ToggleReadCircleButtonWidget.super.call( this, $.extend( { + invisibleLabel: true, + // Set a dummy icon so we get focus styles + icon: '_' + }, config ) ); this.$circle = $( '<div>' ) .addClass( 'mw-echo-ui-toggleReadCircleButtonWidget-circle' ); @@ -39,15 +43,16 @@ * @param {boolean} [isMarkAsRead] The state is mark as read */ mw.echo.ui.ToggleReadCircleButtonWidget.prototype.toggleState = function ( isMarkAsRead ) { + var label; isMarkAsRead = isMarkAsRead === undefined ? !this.markAsRead : !!isMarkAsRead; this.markAsRead = isMarkAsRead; this.$circle.toggleClass( 'mw-echo-ui-toggleReadCircleButtonWidget-circle-unread', !this.markAsRead ); - this.setTitle( - this.markAsRead ? - mw.msg( 'echo-notification-markasread' ) : - mw.msg( 'echo-notification-markasunread' ) - ); + label = this.markAsRead ? + mw.msg( 'echo-notification-markasread' ) : + mw.msg( 'echo-notification-markasunread' ); + this.setLabel( label ); + this.setTitle( label ); }; }() ); diff --git a/Echo/package-lock.json b/Echo/package-lock.json index 37ad3236..3e435bfa 100644 --- a/Echo/package-lock.json +++ b/Echo/package-lock.json @@ -1,202 +1,8982 @@ { "name": "echo", "version": "0.0.1", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.3.tgz", - "integrity": "sha512-fDx9eNW0qz0WkUeqL6tXEXzVlPh6Y5aCDEZesl0xBGA8ndRukX91Uk44ZqnkECp01NAZUdCAl+aiQNGi0k88Eg==", + "packages": { + "": { + "name": "echo", + "version": "0.0.1", + "devDependencies": { + "@wdio/cli": "7.16.13", + "@wdio/junit-reporter": "7.16.13", + "@wdio/local-runner": "7.16.13", + "@wdio/mocha-framework": "7.16.13", + "@wdio/spec-reporter": "7.16.13", + "eslint-config-wikimedia": "0.22.1", + "grunt": "1.5.3", + "grunt-banana-checker": "0.10.0", + "grunt-contrib-watch": "1.1.0", + "grunt-eslint": "24.0.0", + "grunt-stylelint": "0.18.0", + "stylelint-config-wikimedia": "0.13.0", + "svgo": "2.8.0", + "wdio-mediawiki": "2.1.0", + "webdriverio": "7.16.13" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, - "requires": { - "@babel/highlight": "^7.10.3" + "dependencies": { + "@babel/highlight": "^7.10.4" } }, - "@babel/core": { - "version": "7.10.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.3.tgz", - "integrity": "sha512-5YqWxYE3pyhIi84L84YcwjeEgS+fa7ZjK6IBVGTjDVfm64njkR2lfDhVR5OudLk8x2GK59YoSyVv+L/03k1q9w==", + "node_modules/@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", "dev": true, - "requires": { - "@babel/code-frame": "^7.10.3", - "@babel/generator": "^7.10.3", - "@babel/helper-module-transforms": "^7.10.1", - "@babel/helpers": "^7.10.1", - "@babel/parser": "^7.10.3", - "@babel/template": "^7.10.3", - "@babel/traverse": "^7.10.3", - "@babel/types": "^7.10.3", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@es-joy/jsdoccomment": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.20.1.tgz", + "integrity": "sha512-oeJK41dcdqkvdZy/HctKklJNkt/jh+av3PZARrZEl+fs/8HaHeeYoAvEwOV0u5I6bArTF17JEsTZMY359e/nfQ==", + "dev": true, + "dependencies": { + "comment-parser": "1.3.0", + "esquery": "^1.4.0", + "jsdoc-type-pratt-parser": "~2.2.3" + }, + "engines": { + "node": "^12 || ^14 || ^16 || ^17" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.0.tgz", + "integrity": "sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.3.1", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", + "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@mdn/browser-compat-data": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-4.1.9.tgz", + "integrity": "sha512-MGIACLLfhkuJ4rV5JPIOFNLJN+JWgYmV83NMBfx8EvRma+kcEAFivVgHHuEPJtdCba5zRpMx/cIGrXfVyGN56g==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sindresorhus/is": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.4.0.tgz", + "integrity": "sha512-QppPM/8l3Mawvh4rn9CNEYIU9bxpXUCRMaX9yUpvBk1nMKusLKpfXGDEKExKaPhLzcn3lzil7pR6rnJ11HgeRQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.0.tgz", + "integrity": "sha512-P+dkdFu0n08PDIvw+9nT9ByQnd+Udc8DaWPb9HKfaPwCvWvQpC5XaMRx2xLWECm9x1VKNps6vEAlirjA6+uNrQ==", + "dev": true + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", + "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", + "dev": true, + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "*", + "@types/node": "*", + "@types/responselike": "*" + } + }, + "node_modules/@types/diff": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/diff/-/diff-5.0.2.tgz", + "integrity": "sha512-uw8eYMIReOwstQ0QKF0sICefSy8cNO/v7gOTiIy9SbwuHyEecJUm7qlgueOO5S1udZ5I/irVydHVwMchgzbKTg==", + "dev": true + }, + "node_modules/@types/easy-table": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/easy-table/-/easy-table-0.0.33.tgz", + "integrity": "sha512-/vvqcJPmZUfQwCgemL0/34G7bIQnCuvgls379ygRlcC1FqNqk3n+VZ15dAO51yl6JNDoWd8vsk+kT8zfZ1VZSw==", + "dev": true + }, + "node_modules/@types/ejs": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/ejs/-/ejs-3.1.0.tgz", + "integrity": "sha512-DCg+Ka+uDQ31lJ/UtEXVlaeV3d6t81gifaVWKJy4MYVVgvJttyX/viREy+If7fz+tK/gVxTGMtyrFPnm4gjrVA==", + "dev": true + }, + "node_modules/@types/fs-extra": { + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", + "dev": true + }, + "node_modules/@types/inquirer": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-8.2.0.tgz", + "integrity": "sha512-BNoMetRf3gmkpAlV5we+kxyZTle7YibdOntIZbU5pyIfMdcwy784KfeZDAcuyMznkh5OLa17RVXZOGA5LTlkgQ==", + "dev": true, + "dependencies": { + "@types/through": "*", + "rxjs": "^7.2.0" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/json-stringify-safe": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/json-stringify-safe/-/json-stringify-safe-5.0.0.tgz", + "integrity": "sha512-UUA1sH0RSRROdInuDOA1yoRzbi5xVFD1RHCoOvNRPTNwR8zBkJ/84PZ6NhKVDtKp0FTeIccJCdQz1X2aJPr4uw==", + "dev": true + }, + "node_modules/@types/keyv": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.3.tgz", + "integrity": "sha512-FXCJgyyN3ivVgRoml4h94G/p3kY+u/B86La+QptcqJaWtBWtmc6TtkNfS40n9bIvyLteHh7zXOtgbobORKPbDg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/lodash": { + "version": "4.14.178", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz", + "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==", + "dev": true + }, + "node_modules/@types/lodash.flattendeep": { + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@types/lodash.flattendeep/-/lodash.flattendeep-4.4.6.tgz", + "integrity": "sha512-uLm2MaRVlqJSGsMK0RZpP5T3KqReq+9WbYDHCUhBhp98v56hMG/Yht52bsoTSui9xz2mUvQ9NfG3LrNGDL92Ng==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/lodash.pickby": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/@types/lodash.pickby/-/lodash.pickby-4.6.6.tgz", + "integrity": "sha512-NFa13XxlMd9eFi0UFZFWIztpMpXhozbijrx3Yb1viYZphT7jyopIFVoIRF4eYMjruWNEG1rnyrRmg/8ej9T8Iw==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/lodash.union": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/@types/lodash.union/-/lodash.union-4.6.6.tgz", + "integrity": "sha512-Wu0ZEVNcyCz8eAn6TlUbYWZoGbH9E+iOHxAZbwUoCEXdUiy6qpcz5o44mMXViM4vlPLLCPlkAubEP1gokoSZaw==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "node_modules/@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "dev": true + }, + "node_modules/@types/mocha": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.0.tgz", + "integrity": "sha512-QCWHkbMv4Y5U9oW10Uxbr45qMMSzl4OzijsozynUAgx3kEHUdXB00udx2dWDQ7f2TU2a2uuiFaRZjCe3unPpeg==", + "dev": true + }, + "node_modules/@types/node": { + "version": "17.0.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.19.tgz", + "integrity": "sha512-PfeQhvcMR4cPFVuYfBN4ifG7p9c+Dlh3yUZR6k+5yQK7wX3gDgVxBly4/WkBRs9x4dmcy1TVl08SY67wwtEvmA==", + "dev": true + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, + "node_modules/@types/object-inspect": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@types/object-inspect/-/object-inspect-1.8.1.tgz", + "integrity": "sha512-0JTdf3CGV0oWzE6Wa40Ayv2e2GhpP3pEJMcrlM74vBSJPuuNkVwfDnl0SZxyFCXETcB4oKA/MpTVfuYSMOelBg==", + "dev": true + }, + "node_modules/@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "node_modules/@types/recursive-readdir": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@types/recursive-readdir/-/recursive-readdir-2.2.0.tgz", + "integrity": "sha512-HGk753KRu2N4mWduovY4BLjYq4jTOL29gV2OfGdGxHcPSWGFkC5RRIdk+VTs5XmYd7MVAD+JwKrcb5+5Y7FOCg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/stream-buffers": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/stream-buffers/-/stream-buffers-3.0.4.tgz", + "integrity": "sha512-qU/K1tb2yUdhXkLIATzsIPwbtX6BpZk0l3dPW6xqWyhfzzM1ECaQ/8faEnu3CNraLiQ9LHyQQPBGp7N9Fbs25w==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@types/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-dPWnWsf+kzIG140B8z2w3fr5D03TLWbOAFQl45xUpI3vcizeXriNR5VYkWZ+WTMsUHqZ9Xlt3hrxGNANFyNQfw==", + "dev": true + }, + "node_modules/@types/through": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/through/-/through-0.0.30.tgz", + "integrity": "sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-dDZH/tXzwjutnuk4UacGgFRwV+JSLaXL1ikvidfJprkb7L9Nx1njcRHHmi3Dsvt7pgqqTEeucQuOrWHPFgzVHA==", + "dev": true + }, + "node_modules/@types/ua-parser-js": { + "version": "0.7.36", + "resolved": "https://registry.npmjs.org/@types/ua-parser-js/-/ua-parser-js-0.7.36.tgz", + "integrity": "sha512-N1rW+njavs70y2cApeIw1vLMYXRwfBy+7trgavGuuTfOd7j1Yh7QTRc/yqsPl6ncokt72ZXuxEU0PiCp9bSwNQ==", + "dev": true + }, + "node_modules/@types/validator": { + "version": "13.7.1", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.1.tgz", + "integrity": "sha512-I6OUIZ5cYRk5lp14xSOAiXjWrfVoMZVjDuevBYgQDYzZIjsf2CAISpEcXOkFAtpAHbmWIDLcZObejqny/9xq5Q==", + "dev": true + }, + "node_modules/@types/which": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/which/-/which-1.3.2.tgz", + "integrity": "sha512-8oDqyLC7eD4HM307boe2QWKyuzdzWBj56xI/imSl2cpL+U3tCMaTAkMJ4ee5JBZ/FsOJlvRGeIShiZDAl1qERA==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", + "dev": true + }, + "node_modules/@types/yauzl": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", + "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "node_modules/@wdio/cli": { + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-7.16.13.tgz", + "integrity": "sha512-y0C/eLLyLCVWrsJVimozUQBQWD/goIUxmtB91rjMAqTjeLn5b0VoPhr+EKXGCHXz3ylvXGGJ3RaI0l1vz9Cf8w==", + "dev": true, + "dependencies": { + "@types/ejs": "^3.0.5", + "@types/fs-extra": "^9.0.4", + "@types/inquirer": "^8.1.2", + "@types/lodash.flattendeep": "^4.4.6", + "@types/lodash.pickby": "^4.6.6", + "@types/lodash.union": "^4.6.6", + "@types/node": "^17.0.4", + "@types/recursive-readdir": "^2.2.0", + "@wdio/config": "7.16.13", + "@wdio/logger": "7.16.0", + "@wdio/types": "7.16.13", + "@wdio/utils": "7.16.13", + "async-exit-hook": "^2.0.1", + "chalk": "^4.0.0", + "chokidar": "^3.0.0", + "cli-spinners": "^2.1.0", + "ejs": "^3.0.1", + "fs-extra": "^10.0.0", + "inquirer": "8.1.5", + "lodash.flattendeep": "^4.4.0", + "lodash.pickby": "^4.6.0", + "lodash.union": "^4.6.0", + "mkdirp": "^1.0.4", + "recursive-readdir": "^2.2.2", + "webdriverio": "7.16.13", + "yargs": "^17.0.0", + "yarn-install": "^1.0.0" + }, + "bin": { + "wdio": "bin/wdio.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@wdio/config": { + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-7.16.13.tgz", + "integrity": "sha512-LSGoa83tWQIBppB+LeHjY40B9tuuvmDV1qdBLVXR1ROcOUWWz/oQP3NFLtLm3266LXoJUbwebzGcRIK1EcNk3Q==", + "dev": true, + "dependencies": { + "@wdio/logger": "7.16.0", + "@wdio/types": "7.16.13", + "deepmerge": "^4.0.0", + "glob": "^7.1.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@wdio/junit-reporter": { + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/@wdio/junit-reporter/-/junit-reporter-7.16.13.tgz", + "integrity": "sha512-VKhly72NZY2/SNnfbYXO/HHov9oj+pk0aaq5TNzIJJoqtH4uqDz+L2p7wu9nKnRnywmwvaTm7pbYZGlOuty26A==", + "dev": true, + "dependencies": { + "@types/json-stringify-safe": "^5.0.0", + "@types/validator": "^13.1.3", + "@wdio/reporter": "7.16.13", + "@wdio/types": "7.16.13", + "json-stringify-safe": "^5.0.1", + "junit-report-builder": "^3.0.0", + "validator": "^13.0.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@wdio/cli": "^7.0.0" + } + }, + "node_modules/@wdio/local-runner": { + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-7.16.13.tgz", + "integrity": "sha512-Ri8R6RHD5VjI4m2CramKO9w+4jD7VwEoQFWqFzUI1g31UAuN1zy67R3UiYv0ohiBTW4MZt90CMLgumQNk7C5kA==", + "dev": true, + "dependencies": { + "@types/stream-buffers": "^3.0.3", + "@wdio/logger": "7.16.0", + "@wdio/repl": "7.16.13", + "@wdio/runner": "7.16.13", + "@wdio/types": "7.16.13", + "async-exit-hook": "^2.0.1", + "split2": "^4.0.0", + "stream-buffers": "^3.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@wdio/cli": "^7.0.0" + } + }, + "node_modules/@wdio/logger": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-7.16.0.tgz", + "integrity": "sha512-/6lOGb2Iow5eSsy7RJOl1kCwsP4eMlG+/QKro5zUJsuyNJSQXf2ejhpkzyKWLgQbHu83WX6cM1014AZuLkzoQg==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "loglevel": "^1.6.0", + "loglevel-plugin-prefix": "^0.8.4", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@wdio/mocha-framework": { + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-7.16.13.tgz", + "integrity": "sha512-yaLxEF5evXACGqxkch/IoJz8JGoQmcV+X635JBiMF6tl0+HSTYrL1ZPk1cED+9OI4jIPtmlhbgzne9IhoKCbpg==", + "dev": true, + "dependencies": { + "@types/mocha": "^9.0.0", + "@wdio/logger": "7.16.0", + "@wdio/types": "7.16.13", + "@wdio/utils": "7.16.13", + "expect-webdriverio": "^3.0.0", + "mocha": "^9.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@wdio/protocols": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-7.16.7.tgz", + "integrity": "sha512-Wv40pNQcLiPzQ3o98Mv4A8T1EBQ6k4khglz/e2r16CTm+F3DDYh8eLMAsU5cgnmuwwDKX1EyOiFwieykBn5MCg==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@wdio/repl": { + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-7.16.13.tgz", + "integrity": "sha512-XWh3dzp6U8LLL4cNGWFra+quVyXZ25Ym38zpsBVtV0/z5NCHJmjRS4ytyvvkzbQ8SyqQ7Y3G8MjfGNi2sBNkIQ==", + "dev": true, + "dependencies": { + "@wdio/utils": "7.16.13" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@wdio/reporter": { + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-7.16.13.tgz", + "integrity": "sha512-S7OH96yfSCJwmirsvT8khfWUfoMTiw0O1+UyiOYS/g0l+IideVK83kpyXYWfsALPahL2te0g57lPazriSfNAyA==", + "dev": true, + "dependencies": { + "@types/diff": "^5.0.0", + "@types/node": "^17.0.4", + "@types/object-inspect": "^1.8.0", + "@types/supports-color": "^8.1.0", + "@types/tmp": "^0.2.0", + "@wdio/types": "7.16.13", + "diff": "^5.0.0", + "fs-extra": "^10.0.0", + "object-inspect": "^1.10.3", + "supports-color": "8.1.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@wdio/runner": { + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-7.16.13.tgz", + "integrity": "sha512-/PJUK+8orHsUd5v8edWv5XS3pKx/si7DoYkU8PsgQX9FnU2y3oRfHrQwzI8s3TOnGag79f+yrGzzGCZFmmW0cw==", + "dev": true, + "dependencies": { + "@wdio/config": "7.16.13", + "@wdio/logger": "7.16.0", + "@wdio/types": "7.16.13", + "@wdio/utils": "7.16.13", + "deepmerge": "^4.0.0", + "gaze": "^1.1.2", + "webdriver": "7.16.13", + "webdriverio": "7.16.13" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@wdio/spec-reporter": { + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-7.16.13.tgz", + "integrity": "sha512-4gnflBJU+QDcmWgRy3tSRD47cqZmdjPLEJhsfhv/aBNtWPWMJtQru7nDFcLkxKLFPiN0D1F7gUMWbUMaDVlojg==", + "dev": true, + "dependencies": { + "@types/easy-table": "^0.0.33", + "@wdio/reporter": "7.16.13", + "@wdio/types": "7.16.13", + "chalk": "^4.0.0", + "easy-table": "^1.1.1", + "pretty-ms": "^7.0.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@wdio/cli": "^7.0.0" + } + }, + "node_modules/@wdio/types": { + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.16.13.tgz", + "integrity": "sha512-HIeXKCL+mUjyJxvnHSoaIo3NRgZLbeekyRIwo6USfd9qGlQ8dQ6fyCR3ZU9VqNz9j4+JIn+LRQ7imbz5SdnGbw==", + "dev": true, + "dependencies": { + "@types/node": "^17.0.4", + "got": "^11.8.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@wdio/utils": { + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-7.16.13.tgz", + "integrity": "sha512-O6D89Ghtm5XtTv4DPKvCBKZOZYNONIcBM5/hmdr3V9mzVrTFq8Q3uE8pmmq303Oh91KcoN8Em5zoAG7Zpc5tRg==", + "dev": true, + "dependencies": { + "@wdio/logger": "7.16.0", + "@wdio/types": "7.16.13", + "p-iteration": "^1.1.8" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/archiver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.0.tgz", + "integrity": "sha512-iUw+oDwK0fgNpvveEsdQ0Ase6IIKztBJU2U0E9MzszMfmVVUyv1QJhS2ITW9ZCqx8dktAxVAjWWkKehuZE8OPg==", + "dev": true, + "dependencies": { + "archiver-utils": "^2.1.0", + "async": "^3.2.0", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.0.0", + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "dev": true, + "dependencies": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/archiver-utils/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/archiver-utils/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/archiver/node_modules/async": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", + "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", + "dev": true + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/aria-query": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.0.0.tgz", + "integrity": "sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/array-differ": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", + "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/ast-metadata-inferer": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.7.0.tgz", + "integrity": "sha512-OkMLzd8xelb3gmnp6ToFvvsHLtS6CbagTkFQvQ+ZYFe3/AIl9iKikNR9G7pY3GfOR/2Xc222hwBjzI7HLkE76Q==", + "dev": true, + "dependencies": { + "@mdn/browser-compat-data": "^3.3.14" + } + }, + "node_modules/ast-metadata-inferer/node_modules/@mdn/browser-compat-data": { + "version": "3.3.14", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-3.3.14.tgz", + "integrity": "sha512-n2RC9d6XatVbWFdHLimzzUJxJ1KY8LdjqrW6YvGPiRmsHkhOUx74/Ct10x5Yo7bC/Jvqx7cDEW8IMPv/+vwEzA==", + "dev": true + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/async-exit-hook": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", + "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + { + "type": "consulting", + "url": "https://feross.org/support" } + ] + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" } }, - "@babel/generator": { - "version": "7.10.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.3.tgz", - "integrity": "sha512-drt8MUHbEqRzNR0xnF8nMehbY11b1SDkRw03PSNH/3Rb2Z35oxkddVSi3rcaak0YJQ86PCuE7Qx1jSFhbLNBMA==", + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true, - "requires": { - "@babel/types": "^7.10.3", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" + "engines": { + "node": ">=8" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/body": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz", + "integrity": "sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=", + "dev": true, + "dependencies": { + "continuable-cache": "^0.3.1", + "error": "^7.0.0", + "raw-body": "~1.1.0", + "safe-json-parse": "~1.0.1" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/browserslist": { + "version": "4.19.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.3.tgz", + "integrity": "sha512-XK3X4xtKJ+Txj8G5c30B4gsm71s69lqXlkYui4s6EkKxuv49qjYlY6oVd+IFJ73d4YymtM3+djvvt/R/iJwwDg==", + "dev": true, "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "caniuse-lite": "^1.0.30001312", + "electron-to-chromium": "^1.4.71", + "escalade": "^3.1.1", + "node-releases": "^2.0.2", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/browserslist-config-wikimedia": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/browserslist-config-wikimedia/-/browserslist-config-wikimedia-0.4.0.tgz", + "integrity": "sha512-U/fmsaGlCKOqRIjKqXwQ44qFqiStngRTphj1Cf6IHV6J8OK8T0gu9dKc7Ljq4v7bwhnhN+YCCa4fA3nZlPNivQ==", + "dev": true + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" } }, - "@babel/helper-function-name": { - "version": "7.10.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.3.tgz", - "integrity": "sha512-FvSj2aiOd8zbeqijjgqdMDSyxsGHaMt5Tr0XjQsGKHD3/1FP3wksjnLAWzxw7lvXiej8W1Jt47SKTZ6upQNiRw==", + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.10.3", - "@babel/template": "^7.10.3", - "@babel/types": "^7.10.3" + "engines": { + "node": "*" } }, - "@babel/helper-get-function-arity": { - "version": "7.10.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.3.tgz", - "integrity": "sha512-iUD/gFsR+M6uiy69JA6fzM5seno8oE85IYZdbVVEuQaZlEzMO2MXblh+KSPJgsZAUx0EEbWXU0yJaW7C9CdAVg==", + "node_modules/builtin-modules": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", "dev": true, - "requires": { - "@babel/types": "^7.10.3" + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "@babel/helper-member-expression-to-functions": { - "version": "7.10.3", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.3.tgz", - "integrity": "sha512-q7+37c4EPLSjNb2NmWOjNwj0+BOyYlssuQ58kHEWk1Z78K5i8vTUsteq78HMieRPQSl/NtpQyJfdjt3qZ5V2vw==", + "node_modules/bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", + "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=", + "dev": true + }, + "node_modules/cac": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/cac/-/cac-3.0.4.tgz", + "integrity": "sha1-bSTO7Dcu/lybeYgIvH9JtHJCpO8=", "dev": true, - "requires": { - "@babel/types": "^7.10.3" + "dependencies": { + "camelcase-keys": "^3.0.0", + "chalk": "^1.1.3", + "indent-string": "^3.0.0", + "minimist": "^1.2.0", + "read-pkg-up": "^1.0.1", + "suffix": "^0.1.0", + "text-table": "^0.2.0" + }, + "engines": { + "node": ">=4" } }, - "@babel/helper-module-imports": { - "version": "7.10.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.3.tgz", - "integrity": "sha512-Jtqw5M9pahLSUWA+76nhK9OG8nwYXzhQzVIGFoNaHnXF/r4l7kz4Fl0UAW7B6mqC5myoJiBP5/YQlXQTMfHI9w==", + "node_modules/cac/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true, - "requires": { - "@babel/types": "^7.10.3" + "engines": { + "node": ">=0.10.0" } }, - "@babel/helper-module-transforms": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz", - "integrity": "sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg==", + "node_modules/cac/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.10.1", - "@babel/helper-replace-supers": "^7.10.1", - "@babel/helper-simple-access": "^7.10.1", - "@babel/helper-split-export-declaration": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1", - "lodash": "^4.17.13" + "engines": { + "node": ">=0.10.0" } }, - "@babel/helper-optimise-call-expression": { - "version": "7.10.3", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.3.tgz", - "integrity": "sha512-kT2R3VBH/cnSz+yChKpaKRJQJWxdGoc6SjioRId2wkeV3bK0wLLioFpJROrX0U4xr/NmxSSAWT/9Ih5snwIIzg==", + "node_modules/cac/node_modules/camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", "dev": true, - "requires": { - "@babel/types": "^7.10.3" + "engines": { + "node": ">=0.10.0" } }, - "@babel/helper-replace-supers": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz", - "integrity": "sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A==", + "node_modules/cac/node_modules/camelcase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-3.0.0.tgz", + "integrity": "sha1-/AxsNgNj9zd+N5O5oWvM8QcMHKQ=", "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.10.1", - "@babel/helper-optimise-call-expression": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1" + "dependencies": { + "camelcase": "^3.0.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "@babel/helper-simple-access": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz", - "integrity": "sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw==", + "node_modules/cac/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, - "requires": { - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1" + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "@babel/helper-split-export-declaration": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz", - "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==", + "node_modules/cac/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true, - "requires": { - "@babel/types": "^7.10.1" + "engines": { + "node": ">=0.8.0" } }, - "@babel/helper-validator-identifier": { - "version": "7.10.3", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.3.tgz", - "integrity": "sha512-bU8JvtlYpJSBPuj1VUmKpFGaDZuLxASky3LhaKj3bmpSTY6VWooSM8msk+Z0CZoErFye2tlABF6yDkT3FOPAXw==", + "node_modules/cac/node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cac/node_modules/indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/cac/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cac/node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cac/node_modules/path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cac/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cac/node_modules/read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "dependencies": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cac/node_modules/read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "dependencies": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cac/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cac/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true, + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", + "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "dev": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-keys/node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001312", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz", + "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/chrome-launcher": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.0.tgz", + "integrity": "sha512-ZQqX5kb9H0+jy1OqLnWampfocrtSZaGl7Ny3F9GRha85o4odbL8x55paUzh51UC7cEmZ5obp3H2Mm70uC2PpRA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "escape-string-regexp": "^4.0.0", + "is-wsl": "^2.2.0", + "lighthouse-logger": "^1.0.0" + }, + "bin": { + "print-chrome-path": "bin/print-chrome-path.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/ci-info": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", + "dev": true + }, + "node_modules/clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha1-jffHquUf02h06PjQW5GAvBGj/tc=", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/clean-regexp/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", + "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-regexp": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz", + "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==", + "dev": true, + "dependencies": { + "is-regexp": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/colord": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.2.tgz", + "integrity": "sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==", + "dev": true + }, + "node_modules/colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/comment-parser": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.0.tgz", + "integrity": "sha512-hRpmWIKgzd81vn0ydoWoyPoALEOnF4wt8yKD35Ib1D6XC2siLiYaiqfGkYrunuKdsXGwpBpHU3+9r+RVw2NZfA==", + "dev": true, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/compress-commons": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", + "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==", + "dev": true, + "dependencies": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^4.0.2", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/continuable-cache": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz", + "integrity": "sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=", + "dev": true + }, + "node_modules/core-js": { + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.21.1.tgz", + "integrity": "sha512-FRq5b/VMrWlrmCzwRrpDYNxyHP9BcAZC+xHJaqTgIE5091ZV1NTmyh0sGOg5XqpnHvR0svdy0sv1gWA1zmhxig==", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", + "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "dev": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/crc-32": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.1.tgz", + "integrity": "sha512-Dn/xm/1vFFgs3nfrpEVScHoIslO9NZRITWGz/1E/St6u4xw99vfZzVkW0OSnzx2h9egej9xwMCEut6sqwokM/w==", + "dev": true, + "dependencies": { + "exit-on-epipe": "~1.0.1", + "printj": "~1.3.1" + }, + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/crc32-stream": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz", + "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==", + "dev": true, + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/cross-fetch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "dev": true, + "dependencies": { + "node-fetch": "2.6.7" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-functions-list": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.0.1.tgz", + "integrity": "sha512-PriDuifDt4u4rkDgnqRCLnjfMatufLmWNfQnGCq34xZwpY3oabwhB9SqRBmuvWUgndbemCFlKqg+nO7C2q0SBw==", + "dev": true, + "engines": { + "node": ">=12.22" + } + }, + "node_modules/css-rule-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/css-rule-stream/-/css-rule-stream-1.1.0.tgz", + "integrity": "sha1-N4bnGYmD2WWibjGVfgkHjLt3BaI=", + "dev": true, + "dependencies": { + "css-tokenize": "^1.0.1", + "duplexer2": "0.0.2", + "ldjson-stream": "^1.2.1", + "through2": "^0.6.3" + }, + "bin": { + "css-rule-stream": "index.js" + } + }, + "node_modules/css-rule-stream/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "node_modules/css-rule-stream/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/css-rule-stream/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "node_modules/css-rule-stream/node_modules/through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "dependencies": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + }, + "node_modules/css-select": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.2.1.tgz", + "integrity": "sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^5.1.0", + "domhandler": "^4.3.0", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-shorthand-properties": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/css-shorthand-properties/-/css-shorthand-properties-1.1.1.tgz", + "integrity": "sha512-Md+Juc7M3uOdbAFwOYlTrccIZ7oCFuzrhKYQjdeUEW/sE1hv17Jp/Bws+ReOPpGVBTYCBoYo+G17V5Qo8QQ75A==", + "dev": true + }, + "node_modules/css-tokenize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-tokenize/-/css-tokenize-1.0.1.tgz", + "integrity": "sha1-RiXLHtohwUOFi3+B1oA8HSb8FL4=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^1.0.33" + } + }, + "node_modules/css-tokenize/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "node_modules/css-tokenize/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/css-tokenize/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/css-tree/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-value": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/css-value/-/css-value-0.0.1.tgz", + "integrity": "sha1-Xv1sLupeof1rasV+wEJ7GEUkJOo=", + "dev": true + }, + "node_modules/css-what": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", + "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dev": true, + "dependencies": { + "css-tree": "^1.1.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/date-format": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-0.0.2.tgz", + "integrity": "sha1-+v1Ej3IRXvHitzkVWukvK+bCjdE=", + "dev": true + }, + "node_modules/dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/devtools": { + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/devtools/-/devtools-7.16.13.tgz", + "integrity": "sha512-jm/DL5tlOUUMe0pUgahDqixw3z+NANLN6DYDeZPFv7z0CBtmnaTyOe2zbT0apLxCBpi800VeXaISVZwmKE2NiQ==", + "dev": true, + "dependencies": { + "@types/node": "^17.0.4", + "@types/ua-parser-js": "^0.7.33", + "@wdio/config": "7.16.13", + "@wdio/logger": "7.16.0", + "@wdio/protocols": "7.16.7", + "@wdio/types": "7.16.13", + "@wdio/utils": "7.16.13", + "chrome-launcher": "^0.15.0", + "edge-paths": "^2.1.0", + "puppeteer-core": "^13.0.0", + "query-selector-shadow-dom": "^1.0.0", + "ua-parser-js": "^1.0.1", + "uuid": "^8.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/devtools-protocol": { + "version": "0.0.953906", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.953906.tgz", + "integrity": "sha512-Z2vAafCNnl0Iw/u7TUjqOXW1sOhAMDOviflmUoUIxfq2rgfsoCO3qruB/LUJCdqF9aTJ32DUjXyMsX3+if6kDQ==", + "dev": true + }, + "node_modules/devtools/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/doiuse": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/doiuse/-/doiuse-4.4.1.tgz", + "integrity": "sha512-TUpr1/YNg20IB09tZmwGCTsTQoxj8jUld/hUZprZMj8vj0VpAJySXEWCr8WMvqvgzk0/kG/FxeSMGKode4UjPg==", + "dev": true, + "dependencies": { + "browserslist": "^4.16.1", + "caniuse-lite": "^1.0.30001179", + "css-rule-stream": "^1.1.0", + "duplexer2": "0.0.2", + "ldjson-stream": "^1.2.1", + "multimatch": "^5.0.0", + "postcss": "^8.2.4", + "source-map": "^0.7.3", + "through2": "^4.0.2", + "yargs": "^16.2.0" + }, + "bin": { + "doiuse": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/doiuse/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/dom-serializer": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz", + "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==", + "dev": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "dev": true, + "dependencies": { + "readable-stream": "~1.1.9" + } + }, + "node_modules/duplexer2/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/duplexer2/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "node_modules/easy-table": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.2.0.tgz", + "integrity": "sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "optionalDependencies": { + "wcwidth": "^1.0.1" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/edge-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-2.2.1.tgz", + "integrity": "sha512-AI5fC7dfDmCdKo3m5y7PkYE8m6bMqR6pvVpgtrZkkhcJXFLelUgkjrhk3kXXx8Kbw2cRaTT4LkOR7hqf39KJdw==", + "dev": true, + "dependencies": { + "@types/which": "^1.3.2", + "which": "^2.0.2" + } + }, + "node_modules/ejs": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", + "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==", + "dev": true, + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.71", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.71.tgz", + "integrity": "sha512-Hk61vXXKRb2cd3znPE9F+2pLWdIOmP7GjiTj45y6L3W/lO+hSnUSUhq+6lEaERWBdZOHbk2s3YV5c9xVl3boVw==", "dev": true }, - "@babel/helpers": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.1.tgz", - "integrity": "sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw==", + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/error/-/error-7.2.1.tgz", + "integrity": "sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA==", + "dev": true, + "dependencies": { + "string-template": "~0.2.1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.10.0.tgz", + "integrity": "sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw==", + "dev": true, + "dependencies": { + "@eslint/eslintrc": "^1.2.0", + "@humanwhocodes/config-array": "^0.9.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-wikimedia": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.22.1.tgz", + "integrity": "sha512-TtN+gWJrcW0i1sEu7vPE1tHpEilrMUuTxP6UK97Amvva/KDV9/tvRUifGhw0q5uBswp+HWgF12p8rq68hZqMbA==", + "dev": true, + "dependencies": { + "eslint": "^8.6.0", + "eslint-plugin-compat": "^4.0.2", + "eslint-plugin-es": "^4.1.0", + "eslint-plugin-jsdoc": "^37.7.1", + "eslint-plugin-json-es": "^1.5.4", + "eslint-plugin-mediawiki": "^0.3.0", + "eslint-plugin-mocha": "^9.0.0", + "eslint-plugin-no-jquery": "^2.7.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-qunit": "^7.2.0", + "eslint-plugin-unicorn": "^40.1.0", + "eslint-plugin-vue": "^8.4.1", + "eslint-plugin-wdio": "^7.4.2", + "eslint-plugin-yml": "^0.13.0" + } + }, + "node_modules/eslint-plugin-compat": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-4.0.2.tgz", + "integrity": "sha512-xqvoO54CLTVaEYGMzhu35Wzwk/As7rCvz/2dqwnFiWi0OJccEtGIn+5qq3zqIu9nboXlpdBN579fZcItC73Ycg==", + "dev": true, + "dependencies": { + "@mdn/browser-compat-data": "^4.1.5", + "ast-metadata-inferer": "^0.7.0", + "browserslist": "^4.16.8", + "caniuse-lite": "^1.0.30001304", + "core-js": "^3.16.2", + "find-up": "^5.0.0", + "lodash.memoize": "4.1.2", + "semver": "7.3.5" + }, + "engines": { + "node": ">=9.x" + }, + "peerDependencies": { + "eslint": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-plugin-es": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz", + "integrity": "sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==", + "dev": true, + "dependencies": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" + } + }, + "node_modules/eslint-plugin-jsdoc": { + "version": "37.9.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-37.9.4.tgz", + "integrity": "sha512-VxCyGgUNNnj2T4bb1OqltkbsPp3ehRzR5onIfh6zGrAvISmvgX/sbxUlh3YyGqWtjOTSBCURdKdmelSXEIHnlA==", + "dev": true, + "dependencies": { + "@es-joy/jsdoccomment": "~0.20.1", + "comment-parser": "1.3.0", + "debug": "^4.3.3", + "escape-string-regexp": "^4.0.0", + "esquery": "^1.4.0", + "regextras": "^0.8.0", + "semver": "^7.3.5", + "spdx-expression-parse": "^3.0.1" + }, + "engines": { + "node": "^12 || ^14 || ^16 || ^17" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-plugin-json-es": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-json-es/-/eslint-plugin-json-es-1.5.4.tgz", + "integrity": "sha512-DdjnNMUZ1iMrUXfxUQrTU7IyoEOsa4Kg0Zd6nOyOq1mUb75deK7NrcbI1FlWGdGVgqX99bUOD27i81EYiG794Q==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.0.0", + "espree": "^9.0.0" + }, + "peerDependencies": { + "eslint": ">= 7" + } + }, + "node_modules/eslint-plugin-json-es/node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-plugin-mediawiki": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.3.0.tgz", + "integrity": "sha512-Lhyj2PSkhDzYSc1PNbURysY/WoqvY0brw558ZInT3erzf5KUlro18MTKFdV+nlht475ZgnsfHsgfg6Ut2w1SVg==", + "dev": true, + "dependencies": { + "eslint-plugin-vue": "^7.20.0", + "upath": "^2.0.1" + }, + "peerDependencies": { + "eslint": ">=5.0.0" + } + }, + "node_modules/eslint-plugin-mediawiki/node_modules/eslint-plugin-vue": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-7.20.0.tgz", + "integrity": "sha512-oVNDqzBC9h3GO+NTgWeLMhhGigy6/bQaQbHS+0z7C4YEu/qK/yxHvca/2PTZtGNPsCrHwOTgKMrwu02A9iPBmw==", + "dev": true, + "dependencies": { + "eslint-utils": "^2.1.0", + "natural-compare": "^1.4.0", + "semver": "^6.3.0", + "vue-eslint-parser": "^7.10.0" + }, + "engines": { + "node": ">=8.10" + }, + "peerDependencies": { + "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-plugin-mediawiki/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-mediawiki/node_modules/espree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", + "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/eslint-plugin-mediawiki/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-mediawiki/node_modules/vue-eslint-parser": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.11.0.tgz", + "integrity": "sha512-qh3VhDLeh773wjgNTl7ss0VejY9bMMa0GoDG2fQVyDzRFdiU3L7fw74tWZDHNQXdZqxO3EveQroa9ct39D2nqg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "eslint-scope": "^5.1.1", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.2.1", + "esquery": "^1.4.0", + "lodash": "^4.17.21", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8.10" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5.0.0" + } + }, + "node_modules/eslint-plugin-mocha": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-9.0.0.tgz", + "integrity": "sha512-d7knAcQj1jPCzZf3caeBIn3BnW6ikcvfz0kSqQpwPYcVGLoJV5sz0l0OJB2LR8I7dvTDbqq1oV6ylhSgzA10zg==", + "dev": true, + "dependencies": { + "eslint-utils": "^3.0.0", + "ramda": "^0.27.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-mocha/node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-plugin-no-jquery": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-2.7.0.tgz", + "integrity": "sha512-Aeg7dA6GTH1AcWLlBtWNzOU9efK5KpNi7b0EhBO0o0M+awyzguUUo8gF6hXGjQ9n5h8/uRtYv9zOqQkeC5CG0w==", + "dev": true, + "peerDependencies": { + "eslint": ">=2.3.0" + } + }, + "node_modules/eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "dependencies": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "peerDependencies": { + "eslint": ">=5.16.0" + } + }, + "node_modules/eslint-plugin-node/node_modules/eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "dependencies": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" + } + }, + "node_modules/eslint-plugin-node/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-qunit": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-qunit/-/eslint-plugin-qunit-7.2.0.tgz", + "integrity": "sha512-ebT6aOpmMj4vchG0hVw9Ukbutk/lgywrc8gc9w9hH2/4WjKqwMlyM7iVwqB7OAXv6gtQMJZuziT0wNjjymAuWA==", + "dev": true, + "dependencies": { + "eslint-utils": "^3.0.0", + "requireindex": "^1.2.0" + }, + "engines": { + "node": "12.x || 14.x || >=16.0.0" + } + }, + "node_modules/eslint-plugin-qunit/node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-plugin-unicorn": { + "version": "40.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-40.1.0.tgz", + "integrity": "sha512-y5doK2DF9Sr5AqKEHbHxjFllJ167nKDRU01HDcWyv4Tnmaoe9iNxMrBnaybZvWZUaE3OC5Unu0lNIevYamloig==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.15.7", + "ci-info": "^3.3.0", + "clean-regexp": "^1.0.0", + "eslint-utils": "^3.0.0", + "esquery": "^1.4.0", + "indent-string": "^4.0.0", + "is-builtin-module": "^3.1.0", + "lodash": "^4.17.21", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.24", + "safe-regex": "^2.1.1", + "semver": "^7.3.5", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" + }, + "peerDependencies": { + "eslint": ">=7.32.0" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-plugin-vue": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-8.5.0.tgz", + "integrity": "sha512-i1uHCTAKOoEj12RDvdtONWrGzjFm/djkzqfhmQ0d6M/W8KM81mhswd/z+iTZ0jCpdUedW3YRgcVfQ37/J4zoYQ==", + "dev": true, + "dependencies": { + "eslint-utils": "^3.0.0", + "natural-compare": "^1.4.0", + "semver": "^7.3.5", + "vue-eslint-parser": "^8.0.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-plugin-vue/node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-plugin-wdio": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-wdio/-/eslint-plugin-wdio-7.4.2.tgz", + "integrity": "sha512-tkISFycJmRFMKsEjetRcAmWSHKJKnw5rKHDxfE7Ob3tF5lbmYlCLfNKH0UwanOpSdulpe52s3K+CBHSd6qUUNQ==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/eslint-plugin-yml": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-0.13.0.tgz", + "integrity": "sha512-rZvdnhe28jIbgSIZo3qYqkl9hKslyTDfMwqIGDzz873gxghzBw0yeFG+P7sMfOkFfpqwJzZy3IKe2cIiCp4FrA==", + "dev": true, + "dependencies": { + "debug": "^4.3.2", + "lodash": "^4.17.21", + "natural-compare": "^1.4.0", + "yaml-eslint-parser": "^0.5.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/espree": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", + "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "dev": true, + "dependencies": { + "acorn": "^8.7.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/espree/node_modules/acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", + "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", + "dev": true + }, + "node_modules/execall": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz", + "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==", + "dev": true, + "dependencies": { + "clone-regexp": "^2.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/exit-on-epipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", + "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/expect-webdriverio": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/expect-webdriverio/-/expect-webdriverio-3.1.4.tgz", + "integrity": "sha512-65FTS3bmxcIp0cq6fLb/72TrCQXBCpwPLC7SwMWdpPlLq461mXcK1BPKJJjnIC587aXSKD+3E4hvnlCtwDmXfg==", + "dev": true, + "dependencies": { + "expect": "^27.0.2", + "jest-matcher-utils": "^27.0.2" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/findup-sync": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", + "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", + "dev": true, + "dependencies": { + "glob": "~5.0.0" + }, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/findup-sync/node_modules/glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/fined": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", + "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/flagged-respawn": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", + "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "dev": true + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "dependencies": { + "for-in": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "node_modules/fs-extra": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", + "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/gaze": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", + "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "dev": true, + "dependencies": { + "globule": "^1.0.0" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-port": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", + "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/getobject": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/getobject/-/getobject-1.0.2.tgz", + "integrity": "sha512-2zblDBaFcb3rB4rF77XVnuINOE2h2k/OnqXAiy0IrTxUfV1iFp3la33oAQVY9pCpWU268WFYVt2t71hlMuLsOg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "13.12.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", + "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=", + "dev": true + }, + "node_modules/globule": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.3.tgz", + "integrity": "sha512-mb1aYtDbIjTu4ShMB85m3UzjX9BVKe9WCzsnfMSZk+K5GpIbBOexgg4PPCt5eHDEG5/ZQAUX2Kct02zfiPLsKg==", + "dev": true, + "dependencies": { + "glob": "~7.1.1", + "lodash": "~4.17.10", + "minimatch": "~3.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/globule/node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globule/node_modules/minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/got": { + "version": "11.8.5", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.5.tgz", + "integrity": "sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", + "dev": true + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "node_modules/growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true, + "engines": { + "node": ">=4.x" + } + }, + "node_modules/grunt": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.5.3.tgz", + "integrity": "sha512-mKwmo4X2d8/4c/BmcOETHek675uOqw0RuA/zy12jaspWqvTp4+ZeQF1W+OTpcbncnaBsfbQJ6l0l4j+Sn/GmaQ==", + "dev": true, + "dependencies": { + "dateformat": "~3.0.3", + "eventemitter2": "~0.4.13", + "exit": "~0.1.2", + "findup-sync": "~0.3.0", + "glob": "~7.1.6", + "grunt-cli": "~1.4.3", + "grunt-known-options": "~2.0.0", + "grunt-legacy-log": "~3.0.0", + "grunt-legacy-util": "~2.0.1", + "iconv-lite": "~0.4.13", + "js-yaml": "~3.14.0", + "minimatch": "~3.0.4", + "mkdirp": "~1.0.4", + "nopt": "~3.0.6", + "rimraf": "~3.0.2" + }, + "bin": { + "grunt": "bin/grunt" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/grunt-banana-checker": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/grunt-banana-checker/-/grunt-banana-checker-0.10.0.tgz", + "integrity": "sha512-Sx+P3zWjn4YmBCqzidnCEkYrACe1SLTIT8kKC6C3f21Hu6sm17U/V+re343cuK3U+iGZv15ux6bY+69buIbYrA==", + "dev": true, + "bin": { + "banana-checker": "src/cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/grunt-cli": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.4.3.tgz", + "integrity": "sha512-9Dtx/AhVeB4LYzsViCjUQkd0Kw0McN2gYpdmGYKtE2a5Yt7v1Q+HYZVWhqXc/kGnxlMtqKDxSwotiGeFmkrCoQ==", + "dev": true, + "dependencies": { + "grunt-known-options": "~2.0.0", + "interpret": "~1.1.0", + "liftup": "~3.0.1", + "nopt": "~4.0.1", + "v8flags": "~3.2.0" + }, + "bin": { + "grunt": "bin/grunt" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/grunt-cli/node_modules/nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "dependencies": { + "abbrev": "1", + "osenv": "^0.1.4" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/grunt-contrib-watch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-1.1.0.tgz", + "integrity": "sha512-yGweN+0DW5yM+oo58fRu/XIRrPcn3r4tQx+nL7eMRwjpvk+rQY6R8o94BPK0i2UhTg9FN21hS+m8vR8v9vXfeg==", + "dev": true, + "dependencies": { + "async": "^2.6.0", + "gaze": "^1.1.0", + "lodash": "^4.17.10", + "tiny-lr": "^1.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/grunt-eslint": { + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/grunt-eslint/-/grunt-eslint-24.0.0.tgz", + "integrity": "sha512-WpTeBBFweyhMuPjGwRSQV9JFJ+EczIdlsc7Dd/1g78QVI1aZsk4g/H3e+3S5HEwsS1RKL2YZIrGj8hMLlBfN8w==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2", + "eslint": "^8.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + }, + "peerDependencies": { + "grunt": ">=1" + } + }, + "node_modules/grunt-known-options": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-2.0.0.tgz", + "integrity": "sha512-GD7cTz0I4SAede1/+pAbmJRG44zFLPipVtdL9o3vqx9IEyb7b4/Y3s7r6ofI3CchR5GvYJ+8buCSioDv5dQLiA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/grunt-legacy-log": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-3.0.0.tgz", + "integrity": "sha512-GHZQzZmhyq0u3hr7aHW4qUH0xDzwp2YXldLPZTCjlOeGscAOWWPftZG3XioW8MasGp+OBRIu39LFx14SLjXRcA==", + "dev": true, + "dependencies": { + "colors": "~1.1.2", + "grunt-legacy-log-utils": "~2.1.0", + "hooker": "~0.2.3", + "lodash": "~4.17.19" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/grunt-legacy-log-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.1.0.tgz", + "integrity": "sha512-lwquaPXJtKQk0rUM1IQAop5noEpwFqOXasVoedLeNzaibf/OPWjKYvvdqnEHNmU+0T0CaReAXIbGo747ZD+Aaw==", + "dev": true, + "dependencies": { + "chalk": "~4.1.0", + "lodash": "~4.17.19" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/grunt-legacy-util": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-2.0.1.tgz", + "integrity": "sha512-2bQiD4fzXqX8rhNdXkAywCadeqiPiay0oQny77wA2F3WF4grPJXCvAcyoWUJV+po/b15glGkxuSiQCK299UC2w==", + "dev": true, + "dependencies": { + "async": "~3.2.0", + "exit": "~0.1.2", + "getobject": "~1.0.0", + "hooker": "~0.2.3", + "lodash": "~4.17.21", + "underscore.string": "~3.3.5", + "which": "~2.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/grunt-legacy-util/node_modules/async": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", + "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", + "dev": true + }, + "node_modules/grunt-stylelint": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/grunt-stylelint/-/grunt-stylelint-0.18.0.tgz", + "integrity": "sha512-Ks5OfRUCA6E1v5PkCQKYaMErHtoec/Ub0Vb1xvZ0CKm/1zzWKuqEu2ZVtFcQVDqrC5UM6AXaLHpsLiocVKAgbg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "stylelint": "14.x" + } + }, + "node_modules/grunt/node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/grunt/node_modules/minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dev": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "dependencies": { + "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hooker": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", + "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/html-tags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.2.0.tgz", + "integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "node_modules/http-parser-js": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.5.tgz", + "integrity": "sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA==", + "dev": true + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/inquirer": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.1.5.tgz", + "integrity": "sha512-G6/9xUqmt/r+UvufSyrPpt84NYwhKZ9jLsgMbQzlx804XErNupor8WQdBnBRrXmBfTPpuwf1sV+ss2ovjgdXIg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.2.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "node_modules/is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "dependencies": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-builtin-module": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz", + "integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==", + "dev": true, + "dependencies": { + "builtin-modules": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regexp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz", + "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "dependencies": { + "is-unc-path": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "dependencies": { + "unc-path-regex": "^0.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "node_modules/jake": { + "version": "10.8.5", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", + "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", + "dev": true, + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/async": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", + "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", + "dev": true + }, + "node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-message-util/node_modules/@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "node_modules/jsdoc-type-pratt-parser": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-2.2.3.tgz", + "integrity": "sha512-QPyxq62Q8veBSDtDrWmqaEPjSCeknUV9dH/OAGt3q9an8qC8UQDqitQiw1NvoMskIESpoRZ6qzt4H3rlK0xo8A==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dev": true, + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/junit-report-builder": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/junit-report-builder/-/junit-report-builder-3.0.0.tgz", + "integrity": "sha512-aW7DnfLddUb51T+V08bJyecexaLomy5ID/0FXvhwsRXs9E0abvDaDT024U99J2agU3dt4q0ppzfKxSwrIIgXWg==", + "dev": true, + "dependencies": { + "date-format": "0.0.2", + "lodash": "^4.17.15", + "make-dir": "^1.3.0", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/keyv": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.1.1.tgz", + "integrity": "sha512-tGv1yP6snQVDSM4X6yxrv2zzq/EvpW+oYiUz6aueW1u9CtS8RzUQYxxmFwgZlO2jSgCxQbchhxaqXXp2hnKGpQ==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/known-css-properties": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.24.0.tgz", + "integrity": "sha512-RTSoaUAfLvpR357vWzAz/50Q/BmHfmE6ETSWfutT0AJiw10e6CmcdYRQJlLRd95B53D0Y2aD1jSxD3V3ySF+PA==", + "dev": true + }, + "node_modules/ky": { + "version": "0.28.7", + "resolved": "https://registry.npmjs.org/ky/-/ky-0.28.7.tgz", + "integrity": "sha512-a23i6qSr/ep15vdtw/zyEQIDLoUaKDg9Jf04CYl/0ns/wXNYna26zJpI+MeIFaPeDvkrjLPrKtKOiiI3IE53RQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/ky?sponsor=1" + } + }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/ldjson-stream": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ldjson-stream/-/ldjson-stream-1.2.1.tgz", + "integrity": "sha1-kb7O2lrE7SsX5kn7d356v6AYnCs=", + "dev": true, + "dependencies": { + "split2": "^0.2.1", + "through2": "^0.6.1" + } + }, + "node_modules/ldjson-stream/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "node_modules/ldjson-stream/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ldjson-stream/node_modules/split2": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/split2/-/split2-0.2.1.tgz", + "integrity": "sha1-At2smtwD7Au3jBKC7Aecpuha6QA=", + "dev": true, + "dependencies": { + "through2": "~0.6.1" + } + }, + "node_modules/ldjson-stream/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "node_modules/ldjson-stream/node_modules/through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "dependencies": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/liftup": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/liftup/-/liftup-3.0.1.tgz", + "integrity": "sha512-yRHaiQDizWSzoXk3APcA71eOI/UuhEkNN9DiW2Tt44mhYzX4joFoCZlxsSOF7RyeLlfqzFLQI1ngFq3ggMPhOw==", + "dev": true, + "dependencies": { + "extend": "^3.0.2", + "findup-sync": "^4.0.0", + "fined": "^1.2.0", + "flagged-respawn": "^1.0.1", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.1", + "rechoir": "^0.7.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/liftup/node_modules/findup-sync": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", + "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", + "dev": true, + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^4.0.2", + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/lighthouse-logger": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.3.0.tgz", + "integrity": "sha512-BbqAKApLb9ywUli+0a+PcV04SyJ/N1q/8qgCNe6U97KbPCS1BTksEuHFLYdvc8DltuhfxIUBqDZsC0bBGtl3lA==", + "dev": true, + "dependencies": { + "debug": "^2.6.9", + "marky": "^1.2.2" + } + }, + "node_modules/lighthouse-logger/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/lighthouse-logger/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/livereload-js": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz", + "integrity": "sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw==", + "dev": true + }, + "node_modules/load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file/node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", + "dev": true + }, + "node_modules/lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", + "dev": true + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", + "dev": true + }, + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "dev": true + }, + "node_modules/lodash.isobject": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz", + "integrity": "sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=", + "dev": true + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", + "dev": true + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.pickby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", + "integrity": "sha1-feoh2MGNdwOifHBMFdO4SmfjOv8=", + "dev": true + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "node_modules/lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", + "dev": true + }, + "node_modules/lodash.zip": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", + "integrity": "sha1-7GZi5IlkCO1KtsVCo5kLcswIACA=", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/loglevel": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.0.tgz", + "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, + "node_modules/loglevel-plugin-prefix": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz", + "integrity": "sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==", + "dev": true + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/marky": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/marky/-/marky-1.2.4.tgz", + "integrity": "sha512-zd2/GiSn6U3/jeFVZ0J9CA1LzQ8RfIVvXkb/U0swFHF/zT+dVohTAWjmo2DcIuofmIIIROlwTbd+shSeXmxr0w==", + "dev": true + }, + "node_modules/mathml-tag-names": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true + }, + "node_modules/meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "dev": true, + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/meow/node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/meow/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "dev": true, + "dependencies": { + "mime-db": "1.51.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, + "node_modules/mocha": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", + "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", + "dev": true, + "dependencies": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.3", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "4.2.1", + "ms": "2.1.3", + "nanoid": "3.3.1", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.2.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/mocha/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", + "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/mocha/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/multimatch": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz", + "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==", + "dev": true, + "dependencies": { + "@types/minimatch": "^3.0.3", + "array-differ": "^3.0.0", + "array-union": "^2.1.0", + "arrify": "^2.0.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/multimatch/node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "node_modules/mwbot": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mwbot/-/mwbot-2.0.0.tgz", + "integrity": "sha512-9iTx8oFMntC60yyaPJjN4GEgiQlal7i03jATu7kq5b9BGW5aNz7YbrpjaciLNr0Z33PTdQe0hRTJ0JdUJi2WQg==", + "dev": true, + "dependencies": { + "bluebird": "^3.7.2", + "request": "^2.88.2", + "semlog": "^0.6.10", + "semver": "7.3.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mwbot/node_modules/semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/nanoid": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", + "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-releases": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", + "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", + "dev": true + }, + "node_modules/nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-selector": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz", + "integrity": "sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=", + "dev": true + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nth-check": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", + "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "dev": true, + "dependencies": { + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "dev": true, + "dependencies": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-iteration": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/p-iteration/-/p-iteration-1.1.8.tgz", + "integrity": "sha512-IMFBSDIYcPNnW7uWYGrBqmvTiq7W0uB0fJn6shQZs7dlF3OvrHOre+JT9ikSZ7gZS3vWqclVgoQSvToJrns7uQ==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "dev": true, + "dependencies": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", + "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dev": true, + "dependencies": { + "path-root-regex": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss": { + "version": "8.4.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.13.tgz", + "integrity": "sha512-jtL6eTBrza5MPzy8oJLFuUscHDXTV5KcLlqAWHl5q5WYRfnNRGSmOZmOZ1T6Gy7A99mOZfqungmZMpMmCVJ8ZA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "dependencies": { + "nanoid": "^3.3.3", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-less": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-6.0.0.tgz", + "integrity": "sha512-FPX16mQLyEjLzEuuJtxA8X3ejDLNGGEG503d2YGZR5Ask1SpDN8KmZUMpzCvyalWRywAn1n1VOA5dcqfCLo5rg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "postcss": "^8.3.5" + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=", + "dev": true + }, + "node_modules/postcss-resolve-nested-selector": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", + "integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=", + "dev": true + }, + "node_modules/postcss-safe-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", + "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", + "dev": true, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pretty-ms": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", + "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", + "dev": true, + "dependencies": { + "parse-ms": "^2.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prettyjson": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/prettyjson/-/prettyjson-1.2.5.tgz", + "integrity": "sha512-rksPWtoZb2ZpT5OVgtmy0KHVM+Dca3iVwWY9ifwhcexfjebtgjg3wmrUt9PvJ59XIYBcknQeYHD8IAnVlh9lAw==", + "dev": true, + "dependencies": { + "colors": "1.4.0", + "minimist": "^1.2.0" + }, + "bin": { + "prettyjson": "bin/prettyjson" + } + }, + "node_modules/prettyjson/node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/printj": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/printj/-/printj-1.3.1.tgz", + "integrity": "sha512-GA3TdL8szPK4AQ2YnOe/b+Y1jUFwmmGMMK/qbY7VcE3Z7FU8JstbKiKRzO6CIiAKPhTO8m01NoQ0V5f3jc4OGg==", + "dev": true, + "bin": { + "printj": "bin/printj.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/puppeteer-core": { + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-13.4.0.tgz", + "integrity": "sha512-TcGT5Qgq9tgI0msFrIhq70N1+WrnGowjn0hc4vtzEIizJETXOZVrQZVWy051lO/nxEVGyqRXHwtpWjv4/fRbUw==", + "dev": true, + "dependencies": { + "cross-fetch": "3.1.5", + "debug": "4.3.3", + "devtools-protocol": "0.0.960912", + "extract-zip": "2.0.1", + "https-proxy-agent": "5.0.0", + "pkg-dir": "4.2.0", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "rimraf": "3.0.2", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "ws": "8.5.0" + }, + "engines": { + "node": ">=10.18.1" + } + }, + "node_modules/puppeteer-core/node_modules/devtools-protocol": { + "version": "0.0.960912", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.960912.tgz", + "integrity": "sha512-I3hWmV9rWHbdnUdmMKHF2NuYutIM2kXz2mdXW8ha7TbRlGTVs+PF+PsB5QWvpCek4Fy9B+msiispCfwlhG5Sqg==", + "dev": true + }, + "node_modules/qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/query-selector-shadow-dom": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.0.tgz", + "integrity": "sha512-bK0/0cCI+R8ZmOF1QjT7HupDUYCxbf/9TJgAmSXQxZpftXmTAeil9DRoCnTDkWbvOyZzhcMBwKpptWcdkGFIMg==", + "dev": true + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ramda": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.2.tgz", + "integrity": "sha512-SbiLPU40JuJniHexQSAgad32hfwd+DRUdwF2PlVuI5RZD0/vahUco7R8vD86J/tcEKKF9vZrUVwgtmGCqlCKyA==", + "dev": true + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/raw-body": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", + "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=", + "dev": true, + "dependencies": { + "bytes": "1", + "string_decoder": "0.10" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/raw-body/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdir-glob": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.1.tgz", + "integrity": "sha512-91/k1EzZwDx6HbERR+zucygRFfiPl2zkIYZtv3Jjr6Mn7SkKcVct8aVO+sSRiGMc6fLf72du3d92/uY63YPdEA==", + "dev": true, + "dependencies": { + "minimatch": "^3.0.4" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", + "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "dev": true, + "dependencies": { + "resolve": "^1.9.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "dev": true, + "dependencies": { + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/regexp-tree": { + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz", + "integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==", + "dev": true, + "bin": { + "regexp-tree": "bin/regexp-tree" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/regextras": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.8.0.tgz", + "integrity": "sha512-k519uI04Z3SaY0fLX843MRXnDeG2+vHOFsyhiPZvNLe7r8rD2YNRjq4BQLZZ0oAr2NrtvZlICsXysGNFPGa3CQ==", + "dev": true, + "engines": { + "node": ">=0.1.14" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "dev": true, + "engines": { + "node": ">=0.10.5" + } + }, + "node_modules/resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true + }, + "node_modules/resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-dir/node_modules/global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "dependencies": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-dir/node_modules/global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-dir/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/responselike": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", + "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", + "dev": true, + "dependencies": { + "lowercase-keys": "^2.0.0" + } + }, + "node_modules/resq": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/resq/-/resq-1.10.2.tgz", + "integrity": "sha512-HmgVS3j+FLrEDBTDYysPdPVF9/hioDMJ/otOiQDKqk77YfZeeLOj0qi34yObumcud1gBpk+wpBTEg4kMicD++A==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^2.0.1" + } + }, + "node_modules/resq/node_modules/fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rgb2hex": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.2.5.tgz", + "integrity": "sha512-22MOP1Rh7sAo1BZpDG6R5RFYzR2lYEgwq7HEmyW2qcsOqR2lQKmn+O//xV3YG/0rrhMC6KVX2hU+ZXuaw9a5bw==", + "dev": true + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.4.tgz", + "integrity": "sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/safe-json-parse": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz", + "integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=", + "dev": true + }, + "node_modules/safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "dev": true, + "dependencies": { + "regexp-tree": "~0.1.1" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/semlog": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/semlog/-/semlog-0.6.10.tgz", + "integrity": "sha1-DyJa6o6zwvJM6TWNhnjQ9Bp/4Fs=", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "prettyjson": "^1.1.3" + } + }, + "node_modules/semlog/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/semlog/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/semlog/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/semlog/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/semlog/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/semlog/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-error": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz", + "integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", + "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", + "dev": true + }, + "node_modules/specificity": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz", + "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==", + "dev": true, + "bin": { + "specificity": "bin/specificity" + } + }, + "node_modules/split2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz", + "integrity": "sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==", + "dev": true, + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stream-buffers": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.2.tgz", + "integrity": "sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/string-template": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", + "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=", + "dev": true + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-search": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", + "integrity": "sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=", + "dev": true + }, + "node_modules/stylelint": { + "version": "14.8.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.8.1.tgz", + "integrity": "sha512-0YxTop3wTeEVmQWhS7jjLFaBkvfPmffRiJ6eFIDlK++f3OklaobTYFJu32E5u/cIrFLbcW52pLqrYpihA/y0/w==", + "dev": true, + "dependencies": { + "balanced-match": "^2.0.0", + "colord": "^2.9.2", + "cosmiconfig": "^7.0.1", + "css-functions-list": "^3.0.1", + "debug": "^4.3.4", + "execall": "^2.0.0", + "fast-glob": "^3.2.11", + "fastest-levenshtein": "^1.0.12", + "file-entry-cache": "^6.0.1", + "get-stdin": "^8.0.0", + "global-modules": "^2.0.0", + "globby": "^11.1.0", + "globjoin": "^0.1.4", + "html-tags": "^3.2.0", + "ignore": "^5.2.0", + "import-lazy": "^4.0.0", + "imurmurhash": "^0.1.4", + "is-plain-object": "^5.0.0", + "known-css-properties": "^0.24.0", + "mathml-tag-names": "^2.1.3", + "meow": "^9.0.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "normalize-selector": "^0.2.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.12", + "postcss-media-query-parser": "^0.2.3", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-safe-parser": "^6.0.0", + "postcss-selector-parser": "^6.0.10", + "postcss-value-parser": "^4.2.0", + "resolve-from": "^5.0.0", + "specificity": "^0.4.1", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "style-search": "^0.1.0", + "supports-hyperlinks": "^2.2.0", + "svg-tags": "^1.0.0", + "table": "^6.8.0", + "v8-compile-cache": "^2.3.0", + "write-file-atomic": "^4.0.1" + }, + "bin": { + "stylelint": "bin/stylelint.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + } + }, + "node_modules/stylelint-config-recommended": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-7.0.0.tgz", + "integrity": "sha512-yGn84Bf/q41J4luis1AZ95gj0EQwRX8lWmGmBwkwBNSkpGSpl66XcPTulxGa/Z91aPoNGuIGBmFkcM1MejMo9Q==", + "dev": true, + "peerDependencies": { + "stylelint": "^14.4.0" + } + }, + "node_modules/stylelint-config-wikimedia": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/stylelint-config-wikimedia/-/stylelint-config-wikimedia-0.13.0.tgz", + "integrity": "sha512-1R1g/uc53z2z39ejZMALwC6fTfSZhkzDjj1v8ODCWtLCiuqWuSf3HR1ZTXT5X5AtSbZq1W9+0p5HJp6rPVXkRg==", + "dev": true, + "dependencies": { + "browserslist-config-wikimedia": "0.4.0", + "postcss-less": "6.0.0", + "stylelint": "14.8.1", + "stylelint-config-recommended": "7.0.0", + "stylelint-no-unsupported-browser-features": "5.0.3" + }, + "peerDependencies": { + "postcss-less": "^6.0.0" + } + }, + "node_modules/stylelint-no-unsupported-browser-features": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/stylelint-no-unsupported-browser-features/-/stylelint-no-unsupported-browser-features-5.0.3.tgz", + "integrity": "sha512-FqfbOTk5UEkHsAKOkPH6SvajsfO9YuoWvKxd34tCRBZug9ZNeaPn141nyWkd+ncc8S1gVmO2+O6qVAMj9bvWww==", + "dev": true, + "dependencies": { + "doiuse": "^4.4.1", + "lodash": "^4.17.15", + "postcss": "^8.3.6" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "stylelint": ">=13.0.0" + } + }, + "node_modules/stylelint/node_modules/balanced-match": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", + "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", + "dev": true + }, + "node_modules/stylelint/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/stylelint/node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/suffix": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/suffix/-/suffix-0.1.1.tgz", + "integrity": "sha1-zFgjFkag7xEC95R47zqSSP2chC8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", + "dev": true + }, + "node_modules/svgo": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", + "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", + "dev": true, + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "picocolors": "^1.0.0", + "stable": "^0.1.8" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/table": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", + "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz", + "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "dependencies": { + "readable-stream": "3" + } + }, + "node_modules/tiny-lr": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", + "integrity": "sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==", + "dev": true, + "dependencies": { + "body": "^5.1.0", + "debug": "^3.1.0", + "faye-websocket": "~0.10.0", + "livereload-js": "^2.3.0", + "object-assign": "^4.1.0", + "qs": "^6.4.0" + } + }, + "node_modules/tiny-lr/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "dev": true + }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ua-parser-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.2.tgz", + "integrity": "sha512-00y/AXhx0/SsnI51fTc0rLRmafiGOM4/O+ny10Ps7f+j/b8p/ZY11ytMgznXkOVo4GQ+KwQG5UQLkLGirsACRg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + } + ], + "engines": { + "node": "*" + } + }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "node_modules/unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/underscore.string": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz", + "integrity": "sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==", + "dev": true, + "dependencies": { + "sprintf-js": "^1.1.1", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/underscore.string/node_modules/sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "dev": true + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/upath": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz", + "integrity": "sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==", + "dev": true, + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/v8flags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", + "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", + "dev": true, + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validator": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", + "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/vue-eslint-parser": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz", + "integrity": "sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g==", + "dev": true, + "dependencies": { + "debug": "^4.3.2", + "eslint-scope": "^7.0.0", + "eslint-visitor-keys": "^3.1.0", + "espree": "^9.0.0", + "esquery": "^1.4.0", + "lodash": "^4.17.21", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/vue-eslint-parser/node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/vue-eslint-parser/node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/vue-eslint-parser/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/wdio-mediawiki": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wdio-mediawiki/-/wdio-mediawiki-2.1.0.tgz", + "integrity": "sha512-gbC05sQR8lWgYUfl4Zeghl2Axa7b0IFv/FAWMmqDPEK/SRMEUXc5I9J6/Iowa8Bo5sRc7pGuQi4p34fLbivl8g==", + "dev": true, + "dependencies": { + "mwbot": "2.0.0" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/webdriver": { + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-7.16.13.tgz", + "integrity": "sha512-Vfr952W1uIgDeWHPGzqH43dYLeRSZshh3TzA9ICUkvnC+Q7YziQdv/8xI8tuuyvb7lSr3VsuB2cGzyCRoC/NWw==", + "dev": true, + "dependencies": { + "@types/node": "^17.0.4", + "@wdio/config": "7.16.13", + "@wdio/logger": "7.16.0", + "@wdio/protocols": "7.16.7", + "@wdio/types": "7.16.13", + "@wdio/utils": "7.16.13", + "got": "^11.0.2", + "ky": "^0.28.5", + "lodash.merge": "^4.6.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/webdriverio": { + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-7.16.13.tgz", + "integrity": "sha512-jl1VRZYL1+cPeG6klskKX7mCEBWNQWDFaNtaIl5pwWgtKWPau6fCzKntSARzfNV8+hKJKwJ2mZn5Nsxfw28Oeg==", + "dev": true, + "dependencies": { + "@types/aria-query": "^5.0.0", + "@types/node": "^17.0.4", + "@wdio/config": "7.16.13", + "@wdio/logger": "7.16.0", + "@wdio/protocols": "7.16.7", + "@wdio/repl": "7.16.13", + "@wdio/types": "7.16.13", + "@wdio/utils": "7.16.13", + "archiver": "^5.0.0", + "aria-query": "^5.0.0", + "css-shorthand-properties": "^1.1.1", + "css-value": "^0.0.1", + "devtools": "7.16.13", + "devtools-protocol": "^0.0.953906", + "fs-extra": "^10.0.0", + "get-port": "^5.1.1", + "grapheme-splitter": "^1.0.2", + "lodash.clonedeep": "^4.5.0", + "lodash.isobject": "^3.0.2", + "lodash.isplainobject": "^4.0.6", + "lodash.zip": "^4.2.0", + "minimatch": "^3.0.4", + "puppeteer-core": "^13.0.0", + "query-selector-shadow-dom": "^1.0.0", + "resq": "^1.9.1", + "rgb2hex": "0.2.5", + "serialize-error": "^8.0.0", + "webdriver": "7.16.13" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "dev": true + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workerpool": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz", + "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16" + } + }, + "node_modules/ws": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "dev": true, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/yaml-eslint-parser": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-0.5.0.tgz", + "integrity": "sha512-nJeyLA3YHAzhBTZbRAbu3W6xrSCucyxExmA+ZDtEdUFpGllxAZpto2Zxo2IG0r0eiuEiBM4e+wiAdxTziTq94g==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.0.0", + "lodash": "^4.17.21", + "yaml": "^1.10.2" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/yaml-eslint-parser/node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/yargs": { + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz", + "integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yarn-install": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yarn-install/-/yarn-install-1.0.0.tgz", + "integrity": "sha1-V/RQULgu/VcYKzlzxUqgXLXSUjA=", + "dev": true, + "dependencies": { + "cac": "^3.0.3", + "chalk": "^1.1.3", + "cross-spawn": "^4.0.2" + }, + "bin": { + "yarn-install": "bin/yarn-install.js", + "yarn-remove": "bin/yarn-remove.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yarn-install/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yarn-install/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yarn-install/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yarn-install/node_modules/cross-spawn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", + "dev": true, + "dependencies": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "node_modules/yarn-install/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/yarn-install/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/yarn-install/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yarn-install/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/yarn-install/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/yarn-install/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zip-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz", + "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==", + "dev": true, + "dependencies": { + "archiver-utils": "^2.1.0", + "compress-commons": "^4.1.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { - "@babel/template": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1" + "@babel/highlight": "^7.10.4" } }, + "@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true + }, "@babel/highlight": { - "version": "7.10.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.3.tgz", - "integrity": "sha512-Ih9B/u7AtgEnySE2L2F0Xm0GaM729XqqLfHkalTsbjXGyqmf/6M0Cu0WpvqueUlW+xk88BHw9Nkpj49naU+vWw==", + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.3", + "@babel/helper-validator-identifier": "^7.16.7", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -236,6 +9016,12 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -253,162 +9039,150 @@ } } }, - "@babel/parser": { - "version": "7.10.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.3.tgz", - "integrity": "sha512-oJtNJCMFdIMwXGmx+KxuaD7i3b8uS7TTFYW/FNG2BT8m+fmGHoiPYoH0Pe3gya07WuFmM5FCDIr1x0irkD/hyA==", - "dev": true - }, - "@babel/template": { - "version": "7.10.3", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.3.tgz", - "integrity": "sha512-5BjI4gdtD+9fHZUsaxPHPNpwa+xRkDO7c7JbhYn2afvrkDu5SfAAbi9AIMXw2xEhO/BR35TqiW97IqNvCo/GqA==", + "@es-joy/jsdoccomment": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.20.1.tgz", + "integrity": "sha512-oeJK41dcdqkvdZy/HctKklJNkt/jh+av3PZARrZEl+fs/8HaHeeYoAvEwOV0u5I6bArTF17JEsTZMY359e/nfQ==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.3", - "@babel/parser": "^7.10.3", - "@babel/types": "^7.10.3" + "comment-parser": "1.3.0", + "esquery": "^1.4.0", + "jsdoc-type-pratt-parser": "~2.2.3" } }, - "@babel/traverse": { - "version": "7.10.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.3.tgz", - "integrity": "sha512-qO6623eBFhuPm0TmmrUFMT1FulCmsSeJuVGhiLodk2raUDFhhTECLd9E9jC4LBIWziqt4wgF6KuXE4d+Jz9yug==", + "@eslint/eslintrc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.0.tgz", + "integrity": "sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.3", - "@babel/generator": "^7.10.3", - "@babel/helper-function-name": "^7.10.3", - "@babel/helper-split-export-declaration": "^7.10.1", - "@babel/parser": "^7.10.3", - "@babel/types": "^7.10.3", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.3.1", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" }, "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } } } }, - "@babel/types": { - "version": "7.10.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.3.tgz", - "integrity": "sha512-nZxaJhBXBQ8HVoIcGsf9qWep3Oh3jCENK54V4mRF7qaJabVsAYdbTtmSD8WmAp1R6ytPiu5apMwSXyxB1WlaBA==", + "@humanwhocodes/config-array": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", + "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.3", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" } }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "dependencies": { - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" } }, + "@mdn/browser-compat-data": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-4.1.9.tgz", + "integrity": "sha512-MGIACLLfhkuJ4rV5JPIOFNLJN+JWgYmV83NMBfx8EvRma+kcEAFivVgHHuEPJtdCba5zRpMx/cIGrXfVyGN56g==", + "dev": true + }, "@nodelib/fs.scandir": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", - "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "requires": { - "@nodelib/fs.stat": "2.0.3", + "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "@nodelib/fs.stat": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", - "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true }, "@nodelib/fs.walk": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", - "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "requires": { - "@nodelib/fs.scandir": "2.1.3", + "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "@sindresorhus/is": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-2.1.1.tgz", - "integrity": "sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.4.0.tgz", + "integrity": "sha512-QppPM/8l3Mawvh4rn9CNEYIU9bxpXUCRMaX9yUpvBk1nMKusLKpfXGDEKExKaPhLzcn3lzil7pR6rnJ11HgeRQ==", "dev": true }, - "@stylelint/postcss-css-in-js": { - "version": "0.37.1", - "resolved": "https://registry.npmjs.org/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.37.1.tgz", - "integrity": "sha512-UMf2Rni3JGKi3ZwYRGMYJ5ipOA5ENJSKMtYA/pE1ZLURwdh7B5+z2r73RmWvub+N0UuH1Lo+TGfCgYwPvqpXNw==", - "dev": true, - "requires": { - "@babel/core": ">=7.9.0" - } - }, - "@stylelint/postcss-markdown": { - "version": "0.36.1", - "resolved": "https://registry.npmjs.org/@stylelint/postcss-markdown/-/postcss-markdown-0.36.1.tgz", - "integrity": "sha512-iDxMBWk9nB2BPi1VFQ+Dc5+XpvODBHw2n3tYpaBZuEAFQlbtF9If0Qh5LTTwSi/XwdbJ2jt+0dis3i8omyggpw==", - "dev": true, - "requires": { - "remark": "^12.0.0", - "unist-util-find-all-after": "^3.0.1" - } - }, "@szmarczak/http-timer": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz", - "integrity": "sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", "dev": true, "requires": { "defer-to-connect": "^2.0.0" } }, + "@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "dev": true + }, + "@types/aria-query": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.0.tgz", + "integrity": "sha512-P+dkdFu0n08PDIvw+9nT9ByQnd+Udc8DaWPb9HKfaPwCvWvQpC5XaMRx2xLWECm9x1VKNps6vEAlirjA6+uNrQ==", + "dev": true + }, "@types/cacheable-request": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.1.tgz", - "integrity": "sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", + "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", "dev": true, "requires": { "@types/http-cache-semantics": "*", @@ -417,22 +9191,53 @@ "@types/responselike": "*" } }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "@types/diff": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/diff/-/diff-5.0.2.tgz", + "integrity": "sha512-uw8eYMIReOwstQ0QKF0sICefSy8cNO/v7gOTiIy9SbwuHyEecJUm7qlgueOO5S1udZ5I/irVydHVwMchgzbKTg==", + "dev": true + }, + "@types/easy-table": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/easy-table/-/easy-table-0.0.33.tgz", + "integrity": "sha512-/vvqcJPmZUfQwCgemL0/34G7bIQnCuvgls379ygRlcC1FqNqk3n+VZ15dAO51yl6JNDoWd8vsk+kT8zfZ1VZSw==", + "dev": true + }, + "@types/ejs": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/ejs/-/ejs-3.1.0.tgz", + "integrity": "sha512-DCg+Ka+uDQ31lJ/UtEXVlaeV3d6t81gifaVWKJy4MYVVgvJttyX/viREy+If7fz+tK/gVxTGMtyrFPnm4gjrVA==", "dev": true }, + "@types/fs-extra": { + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/http-cache-semantics": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz", - "integrity": "sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", "dev": true }, + "@types/inquirer": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-8.2.0.tgz", + "integrity": "sha512-BNoMetRf3gmkpAlV5we+kxyZTle7YibdOntIZbU5pyIfMdcwy784KfeZDAcuyMznkh5OLa17RVXZOGA5LTlkgQ==", + "dev": true, + "requires": { + "@types/through": "*", + "rxjs": "^7.2.0" + } + }, "@types/istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", "dev": true }, "@types/istanbul-lib-report": { @@ -445,40 +9250,96 @@ } }, "@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "*", "@types/istanbul-lib-report": "*" } }, + "@types/json-stringify-safe": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/json-stringify-safe/-/json-stringify-safe-5.0.0.tgz", + "integrity": "sha512-UUA1sH0RSRROdInuDOA1yoRzbi5xVFD1RHCoOvNRPTNwR8zBkJ/84PZ6NhKVDtKp0FTeIccJCdQz1X2aJPr4uw==", + "dev": true + }, "@types/keyv": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.1.tgz", - "integrity": "sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.3.tgz", + "integrity": "sha512-FXCJgyyN3ivVgRoml4h94G/p3kY+u/B86La+QptcqJaWtBWtmc6TtkNfS40n9bIvyLteHh7zXOtgbobORKPbDg==", "dev": true, "requires": { "@types/node": "*" } }, + "@types/lodash": { + "version": "4.14.178", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz", + "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==", + "dev": true + }, + "@types/lodash.flattendeep": { + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@types/lodash.flattendeep/-/lodash.flattendeep-4.4.6.tgz", + "integrity": "sha512-uLm2MaRVlqJSGsMK0RZpP5T3KqReq+9WbYDHCUhBhp98v56hMG/Yht52bsoTSui9xz2mUvQ9NfG3LrNGDL92Ng==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, + "@types/lodash.pickby": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/@types/lodash.pickby/-/lodash.pickby-4.6.6.tgz", + "integrity": "sha512-NFa13XxlMd9eFi0UFZFWIztpMpXhozbijrx3Yb1viYZphT7jyopIFVoIRF4eYMjruWNEG1rnyrRmg/8ej9T8Iw==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, + "@types/lodash.union": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/@types/lodash.union/-/lodash.union-4.6.6.tgz", + "integrity": "sha512-Wu0ZEVNcyCz8eAn6TlUbYWZoGbH9E+iOHxAZbwUoCEXdUiy6qpcz5o44mMXViM4vlPLLCPlkAubEP1gokoSZaw==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, + "@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, "@types/minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "dev": true + }, + "@types/mocha": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.0.tgz", + "integrity": "sha512-QCWHkbMv4Y5U9oW10Uxbr45qMMSzl4OzijsozynUAgx3kEHUdXB00udx2dWDQ7f2TU2a2uuiFaRZjCe3unPpeg==", "dev": true }, "@types/node": { - "version": "14.0.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.14.tgz", - "integrity": "sha512-syUgf67ZQpaJj01/tRTknkMNoBBLWJOBODF0Zm4NrXmiSuxjymFrxnTu1QVYRubhVkRcZLYZG8STTwJRdVm/WQ==", + "version": "17.0.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.19.tgz", + "integrity": "sha512-PfeQhvcMR4cPFVuYfBN4ifG7p9c+Dlh3yUZR6k+5yQK7wX3gDgVxBly4/WkBRs9x4dmcy1TVl08SY67wwtEvmA==", "dev": true }, "@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, + "@types/object-inspect": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@types/object-inspect/-/object-inspect-1.8.1.tgz", + "integrity": "sha512-0JTdf3CGV0oWzE6Wa40Ayv2e2GhpP3pEJMcrlM74vBSJPuuNkVwfDnl0SZxyFCXETcB4oKA/MpTVfuYSMOelBg==", "dev": true }, "@types/parse-json": { @@ -487,11 +9348,14 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, - "@types/q": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", - "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", - "dev": true + "@types/recursive-readdir": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@types/recursive-readdir/-/recursive-readdir-2.2.0.tgz", + "integrity": "sha512-HGk753KRu2N4mWduovY4BLjYq4jTOL29gV2OfGdGxHcPSWGFkC5RRIdk+VTs5XmYd7MVAD+JwKrcb5+5Y7FOCg==", + "dev": true, + "requires": { + "@types/node": "*" + } }, "@types/responselike": { "version": "1.0.0", @@ -503,95 +9367,172 @@ } }, "@types/stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, - "@types/unist": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", - "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==", + "@types/stream-buffers": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/stream-buffers/-/stream-buffers-3.0.4.tgz", + "integrity": "sha512-qU/K1tb2yUdhXkLIATzsIPwbtX6BpZk0l3dPW6xqWyhfzzM1ECaQ/8faEnu3CNraLiQ9LHyQQPBGp7N9Fbs25w==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@types/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-dPWnWsf+kzIG140B8z2w3fr5D03TLWbOAFQl45xUpI3vcizeXriNR5VYkWZ+WTMsUHqZ9Xlt3hrxGNANFyNQfw==", + "dev": true + }, + "@types/through": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/through/-/through-0.0.30.tgz", + "integrity": "sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-dDZH/tXzwjutnuk4UacGgFRwV+JSLaXL1ikvidfJprkb7L9Nx1njcRHHmi3Dsvt7pgqqTEeucQuOrWHPFgzVHA==", + "dev": true + }, + "@types/ua-parser-js": { + "version": "0.7.36", + "resolved": "https://registry.npmjs.org/@types/ua-parser-js/-/ua-parser-js-0.7.36.tgz", + "integrity": "sha512-N1rW+njavs70y2cApeIw1vLMYXRwfBy+7trgavGuuTfOd7j1Yh7QTRc/yqsPl6ncokt72ZXuxEU0PiCp9bSwNQ==", + "dev": true + }, + "@types/validator": { + "version": "13.7.1", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.1.tgz", + "integrity": "sha512-I6OUIZ5cYRk5lp14xSOAiXjWrfVoMZVjDuevBYgQDYzZIjsf2CAISpEcXOkFAtpAHbmWIDLcZObejqny/9xq5Q==", + "dev": true + }, + "@types/which": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/which/-/which-1.3.2.tgz", + "integrity": "sha512-8oDqyLC7eD4HM307boe2QWKyuzdzWBj56xI/imSl2cpL+U3tCMaTAkMJ4ee5JBZ/FsOJlvRGeIShiZDAl1qERA==", "dev": true }, "@types/yargs": { - "version": "15.0.5", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", - "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", "dev": true, "requires": { "@types/yargs-parser": "*" } }, "@types/yargs-parser": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", - "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", "dev": true }, "@types/yauzl": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz", - "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", + "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", "dev": true, "optional": true, "requires": { "@types/node": "*" } }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, "@wdio/cli": { - "version": "6.1.16", - "resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-6.1.16.tgz", - "integrity": "sha512-q7JaEiLU2mdOibeKAQFqdWTS2evdkwgWSft1rmWDN7idiV39uncTTUcwlXBKE2a9yDk/8qn6EEXdBLthOCfyOA==", - "dev": true, - "requires": { - "@wdio/config": "6.1.14", - "@wdio/logger": "6.0.16", - "@wdio/utils": "6.1.8", + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-7.16.13.tgz", + "integrity": "sha512-y0C/eLLyLCVWrsJVimozUQBQWD/goIUxmtB91rjMAqTjeLn5b0VoPhr+EKXGCHXz3ylvXGGJ3RaI0l1vz9Cf8w==", + "dev": true, + "requires": { + "@types/ejs": "^3.0.5", + "@types/fs-extra": "^9.0.4", + "@types/inquirer": "^8.1.2", + "@types/lodash.flattendeep": "^4.4.6", + "@types/lodash.pickby": "^4.6.6", + "@types/lodash.union": "^4.6.6", + "@types/node": "^17.0.4", + "@types/recursive-readdir": "^2.2.0", + "@wdio/config": "7.16.13", + "@wdio/logger": "7.16.0", + "@wdio/types": "7.16.13", + "@wdio/utils": "7.16.13", "async-exit-hook": "^2.0.1", "chalk": "^4.0.0", "chokidar": "^3.0.0", "cli-spinners": "^2.1.0", "ejs": "^3.0.1", - "fs-extra": "^9.0.0", - "inquirer": "^7.0.0", + "fs-extra": "^10.0.0", + "inquirer": "8.1.5", "lodash.flattendeep": "^4.4.0", "lodash.pickby": "^4.6.0", "lodash.union": "^4.6.0", - "log-update": "^4.0.0", - "webdriverio": "6.1.16", - "yargs": "^15.0.1", + "mkdirp": "^1.0.4", + "recursive-readdir": "^2.2.2", + "webdriverio": "7.16.13", + "yargs": "^17.0.0", "yarn-install": "^1.0.0" } }, "@wdio/config": { - "version": "6.1.14", - "resolved": "https://registry.npmjs.org/@wdio/config/-/config-6.1.14.tgz", - "integrity": "sha512-MXHMHwtkAblfnIxONs9aW//T9Fq5XIw3oH+tztcBRvNTTAIXmwHd+4sOjAwjpCdBSGs0C4kM/aTpGfwDZVURvQ==", + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-7.16.13.tgz", + "integrity": "sha512-LSGoa83tWQIBppB+LeHjY40B9tuuvmDV1qdBLVXR1ROcOUWWz/oQP3NFLtLm3266LXoJUbwebzGcRIK1EcNk3Q==", "dev": true, "requires": { - "@wdio/logger": "6.0.16", + "@wdio/logger": "7.16.0", + "@wdio/types": "7.16.13", "deepmerge": "^4.0.0", "glob": "^7.1.2" } }, + "@wdio/junit-reporter": { + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/@wdio/junit-reporter/-/junit-reporter-7.16.13.tgz", + "integrity": "sha512-VKhly72NZY2/SNnfbYXO/HHov9oj+pk0aaq5TNzIJJoqtH4uqDz+L2p7wu9nKnRnywmwvaTm7pbYZGlOuty26A==", + "dev": true, + "requires": { + "@types/json-stringify-safe": "^5.0.0", + "@types/validator": "^13.1.3", + "@wdio/reporter": "7.16.13", + "@wdio/types": "7.16.13", + "json-stringify-safe": "^5.0.1", + "junit-report-builder": "^3.0.0", + "validator": "^13.0.0" + } + }, "@wdio/local-runner": { - "version": "6.1.16", - "resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-6.1.16.tgz", - "integrity": "sha512-3+pT2fcMXFAnELA6jYjVm6Nt8Il7tGL66A90UbRiT0sL2faTcD3uGAPbmzxMclsmWLh7C04ucCnFwQoTMW1emg==", + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-7.16.13.tgz", + "integrity": "sha512-Ri8R6RHD5VjI4m2CramKO9w+4jD7VwEoQFWqFzUI1g31UAuN1zy67R3UiYv0ohiBTW4MZt90CMLgumQNk7C5kA==", "dev": true, "requires": { - "@wdio/logger": "6.0.16", - "@wdio/repl": "6.1.8", - "@wdio/runner": "6.1.16", + "@types/stream-buffers": "^3.0.3", + "@wdio/logger": "7.16.0", + "@wdio/repl": "7.16.13", + "@wdio/runner": "7.16.13", + "@wdio/types": "7.16.13", "async-exit-hook": "^2.0.1", + "split2": "^4.0.0", "stream-buffers": "^3.0.2" } }, "@wdio/logger": { - "version": "6.0.16", - "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-6.0.16.tgz", - "integrity": "sha512-VbH5UnQIG/3sSMV+Y38+rOdwyK9mVA9vuL7iOngoTafHwUjL1MObfN/Cex84L4mGxIgfxCu6GV48iUmSuQ7sqA==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-7.16.0.tgz", + "integrity": "sha512-/6lOGb2Iow5eSsy7RJOl1kCwsP4eMlG+/QKro5zUJsuyNJSQXf2ejhpkzyKWLgQbHu83WX6cM1014AZuLkzoQg==", "dev": true, "requires": { "chalk": "^4.0.0", @@ -601,85 +9542,101 @@ } }, "@wdio/mocha-framework": { - "version": "6.1.14", - "resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-6.1.14.tgz", - "integrity": "sha512-2AmUH/v3kZoIDAMdW73AhI4tDJU3ie/2dO/DtpXJ3XFnuJ1CtklZGyCTtYHGMZ8DBj18/8Lrs/O0CjS5bAu2tw==", + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-7.16.13.tgz", + "integrity": "sha512-yaLxEF5evXACGqxkch/IoJz8JGoQmcV+X635JBiMF6tl0+HSTYrL1ZPk1cED+9OI4jIPtmlhbgzne9IhoKCbpg==", "dev": true, "requires": { - "@wdio/logger": "6.0.16", - "@wdio/utils": "6.1.8", - "expect-webdriverio": "^1.1.5", - "mocha": "^7.0.1" + "@types/mocha": "^9.0.0", + "@wdio/logger": "7.16.0", + "@wdio/types": "7.16.13", + "@wdio/utils": "7.16.13", + "expect-webdriverio": "^3.0.0", + "mocha": "^9.0.0" } }, "@wdio/protocols": { - "version": "6.1.14", - "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-6.1.14.tgz", - "integrity": "sha512-UtRLQ55i23cLQRGtFiEJty1F6AbAfiSpfIxDAiXKHbw6Rp1StwxlqHFrhNe5F48Zu4hnie46t9N/tr/cZOe0kA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-7.16.7.tgz", + "integrity": "sha512-Wv40pNQcLiPzQ3o98Mv4A8T1EBQ6k4khglz/e2r16CTm+F3DDYh8eLMAsU5cgnmuwwDKX1EyOiFwieykBn5MCg==", "dev": true }, "@wdio/repl": { - "version": "6.1.8", - "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-6.1.8.tgz", - "integrity": "sha512-C647KvDIcOHYN24eFbiM2xE+etPEACvRYkEp7BPLyopEABDr0I3Qdb5MLhopC5eMAVHp70/WT27H1CE2v9iILQ==", + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-7.16.13.tgz", + "integrity": "sha512-XWh3dzp6U8LLL4cNGWFra+quVyXZ25Ym38zpsBVtV0/z5NCHJmjRS4ytyvvkzbQ8SyqQ7Y3G8MjfGNi2sBNkIQ==", "dev": true, "requires": { - "@wdio/utils": "6.1.8" + "@wdio/utils": "7.16.13" } }, "@wdio/reporter": { - "version": "6.1.14", - "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-6.1.14.tgz", - "integrity": "sha512-Pt6P0JU0COHTpggsOoJKUJyAyQsi7xlHebBNU/DWdHHpmzYd4e9vDutjyTqXu/1zn+t+Zq+uL1IC0E4Xjv6f7w==", + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-7.16.13.tgz", + "integrity": "sha512-S7OH96yfSCJwmirsvT8khfWUfoMTiw0O1+UyiOYS/g0l+IideVK83kpyXYWfsALPahL2te0g57lPazriSfNAyA==", "dev": true, "requires": { - "fs-extra": "^9.0.0" + "@types/diff": "^5.0.0", + "@types/node": "^17.0.4", + "@types/object-inspect": "^1.8.0", + "@types/supports-color": "^8.1.0", + "@types/tmp": "^0.2.0", + "@wdio/types": "7.16.13", + "diff": "^5.0.0", + "fs-extra": "^10.0.0", + "object-inspect": "^1.10.3", + "supports-color": "8.1.1" } }, "@wdio/runner": { - "version": "6.1.16", - "resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-6.1.16.tgz", - "integrity": "sha512-pGRT51BGnxp4zFD1pSp6qZD/4dnbSnDyV4g/MbbFiA4PFKF41mFhaxRwIGMHcp4EYlv9gaT31UA52JaFIYyuNA==", + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-7.16.13.tgz", + "integrity": "sha512-/PJUK+8orHsUd5v8edWv5XS3pKx/si7DoYkU8PsgQX9FnU2y3oRfHrQwzI8s3TOnGag79f+yrGzzGCZFmmW0cw==", "dev": true, "requires": { - "@wdio/config": "6.1.14", - "@wdio/logger": "6.0.16", - "@wdio/utils": "6.1.8", + "@wdio/config": "7.16.13", + "@wdio/logger": "7.16.0", + "@wdio/types": "7.16.13", + "@wdio/utils": "7.16.13", "deepmerge": "^4.0.0", "gaze": "^1.1.2", - "webdriver": "6.1.14", - "webdriverio": "6.1.16" + "webdriver": "7.16.13", + "webdriverio": "7.16.13" } }, "@wdio/spec-reporter": { - "version": "6.1.14", - "resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-6.1.14.tgz", - "integrity": "sha512-QaSBgnzllzLp9LR7/5DTkmrI8BqcznUma8ZxwUNmhvskv/oKzrmNyeCsGoiExFmCk81A9FgZiZPXey7CuaTkdw==", + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-7.16.13.tgz", + "integrity": "sha512-4gnflBJU+QDcmWgRy3tSRD47cqZmdjPLEJhsfhv/aBNtWPWMJtQru7nDFcLkxKLFPiN0D1F7gUMWbUMaDVlojg==", "dev": true, "requires": { - "@wdio/reporter": "6.1.14", + "@types/easy-table": "^0.0.33", + "@wdio/reporter": "7.16.13", + "@wdio/types": "7.16.13", "chalk": "^4.0.0", "easy-table": "^1.1.1", "pretty-ms": "^7.0.0" } }, - "@wdio/sync": { - "version": "6.1.14", - "resolved": "https://registry.npmjs.org/@wdio/sync/-/sync-6.1.14.tgz", - "integrity": "sha512-94K0kQdrOU0aMlJ2Xsd4tWr4tPpmCFp612Ml5+ecQh4C4XD07ocfsvGs+mwI7cfF1sO6g/Hoc+XTY2D+/8En3w==", + "@wdio/types": { + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.16.13.tgz", + "integrity": "sha512-HIeXKCL+mUjyJxvnHSoaIo3NRgZLbeekyRIwo6USfd9qGlQ8dQ6fyCR3ZU9VqNz9j4+JIn+LRQ7imbz5SdnGbw==", "dev": true, "requires": { - "@wdio/logger": "6.0.16", - "fibers": "^4.0.1" + "@types/node": "^17.0.4", + "got": "^11.8.1" } }, "@wdio/utils": { - "version": "6.1.8", - "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-6.1.8.tgz", - "integrity": "sha512-qzvD8qCPpIpDrZ0HNOx1hTlfKY26p8WByUXgr52ll6DXxtAYXZLIJ8GAYFJUi87NVfwtv6+O7owQGSM/jtr8AQ==", + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-7.16.13.tgz", + "integrity": "sha512-O6D89Ghtm5XtTv4DPKvCBKZOZYNONIcBM5/hmdr3V9mzVrTFq8Q3uE8pmmq303Oh91KcoN8Em5zoAG7Zpc5tRg==", "dev": true, "requires": { - "@wdio/logger": "6.0.16" + "@wdio/logger": "7.16.0", + "@wdio/types": "7.16.13", + "p-iteration": "^1.1.8" } }, "abbrev": { @@ -689,78 +9646,80 @@ "dev": true }, "acorn": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", - "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, "acorn-jsx": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", - "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true }, "agent-base": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", - "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", - "dev": true + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } }, "ajv": { - "version": "6.12.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", - "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" - }, - "dependencies": { - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - } } }, "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true }, "ansi-escapes": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", - "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, "requires": { - "type-fest": "^0.11.0" + "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + } } }, "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -768,28 +9727,25 @@ } }, "archiver": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-4.0.1.tgz", - "integrity": "sha512-/YV1pU4Nhpf/rJArM23W6GTUjT0l++VbjykrCRua1TSXrn+yM8Qs7XvtwSiRse0iCe49EPNf7ktXnPsWuSb91Q==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.0.tgz", + "integrity": "sha512-iUw+oDwK0fgNpvveEsdQ0Ase6IIKztBJU2U0E9MzszMfmVVUyv1QJhS2ITW9ZCqx8dktAxVAjWWkKehuZE8OPg==", "dev": true, "requires": { "archiver-utils": "^2.1.0", - "async": "^2.6.3", + "async": "^3.2.0", "buffer-crc32": "^0.2.1", - "glob": "^7.1.6", "readable-stream": "^3.6.0", - "tar-stream": "^2.1.2", - "zip-stream": "^3.0.1" + "readdir-glob": "^1.0.0", + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" }, "dependencies": { "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", + "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", + "dev": true } } }, @@ -825,6 +9781,15 @@ "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } } } }, @@ -837,10 +9802,28 @@ "sprintf-js": "~1.0.2" } }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "aria-query": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.0.0.tgz", + "integrity": "sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==", + "dev": true + }, + "array-differ": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", + "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", + "dev": true + }, + "array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", + "dev": true + }, + "array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", "dev": true }, "array-union": { @@ -856,9 +9839,9 @@ "dev": true }, "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", "dev": true, "requires": { "safer-buffer": "~2.1.0" @@ -870,6 +9853,23 @@ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true }, + "ast-metadata-inferer": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.7.0.tgz", + "integrity": "sha512-OkMLzd8xelb3gmnp6ToFvvsHLtS6CbagTkFQvQ+ZYFe3/AIl9iKikNR9G7pY3GfOR/2Xc222hwBjzI7HLkE76Q==", + "dev": true, + "requires": { + "@mdn/browser-compat-data": "^3.3.14" + }, + "dependencies": { + "@mdn/browser-compat-data": { + "version": "3.3.14", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-3.3.14.tgz", + "integrity": "sha512-n2RC9d6XatVbWFdHLimzzUJxJ1KY8LdjqrW6YvGPiRmsHkhOUx74/Ct10x5Yo7bC/Jvqx7cDEW8IMPv/+vwEzA==", + "dev": true + } + } + }, "astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -877,10 +9877,13 @@ "dev": true }, "async": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", - "dev": true + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } }, "async-exit-hook": { "version": "2.0.1", @@ -894,27 +9897,6 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true - }, - "autoprefixer": { - "version": "9.8.4", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.4.tgz", - "integrity": "sha512-84aYfXlpUe45lvmS+HoAWKCkirI/sw4JK0/bTeeqgHYco3dcsOn0NqdejISjptsYwNji/21dnkDri9PsYKk89A==", - "dev": true, - "requires": { - "browserslist": "^4.12.0", - "caniuse-lite": "^1.0.30001087", - "colorette": "^1.2.0", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^7.0.32", - "postcss-value-parser": "^4.1.0" - } - }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -922,27 +9904,21 @@ "dev": true }, "aws4": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", - "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", - "dev": true - }, - "bail": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", - "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "dev": true }, "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true }, "bcrypt-pbkdf": { @@ -955,15 +9931,15 @@ } }, "binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, "bl": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz", - "integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "dev": true, "requires": { "buffer": "^5.5.0", @@ -1021,25 +9997,32 @@ "dev": true }, "browserslist": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.1.tgz", - "integrity": "sha512-WMjXwFtPskSW1pQUDJRxvRKRkeCr7usN0O/Za76N+F4oadaTdQHotSGcX9jT/Hs7mSKPkyMFNvqawB/1HzYDKQ==", + "version": "4.19.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.3.tgz", + "integrity": "sha512-XK3X4xtKJ+Txj8G5c30B4gsm71s69lqXlkYui4s6EkKxuv49qjYlY6oVd+IFJ73d4YymtM3+djvvt/R/iJwwDg==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001088", - "electron-to-chromium": "^1.3.481", - "escalade": "^3.0.1", - "node-releases": "^1.1.58" + "caniuse-lite": "^1.0.30001312", + "electron-to-chromium": "^1.4.71", + "escalade": "^3.1.1", + "node-releases": "^2.0.2", + "picocolors": "^1.0.0" } }, + "browserslist-config-wikimedia": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/browserslist-config-wikimedia/-/browserslist-config-wikimedia-0.4.0.tgz", + "integrity": "sha512-U/fmsaGlCKOqRIjKqXwQ44qFqiStngRTphj1Cf6IHV6J8OK8T0gu9dKc7Ljq4v7bwhnhN+YCCa4fA3nZlPNivQ==", + "dev": true + }, "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "dev": true, "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" } }, "buffer-crc32": { @@ -1048,6 +10031,12 @@ "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", "dev": true }, + "builtin-modules": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "dev": true + }, "bytes": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", @@ -1081,6 +10070,22 @@ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + }, + "camelcase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-3.0.0.tgz", + "integrity": "sha1-/AxsNgNj9zd+N5O5oWvM8QcMHKQ=", + "dev": true, + "requires": { + "camelcase": "^3.0.0", + "map-obj": "^1.0.0" + } + }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", @@ -1094,6 +10099,81 @@ "supports-color": "^2.0.0" } }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -1112,15 +10192,15 @@ } }, "cacheable-lookup": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.3.tgz", - "integrity": "sha512-W+JBqF9SWe18A72XFzN/V/CULFzPm7sBXzzR6ekkE+3tLG72wFZrBiBZhrZuDoYexop4PHJVdFAKb/Nj9+tm9w==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", "dev": true }, "cacheable-request": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.1.tgz", - "integrity": "sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", + "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", "dev": true, "requires": { "clone-response": "^1.0.2", @@ -1128,10 +10208,20 @@ "http-cache-semantics": "^4.0.0", "keyv": "^4.0.0", "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", + "normalize-url": "^6.0.1", "responselike": "^2.0.0" } }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1145,27 +10235,28 @@ "dev": true }, "camelcase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-3.0.0.tgz", - "integrity": "sha1-/AxsNgNj9zd+N5O5oWvM8QcMHKQ=", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dev": true, "requires": { - "camelcase": "^3.0.0", - "map-obj": "^1.0.0" + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" }, "dependencies": { - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true } } }, "caniuse-lite": { - "version": "1.0.30001088", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001088.tgz", - "integrity": "sha512-6eYUrlShRYveyqKG58HcyOfPgh3zb2xqs7NvT2VVtP3hEUeeWvc3lqhpeMTxYWBBeeaT9A4bKsrtjATm66BTHg==", + "version": "1.0.30001312", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz", + "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==", "dev": true }, "caseless": { @@ -1174,46 +10265,27 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, - "ccount": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.5.tgz", - "integrity": "sha512-MOli1W+nfbPLlKEhInaxhRdp7KVLFxLN5ykwzHgLsLI3H3gs5jjFAK4Eoj3OzzcxCtumDaI8onoVDeQyWaNTkw==", - "dev": true - }, "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, - "character-entities": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", - "dev": true - }, - "character-entities-html4": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz", - "integrity": "sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==", - "dev": true - }, - "character-entities-legacy": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", - "dev": true - }, - "character-reference-invalid": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", - "dev": true - }, "chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", @@ -1221,19 +10293,19 @@ "dev": true }, "chokidar": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz", - "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "requires": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.4.0" + "readdirp": "~3.6.0" } }, "chownr": { @@ -1243,17 +10315,38 @@ "dev": true }, "chrome-launcher": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.13.3.tgz", - "integrity": "sha512-ovrDuFXgXS96lzeDqFPQRsczkxla+6QMvzsF+1u0mKlD1KE8EuhjdLwiDfIFedb0FSLz18RK3y6IbKu8oqA0qw==", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.0.tgz", + "integrity": "sha512-ZQqX5kb9H0+jy1OqLnWampfocrtSZaGl7Ny3F9GRha85o4odbL8x55paUzh51UC7cEmZ5obp3H2Mm70uC2PpRA==", "dev": true, "requires": { "@types/node": "*", - "escape-string-regexp": "^1.0.5", + "escape-string-regexp": "^4.0.0", "is-wsl": "^2.2.0", - "lighthouse-logger": "^1.0.0", - "mkdirp": "^0.5.3", - "rimraf": "^3.0.2" + "lighthouse-logger": "^1.0.0" + } + }, + "ci-info": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", + "dev": true + }, + "clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha1-jffHquUf02h06PjQW5GAvBGj/tc=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + } } }, "cli-cursor": { @@ -1266,34 +10359,33 @@ } }, "cli-spinners": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.3.0.tgz", - "integrity": "sha512-Xs2Hf2nzrvJMFKimOR7YR0QwZ8fc0u98kdtwN1eNAZzNQgH3vK2pXzff6GJtKh7S5hoJ87ECiAiZFS2fb5Ii2w==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", + "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", "dev": true }, "cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", "dev": true }, "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" + "wrap-ansi": "^7.0.0" } }, "clone": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true, - "optional": true + "dev": true }, "clone-regexp": { "version": "2.2.0", @@ -1313,81 +10405,6 @@ "mimic-response": "^1.0.0" } }, - "coa": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", - "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", - "dev": true, - "requires": { - "@types/q": "^1.5.1", - "chalk": "^2.4.1", - "q": "^1.1.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "coffeescript": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.10.0.tgz", - "integrity": "sha1-56qDAZF+9iGzXYo580jc3R234z4=", - "dev": true - }, - "collapse-white-space": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", - "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", - "dev": true - }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1403,10 +10420,10 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "colorette": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.0.tgz", - "integrity": "sha512-soRSroY+OF/8OdA3PTQXwaDJeMc7TfknKKrxeSCencL2a4+Tx5zhxmmv7hdpCjhKBjehzp8+bwe/T68K0hpIjw==", + "colord": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.2.tgz", + "integrity": "sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==", "dev": true }, "colors": { @@ -1424,39 +10441,28 @@ "delayed-stream": "~1.0.0" } }, + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + }, "comment-parser": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-0.7.5.tgz", - "integrity": "sha512-iH9YA35ccw94nx5244GVkpyC9eVTsL71jZz6iz5w6RIf79JLF2AsXHXq9p6Oaohyl3sx5qSMnGsWUDFIAfWL4w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.0.tgz", + "integrity": "sha512-hRpmWIKgzd81vn0ydoWoyPoALEOnF4wt8yKD35Ib1D6XC2siLiYaiqfGkYrunuKdsXGwpBpHU3+9r+RVw2NZfA==", "dev": true }, "compress-commons": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-3.0.0.tgz", - "integrity": "sha512-FyDqr8TKX5/X0qo+aVfaZ+PVmNJHJeckFBlq8jZGSJOgnynhfifoyl24qaqdUdDIBe0EVTHByN6NAkqYvE/2Xg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", + "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==", "dev": true, "requires": { "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", + "crc32-stream": "^4.0.2", "normalize-path": "^3.0.0", - "readable-stream": "^2.3.7" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } + "readable-stream": "^3.6.0" } }, "concat-map": { @@ -1471,14 +10477,11 @@ "integrity": "sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=", "dev": true }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } + "core-js": { + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.21.1.tgz", + "integrity": "sha512-FRq5b/VMrWlrmCzwRrpDYNxyHP9BcAZC+xHJaqTgIE5091ZV1NTmyh0sGOg5XqpnHvR0svdy0sv1gWA1zmhxig==", + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -1487,93 +10490,183 @@ "dev": true }, "cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", + "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", "dev": true, "requires": { "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", + "import-fresh": "^3.2.1", "parse-json": "^5.0.0", "path-type": "^4.0.0", - "yaml": "^1.7.2" - }, - "dependencies": { - "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", - "lines-and-columns": "^1.1.6" - } - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - } + "yaml": "^1.10.0" } }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", + "crc-32": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.1.tgz", + "integrity": "sha512-Dn/xm/1vFFgs3nfrpEVScHoIslO9NZRITWGz/1E/St6u4xw99vfZzVkW0OSnzx2h9egej9xwMCEut6sqwokM/w==", "dev": true, "requires": { - "buffer": "^5.1.0" + "exit-on-epipe": "~1.0.1", + "printj": "~1.3.1" } }, "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz", + "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==", "dev": true, "requires": { - "crc": "^3.4.4", + "crc-32": "^1.2.0", "readable-stream": "^3.4.0" } }, + "cross-fetch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "dev": true, + "requires": { + "node-fetch": "2.6.7" + } + }, "cross-spawn": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", - "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "css-functions-list": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.0.1.tgz", + "integrity": "sha512-PriDuifDt4u4rkDgnqRCLnjfMatufLmWNfQnGCq34xZwpY3oabwhB9SqRBmuvWUgndbemCFlKqg+nO7C2q0SBw==", + "dev": true + }, + "css-rule-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/css-rule-stream/-/css-rule-stream-1.1.0.tgz", + "integrity": "sha1-N4bnGYmD2WWibjGVfgkHjLt3BaI=", + "dev": true, + "requires": { + "css-tokenize": "^1.0.1", + "duplexer2": "0.0.2", + "ldjson-stream": "^1.2.1", + "through2": "^0.6.3" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + } } }, "css-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", - "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.2.1.tgz", + "integrity": "sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==", "dev": true, "requires": { "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" + "css-what": "^5.1.0", + "domhandler": "^4.3.0", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" } }, - "css-select-base-adapter": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", - "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", + "css-shorthand-properties": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/css-shorthand-properties/-/css-shorthand-properties-1.1.1.tgz", + "integrity": "sha512-Md+Juc7M3uOdbAFwOYlTrccIZ7oCFuzrhKYQjdeUEW/sE1hv17Jp/Bws+ReOPpGVBTYCBoYo+G17V5Qo8QQ75A==", "dev": true }, + "css-tokenize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-tokenize/-/css-tokenize-1.0.1.tgz", + "integrity": "sha1-RiXLHtohwUOFi3+B1oA8HSb8FL4=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^1.0.33" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, "css-tree": { - "version": "1.0.0-alpha.37", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", - "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", "dev": true, "requires": { - "mdn-data": "2.0.4", + "mdn-data": "2.0.14", "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "css-value": { @@ -1583,9 +10676,9 @@ "dev": true }, "css-what": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.3.0.tgz", - "integrity": "sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", + "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==", "dev": true }, "cssesc": { @@ -1595,39 +10688,12 @@ "dev": true }, "csso": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.3.tgz", - "integrity": "sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ==", - "dev": true, - "requires": { - "css-tree": "1.0.0-alpha.39" - }, - "dependencies": { - "css-tree": { - "version": "1.0.0-alpha.39", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.39.tgz", - "integrity": "sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==", - "dev": true, - "requires": { - "mdn-data": "2.0.6", - "source-map": "^0.6.1" - } - }, - "mdn-data": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz", - "integrity": "sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==", - "dev": true - } - } - }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", "dev": true, "requires": { - "array-find-index": "^1.0.1" + "css-tree": "^1.1.2" } }, "dashdash": { @@ -1639,23 +10705,25 @@ "assert-plus": "^1.0.0" } }, + "date-format": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-0.0.2.tgz", + "integrity": "sha1-+v1Ej3IRXvHitzkVWukvK+bCjdE=", + "dev": true + }, "dateformat": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", - "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1", - "meow": "^3.3.0" - } + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true }, "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "2.1.2" } }, "decamelize": { @@ -1672,6 +10740,14 @@ "requires": { "decamelize": "^1.1.0", "map-obj": "^1.0.0" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + } } }, "decompress-response": { @@ -1692,9 +10768,9 @@ } }, "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, "deepmerge": { @@ -1708,64 +10784,73 @@ "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", "dev": true, - "optional": true, "requires": { "clone": "^1.0.2" } }, "defer-to-connect": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.0.tgz", - "integrity": "sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", "dev": true }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", "dev": true }, "devtools": { - "version": "6.1.16", - "resolved": "https://registry.npmjs.org/devtools/-/devtools-6.1.16.tgz", - "integrity": "sha512-Px/K/xYY+fTW8D5yt7p6ZZJfkfHHulKVr2Y+BJSCQyKNSY/hiZFT6KAjoUFrAastLCqqs1gW2Dy/OGb0qWm+Hg==", - "dev": true, - "requires": { - "@wdio/config": "6.1.14", - "@wdio/logger": "6.0.16", - "@wdio/protocols": "6.1.14", - "@wdio/utils": "6.1.8", - "chrome-launcher": "^0.13.1", - "puppeteer-core": "^3.0.0", - "ua-parser-js": "^0.7.21", + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/devtools/-/devtools-7.16.13.tgz", + "integrity": "sha512-jm/DL5tlOUUMe0pUgahDqixw3z+NANLN6DYDeZPFv7z0CBtmnaTyOe2zbT0apLxCBpi800VeXaISVZwmKE2NiQ==", + "dev": true, + "requires": { + "@types/node": "^17.0.4", + "@types/ua-parser-js": "^0.7.33", + "@wdio/config": "7.16.13", + "@wdio/logger": "7.16.0", + "@wdio/protocols": "7.16.7", + "@wdio/types": "7.16.13", + "@wdio/utils": "7.16.13", + "chrome-launcher": "^0.15.0", + "edge-paths": "^2.1.0", + "puppeteer-core": "^13.0.0", + "query-selector-shadow-dom": "^1.0.0", + "ua-parser-js": "^1.0.1", "uuid": "^8.0.0" + }, + "dependencies": { + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true + } } }, + "devtools-protocol": { + "version": "0.0.953906", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.953906.tgz", + "integrity": "sha512-Z2vAafCNnl0Iw/u7TUjqOXW1sOhAMDOviflmUoUIxfq2rgfsoCO3qruB/LUJCdqF9aTJ32DUjXyMsX3+if6kDQ==", + "dev": true + }, "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, "diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", "dev": true }, "dir-glob": { @@ -1775,14 +10860,6 @@ "dev": true, "requires": { "path-type": "^4.0.0" - }, - "dependencies": { - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - } } }, "doctrine": { @@ -1794,83 +10871,121 @@ "esutils": "^2.0.2" } }, - "dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "doiuse": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/doiuse/-/doiuse-4.4.1.tgz", + "integrity": "sha512-TUpr1/YNg20IB09tZmwGCTsTQoxj8jUld/hUZprZMj8vj0VpAJySXEWCr8WMvqvgzk0/kG/FxeSMGKode4UjPg==", "dev": true, "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" + "browserslist": "^4.16.1", + "caniuse-lite": "^1.0.30001179", + "css-rule-stream": "^1.1.0", + "duplexer2": "0.0.2", + "ldjson-stream": "^1.2.1", + "multimatch": "^5.0.0", + "postcss": "^8.2.4", + "source-map": "^0.7.3", + "through2": "^4.0.2", + "yargs": "^16.2.0" }, "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==", - "dev": true + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } } } }, + "dom-serializer": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", "dev": true }, "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz", + "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==", "dev": true, "requires": { - "domelementtype": "1" + "domelementtype": "^2.2.0" } }, "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", "dev": true, "requires": { - "dom-serializer": "0", - "domelementtype": "1" + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" } }, - "each-async": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/each-async/-/each-async-1.1.1.tgz", - "integrity": "sha1-3uUim98KtrogEqOV4bhpq/iBNHM=", + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", "dev": true, "requires": { - "onetime": "^1.0.0", - "set-immediate-shim": "^1.0.0" + "readable-stream": "~1.1.9" }, "dependencies": { - "onetime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } } }, "easy-table": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.1.1.tgz", - "integrity": "sha512-C9Lvm0WFcn2RgxbMnTbXZenMIWcBtkzMr+dWqq/JsVoGFSVUVlPqeOa5LP5kM0I3zoOazFpckOEb2/0LDFfToQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.2.0.tgz", + "integrity": "sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww==", "dev": true, "requires": { - "ansi-regex": "^3.0.0", - "wcwidth": ">=1.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - } + "ansi-regex": "^5.0.1", + "wcwidth": "^1.0.1" } }, "ecc-jsbn": { @@ -1883,19 +10998,29 @@ "safer-buffer": "^2.1.0" } }, + "edge-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-2.2.1.tgz", + "integrity": "sha512-AI5fC7dfDmCdKo3m5y7PkYE8m6bMqR6pvVpgtrZkkhcJXFLelUgkjrhk3kXXx8Kbw2cRaTT4LkOR7hqf39KJdw==", + "dev": true, + "requires": { + "@types/which": "^1.3.2", + "which": "^2.0.2" + } + }, "ejs": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.3.tgz", - "integrity": "sha512-wmtrUGyfSC23GC/B1SMv2ogAUgbQEtDmTIhfqielrG5ExIM9TP4UoYdi90jLF1aTcsWCJNEO0UrgKzP0y3nTSg==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", + "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==", "dev": true, "requires": { - "jake": "^10.6.1" + "jake": "^10.8.5" } }, "electron-to-chromium": { - "version": "1.3.481", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.481.tgz", - "integrity": "sha512-q2PeCP2PQXSYadDo9uNY+uHXjdB9PcsUpCVoGlY8TZOPHGlXdevlqW9PkKeqCxn2QBkGB8b6AcMO++gh8X82bA==", + "version": "1.4.71", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.71.tgz", + "integrity": "sha512-Hk61vXXKRb2cd3znPE9F+2pLWdIOmP7GjiTj45y6L3W/lO+hSnUSUhq+6lEaERWBdZOHbk2s3YV5c9xVl3boVw==", "dev": true }, "emoji-regex": { @@ -1913,19 +11038,10 @@ "once": "^1.4.0" } }, - "enquirer": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.5.tgz", - "integrity": "sha512-BNT1C08P9XD0vNg3J475yIUG+mVdp9T6towYFHUv897X0KoHBjB1shyrNmhmtHWKP17iSWgo7Gqh7BBuzLZMSA==", - "dev": true, - "requires": { - "ansi-colors": "^3.2.1" - } - }, "entities": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", "dev": true }, "error": { @@ -1946,164 +11062,168 @@ "is-arrayish": "^0.2.1" } }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, "escalade": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.0.1.tgz", - "integrity": "sha512-DR6NO3h9niOT+MZs7bjxlj2a1k+POu5RN8CLTPX2+i78bRi9eLe7+0zXgUHMnGXWybYcL61E9hGhPKqedy8tQA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true }, "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, "eslint": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.3.1.tgz", - "integrity": "sha512-cQC/xj9bhWUcyi/RuMbRtC3I0eW8MH0jhRELSvpKYkWep3C6YZ2OkvcvJVUeO6gcunABmzptbXBuDoXsjHmfTA==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.10.0.tgz", + "integrity": "sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", + "@eslint/eslintrc": "^1.2.0", + "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", - "debug": "^4.0.1", + "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "eslint-scope": "^5.1.0", - "eslint-utils": "^2.0.0", - "eslint-visitor-keys": "^1.2.0", - "espree": "^7.1.0", - "esquery": "^1.2.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", + "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", - "lodash": "^4.17.14", + "lodash.merge": "^4.6.2", "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "table": "^5.2.3", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" } }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, "requires": { - "ms": "^2.1.1" + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, - "strip-json-comments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz", - "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==", - "dev": true + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "requires": { - "isexe": "^2.0.0" + "argparse": "^2.0.1" } } } }, "eslint-config-wikimedia": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.16.1.tgz", - "integrity": "sha512-VFP+zOaehZgbcH1TCeH6iBZuYv83mZMvu+YYntblbmFrw36Oo9lcNWiUL95SAE+5JtkGtAy51NLE1T61XJYn5w==", - "dev": true, - "requires": { - "eslint": "^7.1.0", - "eslint-plugin-es": "^3.0.1", - "eslint-plugin-jsdoc": "^26.0.0", - "eslint-plugin-json": "^2.1.1", - "eslint-plugin-mediawiki": "^0.2.4", - "eslint-plugin-mocha": "^7.0.1", - "eslint-plugin-no-jquery": "^2.4.1", + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.22.1.tgz", + "integrity": "sha512-TtN+gWJrcW0i1sEu7vPE1tHpEilrMUuTxP6UK97Amvva/KDV9/tvRUifGhw0q5uBswp+HWgF12p8rq68hZqMbA==", + "dev": true, + "requires": { + "eslint": "^8.6.0", + "eslint-plugin-compat": "^4.0.2", + "eslint-plugin-es": "^4.1.0", + "eslint-plugin-jsdoc": "^37.7.1", + "eslint-plugin-json-es": "^1.5.4", + "eslint-plugin-mediawiki": "^0.3.0", + "eslint-plugin-mocha": "^9.0.0", + "eslint-plugin-no-jquery": "^2.7.0", "eslint-plugin-node": "^11.1.0", - "eslint-plugin-qunit": "^4.2.0", - "eslint-plugin-vue": "^6.2.2", - "eslint-plugin-wdio": "^6.0.12" + "eslint-plugin-qunit": "^7.2.0", + "eslint-plugin-unicorn": "^40.1.0", + "eslint-plugin-vue": "^8.4.1", + "eslint-plugin-wdio": "^7.4.2", + "eslint-plugin-yml": "^0.13.0" + } + }, + "eslint-plugin-compat": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-4.0.2.tgz", + "integrity": "sha512-xqvoO54CLTVaEYGMzhu35Wzwk/As7rCvz/2dqwnFiWi0OJccEtGIn+5qq3zqIu9nboXlpdBN579fZcItC73Ycg==", + "dev": true, + "requires": { + "@mdn/browser-compat-data": "^4.1.5", + "ast-metadata-inferer": "^0.7.0", + "browserslist": "^4.16.8", + "caniuse-lite": "^1.0.30001304", + "core-js": "^3.16.2", + "find-up": "^5.0.0", + "lodash.memoize": "4.1.2", + "semver": "7.3.5" } }, "eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz", + "integrity": "sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==", "dev": true, "requires": { "eslint-utils": "^2.0.0", @@ -2111,77 +11231,126 @@ } }, "eslint-plugin-jsdoc": { - "version": "26.0.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-26.0.2.tgz", - "integrity": "sha512-KtZjqtM3Z8x84vQBFKGUyBbZRGXYHVWSJ2XyYSUTc8KhfFrvzQ/GXPp6f1M1/YCNzP3ImD5RuDNcr+OVvIZcBA==", + "version": "37.9.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-37.9.4.tgz", + "integrity": "sha512-VxCyGgUNNnj2T4bb1OqltkbsPp3ehRzR5onIfh6zGrAvISmvgX/sbxUlh3YyGqWtjOTSBCURdKdmelSXEIHnlA==", + "dev": true, + "requires": { + "@es-joy/jsdoccomment": "~0.20.1", + "comment-parser": "1.3.0", + "debug": "^4.3.3", + "escape-string-regexp": "^4.0.0", + "esquery": "^1.4.0", + "regextras": "^0.8.0", + "semver": "^7.3.5", + "spdx-expression-parse": "^3.0.1" + } + }, + "eslint-plugin-json-es": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-json-es/-/eslint-plugin-json-es-1.5.4.tgz", + "integrity": "sha512-DdjnNMUZ1iMrUXfxUQrTU7IyoEOsa4Kg0Zd6nOyOq1mUb75deK7NrcbI1FlWGdGVgqX99bUOD27i81EYiG794Q==", "dev": true, "requires": { - "comment-parser": "^0.7.4", - "debug": "^4.1.1", - "jsdoctypeparser": "^6.1.0", - "lodash": "^4.17.15", - "regextras": "^0.7.1", - "semver": "^6.3.0", - "spdx-expression-parse": "^3.0.1" + "eslint-visitor-keys": "^3.0.0", + "espree": "^9.0.0" }, "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true + } + } + }, + "eslint-plugin-mediawiki": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.3.0.tgz", + "integrity": "sha512-Lhyj2PSkhDzYSc1PNbURysY/WoqvY0brw558ZInT3erzf5KUlro18MTKFdV+nlht475ZgnsfHsgfg6Ut2w1SVg==", + "dev": true, + "requires": { + "eslint-plugin-vue": "^7.20.0", + "upath": "^2.0.1" + }, + "dependencies": { + "eslint-plugin-vue": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-7.20.0.tgz", + "integrity": "sha512-oVNDqzBC9h3GO+NTgWeLMhhGigy6/bQaQbHS+0z7C4YEu/qK/yxHvca/2PTZtGNPsCrHwOTgKMrwu02A9iPBmw==", "dev": true, "requires": { - "ms": "^2.1.1" + "eslint-utils": "^2.1.0", + "natural-compare": "^1.4.0", + "semver": "^6.3.0", + "vue-eslint-parser": "^7.10.0" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true }, + "espree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", + "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.1.0" + } + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true + }, + "vue-eslint-parser": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.11.0.tgz", + "integrity": "sha512-qh3VhDLeh773wjgNTl7ss0VejY9bMMa0GoDG2fQVyDzRFdiU3L7fw74tWZDHNQXdZqxO3EveQroa9ct39D2nqg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-scope": "^5.1.1", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.2.1", + "esquery": "^1.4.0", + "lodash": "^4.17.21", + "semver": "^6.3.0" + } } } }, - "eslint-plugin-json": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-json/-/eslint-plugin-json-2.1.1.tgz", - "integrity": "sha512-Ktsab8ij33V2KFLhh4alC1FYztdmbV32DeMZYYUCZm4kKLW1s4DrleKKgtbAHSJsmshCK5QGOZtfyc2r3jCRsg==", - "dev": true, - "requires": { - "lodash": "^4.17.15", - "vscode-json-languageservice": "^3.5.1" - } - }, - "eslint-plugin-mediawiki": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.2.5.tgz", - "integrity": "sha512-Xs5G4f1EnS6+9gFWkk28nWA9xcOEPx7YZEGsMYGLelZRAF+2DmV/PigF5N5VqoOkNBpwcbXqLD8wLfkg29aF8w==", - "dev": true, - "requires": { - "eslint-plugin-vue": "^6.2.2", - "upath": "^1.2.0" - } - }, "eslint-plugin-mocha": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-7.0.1.tgz", - "integrity": "sha512-zkQRW9UigRaayGm/pK9TD5RjccKXSgQksNtpsXbG9b6L5I+jNx7m98VUbZ4w1H1ArlNA+K7IOH+z8TscN6sOYg==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-9.0.0.tgz", + "integrity": "sha512-d7knAcQj1jPCzZf3caeBIn3BnW6ikcvfz0kSqQpwPYcVGLoJV5sz0l0OJB2LR8I7dvTDbqq1oV6ylhSgzA10zg==", "dev": true, "requires": { - "eslint-utils": "^2.0.0", - "ramda": "^0.27.0" + "eslint-utils": "^3.0.0", + "ramda": "^0.27.1" + }, + "dependencies": { + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + } + } } }, "eslint-plugin-no-jquery": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-2.5.0.tgz", - "integrity": "sha512-RrQ380mUJJKdjgpQ/tZAJ3B3W1n3LbVmULooS2Pv5pUDcc5uVHVSJMTdUlsbvQyfo6hWP2LJ4FbOoDzENWcF7A==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-2.7.0.tgz", + "integrity": "sha512-Aeg7dA6GTH1AcWLlBtWNzOU9efK5KpNi7b0EhBO0o0M+awyzguUUo8gF6hXGjQ9n5h8/uRtYv9zOqQkeC5CG0w==", "dev": true }, "eslint-plugin-node": { @@ -2198,11 +11367,15 @@ "semver": "^6.1.0" }, "dependencies": { - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true + "eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + } }, "semver": { "version": "6.3.0", @@ -2213,35 +11386,107 @@ } }, "eslint-plugin-qunit": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-qunit/-/eslint-plugin-qunit-4.2.0.tgz", - "integrity": "sha512-UibPK0fSshPTJauyitsHjACixpf+I5BEKqXi6WJ/WGhW31WwP7flSdBW8+Y9B46v05KYH6MJg/uZVIaiaHO5Cg==", - "dev": true + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-qunit/-/eslint-plugin-qunit-7.2.0.tgz", + "integrity": "sha512-ebT6aOpmMj4vchG0hVw9Ukbutk/lgywrc8gc9w9hH2/4WjKqwMlyM7iVwqB7OAXv6gtQMJZuziT0wNjjymAuWA==", + "dev": true, + "requires": { + "eslint-utils": "^3.0.0", + "requireindex": "^1.2.0" + }, + "dependencies": { + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + } + } + } + }, + "eslint-plugin-unicorn": { + "version": "40.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-40.1.0.tgz", + "integrity": "sha512-y5doK2DF9Sr5AqKEHbHxjFllJ167nKDRU01HDcWyv4Tnmaoe9iNxMrBnaybZvWZUaE3OC5Unu0lNIevYamloig==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.15.7", + "ci-info": "^3.3.0", + "clean-regexp": "^1.0.0", + "eslint-utils": "^3.0.0", + "esquery": "^1.4.0", + "indent-string": "^4.0.0", + "is-builtin-module": "^3.1.0", + "lodash": "^4.17.21", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.24", + "safe-regex": "^2.1.1", + "semver": "^7.3.5", + "strip-indent": "^3.0.0" + }, + "dependencies": { + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + } + } + } }, "eslint-plugin-vue": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-6.2.2.tgz", - "integrity": "sha512-Nhc+oVAHm0uz/PkJAWscwIT4ijTrK5fqNqz9QB1D35SbbuMG1uB6Yr5AJpvPSWg+WOw7nYNswerYh0kOk64gqQ==", + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-8.5.0.tgz", + "integrity": "sha512-i1uHCTAKOoEj12RDvdtONWrGzjFm/djkzqfhmQ0d6M/W8KM81mhswd/z+iTZ0jCpdUedW3YRgcVfQ37/J4zoYQ==", "dev": true, "requires": { + "eslint-utils": "^3.0.0", "natural-compare": "^1.4.0", - "semver": "^5.6.0", - "vue-eslint-parser": "^7.0.0" + "semver": "^7.3.5", + "vue-eslint-parser": "^8.0.1" + }, + "dependencies": { + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + } + } } }, "eslint-plugin-wdio": { - "version": "6.0.12", - "resolved": "https://registry.npmjs.org/eslint-plugin-wdio/-/eslint-plugin-wdio-6.0.12.tgz", - "integrity": "sha512-qZqcU1Z0bqrqhYM1MbwIvKQxcQEGIOEclOjcveavvLZAN4ezpXb1Ogw3xu+UK13iArregJOMI6uUt+JkFmER1A==", + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-wdio/-/eslint-plugin-wdio-7.4.2.tgz", + "integrity": "sha512-tkISFycJmRFMKsEjetRcAmWSHKJKnw5rKHDxfE7Ob3tF5lbmYlCLfNKH0UwanOpSdulpe52s3K+CBHSd6qUUNQ==", "dev": true }, + "eslint-plugin-yml": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-0.13.0.tgz", + "integrity": "sha512-rZvdnhe28jIbgSIZo3qYqkl9hKslyTDfMwqIGDzz873gxghzBw0yeFG+P7sMfOkFfpqwJzZy3IKe2cIiCp4FrA==", + "dev": true, + "requires": { + "debug": "^4.3.2", + "lodash": "^4.17.21", + "natural-compare": "^1.4.0", + "yaml-eslint-parser": "^0.5.0" + } + }, "eslint-scope": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", - "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "requires": { - "esrecurse": "^4.1.0", + "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, @@ -2252,23 +11497,45 @@ "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } } }, "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true }, "espree": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.1.0.tgz", - "integrity": "sha512-dcorZSyfmm4WTuTnE5Y7MEN1DyoPYy1ZR783QW1FJoenn7RailyWFsq/UL6ZAAA7uXurN9FIpYyUs3OfiIW+Qw==", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", + "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", "dev": true, "requires": { - "acorn": "^7.2.0", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.2.0" + "acorn": "^8.7.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.3.0" + }, + "dependencies": { + "acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true + } } }, "esprima": { @@ -2278,29 +11545,37 @@ "dev": true }, "esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "requires": { "estraverse": "^5.1.0" }, "dependencies": { "estraverse": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz", - "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } }, "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "requires": { - "estraverse": "^4.1.0" + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } } }, "estraverse": { @@ -2336,28 +11611,41 @@ "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", "dev": true }, + "exit-on-epipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", + "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==", + "dev": true + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, "expect": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-25.5.0.tgz", - "integrity": "sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", "dev": true, "requires": { - "@jest/types": "^25.5.0", - "ansi-styles": "^4.0.0", - "jest-get-type": "^25.2.6", - "jest-matcher-utils": "^25.5.0", - "jest-message-util": "^25.5.0", - "jest-regex-util": "^25.2.6" + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" } }, "expect-webdriverio": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/expect-webdriverio/-/expect-webdriverio-1.1.5.tgz", - "integrity": "sha512-+RL4Lkne+/z+o1G5Y0S5QuEXeICxt4jExhBSM2Jn/mrDwb+PZVKPM2Yd1OzLsKeCdQLtw4Oft6514Gp5GLgdZA==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/expect-webdriverio/-/expect-webdriverio-3.1.4.tgz", + "integrity": "sha512-65FTS3bmxcIp0cq6fLb/72TrCQXBCpwPLC7SwMWdpPlLq461mXcK1BPKJJjnIC587aXSKD+3E4hvnlCtwDmXfg==", "dev": true, "requires": { - "expect": "^25.2.1", - "jest-matcher-utils": "^25.1.0" + "expect": "^27.0.2", + "jest-matcher-utils": "^27.0.2" } }, "extend": { @@ -2387,23 +11675,6 @@ "debug": "^4.1.1", "get-stream": "^5.1.0", "yauzl": "^2.10.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } } }, "extsprintf": { @@ -2413,23 +11684,22 @@ "dev": true }, "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "fast-glob": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", - "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", + "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" + "micromatch": "^4.0.4" } }, "fast-json-stable-stringify": { @@ -2444,10 +11714,16 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", + "dev": true + }, "fastq": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", - "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -2471,15 +11747,6 @@ "pend": "~1.2.0" } }, - "fibers": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fibers/-/fibers-4.0.3.tgz", - "integrity": "sha512-MW5VrDtTOLpKK7lzw4qD7Z9tXaAhdOmOED5RHzg3+HjUk+ibkjVW0Py2ERtdqgTXaerLkVkBy2AEmJiT6RMyzg==", - "dev": true, - "requires": { - "detect-libc": "^1.0.3" - } - }, "figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -2487,24 +11754,52 @@ "dev": true, "requires": { "escape-string-regexp": "^1.0.5" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + } } }, "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "requires": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" } }, "filelist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.1.tgz", - "integrity": "sha512-8zSK6Nu0DQIC08mUC46sWGXi+q3GGpKydAG36k+JDba6VRpkevvOWUW5a/PhShij4+vHT9M+ghgG7eM+a9JDUQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", "dev": true, "requires": { - "minimatch": "^3.0.4" + "minimatch": "^5.0.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, "fill-range": { @@ -2517,12 +11812,12 @@ } }, "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "requires": { - "locate-path": "^5.0.0", + "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, @@ -2550,43 +11845,62 @@ } } }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "fined": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", + "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", "dev": true, "requires": { - "is-buffer": "~2.0.3" + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" } }, + "flagged-respawn": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", + "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", + "dev": true + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "dependencies": { - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } + "flatted": "^3.1.0", + "rimraf": "^3.0.2" } }, "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "dev": true + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -2611,15 +11925,14 @@ "dev": true }, "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", + "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", "dev": true, "requires": { - "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", - "universalify": "^1.0.0" + "universalify": "^2.0.0" } }, "fs.realpath": { @@ -2628,13 +11941,6 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -2656,37 +11962,48 @@ "globule": "^1.0.0" } }, - "gensync": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", - "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", - "dev": true - }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-port": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", + "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", + "dev": true + }, "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", "dev": true }, "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { "pump": "^3.0.0" } }, "getobject": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz", - "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/getobject/-/getobject-1.0.2.tgz", + "integrity": "sha512-2zblDBaFcb3rB4rF77XVnuINOE2h2k/OnqXAiy0IrTxUfV1iFp3la33oAQVY9pCpWU268WFYVt2t71hlMuLsOg==", "dev": true }, "getpass": { @@ -2699,9 +12016,9 @@ } }, "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -2713,9 +12030,9 @@ } }, "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -2739,45 +12056,40 @@ "ini": "^1.3.5", "kind-of": "^6.0.2", "which": "^1.3.1" + }, + "dependencies": { + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } } }, "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "version": "13.12.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", + "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", "dev": true, "requires": { - "type-fest": "^0.8.1" - }, - "dependencies": { - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - } + "type-fest": "^0.20.2" } }, "globby": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", - "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "requires": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", "slash": "^3.0.0" - }, - "dependencies": { - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - } } }, "globjoin": { @@ -2787,49 +12099,64 @@ "dev": true }, "globule": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz", - "integrity": "sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.3.tgz", + "integrity": "sha512-mb1aYtDbIjTu4ShMB85m3UzjX9BVKe9WCzsnfMSZk+K5GpIbBOexgg4PPCt5eHDEG5/ZQAUX2Kct02zfiPLsKg==", "dev": true, "requires": { "glob": "~7.1.1", "lodash": "~4.17.10", "minimatch": "~3.0.2" - } - }, - "gonzales-pe": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", - "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" + }, + "dependencies": { + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } } }, "got": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/got/-/got-11.3.0.tgz", - "integrity": "sha512-yi/kiZY2tNMtt5IfbfX8UL3hAZWb2gZruxYZ72AY28pU5p0TZjZdl0uRsuaFbnC0JopdUi3I+Mh1F3dPQ9Dh0Q==", + "version": "11.8.5", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.5.tgz", + "integrity": "sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==", "dev": true, "requires": { - "@sindresorhus/is": "^2.1.1", + "@sindresorhus/is": "^4.0.0", "@szmarczak/http-timer": "^4.0.5", "@types/cacheable-request": "^6.0.1", "@types/responselike": "^1.0.0", "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.1", + "cacheable-request": "^7.0.2", "decompress-response": "^6.0.0", - "get-stream": "^5.1.0", - "http2-wrapper": "^1.0.0-beta.4.5", + "http2-wrapper": "^1.0.0-beta.5.2", "lowercase-keys": "^2.0.0", "p-cancelable": "^2.0.0", "responselike": "^2.0.0" } }, "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "dev": true }, "grapheme-splitter": { @@ -2845,101 +12172,84 @@ "dev": true }, "grunt": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.1.0.tgz", - "integrity": "sha512-+NGod0grmviZ7Nzdi9am7vuRS/h76PcWDsV635mEXF0PEQMUV6Kb+OjTdsVxbi0PZmfQOjCMKb3w8CVZcqsn1g==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.5.3.tgz", + "integrity": "sha512-mKwmo4X2d8/4c/BmcOETHek675uOqw0RuA/zy12jaspWqvTp4+ZeQF1W+OTpcbncnaBsfbQJ6l0l4j+Sn/GmaQ==", "dev": true, "requires": { - "coffeescript": "~1.10.0", - "dateformat": "~1.0.12", + "dateformat": "~3.0.3", "eventemitter2": "~0.4.13", - "exit": "~0.1.1", + "exit": "~0.1.2", "findup-sync": "~0.3.0", - "glob": "~7.0.0", - "grunt-cli": "~1.2.0", - "grunt-known-options": "~1.1.0", - "grunt-legacy-log": "~2.0.0", - "grunt-legacy-util": "~1.1.1", + "glob": "~7.1.6", + "grunt-cli": "~1.4.3", + "grunt-known-options": "~2.0.0", + "grunt-legacy-log": "~3.0.0", + "grunt-legacy-util": "~2.0.1", "iconv-lite": "~0.4.13", - "js-yaml": "~3.13.1", - "minimatch": "~3.0.2", - "mkdirp": "~1.0.3", + "js-yaml": "~3.14.0", + "minimatch": "~3.0.4", + "mkdirp": "~1.0.4", "nopt": "~3.0.6", - "path-is-absolute": "~1.0.0", - "rimraf": "~2.6.2" + "rimraf": "~3.0.2" }, "dependencies": { "glob": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", - "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.2", + "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, - "grunt-cli": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz", - "integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=", + "minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", "dev": true, "requires": { - "findup-sync": "~0.3.0", - "grunt-known-options": "~1.1.0", - "nopt": "~3.0.6", - "resolve": "~1.1.0" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } + "brace-expansion": "^1.1.7" } } } }, "grunt-banana-checker": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/grunt-banana-checker/-/grunt-banana-checker-0.9.0.tgz", - "integrity": "sha512-SqPiB6OazWqR8USL0NymtuT5Br3mD9WBBsM1rHC/3wIi2SrZNM6/+j9CIeuEM5oCn+AtO2Y0+rzzFyOdC9afAg==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/grunt-banana-checker/-/grunt-banana-checker-0.10.0.tgz", + "integrity": "sha512-Sx+P3zWjn4YmBCqzidnCEkYrACe1SLTIT8kKC6C3f21Hu6sm17U/V+re343cuK3U+iGZv15ux6bY+69buIbYrA==", "dev": true }, + "grunt-cli": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.4.3.tgz", + "integrity": "sha512-9Dtx/AhVeB4LYzsViCjUQkd0Kw0McN2gYpdmGYKtE2a5Yt7v1Q+HYZVWhqXc/kGnxlMtqKDxSwotiGeFmkrCoQ==", + "dev": true, + "requires": { + "grunt-known-options": "~2.0.0", + "interpret": "~1.1.0", + "liftup": "~3.0.1", + "nopt": "~4.0.1", + "v8flags": "~3.2.0" + }, + "dependencies": { + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + } + } + }, "grunt-contrib-watch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-1.1.0.tgz", @@ -2950,231 +12260,76 @@ "gaze": "^1.1.0", "lodash": "^4.17.10", "tiny-lr": "^1.1.1" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", - "dev": true - } } }, "grunt-eslint": { - "version": "23.0.0", - "resolved": "https://registry.npmjs.org/grunt-eslint/-/grunt-eslint-23.0.0.tgz", - "integrity": "sha512-QqHSAiGF08EVD7YlD4OSRWuLRaDvpsRdTptwy9WaxUXE+03mCLVA/lEaR6SHWehF7oUwIqCEjaNONeeeWlB4LQ==", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/grunt-eslint/-/grunt-eslint-24.0.0.tgz", + "integrity": "sha512-WpTeBBFweyhMuPjGwRSQV9JFJ+EczIdlsc7Dd/1g78QVI1aZsk4g/H3e+3S5HEwsS1RKL2YZIrGj8hMLlBfN8w==", "dev": true, "requires": { - "chalk": "^4.0.0", - "eslint": "^7.0.0" + "chalk": "^4.1.2", + "eslint": "^8.0.1" } }, "grunt-known-options": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.1.tgz", - "integrity": "sha512-cHwsLqoighpu7TuYj5RonnEuxGVFnztcUqTqp5rXFGYL4OuPFofwC4Ycg7n9fYwvK6F5WbYgeVOwph9Crs2fsQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-2.0.0.tgz", + "integrity": "sha512-GD7cTz0I4SAede1/+pAbmJRG44zFLPipVtdL9o3vqx9IEyb7b4/Y3s7r6ofI3CchR5GvYJ+8buCSioDv5dQLiA==", "dev": true }, "grunt-legacy-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-2.0.0.tgz", - "integrity": "sha512-1m3+5QvDYfR1ltr8hjiaiNjddxGdQWcH0rw1iKKiQnF0+xtgTazirSTGu68RchPyh1OBng1bBUjLmX8q9NpoCw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-3.0.0.tgz", + "integrity": "sha512-GHZQzZmhyq0u3hr7aHW4qUH0xDzwp2YXldLPZTCjlOeGscAOWWPftZG3XioW8MasGp+OBRIu39LFx14SLjXRcA==", "dev": true, "requires": { "colors": "~1.1.2", - "grunt-legacy-log-utils": "~2.0.0", + "grunt-legacy-log-utils": "~2.1.0", "hooker": "~0.2.3", - "lodash": "~4.17.5" + "lodash": "~4.17.19" } }, "grunt-legacy-log-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.0.1.tgz", - "integrity": "sha512-o7uHyO/J+i2tXG8r2bZNlVk20vlIFJ9IEYyHMCQGfWYru8Jv3wTqKZzvV30YW9rWEjq0eP3cflQ1qWojIe9VFA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.1.0.tgz", + "integrity": "sha512-lwquaPXJtKQk0rUM1IQAop5noEpwFqOXasVoedLeNzaibf/OPWjKYvvdqnEHNmU+0T0CaReAXIbGo747ZD+Aaw==", "dev": true, "requires": { - "chalk": "~2.4.1", - "lodash": "~4.17.10" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "chalk": "~4.1.0", + "lodash": "~4.17.19" } }, "grunt-legacy-util": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.1.1.tgz", - "integrity": "sha512-9zyA29w/fBe6BIfjGENndwoe1Uy31BIXxTH3s8mga0Z5Bz2Sp4UCjkeyv2tI449ymkx3x26B+46FV4fXEddl5A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-2.0.1.tgz", + "integrity": "sha512-2bQiD4fzXqX8rhNdXkAywCadeqiPiay0oQny77wA2F3WF4grPJXCvAcyoWUJV+po/b15glGkxuSiQCK299UC2w==", "dev": true, "requires": { - "async": "~1.5.2", - "exit": "~0.1.1", - "getobject": "~0.1.0", + "async": "~3.2.0", + "exit": "~0.1.2", + "getobject": "~1.0.0", "hooker": "~0.2.3", - "lodash": "~4.17.10", - "underscore.string": "~3.3.4", - "which": "~1.3.0" + "lodash": "~4.17.21", + "underscore.string": "~3.3.5", + "which": "~2.0.2" }, "dependencies": { "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", + "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", "dev": true } } }, "grunt-stylelint": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/grunt-stylelint/-/grunt-stylelint-0.15.0.tgz", - "integrity": "sha512-1G5kbT3Y6OtAqgIv/XErtI6ai1t1UdtQWXxUV5Gd900PQoEzu/WrBYhGNAXdb/9nAsNWNjFHQjtdXQtZcDmobA==", - "dev": true, - "requires": { - "chalk": "^3.0.0" - }, - "dependencies": { - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "grunt-svgmin": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/grunt-svgmin/-/grunt-svgmin-5.0.0.tgz", - "integrity": "sha1-8O4pOtFi++hcjD5o2xUt/3J3qCQ=", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/grunt-stylelint/-/grunt-stylelint-0.18.0.tgz", + "integrity": "sha512-Ks5OfRUCA6E1v5PkCQKYaMErHtoec/Ub0Vb1xvZ0CKm/1zzWKuqEu2ZVtFcQVDqrC5UM6AXaLHpsLiocVKAgbg==", "dev": true, "requires": { - "chalk": "^2.3.0", - "each-async": "^1.1.1", - "log-symbols": "^2.1.0", - "pretty-bytes": "^4.0.2", - "svgo": "^1.0.3" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "requires": { - "chalk": "^2.0.1" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "chalk": "^4.1.2" } }, "har-schema": { @@ -3184,12 +12339,12 @@ "dev": true }, "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "dev": true, "requires": { - "ajv": "^6.5.5", + "ajv": "^6.12.3", "har-schema": "^2.0.0" } }, @@ -3232,9 +12387,9 @@ "dev": true }, "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", "dev": true }, "he": { @@ -3243,6 +12398,15 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, "hooker": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", @@ -3250,39 +12414,17 @@ "dev": true }, "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "html-tags": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz", - "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.2.0.tgz", + "integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==", "dev": true }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "dev": true, - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - }, - "dependencies": { - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - } - } - }, "http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", @@ -3290,9 +12432,9 @@ "dev": true }, "http-parser-js": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.2.tgz", - "integrity": "sha512-opCO9ASqg5Wy2FNo7A0sxy71yGbbkJJXLdgMK04Tcypw9jr2MgWbyubb0+WdmDmGnFflO7fRbqbaihh/ENDlRQ==", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.5.tgz", + "integrity": "sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA==", "dev": true }, "http-signature": { @@ -3307,40 +12449,23 @@ } }, "http2-wrapper": { - "version": "1.0.0-beta.4.6", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.0-beta.4.6.tgz", - "integrity": "sha512-9oB4BiGDTI1FmIBlOF9OJ5hwJvcBEmPCqk/hy314Uhy2uq5TjekUZM8w8SPLLlUEM+mxNhXdPAXfrJN2Zbb/GQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", "dev": true, "requires": { - "quick-lru": "^5.0.0", + "quick-lru": "^5.1.1", "resolve-alpn": "^1.0.0" } }, "https-proxy-agent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", - "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", "dev": true, "requires": { - "agent-base": "5", + "agent-base": "6", "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } } }, "iconv-lite": { @@ -3353,21 +12478,21 @@ } }, "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "dev": true }, "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true }, "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "requires": { "parent-module": "^1.0.0", @@ -3387,15 +12512,9 @@ "dev": true }, "indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", - "dev": true - }, - "indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true }, "inflight": { @@ -3415,64 +12534,47 @@ "dev": true }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, "inquirer": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.2.0.tgz", - "integrity": "sha512-E0c4rPwr9ByePfNlTIB8z51kK1s2n6jrHuJeEHENl/sbq2G/S1auvibgEwNR4uSyiU+PiYHqSwsgGiXjG8p5ZQ==", + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.1.5.tgz", + "integrity": "sha512-G6/9xUqmt/r+UvufSyrPpt84NYwhKZ9jLsgMbQzlx804XErNupor8WQdBnBRrXmBfTPpuwf1sV+ss2ovjgdXIg==", "dev": true, "requires": { "ansi-escapes": "^4.2.1", - "chalk": "^3.0.0", + "chalk": "^4.1.1", "cli-cursor": "^3.1.0", - "cli-width": "^2.0.0", + "cli-width": "^3.0.0", "external-editor": "^3.0.3", "figures": "^3.0.0", - "lodash": "^4.17.15", + "lodash": "^4.17.21", "mute-stream": "0.0.8", + "ora": "^5.4.1", "run-async": "^2.4.0", - "rxjs": "^6.5.3", + "rxjs": "^7.2.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0", "through": "^2.3.6" - }, - "dependencies": { - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } } }, - "is-alphabetical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", "dev": true }, - "is-alphanumeric": { + "is-absolute": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz", - "integrity": "sha1-Spzvcdr0wAHB2B1j0UDPU/1oifQ=", - "dev": true - }, - "is-alphanumerical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", "dev": true, "requires": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" } }, "is-arrayish": { @@ -3490,34 +12592,28 @@ "binary-extensions": "^2.0.0" } }, - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true + "is-builtin-module": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz", + "integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==", + "dev": true, + "requires": { + "builtin-modules": "^3.0.0" + } }, - "is-decimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", - "dev": true + "is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "dev": true, + "requires": { + "has": "^1.0.3" + } }, "is-docker": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", - "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true }, "is-extglob": { @@ -3526,12 +12622,6 @@ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, - "is-finite": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", - "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", - "dev": true - }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -3539,18 +12629,18 @@ "dev": true }, "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "requires": { "is-extglob": "^2.1.1" } }, - "is-hexadecimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", "dev": true }, "is-number": { @@ -3560,18 +12650,18 @@ "dev": true }, "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", "dev": true }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "requires": { - "has-symbols": "^1.0.1" + "isobject": "^3.0.1" } }, "is-regexp": { @@ -3580,13 +12670,13 @@ "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==", "dev": true }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", "dev": true, "requires": { - "has-symbols": "^1.0.1" + "is-unc-path": "^1.0.0" } }, "is-typedarray": { @@ -3595,22 +12685,31 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "requires": { + "unc-path-regex": "^0.1.2" + } + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, "is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", "dev": true }, - "is-whitespace-character": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", - "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", - "dev": true - }, - "is-word-character": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", - "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, "is-wsl": { @@ -3634,6 +12733,12 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -3641,157 +12746,83 @@ "dev": true }, "jake": { - "version": "10.8.2", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz", - "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==", + "version": "10.8.5", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", + "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", "dev": true, "requires": { - "async": "0.9.x", - "chalk": "^2.4.2", + "async": "^3.2.3", + "chalk": "^4.0.2", "filelist": "^1.0.1", "minimatch": "^3.0.4" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "async": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", + "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } } } }, "jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", "dev": true, "requires": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - }, - "dependencies": { - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" } }, "jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", "dev": true }, "jest-matcher-utils": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", - "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", "dev": true, "requires": { - "chalk": "^3.0.0", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - }, - "dependencies": { - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" } }, "jest-message-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", - "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.5.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", "slash": "^3.0.0", - "stack-utils": "^1.0.1" + "stack-utils": "^2.0.3" }, "dependencies": { - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@babel/highlight": "^7.16.7" } } } }, - "jest-regex-util": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", - "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", - "dev": true - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -3799,9 +12830,9 @@ "dev": true }, "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -3814,16 +12845,10 @@ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "dev": true }, - "jsdoctypeparser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-6.1.0.tgz", - "integrity": "sha512-UCQBZ3xCUBv/PLfwKAJhp6jmGOSLFNKzrotXGNgbKhWvz27wPsCsVeP7gIcHPElQw2agBmynAitXqhxR58XAmA==", - "dev": true - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "jsdoc-type-pratt-parser": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-2.2.3.tgz", + "integrity": "sha512-QPyxq62Q8veBSDtDrWmqaEPjSCeknUV9dH/OAGt3q9an8qC8UQDqitQiw1NvoMskIESpoRZ6qzt4H3rlK0xo8A==", "dev": true }, "json-buffer": { @@ -3832,16 +12857,16 @@ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", "dev": true }, "json-schema-traverse": { @@ -3862,47 +12887,44 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "dev": true }, - "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==", - "dev": true - }, "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "requires": { "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" + "universalify": "^2.0.0" } }, "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", - "json-schema": "0.2.3", + "json-schema": "0.4.0", "verror": "1.10.0" } }, + "junit-report-builder": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/junit-report-builder/-/junit-report-builder-3.0.0.tgz", + "integrity": "sha512-aW7DnfLddUb51T+V08bJyecexaLomy5ID/0FXvhwsRXs9E0abvDaDT024U99J2agU3dt4q0ppzfKxSwrIIgXWg==", + "dev": true, + "requires": { + "date-format": "0.0.2", + "lodash": "^4.17.15", + "make-dir": "^1.3.0", + "xmlbuilder": "^15.1.1" + } + }, "keyv": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.1.tgz", - "integrity": "sha512-xz6Jv6oNkbhrFCvCP7HQa8AaII8y8LRpoSm661NOKLr4uHuBwhX4epXrPQgF3+xdJnN4Esm5X0xwY4bOlALOtw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.1.1.tgz", + "integrity": "sha512-tGv1yP6snQVDSM4X6yxrv2zzq/EvpW+oYiUz6aueW1u9CtS8RzUQYxxmFwgZlO2jSgCxQbchhxaqXXp2hnKGpQ==", "dev": true, "requires": { "json-buffer": "3.0.1" @@ -3915,15 +12937,21 @@ "dev": true }, "known-css-properties": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.18.0.tgz", - "integrity": "sha512-69AgJ1rQa7VvUsd2kpvVq+VeObDuo3zrj0CzM5Slmf6yduQFAI2kXPDQJR2IE/u6MSAUOJrwSzjg5vlz8qcMiw==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.24.0.tgz", + "integrity": "sha512-RTSoaUAfLvpR357vWzAz/50Q/BmHfmE6ETSWfutT0AJiw10e6CmcdYRQJlLRd95B53D0Y2aD1jSxD3V3ySF+PA==", + "dev": true + }, + "ky": { + "version": "0.28.7", + "resolved": "https://registry.npmjs.org/ky/-/ky-0.28.7.tgz", + "integrity": "sha512-a23i6qSr/ep15vdtw/zyEQIDLoUaKDg9Jf04CYl/0ns/wXNYna26zJpI+MeIFaPeDvkrjLPrKtKOiiI3IE53RQ==", "dev": true }, "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", "dev": true, "requires": { "readable-stream": "^2.0.5" @@ -3943,14 +12971,72 @@ "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } } } }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true + "ldjson-stream": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ldjson-stream/-/ldjson-stream-1.2.1.tgz", + "integrity": "sha1-kb7O2lrE7SsX5kn7d356v6AYnCs=", + "dev": true, + "requires": { + "split2": "^0.2.1", + "through2": "^0.6.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "split2": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/split2/-/split2-0.2.1.tgz", + "integrity": "sha1-At2smtwD7Au3jBKC7Aecpuha6QA=", + "dev": true, + "requires": { + "through2": "~0.6.1" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + } + } }, "levn": { "version": "0.4.1", @@ -3962,20 +13048,67 @@ "type-check": "~0.4.0" } }, + "liftup": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/liftup/-/liftup-3.0.1.tgz", + "integrity": "sha512-yRHaiQDizWSzoXk3APcA71eOI/UuhEkNN9DiW2Tt44mhYzX4joFoCZlxsSOF7RyeLlfqzFLQI1ngFq3ggMPhOw==", + "dev": true, + "requires": { + "extend": "^3.0.2", + "findup-sync": "^4.0.0", + "fined": "^1.2.0", + "flagged-respawn": "^1.0.1", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.1", + "rechoir": "^0.7.0", + "resolve": "^1.19.0" + }, + "dependencies": { + "findup-sync": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", + "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^4.0.2", + "resolve-dir": "^1.0.1" + } + } + } + }, "lighthouse-logger": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.2.0.tgz", - "integrity": "sha512-wzUvdIeJZhRsG6gpZfmSCfysaxNEr43i+QT+Hie94wvHDKFLi4n7C2GqZ4sTC+PH5b5iktmXJvU87rWvhP3lHw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.3.0.tgz", + "integrity": "sha512-BbqAKApLb9ywUli+0a+PcV04SyJ/N1q/8qgCNe6U97KbPCS1BTksEuHFLYdvc8DltuhfxIUBqDZsC0bBGtl3lA==", "dev": true, "requires": { - "debug": "^2.6.8", - "marky": "^1.2.0" + "debug": "^2.6.9", + "marky": "^1.2.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } } }, "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, "livereload-js": { @@ -3995,21 +13128,38 @@ "pify": "^2.0.0", "pinkie-promise": "^2.0.0", "strip-bom": "^2.0.0" + }, + "dependencies": { + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } } }, "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "requires": { - "p-locate": "^4.1.0" + "p-locate": "^5.0.0" } }, "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "lodash.clonedeep": { @@ -4054,6 +13204,12 @@ "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", "dev": true }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -4066,6 +13222,12 @@ "integrity": "sha1-feoh2MGNdwOifHBMFdO4SmfjOv8=", "dev": true }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, "lodash.union": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", @@ -4079,82 +13241,19 @@ "dev": true }, "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "requires": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" } }, "loglevel": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz", - "integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.0.tgz", + "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==", "dev": true }, "loglevel-plugin-prefix": { @@ -4163,22 +13262,6 @@ "integrity": "sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==", "dev": true }, - "longest-streak": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", - "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", - "dev": true - }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "dev": true, - "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" - } - }, "lowercase-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", @@ -4186,40 +13269,48 @@ "dev": true }, "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "yallist": "^4.0.0" } }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true - }, - "markdown-escapes": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", - "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", - "dev": true + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } }, - "markdown-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", - "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", + "make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", "dev": true, "requires": { - "repeat-string": "^1.0.0" + "kind-of": "^6.0.2" } }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true + }, "marky": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/marky/-/marky-1.2.1.tgz", - "integrity": "sha512-md9k+Gxa3qLH6sUKpeC2CNkJK/Ld+bEz5X96nYwloqphQE0CKCVEKco/6jxEZixinqNdz5RFi/KaCyfbMDMAXQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/marky/-/marky-1.2.4.tgz", + "integrity": "sha512-zd2/GiSn6U3/jeFVZ0J9CA1LzQ8RfIVvXkb/U0swFHF/zT+dVohTAWjmo2DcIuofmIIIROlwTbd+shSeXmxr0w==", "dev": true }, "mathml-tag-names": { @@ -4228,54 +13319,58 @@ "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", "dev": true }, - "mdast-util-compact": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-2.0.1.tgz", - "integrity": "sha512-7GlnT24gEwDrdAwEHrU4Vv5lLWrEer4KOkAiKT9nYstsTad7Oc1TwqT2zIMKRdZF7cTuaf+GA1E4Kv7jJh8mPA==", - "dev": true, - "requires": { - "unist-util-visit": "^2.0.0" - } - }, "mdn-data": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", - "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", "dev": true }, "meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dev": true, - "requires": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "dev": true, + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" }, "dependencies": { - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true + "hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", "dev": true, "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" } + }, + "type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true } } }, @@ -4286,34 +13381,28 @@ "dev": true }, "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" + "braces": "^3.0.2", + "picomatch": "^2.3.1" } }, - "mime": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", - "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", - "dev": true - }, "mime-db": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", - "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", "dev": true }, "mime-types": { - "version": "2.1.27", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", - "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", "dev": true, "requires": { - "mime-db": "1.44.0" + "mime-db": "1.51.0" } }, "mimic-fn": { @@ -4335,18 +13424,18 @@ "dev": true }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", "dev": true }, "minimist-options": { @@ -4358,24 +13447,13 @@ "arrify": "^1.0.1", "is-plain-obj": "^1.1.0", "kind-of": "^6.0.3" - }, - "dependencies": { - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true - } } }, "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true }, "mkdirp-classic": { "version": "0.5.3", @@ -4384,260 +13462,111 @@ "dev": true }, "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", + "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", "dev": true, "requires": { - "ansi-colors": "3.2.3", + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", + "chokidar": "3.5.3", + "debug": "4.3.3", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", "growl": "1.10.5", "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "4.2.1", + "ms": "2.1.3", + "nanoid": "3.3.1", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.2.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "requires": { - "locate-path": "^3.0.0" + "argparse": "^2.0.1" } }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "minimatch": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", + "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "brace-expansion": "^1.1.7" } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" } } } }, "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "multimatch": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz", + "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==", + "dev": true, + "requires": { + "@types/minimatch": "^3.0.3", + "array-differ": "^3.0.0", + "array-union": "^2.1.0", + "arrify": "^2.0.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true + } + } + }, "mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", @@ -4645,36 +13574,53 @@ "dev": true }, "mwbot": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/mwbot/-/mwbot-1.0.10.tgz", - "integrity": "sha1-pEC9ZmOnYoq1t5lgnpjLL8ThM8k=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mwbot/-/mwbot-2.0.0.tgz", + "integrity": "sha512-9iTx8oFMntC60yyaPJjN4GEgiQlal7i03jATu7kq5b9BGW5aNz7YbrpjaciLNr0Z33PTdQe0hRTJ0JdUJi2WQg==", "dev": true, "requires": { - "bluebird": "^3.4.6", - "request": "^2.75.0", - "semlog": "^0.6.10" + "bluebird": "^3.7.2", + "request": "^2.88.2", + "semlog": "^0.6.10", + "semver": "7.3.4" + }, + "dependencies": { + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } } }, + "nanoid": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", + "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "dev": true + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", "dev": true, "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" + "whatwg-url": "^5.0.0" } }, "node-releases": { - "version": "1.1.58", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.58.tgz", - "integrity": "sha512-NxBudgVKiRh/2aPWMgPR7bPTX0VPmGx5QBwCtdHitnqFE5/O8DeBXuIMH1nwNnw/aMo6AjOrpsHzfY3UbUJ7yg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", + "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", "dev": true }, "nopt": { @@ -4696,6 +13642,14 @@ "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } } }, "normalize-path": { @@ -4704,12 +13658,6 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", - "dev": true - }, "normalize-selector": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz", @@ -4717,26 +13665,20 @@ "dev": true }, "normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", "dev": true }, "nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", + "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", "dev": true, "requires": { - "boolbase": "~1.0.0" + "boolbase": "^1.0.0" } }, - "num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", - "dev": true - }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -4750,49 +13692,40 @@ "dev": true }, "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", "dev": true }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", "dev": true, "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" } }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", + "object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" } }, - "object.values": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", - "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" + "isobject": "^3.0.1" } }, "once": { @@ -4805,9 +13738,9 @@ } }, "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "requires": { "mimic-fn": "^2.1.0" @@ -4827,34 +13760,73 @@ "word-wrap": "^1.2.3" } }, + "ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "requires": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, "p-cancelable": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz", - "integrity": "sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true + }, + "p-iteration": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/p-iteration/-/p-iteration-1.1.8.tgz", + "integrity": "sha512-IMFBSDIYcPNnW7uWYGrBqmvTiq7W0uB0fJn6shQZs7dlF3OvrHOre+JT9ikSZ7gZS3vWqclVgoQSvToJrns7uQ==", "dev": true }, "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "requires": { - "p-try": "^2.0.0" + "yocto-queue": "^0.1.0" } }, "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "requires": { - "p-limit": "^2.2.0" + "p-limit": "^3.0.2" } }, "p-try": { @@ -4872,27 +13844,27 @@ "callsites": "^3.0.0" } }, - "parse-entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", - "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", "dev": true, "requires": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" } }, "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { - "error-ex": "^1.2.0" + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" } }, "parse-ms": { @@ -4901,6 +13873,12 @@ "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", "dev": true }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -4920,22 +13898,32 @@ "dev": true }, "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "path-root-regex": "^0.1.0" } }, + "path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -4948,16 +13936,22 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, "pinkie": { @@ -4975,97 +13969,84 @@ "pinkie": "^2.0.0" } }, - "postcss": { - "version": "7.0.32", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz", - "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==", + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" + "find-up": "^4.0.0" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "p-locate": "^4.1.0" } }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { - "color-name": "1.1.3" + "p-try": "^2.0.0" } }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "p-limit": "^2.2.0" } } } }, - "postcss-html": { - "version": "0.36.0", - "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-0.36.0.tgz", - "integrity": "sha512-HeiOxGcuwID0AFsNAL0ox3mW6MHH5cstWN1Z3Y+n6H+g12ih7LHdYxWwEA/QmrebctLjo79xz9ouK3MroHwOJw==", + "pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true + }, + "postcss": { + "version": "8.4.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.13.tgz", + "integrity": "sha512-jtL6eTBrza5MPzy8oJLFuUscHDXTV5KcLlqAWHl5q5WYRfnNRGSmOZmOZ1T6Gy7A99mOZfqungmZMpMmCVJ8ZA==", "dev": true, "requires": { - "htmlparser2": "^3.10.0" + "nanoid": "^3.3.3", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "dependencies": { + "nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true + } } }, "postcss-less": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.4.tgz", - "integrity": "sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA==", - "dev": true, - "requires": { - "postcss": "^7.0.14" - } + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-6.0.0.tgz", + "integrity": "sha512-FPX16mQLyEjLzEuuJtxA8X3ejDLNGGEG503d2YGZR5Ask1SpDN8KmZUMpzCvyalWRywAn1n1VOA5dcqfCLo5rg==", + "dev": true }, "postcss-media-query-parser": { "version": "0.2.3", @@ -5073,79 +14054,6 @@ "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=", "dev": true }, - "postcss-reporter": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-6.0.1.tgz", - "integrity": "sha512-LpmQjfRWyabc+fRygxZjpRxfhRf9u/fdlKf4VHG4TSPbV2XNsuISzYW1KL+1aQzx53CAppa1bKG4APIB/DOXXw==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "lodash": "^4.17.11", - "log-symbols": "^2.2.0", - "postcss": "^7.0.7" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "requires": { - "chalk": "^2.0.1" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, "postcss-resolve-nested-selector": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", @@ -5153,54 +14061,25 @@ "dev": true }, "postcss-safe-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz", - "integrity": "sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g==", - "dev": true, - "requires": { - "postcss": "^7.0.26" - } - }, - "postcss-sass": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.4.4.tgz", - "integrity": "sha512-BYxnVYx4mQooOhr+zer0qWbSPYnarAy8ZT7hAQtbxtgVf8gy+LSLT/hHGe35h14/pZDTw1DsxdbrwxBN++H+fg==", - "dev": true, - "requires": { - "gonzales-pe": "^4.3.0", - "postcss": "^7.0.21" - } - }, - "postcss-scss": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.1.1.tgz", - "integrity": "sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA==", - "dev": true, - "requires": { - "postcss": "^7.0.6" - } + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", + "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", + "dev": true }, "postcss-selector-parser": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", - "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", "dev": true, "requires": { "cssesc": "^3.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" + "util-deprecate": "^1.0.2" } }, - "postcss-syntax": { - "version": "0.36.2", - "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz", - "integrity": "sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==", - "dev": true - }, "postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "dev": true }, "prelude-ls": { @@ -5209,43 +14088,58 @@ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, - "pretty-bytes": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-4.0.2.tgz", - "integrity": "sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk=", - "dev": true - }, "pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "requires": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + } } }, "pretty-ms": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.0.tgz", - "integrity": "sha512-J3aPWiC5e9ZeZFuSeBraGxSkGMOvulSWsxDByOcbD1Pr75YL3LSNIKIb52WXbCLE1sS5s4inBBbryjF4Y05Ceg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", + "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", "dev": true, "requires": { "parse-ms": "^2.1.0" } }, "prettyjson": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prettyjson/-/prettyjson-1.2.1.tgz", - "integrity": "sha1-/P+rQdGcq0365eV15kJGYZsS0ok=", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/prettyjson/-/prettyjson-1.2.5.tgz", + "integrity": "sha512-rksPWtoZb2ZpT5OVgtmy0KHVM+Dca3iVwWY9ifwhcexfjebtgjg3wmrUt9PvJ59XIYBcknQeYHD8IAnVlh9lAw==", "dev": true, "requires": { - "colors": "^1.1.2", + "colors": "1.4.0", "minimist": "^1.2.0" + }, + "dependencies": { + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true + } } }, + "printj": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/printj/-/printj-1.3.1.tgz", + "integrity": "sha512-GA3TdL8szPK4AQ2YnOe/b+Y1jUFwmmGMMK/qbY7VcE3Z7FU8JstbKiKRzO6CIiAKPhTO8m01NoQ0V5f3jc4OGg==", + "dev": true + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -5293,50 +14187,52 @@ "dev": true }, "puppeteer-core": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-3.3.0.tgz", - "integrity": "sha512-hynQ3r0J/lkGrKeBCqu160jrj0WhthYLIzDQPkBxLzxPokjw4elk1sn6mXAian/kfD2NRzpdh9FSykxZyL56uA==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "extract-zip": "^2.0.0", - "https-proxy-agent": "^4.0.0", - "mime": "^2.0.3", - "progress": "^2.0.1", - "proxy-from-env": "^1.0.0", - "rimraf": "^3.0.2", - "tar-fs": "^2.0.0", - "unbzip2-stream": "^1.3.3", - "ws": "^7.2.3" + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-13.4.0.tgz", + "integrity": "sha512-TcGT5Qgq9tgI0msFrIhq70N1+WrnGowjn0hc4vtzEIizJETXOZVrQZVWy051lO/nxEVGyqRXHwtpWjv4/fRbUw==", + "dev": true, + "requires": { + "cross-fetch": "3.1.5", + "debug": "4.3.3", + "devtools-protocol": "0.0.960912", + "extract-zip": "2.0.1", + "https-proxy-agent": "5.0.0", + "pkg-dir": "4.2.0", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "rimraf": "3.0.2", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "ws": "8.5.0" }, "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "devtools-protocol": { + "version": "0.0.960912", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.960912.tgz", + "integrity": "sha512-I3hWmV9rWHbdnUdmMKHF2NuYutIM2kXz2mdXW8ha7TbRlGTVs+PF+PsB5QWvpCek4Fy9B+msiispCfwlhG5Sqg==", "dev": true } } }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + }, + "query-selector-shadow-dom": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.0.tgz", + "integrity": "sha512-bK0/0cCI+R8ZmOF1QjT7HupDUYCxbf/9TJgAmSXQxZpftXmTAeil9DRoCnTDkWbvOyZzhcMBwKpptWcdkGFIMg==", "dev": true }, - "qs": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", - "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==", + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, "quick-lru": { @@ -5346,11 +14242,20 @@ "dev": true }, "ramda": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.0.tgz", - "integrity": "sha512-pVzZdDpWwWqEVVLshWUHjNwuVP7SfcmPraYuqocJp1yo2U1R7P+5QAfDhdItkuoGqIBnBYrtPp7rEPqDn9HlZA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.2.tgz", + "integrity": "sha512-SbiLPU40JuJniHexQSAgad32hfwd+DRUdwF2PlVuI5RZD0/vahUco7R8vD86J/tcEKKF9vZrUVwgtmGCqlCKyA==", "dev": true }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, "raw-body": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", @@ -5370,50 +14275,84 @@ } }, "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } } }, "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" }, "dependencies": { "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "pinkie-promise": "^2.0.0" + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true } } }, @@ -5428,124 +14367,68 @@ "util-deprecate": "^1.0.1" } }, - "readdirp": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", - "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "readdir-glob": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.1.tgz", + "integrity": "sha512-91/k1EzZwDx6HbERR+zucygRFfiPl2zkIYZtv3Jjr6Mn7SkKcVct8aVO+sSRiGMc6fLf72du3d92/uY63YPdEA==", "dev": true, "requires": { - "picomatch": "^2.2.1" + "minimatch": "^3.0.4" } }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" - }, - "dependencies": { - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - } + "picomatch": "^2.2.1" } }, - "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", - "dev": true - }, - "regextras": { + "rechoir": { "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.7.1.tgz", - "integrity": "sha512-9YXf6xtW+qzQ+hcMQXx95MOvfqXFgsKDZodX3qZB0x2n5Z94ioetIITsBtvJbiOyxa/6s9AtyweBLCdPmPko/w==", - "dev": true - }, - "remark": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/remark/-/remark-12.0.0.tgz", - "integrity": "sha512-oX4lMIS0csgk8AEbzY0h2jdR0ngiCHOpwwpxjmRa5TqAkeknY+tkhjRJGZqnCmvyuWh55/0SW5WY3R3nn3PH9A==", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", + "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", "dev": true, "requires": { - "remark-parse": "^8.0.0", - "remark-stringify": "^8.0.0", - "unified": "^9.0.0" + "resolve": "^1.9.0" } }, - "remark-parse": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-8.0.2.tgz", - "integrity": "sha512-eMI6kMRjsAGpMXXBAywJwiwAse+KNpmt+BK55Oofy4KvBZEqUDj6mWbGLJZrujoPIPPxDXzn3T9baRlpsm2jnQ==", + "recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", "dev": true, "requires": { - "ccount": "^1.0.0", - "collapse-white-space": "^1.0.2", - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "is-word-character": "^1.0.0", - "markdown-escapes": "^1.0.0", - "parse-entities": "^2.0.0", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "trim": "0.0.1", - "trim-trailing-lines": "^1.0.0", - "unherit": "^1.0.4", - "unist-util-remove-position": "^2.0.0", - "vfile-location": "^3.0.0", - "xtend": "^4.0.1" + "minimatch": "^3.0.5" } }, - "remark-stringify": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-8.1.0.tgz", - "integrity": "sha512-FSPZv1ds76oAZjurhhuV5qXSUSoz6QRPuwYK38S41sLHwg4oB7ejnmZshj7qwjgYLf93kdz6BOX9j5aidNE7rA==", + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, "requires": { - "ccount": "^1.0.0", - "is-alphanumeric": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "longest-streak": "^2.0.1", - "markdown-escapes": "^1.0.0", - "markdown-table": "^2.0.0", - "mdast-util-compact": "^2.0.0", - "parse-entities": "^2.0.0", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "stringify-entities": "^3.0.0", - "unherit": "^1.0.4", - "xtend": "^4.0.1" + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" } }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "regexp-tree": { + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz", + "integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==", "dev": true }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true }, - "replace-ext": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "regextras": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.8.0.tgz", + "integrity": "sha512-k519uI04Z3SaY0fLX843MRXnDeG2+vHOFsyhiPZvNLe7r8rD2YNRjq4BQLZZ0oAr2NrtvZlICsXysGNFPGa3CQ==", "dev": true }, "request": { @@ -5577,15 +14460,9 @@ }, "dependencies": { "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", "dev": true } } @@ -5596,27 +14473,80 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", "dev": true }, "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", "dev": true, "requires": { - "path-parse": "^1.0.6" + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" } }, "resolve-alpn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.0.0.tgz", - "integrity": "sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", "dev": true }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "dependencies": { + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -5633,12 +14563,20 @@ } }, "resq": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/resq/-/resq-1.7.1.tgz", - "integrity": "sha512-09u9Q5SAuJfAW5UoVAmvRtLvCOMaKP+djiixTXsZvPaojGKhuvc0Nfvp84U1rIfopJWEOXi5ywpCFwCk7mj8Xw==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/resq/-/resq-1.10.2.tgz", + "integrity": "sha512-HmgVS3j+FLrEDBTDYysPdPVF9/hioDMJ/otOiQDKqk77YfZeeLOj0qi34yObumcud1gBpk+wpBTEg4kMicD++A==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1" + }, + "dependencies": { + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + } } }, "restore-cursor": { @@ -5658,9 +14596,9 @@ "dev": true }, "rgb2hex": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.2.0.tgz", - "integrity": "sha512-cHdNTwmTMPu/TpP1bJfdApd6MbD+Kzi4GNnM6h35mdFChhQPSi9cAI8J7DMn5kQDKX8NuBaQXAyo360Oa7tOEA==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.2.5.tgz", + "integrity": "sha512-22MOP1Rh7sAo1BZpDG6R5RFYzR2lYEgwq7HEmyW2qcsOqR2lQKmn+O//xV3YG/0rrhMC6KVX2hU+ZXuaw9a5bw==", "dev": true }, "rimraf": { @@ -5679,18 +14617,21 @@ "dev": true }, "run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", - "dev": true + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } }, "rxjs": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", - "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.4.tgz", + "integrity": "sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ==", "dev": true, "requires": { - "tslib": "^1.9.0" + "tslib": "^2.1.0" } }, "safe-buffer": { @@ -5705,18 +14646,21 @@ "integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=", "dev": true }, + "safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "dev": true, + "requires": { + "regexp-tree": "~0.1.1" + } + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true - }, "semlog": { "version": "0.6.10", "resolved": "https://registry.npmjs.org/semlog/-/semlog-0.6.10.tgz", @@ -5752,6 +14696,12 @@ "supports-color": "^2.0.0" } }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -5770,39 +14720,31 @@ } }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz", + "integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==", "dev": true, "requires": { - "type-fest": "^0.13.1" - }, - "dependencies": { - "type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true - } + "type-fest": "^0.20.2" } }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true + "serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } }, "shebang-command": { "version": "2.0.0", @@ -5819,10 +14761,21 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, "slash": { @@ -5843,9 +14796,15 @@ } }, "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", "dev": true }, "spdx-correct": { @@ -5875,9 +14834,9 @@ } }, "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", + "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", "dev": true }, "specificity": { @@ -5886,6 +14845,12 @@ "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==", "dev": true }, + "split2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz", + "integrity": "sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==", + "dev": true + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -5893,9 +14858,9 @@ "dev": true }, "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", "dev": true, "requires": { "asn1": "~0.2.3", @@ -5916,16 +14881,21 @@ "dev": true }, "stack-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", - "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", - "dev": true - }, - "state-toggle": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", - "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", - "dev": true + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + } + } }, "stream-buffers": { "version": "3.0.2", @@ -5933,6 +14903,23 @@ "integrity": "sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ==", "dev": true }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, "string-template": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", @@ -5940,65 +14927,23 @@ "dev": true }, "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "stringify-entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-3.0.1.tgz", - "integrity": "sha512-Lsk3ISA2++eJYqBMPKcr/8eby1I6L0gP0NlxF8Zja6c05yr/yCYyb2c9PwXjd08Ib3If1vn1rbs1H5ZtVuOfvQ==", - "dev": true, - "requires": { - "character-entities-html4": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.2", - "is-hexadecimal": "^1.0.0" + "strip-ansi": "^6.0.1" } }, "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^5.0.0" + "ansi-regex": "^5.0.1" } }, "strip-bom": { @@ -6011,18 +14956,18 @@ } }, "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, "requires": { - "get-stdin": "^4.0.1" + "min-indent": "^1.0.0" } }, "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, "style-search": { @@ -6032,233 +14977,111 @@ "dev": true }, "stylelint": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.3.2.tgz", - "integrity": "sha512-kpO3/Gz2ZY40EWUwFYYkgpzhf8ZDUyKpcui5+pS0XKJBj/EMYmZpOJoL8IFAz2yApYeg91NVy5yAjE39hDzWvQ==", + "version": "14.8.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.8.1.tgz", + "integrity": "sha512-0YxTop3wTeEVmQWhS7jjLFaBkvfPmffRiJ6eFIDlK++f3OklaobTYFJu32E5u/cIrFLbcW52pLqrYpihA/y0/w==", "dev": true, "requires": { - "@stylelint/postcss-css-in-js": "^0.37.1", - "@stylelint/postcss-markdown": "^0.36.1", - "autoprefixer": "^9.7.6", - "balanced-match": "^1.0.0", - "chalk": "^4.0.0", - "cosmiconfig": "^6.0.0", - "debug": "^4.1.1", + "balanced-match": "^2.0.0", + "colord": "^2.9.2", + "cosmiconfig": "^7.0.1", + "css-functions-list": "^3.0.1", + "debug": "^4.3.4", "execall": "^2.0.0", - "file-entry-cache": "^5.0.1", - "get-stdin": "^7.0.0", + "fast-glob": "^3.2.11", + "fastest-levenshtein": "^1.0.12", + "file-entry-cache": "^6.0.1", + "get-stdin": "^8.0.0", "global-modules": "^2.0.0", - "globby": "^11.0.0", + "globby": "^11.1.0", "globjoin": "^0.1.4", - "html-tags": "^3.1.0", - "ignore": "^5.1.4", + "html-tags": "^3.2.0", + "ignore": "^5.2.0", "import-lazy": "^4.0.0", "imurmurhash": "^0.1.4", - "known-css-properties": "^0.18.0", - "leven": "^3.1.0", - "lodash": "^4.17.15", - "log-symbols": "^3.0.0", + "is-plain-object": "^5.0.0", + "known-css-properties": "^0.24.0", "mathml-tag-names": "^2.1.3", - "meow": "^6.1.0", - "micromatch": "^4.0.2", + "meow": "^9.0.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", "normalize-selector": "^0.2.0", - "postcss": "^7.0.27", - "postcss-html": "^0.36.0", - "postcss-less": "^3.1.4", + "picocolors": "^1.0.0", + "postcss": "^8.4.12", "postcss-media-query-parser": "^0.2.3", - "postcss-reporter": "^6.0.1", "postcss-resolve-nested-selector": "^0.1.1", - "postcss-safe-parser": "^4.0.2", - "postcss-sass": "^0.4.4", - "postcss-scss": "^2.0.0", - "postcss-selector-parser": "^6.0.2", - "postcss-syntax": "^0.36.2", - "postcss-value-parser": "^4.0.3", + "postcss-safe-parser": "^6.0.0", + "postcss-selector-parser": "^6.0.10", + "postcss-value-parser": "^4.2.0", "resolve-from": "^5.0.0", - "slash": "^3.0.0", "specificity": "^0.4.1", - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", "style-search": "^0.1.0", - "sugarss": "^2.0.0", + "supports-hyperlinks": "^2.2.0", "svg-tags": "^1.0.0", - "table": "^5.4.6", - "v8-compile-cache": "^2.1.0", - "write-file-atomic": "^3.0.3" + "table": "^6.8.0", + "v8-compile-cache": "^2.3.0", + "write-file-atomic": "^4.0.1" }, "dependencies": { - "camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "get-stdin": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", - "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==", - "dev": true - }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "map-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", - "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==", + "balanced-match": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", + "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", "dev": true }, - "meow": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-6.1.1.tgz", - "integrity": "sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==", + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "^4.0.2", - "normalize-package-data": "^2.5.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.13.1", - "yargs-parser": "^18.1.3" + "ms": "2.1.2" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "parse-json": { + "is-plain-object": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", - "lines-and-columns": "^1.1.6" - } - }, - "quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "dependencies": { - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - } - } - }, - "redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dev": true, - "requires": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - } - }, "resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true - }, - "strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "requires": { - "min-indent": "^1.0.0" - } - }, - "trim-newlines": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", - "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==", - "dev": true - }, - "type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true } } }, + "stylelint-config-recommended": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-7.0.0.tgz", + "integrity": "sha512-yGn84Bf/q41J4luis1AZ95gj0EQwRX8lWmGmBwkwBNSkpGSpl66XcPTulxGa/Z91aPoNGuIGBmFkcM1MejMo9Q==", + "dev": true + }, "stylelint-config-wikimedia": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/stylelint-config-wikimedia/-/stylelint-config-wikimedia-0.10.1.tgz", - "integrity": "sha512-R/E7xVKwDyneKmVwkNi+TqJlXZjnL5IH+bQPmfHrgwwyAekNx5GdYZ+tVjx7VBXdv/pjOr0HevVpXSQe86ZfVQ==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/stylelint-config-wikimedia/-/stylelint-config-wikimedia-0.13.0.tgz", + "integrity": "sha512-1R1g/uc53z2z39ejZMALwC6fTfSZhkzDjj1v8ODCWtLCiuqWuSf3HR1ZTXT5X5AtSbZq1W9+0p5HJp6rPVXkRg==", + "dev": true, + "requires": { + "browserslist-config-wikimedia": "0.4.0", + "postcss-less": "6.0.0", + "stylelint": "14.8.1", + "stylelint-config-recommended": "7.0.0", + "stylelint-no-unsupported-browser-features": "5.0.3" + } + }, + "stylelint-no-unsupported-browser-features": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/stylelint-no-unsupported-browser-features/-/stylelint-no-unsupported-browser-features-5.0.3.tgz", + "integrity": "sha512-FqfbOTk5UEkHsAKOkPH6SvajsfO9YuoWvKxd34tCRBZug9ZNeaPn141nyWkd+ncc8S1gVmO2+O6qVAMj9bvWww==", "dev": true, "requires": { - "stylelint": "13.3.2" + "doiuse": "^4.4.1", + "lodash": "^4.17.15", + "postcss": "^8.3.6" } }, "suffix": { @@ -6267,24 +15090,42 @@ "integrity": "sha1-zFgjFkag7xEC95R47zqSSP2chC8=", "dev": true }, - "sugarss": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-2.0.0.tgz", - "integrity": "sha512-WfxjozUk0UVA4jm+U1d736AUpzSrNsQcIbyOkoE364GrtWmIrFdk5lksEupgWMD4VaT/0kVx1dobpiDumSgmJQ==", + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { - "postcss": "^7.0.2" + "has-flag": "^4.0.0" } }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, "svg-tags": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", @@ -6292,190 +15133,72 @@ "dev": true }, "svgo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", - "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", + "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", "dev": true, "requires": { - "chalk": "^2.4.1", - "coa": "^2.0.2", - "css-select": "^2.0.0", - "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.37", - "csso": "^4.0.2", - "js-yaml": "^3.13.1", - "mkdirp": "~0.5.1", - "object.values": "^1.1.0", - "sax": "~1.2.4", - "stable": "^0.1.8", - "unquote": "~1.1.1", - "util.promisify": "~1.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "picocolors": "^1.0.0", + "stable": "^0.1.8" } }, "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", + "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", "dev": true, "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "ajv": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz", + "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" } }, - "astral-regex": { + "json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - } - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } } } }, "tar-fs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.0.tgz", - "integrity": "sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", "dev": true, "requires": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", - "tar-stream": "^2.0.0" + "tar-stream": "^2.1.4" } }, "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "dev": true, "requires": { - "bl": "^4.0.1", + "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", @@ -6494,6 +15217,15 @@ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "requires": { + "readable-stream": "3" + } + }, "tiny-lr": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", @@ -6509,19 +15241,13 @@ }, "dependencies": { "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { "ms": "^2.1.1" } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true } } }, @@ -6534,12 +15260,6 @@ "os-tmpdir": "~1.0.2" } }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -6559,34 +15279,22 @@ "punycode": "^2.1.1" } }, - "trim": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", "dev": true }, "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "dev": true - }, - "trim-trailing-lines": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.3.tgz", - "integrity": "sha512-4ku0mmjXifQcTVfYDfR5lpgV7zVqPg6zV9rdZmwOPqq0+Zq19xDqEgagqVbc4pOOShbncuAOIs59R3+3gcF3ZA==", - "dev": true - }, - "trough": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", - "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true }, "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", "dev": true }, "tunnel-agent": { @@ -6614,24 +15322,15 @@ } }, "type-fest": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, "ua-parser-js": { - "version": "0.7.21", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz", - "integrity": "sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.2.tgz", + "integrity": "sha512-00y/AXhx0/SsnI51fTc0rLRmafiGOM4/O+ny10Ps7f+j/b8p/ZY11ytMgznXkOVo4GQ+KwQG5UQLkLGirsACRg==", "dev": true }, "unbzip2-stream": { @@ -6644,122 +15343,46 @@ "through": "^2.3.8" } }, - "underscore.string": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz", - "integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==", - "dev": true, - "requires": { - "sprintf-js": "^1.0.3", - "util-deprecate": "^1.0.2" - } - }, - "unherit": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", - "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", - "dev": true, - "requires": { - "inherits": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "unified": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/unified/-/unified-9.0.0.tgz", - "integrity": "sha512-ssFo33gljU3PdlWLjNp15Inqb77d6JnJSfyplGJPT/a+fNRNyCBeveBAYJdO5khKdF6WVHa/yYCC7Xl6BDwZUQ==", - "dev": true, - "requires": { - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-buffer": "^2.0.0", - "is-plain-obj": "^2.0.0", - "trough": "^1.0.0", - "vfile": "^4.0.0" - } - }, - "uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", - "dev": true - }, - "unist-util-find-all-after": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-3.0.1.tgz", - "integrity": "sha512-0GICgc++sRJesLwEYDjFVJPJttBpVQaTNgc6Jw0Jhzvfs+jtKePEMu+uD+PqkRUrAvGQqwhpDwLGWo1PK8PDEw==", - "dev": true, - "requires": { - "unist-util-is": "^4.0.0" - } - }, - "unist-util-is": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", - "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==", + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", "dev": true }, - "unist-util-remove-position": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz", - "integrity": "sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA==", - "dev": true, - "requires": { - "unist-util-visit": "^2.0.0" - } - }, - "unist-util-stringify-position": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", - "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", - "dev": true, - "requires": { - "@types/unist": "^2.0.2" - } - }, - "unist-util-visit": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", - "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", - "dev": true, - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0", - "unist-util-visit-parents": "^3.0.0" - } - }, - "unist-util-visit-parents": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", - "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "underscore.string": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz", + "integrity": "sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==", "dev": true, "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0" + "sprintf-js": "^1.1.1", + "util-deprecate": "^1.0.2" + }, + "dependencies": { + "sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "dev": true + } } }, "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", - "dev": true - }, - "unquote": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "dev": true }, "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz", + "integrity": "sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==", "dev": true }, "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "requires": { "punycode": "^2.1.0" @@ -6771,30 +15394,27 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, - "util.promisify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", - "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.2", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.0" - } - }, "uuid": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.2.0.tgz", - "integrity": "sha512-CYpGiFTUrmI6OBMkAdjSDM0k5h8SkkiTP4WAjQgDgNB1S3Ou9VBEvr6q0Kv2H1mMk7IWfxYGpMH5sd5AvcIV2Q==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true }, "v8-compile-cache": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", - "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, + "v8flags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", + "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -6805,6 +15425,12 @@ "spdx-expression-parse": "^3.0.0" } }, + "validator": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", + "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==", + "dev": true + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -6816,110 +15442,41 @@ "extsprintf": "^1.2.0" } }, - "vfile": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.1.1.tgz", - "integrity": "sha512-lRjkpyDGjVlBA7cDQhQ+gNcvB1BGaTHYuSOcY3S7OhDmBtnzX95FhtZZDecSTDm6aajFymyve6S5DN4ZHGezdQ==", - "dev": true, - "requires": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "replace-ext": "1.0.0", - "unist-util-stringify-position": "^2.0.0", - "vfile-message": "^2.0.0" - } - }, - "vfile-location": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.0.1.tgz", - "integrity": "sha512-yYBO06eeN/Ki6Kh1QAkgzYpWT1d3Qln+ZCtSbJqFExPl1S3y2qqotJQXoh6qEvl/jDlgpUJolBn3PItVnnZRqQ==", - "dev": true - }, - "vfile-message": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", - "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", - "dev": true, - "requires": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "dev": true, - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==", - "dev": true - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==", - "dev": true - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==", - "dev": true - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==", - "dev": true - }, "vue-eslint-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.1.0.tgz", - "integrity": "sha512-Kr21uPfthDc63nDl27AGQEhtt9VrZ9nkYk/NTftJ2ws9XiJwzJJCnCr3AITQ2jpRMA0XPGDECxYH8E027qMK9Q==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "eslint-scope": "^5.0.0", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.2.1", - "esquery": "^1.0.1", - "lodash": "^4.17.15" + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz", + "integrity": "sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g==", + "dev": true, + "requires": { + "debug": "^4.3.2", + "eslint-scope": "^7.0.0", + "eslint-visitor-keys": "^3.1.0", + "espree": "^9.0.0", + "esquery": "^1.4.0", + "lodash": "^4.17.21", + "semver": "^7.3.5" }, "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, "requires": { - "ms": "^2.1.1" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" } }, - "espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", - "dev": true, - "requires": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" - } + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } @@ -6929,58 +15486,78 @@ "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", "dev": true, - "optional": true, "requires": { "defaults": "^1.0.3" } }, "wdio-mediawiki": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wdio-mediawiki/-/wdio-mediawiki-1.0.0.tgz", - "integrity": "sha512-eKrPx3MHTQvWaI+YUi6pLmebOdsdBegnx5MJx8m9ejh6US7TIKKzLmsh9p9gfj6PW7HzHNN/e8EkDwKo3M0kJg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wdio-mediawiki/-/wdio-mediawiki-2.1.0.tgz", + "integrity": "sha512-gbC05sQR8lWgYUfl4Zeghl2Axa7b0IFv/FAWMmqDPEK/SRMEUXc5I9J6/Iowa8Bo5sRc7pGuQi4p34fLbivl8g==", "dev": true, "requires": { - "mwbot": "1.0.10" + "mwbot": "2.0.0" } }, "webdriver": { - "version": "6.1.14", - "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-6.1.14.tgz", - "integrity": "sha512-6fXoGDnxWfJn9zqfYbc6+VEV5N1obd3K7iuRmJ7w/hH9d9XDxcrcx147T5egiy1qziko61hqYE/x9VtSQbjPcA==", + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-7.16.13.tgz", + "integrity": "sha512-Vfr952W1uIgDeWHPGzqH43dYLeRSZshh3TzA9ICUkvnC+Q7YziQdv/8xI8tuuyvb7lSr3VsuB2cGzyCRoC/NWw==", "dev": true, "requires": { - "@wdio/config": "6.1.14", - "@wdio/logger": "6.0.16", - "@wdio/protocols": "6.1.14", - "@wdio/utils": "6.1.8", + "@types/node": "^17.0.4", + "@wdio/config": "7.16.13", + "@wdio/logger": "7.16.0", + "@wdio/protocols": "7.16.7", + "@wdio/types": "7.16.13", + "@wdio/utils": "7.16.13", "got": "^11.0.2", + "ky": "^0.28.5", "lodash.merge": "^4.6.1" } }, "webdriverio": { - "version": "6.1.16", - "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-6.1.16.tgz", - "integrity": "sha512-vk6/XeErNnMooebCtxwIR//LqrastXO9gXL+eVUGNRAuG5omp8XCdT+MK2fmlw53xhcPULQ/y3h8ysYlPnPeyA==", - "dev": true, - "requires": { - "@wdio/config": "6.1.14", - "@wdio/logger": "6.0.16", - "@wdio/repl": "6.1.8", - "@wdio/utils": "6.1.8", - "archiver": "^4.0.1", + "version": "7.16.13", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-7.16.13.tgz", + "integrity": "sha512-jl1VRZYL1+cPeG6klskKX7mCEBWNQWDFaNtaIl5pwWgtKWPau6fCzKntSARzfNV8+hKJKwJ2mZn5Nsxfw28Oeg==", + "dev": true, + "requires": { + "@types/aria-query": "^5.0.0", + "@types/node": "^17.0.4", + "@wdio/config": "7.16.13", + "@wdio/logger": "7.16.0", + "@wdio/protocols": "7.16.7", + "@wdio/repl": "7.16.13", + "@wdio/types": "7.16.13", + "@wdio/utils": "7.16.13", + "archiver": "^5.0.0", + "aria-query": "^5.0.0", + "css-shorthand-properties": "^1.1.1", "css-value": "^0.0.1", - "devtools": "6.1.16", + "devtools": "7.16.13", + "devtools-protocol": "^0.0.953906", + "fs-extra": "^10.0.0", + "get-port": "^5.1.1", "grapheme-splitter": "^1.0.2", "lodash.clonedeep": "^4.5.0", "lodash.isobject": "^3.0.2", "lodash.isplainobject": "^4.0.6", "lodash.zip": "^4.2.0", - "resq": "^1.6.0", - "rgb2hex": "^0.2.0", - "serialize-error": "^7.0.0", - "webdriver": "6.1.14" + "minimatch": "^3.0.4", + "puppeteer-core": "^13.0.0", + "query-selector-shadow-dom": "^1.0.0", + "resq": "^1.9.1", + "rgb2hex": "0.2.5", + "serialize-error": "^8.0.0", + "webdriver": "7.16.13" } }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "dev": true + }, "websocket-driver": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", @@ -6998,61 +15575,23 @@ "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", "dev": true }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", "dev": true, "requires": { - "isexe": "^2.0.0" + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } + "isexe": "^2.0.0" } }, "word-wrap": { @@ -7061,10 +15600,16 @@ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, - "wrap-ansi": { + "workerpool": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -7078,31 +15623,26 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz", + "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==", "dev": true, "requires": { "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" + "signal-exit": "^3.0.7" } }, "ws": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz", - "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==", + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "dev": true + }, + "xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", "dev": true }, "xtend": { @@ -7112,208 +15652,100 @@ "dev": true }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "yaml": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", - "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true }, - "yargs": { - "version": "15.3.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", - "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", + "yaml-eslint-parser": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-0.5.0.tgz", + "integrity": "sha512-nJeyLA3YHAzhBTZbRAbu3W6xrSCucyxExmA+ZDtEdUFpGllxAZpto2Zxo2IG0r0eiuEiBM4e+wiAdxTziTq94g==", "dev": true, "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.1" + "eslint-visitor-keys": "^3.0.0", + "lodash": "^4.17.21", + "yaml": "^1.10.2" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true + } } }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "yargs": { + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz", + "integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==", "dev": true, "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" + }, + "dependencies": { + "yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA==", + "dev": true + } } }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true + }, "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } } } }, @@ -7353,6 +15785,32 @@ "supports-color": "^2.0.0" } }, + "cross-spawn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -7367,6 +15825,21 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true } } }, @@ -7380,14 +15853,20 @@ "fd-slicer": "~1.1.0" } }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + }, "zip-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-3.0.1.tgz", - "integrity": "sha512-r+JdDipt93ttDjsOVPU5zaq5bAyY+3H19bDrThkvuVxC0xMQzU1PJcS6D+KrP3u96gH9XLomcHPb+2skoDjulQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz", + "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==", "dev": true, "requires": { "archiver-utils": "^2.1.0", - "compress-commons": "^3.0.0", + "compress-commons": "^4.1.0", "readable-stream": "^3.6.0" } } diff --git a/Echo/package.json b/Echo/package.json index 6b05ca57..137b946c 100644 --- a/Echo/package.json +++ b/Echo/package.json @@ -6,24 +6,25 @@ "scripts": { "test": "grunt test", "doc": "jsduck", + "minify-svg": "svgo --config=.svgo.config.js --quiet --recursive --folder modules/icons/", "selenium-test": "wdio tests/selenium/wdio.conf.js", "selenium-daily": "npm run selenium-test -- --mochaOpts.grep @daily" }, "devDependencies": { - "@wdio/cli": "6.1.16", - "@wdio/local-runner": "6.1.16", - "@wdio/mocha-framework": "6.1.14", - "@wdio/spec-reporter": "6.1.14", - "@wdio/sync": "6.1.14", - "eslint-config-wikimedia": "0.16.1", - "grunt": "1.1.0", - "grunt-banana-checker": "0.9.0", + "@wdio/cli": "7.16.13", + "@wdio/junit-reporter": "7.16.13", + "@wdio/local-runner": "7.16.13", + "@wdio/mocha-framework": "7.16.13", + "@wdio/spec-reporter": "7.16.13", + "eslint-config-wikimedia": "0.22.1", + "grunt": "1.5.3", + "grunt-banana-checker": "0.10.0", "grunt-contrib-watch": "1.1.0", - "grunt-eslint": "23.0.0", - "grunt-stylelint": "0.15.0", - "grunt-svgmin": "5.0.0", - "stylelint-config-wikimedia": "0.10.1", - "wdio-mediawiki": "1.0.0", - "webdriverio": "6.1.16" + "grunt-eslint": "24.0.0", + "grunt-stylelint": "0.18.0", + "stylelint-config-wikimedia": "0.13.0", + "svgo": "2.8.0", + "wdio-mediawiki": "2.1.0", + "webdriverio": "7.16.13" } } diff --git a/Echo/scripts/gen-autoload.php b/Echo/scripts/gen-autoload.php index 97a726b8..f898fc07 100644 --- a/Echo/scripts/gen-autoload.php +++ b/Echo/scripts/gen-autoload.php @@ -42,5 +42,5 @@ class GenerateEchoAutoload extends Maintenance { } } -$maintClass = "GenerateEchoAutoload"; +$maintClass = GenerateEchoAutoload::class; require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/Echo/db_patches/echo_push_provider.sql b/Echo/sql/echo_push_provider.sql index 2e9f27b1..fd617a85 100644 --- a/Echo/db_patches/echo_push_provider.sql +++ b/Echo/sql/echo_push_provider.sql @@ -1,6 +1,6 @@ -- Table for normalizing push providers; intended for use with the NameTableStore construct. CREATE TABLE /*_*/echo_push_provider ( - epp_id TINYINT UNSIGNED NOT NULL PRIMARY KEY, + epp_id TINYINT UNSIGNED NOT NULL PRIMARY KEY auto_increment, -- push provider name; expected values are 'fcm' and 'apns' - epp_name TINYTEXT NOT NULL + epp_name TINYBLOB NOT NULL ) /*$wgDBTableOptions*/; diff --git a/Echo/db_patches/echo_push_subscription.sql b/Echo/sql/echo_push_subscription.sql index 94cab89e..2e42f049 100644 --- a/Echo/db_patches/echo_push_subscription.sql +++ b/Echo/sql/echo_push_subscription.sql @@ -4,17 +4,22 @@ CREATE TABLE /*_*/echo_push_subscription ( -- central user ID eps_user INT UNSIGNED NOT NULL, -- platform-provided push subscription token - eps_token TEXT NOT NULL, + eps_token BLOB NOT NULL, -- SHA256 digest of the push subscription token (to be used as a uniqueness constraint, since -- the tokens themselves may be large) - eps_token_sha256 CHAR(64) NOT NULL UNIQUE, + eps_token_sha256 CHAR(64) NOT NULL, -- push provider ID, expected to reference values 'fcm' or 'apns' eps_provider TINYINT UNSIGNED NOT NULL, -- last updated timestamp eps_updated TIMESTAMP NOT NULL, -- push subscription metadata (e.g APNS notification topic) eps_data BLOB, - FOREIGN KEY (eps_provider) REFERENCES /*_*/echo_push_provider(epp_id) + -- APNS topic ID, references a row ID (ept_id) from echo_push_topic + eps_topic TINYINT UNSIGNED ) /*$wgDBTableOptions*/; -CREATE INDEX /*i*/echo_push_subscription_user_id ON /*_*/echo_push_subscription (eps_user); +CREATE UNIQUE INDEX /*i*/eps_token_sha256 ON /*_*/echo_push_subscription (eps_token_sha256); +CREATE INDEX /*i*/eps_provider ON /*_*/echo_push_subscription (eps_provider); +CREATE INDEX /*i*/eps_topic ON /*_*/echo_push_subscription (eps_topic); +CREATE INDEX /*i*/eps_user ON /*_*/echo_push_subscription (eps_user); +CREATE INDEX /*i*/eps_token ON /*_*/echo_push_subscription (eps_token(10)); diff --git a/Echo/sql/echo_push_topic.sql b/Echo/sql/echo_push_topic.sql new file mode 100644 index 00000000..88d542a9 --- /dev/null +++ b/Echo/sql/echo_push_topic.sql @@ -0,0 +1,6 @@ +-- Table for normalizing APNS push message topics, for use with the NameTableStore construct. +CREATE TABLE /*_*/echo_push_topic ( + ept_id TINYINT UNSIGNED NOT NULL PRIMARY KEY auto_increment, + -- full topic text + ept_text TINYBLOB NOT NULL +) /*$wgDBTableOptions*/; diff --git a/Echo/sql/mysql/patch-cleanup-push_subscription-foreign-keys-indexes.sql b/Echo/sql/mysql/patch-cleanup-push_subscription-foreign-keys-indexes.sql new file mode 100644 index 00000000..d6fa63fb --- /dev/null +++ b/Echo/sql/mysql/patch-cleanup-push_subscription-foreign-keys-indexes.sql @@ -0,0 +1,10 @@ +-- Drop foreign keys from echo_push_subscription - T306473 +ALTER TABLE /*_*/echo_push_subscription DROP FOREIGN KEY /*_*/echo_push_subscription_ibfk_1; +ALTER TABLE /*_*/echo_push_subscription DROP FOREIGN KEY /*_*/echo_push_subscription_ibfk_2; + +-- Rename index to match table prefix +DROP INDEX /*i*/echo_push_subscription_user_id ON /*_*/echo_push_subscription; +CREATE INDEX /*i*/eps_user ON /*_*/echo_push_subscription (eps_user); + +DROP INDEX /*i*/echo_push_subscription_token ON /*_*/echo_push_subscription; +CREATE INDEX /*i*/eps_token ON /*_*/echo_push_subscription (eps_token(10)); diff --git a/Echo/db_patches/patch-drop-notification_bundle_base.sql b/Echo/sql/mysql/patch-drop-notification_bundle_base.sql index 0da891c3..0da891c3 100644 --- a/Echo/db_patches/patch-drop-notification_bundle_base.sql +++ b/Echo/sql/mysql/patch-drop-notification_bundle_base.sql diff --git a/Echo/db_patches/patch-drop-notification_bundle_display_hash.sql b/Echo/sql/mysql/patch-drop-notification_bundle_display_hash.sql index 7cbf8aa4..7cbf8aa4 100644 --- a/Echo/db_patches/patch-drop-notification_bundle_display_hash.sql +++ b/Echo/sql/mysql/patch-drop-notification_bundle_display_hash.sql diff --git a/Echo/db_patches/patch-increase-varchar-echo_unread_wikis-euw_wiki.sql b/Echo/sql/mysql/patch-increase-varchar-echo_unread_wikis-euw_wiki.sql index 7bcd037b..7bcd037b 100644 --- a/Echo/db_patches/patch-increase-varchar-echo_unread_wikis-euw_wiki.sql +++ b/Echo/sql/mysql/patch-increase-varchar-echo_unread_wikis-euw_wiki.sql diff --git a/Echo/sql/mysql/tables-generated.sql b/Echo/sql/mysql/tables-generated.sql new file mode 100644 index 00000000..abf948dc --- /dev/null +++ b/Echo/sql/mysql/tables-generated.sql @@ -0,0 +1,94 @@ +-- This file is automatically generated using maintenance/generateSchemaSql.php. +-- Source: sql/tables.json +-- Do not modify this file directly. +-- See https://www.mediawiki.org/wiki/Manual:Schema_changes +CREATE TABLE /*_*/echo_event ( + event_id INT UNSIGNED AUTO_INCREMENT NOT NULL, + event_type VARBINARY(64) NOT NULL, + event_variant VARBINARY(64) DEFAULT NULL, + event_agent_id INT UNSIGNED DEFAULT NULL, + event_agent_ip VARBINARY(39) DEFAULT NULL, + event_extra BLOB DEFAULT NULL, + event_page_id INT UNSIGNED DEFAULT NULL, + event_deleted TINYINT UNSIGNED DEFAULT 0 NOT NULL, + INDEX echo_event_type (event_type), + INDEX echo_event_page_id (event_page_id), + PRIMARY KEY(event_id) +) /*$wgDBTableOptions*/; + + +CREATE TABLE /*_*/echo_notification ( + notification_event INT UNSIGNED NOT NULL, + notification_user INT UNSIGNED NOT NULL, + notification_timestamp BINARY(14) NOT NULL, + notification_read_timestamp BINARY(14) DEFAULT NULL, + notification_bundle_hash VARBINARY(32) NOT NULL, + INDEX echo_user_timestamp ( + notification_user, notification_timestamp + ), + INDEX echo_notification_event (notification_event), + INDEX echo_notification_user_read_timestamp ( + notification_user, notification_read_timestamp + ), + PRIMARY KEY( + notification_user, notification_event + ) +) /*$wgDBTableOptions*/; + + +CREATE TABLE /*_*/echo_email_batch ( + eeb_id INT UNSIGNED AUTO_INCREMENT NOT NULL, + eeb_user_id INT UNSIGNED NOT NULL, + eeb_event_priority TINYINT UNSIGNED DEFAULT 10 NOT NULL, + eeb_event_id INT UNSIGNED NOT NULL, + eeb_event_hash VARBINARY(32) NOT NULL, + UNIQUE INDEX echo_email_batch_user_event (eeb_user_id, eeb_event_id), + INDEX echo_email_batch_user_hash_priority ( + eeb_user_id, eeb_event_hash, eeb_event_priority + ), + PRIMARY KEY(eeb_id) +) /*$wgDBTableOptions*/; + + +CREATE TABLE /*_*/echo_target_page ( + etp_id INT UNSIGNED AUTO_INCREMENT NOT NULL, + etp_page INT UNSIGNED DEFAULT 0 NOT NULL, + etp_event INT UNSIGNED DEFAULT 0 NOT NULL, + INDEX echo_target_page_event (etp_event), + INDEX echo_target_page_page_event (etp_page, etp_event), + PRIMARY KEY(etp_id) +) /*$wgDBTableOptions*/; + + +CREATE TABLE /*_*/echo_push_provider ( + epp_id TINYINT UNSIGNED AUTO_INCREMENT NOT NULL, + epp_name TINYBLOB NOT NULL, + PRIMARY KEY(epp_id) +) /*$wgDBTableOptions*/; + + +CREATE TABLE /*_*/echo_push_subscription ( + eps_id INT UNSIGNED AUTO_INCREMENT NOT NULL, + eps_user INT UNSIGNED NOT NULL, + eps_token BLOB NOT NULL, + eps_token_sha256 CHAR(64) NOT NULL, + eps_provider TINYINT UNSIGNED NOT NULL, + eps_updated TIMESTAMP NOT NULL, + eps_data BLOB DEFAULT NULL, + eps_topic TINYINT UNSIGNED DEFAULT NULL, + UNIQUE INDEX eps_token_sha256 (eps_token_sha256), + INDEX eps_provider (eps_provider), + INDEX eps_topic (eps_topic), + INDEX eps_user (eps_user), + INDEX eps_token ( + eps_token(10) + ), + PRIMARY KEY(eps_id) +) /*$wgDBTableOptions*/; + + +CREATE TABLE /*_*/echo_push_topic ( + ept_id TINYINT UNSIGNED AUTO_INCREMENT NOT NULL, + ept_text TINYBLOB NOT NULL, + PRIMARY KEY(ept_id) +) /*$wgDBTableOptions*/; diff --git a/Echo/sql/mysql/tables-sharedtracking-generated.sql b/Echo/sql/mysql/tables-sharedtracking-generated.sql new file mode 100644 index 00000000..40be5504 --- /dev/null +++ b/Echo/sql/mysql/tables-sharedtracking-generated.sql @@ -0,0 +1,15 @@ +-- This file is automatically generated using maintenance/generateSchemaSql.php. +-- Source: sql/tables-sharedtracking.json +-- Do not modify this file directly. +-- See https://www.mediawiki.org/wiki/Manual:Schema_changes +CREATE TABLE /*_*/echo_unread_wikis ( + euw_id INT UNSIGNED AUTO_INCREMENT NOT NULL, + euw_user INT UNSIGNED NOT NULL, + euw_wiki VARCHAR(64) NOT NULL, + euw_alerts INT UNSIGNED NOT NULL, + euw_alerts_ts BINARY(14) NOT NULL, + euw_messages INT UNSIGNED NOT NULL, + euw_messages_ts BINARY(14) NOT NULL, + UNIQUE INDEX echo_unread_wikis_user_wiki (euw_user, euw_wiki), + PRIMARY KEY(euw_id) +) /*$wgDBTableOptions*/; diff --git a/Echo/db_patches/patch-drop-echo_event-event_page_namespace.sql b/Echo/sql/patch-drop-echo_event-event_page_namespace.sql index 95244ff9..95244ff9 100644 --- a/Echo/db_patches/patch-drop-echo_event-event_page_namespace.sql +++ b/Echo/sql/patch-drop-echo_event-event_page_namespace.sql diff --git a/Echo/db_patches/patch-drop-echo_event-event_page_title.sql b/Echo/sql/patch-drop-echo_event-event_page_title.sql index 34451c4d..34451c4d 100644 --- a/Echo/db_patches/patch-drop-echo_event-event_page_title.sql +++ b/Echo/sql/patch-drop-echo_event-event_page_title.sql diff --git a/Echo/db_patches/patch-drop-user-hash-timestamp-index.sql b/Echo/sql/patch-drop-user-hash-timestamp-index.sql index 83aae620..83aae620 100644 --- a/Echo/db_patches/patch-drop-user-hash-timestamp-index.sql +++ b/Echo/sql/patch-drop-user-hash-timestamp-index.sql diff --git a/Echo/sql/postgres/tables-generated.sql b/Echo/sql/postgres/tables-generated.sql new file mode 100644 index 00000000..2a2b1ddf --- /dev/null +++ b/Echo/sql/postgres/tables-generated.sql @@ -0,0 +1,106 @@ +-- This file is automatically generated using maintenance/generateSchemaSql.php. +-- Source: sql/tables.json +-- Do not modify this file directly. +-- See https://www.mediawiki.org/wiki/Manual:Schema_changes +CREATE TABLE echo_event ( + event_id SERIAL NOT NULL, + event_type TEXT NOT NULL, + event_variant TEXT DEFAULT NULL, + event_agent_id INT DEFAULT NULL, + event_agent_ip TEXT DEFAULT NULL, + event_extra TEXT DEFAULT NULL, + event_page_id INT DEFAULT NULL, + event_deleted SMALLINT DEFAULT 0 NOT NULL, + PRIMARY KEY(event_id) +); + +CREATE INDEX echo_event_type ON echo_event (event_type); + +CREATE INDEX echo_event_page_id ON echo_event (event_page_id); + + +CREATE TABLE echo_notification ( + notification_event INT NOT NULL, + notification_user INT NOT NULL, + notification_timestamp TIMESTAMPTZ NOT NULL, + notification_read_timestamp TIMESTAMPTZ DEFAULT NULL, + notification_bundle_hash TEXT NOT NULL, + PRIMARY KEY( + notification_user, notification_event + ) +); + +CREATE INDEX echo_user_timestamp ON echo_notification ( + notification_user, notification_timestamp +); + +CREATE INDEX echo_notification_event ON echo_notification (notification_event); + +CREATE INDEX echo_notification_user_read_timestamp ON echo_notification ( + notification_user, notification_read_timestamp +); + + +CREATE TABLE echo_email_batch ( + eeb_id SERIAL NOT NULL, + eeb_user_id INT NOT NULL, + eeb_event_priority SMALLINT DEFAULT 10 NOT NULL, + eeb_event_id INT NOT NULL, + eeb_event_hash TEXT NOT NULL, + PRIMARY KEY(eeb_id) +); + +CREATE UNIQUE INDEX echo_email_batch_user_event ON echo_email_batch (eeb_user_id, eeb_event_id); + +CREATE INDEX echo_email_batch_user_hash_priority ON echo_email_batch ( + eeb_user_id, eeb_event_hash, eeb_event_priority +); + + +CREATE TABLE echo_target_page ( + etp_id SERIAL NOT NULL, + etp_page INT DEFAULT 0 NOT NULL, + etp_event INT DEFAULT 0 NOT NULL, + PRIMARY KEY(etp_id) +); + +CREATE INDEX echo_target_page_event ON echo_target_page (etp_event); + +CREATE INDEX echo_target_page_page_event ON echo_target_page (etp_page, etp_event); + + +CREATE TABLE echo_push_provider ( + epp_id SMALLSERIAL NOT NULL, + epp_name TEXT NOT NULL, + PRIMARY KEY(epp_id) +); + + +CREATE TABLE echo_push_subscription ( + eps_id SERIAL NOT NULL, + eps_user INT NOT NULL, + eps_token TEXT NOT NULL, + eps_token_sha256 CHAR(64) NOT NULL, + eps_provider SMALLINT NOT NULL, + eps_updated TIMESTAMPTZ NOT NULL, + eps_data TEXT DEFAULT NULL, + eps_topic SMALLINT DEFAULT NULL, + PRIMARY KEY(eps_id) +); + +CREATE UNIQUE INDEX eps_token_sha256 ON echo_push_subscription (eps_token_sha256); + +CREATE INDEX eps_provider ON echo_push_subscription (eps_provider); + +CREATE INDEX eps_topic ON echo_push_subscription (eps_topic); + +CREATE INDEX eps_user ON echo_push_subscription (eps_user); + +CREATE INDEX eps_token ON echo_push_subscription (eps_token); + + +CREATE TABLE echo_push_topic ( + ept_id SMALLSERIAL NOT NULL, + ept_text TEXT NOT NULL, + PRIMARY KEY(ept_id) +); diff --git a/Echo/sql/postgres/tables-sharedtracking-generated.sql b/Echo/sql/postgres/tables-sharedtracking-generated.sql new file mode 100644 index 00000000..ef190be5 --- /dev/null +++ b/Echo/sql/postgres/tables-sharedtracking-generated.sql @@ -0,0 +1,16 @@ +-- This file is automatically generated using maintenance/generateSchemaSql.php. +-- Source: sql/tables-sharedtracking.json +-- Do not modify this file directly. +-- See https://www.mediawiki.org/wiki/Manual:Schema_changes +CREATE TABLE echo_unread_wikis ( + euw_id SERIAL NOT NULL, + euw_user INT NOT NULL, + euw_wiki VARCHAR(64) NOT NULL, + euw_alerts INT NOT NULL, + euw_alerts_ts TIMESTAMPTZ NOT NULL, + euw_messages INT NOT NULL, + euw_messages_ts TIMESTAMPTZ NOT NULL, + PRIMARY KEY(euw_id) +); + +CREATE UNIQUE INDEX echo_unread_wikis_user_wiki ON echo_unread_wikis (euw_user, euw_wiki); diff --git a/Echo/sql/sqlite/patch-cleanup-push_subscription-foreign-keys-indexes.sql b/Echo/sql/sqlite/patch-cleanup-push_subscription-foreign-keys-indexes.sql new file mode 100644 index 00000000..6460288e --- /dev/null +++ b/Echo/sql/sqlite/patch-cleanup-push_subscription-foreign-keys-indexes.sql @@ -0,0 +1,27 @@ +-- Drop foreign keys from echo_push_subscription and rename index to match table prefix - T306473 + +DROP TABLE IF EXISTS /*_*/echo_push_subscription_tmp; +CREATE TABLE /*_*/echo_push_subscription_tmp ( + eps_id INT UNSIGNED NOT NULL PRIMARY KEY auto_increment, + eps_user INT UNSIGNED NOT NULL, + eps_token BLOB NOT NULL, + eps_token_sha256 CHAR(64) NOT NULL, + eps_provider TINYINT UNSIGNED NOT NULL, + eps_updated TIMESTAMP NOT NULL, + eps_data BLOB, + eps_topic TINYINT UNSIGNED +) /*$wgDBTableOptions*/; + +INSERT INTO /*_*/echo_push_subscription_tmp + SELECT eps_id, eps_user, eps_token, eps_token_sha256, eps_provider, eps_updated, eps_data, eps_topic + FROM /*_*/echo_push_subscription; + +DROP TABLE /*_*/echo_push_subscription; + +ALTER TABLE /*_*/echo_push_subscription_tmp RENAME TO /*_*/echo_push_subscription; + +CREATE UNIQUE INDEX /*i*/eps_token_sha256 ON /*_*/echo_push_subscription (eps_token_sha256); +CREATE INDEX /*i*/eps_provider ON /*_*/echo_push_subscription (eps_provider); +CREATE INDEX /*i*/eps_topic ON /*_*/echo_push_subscription (eps_topic); +CREATE INDEX /*i*/eps_user ON /*_*/echo_push_subscription (eps_user); +CREATE INDEX /*i*/eps_token ON /*_*/echo_push_subscription (eps_token(10)); diff --git a/Echo/sql/sqlite/tables-generated.sql b/Echo/sql/sqlite/tables-generated.sql new file mode 100644 index 00000000..a75d5b76 --- /dev/null +++ b/Echo/sql/sqlite/tables-generated.sql @@ -0,0 +1,98 @@ +-- This file is automatically generated using maintenance/generateSchemaSql.php. +-- Source: sql/tables.json +-- Do not modify this file directly. +-- See https://www.mediawiki.org/wiki/Manual:Schema_changes +CREATE TABLE /*_*/echo_event ( + event_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + event_type BLOB NOT NULL, event_variant BLOB DEFAULT NULL, + event_agent_id INTEGER UNSIGNED DEFAULT NULL, + event_agent_ip BLOB DEFAULT NULL, + event_extra BLOB DEFAULT NULL, event_page_id INTEGER UNSIGNED DEFAULT NULL, + event_deleted SMALLINT UNSIGNED DEFAULT 0 NOT NULL +); + +CREATE INDEX echo_event_type ON /*_*/echo_event (event_type); + +CREATE INDEX echo_event_page_id ON /*_*/echo_event (event_page_id); + + +CREATE TABLE /*_*/echo_notification ( + notification_event INTEGER UNSIGNED NOT NULL, + notification_user INTEGER UNSIGNED NOT NULL, + notification_timestamp BLOB NOT NULL, + notification_read_timestamp BLOB DEFAULT NULL, + notification_bundle_hash BLOB NOT NULL, + PRIMARY KEY( + notification_user, notification_event + ) +); + +CREATE INDEX echo_user_timestamp ON /*_*/echo_notification ( + notification_user, notification_timestamp +); + +CREATE INDEX echo_notification_event ON /*_*/echo_notification (notification_event); + +CREATE INDEX echo_notification_user_read_timestamp ON /*_*/echo_notification ( + notification_user, notification_read_timestamp +); + + +CREATE TABLE /*_*/echo_email_batch ( + eeb_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + eeb_user_id INTEGER UNSIGNED NOT NULL, + eeb_event_priority SMALLINT UNSIGNED DEFAULT 10 NOT NULL, + eeb_event_id INTEGER UNSIGNED NOT NULL, + eeb_event_hash BLOB NOT NULL +); + +CREATE UNIQUE INDEX echo_email_batch_user_event ON /*_*/echo_email_batch (eeb_user_id, eeb_event_id); + +CREATE INDEX echo_email_batch_user_hash_priority ON /*_*/echo_email_batch ( + eeb_user_id, eeb_event_hash, eeb_event_priority +); + + +CREATE TABLE /*_*/echo_target_page ( + etp_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + etp_page INTEGER UNSIGNED DEFAULT 0 NOT NULL, + etp_event INTEGER UNSIGNED DEFAULT 0 NOT NULL +); + +CREATE INDEX echo_target_page_event ON /*_*/echo_target_page (etp_event); + +CREATE INDEX echo_target_page_page_event ON /*_*/echo_target_page (etp_page, etp_event); + + +CREATE TABLE /*_*/echo_push_provider ( + epp_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + epp_name BLOB NOT NULL +); + + +CREATE TABLE /*_*/echo_push_subscription ( + eps_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + eps_user INTEGER UNSIGNED NOT NULL, + eps_token BLOB NOT NULL, + eps_token_sha256 CHAR(64) NOT NULL, + eps_provider SMALLINT UNSIGNED NOT NULL, + eps_updated DATETIME NOT NULL, + eps_data BLOB DEFAULT NULL, + eps_topic SMALLINT UNSIGNED DEFAULT NULL +); + +CREATE UNIQUE INDEX eps_token_sha256 ON /*_*/echo_push_subscription (eps_token_sha256); + +CREATE INDEX eps_provider ON /*_*/echo_push_subscription (eps_provider); + +CREATE INDEX eps_topic ON /*_*/echo_push_subscription (eps_topic); + +CREATE INDEX eps_user ON /*_*/echo_push_subscription (eps_user); + +CREATE INDEX eps_token ON /*_*/echo_push_subscription (eps_token); + + +CREATE TABLE /*_*/echo_push_topic ( + ept_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + ept_text BLOB NOT NULL +); diff --git a/Echo/sql/sqlite/tables-sharedtracking-generated.sql b/Echo/sql/sqlite/tables-sharedtracking-generated.sql new file mode 100644 index 00000000..cbbb0db9 --- /dev/null +++ b/Echo/sql/sqlite/tables-sharedtracking-generated.sql @@ -0,0 +1,15 @@ +-- This file is automatically generated using maintenance/generateSchemaSql.php. +-- Source: sql/tables-sharedtracking.json +-- Do not modify this file directly. +-- See https://www.mediawiki.org/wiki/Manual:Schema_changes +CREATE TABLE /*_*/echo_unread_wikis ( + euw_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + euw_user INTEGER UNSIGNED NOT NULL, + euw_wiki VARCHAR(64) NOT NULL, + euw_alerts INTEGER UNSIGNED NOT NULL, + euw_alerts_ts BLOB NOT NULL, + euw_messages INTEGER UNSIGNED NOT NULL, + euw_messages_ts BLOB NOT NULL +); + +CREATE UNIQUE INDEX echo_unread_wikis_user_wiki ON /*_*/echo_unread_wikis (euw_user, euw_wiki); diff --git a/Echo/sql/tables-sharedtracking.json b/Echo/sql/tables-sharedtracking.json new file mode 100644 index 00000000..39caa613 --- /dev/null +++ b/Echo/sql/tables-sharedtracking.json @@ -0,0 +1,57 @@ +[ + { + "name": "echo_unread_wikis", + "columns": [ + { + "name": "euw_id", + "comment": "Primary key", + "type": "integer", + "options": { "autoincrement": true, "notnull": true, "unsigned": true } + }, + { + "name": "euw_user", + "comment": "Global user id", + "type": "integer", + "options": { "notnull": true, "unsigned": true } + }, + { + "name": "euw_wiki", + "comment": "Name of wiki", + "type": "string", + "options": { "notnull": true, "length": 64 } + }, + { + "name": "euw_alerts", + "comment": "unread alerts count on that wiki", + "type": "integer", + "options": { "notnull": true, "unsigned": true } + }, + { + "name": "euw_alerts_ts", + "comment": "Timestamp of the most recent unread alert", + "type": "mwtimestamp", + "options": { "notnull": true } + }, + { + "name": "euw_messages", + "comment": "unread messages count on that wiki", + "type": "integer", + "options": { "notnull": true, "unsigned": true } + }, + { + "name": "euw_messages_ts", + "comment": "Timestamp of the most recent unread message", + "type": "mwtimestamp", + "options": { "notnull": true } + } + ], + "indexes": [ + { + "name": "echo_unread_wikis_user_wiki", + "columns": [ "euw_user", "euw_wiki" ], + "unique": true + } + ], + "pk": [ "euw_id" ] + } +] diff --git a/Echo/sql/tables.json b/Echo/sql/tables.json new file mode 100644 index 00000000..6b7b3d9e --- /dev/null +++ b/Echo/sql/tables.json @@ -0,0 +1,338 @@ +[ + { + "name": "echo_event", + "comment": "An event is a thing that happened that caused one or more users to be notified. For every notified user, there is a corresponding row in the echo_notification table.", + "columns": [ + { + "name": "event_id", + "comment": "Unique auto-increment ID", + "type": "integer", + "options": { "autoincrement": true, "notnull": true, "unsigned": true } + }, + { + "name": "event_type", + "comment": "Event type; one of the keys in $wgEchoNotifications", + "type": "binary", + "options": { "notnull": true, "length": 64 } + }, + { + "name": "event_variant", + "comment": "Unused, always null", + "type": "binary", + "options": { "notnull": false, "length": 64 } + }, + { + "name": "event_agent_id", + "comment": "The agent (user who triggered the event), if any. If the agent is a logged-in user, event_agent_id contains their user ID and event_agent_ip is null. If the agent is an anonymous user, event_agent_ip contains their IP address and event_agent_id is null. If the event doesn't have an agent, both fields are null.", + "type": "integer", + "options": { "notnull": false, "unsigned": true } + }, + { + "name": "event_agent_ip", + "comment": "The agent (user who triggered the event), if any. If the agent is a logged-in user, event_agent_id contains their user ID and event_agent_ip is null. If the agent is an anonymous user, event_agent_ip contains their IP address and event_agent_id is null. If the event doesn't have an agent, both fields are null.", + "type": "binary", + "options": { "notnull": false, "length": 39 } + }, + { + "name": "event_extra", + "comment": "JSON blob with additional information about the event", + "type": "blob", + "options": { "notnull": false, "length": 65530 } + }, + { + "name": "event_page_id", + "comment": "Page ID of the page the event happened on, if any (key to page_id)", + "type": "integer", + "options": { "notnull": false, "unsigned": true } + }, + { + "name": "event_deleted", + "comment": "Whether the event pertains to a deleted page and should be hidden. Events are marked as deleted when the related page is deleted, and unmarked as deleted when the related page is undeleted", + "type": "mwtinyint", + "options": { "notnull": true, "unsigned": true, "default": 0 } + } + ], + "indexes": [ + { + "name": "echo_event_type", + "comment": "Index to get only 'alert' types or only 'message' types", + "columns": [ "event_type" ], + "unique": false + }, + { + "name": "echo_event_page_id", + "comment": "Index to find events for a specific page", + "columns": [ "event_page_id" ], + "unique": false + } + ], + "pk": [ "event_id" ] + }, + { + "name": "echo_notification", + "comment": "A notification is a user being notified about a certain event. Multiple users can be notified about the same event.", + "columns": [ + { + "name": "notification_event", + "comment": "Key to event_id", + "type": "integer", + "options": { "notnull": true, "unsigned": true } + }, + { + "name": "notification_user", + "comment": "Key to user_id", + "type": "integer", + "options": { "notnull": true, "unsigned": true } + }, + { + "name": "notification_timestamp", + "comment": "Timestamp when the notification was created", + "type": "mwtimestamp", + "options": { "notnull": true } + }, + { + "name": "notification_read_timestamp", + "comment": "Timestamp when the user read the notification, or null if unread", + "type": "mwtimestamp", + "options": { "notnull": false } + }, + { + "name": "notification_bundle_hash", + "comment": "Hash for bundling together similar notifications. Notifications that can be bundled together will have the same hash", + "type": "binary", + "options": { "notnull": true, "length": 32 } + } + ], + "indexes": [ + { + "name": "echo_user_timestamp", + "comment": "Index to get a user's notifications in chronological order", + "columns": [ "notification_user", "notification_timestamp" ], + "unique": false + }, + { + "name": "echo_notification_event", + "comment": "Used to get all notifications for a given event", + "columns": [ "notification_event" ], + "unique": false + }, + { + "name": "echo_notification_user_read_timestamp", + "comment": "Used to get read/unread notifications for a user", + "columns": [ "notification_user", "notification_read_timestamp" ], + "unique": false + } + ], + "pk": [ "notification_user", "notification_event" ] + }, + { + "name": "echo_email_batch", + "comment": "Table gathering events for batch emails. If a user asks to receive batch emails, events are gathered in this table until it's time to send an email. Once a user has been emailed about an event, it's deleted from this table.", + "columns": [ + { + "name": "eeb_id", + "comment": "Unique auto-increment ID", + "type": "integer", + "options": { "autoincrement": true, "notnull": true, "unsigned": true } + }, + { + "name": "eeb_user_id", + "comment": "Key to user_id", + "type": "integer", + "options": { "notnull": true, "unsigned": true } + }, + { + "name": "eeb_event_priority", + "comment": "Priority of the event as defined in $wgEchoNotifications; events with lower numbers are listed first", + "type": "mwtinyint", + "options": { "notnull": true, "unsigned": true, "default": 10 } + }, + { + "name": "eeb_event_id", + "comment": "Key to event_id", + "type": "integer", + "options": { "notnull": true, "unsigned": true } + }, + { + "name": "eeb_event_hash", + "comment": "Same value as notification_bundle_hash, or a unique value if notification_bundle_hash is empty", + "type": "binary", + "options": { "notnull": true, "length": 32 } + } + ], + "indexes": [ + { + "name": "echo_email_batch_user_event", + "comment": "Used to delete events once they have been processed, and to identify users with events to process", + "columns": [ "eeb_user_id", "eeb_event_id" ], + "unique": true + }, + { + "name": "echo_email_batch_user_hash_priority", + "comment": "Used to get a list of events for a user, grouping events with the same hash and ordering by priority", + "columns": [ "eeb_user_id", "eeb_event_hash", "eeb_event_priority" ], + "unique": false + } + ], + "pk": [ "eeb_id" ] + }, + { + "name": "echo_target_page", + "comment": "A \"target page\" of an event is a page that, when the user visits it, causes the event to be marked as read. Typically this is the same as the event's event_page_id, but some events have multiple target pages, and many events don't set a target page at all. An event's target pages are derived from the 'target-page' key in event_extra. This table is also used for moderating events when the related page is deleted, but this should use event_page_id instead (T217452).", + "columns": [ + { + "name": "etp_id", + "comment": "Unique auto-increment ID", + "type": "integer", + "options": { "autoincrement": true, "notnull": true, "unsigned": true } + }, + { + "name": "etp_page", + "comment": "Key to page_id", + "type": "integer", + "options": { "notnull": true, "unsigned": true, "default": 0 } + }, + { + "name": "etp_event", + "comment": "Key to event_id", + "type": "integer", + "options": { "notnull": true, "unsigned": true, "default": 0 } + } + ], + "indexes": [ + { + "name": "echo_target_page_event", + "comment": "Not currently used", + "columns": [ "etp_event" ], + "unique": false + }, + { + "name": "echo_target_page_page_event", + "comment": "Used to get the events associated with a given page", + "columns": [ "etp_page", "etp_event" ], + "unique": false + } + ], + "pk": [ "etp_id" ] + }, + { + "name": "echo_push_provider", + "comment": "Table for normalizing push providers; intended for use with the NameTableStore construct.", + "columns": [ + { + "name": "epp_id", + "type": "mwtinyint", + "options": { "autoincrement": true, "notnull": true, "unsigned": true } + }, + { + "name": "epp_name", + "comment": "push provider name; expected values are 'fcm' and 'apns'", + "type": "blob", + "options": { "notnull": true, "length": 255 } + } + ], + "indexes": [], + "pk": [ "epp_id" ] + }, + { + "name": "echo_push_subscription", + "comment": "Stores push subscriptions associated with wiki users.", + "columns": [ + { + "name": "eps_id", + "type": "integer", + "options": { "autoincrement": true, "notnull": true, "unsigned": true } + }, + { + "name": "eps_user", + "comment": "central user ID", + "type": "integer", + "options": { "notnull": true, "unsigned": true } + }, + { + "name": "eps_token", + "comment": "platform-provided push subscription token", + "type": "blob", + "options": { "notnull": true, "length": 65530 } + }, + { + "name": "eps_token_sha256", + "comment": "SHA256 digest of the push subscription token (to be used as a uniqueness constraint, since the tokens themselves may be large)", + "type": "string", + "options": { "notnull": true, "length": 64, "fixed": true } + }, + { + "name": "eps_provider", + "comment": "push provider ID, expected to reference values 'fcm' or 'apns'", + "type": "mwtinyint", + "options": { "notnull": true, "unsigned": true } + }, + { + "name": "eps_updated", + "comment": "last updated timestamp", + "type": "datetimetz", + "options": { "notnull": true, "PlatformOptions": { "version": true } } + }, + { + "name": "eps_data", + "comment": "push subscription metadata (e.g APNS notification topic)", + "type": "blob", + "options": { "notnull": false, "length": 65530 } + }, + { + "name": "eps_topic", + "comment": "APNS topic ID, references a row ID (ept_id) from echo_push_topic", + "type": "mwtinyint", + "options": { "notnull": false, "unsigned": true } + } + ], + "indexes": [ + { + "name": "eps_token_sha256", + "columns": [ "eps_token_sha256" ], + "unique": true + }, + { + "name": "eps_provider", + "columns": [ "eps_provider" ], + "unique": false + }, + { + "name": "eps_topic", + "columns": [ "eps_topic" ], + "unique": false + }, + { + "name": "eps_user", + "columns": [ "eps_user" ], + "unique": false + }, + { + "name": "eps_token", + "columns": [ "eps_token" ], + "options": { "lengths": [ 10 ] }, + "unique": false + } + ], + "pk": [ "eps_id" ] + }, + { + "name": "echo_push_topic", + "comment": "Table for normalizing APNS push message topics, for use with the NameTableStore construct.", + "columns": [ + { + "name": "ept_id", + "type": "mwtinyint", + "options": { "autoincrement": true, "notnull": true, "unsigned": true } + }, + { + "name": "ept_text", + "comment": "full topic text", + "type": "blob", + "options": { "notnull": true, "length": 255 } + } + ], + "indexes": [], + "pk": [ "ept_id" ] + } +] diff --git a/Echo/tests/phpunit/api/ApiEchoMarkReadTest.php b/Echo/tests/phpunit/Api/ApiEchoMarkReadTest.php index b5a4b6e1..28c2b9a6 100644 --- a/Echo/tests/phpunit/api/ApiEchoMarkReadTest.php +++ b/Echo/tests/phpunit/Api/ApiEchoMarkReadTest.php @@ -4,21 +4,16 @@ * @group medium * @group API * @group Database - * @covers \ApiEchoMarkRead + * @covers \MediaWiki\Extension\Notifications\Api\ApiEchoMarkRead */ class ApiEchoMarkReadTest extends ApiTestCase { - public function getTokens() { - return $this->getTokenList( self::$users['sysop'] ); - } - public function testMarkReadWithList() { - $tokens = $this->getTokens(); // Grouping by section - $data = $this->doApiRequest( [ + $data = $this->doApiRequestWithToken( [ 'action' => 'echomarkread', 'notlist' => '121|122|123', - 'token' => $tokens['edittoken'] ] ); + ] ); $this->assertArrayHasKey( 'query', $data[0] ); $this->assertArrayHasKey( 'echomarkread', $data[0]['query'] ); @@ -41,12 +36,11 @@ class ApiEchoMarkReadTest extends ApiTestCase { } public function testMarkReadWithAll() { - $tokens = $this->getTokens(); // Grouping by section - $data = $this->doApiRequest( [ + $data = $this->doApiRequestWithToken( [ 'action' => 'echomarkread', 'notall' => '1', - 'token' => $tokens['edittoken'] ] ); + ] ); $this->assertArrayHasKey( 'query', $data[0] ); $this->assertArrayHasKey( 'echomarkread', $data[0]['query'] ); @@ -69,12 +63,11 @@ class ApiEchoMarkReadTest extends ApiTestCase { } public function testMarkReadWithSections() { - $tokens = $this->getTokens(); // Grouping by section - $data = $this->doApiRequest( [ + $data = $this->doApiRequestWithToken( [ 'action' => 'echomarkread', 'sections' => 'alert|message', - 'token' => $tokens['edittoken'] ] ); + ] ); $this->assertArrayHasKey( 'query', $data[0] ); $this->assertArrayHasKey( 'echomarkread', $data[0]['query'] ); diff --git a/Echo/tests/phpunit/api/ApiEchoNotificationsTest.php b/Echo/tests/phpunit/Api/ApiEchoNotificationsTest.php index d430fa12..873261b6 100644 --- a/Echo/tests/phpunit/api/ApiEchoNotificationsTest.php +++ b/Echo/tests/phpunit/Api/ApiEchoNotificationsTest.php @@ -3,7 +3,7 @@ /** * @group medium * @group API - * @covers \ApiEchoNotifications + * @covers \MediaWiki\Extension\Notifications\Api\ApiEchoNotifications */ class ApiEchoNotificationsTest extends ApiTestCase { diff --git a/Echo/tests/phpunit/Api/Push/ApiEchoPushSubscriptionsCreateTest.php b/Echo/tests/phpunit/Api/Push/ApiEchoPushSubscriptionsCreateTest.php new file mode 100644 index 00000000..f0fe1bdb --- /dev/null +++ b/Echo/tests/phpunit/Api/Push/ApiEchoPushSubscriptionsCreateTest.php @@ -0,0 +1,92 @@ +<?php + +use MediaWiki\Extension\Notifications\Push\Utils; + +/** + * @group medium + * @group API + * @group Database + * @covers \MediaWiki\Extension\Notifications\Push\Api\ApiEchoPushSubscriptionsCreate + */ +class ApiEchoPushSubscriptionsCreateTest extends ApiTestCase { + + /** @var User */ + private $user; + + protected function setUp(): void { + parent::setUp(); + $this->setMwGlobals( [ + 'wgEchoEnablePush' => true, + 'wgEchoPushMaxSubscriptionsPerUser' => 2 + ] ); + $this->tablesUsed[] = 'echo_push_subscription'; + $this->tablesUsed[] = 'echo_push_provider'; + $this->user = $this->getTestUser()->getUser(); + $this->createTestData(); + } + + public function testApiCreateSubscription(): void { + // Before max subscriptions reached + $params = [ + 'action' => 'echopushsubscriptions', + 'command' => 'create', + 'provider' => 'fcm', + 'providertoken' => 'ABC123', + ]; + $result = $this->doApiRequestWithToken( $params, null, $this->user ); + $this->assertEquals( 'Success', $result[0]['create']['result'] ); + + // Make sure it's possible to register a new token even when limit is reached + $params['providertoken'] = 'DEF456'; + $result = $this->doApiRequestWithToken( $params, null, $this->user ); + $this->assertEquals( 'Success', $result[0]['create']['result'] ); + + // Explicitly verify that the oldest token was removed + $subscriptionManager = EchoServices::getInstance()->getPushSubscriptionManager(); + $subscriptions = $subscriptionManager->getSubscriptionsForUser( Utils::getPushUserId( $this->user ) ); + foreach ( $subscriptions as $subscription ) { + $this->assertNotEquals( 'XYZ789', $subscription->getToken() ); + } + } + + public function testApiCreateSubscriptionTokenExists(): void { + $params = [ + 'action' => 'echopushsubscriptions', + 'command' => 'create', + 'provider' => 'fcm', + 'providertoken' => 'XYZ789', + ]; + $this->expectException( ApiUsageException::class ); + $this->doApiRequestWithToken( $params, null, $this->user ); + } + + public function testApiCreateApnsSubscriptionWithTopic(): void { + $params = [ + 'action' => 'echopushsubscriptions', + 'command' => 'create', + 'provider' => 'apns', + 'providertoken' => 'ABC123', + 'topic' => 'test', + ]; + $result = $this->doApiRequestWithToken( $params, null, $this->user ); + $this->assertEquals( 'Success', $result[0]['create']['result'] ); + } + + public function testApiCreateApnsSubscriptionWithoutTopic(): void { + $params = [ + 'action' => 'echopushsubscriptions', + 'command' => 'create', + 'provider' => 'apns', + 'providertoken' => 'DEF456', + ]; + $this->expectException( ApiUsageException::class ); + $this->doApiRequestWithToken( $params, null, $this->user ); + } + + private function createTestData(): void { + $subscriptionManager = EchoServices::getInstance()->getPushSubscriptionManager(); + $userId = Utils::getPushUserId( $this->user ); + $subscriptionManager->create( 'fcm', 'XYZ789', $userId ); + } + +} diff --git a/Echo/tests/phpunit/Api/Push/ApiEchoPushSubscriptionsDeleteTest.php b/Echo/tests/phpunit/Api/Push/ApiEchoPushSubscriptionsDeleteTest.php new file mode 100644 index 00000000..a345cc0e --- /dev/null +++ b/Echo/tests/phpunit/Api/Push/ApiEchoPushSubscriptionsDeleteTest.php @@ -0,0 +1,107 @@ +<?php + +use MediaWiki\Extension\Notifications\Push\Utils; + +/** + * @group medium + * @group API + * @group Database + * @covers \MediaWiki\Extension\Notifications\Push\Api\ApiEchoPushSubscriptionsDelete + */ +class ApiEchoPushSubscriptionsDeleteTest extends ApiTestCase { + + /** @var User */ + private $user; + + /** @var User */ + private $subscriptionManager; + + /** @var User */ + private $otherUser; + + protected function setUp(): void { + parent::setUp(); + $this->setMwGlobals( [ + 'wgEchoEnablePush' => true, + 'wgEchoPushMaxSubscriptionsPerUser' => 3 + ] ); + $this->tablesUsed[] = 'echo_push_subscription'; + $this->tablesUsed[] = 'echo_push_provider'; + + // Use mutable users for our generic users so we don't get two references to the same User + $this->user = $this->getMutableTestUser()->getUser(); + $this->otherUser = $this->getMutableTestUser()->getUser(); + $this->subscriptionManager = $this->getTestUser( 'push-subscription-manager' )->getUser(); + + $this->createTestData(); + } + + public function testApiDeleteSubscription(): void { + $params = [ + 'action' => 'echopushsubscriptions', + 'command' => 'delete', + 'providertoken' => 'ABC', + ]; + $result = $this->doApiRequestWithToken( $params, null, $this->user ); + $this->assertEquals( 'Success', $result[0]['delete']['result'] ); + } + + public function testApiDeleteSubscriptionNotFound(): void { + $params = [ + 'action' => 'echopushsubscriptions', + 'command' => 'delete', + 'providertoken' => 'XYZ', + ]; + $this->expectException( ApiUsageException::class ); + $this->doApiRequestWithToken( $params, null, $this->user ); + } + + public function testApiDeleteSubscriptionWithOwnCentralId(): void { + $params = [ + 'action' => 'echopushsubscriptions', + 'command' => 'delete', + 'providertoken' => 'ABC', + 'centraluserid' => Utils::getPushUserId( $this->user ), + ]; + $result = $this->doApiRequestWithToken( $params, null, $this->user ); + $this->assertEquals( 'Success', $result[0]['delete']['result'] ); + } + + public function testApiDeleteSubscriptionWithOtherNonSubscriptionManagerUser(): void { + $params = [ + 'action' => 'echopushsubscriptions', + 'command' => 'delete', + 'providertoken' => 'ABC', + 'centraluserid' => Utils::getPushUserId( $this->user ), + ]; + $this->expectException( ApiUsageException::class ); + $this->doApiRequestWithToken( $params, null, $this->otherUser ); + } + + public function testApiDeleteSubscriptionWithPushSubscriptionManager(): void { + $params = [ + 'action' => 'echopushsubscriptions', + 'command' => 'delete', + 'providertoken' => 'ABC', + ]; + $result = $this->doApiRequestWithToken( $params, null, $this->subscriptionManager ); + $this->assertEquals( 'Success', $result[0]['delete']['result'] ); + } + + public function testApiDeleteSubscriptionProviderTokenEmpty(): void { + $params = [ + 'action' => 'echopushsubscriptions', + 'command' => 'delete', + 'providertoken' => '' + ]; + $this->expectException( ApiUsageException::class ); + $result = $this->doApiRequestWithToken( $params, null, $this->user ); + } + + private function createTestData(): void { + $subscriptionManager = EchoServices::getInstance()->getPushSubscriptionManager(); + $userId = Utils::getPushUserId( $this->user ); + $subscriptionManager->create( 'fcm', 'ABC', $userId ); + } + +} diff --git a/Echo/tests/phpunit/api/Push/ApiEchoPushSubscriptionsTest.php b/Echo/tests/phpunit/Api/Push/ApiEchoPushSubscriptionsTest.php index 857464a8..81ca5ad2 100644 --- a/Echo/tests/phpunit/api/Push/ApiEchoPushSubscriptionsTest.php +++ b/Echo/tests/phpunit/Api/Push/ApiEchoPushSubscriptionsTest.php @@ -3,7 +3,7 @@ /** * @group medium * @group API - * @covers \EchoPush\Api\ApiEchoPushSubscriptions + * @covers \MediaWiki\Extension\Notifications\Push\Api\ApiEchoPushSubscriptions */ class ApiEchoPushSubscriptionsTest extends ApiTestCase { diff --git a/Echo/tests/phpunit/ContainmentSetTest.php b/Echo/tests/phpunit/ContainmentSetTest.php index d85de7f3..2f3ae4f7 100644 --- a/Echo/tests/phpunit/ContainmentSetTest.php +++ b/Echo/tests/phpunit/ContainmentSetTest.php @@ -5,7 +5,7 @@ * @group Echo * @group Database */ -class ContainmentSetTest extends MediaWikiTestCase { +class ContainmentSetTest extends MediaWikiIntegrationTestCase { public function testGenericContains() { $list = new EchoContainmentSet( self::getTestUser()->getUser() ); @@ -29,12 +29,11 @@ class ContainmentSetTest extends MediaWikiTestCase { $inner = [ 'bing', 'bang' ]; // We use a mock instead of the real thing for the $this->once() assertion // verifying that the cache doesn't just keep asking the inner object - $list = $this->getMockBuilder( EchoArrayList::class ) - ->disableOriginalConstructor() - ->getMock(); + $list = $this->createMock( EchoArrayList::class ); $list->expects( $this->once() ) ->method( 'getValues' ) - ->will( $this->returnValue( $inner ) ); + ->willReturn( $inner ); + $list->method( 'getCacheKey' )->willReturn( '' ); $cached = new EchoCachedList( $wanCache, 'test_key', $list ); diff --git a/Echo/tests/phpunit/DiscussionParserTest.php b/Echo/tests/phpunit/DiscussionParserTest.php index a161cd07..c5a3474c 100644 --- a/Echo/tests/phpunit/DiscussionParserTest.php +++ b/Echo/tests/phpunit/DiscussionParserTest.php @@ -3,6 +3,8 @@ // phpcs:disable Generic.Files.LineLength -- Long html test examples use MediaWiki\MediaWikiServices; +use MediaWiki\Revision\MutableRevisionRecord; +use MediaWiki\Revision\SlotRecord; use Wikimedia\TestingAccessWrapper; /** @@ -10,7 +12,7 @@ use Wikimedia\TestingAccessWrapper; * @group Echo * @group Database */ -class EchoDiscussionParserTest extends MediaWikiTestCase { +class EchoDiscussionParserTest extends MediaWikiIntegrationTestCase { /** * @var string[] */ @@ -130,12 +132,12 @@ class EchoDiscussionParserTest extends MediaWikiTestCase { ], ]; - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->setMwGlobals( [ 'wgDiff' => false ] ); } - protected function tearDown() : void { + protected function tearDown(): void { parent::tearDown(); global $wgHooks; @@ -159,8 +161,9 @@ class EchoDiscussionParserTest extends MediaWikiTestCase { // Set preferences if ( $user ) { + $userOptionsManager = $this->getServiceContainer()->getUserOptionsManager(); foreach ( $preferences as $option => $value ) { - $user->setOption( $option, $value ); + $userOptionsManager->setOption( $user, $option, $value ); } $user->saveSettings(); } @@ -383,7 +386,7 @@ class EchoDiscussionParserTest extends MediaWikiTestCase { ); $events = []; $this->setupEventCallbackForEventGeneration( - function ( EchoEvent $event ) use ( &$events ) { + static function ( EchoEvent $event ) use ( &$events ) { $events[] = [ 'type' => $event->getType(), 'agent' => $event->getAgent()->getName(), @@ -399,6 +402,7 @@ class EchoDiscussionParserTest extends MediaWikiTestCase { // enable pings from summary 'wgEchoMaxMentionsInEditSummary' => 5, ] ); + $this->clearHook( 'EchoGetEventsForRevision' ); EchoDiscussionParser::generateEventsForRevision( $revision, false ); @@ -700,7 +704,7 @@ class EchoDiscussionParserTest extends MediaWikiTestCase { ); $events = []; $this->setupEventCallbackForEventGeneration( - function ( EchoEvent $event ) use ( &$events ) { + static function ( EchoEvent $event ) use ( &$events ) { $events[] = [ 'type' => $event->getType(), 'agent' => $event->getAgent()->getName(), @@ -715,6 +719,7 @@ class EchoDiscussionParserTest extends MediaWikiTestCase { $this->setMwGlobals( 'wgEchoMentionStatusNotifications', true ); // enable multiple sections mentions $this->setMwGlobals( 'wgEchoMentionsOnMultipleSectionEdits', true ); + $this->clearHook( 'EchoGetEventsForRevision' ); EchoDiscussionParser::generateEventsForRevision( $revision, false ); @@ -900,7 +905,7 @@ TEXT $events = []; $this->setupEventCallbackForEventGeneration( - function ( EchoEvent $event ) use ( &$events ) { + static function ( EchoEvent $event ) use ( &$events ) { $events[] = [ 'type' => $event->getType(), 'agent' => $event->getAgent()->getName(), @@ -917,6 +922,7 @@ TEXT // lower limit for the mention-failure-too-many notification 'wgEchoMaxMentionsCount' => 5 ] ); + $this->clearHook( 'EchoGetEventsForRevision' ); EchoDiscussionParser::generateEventsForRevision( $revision, false ); @@ -940,9 +946,12 @@ TEXT // pages to be created: templates may be used to ping users (e.g. // {{u|...}}) but if we don't have that template, it just won't work! $pages += [ $title => '' ]; + + $user = $this->getTestUser()->getUser(); + $wikiPageFactory = MediaWikiServices::getInstance()->getWikiPageFactory(); foreach ( $pages as $pageTitle => $pageText ) { - $template = WikiPage::factory( Title::newFromText( $pageTitle ) ); - $template->doEditContent( new WikitextContent( $pageText ), '' ); + $template = $wikiPageFactory->newFromTitle( Title::newFromText( $pageTitle ) ); + $template->doUserEditContent( new WikitextContent( $pageText ), $user, '' ); } // force i18n messages to be reloaded from MessageCache (from DB, where a new message @@ -964,16 +973,21 @@ TEXT $property->setValue( $title, $lang ); // create stub MutableRevisionRecord object - $row = [ - 'id' => $newId, - 'user_text' => $username, - 'user' => User::newFromName( $username )->getId(), - 'parent_id' => $oldId, - 'text' => $newText, - 'title' => $title, - 'comment' => $summary, - ]; - $revision = $store->newMutableRevisionFromArray( $row ); + $revision = new MutableRevisionRecord( $title ); + + $content = new WikitextContent( $newText ); + + $revision->setId( $newId ); + $revision->setUser( User::newFromName( $username ) ); + + $revision->setParentId( $oldId ); + $comment = CommentStoreComment::newUnsavedComment( + $summary, + null + ); + $revision->setComment( $comment ); + $revision->setContent( SlotRecord::MAIN, $content ); + $userName = $revision->getUser()->getName(); // generate diff between 2 revisions @@ -1013,6 +1027,11 @@ TEXT $this->assertSame( 1, $match ); } + public function testTimestampRegex_T264922() { + $this->setMwGlobals( 'wgLanguageCode', 'skr' ); + $this->assertIsString( EchoDiscussionParser::getTimestampRegex(), 'does not fail' ); + } + public function testGetTimestampPosition() { $line = 'Hello World. ' . self::getExemplarTimestamp(); $pos = EchoDiscussionParser::getTimestampPosition( $line ); @@ -1029,8 +1048,7 @@ TEXT } if ( !EchoDiscussionParser::isSignedComment( $line ) ) { - $this->assertEquals( $expectedUser, false ); - + $this->assertFalse( $expectedUser ); return; } @@ -1795,9 +1813,29 @@ TEXT EchoDiscussionParser::getTextSnippet( '[[:{{BASEPAGENAME}}]]', Language::factory( 'en' ), - 150, + EchoDiscussionParser::DEFAULT_SNIPPET_LENGTH, Title::newFromText( 'Page001' ) ) ); + $this->assertEquals( + 'Hello', + EchoDiscussionParser::getTextSnippet( + '* Hello', + Language::factory( 'en' ), + EchoDiscussionParser::DEFAULT_SNIPPET_LENGTH, + null, + true + ) + ); + $this->assertEquals( + '* Hello', + EchoDiscussionParser::getTextSnippet( + '* Hello', + Language::factory( 'en' ), + EchoDiscussionParser::DEFAULT_SNIPPET_LENGTH, + null, + false + ) + ); } } diff --git a/Echo/tests/phpunit/EchoDbFactoryTest.php b/Echo/tests/phpunit/EchoDbFactoryTest.php index 1c10c0d0..121e4e9a 100644 --- a/Echo/tests/phpunit/EchoDbFactoryTest.php +++ b/Echo/tests/phpunit/EchoDbFactoryTest.php @@ -6,7 +6,7 @@ use Wikimedia\Rdbms\ILoadBalancer; /** * @covers \MWEchoDbFactory */ -class MWEchoDbFactoryTest extends MediaWikiTestCase { +class MWEchoDbFactoryTest extends MediaWikiIntegrationTestCase { public function testNewFromDefault() { $db = MWEchoDbFactory::newFromDefault(); @@ -19,7 +19,7 @@ class MWEchoDbFactoryTest extends MediaWikiTestCase { * @depends testNewFromDefault */ public function testGetEchoDb( MWEchoDbFactory $db ) { - $this->assertInstanceOf( IDatabase::class, $db->getEchoDb( DB_MASTER ) ); + $this->assertInstanceOf( IDatabase::class, $db->getEchoDb( DB_PRIMARY ) ); $this->assertInstanceOf( IDatabase::class, $db->getEchoDb( DB_REPLICA ) ); } diff --git a/Echo/tests/phpunit/EchoHooksTest.php b/Echo/tests/phpunit/EchoHooksTest.php index d1f2ac56..3040227b 100644 --- a/Echo/tests/phpunit/EchoHooksTest.php +++ b/Echo/tests/phpunit/EchoHooksTest.php @@ -1,8 +1,10 @@ <?php -class EchoHooksTest extends MediaWikiTestCase { +use MediaWiki\Extension\Notifications\Hooks as EchoHooks; + +class EchoHooksTest extends MediaWikiIntegrationTestCase { /** - * @covers \EchoHooks::onUserGetDefaultOptions() + * @covers \MediaWiki\Extension\Notifications\Hooks::onUserGetDefaultOptions() */ public function testOnUserGetDefaultOptions() { $this->setMwGlobals( [ @@ -33,7 +35,7 @@ class EchoHooksTest extends MediaWikiTestCase { // T174220: don't overwrite defaults set elsewhere 'echo-subscriptions-web-mention' => false, ]; - EchoHooks::onUserGetDefaultOptions( $defaults ); + ( new EchoHooks( new HashConfig ) )->onUserGetDefaultOptions( $defaults ); self::assertEquals( [ 'something' => 'unrelated', diff --git a/Echo/tests/phpunit/EchoSummaryParserTest.php b/Echo/tests/phpunit/EchoSummaryParserTest.php index 7fc7a9bf..44047ecf 100644 --- a/Echo/tests/phpunit/EchoSummaryParserTest.php +++ b/Echo/tests/phpunit/EchoSummaryParserTest.php @@ -3,7 +3,8 @@ /** * @group Echo */ -class EchoSummaryParserTest extends MediaWikiTestCase { +class EchoSummaryParserTest extends MediaWikiIntegrationTestCase { + /** @var string[] */ private $existingUsers = [ 'Werdna', 'Jorm', diff --git a/Echo/tests/phpunit/formatters/PresentationModelSectionTest.php b/Echo/tests/phpunit/Formatters/EchoPresentationModelSectionTest.php index b17af684..90d85488 100644 --- a/Echo/tests/phpunit/formatters/PresentationModelSectionTest.php +++ b/Echo/tests/phpunit/Formatters/EchoPresentationModelSectionTest.php @@ -1,13 +1,13 @@ <?php +use MediaWiki\Extension\Notifications\Formatters\EchoPresentationModelSection; + /** + * @covers \MediaWiki\Extension\Notifications\Formatters\EchoPresentationModelSection * @group Database */ -class EchoPresentationModelSectionTest extends MediaWikiTestCase { +class EchoPresentationModelSectionTest extends MediaWikiIntegrationTestCase { - /** - * @covers \EchoPresentationModelSection::getTruncatedSectionTitle - */ public function testGetTruncatedSectionTitle_short() { $lang = Language::factory( 'en' ); $section = new EchoPresentationModelSection( @@ -19,9 +19,6 @@ class EchoPresentationModelSectionTest extends MediaWikiTestCase { $this->assertEquals( $lang->embedBidi( 'asdf' ), $section->getTruncatedSectionTitle() ); } - /** - * @covers \EchoPresentationModelSection::getTruncatedSectionTitle - */ public function testGetTruncatedSectionTitle_long() { $lang = Language::factory( 'en' ); $section = new EchoPresentationModelSection( @@ -36,9 +33,6 @@ class EchoPresentationModelSectionTest extends MediaWikiTestCase { ); } - /** - * @covers \EchoPresentationModelSection::getTitleWithSection - */ public function testGetTitleWithSection() { $page = $this->getExistingTestPage(); $section = new EchoPresentationModelSection( @@ -56,9 +50,6 @@ class EchoPresentationModelSectionTest extends MediaWikiTestCase { $this->assertEquals( $page->getTitle()->getPrefixedText(), $titleWithSection->getPrefixedText() ); } - /** - * @covers \EchoPresentationModelSection::exists - */ public function testExists_no() { $section = new EchoPresentationModelSection( $this->makeEvent(), @@ -69,9 +60,6 @@ class EchoPresentationModelSectionTest extends MediaWikiTestCase { $this->assertFalse( $section->exists() ); } - /** - * @covers \EchoPresentationModelSection::exists - */ public function testExists_yes() { $section = new EchoPresentationModelSection( $this->makeEvent( [ 'event_extra' => serialize( [ 'section-title' => 'asdf' ] ) ] ), diff --git a/Echo/tests/phpunit/NotifUserTest.php b/Echo/tests/phpunit/NotifUserTest.php index 11a182d3..cbdfa3bf 100644 --- a/Echo/tests/phpunit/NotifUserTest.php +++ b/Echo/tests/phpunit/NotifUserTest.php @@ -1,19 +1,20 @@ <?php use MediaWiki\MediaWikiServices; +use MediaWiki\User\UserOptionsLookup; /** * @covers \MWEchoNotifUser * @group Echo */ -class MWEchoNotifUserTest extends MediaWikiTestCase { +class MWEchoNotifUserTest extends MediaWikiIntegrationTestCase { /** * @var WANObjectCache */ private $cache; - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->cache = new WANObjectCache( [ 'cache' => MediaWikiServices::getInstance()->getMainObjectStash(), @@ -36,11 +37,13 @@ class MWEchoNotifUserTest extends MediaWikiTestCase { } public function testGetEmailFormat() { + $userOptionsLookup = $this->getServiceContainer()->getUserOptionsLookup(); $user = User::newFromId( 2 ); $notifUser = MWEchoNotifUser::newFromUser( $user ); $this->setMwGlobals( 'wgAllowHTMLEmail', true ); - $this->assertEquals( $notifUser->getEmailFormat(), $user->getOption( 'echo-email-format' ) ); + $this->assertEquals( $notifUser->getEmailFormat(), + $userOptionsLookup->getOption( $user, 'echo-email-format' ) ); $this->setMwGlobals( 'wgAllowHTMLEmail', false ); $this->assertEquals( $notifUser->getEmailFormat(), EchoEmailFormat::PLAIN_TEXT ); } @@ -51,7 +54,10 @@ class MWEchoNotifUserTest extends MediaWikiTestCase { $this->cache, $this->mockEchoUserNotificationGateway( [ 'markRead' => true ] ), $this->mockEchoNotificationMapper(), - $this->mockEchoTargetPageMapper() + $this->createMock( EchoTargetPageMapper::class ), + $this->createNoOpMock( UserOptionsLookup::class ), + $this->getServiceContainer()->getUserFactory(), + $this->getServiceContainer()->getReadOnlyMode() ); $this->assertFalse( $notifUser->markRead( [] ) ); $this->assertTrue( $notifUser->markRead( [ 1 ] ) ); @@ -61,7 +67,10 @@ class MWEchoNotifUserTest extends MediaWikiTestCase { $this->cache, $this->mockEchoUserNotificationGateway( [ 'markRead' => false ] ), $this->mockEchoNotificationMapper(), - $this->mockEchoTargetPageMapper() + $this->createMock( EchoTargetPageMapper::class ), + $this->createNoOpMock( UserOptionsLookup::class ), + $this->getServiceContainer()->getUserFactory(), + $this->getServiceContainer()->getReadOnlyMode() ); $this->assertFalse( $notifUser->markRead( [] ) ); $this->assertFalse( $notifUser->markRead( [ 1 ] ) ); @@ -74,7 +83,10 @@ class MWEchoNotifUserTest extends MediaWikiTestCase { $this->cache, $this->mockEchoUserNotificationGateway( [ 'markRead' => true ] ), $this->mockEchoNotificationMapper( [ $this->mockEchoNotification() ] ), - $this->mockEchoTargetPageMapper() + $this->createMock( EchoTargetPageMapper::class ), + $this->createNoOpMock( UserOptionsLookup::class ), + $this->getServiceContainer()->getUserFactory(), + $this->getServiceContainer()->getReadOnlyMode() ); $this->assertTrue( $notifUser->markAllRead() ); @@ -84,7 +96,10 @@ class MWEchoNotifUserTest extends MediaWikiTestCase { $this->cache, $this->mockEchoUserNotificationGateway( [ 'markRead' => false ] ), $this->mockEchoNotificationMapper( [ $this->mockEchoNotification() ] ), - $this->mockEchoTargetPageMapper() + $this->createMock( EchoTargetPageMapper::class ), + $this->createNoOpMock( UserOptionsLookup::class ), + $this->getServiceContainer()->getUserFactory(), + $this->getServiceContainer()->getReadOnlyMode() ); $this->assertFalse( $notifUser->markAllRead() ); @@ -94,7 +109,10 @@ class MWEchoNotifUserTest extends MediaWikiTestCase { $this->cache, $this->mockEchoUserNotificationGateway( [ 'markRead' => true ] ), $this->mockEchoNotificationMapper(), - $this->mockEchoTargetPageMapper() + $this->createMock( EchoTargetPageMapper::class ), + $this->createNoOpMock( UserOptionsLookup::class ), + $this->getServiceContainer()->getUserFactory(), + $this->getServiceContainer()->getReadOnlyMode() ); $this->assertFalse( $notifUser->markAllRead() ); @@ -104,7 +122,10 @@ class MWEchoNotifUserTest extends MediaWikiTestCase { $this->cache, $this->mockEchoUserNotificationGateway( [ 'markRead' => false ] ), $this->mockEchoNotificationMapper(), - $this->mockEchoTargetPageMapper() + $this->createMock( EchoTargetPageMapper::class ), + $this->createNoOpMock( UserOptionsLookup::class ), + $this->getServiceContainer()->getUserFactory(), + $this->getServiceContainer()->getReadOnlyMode() ); $this->assertFalse( $notifUser->markAllRead() ); } @@ -113,57 +134,35 @@ class MWEchoNotifUserTest extends MediaWikiTestCase { $dbResult += [ 'markRead' => true ]; - $gateway = $this->getMockBuilder( EchoUserNotificationGateway::class ) - ->disableOriginalConstructor() - ->getMock(); - $gateway->expects( $this->any() ) - ->method( 'markRead' ) - ->will( $this->returnValue( $dbResult['markRead'] ) ); - $gateway->expects( $this->any() ) - ->method( 'getDB' ) - ->will( $this->returnValue( - $this->getMockBuilder( IDatabase::class ) - ->disableOriginalConstructor()->getMock() - ) ); + $gateway = $this->createMock( EchoUserNotificationGateway::class ); + $gateway->method( 'markRead' ) + ->willReturn( $dbResult['markRead'] ); + $gateway->method( 'getDB' ) + ->willReturn( $this->createMock( IDatabase::class ) ); return $gateway; } public function mockEchoNotificationMapper( array $result = [] ) { - $mapper = $this->getMockBuilder( EchoNotificationMapper::class ) - ->disableOriginalConstructor() - ->getMock(); - $mapper->expects( $this->any() ) - ->method( 'fetchUnreadByUser' ) - ->will( $this->returnValue( $result ) ); + $mapper = $this->createMock( EchoNotificationMapper::class ); + $mapper->method( 'fetchUnreadByUser' ) + ->willReturn( $result ); return $mapper; } - public function mockEchoTargetPageMapper() { - return $this->getMockBuilder( EchoTargetPageMapper::class ) - ->disableOriginalConstructor() - ->getMock(); - } - protected function mockEchoNotification() { - $notification = $this->getMockBuilder( EchoNotification::class ) - ->disableOriginalConstructor() - ->getMock(); - $notification->expects( $this->any() ) - ->method( 'getEvent' ) - ->will( $this->returnValue( $this->mockEchoEvent() ) ); + $notification = $this->createMock( EchoNotification::class ); + $notification->method( 'getEvent' ) + ->willReturn( $this->mockEchoEvent() ); return $notification; } protected function mockEchoEvent() { - $event = $this->getMockBuilder( EchoEvent::class ) - ->disableOriginalConstructor() - ->getMock(); - $event->expects( $this->any() ) - ->method( 'getId' ) - ->will( $this->returnValue( 1 ) ); + $event = $this->createMock( EchoEvent::class ); + $event->method( 'getId' ) + ->willReturn( 1 ); return $event; } @@ -174,7 +173,10 @@ class MWEchoNotifUserTest extends MediaWikiTestCase { $this->cache, $this->mockEchoUserNotificationGateway(), $this->mockEchoNotificationMapper(), - $this->mockEchoTargetPageMapper() + $this->createMock( EchoTargetPageMapper::class ), + $this->createNoOpMock( UserOptionsLookup::class ), + $this->getServiceContainer()->getUserFactory(), + $this->getServiceContainer()->getReadOnlyMode() ); } } diff --git a/Echo/tests/phpunit/NotificationStructureTest.php b/Echo/tests/phpunit/NotificationStructureTest.php index 17f5a5f3..75373ee5 100644 --- a/Echo/tests/phpunit/NotificationStructureTest.php +++ b/Echo/tests/phpunit/NotificationStructureTest.php @@ -1,6 +1,6 @@ <?php -class NotificationStructureTest extends MediaWikiTestCase { +class NotificationStructureTest extends MediaWikiIntegrationTestCase { /** * @coversNothing * @dataProvider provideNotificationTypes @@ -16,13 +16,13 @@ class NotificationStructureTest extends MediaWikiTestCase { } if ( isset( $info['user-locators'] ) ) { - $locators = $info['user-locators']; - $locator = reset( $locators ); - if ( is_array( $locator ) ) { - $locator = reset( $locator ); + $locators = (array)$info['user-locators']; + $callable = reset( $locators ); + if ( is_array( $callable ) ) { + $callable = reset( $callable ); } - self::assertTrue( is_callable( $locator ), - 'User locator ' . print_r( $locator, true ) . " for {$type} must be callable" + self::assertTrue( is_callable( $callable ), + 'User locator ' . print_r( $callable, true ) . " for {$type} must be callable" ); } } diff --git a/Echo/tests/phpunit/NotificationsTest.php b/Echo/tests/phpunit/NotificationsTest.php index ab971a97..84cf8364 100644 --- a/Echo/tests/phpunit/NotificationsTest.php +++ b/Echo/tests/phpunit/NotificationsTest.php @@ -1,23 +1,18 @@ <?php -use MediaWiki\MediaWikiServices; - /** * Tests for the built in notification types * * @group Database */ -class NotificationsTest extends MediaWikiTestCase { +class NotificationsTest extends MediaWikiIntegrationTestCase { - /** @var User $sysop */ - // @codingStandardsIgnoreStart - var $sysop; - // @codingStandardsIgnoreEnd + /** @var User */ + private $sysop; - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); - $this->sysop = User::newFromName( 'UTSysop' ); - $this->setMwGlobals( 'wgUser', $this->sysop ); + $this->sysop = $this->getTestSysop()->getUser(); } /** @@ -34,7 +29,7 @@ class NotificationsTest extends MediaWikiTestCase { } /** - * @covers \EchoHooks::onUserGroupsChanged + * @covers \MediaWiki\Extension\Notifications\Hooks::onUserGroupsChanged */ public function testUserRightsNotif() { $user = new User(); @@ -43,13 +38,13 @@ class NotificationsTest extends MediaWikiTestCase { $context = new DerivativeContext( RequestContext::getMain() ); $context->setUser( $this->sysop ); - $ur = new UserrightsPage( - MediaWikiServices::getInstance()->getPermissionManager() - ); + $ur = $this->getServiceContainer() + ->getSpecialPageFactory() + ->getPage( 'Userrights' ); $ur->setContext( $context ); $ur->doSaveUserGroups( $user, [ 'sysop' ], [], 'reason' ); $event = self::getLatestNotification( $user ); - $this->assertEquals( $event->getType(), 'user-rights' ); + $this->assertEquals( 'user-rights', $event->getType() ); $this->assertEquals( $this->sysop->getName(), $event->getAgent()->getName() ); $extra = $event->getExtra(); $this->assertArrayHasKey( 'add', $extra ); diff --git a/Echo/tests/phpunit/TalkPageFunctionalTest.php b/Echo/tests/phpunit/TalkPageFunctionalTest.php index 1e6786c5..88a8f041 100644 --- a/Echo/tests/phpunit/TalkPageFunctionalTest.php +++ b/Echo/tests/phpunit/TalkPageFunctionalTest.php @@ -7,7 +7,7 @@ */ class EchoTalkPageFunctionalTest extends ApiTestCase { - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->db->delete( 'echo_event', '*' ); } @@ -20,41 +20,59 @@ class EchoTalkPageFunctionalTest extends ApiTestCase { public function testAddCommentsToTalkPage() { $talkPage = self::$users['uploader']->getUser()->getName(); - $messageCount = 0; - $this->assertCount( $messageCount, $this->fetchAllEvents() ); + $expectedMessageCount = 0; + $this->assertCount( $expectedMessageCount, $this->fetchAllEvents() ); // Start a talkpage + $expectedMessageCount++; $content = "== Section 8 ==\n\nblah blah ~~~~\n"; - $this->editPage( $talkPage, $content, '', NS_USER_TALK ); + $this->editPage( + $talkPage, + $content, + '', + NS_USER_TALK, + self::$users['sysop']->getUser() + ); // Ensure the proper event was created $events = $this->fetchAllEvents(); - // +1 is due to 0 index - $this->assertCount( 1 + $messageCount, $events, 'After initial edit a single event must exist.' ); - $row = array_shift( $events ); + $this->assertCount( $expectedMessageCount, $events, 'After initial edit a single event must exist.' ); + $row = array_pop( $events ); $this->assertEquals( 'edit-user-talk', $row->event_type ); $this->assertEventSectionTitle( 'Section 8', $row ); // Add another message to the talk page - $messageCount++; + $expectedMessageCount++; $content .= "More content ~~~~\n"; - $this->editPage( $talkPage, $content, '', NS_USER_TALK ); + $this->editPage( + $talkPage, + $content, + '', + NS_USER_TALK, + self::$users['sysop']->getUser() + ); // Ensure another event was created $events = $this->fetchAllEvents(); - $this->assertCount( 1 + $messageCount, $events ); - $row = array_shift( $events ); + $this->assertCount( $expectedMessageCount, $events ); + $row = array_pop( $events ); $this->assertEquals( 'edit-user-talk', $row->event_type ); $this->assertEventSectionTitle( 'Section 8', $row ); // Add a new section and a message within it - $messageCount++; + $expectedMessageCount++; $content .= "\n\n== EE ==\n\nhere we go with a new section ~~~~\n"; - $this->editPage( $talkPage, $content, '', NS_USER_TALK ); + $this->editPage( + $talkPage, + $content, + '', + NS_USER_TALK, + self::$users['sysop']->getUser() + ); // Ensure this event has the new section title $events = $this->fetchAllEvents(); - $this->assertCount( 1 + $messageCount, $events ); + $this->assertCount( $expectedMessageCount, $events ); $row = array_pop( $events ); $this->assertEquals( 'edit-user-talk', $row->event_type ); $this->assertEventSectionTitle( 'EE', $row ); @@ -68,11 +86,11 @@ class EchoTalkPageFunctionalTest extends ApiTestCase { } /** - * @return \stdClass[] All non-watchlist events in db sorted from oldest to newest + * @return \stdClass[] All talk page edit events in db sorted from oldest to newest */ protected function fetchAllEvents() { $res = $this->db->select( 'echo_event', EchoEvent::selectFields(), [ - 'event_type != "watchlist-change"' + 'event_type' => 'edit-user-talk', ], __METHOD__, [ 'ORDER BY' => 'event_id ASC' ] ); return iterator_to_array( $res ); diff --git a/Echo/tests/phpunit/ThankYouEditTest.php b/Echo/tests/phpunit/ThankYouEditTest.php index e9f89a99..a1bb0109 100644 --- a/Echo/tests/phpunit/ThankYouEditTest.php +++ b/Echo/tests/phpunit/ThankYouEditTest.php @@ -4,22 +4,22 @@ * @group Echo * @group Database */ -class MWEchoThankYouEditTest extends MediaWikiTestCase { +class MWEchoThankYouEditTest extends MediaWikiIntegrationTestCase { - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->tablesUsed[] = 'echo_event'; $this->tablesUsed[] = 'echo_notification'; } private function deleteEchoData() { - $db = MWEchoDbFactory::newFromDefault()->getEchoDb( DB_MASTER ); + $db = MWEchoDbFactory::newFromDefault()->getEchoDb( DB_PRIMARY ); $db->delete( 'echo_event', '*', __METHOD__ ); $db->delete( 'echo_notification', '*', __METHOD__ ); } /** - * @covers \EchoHooks::onPageSaveComplete + * @covers \MediaWiki\Extension\Notifications\Hooks::onPageSaveComplete */ public function testFirstEdit() { // setup @@ -41,7 +41,7 @@ class MWEchoThankYouEditTest extends MediaWikiTestCase { } /** - * @covers \EchoHooks::onPageSaveComplete + * @covers \MediaWiki\Extension\Notifications\Hooks::onPageSaveComplete */ public function testTenthEdit() { // setup @@ -70,8 +70,8 @@ class MWEchoThankYouEditTest extends MediaWikiTestCase { } private function edit( Title $title, User $user, $text ) { - $page = WikiPage::factory( $title ); + $page = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title ); $content = ContentHandler::makeContent( $text, $title ); - $page->doEditContent( $content, 'test', 0, false, $user ); + $page->doUserEditContent( $content, $user, 'test' ); } } diff --git a/Echo/tests/phpunit/UnreadWikisTest.php b/Echo/tests/phpunit/UnreadWikisTest.php new file mode 100644 index 00000000..aa62bf3e --- /dev/null +++ b/Echo/tests/phpunit/UnreadWikisTest.php @@ -0,0 +1,68 @@ +<?php + +use Wikimedia\TestingAccessWrapper; + +/** + * Tests for unread wiki database access + * + * @group Database + * @covers \EchoUnreadWikis + */ +class UnreadWikisTest extends MediaWikiIntegrationTestCase { + + public function testUpdateCount() { + $unread = TestingAccessWrapper::newFromObject( new EchoUnreadWikis( 1 ) ); + $unread->dbFactory = $this->mockMWEchoDbFactory( $this->db ); + $unread->updateCount( + 'foobar', + 2, + new MWTimestamp( '20220322222222' ), + 3, + new MWTimestamp( '20220322222223' ) + ); + $this->assertSame( + [ + 'foobar' => [ + 'alert' => [ 'count' => '2', 'ts' => '20220322222222' ], + 'message' => [ 'count' => '3', 'ts' => '20220322222223' ], + ] + ], + $unread->getUnreadCounts() + ); + } + + public function testUpdateCountFalse() { + $unread = TestingAccessWrapper::newFromObject( new EchoUnreadWikis( 1 ) ); + $unread->dbFactory = $this->mockMWEchoDbFactory( $this->db ); + $unread->updateCount( + 'foobar', + 3, + false, + 4, + false + ); + $this->assertSame( + [ + 'foobar' => [ + 'alert' => [ 'count' => '3', 'ts' => '00000000000000' ], + 'message' => [ 'count' => '4', 'ts' => '00000000000000' ], + ] + ], + $unread->getUnreadCounts() + ); + } + + /** + * Mock object of MWEchoDbFactory + * @param \Wikimedia\Rdbms\IDatabase $db + * @return MWEchoDbFactory + */ + protected function mockMWEchoDbFactory( $db ) { + $dbFactory = $this->createMock( MWEchoDbFactory::class ); + $dbFactory->expects( $this->any() ) + ->method( 'getSharedDb' ) + ->will( $this->returnValue( $db ) ); + + return $dbFactory; + } +} diff --git a/Echo/tests/phpunit/UserLocatorTest.php b/Echo/tests/phpunit/UserLocatorTest.php index bcf5b47b..6ce990d7 100644 --- a/Echo/tests/phpunit/UserLocatorTest.php +++ b/Echo/tests/phpunit/UserLocatorTest.php @@ -4,8 +4,9 @@ * @group Database * @covers \EchoUserLocator */ -class EchoUserLocatorTest extends MediaWikiTestCase { +class EchoUserLocatorTest extends MediaWikiIntegrationTestCase { + /** @inheritDoc */ protected $tablesUsed = [ 'user', 'watchlist' ]; public function testLocateUsersWatchingTitle() { @@ -19,14 +20,11 @@ class EchoUserLocatorTest extends MediaWikiTestCase { 'wl_title' => $key ]; } - wfGetDB( DB_MASTER )->insert( 'watchlist', $rows, __METHOD__ ); + wfGetDB( DB_PRIMARY )->insert( 'watchlist', $rows, __METHOD__ ); - $event = $this->getMockBuilder( EchoEvent::class ) - ->disableOriginalConstructor() - ->getMock(); - $event->expects( $this->any() ) - ->method( 'getTitle' ) - ->will( $this->returnValue( $title ) ); + $event = $this->createMock( EchoEvent::class ); + $event->method( 'getTitle' ) + ->willReturn( $title ); $it = EchoUserLocator::locateUsersWatchingTitle( $event, 10 ); $this->assertCount( 50, $it ); @@ -56,7 +54,7 @@ class EchoUserLocatorTest extends MediaWikiTestCase { // callback returning expected user ids and event title. // required because database insert must be inside test. function () { - $user = User::newFromName( 'UTUser' ); + $user = $this->getTestUser()->getUser(); $user->addToDatabase(); return [ @@ -75,10 +73,9 @@ class EchoUserLocatorTest extends MediaWikiTestCase { if ( $expect instanceof Closure ) { list( $expect, $title ) = $expect(); } - $event = $this->mockEchoEvent(); - $event->expects( $this->any() ) - ->method( 'getTitle' ) - ->will( $this->returnValue( $title ) ); + $event = $this->createMock( EchoEvent::class ); + $event->method( 'getTitle' ) + ->willReturn( $title ); $users = EchoUserLocator::locateTalkPageOwner( $event ); $this->assertEquals( $expect, array_keys( $users ), $message ); @@ -89,7 +86,7 @@ class EchoUserLocatorTest extends MediaWikiTestCase { [ 'Something', function () { - $user = User::newFromName( 'UTUser' ); + $user = $this->getTestUser()->getUser(); $user->addToDatabase(); return [ @@ -107,21 +104,17 @@ class EchoUserLocatorTest extends MediaWikiTestCase { */ public function testLocateArticleCreator( $message, $initialize ) { list( $expect, $title, $user ) = $initialize(); - WikiPage::factory( $title )->doEditContent( + $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title )->doUserEditContent( /* $content = */ ContentHandler::makeContent( 'content', $title ), - /* $summary = */ 'summary', - /* $flags = */ 0, - /* $baseRevId = */ false, - /* $user = */ $user + /* $user = */ $user, + /* $summary = */ 'summary' ); - $event = $this->mockEchoEvent(); - $event->expects( $this->any() ) - ->method( 'getTitle' ) - ->will( $this->returnValue( $title ) ); - $event->expects( $this->any() ) - ->method( 'getAgent' ) - ->will( $this->returnValue( User::newFromId( 123 ) ) ); + $event = $this->createMock( EchoEvent::class ); + $event->method( 'getTitle' ) + ->willReturn( $title ); + $event->method( 'getAgent' ) + ->willReturn( User::newFromId( 123 ) ); $users = EchoUserLocator::locateArticleCreator( $event ); $this->assertEquals( $expect, array_keys( $users ), $message ); @@ -159,10 +152,9 @@ class EchoUserLocatorTest extends MediaWikiTestCase { * @dataProvider locateEventAgentProvider */ public function testLocateEventAgent( $message, $expect, User $agent = null ) { - $event = $this->mockEchoEvent(); - $event->expects( $this->any() ) - ->method( 'getAgent' ) - ->will( $this->returnValue( $agent ) ); + $event = $this->createMock( EchoEvent::class ); + $event->method( 'getAgent' ) + ->willReturn( $agent ); $users = EchoUserLocator::locateEventAgent( $event ); $this->assertEquals( $expect, array_keys( $users ), $message ); @@ -237,12 +229,10 @@ class EchoUserLocatorTest extends MediaWikiTestCase { * @dataProvider locateFromEventExtraProvider */ public function testLocateFromEventExtra( $message, $expect, array $extra, array $keys ) { - $event = $this->mockEchoEvent(); - $event->expects( $this->any() ) - ->method( 'getExtra' ) - ->will( $this->returnValue( $extra ) ); - $event->expects( $this->any() ) - ->method( 'getExtraParam' ) + $event = $this->createMock( EchoEvent::class ); + $event->method( 'getExtra' ) + ->willReturn( $extra ); + $event->method( 'getExtraParam' ) ->will( $this->returnValueMap( self::arrayToValueMap( $extra ) ) ); $users = EchoUserLocator::locateFromEventExtra( $event, $keys ); @@ -259,9 +249,4 @@ class EchoUserLocatorTest extends MediaWikiTestCase { return $result; } - protected function mockEchoEvent() { - return $this->getMockBuilder( EchoEvent::class ) - ->disableOriginalConstructor() - ->getMock(); - } } diff --git a/Echo/tests/phpunit/api/Push/ApiEchoPushSubscriptionsCreateTest.php b/Echo/tests/phpunit/api/Push/ApiEchoPushSubscriptionsCreateTest.php deleted file mode 100644 index 5361309d..00000000 --- a/Echo/tests/phpunit/api/Push/ApiEchoPushSubscriptionsCreateTest.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php - -/** - * @group medium - * @group API - * @group Database - * @covers \EchoPush\Api\ApiEchoPushSubscriptionsCreate - */ -class ApiEchoPushSubscriptionsCreateTest extends ApiTestCase { - - /** @var User */ - private $user; - - public function setUp(): void { - parent::setUp(); - $this->setMwGlobals( 'wgEchoEnablePush', true ); - $this->tablesUsed[] = 'echo_push_subscription'; - $this->tablesUsed[] = 'echo_push_provider'; - $this->user = $this->getTestUser()->getUser(); - $this->createTestData(); - } - - public function testApiCreateSubscription(): void { - $params = [ - 'action' => 'echopushsubscriptions', - 'command' => 'create', - 'provider' => 'fcm', - 'providertoken' => 'ABC123', - ]; - $result = $this->doApiRequestWithToken( $params, null, $this->user ); - $this->assertEquals( 'Success', $result[0]['create']['result'] ); - } - - public function testApiCreateSubscriptionTokenExists(): void { - $params = [ - 'action' => 'echopushsubscriptions', - 'command' => 'create', - 'provider' => 'fcm', - 'providertoken' => 'XYZ789', - ]; - $this->expectException( ApiUsageException::class ); - $this->doApiRequestWithToken( $params, null, $this->user ); - } - - private function createTestData(): void { - $subscriptionManager = EchoServices::getInstance()->getPushSubscriptionManager(); - $subscriptionManager->create( $this->user, 'fcm', 'XYZ789' ); - } - -} diff --git a/Echo/tests/phpunit/api/Push/ApiEchoPushSubscriptionsDeleteTest.php b/Echo/tests/phpunit/api/Push/ApiEchoPushSubscriptionsDeleteTest.php deleted file mode 100644 index f2ec0d66..00000000 --- a/Echo/tests/phpunit/api/Push/ApiEchoPushSubscriptionsDeleteTest.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php - -/** - * @group medium - * @group API - * @group Database - * @covers \EchoPush\Api\ApiEchoPushSubscriptionsDelete - */ -class ApiEchoPushSubscriptionsDeleteTest extends ApiTestCase { - - /** @var User */ - private $user; - - public function setUp(): void { - parent::setUp(); - $this->setMwGlobals( 'wgEchoEnablePush', true ); - $this->tablesUsed[] = 'echo_push_subscription'; - $this->tablesUsed[] = 'echo_push_provider'; - $this->user = $this->getTestUser()->getUser(); - $this->createTestData(); - } - - public function testApiDeleteSubscription(): void { - $params = [ - 'action' => 'echopushsubscriptions', - 'command' => 'delete', - 'providertoken' => 'XYZ789', - ]; - $result = $this->doApiRequestWithToken( $params, null, $this->user ); - $this->assertEquals( 'Success', $result[0]['delete']['result'] ); - } - - public function testApiDeleteSubscriptionNotFound(): void { - $params = [ - 'action' => 'echopushsubscriptions', - 'command' => 'delete', - 'providertoken' => 'ABC123', - ]; - $this->expectException( ApiUsageException::class ); - $this->doApiRequestWithToken( $params, null, $this->user ); - } - - private function createTestData(): void { - $subscriptionManager = EchoServices::getInstance()->getPushSubscriptionManager(); - $subscriptionManager->create( $this->user, 'fcm', 'XYZ789' ); - } - -} diff --git a/Echo/tests/phpunit/cache/TitleLocalCacheTest.php b/Echo/tests/phpunit/cache/TitleLocalCacheTest.php index c046b6ba..b7cd0228 100644 --- a/Echo/tests/phpunit/cache/TitleLocalCacheTest.php +++ b/Echo/tests/phpunit/cache/TitleLocalCacheTest.php @@ -6,7 +6,7 @@ use Wikimedia\TestingAccessWrapper; * @covers \EchoTitleLocalCache * @group Database */ -class EchoTitleLocalCacheTest extends MediaWikiTestCase { +class EchoTitleLocalCacheTest extends MediaWikiIntegrationTestCase { public function testCreate() { $cache = EchoTitleLocalCache::create(); @@ -15,13 +15,13 @@ class EchoTitleLocalCacheTest extends MediaWikiTestCase { public function testAdd() { $cache = $this->getMockBuilder( EchoTitleLocalCache::class ) - ->setMethods( [ 'resolve' ] )->getMock(); + ->onlyMethods( [ 'resolve' ] )->getMock(); $cache->add( 1 ); $cache->add( 9 ); // Resolutions should be batched - $cache->expects( $this->exactly( 1 ) )->method( 'resolve' ) + $cache->expects( $this->once() )->method( 'resolve' ) ->with( [ 1, 9 ] )->willReturn( [] ); // Trigger @@ -30,7 +30,7 @@ class EchoTitleLocalCacheTest extends MediaWikiTestCase { public function testGet() { $cache = $this->getMockBuilder( EchoTitleLocalCache::class ) - ->setMethods( [ 'resolve' ] )->getMock(); + ->onlyMethods( [ 'resolve' ] )->getMock(); $cachePriv = TestingAccessWrapper::newFromObject( $cache ); // First title included in cache @@ -38,7 +38,7 @@ class EchoTitleLocalCacheTest extends MediaWikiTestCase { $cachePriv->targets->set( $res1['id'], $res1['title'] ); // Second title not in internal cache, resolves from db. $res2 = $this->insertPage( 'EchoTitleLocalCacheTest_testGet2' ); - $cache->expects( $this->exactly( 1 ) )->method( 'resolve' ) + $cache->expects( $this->once() )->method( 'resolve' ) ->with( [ $res2['id'] ] ) ->willReturn( [ $res2['id'] => $res2['title'] ] ); @@ -55,7 +55,7 @@ class EchoTitleLocalCacheTest extends MediaWikiTestCase { public function testClearAll() { $cache = $this->getMockBuilder( EchoTitleLocalCache::class ) - ->setMethods( [ 'resolve' ] )->getMock(); + ->onlyMethods( [ 'resolve' ] )->getMock(); // Add 1 to cache $cachePriv = TestingAccessWrapper::newFromObject( $cache ); @@ -68,7 +68,7 @@ class EchoTitleLocalCacheTest extends MediaWikiTestCase { $this->assertNull( $cache->get( 1 ), 'Cache was cleared' ); // Lookups batch was cleared - $cache->expects( $this->exactly( 1 ) )->method( 'resolve' ) + $cache->expects( $this->once() )->method( 'resolve' ) ->with( [ 4 ] ) ->willReturn( [] ); $cache->add( 4 ); @@ -79,9 +79,7 @@ class EchoTitleLocalCacheTest extends MediaWikiTestCase { * @return Title */ protected function mockTitle() { - $title = $this->getMockBuilder( Title::class ) - ->disableOriginalConstructor() - ->getMock(); + $title = $this->createMock( Title::class ); return $title; } diff --git a/Echo/tests/phpunit/controller/NotificationControllerTest.php b/Echo/tests/phpunit/controller/NotificationControllerTest.php index c7bfb064..954570e6 100644 --- a/Echo/tests/phpunit/controller/NotificationControllerTest.php +++ b/Echo/tests/phpunit/controller/NotificationControllerTest.php @@ -1,9 +1,12 @@ <?php +use MediaWiki\User\UserOptionsLookup; +use Wikimedia\TestingAccessWrapper; + /** * @covers \EchoNotificationController */ -class NotificationControllerTest extends MediaWikiTestCase { +class NotificationControllerTest extends MediaWikiIntegrationTestCase { public function evaluateUserLocatorsProvider() { return [ @@ -28,7 +31,7 @@ class NotificationControllerTest extends MediaWikiTestCase { // expected result [ [ 123 ] ], // event user locator config - function () { + static function () { return [ 123 => 123 ]; } ], @@ -39,10 +42,10 @@ class NotificationControllerTest extends MediaWikiTestCase { [ [ 123 ], [ 456 ] ], // event user locator config [ - function () { + static function () { return [ 123 => 123 ]; }, - function () { + static function () { return [ 456 => 456 ]; }, ], @@ -57,7 +60,7 @@ class NotificationControllerTest extends MediaWikiTestCase { [ [ EchoUserLocator::class, 'locateFromEventExtra' ], [ 'other-user' ] ], ], // additional setup - function ( $test, $event ) { + static function ( $test, $event ) { $event->expects( $test->any() ) ->method( 'getExtraParam' ) ->with( 'other-user' ) @@ -79,12 +82,9 @@ class NotificationControllerTest extends MediaWikiTestCase { ], ] ); - $event = $this->getMockBuilder( EchoEvent::class ) - ->disableOriginalConstructor() - ->getMock(); - $event->expects( $this->any() ) - ->method( 'getType' ) - ->will( $this->returnValue( 'unit-test' ) ); + $event = $this->createMock( EchoEvent::class ); + $event->method( 'getType' ) + ->willReturn( 'unit-test' ); if ( $setup !== null ) { $setup( $this, $event ); @@ -95,11 +95,10 @@ class NotificationControllerTest extends MediaWikiTestCase { } public function testEvaluateUserLocatorPassesParameters() { - $test = $this; - $callback = function ( $event, $firstOption, $secondOption ) use ( $test ) { - $test->assertInstanceOf( EchoEvent::class, $event ); - $test->assertEquals( 'first', $firstOption ); - $test->assertEquals( 'second', $secondOption ); + $callback = function ( $event, $firstOption, $secondOption ) { + $this->assertInstanceOf( EchoEvent::class, $event ); + $this->assertEquals( 'first', $firstOption ); + $this->assertEquals( 'second', $secondOption ); return []; }; @@ -134,7 +133,7 @@ class NotificationControllerTest extends MediaWikiTestCase { // expected result [ 123 ], // users returned from locator - [ null, 'foo', User::newFromId( 123 ), new stdClass, 456 ], + [ null, 'foo', User::newFromId( 123 ), (object)[], 456 ], ], ]; } @@ -150,19 +149,16 @@ class NotificationControllerTest extends MediaWikiTestCase { $this->setMwGlobals( [ 'wgEchoNotifications' => [ 'unit-test' => [ - EchoAttributeManager::ATTR_LOCATORS => function () use ( $users ) { + EchoAttributeManager::ATTR_LOCATORS => static function () use ( $users ) { return $users; }, ], ], ] ); - $event = $this->getMockBuilder( EchoEvent::class ) - ->disableOriginalConstructor() - ->getMock(); - $event->expects( $this->any() ) - ->method( 'getType' ) - ->will( $this->returnValue( 'unit-test' ) ); + $event = $this->createMock( EchoEvent::class ); + $event->method( 'getType' ) + ->willReturn( 'unit-test' ); $result = EchoNotificationController::getUsersToNotifyForEvent( $event ); $ids = []; @@ -173,12 +169,9 @@ class NotificationControllerTest extends MediaWikiTestCase { } public function testDoesNotDeliverDisabledEvent() { - $event = $this->getMockBuilder( EchoEvent::class ) - ->disableOriginalConstructor() - ->getMock(); - $event->expects( $this->any() ) - ->method( 'isEnabledEvent' ) - ->will( $this->returnValue( false ) ); + $event = $this->createMock( EchoEvent::class ); + $event->method( 'isEnabledEvent' ) + ->willReturn( false ); // Assume it would have to check the event type to // determine how to deliver $event->expects( $this->never() ) @@ -261,4 +254,138 @@ class NotificationControllerTest extends MediaWikiTestCase { $result = EchoNotificationController::getEventNotifyTypes( $type ); $this->assertEquals( $expect, $result, $message ); } + + public function testEnqueueEvent() { + $event = $this->createMock( EchoEvent::class ); + $event->method( 'getExtraParam' ) + ->willReturn( null ); + $event->expects( $this->once() ) + ->method( 'getTitle' ) + ->willReturn( Title::newFromText( 'test-title' ) ); + $event->expects( $this->once() ) + ->method( 'getId' ) + ->willReturn( 42 ); + EchoNotificationController::enqueueEvent( $event ); + $jobQueueGroup = $this->getServiceContainer()->getJobQueueGroup(); + $queues = $jobQueueGroup->getQueuesWithJobs(); + $this->assertCount( 1, $queues ); + $this->assertEquals( 'EchoNotificationJob', $queues[0] ); + $job = $jobQueueGroup->pop( 'EchoNotificationJob' ); + $this->assertEquals( 'Test-title', $job->params[ 'title' ] ); + $this->assertEquals( 42, $job->params[ 'eventId' ] ); + } + + public function testNotSupportedDelay() { + $queueGroup = $this->getServiceContainer()->getJobQueueGroup(); + $this->assertCount( 0, $queueGroup->getQueuesWithJobs() ); + + $event = $this->createMock( EchoEvent::class ); + $event->method( 'getExtraParam' ) + ->will( $this->returnValueMap( + [ + [ 'delay', null, 120 ], + [ 'rootJobSignature', null, 'test-signature' ], + [ 'rootJobTimestamp', null, wfTimestamp() ] + ] + ) ); + $event->expects( $this->once() ) + ->method( 'getTitle' ) + ->willReturn( Title::newFromText( 'test-title' ) ); + $event->method( 'getId' ) + ->willReturn( 42 ); + EchoNotificationController::enqueueEvent( $event ); + + $this->assertCount( 0, $queueGroup->getQueuesWithJobs() ); + } + + public function testEventParams() { + $rootJobTimestamp = wfTimestamp(); + MWTimestamp::setFakeTime( 0 ); + + $event = $this->createMock( EchoEvent::class ); + $event->method( 'getExtraParam' ) + ->will( $this->returnValueMap( + [ + [ 'delay', null, 10 ], + [ 'rootJobSignature', null, 'test-signature' ], + [ 'rootJobTimestamp', null, $rootJobTimestamp ] + ] + ) ); + $event->expects( $this->once() ) + ->method( 'getId' ) + ->willReturn( 42 ); + + $params = EchoNotificationController::getEventParams( $event ); + $expectedParams = [ + 'eventId' => 42, + 'rootJobSignature' => 'test-signature', + 'rootJobTimestamp' => $rootJobTimestamp, + 'jobReleaseTimestamp' => 10 + ]; + $this->assertArrayEquals( $expectedParams, $params ); + } + + /** + * @dataProvider PageLinkedTitleMutedByUserDataProvider + * @covers EchoNotificationController::isPageLinkedTitleMutedByUser + * @param Title $title + * @param User $user + * @param UserOptionsLookup $userOptionsLookup + * @param bool $expected + */ + public function testIsPageLinkedTitleMutedByUser( + Title $title, User $user, UserOptionsLookup $userOptionsLookup, $expected ): void { + $wrapper = TestingAccessWrapper::newFromClass( EchoNotificationController::class ); + $wrapper->mutedPageLinkedTitlesCache = $this->createMock( MapCacheLRU::class ); + $this->setService( 'UserOptionsLookup', $userOptionsLookup ); + $this->assertSame( + $expected, + $wrapper->isPageLinkedTitleMutedByUser( $title, $user ) + ); + } + + public function PageLinkedTitleMutedByUserDataProvider(): array { + return [ + [ + $this->getMockTitle( 123 ), + $this->getMockUser(), + $this->getUserOptionsLookupMock( [] ), + false + ], + [ + $this->getMockTitle( 123 ), + $this->getMockUser(), + $this->getUserOptionsLookupMock( [ 123, 456, 789 ] ), + true + ], + [ + $this->getMockTitle( 456 ), + $this->getMockUser(), + $this->getUserOptionsLookupMock( [ 489 ] ), + false + ] + + ]; + } + + private function getMockTitle( int $articleID ) { + $title = $this->createMock( Title::class ); + $title->method( 'getArticleID' ) + ->willReturn( $articleID ); + return $title; + } + + private function getMockUser() { + $user = $this->createMock( User::class ); + $user->method( 'getId' ) + ->willReturn( 456 ); + return $user; + } + + private function getUserOptionsLookupMock( $mutedTitlePreferences = [] ) { + $userOptionsLookupMock = $this->createMock( UserOptionsLookup::class ); + $userOptionsLookupMock->method( 'getOption' ) + ->willReturn( implode( "\n", $mutedTitlePreferences ) ); + return $userOptionsLookupMock; + } } diff --git a/Echo/tests/phpunit/unit/EchoContainmentSetTest.php b/Echo/tests/phpunit/integration/EchoContainmentSetTest.php index edf8cf92..e0869dd1 100644 --- a/Echo/tests/phpunit/unit/EchoContainmentSetTest.php +++ b/Echo/tests/phpunit/integration/EchoContainmentSetTest.php @@ -1,14 +1,15 @@ <?php +use MediaWiki\User\UserOptionsLookup; + /** * @coversDefaultClass EchoContainmentSet */ -class EchoContainmentSetTest extends \MediaWikiUnitTestCase { +class EchoContainmentSetTest extends MediaWikiIntegrationTestCase { /** * @covers ::addTitleIDsFromUserOption * @dataProvider addTitlesFromUserOptionProvider - * @param User $user * @param string $prefData * @param string $contains * @param bool $expected @@ -16,15 +17,15 @@ class EchoContainmentSetTest extends \MediaWikiUnitTestCase { public function testAddTitlesFromUserOption( $prefData, string $contains, bool $expected ) { - $user = $this->getDefaultUserMock(); - $user->method( 'getOption' ) - ->willReturn( $prefData ); - $containmentSet = new EchoContainmentSet( $user ); + $userOptionsLookupMock = $this->createMock( UserOptionsLookup::class ); + $userOptionsLookupMock->method( 'getOption' )->willReturn( $prefData ); + $this->setService( 'UserOptionsLookup', $userOptionsLookupMock ); + $containmentSet = new EchoContainmentSet( $this->createMock( User::class ) ); $containmentSet->addTitleIDsFromUserOption( 'preference-name' ); $this->assertSame( $expected, $containmentSet->contains( $contains ) ); } - public function addTitlesFromUserOptionProvider() :array { + public function addTitlesFromUserOptionProvider(): array { return [ [ 'foo', @@ -50,10 +51,4 @@ class EchoContainmentSetTest extends \MediaWikiUnitTestCase { ]; } - private function getDefaultUserMock() { - return $this->getMockBuilder( User::class ) - ->disableOriginalConstructor() - ->getMock(); - } - } diff --git a/Echo/tests/phpunit/integration/EchoServicesTest.php b/Echo/tests/phpunit/integration/EchoServicesTest.php index 60c46855..e7f9a3d3 100644 --- a/Echo/tests/phpunit/integration/EchoServicesTest.php +++ b/Echo/tests/phpunit/integration/EchoServicesTest.php @@ -1,7 +1,7 @@ <?php -use EchoPush\NotificationServiceClient; -use EchoPush\SubscriptionManager; +use MediaWiki\Extension\Notifications\Push\NotificationServiceClient; +use MediaWiki\Extension\Notifications\Push\SubscriptionManager; use MediaWiki\MediaWikiServices; /** @covers EchoServices */ @@ -10,7 +10,7 @@ class EchoServicesTest extends MediaWikiIntegrationTestCase { /** @var EchoServices */ private $echoServices; - public function setUp(): void { + protected function setUp(): void { parent::setUp(); $this->echoServices = EchoServices::getInstance(); } @@ -30,4 +30,9 @@ class EchoServicesTest extends MediaWikiIntegrationTestCase { $this->assertInstanceOf( SubscriptionManager::class, $subscriptionManager ); } + public function testGetAttributeManager(): void { + $attributeManager = $this->echoServices->getAttributeManager(); + $this->assertInstanceOf( EchoAttributeManager::class, $attributeManager ); + } + } diff --git a/Echo/tests/phpunit/integration/Push/NotificationServiceClientTest.php b/Echo/tests/phpunit/integration/Push/NotificationServiceClientTest.php index 26cb868d..ebda7c41 100644 --- a/Echo/tests/phpunit/integration/Push/NotificationServiceClientTest.php +++ b/Echo/tests/phpunit/integration/Push/NotificationServiceClientTest.php @@ -2,10 +2,13 @@ use Wikimedia\TestingAccessWrapper; -/** @covers \EchoPush\NotificationServiceClient */ +/** @covers \MediaWiki\Extension\Notifications\Push\NotificationServiceClient */ class NotificationServiceClientTest extends MediaWikiIntegrationTestCase { + use MockHttpTrait; public function testConstructRequest(): void { + $this->installMockHttp( 'hi' ); + $client = EchoServices::getInstance()->getPushNotificationServiceClient(); $client = TestingAccessWrapper::newFromObject( $client ); $payload = [ 'deviceTokens' => [ 'foo' ], 'messageType' => 'checkEchoV1' ]; diff --git a/Echo/tests/phpunit/integration/Push/PushNotifierTest.php b/Echo/tests/phpunit/integration/Push/PushNotifierTest.php index 1e60f230..117975a7 100644 --- a/Echo/tests/phpunit/integration/Push/PushNotifierTest.php +++ b/Echo/tests/phpunit/integration/Push/PushNotifierTest.php @@ -1,16 +1,17 @@ <?php -use EchoPush\NotificationRequestJob; -use EchoPush\PushNotifier; +use MediaWiki\Extension\Notifications\Push\NotificationRequestJob; +use MediaWiki\Extension\Notifications\Push\PushNotifier; +use MediaWiki\Extension\Notifications\Push\Utils; use Wikimedia\TestingAccessWrapper; -/** @covers \EchoPush\PushNotifier */ +/** @covers \MediaWiki\Extension\Notifications\Push\PushNotifier */ class PushNotifierTest extends MediaWikiIntegrationTestCase { public function testCreateJob(): void { $notifier = TestingAccessWrapper::newFromClass( PushNotifier::class ); $user = $this->getTestUser()->getUser(); - $centralId = CentralIdLookup::factory()->centralIdFromLocalUser( $user ); + $centralId = Utils::getPushUserId( $user ); $job = $notifier->createJob( $user ); $this->assertInstanceOf( NotificationRequestJob::class, $job ); $this->assertSame( 'EchoPushNotificationRequest', $job->getType() ); diff --git a/Echo/tests/phpunit/integration/Push/SubscriptionManagerTest.php b/Echo/tests/phpunit/integration/Push/SubscriptionManagerTest.php index 7a9f32f1..ec173154 100644 --- a/Echo/tests/phpunit/integration/Push/SubscriptionManagerTest.php +++ b/Echo/tests/phpunit/integration/Push/SubscriptionManagerTest.php @@ -1,27 +1,44 @@ <?php +use MediaWiki\Extension\Notifications\Push\Utils; +use Wikimedia\TestingAccessWrapper; + /** * @group Database - * @covers \EchoPush\SubscriptionManager + * @covers \MediaWiki\Extension\Notifications\Push\SubscriptionManager */ class SubscriptionManagerTest extends MediaWikiIntegrationTestCase { - public function setUp(): void { + protected function setUp(): void { parent::setUp(); $this->tablesUsed[] = 'echo_push_subscription'; $this->tablesUsed[] = 'echo_push_provider'; + $this->setMwGlobals( 'wgEchoPushMaxSubscriptionsPerUser', 1 ); } public function testManagePushSubscriptions(): void { - $subscriptionManager = EchoServices::getInstance()->getPushSubscriptionManager(); + $subscriptionManagerBase = EchoServices::getInstance()->getPushSubscriptionManager(); + $subscriptionManager = TestingAccessWrapper::newFromObject( $subscriptionManagerBase ); + $user = $this->getTestUser()->getUser(); - $centralId = CentralIdLookup::factory()->centralIdFromLocalUser( $user ); - $subscriptionManager->create( $user, 'test', 'ABC123' ); + $centralId = Utils::getPushUserId( $user ); + + $subscriptionManager->create( 'test', 'ABC123', $centralId ); $subscriptions = $subscriptionManager->getSubscriptionsForUser( $centralId ); $this->assertCount( 1, $subscriptions ); - $subscriptionManager->delete( $user, 'ABC123' ); + + $subscriptionManager->delete( [ 'ABC123' ], $centralId ); $subscriptions = $subscriptionManager->getSubscriptionsForUser( $centralId ); $this->assertCount( 0, $subscriptions ); + + $subscriptionManager->create( 'test', 'ABC123', $centralId ); + $subscriptions = $subscriptionManager->getSubscriptionsForUser( $centralId ); + $this->assertCount( 1, $subscriptions ); + + $subscriptionManager->create( 'test', 'DEF456', $centralId ); + $subscriptions = $subscriptionManager->getSubscriptionsForUser( $centralId ); + $this->assertCount( 1, $subscriptions ); + $this->assertEquals( 'DEF456', $subscriptions[0]->getToken() ); } } diff --git a/Echo/tests/phpunit/integration/Push/UtilsTest.php b/Echo/tests/phpunit/integration/Push/UtilsTest.php new file mode 100644 index 00000000..0ec5e138 --- /dev/null +++ b/Echo/tests/phpunit/integration/Push/UtilsTest.php @@ -0,0 +1,19 @@ +<?php + +use MediaWiki\Extension\Notifications\Push\Utils; + +/** @covers \MediaWiki\Extension\Notifications\Push\Utils */ +class UtilsTest extends MediaWikiIntegrationTestCase { + + public function testGetLoggedInPushId(): void { + $user = $this->getTestUser()->getUser(); + $this->assertGreaterThan( 0, Utils::getPushUserId( $user ) ); + } + + public function testGetLoggedOutPushId(): void { + $user = $this->getTestUser()->getUser(); + $user->doLogout(); + $this->assertSame( 0, Utils::getPushUserId( $user ) ); + } + +} diff --git a/Echo/tests/phpunit/maintenance/SupressionMaintenanceTest.php b/Echo/tests/phpunit/maintenance/SupressionMaintenanceTest.php index 31149b46..a0b7cf4c 100644 --- a/Echo/tests/phpunit/maintenance/SupressionMaintenanceTest.php +++ b/Echo/tests/phpunit/maintenance/SupressionMaintenanceTest.php @@ -6,7 +6,7 @@ use PHPUnit\Framework\TestCase; * @group Echo * @covers \EchoSuppressionRowUpdateGenerator */ -class SuppressionMaintenanceTest extends MediaWikiTestCase { +class SuppressionMaintenanceTest extends MediaWikiIntegrationTestCase { public static function provider_updateRow() { $input = [ @@ -103,7 +103,7 @@ class SuppressionMaintenanceTest extends MediaWikiTestCase { } protected static function attachTitleFor( $id, $providedText, $providedNamespace ) { - return function ( + return static function ( TestCase $test, EchoSuppressionRowUpdateGenerator $gen ) use ( $id, $providedText, $providedNamespace ) { @@ -114,7 +114,7 @@ class SuppressionMaintenanceTest extends MediaWikiTestCase { $titles = [ $providedNamespace => [ $providedText => $title ] ]; - $gen->setNewTitleFromNsAndText( function ( $namespace, $text ) use ( $titles ) { + $gen->setNewTitleFromNsAndText( static function ( $namespace, $text ) use ( $titles ) { return $titles[$namespace][$text] ?? Title::makeTitleSafe( $namespace, $text ); } ); }; diff --git a/Echo/tests/phpunit/mapper/EchoExecuteFirstArgumentStub.php b/Echo/tests/phpunit/mapper/EchoExecuteFirstArgumentStub.php index 8ecf0609..5281b76f 100644 --- a/Echo/tests/phpunit/mapper/EchoExecuteFirstArgumentStub.php +++ b/Echo/tests/phpunit/mapper/EchoExecuteFirstArgumentStub.php @@ -16,7 +16,7 @@ class EchoExecuteFirstArgumentStub implements Stub { return call_user_func( reset( $invocation->arguments ) ); } - public function toString() : string { + public function toString(): string { return 'return result of call_user_func on first invocation argument'; } } diff --git a/Echo/tests/phpunit/mapper/EventMapperTest.php b/Echo/tests/phpunit/mapper/EventMapperTest.php index f42615f6..e676075b 100644 --- a/Echo/tests/phpunit/mapper/EventMapperTest.php +++ b/Echo/tests/phpunit/mapper/EventMapperTest.php @@ -6,9 +6,9 @@ use Wikimedia\Rdbms\IDatabase; * @group Database * @covers \EchoEventMapper */ -class EchoEventMapperTest extends MediaWikiTestCase { +class EchoEventMapperTest extends MediaWikiIntegrationTestCase { - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->tablesUsed[] = 'echo_event'; $this->tablesUsed[] = 'echo_notification'; @@ -79,31 +79,27 @@ class EchoEventMapperTest extends MediaWikiTestCase { * @return EchoEvent */ protected function mockEchoEvent() { - $event = $this->getMockBuilder( EchoEvent::class ) - ->disableOriginalConstructor() - ->getMock(); - $event->expects( $this->any() ) - ->method( 'toDbArray' ) - ->will( $this->returnValue( [] ) ); + $event = $this->createMock( EchoEvent::class ); + $event->method( 'toDbArray' ) + ->willReturn( [] ); return $event; } /** + * @param array $dbResult * @return MWEchoDbFactory */ protected function mockMWEchoDbFactory( $dbResult ) { - $dbFactory = $this->getMockBuilder( MWEchoDbFactory::class ) - ->disableOriginalConstructor() - ->getMock(); - $dbFactory->expects( $this->any() ) - ->method( 'getEchoDb' ) - ->will( $this->returnValue( $this->mockDb( $dbResult ) ) ); + $dbFactory = $this->createMock( MWEchoDbFactory::class ); + $dbFactory->method( 'getEchoDb' ) + ->willReturn( $this->mockDb( $dbResult ) ); return $dbFactory; } /** + * @param array $dbResult * @return IDatabase */ protected function mockDb( array $dbResult ) { @@ -114,18 +110,14 @@ class EchoEventMapperTest extends MediaWikiTestCase { 'selectRow' => '' ]; $db = $this->createMock( IDatabase::class ); - $db->expects( $this->any() ) - ->method( 'insert' ) - ->will( $this->returnValue( $dbResult['insert'] ) ); - $db->expects( $this->any() ) - ->method( 'insertId' ) - ->will( $this->returnValue( $dbResult['insertId'] ) ); - $db->expects( $this->any() ) - ->method( 'select' ) - ->will( $this->returnValue( $dbResult['select'] ) ); - $db->expects( $this->any() ) - ->method( 'selectRow' ) - ->will( $this->returnValue( $dbResult['selectRow'] ) ); + $db->method( 'insert' ) + ->willReturn( $dbResult['insert'] ); + $db->method( 'insertId' ) + ->willReturn( $dbResult['insertId'] ); + $db->method( 'select' ) + ->willReturn( $dbResult['select'] ); + $db->method( 'selectRow' ) + ->willReturn( $dbResult['selectRow'] ); return $db; } diff --git a/Echo/tests/phpunit/mapper/NotificationMapperTest.php b/Echo/tests/phpunit/mapper/NotificationMapperTest.php index 27a2698a..80ba183f 100644 --- a/Echo/tests/phpunit/mapper/NotificationMapperTest.php +++ b/Echo/tests/phpunit/mapper/NotificationMapperTest.php @@ -5,7 +5,7 @@ use Wikimedia\Rdbms\IDatabase; /** * @covers \EchoNotificationMapper */ -class EchoNotificationMapperTest extends MediaWikiTestCase { +class EchoNotificationMapperTest extends MediaWikiIntegrationTestCase { /** * @todo write this test @@ -32,7 +32,7 @@ class EchoNotificationMapperTest extends MediaWikiTestCase { 'event_agent_ip' => '', 'notification_user' => 1, 'notification_timestamp' => '20140615101010', - 'notification_read_timestamp' => '', + 'notification_read_timestamp' => null, 'notification_bundle_hash' => 'testhash', ] ]; @@ -131,8 +131,8 @@ class EchoNotificationMapperTest extends MediaWikiTestCase { public function testDeleteByUserEventOffset() { $this->setMwGlobals( [ 'wgUpdateRowsPerQuery' => 4 ] ); $mockDb = $this->createMock( IDatabase::class ); - $makeResultRows = function ( $eventIds ) { - return new ArrayIterator( array_map( function ( $eventId ) { + $makeResultRows = static function ( $eventIds ) { + return new ArrayIterator( array_map( static function ( $eventId ) { return (object)[ 'notification_event' => $eventId ]; }, $eventIds ) ); }; @@ -155,38 +155,38 @@ class EchoNotificationMapperTest extends MediaWikiTestCase { ->method( 'delete' ) ->withConsecutive( [ - $this->equalTo( 'echo_notification' ), - $this->equalTo( [ 'notification_user' => 1, 'notification_event' => [ 1, 2, 3, 5 ] ] ), + 'echo_notification', + [ 'notification_user' => 1, 'notification_event' => [ 1, 2, 3, 5 ] ], $this->anything() ], [ - $this->equalTo( 'echo_notification' ), - $this->equalTo( [ 'notification_user' => 1, 'notification_event' => [ 8, 13, 21, 34 ] ] ), + 'echo_notification', + [ 'notification_user' => 1, 'notification_event' => [ 8, 13, 21, 34 ] ], $this->anything() ], [ - $this->equalTo( 'echo_event' ), - $this->equalTo( [ 'event_id' => [ 13, 21 ] ] ), + 'echo_event', + [ 'event_id' => [ 13, 21 ] ], $this->anything() ], [ - $this->equalTo( 'echo_target_page' ), - $this->equalTo( [ 'etp_event' => [ 13, 21 ] ] ), + 'echo_target_page', + [ 'etp_event' => [ 13, 21 ] ], $this->anything() ], [ - $this->equalTo( 'echo_notification' ), - $this->equalTo( [ 'notification_user' => 1, 'notification_event' => [ 55, 89 ] ] ), + 'echo_notification', + [ 'notification_user' => 1, 'notification_event' => [ 55, 89 ] ], $this->anything() ], [ - $this->equalTo( 'echo_event' ), - $this->equalTo( [ 'event_id' => [ 55 ] ] ), + 'echo_event', + [ 'event_id' => [ 55 ] ], $this->anything() ], [ - $this->equalTo( 'echo_target_page' ), - $this->equalTo( [ 'etp_event' => [ 55 ] ] ), + 'echo_target_page', + [ 'etp_event' => [ 55 ] ], $this->anything() ] ) @@ -198,34 +198,24 @@ class EchoNotificationMapperTest extends MediaWikiTestCase { /** * Mock object of User + * @return User */ protected function mockUser() { - $user = $this->getMockBuilder( User::class ) - ->disableOriginalConstructor() - ->getMock(); - $user->expects( $this->any() ) - ->method( 'getID' ) - ->will( $this->returnValue( 1 ) ); - $user->expects( $this->any() ) - ->method( 'getOption' ) - ->will( $this->returnValue( true ) ); - $user->expects( $this->any() ) - ->method( 'getGroups' ) - ->will( $this->returnValue( [ 'echo_group' ] ) ); + $user = $this->createMock( User::class ); + $user->method( 'getID' ) + ->willReturn( 1 ); return $user; } /** * Mock object of EchoNotification + * @return EchoNotification */ protected function mockEchoNotification() { - $event = $this->getMockBuilder( EchoNotification::class ) - ->disableOriginalConstructor() - ->getMock(); - $event->expects( $this->any() ) - ->method( 'toDbArray' ) - ->will( $this->returnValue( [] ) ); + $event = $this->createMock( EchoNotification::class ); + $event->method( 'toDbArray' ) + ->willReturn( [] ); return $event; } @@ -233,21 +223,20 @@ class EchoNotificationMapperTest extends MediaWikiTestCase { /** * Mock object of MWEchoDbFactory * @param array|\Wikimedia\Rdbms\IDatabase $dbResultOrMockDb + * @return MWEchoDbFactory */ protected function mockMWEchoDbFactory( $dbResultOrMockDb ) { $mockDb = is_array( $dbResultOrMockDb ) ? $this->mockDb( $dbResultOrMockDb ) : $dbResultOrMockDb; - $dbFactory = $this->getMockBuilder( MWEchoDbFactory::class ) - ->disableOriginalConstructor() - ->getMock(); - $dbFactory->expects( $this->any() ) - ->method( 'getEchoDb' ) - ->will( $this->returnValue( $mockDb ) ); + $dbFactory = $this->createMock( MWEchoDbFactory::class ); + $dbFactory->method( 'getEchoDb' ) + ->willReturn( $mockDb ); return $dbFactory; } /** * Returns a mock database object + * @param array $dbResult * @return \Wikimedia\Rdbms\IDatabase */ protected function mockDb( array $dbResult ) { @@ -259,20 +248,15 @@ class EchoNotificationMapperTest extends MediaWikiTestCase { ]; $db = $this->createMock( IDatabase::class ); - $db->expects( $this->any() ) - ->method( 'insert' ) - ->will( $this->returnValue( $dbResult['insert'] ) ); - $db->expects( $this->any() ) - ->method( 'select' ) - ->will( $this->returnValue( $dbResult['select'] ) ); - $db->expects( $this->any() ) - ->method( 'delete' ) - ->will( $this->returnValue( $dbResult['delete'] ) ); - $db->expects( $this->any() ) - ->method( 'selectRow' ) - ->will( $this->returnValue( $dbResult['selectRow'] ) ); - $db->expects( $this->any() ) - ->method( 'onTransactionCommitOrIdle' ) + $db->method( 'insert' ) + ->willReturn( $dbResult['insert'] ); + $db->method( 'select' ) + ->willReturn( $dbResult['select'] ); + $db->method( 'delete' ) + ->willReturn( $dbResult['delete'] ); + $db->method( 'selectRow' ) + ->willReturn( $dbResult['selectRow'] ); + $db->method( 'onTransactionCommitOrIdle' ) ->will( new EchoExecuteFirstArgumentStub ); return $db; diff --git a/Echo/tests/phpunit/model/NotificationTest.php b/Echo/tests/phpunit/model/NotificationTest.php index 92727589..f9ebc625 100644 --- a/Echo/tests/phpunit/model/NotificationTest.php +++ b/Echo/tests/phpunit/model/NotificationTest.php @@ -3,7 +3,7 @@ /** * @covers \EchoNotification */ -class EchoNotificationTest extends MediaWikiTestCase { +class EchoNotificationTest extends MediaWikiIntegrationTestCase { public function testNewFromRow() { $row = $this->mockNotificationRow() + $this->mockEventRow(); @@ -47,19 +47,21 @@ class EchoNotificationTest extends MediaWikiTestCase { /** * Mock a notification row from database + * @return array */ protected function mockNotificationRow() { return [ 'notification_user' => 1, 'notification_event' => 1, 'notification_timestamp' => time(), - 'notification_read_timestamp' => '', + 'notification_read_timestamp' => null, 'notification_bundle_hash' => 'testhash', ]; } /** * Mock an event row from database + * @return array */ protected function mockEventRow() { return [ @@ -76,6 +78,7 @@ class EchoNotificationTest extends MediaWikiTestCase { /** * Mock a target page row + * @return array */ protected function mockTargetPageRow() { return [ diff --git a/Echo/tests/phpunit/AttributeManagerTest.php b/Echo/tests/phpunit/unit/AttributeManagerTest.php index 856c51c7..f7744711 100644 --- a/Echo/tests/phpunit/AttributeManagerTest.php +++ b/Echo/tests/phpunit/unit/AttributeManagerTest.php @@ -1,12 +1,42 @@ <?php +use MediaWiki\User\UserGroupManager; +use MediaWiki\User\UserIdentity; +use MediaWiki\User\UserIdentityValue; +use MediaWiki\User\UserOptionsLookup; + /** * @covers \EchoAttributeManager */ -class EchoAttributeManagerTest extends MediaWikiTestCase { +class EchoAttributeManagerTest extends MediaWikiUnitTestCase { + + private function getAttributeManager( + array $notifications, + array $categories = [], + array $defaultNotifyTypeAvailability = [], + array $notifyTypeAvailabilityByCategory = [] + ): EchoAttributeManager { + $userGroupManager = $this->createNoOpMock( UserGroupManager::class, [ 'getUserGroups' ] ); + $userGroupManager->method( 'getUserGroups' )->willReturn( [ 'echo_group' ] ); + + $userOptionsLookup = $this->createNoOpMock( UserOptionsLookup::class, [ 'getOption' ] ); + $userOptionsLookup->method( 'getOption' )->willReturn( true ); - public function testNewFromGlobalVars() { - $this->assertInstanceOf( EchoAttributeManager::class, EchoAttributeManager::newFromGlobalVars() ); + return new EchoAttributeManager( + $notifications, + $categories, + $defaultNotifyTypeAvailability, + $notifyTypeAvailabilityByCategory, + $userGroupManager, + $userOptionsLookup + ); + } + + /** + * @return UserIdentity + */ + protected function getUser(): UserIdentity { + return new UserIdentityValue( 1, 'ExampleUserName' ); } public static function getUserLocatorsProvider() { @@ -58,7 +88,7 @@ class EchoAttributeManagerTest extends MediaWikiTestCase { * @dataProvider getUserLocatorsProvider */ public function testGetUserLocators( $message, $expect, $type, $notifications ) { - $manager = new EchoAttributeManager( $notifications, [], [], [] ); + $manager = $this->getAttributeManager( $notifications ); $result = $manager->getUserCallable( $type, EchoAttributeManager::ATTR_LOCATORS ); $this->assertEquals( $expect, $result, $message ); @@ -75,8 +105,8 @@ class EchoAttributeManagerTest extends MediaWikiTestCase { 'priority' => 10 ] ]; - $manager = new EchoAttributeManager( $notif, $category, [], [] ); - $this->assertTrue( $manager->getCategoryEligibility( $this->mockUser(), 'category_one' ) ); + $manager = $this->getAttributeManager( $notif, $category ); + $this->assertTrue( $manager->getCategoryEligibility( $this->getUser(), 'category_one' ) ); $category = [ 'category_one' => [ 'priority' => 10, @@ -85,8 +115,8 @@ class EchoAttributeManagerTest extends MediaWikiTestCase { ] ] ]; - $manager = new EchoAttributeManager( $notif, $category, [], [] ); - $this->assertFalse( $manager->getCategoryEligibility( $this->mockUser(), 'category_one' ) ); + $manager = $this->getAttributeManager( $notif, $category ); + $this->assertFalse( $manager->getCategoryEligibility( $this->getUser(), 'category_one' ) ); } public function testGetNotificationCategory() { @@ -100,11 +130,11 @@ class EchoAttributeManagerTest extends MediaWikiTestCase { 'priority' => 10 ] ]; - $manager = new EchoAttributeManager( $notif, $category, [], [] ); - $this->assertEquals( $manager->getNotificationCategory( 'event_one' ), 'category_one' ); + $manager = $this->getAttributeManager( $notif, $category ); + $this->assertEquals( 'category_one', $manager->getNotificationCategory( 'event_one' ) ); - $manager = new EchoAttributeManager( $notif, [], [], [] ); - $this->assertEquals( $manager->getNotificationCategory( 'event_one' ), 'other' ); + $manager = $this->getAttributeManager( $notif ); + $this->assertEquals( 'other', $manager->getNotificationCategory( 'event_one' ) ); $notif = [ 'event_one' => [ @@ -116,8 +146,8 @@ class EchoAttributeManagerTest extends MediaWikiTestCase { 'priority' => 10 ] ]; - $manager = new EchoAttributeManager( $notif, $category, [], [] ); - $this->assertEquals( $manager->getNotificationCategory( 'event_one' ), 'other' ); + $manager = $this->getAttributeManager( $notif, $category ); + $this->assertEquals( 'other', $manager->getNotificationCategory( 'event_one' ) ); } public function testGetCategoryPriority() { @@ -138,7 +168,7 @@ class EchoAttributeManagerTest extends MediaWikiTestCase { ], 'category_four' => [] ]; - $manager = new EchoAttributeManager( $notif, $category, [], [] ); + $manager = $this->getAttributeManager( $notif, $category ); $this->assertSame( 6, $manager->getCategoryPriority( 'category_one' ) ); $this->assertSame( 10, $manager->getCategoryPriority( 'category_two' ) ); $this->assertSame( 10, $manager->getCategoryPriority( 'category_three' ) ); @@ -172,7 +202,7 @@ class EchoAttributeManagerTest extends MediaWikiTestCase { ], 'category_four' => [] ]; - $manager = new EchoAttributeManager( $notif, $category, [], [] ); + $manager = $this->getAttributeManager( $notif, $category ); $this->assertSame( 6, $manager->getNotificationPriority( 'event_one' ) ); $this->assertSame( 10, $manager->getNotificationPriority( 'event_two' ) ); $this->assertSame( 10, $manager->getNotificationPriority( 'event_three' ) ); @@ -224,7 +254,7 @@ class EchoAttributeManagerTest extends MediaWikiTestCase { * @dataProvider getEventsForSectionProvider */ public function testGetEventsForSection( $expected, $notificationTypes, $section, $message ) { - $am = new EchoAttributeManager( $notificationTypes, [], [], [] ); + $am = $this->getAttributeManager( $notificationTypes ); $actual = $am->getEventsForSection( $section ); $this->assertEquals( $expected, $actual, $message ); } @@ -274,7 +304,7 @@ class EchoAttributeManagerTest extends MediaWikiTestCase { 'email' => true, ] ]; - $manager = new EchoAttributeManager( + $manager = $this->getAttributeManager( $notif, $category, $defaultNotifyTypeAvailability, @@ -282,11 +312,15 @@ class EchoAttributeManagerTest extends MediaWikiTestCase { ); $this->assertEquals( [ 'event_two', 'event_four' ], - $manager->getUserEnabledEvents( $this->mockUser(), 'web' ) + $manager->getUserEnabledEvents( $this->getUser(), 'web' ) + ); + $this->assertEquals( + [ 'event_two', 'event_three', 'event_four' ], + $manager->getUserEnabledEvents( $this->getUser(), [ 'web', 'email' ] ) ); } - public function testGetUserEnabledEventsbySections() { + public function testGetUserEnabledEventsBySections() { $notif = [ 'event_one' => [ 'category' => 'category_one' @@ -330,26 +364,32 @@ class EchoAttributeManagerTest extends MediaWikiTestCase { 'email' => true, ] ]; - $manager = new EchoAttributeManager( + $manager = $this->getAttributeManager( $notif, $category, $defaultNotifyTypeAvailability, $notifyTypeAvailabilityByCategory ); $expected = [ 'event_one', 'event_three', 'event_four' ]; - $actual = $manager->getUserEnabledEventsbySections( $this->mockUser(), 'web', [ 'alert' ] ); + $actual = $manager->getUserEnabledEventsBySections( $this->getUser(), 'web', [ 'alert' ] ); + sort( $expected ); + sort( $actual ); + $this->assertEquals( $expected, $actual ); + + $expected = [ 'event_one', 'event_three', 'event_four', 'event_five' ]; + $actual = $manager->getUserEnabledEventsBySections( $this->getUser(), [ 'web', 'email' ], [ 'alert' ] ); sort( $expected ); sort( $actual ); $this->assertEquals( $expected, $actual ); $expected = [ 'event_two' ]; - $actual = $manager->getUserEnabledEventsbySections( $this->mockUser(), 'web', [ 'message' ] ); + $actual = $manager->getUserEnabledEventsBySections( $this->getUser(), 'web', [ 'message' ] ); sort( $expected ); sort( $actual ); $this->assertEquals( $expected, $actual ); $expected = [ 'event_one', 'event_two', 'event_three', 'event_four' ]; - $actual = $manager->getUserEnabledEventsbySections( $this->mockUser(), 'web', + $actual = $manager->getUserEnabledEventsBySections( $this->getUser(), 'web', [ 'message', 'alert' ] ); sort( $expected ); sort( $actual ); @@ -407,7 +447,7 @@ class EchoAttributeManagerTest extends MediaWikiTestCase { $categories, $notifications ) { - $am = new EchoAttributeManager( $notifications, $categories, [], [] ); + $am = $this->getAttributeManager( $notifications, $categories ); $actualMapping = $am->getEventsByCategory(); $this->assertEquals( $expectedMapping, $actualMapping, $message ); } @@ -460,8 +500,12 @@ class EchoAttributeManagerTest extends MediaWikiTestCase { $defaultNotifyTypeAvailability, $notifyTypeAvailabilityByCategory ) { - $am = new EchoAttributeManager( [], [], $defaultNotifyTypeAvailability, - $notifyTypeAvailabilityByCategory ); + $am = $this->getAttributeManager( + [], + [], + $defaultNotifyTypeAvailability, + $notifyTypeAvailabilityByCategory + ); $actual = $am->isNotifyTypeAvailableForCategory( $categoryName, $notifyType ); $this->assertEquals( $expected, $actual, $message ); } @@ -514,28 +558,71 @@ class EchoAttributeManagerTest extends MediaWikiTestCase { $categoryName, $notifyType ) { - $am = new EchoAttributeManager( [], $categories, [], [] ); + $am = $this->getAttributeManager( [], $categories ); $actual = $am->isNotifyTypeDismissableForCategory( $categoryName, $notifyType ); $this->assertEquals( $expected, $actual, $message ); } + public function getNotificationSectionProvider() { + yield [ 'event_one', 'alert' ]; + yield [ 'event_two', 'message' ]; + yield [ 'event_three', 'alert' ]; + yield [ 'event_undefined', 'alert' ]; + } + + /** + * @dataProvider getNotificationSectionProvider + */ + public function testGetNotificationSection( $type, $expected ) { + $am = $this->getAttributeManager( [ + 'event_one' => [ + 'section' => 'alert', + ], + 'event_two' => [ + 'section' => 'message', + ], + 'event_three' => [], + ] ); + $actual = $am->getNotificationSection( $type ); + $this->assertSame( $expected, $actual ); + } + + public function isBundleExpandableProvider() { + yield [ 'event_one', false ]; + yield [ 'event_two', false ]; + yield [ 'event_three', false ]; + yield [ 'event_four', true ]; + yield [ 'event_undefined', false ]; + } + /** - * Mock object of User + * @dataProvider isBundleExpandableProvider */ - protected function mockUser() { - $user = $this->getMockBuilder( User::class ) - ->disableOriginalConstructor() - ->getMock(); - $user->expects( $this->any() ) - ->method( 'getID' ) - ->will( $this->returnValue( 1 ) ); - $user->expects( $this->any() ) - ->method( 'getOption' ) - ->will( $this->returnValue( true ) ); - $user->expects( $this->any() ) - ->method( 'getGroups' ) - ->will( $this->returnValue( [ 'echo_group' ] ) ); - - return $user; + public function testIsBundleExpandable( $type, $expected ) { + $am = $this->getAttributeManager( [ + 'event_one' => [], + 'event_two' => [ + 'bundle' => [ + 'web' => true + ] + ], + 'event_three' => [ + 'bundle' => [ + 'web' => true, + 'email' => false, + 'expandable' => false + ] + ], + 'event_four' => [ + 'bundle' => [ + 'web' => true, + 'email' => true, + 'expandable' => true + ] + ], + ] ); + $actual = $am->isBundleExpandable( $type ); + $this->assertSame( $expected, $actual ); } + } diff --git a/Echo/tests/phpunit/unit/BundlerTest.php b/Echo/tests/phpunit/unit/BundlerTest.php index 121afccc..f0773509 100644 --- a/Echo/tests/phpunit/unit/BundlerTest.php +++ b/Echo/tests/phpunit/unit/BundlerTest.php @@ -30,7 +30,7 @@ class BundlerTest extends MediaWikiUnitTestCase { private function createNotificationForBundling( $bundleHash, $timestamp, $readStatus ) { $mock = $this->getMockBuilder( EchoNotification::class ) ->disableOriginalConstructor() - ->setMethods( [ + ->onlyMethods( [ 'getBundlingKey', 'getSortingKey', 'canBeBundled', diff --git a/Echo/tests/phpunit/unit/Push/NotificationServiceClientUnitTest.php b/Echo/tests/phpunit/unit/Push/NotificationServiceClientUnitTest.php new file mode 100644 index 00000000..867526ed --- /dev/null +++ b/Echo/tests/phpunit/unit/Push/NotificationServiceClientUnitTest.php @@ -0,0 +1,88 @@ +<?php + +use MediaWiki\Extension\Notifications\Push\NotificationServiceClient; +use MediaWiki\Extension\Notifications\Push\Subscription; + +/** @covers \MediaWiki\Extension\Notifications\Push\NotificationServiceClient */ +class NotificationServiceClientUnitTest extends MediaWikiUnitTestCase { + + /** + * @dataProvider sendCheckEchoRequestsProvider + */ + public function testSendCheckEchoRequests( $numOfCalls, $subscriptions, $expected ): void { + $mock = $this->getMockBuilder( NotificationServiceClient::class ) + ->disableOriginalConstructor() + ->onlyMethods( [ 'sendRequest' ] ) + ->getMock(); + + $mock->expects( $this->exactly( $numOfCalls ) ) + ->method( 'sendRequest' ) + ->withConsecutive( ...$expected ); + + $mock->sendCheckEchoRequests( $subscriptions ); + } + + public function sendCheckEchoRequestsProvider(): array { + $row = (object)[ + 'eps_token' => 'JKL123', + 'epp_name' => 'fcm', + 'ept_text' => null, + 'eps_updated' => '2020-01-01 10:10:10', + ]; + $subscriptions[] = Subscription::newFromRow( $row ); + + $row = (object)[ + 'eps_token' => 'DEF456', + 'epp_name' => 'fcm', + 'ept_text' => null, + 'eps_updated' => '2020-01-01 10:10:10', + ]; + $subscriptions[] = Subscription::newFromRow( $row ); + + $row = (object)[ + 'eps_token' => 'GHI789', + 'epp_name' => 'apns', + 'ept_text' => 'test', + 'eps_updated' => '2020-01-01 10:10:10', + ]; + $subscriptions[] = Subscription::newFromRow( $row ); + + return [ + [ + 1, + [ $subscriptions[0], $subscriptions[1] ], + [ + [ + 'fcm', + [ + 'deviceTokens' => [ "JKL123", 'DEF456' ], + 'messageType' => 'checkEchoV1' + ] + ] + ] + ], + [ + 2, + $subscriptions, + [ + [ + 'fcm', + [ + 'deviceTokens' => [ "JKL123", 'DEF456' ], + 'messageType' => 'checkEchoV1' + ] + ], + [ + 'apns', + [ + 'deviceTokens' => [ 'GHI789' ], + 'messageType' => 'checkEchoV1', + 'topic' => 'test' + ] + ] + ] + ] + ]; + } + +} diff --git a/Echo/tests/phpunit/unit/Push/SubscriptionTest.php b/Echo/tests/phpunit/unit/Push/SubscriptionTest.php index b63e8c16..06b66b75 100644 --- a/Echo/tests/phpunit/unit/Push/SubscriptionTest.php +++ b/Echo/tests/phpunit/unit/Push/SubscriptionTest.php @@ -1,20 +1,41 @@ <?php -use EchoPush\Subscription; +use MediaWiki\Extension\Notifications\Push\Subscription; use Wikimedia\Timestamp\ConvertibleTimestamp; -/** @covers \EchoPush\Subscription */ +/** @covers \MediaWiki\Extension\Notifications\Push\Subscription */ class SubscriptionTest extends MediaWikiUnitTestCase { public function testNewFromRow(): void { - $row = new stdClass(); - $row->eps_token = 'ABC123'; - $row->epp_name = 'fcm'; - $row->eps_updated = '2020-01-01 10:10:10'; + $row = (object)[ + 'eps_token' => 'AABC123', + 'epp_name' => 'fcm', + 'eps_data' => null, + 'ept_text' => null, + 'eps_updated' => '2020-01-01 10:10:10', + ]; $subscription = Subscription::newFromRow( $row ); - $this->assertSame( 'ABC123', $subscription->getToken() ); + $this->assertSame( 'AABC123', $subscription->getToken() ); $this->assertSame( 'fcm', $subscription->getProvider() ); + $this->assertNull( $subscription->getTopic() ); + $this->assertInstanceOf( ConvertibleTimestamp::class, $subscription->getUpdated() ); + $this->assertSame( '1577873410', $subscription->getUpdated()->getTimestamp() ); + } + + public function testNewFromRowWithTopic(): void { + $row = (object)[ + 'eps_token' => 'DEF456', + 'epp_name' => 'apns', + 'eps_data' => null, + 'ept_text' => 'test', + 'eps_updated' => '2020-01-01 10:10:10', + ]; + + $subscription = Subscription::newFromRow( $row ); + $this->assertSame( 'DEF456', $subscription->getToken() ); + $this->assertSame( 'apns', $subscription->getProvider() ); + $this->assertSame( 'test', $subscription->getTopic() ); $this->assertInstanceOf( ConvertibleTimestamp::class, $subscription->getUpdated() ); $this->assertSame( '1577873410', $subscription->getUpdated()->getTimestamp() ); } diff --git a/Echo/tests/phpunit/unit/controller/NotificationControllerUnitTest.php b/Echo/tests/phpunit/unit/controller/NotificationControllerUnitTest.php deleted file mode 100644 index 9c0c7cb8..00000000 --- a/Echo/tests/phpunit/unit/controller/NotificationControllerUnitTest.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php - -use Wikimedia\TestingAccessWrapper; - -/** - * @coversDefaultClass EchoNotificationController - */ -class NotificationControllerUnitTest extends MediaWikiUnitTestCase { - - /** - * @dataProvider PageLinkedTitleMutedByUserDataProvider - * @covers ::isPageLinkedTitleMutedByUser - * @param Title $title - * @param User $user - * @param bool $expected - */ - public function testIsPageLinkedTitleMutedByUser( - Title $title, User $user, bool $expected ): void { - $wrapper = TestingAccessWrapper::newFromClass( EchoNotificationController::class ); - $wrapper->mutedPageLinkedTitlesCache = $this->getMapCacheLruMock(); - $this->assertSame( - $expected, - $wrapper->isPageLinkedTitleMutedByUser( $title, $user ) - ); - } - - public function PageLinkedTitleMutedByUserDataProvider() :array { - return [ - [ - $this->getMockTitle( 123 ), - $this->getMockUser( [] ), - false - ], - [ - $this->getMockTitle( 123 ), - $this->getMockUser( [ 123, 456, 789 ] ), - true - ], - [ - $this->getMockTitle( 456 ), - $this->getMockUser( [ 489 ] ), - false - ] - - ]; - } - - private function getMockTitle( int $articleID ) { - $title = $this->getMockBuilder( Title::class ) - ->disableOriginalConstructor() - ->getMock(); - $title->method( 'getArticleID' ) - ->willReturn( $articleID ); - return $title; - } - - private function getMockUser( $mutedTitlePreferences = [] ) { - $user = $this->getMockBuilder( User::class ) - ->disableOriginalConstructor() - ->getMock(); - $user->method( 'getId' ) - ->willReturn( 456 ); - $user->method( 'getOption' ) - ->willReturn( implode( "\n", $mutedTitlePreferences ) ); - return $user; - } - - private function getMapCacheLruMock() { - return $this->getMockBuilder( MapCacheLRU::class ) - ->disableOriginalConstructor() - ->getMock(); - } - -} diff --git a/Echo/tests/phpunit/unit/gateway/UserNotificationGatewayTest.php b/Echo/tests/phpunit/unit/gateway/UserNotificationGatewayTest.php index 2f45ee2f..86d6f58f 100644 --- a/Echo/tests/phpunit/unit/gateway/UserNotificationGatewayTest.php +++ b/Echo/tests/phpunit/unit/gateway/UserNotificationGatewayTest.php @@ -10,7 +10,7 @@ class EchoUserNotificationGatewayTest extends MediaWikiUnitTestCase { public function testMarkRead() { // no event ids to mark $gateway = new EchoUserNotificationGateway( - User::newFromId( 1 ), + $this->mockUser(), $this->mockMWEchoDbFactory(), $this->mockConfig() ); @@ -18,7 +18,7 @@ class EchoUserNotificationGatewayTest extends MediaWikiUnitTestCase { // successful update $gateway = new EchoUserNotificationGateway( - User::newFromId( 1 ), + $this->mockUser(), $this->mockMWEchoDbFactory( [ 'update' => true ] ), $this->mockConfig() ); @@ -26,7 +26,7 @@ class EchoUserNotificationGatewayTest extends MediaWikiUnitTestCase { // unsuccessful update $gateway = new EchoUserNotificationGateway( - User::newFromId( 1 ), + $this->mockUser(), $this->mockMWEchoDbFactory( [ 'update' => false ] ), $this->mockConfig() ); @@ -36,7 +36,7 @@ class EchoUserNotificationGatewayTest extends MediaWikiUnitTestCase { public function testMarkAllRead() { // successful update $gateway = new EchoUserNotificationGateway( - User::newFromId( 1 ), + $this->mockUser(), $this->mockMWEchoDbFactory( [ 'update' => true ] ), $this->mockConfig() ); @@ -44,7 +44,7 @@ class EchoUserNotificationGatewayTest extends MediaWikiUnitTestCase { // null update $gateway = new EchoUserNotificationGateway( - User::newFromId( 1 ), + $this->mockUser(), $this->mockMWEchoDbFactory( [ 'update' => false ] ), $this->mockConfig() ); @@ -109,34 +109,25 @@ class EchoUserNotificationGatewayTest extends MediaWikiUnitTestCase { /** * Mock object of User + * @return User */ - protected function mockUser( $group = 'echo_group' ) { - $user = $this->getMockBuilder( User::class ) - ->disableOriginalConstructor() - ->getMock(); - $user->expects( $this->any() ) - ->method( 'getID' ) - ->will( $this->returnValue( 1 ) ); - $user->expects( $this->any() ) - ->method( 'getOption' ) - ->will( $this->returnValue( true ) ); - $user->expects( $this->any() ) - ->method( 'getGroups' ) - ->will( $this->returnValue( [ $group ] ) ); + protected function mockUser() { + $user = $this->createMock( User::class ); + $user->method( 'getID' ) + ->willReturn( 1 ); return $user; } /** * Mock object of MWEchoDbFactory + * @param array $dbResult + * @return MWEchoDbFactory */ protected function mockMWEchoDbFactory( array $dbResult = [] ) { - $dbFactory = $this->getMockBuilder( MWEchoDbFactory::class ) - ->disableOriginalConstructor() - ->getMock(); - $dbFactory->expects( $this->any() ) - ->method( 'getEchoDb' ) - ->will( $this->returnValue( $this->mockDb( $dbResult ) ) ); + $dbFactory = $this->createMock( MWEchoDbFactory::class ); + $dbFactory->method( 'getEchoDb' ) + ->willReturn( $this->mockDb( $dbResult ) ); return $dbFactory; } @@ -149,6 +140,7 @@ class EchoUserNotificationGatewayTest extends MediaWikiUnitTestCase { /** * Returns a mock database object + * @param array $dbResult * @return \Wikimedia\Rdbms\IDatabase */ protected function mockDb( array $dbResult = [] ) { @@ -159,22 +151,14 @@ class EchoUserNotificationGatewayTest extends MediaWikiUnitTestCase { 'selectRowCount' => '', ]; $db = $this->createMock( IDatabase::class ); - $db->expects( $this->any() ) - ->method( 'update' ) - ->will( $this->returnValue( $dbResult['update'] ) ); - $db->expects( $this->any() ) - ->method( 'select' ) - ->will( $this->returnValue( $dbResult['select'] ) ); - $db->expects( $this->any() ) - ->method( 'selectRow' ) - ->will( $this->returnValue( $dbResult['selectRow'] ) ); - $db->expects( $this->any() ) - ->method( 'selectRowCount' ) - ->will( $this->returnValue( $dbResult['selectRowCount'] ) ); - $numRows = is_array( $dbResult['select'] ) ? count( $dbResult['select'] ) : 0; - $db->expects( $this->any() ) - ->method( 'numRows' ) - ->will( $this->returnValue( $numRows ) ); + $db->method( 'update' ) + ->willReturn( $dbResult['update'] ); + $db->method( 'select' ) + ->willReturn( $dbResult['select'] ); + $db->method( 'selectRow' ) + ->willReturn( $dbResult['selectRow'] ); + $db->method( 'selectRowCount' ) + ->willReturn( $dbResult['selectRowCount'] ); return $db; } diff --git a/Echo/tests/phpunit/unit/iterator/FilteredSequentialIteratorTest.php b/Echo/tests/phpunit/unit/iterator/FilteredSequentialIteratorTest.php index 25086cf2..9819ebe0 100644 --- a/Echo/tests/phpunit/unit/iterator/FilteredSequentialIteratorTest.php +++ b/Echo/tests/phpunit/unit/iterator/FilteredSequentialIteratorTest.php @@ -9,7 +9,7 @@ class FilteredSequentialIteratorTest extends MediaWikiUnitTestCase { public function testEchoCallbackIteratorDoesntBlowUp() { $it = new EchoCallbackIterator( new ArrayIterator( [ 1, 2, 3 ] ), - function ( $num ) { + static function ( $num ) { return "There were $num items"; } ); @@ -23,10 +23,10 @@ class FilteredSequentialIteratorTest extends MediaWikiUnitTestCase { } public static function echoFilteredSequentialIteratorProvider() { - $odd = function ( $v ) { + $odd = static function ( $v ) { return $v & 1; }; - $greaterThanFour = function ( $v ) { + $greaterThanFour = static function ( $v ) { return $v > 4; }; diff --git a/Echo/tests/phpunit/unit/mapper/AbstractMapperTest.php b/Echo/tests/phpunit/unit/mapper/AbstractMapperTest.php index 646caa0f..ac5b9642 100644 --- a/Echo/tests/phpunit/unit/mapper/AbstractMapperTest.php +++ b/Echo/tests/phpunit/unit/mapper/AbstractMapperTest.php @@ -10,7 +10,7 @@ class EchoAbstractMapperTest extends MediaWikiUnitTestCase { */ public function testAttachListener() { $mapper = new EchoAbstractMapperStub(); - $mapper->attachListener( 'testMethod', 'key_a', function () { + $mapper->attachListener( 'testMethod', 'key_a', static function () { } ); $class = new ReflectionClass( EchoAbstractMapperStub::class ); @@ -20,7 +20,7 @@ class EchoAbstractMapperTest extends MediaWikiUnitTestCase { $this->assertArrayHasKey( 'testMethod', $listeners ); $this->assertArrayHasKey( 'key_a', $listeners['testMethod'] ); - $this->assertTrue( is_callable( $listeners['testMethod']['key_a'] ) ); + $this->assertIsCallable( $listeners['testMethod']['key_a'] ); return [ 'mapper' => $mapper, 'property' => $property ]; } @@ -28,7 +28,7 @@ class EchoAbstractMapperTest extends MediaWikiUnitTestCase { public function testAttachListenerWithException() { $mapper = new EchoAbstractMapperStub(); $this->expectException( MWException::class ); - $mapper->attachListener( 'nonExistingMethod', 'key_a', function () { + $mapper->attachListener( 'nonExistingMethod', 'key_a', static function () { } ); } @@ -41,7 +41,7 @@ class EchoAbstractMapperTest extends MediaWikiUnitTestCase { $listeners = $mapper->getMethodListeners( 'testMethod' ); $this->assertArrayHasKey( 'key_a', $listeners ); - $this->assertTrue( is_callable( $listeners['key_a'] ) ); + $this->assertIsCallable( $listeners['key_a'] ); } /** diff --git a/Echo/tests/phpunit/unit/mapper/TargetPageMapperTest.php b/Echo/tests/phpunit/unit/mapper/TargetPageMapperTest.php index eecc3712..88f11899 100644 --- a/Echo/tests/phpunit/unit/mapper/TargetPageMapperTest.php +++ b/Echo/tests/phpunit/unit/mapper/TargetPageMapperTest.php @@ -33,40 +33,36 @@ class EchoTargetPageMapperTest extends MediaWikiUnitTestCase { /** * Mock object of EchoTargetPage + * @return EchoTargetPage */ protected function mockEchoTargetPage() { - $target = $this->getMockBuilder( EchoTargetPage::class ) - ->disableOriginalConstructor() - ->getMock(); - $target->expects( $this->any() ) - ->method( 'toDbArray' ) - ->will( $this->returnValue( [] ) ); - $target->expects( $this->any() ) - ->method( 'getPageId' ) - ->will( $this->returnValue( 2 ) ); - $target->expects( $this->any() ) - ->method( 'getEventId' ) - ->will( $this->returnValue( 3 ) ); + $target = $this->createMock( EchoTargetPage::class ); + $target->method( 'toDbArray' ) + ->willReturn( [] ); + $target->method( 'getPageId' ) + ->willReturn( 2 ); + $target->method( 'getEventId' ) + ->willReturn( 3 ); return $target; } /** * Mock object of MWEchoDbFactory + * @param array $dbResult + * @return MWEchoDbFactory */ protected function mockMWEchoDbFactory( $dbResult ) { - $dbFactory = $this->getMockBuilder( MWEchoDbFactory::class ) - ->disableOriginalConstructor() - ->getMock(); - $dbFactory->expects( $this->any() ) - ->method( 'getEchoDb' ) - ->will( $this->returnValue( $this->mockDb( $dbResult ) ) ); + $dbFactory = $this->createMock( MWEchoDbFactory::class ); + $dbFactory->method( 'getEchoDb' ) + ->willReturn( $this->mockDb( $dbResult ) ); return $dbFactory; } /** * Returns a mock database object + * @param array $dbResult * @return \Wikimedia\Rdbms\IDatabase */ protected function mockDb( array $dbResult ) { @@ -77,18 +73,14 @@ class EchoTargetPageMapperTest extends MediaWikiUnitTestCase { 'delete' => '' ]; $db = $this->createMock( IDatabase::class ); - $db->expects( $this->any() ) - ->method( 'insert' ) - ->will( $this->returnValue( $dbResult['insert'] ) ); - $db->expects( $this->any() ) - ->method( 'insertId' ) - ->will( $this->returnValue( $dbResult['insertId'] ) ); - $db->expects( $this->any() ) - ->method( 'select' ) - ->will( $this->returnValue( $dbResult['select'] ) ); - $db->expects( $this->any() ) - ->method( 'delete' ) - ->will( $this->returnValue( $dbResult['delete'] ) ); + $db->method( 'insert' ) + ->willReturn( $dbResult['insert'] ); + $db->method( 'insertId' ) + ->willReturn( $dbResult['insertId'] ); + $db->method( 'select' ) + ->willReturn( $dbResult['select'] ); + $db->method( 'delete' ) + ->willReturn( $dbResult['delete'] ); return $db; } diff --git a/Echo/tests/phpunit/unit/model/TargetPageTest.php b/Echo/tests/phpunit/unit/model/TargetPageTest.php index 565f5f94..b6bfb604 100644 --- a/Echo/tests/phpunit/unit/model/TargetPageTest.php +++ b/Echo/tests/phpunit/unit/model/TargetPageTest.php @@ -49,7 +49,7 @@ class EchoTargetPageTest extends MediaWikiUnitTestCase { */ public function testToDbArray( EchoTargetPage $obj ) { $row = $obj->toDbArray(); - $this->assertTrue( is_array( $row ) ); + $this->assertIsArray( $row ); // Not very common to assert that a field does _not_ exist // but since we are explicitly removing it, it seems to make sense. @@ -60,29 +60,25 @@ class EchoTargetPageTest extends MediaWikiUnitTestCase { } /** + * @param int $pageId * @return Title */ protected function mockTitle( $pageId ) { - $event = $this->getMockBuilder( Title::class ) - ->disableOriginalConstructor() - ->getMock(); - $event->expects( $this->any() ) - ->method( 'getArticleID' ) - ->will( $this->returnValue( $pageId ) ); + $event = $this->createMock( Title::class ); + $event->method( 'getArticleID' ) + ->willReturn( $pageId ); return $event; } /** + * @param int $eventId * @return EchoEvent */ protected function mockEchoEvent( $eventId = 1 ) { - $event = $this->getMockBuilder( EchoEvent::class ) - ->disableOriginalConstructor() - ->getMock(); - $event->expects( $this->any() ) - ->method( 'getId' ) - ->will( $this->returnValue( $eventId ) ); + $event = $this->createMock( EchoEvent::class ); + $event->method( 'getId' ) + ->willReturn( $eventId ); return $event; } diff --git a/Echo/tests/qunit/.eslintrc.json b/Echo/tests/qunit/.eslintrc.json index 1b7ccf1c..d7d35aa7 100644 --- a/Echo/tests/qunit/.eslintrc.json +++ b/Echo/tests/qunit/.eslintrc.json @@ -1,11 +1,14 @@ { + "root": true, "extends": [ + "../../modules/.eslintrc.json", "wikimedia/qunit" ], "rules": { "no-jquery/no-class-state": "off", "no-jquery/no-parse-html-literal": "off", "no-jquery/no-global-selector": "off", - "no-jquery/no-sizzle": "off" + "no-jquery/no-sizzle": "off", + "qunit/no-loose-assertions": "warn" } } diff --git a/Echo/modules/mw.echo.js b/Echo/tests/qunit/index.js index e69de29b..e69de29b 100644 --- a/Echo/modules/mw.echo.js +++ b/Echo/tests/qunit/index.js diff --git a/Echo/tests/qunit/mobile/index.js b/Echo/tests/qunit/mobile/index.js deleted file mode 100644 index d1dc108f..00000000 --- a/Echo/tests/qunit/mobile/index.js +++ /dev/null @@ -1,7 +0,0 @@ -mw.template.add( 'ext.echo.mobile', 'NotificationBadge.mustache', - mw.template.get( 'test.Echo', 'NotificationBadge.mustache' ).getSource() -); - -mw.loader.using( 'mobile.startup' ).then( function () { - require( './test_NotificationBadge.js' ); -} ); diff --git a/Echo/tests/qunit/mobile/test_NotificationBadge.js b/Echo/tests/qunit/mobile/test_NotificationBadge.js index 02304ec6..c28168a6 100644 --- a/Echo/tests/qunit/mobile/test_NotificationBadge.js +++ b/Echo/tests/qunit/mobile/test_NotificationBadge.js @@ -1,32 +1,22 @@ -( function ( M ) { - var OverlayManager = M.require( 'mobile.startup' ).OverlayManager, - NotificationBadge = require( '../../../modules/mobile/NotificationBadge.js' ); +QUnit.module( 'ext.echo.mobile - NotificationBadge', function () { + var NotificationBadge = require( 'ext.echo.mobile' ).NotificationBadge; - QUnit.module( 'ext.echo.mobile - NotificationBadge', { - beforeEach: function () { - this.OverlayManager = OverlayManager.getSingleton(); - } - } ); - - QUnit.test( '#setCount', function ( assert ) { - var initialClassExpectationsMet, + QUnit.test( '.setCount()', function ( assert ) { + var initialExpectationsMet, badge = new NotificationBadge( { - overlayManager: this.OverlayManager, hasNotifications: true, hasUnseenNotifications: true, notificationCountRaw: 5 } ); - initialClassExpectationsMet = badge.$el.find( '.mw-ui-icon' ).length === 0 && - badge.$el.find( '.zero' ).length === 0; + initialExpectationsMet = badge.$el.find( '.mw-ui-icon' ).length === 0; badge.setCount( 0 ); - assert.ok( initialClassExpectationsMet, 'No icon and no zero class' ); - assert.strictEqual( badge.$el.find( '.zero' ).length, 1, 'A zero class is present on the badge' ); + assert.true( initialExpectationsMet, 'No icon.' ); badge.setCount( 105 ); assert.strictEqual( badge.options.notificationCountRaw, 100, 'Number is capped to 100.' ); } ); - QUnit.test( '#setCount (Eastern Arabic numerals)', function ( assert ) { + QUnit.test( '.setCount() Eastern Arabic numerals', function ( assert ) { var badge; this.sandbox.stub( mw.language, 'convertNumber' ) @@ -37,7 +27,6 @@ .withArgs( 'echo-badge-count', '۲' ).returns( { text: function () { return '۲'; } } ); badge = new NotificationBadge( { - overlayManager: this.OverlayManager, el: $( '<div><a title="n" href="/" class="notification-unseen"><div class="circle" ><span data-notification-count="2">۲</span></div></a></div>' ) } ); assert.strictEqual( badge.options.notificationCountRaw, 2, @@ -49,20 +38,18 @@ 'Number will be rendered in Eastern Arabic numerals' ); } ); - QUnit.test( '#render [hasUnseenNotifications]', function ( assert ) { + QUnit.test( '.render() [hasUnseenNotifications]', function ( assert ) { var badge = new NotificationBadge( { notificationCountRaw: 0, - overlayManager: this.OverlayManager, hasNotifications: false, hasUnseenNotifications: false } ); assert.strictEqual( badge.$el.find( '.mw-ui-icon' ).length, 1, 'A bell icon is visible' ); } ); - QUnit.test( '#markAsSeen', function ( assert ) { + QUnit.test( '.markAsSeen()', function ( assert ) { var badge = new NotificationBadge( { notificationCountRaw: 2, - overlayManager: this.OverlayManager, hasNotifications: true, hasUnseenNotifications: true } ); @@ -73,4 +60,4 @@ assert.strictEqual( badge.$el.find( '.notification-unseen' ).length, 0, 'Unseen class disappears after markAsSeen called.' ); } ); -}( mw.mobileFrontend ) ); +} ); diff --git a/Echo/tests/qunit/model/test_mw.echo.dm.BundleNotificationItem.js b/Echo/tests/qunit/model/test_mw.echo.dm.BundleNotificationItem.js index 1903fa03..e28ebb1f 100644 --- a/Echo/tests/qunit/model/test_mw.echo.dm.BundleNotificationItem.js +++ b/Echo/tests/qunit/model/test_mw.echo.dm.BundleNotificationItem.js @@ -1,117 +1,112 @@ -( function () { - QUnit.module( 'ext.echo.dm - mw.echo.dm.BundleNotificationItem' ); +QUnit.module( 'ext.echo.dm - BundleNotificationItem' ); - QUnit.test( 'Constructing the model', function ( assert ) { - var bundledItems = [ - new mw.echo.dm.NotificationItem( 0, { read: false, seen: false, timestamp: '201601010000' } ), - new mw.echo.dm.NotificationItem( 1, { read: false, seen: false, timestamp: '201601010100' } ), - new mw.echo.dm.NotificationItem( 2, { read: false, seen: true, timestamp: '201601010200' } ), - new mw.echo.dm.NotificationItem( 3, { read: false, seen: true, timestamp: '201601010300' } ), - new mw.echo.dm.NotificationItem( 4, { read: false, seen: true, timestamp: '201601010400' } ) - ], - bundle = new mw.echo.dm.BundleNotificationItem( - 100, - bundledItems, - { modelName: 'foo' } - ); +QUnit.test( 'Constructing the model', function ( assert ) { + var bundledItems = [ + new mw.echo.dm.NotificationItem( 0, { read: false, seen: false, timestamp: '201601010000' } ), + new mw.echo.dm.NotificationItem( 1, { read: false, seen: false, timestamp: '201601010100' } ), + new mw.echo.dm.NotificationItem( 2, { read: false, seen: true, timestamp: '201601010200' } ), + new mw.echo.dm.NotificationItem( 3, { read: false, seen: true, timestamp: '201601010300' } ), + new mw.echo.dm.NotificationItem( 4, { read: false, seen: true, timestamp: '201601010400' } ) + ]; + var bundle = new mw.echo.dm.BundleNotificationItem( + 100, + bundledItems, + { modelName: 'foo' } + ); - assert.strictEqual( - bundle.getCount(), - 5, - 'Bundled items added to internal list' - ); + assert.strictEqual( + bundle.getCount(), + 5, + 'Bundled items added to internal list' + ); - assert.strictEqual( - bundle.getName(), - 'foo', - 'Bundle name stored' - ); + assert.strictEqual( + bundle.getName(), + 'foo', + 'Bundle name stored' + ); - assert.deepEqual( - bundle.getAllIds(), - [ 4, 3, 2, 1, 0 ], - 'All ids present' - ); + assert.deepEqual( + bundle.getAllIds(), + [ 4, 3, 2, 1, 0 ], + 'All ids present' + ); - assert.strictEqual( - bundle.isRead(), - false, - 'Bundle with all unread items is unread' - ); + assert.strictEqual( + bundle.isRead(), + false, + 'Bundle with all unread items is unread' + ); - assert.strictEqual( - bundle.hasUnseen(), - true, - 'Bundle has unseen items' - ); + assert.strictEqual( + bundle.hasUnseen(), + true, + 'Bundle has unseen items' + ); - assert.deepEqual( - ( function () { - var findItems = bundle.findByIds( [ 1, 4 ] ); - return findItems.map( function ( item ) { - return item.getId(); - } ); - }() ), - [ 4, 1 ], - 'findByIds fetches correct items in the default sorting order' - ); + var findItems = bundle.findByIds( [ 1, 4 ] ).map( function ( item ) { + return item.getId(); } ); + assert.deepEqual( + findItems, + [ 4, 1 ], + 'findByIds fetches correct items in the default sorting order' + ); +} ); - QUnit.test( 'Managing a list of items', function ( assert ) { - var i, - bundledItems = [ - new mw.echo.dm.NotificationItem( 0, { read: false, seen: false, timestamp: '201601010000' } ), - new mw.echo.dm.NotificationItem( 1, { read: false, seen: false, timestamp: '201601010100' } ), - new mw.echo.dm.NotificationItem( 2, { read: false, seen: true, timestamp: '201601010200' } ), - new mw.echo.dm.NotificationItem( 3, { read: false, seen: true, timestamp: '201601010300' } ), - new mw.echo.dm.NotificationItem( 4, { read: false, seen: true, timestamp: '201601010400' } ) - ], - bundle = new mw.echo.dm.BundleNotificationItem( - 100, - bundledItems, - { - name: 'foo' - } - ); +QUnit.test( 'Managing a list of items', function ( assert ) { + var bundledItems = [ + new mw.echo.dm.NotificationItem( 0, { read: false, seen: false, timestamp: '201601010000' } ), + new mw.echo.dm.NotificationItem( 1, { read: false, seen: false, timestamp: '201601010100' } ), + new mw.echo.dm.NotificationItem( 2, { read: false, seen: true, timestamp: '201601010200' } ), + new mw.echo.dm.NotificationItem( 3, { read: false, seen: true, timestamp: '201601010300' } ), + new mw.echo.dm.NotificationItem( 4, { read: false, seen: true, timestamp: '201601010400' } ) + ]; + var bundle = new mw.echo.dm.BundleNotificationItem( + 100, + bundledItems, + { + name: 'foo' + } + ); - assert.strictEqual( - bundle.hasUnseen(), - true, - 'Bundle has unseen' - ); + assert.strictEqual( + bundle.hasUnseen(), + true, + 'Bundle has unseen' + ); - // Mark all items as seen - for ( i = 0; i < bundledItems.length; i++ ) { - bundledItems[ i ].toggleSeen( true ); - } + // Mark all items as seen + bundledItems.forEach( function ( item ) { + item.toggleSeen( true ); + } ); - assert.strictEqual( - bundle.hasUnseen(), - false, - 'Bundle does not have unseen after all items marked as seen' - ); + assert.strictEqual( + bundle.hasUnseen(), + false, + 'Bundle does not have unseen after all items marked as seen' + ); - assert.strictEqual( - bundle.isRead(), - false, - 'Bundle is unread' - ); - // Mark one item as read - bundledItems[ 0 ].toggleRead( true ); - assert.strictEqual( - bundle.isRead(), - false, - 'Bundle is still unread if it has some unread items' - ); + assert.strictEqual( + bundle.isRead(), + false, + 'Bundle is unread' + ); + // Mark one item as read + bundledItems[ 0 ].toggleRead( true ); + assert.strictEqual( + bundle.isRead(), + false, + 'Bundle is still unread if it has some unread items' + ); - // Mark all items as read - for ( i = 0; i < bundledItems.length; i++ ) { - bundledItems[ i ].toggleRead( true ); - } - assert.strictEqual( - bundle.isRead(), - true, - 'Bundle is marked as read if all items are read' - ); + // Mark all items as read + bundledItems.forEach( function ( item ) { + item.toggleRead( true ); } ); -}() ); + assert.strictEqual( + bundle.isRead(), + true, + 'Bundle is marked as read if all items are read' + ); +} ); diff --git a/Echo/tests/qunit/model/test_mw.echo.dm.CrossWikiNotificationItem.js b/Echo/tests/qunit/model/test_mw.echo.dm.CrossWikiNotificationItem.js index d069d3f5..a65ee57b 100644 --- a/Echo/tests/qunit/model/test_mw.echo.dm.CrossWikiNotificationItem.js +++ b/Echo/tests/qunit/model/test_mw.echo.dm.CrossWikiNotificationItem.js @@ -1,4 +1,32 @@ -( function () { +QUnit.module( 'ext.echo.dm - CrossWikiNotificationItem' ); + +QUnit.test.each( 'Constructing the model', { + 'Default values': { + params: { + id: -1, + config: {} + }, + expected: {} + }, + 'Overriding model name': { + params: { + id: -1, + config: { modelName: 'foo' } + }, + expected: { + getModelName: 'foo' + } + }, + 'Overriding model count': { + params: { + id: -1, + config: { count: 10 } + }, + expected: { + getCount: 10 + } + } +}, function ( assert, data ) { var defaults = { getModelName: 'xwiki', getSourceNames: [], @@ -7,305 +35,265 @@ getItems: [], isEmpty: true }; + var expected = $.extend( true, {}, defaults, data.expected ); - QUnit.module( 'ext.echo.dm - mw.echo.dm.CrossWikiNotificationItem' ); - - QUnit.test( 'Constructing the model', function ( assert ) { - var i, method, model, - cases = [ - { - params: { - id: -1, - config: {} - }, - expected: defaults, - msg: 'Default values' - }, - { - params: { - id: -1, - config: { modelName: 'foo' } - }, - expected: $.extend( true, {}, defaults, { - getModelName: 'foo' - } ), - msg: 'Overriding model name' - }, - { - params: { - id: -1, - config: { count: 10 } - }, - expected: $.extend( true, {}, defaults, { - getCount: 10 - } ), - msg: 'Overriding model count' - } - ]; - - for ( i = 0; i < cases.length; i++ ) { - model = new mw.echo.dm.CrossWikiNotificationItem( - cases[ i ].params.id, - cases[ i ].params.config - ); - - for ( method in defaults ) { - assert.deepEqual( - // Method - model[ method ](), - // Expected value - cases[ i ].expected[ method ], - cases[ i ].msg + ' (' + method + ')' - ); - } - } - } ); - - QUnit.test( 'Managing notification lists', function ( assert ) { - var i, j, - model = new mw.echo.dm.CrossWikiNotificationItem( 1 ), - groupDefinitions = [ - { - name: 'foo', - sourceData: { - title: 'Foo Wiki', - base: 'http://foo.wiki.sample/$1' - }, - items: [ - new mw.echo.dm.NotificationItem( 0, { source: 'foo', read: false, seen: false, timestamp: '201601010100' } ), - new mw.echo.dm.NotificationItem( 1, { source: 'foo', read: false, seen: false, timestamp: '201601010200' } ), - new mw.echo.dm.NotificationItem( 2, { source: 'foo', read: false, seen: false, timestamp: '201601010300' } ) - ] - }, - { - name: 'bar', - sourceData: { - title: 'Bar Wiki', - base: 'http://bar.wiki.sample/$1' - }, - items: [ - new mw.echo.dm.NotificationItem( 3, { source: 'bar', read: false, seen: false, timestamp: '201601020000' } ), - new mw.echo.dm.NotificationItem( 4, { source: 'bar', read: false, seen: false, timestamp: '201601020100' } ), - new mw.echo.dm.NotificationItem( 5, { source: 'bar', read: false, seen: false, timestamp: '201601020200' } ), - new mw.echo.dm.NotificationItem( 6, { source: 'bar', read: false, seen: false, timestamp: '201601020300' } ) - ] - }, - { - name: 'baz', - sourceData: { - title: 'Baz Wiki', - base: 'http://baz.wiki.sample/$1' - }, - items: [ - new mw.echo.dm.NotificationItem( 7, { source: 'baz', timestamp: '201601050100' } ) - ] - } - ]; - - // Add groups to model - for ( i = 0; i < groupDefinitions.length; i++ ) { - model.getList().addGroup( - groupDefinitions[ i ].name, - groupDefinitions[ i ].sourceData, - groupDefinitions[ i ].items - ); - } + var model = new mw.echo.dm.CrossWikiNotificationItem( + data.params.id, + data.params.config + ); + for ( var method in defaults ) { assert.deepEqual( - model.getSourceNames(), - [ 'baz', 'bar', 'foo' ], - 'Model source names exist in order' - ); - assert.strictEqual( - model.hasUnseen(), - true, - 'hasUnseen is true if there are unseen items in any group' + // Run the method + model[ method ](), + // Expected value + expected[ method ], + // Message + method ); + } +} ); - // Mark all items as seen except one - for ( i = 0; i < groupDefinitions.length; i++ ) { - for ( j = 0; j < groupDefinitions[ i ].items.length; j++ ) { - groupDefinitions[ i ].items[ j ].toggleSeen( true ); - } +QUnit.test( 'Managing notification lists', function ( assert ) { + var model = new mw.echo.dm.CrossWikiNotificationItem( 1 ); + var groupDefinitions = [ + { + name: 'foo', + sourceData: { + title: 'Foo Wiki', + base: 'http://foo.wiki.sample/$1' + }, + items: [ + new mw.echo.dm.NotificationItem( 0, { source: 'foo', read: false, seen: false, timestamp: '201601010100' } ), + new mw.echo.dm.NotificationItem( 1, { source: 'foo', read: false, seen: false, timestamp: '201601010200' } ), + new mw.echo.dm.NotificationItem( 2, { source: 'foo', read: false, seen: false, timestamp: '201601010300' } ) + ] + }, + { + name: 'bar', + sourceData: { + title: 'Bar Wiki', + base: 'http://bar.wiki.sample/$1' + }, + items: [ + new mw.echo.dm.NotificationItem( 3, { source: 'bar', read: false, seen: false, timestamp: '201601020000' } ), + new mw.echo.dm.NotificationItem( 4, { source: 'bar', read: false, seen: false, timestamp: '201601020100' } ), + new mw.echo.dm.NotificationItem( 5, { source: 'bar', read: false, seen: false, timestamp: '201601020200' } ), + new mw.echo.dm.NotificationItem( 6, { source: 'bar', read: false, seen: false, timestamp: '201601020300' } ) + ] + }, + { + name: 'baz', + sourceData: { + title: 'Baz Wiki', + base: 'http://baz.wiki.sample/$1' + }, + items: [ + new mw.echo.dm.NotificationItem( 7, { source: 'baz', timestamp: '201601050100' } ) + ] } - groupDefinitions[ 0 ].items[ 0 ].toggleSeen( false ); - assert.strictEqual( - model.hasUnseen(), - true, - 'hasUnseen is true even if only one item in one group is unseen' - ); + ]; - groupDefinitions[ 0 ].items[ 0 ].toggleSeen( true ); - assert.strictEqual( - model.hasUnseen(), - false, - 'hasUnseen is false if there are no unseen items in any of the groups' + // Add groups to model + groupDefinitions.forEach( function ( def ) { + model.getList().addGroup( + def.name, + def.sourceData, + def.items ); + } ); - // Discard group - model.getList().removeGroup( 'foo' ); - assert.deepEqual( - model.getSourceNames(), - [ 'baz', 'bar' ], - 'Group discarded successfully' - ); + assert.deepEqual( + model.getSourceNames(), + [ 'baz', 'bar', 'foo' ], + 'Model source names exist in order' + ); + assert.strictEqual( + model.hasUnseen(), + true, + 'hasUnseen is true if there are unseen items in any group' + ); + + // Mark all items as seen except one + groupDefinitions.forEach( function ( def ) { + def.items.forEach( function ( item ) { + item.toggleSeen( true ); + } ); } ); + groupDefinitions[ 0 ].items[ 0 ].toggleSeen( false ); + assert.strictEqual( + model.hasUnseen(), + true, + 'hasUnseen is true even if only one item in one group is unseen' + ); - QUnit.test( 'Update seen state', function ( assert ) { - var i, numUnseenItems, numAllItems, - model = new mw.echo.dm.CrossWikiNotificationItem( 1 ), - groupDefinitions = [ - { - name: 'foo', - sourceData: { - title: 'Foo Wiki', - base: 'http://foo.wiki.sample/$1' - }, - items: [ - new mw.echo.dm.NotificationItem( 0, { source: 'foo', read: false, seen: false, timestamp: '201601010100' } ), - new mw.echo.dm.NotificationItem( 1, { source: 'foo', read: false, seen: false, timestamp: '201601010200' } ), - new mw.echo.dm.NotificationItem( 2, { source: 'foo', read: false, seen: false, timestamp: '201601010300' } ) - ] - }, - { - name: 'bar', - sourceData: { - title: 'Bar Wiki', - base: 'http://bar.wiki.sample/$1' - }, - items: [ - new mw.echo.dm.NotificationItem( 3, { source: 'bar', read: false, seen: false, timestamp: '201601020000' } ), - new mw.echo.dm.NotificationItem( 4, { source: 'bar', read: false, seen: false, timestamp: '201601020100' } ), - new mw.echo.dm.NotificationItem( 5, { source: 'bar', read: false, seen: false, timestamp: '201601020200' } ), - new mw.echo.dm.NotificationItem( 6, { source: 'bar', read: false, seen: false, timestamp: '201601020300' } ) - ] - }, - { - name: 'baz', - sourceData: { - title: 'Baz Wiki', - base: 'http://baz.wiki.sample/$1' - }, - items: [ - new mw.echo.dm.NotificationItem( 7, { source: 'baz', timestamp: '201601050100' } ) - ] - } - ]; + groupDefinitions[ 0 ].items[ 0 ].toggleSeen( true ); + assert.strictEqual( + model.hasUnseen(), + false, + 'hasUnseen is false if there are no unseen items in any of the groups' + ); - // Count all actual items - numAllItems = groupDefinitions.reduce( function ( prev, curr ) { - return prev + curr.items.length; - }, 0 ); + // Discard group + model.getList().removeGroup( 'foo' ); + assert.deepEqual( + model.getSourceNames(), + [ 'baz', 'bar' ], + 'Group discarded successfully' + ); +} ); - // Add groups to model - for ( i = 0; i < groupDefinitions.length; i++ ) { - model.getList().addGroup( - groupDefinitions[ i ].name, - groupDefinitions[ i ].sourceData, - groupDefinitions[ i ].items - ); +QUnit.test( 'Update seen state', function ( assert ) { + var model = new mw.echo.dm.CrossWikiNotificationItem( 1 ); + var groupDefinitions = [ + { + name: 'foo', + sourceData: { + title: 'Foo Wiki', + base: 'http://foo.wiki.sample/$1' + }, + items: [ + new mw.echo.dm.NotificationItem( 0, { source: 'foo', read: false, seen: false, timestamp: '201601010100' } ), + new mw.echo.dm.NotificationItem( 1, { source: 'foo', read: false, seen: false, timestamp: '201601010200' } ), + new mw.echo.dm.NotificationItem( 2, { source: 'foo', read: false, seen: false, timestamp: '201601010300' } ) + ] + }, + { + name: 'bar', + sourceData: { + title: 'Bar Wiki', + base: 'http://bar.wiki.sample/$1' + }, + items: [ + new mw.echo.dm.NotificationItem( 3, { source: 'bar', read: false, seen: false, timestamp: '201601020000' } ), + new mw.echo.dm.NotificationItem( 4, { source: 'bar', read: false, seen: false, timestamp: '201601020100' } ), + new mw.echo.dm.NotificationItem( 5, { source: 'bar', read: false, seen: false, timestamp: '201601020200' } ), + new mw.echo.dm.NotificationItem( 6, { source: 'bar', read: false, seen: false, timestamp: '201601020300' } ) + ] + }, + { + name: 'baz', + sourceData: { + title: 'Baz Wiki', + base: 'http://baz.wiki.sample/$1' + }, + items: [ + new mw.echo.dm.NotificationItem( 7, { source: 'baz', timestamp: '201601050100' } ) + ] } + ]; - numUnseenItems = model.getItems().filter( function ( item ) { - return !item.isSeen(); - } ).length; - assert.strictEqual( - numUnseenItems, - numAllItems, - 'Starting state: all items are unseen' - ); - - // Update seen time to be bigger than 'foo' but smaller than the other groups - model.updateSeenState( '201601010400' ); + // Count all actual items + var numAllItems = groupDefinitions.reduce( function ( prev, curr ) { + return prev + curr.items.length; + }, 0 ); - numUnseenItems = model.getItems().filter( function ( item ) { - return !item.isSeen(); - } ).length; - assert.strictEqual( - numUnseenItems, - numAllItems - groupDefinitions[ 0 ].items.length, - 'Only some items are seen' + // Add groups to model + for ( var i = 0; i < groupDefinitions.length; i++ ) { + model.getList().addGroup( + groupDefinitions[ i ].name, + groupDefinitions[ i ].sourceData, + groupDefinitions[ i ].items ); + } - // Update seen time to be bigger than all - model.updateSeenState( '201701010000' ); + var numUnseenItems = model.getItems().filter( function ( item ) { + return !item.isSeen(); + } ).length; + assert.strictEqual( + numUnseenItems, + numAllItems, + 'Starting state: all items are unseen' + ); - numUnseenItems = model.getItems().filter( function ( item ) { - return !item.isSeen(); - } ).length; - assert.strictEqual( - numUnseenItems, - 0, - 'All items are seen' - ); - } ); + // Update seen time to be bigger than 'foo' but smaller than the other groups + model.updateSeenState( '201601010400' ); - QUnit.test( 'Emit discard event', function ( assert ) { - var i, - results = [], - model = new mw.echo.dm.CrossWikiNotificationItem( -1 ), - groupDefinitions = [ - { - name: 'foo', - sourceData: { - title: 'Foo Wiki', - base: 'http://foo.wiki.sample/$1' - }, - items: [ - new mw.echo.dm.NotificationItem( 0, { source: 'foo', read: false, seen: false, timestamp: '201601010100' } ), - new mw.echo.dm.NotificationItem( 1, { source: 'foo', read: false, seen: false, timestamp: '201601010200' } ), - new mw.echo.dm.NotificationItem( 2, { source: 'foo', read: false, seen: false, timestamp: '201601010300' } ) - ] - }, - { - name: 'bar', - sourceData: { - title: 'Bar Wiki', - base: 'http://bar.wiki.sample/$1' - }, - items: [ - new mw.echo.dm.NotificationItem( 3, { source: 'bar', read: false, seen: false, timestamp: '201601020000' } ), - new mw.echo.dm.NotificationItem( 4, { source: 'bar', read: false, seen: false, timestamp: '201601020100' } ), - new mw.echo.dm.NotificationItem( 5, { source: 'bar', read: false, seen: false, timestamp: '201601020200' } ), - new mw.echo.dm.NotificationItem( 6, { source: 'bar', read: false, seen: false, timestamp: '201601020300' } ) - ] - }, - { - name: 'baz', - sourceData: { - title: 'Baz Wiki', - base: 'http://baz.wiki.sample/$1' - }, - items: [ - new mw.echo.dm.NotificationItem( 7, { source: 'baz', timestamp: '201601050100' } ) - ] - } - ]; + numUnseenItems = model.getItems().filter( function ( item ) { + return !item.isSeen(); + } ).length; + assert.strictEqual( + numUnseenItems, + numAllItems - groupDefinitions[ 0 ].items.length, + 'Only some items are seen' + ); - // Add groups to model - for ( i = 0; i < groupDefinitions.length; i++ ) { - model.getList().addGroup( - groupDefinitions[ i ].name, - groupDefinitions[ i ].sourceData, - groupDefinitions[ i ].items - ); - } + // Update seen time to be bigger than all + model.updateSeenState( '201701010000' ); - // Listen to event - model.on( 'discard', function ( name ) { - results.push( name ); - } ); + numUnseenItems = model.getItems().filter( function ( item ) { + return !item.isSeen(); + } ).length; + assert.strictEqual( + numUnseenItems, + 0, + 'All items are seen' + ); +} ); - // Trigger - model.getList().removeGroup( 'foo' ); // [ 'foo' ] - // Empty a list - model.getList().getGroupByName( 'baz' ).discardItems( groupDefinitions[ 2 ].items ); // [ 'foo', 'baz' ] +QUnit.test( 'Emit discard event', function ( assert ) { + var results = []; + var model = new mw.echo.dm.CrossWikiNotificationItem( -1 ); + var groupDefinitions = [ + { + name: 'foo', + sourceData: { + title: 'Foo Wiki', + base: 'http://foo.wiki.sample/$1' + }, + items: [ + new mw.echo.dm.NotificationItem( 0, { source: 'foo', read: false, seen: false, timestamp: '201601010100' } ), + new mw.echo.dm.NotificationItem( 1, { source: 'foo', read: false, seen: false, timestamp: '201601010200' } ), + new mw.echo.dm.NotificationItem( 2, { source: 'foo', read: false, seen: false, timestamp: '201601010300' } ) + ] + }, + { + name: 'bar', + sourceData: { + title: 'Bar Wiki', + base: 'http://bar.wiki.sample/$1' + }, + items: [ + new mw.echo.dm.NotificationItem( 3, { source: 'bar', read: false, seen: false, timestamp: '201601020000' } ), + new mw.echo.dm.NotificationItem( 4, { source: 'bar', read: false, seen: false, timestamp: '201601020100' } ), + new mw.echo.dm.NotificationItem( 5, { source: 'bar', read: false, seen: false, timestamp: '201601020200' } ), + new mw.echo.dm.NotificationItem( 6, { source: 'bar', read: false, seen: false, timestamp: '201601020300' } ) + ] + }, + { + name: 'baz', + sourceData: { + title: 'Baz Wiki', + base: 'http://baz.wiki.sample/$1' + }, + items: [ + new mw.echo.dm.NotificationItem( 7, { source: 'baz', timestamp: '201601050100' } ) + ] + } + ]; - assert.deepEqual( - results, - [ 'foo', 'baz' ], - 'Discard event emitted' + // Add groups to model + for ( var i = 0; i < groupDefinitions.length; i++ ) { + model.getList().addGroup( + groupDefinitions[ i ].name, + groupDefinitions[ i ].sourceData, + groupDefinitions[ i ].items ); + } + + // Listen to event + model.on( 'discard', function ( name ) { + results.push( name ); } ); -}() ); + // Trigger + model.getList().removeGroup( 'foo' ); // [ 'foo' ] + // Empty a list + model.getList().getGroupByName( 'baz' ).discardItems( groupDefinitions[ 2 ].items ); // [ 'foo', 'baz' ] + + assert.deepEqual( + results, + [ 'foo', 'baz' ], + 'Discard event emitted' + ); +} ); diff --git a/Echo/tests/qunit/model/test_mw.echo.dm.FiltersModel.js b/Echo/tests/qunit/model/test_mw.echo.dm.FiltersModel.js index 21855af0..0031c832 100644 --- a/Echo/tests/qunit/model/test_mw.echo.dm.FiltersModel.js +++ b/Echo/tests/qunit/model/test_mw.echo.dm.FiltersModel.js @@ -1,110 +1,100 @@ -( function () { +QUnit.module( 'ext.echo.dm - FiltersModel' ); + +QUnit.test.each( 'Constructing the model', { + 'Empty config': { + config: {}, + expected: {} + }, + 'Readstate: unread': { + config: { + readState: 'unread' + }, + expected: { + getReadState: 'unread' + } + }, + 'Readstate: read': { + config: { + readState: 'read' + }, + expected: { + getReadState: 'read' + } + } +}, function ( assert, data ) { var defaultValues = { getReadState: 'all' }; + var expected = $.extend( true, {}, defaultValues, data.expected ); - QUnit.module( 'ext.echo.dm - mw.echo.dm.FiltersModel' ); - - QUnit.test( 'Constructing the model', function ( assert ) { - var i, model, method, - cases = [ - { - msg: 'Empty config', - config: {}, - expected: defaultValues - }, - { - msg: 'Readstate: unread', - config: { - readState: 'unread' - }, - expected: $.extend( true, {}, defaultValues, { - getReadState: 'unread' - } ) - }, - { - msg: 'Readstate: read', - config: { - readState: 'read' - }, - expected: $.extend( true, {}, defaultValues, { - getReadState: 'read' - } ) - } - ]; - - for ( i = 0; i < cases.length; i++ ) { - model = new mw.echo.dm.FiltersModel( cases[ i ].config ); + var model = new mw.echo.dm.FiltersModel( data.config ); - for ( method in cases[ i ].expected ) { - assert.deepEqual( - // Run the method - model[ method ](), - // Expected value - cases[ i ].expected[ method ], - // Message - cases[ i ].msg + ' (' + method + ')' - ); - } - } - } ); - - QUnit.test( 'Changing filters', function ( assert ) { - var model = new mw.echo.dm.FiltersModel(); - - assert.strictEqual( - model.getReadState(), - 'all', - 'Initial value: all' + for ( var method in expected ) { + assert.deepEqual( + // Run the method + model[ method ](), + // Expected value + expected[ method ], + // Message + method ); + } +} ); - model.setReadState( 'unread' ); - assert.strictEqual( - model.getReadState(), - 'unread', - 'Changing state (unread)' - ); +QUnit.test( 'Changing filters', function ( assert ) { + var model = new mw.echo.dm.FiltersModel(); - model.setReadState( 'read' ); - assert.strictEqual( - model.getReadState(), - 'read', - 'Changing state (read)' - ); + assert.strictEqual( + model.getReadState(), + 'all', + 'Initial value: all' + ); - model.setReadState( 'foo' ); - assert.strictEqual( - model.getReadState(), - 'read', - 'Ignoring invalid state (foo)' - ); - } ); + model.setReadState( 'unread' ); + assert.strictEqual( + model.getReadState(), + 'unread', + 'Changing state (unread)' + ); - QUnit.test( 'Emitting update event', function ( assert ) { - var results = [], - model = new mw.echo.dm.FiltersModel(); + model.setReadState( 'read' ); + assert.strictEqual( + model.getReadState(), + 'read', + 'Changing state (read)' + ); - // Listen to update event - model.on( 'update', function () { - results.push( model.getReadState() ); - } ); + model.setReadState( 'foo' ); + assert.strictEqual( + model.getReadState(), + 'read', + 'Ignoring invalid state (foo)' + ); +} ); - // Trigger events - model.setReadState( 'read' ); // [ 'read' ] - model.setReadState( 'unread' ); // [ 'read', 'unread' ] - model.setReadState( 'unread' ); // (no change, no event) [ 'read', 'unread' ] - model.setReadState( 'all' ); // [ 'read', 'unread', 'all' ] - model.setReadState( 'foo' ); // (invalid value, no event) [ 'read', 'unread', 'all' ] - model.setReadState( 'unread' ); // [ 'read', 'unread', 'all', 'unread' ] +QUnit.test( '.setReadState() events', function ( assert ) { + var results = []; + var model = new mw.echo.dm.FiltersModel(); - assert.deepEqual( - // Actual - results, - // Expected: - [ 'read', 'unread', 'all', 'unread' ], - // Message - 'Update events emitted' - ); + // Listen to update event + model.on( 'update', function () { + results.push( model.getReadState() ); } ); -}() ); + // Trigger events + model.setReadState( 'read' ); // [ 'read' ] + model.setReadState( 'unread' ); // [ 'read', 'unread' ] + model.setReadState( 'unread' ); // (no change, no event) [ 'read', 'unread' ] + model.setReadState( 'all' ); // [ 'read', 'unread', 'all' ] + model.setReadState( 'foo' ); // (invalid value, no event) [ 'read', 'unread', 'all' ] + model.setReadState( 'unread' ); // [ 'read', 'unread', 'all', 'unread' ] + + assert.deepEqual( + // Actual + results, + // Expected: + [ 'read', 'unread', 'all', 'unread' ], + // Message + 'Update events emitted' + ); +} ); diff --git a/Echo/tests/qunit/model/test_mw.echo.dm.NotificationGroupsList.js b/Echo/tests/qunit/model/test_mw.echo.dm.NotificationGroupsList.js index c71845a5..290b0423 100644 --- a/Echo/tests/qunit/model/test_mw.echo.dm.NotificationGroupsList.js +++ b/Echo/tests/qunit/model/test_mw.echo.dm.NotificationGroupsList.js @@ -1,156 +1,151 @@ -( function () { - QUnit.module( 'ext.echo.dm - mw.echo.dm.NotificationGroupsList' ); +QUnit.module( 'ext.echo.dm - NotificationGroupsList' ); - QUnit.test( 'Constructing the model', function ( assert ) { - var model = new mw.echo.dm.NotificationGroupsList(); +QUnit.test( 'Constructing the model', function ( assert ) { + var model = new mw.echo.dm.NotificationGroupsList(); - assert.strictEqual( - model.getTimestamp(), - 0, - 'Empty group has timestamp 0' - ); - } ); - - QUnit.test( 'Managing lists', function ( assert ) { - var i, group, - model = new mw.echo.dm.NotificationGroupsList(), - groupDefinitions = [ - { - name: 'foo', - sourceData: { - title: 'Foo Wiki', - base: 'http://foo.wiki.sample/$1' - }, - items: [ - new mw.echo.dm.NotificationItem( 0 ), - new mw.echo.dm.NotificationItem( 1 ), - new mw.echo.dm.NotificationItem( 2 ) - ] - }, - { - name: 'bar', - sourceData: { - title: 'Bar Wiki', - base: 'http://bar.wiki.sample/$1' - }, - items: [ - new mw.echo.dm.NotificationItem( 3 ), - new mw.echo.dm.NotificationItem( 4 ), - new mw.echo.dm.NotificationItem( 5 ), - new mw.echo.dm.NotificationItem( 6 ) - ] - }, - { - name: 'baz', - sourceData: { - title: 'Baz Wiki', - base: 'http://baz.wiki.sample/$1' - }, - items: [ - new mw.echo.dm.NotificationItem( 7 ) - ] - } - ]; + assert.strictEqual( + model.getTimestamp(), + 0, + 'Empty group has timestamp 0' + ); +} ); - for ( i = 0; i < groupDefinitions.length; i++ ) { - model.addGroup( - groupDefinitions[ i ].name, - groupDefinitions[ i ].sourceData, - groupDefinitions[ i ].items - ); - - assert.strictEqual( - model.getItemCount(), - i + 1, - 'Group number increases after addGroup ("' + groupDefinitions[ i ].name + '")' - ); - - group = model.getGroupByName( groupDefinitions[ i ].name ); - assert.strictEqual( - group.getName(), - groupDefinitions[ i ].name, - 'Group exists after addGroup ("' + groupDefinitions[ i ].name + '")' - ); +QUnit.test( 'Managing lists', function ( assert ) { + var model = new mw.echo.dm.NotificationGroupsList(); + var groupDefinitions = [ + { + name: 'foo', + sourceData: { + title: 'Foo Wiki', + base: 'http://foo.wiki.sample/$1' + }, + items: [ + new mw.echo.dm.NotificationItem( 0 ), + new mw.echo.dm.NotificationItem( 1 ), + new mw.echo.dm.NotificationItem( 2 ) + ] + }, + { + name: 'bar', + sourceData: { + title: 'Bar Wiki', + base: 'http://bar.wiki.sample/$1' + }, + items: [ + new mw.echo.dm.NotificationItem( 3 ), + new mw.echo.dm.NotificationItem( 4 ), + new mw.echo.dm.NotificationItem( 5 ), + new mw.echo.dm.NotificationItem( 6 ) + ] + }, + { + name: 'baz', + sourceData: { + title: 'Baz Wiki', + base: 'http://baz.wiki.sample/$1' + }, + items: [ + new mw.echo.dm.NotificationItem( 7 ) + ] } + ]; - // Remove group - model.removeGroup( groupDefinitions[ 0 ].name ); + groupDefinitions.forEach( function ( def, i ) { + model.addGroup( + def.name, + def.sourceData, + def.items + ); assert.strictEqual( model.getItemCount(), - groupDefinitions.length - 1, - 'Group number decreased after removeGroup' - ); - assert.strictEqual( - model.getGroupByName( groupDefinitions[ 0 ] ), - null, - 'Removed group is no longer in the list' + i + 1, + 'Group number increases after addGroup ("' + def.name + '")' ); - // Removing the last item from a group should remove the group - group = model.getGroupByName( 'baz' ); - group.discardItems( groupDefinitions[ 2 ].items ); + var result = model.getGroupByName( def.name ); assert.strictEqual( - model.getGroupByName( 'baz' ), - null, - 'Empty group is no longer in the list' + result.getName(), + def.name, + 'Group exists after addGroup ("' + def.name + '")' ); } ); - QUnit.test( 'Emitting discard event', function ( assert ) { - var group, - results = [], - model = new mw.echo.dm.NotificationGroupsList(), - groups = { - first: [ - new mw.echo.dm.NotificationItem( 0 ), - new mw.echo.dm.NotificationItem( 1 ), - new mw.echo.dm.NotificationItem( 2 ) - ], - second: [ - new mw.echo.dm.NotificationItem( 3 ), - new mw.echo.dm.NotificationItem( 4 ), - new mw.echo.dm.NotificationItem( 5 ) - ], - third: [ - new mw.echo.dm.NotificationItem( 6 ), - new mw.echo.dm.NotificationItem( 7 ) - ], - fourth: [ - new mw.echo.dm.NotificationItem( 8 ), - new mw.echo.dm.NotificationItem( 9 ) - ] - }; + // Remove group + model.removeGroup( groupDefinitions[ 0 ].name ); - // Listen to the event - model - .on( 'discard', function ( group ) { - results.push( group.getName() ); - } ); + assert.strictEqual( + model.getItemCount(), + groupDefinitions.length - 1, + 'Group number decreased after removeGroup' + ); + assert.strictEqual( + model.getGroupByName( groupDefinitions[ 0 ] ), + null, + 'Removed group is no longer in the list' + ); - // Fill the list - for ( group in groups ) { - model.addGroup( group, {}, groups[ group ] ); - } + // Removing the last item from a group should remove the group + var group = model.getGroupByName( 'baz' ); + group.discardItems( groupDefinitions[ 2 ].items ); + assert.strictEqual( + model.getGroupByName( 'baz' ), + null, + 'Empty group is no longer in the list' + ); +} ); - // Trigger events - model.removeGroup( 'first' ); // [ 'first' ] - model.removeGroup( 'fourth' ); // [ 'first', 'fourth' ] - // Group doesn't exist, no change - model.removeGroup( 'first' ); // [ 'first', 'fourth' ] - // Discard of an item in a group (no event on the list model) - model.getGroupByName( 'third' ).discardItems( groups.third[ 0 ] ); // [ 'first', 'fourth' ] - // Discard of the last item in a group (trigger discard event on the list model) - model.getGroupByName( 'third' ).discardItems( groups.third[ 1 ] ); // [ 'first', 'fourth', 'third' ] +QUnit.test( 'Emitting discard event', function ( assert ) { + var results = []; + var model = new mw.echo.dm.NotificationGroupsList(); + var groups = { + first: [ + new mw.echo.dm.NotificationItem( 0 ), + new mw.echo.dm.NotificationItem( 1 ), + new mw.echo.dm.NotificationItem( 2 ) + ], + second: [ + new mw.echo.dm.NotificationItem( 3 ), + new mw.echo.dm.NotificationItem( 4 ), + new mw.echo.dm.NotificationItem( 5 ) + ], + third: [ + new mw.echo.dm.NotificationItem( 6 ), + new mw.echo.dm.NotificationItem( 7 ) + ], + fourth: [ + new mw.echo.dm.NotificationItem( 8 ), + new mw.echo.dm.NotificationItem( 9 ) + ] + }; - assert.deepEqual( - // Actual - results, - // Expected: - [ 'first', 'fourth', 'third' ], - // Message - 'Discard events emitted' - ); - } ); + // Listen to the event + model + .on( 'discard', function ( g ) { + results.push( g.getName() ); + } ); + + // Fill the list + for ( var group in groups ) { + model.addGroup( group, {}, groups[ group ] ); + } + + // Trigger events + model.removeGroup( 'first' ); // [ 'first' ] + model.removeGroup( 'fourth' ); // [ 'first', 'fourth' ] + // Group doesn't exist, no change + model.removeGroup( 'first' ); // [ 'first', 'fourth' ] + // Discard of an item in a group (no event on the list model) + model.getGroupByName( 'third' ).discardItems( groups.third[ 0 ] ); // [ 'first', 'fourth' ] + // Discard of the last item in a group (trigger discard event on the list model) + model.getGroupByName( 'third' ).discardItems( groups.third[ 1 ] ); // [ 'first', 'fourth', 'third' ] -}() ); + assert.deepEqual( + // Actual + results, + // Expected: + [ 'first', 'fourth', 'third' ], + // Message + 'Discard events emitted' + ); +} ); diff --git a/Echo/tests/qunit/model/test_mw.echo.dm.NotificationItem.js b/Echo/tests/qunit/model/test_mw.echo.dm.NotificationItem.js index 34003830..daabb36a 100644 --- a/Echo/tests/qunit/model/test_mw.echo.dm.NotificationItem.js +++ b/Echo/tests/qunit/model/test_mw.echo.dm.NotificationItem.js @@ -1,122 +1,116 @@ ( function () { var fakeData = { - type: 'alert', - read: true, - seen: true, - timestamp: '2016-09-14T23:21:56Z', - content: { - header: 'Your edit on <strong>Moai</strong> was reverted.', - compactHeader: 'Your edit on <strong>Moai</strong> was reverted.', - body: 'undo' - }, - iconType: 'revert', - primaryUrl: 'http://dev.wiki.local.wmftest.net:8080/w/index.php?title=Moai&oldid=prev&diff=1978&markasread=2126', - secondaryUrls: [ - { - url: 'http://dev.wiki.local.wmftest.net:8080/wiki/User:RandomUser', - label: 'RandomUser', - icon: 'userAvatar' - }, - { - url: 'http://dev.wiki.local.wmftest.net:8080/wiki/Talk:Moai', - label: 'Moai', - tooltip: 'Talk:Moai', - icon: 'speechBubbles' - } - ] + type: 'alert', + read: true, + seen: true, + timestamp: '2016-09-14T23:21:56Z', + content: { + header: 'Your edit on <strong>Moai</strong> was reverted.', + compactHeader: 'Your edit on <strong>Moai</strong> was reverted.', + body: 'undo' }, - now = 1234567890000, - nowFormatted = '2009-02-13T23:31:30Z'; + iconType: 'revert', + primaryUrl: 'http://dev.wiki.local.wmftest.net:8080/w/index.php?title=Moai&oldid=prev&diff=1978&markasread=2126', + secondaryUrls: [ + { + url: 'http://dev.wiki.local.wmftest.net:8080/wiki/User:RandomUser', + label: 'RandomUser', + icon: 'userAvatar' + }, + { + url: 'http://dev.wiki.local.wmftest.net:8080/wiki/Talk:Moai', + label: 'Moai', + tooltip: 'Talk:Moai', + icon: 'speechBubbles' + } + ] + }; + var now = 1234567890000; + var nowFormatted = '2009-02-13T23:31:30Z'; - QUnit.module( 'ext.echo.dm - mw.echo.dm.NotificationItem', QUnit.newMwEnvironment( { - setup: function () { + QUnit.module( 'ext.echo.dm - NotificationItem', QUnit.newMwEnvironment( { + beforeEach: function () { this.sandbox.useFakeTimers( now ); } } ) ); - QUnit.test( 'Constructing items', function ( assert ) { - var i, j, itemModel, checkMethods, - defaultValues = { - getId: undefined, - getContentHeader: '', - getContentBody: '', - getCategory: '', - getType: 'message', - isRead: false, - isSeen: false, - isForeign: false, - isBundled: false, - getTimestamp: nowFormatted, - getPrimaryUrl: undefined, - getIconURL: undefined, - getIconType: undefined, - getSecondaryUrls: [], - getModelName: 'local', - getAllIds: [] - }, - tests = [ - { - msg: 'Empty data', - params: { id: 0, config: {} }, - tests: 'all', - expected: $.extend( true, {}, defaultValues, { getId: 0, getAllIds: [ 0 ] } ) - }, - { - msg: 'Fake data', - params: { id: 999, config: fakeData }, - tests: 'all', - expected: $.extend( true, {}, defaultValues, { - getId: 999, - getAllIds: [ 999 ], - getType: 'alert', - isRead: true, - isSeen: true, - getTimestamp: '2016-09-14T23:21:56Z', - getContentHeader: 'Your edit on <strong>Moai</strong> was reverted.', - getContentBody: 'undo', - getIconType: 'revert', - getPrimaryUrl: 'http://dev.wiki.local.wmftest.net:8080/w/index.php?title=Moai&oldid=prev&diff=1978&markasread=2126', - getSecondaryUrls: [ - { - url: 'http://dev.wiki.local.wmftest.net:8080/wiki/User:RandomUser', - label: 'RandomUser', - icon: 'userAvatar' - }, - { - url: 'http://dev.wiki.local.wmftest.net:8080/wiki/Talk:Moai', - label: 'Moai', - tooltip: 'Talk:Moai', - icon: 'speechBubbles' - } - ] - } ) - } - ]; - - for ( i = 0; i < tests.length; i++ ) { - itemModel = new mw.echo.dm.NotificationItem( tests[ i ].params.id, tests[ i ].params.config ); - - checkMethods = tests[ i ].tests; - if ( tests[ i ].tests === 'all' ) { - checkMethods = Object.keys( defaultValues ); - } - - for ( j = 0; j < checkMethods.length; j++ ) { - assert.deepEqual( - // Run the method - itemModel[ checkMethods[ j ] ](), - // Expected result - tests[ i ].expected[ checkMethods[ j ] ], - // Message - tests[ i ].msg + ' (' + checkMethods[ j ] + ')' - ); + QUnit.test.each( 'Constructing items', { + 'Empty data': { + params: { id: 0, config: {} }, + methods: 'all', + expected: { getId: 0, getAllIds: [ 0 ] } + }, + 'Fake data': { + params: { id: 999, config: fakeData }, + methods: 'all', + expected: { + getId: 999, + getAllIds: [ 999 ], + getType: 'alert', + isRead: true, + isSeen: true, + getTimestamp: '2016-09-14T23:21:56Z', + getContentHeader: 'Your edit on <strong>Moai</strong> was reverted.', + getContentBody: 'undo', + getIconType: 'revert', + getPrimaryUrl: 'http://dev.wiki.local.wmftest.net:8080/w/index.php?title=Moai&oldid=prev&diff=1978&markasread=2126', + getSecondaryUrls: [ + { + url: 'http://dev.wiki.local.wmftest.net:8080/wiki/User:RandomUser', + label: 'RandomUser', + icon: 'userAvatar' + }, + { + url: 'http://dev.wiki.local.wmftest.net:8080/wiki/Talk:Moai', + label: 'Moai', + tooltip: 'Talk:Moai', + icon: 'speechBubbles' + } + ] } } + }, function ( assert, data ) { + var defaultValues = { + getId: undefined, + getContentHeader: '', + getContentBody: '', + getCategory: '', + getType: 'message', + isRead: false, + isSeen: false, + isForeign: false, + isBundled: false, + getTimestamp: nowFormatted, + getPrimaryUrl: undefined, + getIconURL: undefined, + getIconType: undefined, + getSecondaryUrls: [], + getModelName: 'local', + getAllIds: [] + }; + var expected = $.extend( true, {}, defaultValues, data.expected ); + + var itemModel = new mw.echo.dm.NotificationItem( + data.params.id, + data.params.config + ); + + var methods = ( data.methods === 'all' ? Object.keys( expected ) : data.methods ); + methods.forEach( function ( method ) { + assert.deepEqual( + // Run the method + itemModel[ method ](), + // Expected result + expected[ method ], + // Message + method + ); + } ); } ); QUnit.test( 'Emitting update event', function ( assert ) { - var results = [], - itemModel = new mw.echo.dm.NotificationItem( 0, $.extend( true, {}, fakeData, { seen: false, read: false } ) ); + var results = []; + var itemModel = new mw.echo.dm.NotificationItem( 0, $.extend( true, {}, fakeData, { seen: false, read: false } ) ); // Listen to update event itemModel.on( 'update', function () { diff --git a/Echo/tests/qunit/model/test_mw.echo.dm.NotificationsList.js b/Echo/tests/qunit/model/test_mw.echo.dm.NotificationsList.js index ef700aa5..46101570 100644 --- a/Echo/tests/qunit/model/test_mw.echo.dm.NotificationsList.js +++ b/Echo/tests/qunit/model/test_mw.echo.dm.NotificationsList.js @@ -1,4 +1,28 @@ -( function () { +QUnit.module( 'ext.echo.dm - NotificationsList' ); + +QUnit.test.each( 'Constructing the model', { + 'Empty config': { + config: {}, + expected: {} + }, + 'Prefilled data': { + config: { + title: 'Some title', + name: 'local_demo', + source: 'hewiki', + sourceURL: 'http://he.wiki.local.wmftest.net:8080/wiki/$1', + timestamp: '20160916171300' + }, + expected: { + getTitle: 'Some title', + getName: 'local_demo', + getSource: 'hewiki', + getSourceURL: 'http://he.wiki.local.wmftest.net:8080/wiki/$1', + getTimestamp: '20160916171300', + isForeign: true + } + } +}, function ( assert, data ) { var defaultValues = { getAllItemIds: [], getAllItemIdsByType: [], @@ -11,179 +35,145 @@ hasUnseen: false, isForeign: false }; + var expected = $.extend( true, {}, defaultValues, data.expected ); + var model = new mw.echo.dm.NotificationsList( data.config ); - QUnit.module( 'ext.echo.dm - mw.echo.dm.NotificationsList' ); - - QUnit.test( 'Constructing the model', function ( assert ) { - var i, model, method, - cases = [ - { - msg: 'Empty config', - config: {}, - expected: defaultValues - }, - { - msg: 'Prefilled data', - config: { - title: 'Some title', - name: 'local_demo', - source: 'hewiki', - sourceURL: 'http://he.wiki.local.wmftest.net:8080/wiki/$1', - timestamp: '20160916171300' - }, - expected: $.extend( true, {}, defaultValues, { - getTitle: 'Some title', - getName: 'local_demo', - getSource: 'hewiki', - getSourceURL: 'http://he.wiki.local.wmftest.net:8080/wiki/$1', - getTimestamp: '20160916171300', - isForeign: true - } ) - } - ]; - - for ( i = 0; i < cases.length; i++ ) { - model = new mw.echo.dm.NotificationsList( cases[ i ].config ); - - for ( method in cases[ i ].expected ) { - assert.deepEqual( - // Run the method - model[ method ](), - // Expected value - cases[ i ].expected[ method ], - // Message - cases[ i ].msg + ' (' + method + ')' - ); - } - } - } ); - - QUnit.test( 'Handling notification items', function ( assert ) { - var model = new mw.echo.dm.NotificationsList( { timestamp: '200101010000' } ), - items = [ - new mw.echo.dm.NotificationItem( 0, { type: 'alert', timestamp: '201609190000', read: false, seen: false } ), - new mw.echo.dm.NotificationItem( 1, { type: 'message', timestamp: '201609190100', read: false, seen: true } ), - new mw.echo.dm.NotificationItem( 2, { type: 'alert', timestamp: '201609190200', read: true, seen: true } ), - new mw.echo.dm.NotificationItem( 3, { type: 'message', timestamp: '201609190300', read: true, seen: true } ), - new mw.echo.dm.NotificationItem( 4, { type: 'alert', timestamp: '201609190400', read: true, seen: true } ), - new mw.echo.dm.NotificationItem( 5, { type: 'message', timestamp: '201609190500', read: true, seen: false } ) - ]; - - assert.strictEqual( - model.getCount(), - 0, - 'Model list starts empty' - ); - assert.strictEqual( - model.getTimestamp(), - '200101010000', - 'Model timestamp is its default' - ); - - model.setItems( items ); - assert.strictEqual( - model.getCount(), - 6, - 'Item list setup' - ); - assert.strictEqual( - model.getTimestamp(), - '201609190100', - 'Model timestamp is the latest unread item\'s timestamp' - ); - assert.deepEqual( - model.getAllItemIds(), - [ 1, 0, 5, 4, 3, 2 ], - 'getAllItemIds (sorted)' - ); - assert.deepEqual( - [ - model.getAllItemIdsByType( 'alert' ), - model.getAllItemIdsByType( 'message' ) - ], - [ - [ 0, 4, 2 ], - [ 1, 5, 3 ] - ], - 'getAllItemIdsByType (sorted)' - ); + for ( var method in expected ) { assert.deepEqual( - model.findByIds( [ 1, 2 ] ), - [ items[ 1 ], items[ 2 ] ], - 'findByIds' - ); - - // Change item state (trigger resort) - items[ 1 ].toggleRead( true ); - items[ 3 ].toggleRead( false ); - items[ 5 ].toggleSeen( true ); // Will not affect sorting order of the item - assert.deepEqual( - model.getAllItemIds(), - [ 3, 0, 5, 4, 2, 1 ], - 'getAllItemIds (re-sorted)' - ); - - // Discard items - model.discardItems( [ items[ 5 ], items[ 2 ] ] ); - - assert.deepEqual( - model.getAllItemIds(), - [ 3, 0, 4, 1 ], - 'getAllItemIds (discarded items)' - ); - assert.deepEqual( - [ - model.getAllItemIdsByType( 'alert' ), - model.getAllItemIdsByType( 'message' ) - ], - [ - [ 0, 4 ], - [ 3, 1 ] - ], - 'getAllItemIdsByType (discarded items)' - ); - - } ); - - QUnit.test( 'Intercepting events', function ( assert ) { - var model = new mw.echo.dm.NotificationsList(), - result = [], - items = [ - new mw.echo.dm.NotificationItem( 0, { timestamp: '201609190000', read: false, seen: false } ), - new mw.echo.dm.NotificationItem( 1, { timestamp: '201609190100', read: false, seen: true } ), - new mw.echo.dm.NotificationItem( 2, { timestamp: '201609190200', read: true, seen: true } ), - new mw.echo.dm.NotificationItem( 3, { timestamp: '201609190300', read: true, seen: true } ), - new mw.echo.dm.NotificationItem( 4, { timestamp: '201609190400', read: true, seen: true } ), - new mw.echo.dm.NotificationItem( 5, { timestamp: '201609190500', read: true, seen: true } ) - ]; - - // Listen to events - model - .on( 'update', function ( items ) { - result.push( 'update:' + items.length ); - } ) - .on( 'discard', function ( item ) { - result.push( 'discard:' + item.getId() ); - } ) - .on( 'itemUpdate', function ( item ) { - result.push( 'itemUpdate:' + item.getId() ); - } ); - - // Set up and trigger events - model - .setItems( items ); // [ 'update:6' ] - model.discardItems( items[ items.length - 1 ] ); // [ 'update:6', 'discard:5' ] - items[ 0 ].toggleSeen( true ); // [ 'update:6', 'discard:5', 'itemUpdate:0' ] - items[ 1 ].toggleRead( true ); // [ 'update:6', 'discard:5', 'itemUpdate:0', 'itemUpdate:1' ] - - assert.deepEqual( - // Actual - result, - // Expected: - [ 'update:6', 'discard:5', 'itemUpdate:0', 'itemUpdate:1' ], + // Run the method + model[ method ](), + // Expected value + expected[ method ], // Message - 'Events emitted correctly' + method ); - } ); - -}() ); + } +} ); + +QUnit.test( 'Handling notification items', function ( assert ) { + var model = new mw.echo.dm.NotificationsList( { timestamp: '200101010000' } ); + var items = [ + new mw.echo.dm.NotificationItem( 0, { type: 'alert', timestamp: '201609190000', read: false, seen: false } ), + new mw.echo.dm.NotificationItem( 1, { type: 'message', timestamp: '201609190100', read: false, seen: true } ), + new mw.echo.dm.NotificationItem( 2, { type: 'alert', timestamp: '201609190200', read: true, seen: true } ), + new mw.echo.dm.NotificationItem( 3, { type: 'message', timestamp: '201609190300', read: true, seen: true } ), + new mw.echo.dm.NotificationItem( 4, { type: 'alert', timestamp: '201609190400', read: true, seen: true } ), + new mw.echo.dm.NotificationItem( 5, { type: 'message', timestamp: '201609190500', read: true, seen: false } ) + ]; + + assert.strictEqual( + model.getCount(), + 0, + 'Model list starts empty' + ); + assert.strictEqual( + model.getTimestamp(), + '200101010000', + 'Model timestamp is its default' + ); + + model.setItems( items ); + assert.strictEqual( + model.getCount(), + 6, + 'Item list setup' + ); + assert.strictEqual( + model.getTimestamp(), + '201609190100', + 'Model timestamp is the latest unread item\'s timestamp' + ); + assert.deepEqual( + model.getAllItemIds(), + [ 1, 0, 5, 4, 3, 2 ], + 'getAllItemIds (sorted)' + ); + assert.deepEqual( + [ + model.getAllItemIdsByType( 'alert' ), + model.getAllItemIdsByType( 'message' ) + ], + [ + [ 0, 4, 2 ], + [ 1, 5, 3 ] + ], + 'getAllItemIdsByType (sorted)' + ); + assert.deepEqual( + model.findByIds( [ 1, 2 ] ), + [ items[ 1 ], items[ 2 ] ], + 'findByIds' + ); + + // Change item state (trigger resort) + items[ 1 ].toggleRead( true ); + items[ 3 ].toggleRead( false ); + items[ 5 ].toggleSeen( true ); // Will not affect sorting order of the item + assert.deepEqual( + model.getAllItemIds(), + [ 3, 0, 5, 4, 2, 1 ], + 'getAllItemIds (re-sorted)' + ); + + // Discard items + model.discardItems( [ items[ 5 ], items[ 2 ] ] ); + + assert.deepEqual( + model.getAllItemIds(), + [ 3, 0, 4, 1 ], + 'getAllItemIds (discarded items)' + ); + assert.deepEqual( + [ + model.getAllItemIdsByType( 'alert' ), + model.getAllItemIdsByType( 'message' ) + ], + [ + [ 0, 4 ], + [ 3, 1 ] + ], + 'getAllItemIdsByType (discarded items)' + ); + +} ); + +QUnit.test( 'Intercepting events', function ( assert ) { + var model = new mw.echo.dm.NotificationsList(); + var result = []; + var items = [ + new mw.echo.dm.NotificationItem( 0, { timestamp: '201609190000', read: false, seen: false } ), + new mw.echo.dm.NotificationItem( 1, { timestamp: '201609190100', read: false, seen: true } ), + new mw.echo.dm.NotificationItem( 2, { timestamp: '201609190200', read: true, seen: true } ), + new mw.echo.dm.NotificationItem( 3, { timestamp: '201609190300', read: true, seen: true } ), + new mw.echo.dm.NotificationItem( 4, { timestamp: '201609190400', read: true, seen: true } ), + new mw.echo.dm.NotificationItem( 5, { timestamp: '201609190500', read: true, seen: true } ) + ]; + + // Listen to events + model + .on( 'update', function ( itms ) { + result.push( 'update:' + itms.length ); + } ) + .on( 'discard', function ( item ) { + result.push( 'discard:' + item.getId() ); + } ) + .on( 'itemUpdate', function ( item ) { + result.push( 'itemUpdate:' + item.getId() ); + } ); + + // Set up and trigger events + model + .setItems( items ); // [ 'update:6' ] + model.discardItems( items[ items.length - 1 ] ); // [ 'update:6', 'discard:5' ] + items[ 0 ].toggleSeen( true ); // [ 'update:6', 'discard:5', 'itemUpdate:0' ] + items[ 1 ].toggleRead( true ); // [ 'update:6', 'discard:5', 'itemUpdate:0', 'itemUpdate:1' ] + + assert.deepEqual( + // Actual + result, + // Expected: + [ 'update:6', 'discard:5', 'itemUpdate:0', 'itemUpdate:1' ], + // Message + 'Events emitted correctly' + ); +} ); diff --git a/Echo/tests/qunit/model/test_mw.echo.dm.PaginationModel.js b/Echo/tests/qunit/model/test_mw.echo.dm.PaginationModel.js index 52dca12a..453eefcd 100644 --- a/Echo/tests/qunit/model/test_mw.echo.dm.PaginationModel.js +++ b/Echo/tests/qunit/model/test_mw.echo.dm.PaginationModel.js @@ -1,4 +1,23 @@ -( function () { +QUnit.module( 'ext.echo.dm - PaginationModel' ); + +QUnit.test.each( 'Constructing the model', { + 'Empty config': { + config: {}, + expected: {} + }, + 'Overriding defaults': { + config: { + pageNext: 'continueValNext|123', + itemsPerPage: 10 + }, + expected: { + getNextPageContinue: 'continueValNext|123', + hasNextPage: true, + getItemsPerPage: 10, + getCurrentPageItemCount: 10 + } + } +}, function ( assert, data ) { var defaultValues = { getPageContinue: undefined, getCurrPageIndex: 0, @@ -10,82 +29,54 @@ getCurrentPageItemCount: 25, getItemsPerPage: 25 }; + var expected = $.extend( true, {}, defaultValues, data.expected ); - QUnit.module( 'ext.echo.dm - mw.echo.dm.PaginationModel' ); + var model = new mw.echo.dm.PaginationModel( data.config ); - QUnit.test( 'Constructing the model', function ( assert ) { - var i, model, method, - cases = [ - { - msg: 'Empty config', - config: {}, - expected: defaultValues - }, - { - msg: 'Overridng defaults', - config: { - pageNext: 'continueValNext|123', - itemsPerPage: 10 - }, - expected: $.extend( true, {}, defaultValues, { - getNextPageContinue: 'continueValNext|123', - hasNextPage: true, - getItemsPerPage: 10, - getCurrentPageItemCount: 10 - } ) - } - ]; + for ( var method in expected ) { + assert.deepEqual( + // Run the method + model[ method ](), + // Expected value + expected[ method ], + // Message + method + ); + } +} ); - for ( i = 0; i < cases.length; i++ ) { - model = new mw.echo.dm.PaginationModel( cases[ i ].config ); +QUnit.test( 'Emitting update event', function ( assert ) { + var results = []; + var model = new mw.echo.dm.PaginationModel(); - for ( method in cases[ i ].expected ) { - assert.deepEqual( - // Run the method - model[ method ](), - // Expected value - cases[ i ].expected[ method ], - // Message - cases[ i ].msg + ' (' + method + ')' - ); - } - } + // Listen to update event + model.on( 'update', function () { + results.push( [ + model.getCurrPageIndex(), + model.hasNextPage() + ] ); } ); - QUnit.test( 'Emitting update event', function ( assert ) { - var results = [], - model = new mw.echo.dm.PaginationModel(); - - // Listen to update event - model.on( 'update', function () { - results.push( [ - model.getCurrPageIndex(), - model.hasNextPage() - ] ); - } ); + // Trigger events - // Trigger events + // Set up initial pages (first page is 0) + model.setPageContinue( 1, 'page2|2' ); // [ [ 0, true ] ] + model.setPageContinue( 2, 'page3|3' ); // [ [ 0, true ], [ 0, true ] ] + model.setPageContinue( 3, 'page4|4' ); // [ [ 0, true ], [ 0, true ], [ 0, true ] ] - // Set up initial pages (first page is 0) - model.setPageContinue( 1, 'page2|2' ); // [ [ 0, true ] ] - model.setPageContinue( 2, 'page3|3' ); // [ [ 0, true ], [ 0, true ] ] - model.setPageContinue( 3, 'page4|4' ); // [ [ 0, true ], [ 0, true ], [ 0, true ] ] - - model.forwards(); // [ [ 0, true ], [ 0, true ], [ 0, true ], [ 1, true ] ] - model.forwards(); // [ [ 0, true ], [ 0, true ], [ 0, true ], [ 1, true ], [ 2, true ] ] - model.forwards(); // [ [ 0, true ], [ 0, true ], [ 0, true ], [ 1, true ], [ 2, true ], [ 3, false ] ] - model.backwards(); // [ [ 0, true ], [ 0, true ], [ 0, true ], [ 1, true ], [ 2, true ], [ 3, false ], [ 2, true ] ] - model.setCurrentPageItemCount(); // [ [ 0, true ], [ 0, true ], [ 0, true ], [ 1, true ], [ 2, true ], [ 3, false ], [ 2, true ], [ 2, true ] ] - model.reset(); // [ [ 0, true ], [ 0, true ], [ 0, true ], [ 1, true ], [ 2, true ], [ 3, false ], [ 2, true ], [ 2, true ], [ 0, false ] ] - - assert.deepEqual( - // Actual - results, - // Expected: - [ [ 0, true ], [ 0, true ], [ 0, true ], [ 1, true ], [ 2, true ], [ 3, false ], [ 2, true ], [ 2, true ], [ 0, false ] ], - // Message - 'Update events emitted' - ); - } ); + model.forwards(); // [ [ 0, true ], [ 0, true ], [ 0, true ], [ 1, true ] ] + model.forwards(); // [ [ 0, true ], [ 0, true ], [ 0, true ], [ 1, true ], [ 2, true ] ] + model.forwards(); // [ [ 0, true ], [ 0, true ], [ 0, true ], [ 1, true ], [ 2, true ], [ 3, false ] ] + model.backwards(); // [ [ 0, true ], [ 0, true ], [ 0, true ], [ 1, true ], [ 2, true ], [ 3, false ], [ 2, true ] ] + model.setCurrentPageItemCount(); // [ [ 0, true ], [ 0, true ], [ 0, true ], [ 1, true ], [ 2, true ], [ 3, false ], [ 2, true ], [ 2, true ] ] + model.reset(); // [ [ 0, true ], [ 0, true ], [ 0, true ], [ 1, true ], [ 2, true ], [ 3, false ], [ 2, true ], [ 2, true ], [ 0, false ] ] -}() ); + assert.deepEqual( + // Actual + results, + // Expected: + [ [ 0, true ], [ 0, true ], [ 0, true ], [ 1, true ], [ 2, true ], [ 3, false ], [ 2, true ], [ 2, true ], [ 0, false ] ], + // Message + 'Update events emitted' + ); +} ); diff --git a/Echo/tests/qunit/model/test_mw.echo.dm.SeenTimeModel.js b/Echo/tests/qunit/model/test_mw.echo.dm.SeenTimeModel.js index ce25ae14..d246ef5c 100644 --- a/Echo/tests/qunit/model/test_mw.echo.dm.SeenTimeModel.js +++ b/Echo/tests/qunit/model/test_mw.echo.dm.SeenTimeModel.js @@ -1,56 +1,54 @@ -( function () { - QUnit.module( 'ext.echo.dm - mw.echo.dm.SeenTimeModel' ); - - QUnit.test( 'Constructing the model', function ( assert ) { - var model = new mw.echo.dm.SeenTimeModel(); - - assert.deepEqual( - model.getTypes(), - [ 'alert', 'message' ], - 'Default model has both types' - ); +QUnit.module( 'ext.echo.dm - SeenTimeModel' ); + +QUnit.test( '.getTypes()', function ( assert ) { + var model = new mw.echo.dm.SeenTimeModel(); + + assert.deepEqual( + model.getTypes(), + [ 'alert', 'message' ], + 'Default model has both types' + ); +} ); + +QUnit.test( '.setSeenTime() reflected', function ( assert ) { + var model; + + model = new mw.echo.dm.SeenTimeModel(); + model.setSeenTime( '20160101010000' ); + + assert.deepEqual( + model.getSeenTime(), + '20160101010000', + 'Model sets seen time for both types' + ); + + model = new mw.echo.dm.SeenTimeModel( { types: 'alert' } ); + model.setSeenTime( '20160101010001' ); + + assert.deepEqual( + model.getSeenTime(), + '20160101010001', + 'Alerts seen time model returns correct time' + ); +} ); + +QUnit.test( '.setSeenTime() events', function ( assert ) { + var results = []; + var model = new mw.echo.dm.SeenTimeModel(); + + // Attach a listener + model.on( 'update', function ( time ) { + results.push( time ); } ); - QUnit.test( 'Handling seenTime', function ( assert ) { - var model; - - model = new mw.echo.dm.SeenTimeModel(); - model.setSeenTime( '20160101010000' ); - - assert.deepEqual( - model.getSeenTime(), - '20160101010000', - 'Model sets seen time for both types' - ); - - model = new mw.echo.dm.SeenTimeModel( { types: 'alert' } ); - model.setSeenTime( '20160101010001' ); - - assert.deepEqual( - model.getSeenTime(), - '20160101010001', - 'Alerts seen time model returns correct time' - ); - } ); - - QUnit.test( 'Emitting update event', function ( assert ) { - var results = [], - model = new mw.echo.dm.SeenTimeModel(); - - // Attach a listener - model.on( 'update', function ( time ) { - results.push( time ); - } ); - - // Trigger events - model.setSeenTime( '1' ); // [ '1' ] - model.setSeenTime( '2' ); // [ '1', '2' ] - model.setSeenTime( '2' ); // (no change, no event) [ '1', '2' ] - - assert.deepEqual( - results, - [ '1', '2' ], - 'Update event emitted' - ); - } ); -}() ); + // Trigger events + model.setSeenTime( '1' ); // [ '1' ] + model.setSeenTime( '2' ); // [ '1', '2' ] + model.setSeenTime( '2' ); // (no change, no event) [ '1', '2' ] + + assert.deepEqual( + results, + [ '1', '2' ], + 'events emitted' + ); +} ); diff --git a/Echo/tests/qunit/model/test_mw.echo.dm.SourcePagesModel.js b/Echo/tests/qunit/model/test_mw.echo.dm.SourcePagesModel.js index 49162632..981702c3 100644 --- a/Echo/tests/qunit/model/test_mw.echo.dm.SourcePagesModel.js +++ b/Echo/tests/qunit/model/test_mw.echo.dm.SourcePagesModel.js @@ -1,4 +1,4 @@ -( function () { +QUnit.module( 'ext.echo.dm - SourcePagesModel', function () { // Mock partial API response we feed into the model var sources = { local: { @@ -75,8 +75,6 @@ } }; - QUnit.module( 'ext.echo.dm - mw.echo.dm.SourcePagesModel' ); - QUnit.test( 'Creating source-page map', function ( assert ) { var model = new mw.echo.dm.SourcePagesModel(); @@ -169,4 +167,4 @@ ); } ); -}() ); +} ); diff --git a/Echo/tests/qunit/model/test_mw.echo.dm.UnreadNotificationCounter.js b/Echo/tests/qunit/model/test_mw.echo.dm.UnreadNotificationCounter.js index 2f2a2a09..ecd8c0b0 100644 --- a/Echo/tests/qunit/model/test_mw.echo.dm.UnreadNotificationCounter.js +++ b/Echo/tests/qunit/model/test_mw.echo.dm.UnreadNotificationCounter.js @@ -1,85 +1,76 @@ -( function () { - QUnit.module( 'ext.echo.dm - mw.echo.dm.UnreadNotificationCounter' ); +QUnit.module( 'ext.echo.dm - UnreadNotificationCounter' ); - QUnit.test( 'Returning capped notifications count', function ( assert ) { - var i, - model = new mw.echo.dm.UnreadNotificationCounter( - null, - 'all', // type - 10 // max - ), - cases = [ - { input: 5, output: 5 }, - { input: 20, output: 11 }, - { input: 10, output: 10 } - ]; +QUnit.test.each( '.getCappedNotificationCount()', [ + { input: 5, output: 5 }, + { input: 20, output: 11 }, + { input: 10, output: 10 } +], function ( assert, data ) { + var model = new mw.echo.dm.UnreadNotificationCounter( + null, + 'all', // type + 10 // max + ); + assert.strictEqual( + model.getCappedNotificationCount( data.input ), + data.output, + 'count for ' + data.input + ); +} ); - for ( i = 0; i < cases.length; i++ ) { - assert.strictEqual( - model.getCappedNotificationCount( cases[ i ].input ), - cases[ i ].output, - 'Capped notifications count: ' + - cases[ i ].input + ' -> ' + - cases[ i ].output - ); - } - } ); - - QUnit.test( 'Estimate change', function ( assert ) { - var model = new mw.echo.dm.UnreadNotificationCounter( - null, - 'all', // type - 99 // max - ); - // Set initial - model.setCount( 50 ); +QUnit.test( '.estimateChange()', function ( assert ) { + var model = new mw.echo.dm.UnreadNotificationCounter( + null, + 'all', // type + 99 // max + ); + // Set initial + model.setCount( 50 ); - model.estimateChange( -10 ); - assert.strictEqual( - model.getCount(), - 40, // 50-10 - 'Estimation within range' - ); + model.estimateChange( -10 ); + assert.strictEqual( + model.getCount(), + 40, // 50-10 + 'Estimation within range' + ); - model.estimateChange( 70 ); - assert.strictEqual( - model.getCount(), - 100, // Estimation reached above cap - cap is set - 'Estimation brings count to cap' - ); + model.estimateChange( 70 ); + assert.strictEqual( + model.getCount(), + 100, // Estimation reached above cap - cap is set + 'Estimation brings count to cap' + ); - model.estimateChange( -10 ); - assert.strictEqual( - model.getCount(), - 100, // We are already above cap, count will not change - 'Estimation while counter is outside of cap - no change' - ); - } ); + model.estimateChange( -10 ); + assert.strictEqual( + model.getCount(), + 100, // We are already above cap, count will not change + 'Estimation while counter is outside of cap - no change' + ); +} ); - QUnit.test( 'Emitting countChange event', function ( assert ) { - var results = [], - model = new mw.echo.dm.UnreadNotificationCounter( - null, - 'all', // type - 99 // max - ); +QUnit.test( '.setCount()', function ( assert ) { + var results = []; + var model = new mw.echo.dm.UnreadNotificationCounter( + null, + 'all', // type + 99 // max + ); - // Listen to event - model.on( 'countChange', function ( count ) { - results.push( count ); - } ); + // Listen to event + model.on( 'countChange', function ( count ) { + results.push( count ); + } ); - // Trigger events - model.setCount( 50 ); // [ 50 ] - model.setCount( 300, true ); // (estimate, above max, bring to cap) [ 50, 100 ] - model.setCount( -1, true ); // (estimate while counter is above cap, no event) [ 50, 100 ] - model.setCount( 200 ); // (setting above cap, value is capped, same as current, no event) [ 50,100 ] - model.setCount( 10 ); // [ 50, 100, 10 ] + // Trigger events + model.setCount( 50 ); // [ 50 ] + model.setCount( 300, true ); // (estimate, above max, bring to cap) [ 50, 100 ] + model.setCount( -1, true ); // (estimate while counter is above cap, no event) [ 50, 100 ] + model.setCount( 200 ); // (setting above cap, value is capped, same as current, no event) [ 50,100 ] + model.setCount( 10 ); // [ 50, 100, 10 ] - assert.deepEqual( - results, - [ 50, 100, 10 ], - 'countChange events emitted.' - ); - } ); -}() ); + assert.deepEqual( + results, + [ 50, 100, 10 ], + 'countChange events emitted.' + ); +} ); diff --git a/Echo/tests/qunit/overlay/test_ext.echo.overlay.js b/Echo/tests/qunit/overlay/test_ext.echo.overlay.js deleted file mode 100644 index 9d54139a..00000000 --- a/Echo/tests/qunit/overlay/test_ext.echo.overlay.js +++ /dev/null @@ -1,351 +0,0 @@ -( function () { - QUnit.module( 'ext.echo.overlay', { - beforeEach: function () { - var ApiStub; - - this.$badge = $( '<a class="mw-echo-notifications-badge mw-echo-unseen-notifications">1</a>' ); - this.sandbox.stub( mw.echo, 'getBadge' ).returns( this.$badge ); - // Kill any existing overlays to avoid clashing with other tests - $( '.mw-echo-overlay' ).remove(); - - ApiStub = function ( mode, numberUnreadMessages ) { - this.mode = mode; - this.numberUnreadMessages = numberUnreadMessages || 7; - }; - ApiStub.prototype = { - post: function ( data ) { - switch ( data.action ) { - case 'echomarkread': - data = this.getNewNotificationCountData( data, this.mode === 'with-new-messages' ); - break; - - case 'echomarkseen': - data = { query: { echomarkseen: { result: 'success', timestamp: '20140509000000' } } }; - break; - - default: - throw new Error( 'Unrecognized post action: ' + data.action ); - } - - return $.Deferred().resolve( data ); - }, - postWithToken: function ( type, data ) { - return this.post( data ); - }, - get: function () { - var i, id, - index = [], - listObj = {}, - data = this.getData(); - // a response which contains 0 unread messages and 1 unread alert - if ( this.mode === 'no-new-messages' ) { - data.query.notifications.message = { - index: [ 100 ], - list: { - 100: { - '*': 'Jon sent you a message on the Flow board Talk:XYZ', - read: '20140805211446', - category: 'message', - id: 100, - timestamp: { - date: '8 May', - mw: '20140508211436', - unix: '1407273276', - utcunix: '1407273276' - }, - type: 'message' - } - }, - rawcount: 0, - count: '0' - }; - // a response which contains 8 unread messages and 1 unread alert - } else if ( this.mode === 'with-new-messages' ) { - for ( i = 0; i < 7; i++ ) { - id = 500 + i; - index.push( id ); - listObj[ id ] = { - '*': '!', - category: 'message', - id: id, - timestamp: { - date: '8 May', - mw: '20140508211436', - unix: '1407273276', - utcunix: '1407273276' - }, - type: 'message' - }; - } - data.query.notifications.message = { - index: index, - list: listObj, - rawcount: this.numberUnreadMessages, - count: String( this.numberUnreadMessages ) - }; - // Total number is number of messages + number of alerts (1) - data.query.notifications.count = this.numberUnreadMessages + 1; - data.query.notifications.rawcount = this.numberUnreadMessages + 1; - } - return $.Deferred().resolve( data ); - }, - getNewNotificationCountData: function ( data, hasNewMessages ) { - var alertCount, messageCount, - rawCount = 0, - count = 0; - - messageCount = { - count: '0', - rawcount: 0 - }; - alertCount = { - count: '0', - rawcount: 0 - }; - if ( data.list === '100' ) { - alertCount = { - count: '0', - rawcount: 0 - }; - count = 1; - rawCount = 1; - } - - if ( hasNewMessages && data.sections === 'alert' ) { - messageCount = { - count: '7', - rawcount: 7 - }; - rawCount = 7; - count = 7; - } - - if ( data.list === 500 ) { - messageCount = { - count: '6', - rawcount: 6 - }; - rawCount = 6; - count = 6; - } - - data = { - query: { - echomarkread: { - alert: alertCount, - message: messageCount, - rawcount: rawCount, - count: count - } - } - }; - return data; - }, - getData: function () { - return { - query: { - notifications: { - count: '1', - rawcount: 1, - message: { - rawcount: 0, - count: '0', - index: [], - list: {} - }, - alert: { - rawcount: 1, - count: '1', - index: [ 70, 71 ], - list: { - 70: { - '*': 'Jon mentioned you.', - agent: { id: 212, name: 'Jon' }, - category: 'mention', - id: 70, - read: '20140805211446', - timestamp: { - date: '8 May', - mw: '20140508211436', - unix: '1407273276', - utcunix: '1407273276' - }, - title: { - full: 'Spiders' - }, - type: 'mention' - }, - 71: { - '*': 'X talked to you.', - category: 'edit-user-talk', - id: 71, - timestamp: { - date: '8 May', - mw: '20140508211436', - unix: '1407273276', - utcunix: '1407273276' - }, - type: 'edit-user-talk' - } - } - } - } - } - }; - } - }; - this.ApiStub = ApiStub; - } - } ); - - QUnit.test( 'mw.echo.overlay.buildOverlay', function ( assert ) { - var $overlay; - this.sandbox.stub( mw.echo.overlay, 'api', new this.ApiStub() ); - mw.echo.overlay.buildOverlay( function ( $o ) { - $overlay = $o; - } ); - assert.strictEqual( $overlay.find( '.mw-echo-overlay-title ul li' ).length, 1, 'Only one tab in header' ); - assert.strictEqual( $overlay.find( '.mw-echo-notifications' ).length, 1, 'Overlay contains a list of notifications.' ); - assert.strictEqual( $overlay.find( '.mw-echo-notifications li' ).length, 2, 'There are two notifications.' ); - assert.strictEqual( $overlay.find( '.mw-echo-unread' ).length, 1, 'There is one unread notification.' ); - assert.strictEqual( $overlay.find( '.mw-echo-overlay-footer a' ).length, 2, - 'There is a footer with 2 links to preferences and all notifications.' ); - assert.strictEqual( this.$badge.text(), - '0', 'The alerts are marked as read once opened.' ); - assert.strictEqual( this.$badge.hasClass( 'mw-echo-unseen-notifications' ), - false, 'The badge no longer indicates new messages.' ); - } ); - - QUnit.test( 'mw.echo.overlay.buildOverlay with messages', function ( assert ) { - var $overlay; - this.sandbox.stub( mw.echo.overlay, 'api', new this.ApiStub( 'no-new-messages' ) ); - mw.echo.overlay.buildOverlay( function ( $o ) { - $overlay = $o; - } ); - assert.strictEqual( $overlay.find( '.mw-echo-overlay-title ul li' ).length, 2, 'There are two tabs in header' ); - assert.strictEqual( $overlay.find( '.mw-echo-notifications' ).length, 2, 'Overlay contains 2 lists of notifications.' ); - assert.strictEqual( $overlay.find( '.mw-echo-overlay-title a' ).eq( 0 ).hasClass( 'mw-ui-quiet' ), - true, 'First tab is the selected tab upon opening.' ); - assert.strictEqual( this.$badge.text(), - '0', 'The label updates to 0 as alerts tab is default and now alerts have been read.' ); - assert.strictEqual( this.$badge.hasClass( 'mw-echo-unseen-notifications' ), - false, 'The notification button class is updated with the default switch to alert tab.' ); - } ); - - QUnit.test( 'Switch tabs on overlay. 1 unread alert, no unread messages.', function ( assert ) { - var $overlay, $tabs; - - this.sandbox.stub( mw.echo.overlay, 'api', new this.ApiStub( 'no-new-messages' ) ); - mw.echo.overlay.buildOverlay( function ( $o ) { - $overlay = $o; - // switch to 1st tab (alerts) - $overlay.find( '.mw-echo-overlay-title li a' ).eq( 0 ).trigger( 'click' ); - } ); - - $tabs = $overlay.find( '.mw-echo-overlay-title li a' ); - - assert.strictEqual( $tabs.eq( 0 ).hasClass( 'mw-ui-quiet' ), - true, 'First tab is now the selected tab.' ); - assert.strictEqual( $tabs.eq( 1 ).hasClass( 'mw-ui-quiet' ), - false, 'Second tab is not the selected tab.' ); - assert.strictEqual( this.$badge.text(), - '0', 'The label is now set to 0.' ); - assert.strictEqual( this.$badge.hasClass( 'mw-echo-unseen-notifications' ), - false, 'There are now zero unread notifications.' ); - - assert.strictEqual( $tabs.eq( 0 ).text(), 'Alerts (0)', 'Check the label has a count in it.' ); - assert.strictEqual( $tabs.eq( 1 ).text(), 'Messages (0)', 'Check the label has an updated count in it.' ); - assert.strictEqual( $tabs.eq( 1 ).hasClass( 'mw-ui-active' ), - true, 'Second tab has active class .as it is the only clickable tab' ); - } ); - - QUnit.test( 'Unread message behaviour', function ( assert ) { - var $overlay; - - this.sandbox.stub( mw.echo.overlay, 'api', new this.ApiStub( 'with-new-messages' ) ); - mw.echo.overlay.buildOverlay( function ( $o ) { - $overlay = $o; - } ); - - // Test initial state - assert.strictEqual( $overlay.find( '.mw-echo-overlay-title li a' ).eq( 1 ).text(), 'Messages (7)', - 'Check the label has a count in it and it is not automatically reset when tab is open.' ); - assert.strictEqual( $overlay.find( '.mw-echo-unread' ).length, 8, 'There are 8 unread notifications.' ); - - // Click mark as read - $overlay.find( '.mw-echo-notifications > button' ).eq( 0 ).trigger( 'click' ); - assert.strictEqual( $overlay.find( '.mw-echo-overlay-title li a' ).eq( 1 ).text(), 'Messages (0)', - 'Check all the notifications (even those outside overlay) have been marked as read.' ); - assert.strictEqual( $overlay.find( '.mw-echo-notifications ' ).eq( 1 ).find( '.mw-echo-unread' ).length, - 0, 'There are now no unread notifications in this tab.' ); - assert.strictEqual( $overlay.find( '.mw-echo-notifications > button' ).length, 0, - 'There are no notifications now so no need for button.' ); - } ); - - QUnit.test( 'Mark as read.', function ( assert ) { - var $overlay; - this.$badge.text( '8' ); - this.sandbox.stub( mw.echo.overlay, 'api', new this.ApiStub( 'with-new-messages' ) ); - mw.echo.overlay.buildOverlay( function ( $o ) { - $overlay = $o; - } ); - - // Test initial state - assert.strictEqual( $overlay.find( '.mw-echo-overlay-title li a' ).eq( 1 ).text(), 'Messages (7)', - 'Check the label has a count in it and it is not automatically reset when tab is open.' ); - assert.strictEqual( $overlay.find( '.mw-echo-unread' ).length, 8, - 'There are 7 unread message notifications and although the alert is marked as read on server is displays as unread in overlay.' ); - assert.strictEqual( this.$badge.text(), '7', '7 unread notifications in badge (alerts get marked automatically).' ); - assert.strictEqual( $overlay.find( '.mw-echo-notifications li button' ).length, 7, - 'There are 7 mark as read button.' ); - - // Click first mark as read - $overlay.find( '.mw-echo-notifications li button' ).eq( 0 ).trigger( 'click' ); - - assert.strictEqual( $overlay.find( '.mw-echo-overlay-title li a' ).eq( 1 ).text(), 'Messages (6)', - 'Check the notification was marked as read.' ); - assert.strictEqual( $overlay.find( '.mw-echo-unread' ).length, 7, - 'There are now 6 unread message notifications in UI and 1 unread alert.' ); - assert.strictEqual( $overlay.find( '.mw-echo-notifications li button' ).length, 6, - 'There are now 6 mark as read buttons.' ); - assert.strictEqual( this.$badge.text(), '6', 'Now 6 unread notifications.' ); - } ); - - QUnit.test( 'Tabs when there is overflow.', function ( assert ) { - var $overlay; - this.sandbox.stub( mw.echo.overlay, 'api', new this.ApiStub( 'with-new-messages', 50 ) ); - mw.echo.overlay.buildOverlay( function ( $o ) { - $overlay = $o; - } ); - - // Test initial state - assert.strictEqual( $overlay.find( '.mw-echo-overlay-title li a' ).eq( 1 ).text(), 'Messages (50)', - 'Check the label has a count in it and reflects the total unread and not the shown unread' ); - assert.strictEqual( $overlay.find( '.mw-echo-unread' ).length, 8, 'There are 8 unread notifications.' ); - } ); - - QUnit.test( 'Switching tabs visibility', function ( assert ) { - var $overlay; - - this.sandbox.stub( mw.echo.overlay, 'api', new this.ApiStub( 'with-new-messages' ) ); - mw.echo.overlay.buildOverlay( function ( $o ) { - // put in dom so we can do visibility tests - $overlay = $o.appendTo( '#qunit-fixture' ); - } ); - - // Test initial state - assert.strictEqual( $overlay.find( '.mw-echo-notifications' ).eq( 0 ).is( ':visible' ), - true, 'First tab (alerts) starts visible.' ); - assert.strictEqual( $overlay.find( '.mw-echo-notifications' ).eq( 1 ).is( ':visible' ), - false, 'Second tab (messages) starts hidden.' ); - - // Switch to second tab - $overlay.find( '.mw-echo-overlay-title li a' ).eq( 1 ).trigger( 'click' ); - - // check new tab visibility - assert.strictEqual( $overlay.find( '.mw-echo-notifications' ).eq( 0 ).is( ':visible' ), - false, 'First tab is now hidden.' ); - assert.strictEqual( $overlay.find( '.mw-echo-notifications' ).eq( 1 ).is( ':visible' ), - true, 'Second tab is now visible.' ); - } ); -}() ); diff --git a/Echo/tests/selenium/README.md b/Echo/tests/selenium/README.md index 340fd262..4a500268 100644 --- a/Echo/tests/selenium/README.md +++ b/Echo/tests/selenium/README.md @@ -1,40 +1,21 @@ # Selenium tests -For more information see https://www.mediawiki.org/wiki/Selenium/Node.js and [PATH]/mediawiki/vagrant/mediawiki/tests/selenium/README.md. +For more information see https://www.mediawiki.org/wiki/Selenium ## Setup -Set up MediaWiki-Vagrant: - - cd [PATH]/mediawiki/vagrant/mediawiki/extensions/Echo - vagrant up - vagrant roles enable echo - vagrant provision - npm install - -Chromedriver has to run in one terminal window: - - chromedriver --url-base=wd/hub --port=4444 +See https://www.mediawiki.org/wiki/MediaWiki-Docker/Extension/Echo ## Run all specs -In another terminal window: - npm run selenium-test -## [T171963](https://phabricator.wikimedia.org/T171963) `No active login attempt is in progress for your session` - -If you get this error message when logging in at `127.0.0.1:8080`, the workaround -is to log in at `dev.wiki.local.wmftest.net:8080` - - MW_SERVER=http://dev.wiki.local.wmftest.net:8080 npm run selenium-test - ## Run specific tests Filter by file name: - npm run selenium-test -- --spec tests/selenium/specs/[FILE-NAME].js + npm run selenium-test -- --spec tests/selenium/specs/[FILE-NAME] Filter by file name and test name: - npm run selenium-test -- --spec tests/selenium/specs/[FILE-NAME.js] --mochaOpts.grep [TEST-NAME] + npm run selenium-test -- --spec tests/selenium/specs/[FILE-NAME] --mochaOpts.grep [TEST-NAME]
\ No newline at end of file diff --git a/Echo/tests/selenium/specs/echo.js b/Echo/tests/selenium/specs/echo.js index 4f0d9637..07f676c0 100644 --- a/Echo/tests/selenium/specs/echo.js +++ b/Echo/tests/selenium/specs/echo.js @@ -13,49 +13,49 @@ describe( 'Echo', function () { bot = await Api.bot(); } ); - it( 'alerts and notices are visible after logging in @daily', function () { + it( 'alerts and notices are visible after logging in @daily', async function () { - UserLoginPage.login( browser.config.mwUser, browser.config.mwPwd ); + await UserLoginPage.login( browser.config.mwUser, browser.config.mwPwd ); assert( EchoPage.alerts.isExisting() ); assert( EchoPage.notices.isExisting() ); } ); - it( 'flyout for alert appears when clicked @daily', function () { + it( 'flyout for alert appears when clicked @daily', async function () { - UserLoginPage.login( browser.config.mwUser, browser.config.mwPwd ); - EchoPage.alerts.click(); + await UserLoginPage.login( browser.config.mwUser, browser.config.mwPwd ); + await EchoPage.alerts.click(); EchoPage.alertsFlyout.waitForDisplayed(); assert( EchoPage.alertsFlyout.isExisting() ); } ); - it( 'flyout for notices appears when clicked @daily', function () { + it( 'flyout for notices appears when clicked @daily', async function () { - UserLoginPage.login( browser.config.mwUser, browser.config.mwPwd ); - EchoPage.notices.click(); + await UserLoginPage.login( browser.config.mwUser, browser.config.mwPwd ); + await EchoPage.notices.click(); EchoPage.noticesFlyout.waitForDisplayed(); assert( EchoPage.noticesFlyout.isExisting() ); } ); - it( 'checks for welcome message after signup', function () { + it.skip( 'checks for welcome message after signup', async function () { const username = Util.getTestString( 'NewUser-' ); const password = Util.getTestString(); - browser.call( async () => { - await Api.createAccount( bot, username, password ); - } ); - UserLoginPage.login( username, password ); - EchoPage.notices.click(); + await Api.createAccount( bot, username, password ); - EchoPage.alertMessage.waitForDisplayed(); - const regexp = /Welcome to .*, .*! We're glad you're here./; - assert( regexp.test( EchoPage.alertMessage.getText() ) ); + await UserLoginPage.login( username, password ); + + await EchoPage.notices.click(); + + await EchoPage.alertMessage.waitForDisplayed(); + const regexp = /Welcome to .*, .*! We're glad you're here./; + assert( regexp.test( await EchoPage.alertMessage.getText() ) ); } ); diff --git a/Echo/tests/selenium/specs/mention.js b/Echo/tests/selenium/specs/mention.js deleted file mode 100644 index cef0217a..00000000 --- a/Echo/tests/selenium/specs/mention.js +++ /dev/null @@ -1,32 +0,0 @@ -'use strict'; - -const assert = require( 'assert' ), - EchoPage = require( '../pageobjects/echo.page' ), - UserLoginPage = require( 'wdio-mediawiki/LoginPage' ), - Util = require( 'wdio-mediawiki/Util' ), - Api = require( 'wdio-mediawiki/Api' ); - -describe( 'Mention test for Echo', function () { - let bot; - - before( async () => { - bot = await Api.bot(); - } ); - it.skip( 'checks if admin gets alert when mentioned', function () { - - const username = Util.getTestString( 'NewUser-' ); - const password = Util.getTestString(); - browser.call( async () => { - await Api.createAccount( bot, username, password ); - await bot.edit( `User:${username}`, `Hello [[User:${browser.config.mwUser}]] ~~~~`, username, password ); - } ); - UserLoginPage.login( browser.config.mwUser, browser.config.mwPwd ); - - EchoPage.alerts.click(); - - EchoPage.alertMessage.waitForDisplayed(); - const regexp = /.* mentioned you on User:.*./; - assert( regexp.test( EchoPage.alertMessage.getText() ) ); - } ); - -} ); diff --git a/Echo/tests/selenium/specs/notifications.js b/Echo/tests/selenium/specs/notifications.js index c2b37188..b639ed4c 100644 --- a/Echo/tests/selenium/specs/notifications.js +++ b/Echo/tests/selenium/specs/notifications.js @@ -6,12 +6,12 @@ const assert = require( 'assert' ), describe( 'Notifications', function () { - it( 'checks for Notifications Page @daily', function () { + it( 'checks for Notifications Page @daily', async function () { - UserLoginPage.login( browser.config.mwUser, browser.config.mwPwd ); - NotificationsPage.open(); + await UserLoginPage.login( browser.config.mwUser, browser.config.mwPwd ); + await NotificationsPage.open(); - assert.strictEqual( NotificationsPage.notificationHeading.getText(), 'Notifications' ); + assert.strictEqual( await NotificationsPage.notificationHeading.getText(), 'Notifications' ); } ); diff --git a/Echo/tests/selenium/wdio.conf.js b/Echo/tests/selenium/wdio.conf.js index 196cd227..18d71e2d 100644 --- a/Echo/tests/selenium/wdio.conf.js +++ b/Echo/tests/selenium/wdio.conf.js @@ -1,89 +1,11 @@ 'use strict'; -/** - * See also: http://webdriver.io/guide/testrunner/configurationfile.html - */ -const fs = require( 'fs' ), - saveScreenshot = require( 'wdio-mediawiki' ).saveScreenshot; - -exports.config = { - // ====== - // Custom WDIO config specific to MediaWiki - // ====== - // Use in a test as `browser.options.<key>`. - // Defaults are for convenience with MediaWiki-Vagrant - - // Wiki admin - mwUser: process.env.MEDIAWIKI_USER || 'Admin', - mwPwd: process.env.MEDIAWIKI_PASSWORD || 'vagrant', - - // Base for browser.url() and Page#openTitle() - baseUrl: ( process.env.MW_SERVER || 'http://127.0.0.1:8080' ) + ( - process.env.MW_SCRIPT_PATH || '/w' - ), - - // ================== - // Test Files - // ================== - specs: [ - __dirname + '/specs/*.js' - ], - - // ============ - // Capabilities - // ============ - capabilities: [ { - // https://sites.google.com/a/chromium.org/chromedriver/capabilities - browserName: 'chrome', - maxInstances: 1, - 'goog:chromeOptions': { - // If DISPLAY is set, assume developer asked non-headless or CI with Xvfb. - // Otherwise, use --headless (added in Chrome 59) - // https://chromium.googlesource.com/chromium/src/+/59.0.3030.0/headless/README.md - args: [ - ...( process.env.DISPLAY ? [] : [ '--headless' ] ), - // Chrome sandbox does not work in Docker - ...( fs.existsSync( '/.dockerenv' ) ? [ '--no-sandbox' ] : [] ) - ] - } - } ], - - // =================== - // Test Configurations - // =================== - - // Level of verbosity: silent | verbose | command | data | result | error - logLevel: 'error', - - // Setting this enables automatic screenshots for when a browser command fails - // It is also used by afterTest for capturig failed assertions. - screenshotPath: process.env.LOG_DIR || __dirname + '/log', - - // Default timeout for each waitFor* command. - waitforTimeout: 10 * 1000, - - // See also: http://webdriver.io/guide/testrunner/reporters.html - reporters: [ 'spec' ], - - // See also: http://mochajs.org - mochaOpts: { - ui: 'bdd', - timeout: 60 * 1000 - }, - - // ===== - // Hooks - // ===== - - /** - * Save a screenshot when test fails. - * - * @param {Object} test Mocha Test object - */ - afterTest: function ( test ) { - if ( !test.passed ) { - const filePath = saveScreenshot( test.title ); - console.log( '\n\tScreenshot: ' + filePath + '\n' ); - } - } +const { config } = require( 'wdio-mediawiki/wdio-defaults.conf.js' ); + +exports.config = { ...config + // Override, or add to, the setting from wdio-mediawiki. + // Learn more at https://webdriver.io/docs/configurationfile/ + // + // Example: + // logLevel: 'info', }; |