diff options
author | 2020-10-02 14:32:39 -0400 | |
---|---|---|
committer | 2020-10-02 14:32:39 -0400 | |
commit | 1f029fca0e032ee20673003d136f8603984b0841 (patch) | |
tree | 50d3a1748543abec2e7bbc3d94a7290cb57a78d2 | |
parent | Update Echo to 1.35 (diff) | |
download | extensions-1f029fca0e032ee20673003d136f8603984b0841.tar.gz extensions-1f029fca0e032ee20673003d136f8603984b0841.tar.bz2 extensions-1f029fca0e032ee20673003d136f8603984b0841.zip |
Update AbuseFilter to 1.35
Signed-off-by: Brian Evans <grknight@gentoo.org>
484 files changed, 36285 insertions, 13077 deletions
diff --git a/AbuseFilter/.eslintrc.json b/AbuseFilter/.eslintrc.json index a29fd888..d4172e97 100644 --- a/AbuseFilter/.eslintrc.json +++ b/AbuseFilter/.eslintrc.json @@ -1,11 +1,11 @@ { - "extends": "wikimedia", - "env": { - "browser": true, - "jquery": true - }, - "globals": { - "mediaWiki": false, - "OO": false + "root": true, + "extends": [ + "wikimedia/client", + "wikimedia/jquery", + "wikimedia/mediawiki" + ], + "rules": { + "no-jquery/no-global-selector": "off" } } diff --git a/AbuseFilter/.gitignore b/AbuseFilter/.gitignore index d08bf099..e62d5434 100644 --- a/AbuseFilter/.gitignore +++ b/AbuseFilter/.gitignore @@ -2,6 +2,7 @@ /vendor/ node_modules/ /composer.lock +.eslintcache # Editors *.kate-swp @@ -22,4 +23,4 @@ project.index ## Sublime sublime-* sftp-config.json -/tests/phan/issues +/tests/selenium/log diff --git a/AbuseFilter/.phan/config.php b/AbuseFilter/.phan/config.php new file mode 100644 index 00000000..3dc8bb53 --- /dev/null +++ b/AbuseFilter/.phan/config.php @@ -0,0 +1,21 @@ +<?php + +$cfg = require __DIR__ . '/../vendor/mediawiki/mediawiki-phan-config/src/config.php'; + +$cfg['directory_list'] = array_merge( + $cfg['directory_list'], + [ + '../../extensions/CheckUser', + '../../extensions/Renameuser', + ] +); + +$cfg['exclude_analysis_directory_list'] = array_merge( + $cfg['exclude_analysis_directory_list'], + [ + '../../extensions/CheckUser', + '../../extensions/Renameuser', + ] +); + +return $cfg; diff --git a/AbuseFilter/.phpcs.xml b/AbuseFilter/.phpcs.xml index 77c6d677..078cb66c 100644 --- a/AbuseFilter/.phpcs.xml +++ b/AbuseFilter/.phpcs.xml @@ -1,11 +1,8 @@ <?xml version="1.0"?> <ruleset> - <rule ref="./vendor/mediawiki/mediawiki-codesniffer/MediaWiki"> - </rule> + <rule ref="./vendor/mediawiki/mediawiki-codesniffer/MediaWiki" /> <rule ref="Generic.Files.LineLength"> <exclude-pattern>AbuseFilter\.alias\.php</exclude-pattern> - <exclude-pattern>AbuseFilterParserTest\.php</exclude-pattern> - <exclude-pattern>AbuseFilterConsequencesTest\.php</exclude-pattern> </rule> <file>.</file> <arg name="extensions" value="php,php5,inc"/> diff --git a/AbuseFilter/AbuseFilter.alias.php b/AbuseFilter/AbuseFilter.alias.php index 7895b6d4..43f0fa41 100644 --- a/AbuseFilter/AbuseFilter.alias.php +++ b/AbuseFilter/AbuseFilter.alias.php @@ -445,6 +445,18 @@ $specialPageAliases['sk'] = [ 'AbuseFilter' => [ 'FilterZneužití' ], ]; +/** Serbian Cyrillic (српски (ћирилица)) */ +$specialPageAliases['sr-ec'] = [ + 'AbuseLog' => [ 'Дневник_злоупотребе' ], + 'AbuseFilter' => [ 'Филтер_злоупотребе' ], +]; + +/** Serbian Latin (srpski (latinica)) */ +$specialPageAliases['sr-el'] = [ + 'AbuseLog' => [ 'Dnevnik_zloupotrebe' ], + 'AbuseFilter' => [ 'Filter_zloupotrebe' ], +]; + /** Swedish (svenska) */ $specialPageAliases['sv'] = [ 'AbuseLog' => [ 'Missbrukslogg' ], @@ -478,7 +490,7 @@ $specialPageAliases['uk'] = [ /** Urdu (اردو) */ $specialPageAliases['ur'] = [ 'AbuseLog' => [ 'نوشتہ_غلط_کاری' ], - 'AbuseFilter' => [ 'مقطار_غلط_کاری' ], + 'AbuseFilter' => [ 'مقطر_غلط_کاری', 'مقطار_غلط_کاری' ], ]; /** Venetian (vèneto) */ diff --git a/AbuseFilter/Gruntfile.js b/AbuseFilter/Gruntfile.js index a572f9af..ba323e1f 100644 --- a/AbuseFilter/Gruntfile.js +++ b/AbuseFilter/Gruntfile.js @@ -1,24 +1,20 @@ -/* eslint-env node */ +/* eslint-env node, es6 */ module.exports = function ( grunt ) { var conf = grunt.file.readJSON( 'extension.json' ); - grunt.loadNpmTasks( 'grunt-jsonlint' ); grunt.loadNpmTasks( 'grunt-banana-checker' ); grunt.loadNpmTasks( 'grunt-eslint' ); grunt.loadNpmTasks( 'grunt-stylelint' ); grunt.initConfig( { - jsonlint: { - all: [ - '**/*.json', - '!node_modules/**', - '!vendor/**' - ] - }, banana: conf.MessagesDirs, eslint: { + options: { + cache: true, + fix: grunt.option( 'fix' ) + }, all: [ - '**/*.js', + '**/*.{js,json}', '!node_modules/**', '!vendor/**' ] @@ -32,6 +28,6 @@ module.exports = function ( grunt ) { } } ); - grunt.registerTask( 'test', [ 'jsonlint', 'banana', 'eslint', 'stylelint' ] ); + grunt.registerTask( 'test', [ 'eslint', 'stylelint', 'banana' ] ); grunt.registerTask( 'default', 'test' ); }; diff --git a/AbuseFilter/abusefilter.tables.pg.sql b/AbuseFilter/abusefilter.tables.pg.sql index 272eb50a..b2d5cad3 100644 --- a/AbuseFilter/abusefilter.tables.pg.sql +++ b/AbuseFilter/abusefilter.tables.pg.sql @@ -36,7 +36,7 @@ CREATE INDEX abuse_filter_action_consequence ON abuse_filter_action(afa_conseque CREATE SEQUENCE abuse_filter_log_afl_id_seq; CREATE TABLE abuse_filter_log ( afl_id INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('abuse_filter_log_afl_id_seq'), - afl_filter TEXT NOT NULL, + afl_filter TEXT NOT NULL DEFAULT '', afl_user INTEGER NOT NULL, afl_user_text TEXT NOT NULL, afl_ip TEXT NOT NULL, @@ -50,17 +50,18 @@ CREATE TABLE abuse_filter_log ( afl_deleted SMALLINT NOT NULL DEFAULT 0, afl_patrolled_by INTEGER NULL, afl_rev_id INTEGER NULL, - afl_log_id INTEGER NULL + afl_global SMALLINT NOT NULL DEFAULT 0, + afl_filter_id INTEGER NOT NULL DEFAULT 0 ); -CREATE INDEX abuse_filter_log_filter_timestamp ON abuse_filter_log(afl_filter,afl_timestamp); -CREATE INDEX abuse_filter_log_user_timestamp ON abuse_filter_log(afl_user,afl_user_text,afl_timestamp); -CREATE INDEX abuse_filter_log_timestamp ON abuse_filter_log(afl_timestamp); -CREATE INDEX abuse_filter_log_page_timestamp ON abuse_filter_log(afl_namespace, afl_title, afl_timestamp); -CREATE INDEX abuse_filter_log_ip_timestamp ON abuse_filter_log(afl_ip, afl_timestamp); -CREATE INDEX abuse_filter_log_rev_id ON abuse_filter_log(afl_rev_id); -CREATE INDEX abuse_filter_log_log_id ON abuse_filter_log(afl_log_id); -CREATE INDEX abuse_filter_log_wiki_timestamp ON abuse_filter_log(afl_wiki, afl_timestamp); +CREATE INDEX abuse_filter_log_filter_timestamp ON abuse_filter_log(afl_filter,afl_timestamp); +CREATE INDEX abuse_filter_log_filter_timestamp_full ON abuse_filter_log(afl_global,afl_filter_id,afl_timestamp); +CREATE INDEX abuse_filter_log_user_timestamp ON abuse_filter_log(afl_user,afl_user_text,afl_timestamp); +CREATE INDEX abuse_filter_log_timestamp ON abuse_filter_log(afl_timestamp); +CREATE INDEX abuse_filter_log_page_timestamp ON abuse_filter_log(afl_namespace, afl_title, afl_timestamp); +CREATE INDEX abuse_filter_log_ip_timestamp ON abuse_filter_log(afl_ip, afl_timestamp); +CREATE INDEX abuse_filter_log_rev_id ON abuse_filter_log(afl_rev_id); +CREATE INDEX abuse_filter_log_wiki_timestamp ON abuse_filter_log(afl_wiki, afl_timestamp); CREATE SEQUENCE abuse_filter_history_afh_id_seq; CREATE TABLE abuse_filter_history ( diff --git a/AbuseFilter/abusefilter.tables.sql b/AbuseFilter/abusefilter.tables.sql index ff9bdb3d..a7709517 100644 --- a/AbuseFilter/abusefilter.tables.sql +++ b/AbuseFilter/abusefilter.tables.sql @@ -33,7 +33,9 @@ CREATE TABLE /*$wgDBprefix*/abuse_filter_action ( CREATE TABLE /*$wgDBprefix*/abuse_filter_log ( afl_id BIGINT unsigned NOT NULL AUTO_INCREMENT, - afl_filter varchar(64) binary NOT NULL, + afl_filter varchar(64) binary NOT NULL DEFAULT '', + afl_global tinyint(1) NOT NULL DEFAULT 0, + afl_filter_id BIGINT unsigned NOT NULL DEFAULT 0, afl_user BIGINT unsigned NOT NULL, afl_user_text varchar(255) binary NOT NULL, afl_ip varchar(255) not null, @@ -47,16 +49,15 @@ CREATE TABLE /*$wgDBprefix*/abuse_filter_log ( afl_deleted tinyint(1) NOT NULL DEFAULT 0, afl_patrolled_by int unsigned NULL, afl_rev_id int unsigned, - afl_log_id int unsigned, PRIMARY KEY (afl_id), KEY filter_timestamp (afl_filter,afl_timestamp), + KEY filter_timestamp_full (afl_global,afl_filter_id,afl_timestamp), KEY user_timestamp (afl_user,afl_user_text,afl_timestamp), KEY (afl_timestamp), KEY page_timestamp (afl_namespace, afl_title, afl_timestamp), KEY ip_timestamp (afl_ip, afl_timestamp), KEY (afl_rev_id), - KEY (afl_log_id), KEY wiki_timestamp (afl_wiki, afl_timestamp) ) /*$wgDBTableOptions*/; diff --git a/AbuseFilter/abusefilter.tables.sqlite.sql b/AbuseFilter/abusefilter.tables.sqlite.sql index d36c35ce..812e318b 100644 --- a/AbuseFilter/abusefilter.tables.sqlite.sql +++ b/AbuseFilter/abusefilter.tables.sqlite.sql @@ -31,7 +31,9 @@ CREATE INDEX afa_consequence ON /*$wgDBprefix*/abuse_filter_action (afa_conseque CREATE TABLE /*$wgDBprefix*/abuse_filter_log ( afl_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - afl_filter varbinary(64) NOT NULL, + afl_filter varbinary(64) NOT NULL DEFAULT '', + afl_global tinyint(1) NOT NULL DEFAULT 0, + afl_filter_id INTEGER NOT NULL DEFAULT 0, afl_user BIGINT unsigned NOT NULL, afl_user_text varbinary(255) NOT NULL, afl_ip varbinary(255) not null, @@ -44,17 +46,16 @@ CREATE TABLE /*$wgDBprefix*/abuse_filter_log ( afl_wiki varbinary(64) NULL, afl_deleted tinyint(1) NOT NULL DEFAULT 0, afl_patrolled_by int unsigned NULL, - afl_rev_id int unsigned, - afl_log_id int unsigned + afl_rev_id int unsigned ) /*$wgDBTableOptions*/; CREATE INDEX afl_filter_timestamp ON /*$wgDBprefix*/abuse_filter_log (afl_filter,afl_timestamp); +CREATE INDEX afl_filter_timestamp_full ON /*$wgDBprefix*/abuse_filter_log (afl_global,afl_filter_id,afl_timestamp); CREATE INDEX afl_user_timestamp ON /*$wgDBprefix*/abuse_filter_log (afl_user,afl_user_text,afl_timestamp); CREATE INDEX afl_timestamp ON /*$wgDBprefix*/abuse_filter_log (afl_timestamp); CREATE INDEX afl_page_timestamp ON /*$wgDBprefix*/abuse_filter_log (afl_namespace, afl_title, afl_timestamp); CREATE INDEX afl_ip_timestamp ON /*$wgDBprefix*/abuse_filter_log (afl_ip, afl_timestamp); CREATE INDEX afl_wiki_timestamp ON /*$wgDBprefix*/abuse_filter_log (afl_wiki, afl_timestamp); CREATE INDEX afl_rev_id ON /*$wgDBprefix*/abuse_filter_log (afl_rev_id); -CREATE INDEX afl_log_id ON /*$wgDBprefix*/abuse_filter_log (afl_log_id); CREATE TABLE /*$wgDBprefix*/abuse_filter_history ( afh_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, diff --git a/AbuseFilter/composer.json b/AbuseFilter/composer.json index 67f40d5b..7ad48e2a 100644 --- a/AbuseFilter/composer.json +++ b/AbuseFilter/composer.json @@ -5,28 +5,25 @@ "homepage": "https://www.mediawiki.org/wiki/Extension:AbuseFilter", "license": "GPL-2.0-or-later", "require": { - "php": ">=5.4", - "wikimedia/equivset": "^1.3" + "php": ">=7.2.0", + "wikimedia/equivset": "^1.4" }, "require-dev": { - "jakub-onderka/php-parallel-lint": "1.0.0", - "mediawiki/mediawiki-codesniffer": "22.0.0", - "jakub-onderka/php-console-highlighter": "0.3.2", - "mediawiki/minus-x": "0.3.1", - "mediawiki/mediawiki-phan-config": "0.3.0" + "mediawiki/mediawiki-codesniffer": "31.0.0", + "mediawiki/mediawiki-phan-config": "0.10.3", + "mediawiki/minus-x": "1.1.0", + "php-parallel-lint/php-console-highlighter": "0.5.0", + "php-parallel-lint/php-parallel-lint": "1.2.0" }, "scripts": { "fix": [ - "phpcbf", - "minus-x fix ." + "minus-x fix .", + "phpcbf" ], "test": [ "parallel-lint . --exclude node_modules --exclude vendor", "phpcs -p -s", "minus-x check ." ] - }, - "extra": { - "phan-taint-check-plugin": "1.5.0" } } diff --git a/AbuseFilter/db_patches/patch-abuse_filter_history.sql b/AbuseFilter/db_patches/patch-abuse_filter_history.sql index 0cd7f07a..c1d26508 100644 --- a/AbuseFilter/db_patches/patch-abuse_filter_history.sql +++ b/AbuseFilter/db_patches/patch-abuse_filter_history.sql @@ -10,11 +10,9 @@ CREATE TABLE /*$wgDBprefix*/abuse_filter_history ( afh_comments BLOB NOT NULL, afh_flags TINYBLOB NOT NULL, afh_public_comments TINYBLOB, - afh_actions BLOB, - - PRIMARY KEY (afh_id), - KEY (afh_filter), - KEY (afh_user), - KEY (afh_user_text), - KEY (afh_timestamp) + afh_actions BLOB ) /*$wgDBTableOptions*/; +CREATE INDEX afh_filter ON /*$wgDBprefix*/abuse_filter_history (afh_filter); +CREATE INDEX afh_user ON /*$wgDBprefix*/abuse_filter_history (afh_user); +CREATE INDEX afh_user_text ON /*$wgDBprefix*/abuse_filter_history (afh_user_text); +CREATE INDEX afh_timestamp ON /*$wgDBprefix*/abuse_filter_history (afh_timestamp); diff --git a/AbuseFilter/db_patches/patch-abuse_filter_history.sqlite.sql b/AbuseFilter/db_patches/patch-abuse_filter_history.sqlite.sql deleted file mode 100644 index c1d26508..00000000 --- a/AbuseFilter/db_patches/patch-abuse_filter_history.sqlite.sql +++ /dev/null @@ -1,18 +0,0 @@ --- Patch to add abuse_filter_history table - -CREATE TABLE /*$wgDBprefix*/abuse_filter_history ( - afh_id BIGINT unsigned NOT NULL AUTO_INCREMENT, - afh_filter BIGINT unsigned NOT NULL, - afh_user BIGINT unsigned NOT NULL, - afh_user_text varchar(255) binary NOT NULL, - afh_timestamp binary(14) NOT NULL, - afh_pattern BLOB NOT NULL, - afh_comments BLOB NOT NULL, - afh_flags TINYBLOB NOT NULL, - afh_public_comments TINYBLOB, - afh_actions BLOB -) /*$wgDBTableOptions*/; -CREATE INDEX afh_filter ON /*$wgDBprefix*/abuse_filter_history (afh_filter); -CREATE INDEX afh_user ON /*$wgDBprefix*/abuse_filter_history (afh_user); -CREATE INDEX afh_user_text ON /*$wgDBprefix*/abuse_filter_history (afh_user_text); -CREATE INDEX afh_timestamp ON /*$wgDBprefix*/abuse_filter_history (afh_timestamp); diff --git a/AbuseFilter/db_patches/patch-afl-namespace_int.sqlite.sql b/AbuseFilter/db_patches/patch-afl-namespace_int.sqlite.sql new file mode 100644 index 00000000..52f222d1 --- /dev/null +++ b/AbuseFilter/db_patches/patch-afl-namespace_int.sqlite.sql @@ -0,0 +1,43 @@ +-- (Just) change afl_namespace field to int NOT NULL. +BEGIN; + +DROP TABLE IF EXISTS /*_*/abuse_filter_log_tmp; + +CREATE TABLE /*_*/abuse_filter_log_tmp ( + afl_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + afl_filter varbinary(64) NOT NULL, + afl_user BIGINT unsigned NOT NULL, + afl_user_text varbinary(255) NOT NULL, + afl_ip varbinary(255) not null, + afl_action varbinary(255) not null, + afl_actions varbinary(255) not null, + afl_var_dump BLOB NOT NULL, + afl_timestamp varbinary(14) NOT NULL, + afl_namespace int NOT NULL, + afl_title varbinary(255) NOT NULL, + afl_wiki varbinary(64) NULL, + afl_deleted tinyint(1) NOT NULL DEFAULT 0, + afl_patrolled_by int unsigned NULL, + afl_rev_id int unsigned +) /*$wgDBTableOptions*/; + +INSERT OR IGNORE INTO /*_*/abuse_filter_log_tmp ( + afl_id, afl_filter, afl_user, afl_user_text, afl_ip, afl_action, afl_actions, + afl_var_dump, afl_timestamp, afl_namespace, afl_title, afl_wiki, afl_deleted, + afl_patrolled_by, afl_rev_id) + SELECT afl_id, afl_filter, afl_user, afl_user_text, afl_ip, afl_action, afl_actions, + afl_var_dump, afl_timestamp, afl_namespace, afl_title, afl_wiki, afl_deleted, + afl_patrolled_by, afl_rev_id + FROM /*_*/abuse_filter_log; + +DROP TABLE /*_*/abuse_filter_log; +ALTER TABLE /*_*/abuse_filter_log_tmp RENAME TO /*_*/abuse_filter_log; +CREATE INDEX /*i*/afl_filter_timestamp ON /*_*/abuse_filter_log (afl_filter,afl_timestamp); +CREATE INDEX /*i*/afl_user_timestamp ON /*_*/abuse_filter_log (afl_user,afl_user_text,afl_timestamp); +CREATE INDEX /*i*/afl_timestamp ON /*_*/abuse_filter_log (afl_timestamp); +CREATE INDEX /*i*/afl_page_timestamp ON /*_*/abuse_filter_log (afl_namespace, afl_title, afl_timestamp); +CREATE INDEX /*i*/afl_ip_timestamp ON /*_*/abuse_filter_log (afl_ip, afl_timestamp); +CREATE INDEX /*i*/afl_wiki_timestamp ON /*_*/abuse_filter_log (afl_wiki, afl_timestamp); +CREATE INDEX /*i*/afl_rev_id ON /*_*/abuse_filter_log (afl_rev_id); + +COMMIT;
\ No newline at end of file diff --git a/AbuseFilter/db_patches/patch-afl_action_id.sql b/AbuseFilter/db_patches/patch-afl_action_id.sql index 85eab834..cd1ff1da 100644 --- a/AbuseFilter/db_patches/patch-afl_action_id.sql +++ b/AbuseFilter/db_patches/patch-afl_action_id.sql @@ -1,8 +1,4 @@ -- Store the ID of successful actions in the abuse_filter_log table. ALTER TABLE /*_*/abuse_filter_log ADD COLUMN afl_rev_id int unsigned; -CREATE INDEX /*i*/afl_rev_id ON /*_*/abuse_filter_log (afl_rev_id); - -ALTER TABLE /*_*/abuse_filter_log - ADD COLUMN afl_log_id int unsigned; -CREATE INDEX /*i*/afl_log_id ON /*_*/abuse_filter_log (afl_log_id);
\ No newline at end of file +CREATE INDEX /*i*/afl_rev_id ON /*_*/abuse_filter_log (afl_rev_id);
\ No newline at end of file diff --git a/AbuseFilter/db_patches/patch-drop_afl_log_id.sql b/AbuseFilter/db_patches/patch-drop_afl_log_id.sql new file mode 100644 index 00000000..9dc7c24c --- /dev/null +++ b/AbuseFilter/db_patches/patch-drop_afl_log_id.sql @@ -0,0 +1,2 @@ +ALTER TABLE /*_*/abuse_filter_log + DROP COLUMN afl_log_id; diff --git a/AbuseFilter/db_patches/patch-drop_afl_log_id.sqlite.sql b/AbuseFilter/db_patches/patch-drop_afl_log_id.sqlite.sql new file mode 100644 index 00000000..b5518dd4 --- /dev/null +++ b/AbuseFilter/db_patches/patch-drop_afl_log_id.sqlite.sql @@ -0,0 +1,44 @@ +-- This monster is just an `ALTER TABLE abuse_filter_log DROP COLUMN afl_log_id` + +BEGIN; + +DROP TABLE IF EXISTS /*_*/abuse_filter_log_tmp; +CREATE TABLE /*_*/abuse_filter_log_tmp ( + afl_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + afl_filter varbinary(64) NOT NULL, + afl_user BIGINT unsigned NOT NULL, + afl_user_text varbinary(255) NOT NULL, + afl_ip varbinary(255) not null, + afl_action varbinary(255) not null, + afl_actions varbinary(255) not null, + afl_var_dump BLOB NOT NULL, + afl_timestamp varbinary(14) NOT NULL, + afl_namespace int NOT NULL, + afl_title varbinary(255) NOT NULL, + afl_wiki varbinary(64) NULL, + afl_deleted tinyint(1) NOT NULL DEFAULT 0, + afl_patrolled_by int unsigned NULL, + afl_rev_id int unsigned +) /*$wgDBTableOptions*/; + +INSERT INTO abuse_filter_log_tmp + + SELECT afl_id, afl_filter, afl_user, afl_user_text, afl_ip, afl_action, afl_actions, afl_var_dump, + afl_timestamp, afl_namespace, afl_title, afl_wiki, afl_deleted, afl_patrolled_by, afl_rev_id + + FROM /*_*/abuse_filter_log; + +DROP TABLE /*_*/abuse_filter_log; + +ALTER TABLE /*_*/abuse_filter_log_tmp RENAME TO /*_*/abuse_filter_log; + +CREATE INDEX /*i*/afl_filter_timestamp ON /*_*/abuse_filter_log (afl_filter,afl_timestamp); +CREATE INDEX /*i*/afl_user_timestamp ON /*_*/abuse_filter_log (afl_user,afl_user_text,afl_timestamp); +CREATE INDEX /*i*/afl_timestamp ON /*_*/abuse_filter_log (afl_timestamp); +CREATE INDEX /*i*/afl_page_timestamp ON /*_*/abuse_filter_log (afl_namespace, afl_title, afl_timestamp); +CREATE INDEX /*i*/afl_ip_timestamp ON /*_*/abuse_filter_log (afl_ip, afl_timestamp); +CREATE INDEX /*i*/afl_wiki_timestamp ON /*_*/abuse_filter_log (afl_wiki, afl_timestamp); +CREATE INDEX /*i*/afl_rev_id ON /*_*/abuse_filter_log (afl_rev_id); + + +COMMIT;
\ No newline at end of file diff --git a/AbuseFilter/db_patches/patch-global_logging_wiki-index.sql b/AbuseFilter/db_patches/patch-global_logging_wiki-index.sql index 690d034e..694b6e3d 100644 --- a/AbuseFilter/db_patches/patch-global_logging_wiki-index.sql +++ b/AbuseFilter/db_patches/patch-global_logging_wiki-index.sql @@ -1,3 +1,3 @@ --- Add abuse_filter_log idex for afl_wiki. +-- Add abuse_filter_log index for afl_wiki. -ALTER TABLE /*_*/abuse_filter_log ADD KEY wiki_timestamp (afl_wiki, afl_timestamp); +CREATE INDEX afl_wiki_timestamp ON /*$wgDBprefix*/abuse_filter_log (afl_wiki, afl_timestamp); diff --git a/AbuseFilter/db_patches/patch-global_logging_wiki-index.sqlite.sql b/AbuseFilter/db_patches/patch-global_logging_wiki-index.sqlite.sql deleted file mode 100644 index 45c619c6..00000000 --- a/AbuseFilter/db_patches/patch-global_logging_wiki-index.sqlite.sql +++ /dev/null @@ -1,3 +0,0 @@ --- Add abuse_filter_log idex for afl_wiki. - -CREATE INDEX afl_wiki_timestamp ON /*$wgDBprefix*/abuse_filter_log (afl_wiki, afl_timestamp); diff --git a/AbuseFilter/db_patches/patch-split-afl_filter.sql b/AbuseFilter/db_patches/patch-split-afl_filter.sql new file mode 100644 index 00000000..7b4652bd --- /dev/null +++ b/AbuseFilter/db_patches/patch-split-afl_filter.sql @@ -0,0 +1,7 @@ +-- Split afl_filter into afl_filter_id and afl_global +ALTER TABLE /*_*/abuse_filter_log + ADD COLUMN afl_global tinyint(1) NOT NULL DEFAULT 0 AFTER afl_filter, + ADD COLUMN afl_filter_id BIGINT unsigned NOT NULL DEFAULT 0 AFTER afl_global, + ALTER COLUMN afl_filter SET DEFAULT ''; + +CREATE INDEX /*i*/filter_timestamp_full ON /*_*/abuse_filter_log (afl_global,afl_filter_id,afl_timestamp); diff --git a/AbuseFilter/db_patches/patch-split-afl_filter.sqlite.sql b/AbuseFilter/db_patches/patch-split-afl_filter.sqlite.sql new file mode 100644 index 00000000..72894b6b --- /dev/null +++ b/AbuseFilter/db_patches/patch-split-afl_filter.sqlite.sql @@ -0,0 +1,47 @@ +-- Split afl_filter into afl_filter_id and afl_global +BEGIN; + +DROP TABLE IF EXISTS /*_*/abuse_filter_log_tmp; +CREATE TABLE /*_*/abuse_filter_log_tmp ( + afl_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + afl_filter varbinary(64) NOT NULL DEFAULT '', + afl_global tinyint(1) NOT NULL DEFAULT 0, + afl_filter_id INTEGER NOT NULL DEFAULT 0, + afl_user BIGINT unsigned NOT NULL, + afl_user_text varbinary(255) NOT NULL, + afl_ip varbinary(255) not null, + afl_action varbinary(255) not null, + afl_actions varbinary(255) not null, + afl_var_dump BLOB NOT NULL, + afl_timestamp varbinary(14) NOT NULL, + afl_namespace int NOT NULL, + afl_title varbinary(255) NOT NULL, + afl_wiki varbinary(64) NULL, + afl_deleted tinyint(1) NOT NULL DEFAULT 0, + afl_patrolled_by int unsigned NULL, + afl_rev_id int unsigned +) /*$wgDBTableOptions*/; + +INSERT OR IGNORE INTO /*_*/abuse_filter_log_tmp ( + afl_id, afl_filter, afl_user, afl_user_text, afl_ip, + afl_action, afl_actions, afl_var_dump, afl_timestamp, afl_namespace, afl_title, + afl_wiki, afl_deleted, afl_patrolled_by, afl_rev_id ) + SELECT + afl_id, afl_filter, afl_user, afl_user_text, afl_ip, + afl_action, afl_actions, afl_var_dump, afl_timestamp, afl_namespace, afl_title, + afl_wiki, afl_deleted, afl_patrolled_by, afl_rev_id + FROM /*_*/abuse_filter_log; + +DROP TABLE /*_*/abuse_filter_log; +ALTER TABLE /*_*/abuse_filter_log_tmp RENAME TO /*_*/abuse_filter_log; + +CREATE INDEX /*i*/afl_filter_timestamp ON /*_*/abuse_filter_log (afl_filter,afl_timestamp); +CREATE INDEX /*i*/afl_filter_timestamp_full ON /*_*/abuse_filter_log (afl_global,afl_filter_id,afl_timestamp); +CREATE INDEX /*i*/afl_user_timestamp ON /*_*/abuse_filter_log (afl_user,afl_user_text,afl_timestamp); +CREATE INDEX /*i*/afl_timestamp ON /*_*/abuse_filter_log (afl_timestamp); +CREATE INDEX /*i*/afl_page_timestamp ON /*_*/abuse_filter_log (afl_namespace, afl_title, afl_timestamp); +CREATE INDEX /*i*/afl_ip_timestamp ON /*_*/abuse_filter_log (afl_ip, afl_timestamp); +CREATE INDEX /*i*/afl_wiki_timestamp ON /*_*/abuse_filter_log (afl_wiki, afl_timestamp); +CREATE INDEX /*i*/afl_rev_id ON /*_*/abuse_filter_log (afl_rev_id); + +COMMIT;
\ No newline at end of file diff --git a/AbuseFilter/extension.json b/AbuseFilter/extension.json index efce9fe0..bc0af45b 100644 --- a/AbuseFilter/extension.json +++ b/AbuseFilter/extension.json @@ -2,24 +2,25 @@ "name": "Abuse Filter", "author": [ "Andrew Garrett", + "[https://www.mediawiki.org/wiki/User:Daimona_Eaytoy Daimona Eaytoy]", + "Marius Hoch", "River Tarnell", - "Victor Vasiliev", - "Marius Hoch" + "Victor Vasiliev" ], "url": "https://www.mediawiki.org/wiki/Extension:AbuseFilter", "descriptionmsg": "abusefilter-desc", "license-name": "GPL-2.0-or-later", "type": "antispam", "requires": { - "MediaWiki": ">= 1.31.0" + "MediaWiki": ">= 1.35.0" }, "AvailableRights": [ "abusefilter-modify", "abusefilter-log-detail", "abusefilter-view", "abusefilter-log", - "abusefilter-private", - "abusefilter-private-log", + "abusefilter-privatedetails", + "abusefilter-privatedetails-log", "abusefilter-modify-restricted", "abusefilter-revert", "abusefilter-view-private", @@ -35,7 +36,15 @@ }, "sysop": { "abusefilter-log-detail": true, - "abusefilter-modify": true + "abusefilter-view-private": true, + "abusefilter-log-private": true, + "abusefilter-modify": true, + "abusefilter-modify-restricted": true, + "abusefilter-revert": true + }, + "suppress": { + "abusefilter-hidden-log": true, + "abusefilter-hide-log": true } }, "GrantPermissions": { @@ -44,16 +53,23 @@ "abusefilter-log-detail": true, "abusefilter-view": true }, - "rollback": { - "abusefilter-revert": true + "oversight": { + "abusefilter-hide-log": true }, "viewrestrictedlogs": { "abusefilter-hidden-log": true, + "abusefilter-log-private": true, "abusefilter-view-private": true } }, "SpecialPages": { - "AbuseLog": "SpecialAbuseLog", + "AbuseLog": { + "class": "SpecialAbuseLog", + "services": [ + "LinkBatchFactory", + "PermissionManager" + ] + }, "AbuseFilter": "SpecialAbuseFilter" }, "LogTypes": [ @@ -73,7 +89,9 @@ "abusefilter/create": "AbuseFilterModifyLogFormatter", "abusefilterprivatedetails/access": "LogFormatter", "suppress/hide-afl": "AbuseFilterSuppressLogFormatter", - "suppress/unhide-afl": "AbuseFilterSuppressLogFormatter" + "suppress/unhide-afl": "AbuseFilterSuppressLogFormatter", + "rights/blockautopromote": "AbuseFilterRightsLogFormatter", + "rights/restoreautopromote": "AbuseFilterRightsLogFormatter" }, "ActionFilteredLogs": { "abusefilter": { @@ -86,13 +104,15 @@ } }, "LogRestrictions": { - "abusefilterprivatedetails": "abusefilter-private-log" + "abusefilter": "abusefilter-view", + "abusefilterprivatedetails": "abusefilter-privatedetails-log" }, "APIModules": { "abusefilterchecksyntax": "ApiAbuseFilterCheckSyntax", "abusefilterevalexpression": "ApiAbuseFilterEvalExpression", "abusefilterunblockautopromote": "ApiAbuseFilterUnblockAutopromote", - "abusefiltercheckmatch": "ApiAbuseFilterCheckMatch" + "abusefiltercheckmatch": "ApiAbuseFilterCheckMatch", + "abuselogprivatedetails": "ApiAbuseLogPrivateDetails" }, "APIListModules": { "abuselog": "ApiQueryAbuseLog", @@ -107,6 +127,10 @@ "ExtensionMessagesFiles": { "AbuseFilterAliases": "AbuseFilter.alias.php" }, + "AutoloadNamespaces": { + "MediaWiki\\Extension\\AbuseFilter\\VariableGenerator\\": "includes/VariableGenerator/", + "MediaWiki\\Extension\\AbuseFilter\\Hooks\\": "includes/Hooks/" + }, "AutoloadClasses": { "AbuseFilter": "includes/AbuseFilter.php", "AbuseFilterCachingParser" : "includes/parser/AbuseFilterCachingParser.php", @@ -114,12 +138,15 @@ "AbuseFilterTokenizer": "includes/parser/AbuseFilterTokenizer.php", "AbuseFilterHooks": "includes/AbuseFilterHooks.php", "AbuseFilterPreAuthenticationProvider": "includes/AbuseFilterPreAuthenticationProvider.php", + "AbuseFilterRunner": "includes/AbuseFilterRunner.php", + "AbuseFilterSpecialPage": "includes/special/AbuseFilterSpecialPage.php", "SpecialAbuseLog": "includes/special/SpecialAbuseLog.php", "AbuseLogPager": "includes/pagers/AbuseLogPager.php", "SpecialAbuseFilter": "includes/special/SpecialAbuseFilter.php", "AbuseLogHitFormatter": "includes/AbuseLogHitFormatter.php", "AbuseFilterModifyLogFormatter": "includes/AbuseFilterModifyLogFormatter.php", "AbuseFilterSuppressLogFormatter": "includes/AbuseFilterSuppressLogFormatter.php", + "AbuseFilterRightsLogFormatter": "includes/AbuseFilterRightsLogFormatter.php", "AbuseFilterViewList": "includes/Views/AbuseFilterViewList.php", "AbuseFilterPager": "includes/pagers/AbuseFilterPager.php", "GlobalAbuseFilterPager": "includes/pagers/GlobalAbuseFilterPager.php", @@ -137,12 +164,16 @@ "TableDiffFormatterFullContext": "includes/TableDiffFormatterFullContext.php", "AbuseFilterViewImport": "includes/Views/AbuseFilterViewImport.php", "AbuseFilterVariableHolder": "includes/AbuseFilterVariableHolder.php", + "MediaWiki\\Extension\\AbuseFilter\\KeywordsManager": "includes/KeywordsManager.php", + "MediaWiki\\Extension\\AbuseFilter\\AbuseFilterServices": "includes/AbuseFilterServices.php", "AFComputedVariable": "includes/AFComputedVariable.php", "AFPData": "includes/parser/AFPData.php", "AFPException": "includes/parser/AFPException.php", "AFPParserState": "includes/parser/AFPParserState.php", "AFPToken": "includes/parser/AFPToken.php", + "AFPTransitionBase": "includes/parser/AFPTransitionBase.php", "AFPTreeNode": "includes/parser/AFPTreeNode.php", + "AFPSyntaxTree": "includes/parser/AFPSyntaxTree.php", "AFPTreeParser": "includes/parser/AFPTreeParser.php", "AFPUserVisibleException": "includes/parser/AFPUserVisibleException.php", "ApiQueryAbuseLog": "includes/api/ApiQueryAbuseLog.php", @@ -151,7 +182,14 @@ "ApiAbuseFilterEvalExpression": "includes/api/ApiAbuseFilterEvalExpression.php", "ApiAbuseFilterUnblockAutopromote": "includes/api/ApiAbuseFilterUnblockAutopromote.php", "ApiAbuseFilterCheckMatch": "includes/api/ApiAbuseFilterCheckMatch.php", - "NormalizeThrottleParameters": "maintenance/normalizeThrottleParameters.php" + "ApiAbuseLogPrivateDetails": "includes/api/ApiAbuseLogPrivateDetails.php", + "NormalizeThrottleParameters": "maintenance/normalizeThrottleParameters.php", + "FixOldLogEntries": "maintenance/fixOldLogEntries.php", + "UpdateVarDumps": "maintenance/updateVarDumps.php" + }, + "TestAutoloadClasses": { + "AbuseFilterConsequencesTest": "tests/phpunit/AbuseFilterConsequencesTest.php", + "AbuseFilterParserTestCase": "tests/phpunit/unit/AbuseFilterParserTestCase.php" }, "ResourceModules": { "ext.abuseFilter": { @@ -165,11 +203,13 @@ "abusefilter-http-error", "abusefilter-edit-throttle-placeholder", "abusefilter-edit-tag-placeholder", + "abusefilter-edit-warn-leave", "unknown-error" ], "dependencies": [ "mediawiki.util", "mediawiki.api", + "mediawiki.confirmCloseWindow", "jquery.textSelection", "jquery.spinner", "oojs-ui-core", @@ -183,12 +223,12 @@ "abusefilter-reautoconfirm-none", "abusefilter-reautoconfirm-done", "abusefilter-http-error", + "abusefilter-tools-syntax-error", "unknown-error" ], "dependencies": [ "mediawiki.api", - "mediawiki.notify", - "user.tokens", + "user.options", "jquery.spinner" ] }, @@ -211,6 +251,17 @@ "ext.abuseFilter.ace": { "scripts": "mode-abusefilter.js", "dependencies": "ext.codeEditor.ace" + }, + "ext.abuseFilter.visualEditor": { + "scripts": "ve-abusefilter/ve.init.mw.AbuseFilterSaveErrorHandler.js", + "targets": [ "desktop", "mobile" ] + } + }, + "attributes": { + "VisualEditor": { + "PluginModules": [ + "ext.abuseFilter.visualEditor" + ] } }, "ResourceFileModulePaths": { @@ -221,7 +272,7 @@ "Hooks": { "EditFilterMergedContent": "AbuseFilterHooks::onEditFilterMergedContent", "GetAutoPromoteGroups": "AbuseFilterHooks::onGetAutoPromoteGroups", - "MovePageCheckPermissions": "AbuseFilterHooks::onMovePageCheckPermissions", + "TitleMove": "AbuseFilterHooks::onTitleMove", "ArticleDelete": "AbuseFilterHooks::onArticleDelete", "RecentChange_save": "AbuseFilterHooks::onRecentChangeSave", "ListDefinedTags": "AbuseFilterHooks::onListDefinedTags", @@ -229,13 +280,19 @@ "LoadExtensionSchemaUpdates": "AbuseFilterHooks::onLoadExtensionSchemaUpdates", "ContributionsToolLinks": "AbuseFilterHooks::onContributionsToolLinks", "HistoryPageToolLinks": "AbuseFilterHooks::onHistoryPageToolLinks", + "UndeletePageToolLinks": "AbuseFilterHooks::onUndeletePageToolLinks", "UploadVerifyUpload": "AbuseFilterHooks::onUploadVerifyUpload", "UploadStashFile": "AbuseFilterHooks::onUploadStashFile", - "MakeGlobalVariablesScript": "AbuseFilterHooks::onMakeGlobalVariablesScript", - "PageContentSaveComplete": "AbuseFilterHooks::onPageContentSaveComplete", + "PageSaveComplete": "AbuseFilterHooks::onPageSaveComplete", + "RenameUserSQL": "AbuseFilterHooks::onRenameUserSQL", "UserMergeAccountFields": "AbuseFilterHooks::onUserMergeAccountFields", - "ParserOutputStashForEdit": "AbuseFilterHooks::onParserOutputStashForEdit" + "ParserOutputStashForEdit": "AbuseFilterHooks::onParserOutputStashForEdit", + "UnitTestsAfterDatabaseSetup": "AbuseFilterHooks::onUnitTestsAfterDatabaseSetup", + "UnitTestsBeforeDatabaseTeardown": "AbuseFilterHooks::onUnitTestsBeforeDatabaseTeardown" }, + "ServiceWiringFiles": [ + "includes/ServiceWiring.php" + ], "config": { "AbuseFilterActions": { "value": { @@ -245,10 +302,9 @@ "blockautopromote": true, "block": true, "rangeblock": false, - "degroup": true, + "degroup": false, "tag": true }, - "_merge_strategy": "array_plus", "description": "Array of enabled actions in the form [action name => is enabled?]. At the end of setup, false values will be filtered out" }, "AbuseFilterConditionLimit": { @@ -257,32 +313,28 @@ }, "AbuseFilterParserClass": { "value": "AbuseFilterParser", - "description": "Class of the parser to use" + "description": "Class of the parser to use. The only possible values are 'AbuseFilterParser' and 'AbuseFilterCachingParser' (experimental). The code should only use the wrapper AbuseFilter::getDefaultParser." }, "AbuseFilterEmergencyDisableThreshold": { "value": { "default": 0.05 }, - "_merge_strategy": "array_plus", - "description": "Disable filters if they match more than X edits, constituting more than Y% of the last Z edits, if they have been changed in the last S seconds." + "description": "Disable potentially dangerous actions (AbuseFilterRestrictions) of a filter if it matches more than X actions, constituting more than Y% (e.g. 0.05 = 5%) of the last Z actions, and the filter has been modified in the last S seconds. X is AbuseFilterEmergencyDisableCount, Y is AbuseFilterEmergencyDisableThreshold, S is AbuseFilterEmergencyDisableAge and Z is a number between 1 and AbuseFilterProfileActionsCap." }, "AbuseFilterEmergencyDisableCount": { "value": { "default": 2 }, - "_merge_strategy": "array_plus", "description": "See description for AbuseFilterEmergencyDisableThreshold" }, "AbuseFilterEmergencyDisableAge": { "value": { "default": 86400 }, - "_merge_strategy": "array_plus", "description": "See description for AbuseFilterEmergencyDisableThreshold" }, "AbuseFilterRestrictions": { "value": { - "flag": false, "throttle": false, "warn": false, "disallow": false, @@ -292,7 +344,6 @@ "degroup": true, "tag": false }, - "_merge_strategy": "array_plus", "description": "Do users need 'abusefilter-modify-restricted' user right as well as 'abusefilter-modify' in order to create or modify filters which carry out this action? Array like [action name => is restricted?]" }, "AbuseFilterNotifications": { @@ -305,7 +356,7 @@ }, "AbuseFilterCentralDB": { "value": null, - "description": "Name of a database where global abuse filters will be stored in" + "description": "Name of a database where global abuse filters will be stored in. To use a DB with prefixed tables, set this to \"{$databaseName}-{$prefix}\"." }, "AbuseFilterIsCentral": { "value": false, @@ -323,6 +374,10 @@ "value": null, "description": "Old standard block duration for anonymous users, $wgAbuseFilterBlockDuration will be used if null. Kept for backward compatibility after T32024." }, + "AbuseFilterBlockAutopromoteDuration": { + "value": 5, + "description": "Duration, in days, for which users' autopromotion is blocked by filters." + }, "AbuseFilterCustomActionsHandlers": { "value": [], "description": "Callback functions for custom actions" @@ -335,28 +390,18 @@ "value": { "default": "abusefilter-warning" }, - "_merge_strategy": "array_plus", "description": "Default warning messages, per filter group" }, "AbuseFilterDefaultDisallowMessage": { "value": { "default": "abusefilter-disallowed" }, - "description": "Default disallow messages, per filter group", - "_merge_strategy": "array_plus" + "description": "Default disallow messages, per filter group" }, "AbuseFilterLogIPMaxAge": { "value": 7776000, "description": "Age used as cutoff when purging old IP log data, defaults to 3 months. Used by maintenance script purgeOldLogIPData.php" }, - "AbuseFilterProfile": { - "value": false, - "description": "Whether to record the average time taken and average number of conditions used by each filter." - }, - "AbuseFilterRuntimeProfile": { - "value": false, - "description": "Whether to record runtime metrics for all filters combined." - }, "AbuseFilterSlowFilterRuntimeLimit": { "value": 500, "description": "Runtime in milliseconds before a filter is considered slow." @@ -365,18 +410,18 @@ "value": 10000, "description": "Number of action that determines when to reset profiling stats." }, - "AbuseFilterRangeBlockSize" : { + "AbuseFilterRangeBlockSize": { "value": { "IPv4": 16, "IPv6": 19 }, "description": "Size of the range blocked by 'rangeblock' action." }, - "AbuseFilterPrivateLog": { + "AbuseFilterLogPrivateDetailsAccess": { "value": false, "description": "Whether accessing private information from a filter log entry is logged." }, - "AbuseFilterForceSummary": { + "AbuseFilterPrivateDetailsForceReason": { "value": false, "description": "Whether users are forced to provide a reason for accessing private information from a filter log entry." }, diff --git a/AbuseFilter/gitinfo.json b/AbuseFilter/gitinfo.json deleted file mode 100644 index 7a5763cb..00000000 --- a/AbuseFilter/gitinfo.json +++ /dev/null @@ -1 +0,0 @@ -{"headSHA1": "01df8284e6849d6bec6bc413c57f8eb5bc2f4f6f\n", "remoteURL": "https://gerrit.wikimedia.org/r/mediawiki/extensions/AbuseFilter", "headCommitDate": "1551464876", "branch": "01df8284e6849d6bec6bc413c57f8eb5bc2f4f6f\n", "head": "01df8284e6849d6bec6bc413c57f8eb5bc2f4f6f\n"}
\ No newline at end of file diff --git a/AbuseFilter/hooks.txt b/AbuseFilter/hooks.txt index 4d49a073..3d27c977 100644 --- a/AbuseFilter/hooks.txt +++ b/AbuseFilter/hooks.txt @@ -7,7 +7,8 @@ directory and read docs/hooks.txt. This is a list of known events and parameters; please add to it if you're going to add events to the AbuseFilter extension. -'AbuseFilter-builder': Allows overwriting of the builder values returned by AbuseFilter::getBuilderValues +'AbuseFilter-builder': Allows overwriting of the builder values, i.e. names and descriptions of +the AbuseFilter language like variables. &$realValues: Builder values 'AbuseFilter-deprecatedVariables': Allows adding deprecated variables. If a filter uses an old variable, the parser @@ -27,19 +28,34 @@ will be used for non-text content. $content: The Content object &$text: Set this to the desired text. -'AbuseFilter-filterAction': Allows overwriting of abusefilter variables in AbuseFilter::filterAction just -before they're checked against filters. +'AbuseFilter-filterAction': DEPRECATED! Use AbuseFilterAlterVariables instead. +Allows overwriting of abusefilter variables in AbuseFilter::filterAction just before they're +checked against filters. Note that you may specify custom variables in a saner way using other hooks: +AbuseFilter-generateTitleVars, AbuseFilter-generateUserVars and AbuseFilter-generateGenericVars. $vars: AbuseFilterVariableHolder with variables $title: Title object +'AbuseFilterAlterVariables': Allows overwriting of abusefilter variables just before they're +checked against filters. Note that you may specify custom variables in a saner way using other hooks: +AbuseFilter-generateTitleVars, AbuseFilter-generateUserVars and AbuseFilter-generateGenericVars. +$vars: AbuseFilterVariableHolder with variables +$title: Title object target of the action +$user: User object performer of the action + 'AbuseFilter-generateTitleVars': Allows altering the variables generated for a title $vars: AbuseFilterVariableHolder $title: Title object $prefix: Variable name prefix +$rc: RecentChange|null If the variables should be generated for an RC entry, this is the entry. Null if it's for the current action being filtered. 'AbuseFilter-generateUserVars': Allows altering the variables generated for a specific user $vars: AbuseFilterVariableHolder $user: User object +$rc: RecentChange|null If the variables should be generated for an RC entry, this is the entry. Null if it's for the current action being filtered. + +'AbuseFilter-generateGenericVars': Allows altering generic variables, i.e. independent from page and user +$vars: AbuseFilterVariableHolder +$rc: RecentChange|null If the variables should be generated for an RC entry, this is the entry. Null if it's for the current action being filtered. 'AbuseFilter-interceptVariable': Called before a variable is set in AFComputedVariable::compute to be able to set it before the core code runs. Return false to make the function return right after. @@ -47,3 +63,10 @@ $method: Method to generate the variable $vars: AbuseFilterVariableHolder $parameters: Parameters with data to compute the value &$result: Result of the computation + +'AbuseFilterShouldFilterAction': Called before filtering an action. If the current action should not be filtered, +return false and add a useful reason to $skipReasons. +$vars: AbuseFilterVariableHolder +$title: Title object target of the action +$user: User object performer of the action +&$skipReasons: Array of reasons why the action should be skipped diff --git a/AbuseFilter/i18n/ab.json b/AbuseFilter/i18n/ab.json index e67b75d4..33e041ee 100644 --- a/AbuseFilter/i18n/ab.json +++ b/AbuseFilter/i18n/ab.json @@ -4,6 +4,5 @@ "Irus" ] }, - "abusefilter": "Фиҟьльҭә азлоупоҭреблении", "abusefilter-list-edit": "Ариашамҭа" } diff --git a/AbuseFilter/i18n/af.json b/AbuseFilter/i18n/af.json index 0526cdd0..c1d774df 100644 --- a/AbuseFilter/i18n/af.json +++ b/AbuseFilter/i18n/af.json @@ -1,13 +1,13 @@ { "@metadata": { "authors": [ + "Fwolff", "Naudefj", - "පසිඳු කාවින්ද", - "Fwolff" + "පසිඳු කාවින්ද" ] }, "abusefilter-desc": "Pas outomatiese heuristiek te wysigings", - "abusefilter": "Opstelling van misbruikfilter", + "abusefilter": "Misbruik filter bestuur", "abuselog": "Misbruiklogboek", "abusefilter-intro": "Welkom by die misbruik Filter beheer jou.\nDie misbruik Filter is 'n outomatiese sagteware meganisme van die toepassing van outomatiese heuristiek aan alle aksies.\nHierdie koppelvlak toon 'n lys van gedefinieer filters, en kan hulle verander word.", "abusefilter-blocker": "Misbruikfilter", @@ -15,18 +15,17 @@ "right-abusefilter-modify": "Wysig misbruikfilters", "right-abusefilter-view": "Wys misbruikfilters", "right-abusefilter-log": "Die misbruiklogboek bekyk", - "right-abusefilter-private": "Private data in die misbruik log", + "right-abusefilter-privatedetails": "Private data in die misbruik log", "right-abusefilter-modify-restricted": "Verander misbruik filters met 'n beperkte aksies", "right-abusefilter-hidden-log": "View verborge misbruik log inskrywings", "action-abusefilter-modify": "misbruik filters verander", "action-abusefilter-view": "sien misbruik filters", "action-abusefilter-log": "sien die misbruik Wikiquote", "action-abusefilter-log-detail": "gedetailleerde misbruik log inskrywings", - "action-abusefilter-private": "private data in die misbruik log", + "action-abusefilter-privatedetails": "private data in die misbruik log", "action-abusefilter-modify-restricted": "verander misbruik filters met 'n beperkte aksies", "action-abusefilter-revert": "terugkeer om al die veranderinge deur 'n gegewe misbruik filter", "action-abusefilter-view-private": "View misbruik filters gemerk as privaat", - "abusefilter-log": "Misbruiklogboek", "abusefilter-log-summary": "Hierdie log toon 'n lys van al die aksies wat deur die filters gevang.", "abusefilter-log-search": "Die misbruiklogboek deursoek", "abusefilter-log-search-user": "Gebruiker:", @@ -42,13 +41,12 @@ "abusefilter-log-details-var": "Veranderlike", "abusefilter-log-details-val": "Waarde", "abusefilter-log-details-vars": "Aksie parameters", - "abusefilter-log-details-private": "Private data", + "abusefilter-log-details-privatedetails": "Private data", "abusefilter-log-details-ip": "IP-adres", "abusefilter-log-noactions": "geen", "abusefilter-log-details-diff": "Wysigings gemaak in wysig", "abusefilter-log-linkoncontribs": "misbruiklogboek", "abusefilter-log-linkoncontribs-text": "Misbruik log vir hierdie gebruiker", - "abusefilter-log-hidden": "(inskrywing versteek)", "abusefilter-log-cannot-see-details": "Jy hoef nie toestemming om die besonderhede van enige inskrywings te sien.", "abusefilter-log-details-hidden": "Jy kan nie die besonderhede vir hierdie inskrywing, want dit is weggesteek uit die openbare oog.", "abusefilter-log-hide-legend": "Versteek logboekinskrywing", @@ -56,7 +54,6 @@ "abusefilter-log-hide-hidden": "Adres hierdie item uit die publieke oog", "abusefilter-log-hide-reason": "Rede:", "abusefilter-log-hide-forbidden": "Jy hoef nie toestemming om misbruik logitems te verberg.", - "abusefilter-management": "Misbruik filter bestuur", "abusefilter-list": "Alle filters", "abusefilter-list-id": "Filternommer", "abusefilter-list-status": "Status", @@ -76,6 +73,7 @@ "abusefilter-disabled": "Afgeskakel", "abusefilter-hitcount": "$1 {{PLURAL:$1|keer|kere}}", "abusefilter-new": "Skep 'n nuwe filter", + "abusefilter-import-button": "import filter", "abusefilter-return": "Terug na die filterbestuur", "abusefilter-status-global": "Globaal", "abusefilter-list-options": "Opsies", @@ -204,8 +202,8 @@ "abusefilter-edit-builder-vars-all-links": "Alle eksterne skakels in die nuwe teks", "abusefilter-edit-builder-vars-added-links": "Alle eksterne skakels bygevoeg in die bewerking", "abusefilter-edit-builder-vars-removed-links": "Alle eksterne skakels verwyder in die bewerking", - "abusefilter-edit-builder-vars-old-text": "Ou bladsy Text, voor die aangesig van die wysig", - "abusefilter-edit-builder-vars-new-text": "Nuwe blad Text, na die wysig", + "abusefilter-edit-builder-vars-old-wikitext": "Ou bladsy Text, voor die aangesig van die wysig", + "abusefilter-edit-builder-vars-new-wikitext": "Nuwe blad Text, na die wysig", "abusefilter-edit-builder-vars-minor-edit": "Of die wysig is gemerk as 'n kleinigheid", "abusefilter-edit-builder-vars-file-sha1": "SHA1-hashkode van die lêerinhoud", "abusefilter-filter-log": "Onlangse filterveranderinge", @@ -276,7 +274,6 @@ "abusefilter-topnav-examine": "Ondersoek vorige wysigings", "abusefilter-topnav-log": "Filterlogboek", "abusefilter-topnav-tools": "ontfouting gereedskap", - "abusefilter-topnav-import": "import filter", "abusefilter-log-name": "Misbruikfilter se logboek", "abusefilter-log-noresults": "Geen resultate nie", "abusefilter-diff-title": "Verskille tussen weergawes", diff --git a/AbuseFilter/i18n/aln.json b/AbuseFilter/i18n/aln.json index 04617101..f8ef3193 100644 --- a/AbuseFilter/i18n/aln.json +++ b/AbuseFilter/i18n/aln.json @@ -4,6 +4,7 @@ "Mdupont" ] }, + "abusefilter-import-button": "filtër Import", "abusefilter-edit-global": "Apliko këtë filtër globalisht", "abusefilter-edit-throttle-count": "Numri i veprimeve të lejojë:", "abusefilter-edit-throttle-period": "Periudha kohore:", @@ -63,7 +64,6 @@ "abusefilter-topnav-examine": "Ekzaminimi i redaktimet e kaluara", "abusefilter-topnav-log": "Abuse Hyni", "abusefilter-topnav-tools": "Debugging tools", - "abusefilter-topnav-import": "filtër Import", "abusefilter-log-name": "log Abuse Filter", "abusefilter-log-header": "Kjo log tregon një përmbledhje të ndryshimet e bëra në filtra. Për hollësi të plota, shikoni [[Special:AbuseFilter/history|lista]] filtër të ndryshimeve të fundit.", "abusefilter-diff-title": "Dallimet midis versioneve", diff --git a/AbuseFilter/i18n/am.json b/AbuseFilter/i18n/am.json index 5f88b220..3d096db7 100644 --- a/AbuseFilter/i18n/am.json +++ b/AbuseFilter/i18n/am.json @@ -4,7 +4,7 @@ "Codex Sinaiticus" ] }, - "abuselog": "የጥፋቶች መዝገብ", + "abuselog": "የጥፋት ማጣሪያዎች መዝገብ", "abusefilter-blocker": "የጥፋቶች ማጣሪያ", "right-abusefilter-modify": "የጥፋት ማጣሪያዎችን ለመቀይር", "right-abusefilter-view": "የጥፋት ማጣሪያዎችን ለማየት", @@ -12,7 +12,6 @@ "action-abusefilter-modify": "የጥፋት ማጣሪያዎችን ለመቀይር", "action-abusefilter-view": "የጥፋት ማጣሪያዎችን ለማየት", "action-abusefilter-log": "የጥፋትን መዝገብ ለማየት", - "abusefilter-log": "የጥፋት ማጣሪያዎች መዝገብ", "abusefilter-log-search": "የጥፋቶች መዝገብ መፈልግ", "abusefilter-log-search-user": "ተጠቃሚ:", "abusefilter-log-search-filter": "የማጣሪያ መታወቂያ፦", diff --git a/AbuseFilter/i18n/an.json b/AbuseFilter/i18n/an.json index 219105b5..6642842d 100644 --- a/AbuseFilter/i18n/an.json +++ b/AbuseFilter/i18n/an.json @@ -1,8 +1,8 @@ { "@metadata": { "authors": [ - "Juanpabl", - "Carlos Cristia" + "Carlos Cristia", + "Juanpabl" ] }, "abusefilter-log-search-wiki": "Biwi:", diff --git a/AbuseFilter/i18n/api/ar.json b/AbuseFilter/i18n/api/ar.json index 342a88d9..6760fcdd 100644 --- a/AbuseFilter/i18n/api/ar.json +++ b/AbuseFilter/i18n/api/ar.json @@ -1,6 +1,7 @@ { "@metadata": { "authors": [ + "Meno25", "ديفيد", "محمد أحمد عبد الفتاح" ] @@ -40,16 +41,22 @@ "apihelp-query+abuselog-param-logid": "إظهار إدخال بمعرف السجل المحدد.", "apihelp-query+abuselog-param-start": "الطابع الزمني لبدء تعداد منه.", "apihelp-query+abuselog-param-end": "الطابع الزمني لوقف التعداد فيه.", - "apihelp-query+abuselog-param-user": "إظهار الإدخالات من قبل مستخدم معين أو عنوان آيبي فقط.", + "apihelp-query+abuselog-param-user": "إظهار الإدخالات من قبل مستخدم معين أو عنوان أيبي فقط.", "apihelp-query+abuselog-param-title": "إظهار الإدخالات التي تحدث في صفحة معينة فقط.", - "apihelp-query+abuselog-param-filter": "إظهار الإدخالات التي تم التقاطها بواسطة معرف مرشح معين فقط.", + "apihelp-query+abuselog-param-filter": "إظهار الإدخالات فقط التي تم اكتشافها بواسطة معرفات المرشحات المحددة، افصل بالأنابيب والبادئة بـ\"$1\" للمرشحات العالمية.", "apihelp-query+abuselog-param-limit": "الحد الأقصى لعدد الإدخالات للقائمة.", "apihelp-query+abuselog-param-prop": "أي خصائص للحصول عليها.", "apihelp-query+abuselog-param-wiki": "ويكي لإظهار نتائج منه.", "apihelp-query+abuselog-example-1": "أظهر مدخلات السجل الأخيرة", "apihelp-query+abuselog-example-2": "عرض إدخالات السجل الأخيرة لـ[[API]]", + "apihelp-abuselogprivatedetails-description": "عرض تفاصيل إدخال سجل الإساءة الخاصة", + "apihelp-abuselogprivatedetails-summary": "عرض تفاصيل إدخال سجل الإساءة الخاصة", + "apihelp-abuselogprivatedetails-param-logid": "معرف إدخال سجل الإساءة ليتم التحقق منه.", + "apihelp-abuselogprivatedetails-param-reason": "سبب وجيه لأداء التحقق.", + "apihelp-abuselogprivatedetails-example-1": "احصل على تفاصيل خاصة لإدخال سجل الإساءة بالمعرف 1، باستخدام السبب \"مثال\".", "apierror-abusefilter-canttest": "ليست لديك الصلاحية لاختبار مرشحات الإساءة.", "apierror-abusefilter-cantcheck": "ليست لديك الصلاحية للتحقق من بناء مرشحات الإساءة.", + "apierror-abusefilter-canteval": "ليست لديك صلاحية لتقييم تعبيرات مرشح الإساءة", "apierror-abusefilter-nosuchlogid": "ليس هناك إدخال سجل إساءة بالمعرف $1.", "apierror-abusefilter-badsyntax": "يحتوي المرشح على بنية غير صالحة." } diff --git a/AbuseFilter/i18n/api/ast.json b/AbuseFilter/i18n/api/ast.json index 8eb20eea..099dca0c 100644 --- a/AbuseFilter/i18n/api/ast.json +++ b/AbuseFilter/i18n/api/ast.json @@ -41,14 +41,20 @@ "apihelp-query+abuselog-param-end": "La marca horaria na que finar la enumeración.", "apihelp-query+abuselog-param-user": "Amosar solo les entraes feches por un determináu usuariu o IP.", "apihelp-query+abuselog-param-title": "Amosar solo les entraes correspondientes a una páxina determinada.", - "apihelp-query+abuselog-param-filter": "Amostrar solo les entraes recoyíes por un identificador de filtru determináu.", + "apihelp-query+abuselog-param-filter": "Amostrar solo les entraes recoyíes por un identificador de filtru determináu. Separar con barres verticales, prefixar con «$1» pa filtros globales.", "apihelp-query+abuselog-param-limit": "La cantidá máxima d'entraes qu'apaecerán.", "apihelp-query+abuselog-param-prop": "Qué propiedaes algamar.", "apihelp-query+abuselog-param-wiki": "Wiki de la qu'amosar les detecciones.", "apihelp-query+abuselog-example-1": "Amosar les entraes recientes del rexistru", "apihelp-query+abuselog-example-2": "Amosar les entraes recientes del rexistru pa la [[API]]", + "apihelp-abuselogprivatedetails-description": "Ver detalles privaos d'una entrada de AbuseLog.", + "apihelp-abuselogprivatedetails-summary": "Ver detalles privaos d'una entrada de AbuseLog.", + "apihelp-abuselogprivatedetails-param-logid": "L'identificador de la entrada de AbuseLog a comprobar.", + "apihelp-abuselogprivatedetails-param-reason": "Un motivu válidu pa realizar la comprobación.", + "apihelp-abuselogprivatedetails-example-1": "Ver los detalles privaos de la entrada d'AbuseLog con ID 1, usando'l motivu \"example\".", "apierror-abusefilter-canttest": "Nun tienes permisu pa probar peñeres d'abusu.", "apierror-abusefilter-cantcheck": "Nun tienes permisu pa comprobar la sintaxis de les peñeres d'abusu.", + "apierror-abusefilter-canteval": "Nun tienes permisu pa evaluar espresiones d'AbuseFilter.", "apierror-abusefilter-nosuchlogid": "Nun hai nenguna entrada nos rexistros de les peñeres d'abusu con id $1.", "apierror-abusefilter-badsyntax": "El filtru tien una sintaxis inválida." } diff --git a/AbuseFilter/i18n/api/be-tarask.json b/AbuseFilter/i18n/api/be-tarask.json new file mode 100644 index 00000000..95853053 --- /dev/null +++ b/AbuseFilter/i18n/api/be-tarask.json @@ -0,0 +1,62 @@ +{ + "@metadata": { + "authors": [ + "Nerogaf", + "Red Winged Duck", + "Renessaince" + ] + }, + "apihelp-abusefiltercheckmatch-description": "Праверце, ці адпавядае Фільтру злоўжываньняў набор зьменных, рэдагаваньне ці запратакаляваная падзея Фільтру.", + "apihelp-abusefiltercheckmatch-summary": "Праверце, ці адпавядае Фільтру злоўжываньняў набор зьменных, рэдагаваньне ці запратакаляваная падзея Фільтру.", + "apihelp-abusefiltercheckmatch-extended-description": "патрабуюцца vars, rcid або logid, аднак можа выкарыстоўвацца толькі адзін зь іх.", + "apihelp-abusefiltercheckmatch-param-filter": "Паўнатэкставы фільтар для праверкі на адпаведнасьць.", + "apihelp-abusefiltercheckmatch-param-vars": "JSON-закадаваны масіў зьменных для тэставаньня.", + "apihelp-abusefiltercheckmatch-param-rcid": "Ідэнтыфікатар у нядаўніх зьменах, на аснове якога будзе зьдзейсьненая праверка.", + "apihelp-abusefiltercheckmatch-param-logid": "Ідэнтыфікатар журналу фільтру злоўжываньняў для праверкі.", + "apihelp-abusefiltercheckmatch-example-1": "Праверыць, ці ідэнтыфікатар апошніх зьменаў 15 супадае з простым фільтрам", + "apihelp-abusefilterchecksyntax-description": "Праверыць сынтаксыс асобнага фільтру злоўжываньняў.", + "apihelp-abusefilterchecksyntax-summary": "Праверыць сынтаксыс фільтру злоўжываньняў.", + "apihelp-abusefilterchecksyntax-param-filter": "Паўнатэкставы фільтар тэксту для праверкі на адпаведнасьць.", + "apihelp-abusefilterchecksyntax-example-1": "Праверыць сынтаксыс дзейнага фільтру", + "apihelp-abusefilterchecksyntax-example-2": "Праверыць сынтаксыс некарэктнага фільтру", + "apihelp-abusefilterevalexpression-description": "Ацэньвае значэньне выразу фільтара рэдагаваньняў.", + "apihelp-abusefilterevalexpression-summary": "Ацэньвае значэньне выразу фільтара злоўжываньняў.", + "apihelp-abusefilterevalexpression-param-expression": "Выраз для вылічэньня.", + "apihelp-abusefilterevalexpression-example-1": "Ацаніць просты выраз.", + "apihelp-abusefilterunblockautopromote-description": "Разблякаваць карыстальніка ад атрыманьня аўтаматычных рэклямных акцыяў з-за наступстваў abusefilter.", + "apihelp-abusefilterunblockautopromote-summary": "Разблякаваць карыстальніка ад атрыманьня аўтаматычных рэклямных акцыяў з-за наступстваў abusefilter.", + "apihelp-abusefilterunblockautopromote-param-user": "Імя карыстальніка, якога вы жадаеце разблякаваць.", + "apihelp-abusefilterunblockautopromote-example-1": "Зьняць блякаваньне з аўтаматычнага прасоўваньня карыстача [[User:Example]]", + "apihelp-query+abusefilters-description": "Паказаць падрабязнасьці фільтраў злоўжываньняў.", + "apihelp-query+abusefilters-summary": "Паказаць падрабязнасьці фільтраў злоўжываньняў.", + "apihelp-query+abusefilters-param-startid": "Ідэнтыфікатар фільтру, зь якога пачынаць пералік.", + "apihelp-query+abusefilters-param-endid": "Ідэнтыфікатар фільтру, на якім спыніць пералік.", + "apihelp-query+abusefilters-param-show": "Паказаць толькі фільтры, якія адпавядаюць гэтым крытэрам.", + "apihelp-query+abusefilters-param-limit": "Максымальная колькасьць фільтраў у сьпісе.", + "apihelp-query+abusefilters-param-prop": "Якія ўласьцівасьці атрымаць.", + "apihelp-query+abusefilters-example-1": "Сьпіс уключаных публічных фільтраў", + "apihelp-query+abusefilters-example-2": "Паказаць некаторыя падрабязнасьці пра фільтры", + "apihelp-query+abuselog-description": "Паказаць падзеі, якія былі адсочаны адным з фільтраў злоўжываньняў.", + "apihelp-query+abuselog-summary": "Паказаць падзеі, якія былі выяўлены адным з фільтраў злоўжываньняў.", + "apihelp-query+abuselog-param-logid": "Паказаць запіс з пададзеным ідэнтыфікатарам журналу.", + "apihelp-query+abuselog-param-start": "Адзнака часу, зь якой пачынаць пералік.", + "apihelp-query+abuselog-param-end": "Адзнака часу, на якой спыніць пералік.", + "apihelp-query+abuselog-param-user": "Паказаць толькі элемэнты, зробленыя пэўным карыстачом або ІП-адрасам.", + "apihelp-query+abuselog-param-title": "Паказаць толькі запісы, якія адбыліся на пададзенай старонцы.", + "apihelp-query+abuselog-param-filter": "Паказваць толькі запісы, якія былі перахопленыя дадзенымі ідэнтыфікатарамі фільтру. Аддзяляюцца вэртыкальнымі рыскамі, для глябальных фільтраў прымяняецца прэфікс «$1».", + "apihelp-query+abuselog-param-limit": "Максімальная колькасьць запісаў у сьпісе.", + "apihelp-query+abuselog-param-prop": "Якія ўласьцівасьці атрымаць.", + "apihelp-query+abuselog-param-wiki": "Вікі, з якой паказаць вылучэньні.", + "apihelp-query+abuselog-example-1": "Паказаць нядаўнія запісы ў журнале", + "apihelp-query+abuselog-example-2": "Паказаць нядаўнія запісы ў часопіс [[API]]", + "apihelp-abuselogprivatedetails-description": "Паказаць асабістыя падрабязнасьці запісу у часопісе фільтара рэдагаваньняў.", + "apihelp-abuselogprivatedetails-summary": "Прагляд прыватных зьвестак пра запіс журналу злоўжываньняў.", + "apihelp-abuselogprivatedetails-param-logid": "Ідэнтыфікатар запісу журналу злоўжываньняў, які падлягае праверцы.", + "apihelp-abuselogprivatedetails-param-reason": "Важкая прычына для правядзеньня праверкі.", + "apihelp-abuselogprivatedetails-example-1": "Атрымаць прыватныя зьвесткі для запісу журналу злоўжываньняў з ідэнтыфікатарам 1, выкарыстоўваючы прычыну «прыклад».", + "apierror-abusefilter-canttest": "Вы ня маеце дазволу на тэставаньне фільтараў злоўжываньняў.", + "apierror-abusefilter-cantcheck": "Вы ня маеце дазволу на праверку сынтаксісу фільтраў злоўжываньняў.", + "apierror-abusefilter-canteval": "Вы ня маеце дазволу на ацэнку выразаў фільтру злоўжываньняў.", + "apierror-abusefilter-nosuchlogid": "Няма ніякага запісу журналу злоўжываньняў з ідэнтыфікатарам $1.", + "apierror-abusefilter-badsyntax": "Сынтаксычная памылка ў фільтры." +} diff --git a/AbuseFilter/i18n/api/bg.json b/AbuseFilter/i18n/api/bg.json index b4c8b7f2..4e49f7ca 100644 --- a/AbuseFilter/i18n/api/bg.json +++ b/AbuseFilter/i18n/api/bg.json @@ -2,18 +2,22 @@ "@metadata": { "authors": [ "StanProg", + "Vlad5250", "Vodnokon4e" ] }, "apihelp-abusefiltercheckmatch-param-filter": "Пълния текст на филтър за проверка за съвпадение.", "apihelp-abusefilterchecksyntax-description": "Проверка на синтаксиса на филтър срещу злоупотреби.", + "apihelp-abusefilterchecksyntax-summary": "Проверка на синтаксиса на даден филтър срещу злоупотреби.", "apihelp-abusefilterchecksyntax-example-1": "Проверка на синтаксиса на валиден филтър", "apihelp-abusefilterchecksyntax-example-2": "Проверка на синтаксиса на невалиден филтър", "apihelp-abusefilterevalexpression-description": "Изчисляване на израз от филтър срещу злоупотреби", + "apihelp-abusefilterevalexpression-summary": "Изчисляване на израз от филтър срещу злоупотреби", "apihelp-abusefilterevalexpression-param-expression": "Израз за изчисляване.", "apihelp-abusefilterevalexpression-example-1": "Изчисляване на прост израз", "apihelp-abusefilterunblockautopromote-param-user": "Име на потребителя, който искате да отблокирате.", "apihelp-query+abusefilters-description": "Показване на детайлите на филтрите срещу злоупотреби", + "apihelp-query+abusefilters-summary": "Показване на детайлите на филтрите срещу злоупотреби.", "apihelp-query+abusefilters-param-startid": "Идентификатор на филтъра, от който да започне изчислението.", "apihelp-query+abusefilters-param-endid": "Идентификатор на филтъра, при който да завърши изчислението.", "apihelp-query+abusefilters-param-show": "Показване само на филтри, които отговарят на тези критерии.", @@ -22,15 +26,23 @@ "apihelp-query+abusefilters-example-1": "Списък на активираните публични филтри", "apihelp-query+abusefilters-example-2": "Показване на допълнителна информация за филтри", "apihelp-query+abuselog-description": "Показване на събития, които отговарят на един от филтрите срещу злоупотреби.", + "apihelp-query+abuselog-summary": "Показване на събития, които отговарят на един от филтрите срещу злоупотреби.", + "apihelp-query+abuselog-param-logid": "Показване на запис с дадено ID на дневника.", "apihelp-query+abuselog-param-start": "Времева отметка, от която да започва изчислението.", "apihelp-query+abuselog-param-end": "Времева отметка, при която да спира изчислението.", "apihelp-query+abuselog-param-user": "Показване само на записи, свързани с даден потребител или IP адрес.", "apihelp-query+abuselog-param-title": "Показване само на записи, свързани с определена страница.", - "apihelp-query+abuselog-param-filter": "Показване само записи, които отговарят на даден ID на филтър.", + "apihelp-query+abuselog-param-filter": "Показване само записи, които отговарят на даден ID на филтър. Разделени с вертикални черти, с префикс „$1“ за глобалните филтри.", "apihelp-query+abuselog-param-limit": "Максимален брой записи в списъка.", "apihelp-query+abuselog-param-prop": "Какви свойства трябва да се получат.", + "apihelp-query+abuselog-param-wiki": "Уики, от което да се покажат посещенията.", "apihelp-query+abuselog-example-1": "Показване на последните записи в дневника", "apihelp-query+abuselog-example-2": "Показване на последните записи в дневника на [[API]]", + "apihelp-abuselogprivatedetails-description": "Преглед на личните данни от запис на AbuseLog.", + "apihelp-abuselogprivatedetails-summary": "Преглед на личните данни от запис на AbuseLog.", + "apihelp-abuselogprivatedetails-param-logid": "Номера на записа от AbuseLog за проверка.", + "apihelp-abuselogprivatedetails-param-reason": "Основателна причина за извършване на проверката.", + "apihelp-abuselogprivatedetails-example-1": "Получаване на лични данни за запис от AbuseLog с ID 1, използвайки като причина „пример“.", "apierror-abusefilter-canttest": "Нямате права за тестване на филтрите срещу злоупотреби.", "apierror-abusefilter-cantcheck": "Нямате права за проверка на синтаксиса на филтрите срещу злоупотреби.", "apierror-abusefilter-nosuchlogid": "В дневника за злоупотреби не съществува запис с ID $1.", diff --git a/AbuseFilter/i18n/api/br.json b/AbuseFilter/i18n/api/br.json new file mode 100644 index 00000000..eaf41d9b --- /dev/null +++ b/AbuseFilter/i18n/api/br.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Fulup" + ] + }, + "apihelp-abusefilterevalexpression-param-prettyprint": "Daoust ha ret eo d'an disoc'h bezañ diskwelet brav.", + "apihelp-abusefilterevalexpression-example-2": "Priziañ ur jedad eeun ha pajennaozañ an disoc'h" +} diff --git a/AbuseFilter/i18n/api/ca.json b/AbuseFilter/i18n/api/ca.json index 56f3eb3d..68993104 100644 --- a/AbuseFilter/i18n/api/ca.json +++ b/AbuseFilter/i18n/api/ca.json @@ -1,10 +1,12 @@ { "@metadata": { "authors": [ + "Fitoschido", "Toniher" ] }, "apihelp-query+abusefilters-param-prop": "Quines propietats obtenir.", "apihelp-query+abusefilters-example-1": "Llista els filtres públics habilitats", - "apihelp-query+abusefilters-example-2": "Mostra alguns detalls dels filtres" + "apihelp-query+abusefilters-example-2": "Mostra alguns detalls dels filtres", + "apierror-abusefilter-badsyntax": "La sintaxi del filtre no és vàlida." } diff --git a/AbuseFilter/i18n/api/cs.json b/AbuseFilter/i18n/api/cs.json index e792c803..1679b4a0 100644 --- a/AbuseFilter/i18n/api/cs.json +++ b/AbuseFilter/i18n/api/cs.json @@ -4,10 +4,12 @@ "Cvanca", "Dvorapa", "Matěj Suchánek", - "Mormegil" + "Mormegil", + "Slepi" ] }, "apihelp-abusefiltercheckmatch-description": "Zkontrolovat, zda filtr zneužití odpovídá sadě proměnných, editaci nebo změně zaznamenané ve filtru.\n\nJe vyžadována právě jedna z následujících možností: vars, rcid nebo logid.", + "apihelp-abusefiltercheckmatch-extended-description": "vars, rcid nebo logid jsou povinné parametry, avšak jen jeden z nich může být použit", "apihelp-abusefiltercheckmatch-param-filter": "Plný text filtru, který se má kontrolovat na shodu.", "apihelp-abusefiltercheckmatch-param-vars": "Pole proměnných vůči kterým chcete testovat, kódované v JSON.", "apihelp-abusefiltercheckmatch-param-rcid": "ID poslední změny vůči které chcete testovat.", @@ -26,6 +28,7 @@ "apihelp-abusefilterunblockautopromote-param-user": "Jméno uživatele, jehož chcete odblokovat.", "apihelp-abusefilterunblockautopromote-example-1": "Zrušit blokování automatického povýšení uživatele [[User:Example]]", "apihelp-query+abusefilters-description": "Zobrazit podrobnosti o filtrech zneužití.", + "apihelp-query+abusefilters-summary": "Zobrazit podrobnosti o filtrech zneužití.", "apihelp-query+abusefilters-param-startid": "ID filtru, od kterého se začne s výčtem.", "apihelp-query+abusefilters-param-endid": "ID filtru, u kterého výčet skončí.", "apihelp-query+abusefilters-param-show": "Zobrazit pouze filtry, které splňují tato kritéria.", @@ -34,11 +37,12 @@ "apihelp-query+abusefilters-example-1": "Zobrazit zapnuté veřejné filtry", "apihelp-query+abusefilters-example-2": "Zobrazit podrobnosti o filtrech", "apihelp-query+abuselog-description": "Zobrazit události, které byly zachyceny filtrem zneužití.", + "apihelp-query+abuselog-summary": "Zobrazit události, které byly zachyceny filtrem zneužití.", "apihelp-query+abuselog-param-start": "Časová značka, od které se začne s výčtem.", "apihelp-query+abuselog-param-end": "Časová značka, u které výčet skončí.", "apihelp-query+abuselog-param-user": "Zobrazit pouze změny provedené daným uživatelem nebo z příslušné IP adresy.", "apihelp-query+abuselog-param-title": "Zobrazit pouze změny, které se vyskytují na dané stránce.", - "apihelp-query+abuselog-param-filter": "Zobrazit pouze změny, které byly zachyceny daným filtrem.", + "apihelp-query+abuselog-param-filter": "Zobrazit pouze změny, které byly zachyceny daným filtrem. Oddělte je pomocí svislítka, před globální filtry přidejte „$1“.", "apihelp-query+abuselog-param-limit": "Maximální počet změn k zobrazení.", "apihelp-query+abuselog-param-prop": "Jaké vlastnosti získat.", "apihelp-query+abuselog-param-wiki": "Wiki, na nichž došlo k zásahům filtrů.", diff --git a/AbuseFilter/i18n/api/da.json b/AbuseFilter/i18n/api/da.json new file mode 100644 index 00000000..9769be61 --- /dev/null +++ b/AbuseFilter/i18n/api/da.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Saederup92" + ] + }, + "apihelp-abusefilterunblockautopromote-param-user": "Brugernavnet åp brugeren du ønsker at fjerne blokeringen fra.", + "apihelp-query+abusefilters-param-prop": "Hvilke egenskaber at få.", + "apihelp-query+abuselog-param-prop": "Hvilke egenskaber der skal hentes." +} diff --git a/AbuseFilter/i18n/api/de.json b/AbuseFilter/i18n/api/de.json index c1b59cba..6da52c53 100644 --- a/AbuseFilter/i18n/api/de.json +++ b/AbuseFilter/i18n/api/de.json @@ -1,12 +1,16 @@ { "@metadata": { "authors": [ + "FF11", "Inkowik", "MGChecker", "Metalhead64", + "Schmackes", "ToBeFree" ] }, + "apihelp-abusefiltercheckmatch-description": "Prüfen, ob ein Missbrauchsfilter mit einem Satz von Variablen, einer Bearbeitung oder einem protokollierten Missbrauchsfilter-Ereignis übereinstimmt.\n\nvars, rcid oder logid ist erforderlich, es darf jedoch nur eine davon verwendet werden.", + "apihelp-abusefiltercheckmatch-summary": "Prüfen, ob ein Missbrauchsfilter mit einem Satz von Variablen, einer Bearbeitung oder einem protokollierten Missbrauchsfilter-Ereignis übereinstimmt.", "apihelp-abusefiltercheckmatch-extended-description": "Es ist vars, rcid oder logid erforderlich, jedoch kann nur eines verwendet werden.", "apihelp-abusefiltercheckmatch-param-filter": "Der vollständige Filtertext, der für einen Treffer überprüft werden soll.", "apihelp-abusefiltercheckmatch-param-vars": "JSON-kodierte Anordnung von Variablen, die gegengetestet werden sollen.", @@ -21,8 +25,13 @@ "apihelp-abusefilterevalexpression-description": "Evaluiert einen Missbrauchsfilter-Ausdruck.", "apihelp-abusefilterevalexpression-summary": "Bewertet einen Ausdruck des Missbrauchfilters.", "apihelp-abusefilterevalexpression-param-expression": "Der zu evaluierende Ausdruck.", + "apihelp-abusefilterevalexpression-param-prettyprint": "Ob das Ergebnis hübsch ausgedruckt werden soll.", "apihelp-abusefilterevalexpression-example-1": "Evaluiert einen einfachen Ausdruck", + "apihelp-abusefilterevalexpression-example-2": "Auswertung eines einfachen Ausdrucks, Formatierung des Ergebnisses", + "apihelp-abusefilterunblockautopromote-description": "Verhindert, dass ein Benutzer aufgrund einer Missbrauchsfilter-Folge Autopromotions erhält.", + "apihelp-abusefilterunblockautopromote-summary": "Verhindert, dass ein Benutzer aufgrund einer Missbrauchsfilter-Folge Autopromotions erhält.", "apihelp-abusefilterunblockautopromote-param-user": "Benutzername des Benutzers, den du entsperren möchtest.", + "apihelp-abusefilterunblockautopromote-example-1": "Entfernet die Sperre auf der Autopromotion von [[User:Example]]", "apihelp-query+abusefilters-description": "Einzelheiten über die Missbrauchsfilter anzeigen.", "apihelp-query+abusefilters-summary": "Zeigt Einzelheiten des Missbrauchfilters an.", "apihelp-query+abusefilters-param-startid": "Die Filterkennung, bei der die Aufzählung beginnen soll.", @@ -39,14 +48,21 @@ "apihelp-query+abuselog-param-end": "Der Zeitstempel, bei dem die Aufzählung beendet werden soll.", "apihelp-query+abuselog-param-user": "Nur Einträge von einem angegebenen Benutzer oder einer IP-Adresse anzeigen.", "apihelp-query+abuselog-param-title": "Zeigt nur Einträge, die auf einer angegebenen Seite erscheinen.", - "apihelp-query+abuselog-param-filter": "Zeigt nur Einträge an, die von einer angegebenen Filterkennung erfasst wurden.", + "apihelp-query+abuselog-param-filter": "Nur Einträge anzeigen, die von den angegebenen Filter-IDs erfasst wurden. Mit Pipes trennen, Präfix mit „$1“ für globale Filter.", + "apihelp-query+abuselog-param-filter-central": "Nur Einträge anzeigen, die von den angegebenen Filter-IDs erfasst wurden. Mit Pipes trennen.", "apihelp-query+abuselog-param-limit": "Die maximale Anzahl der aufzulistenden Einträge.", "apihelp-query+abuselog-param-prop": "Zurückzugebende Eigenschaften.", "apihelp-query+abuselog-param-wiki": "Wiki, von dem Treffer angezeigt werden sollen.", "apihelp-query+abuselog-example-1": "Zeigt die letzten Logbucheinträge", "apihelp-query+abuselog-example-2": "Zeigt die letzten Logbucheinträge für [[API]]", + "apihelp-abuselogprivatedetails-description": "Private Details des AbuseLog-Eintrags ansehen.", + "apihelp-abuselogprivatedetails-summary": "Private Details des AbuseLog-Eintrags ansehen.", + "apihelp-abuselogprivatedetails-param-logid": "Die Kennung des zu überprüfenden AbuseLog-Eintrags.", + "apihelp-abuselogprivatedetails-param-reason": "Ein gültiger Grund für das Ausführen der Überprüfung.", + "apihelp-abuselogprivatedetails-example-1": "Private Details für den AbuseLog-Eintrag mit der Kennung 1 erhalten mit der Begründung „Beispiel“.", "apierror-abusefilter-canttest": "Du hast keine Berechtigung, Missbrauchsfilter zu testen.", "apierror-abusefilter-cantcheck": "Du hast keine Berechtigung, die Syntax von Missbrauchsfiltern zu überprüfen.", + "apierror-abusefilter-canteval": "Du hast keine Berechtigung zum Auswerten von AbuseFilter-Ausdrücken.", "apierror-abusefilter-nosuchlogid": "Es gibt keinen Missbrauchsfilter-Logbuch-Eintrag mit der Kennung $1.", "apierror-abusefilter-badsyntax": "Der Filter hat eine ungültige Syntax." } diff --git a/AbuseFilter/i18n/api/diq.json b/AbuseFilter/i18n/api/diq.json index e1ca16bf..5cb39be0 100644 --- a/AbuseFilter/i18n/api/diq.json +++ b/AbuseFilter/i18n/api/diq.json @@ -3,7 +3,9 @@ "authors": [ "1917 Ekim Devrimi", "Asmen", - "Kumkumuk" + "Kumkumuk", + "Mirzali", + "Orbot707" ] }, "apihelp-abusefiltercheckmatch-description": "Ratena Fiktrandê nengan dı têversanayış esto se, filtrey nengan de vurnayış vurnayışi kontrol kerê \n\nVurnayoğê RCID ya na LOGID eger ke icab krno se karêno", @@ -13,16 +15,20 @@ "apihelp-abusefiltercheckmatch-param-logid": "Têverşanaene rê IDy qeydê filtrey heqareti", "apihelp-abusefiltercheckmatch-example-1": "Vurnayışê peyêni kamiya basit filtre de 15 ra vêşi se test ke", "apihelp-abusefilterchecksyntax-description": "Filtreya nengan parzuna syntaxi çımraravyarn", + "apihelp-abusefilterchecksyntax-summary": "Rêza qıseyanê yew parzûnê istısmari çım ra raviyarne.", "apihelp-abusefilterchecksyntax-param-filter": "Ful filtreya metini çımraravyarn syntaxi", "apihelp-abusefilterchecksyntax-example-1": "Filtreya ravêrdi syntaxi çım ra ravyarn", "apihelp-abusefilterchecksyntax-example-2": "Rêzê yew filtreyo ke muteber niyo, çım ra raviyarne", "apihelp-abusefilterevalexpression-description": "Erca ifadeya Filtreya nengan", + "apihelp-abusefilterevalexpression-summary": "İfadeyê yew parzûnê istısmari ercneno.", "apihelp-abusefilterevalexpression-param-expression": "Erceya ifadeyan", "apihelp-abusefilterevalexpression-example-1": "Erca gasit ifadeyan", "apihelp-abusefilterunblockautopromote-description": "Filtreya nengan karberi neticeya bloqe bıyayışa cı otomatik kerdau gêriya ya", + "apihelp-abusefilterunblockautopromote-summary": "Seba parzûnê istısmari ra gırewtışê qıseykerdışê otomatiki ra yew karberi kılit keno.", "apihelp-abusefilterunblockautopromote-param-user": "Şıma qayılê ke bloqey kanci bamaey karberi wedarne.", "apihelp-abusefilterunblockautopromote-example-1": "Otomatik [[User:Example]] bloqey cı wedarnê", "apihelp-query+abusefilters-description": "Detaya filtreya nengan bıvin", + "apihelp-query+abusefilters-summary": "Detayanê parzûnê istısmari bımocne.", "apihelp-query+abusefilters-param-startid": "Kamiya filtre nımre kerdışmra start ke", "apihelp-query+abusefilters-param-endid": "Kamiya filtri nımre kedışi vındarn", "apihelp-query+abusefilters-param-show": "Kanci filtrey teyna ena kriterer anê bıvin", @@ -31,15 +37,21 @@ "apihelp-query+abusefilters-example-1": "Listey filtreya şari aktiva", "apihelp-query+abusefilters-example-2": "Heqdê filtranndı tayna detaya bıvin", "apihelp-query+abuselog-description": "Filtreya nengan yew merdımi teref ra tepêşyaya bıvin", + "apihelp-query+abuselog-summary": "Parzûnanê istısmari ra yewo ke weqeyi tepıştê, bımocne.", "apihelp-query+abuselog-param-start": "Mora zemani nımre kerdışmra start ke", "apihelp-query+abuselog-param-end": "Mora zemani nımre kedışi vındarn", "apihelp-query+abuselog-param-user": "Teyna qeydé dekerdena grotena IP adresa karberi bıvin", "apihelp-query+abuselog-param-title": "Dekerdenanê perer teyna bıvin", - "apihelp-query+abuselog-param-filter": "Teyna dekerdenanê kamiya filtrande tepêştena grotışa bıvin", + "apihelp-query+abuselog-param-filter": "Teyna dekerdenanê kamiya filtrande tepêştena grotışa bıvin. Pey blokana abırne u parzûnê $1ya verole cıkuye", "apihelp-query+abuselog-param-limit": "Azami miktarê dekerdena liste ke", "apihelp-query+abuselog-param-prop": "Kamci xısusiyeta ke gê no", + "apihelp-query+abuselog-param-wiki": "Wiki ra isabetê ke bımocniyê.", "apihelp-query+abuselog-example-1": "Qeydanê dekerdanê peyênan bıasne", "apihelp-query+abuselog-example-2": "Qandé [[API]] Qeydanê dekerdanê peyênan bıasne", + "apihelp-abuselogprivatedetails-description": "Yew cıkewtışê xısusiyê detayanê AbuseLogi bımocne .", + "apihelp-abuselogprivatedetails-summary": "Yew cıkewtışê xısusiyê detayanê AbuseLogi bımocne", + "apihelp-abuselogprivatedetails-param-logid": "Kontrol bıyaye cıkewtışê kamiya AbuseLogi", + "apihelp-abuselogprivatedetails-param-reason": "Seba kontrol kerdışi rê yew sebeb", "apierror-abusefilter-canttest": "Testê qeydê nengan rê izinê şıma çıni yo.", "apierror-abusefilter-cantcheck": "rêz kerdena qeydanê nengan rê izinê şıma çıni yo.", "apierror-abusefilter-nosuchlogid": "Tiya ra qeydê nengan nêdebêno kamiya $1", diff --git a/AbuseFilter/i18n/api/en.json b/AbuseFilter/i18n/api/en.json index 45bc1583..8e46cd72 100644 --- a/AbuseFilter/i18n/api/en.json +++ b/AbuseFilter/i18n/api/en.json @@ -23,7 +23,9 @@ "apihelp-abusefilterevalexpression-description": "Evaluates an AbuseFilter expression.", "apihelp-abusefilterevalexpression-summary": "Evaluates an AbuseFilter expression.", "apihelp-abusefilterevalexpression-param-expression": "The expression to evaluate.", + "apihelp-abusefilterevalexpression-param-prettyprint": "Whether the result should be pretty-printed.", "apihelp-abusefilterevalexpression-example-1": "Evaluate a simple expression", + "apihelp-abusefilterevalexpression-example-2": "Evaluate a simple expression, formatting the result", "apihelp-abusefilterunblockautopromote-description": "Unblocks a user from receiving autopromotions due to an abusefilter consequence.", "apihelp-abusefilterunblockautopromote-summary": "Unblocks a user from receiving autopromotions due to an abusefilter consequence.", "apihelp-abusefilterunblockautopromote-param-user": "Username of the user you want to unblock.", @@ -44,14 +46,21 @@ "apihelp-query+abuselog-param-end": "The timestamp to stop enumerating at.", "apihelp-query+abuselog-param-user": "Show only entries done by a given user or IP address.", "apihelp-query+abuselog-param-title": "Show only entries occurring on a given page.", - "apihelp-query+abuselog-param-filter": "Show only entries that were caught by a given filter ID.", + "apihelp-query+abuselog-param-filter": "Show only entries that were caught by the given filter IDs. Separate with pipes, prefix with \"$1\" for global filters.", + "apihelp-query+abuselog-param-filter-central": "Show only entries that were caught by the given filter IDs. Separate with pipes.", "apihelp-query+abuselog-param-limit": "The maximum amount of entries to list.", "apihelp-query+abuselog-param-prop": "Which properties to get.", "apihelp-query+abuselog-param-wiki": "Wiki to show hits from.", "apihelp-query+abuselog-example-1": "Show recent log entries", "apihelp-query+abuselog-example-2": "Show recent log entries for [[API]]", + "apihelp-abuselogprivatedetails-description": "View private details of an AbuseLog entry.", + "apihelp-abuselogprivatedetails-summary": "View private details of an AbuseLog entry.", + "apihelp-abuselogprivatedetails-param-logid": "The ID of the AbuseLog entry to be checked.", + "apihelp-abuselogprivatedetails-param-reason": "A valid reason for performing the check.", + "apihelp-abuselogprivatedetails-example-1": "Get private details for the AbuseLog entry with ID 1, using the reason \"example\".", "apierror-abusefilter-canttest": "You don't have permission to test abuse filters.", "apierror-abusefilter-cantcheck": "You don't have permission to check syntax of abuse filters.", + "apierror-abusefilter-canteval": "You don't have permission to evaluate AbuseFilter expressions.", "apierror-abusefilter-nosuchlogid": "There is no abuselog entry with the id $1.", "apierror-abusefilter-badsyntax": "The filter has invalid syntax." } diff --git a/AbuseFilter/i18n/api/eo.json b/AbuseFilter/i18n/api/eo.json new file mode 100644 index 00000000..32f5068f --- /dev/null +++ b/AbuseFilter/i18n/api/eo.json @@ -0,0 +1,22 @@ +{ + "@metadata": { + "authors": [ + "Mirin" + ] + }, + "apihelp-abusefilterchecksyntax-description": "Kontroli sintakson de AbuseFilter-filtrilo.", + "apihelp-abusefilterchecksyntax-summary": "Kontroli sintakson de AbuseFilter-filtrilo.", + "apihelp-abusefilterchecksyntax-example-1": "Kontroli sintakson de valida filtrilo", + "apihelp-abusefilterchecksyntax-example-2": "Kontroli sintakson de ne valida filtrilo", + "apihelp-abusefilterevalexpression-description": "Komputi AbuseFilter-esprimon.", + "apihelp-abusefilterevalexpression-summary": "Komputi AbuseFilter-esprimon.", + "apihelp-abusefilterevalexpression-param-expression": "La komputota esprimo.", + "apihelp-abusefilterevalexpression-example-1": "Komputi simplan esprimon", + "apihelp-abusefilterunblockautopromote-param-user": "Uzantnomo de la forbarota uzanto.", + "apihelp-query+abusefilters-param-prop": "Akirotajn ecojn.", + "apihelp-query+abusefilters-example-2": "Montri iujn detalojn pri filtriloj", + "apihelp-query+abuselog-param-prop": "Akirotajn ecojn.", + "apihelp-query+abuselog-example-1": "Montri lastatempajn protokolerojn", + "apihelp-query+abuselog-example-2": "Montri lastatempajn protokolerojn pri [[API]]", + "apierror-abusefilter-badsyntax": "La sintakso de la filtrilo ne estas valida." +} diff --git a/AbuseFilter/i18n/api/es.json b/AbuseFilter/i18n/api/es.json index 82539824..cd6ee107 100644 --- a/AbuseFilter/i18n/api/es.json +++ b/AbuseFilter/i18n/api/es.json @@ -1,17 +1,21 @@ { "@metadata": { "authors": [ + "Agusbou2015", "Ciencia Al Poder", "Dgstranz", "Fitoschido", + "Geryescalier", + "Ihojose", "Macofe", "MarcoAurelio", - "Ryo567" + "Ryo567", + "Whytheonlyone" ] }, "apihelp-abusefiltercheckmatch-description": "Comprueba si el filtro antiabusos coincide con un conjunto de variables, una edición o un evento del registro del editor antiabusos.\n\nSe necesita \"vars\", \"rcid\" o \"logid\", pero solo se utiliza uno.", "apihelp-abusefiltercheckmatch-summary": "Comprobar si un filtro antiabusos coincide con un conjunto de variables, una edición o un suceso registrado del filtro antiabusos.", - "apihelp-abusefiltercheckmatch-extended-description": "Se requieren vars, rcid o logid, pero sólo uno puede ser usado.", + "apihelp-abusefiltercheckmatch-extended-description": "Se requieren vars, rcid o logid, pero solo uno puede ser usado.", "apihelp-abusefiltercheckmatch-param-filter": "El texto completo que se comprobará en busca de coincidencias.", "apihelp-abusefiltercheckmatch-param-vars": "Matriz JSON codificada de variables para realizar la prueba.", "apihelp-abusefiltercheckmatch-param-rcid": "Identificador del cambio reciente contra el cual verificar.", @@ -25,7 +29,9 @@ "apihelp-abusefilterevalexpression-description": "Evalúa una expresión del filtro antiabusos.", "apihelp-abusefilterevalexpression-summary": "Evalúa una expresión del filtro antiabusos.", "apihelp-abusefilterevalexpression-param-expression": "La expresión que se evaluará.", + "apihelp-abusefilterevalexpression-param-prettyprint": "Si el resultado tendría que ser imprimió.", "apihelp-abusefilterevalexpression-example-1": "Evaluar una expresión simple", + "apihelp-abusefilterevalexpression-example-2": "Evaluar una expresión simple, formateando el resultado.", "apihelp-abusefilterunblockautopromote-description": "Desbloquea un usuario de recibir autopromociones como consecuencia del filtro antiabusos.", "apihelp-abusefilterunblockautopromote-summary": "Desbloquea a un usuario para que pueda recibir permisos de usuario otorgados automáticamente por el sistema, anteriormente impedido como consecuencia de un disparo del filtro antiabusos.", "apihelp-abusefilterunblockautopromote-param-user": "El nombre del usuario que se desbloqueará.", @@ -34,26 +40,32 @@ "apihelp-query+abusefilters-summary": "Mostrar los detalles de los filtros antiabusos.", "apihelp-query+abusefilters-param-startid": "El identificador de filtro para comenzar la enumeración.", "apihelp-query+abusefilters-param-endid": "El identificador de filtro para detener la enumeración.", - "apihelp-query+abusefilters-param-show": "Sólo mostrar los filtros que cumplan con estos criterios.", - "apihelp-query+abusefilters-param-limit": "El número máximo de filtros a listar.", + "apihelp-query+abusefilters-param-show": "Solo mostrar los filtros que cumplan con estos criterios.", + "apihelp-query+abusefilters-param-limit": "El número máximo de filtros que se van a listar.", "apihelp-query+abusefilters-param-prop": "Qué propiedades obtener", "apihelp-query+abusefilters-example-1": "Listar los filtros públicos habilitados", "apihelp-query+abusefilters-example-2": "Mostrar algunos detalles acerca de los filtros", "apihelp-query+abuselog-description": "Mostrar eventos que fueron detectados por uno de los filtros antiabusos.", "apihelp-query+abuselog-summary": "Mostrar los eventos que fueron detectados por uno de los filtros antiabusos.", "apihelp-query+abuselog-param-logid": "Muestra una entrada a partir del ID de log proporcionado.", - "apihelp-query+abuselog-param-start": "El sello de tiempo para comenzar la enumeración", - "apihelp-query+abuselog-param-end": "El sello de tiempo para detener la enumeración.", + "apihelp-query+abuselog-param-start": "El cronomarcador para comenzar la enumeración.", + "apihelp-query+abuselog-param-end": "El cronomarcador para detener la enumeración.", "apihelp-query+abuselog-param-user": "Mostrar solo entradas correspondientes a un usuario o IP determinado.", "apihelp-query+abuselog-param-title": "Mostrar solo entradas correspondientes a una página determinada.", - "apihelp-query+abuselog-param-filter": "Mostrar solo entradas capturadas por un identificador de filtro determinado.", + "apihelp-query+abuselog-param-filter": "Mostrar solo las entradas que fueron capturadas por los ID de filtro de datos. Separar con pipes, el prefijo con \"$1\" para filtros globales.", "apihelp-query+abuselog-param-limit": "La cantidad máxima de entradas que aparecerán.", "apihelp-query+abuselog-param-prop": "Qué propiedades se obtendrán.", "apihelp-query+abuselog-param-wiki": "Wiki del cual mostrar las detecciones.", "apihelp-query+abuselog-example-1": "Mostrar entradas recientes del registro", "apihelp-query+abuselog-example-2": "Mostrar entradas recientes del registro para [[API]]", + "apihelp-abuselogprivatedetails-description": "Ver detalles privados de una entrada de AbuseLog (registro de abuso).", + "apihelp-abuselogprivatedetails-summary": "Ver detalles privados de una entrada de AbuseLog (registro de abuso).", + "apihelp-abuselogprivatedetails-param-logid": "ID de la entrada de AbuseLog por verificar.", + "apihelp-abuselogprivatedetails-param-reason": "Razón para realizar la verificación.", + "apihelp-abuselogprivatedetails-example-1": "Obtener los detalles privados para la entrada de AbuseLog con el ID 1, usando el razón \"ejemplo\".", "apierror-abusefilter-canttest": "No tienes permiso para probar filtros antiabusos.", "apierror-abusefilter-cantcheck": "No tienes permiso para comprobar la sintaxis de los filtros antiabusos.", + "apierror-abusefilter-canteval": "No tienes permiso para evaluar las expresiones del filtro antiabusos.", "apierror-abusefilter-nosuchlogid": "No existe ninguna entrada en el registro de abusos con la ID $1.", "apierror-abusefilter-badsyntax": "El filtro contiene sintaxis no válida." } diff --git a/AbuseFilter/i18n/api/eu.json b/AbuseFilter/i18n/api/eu.json new file mode 100644 index 00000000..26acc8f9 --- /dev/null +++ b/AbuseFilter/i18n/api/eu.json @@ -0,0 +1,40 @@ +{ + "@metadata": { + "authors": [ + "Joseba", + "Manex" + ] + }, + "apihelp-abusefiltercheckmatch-param-filter": "Iragazki osoko testua kointzidentzia bat egiaztatzeko.", + "apihelp-abusefiltercheckmatch-param-vars": "JSON aldagaien array kodetua probatzeko.", + "apihelp-abusefiltercheckmatch-param-rcid": "Duela gutxiko aldaketaren IDa konprobatzeko.", + "apihelp-abusefiltercheckmatch-param-logid": "Abusu-Iragazkiaren erregistroaren IDa konprobatzeko.", + "apihelp-abusefiltercheckmatch-example-1": "Probatu duela gutxiko ID 15 aldaketa iragazki sinple batekin bat datorren", + "apihelp-abusefilterchecksyntax-description": "Abusu-Iragazki baten sintaxia konprobatu.", + "apihelp-abusefilterchecksyntax-summary": "Abusu-iragazki baten sintaxia konprobatu.", + "apihelp-abusefilterchecksyntax-param-filter": "Sintaxia egiaztatzeko iragazki osoko testua.", + "apihelp-abusefilterchecksyntax-example-1": "Berrikusi iragazki baliogarri baten sintaxia", + "apihelp-abusefilterchecksyntax-example-2": "Berrikusi iragazki baliogabe baten sintaxia", + "apihelp-abusefilterevalexpression-description": "Abusu-Iragazki baten espresioa ebaluatzen du.", + "apihelp-abusefilterevalexpression-param-expression": "Ebaluatzeko espresioa.", + "apihelp-abusefilterevalexpression-example-1": "Ebaluatu espresio arrunt bat", + "apihelp-abusefilterunblockautopromote-param-user": "Desgaitu nahi duzun erabiltzailearen erabiltzaile-izena.", + "apihelp-query+abusefilters-description": "Abusu-Iragazkien xehetasunak erakutsi.", + "apihelp-query+abusefilters-param-show": "Soilik kriterio hau betetzen duten iragazkiak erakutsi.", + "apihelp-query+abusefilters-param-limit": "Gehienez zerrendatzeko iragazkien kopurua.", + "apihelp-query+abusefilters-param-prop": "Zein propietate lortu.", + "apihelp-query+abusefilters-example-1": "Iragazki publiko baimenduak zerrendatu", + "apihelp-query+abusefilters-example-2": "erakutsi iragazkien zehaztasunak", + "apihelp-query+abuselog-description": "Abusu-Iragazki batek atzemandako ebentuak erakutsi.", + "apihelp-query+abuselog-param-logid": "Emandako erregistroaren IDrako sarrera bat erakutsi.", + "apihelp-query+abuselog-param-title": "Soilik emandako orrialde batean dauden sarrerak erakutsi.", + "apihelp-query+abuselog-example-1": "Azken momentuko sarrera-erregistroak erakutsi", + "apihelp-query+abuselog-example-2": "Azken momentuko sarrera-erregistroak erakutsi [[API]]rako", + "apihelp-abuselogprivatedetails-description": "Ikusi abusu erregistro baten sarrerako xehetasun pribatuak.", + "apihelp-abuselogprivatedetails-param-reason": "Egiaztapena egiteko baliozko arrazoi bat", + "apierror-abusefilter-canttest": "Abusu-iragazkiak probatzeko baimenik ez daukazu.", + "apierror-abusefilter-cantcheck": "Abusu-iragazkien sintaxia egiaztatzeko baimenik ez daukazu.", + "apierror-abusefilter-canteval": "Abusu-iragazkien espresioak ebaluatzeko baimenik ez daukazu.", + "apierror-abusefilter-nosuchlogid": "Ez dago abusu erregistroaren sarrerarik $1 id -arekin.", + "apierror-abusefilter-badsyntax": "Iragazki honek baliozkoa ez den sintaxia dauka." +} diff --git a/AbuseFilter/i18n/api/fa.json b/AbuseFilter/i18n/api/fa.json index f24ceaa7..d7cee824 100644 --- a/AbuseFilter/i18n/api/fa.json +++ b/AbuseFilter/i18n/api/fa.json @@ -1,14 +1,16 @@ { "@metadata": { "authors": [ + "Ahmad252", "Alirezaaa", + "FarsiNevis", "Huji", "Ladsgroup", "Reza1615" ] }, - "apihelp-abusefiltercheckmatch-description": "بررسی کنید تا ببینید اگر پالایهٔ خرابکاری با مجموعهای از متغییرها، یک ویرایش، یا یک رویداد سیاههٔ پالایهٔ خرابکاری کاربر مطابق است.\n\n متغییر، شناسهٔ تغییرات اخیر یا شناسهٔ ورود مورد نیاز است، اما فقط یکی از این سه میتواند استفاده شود.", - "apihelp-abusefiltercheckmatch-summary": "بررسی کنید اگر یک پالایهٔ خرابکاری با مجموعهای از متغیرها مطابقت داشت، editor logged AbuseFilter event.", + "apihelp-abusefiltercheckmatch-description": "بررسی کنید تا ببینید پالایهٔ خرابکاری با مجموعهای از متغیرها، یک ویرایش، یا یک رویداد سیاههٔ پالایهٔ خرابکاری کاربر مطابق است یا خیر.\n\nمتغیر، شناسهٔ تغییرات اخیر یا شناسهٔ ورود مورد نیاز است، اما فقط یکی از این سه میتواند استفاده شود.", + "apihelp-abusefiltercheckmatch-summary": "بررسی کنید تا ببینید پالایهٔ خرابکاری با مجموعهای از متغیرها، یک ویرایش، یا یک رویداد سیاههٔ پالایهٔ ویرایش کاربر مطابق است یا خیر.", "apihelp-abusefiltercheckmatch-extended-description": "vars، rcid، یا logid لازم است هرچند یکی از آنها استفاده میشود.", "apihelp-abusefiltercheckmatch-param-filter": "متن کامل پالایه برای بررسی یک مورد مطابقتیافته.", "apihelp-abusefiltercheckmatch-param-vars": "آرایه رمزگذاری شدهٔ به صورت جیسان از متغیرها برای آزمایش کردن.", @@ -50,6 +52,7 @@ "apihelp-query+abuselog-param-wiki": "ویکی برای نمایش تأثیر گرفته از آن", "apihelp-query+abuselog-example-1": "نمایش سیاههٔ آخرین ورودیها", "apihelp-query+abuselog-example-2": "نمایش آخرین موارد سیاهه از [[API]]", + "apihelp-abuselogprivatedetails-param-reason": "دلیلی معتبر برای اجرای این وارسی.", "apierror-abusefilter-canttest": "شما اجازهٔ آزمایش پالایههای خرابکاری را ندارید.", "apierror-abusefilter-cantcheck": "شما اجازهٔ آزمایش نحوی پالایههای خرابکاری را ندارید.", "apierror-abusefilter-nosuchlogid": "هیچ موردی در سیاههٔ خرابکاری با شناسهٔ $1 وجود ندارد.", diff --git a/AbuseFilter/i18n/api/fi.json b/AbuseFilter/i18n/api/fi.json index f15a42b8..43f6c5a3 100644 --- a/AbuseFilter/i18n/api/fi.json +++ b/AbuseFilter/i18n/api/fi.json @@ -7,6 +7,7 @@ ] }, "apihelp-abusefilterchecksyntax-description": "Tarkista väärinkäyttösuodattimen syntaksi.", + "apihelp-abusefilterchecksyntax-summary": "Tarkista väärinkäyttösuodattimen syntaksi.", "apihelp-abusefilterchecksyntax-example-1": "Tarkasta kelvollisen suodattimen ehtolauserakenne", "apihelp-abusefilterchecksyntax-example-2": "Tarkasta epäkelvon suodattimen ehtolauserakenne", "apihelp-abusefilterevalexpression-description": "Arvioi väärinkäyttösuodattimen lauseketta.", diff --git a/AbuseFilter/i18n/api/fr.json b/AbuseFilter/i18n/api/fr.json index 60eaf001..6b3cc287 100644 --- a/AbuseFilter/i18n/api/fr.json +++ b/AbuseFilter/i18n/api/fr.json @@ -1,15 +1,18 @@ { "@metadata": { "authors": [ + "Florian COLLIN", "Gomoko", + "Manu1400", "Orlodrim", + "Thibaut120094", "Urhixidur", "Wladek92" ] }, "apihelp-abusefiltercheckmatch-description": "Cocher pour voir si un AbuseFilter correspond à un ensemble de variables, une modification, ou un événement AbuseFilter du journal.\n\nvars, rcid ou logid est obligatoire, mais un seul d’entre-eux doit être utilisé.", "apihelp-abusefiltercheckmatch-summary": "Vérifier pour voir si un AbuseFilter correspond à un ensemble de variables, une modification, ou un événement AbuseFilter du journal.", - "apihelp-abusefiltercheckmatch-extended-description": "vars, rcid ou logid est nécessaire bien qu'un seul puisse être utilisé.", + "apihelp-abusefiltercheckmatch-extended-description": "vars, rcid ou logid est nécessaire bien qu’un seul puisse être utilisé.", "apihelp-abusefiltercheckmatch-param-filter": "Le texte complet du filtre pour vérifier une correspondance.", "apihelp-abusefiltercheckmatch-param-vars": "Tableau JSON encodé de variables à tester.", "apihelp-abusefiltercheckmatch-param-rcid": "ID de la modification récente sur laquelle tester le filtre.", @@ -19,39 +22,48 @@ "apihelp-abusefilterchecksyntax-summary": "Vérifier la syntaxe d’un filtre anti-abus.", "apihelp-abusefilterchecksyntax-param-filter": "Le texte complet du filtre dont la syntaxe doit être vérifiée.", "apihelp-abusefilterchecksyntax-example-1": "Vérifier la syntaxe d’un filtre valide", - "apihelp-abusefilterchecksyntax-example-2": "Vérifier la syntaxe d’un filtre invalide", - "apihelp-abusefilterevalexpression-description": "Évalue une expression du filtre antiabus.", - "apihelp-abusefilterevalexpression-summary": "Evalue l'expression d'un filtre anti-abus.", + "apihelp-abusefilterchecksyntax-example-2": "Vérifier la syntaxe d’un filtre non valide", + "apihelp-abusefilterevalexpression-description": "Évalue une expression du filtre anti-abus.", + "apihelp-abusefilterevalexpression-summary": "Évalue une expression de filtre anti-abus.", "apihelp-abusefilterevalexpression-param-expression": "L’expression à évaluer.", + "apihelp-abusefilterevalexpression-param-prettyprint": "Si le résultat doit être joliment affiché.", "apihelp-abusefilterevalexpression-example-1": "Évaluer une expression simple", + "apihelp-abusefilterevalexpression-example-2": "Évaluer une expression simple, avec mise en forme du résultat", "apihelp-abusefilterunblockautopromote-description": "Annule le blocage par un filtre antiabus des promotions automatiques de statut d’un utilisateur.", - "apihelp-abusefilterunblockautopromote-summary": "Empêche un utilisateur de recevoir des auto-promotions résultant d'un filtre anti-abus.", + "apihelp-abusefilterunblockautopromote-summary": "Annule le blocage par un filtre anti-abus des promotions automatiques de statut d’un utilisateur.", "apihelp-abusefilterunblockautopromote-param-user": "Nom de l’utilisateur à débloquer.", "apihelp-abusefilterunblockautopromote-example-1": "Supprime le blocage des promotions automatiques de statut pour [[User:Example]]", - "apihelp-query+abusefilters-description": "Afficher les détails des filtres antiabus.", + "apihelp-query+abusefilters-description": "Afficher les détails des filtres anti-abus.", "apihelp-query+abusefilters-summary": "Afficher les détails des filtres anti-abus.", - "apihelp-query+abusefilters-param-startid": "Numéro de filtre auquel commencer l’énumération.", + "apihelp-query+abusefilters-param-startid": "Numéro de filtre à partir duquel commencer l’énumération.", "apihelp-query+abusefilters-param-endid": "Numéro de filtre auquel terminer l’énumération.", "apihelp-query+abusefilters-param-show": "Afficher seulement les filtres correspondant à ces critères.", "apihelp-query+abusefilters-param-limit": "Le nombre maximum de filtres à renvoyer.", "apihelp-query+abusefilters-param-prop": "Quelles propriétés obtenir.", "apihelp-query+abusefilters-example-1": "Afficher les filtres publics activés.", - "apihelp-query+abusefilters-example-2": "Afficher certains détails sur les filtres.", + "apihelp-query+abusefilters-example-2": "Afficher quelques détails sur les filtres.", "apihelp-query+abuselog-description": "Afficher les événements détectés par l’un des filtres antiabus.", - "apihelp-query+abuselog-summary": "Affiche les événements capturés par un des filtres anti-abus.", + "apihelp-query+abuselog-summary": "Affiche les événements détectés par un des filtres anti-abus.", "apihelp-query+abuselog-param-logid": "Afficher une entrée avec l’ID de journal fourni.", "apihelp-query+abuselog-param-start": "L’horodatage auquel commencer l’énumération.", "apihelp-query+abuselog-param-end": "L’horodatage auquel terminer l’énumération.", "apihelp-query+abuselog-param-user": "Afficher uniquement les entrées faites par un utilisateur ou une adresse IP donné.", "apihelp-query+abuselog-param-title": "Afficher uniquement les entrées se produisant sur une page donnée.", - "apihelp-query+abuselog-param-filter": "Afficher uniquement les entrées capturées par un ID de filtre donné.", - "apihelp-query+abuselog-param-limit": "Le nombre maximal d’entrées à liter.", + "apihelp-query+abuselog-param-filter": "Afficher uniquement les entrées capturées par un des ID de filtre donnés. Séparés avec des barres verticales, préfixés par « $1 » pour les filtres globaux.", + "apihelp-query+abuselog-param-filter-central": "Afficher uniquement les entrées qui ont été capturées par les ID de filtre donnés. Séparez avec des tuyaux.", + "apihelp-query+abuselog-param-limit": "Le nombre maximal d’entrées à lister.", "apihelp-query+abuselog-param-prop": "Quelles propriétés obtenir.", - "apihelp-query+abuselog-param-wiki": "Wiki depuis lequel afficher les visites", + "apihelp-query+abuselog-param-wiki": "Wiki duquel afficher les visites.", "apihelp-query+abuselog-example-1": "Afficher les entrées récentes du journal", "apihelp-query+abuselog-example-2": "Afficher les entrées récentes du journal pour [[API]]", - "apierror-abusefilter-canttest": "Vous n'avez pas la permission de tester les filtres antiabus.", + "apihelp-abuselogprivatedetails-description": "Afficher les détails privés d’une entrée de AbuseLog.", + "apihelp-abuselogprivatedetails-summary": "Afficher les détails privés d’une entrée de AbuseLog.", + "apihelp-abuselogprivatedetails-param-logid": "ID de l’entrée dans AbuseLog à vérifier.", + "apihelp-abuselogprivatedetails-param-reason": "Une raison valide pour faire le contrôle.", + "apihelp-abuselogprivatedetails-example-1": "Obtenir les détails privés de AbuseLog, correspondants à l’entrée dont l’ID vaut 1 , et en utilisant la raison « example ».", + "apierror-abusefilter-canttest": "Vous n’avez pas la permission de tester les filtres antiabus.", "apierror-abusefilter-cantcheck": "Vous n’avez pas la permission de vérifier la syntaxe des filtres antiabus.", - "apierror-abusefilter-nosuchlogid": "Il n'y a pas d'entrée dans le journal des abus avec l'identifiant $1.", + "apierror-abusefilter-canteval": "Vous n’avez pas le droit d’évaluer les expressions AbuseFilter.", + "apierror-abusefilter-nosuchlogid": "Il n’y a pas d’entrée dans le journal des abus avec l’identifiant $1.", "apierror-abusefilter-badsyntax": "Le filtre a une syntaxe non valide." } diff --git a/AbuseFilter/i18n/api/gl.json b/AbuseFilter/i18n/api/gl.json index 2e603383..5e70af87 100644 --- a/AbuseFilter/i18n/api/gl.json +++ b/AbuseFilter/i18n/api/gl.json @@ -2,8 +2,9 @@ "@metadata": { "authors": [ "Banjo", + "Breogan2008", "Elisardojm", - "Navhy" + "Iváns" ] }, "apihelp-abusefiltercheckmatch-description": "Revise se un AbuseFilter concorda cun conxunto de variables, evento de rexistro de editor AbuseFilter.\n\nvars, rcid ou logid se necesita aínda que só un pode ser usado.", @@ -38,15 +39,22 @@ "apihelp-query+abusefilters-example-2": "Amosar algúns detalles sobre os filtros", "apihelp-query+abuselog-description": "Amosar eventos que foron detectados por un dos filtros antiabusos.", "apihelp-query+abuselog-summary": "Amosar eventos que foron detectados por un dos filtros antiabusos.", + "apihelp-query+abuselog-param-logid": "Amosar unha entrada co identificador de rexistro fornecido.", "apihelp-query+abuselog-param-start": "Selo de tempo para comezar a enumeración", "apihelp-query+abuselog-param-end": "Selo de tempo para rematar a enumeración.", "apihelp-query+abuselog-param-user": "Só amosar entradas feitas por un usuario ou dirección IP dados.", "apihelp-query+abuselog-param-title": "Só amosar entradas ocorridas nunha páxina dada.", - "apihelp-query+abuselog-param-filter": "Só amosar as entradas que foron capturadas por un ID de filtro indicado.", + "apihelp-query+abuselog-param-filter": "Amosar só as entradas que foron detectadas polos identificadores de filtros fornecidos. Separar com barra vertical (|), prefixar com \"$1\" para filtros globais.", "apihelp-query+abuselog-param-limit": "Máximo número de entradas a listar.", "apihelp-query+abuselog-param-prop": "Que propiedades obter.", + "apihelp-query+abuselog-param-wiki": "A wiki da cal amosa as visitas.", "apihelp-query+abuselog-example-1": "Amosar entradas recentes do rexistro", "apihelp-query+abuselog-example-2": "Amosar entradas recentes do rexistro para [[API]]", + "apihelp-abuselogprivatedetails-description": "Ver detalles privados dunha entrada do rexistro de abusos.", + "apihelp-abuselogprivatedetails-summary": "Ver detalles privados dunha entrada do rexistro de abusos.", + "apihelp-abuselogprivatedetails-param-logid": "O identificador da entrada do rexistro de abusos a ser verificada.", + "apihelp-abuselogprivatedetails-param-reason": "Un motivo válido para executar a verificación.", + "apihelp-abuselogprivatedetails-example-1": "Obter detalles privados da entrada do rexisto de abusos co identificador 1, empregando o motivo \"example\".", "apierror-abusefilter-canttest": "Non tes permiso para probar filtros de abusos.", "apierror-abusefilter-cantcheck": "Non tes permiso para comprobar a sintaxe de filtros de abusos.", "apierror-abusefilter-nosuchlogid": "Non existe ningunha entrada no rexistro de abusos co ID $1.", diff --git a/AbuseFilter/i18n/api/he.json b/AbuseFilter/i18n/api/he.json index d67d865d..14bd3eba 100644 --- a/AbuseFilter/i18n/api/he.json +++ b/AbuseFilter/i18n/api/he.json @@ -20,10 +20,12 @@ "apihelp-abusefilterchecksyntax-param-filter": "הטקסט המלא של המסנן לבדיקת תחביר עבורו.", "apihelp-abusefilterchecksyntax-example-1": "בדיקת תחביר למסנן תקין", "apihelp-abusefilterchecksyntax-example-2": "בדיקת תחביר למסנן לא תקין", - "apihelp-abusefilterevalexpression-description": "הערכת ביטוח מסנן השחתות.", + "apihelp-abusefilterevalexpression-description": "הערכת ביטוי מסנן השחתות.", "apihelp-abusefilterevalexpression-summary": "הערכת ביטוי מסנן השחתות.", - "apihelp-abusefilterevalexpression-param-expression": "איזה ביטוח להעריך.", + "apihelp-abusefilterevalexpression-param-expression": "איזה ביטוי להעריך.", + "apihelp-abusefilterevalexpression-param-prettyprint": "האם התוצאה צריכה להיות מודפסת יפה.", "apihelp-abusefilterevalexpression-example-1": "הערכת ביטוי פשוט", + "apihelp-abusefilterevalexpression-example-2": "הערכת ביטוח פשוט, עם תוצאה מעוצבת", "apihelp-abusefilterunblockautopromote-description": "ביטול מניעה ממשתמש לקבל קידום אוטומטי בעקבות תוצאה של פעולת מסנן השחתות.", "apihelp-abusefilterunblockautopromote-summary": "מסיר ממשתמש את החסימה מפני קבלת קידום אוטומטי כתוצאה מפעולת מסנן השחתות.", "apihelp-abusefilterunblockautopromote-param-user": "שם של משתמש שברצונך ליטול ממנו את המניעה.", @@ -42,16 +44,23 @@ "apihelp-query+abuselog-param-logid": "הצגת ערך עם מזהה היומן שצוין.", "apihelp-query+abuselog-param-start": "חותם־הזמן שהמנייה תתחיל ממנו.", "apihelp-query+abuselog-param-end": "חותם־הזמן שבו תסתיים המנייה.", - "apihelp-query+abuselog-param-user": "להציג רק עיולים שנעשו על־ידי משתמש נתון או כתובת IP.", - "apihelp-query+abuselog-param-title": "להציג רק עיולים שאירעו בדך נתון.", - "apihelp-query+abuselog-param-filter": "להציג רק עיולים שנתפסו במסנן עם מזהה מסנן נתון.", - "apihelp-query+abuselog-param-limit": "מספר מרבי של עיולים שיהיו ברשימה.", + "apihelp-query+abuselog-param-user": "להציג רק רשומות שנעשו על־ידי משתמש נתון או כתובת IP.", + "apihelp-query+abuselog-param-title": "להציג רק רשומות שאירעו בדף נתון.", + "apihelp-query+abuselog-param-filter": "להציג רק רשומות שנתפסו במסנן עם מזהי המסננים הנתונים. להפריד בתווי מקל, להוסיף תחילית \"$1\" עבור מסננים גלובליים.", + "apihelp-query+abuselog-param-filter-central": "להציג רק רשומות שנתפסו על־ידי מסנן עם המזהה הנתון. להפריד עם תווי מקל.", + "apihelp-query+abuselog-param-limit": "מספר מרבי של רשומות ברשימה.", "apihelp-query+abuselog-param-prop": "אילו מאפיינים לקבל.", "apihelp-query+abuselog-param-wiki": "אתר הוויקי שממנו יוצגו תוצאות.", - "apihelp-query+abuselog-example-1": "להציג עיולי יומן אחרונים", - "apihelp-query+abuselog-example-2": "הצגת עיולי יומן אחרונים עבור [[API]]", + "apihelp-query+abuselog-example-1": "להציג רשומות יומן אחרונות", + "apihelp-query+abuselog-example-2": "הצגת רשומות יומן אחרונות עבור [[API]]", + "apihelp-abuselogprivatedetails-description": "צפייה במידע פרטי של רשומת יומן השחתה.", + "apihelp-abuselogprivatedetails-summary": "צפייה במידע פרטי של רשומת יומן השחתה.", + "apihelp-abuselogprivatedetails-param-logid": "המזהה של רשומת יומן השחתה שצריך לבדוק.", + "apihelp-abuselogprivatedetails-param-reason": "סיבה תקינה לביצוע הבדיקה.", + "apihelp-abuselogprivatedetails-example-1": "קבלת מידע פרטי על רשומת יומן מסנן השחתות בעלת המזהה 1, עם הסיבה \"example\".", "apierror-abusefilter-canttest": "אין לך הרשאה לבחון מסנני השחתות.", "apierror-abusefilter-cantcheck": "אין לך הרשאה לבדוק את התחביר של מסנני השחתות.", + "apierror-abusefilter-canteval": "אין לך הרשאה להעריך ביטויי מסנן השחתות.", "apierror-abusefilter-nosuchlogid": "אין רשומה ביומן ההשחתות עם המזהה $1.", - "apierror-abusefilter-badsyntax": "המסנן מכיל תחביר בלתי תקין." + "apierror-abusefilter-badsyntax": "המסנן מכיל תחביר בלתי־תקין." } diff --git a/AbuseFilter/i18n/api/hu.json b/AbuseFilter/i18n/api/hu.json index 629d6822..73e8d23d 100644 --- a/AbuseFilter/i18n/api/hu.json +++ b/AbuseFilter/i18n/api/hu.json @@ -1,11 +1,23 @@ { "@metadata": { "authors": [ + "Bencemac", "Dj", "Wolf Rex" ] }, "apihelp-abusefiltercheckmatch-description": "vars, rcid vagy logid szükséges, de csak egyet lehet használni.", + "apihelp-abusefilterchecksyntax-description": "Egy Vandálszűrő szintaxisának ellenőrzése.", + "apihelp-abusefilterchecksyntax-summary": "Egy Vandálszűrő szintaxisának ellenőrzése.", + "apihelp-abusefilterchecksyntax-example-1": "Egy érvényes szűrő szintaxisának ellenőrzése", + "apihelp-abusefilterchecksyntax-example-2": "Egy érvénytelen szűrő szintaxisának ellenőrzése", + "apihelp-abusefilterunblockautopromote-param-user": "A szerkesztő felhasználóneve, akinek blokkját fel akarod oldani.", + "apihelp-query+abusefilters-description": "Vandálszűrők részleteinek megjelenítése.", + "apihelp-query+abusefilters-summary": "Vandálszűrők részleteinek megjelenítése.", "apihelp-query+abusefilters-example-1": "Az engedélyezett nyilvános szűrők listázása.", - "apihelp-query+abuselog-example-1": "Friss naplóbejegyzések mutatása" + "apihelp-query+abuselog-example-1": "Friss naplóbejegyzések mutatása", + "apierror-abusefilter-canttest": "Nincs jogosultságod Vandálszűrők teszteléshez.", + "apierror-abusefilter-cantcheck": "Nincs jogosultságod a vandálszűrők szintaxisának ellenőrzéséhez.", + "apierror-abusefilter-nosuchlogid": "Nincsen $1. számú bejegyzés a Vandálszűrő-naplóban.", + "apierror-abusefilter-badsyntax": "A szűrő szintaktikailag hibás." } diff --git a/AbuseFilter/i18n/api/ia.json b/AbuseFilter/i18n/api/ia.json index f5453220..7ddf061e 100644 --- a/AbuseFilter/i18n/api/ia.json +++ b/AbuseFilter/i18n/api/ia.json @@ -36,17 +36,25 @@ "apihelp-query+abusefilters-example-2": "Monstrar alcun detalios sur filtros", "apihelp-query+abuselog-description": "Monstrar eventos detegite per un del filtros anti-abuso", "apihelp-query+abuselog-summary": "Monstrar eventos detegite per un del filtros anti-abuso.", + "apihelp-query+abuselog-param-logid": "Monstrar un entrata con le ID de registro specificate.", "apihelp-query+abuselog-param-start": "Le data e hora al qual comenciar a enumerar.", "apihelp-query+abuselog-param-end": "Le data e hora al qual cessar de enumerar.", "apihelp-query+abuselog-param-user": "Monstrar solmente entratas facite per un usator o adresse IP date.", "apihelp-query+abuselog-param-title": "Monstrar solmente entratas que occurre in un pagina date.", - "apihelp-query+abuselog-param-filter": "Monstrar solmente entratas detegite per un ID de filtro date.", + "apihelp-query+abuselog-param-filter": "Monstrar solmente entratas detegite per le filtros con le IDs specificate. Separar con barras vertical. Prefixar \"$1\" pro monstrar filtros global.", "apihelp-query+abuselog-param-limit": "Le numero maxime de entratas a listar.", "apihelp-query+abuselog-param-prop": "Qual proprietates obtener.", + "apihelp-query+abuselog-param-wiki": "Wiki ab le qual monstrar accessos.", "apihelp-query+abuselog-example-1": "Monstrar entratas recente de registro", "apihelp-query+abuselog-example-2": "Monstrar entratas recente de registro pro [[API]]", + "apihelp-abuselogprivatedetails-description": "Vider le detalios private de un entrata del registro de abusos.", + "apihelp-abuselogprivatedetails-summary": "Vider le detalios private de un entrata del registro de abusos.", + "apihelp-abuselogprivatedetails-param-logid": "Le ID del entrata del registro de abusos a verificar.", + "apihelp-abuselogprivatedetails-param-reason": "Un motivo valide pro exequer le consulta.", + "apihelp-abuselogprivatedetails-example-1": "Obtener le detalios private del entrata del registro de abusos con ID 1, usante le motivo \"exemplo\".", "apierror-abusefilter-canttest": "Tu non ha le permission de testar le filtros anti-abuso.", "apierror-abusefilter-cantcheck": "Tu non ha le permission de verificar le syntaxe de filtros anti-abuso.", + "apierror-abusefilter-canteval": "Tu non ha le permission de evalutar le expressiones del filtro anti-abuso.", "apierror-abusefilter-nosuchlogid": "Il non ha un entrata con ID $1 in le registro de abusos.", "apierror-abusefilter-badsyntax": "Le filtro ha un syntaxe invalide." } diff --git a/AbuseFilter/i18n/api/id.json b/AbuseFilter/i18n/api/id.json new file mode 100644 index 00000000..8a6953c4 --- /dev/null +++ b/AbuseFilter/i18n/api/id.json @@ -0,0 +1,14 @@ +{ + "@metadata": { + "authors": [ + "Hidayatsrf" + ] + }, + "apihelp-abusefilterunblockautopromote-param-user": "Nama pengguna dari pengguna yang ingin Anda buka pemblokirannya", + "apihelp-query+abusefilters-description": "Tampilkan detail filter penyalahgunaan.", + "apihelp-query+abusefilters-summary": "Tampilkan detail filter penyalahgunaan.", + "apihelp-query+abuselog-example-1": "Tampilkan entri log terkini", + "apierror-abusefilter-canttest": "Anda tidak memiliki izin untuk menguji filter penyalahgunaan", + "apierror-abusefilter-cantcheck": "Anda tidak memiliki izin untuk memeriksa sintaksis filter penyalahgunaan", + "apierror-abusefilter-badsyntax": "Filter berisi sintaksis yang tidak sah" +} diff --git a/AbuseFilter/i18n/api/it.json b/AbuseFilter/i18n/api/it.json index 4b3269f8..8271000b 100644 --- a/AbuseFilter/i18n/api/it.json +++ b/AbuseFilter/i18n/api/it.json @@ -1,6 +1,7 @@ { "@metadata": { "authors": [ + "Albe Albe460", "Beta16", "Chiara.Graziani1991", "Daimona Eaytoy", @@ -15,17 +16,53 @@ "apihelp-abusefiltercheckmatch-param-filter": "Il testo completo del filtro da utilizzare per trovare una corrispondenza.", "apihelp-abusefiltercheckmatch-param-vars": "Array in formato JSON di variabili da utilizzare per il test.", "apihelp-abusefiltercheckmatch-param-rcid": "ID della modifica recente da controllare.", + "apihelp-abusefiltercheckmatch-param-logid": "ID del registro del filtro anti abusi da verificare.", + "apihelp-abusefiltercheckmatch-example-1": "Verifica se la modifica con ID UltimeModifiche 15 fa attivare un semplice filtro", + "apihelp-abusefilterchecksyntax-description": "Verifica la sintassi di un filtro anti abusi.", + "apihelp-abusefilterchecksyntax-summary": "Verifica la sintassi di un filtro anti abusi.", + "apihelp-abusefilterchecksyntax-param-filter": "Il testo completo del filtro di cui controllare la sintassi.", "apihelp-abusefilterchecksyntax-example-1": "Controlla la sintassi di un filtro valido", "apihelp-abusefilterchecksyntax-example-2": "Controlla la sintassi di un filtro non valido", "apihelp-abusefilterevalexpression-description": "Valuta un'espressione AbuseFilter.", + "apihelp-abusefilterevalexpression-summary": "Valuta un'espressione del filtro anti abusi.", "apihelp-abusefilterevalexpression-param-expression": "L'espressione da valutare.", - "apihelp-abusefilterevalexpression-example-1": "Calcolare una semplice espressione", + "apihelp-abusefilterevalexpression-param-prettyprint": "Se formattare il risultato.", + "apihelp-abusefilterevalexpression-example-1": "Valutare un'espressione semplice", + "apihelp-abusefilterevalexpression-example-2": "Valutare un'espressione semplice, formattando il risultato", + "apihelp-abusefilterunblockautopromote-description": "Sblocca la possibilità di autopromozione a seguito di un blocco imposto dal filtro anti abusi.", + "apihelp-abusefilterunblockautopromote-summary": "Sblocca la possibilità di autopromozione a seguito di un blocco imposto dal filtro anti abusi.", "apihelp-abusefilterunblockautopromote-param-user": "Nome utente dell'utente che vuoi sbloccare.", + "apihelp-abusefilterunblockautopromote-example-1": "Sblocca la possibilità di autopromozione all'utente [[User:Example]]", + "apihelp-query+abusefilters-description": "Mostra dettagli sui filtri anti abusi.", + "apihelp-query+abusefilters-summary": "Mostra dettagli sui filtri anti abusi.", + "apihelp-query+abusefilters-param-startid": "L'ID del filtro da cui iniziare l'elenco.", + "apihelp-query+abusefilters-param-endid": "L'ID del filtro al quale terminare l'elenco.", "apihelp-query+abusefilters-param-show": "Mostra solo i filtri che soddisfano questi criteri.", "apihelp-query+abusefilters-param-limit": "Il numero massimo di filtri da elencare.", "apihelp-query+abusefilters-param-prop": "Quali proprietà ottenere.", "apihelp-query+abusefilters-example-1": "Elenca i filtri pubblici abilitati", "apihelp-query+abusefilters-example-2": "Mostra alcuni dettagli sui filtri", + "apihelp-query+abuselog-description": "Mostra eventi che hanno attivate un filtro anti abusi.", + "apihelp-query+abuselog-summary": "Mostra eventi che hanno attivate un filtro anti abusi.", + "apihelp-query+abuselog-param-logid": "Mostra la voce nel registro con l'ID specificato.", + "apihelp-query+abuselog-param-start": "Il timestamp da cui iniziare l'elenco.", + "apihelp-query+abuselog-param-end": "Il timestamp al quale interrompere l'elenco.", + "apihelp-query+abuselog-param-user": "Mostra solo le voci relative a un utente o IP indicato.", + "apihelp-query+abuselog-param-title": "Mostra solo le voci relative a una pagina indicata.", + "apihelp-query+abuselog-param-filter": "Mostra solo le voci relative ai filtri con gli ID indicati. Separare con barre verticali, utilizzando il prefisso \"$1\" per i filtri globali.", + "apihelp-query+abuselog-param-limit": "Il numero massimo di voci da elencare.", "apihelp-query+abuselog-param-prop": "Quali proprietà ottenere.", + "apihelp-query+abuselog-param-wiki": "Wiki da cui mostrare le corrispondenze.", + "apihelp-query+abuselog-example-1": "Mostra voci di registro recenti.", + "apihelp-query+abuselog-example-2": "Mostra voci di registro recenti per la pagina [[API]]", + "apihelp-abuselogprivatedetails-description": "Visualizza i dettagli privati di una voce del registro anti abusi.", + "apihelp-abuselogprivatedetails-summary": "Visualizza i dettagli privati di una voce del registro anti abusi.", + "apihelp-abuselogprivatedetails-param-logid": "L'ID della voce del registro anti abusi da controllare.", + "apihelp-abuselogprivatedetails-param-reason": "Una motivazione valida per effettuare il controllo.", + "apihelp-abuselogprivatedetails-example-1": "Ottieni i dettagli privati per la voce del registro anti abusi con ID 1, utilizzando la motivazione \"example\".", + "apierror-abusefilter-canttest": "Non disponi dei permessi necessari per provare i filtri anti abusi.", + "apierror-abusefilter-cantcheck": "Non disponi dei permessi necessari per controllare la sintassi dei filtri anti abusi.", + "apierror-abusefilter-canteval": "Non disponi dei permessi necessari per valutare espressioni del filtro anti abusi.", + "apierror-abusefilter-nosuchlogid": "Non esiste una voce nel registro anti abusi con ID $1.", "apierror-abusefilter-badsyntax": "Il filtro contiene sintassi non valida." } diff --git a/AbuseFilter/i18n/api/ja.json b/AbuseFilter/i18n/api/ja.json index 4e60f0f9..78e278a6 100644 --- a/AbuseFilter/i18n/api/ja.json +++ b/AbuseFilter/i18n/api/ja.json @@ -2,33 +2,58 @@ "@metadata": { "authors": [ "2nd-player", + "Aefgh39622", + "Kkairri", + "Omotecho", "Otokoume", + "Shirayuki", "Suyama", - "Yusuke1109" + "Yusuke1109", + "おはぐろ蜻蛉", + "そらたこ" ] }, - "apihelp-abusefilterchecksyntax-description": "不正利用フィルターの構文を確認してください。", - "apihelp-abusefilterchecksyntax-summary": "不正利用フィルターの構文を確認してください。", + "apihelp-abusefiltercheckmatch-extended-description": "vars、rcid、またはlogidが必要です。 ただし、使用できるのは1つだけです。", + "apihelp-abusefiltercheckmatch-param-filter": "一致チェックの対象となるフィルター文全文", + "apihelp-abusefiltercheckmatch-param-vars": "テストする変数のJSONエンコードされた配列。", + "apihelp-abusefiltercheckmatch-param-rcid": "確認する最近の変更ID。", + "apihelp-abusefiltercheckmatch-param-logid": "検査対象となる不正利用フィルターのログID", + "apihelp-abusefiltercheckmatch-example-1": "最近の変更ID 15が単純なフィルターに一致するかどうかをテストする", + "apihelp-abusefilterchecksyntax-description": "不正利用フィルターの構文を確認します。", + "apihelp-abusefilterchecksyntax-summary": "不正利用フィルターの構文を確認します。", + "apihelp-abusefilterchecksyntax-param-filter": "構文チェックの対象となるフィルター文全文", + "apihelp-abusefilterchecksyntax-example-1": "有効なフィルターの構文を確認", + "apihelp-abusefilterchecksyntax-example-2": "無効なフィルターの構文を確認", "apihelp-abusefilterevalexpression-description": "不正利用フィルターの式を評価します。", + "apihelp-abusefilterevalexpression-summary": "不正利用フィルターの式を評価します。", "apihelp-abusefilterevalexpression-param-expression": "評価する式。", "apihelp-abusefilterevalexpression-example-1": "簡単な式を評価します", "apihelp-abusefilterunblockautopromote-param-user": "ブロック解除する利用者の利用者名。", + "apihelp-abusefilterunblockautopromote-example-1": "[[User:Example]]に対する自動承認の不可を取り消す", "apihelp-query+abusefilters-description": "不正利用フィルターの詳細を表示する。", + "apihelp-query+abusefilters-summary": "不正利用フィルターの詳細を表示する。", "apihelp-query+abusefilters-param-startid": "列挙の始点となるフィルターID。", "apihelp-query+abusefilters-param-endid": "列挙の終点となるフィルターID。", + "apihelp-query+abusefilters-param-show": "これらの条件を満たすフィルターのみを表示します。", "apihelp-query+abusefilters-param-limit": "表示するフィルターの最大数。", "apihelp-query+abusefilters-param-prop": "取得するプロパティ。", "apihelp-query+abusefilters-example-1": "有効化されている公開フィルターを一覧表示する", "apihelp-query+abusefilters-example-2": "フィルターに関する詳細の一部を表示します", + "apihelp-query+abuselog-description": "不正利用フィルターによって検知された操作を表示します。", + "apihelp-query+abuselog-summary": "不正利用フィルターによって検知された操作を表示します。", + "apihelp-query+abuselog-param-logid": "指定されたログIDを持つエントリを表示します。", "apihelp-query+abuselog-param-start": "列挙の始点となるタイムスタンプ。", "apihelp-query+abuselog-param-end": "列挙の終点となるタイムスタンプ。", "apihelp-query+abuselog-param-user": "与えられた利用者またはIPアドレスによる項目のみを表示する。", "apihelp-query+abuselog-param-title": "与えられたページに関する項目のみを表示する。", "apihelp-query+abuselog-param-limit": "一覧表示する項目の最大量。", "apihelp-query+abuselog-param-prop": "取得するプロパティ。", + "apihelp-query+abuselog-param-wiki": "ヒットを表示するWiki。", "apihelp-query+abuselog-example-1": "最近の不正利用記録を表示する", "apihelp-query+abuselog-example-2": "[[API]] の最近の記録項目を表示する", "apierror-abusefilter-canttest": "不正利用フィルターをテストする権限がありません。", "apierror-abusefilter-cantcheck": "不正利用フィルターの構文を確認する権限がありません。", + "apierror-abusefilter-canteval": "不正利用フィルターの式を評価する権限がありません。", + "apierror-abusefilter-nosuchlogid": "ID$1にabuselog記録はありません。", "apierror-abusefilter-badsyntax": "フィルターの構文が無効です。" } diff --git a/AbuseFilter/i18n/api/ko.json b/AbuseFilter/i18n/api/ko.json index 7428e6a2..0f9f09e1 100644 --- a/AbuseFilter/i18n/api/ko.json +++ b/AbuseFilter/i18n/api/ko.json @@ -3,6 +3,7 @@ "authors": [ "Jerrykim306", "Kwj2772", + "MemphisA5", "Revi", "Ykhwong", "아라" @@ -24,6 +25,7 @@ "apihelp-abusefilterevalexpression-description": "편집 필터의 식을 검사합니다.", "apihelp-abusefilterevalexpression-summary": "편집 필터의 식을 검사합니다.", "apihelp-abusefilterevalexpression-param-expression": "검사할 표현식.", + "apihelp-abusefilterevalexpression-param-prettyprint": "결과를 예쁘게 출력해야 하는지의 여부입니다.", "apihelp-abusefilterevalexpression-example-1": "간단한 표현식 검사", "apihelp-abusefilterunblockautopromote-description": "편집 필터 동작으로 인해 자동 인증을 받지 못하도록 제한된 사용자의 제한을 해제합니다.", "apihelp-abusefilterunblockautopromote-summary": "편집 필터 동작으로 인해 자동 인증을 받지 못하도록 제한된 사용자의 제한을 해제합니다.", @@ -45,13 +47,17 @@ "apihelp-query+abuselog-param-end": "나열을 끝낼 타임스탬프.", "apihelp-query+abuselog-param-user": "주어진 사용자 또는 IP 주소에 의한 기록만을 보여줍니다.", "apihelp-query+abuselog-param-title": "주어진 문서에서 발생한 기록만을 보여줍니다.", - "apihelp-query+abuselog-param-filter": "주어진 필터 ID에서 발생한 기록만을 보여 줍니다.", + "apihelp-query+abuselog-param-filter": "주어진 필터 ID에서 발생한 기록만을 보여 줍니다. 파이프로 구분되며, 전역 필터의 접두사는 \"$1\"입니다.", "apihelp-query+abuselog-param-limit": "나열할 기록의 최대 양.", "apihelp-query+abuselog-param-prop": "가져올 속성입니다.", "apihelp-query+abuselog-example-1": "최근 기록 보기", "apihelp-query+abuselog-example-2": "[[API]]의 최근 기록 보기", + "apihelp-abuselogprivatedetails-description": "악용 기록 항목의 비공개 세부 사항을 봅니다.", + "apihelp-abuselogprivatedetails-summary": "악용 기록 항목의 비공개 세부 사항을 봅니다.", + "apihelp-abuselogprivatedetails-param-reason": "검사 수행을 위한 유효한 이유입니다.", "apierror-abusefilter-canttest": "편집 필터를 테스트할 권한이 없습니다.", "apierror-abusefilter-cantcheck": "편집 필터의 문법을 검사할 권한이 없습니다.", + "apierror-abusefilter-canteval": "편집 필터 식을 평가할 권한이 없습니다.", "apierror-abusefilter-nosuchlogid": "편집필터 기록 $1 은(는) 존재하지 않습니다.", "apierror-abusefilter-badsyntax": "필터에 유효하지 않은 문법이 있습니다." } diff --git a/AbuseFilter/i18n/api/mk.json b/AbuseFilter/i18n/api/mk.json index 89e5bfb5..1c0423d9 100644 --- a/AbuseFilter/i18n/api/mk.json +++ b/AbuseFilter/i18n/api/mk.json @@ -1,7 +1,8 @@ { "@metadata": { "authors": [ - "Bjankuloski06" + "Bjankuloski06", + "Vlad5250" ] }, "apihelp-abusefiltercheckmatch-description": "Проверете дали филтер за злоупотреби ќе најде збир променливи, уредување или заведен настан во филтерот.\n\nСе бара vars, rcid или logid (може да се употреби само едно).", @@ -13,14 +14,16 @@ "apihelp-abusefiltercheckmatch-param-logid": "Назнака на запис од дневникот на филтерот што треба да се провери.", "apihelp-abusefiltercheckmatch-example-1": "Провери дали скорешната промена со назнака 15 ќе биде пронајдена од прост филтер.", "apihelp-abusefilterchecksyntax-description": "Провери ја синтаксата на филтер за злоупотреби.", - "apihelp-abusefilterchecksyntax-summary": "Провери ја синтаксата на даден филтер за слоупотреби.", + "apihelp-abusefilterchecksyntax-summary": "Провери ја синтаксата на даден филтер за злоупотреби.", "apihelp-abusefilterchecksyntax-param-filter": "Целосниот текст чија синтакса ја проверува филтерот.", "apihelp-abusefilterchecksyntax-example-1": "Провери синтакса на важечки филтер", "apihelp-abusefilterchecksyntax-example-2": "Провери синтакса на неважечки филтер", "apihelp-abusefilterevalexpression-description": "Оценува израз во Филтерот за злоупотреби.", "apihelp-abusefilterevalexpression-summary": "Оценува израз во Филтерот за злоупотреби.", "apihelp-abusefilterevalexpression-param-expression": "Изразот што треба да се оцени.", + "apihelp-abusefilterevalexpression-param-prettyprint": "Дали исходот да има дотеран изглед.", "apihelp-abusefilterevalexpression-example-1": "Оцени прост израз", + "apihelp-abusefilterevalexpression-example-2": "Вреднување на прост израз, форматирање на исходот", "apihelp-abusefilterunblockautopromote-description": "Отстранува блок на автоунапредување на даден корисник, добиен поради последица од филтер за злоупотреби.", "apihelp-abusefilterunblockautopromote-summary": "Отстранува блок на автоунапредување на даден корисник, добиен поради последица од филтер за злоупотреби.", "apihelp-abusefilterunblockautopromote-param-user": "Корисничкото име што сакате да го одблокирате.", @@ -41,14 +44,21 @@ "apihelp-query+abuselog-param-end": "На кој датум и време да запре набројувањето.", "apihelp-query+abuselog-param-user": "Прикажи само ставки за даден корисник или IP-адреса.", "apihelp-query+abuselog-param-title": "Прикажи само ставки што се однесуваат на дадена страница.", - "apihelp-query+abuselog-param-filter": "Прикажи само ставки за настани фатени од дадена филтерска назнака.", + "apihelp-query+abuselog-param-filter": "Прикажи само ставки за настани фатени од дадена филтерска назнака. Одделувајте со прави црти; и претставката „$1“ за глобални филтри.", + "apihelp-query+abuselog-param-filter-central": "Прикажи само ставки зафатени од укажаните филтерски назнаки. Одделете со прави црти.", "apihelp-query+abuselog-param-limit": "Највеќе ставки во списоците.", "apihelp-query+abuselog-param-prop": "Кои својства да се дадат.", "apihelp-query+abuselog-param-wiki": "Од кое вики да се прикажуваат погодоци.", "apihelp-query+abuselog-example-1": "Прикажи ги скорешните дневнички ставки", "apihelp-query+abuselog-example-2": "Прикажи ги скорешните дневнички ставки за [[API|извршникот]] (API)", + "apihelp-abuselogprivatedetails-description": "Преглед на лични податоци за ставка во Дневникот на злоупотреби.", + "apihelp-abuselogprivatedetails-summary": "Преглед на лични податоци за ставка во Дневникот на злоупотреби.", + "apihelp-abuselogprivatedetails-param-logid": "Назнака на ставката во Дневникот на злоупотреби која треба да се провери.", + "apihelp-abuselogprivatedetails-param-reason": "Важечка причина за проверката.", + "apihelp-abuselogprivatedetails-example-1": "Дај лични податоци за ставката во Дневникот на злоупотреби со назнака 1, користејќи ја причината", "apierror-abusefilter-canttest": "Немате дозвола да испробувате филтри на злоупотреба.", "apierror-abusefilter-cantcheck": "Немате дозвола да проверувате синтакса на филтри на злоупотреба.", + "apierror-abusefilter-canteval": "Немате дозвола да вреднување изрази од Филтерот на злоупотреби.", "apierror-abusefilter-nosuchlogid": "Нема запис во дневникот на злоупотреби со назнака $1.", "apierror-abusefilter-badsyntax": "Филтерот има неважечка синтакса." } diff --git a/AbuseFilter/i18n/api/ml.json b/AbuseFilter/i18n/api/ml.json index 41ff6b62..1fcb8ddc 100644 --- a/AbuseFilter/i18n/api/ml.json +++ b/AbuseFilter/i18n/api/ml.json @@ -1,8 +1,10 @@ { "@metadata": { "authors": [ + "Adithyak1997", "Praveenp" ] }, - "apihelp-abusefiltercheckmatch-param-filter": "അരിപ്പയിലെ മൊത്തം എഴുത്തും ഒത്തുപോകുന്നുണ്ടോയെന്ന് പരിശോധിക്കുക." + "apihelp-abusefiltercheckmatch-param-filter": "അരിപ്പയിലെ മൊത്തം എഴുത്തും ഒത്തുപോകുന്നുണ്ടോയെന്ന് പരിശോധിക്കുക.", + "apihelp-query+abusefilters-param-limit": "പട്ടികയിൽ ഉണ്ടാകാവുന്ന പരമാവധി അരിപ്പകളുടെ എണ്ണം." } diff --git a/AbuseFilter/i18n/api/nb.json b/AbuseFilter/i18n/api/nb.json index 96d2599b..93fdb507 100644 --- a/AbuseFilter/i18n/api/nb.json +++ b/AbuseFilter/i18n/api/nb.json @@ -20,7 +20,9 @@ "apihelp-abusefilterevalexpression-description": "Evaluerer et misbruksfilteruttrykk.", "apihelp-abusefilterevalexpression-summary": "Evaluerer et uttrykk i et misbruksfilter.", "apihelp-abusefilterevalexpression-param-expression": "Uttrykket som skal evalueres.", + "apihelp-abusefilterevalexpression-param-prettyprint": "Hvorvidt resultatet burde finformateres.", "apihelp-abusefilterevalexpression-example-1": "Evaluer et enkelt uttrykk", + "apihelp-abusefilterevalexpression-example-2": "Evaluer et enkelt uttrykk og formater resultatet", "apihelp-abusefilterunblockautopromote-description": "Fjerner blokkeringen av en bruker fra å automatisk forfremmes på grunn av konsekvenser fra et misbruksfilter.", "apihelp-abusefilterunblockautopromote-summary": "Fjerner en brukers blokkering fra å få automatiske forfremmelser basert på konsekvenser av misbruksfiltre.", "apihelp-abusefilterunblockautopromote-param-user": "Brukernavnet til brukeren du ønsker å avblokkere.", @@ -36,17 +38,26 @@ "apihelp-query+abusefilters-example-2": "Vis noen detaljer om filtre", "apihelp-query+abuselog-description": "Vis hendelser som ble fanget opp av ett av misbruksfiltrene.", "apihelp-query+abuselog-summary": "Vis hendelser som ble fanget av ett av misbruksfilterne.", + "apihelp-query+abuselog-param-logid": "Vis en oppføring med den gitte logg-ID-en.", "apihelp-query+abuselog-param-start": "Tidsstempelet nummereringen skal starte på.", "apihelp-query+abuselog-param-end": "Tidsstempelet det skal sluttes å nummerere på.", "apihelp-query+abuselog-param-user": "Vis bare oppføringer gjort av en gitt bruker eller IP-adresse.", "apihelp-query+abuselog-param-title": "Vis bare oppføringer på ei gitt side.", - "apihelp-query+abuselog-param-filter": "Vis bare oppføringer som ble fanget av en gitt filter-ID.", + "apihelp-query+abuselog-param-filter": "Vis bare oppføringer som ble fanget av en gitt filter-ID. Atskill med vertikalstreker, bruk prefikset «$1» for globale filtre.", + "apihelp-query+abuselog-param-filter-central": "Vis kun oppføringer som ble fanget opp med de gitte filter-ID-ene. Atskill med vertikalstreker.", "apihelp-query+abuselog-param-limit": "Maksimalt antall oppføringer som skal listes opp.", "apihelp-query+abuselog-param-prop": "Hvilke egenskaper som skal hentes.", + "apihelp-query+abuselog-param-wiki": "Wiki det skal vises treff fra.", "apihelp-query+abuselog-example-1": "Vis nylige loggoppføringer", "apihelp-query+abuselog-example-2": "Vis nylige loggoppføringer for [[API]]", + "apihelp-abuselogprivatedetails-description": "Vis private detaljer i en misbruksloggoppføring.", + "apihelp-abuselogprivatedetails-summary": "Vis private detaljer i en misbruksloggoppføring.", + "apihelp-abuselogprivatedetails-param-logid": "ID-en til misbruksloggoppføringen som skal sjekkes.", + "apihelp-abuselogprivatedetails-param-reason": "En gyldig årsak for å utføre kontrollen.", + "apihelp-abuselogprivatedetails-example-1": "Hent private detaljer fra misbruksloggoppføringen med ID 1, med årsaken «example».", "apierror-abusefilter-canttest": "Du har ikke tillatelse til å teste misbruksfiltre.", "apierror-abusefilter-cantcheck": "Du har ikke tillatelse til å sjekke syntaksen til misbruksfiltre.", + "apierror-abusefilter-canteval": "Du har ikke tillatelse til å evaluere misbruksfilteruttrykk.", "apierror-abusefilter-nosuchlogid": "Det er ingen misbruksloggoppføring med ID $1.", "apierror-abusefilter-badsyntax": "Filteret har ugyldig syntaks." } diff --git a/AbuseFilter/i18n/api/nl.json b/AbuseFilter/i18n/api/nl.json index acf7ab8e..adb37905 100644 --- a/AbuseFilter/i18n/api/nl.json +++ b/AbuseFilter/i18n/api/nl.json @@ -21,6 +21,7 @@ "apihelp-abusefilterevalexpression-description": "Evalueert een misbruikfilterexpressie.", "apihelp-abusefilterevalexpression-summary": "Evalueert een misbruikfilterexpressie.", "apihelp-abusefilterevalexpression-param-expression": "De te evalueren expressie.", + "apihelp-abusefilterevalexpression-param-prettyprint": "Of het resultaat opgemaakt moet worden.", "apihelp-abusefilterevalexpression-example-1": "Evalueer een eenvoudige expressie", "apihelp-abusefilterunblockautopromote-description": "Sta een gebruiker toe automatische promoties te krijgen als gevolg van een misbruikfilterregel.", "apihelp-abusefilterunblockautopromote-summary": "Sta een gebruiker toe automatische promoties te krijgen als gevolg van een misbruikfilterregel.", @@ -41,12 +42,15 @@ "apihelp-query+abuselog-param-end": "Het tijdstip waar de opsomming eindigt.", "apihelp-query+abuselog-param-user": "Alleen regels weergeven die zijn uitgevoerd door een opgegeven gebruiker of IP-adres.", "apihelp-query+abuselog-param-title": "Alleen regels weergeven die betrekking hebben op een opgegeven pagina.", - "apihelp-query+abuselog-param-filter": "Alleen regels weergeven die zijn afgevangen door een opgegeven filter-ID.", + "apihelp-query+abuselog-param-filter": "Alleen regels weergeven die zijn afgevangen door de opgegeven filter-IDs. Scheid met sluistekens (|), gebruik het voorvoegsel \"$1\" voor globale filters", "apihelp-query+abuselog-param-limit": "Het maximale aantal regels in de lijst.", "apihelp-query+abuselog-param-prop": "Welke eigenschappen op te vragen.", "apihelp-query+abuselog-param-wiki": "Wiki waarvan de hits gezien moeten laten worden.", "apihelp-query+abuselog-example-1": "Recente logboekregels weergeven", "apihelp-query+abuselog-example-2": "Recente logboekregels voor [[API]] weergeven", + "apihelp-abuselogprivatedetails-description": "De beperkt zichtbare gegevens van een logboekregel van het misbruikfilter bekijken.", + "apihelp-abuselogprivatedetails-summary": "Bekijk de beperkt zichtbare gegevens van een logboekregel van het misbruikfilter.", + "apihelp-abuselogprivatedetails-example-1": "De beperkt zichtbare gegevens van de logboekregel met het ID 1 ophalen, met de reden \"example\".", "apierror-abusefilter-canttest": "U hebt geen toestemming om misbruikfilters te testen.", "apierror-abusefilter-cantcheck": "U hebt geen toestemming om de syntax van misbruikfilters te controleren.", "apierror-abusefilter-nosuchlogid": "Er is geen misbruikfilterregel met de id $1.", diff --git a/AbuseFilter/i18n/api/pl.json b/AbuseFilter/i18n/api/pl.json index 9a6515f7..1f1ea35a 100644 --- a/AbuseFilter/i18n/api/pl.json +++ b/AbuseFilter/i18n/api/pl.json @@ -3,23 +3,31 @@ "authors": [ "Chrumps", "Halibutt", + "Rail", "Railfail536", "The Polish", "Woytecr" ] }, "apihelp-abusefilterchecksyntax-description": "Sprawdź składnię filtra AbuseFilter.", + "apihelp-abusefilterchecksyntax-example-1": "Sprawdź składnię poprawnego filtra", + "apihelp-abusefilterchecksyntax-example-2": "Sprawdź składnię nieprawidłowego filtra", "apihelp-abusefilterevalexpression-param-expression": "Wyrażenie do sprawdzenia.", "apihelp-abusefilterunblockautopromote-param-user": "Nazwa użytkownika, którego chcesz odblokować.", "apihelp-query+abusefilters-description": "Pokaż szczegóły filtrów nadużyć.", "apihelp-query+abusefilters-summary": "Pokaż szczegóły filtrów nadużyć.", + "apihelp-query+abusefilters-param-startid": "ID filtra, od którego rozpocząć wyliczanie.", + "apihelp-query+abusefilters-param-endid": "ID filtra, na którym zakończyć wyliczanie.", "apihelp-query+abusefilters-param-show": "Pokaż tylko filtry, które spełniają te kryteria.", "apihelp-query+abusefilters-param-limit": "Maksymalna liczba filtrów do wyświetlenia.", + "apihelp-query+abusefilters-param-prop": "Właściwości do odczytu.", "apihelp-query+abusefilters-example-1": "Lista uruchomionych filtrów publicznych", "apihelp-query+abusefilters-example-2": "Pokaż szczegóły dotyczące filtrów", "apihelp-query+abuselog-description": "Pokaż zdarzenia wyłapane przez jeden z filtrów nadużyć.", + "apihelp-query+abuselog-summary": "Pokaż zdarzenia, które zostały złapane przez jeden z filtrów nadużyć.", "apihelp-query+abuselog-param-start": "Znacznik czasu, od którego zacząć wyliczanie.", "apihelp-query+abuselog-param-end": "Znacznik czasu, na którym zakończyć wyliczanie.", + "apihelp-query+abuselog-param-filter-central": "Pokaż tylko wpisy, które zostały złapane przez filtry o podanych ID. Oddzielaj znakiem pionowej kreski.", "apihelp-query+abuselog-param-prop": "Jakie właściwości uzyskać.", "apihelp-query+abuselog-example-1": "Pokaż ostatnie wpisy w rejestrze", "apihelp-query+abuselog-example-2": "Pokaż ostatnie wpisy w dzienniku [[API]]", diff --git a/AbuseFilter/i18n/api/pt-br.json b/AbuseFilter/i18n/api/pt-br.json index 25466d76..38506465 100644 --- a/AbuseFilter/i18n/api/pt-br.json +++ b/AbuseFilter/i18n/api/pt-br.json @@ -24,7 +24,9 @@ "apihelp-abusefilterevalexpression-description": "Avalia uma expressão AbuseFilter.", "apihelp-abusefilterevalexpression-summary": "Avalia uma expressão AbuseFilter.", "apihelp-abusefilterevalexpression-param-expression": "A expressão para avaliar.", + "apihelp-abusefilterevalexpression-param-prettyprint": "Se o resultado deve ser bem impresso.", "apihelp-abusefilterevalexpression-example-1": "Avaliar uma simples expressão", + "apihelp-abusefilterevalexpression-example-2": "Avalie uma expressão simples, formatando o resultado", "apihelp-abusefilterunblockautopromote-description": "Desbloqueia um usuário de receber auto-promoções devido a uma consequência do abusefilter.", "apihelp-abusefilterunblockautopromote-summary": "Desbloqueia um usuário de receber auto-promoções devido a uma consequência do abusefilter.", "apihelp-abusefilterunblockautopromote-param-user": "Nome do usuário que deseja desbloquear.", @@ -45,14 +47,20 @@ "apihelp-query+abuselog-param-end": "O timestamp para parar a enumeração.", "apihelp-query+abuselog-param-user": "Mostrar apenas as entradas feitas por um determinado usuário ou endereço IP.", "apihelp-query+abuselog-param-title": "Mostrar apenas as entradas ocorridas em uma determinada página.", - "apihelp-query+abuselog-param-filter": "Mostrar apenas as entradas que foram capturadas por um determinado ID do filtro.", + "apihelp-query+abuselog-param-filter": "Mostrar apenas as entradas que foram capturadas pelos IDs de filtro fornecidos. Separe com pipes, prefixo com \"$1\" para filtros globais.", "apihelp-query+abuselog-param-limit": "A quantidade máxima de entradas para listar.", "apihelp-query+abuselog-param-prop": "Que propriedades obter.", "apihelp-query+abuselog-param-wiki": "Wiki para mostrar hits de.", "apihelp-query+abuselog-example-1": "Mostrar entradas de registro recentes", "apihelp-query+abuselog-example-2": "Mostrar entradas de registro recentes para [[API]]", + "apihelp-abuselogprivatedetails-description": "Veja detalhes privados de uma entrada do registro de abusos.", + "apihelp-abuselogprivatedetails-summary": "Veja detalhes privados de uma entrada do registro de abusos.", + "apihelp-abuselogprivatedetails-param-logid": "O ID da entrada do registro de abusos a ser verificada.", + "apihelp-abuselogprivatedetails-param-reason": "Um motivo válido para executar a verificação.", + "apihelp-abuselogprivatedetails-example-1": "Obtenha detalhes privados para a entrada do registro de abusos com ID 1, usando o motivo \"exemplo\".", "apierror-abusefilter-canttest": "Você não tem permissão para testar filtros de edições.", "apierror-abusefilter-cantcheck": "Você não tem permissão para conferir a sintaxe de filtros de edições.", + "apierror-abusefilter-canteval": "Você não tem permissão para avaliar expressões do AbuseFilter.", "apierror-abusefilter-nosuchlogid": "Não há entrada no registro de abusos com o id $1.", "apierror-abusefilter-badsyntax": "O filtro tem sintaxe inválida." } diff --git a/AbuseFilter/i18n/api/pt.json b/AbuseFilter/i18n/api/pt.json index e8c9c967..1c8bae6c 100644 --- a/AbuseFilter/i18n/api/pt.json +++ b/AbuseFilter/i18n/api/pt.json @@ -2,7 +2,8 @@ "@metadata": { "authors": [ "Athena in Wonderland", - "Hamilton Abreu" + "Hamilton Abreu", + "Mansil alfalb" ] }, "apihelp-abusefiltercheckmatch-description": "Verificar se um filtro de abusos coincide com um conjunto de variáveis, uma edição, ou um evento do registo de abusos.\n\nÉ necessário um dos seguintes: vars, rcid ou logid (só um pode ser usado).", @@ -21,7 +22,9 @@ "apihelp-abusefilterevalexpression-description": "Avalia uma expressão do filtro de abusos.", "apihelp-abusefilterevalexpression-summary": "Avalia uma expressão do filtro de abusos.", "apihelp-abusefilterevalexpression-param-expression": "A expressão para avaliar.", + "apihelp-abusefilterevalexpression-param-prettyprint": "Se o resultado deve ter realce sintático.", "apihelp-abusefilterevalexpression-example-1": "Avaliar uma expressão simples", + "apihelp-abusefilterevalexpression-example-2": "Avaliar uma expressão simples, formatando o resultado", "apihelp-abusefilterunblockautopromote-description": "Desbloqueia um utilizador de receber autopromoções em consequência do filtro de abusos.", "apihelp-abusefilterunblockautopromote-summary": "Desbloqueia um utilizador de receber autopromoções em consequência do filtro de abusos.", "apihelp-abusefilterunblockautopromote-param-user": "Nome do utilizador que pretende desbloquear.", @@ -42,14 +45,20 @@ "apihelp-query+abuselog-param-end": "A data e hora onde parar a enumeração.", "apihelp-query+abuselog-param-user": "Mostrar só as entradas de um determinado utilizador ou endereço IP.", "apihelp-query+abuselog-param-title": "Mostrar só as entradas de uma determinada página.", - "apihelp-query+abuselog-param-filter": "Mostrar só as entradas que foram detetadas por um determinado identificador de filtro.", + "apihelp-query+abuselog-param-filter": "Mostrar só as entradas que foram detetadas pelos identificadores de filtros fornecidos. Separar com barra vertical (|), prefixar com \"$1\" para filtros globais.", "apihelp-query+abuselog-param-limit": "O número máximo de entradas que serão listadas.", "apihelp-query+abuselog-param-prop": "Que propriedades obter.", "apihelp-query+abuselog-param-wiki": "A wiki da qual mostra as visitas.", "apihelp-query+abuselog-example-1": "Mostrar entradas recentes do registo", "apihelp-query+abuselog-example-2": "Mostrar entradas recentes do registo para [[API]]", + "apihelp-abuselogprivatedetails-description": "Ver detalhes privados de uma entrada do registo de abusos.", + "apihelp-abuselogprivatedetails-summary": "Ver detalhes privados de uma entrada do registo de abusos.", + "apihelp-abuselogprivatedetails-param-logid": "O identificador da entrada do registo de abusos a ser verificada.", + "apihelp-abuselogprivatedetails-param-reason": "Um motivo válido para executar a verificação.", + "apihelp-abuselogprivatedetails-example-1": "Obter detalhes privados da entrada do registo de abusos com o identificador 1, usando o motivo \"example\".", "apierror-abusefilter-canttest": "Não tem permissão para testar filtros de abuso.", "apierror-abusefilter-cantcheck": "Não tem permissão para verificar a sintaxe de filtros de abuso.", + "apierror-abusefilter-canteval": "Não tem permissão para avaliar expressões de filtros de abusos.", "apierror-abusefilter-nosuchlogid": "Não há nenhuma entrada no registo de abusos com o identificador $1.", "apierror-abusefilter-badsyntax": "O filtro contém sintaxe inválida." } diff --git a/AbuseFilter/i18n/api/qqq.json b/AbuseFilter/i18n/api/qqq.json index 77d0b5f2..650dae6b 100644 --- a/AbuseFilter/i18n/api/qqq.json +++ b/AbuseFilter/i18n/api/qqq.json @@ -1,10 +1,11 @@ { "@metadata": { "authors": [ - "Brad Jorsch", - "Matěj Suchánek", + "Amire80", + "Ankam", "Aotake", "Bennylin", + "Brad Jorsch", "ChrisiPK", "Darth Kule", "EugeneZelenko", @@ -16,12 +17,16 @@ "Krenair", "Krinkle", "Kwj2772", + "Legoktm", "Lejonel", + "Liuxinyu970226", "Lloffiwr", + "Matěj Suchánek", "McDutchie", "Meno25", "Mormegil", "Nemo bis", + "Pikne", "Praveenp", "Purodha", "Pxos", @@ -31,12 +36,7 @@ "The Evil IP address", "Translationista", "Umherirrender", - "Yekrats", - "Liuxinyu970226", - "Legoktm", - "Pikne", - "Amire80", - "Ankam" + "Yekrats" ] }, "apihelp-abusefiltercheckmatch-description": "{{doc-apihelp-description|abusefiltercheckmatch}}", @@ -55,7 +55,9 @@ "apihelp-abusefilterevalexpression-description": "{{doc-apihelp-description|abusefilterevalexpression}}", "apihelp-abusefilterevalexpression-summary": "{{doc-apihelp-summary|abusefilterevalexpression}}", "apihelp-abusefilterevalexpression-param-expression": "{{doc-apihelp-param|abusefilterevalexpression|expression}}", + "apihelp-abusefilterevalexpression-param-prettyprint": "{{doc-apihelp-param|abusefilterevalexpression|prettyprint}}", "apihelp-abusefilterevalexpression-example-1": "{{doc-apihelp-example|abusefilterevalexpression}}", + "apihelp-abusefilterevalexpression-example-2": "{{doc-apihelp-example|abusefilterevalexpression}}", "apihelp-abusefilterunblockautopromote-description": "{{doc-apihelp-description|abusefilterunblockautopromote}}\n Autopromotion is an automatic system that gives rights to users when certain conditions are met.", "apihelp-abusefilterunblockautopromote-summary": "{{doc-apihelp-summary|abusefilterunblockautopromote}}\n Autopromotion is an automatic system that gives rights to users when certain conditions are met.", "apihelp-abusefilterunblockautopromote-param-user": "{{doc-apihelp-param|abusefilterunblockautopromote|user}}", @@ -76,14 +78,21 @@ "apihelp-query+abuselog-param-end": "{{doc-apihelp-param|query+abuselog|end}}", "apihelp-query+abuselog-param-user": "{{doc-apihelp-param|query+abuselog|user}}", "apihelp-query+abuselog-param-title": "{{doc-apihelp-param|query+abuselog|title}}", - "apihelp-query+abuselog-param-filter": "{{doc-apihelp-param|query+abuselog|filter}}", + "apihelp-query+abuselog-param-filter": "{{doc-apihelp-param|query+abuselog|filter}}\nParameters:\n* $1 - The prefix to use for global filters.\n\nSee also {{msg-mw|apihelp-query+abuselog-param-filter-central}}", + "apihelp-query+abuselog-param-filter-central": "{{doc-apihelp-param|query+abuselog|filter}}\n\nSee also {{msg-mw|apihelp-query+abuselog-param-filter}}", "apihelp-query+abuselog-param-limit": "{{doc-apihelp-param|query+abuselog|limit}}", "apihelp-query+abuselog-param-prop": "{{doc-apihelp-param|query+abuselog|prop}}", "apihelp-query+abuselog-param-wiki": "{{doc-apihelp-param|query+abuselog|wiki}}", "apihelp-query+abuselog-example-1": "{{doc-apihelp-example|query+abuselog}}", "apihelp-query+abuselog-example-2": "{{doc-apihelp-example|query+abuselog}}", + "apihelp-abuselogprivatedetails-description": "{{doc-apihelp-description|abuselogprivatedetails}}", + "apihelp-abuselogprivatedetails-summary": "{{doc-apihelp-summary|abuselogprivatedetails}}", + "apihelp-abuselogprivatedetails-param-logid": "{{doc-apihelp-param|abuselogprivatedetails|logid}}", + "apihelp-abuselogprivatedetails-param-reason": "{{doc-apihelp-param|abuselogprivatedetails|reason}}", + "apihelp-abuselogprivatedetails-example-1": "{{doc-apihelp-example|abuselogprivatedetails}}", "apierror-abusefilter-canttest": "{{doc-apierror}}", "apierror-abusefilter-cantcheck": "{{doc-apierror}}", + "apierror-abusefilter-canteval": "{{doc-apierror}}", "apierror-abusefilter-nosuchlogid": "{{doc-apierror}}\n\nParameters:\n* $1 - AbuseFilter log ID number.", "apierror-abusefilter-badsyntax": "{{doc-apierror}}" } diff --git a/AbuseFilter/i18n/api/roa-tara.json b/AbuseFilter/i18n/api/roa-tara.json index 9ddb8270..1683f937 100644 --- a/AbuseFilter/i18n/api/roa-tara.json +++ b/AbuseFilter/i18n/api/roa-tara.json @@ -20,7 +20,9 @@ "apihelp-abusefilterevalexpression-description": "Valute 'n'espressione de AbuseFilter.", "apihelp-abusefilterevalexpression-summary": "Valute 'n'espressione de AbuseFilter.", "apihelp-abusefilterevalexpression-param-expression": "L'espressione da valutà.", + "apihelp-abusefilterevalexpression-param-prettyprint": "Ce formattà 'u resultate.", "apihelp-abusefilterevalexpression-example-1": "Valute 'n'espressione facile-facile", + "apihelp-abusefilterevalexpression-example-2": "Valutà 'n'espressione semblice, formattanne 'u resultate", "apihelp-abusefilterunblockautopromote-description": "Sblocche 'n'utende da ricevere auto promozziune cumme conseguenze de 'nu filtre de abbuse.", "apihelp-abusefilterunblockautopromote-summary": "Sblocche 'n'utende da ricevere auto promozziune cumme conseguenze de 'nu filtre de abbuse.", "apihelp-abusefilterunblockautopromote-param-user": "Nome de l'utende ca vue ccù sblocche.", @@ -41,14 +43,21 @@ "apihelp-query+abuselog-param-end": "L'orarie ca stoppe l'enumerazione.", "apihelp-query+abuselog-param-user": "Fà vedè sulamende le vôsce fatte da 'nu date utende o indirizze IP.", "apihelp-query+abuselog-param-title": "Fà vedè sulamende le vôsce ca iessene sus a 'na data pàgene.", - "apihelp-query+abuselog-param-filter": "Fà vedè sulamende le vôsce ca sò azzeccate da 'nu specifiche ID de filtre.", + "apihelp-query+abuselog-param-filter": "Fà 'ndrucà sulamende le vôsce ca sò azzeccate da 'nu specifiche ID de filtre. Separate da le barre verticale (|), 'u prefisse cu \"$1\" pe le filtre globbale.", + "apihelp-query+abuselog-param-filter-central": "Fà 'ndrucà sulamende le vôsce ca onne state pigghiate da 'u filtre ID. Separate cu le | (pipe).", "apihelp-query+abuselog-param-limit": "'U numere massime de vôsce jndr'à l'elenghe.", "apihelp-query+abuselog-param-prop": "Quale probbietà a pigghià.", "apihelp-query+abuselog-param-wiki": "Uicchi da fà 'ndrucà le visite.", "apihelp-query+abuselog-example-1": "Fà vedè le vôsce de l'archivije recende", "apihelp-query+abuselog-example-2": "Fà vedè le vôsce de l'archivije recende pe [[API]]", + "apihelp-abuselogprivatedetails-description": "'Ndruche le dettaglie private de 'na vôsce de l'archivije de l'abbuse.", + "apihelp-abuselogprivatedetails-summary": "'Ndruche le dettaglie private de 'na vôsce de l'archivije de l'abbuse.", + "apihelp-abuselogprivatedetails-param-logid": "L'ID d'a vôsce de l'archivije de l'abbuse ca adda essere condrollate.", + "apihelp-abuselogprivatedetails-param-reason": "'Nu mutive valide pe fà 'u condrolle.", + "apihelp-abuselogprivatedetails-example-1": "Pigghie le dettaglie private pa vôsce de l'archivije de l'abbuse cu l'ID 1, ausanne 'u mutive \"example\".", "apierror-abusefilter-canttest": "Non ge tìne le permesse pe testà le filtre de abbuse.", "apierror-abusefilter-cantcheck": "Non ge tìne le permesse pe testà 'a sindasse de le filtre de abbuse.", + "apierror-abusefilter-canteval": "Non ge tìne le permesse de valutà le espressiune de AbuseFilter.", "apierror-abusefilter-nosuchlogid": "Non ge stonne vôsce jndr'à l'archivije de le abbuse cu le id $1.", "apierror-abusefilter-badsyntax": "'U filtre tène 'na sindasse invalide." } diff --git a/AbuseFilter/i18n/api/ru.json b/AbuseFilter/i18n/api/ru.json index b5d5201b..74511474 100644 --- a/AbuseFilter/i18n/api/ru.json +++ b/AbuseFilter/i18n/api/ru.json @@ -4,8 +4,10 @@ "Cat1987", "Facenapalm", "Mouse21", + "Movses", "Okras", - "Vlad5250" + "Vlad5250", + "Марио" ] }, "apihelp-abusefiltercheckmatch-description": "Проверьте, удовлетворяет ли фильтру злоупотреблений набор переменных или событие фильтра злоупотреблений, записанное редактором.\n\nПеременные vars, rcid и logid обязательны, однако только одна из них может быть использована.", @@ -45,12 +47,15 @@ "apihelp-query+abuselog-param-end": "Временная метка, на которой закончить перечисление.", "apihelp-query+abuselog-param-user": "Показать только записи, связанные с данным участником или IP-адресом.", "apihelp-query+abuselog-param-title": "Показать только записи, связанные с данной страницей.", - "apihelp-query+abuselog-param-filter": "Показать только записи, связанные с фильтром с данным идентификатором.", + "apihelp-query+abuselog-param-filter": "Показать только записи, связанные с фильтрами с данными идентификаторами. Идентификаторы разделяются вертикальной чертой, а префикс \"$1\" используется для глобальных фильтров.", "apihelp-query+abuselog-param-limit": "Максимальное количество записей в списке.", "apihelp-query+abuselog-param-prop": "Какие свойства необходимо получить.", "apihelp-query+abuselog-param-wiki": "Вики, чтобы показывать хиты.", "apihelp-query+abuselog-example-1": "Показать последние записи в журнале", "apihelp-query+abuselog-example-2": "Показать последние записи в журнале [[API]]", + "apihelp-abuselogprivatedetails-description": "Просмотреть приватные данные записи журнала злоупотреблений.", + "apihelp-abuselogprivatedetails-summary": "Просмотреть приватные данные записи журнала злоупотреблений.", + "apihelp-abuselogprivatedetails-param-logid": "Идентификатор записи AbuseLog для проверки.", "apierror-abusefilter-canttest": "У вас недостаточно прав для проверки фильтров злоупотреблений.", "apierror-abusefilter-cantcheck": "У вас недостаточно прав для проверки синтаксиса фильтра злоупотреблений.", "apierror-abusefilter-nosuchlogid": "Не существует записи в журнале злоупотреблений с идентификатором $1.", diff --git a/AbuseFilter/i18n/api/sh.json b/AbuseFilter/i18n/api/sh.json new file mode 100644 index 00000000..f9543fd6 --- /dev/null +++ b/AbuseFilter/i18n/api/sh.json @@ -0,0 +1,59 @@ +{ + "@metadata": { + "authors": [ + "Vlad5250" + ] + }, + "apihelp-abusefiltercheckmatch-description": "Provjerite nalazi li filter za zlouporabu skup varijabli, uređivanje ili zapisan događaj u filteru.\n\nZahtjeva vars, rcid ili logid (može se koristiti samo jedno).", + "apihelp-abusefiltercheckmatch-summary": "Provjerite nalazi li filter za zlouporabu određeni skup varijabli, uređivanje ili zapisan događaj u filteru.", + "apihelp-abusefiltercheckmatch-extended-description": "Zahtjeva vars, rcid iili logid (može se koristiti samo jedno od njih).", + "apihelp-abusefiltercheckmatch-param-filter": "Puni tekst filtera što ga filter provjerava.", + "apihelp-abusefiltercheckmatch-param-vars": "Niz varijabli kodiranih u JSON što se treba provjeriti.", + "apihelp-abusefiltercheckmatch-param-rcid": "Naznaka nedavne promjene što se treba provjeriti.", + "apihelp-abusefiltercheckmatch-param-logid": "Naznaka unosa u dnevniku filtera što se treba provjeriti.", + "apihelp-abusefiltercheckmatch-example-1": "Provjeri nalazi li se nedavna promjena s naznakom 15 iz jednostavnog filtra.", + "apihelp-abusefilterchecksyntax-description": "Provjeri sintaksu filtra zlostavljanja.", + "apihelp-abusefilterchecksyntax-summary": "Provjeri sintaksu danog filtra zlostavljanja.", + "apihelp-abusefilterchecksyntax-param-filter": "Puni tekst čiju sintaksu provjerava filter.", + "apihelp-abusefilterchecksyntax-example-1": "Provjeri sintaksu valjanog filtra", + "apihelp-abusefilterchecksyntax-example-2": "Provjeri sintaksu nevaljanog filtra", + "apihelp-abusefilterevalexpression-description": "Ocjenjuje izraz u Filtru za zloupotrebe.", + "apihelp-abusefilterevalexpression-summary": "Ocjenjuje izraz u Filtru za zloupotrebe.", + "apihelp-abusefilterevalexpression-param-expression": "Izraz što se treba procjeniti.", + "apihelp-abusefilterevalexpression-example-1": "Ocijeni jednostavan izraz", + "apihelp-abusefilterunblockautopromote-description": "Uklanja blok na autounapređivanje određenog korisnika, dobiven zbog posljedice filtra za zlouporabu.", + "apihelp-abusefilterunblockautopromote-summary": "Uklanja blok na autounapređivanje određenog korisnika, dobiven zbog posljedice filtra za zlouporabu.", + "apihelp-abusefilterunblockautopromote-param-user": "Korisničko ime korisnika kojog želite deblokirati.", + "apihelp-abusefilterunblockautopromote-example-1": "Ukloni blok autounapređivanja za [[User:Example]]", + "apihelp-query+abusefilters-description": "Prikaži podrobnosti filtara za zlouporabu.", + "apihelp-query+abusefilters-summary": "Prikaži podrobnosti filtara za zlouporabu.", + "apihelp-query+abusefilters-param-startid": "Naznaka filtra odakle počinje brojanje.", + "apihelp-query+abusefilters-param-endid": "Naznaka filtra gdje će se brojanje zaustaviti.", + "apihelp-query+abusefilters-param-show": "Prikaži samo filtre što zadovoljavaju ove kriterije.", + "apihelp-query+abusefilters-param-limit": "Dopušteni broj filtara za unos na popisu.", + "apihelp-query+abusefilters-param-prop": "Koja svojstva dati.", + "apihelp-query+abusefilters-example-1": "Ispiši uključene javne filtre", + "apihelp-query+abusefilters-example-2": "Prikazivaj neke podrobnosti filtara", + "apihelp-query+abuselog-description": "Prikaži događaje koje je uhvatio jedan od filtara.", + "apihelp-query+abuselog-summary": "Prikaži događaje koje je uhvatio jedan od filtara.", + "apihelp-query+abuselog-param-logid": "Prikaži stavku s danim dnevničkom naznakom.", + "apihelp-query+abuselog-param-start": "Od kojeg datuma i vremena počinje brojanje.", + "apihelp-query+abuselog-param-end": "Na koji datum i vrijeme zaustaviti brojanje.", + "apihelp-query+abuselog-param-user": "Prikaži samo stavke za danog korisnika ili IP adresu.", + "apihelp-query+abuselog-param-title": "Prikaži samo stavke što se odnose na datu stranicu.", + "apihelp-query+abuselog-param-filter": "Prikaži samo stavke za događaje uhvaćene danom filterskom naznakom. Odijelite pravim crtima; i prefiksom \"$1\" za globalne filtre.", + "apihelp-query+abuselog-param-limit": "Najviše stavki u popisima.", + "apihelp-query+abuselog-param-prop": "Koja svojstva dati.", + "apihelp-query+abuselog-param-wiki": "Od kojog wikija se prikazuju pogodci.", + "apihelp-query+abuselog-example-1": "Prikaži nedavne zapisničke stavke", + "apihelp-query+abuselog-example-2": "Prikaži nedavne zapisničke stavke za [[API|izvršnik]] (API)", + "apihelp-abuselogprivatedetails-description": "Pregled osobnih podataka za unos u Evidenciji zloupotreba.", + "apihelp-abuselogprivatedetails-summary": "Pregled osobnih podataka za unos u Evidenciji zloupotreba.", + "apihelp-abuselogprivatedetails-param-logid": "Naznaka unosa u Evidenciji zloupotreba koja treba da se provijeri.", + "apihelp-abuselogprivatedetails-param-reason": "Važeći razlog za provjeru.", + "apihelp-abuselogprivatedetails-example-1": "Daj osobne podatke za unos u Evidenciji zloupotreba s naznakom 1, koristeći razlog", + "apierror-abusefilter-canttest": "Nemate dopuštenje da isprobate filtre za zlouporabu.", + "apierror-abusefilter-cantcheck": "Nemate dopuštenje da provjerite sintaksu filtara za zlouporabu.", + "apierror-abusefilter-nosuchlogid": "Nema unosa u zapisniku zlouporabe s naznakom $1.", + "apierror-abusefilter-badsyntax": "Filter nema valjanu sintaksu." +} diff --git a/AbuseFilter/i18n/api/sk.json b/AbuseFilter/i18n/api/sk.json new file mode 100644 index 00000000..116a3241 --- /dev/null +++ b/AbuseFilter/i18n/api/sk.json @@ -0,0 +1,21 @@ +{ + "@metadata": { + "authors": [ + "TomášPolonec" + ] + }, + "apihelp-abusefilterchecksyntax-example-1": "Skontrolovať syntax platného filtra", + "apihelp-abusefilterchecksyntax-example-2": "Skontrolovať syntax neplatného filtra", + "apihelp-abusefilterevalexpression-description": "Vyhodnotí výraz filtra zneužití.", + "apihelp-abusefilterevalexpression-summary": "Vyhodnotí výraz filtra zneužití.", + "apihelp-abusefilterevalexpression-param-expression": "Výraz, ktorý sa má vyhodnotiť.", + "apihelp-abusefilterevalexpression-example-1": "Vyhodnotiť jednoduchý výraz", + "apihelp-abusefilterevalexpression-example-2": "Vyhodnotiť jednoduchý výraz a formátovať výsledok", + "apihelp-query+abusefilters-description": "Zobraziť podrobnosti filtra zneužití.", + "apihelp-query+abusefilters-summary": "Zobraziť podrobnosti filtra zneužití.", + "apihelp-query+abusefilters-example-2": "Zobraziť niektoré detaily o filtri zneužití", + "apierror-abusefilter-canttest": "Nemáte oprávnenie testovať filtre zneužití.", + "apierror-abusefilter-cantcheck": "Nemáte oprávnenie kontrolovať syntax filtrov zneužití.", + "apierror-abusefilter-canteval": "Nemáte oprávnenie vyhodnocovať výrazy filtra zneužití.", + "apierror-abusefilter-badsyntax": "Filter má neplatnú syntax." +} diff --git a/AbuseFilter/i18n/api/sl.json b/AbuseFilter/i18n/api/sl.json new file mode 100644 index 00000000..cef00cd6 --- /dev/null +++ b/AbuseFilter/i18n/api/sl.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "RStular" + ] + }, + "apihelp-query+abuselog-param-logid": "Pokaži vnos s podano ID številko.", + "apihelp-query+abuselog-example-1": "Pokaži nedavne dnevniške zapise", + "apihelp-abuselogprivatedetails-param-reason": "Veljaven razlog za izvedbo preverjanja." +} diff --git a/AbuseFilter/i18n/api/sr-ec.json b/AbuseFilter/i18n/api/sr-ec.json new file mode 100644 index 00000000..3de4da33 --- /dev/null +++ b/AbuseFilter/i18n/api/sr-ec.json @@ -0,0 +1,12 @@ +{ + "@metadata": { + "authors": [ + "BadDog" + ] + }, + "apihelp-abusefilterunblockautopromote-param-user": "Корисничко име корисника ког желите да деблокирате.", + "apihelp-query+abusefilters-description": "Прикажи детаље филтера злоупотреба.", + "apihelp-query+abusefilters-summary": "Прикажи детаље филтера злоупотреба.", + "apihelp-abuselogprivatedetails-param-reason": "Важећи разлог за проверу", + "apierror-abusefilter-badsyntax": "Филтер има неважећу синтаксу." +} diff --git a/AbuseFilter/i18n/api/sr-el.json b/AbuseFilter/i18n/api/sr-el.json new file mode 100644 index 00000000..26ed6826 --- /dev/null +++ b/AbuseFilter/i18n/api/sr-el.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [] + }, + "apihelp-abusefilterunblockautopromote-param-user": "Korisničko ime korisnika kog želite da deblokirate.", + "apihelp-query+abusefilters-description": "Prikaži detalje filtera zloupotreba.", + "apihelp-query+abusefilters-summary": "Prikaži detalje filtera zloupotreba.", + "apihelp-abuselogprivatedetails-param-reason": "Važeći razlog za proveru", + "apierror-abusefilter-badsyntax": "Filter ima nevažeću sintaksu." +} diff --git a/AbuseFilter/i18n/api/sv.json b/AbuseFilter/i18n/api/sv.json index 24e0af8c..7437d48c 100644 --- a/AbuseFilter/i18n/api/sv.json +++ b/AbuseFilter/i18n/api/sv.json @@ -22,7 +22,9 @@ "apihelp-abusefilterevalexpression-description": "Utvärdera ett AbuseFilter-uttryck.", "apihelp-abusefilterevalexpression-summary": "Utvärderar uttryck i ett missbruksfilter.", "apihelp-abusefilterevalexpression-param-expression": "Uttrycket att utvärdera.", + "apihelp-abusefilterevalexpression-param-prettyprint": "Om resultatet bör formateras.", "apihelp-abusefilterevalexpression-example-1": "Beräkna en enkel formel", + "apihelp-abusefilterevalexpression-example-2": "Räkna ut ett enkelt uttryck och formatera resultatet", "apihelp-abusefilterunblockautopromote-description": "Upphäver blockering för en användare från att få automatiska befordringar p.g.a. konsekvenser från ett missbruksfilter.", "apihelp-abusefilterunblockautopromote-summary": "Upphäver blockering för en användare från att få automatiska befordringar p.g.a. konsekvenser från ett missbruksfilter.", "apihelp-abusefilterunblockautopromote-param-user": "Användarnamn för användaren du vill avblockera.", @@ -43,14 +45,21 @@ "apihelp-query+abuselog-param-end": "Tidsstämpeln att sluta räkna upp vid.", "apihelp-query+abuselog-param-user": "Visa enbart poster gjorda av en viss användare eller IP-adress.", "apihelp-query+abuselog-param-title": "Visa endast poster som förekommer på en viss sida.", - "apihelp-query+abuselog-param-filter": "Visa endast poster som fångats av ett visst filter-ID.", + "apihelp-query+abuselog-param-filter": "Visa endast poster som fångades av angivna filter-ID:n. Separera med vertikala linjer, inled med \"$1\" för globala filter.", + "apihelp-query+abuselog-param-filter-central": "Visa endast poster som fångats upp av angivna filter-ID:n. Separerade med vertikala streck.", "apihelp-query+abuselog-param-limit": "Det maximala antalet poster att lista.", "apihelp-query+abuselog-param-prop": "Vilka egenskaper att hämta.", "apihelp-query+abuselog-param-wiki": "Wiki att visa träffar ifrån.", "apihelp-query+abuselog-example-1": "Visa de senaste loggposterna", "apihelp-query+abuselog-example-2": "Visa de senaste loggposterna för [[API]]", + "apihelp-abuselogprivatedetails-description": "Visa privata detaljer för en post i missbruksloggen.", + "apihelp-abuselogprivatedetails-summary": "Visa privata detaljer för en post i missbruksloggen.", + "apihelp-abuselogprivatedetails-param-logid": "ID för en post i missbruksloggen att kontrollera.", + "apihelp-abuselogprivatedetails-param-reason": "En giltig anledning för att genomföra kontrollen.", + "apihelp-abuselogprivatedetails-example-1": "Hämta privata detaljer för posten i missbruksloggen med ID 1, som har anledningen \"example\".", "apierror-abusefilter-canttest": "Du har inte behörighet att testa missbruksfilter.", "apierror-abusefilter-cantcheck": "Du har inte behörighet att kolla syntaxen för missbruksfilter.", + "apierror-abusefilter-canteval": "Du har inte behörighet att utvärdera missbruksfilteruttryck.", "apierror-abusefilter-nosuchlogid": "Det finns ingen post i missbruksloggen med ID $1.", "apierror-abusefilter-badsyntax": "Filtret har ogiltig syntax." } diff --git a/AbuseFilter/i18n/api/th.json b/AbuseFilter/i18n/api/th.json new file mode 100644 index 00000000..69d05c8f --- /dev/null +++ b/AbuseFilter/i18n/api/th.json @@ -0,0 +1,48 @@ +{ + "@metadata": { + "authors": [ + "Aefgh39622" + ] + }, + "apihelp-abusefiltercheckmatch-extended-description": "ต้องการ vars, rcid หรือ logid แต่สามารถใช้ได้เพียงอย่างเดียว", + "apihelp-abusefiltercheckmatch-param-filter": "ข้อความตัวกรองแบบเต็มที่จะตรวจหารายการที่ตรงกัน", + "apihelp-abusefiltercheckmatch-param-vars": "แถวลำดับที่เข้ารหัสแล้วของ JSON ของตัวแปรที่จะนำมาใช้ทดสอบ", + "apihelp-abusefiltercheckmatch-param-rcid": "ไอดีการเปลี่ยนแปลงล่าสุดที่จะนำมาใช้ตรวจสอบ", + "apihelp-abusefiltercheckmatch-param-logid": "ไอดีปูมตัวกรองการละเมิดกฎที่จะนำมาใช้ตรวจสอบ", + "apihelp-abusefiltercheckmatch-example-1": "ทดสอบว่าไอดีการเปลี่ยนแปลงล่าสุด 15 ตรงกับตัวกรองอย่างง่าย", + "apihelp-abusefilterchecksyntax-description": "ตรวจสอบไวยากรณ์ของตัวกรอง AbuseFilter", + "apihelp-abusefilterchecksyntax-summary": "ตรวจสอบไวยากรณ์ของตัวกรอง AbuseFilter", + "apihelp-abusefilterchecksyntax-param-filter": "ข้อความตัวกรองแบบเต็มที่จะตรวจสอบไวยากรณ์", + "apihelp-abusefilterchecksyntax-example-1": "ตรวจสอบไวยากรณ์ของตัวกรองที่ถูกต้อง", + "apihelp-abusefilterchecksyntax-example-2": "ตรวจสอบไวยากรณ์ของตัวกรองที่ไม่ถูกต้อง", + "apihelp-abusefilterevalexpression-description": "ประเมินนิพจน์ AbuseFilter expression", + "apihelp-abusefilterevalexpression-summary": "ประเมินนิพจน์ตัวกรองการละเมิดกฎ", + "apihelp-abusefilterevalexpression-param-expression": "นิพจน์ที่ต้องการประเมิน", + "apihelp-abusefilterevalexpression-example-1": "ประเมินนิพจน์อย่างง่าย", + "apihelp-abusefilterunblockautopromote-param-user": "ชื่อผู้ใช้ของผู้ใช้ที่คุณต้องการเลิกบล็อก", + "apihelp-query+abusefilters-description": "แสดงรายละเอียดของตัวกรองการละเมิดกฎ", + "apihelp-query+abusefilters-summary": "แสดงรายละเอียดของตัวกรองการละเมิดกฎ", + "apihelp-query+abusefilters-param-startid": "ไอดีตัวกรองที่ต้องการใช้เป็นจุดเริ่มต้นของการแจงนับ", + "apihelp-query+abusefilters-param-endid": "ไอดีตัวกรองที่ต้องการใช้เป็นจุดสิ้นสุดของการแจงนับ", + "apihelp-query+abusefilters-param-show": "แสดงเฉพาะตัวกรองที่ตรงตามเกณฑ์เหล่านี้เท่านั้น", + "apihelp-query+abusefilters-param-limit": "จำนวนตัวกรองสูงสุดที่ต้องการแสดง", + "apihelp-query+abusefilters-param-prop": "คุณสมบัติที่ต้องการรับข้อมูล", + "apihelp-query+abusefilters-example-1": "แสดงรายการตัวกรองสาธราณะที่ถูกเปิดใช้งาน", + "apihelp-query+abusefilters-example-2": "แสดงรายละเอียดบางส่วนเกี่ยวกับตัวกรอง", + "apihelp-query+abuselog-description": "แสดงเหตุการณ์ที่ถูกตรวจจับโดยตัวกรองการละเมิดกฎตัวใดตัวหนึ่ง", + "apihelp-query+abuselog-summary": "แสดงเหตุการณ์ที่ถูกตรวจจับโดยตัวกรองการละเมิดกฎตัวใดตัวหนึ่ง", + "apihelp-query+abuselog-param-logid": "แสดงรายการที่มีไอดีปูมที่ระบุ", + "apihelp-query+abuselog-param-start": "ตราเวลาที่ต้องการใช้เป็นจุดเริ่มต้นของการแจงนับ", + "apihelp-query+abuselog-param-end": "ตราเวลาที่ต้องการใช้เป็นจุดสิ้นสุดของการแจงนับ", + "apihelp-query+abuselog-param-user": "แสดงเฉพาะรายการที่ดำเนินการเสร็จสมบูรณ์โดยผู้ใช้หรือที่อยู่ไอพีที่ระบุเท่านั้น", + "apihelp-query+abuselog-param-title": "แสดงเฉพาะรายการที่เกิดขึ้นบนหน้าที่ระบุเท่านั้น", + "apihelp-query+abuselog-param-limit": "จำนวนรายการสูงสุดที่จะแสดง", + "apihelp-query+abuselog-param-prop": "คุณสมบัติที่ต้องการรับข้อมูล", + "apihelp-query+abuselog-example-1": "แสดงรายการปูมล่าสุด", + "apihelp-query+abuselog-example-2": "แสดงรายการปูมล่าสุดสำหรับ [[API]]", + "apierror-abusefilter-canttest": "คุณไม่มีสิทธิทดสอบตัวกรองการละเมิดกฎ", + "apierror-abusefilter-cantcheck": "คุณไม่มีสิทธิตรวจสอบไวยากรณ์ของตัวกรองการละเมิดกฎ", + "apierror-abusefilter-canteval": "คุณไม่มีสิทธิประเมินนิพจน์ตัวกรองการละเมิดกฎ", + "apierror-abusefilter-nosuchlogid": "ไม่มีรายการปูมการละเมิดกฎที่มีไอดี $1", + "apierror-abusefilter-badsyntax": "ตัวกรองมีไวยากรณ์ที่ไม่ถูกต้อง" +} diff --git a/AbuseFilter/i18n/api/tr.json b/AbuseFilter/i18n/api/tr.json new file mode 100644 index 00000000..0442d3f6 --- /dev/null +++ b/AbuseFilter/i18n/api/tr.json @@ -0,0 +1,64 @@ +{ + "@metadata": { + "authors": [ + "BaRaN6161 TURK", + "MuratTheTurkish" + ] + }, + "apihelp-abusefiltercheckmatch-description": "Bir AbuseFilter'ın bir değişkenler kümesiyle mi, bir düzenleme ile mi yoksa günlüğe kaydedilen bir AbuseFilter olayıyla eşleştiğini kontrol edin.\n\nvars, rcid veya logid gereklidir, ancak yalnızca biri kullanılabilir.", + "apihelp-abusefiltercheckmatch-summary": "Bir AbuseFilter'ın bir değişkenler kümesiyle mi, bir düzenleme ile mi yoksa günlüğe kaydedilen bir AbuseFilter olayıyla eşleştiğini kontrol edin.", + "apihelp-abusefiltercheckmatch-extended-description": "vars, rcid veya logid gereklidir, ancak yalnızca biri kullanılabilir.", + "apihelp-abusefiltercheckmatch-param-filter": "Bir eşleşmeyi kontrol etmek için tam filtre metni.", + "apihelp-abusefiltercheckmatch-param-vars": "JSON, test edilecek değişken dizisini kodladı.", + "apihelp-abusefiltercheckmatch-param-rcid": "Denetlenecek son değişiklik kimliği.", + "apihelp-abusefiltercheckmatch-param-logid": "Kötüye kullanım filtresi günlük kimliğini kontrol etmek için kullanın.", + "apihelp-abusefiltercheckmatch-example-1": "Son değişiklik ID 15'in basit bir filtreyle eşleşip eşleşmediğini test edin", + "apihelp-abusefilterchecksyntax-description": "Bir AbuseFilter filtresinin sözdizimini kontrol edin.", + "apihelp-abusefilterchecksyntax-summary": "Bir AbuseFilter filtresinin sözdizimini kontrol edin.", + "apihelp-abusefilterchecksyntax-param-filter": "Açık sözdizimini kontrol etmek için tam filtre metni.", + "apihelp-abusefilterchecksyntax-example-1": "Geçerli bir filtrenin sözdizimini kontrol et", + "apihelp-abusefilterchecksyntax-example-2": "Geçersiz bir filtrenin sözdizimini kontrol et", + "apihelp-abusefilterevalexpression-description": "Bir AbuseFilter ifadesini değerlendirir.", + "apihelp-abusefilterevalexpression-summary": "Bir AbuseFilter ifadesini değerlendirir.", + "apihelp-abusefilterevalexpression-param-expression": "Değerlendirilecek ifade.", + "apihelp-abusefilterevalexpression-param-prettyprint": "Sonucun güzel yazdırılıp yazdırılmayacağı.", + "apihelp-abusefilterevalexpression-example-1": "Basit bir ifadeyi değerlendirin", + "apihelp-abusefilterevalexpression-example-2": "Sonucu biçimlendirerek basit bir ifadeyi değerlendirin", + "apihelp-abusefilterunblockautopromote-description": "Bir kullanıcının kötüye kullanım filtresinin bir sonucu olması nedeniyle otomatik konuşma almasını engeller.", + "apihelp-abusefilterunblockautopromote-summary": "Bir kullanıcının kötüye kullanım filtresinin bir sonucu olması nedeniyle otomatik konuşma almasını engeller.", + "apihelp-abusefilterunblockautopromote-param-user": "Blokeyi kaldırmak istediğiniz kullanıcının kullanıcı adı.", + "apihelp-abusefilterunblockautopromote-example-1": "[[User:Example]]'ın otomatik hareketinin üzerindeki bloğu kaldırın", + "apihelp-query+abusefilters-description": "Kötüye kullanım filtrelerinin ayrıntılarını gösterin.", + "apihelp-query+abusefilters-summary": "Kötüye kullanım filtrelerinin ayrıntılarını gösterin.", + "apihelp-query+abusefilters-param-startid": "Numaralandırmaya başlamak için filtre kimliği.", + "apihelp-query+abusefilters-param-endid": "Numaralandırmayı durdurmak için filtre kimliği.", + "apihelp-query+abusefilters-param-show": "Yalnızca bu kriterlere uyan filtreleri göster.", + "apihelp-query+abusefilters-param-limit": "Listelenecek maksimum filtre sayısı.", + "apihelp-query+abusefilters-param-prop": "Hangi özellikleri elde etmek.", + "apihelp-query+abusefilters-example-1": "Etkin olan genel filtreleri listele", + "apihelp-query+abusefilters-example-2": "Filtrelerle ilgili bazı ayrıntıları göster", + "apihelp-query+abuselog-description": "Kötüye kullanım filtrelerinden birinin yakaladığı olayları gösterin.", + "apihelp-query+abuselog-summary": "Kötüye kullanım filtrelerinden birinin yakaladığı olayları gösterin.", + "apihelp-query+abuselog-param-logid": "Verilen günlük kimliğiyle bir giriş gösterin.", + "apihelp-query+abuselog-param-start": "Numaralandırmaya başlamak için zaman damgası.", + "apihelp-query+abuselog-param-end": "Numaralandırmayı durdurmak için zaman damgası.", + "apihelp-query+abuselog-param-user": "Yalnızca belirli bir kullanıcı veya IP adresi tarafından yapılan girişleri göster.", + "apihelp-query+abuselog-param-title": "Yalnızca belirli bir sayfada gerçekleşen girişleri göster.", + "apihelp-query+abuselog-param-filter": "Yalnızca verilen filtre kimlikleri tarafından yakalanan girişleri göster. Borularla ayırın, genel filtreler için \"$1\" ile önek koyun.", + "apihelp-query+abuselog-param-filter-central": "Yalnızca verilen filtre kimlikleri tarafından yakalanan girişleri gösterin. Borularla ayırın.", + "apihelp-query+abuselog-param-limit": "Listelenecek maksimum giriş sayısı.", + "apihelp-query+abuselog-param-prop": "Hangi özellikleri elde etmek.", + "apihelp-query+abuselog-param-wiki": "Viki kaynağını gösterecek.", + "apihelp-query+abuselog-example-1": "En son günlük girişlerini göster", + "apihelp-query+abuselog-example-2": "[[API]] için son günlük girişlerini göster", + "apihelp-abuselogprivatedetails-description": "Bir AbuseLog girişinin özel ayrıntılarını görüntüleyin.", + "apihelp-abuselogprivatedetails-summary": "Bir AbuseLog girişinin özel ayrıntılarını görüntüleyin.", + "apihelp-abuselogprivatedetails-param-logid": "Kontrol edilecek AbuseLog girişinin kimliği.", + "apihelp-abuselogprivatedetails-param-reason": "Kontrolün yapılması için geçerli bir sebep.", + "apihelp-abuselogprivatedetails-example-1": "\"Example\" nedenini kullanarak, kimlik 1 ile AbuseLog girişi için özel detaylar alın.", + "apierror-abusefilter-canttest": "Kötüye kullanım filtrelerini test etme izniniz yok.", + "apierror-abusefilter-cantcheck": "Kötüye kullanım filtrelerinin sözdizimini kontrol etme izniniz yok.", + "apierror-abusefilter-canteval": "AbuseFilter ifadelerini değerlendirme izniniz yok.", + "apierror-abusefilter-nosuchlogid": "$1 kimliğiyle hiçbir kötü kullanım günlük girişi yok.", + "apierror-abusefilter-badsyntax": "Filtre geçersiz sözdizimine sahip." +} diff --git a/AbuseFilter/i18n/api/uk.json b/AbuseFilter/i18n/api/uk.json index f621f923..e2868f0d 100644 --- a/AbuseFilter/i18n/api/uk.json +++ b/AbuseFilter/i18n/api/uk.json @@ -4,27 +4,31 @@ "AS", "Base", "DonDrakon", + "Movses", "Piramidion", + "Vlad5250", "Ата" ] }, "apihelp-abusefiltercheckmatch-description": "Перевірте, чи AbuseFilter має збіги з набором змінних, редагуванням чи подією в журналі AbuseFilter.\n\nПотрібні vars, rcid або logid, але використати можна лише один.", - "apihelp-abusefiltercheckmatch-summary": "Перевірити, щоб побачити, чи Фільтр зловживань відповідає набору змінних, редагуванню чи журнальованій дії Фільтру зловживань.", + "apihelp-abusefiltercheckmatch-summary": "Перевірити, щоб побачити, чи Фільтр редагувань відповідає набору змінних, редагуванню чи журнальованій дії Фільтра редагувань.", "apihelp-abusefiltercheckmatch-extended-description": "Необхідні vars, rcid або logid, однак можна використати лише один з цих параметрів.", "apihelp-abusefiltercheckmatch-param-filter": "Повнотекстовий фільтр для перевірки на відповідність.", "apihelp-abusefiltercheckmatch-param-vars": "JSON-кодований масив змінних, за яким тестувати.", "apihelp-abusefiltercheckmatch-param-rcid": "ID у нових редагуваннях, на основі якого має бути здійснена перевірка.", "apihelp-abusefiltercheckmatch-param-logid": "ID із журналу фільтра зловживань, на основі якого має бути здійснена перевірка.", "apihelp-abusefiltercheckmatch-example-1": "Перевірити, чи ID 15 в нових редагуваннях відповідає простому фільтру.", - "apihelp-abusefilterchecksyntax-description": "Перевірити синтаксис фільтру зловживань.", + "apihelp-abusefilterchecksyntax-description": "Перевірити синтаксис певного фільтра редагувань.", "apihelp-abusefilterchecksyntax-summary": "Перевірити синтаксис фільтра зловживань.", - "apihelp-abusefilterchecksyntax-param-filter": "Повний текст фільтру, синтаксис якого необхідно перевірити.", - "apihelp-abusefilterchecksyntax-example-1": "Перевірити синтаксис правильного фільтру", - "apihelp-abusefilterchecksyntax-example-2": "Перевірити синтаксис неправильного фільтру", - "apihelp-abusefilterevalexpression-description": "Оцінює значення виразу Фільтру зловживань.", + "apihelp-abusefilterchecksyntax-param-filter": "Повний текст фільтра, синтаксис якого необхідно перевірити.", + "apihelp-abusefilterchecksyntax-example-1": "Перевірити синтаксис дійсного фільтра", + "apihelp-abusefilterchecksyntax-example-2": "Перевірити синтаксис недійсного фільтра", + "apihelp-abusefilterevalexpression-description": "Оцінює значення виразу Фільтра редагувань.", "apihelp-abusefilterevalexpression-summary": "Оцінює вираз фільтра зловживань.", "apihelp-abusefilterevalexpression-param-expression": "Вираз до оцінки.", + "apihelp-abusefilterevalexpression-param-prettyprint": "Чи потрібно форматувати результат.", "apihelp-abusefilterevalexpression-example-1": "Оцінити простий вираз", + "apihelp-abusefilterevalexpression-example-2": "Обробити простий вираз, форматувати результат", "apihelp-abusefilterunblockautopromote-description": "Зняти з користувача викликане фільтром зловживань обмеження отримувати автоматичне просування.", "apihelp-abusefilterunblockautopromote-summary": "Розблоковує користувача від отримування автоматичних просувань через послідовність фільтрів.", "apihelp-abusefilterunblockautopromote-param-user": "Ім'я користувача, якого Ви хочете розблокувати.", @@ -45,14 +49,20 @@ "apihelp-query+abuselog-param-end": "Часова мітка закінчення переліку.", "apihelp-query+abuselog-param-user": "Показати тільки елементи, зроблені певним користувачем або IP-адресою.", "apihelp-query+abuselog-param-title": "Показати лише елементи, що наявні на даній сторінці.", - "apihelp-query+abuselog-param-filter": "Показати лише елементи, спіймані за допомогою даного ідентифікатора фільтра.", + "apihelp-query+abuselog-param-filter": "Показати лише елементи, спіймані за допомогою даних ідентифікаторів фільтрів. Ідентифікатори розділяються вертикальною рискою, а префікс \"$1\" використовується для глобальних фільтрів.", "apihelp-query+abuselog-param-limit": "Максимальна кількість елементів для переліку.", "apihelp-query+abuselog-param-prop": "Які властивості отримати.", "apihelp-query+abuselog-param-wiki": "Вікі, влучення з якої показувати.", "apihelp-query+abuselog-example-1": "Показати останні записи в журналі", "apihelp-query+abuselog-example-2": "Показати останні записи в журналі [[API]]", + "apihelp-abuselogprivatedetails-description": "Переглянути приватні деталі запису в журналі фільтра редагувань.", + "apihelp-abuselogprivatedetails-summary": "Переглянути приватні деталі запису в журналі фільтра редагувань.", + "apihelp-abuselogprivatedetails-param-logid": "Ідентифікатор запису AbuseLog для перевірки.", + "apihelp-abuselogprivatedetails-param-reason": "Вагома причина виконання перевірки.", + "apihelp-abuselogprivatedetails-example-1": "Отримати деталі запису з ідентифікатором \"1\", вказав причиною \"example\".", "apierror-abusefilter-canttest": "Ви не маєте дозволу тестувати фільтри зловживань.", "apierror-abusefilter-cantcheck": "Ви не маєте дозволу перевіряти синтаксис фільтрів зловживань.", + "apierror-abusefilter-canteval": "У вас немає прав на оцінювання виразів AbuseFilter.", "apierror-abusefilter-nosuchlogid": "Немає запису зловживання з id $1.", "apierror-abusefilter-badsyntax": "Фільтр має неправильний синтаксис." } diff --git a/AbuseFilter/i18n/api/zh-hans.json b/AbuseFilter/i18n/api/zh-hans.json index 41d089c3..29731579 100644 --- a/AbuseFilter/i18n/api/zh-hans.json +++ b/AbuseFilter/i18n/api/zh-hans.json @@ -2,6 +2,10 @@ "@metadata": { "authors": [ "Liuxinyu970226", + "Looong", + "SomeyaMako", + "VulpesVulpes825", + "Wenyuan Liu", "Yfdyh000" ] }, @@ -21,7 +25,9 @@ "apihelp-abusefilterevalexpression-description": "评估防滥用过滤器的表达式。", "apihelp-abusefilterevalexpression-summary": "评估防滥用过滤器的表达式。", "apihelp-abusefilterevalexpression-param-expression": "要评估的表达式。", + "apihelp-abusefilterevalexpression-param-prettyprint": "是否美化输出结果", "apihelp-abusefilterevalexpression-example-1": "评估一个简单的表达式", + "apihelp-abusefilterevalexpression-example-2": "对一个简单表达式求值,并对结果进行格式化处理", "apihelp-abusefilterunblockautopromote-description": "从由于防滥用过滤器的结果而接受的autopromotions解封用户。", "apihelp-abusefilterunblockautopromote-summary": "从由于防滥用过滤器的结果而接受的autopromotions解封用户。", "apihelp-abusefilterunblockautopromote-param-user": "您希望解封的用户的用户名。", @@ -42,14 +48,20 @@ "apihelp-query+abuselog-param-end": "枚举的结束时间戳。", "apihelp-query+abuselog-param-user": "只显示由指定的用户或IP地址完成的记录。", "apihelp-query+abuselog-param-title": "只显示在指定页面上发生过的条项。", - "apihelp-query+abuselog-param-filter": "只显示被指定过滤器ID捕获过的记录。", + "apihelp-query+abuselog-param-filter": "只显示被指定过滤器ID捕获过的记录。使用管道字符分离,以“$1”开始以表示为公共过滤器。", "apihelp-query+abuselog-param-limit": "列出日志记录的最大数量。", "apihelp-query+abuselog-param-prop": "要获得的属性。", "apihelp-query+abuselog-param-wiki": "显示触发来自的Wiki。", "apihelp-query+abuselog-example-1": "显示最近日志记录", "apihelp-query+abuselog-example-2": "显示[[API]]的最近日志记录", + "apihelp-abuselogprivatedetails-description": "显示AbuseLog入口的私有信息。", + "apihelp-abuselogprivatedetails-summary": "显示一个AbuseLog入口的私有信息", + "apihelp-abuselogprivatedetails-param-logid": "检查AbuseLog入口的ID", + "apihelp-abuselogprivatedetails-param-reason": "执行检查的合理原因", + "apihelp-abuselogprivatedetails-example-1": "使用“例子”这个原因,可以获取到带有ID 1 的AbuseLog入口的私有信息。", "apierror-abusefilter-canttest": "您没有权限测试防滥用过滤器。", "apierror-abusefilter-cantcheck": "您没有权限检查防滥用过滤器的语法。", + "apierror-abusefilter-canteval": "您没有计算 AbuseFilter 表达式的权限。", "apierror-abusefilter-nosuchlogid": "没有id为$1的滥用日志记录。", "apierror-abusefilter-badsyntax": "过滤器存在语法错误。" } diff --git a/AbuseFilter/i18n/api/zh-hant.json b/AbuseFilter/i18n/api/zh-hant.json index 6328c665..7706fd8b 100644 --- a/AbuseFilter/i18n/api/zh-hant.json +++ b/AbuseFilter/i18n/api/zh-hant.json @@ -3,8 +3,9 @@ "authors": [ "A2093064", "Kly", + "LNDDYL", "Laundry Machine", - "LNDDYL" + "Xiplus" ] }, "apihelp-abusefiltercheckmatch-description": "檢查防濫用過濾器是否符合變數集、編輯、或是所記錄的防濫用過濾器事件。\n\nvars、rcid 或 logid是必須填入的,然而只會使用其中一個。", @@ -23,7 +24,9 @@ "apihelp-abusefilterevalexpression-description": "評估防濫用過濾器的表達式。", "apihelp-abusefilterevalexpression-summary": "評估防濫用過濾器的表達式。", "apihelp-abusefilterevalexpression-param-expression": "評估的表達式。", + "apihelp-abusefilterevalexpression-param-prettyprint": "是否美化輸出結果", "apihelp-abusefilterevalexpression-example-1": "評估一份簡易表達式", + "apihelp-abusefilterevalexpression-example-2": "評估一個簡易表達式、格式化結果", "apihelp-abusefilterunblockautopromote-description": "從由防濫用過濾器結果所接收到的自動調整來解封使用者。", "apihelp-abusefilterunblockautopromote-summary": "從由防濫用過濾器結果所接收到的自動調整來解封使用者。", "apihelp-abusefilterunblockautopromote-param-user": "您希望解封的使用者名稱。", @@ -44,14 +47,21 @@ "apihelp-query+abuselog-param-end": "終止列舉的時間戳記。", "apihelp-query+abuselog-param-user": "僅顯示由指定使用者或 IP 地址所做出的項目。", "apihelp-query+abuselog-param-title": "僅顯示發生在指定頁面的項目。", - "apihelp-query+abuselog-param-filter": "僅顯示由指定過濾器 ID 偵測到的項目。", + "apihelp-query+abuselog-param-filter": "僅顯示由指定過濾器 ID 偵測到的項目。以豎線字元區分、字首為「$1」用於全域過濾器。", + "apihelp-query+abuselog-param-filter-central": "僅顯示出由指定篩選 ID 所抓取到的項目。以豎線字元區分。", "apihelp-query+abuselog-param-limit": "項目能列出的最大數量。", "apihelp-query+abuselog-param-prop": "要取得的屬性。", "apihelp-query+abuselog-param-wiki": "顯示觸發起始的 wiki。", "apihelp-query+abuselog-example-1": "顯示近期的日誌項目", "apihelp-query+abuselog-example-2": "顯示 [[API]] 近期的日誌項目", + "apihelp-abuselogprivatedetails-description": "檢視 AbuseLog 項目的非公開詳細資料。", + "apihelp-abuselogprivatedetails-summary": "檢視 AbuseLog 項目的非公開詳細資料。", + "apihelp-abuselogprivatedetails-param-logid": "要檢查 AbuseLog 項目 ID。", + "apihelp-abuselogprivatedetails-param-reason": "執行檢查的正當原因。", + "apihelp-abuselogprivatedetails-example-1": "使用原因「範例」來取得 AbuseLog 項目 ID 為 1 的非公開詳細資料。", "apierror-abusefilter-canttest": "您沒有權限來測試防濫用過濾器。", "apierror-abusefilter-cantcheck": "您沒有權限來檢查防濫用過濾器的語法。", + "apierror-abusefilter-canteval": "您沒有權限來評估 AbuseFilter 表達式。", "apierror-abusefilter-nosuchlogid": "沒有 ID 為 $1 的濫用日誌項目。", "apierror-abusefilter-badsyntax": "此過濾器含有無效語法。" } diff --git a/AbuseFilter/i18n/ar.json b/AbuseFilter/i18n/ar.json index 4b264ddd..16486fc4 100644 --- a/AbuseFilter/i18n/ar.json +++ b/AbuseFilter/i18n/ar.json @@ -11,6 +11,7 @@ "Claw eg", "DRIHEM", "Loya", + "Matma Rex", "Meno25", "Mido", "Orango", @@ -18,19 +19,18 @@ "Tarawneh", "Zack wadghiri", "Zanatos", + "أحمد", "ترجمان05", + "ديفيد", "زكريا", - "وهراني", - "محمد أحمد عبد الفتاح", - "أحمد", - "Matma Rex", "علاء", - "ديفيد" + "محمد أحمد عبد الفتاح", + "وهراني" ] }, "abusefilter-desc": "يطبق قواعد آلية على التعديلات.", - "abusefilter": "ضبط مرشح الإساءة", - "abuselog": "سجل الإساءة", + "abusefilter": "التحكم بمرشح الإساءة", + "abuselog": "سجل مرشح الإساءة", "abusefilter-intro": "مرحبا بك إلى واجهة التحكم بمرشح الإساءة.\nمرشح الإساءة هو ميكانيكية برمجية آلية لتطبيق ضوابط تلقائية لكل الأفعال.\nهذه الواجهة تعرض قائمة بالمرشحات المعرفة، وتسمح بتعديلها.", "abusefilter-mustviewprivateoredit": "لأسباب تتعلق بالأمان; يمكن فقط للمستخدمين الذين لديهم صلاحية عرض مرشحات خاصة أو تعديل المرشحات استخدام هذه الواجهة.", "abusefilter-warning": "'''تحذير''': حُسِب هذا الفعل ضارًّا.\nالأفعال غير البناءة سريعا ما تُسترجَع،\nومواصلة عمل تعديلات غير بنّاءة أو الإصرار عليها سيؤدي إلى منع حسابك أو عنوان الآيبي الخاص بك،\nإذا كنت تعتقد أن هذا الإجراء بناء، يمكنك إرساله مرة أخرى لتأكيده،\nالوصف المختصر لقاعدة الإساءة التي طابقها فعلك: $1", @@ -41,13 +41,14 @@ "abusefilter-blocker": "مرشح الإساءة", "abusefilter-blockreason": "ممنوع تلقائيا بواسطة مرشح الإساءة. وصف القاعدة المطابقة: $1", "abusefilter-degroupreason": "الصلاحيات تمت إزالتها تلقائيا بواسطة مرشح الإساءة. وصف القاعدة: $1", + "abusefilter-blockautopromotereason": "تأخرت الترقية التلقائية تلقائيا بواسطة مرشح الإساءة،\nوصف القاعدة: $1", "abusefilter-accountreserved": "اسم الحساب هذا محجوز للاستخدام بواسطة مرشح الإساءة.", "right-abusefilter-modify": "عدل مرشحات الإساءة", "right-abusefilter-view": "عرض مرشحات الإساءة", "right-abusefilter-log": "عرض سجل الإساءة", "right-abusefilter-log-detail": "عرض مدخلات سجل الإساءة المفصلة", - "right-abusefilter-private": "عرض البيانات السرية في سجل الإساءة", - "right-abusefilter-private-log": "عرض سجل دخول التفاصيل الخاصة لمرشح الإساءة", + "right-abusefilter-privatedetails": "عرض البيانات السرية في سجل الإساءة", + "right-abusefilter-privatedetails-log": "عرض سجل دخول التفاصيل الخاصة لمرشح الإساءة", "right-abusefilter-modify-restricted": "عدل مرشحات الإساءة مع الأفعال المحظورة", "right-abusefilter-revert": "استرجع كل التعديلات لمرشح إساءة محدد.", "right-abusefilter-view-private": "اعرض مرشحات الإساءة المعلّمة كخاصة", @@ -59,17 +60,22 @@ "action-abusefilter-view": "رؤية مرشحات الإساءة", "action-abusefilter-log": "رؤية سجل الإساءة", "action-abusefilter-log-detail": "رؤية مدخلات سجل الإساءة المفصلة", - "action-abusefilter-private": "رؤية البيانات السرية في سجل الإساءة", - "action-abusefilter-private-log": "عرض سجل دخول التفاصيل الخاصة لمرشح الإساءة", + "action-abusefilter-privatedetails": "رؤية البيانات السرية في سجل الإساءة", + "action-abusefilter-privatedetails-log": "عرض سجل دخول التفاصيل الخاصة لمرشح الإساءة", "action-abusefilter-modify-restricted": "تعديل مرشحات الإساءة بالأفعال المحظورة", "action-abusefilter-revert": "استرجاع كل التغييرات بواسطة مرشح إساءة معطى", "action-abusefilter-view-private": "اعرض مرشحات الإساءة المعلّمة كخاصة", "action-abusefilter-log-private": "عرض سجلات مرشحات الإساءة المعلَّمة كخاصة", - "abusefilter-log": "سجل مرشح الإساءة", + "action-abusefilter-hide-log": "إخفاء المدخلات في سجل الإساءة", + "action-abusefilter-hidden-log": "عرض مدخلات سجل الإساءة المخفية", + "action-abusefilter-modify-global": "إنشاء أو تعديل مرشحات الإساءة العالمية", "abusefilter-log-summary": "هذا السجل يعرض قائمة بكل الأفعال المُكتشفة بواسطة المرشحات.", "abusefilter-log-search": "بحث سجل الإساءة", "abusefilter-log-search-user": "المستخدم:", - "abusefilter-log-search-filter": "أرقام المُرشِّح (مفصولة بشريط عمودي):", + "abusefilter-log-search-group": "تصفية المجموعة:", + "abusefilter-log-search-group-any": "أي", + "abusefilter-log-search-filter": "معرفات المرشحات:", + "abusefilter-log-search-filter-help": "افصل بالأنابيب والبادئة بـ\"$1\" للمرشحات العالمية", "abusefilter-log-search-title": "العنوان:", "abusefilter-log-search-wiki": "الويكي:", "abusefilter-log-search-impact": "التأثير:", @@ -84,7 +90,7 @@ "abusefilter-log-search-action-other": "أخرى", "abusefilter-log-search-action-any": "أيٌ منها", "abusefilter-log-search-action-taken-label": "الإجراءات المتخذة:", - "abusefilter-log-search-action-taken-any": "أيٌ منها", + "abusefilter-log-search-action-taken-any": "أي منها", "abusefilter-log-search-submit": "بحث", "abusefilter-log-entry": "$1: $2 {{GENDER:$8|فعل}} مرشح إساءة، {{GENDER:$8|مؤديا}} الفعل \"$3\" في $4.\nالأفعال المتخذة: $5،\nوصف المرشح: $6", "abusefilter-log-entry-withdiff": "$1: $2 {{GENDER:$8|فعل}} مرشح إساءة، {{GENDER:$8|مؤديا}} الفعل \"$3\" في $4.\nالأفعال المتخذة: $5،\nوصف المرشح: $6 ($7)", @@ -98,7 +104,7 @@ "abusefilter-log-details-var": "متغير", "abusefilter-log-details-val": "قيمة", "abusefilter-log-details-vars": "محددات الفعل", - "abusefilter-log-details-private": "تفاصيل السجل الخاص", + "abusefilter-log-details-privatedetails": "تفاصيل السجل الخاص", "abusefilter-log-details-ip": "عنوان الأيبي المصدر", "abusefilter-log-details-checkuser": "تدقيق المستخدم", "abusefilter-log-noactions": "لا شيء", @@ -107,10 +113,11 @@ "abusefilter-log-linkoncontribs-text": "سجل الإساءة ل{{GENDER:$1|هذا المستخدم}}", "abusefilter-log-linkonhistory": "عرض سجل الإساءة", "abusefilter-log-linkonhistory-text": "عرض سجل إساءة هذه الصفحة", - "abusefilter-log-hidden": "(السجل مخفي)", + "abusefilter-log-linkonundelete": "عرض سجل الإساءة", + "abusefilter-log-linkonundelete-text": "عرض سجل إساءة هذه الصفحة", "abusefilter-log-hidden-implicit": "(مخفي لأنه تم حذف مراجعة)", "abusefilter-log-cannot-see-details": "ليس لديك الإذن لمعرفة تفاصيل هذا الإدخال.", - "abusefilter-log-cannot-see-private-details": "ليست لديك صلاحية للاطلاع على تفاصيل خاصة لهذا الإدخال.", + "abusefilter-log-cannot-see-privatedetails": "ليست لديك صلاحية لرؤية تفاصيل هذا الإدخال الخاصة.", "abusefilter-log-nonexistent": "إدخال مع معرف مقدم غير موجود.", "abusefilter-log-details-hidden": "لا يمكنك رؤية تفاصيل هذا المدخل، لأنه مخفي من العرض العلني", "abusefilter-log-details-hidden-implicit": "لا يمكنك عرض تفاصيل هذا الإدخال لأن النسخة المرتبط بها مخفية عن العرض العام.", @@ -128,11 +135,14 @@ "log-action-filter-abusefilter-create": "إنشاء مرشح جديد", "log-action-filter-abusefilter-modify": "تعديل المرشح", "log-action-filter-suppress-abuselog": "إزالة سجل الإساءة", + "log-action-filter-rights-blockautopromote": "منع الترقية التلقائية", + "log-action-filter-rights-restoreautopromote": "استرجاع الترقية التلقائية", "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|وصل إلى}} التفاصيل الخاصة ل$3", + "logentry-rights-blockautopromote": "$1 {{GENDER:$2|منع|منعت}} الترقية التلقائية ل{{GENDER:$4|$3}} لمدة $5", + "logentry-rights-restoreautopromote": "$1 {{GENDER:$2|استرجع|استرجعت}} الترقية التلقائية ل{{GENDER:$4|$3}}", "abusefilterprivatedetails-log-name": "سجل الوصول للتفاصيل الخاصة بمرشح الإساءة", - "abusefilter-management": "التحكم بمرشح الإساءة", "abusefilter-list": "كل المرشحات", - "abusefilter-list-id": "رقم المُرشِّح", + "abusefilter-list-id": "رقم المرشح", "abusefilter-list-pattern": "النمط", "abusefilter-list-status": "الحالة", "abusefilter-list-public": "وصف علني", @@ -152,6 +162,7 @@ "abusefilter-throttled": "مخنوق", "abusefilter-hitcount": "$1 {{PLURAL:$1|ضربة|ضربة}}", "abusefilter-new": "إنشاء مرشح جديد", + "abusefilter-import-button": "استيراد المرشح", "abusefilter-return": "رجوع إلى إدارة المرشح", "abusefilter-status-global": "عام", "abusefilter-list-options": "خيارات", @@ -172,36 +183,38 @@ "abusefilter-list-options-search-like": "استعلام عادي", "abusefilter-list-options-search-rlike": "تعبير نمطي", "abusefilter-list-options-search-irlike": "تعبير نمطي غير حساس لحالة الأحرف", + "abusefilter-list-invalid-searchmode": "وضع البحث المحدد غير صالح.", "abusefilter-list-regexerror": "حدث خطأ أثناء البحث: خطأ في صياغة التعبير النمطي.", - "abusefilter-list-options-submit": "حدّث", + "abusefilter-list-options-submit": "تحديث", "abusefilter-tools-text": "هنا بعض الأدوات التي ربما تكون مفيدة في صياغة وتصليح مرشحات الإساءة.", "abusefilter-tools-expr": "مختبر التعبير", "abusefilter-tools-submitexpr": "تقييم", "abusefilter-tools-reautoconfirm": "استرجاع حالة التأكيد التلقائي", "abusefilter-tools-reautoconfirm-user": "المستخدم:", "abusefilter-tools-reautoconfirm-submit": "إعادة التأكيد التلقائي", + "abusefilter-tools-restoreautopromote": "تمت استعادة الترقية التلقائية من خلال أدوات مرشح الإساءة.", "abusefilter-reautoconfirm-none": "{{GENDER:$1|هذا المستخدم|هذه المستخدمة}} لم يتم تعليق حالة {{GENDER:$1|تأكيده|تأكيدها}} التلقائي.", "abusefilter-reautoconfirm-notallowed": "أنت غير مسموح لك باسترجاع حالة التأكيد التلقائي.", "abusefilter-reautoconfirm-done": "حالة التأكيد التلقائي للحساب تمت استعادتها", - "abusefilter-status": "من آخر $1 {{PLURAL:$1|فعل|فعل}}، $2 ($3%) {{PLURAL:$2|وصل|وصل}} إلى حد الحالة ل$4. $5 ($6%) {{PLURAL:$5|طابق|طابق}} واحدا من المرشحات المفعلة حاليا.", + "abusefilter-status": "من آخر $1 {{PLURAL:$1|فعل|أفعال}}، $2 ($3%) {{PLURAL:$2|قد}} وصل إلى الحد الشرطي البالغ $4، و$5 ($6%) {{PLURAL:$5|قد}} طابق واحدا على الأقل من المرشحات الممكنة حاليا.", "abusefilter-edit": "تحرير مرشح الإساءة", - "abusefilter-edit-subtitle": "تعديل المُرشِّح $1", + "abusefilter-edit-subtitle": "تعديل المرشح $1", "abusefilter-edit-subtitle-new": "أنشئ مُرشِّحًا", "abusefilter-edit-token-not-match": "لم يتم حفظ التعديل! يُرجَى الحفظ مرة أخرى.", "abusefilter-edit-oldwarning": "<strong>أنت تعدل نسخة قديمة من هذا المرشح.\nالإحصاءات الموجودة هي لأحدث نسخة من المرشح.\nلو أنك حفظت تغييراتك، فستكتب على كل التغييرات منذ المراجعة التي تعدلها.</strong> • [[Special:AbuseFilter/history/$2|رجوع إلى تاريخ هذا المرشح]]", + "abusefilter-edit-oldwarning-view": "<strong>أنت تعرض نسخة قديمة من هذا المرشح\nالإحصاءات المقتبسة تخص أحدث إصدار من المرشح.</strong> •\n[[Special:AbuseFilter/history/$2|ارجع إلى سجل هذا المرشح]].", "abusefilter-edit-status-label": "إحصاءات:", - "abusefilter-edit-status": "من آخر $1 {{PLURAL:$1|تعديل}}، هذا المرشح طابق $2 ($3%).", - "abusefilter-edit-status-profile": "من آخر $1 {{PLURAL:$1|تعديل|تعديل}}، هذا المرشح طابق $2 ($3%).\nفي المتوسط، زمن تشغيله هو $4 مللي ثانية، ويستهلك $5 {{PLURAL:$5|شرط|شرط}} من شرط الحد.", + "abusefilter-edit-status": "من آخر $1 {{PLURAL:$1|تعديل}}، هذا المرشح طابق $2 ($3%).\nفي المتوسط، تبلغ مدة تشغيله $4 مللي ثانية، ويستهلك $5 {{PLURAL:$5|شرط|شروط}} لحد الشرط.", "abusefilter-edit-throttled-warning": "'''تحذير:'''تم التعليم على هذا المرشح تلقائيا على أنه ضار; كتدبير أمان، لن يتم تنفيذ الإجراءات التالية ($1)، تُرجَى مراجعة و[[mw:Extension:AbuseFilter/Conditions|تحسين]] شروطك لإزالة هذا التقييد", "abusefilter-edit-new": "مرشح جديد", - "abusefilter-edit-save": "حفظ المُرشِّح", - "abusefilter-edit-id": "رقم المُرشِّح:", + "abusefilter-edit-save": "حفظ المرشح", + "abusefilter-edit-id": "رقم المرشح:", "abusefilter-edit-switch-editor": "تبديل المحرر", "abusefilter-edit-description": "الوصف:\n:''(معروض علنيًا)''", "abusefilter-edit-field-description": "وصف", "abusefilter-edit-group": "تصفية المجموعة:", "abusefilter-edit-flags": "الأعلام:", - "abusefilter-edit-enabled": "فعّل هذا المُرشِّح", + "abusefilter-edit-enabled": "تفعيل هذا المرشح", "abusefilter-edit-deleted": "التعليم كمحذوف", "abusefilter-edit-hidden": "إخفاء تفاصيل هذا المرشح من العرض العلني", "abusefilter-edit-global": "مرشح عام", @@ -210,7 +223,7 @@ "abusefilter-edit-notes": "ملاحظات:", "abusefilter-edit-lastmod": "رشح المعدل آخرا", "abusefilter-edit-lastmod-text": "$1 بواسطة $2", - "abusefilter-edit-hitcount": "ضربات المُرشِّح:", + "abusefilter-edit-hitcount": "ضربات المرشح:", "abusefilter-edit-consequences": "الأفعال المتخذة عند التطابق", "abusefilter-edit-action-warn": "نفذ هذه الأفعال بعد إعطاء المستخدم تحذيرا", "abusefilter-edit-action-disallow": "امنع المستخدم من عمل الفعل المقصود", @@ -219,31 +232,36 @@ "abusefilter-edit-action-block": "امنع المستخدم و/أو عنوان الأيبي من التحرير", "abusefilter-edit-action-blocktalk": "منع المستخدم و/أو عنوان الآيبي من تحرير صفحة نقاشهم الخاصة", "abusefilter-edit-action-throttle": "نفذ الأفعال فقط إذا ما تجاوز المستخدم حد المعدل", - "abusefilter-edit-action-rangeblock": "امنع نطاق الآيبي المخصص الذي يأتي منه المستخدم.", + "abusefilter-edit-action-rangeblock": "امنع نطاق الأيبي المخصص الذي يأتي منه المستخدم", "abusefilter-edit-action-tag": "اوسم التعديل لمراجعة أخرى.", "abusefilter-edit-throttle-count": "عدد الأفعال المسموح بها:", "abusefilter-edit-throttle-period": "الفترة الزمنية (بالثواني):", "abusefilter-edit-throttle-groups": "خنق المجموعة بواسطة:", - "abusefilter-edit-throttle-ip": "عنوان الآيبي", - "abusefilter-edit-throttle-user": "حساب المستخدم", - "abusefilter-edit-throttle-range": "نطاق /16", - "abusefilter-edit-throttle-creationdate": "وقت خادم إنشاء الحساب", - "abusefilter-edit-throttle-editcount": "عدد التعديلات", - "abusefilter-edit-throttle-site": "الموقع كله", - "abusefilter-edit-throttle-page": "صفحة", + "abusefilter-edit-throttle-groups-help": "انظر $1.", + "abusefilter-edit-throttle-groups-help-text": "التوثيق على mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "انقسام بفواصل للانضمام إلى AND، ومع وجود فواصل خطية للانضمام إلى OR", + "abusefilter-edit-throttle-placeholder": "انقسام بفواصل للانضمام إلى AND، وإدراج واحدا تلو الآخر للانضمام إلى OR", + "abusefilter-throttle-ip": "عنوان الآيبي", + "abusefilter-throttle-user": "حساب المستخدم", + "abusefilter-throttle-range": "نطاق /16", + "abusefilter-throttle-creationdate": "تاريخ إنشاء الحساب", + "abusefilter-throttle-editcount": "عدد التعديلات", + "abusefilter-throttle-site": "الموقع كله", + "abusefilter-throttle-page": "صفحة", + "abusefilter-throttle-none": "(لا شيء)", "abusefilter-throttle-details": "السماح بـ$1 {{PLURAL:$1|إجراء|إجراءات}} كل $2 {{PLURAL:$2|ثانية|ثوانٍ}}، خنق المجموعة\nبواسطة: $3", "abusefilter-edit-warn-message": "رسالة النظام للاستخدام عند التحذير:", "abusefilter-edit-warn-other": "رسالة أخرى", "abusefilter-edit-warn-other-label": "اسم صفحة الرسالة الأخرى:\n:''(بدون بادئة \"ميدياويكي:\")''", "abusefilter-edit-warn-actions": "أفعال:", - "abusefilter-edit-warn-preview": "إظهار/إخفاء معاينة الرسالة المحددة", + "abusefilter-edit-warn-preview": "إظهار/إخفاء معاينة الرسالة المختارة", "abusefilter-edit-warn-edit": "أنشئ/عدل الرسالة المختارة", "abusefilter-edit-disallow-message": "رسالة النظام لاستخدامها لعدم السماح:", "abusefilter-edit-disallow-other": "رسالة أخرى", "abusefilter-edit-disallow-other-label": "اسم صفحة الرسالة الأخرى:\n:''(بدون بادئة \"ميدياويكي:\")''", "abusefilter-edit-disallow-actions": "أفعال:", - "abusefilter-edit-disallow-preview": "إظهار/إخفاء معاينة الرسالة المحددة", - "abusefilter-edit-disallow-edit": "إنشاء/تحرير الرسالة المحددة", + "abusefilter-edit-disallow-preview": "إظهار/إخفاء معاينة الرسالة المختارة", + "abusefilter-edit-disallow-edit": "أنشئ/عدل الرسالة المختارة", "abusefilter-edit-tag-tag": "[[Special:Tags|وسوم]] للتطبيق:", "abusefilter-edit-tag-placeholder": "إضافة وسوم (واحدا تلو الآخر أو مفصولة بفواصل)", "abusefilter-edit-tag-hidden-placeholder": "إضافة علامات (بينها بفواصل)", @@ -253,8 +271,8 @@ "abusefilter-block-user": "منع المستخدمين المسجلين", "abusefilter-block-talk": "منع صفحة النقاش", "abusefilter-edit-denied": "قد لا يمكنك رؤية تفاصيل هذا المرشح، لأنه مخفي من العرض العلني.", - "abusefilter-edit-main": "مُحدّدات المُرشِّح", - "abusefilter-edit-done-subtitle": "تم تعديل المُرشِّح", + "abusefilter-edit-main": "محددات المرشح", + "abusefilter-edit-done-subtitle": "تم تعديل المرشح", "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|تغييراتك]] إلى [[Special:AbuseFilter/$1|المرشح $3]] قد حفظت.", "abusefilter-edit-badsyntax": "هناك خطأ صياغة في المرشح الذي حددته. الخرج من المحلل كان: <pre>$1</pre>", "abusefilter-edit-missingfields": "الحقول التالية مطلوبة ويجب ملؤها: $1", @@ -266,14 +284,22 @@ "abusefilter-edit-badfilter": "المرشح الذي حددته غير موجود", "abusefilter-edit-revert": "استرجاع الأفعال التي قام بها هذا المرشح", "abusefilter-edit-tools": "أدوات:", - "abusefilter-edit-test-link": "اختبر هذا المرشح ضد التعديلات الحديثة", - "abusefilter-edit-export": "صدر هذا المرشح لويكي آخر", + "abusefilter-edit-test-link": "اختبار هذا المرشح ضد التعديلات الحديثة", + "abusefilter-edit-export": "تصدير هذا المرشح لويكي آخر", "abusefilter-edit-syntaxok": "لم يُكتشف أي خطأ صياغي.", "abusefilter-edit-syntaxerr": "أكشفت خطأ صياغة: $1", + "abusefilter-edit-warn-leave": "سيؤدي ترك الصفحة إلى فقدان أي تغيير تم إجراؤه على هذا المرشح.", "abusefilter-edit-bad-tags": "واحدة أو أكثر من الوسوم التي حددتها غير صالحة،\nيجب أن تكون الوسوم قصيرة وألا تحتوي على أحرف خاصة، ويجب ألا يتم حجزها بواسطة برامج أخرى، جرب اختيار اسم وسم جديد", "abusefilter-edit-notallowed": "لا يسمح لك بإنشاء أو تعديل مرشحات الإساءة", "abusefilter-edit-notallowed-global": "لا يسمح لك بإنشاء أو تعديل مرشحات الإساءة الشاملة", - "abusefilter-edit-notallowed-global-custom-msg": "رسائل تحذير مخصصة غير معتمدة للمرشحات العالمية", + "abusefilter-edit-notallowed-global-custom-msg": "رسائل التحذير أو المنع المخصصة غير مدعومة للمرشحات العالمية", + "abusefilter-edit-invalid-warn-message": "لا يمكن ترك رسالة التحذير فارغة.", + "abusefilter-edit-invalid-disallow-message": "لا يمكن ترك رسالة عدم السماح فارغة.", + "abusefilter-edit-invalid-throttlecount": "يجب أن يكون عدد إجراءات الخنق عددا صحيحا موجبا.", + "abusefilter-edit-invalid-throttleperiod": "يجب أن تكون فترة الخنق عددا صحيحا موجبا.", + "abusefilter-edit-empty-throttlegroups": "يجب تحديد مجموعة خنق واحدة على الأقل.", + "abusefilter-edit-duplicated-throttlegroups": "لا يمكن أن تحتوي مجموعات الخنق على تكرارات.", + "abusefilter-edit-invalid-throttlegroups": "مجموعات الخنق المحددة غير صالحة.", "abusefilter-edit-builder-select": "اختر خيارا لإضافته عند البكرة", "abusefilter-edit-builder-group-op-arithmetic": "معاملات حسابية", "abusefilter-edit-builder-op-arithmetic-addition": "جمع (+)", @@ -304,7 +330,8 @@ "abusefilter-edit-builder-misc-contains": "السلسلة اليسرى تحتوي على السلسلة اليمنى (contains)", "abusefilter-edit-builder-misc-stringlit": "سلسلة حرفية (\"\")", "abusefilter-edit-builder-misc-tern": "معامل تيرنيري (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "شرطي (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "شرطي (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "شرطية قصيرة (if X then Y end)", "abusefilter-edit-builder-group-funcs": "دوال", "abusefilter-edit-builder-funcs-length": "طول السلسلة (length)", "abusefilter-edit-builder-funcs-lcase": "إلى حروف صغيرة (lcase)", @@ -375,12 +402,12 @@ "abusefilter-edit-builder-vars-all-links": "كل الوصلات الخارجية في النص الجديد", "abusefilter-edit-builder-vars-added-links": "كل الوصلات الخارجية المضافة في التعديل", "abusefilter-edit-builder-vars-removed-links": "كل الوصلات الخارجية المزالة في التعديل", - "abusefilter-edit-builder-vars-old-text": "نص الويكي القديم للصفحة، قبل التعديل (لم يعد قيد الاستخدام)", - "abusefilter-edit-builder-vars-new-text": "نص الويكي الجديد للصفحة، بعد التعديل", + "abusefilter-edit-builder-vars-old-wikitext": "نص الويكي القديم للصفحة، قبل التعديل", + "abusefilter-edit-builder-vars-new-wikitext": "نص الويكي الجديد للصفحة، بعد التعديل", "abusefilter-edit-builder-vars-new-pst": "نص الويكي للصفحة الجديدة، تحول قبل الحفظ", "abusefilter-edit-builder-vars-diff-pst": "الفرق الموحد للتغييرات التي تم إجراؤها بواسطة التعديل، تحول قبل الحفظ", "abusefilter-edit-builder-vars-addedlines-pst": "الخطوط المضافة في التحرير، تحول قبل الحفظ", - "abusefilter-edit-builder-vars-new-text-stripped": "نص الصفحة الجديد، مجردا من أي تهيئة", + "abusefilter-edit-builder-vars-new-text": "نص الصفحة الجديد، مجردا من أية تهيئة", "abusefilter-edit-builder-vars-new-html": "مصدر HTML المعروض للمراجعة الجديدة", "abusefilter-edit-builder-vars-restrictions-edit": "مستوى حماية التعديل للصفحة", "abusefilter-edit-builder-vars-restrictions-move": "مستوى حماية النقل للصفحة", @@ -394,10 +421,10 @@ "abusefilter-edit-builder-vars-movedto-restrictions-move": "مستوى حماية نقل صفحة الوجهة", "abusefilter-edit-builder-vars-movedto-restrictions-create": "مستوى حماية إنشاء صفحة الوجهة", "abusefilter-edit-builder-vars-movedto-restrictions-upload": "مستوى حماية رفع ملف الوجهة", - "abusefilter-edit-builder-vars-old-text-stripped": "نص الصفحة القديم، منزوع منه أي تهيئة", + "abusefilter-edit-builder-vars-old-text": "نص الصفحة القديم، مجرد من أية تهيئة (لم يعد قيد الاستخدام)", "abusefilter-edit-builder-vars-old-links": "الوصلات في الصفحة، قبل التعديل", "abusefilter-edit-builder-vars-old-html": "نص الويكي للصفحة الأصلية، المحلل إلى HTML (لم يعد قيد الاستخدام)", - "abusefilter-edit-builder-vars-minor-edit": "ما إذا كان التعديل معلم عليه كطفيف أم لا", + "abusefilter-edit-builder-vars-minor-edit": "ما إذا كان التعديل معلم عليه كطفيف (لا مزيد من الاستخدام)", "abusefilter-edit-builder-vars-file-sha1": "هاش SHA1 لمحتويات الملف", "abusefilter-edit-builder-vars-file-size": "حجم الملف بالبايت", "abusefilter-edit-builder-vars-file-mime": "نوع MIME للملف", @@ -405,6 +432,8 @@ "abusefilter-edit-builder-vars-file-width": "عرض الملف بالبكسل", "abusefilter-edit-builder-vars-file-height": "ارتفاع الملف بالبكسل", "abusefilter-edit-builder-vars-file-bits-per-channel": "بت لكل قناة لون للملف", + "abusefilter-edit-builder-vars-wiki-name": "اسم قاعدة البيانات للويكي", + "abusefilter-edit-builder-vars-wiki-language": "كود اللغة للويكي", "abusefilter-filter-log": "تغييرات المرشح الأخيرة", "abusefilter-history": "غير التاريخ لمرشح الإساءة #$1", "abusefilter-history-foruser": "تغييرات من قبل $1", @@ -438,13 +467,16 @@ "abusefilter-exception-dividebyzero": "محاولة غير قانونية لقسمة $2 على صفر عند الحرف $1.", "abusefilter-exception-unrecognisedvar": "متغير غير متعرف عليه $2 عند الحرف $1", "abusefilter-exception-notenoughargs": "لا محددات كافية للدالة $2 المطلوبة عند الحرف $1.\nتوقع $3 {{PLURAL:$3|محدد|محدد}}، حصل على $4", + "abusefilter-exception-toomanyargs": " تم استدعاءالعديد من الوسيطات للدالة $2 في الحرف $1.\nمن المتوقع بحد أقصى $3 {{PLURAL:$3|وسيط|وسائط}}، حصلت على $4", "abusefilter-exception-regexfailure": "خطأ في التعبير المنتظم \"$2\" عند الحرف $1.", - "abusefilter-exception-overridebuiltin": "تجاوز غير قانوني لمتغير موجود مسبقا \"$2\" عند الحرف $1.", + "abusefilter-exception-overridebuiltin": "تجاوز غير قانوني لمعرف مدمج في \"$2\" عند الحرف $1.", "abusefilter-exception-outofbounds": "طلب عنصر مصفوفة غير موجود $2 (حجم المصفوفة = $3) عند الحرف $1.", + "abusefilter-exception-negativeindex": "المؤشرات السالبة غير مسموح بها في المصفوفات، حصلت على المؤشر \"$2\" في الحرف $1.", "abusefilter-exception-notarray": "طلب مدخلة مصفوفة لغير مصفوفة عند الحرف $1.", "abusefilter-exception-unclosedcomment": "تعليق غير مغلق في الحرف $1.", - "abusefilter-exception-invalidiprange": "نطاق عنوان آيبي غير صالح \"$2\" متوفر بالحرف $1.", + "abusefilter-exception-invalidiprange": "نطاق عنوان أيبي غير صالح \"$2\" متوفر بالحرف $1.", "abusefilter-exception-disabledvar": "لم يعد المتغير $2 عند الحرف $1 قيد الاستخدام.", + "abusefilter-exception-variablevariable": "set وset_var يتوقعان أن تكون الوسيطة الأولى عبارة عن سلسلة حرفية، موجودة في الحرف $1.", "abusefilter-action-tag": "وسم", "abusefilter-action-throttle": "حد", "abusefilter-action-warn": "تحذير", @@ -507,15 +539,16 @@ "abusefilter-examine-noresults": "لا نتائج تم الحصول عليها لمحددات البحث التي وفرتها.", "abusefilter-topnav": "'''تصفح مرشح الإساءة'''", "abusefilter-topnav-home": "الرئيسية", + "abusefilter-topnav-recentchanges": "أحدث تغييرات المرشحات", "abusefilter-topnav-test": "اختبار الباتش", "abusefilter-topnav-examine": "افحص التعديلات الماضية", "abusefilter-topnav-log": "سجل الإساءة", "abusefilter-topnav-tools": "أدوات الإصلاح", - "abusefilter-topnav-import": "استيراد المرشح", "abusefilter-log-name": "سجل مرشح الإساءة", "abusefilter-log-header": "هذا السجل يعرض ملخصا للتغييرات التي أجريت للمرشحات.\nللتفاصيل الكاملة، انظر [[Special:AbuseFilter/history|قائمة]] تغييرات المرشحات الحديثة.", "abusefilter-logentry-create": "$1 {{GENDER:$2|أنشأ}} $4 ($5)", "abusefilter-logentry-modify": "$1 {{GENDER:$2|عدل|عدلت}} $4 ($5)", + "abusefilter-log-invalid-filter": "بعض معرفات المرشحات المحددة غير صالحة.", "abusefilter-log-noresults": "لا توجد نتائج.", "abusefilter-diff-title": "فروقات بين النسخ", "abusefilter-diff-item": "عنصر", @@ -530,9 +563,9 @@ "abusefilter-import-submit": "استيراد البيانات", "abusefilter-group-default": "افتراضي", "abusefilter-http-error": "حدث خطأ HTTP: $1.", - "abusefilter-view-private-submit": "عرض التفاصيل الخاصة", - "abusefilter-view-private": "عرض التفاصيل الخاصة", - "abusefilter-view-private-reason": "سبب الدخول إلى التفاصيل الخاصة:", + "abusefilter-view-privatedetails-submit": "عرض التفاصيل الخاصة", + "abusefilter-view-privatedetails-legend": "عرض التفاصيل الخاصة", + "abusefilter-view-privatedetails-reason": "سبب الدخول إلى التفاصيل الخاصة:", "abusefilter-log-details-id": "معرف السجل", "abusefilter-invalid-request": "طلب غير صالح! يجب عليك الوصول إلى تفاصيل السجل الخاص من خلال النموذج في [[Special:AbuseLog/$1]] وتقديم سبب.", "abusefilter-invalid-request-noid": "طلب غير صالح! يجب عليك الوصول إلى تفاصيل السجل الخاص من خلال النموذج الموجود في صفحة تفاصيل سجل الإساءة وتقديم سبب.", @@ -540,6 +573,6 @@ "abusefilter-noreason": "تحذير: لمشاهدة التفاصيل الخاصة لهذا السجل; يجب تقديم سبب.", "abusefilter-log-ip-not-available": "غير متاح", "abusefilter-tag-reserved": "تم حجز الوسم <code>abusefilter-condition-limit</code> للاستخدام الداخلي بواسطة مرشح الإساءة.", - "tag-abusefilter-condition-limit": "تم التوصل إلى حد الشرط", + "tag-abusefilter-condition-limit": "تم الوصول إلى حد الشرط", "tag-abusefilter-condition-limit-description": "التعديلات أو الأحداث الأخرى التي لا يمكن التحقق منها من قبل جميع [[Special:AbuseFilter|مرشحات الإساءة]] النشطة ([[mw:Extension:AbuseFilter/Conditions|مساعدة]])." } diff --git a/AbuseFilter/i18n/arc.json b/AbuseFilter/i18n/arc.json index da38c839..87cddbf7 100644 --- a/AbuseFilter/i18n/arc.json +++ b/AbuseFilter/i18n/arc.json @@ -5,10 +5,9 @@ "Michaelovic" ] }, - "abusefilter": "ܛܟܣ ܡܨܦܝܢܝܬܐ ܕܚܘܒܠܐ", - "abuselog": "ܡܟܬܒܘܬܐ ܕܚܘܒܠܐ", + "abusefilter": "ܕܘܒܪܐ ܕܡܨܦܝܢܝܬܐ ܕܚܘܒܠܐ", + "abuselog": "ܣܓܠܐ ܕܡܨܦܝܢܝܬܐ ܕܚܘܒܠܐ", "abusefilter-blocker": "ܡܨܦܝܢܝܬܐ ܕܚܘܒܠܐ", - "abusefilter-log": "ܣܓܠܐ ܕܡܨܦܝܢܝܬܐ ܕܚܘܒܠܐ", "abusefilter-log-summary": "ܗܢܐ ܣܓܠܐ ܬܚܘܝ ܡܟܬܒܘܬܐ ܕܟܠ ܥܒܕ̈ܐ ܕܒܝܩܝܢ ܒܝܕ ܡܨܦܝܢܝܬ̈ܐ.", "abusefilter-log-search": "ܒܨܝ ܡܟܬܒܘܬܐ ܕܚܘܒܠܐ", "abusefilter-log-search-user": "ܡܦܠܚܢܐ:", @@ -21,11 +20,10 @@ "abusefilter-log-diff": "ܦܘܪܫܐ", "abusefilter-log-hidelink": "ܐܚܘܕ ܚܙܬܐ", "abusefilter-log-details-val": "ܛܝܡܐ", - "abusefilter-log-details-private": "ܓܠܝܬ̈ܐ ܐܪ̈ܙܢܝܬܐ", + "abusefilter-log-details-privatedetails": "ܓܠܝܬ̈ܐ ܐܪ̈ܙܢܝܬܐ", "abusefilter-log-noactions": "ܠܐ ܡܕܡ", "abusefilter-log-linkoncontribs": "ܡܟܬܒܘܬܐ ܕܚܘܒܠܐ", "abusefilter-log-hide-reason": "ܥܠܬܐ:", - "abusefilter-management": "ܕܘܒܪܐ ܕܡܨܦܝܢܝܬܐ ܕܚܘܒܠܐ", "abusefilter-list": "ܟܠ ܡܨܦܝܢܝܬ̈ܐ", "abusefilter-list-id": "ܗܝܝܘܬܐ ܕܡܨܦܝܢܝܬܐ", "abusefilter-list-status": "ܐܝܟܢܝܘܬܐ", @@ -43,6 +41,7 @@ "abusefilter-deleted": "ܫܝܦܐ", "abusefilter-disabled": "ܠܐ ܬܘܦܥܠܐ", "abusefilter-new": "ܒܪܝ ܡܨܦܝܢܝܬܐ ܚܕܬܐ", + "abusefilter-import-button": "ܡܥܠܢܘܬܐ ܕܡܨܦܝܢܝܬܐ", "abusefilter-status-global": "ܓܘܢܝܐ", "abusefilter-list-options": "ܓܒܝܬ̈ܐ", "abusefilter-list-options-deleted": "ܡܨܦܝܢܝܬ̈ܐ ܫܝܦܬ̈ܐ:", @@ -130,7 +129,6 @@ "abusefilter-topnav-examine": "ܒܚܘܪ ܫܘܚܠܦ̈ܐ ܕܕܥܒܪ", "abusefilter-topnav-log": "ܡܟܬܒܘܬܐ ܕܚܘܒܠܐ", "abusefilter-topnav-tools": "ܡܐܢ̈ܐ ܕܚܕܬܘܬܐ", - "abusefilter-topnav-import": "ܡܥܠܢܘܬܐ ܕܡܨܦܝܢܝܬܐ", "abusefilter-log-name": "ܣܓܠܐ ܕܡܨܦܝܢܝܬܐ ܕܚܘܒܠܐ", "abusefilter-log-noresults": "ܠܝܬ ܦܠܛ̈ܐ", "abusefilter-diff-title": "ܦܘܪ̈ܫܐ ܒܝܢܬ ܨܚܚ̈ܐ", diff --git a/AbuseFilter/i18n/arz.json b/AbuseFilter/i18n/arz.json index dec22514..338456f3 100644 --- a/AbuseFilter/i18n/arz.json +++ b/AbuseFilter/i18n/arz.json @@ -2,15 +2,15 @@ "@metadata": { "authors": [ "Ghaly", + "Matma Rex", "Meno25", "OsamaK", - "Ramsis II", - "Matma Rex" + "Ramsis II" ] }, "abusefilter-desc": "يطبق قواعد آليه على التعديلات.", - "abusefilter": "ضبط مرشح الإساءة", - "abuselog": "سجل الإساءة", + "abusefilter": "التحكم بمرشح الإساءة", + "abuselog": "سجل مرشح الإساءة", "abusefilter-intro": "مرحبا بك إلى واجهه التحكم بمرشح الإساءه.\nمرشح الإساءه هو ميكانيكيه برمجيه آليه لتطبيق ضوابط تلقائيه لكل الأفعال.\nهذه الواجهه تعرض قائمه بالمرشحات المعرفه، وتسمح بتعديلها.", "abusefilter-warning": "'''تحذير''': الإجراء ده أُعتبر مضر.\nهايتم استرجاع التعديلات المضره بسرعه،\nوالتعديل المضر المتكرر أو المستمر هايتسبب فيى منع حسابك أو الكمبيوتر بتاعك .\nإذا كنت فاكر إن التعديل ده كويس، فممكن تضغط \"أرسل\" مرة تانيه.\nوصف مختصر لقاعدة الإساءه : $1", "abusefilter-disallowed": "هذا الفعل تم التعرف عليه تلقائيا كضار،\nولذا تم منعه.\nلو كنت تعتقد أن تعديلك بناء، من فضلك اتصل بإدارى، وأخبره بما كنت تحاول أن تفعل.\nوصف مختصر لقاعده الإساءه التى طابقها فعلك هو: $1", @@ -25,7 +25,7 @@ "right-abusefilter-view": "اعرض مرشحات الإساءة", "right-abusefilter-log": "عرض سجل الإساءة", "right-abusefilter-log-detail": "عرض مدخلات سجل الإساءه المفصلة", - "right-abusefilter-private": "عرض البيانات السريه فى سجل الإساءة", + "right-abusefilter-privatedetails": "عرض البيانات السريه فى سجل الإساءة", "right-abusefilter-modify-restricted": "عدل مرشحات الإساءه مع الأفعال المحظورة", "right-abusefilter-revert": "استرجع كل التعديلات لمرشح إساءه محدد.", "right-abusefilter-view-private": "اعرض مرشحات الإساءه المعلّمه كخاصة", @@ -34,20 +34,19 @@ "action-abusefilter-view": "رؤيه مرشحات الإساءة", "action-abusefilter-log": "رؤيه سجل الإساءة", "action-abusefilter-log-detail": "رؤيه مدخلات سجل الإساءه المفصلة", - "action-abusefilter-private": "رؤيه البيانات السريه فى سجل الإساءة", + "action-abusefilter-privatedetails": "رؤيه البيانات السريه فى سجل الإساءة", "action-abusefilter-modify-restricted": "تعديل مرشحات الإساءه بالأفعال المحظورة", "action-abusefilter-revert": "استرجاع كل التغييرات بواسطه مرشح إساءه معطى", "action-abusefilter-view-private": "اعرض مرشحات الإساءه المعلّمه كخاصة", - "abusefilter-log": "سجل مرشح الإساءة", "abusefilter-log-summary": "هذا السجل يعرض قائمه بكل الأفعال الممسوكه بواسطه المرشحات.", "abusefilter-log-search": "بحث سجل الإساءة", "abusefilter-log-search-user": "المستخدم:", - "abusefilter-log-search-filter": "رقم المُرشِّح:", + "abusefilter-log-search-filter": "أرقام المرشحات (مفصولة ب|):", "abusefilter-log-search-title": "العنوان:", "abusefilter-log-search-wiki": "ويكى", - "abusefilter-log-search-submit": "ابحث", - "abusefilter-log-entry": "$1: $2 فعل مرشح إساءه، مؤديا الفعل \"$3\" فى $4.\nالأفعال المتخذة: $5;\nوصف المرشح: $6", - "abusefilter-log-detailedentry-meta": "$1: $2 أطلق $3، مؤديا الفعل \"$4\" فى $5.\nالأفعال المتخذة: $6;\nوصف المرشح: $7 ($8)", + "abusefilter-log-search-submit": "بحث", + "abusefilter-log-entry": "$1: $2 {{GENDER:$8|فعل}} فلتر اساءه، {{GENDER:$8|و عمل}} الفعل \"$3\" في $4.\nالافعال التى اتاخدت: $5،\nالوصف بتاع المرشح: $6", + "abusefilter-log-detailedentry-meta": "$1: $2 {{GENDER:$9|شغل}} $3; {{GENDER:$9|و عمل}} الفعل \"$4\" فى $5.\nالافعال اللى اتاخدت: $6;\nالوصف بتاع المرشح: $7 ($8)", "abusefilter-log-detailedentry-global": "المرشح العام $1", "abusefilter-log-detailedentry-local": "المرشح $1", "abusefilter-log-detailslink": "التفاصيل", @@ -56,15 +55,13 @@ "abusefilter-log-details-var": "متغير", "abusefilter-log-details-val": "قيمة", "abusefilter-log-details-vars": "محددات الفعل", - "abusefilter-log-details-private": "بيانات سرية", "abusefilter-log-details-ip": "عنوان الأيبى المصدر", "abusefilter-log-noactions": "لا شيء", "abusefilter-log-details-diff": "التغييرات المعموله فى التعديل", "abusefilter-log-linkoncontribs": "سجل الإساءة", - "abusefilter-log-linkoncontribs-text": "سجل الإساءه لهذا المستخدم", - "abusefilter-management": "التحكم بمرشح الإساءة", + "abusefilter-log-linkoncontribs-text": "سجل الإساءه {{GENDER:$1|للمستخدم ده}}", "abusefilter-list": "كل المرشحات", - "abusefilter-list-id": "رقم المُرشِّح", + "abusefilter-list-id": "رقم المرشح", "abusefilter-list-status": "الحالة", "abusefilter-list-public": "وصف علني", "abusefilter-list-consequences": "العواقب", @@ -81,6 +78,7 @@ "abusefilter-disabled": "معطل", "abusefilter-hitcount": "$1 {{PLURAL:$1|ضربة|ضربة}}", "abusefilter-new": "إنشاء مرشح جديد", + "abusefilter-import-button": "استيراد المرشح", "abusefilter-return": "رجوع إلى إداره المرشح", "abusefilter-status-global": "عام", "abusefilter-list-options": "خيارات", @@ -100,17 +98,16 @@ "abusefilter-reautoconfirm-notallowed": "أنت غير مسموح لك باسترجاع حاله التأكيد التلقائى.", "abusefilter-reautoconfirm-done": "حاله التأكيد التلقائى للحساب تمت استعادتها", "abusefilter-status": "من آخر $1 {{PLURAL:$1|فعل|فعل}}، $2 ($3%) {{PLURAL:$2|وصل|وصل}} إلى حد الحاله ل$4. $5 ($6%) {{PLURAL:$5|طابق|طابق}} واحدا من المرشحات المفعله حاليا.", - "abusefilter-edit-subtitle": "تعديل المُرشِّح $1", + "abusefilter-edit-subtitle": "تعديل المرشح $1", "abusefilter-edit-oldwarning": "<strong>أنت تعدل نسخه قديمه من هذا المرشح.\nالإحصاءات الموجوده هى لأحدث نسخه من المرشح.\nلو أنك حفظت تغييراتك، فستكتب على كل التغييرات منذ المراجعه التى تعدلها.</strong> • [[Special:AbuseFilter/history/$2|رجوع إلى تاريخ هذا المرشح]]", "abusefilter-edit-status-label": "إحصاءات:", - "abusefilter-edit-status": "من آخر $1 {{PLURAL:$1|تعديل|تعديل}}، هذا المرشح طابق $2 ($3%).", - "abusefilter-edit-status-profile": "من آخر $1 {{PLURAL:$1|تعديل|تعديل}}، هذا المرشح طابق $2 ($3%).\nفى المتوسط، زمن تشغيله هو $4 مللى ثانيه، ويستهلك $5 {{PLURAL:$5|شرط|شرط}} من شرط الحد.", + "abusefilter-edit-status": "من بين اخر $1 {{PLURAL:$1|تعديل}}، المرشح ده شغل $2 ($3%).\nفي المتوسط، مدة تشغيله هى $4 مللى ثانيه، ويستهلك $5 {{PLURAL:$5|شرط|شروط}} لحد الشرط.", "abusefilter-edit-new": "مرشح جديد", - "abusefilter-edit-save": "حفظ المُرشِّح", - "abusefilter-edit-id": "رقم المُرشِّح:", + "abusefilter-edit-save": "حفظ المرشح", + "abusefilter-edit-id": "رقم المرشح:", "abusefilter-edit-description": "الوصف:\n:''(معروض علنيا)''", "abusefilter-edit-flags": "الأعلام:", - "abusefilter-edit-enabled": "فعّل هذا المُرشِّح", + "abusefilter-edit-enabled": "تفعيل المرشح ده", "abusefilter-edit-deleted": "التعليم كمحذوفة", "abusefilter-edit-hidden": "إخفاء تفاصيل هذا المرشح من العرض العلني", "abusefilter-edit-global": "طبق هذا المرشح بشكل عام", @@ -118,7 +115,7 @@ "abusefilter-edit-notes": "ملاحظات:\n:''(سرية)", "abusefilter-edit-lastmod": "رشح المعدل آخرا", "abusefilter-edit-lastmod-text": "$1 بواسطه $2", - "abusefilter-edit-hitcount": "ضربات المُرشِّح:", + "abusefilter-edit-hitcount": "ضربات المرشح:", "abusefilter-edit-consequences": "الأفعال المتخذه عند التطابق", "abusefilter-edit-action-warn": "نفذ هذه الأفعال بعد إعطاء المستخدم تحذيرا", "abusefilter-edit-action-disallow": "امنع المستخدم من عمل الفعل المقصود", @@ -136,12 +133,12 @@ "abusefilter-edit-warn-other-label": "اسم الصفحه للرساله الأخرى:\n:''(بدون بادئه ميدياويكي)''", "abusefilter-edit-warn-actions": "أفعال:", "abusefilter-edit-warn-preview": "أظهر العرض المسبق للرساله المختارة", - "abusefilter-edit-warn-edit": "أنشيء/عدل الرساله المختارة", - "abusefilter-edit-tag-tag": "الوسوم للتنفيذ (واحد لكل سطر):", + "abusefilter-edit-warn-edit": "اعمل/عدل الرساله المختاره", + "abusefilter-edit-tag-tag": "[[Special:Tags|وسوم]] علشان التطبيق:", "abusefilter-edit-denied": "أنت لا يمكنك رؤيه تفاصيل هذا المرشح، لأنه مخفى من العرض العلني", - "abusefilter-edit-main": "مُحدّدات المُرشِّح", - "abusefilter-edit-done-subtitle": "تم تعديل المُرشِّح", - "abusefilter-edit-done": "أنت حفظت بنجاح تغييراتك للمرشح $1.", + "abusefilter-edit-main": "محددات المرشح", + "abusefilter-edit-done-subtitle": "تم تعديل المرشح", + "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|تغييراتك]] إلى [[Special:AbuseFilter/$1|المرشح $3]] اتعملها سييف.", "abusefilter-edit-badsyntax": "هناك خطأ صياغه فى المرشح الذى حددته. الخرج من المحلل كان: <pre>$1</pre>", "abusefilter-edit-restricted": "أنت لا يمكنك تعديل هذا المرشح، لأنه يحتوى على واحد أو أكثر من الأفعال المحظوره.\nمن فضلك سل مستخدما ذا سماح إضافه الأفعال المحظوره ليفعل التغيير لك.", "abusefilter-edit-viewhistory": "عرض تاريخ هذا المرشح", @@ -233,13 +230,13 @@ "abusefilter-edit-builder-vars-all-links": "كل الوصلات الخارجيه فى النص الجديد", "abusefilter-edit-builder-vars-added-links": "كل الوصلات الخارجيه المضافه فى التعديل", "abusefilter-edit-builder-vars-removed-links": "كل الوصلات الخارجيه المزاله فى التعديل", - "abusefilter-edit-builder-vars-old-text": "نص الويكى القديم للصفحه، قبل التعديل", - "abusefilter-edit-builder-vars-new-text": "نص الويكى الجديد للصفحه، بعد التعديل", - "abusefilter-edit-builder-vars-new-text-stripped": "نص الصفحه الجديد، مجردا من أى تهيئة", + "abusefilter-edit-builder-vars-old-wikitext": "نص الويكى القديم للصفحه، قبل التعديل", + "abusefilter-edit-builder-vars-new-wikitext": "نص الويكى الجديد للصفحه، بعد التعديل", + "abusefilter-edit-builder-vars-new-text": "نص الصفحه الجديد، مجردا من أى تهيئة", "abusefilter-edit-builder-vars-new-html": "مصدر HTML المعروض للمراجعه الجديدة", "abusefilter-edit-builder-vars-restrictions-edit": "مستوى حمايه التعديل للصفحة", "abusefilter-edit-builder-vars-restrictions-move": "مستوى حمايه النقل للصفحة", - "abusefilter-edit-builder-vars-old-text-stripped": "نص الصفحه القديم، منزوع منه أى تهيئة", + "abusefilter-edit-builder-vars-old-text": "نص الصفحه القديم، منزوع منه أى تهيئة", "abusefilter-edit-builder-vars-old-links": "الوصلات فى الصفحه، قبل التعديل", "abusefilter-edit-builder-vars-old-html": "نص ويكى الصفحه القديم، محلل إلى HTML", "abusefilter-edit-builder-vars-minor-edit": "ما إذا كان التعديل معلم عليه كطفيف أم لا", @@ -272,11 +269,11 @@ "abusefilter-exception-unclosedstring": "سلسله غير مغلقه تبدأ عند الحرف $1.", "abusefilter-exception-invalidoperator": "معامل غير صحيح \"$2\" عند الحرف $1.", "abusefilter-exception-unrecognisedtoken": "نص غير متعرف عليه \"$2\" عند الحرف $1.", - "abusefilter-exception-noparams": "لا محددات معطاه للداله \"$2\" عند الحرف $1.", + "abusefilter-exception-noparams": "ما حدش ادى وسايط للشغل \"$2\" بالحرف $1،\nالمتوقع $3 {{PLURAL:$3|وسيط|وسائط}}.", "abusefilter-exception-dividebyzero": "محاوله غير قانونيه لقسمه $2 على صفر عند الحرف $1.", "abusefilter-exception-unrecognisedvar": "متغير غير متعرف عليه $2 عند الحرف $1", "abusefilter-exception-notenoughargs": "لا محددات كافيه للداله $2 المطلوبه عند الحرف $1.\nتوقع $3 {{PLURAL:$3|محدد|محدد}}، حصل على $4", - "abusefilter-exception-regexfailure": "خطأ فى التعبير المنتظم \"$3\" عند الحرف $1: \"$2\"", + "abusefilter-exception-regexfailure": "غلطه فى التعبير المنتظم \"$2\" عند الحرف $1.", "abusefilter-exception-overridebuiltin": "تجاوز غير قانونى لمتغير موجود مسبقا \"$2\" عند الحرف $1.", "abusefilter-exception-outofbounds": "طلب مدخله قائمه غير موجوده $2 (حجم القائمه = $3) عند الحرف $1.", "abusefilter-exception-notarray": "طلب مدخله مصفوفه لغير مصفوفه عند الحرف $1.", @@ -290,7 +287,7 @@ "abusefilter-action-disallow": "عدم السماح", "abusefilter-revert-title": "استرجاع كامل التعديلات للمرشح $1", "abusefilter-revert-intro": "هذه الاستماره تسمح لك باسترجاع كل التغييرات المعموله بواسطه مرشح الإساءه بسبب المرشح $1.\nمن فضلك احترس عند استخدام هذه الأداه.", - "abusefilter-revert-preview-item": "$1: $2 عمل $3 فى $4.\nالأفعال للاسترجاع: $5 ($6)", + "abusefilter-revert-preview-item": "$1: $2 {{GENDER:$7|فعل}} $3 فى $4.\nالافعال اللى ممكن استرجاعها: $5 ($6)", "abusefilter-revert-search-legend": "اختر أفعال مرشح الإساءه التى تريد استرجاعها", "abusefilter-revert-periodstart": "فتره البداية:", "abusefilter-revert-periodend": "فتره النهاية:", @@ -302,7 +299,7 @@ "abusefilter-revert-reason": "استرجاع تلقائى لكل الأفعال المتخذه بواسطه مرشح الإساءه بسبب المرشح $1.\nالسبب المعطى: $2", "abusefilter-revert-reasonfield": "سبب الاسترجاع", "abusefilter-test": "اختبار المرشح على تعديلات سابقة", - "abusefilter-test-intro": "هذه الصفحه تسمح لك بالتحقق من مرشح مدخل فى الصندوق بالأسفل ضد آخر $1 {{PLURAL:$1|تغيير|تغيير}}.\nلتحميل مرشح موجود، اكتب رقم المرشح الخاص به فى الصندوق بأسفل صندوق نص التعديل، واضغط زر \"تحميل\".", + "abusefilter-test-intro": "هذه الصفحه تسمح لك بالتحقق من مرشح مدخل فى الصندوق بالأسفل ضد آخر $1 {{PLURAL:$1|تغيير}}.\nلتحميل مرشح موجود، اكتب رقم المرشح الخاص به فى الصندوق بأسفل صندوق نص التعديل، واضغط زر \"تحميل\".", "abusefilter-test-legend": "اختبار المرشح", "abusefilter-test-load-filter": "تحميل رمز تعريف المرشح:", "abusefilter-test-submit": "اختبار", @@ -336,12 +333,11 @@ "abusefilter-topnav-examine": "افحص التعديلات الماضية", "abusefilter-topnav-log": "سجل الإساءة", "abusefilter-topnav-tools": "أدوات الإصلاح", - "abusefilter-topnav-import": "استيراد المرشح", "abusefilter-log-name": "سجل مرشح الإساءة", "abusefilter-log-header": "هذا السجل يعرض ملخصا للتغييرات المعموله للمرشحات.\nللتفاصيل الكامله، انظر [[Special:AbuseFilter/history|قائمة]] تغييرات المرشحات الحديثه.", "abusefilter-diff-title": "فروقات بين النسخ", "abusefilter-diff-item": "عنصر", - "abusefilter-diff-version": "نسخه من $1 من قبل $2", + "abusefilter-diff-version": "نسخه من $1 {{GENDER:$3|اللى عملها}} $2", "abusefilter-diff-info": "معلومات أساسية", "abusefilter-diff-pattern": "شروط المرشح", "abusefilter-diff-invalid": "ليس بالإمكان إحضار النسخ المطلوبة", diff --git a/AbuseFilter/i18n/as.json b/AbuseFilter/i18n/as.json index 16f78299..bae4fcf6 100644 --- a/AbuseFilter/i18n/as.json +++ b/AbuseFilter/i18n/as.json @@ -8,14 +8,12 @@ "Psneog" ] }, - "abusefilter": "অপব্যৱহাৰ চেকনী বিন্যাস", - "abuselog": "অপব্যৱহাৰ অভিলেখ", + "abuselog": "অপব্যৱহাৰ পৰিশ্ৰাৱক অভিলেখ", "abusefilter-blocker": "অপব্যহাৰ পৰিশ্ৰাৱক", "right-abusefilter-modify": "অপব্যৱহাৰ ফিল্টাৰ সালসলনি কৰক ।", "right-abusefilter-view": "অপব্যৱহাৰ চেকনী চাওক", "action-abusefilter-modify": "অপব্যৱহাৰ ফিল্টাৰ সালসলনি কৰক ।", "action-abusefilter-view": "অপব্যৱহাৰ ছেকনী চাওক ।", - "abusefilter-log": "অপব্যৱহাৰ পৰিশ্ৰাৱক অভিলেখ", "abusefilter-log-search-user": "সদস্য:", "abusefilter-log-search-filter": "পৰিশ্ৰাৱক আইডি:", "abusefilter-log-search-title": "শিৰোনামা", @@ -28,13 +26,12 @@ "abusefilter-log-details-var": "চলক", "abusefilter-log-details-val": "মান", "abusefilter-log-details-vars": "কার্য্যৰ প্রাচলসমূহ", - "abusefilter-log-details-private": "ব্যক্তিগত তথ্য", + "abusefilter-log-details-privatedetails": "ব্যক্তিগত তথ্য", "abusefilter-log-details-ip": "আইপি ঠিকনা সংৰক্ষন কৰা হৈছে", "abusefilter-log-noactions": "একো নাই", "abusefilter-log-details-diff": "সম্পাদনাত কৰা সালসলনিসমূহ ।", "abusefilter-log-linkoncontribs": "অপব্যৱহাৰ অভিলেখ", "abusefilter-log-linkoncontribs-text": "এই সদস্যৰ বাবে অপব্যবহাৰ অভিলেখ", - "abusefilter-log-hidden": "(সংযোজন লুকায়িত)", "abusefilter-log-cannot-see-details": "ইয়াৰ সবিশেষ চোৱাৰ বাবে অনুমতি নাই ।", "abusefilter-log-details-hidden": "আপনি এই সংযোজনটো বিস্তাৰিত ভাৱে চাব নোৱাৰে, কাৰণ এইটো জনসাধাৰনক প্ৰদৰ্শনৰ পৰা লুকুৱাই ৰখা হৈছে।", "abusefilter-log-hide-legend": "অভিলেখ সংযোজন লুকুৱাই ৰাখক", diff --git a/AbuseFilter/i18n/ast.json b/AbuseFilter/i18n/ast.json index 6e7e468c..fd132064 100644 --- a/AbuseFilter/i18n/ast.json +++ b/AbuseFilter/i18n/ast.json @@ -1,14 +1,16 @@ { "@metadata": { "authors": [ + "Enolp", + "Fitoschido", + "Matma Rex", "Mr.Ajedrez", - "Xuacu", - "Matma Rex" + "Xuacu" ] }, "abusefilter-desc": "Aplica heurística automática a les ediciones.", - "abusefilter": "Configuración de la peñera d'abusos", - "abuselog": "Rexistru d'abusos", + "abusefilter": "Xestión del filtru d'abusu", + "abuselog": "Rexistru de la peñera d'abusos", "abusefilter-intro": "Bienveníu a la interfaz d'alministración de la peñera d'abusos.\nLa peñera d'abusos ye un mecanismu de software automatizáu p'aplicar heurística automática a toles aiciones.\nEsta interfaz amuesa la llista de les peñeres definíes, y permite camudales.", "abusefilter-mustviewprivateoredit": "Por razones de seguridá, solamente los usuarios con permisu pa ver les peñeres d'abusu privaes o cambiar filtros pueden usar esta interfaz.", "abusefilter-warning": "'''Avisu''': Esta aición identificóse automáticamente como perxudicial.\nLes aiciones non constructives revertiránse dafechu,\ny la repetición d'ediciones non constructives tendrá como resultáu el bloquéu de la to cuenta o direición IP.\nSi crees qu'esta aición ye constructiva, pues volver a unviala pa confirmala.\nLa descripción curtia de la regla d'abusu que s'activó cola to aición ye: $1", @@ -19,13 +21,14 @@ "abusefilter-blocker": "Peñera d'abusos", "abusefilter-blockreason": "Bloquiáu automáticamente pola peñera d'abusu.\nDescripción de la regla aplicada: $1", "abusefilter-degroupreason": "Permisos retiraos automáticamente pola peñera d'abusu.\nDescripción de la regla: $1", + "abusefilter-blockautopromotereason": "Autopromoción atrasada automáticamente pola peñera d'abusu.\nDescripción de la regla: $1", "abusefilter-accountreserved": "Esti nome de cuenta ta acutáu pa que lu use la peñera d'abusos.", "right-abusefilter-modify": "Camudar les peñeres d'abusu", "right-abusefilter-view": "Ver les peñeres d'abusu", "right-abusefilter-log": "Ver el rexistru d'abusos", "right-abusefilter-log-detail": "Ver los detalles de les entraes del rexistru d'abusos", - "right-abusefilter-private": "Ver los datos privaos del rexistru d'abusos", - "right-abusefilter-private-log": "Ver el rexistru d'accesu a detalles privaos d'AbuseFilter", + "right-abusefilter-privatedetails": "Ver los datos privaos del rexistru d'abusos", + "right-abusefilter-privatedetails-log": "Ver el rexistru d'accesu a detalles privaos d'AbuseFilter", "right-abusefilter-modify-restricted": "Camudar les peñeres d'abusu con aiciones restrinxíes", "right-abusefilter-revert": "Revertir tolos cambios fechos por una determinada peñera d'abusu", "right-abusefilter-view-private": "Ver les peñeres d'abusu marcaes como privaes", @@ -37,17 +40,22 @@ "action-abusefilter-view": "ver les peñeres d'abusu", "action-abusefilter-log": "ver el rexistru d'abusos", "action-abusefilter-log-detail": "ver los detalles de les entraes del rexistru d'abusos", - "action-abusefilter-private": "ver los datos privaos del rexistru d'abusos", - "action-abusefilter-private-log": "ver el rexistru d'accesu a detalles privaos d'AbuseFilter", + "action-abusefilter-privatedetails": "ver los datos privaos del rexistru d'abusos", + "action-abusefilter-privatedetails-log": "ver el rexistru d'accesu a detalles privaos d'AbuseFilter", "action-abusefilter-modify-restricted": "camudar les peñeres d'abusu con aiciones restrinxíes", "action-abusefilter-revert": "revertir tolos cambios fechos por una determinada peñera d'abusu", "action-abusefilter-view-private": "ver les peñeres d'abusu marcaes como privaes", "action-abusefilter-log-private": "ver rexistros de les peñeres d'abusu marcaes como privaes", - "abusefilter-log": "Rexistru de la peñera d'abusos", + "action-abusefilter-hide-log": "anubrir entraes del rexistru d'abusos", + "action-abusefilter-hidden-log": "ver les entraes anubríes del rexistru d'abusos", + "action-abusefilter-modify-global": "crear o camudar los filtros d'abusu globales", "abusefilter-log-summary": "Esti rexistru amuesa una llista de toles aiciones detectaes poles peñeres.", "abusefilter-log-search": "Guetar nel rexistru d'abusos", "abusefilter-log-search-user": "Usuariu:", - "abusefilter-log-search-filter": "IDs del filtru (separar con barres verticales):", + "abusefilter-log-search-group": "Grupu de filtros:", + "abusefilter-log-search-group-any": "Cualquiera", + "abusefilter-log-search-filter": "IDs del filtru:", + "abusefilter-log-search-filter-help": "Separar con barres verticales, prefixu con \"$1\" pa filtros globales", "abusefilter-log-search-title": "Títulu:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-impact": "Impactu:", @@ -76,7 +84,7 @@ "abusefilter-log-details-var": "Variable", "abusefilter-log-details-val": "Valor", "abusefilter-log-details-vars": "Parámetros de l'aición", - "abusefilter-log-details-private": "Detalles privaos del rexistru", + "abusefilter-log-details-privatedetails": "Detalles privaos del rexistru", "abusefilter-log-details-ip": "Direición IP d'orixe", "abusefilter-log-details-checkuser": "Comprobar usuariu", "abusefilter-log-noactions": "dengún", @@ -85,10 +93,11 @@ "abusefilter-log-linkoncontribs-text": "Rexistru d'abusos d'{{GENDER:$1|esti usuariu|esta usuaria}}", "abusefilter-log-linkonhistory": "ver el rexistru d'abusos", "abusefilter-log-linkonhistory-text": "Ver el rexistru d'abusos d'esta páxina", - "abusefilter-log-hidden": "(entrada anubría)", + "abusefilter-log-linkonundelete": "ver el rexistru d'abusos", + "abusefilter-log-linkonundelete-text": "Ver el rexistru d'abusos d'esta páxina", "abusefilter-log-hidden-implicit": "(anubríu porque se desanició la revisión)", "abusefilter-log-cannot-see-details": "Nun tienes permisu pa ver los detalles d'esta entrada.", - "abusefilter-log-cannot-see-private-details": "Nun tienes permisu pa ver los detalles privaos d'esta entrada.", + "abusefilter-log-cannot-see-privatedetails": "Nun tienes permisu pa ver los detalles privaos d'esta entrada.", "abusefilter-log-nonexistent": "Nun esiste nenguna entrada cola ID proporcionada.", "abusefilter-log-details-hidden": "Nun pues ver los detalles d'esta entrada porque ta anubría de la vista pública.", "abusefilter-log-details-hidden-implicit": "Nun pues ver los detalles d'esta entrada porque la revisión asociada ta anubrida de la vista pública.", @@ -106,9 +115,12 @@ "log-action-filter-abusefilter-create": "Creación de filtru nuevu", "log-action-filter-abusefilter-modify": "Cambéu de filtru", "log-action-filter-suppress-abuselog": "Supresiones del filtru antiabusos", + "log-action-filter-rights-blockautopromote": "Bloquiar autopromoción", + "log-action-filter-rights-restoreautopromote": "Restaurar autopromoción", "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|tuvo accesu}} a los detalles privaos de $3", + "logentry-rights-blockautopromote": "$1 {{GENDER:$2|bloquió}} la autopromoción de {{GENDER:$4|$3}} por un periodu de $5", + "logentry-rights-restoreautopromote": "$1 {{GENDER:$2|restauró}} la posibilidá d'autopromoción de {{GENDER:$4|$3}}", "abusefilterprivatedetails-log-name": "Rexistru d'accesu a detalles privaos d'AbuseFilter", - "abusefilter-management": "Xestión del filtru d'abusu", "abusefilter-list": "Tolos filtros", "abusefilter-list-id": "ID del filtru", "abusefilter-list-pattern": "Patrón", @@ -130,6 +142,7 @@ "abusefilter-throttled": "frenada", "abusefilter-hitcount": "$1 {{PLURAL:$1|activación|activaciones}}", "abusefilter-new": "Crear un nuevu filtru", + "abusefilter-import-button": "Importar un filtru", "abusefilter-return": "Volver a l'alministración del filtru", "abusefilter-status-global": "Global", "abusefilter-list-options": "Opciones", @@ -150,6 +163,7 @@ "abusefilter-list-options-search-like": "Consulta simple", "abusefilter-list-options-search-rlike": "Espresión regular", "abusefilter-list-options-search-irlike": "Espresión regular ensin estremar lletres mayúscules", + "abusefilter-list-invalid-searchmode": "El mou de busca especificáu nun ye válidu.", "abusefilter-list-regexerror": "Hebo un fallu cuando se buscaba: error de sintaxis na espresión regular.", "abusefilter-list-options-submit": "Anovar", "abusefilter-tools-text": "Equí hai delles ferramientes que puen ser afayadices pa formular y depurar los filtros d'abusu.", @@ -158,18 +172,19 @@ "abusefilter-tools-reautoconfirm": "Restaurar l'estáu autoconfirmáu", "abusefilter-tools-reautoconfirm-user": "Usuariu:", "abusefilter-tools-reautoconfirm-submit": "Re-autoconfirmar", + "abusefilter-tools-restoreautopromote": "Autopromoción restaurada mediante les ferramientes de la peñera d'abusos", "abusefilter-reautoconfirm-none": "{{GENDER:$1|Esi usuariu|Esa usuaria}} nun tuvo l'estáu d'autoconfirmación suspendíu.", "abusefilter-reautoconfirm-notallowed": "Nun tienes permisu pa restaurar l'estáu d'autoconfirmación.", "abusefilter-reautoconfirm-done": "Restauróse l'estáu d'autoconfirmación de la cuenta", - "abusefilter-status": "{{PLURAL:$1|De la última aición|De les últimes $1 aiciones}}, $2 ($3%) {{PLURAL:$2|llegó|llegaron}} a condición llende de $4, y $5 ($6%) {{PLURAL:$5|coincidió|coincidieron}} con unu de los filtros actualmente activaos.", + "abusefilter-status": "{{PLURAL:$1|De la última aición|De les últimes $1 aiciones}}, $2 ($3%) {{PLURAL:$2|llegó|llegaron}} a condición llende de $4, y $5 ($6%) {{PLURAL:$5|coincidió|coincidieron}} con polo menos unu de los filtros actualmente activaos.", "abusefilter-edit": "Editando la peñera d'abusos", "abusefilter-edit-subtitle": "Editando'l filtru $1", "abusefilter-edit-subtitle-new": "Crear un filtru", "abusefilter-edit-token-not-match": "La edición nun se guardó. Tenta volver a guardala.", "abusefilter-edit-oldwarning": "<strong>Tas editando una versión antigua d'esti filtru.\nLes estadístiques citaes son de la versión más nueva del filtru.\nSi guardes los cambios, escribirás enriba de tolos cambios dende la revisión que tas editando.</strong> •\n[[Special:AbuseFilter/history/$2|Volver al historial d'esti filtru]].", + "abusefilter-edit-oldwarning-view": "<strong>Tas viendo una versión antigua d'esti filtru.\nLes estadístiques citaes son pa la versión más recién del mesmu.</strong> •\n[[Special:AbuseFilter/history/$2|Volver al historial d'esti filtru]].", "abusefilter-edit-status-label": "Estadístiques:", - "abusefilter-edit-status": "De {{PLURAL:$1|la última aición|les $1 últimes aiciones}}, esti filtru coincidió con $2 ($3%).", - "abusefilter-edit-status-profile": "De {{PLURAL:$1|la última aición|les $1 últimes aiciones}}, esti filtru coincidió con $2 ($3%).\nDe media, el so tiempu d'execución ye de $4ms, y consume {{PLURAL:$5|una condición|$5 condiciones}} de la llende de condiciones.", + "abusefilter-edit-status": "De {{PLURAL:$1|la última aición|les $1 últimes aiciones}}, esti filtru coincidió con $2 ($3%).\nDe media, el so tiempu d'execución ye de $4ms, y consume {{PLURAL:$5|una condición|$5 condiciones}} de la llende de condiciones.", "abusefilter-edit-throttled-warning": "'''Atención:''' Esti filtru marcóse automáticamente como dañible. Como midida de seguridá, nun s'executarán les aiciones siguientes ($1). Revisa y [[mw:Extension:AbuseFilter/Conditions|ameyora]] les condiciones pa desaniciar esta torga", "abusefilter-edit-new": "Filtru nuevu", "abusefilter-edit-save": "Guardar el filtru", @@ -202,20 +217,31 @@ "abusefilter-edit-throttle-count": "Númberu d'aiciones a permitir:", "abusefilter-edit-throttle-period": "Periodu de tiempu (en segundos):", "abusefilter-edit-throttle-groups": "Agrupar la regulación por:", - "abusefilter-edit-throttle-ip": "Direición IP", - "abusefilter-edit-throttle-user": "Cuenta d'usuariu", - "abusefilter-edit-throttle-range": "rangu /16", - "abusefilter-edit-throttle-creationdate": "Hora de creación de cuenta nel sirvidor", - "abusefilter-edit-throttle-editcount": "Contador d'ediciones", - "abusefilter-edit-throttle-site": "El sitiu enteru", - "abusefilter-edit-throttle-page": "Páxina", + "abusefilter-edit-throttle-groups-help": "Ver $1.", + "abusefilter-edit-throttle-groups-help-text": "la documentación en mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Dixebrar con comes pa xunir con AND (Y), y con saltos de llinia pa xunir con OR (O)", + "abusefilter-edit-throttle-placeholder": "Dixebrar con comes pa xunir con AND (Y), y inxertar una a una pa xunir con OR (O)", + "abusefilter-throttle-ip": "direición IP", + "abusefilter-throttle-user": "cuenta d'usuariu", + "abusefilter-throttle-range": "rangu /16", + "abusefilter-throttle-creationdate": "fecha de creación de la cuenta", + "abusefilter-throttle-editcount": "contador d'ediciones", + "abusefilter-throttle-site": "el sitiu enteru", + "abusefilter-throttle-page": "páxina", + "abusefilter-throttle-none": "(nenguna)", "abusefilter-throttle-details": "Permitir $1 {{PLURAL:$1|aición|aiciones}} cada {{PLURAL:$2|segundu|$2 segundos}}, regular el grupu por: $3", "abusefilter-edit-warn-message": "Mensaxe del sistema a usar pal avisu:", "abusefilter-edit-warn-other": "Otru mensaxe", - "abusefilter-edit-warn-other-label": "Nome de páxina del otru mensaxe:\n:''(ensin el prefixu MediaWiki)''", + "abusefilter-edit-warn-other-label": "Nome de páxina del otru mensaxe:\n:''(ensin el prefixu \"MediaWiki:\")''", "abusefilter-edit-warn-actions": "Aiciones:", "abusefilter-edit-warn-preview": "Amosar/Anubrir la vista previa del mensaxe seleicionáu", "abusefilter-edit-warn-edit": "Crear/Editar el mensaxe seleicionáu", + "abusefilter-edit-disallow-message": "Mensaxe del sistema a usar pa desautorizar:", + "abusefilter-edit-disallow-other": "Otru mensaxe", + "abusefilter-edit-disallow-other-label": "Nome de páxina del otru mensaxe:\n:''(ensin el prefixu \"MediaWiki:\")''", + "abusefilter-edit-disallow-actions": "Aiciones:", + "abusefilter-edit-disallow-preview": "Amosar/Anubrir la vista previa del mensaxe seleicionáu", + "abusefilter-edit-disallow-edit": "Crear/Editar el mensaxe seleicionáu", "abusefilter-edit-tag-tag": "[[Special:Tags|Etiquetes]] a aplicar:", "abusefilter-edit-tag-placeholder": "Añadir etiquetes (una por una o separaes por comes)", "abusefilter-edit-tag-hidden-placeholder": "Añadir etiquetes (dixebraes por comes)", @@ -242,10 +268,18 @@ "abusefilter-edit-export": "Esportar esti filtru a otra wiki", "abusefilter-edit-syntaxok": "Nun se deteutaron errores de sintaxis.", "abusefilter-edit-syntaxerr": "Deteutóse un error de sintaxis: $1", + "abusefilter-edit-warn-leave": "Si abandones la páxina perderás cualesquier cambéu fechu nesti filtru.", "abusefilter-edit-bad-tags": "Una o más de les etiquetes qu'especificasti nun ye válida.\nLes etiquetes tendríen de ser curties, nun pueden contener caráuteres especiales y nun pueden tar acutaes pa otru software. Tenta escoyer otru nome pa la etiqueta.", "abusefilter-edit-notallowed": "Nun tienes permisu pa crear o editar filtros d'abusos", "abusefilter-edit-notallowed-global": "Nun tienes permisu pa crear o editar filtros d'abusos globales", - "abusefilter-edit-notallowed-global-custom-msg": "Nun se permiten los mensaxes personalizaos pa filtros globales", + "abusefilter-edit-notallowed-global-custom-msg": "Nun se permiten los mensaxes d'avisu o desautorización personalizaos pa los filtros globales", + "abusefilter-edit-invalid-warn-message": "El mensaxe d'avisu nun pué quedar en blanco.", + "abusefilter-edit-invalid-disallow-message": "El mensaxe de desautorización nun pué quedar en blanco.", + "abusefilter-edit-invalid-throttlecount": "El recuentu d'aición del frenu tien de ser un númberu enteru positivu.", + "abusefilter-edit-invalid-throttleperiod": "El periodu de frenáu tien de ser un númberu enteru positivu.", + "abusefilter-edit-empty-throttlegroups": "Tien de tar seleicionáu polo menos un grupu de frenáu.", + "abusefilter-edit-duplicated-throttlegroups": "Los grupos de frenáu nun pueden tener duplicaos.", + "abusefilter-edit-invalid-throttlegroups": "Los grupos de frenáu especificaos nun son válidos.", "abusefilter-edit-builder-select": "Seleiciona una opción p'amestala nel cursor", "abusefilter-edit-builder-group-op-arithmetic": "Operadores aritméticos", "abusefilter-edit-builder-op-arithmetic-addition": "Suma (+)", @@ -275,7 +309,8 @@ "abusefilter-edit-builder-misc-contains": "La cadena izquierda contien la cadena drecha (contains)", "abusefilter-edit-builder-misc-stringlit": "Cadena lliteral (\"\")", "abusefilter-edit-builder-misc-tern": "Operador ternariu (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Condicional (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Condicional (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "Condicional curtiu (if X then Y end)", "abusefilter-edit-builder-group-funcs": "Funciones", "abusefilter-edit-builder-funcs-length": "Llonxitú de la cadena (length)", "abusefilter-edit-builder-funcs-lcase": "A minúscules (lcase)", @@ -346,12 +381,12 @@ "abusefilter-edit-builder-vars-all-links": "Tolos enllaces esternos del nuevu testu", "abusefilter-edit-builder-vars-added-links": "Tolos enllaces esternos amestaos na edición", "abusefilter-edit-builder-vars-removed-links": "Tolos enllaces esternos desaniciaos na edición", - "abusefilter-edit-builder-vars-old-text": "Testu wiki antiguu de la páxina, antes de la edición (yá nun s'usa)", - "abusefilter-edit-builder-vars-new-text": "Testu wiki nuevu de la páxina, dempués de la edición", + "abusefilter-edit-builder-vars-old-wikitext": "Testu wiki antiguu de la páxina, antes de la edición", + "abusefilter-edit-builder-vars-new-wikitext": "Testu wiki nuevu de la páxina, dempués de la edición", "abusefilter-edit-builder-vars-new-pst": "Nuevu testu wiki de la páxina, tresformáu por pre-guardar", "abusefilter-edit-builder-vars-diff-pst": "Diff unificáu de los cambios fechos por edición, tresformaos por pre-guardáu", "abusefilter-edit-builder-vars-addedlines-pst": "Llinies amestaes na edición, tresformaes por pre-guardáu", - "abusefilter-edit-builder-vars-new-text-stripped": "Testu nuevu de la páxina, ensin dengún formatu", + "abusefilter-edit-builder-vars-new-text": "Testu nuevu de la páxina, ensin dengún formatu", "abusefilter-edit-builder-vars-new-html": "Fonte HTML analizada de la nueva revisión", "abusefilter-edit-builder-vars-restrictions-edit": "Nivel de protección d'edición de la páxina", "abusefilter-edit-builder-vars-restrictions-move": "Nivel de protección de treslláu de la páxina", @@ -365,10 +400,10 @@ "abusefilter-edit-builder-vars-movedto-restrictions-move": "Nivel de proteición de treslláu de la páxina de destín del treslláu", "abusefilter-edit-builder-vars-movedto-restrictions-create": "Proteición de creación de la páxina de destín del treslláu", "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Proteición escontra carga del ficheru destín del treslláu", - "abusefilter-edit-builder-vars-old-text-stripped": "Testu antiguu de la páxina, ensin dengún formatu", + "abusefilter-edit-builder-vars-old-text": "Testu antiguu de la páxina, ensin dengún formatu (yá nun s'usa)", "abusefilter-edit-builder-vars-old-links": "Enllaces de la páxina, enantes de la edición", "abusefilter-edit-builder-vars-old-html": "Testu wiki antiguu de la páxina, analizáu en HTML (yá nun s'usa)", - "abusefilter-edit-builder-vars-minor-edit": "Si la edición ta marcada como menor o non", + "abusefilter-edit-builder-vars-minor-edit": "Si la edición ta marcada como menor o non (yá nun s'usa)", "abusefilter-edit-builder-vars-file-sha1": "Hash SHA1 del conteníu del ficheru", "abusefilter-edit-builder-vars-file-size": "Tamañu del ficheru en bytes", "abusefilter-edit-builder-vars-file-mime": "Tipu MIME del ficheru", @@ -376,6 +411,8 @@ "abusefilter-edit-builder-vars-file-width": "Anchor del ficheru en pixels", "abusefilter-edit-builder-vars-file-height": "Altor del ficheru en pixels", "abusefilter-edit-builder-vars-file-bits-per-channel": "Bits per canal de color del ficheru", + "abusefilter-edit-builder-vars-wiki-name": "Nome de la wiki na base de datos", + "abusefilter-edit-builder-vars-wiki-language": "Códigu d'idioma de la wiki", "abusefilter-filter-log": "Cambios de recién nos filtros", "abusefilter-history": "Historial de cambios de la peñera d'abusos #$1", "abusefilter-history-foruser": "Cambios de $1", @@ -409,13 +446,16 @@ "abusefilter-exception-dividebyzero": "Intentu illegal de dividir $2 por cero nel caráuter $1.", "abusefilter-exception-unrecognisedvar": "Variable $2 non reconocida nel caráuter $1.", "abusefilter-exception-notenoughargs": "Non hai argumentos abondo pa la función $2 llamada nel caráuter $1.\n\t{{PLURAL:$3|Esperabase un argumentu|Esperabense $3 argumentos}}, tienense $4", - "abusefilter-exception-regexfailure": "Error na espresión regular \"$3\" nel caráuter $1: \"$2\"", - "abusefilter-exception-overridebuiltin": "Anulación illegal de la variable interna \"$2\" nel caráuter $1.", + "abusefilter-exception-toomanyargs": "Demasiaos argumentos para la función $2 llamada nel caráuter $1.\nEsperábase a lo más $3 {{PLURAL:$3|argumentu|argumentos}}, {{PLURAL:$4|apurrióse|apurriéronse}} $4", + "abusefilter-exception-regexfailure": "Fallu na espresión regular «$2» nel caráuter $1.", + "abusefilter-exception-overridebuiltin": "Saltu illegal del identificador internu «$2» nel caráuter $1.", "abusefilter-exception-outofbounds": "Solicitando l'elementu inesistente $2 de la matriz (tamañu de la matriz = $3) nel caráuter $1.", + "abusefilter-exception-negativeindex": "Los índices negativos nun tán permitíos nes matrices. Recibióse l'índiz «$2» nel caráuter $1.", "abusefilter-exception-notarray": "Solicitando un elementu de matriz d'una non-matriz nel caráuter $1.", "abusefilter-exception-unclosedcomment": "Comentariu sin zarrar nel carácter $1.", "abusefilter-exception-invalidiprange": "Apurrióse un intervalu d'IP inválidu, «$2», nel caráuter $1.", "abusefilter-exception-disabledvar": "La variable $2 nel carácter $1 yá nun s'usa.", + "abusefilter-exception-variablevariable": "set y set_var esperen que'l primer argumentu sía un lliteral de cadena, que s'atopa nel caráuter $1.", "abusefilter-action-tag": "Etiqueta", "abusefilter-action-throttle": "Frenar", "abusefilter-action-warn": "Avisar", @@ -478,15 +518,16 @@ "abusefilter-examine-noresults": "Nun s'alcontraron resultaos pa los parámetros de gueta que disti.", "abusefilter-topnav": "'''Navegación de la Peñera d'abusos'''", "abusefilter-topnav-home": "Entamu", + "abusefilter-topnav-recentchanges": "Cambios de recién nos filtros", "abusefilter-topnav-test": "Conxuntu de pruebes", "abusefilter-topnav-examine": "Esaminar les ediciones pasaes", "abusefilter-topnav-log": "Rexistru d'abusos", "abusefilter-topnav-tools": "Ferramientes de depuración", - "abusefilter-topnav-import": "Importar un filtru", "abusefilter-log-name": "Rexistru de la peñera d'abusos", "abusefilter-log-header": "Esti rexistru amuesa un resume de los cambios fechos nos filtros.\nPara ver los detalles completos, visita [[Special:AbuseFilter/history|la llista]] de los cambios recién fechos nos filtros.", "abusefilter-logentry-create": "$1 {{GENDER:$2|creó}}'l $4 ($5)", "abusefilter-logentry-modify": "$1 {{GENDER:$2|cambió}} el $4 ($5)", + "abusefilter-log-invalid-filter": "Dalgunos de los identificadores de filtru especificaos nun son válidos.", "abusefilter-log-noresults": "Nun hai resultaos", "abusefilter-diff-title": "Diferencies ente versiones", "abusefilter-diff-item": "Elementu", @@ -499,11 +540,12 @@ "abusefilter-diff-next": "Cambiu más nuevu", "abusefilter-import-intro": "Pues emplegar esta interfaz pa importar filtros d'otres wikis.\nNa wiki d'orixe, primi \"{{int:abusefilter-edit-export}}\" baxo \"{{int:abusefilter-edit-tools}}\" na interfaz d'edición.\nCopia del cuadru de testu qu'apaez y pégalo nesti cuadru de testu, y darréu calca \"{{int:abusefilter-import-submit}}\".", "abusefilter-import-submit": "Importar datos", + "abusefilter-import-invalid-data": "Los datos que tentasti importar nun son válidos", "abusefilter-group-default": "Predetermináu", "abusefilter-http-error": "Hebo un error HTTP: $1.", - "abusefilter-view-private-submit": "Ver detalles privaos", - "abusefilter-view-private": "Ver detalles privaos", - "abusefilter-view-private-reason": "Motivu del accesu a los detalles privaos:", + "abusefilter-view-privatedetails-submit": "Ver detalles privaos", + "abusefilter-view-privatedetails-legend": "Ver detalles privaos", + "abusefilter-view-privatedetails-reason": "Motivu del accesu a los detalles privaos:", "abusefilter-log-details-id": "ID del rexistru", "abusefilter-invalid-request": "¡Solicitú inválida! Tienes de facer l'accesu a los detalles privaos del rexistru col formulariu [[Special:AbuseLog/$1]] y dar un motivu.", "abusefilter-invalid-request-noid": "¡Solicitú inválida! Tienes de facer l'accesu a los detalles privaos del rexistru col formulariu de la páxina de detalles del rexistru d'abusos y dar un motivu.", diff --git a/AbuseFilter/i18n/av.json b/AbuseFilter/i18n/av.json index 067a1df0..ab78b440 100644 --- a/AbuseFilter/i18n/av.json +++ b/AbuseFilter/i18n/av.json @@ -1,8 +1,8 @@ { "@metadata": { "authors": [ - "Умар", - "Аль-Гимравий" + "Аль-Гимравий", + "Умар" ] }, "abusefilter-log-hide-reason": "ГӀилла:", diff --git a/AbuseFilter/i18n/awa.json b/AbuseFilter/i18n/awa.json index 45a487bf..686f263b 100644 --- a/AbuseFilter/i18n/awa.json +++ b/AbuseFilter/i18n/awa.json @@ -5,8 +5,8 @@ ] }, "abusefilter-desc": "संपादनों पर स्वतः शोध प्रणाली का प्रयोग लागू करता है", - "abusefilter": "दुरुपयोग फ़िल्टर विन्यास", - "abuselog": "दुरुपयोग लॉग", + "abusefilter": "दुरुपयोग फ़िल्टर प्रबंधन", + "abuselog": "दुरुपयोग फ़िल्टर लॉग", "abusefilter-blocker": "दुरुपयोग फ़िल्टर", "abusefilter-blockreason": "दुरुपयोग फ़िल्टर द्वारा स्वचालित रूप से अवरुद्ध।\nपकड़य वाले नियम कय संक्षिप्त विवरण है: $1", "abusefilter-degroupreason": "सदस्य अधिकार दुरुपयोग फ़िल्टर द्वारा स्वचालित रूप से वापिस लई लिहा हैं।\nपकड़य वाले नियम कय संक्षिप्त विवरण है: $1", @@ -15,7 +15,7 @@ "right-abusefilter-view": "दुरुपयोग फ़िल्टर देखा जाय", "right-abusefilter-log": "दुरुपयोग लॉग देखा जाय", "right-abusefilter-log-detail": "दुरुपयोग लॉग कय प्रविष्टि विस्तार में देखा जाय", - "right-abusefilter-private": "दुरुपयोग लॉग में निजी डेटा देखा जाय", + "right-abusefilter-privatedetails": "दुरुपयोग लॉग में निजी डेटा देखा जाय", "right-abusefilter-modify-restricted": "दुरुपयोग फ़िल्टर कय प्रतिबन्धित काम सहित सम्पादित करा जाय", "right-abusefilter-revert": "किसी एक दिए गए दुरुपयोग फ़िल्टर द्वारा किये सभी परिवर्तनों को वापिस लें", "right-abusefilter-view-private": "वो दुरुपयोग फ़िल्टर देखें जिन्हें निजी चिन्हित किया गया है", @@ -27,11 +27,10 @@ "action-abusefilter-view": "दुरुपयोग फ़िल्टर देखा जाय", "action-abusefilter-log": "दुरुपयोग लॉग देखा जाय", "action-abusefilter-log-detail": "दुरुपयोग लॉग कय प्रविष्टि विस्तार में देखा जाय", - "action-abusefilter-private": "दुरुपयोग लॉग में निजी डेटा देखा जाय", + "action-abusefilter-privatedetails": "दुरुपयोग लॉग में निजी डेटा देखा जाय", "action-abusefilter-modify-restricted": "दुरुपयोग फ़िल्टर कय प्रतिबन्धित काम सहित सम्पादित करा जाय", "action-abusefilter-revert": "किसी एक दिए गए दुरुपयोग फ़िल्टर द्वारा किये सभी परिवर्तनों को वापिस लें", "action-abusefilter-view-private": "वो दुरुपयोग फ़िल्टर देखें जिन्हें निजी चिन्हित किया गया है", - "abusefilter-log": "दुरुपयोग फ़िल्टर लॉग", "abusefilter-log-summary": "ई लॉग फ़िल्टरन् द्वारा पकड़ान् कुल काम कय सूची देखावत है।", "abusefilter-log-search": "दुरुपयोग लॉग खोज", "abusefilter-log-search-user": "सदस्य:", @@ -48,17 +47,15 @@ "abusefilter-log-details-var": "प्राचल", "abusefilter-log-details-val": "मूल्य", "abusefilter-log-details-vars": "काम कय प्राचल", - "abusefilter-log-details-private": "निजी डेटा", + "abusefilter-log-details-privatedetails": "निजी डेटा", "abusefilter-log-details-ip": "स्रोत आइ॰पी ठहर", "abusefilter-log-noactions": "केहु नाई", "abusefilter-log-details-diff": "सम्पादन में करल़ बदलाव", "abusefilter-log-linkoncontribs": "दुरुपयोग लॉग", "abusefilter-log-linkoncontribs-text": "इ सदस्य कय लिए दुरुपयोग लॉग", - "abusefilter-log-hidden": "(प्रविष्टि लुकुआवा है)", "abusefilter-log-hide-legend": "लॉग प्रविष्टि लुकुआवा जाय", "abusefilter-log-hide-id": "लॉग प्रविष्टि आइ॰डी:", "abusefilter-log-hide-reason": "कारण:", - "abusefilter-management": "दुरुपयोग फ़िल्टर प्रबंधन", "abusefilter-list": "कुल फ़िल्टर", "abusefilter-list-id": "फ़िल्टर आइ॰डी", "abusefilter-list-status": "स्थिति", diff --git a/AbuseFilter/i18n/az.json b/AbuseFilter/i18n/az.json index 5d090a51..26b9345d 100644 --- a/AbuseFilter/i18n/az.json +++ b/AbuseFilter/i18n/az.json @@ -6,14 +6,16 @@ "Hydra", "PPerviz", "Sortilegus", + "Toghrul Rahimli", "Vago", "Vugar 1981", - "Wertuose" + "Wertuose", + "Şeyx Şamil" ] }, "abusefilter-desc": "Düzəlişlərə evristik filtrlərin tətbiq olunmasına imkan verir.", - "abusefilter": "Təhqir süzgəcinin tənzimlənməsi", - "abuselog": "Təhqir jurnalı", + "abusefilter": "Təhqir süzgəclərinin idarə olunması", + "abuselog": "Təhqir süzgəci jurnalı", "abusefilter-intro": "Təhqir süzgəcinin idarəetmə səhifəsinə xoş gəlmisiniz.\nTəhqir süzgəci istifadəçilərin fəaliyyətinə avtomatik evristika tətbiq edən avtomatlaşdırılmış proqram mexanizmidir.\nBurada bütün süzgəclərin siyahısı verilib və onların dəyişdirilməsi mümkündür.", "abusefilter-warning": "'''Diqqət'''. Bu fəaliyyət avtomatik olaraq zərərli fəaliyyət kimi təyin olunmuşdur.\nQeyri-konstruktiv dəyişikliklər tezliklə ləğv ediləcək,\nkobud və ya təkrarlanan qeyri-konstruktiv düzəlişlər sizin hesabınızın və ya IP ünvanınızın bloklanmasına gətirib çıxara bilər.\nƏgər siz bunun konstruktiv düzəliş olduğuna əminsinizsə, onda bir daha təsdiq edin.\nFəaliyyətinizə müvafiq olan qaydaların qısa təsviri: $1", "abusefilter-disallowed": "Bu fəaliyyət avtomatik olaraq zərərli fəaliyyət kimi təyin olunmuş və buna görə də qəbul edilməmişdir.\nƏgər siz öz düzəlişinizin konstruktiv olduğuna əminsinizsə, zəhmət olmasa, nə etmək istədiyinizi idarəçilərdən birinə izah edin.\nFəaliyyətinizə müvafiq olan qaydaların qısa təsviri: $1", @@ -26,7 +28,7 @@ "right-abusefilter-view": "Təhqir süzgəclərinə baxış", "right-abusefilter-log": "Təhqir jurnalına baxış", "right-abusefilter-log-detail": "Təhqir jurnalındakı qeydlərə ətraflı baxış", - "right-abusefilter-private": "Təhqir jurnalındakı şəxsi məlumatlara baxış", + "right-abusefilter-privatedetails": "Təhqir jurnalındakı şəxsi məlumatlara baxış", "right-abusefilter-modify-restricted": "Fəaliyyəti məhdudlaşdıran süzgəclərin dəyişdirilməsi", "right-abusefilter-revert": "Təhqir süzgəcinin düzəlişlərini geri qaytar", "right-abusefilter-view-private": "Gizli kimi işarələnmiş təhqir süzgəclərinə bax", @@ -38,11 +40,10 @@ "action-abusefilter-view": "təhqir süzgəcinə baxmaq", "action-abusefilter-log": "təhqir jurnalına baxmaq", "action-abusefilter-log-detail": "təhqir jurnalındakı ətraflı məlumatlara baxmaq", - "action-abusefilter-private": "təhqir jurnalındakı şəxsi məlumatlara baxmaq", + "action-abusefilter-privatedetails": "təhqir jurnalındakı şəxsi məlumatlara baxmaq", "action-abusefilter-modify-restricted": "hərəkəti məhdudlaşdıran təhqir süzgəclərini dəyişmək", "action-abusefilter-revert": "bu təhqir süzgəcinin bütün düzəlişlərini ləğv etmək", "action-abusefilter-view-private": "\"gizlidir\" kimi qeyd olunmuş təhqir süzgəcinə baxmaq", - "abusefilter-log": "Təhqir süzgəci jurnalı", "abusefilter-log-summary": "Bu jurnalda süzgəclər tərəfindən müəyyən olunmuş bütün fəaliyyətlər təsvir olunub.", "abusefilter-log-search": "Təhqir jurnalında axtarış", "abusefilter-log-search-user": "İstifadəçi:", @@ -60,20 +61,19 @@ "abusefilter-log-details-var": "Dəyişən", "abusefilter-log-details-val": "Əhəmiyyəti", "abusefilter-log-details-vars": "Fəaliyyət parametrləri", - "abusefilter-log-details-private": "Şəxsi məlumatlar", + "abusefilter-log-details-privatedetails": "Şəxsi məlumatlar", "abusefilter-log-details-ip": "İstifadə olunduğu IP ünvanı", "abusefilter-log-noactions": "heç biri", "abusefilter-log-details-diff": "Redaktə zamanı edilən dəyişikliklər", "abusefilter-log-linkoncontribs": "təhqir jurnalı", "abusefilter-log-linkoncontribs-text": "Bu istifadəçi üçün təhqir jurnalındakı qeydlər", - "abusefilter-log-hidden": "(qeydlər gizlədilib)", + "abusefilter-log-linkonhistory": "təhqir jurnalına baxmaq", "abusefilter-log-details-hidden": "Bu qeydlər gizlədildiyindən, ona ətraflı baxa bilməzsiniz.", "abusefilter-log-hide-legend": "Jurnaldakı qeydləri gizlət", "abusefilter-log-hide-id": "Jurnaldakı qeydlərin ID-si:", "abusefilter-log-hide-hidden": "Bu qeydə ictimai şəkildə baxılmanı əngəllə", "abusefilter-log-hide-reason": "Səbəb:", "abusefilter-log-hide-forbidden": "Təhqir jurnalındakı qeydləri gizlətmək hüququnuz yoxdur.", - "abusefilter-management": "Təhqir süzgəclərinin idarə olunması", "abusefilter-list": "Bütün süzgəclər", "abusefilter-list-id": "Süzgəc nömrəsi", "abusefilter-list-status": "Status", @@ -92,6 +92,7 @@ "abusefilter-disabled": "Söndürülüb", "abusefilter-hitcount": "$1 dəfə {{PLURAL:$1|işə düşüb}}", "abusefilter-new": "Yeni süzəc yarat", + "abusefilter-import-button": "Süzgəc idxalı", "abusefilter-return": "Süzgəclərin idarə olunmasına qayıtmaq", "abusefilter-status-global": "Qlobal", "abusefilter-list-options": "Parametrlər:", @@ -222,6 +223,7 @@ "abusefilter-test-period-start": "Dəyişikliklər bundan sonra edilib:", "abusefilter-test-period-end": "Dəyişikliklər bundan əvvəl edilib:", "abusefilter-test-page": "Dəyişikliklər bu səhifədə edilib:", + "abusefilter-test-search-type-edit": "Redaktələr", "abusefilter-examine-legend": "Dəyişiklikləri seçilməsi", "abusefilter-examine-diff": "URL-in fərqi:", "abusefilter-examine-user": "İstifadəçi:", @@ -232,7 +234,6 @@ "abusefilter-topnav-home": "Əvvələ", "abusefilter-topnav-test": "Paket testləşdirmə", "abusefilter-topnav-log": "Təhqir jurnalı", - "abusefilter-topnav-import": "Süzgəc idxalı", "abusefilter-log-noresults": "Nəticə yoxdur", "abusefilter-diff-title": "Versiyalar arasındakı fərqlər", "abusefilter-diff-item": "Element", diff --git a/AbuseFilter/i18n/azb.json b/AbuseFilter/i18n/azb.json index ca60927d..9903074f 100644 --- a/AbuseFilter/i18n/azb.json +++ b/AbuseFilter/i18n/azb.json @@ -1,19 +1,20 @@ { "@metadata": { "authors": [ + "Alp Er Tunqa", "Amir a57", + "BaRaN6161 TURK", "E THP", "Ebrahimi-amir", - "Mousa", "Koroğlu", "Macofe", "Matma Rex", - "Alp Er Tunqa" + "Mousa" ] }, "abusefilter-desc": "دوزلیشلره ائوریستیک فیلترلرین تطبیق اولونماسینا ایمکان وئریر.", - "abusefilter": "سوی-ایستیفاده سوزگجینین تنزیملنمهسی", - "abuselog": "سوی-ایستیفاده ژورنالی", + "abusefilter": "سوی-ایستیفاده سوزگجلرینین ایداره اولونماسی", + "abuselog": "سوی-ایستیفاده سوزگجی ژورنالی", "abusefilter-intro": "سوی-ایستیفاده سوزگجینین ایدره اولونماسی صحیفهسینه خوش گلمیسینیز.\nسوی-ایستیفاده سوزگجی اؤزونده ایستیفادهچیلرین فالیتینه آوتوماتیک ائوریستیک تطبیقی مئخانیزمینی عکس ائتدیریر.\nبورادا بوتون سوزگجلرین سیاهیسی وئریلیب و اونلارین دییشیلمهسی مومکوندور.", "abusefilter-warning": "'دیققت. بو فالیت آوتوماتیک اولاراق آرزو اوئدیلمهین کیمی تعیین اولونور.\nکونستروکتیو اولمایان دییشیکلیکلر تئزلیکله لغو ائدیلهجک،\nکوبود و یا تکرار کونستروکتیو اولمایان دوزلیشلر سیزین حسابینیزین و یا ایپ اونوانینیزین بلوکلانماسینا گتیریب چیخارا بیلر.\nاگر سیز بونون کونستروکتیو دوزلیش اولدوغونا امینسینیزسه، اوندا بیر داها «گؤندر» دویمهسینه باسین،\nفالیتینیزه مووافیق اولان قایدالارین قیسا تصویری: $1", "abusefilter-disallowed": "بو حرکت آوتوماتیک اولاراق زررلی اولاراق تعیین اولونموشدور،\nو بو سببله ایجازه وئریلمیر.\nاگر دئغیشیکلیغینیزین قورولوشچو اولدوغونا اینانیرسینیزسا، لطفاً بیر ایدارهچی ایله علاقه قورون، و نه ائتمهیه چالیشدیغینیز حاقیندا معلوماتلاندیرین.\nائیلئمینیزین ائشلئشتیغی سوی-ایستیفاده قایداسینین قیسا بیر شرحی: $1", @@ -28,7 +29,7 @@ "right-abusefilter-view": "سوی-ایستیفاده سوزگجینه باخماق", "right-abusefilter-log": "سوی-ایستیفاده ژورنالینا باخماق", "right-abusefilter-log-detail": "سوی-ایستیفاده سوزگجی ژورنالیندا اطرافلی معلوماتلارا باخماق", - "right-abusefilter-private": "سوی-ایستیفاده ژورنالیدنا شخصی معلوماتلارا باخماق", + "right-abusefilter-privatedetails": "سوی-ایستیفاده ژورنالیدنا شخصی معلوماتلارا باخماق", "right-abusefilter-modify-restricted": "حرکتی مهدودلاشدیران سوزگجلرین دییشدیریلمهسی", "right-abusefilter-revert": "سوی-ایستیفاده سوزگجینین دوزلیشلرینی گئری قایتارماق", "right-abusefilter-view-private": "گیزلیدیر کیمی قئید اولونان سوی-ایستیفاده سوزگجینه باخماق", @@ -39,17 +40,17 @@ "action-abusefilter-view": "سوی-ایستیفاده سوزگجینه باخماق", "action-abusefilter-log": "سوی-ایستیفاده ژورنالینا باخماق", "action-abusefilter-log-detail": "سوی-ایستیفاده سوزگجی ژورنالیندا اطرافلی معلوماتلارا باخماق", - "action-abusefilter-private": "سوی-ایستیفاده ژورنالیدنا شخصی معلوماتلارا باخماق", + "action-abusefilter-privatedetails": "سوی-ایستیفاده ژورنالیدنا شخصی معلوماتلارا باخماق", "action-abusefilter-modify-restricted": "حرکتی مهدودلاشدیران سوی-ایستیفاده سوزگجلرین دییشدیریلمهسی", "action-abusefilter-revert": "گؤستریلن سوی-ایستیفاده سوزگجینین بوتون دوزلیشلرینی لغو ائتمک", "action-abusefilter-view-private": "گیزلیدیر کیمی قئید اولونان سوی-ایستیفاده سوزگجینه باخماق", - "abusefilter-log": "سوی-ایستیفاده سوزگجی ژورنالی", "abusefilter-log-summary": "بو ژورنالدا فیلتر بللی ائتمیش بوتون چالیشمالار گؤروشور.", "abusefilter-log-search": "سوی-ایستیفاده ژورنالیندا آختاریش", "abusefilter-log-search-user": "ایشلدنː", "abusefilter-log-search-filter": "آی-دی سوزگجی:", "abusefilter-log-search-title": "باشلیق:", "abusefilter-log-search-wiki": "ویکی:", + "abusefilter-log-search-action-taken-label": "عمل نوعو:", "abusefilter-log-search-submit": "آختار", "abusefilter-log-entry": "$1: $2 سوی-ایستیفاده سوزگجینین ایشلتمهیه مراجعت ائدیب، «$3»-اون فالیتی سدیفه $4-ده.\nگؤرولموش تدبیرلر: $5.\nسوزگجین تصویری: $6", "abusefilter-log-detailedentry-meta": "$1: $2 $3-اون ایشلمهسی اوچون مراجعت ائدیب، «$4»-اون فالیتی صحیفه $5-ده.\nگؤرولموش تدبیرلر: $6.\nسوزگجین تصویری: $7 ($8)", @@ -62,13 +63,14 @@ "abusefilter-log-details-var": "دییشن", "abusefilter-log-details-val": "اهمیتی", "abusefilter-log-details-vars": "فعالیت پارامئترلری", - "abusefilter-log-details-private": "شخصی معلوماتلار", + "abusefilter-log-details-privatedetails": "شخصی معلوماتلار", "abusefilter-log-details-ip": "ایستیفاده اولوندوغو ای پی آدرسی", + "abusefilter-log-details-checkuser": "تفتیشچیلر", "abusefilter-log-noactions": "هئچ بیری", "abusefilter-log-details-diff": "رئداکته زامانی ائدیلن دییشیکلیکلر", "abusefilter-log-linkoncontribs": "سوی-ایستیفاده ژورنالی", "abusefilter-log-linkoncontribs-text": "بو ایستیفادهچی اوچون سوی-ایستیفاده ژورنالینداکی قئیدلر", - "abusefilter-log-hidden": "(قئیدلر گیزلدیلیب)", + "abusefilter-log-linkonhistory": "سوی-ایستیفاده ژورنالینا باخماق", "abusefilter-log-hidden-implicit": "گیزلنن سیلینن نسخه کیمی اولوب", "abusefilter-log-cannot-see-details": "بو گیریش دئتاللارینی گؤره بیلمک اوچون ایجازهنیز یوخدور.", "abusefilter-log-details-hidden": "بو قئیدلر گیزلدیلدیگیندن، اونا اطرافلی باخا بیلمزسینیز.", @@ -78,7 +80,6 @@ "abusefilter-log-hide-reason": "سبب:", "abusefilter-log-hide-forbidden": "سوی-ایستیفاده ژورنالینداکی قئیدلری گیزلتمک هوقوقونوز یوخدور.", "logentry-abusefilter-hit": "$1 باعث $4 ، ایش گورمک \" $5 \" در $3 . اقداملار: $6 ( $7 )", - "abusefilter-management": "سوی-ایستیفاده سوزگجلرینین ایداره اولونماسی", "abusefilter-list": "بوتون سوزگجلر", "abusefilter-list-id": "اید سوزگجی:", "abusefilter-list-status": "وضعیت", @@ -98,6 +99,7 @@ "abusefilter-disabled": "آیریلیب", "abusefilter-hitcount": "$1 {{PLURAL:$1|اولدو|اولدولار}}", "abusefilter-new": "یئنی سوزگج یارات", + "abusefilter-import-button": "فیلتر ایدخالی", "abusefilter-return": "سوزگجلرین ایداره اولونماسینا قاییتماق", "abusefilter-status-global": "قلوبال", "abusefilter-list-options": "پارامئترلر:", @@ -119,16 +121,16 @@ "abusefilter-reautoconfirm-none": "بو {{GENDER:$1|اوز|اوز|اوز}} آوتوماتیک اونایلی دورومو آسکییا آلینمادی.", "abusefilter-reautoconfirm-notallowed": "آوتوماتیک اونایلی دورومو گئتیرمئیئ یئتکینیز یوخدور.", "abusefilter-reautoconfirm-done": "حسابین آوتوماتیک اونایلی دورومو گئری گئتیریلدی", - "abusefilter-status": "سون 1$ {{جمع: $1 | ائیلمدئ | ائیلمدئ}} $2 (% $3) فیلترئ $4 کوشول سینیرینا ائریشتی، و $5 (% $6) ائیلئم شواندا ائففئکتیو بیر فیلترئیلئ ائشلئشتی.", + "abusefilter-status": "سون 1$ {{PLURAL:$1|ائیلمدئ|ائیلمدئ}} $2 (%$3) فیلترئ $4 کوشول سینیرینا ائریشتی، و $5 (%$6) ائیلئم شواندا ائففئکتیو بیر فیلترئیلئ ائشلئشتی.", "abusefilter-edit-subtitle": "$1 سوزگجینین رئداکتهسی", "abusefilter-edit-subtitle-new": "فیلترئ اولوشتورما", "abusefilter-edit-oldwarning": "<strong>بو فیلترئنین ائسکی بیر سورومونو دئغیشتیریورسونوز.\nگؤستئریلئن ایستاتیستیکلئر بو فیلترئنین ائن سون وئرسیاسی اوچوندور.\nاگر دئغیشیکلیکلئرینیزی کایدئدئرسئنیز، دئغیشیکلیک ائتدیگینیز رئویزیوندان ایتیبارئن بوتون دئغیشیکلیکلئرین اوزئرینئ یازاجاکسینیز.</strong> •\n[[Special:AbuseFilter/history/$2|بو فیلترئنین گئچمیشینئ گئری قاییت]].", "abusefilter-edit-status-label": "ایستاتیستیکالار:", - "abusefilter-edit-status": "سون 1$ {{جمع: $1 | ائیلئمدئ | ائیلئمدئ}} بو فیلترئیلئ ائشلئشئن $2 ($3%).", - "abusefilter-edit-status-profile": "سون 1$ {{جمع: $1 | ائیلئمدئ | ائیلئمدئ}} بو فیلترئیلئ ائشلئشئن $2 ($3%).\nاورتالامادا، ایش واختی $4مس، و کوشول سینیرینین $5 کوشولونو توکئتیور.", + "abusefilter-edit-status": "سون 1$ {{PLURAL:$1|ائیلئمدئ|ائیلئمدئ}} بو فیلترئیلئ ائشلئشئن $2 ($3%).", "abusefilter-edit-new": "یئنی سوزگج", "abusefilter-edit-save": "سوزگجی یاددا ساخلا", "abusefilter-edit-id": "آی-دی سوزگجی:", + "abusefilter-edit-switch-editor": "دییشدیریجینی دَییش", "abusefilter-edit-description": "آچیکلاما:\n:' (اومومی اولاراق گؤرونئبیلیر)'", "abusefilter-edit-group": "فیلتر گروهو", "abusefilter-edit-flags": "بایراقلار:", @@ -258,14 +260,14 @@ "abusefilter-edit-builder-vars-all-links": "یئنی متندکی بوتون خاریجی کئچیدلر", "abusefilter-edit-builder-vars-added-links": "دوزلیش زامانی علاوه اولونموش بوتون خاریجی کئچیدلر", "abusefilter-edit-builder-vars-removed-links": "دوزلیش زامانی سیلینمیش بوتون خاریجی کئچیدلر", - "abusefilter-edit-builder-vars-old-text": "کؤهنه صحیفه ویکی متنی، دییشیکلیکدن قاباق", - "abusefilter-edit-builder-vars-new-text": "یئنی صحیفه ویکی متنی، دییشیکلیکدن سونرا", + "abusefilter-edit-builder-vars-old-wikitext": "کؤهنه صحیفه ویکی متنی، دییشیکلیکدن قاباق", + "abusefilter-edit-builder-vars-new-wikitext": "یئنی صحیفه ویکی متنی، دییشیکلیکدن سونرا", "abusefilter-edit-builder-vars-addedlines-pst": "خطلر دَییشدیرمه یه آرتیریلیبدی، هر ذخیره اولان کؤچورولوبدور", - "abusefilter-edit-builder-vars-new-text-stripped": "یئنی صحیفه متنی، هر هانسی بیر فورمالاندیرما اولمادان", + "abusefilter-edit-builder-vars-new-text": "یئنی صحیفه متنی، هر هانسی بیر فورمالاندیرما اولمادان", "abusefilter-edit-builder-vars-new-html": "یئنی رئویزیونو ییغیلمیش اچ تی ام ال قایناغی", "abusefilter-edit-builder-vars-restrictions-edit": "صحیفهنین قوروما سویهسینی دییشدیر", "abusefilter-edit-builder-vars-restrictions-move": "صحیفهنین قوروما سویهسینی داشی", - "abusefilter-edit-builder-vars-old-text-stripped": "کؤهنه صحیفه متنی، هر هانسی بیر فورمالاندیرما اولمادان", + "abusefilter-edit-builder-vars-old-text": "کؤهنه صحیفه متنی، هر هانسی بیر فورمالاندیرما اولمادان", "abusefilter-edit-builder-vars-old-links": "صحیفهدکی علاقهلر، دییشیکلیکدن قاباق", "abusefilter-edit-builder-vars-old-html": "کؤهنه صحیفه ویکی متنی، اچ تی ام ال ییغیلدی", "abusefilter-edit-builder-vars-minor-edit": "دییشیکلیگین کیچیک اولاراق ایشارئتلئنیپ ایشارئتلئنمئیئجئغی", @@ -340,6 +342,7 @@ "abusefilter-test-page": "دییشیکلیکلر بو صحیفهده ائدیلیب:", "abusefilter-test-shownegative": "سوزگئچلئ ائشلئشمئیئن دئییشیک لیک لری گؤستئر", "abusefilter-test-syntaxerr": "داخیل فیلتر سؤز سهوی ایچردی.\n\"سؤزدیزیمینی ایداره ائت\" دویمهسینه باساراق تام بیر شرح آلا بیلرسینیز.", + "abusefilter-test-action": "عمل نوعو:", "abusefilter-changeslist-examine": "اینجئلئ", "abusefilter-examine": "بیر-بیر دییشیکلیکلری یوخلا", "abusefilter-examine-intro": "بو صفحه، خارابکارلیق فیلتری طرفیندن خاص بیر دییشیکلیک اوچون یارادیلان معیارلاری یوخلاماق و فیلترلر قاباغیندا ایمتحانلاما اجازه سینی وئریر.", @@ -363,7 +366,6 @@ "abusefilter-topnav-examine": "گئچمیش دییشیکلیکلری ایمتحانلا", "abusefilter-topnav-log": "سوی-ایستیفاده ژورنالی", "abusefilter-topnav-tools": "اشکال آییر ائتمه واسطهلری", - "abusefilter-topnav-import": "فیلتر ایدخالی", "abusefilter-log-name": "خارابکارلیق فیلتری ژورنالی", "abusefilter-log-header": "بو ژورنال، فیلترلر دییشیکلیکلرین بیر قیساسینی گؤستریر.\nبوتون ایطلاعات اوچون، سون فیلتر دییشیکلیکلری [[Special:AbuseFilter/history|لیستینه]] باخین.", "abusefilter-log-noresults": "نتیجه یوخدور", diff --git a/AbuseFilter/i18n/ba.json b/AbuseFilter/i18n/ba.json index 588453fd..da060b69 100644 --- a/AbuseFilter/i18n/ba.json +++ b/AbuseFilter/i18n/ba.json @@ -5,17 +5,17 @@ "Assele", "Comp1089", "Haqmar", + "Matma Rex", "Sagan", - "Рустам Нурыев", "Азат Хәлилов", "З. ӘЙЛЕ", "Лилиә", "Ләйсән", - "Matma Rex" + "Рустам Нурыев" ] }, "abusefilter-desc": "Төҙәтеүҙәргә эвристик һөҙгөстәр ҡуйырға мөмкинлек бирә.", - "abusefilter": "Урынһыҙ файҙаланыуҙар һөҙгөсөн көйләү", + "abusefilter": "Урынһыҙ файҙаланыуҙар һөҙгөсө менән идара итеү", "abuselog": "Урынһыҙ файҙаланыуҙар яҙмалары журналы", "abusefilter-intro": "Урынһыҙ файҙаланыуҙар һөҙгөсөн көйләү битенә рәхим итегеҙ!\nУрынһыҙ файҙаланыуҙар һөҙгөсө ҡатнашыусыларҙың ҡулланыуына яраҡлаштырылған автоматик механизм булып тора. Исемлектә бөтә ҡуйылған һөҙгөстәр күрһәтелгән, һәм уларҙы уҙгәртеү мөмкинлеге бирелгән.", "abusefilter-warning": "'''Иғтибар!''' Был ғәмәл автоматик рәүештә зыянлы тип билдәләнде. Эшлекһеҙ ғәмәлдәр тиҙ арала юйыласаҡ, тупаҫ төҙәтеүҙәр һәм ҡабатланған эшлекһеҙ төҙәтеүҙәр һеҙҙең иҫәп яҙмағыҙ йәки IP-адресығыҙ бикләнеүгә килтерәсәк.\nӘгәр был төҙәтеү эшлекле тип уйлаһағыҙ, ебәреү йә һаҡлау төймәһенә тағы баҫығыҙ.\nҺеҙҙең ғәмәлегеҙҙе зыянлы тип билдәләүсе ҡағиҙәнең ҡыҫҡаса тасуирламаһы: $1", @@ -31,7 +31,7 @@ "right-abusefilter-view": "Урынһыҙ файҙаланыуҙар һөҙгөстәрен ҡарау", "right-abusefilter-log": "Урынһыҙ файҙаланыу яҙмалары журналын ҡарау", "right-abusefilter-log-detail": "Урынһыҙ файҙаланыуҙар яҙмалары журналындағы ентекле яҙмаларҙы ҡарау", - "right-abusefilter-private": "Урынһыҙ файҙаланыуҙар яҙмалары журналындағы шәхси мәғлүмәтте ҡарау", + "right-abusefilter-privatedetails": "Урынһыҙ файҙаланыуҙар яҙмалары журналындағы шәхси мәғлүмәтте ҡарау", "right-abusefilter-modify-restricted": "Сикләү ғәмәлдәрен башҡарған һөҙгөстәрҙе үҙгәртеү", "right-abusefilter-revert": "Урынһыҙ файҙаланыуҙар һөҙгөсө башҡарған үҙгәрештәрҙе кире алыу", "right-abusefilter-view-private": "Шәхси тип билдәләнгән урынһыҙ файҙаланыу һөҙгөстәрен ҡарау", @@ -43,11 +43,10 @@ "action-abusefilter-view": "Урынһыҙ файҙаланыу һөҙгөстәрен ҡарау", "action-abusefilter-log": "Урынһыҙ файҙаланыу яҙмалары журналын ҡарау", "action-abusefilter-log-detail": "Урынһыҙ файҙаланыуҙар яҙмалары журналындағы ентекле яҙмаларҙы ҡарау", - "action-abusefilter-private": "Урынһыҙ файҙаланыуҙар яҙмалары журналындағы шәхси мәғлүмәтте ҡарау", + "action-abusefilter-privatedetails": "Урынһыҙ файҙаланыуҙар яҙмалары журналындағы шәхси мәғлүмәтте ҡарау", "action-abusefilter-modify-restricted": "Сикләү ғәмәлдәрен башҡарған һөҙгөстәрҙе үҙгәртеү", "action-abusefilter-revert": "Урынһыҙ файҙаланыуҙар һөҙгөсө башҡарған үҙгәрештәрҙе кире алыу", "action-abusefilter-view-private": "Шәхси тип билдәләнгән урынһыҙ файҙаланыу һөҙгөстәрен ҡарау", - "abusefilter-log": "Урынһыҙ файҙаланыуҙар яҙмалары журналы", "abusefilter-log-summary": "Был журналда барлыҡ һөҙгөстәр тарафынан тотолған ғәмәлдәр исемлеге күрһәтелгән.", "abusefilter-log-search": "Урынһыҙ файҙаланыуҙар яҙмалары журналында эҙләү", "abusefilter-log-search-user": "Ҡатнашыусы:", @@ -67,13 +66,11 @@ "abusefilter-log-details-var": "Үҙгәреүсән дәүмәл", "abusefilter-log-details-val": "Ҡиммәт", "abusefilter-log-details-vars": "Ғәмәлдең параметрҙары", - "abusefilter-log-details-private": "Шәхси мәғлүмәттәр", "abusefilter-log-details-ip": "Сығанаҡ IP адрес", "abusefilter-log-noactions": "юҡ", "abusefilter-log-details-diff": "Мөхәррирләүҙә башҡарылған үҙгәртеүҙәр", "abusefilter-log-linkoncontribs": "урынһыҙ файҙаланыуҙар яҙмалары журналы", "abusefilter-log-linkoncontribs-text": "Был ҡатнашыусы өсөн урынһыҙ файҙаланыуҙар журналы яҙмалары", - "abusefilter-log-hidden": "(яҙма йәшерелгән)", "abusefilter-log-hidden-implicit": "(йәшерелгән, сөнки төҙәтеү юйылған)", "abusefilter-log-cannot-see-details": "Был яҙманың ентекле мәғлүмәттәрен ҡарау өсөн хоҡуғығыҙ юҡ.", "abusefilter-log-details-hidden": "Һеҙ был яҙма тураһында ентекле мәғлүмәт ҡарай алмайһығыҙ, сөнки ул йәшерелгән.", @@ -84,7 +81,6 @@ "abusefilter-log-hide-reason": "Сәбәп:", "abusefilter-log-hide-forbidden": "Һеҙҙең урынһыҙ файҙаланыуҙар яҙмалары журналындағы яҙмаларҙы йәшереү хоҡуғығыҙ юҡ.", "logentry-abusefilter-hit": "$1 ҡулланыусыһы $3 битендә \"$5\" ғәмәлен эшләп $4 фильтрын хәрәкәткә килтерҙе. Башҡарылған хәрәкәт: $6 ($7)", - "abusefilter-management": "Урынһыҙ файҙаланыуҙар һөҙгөсө менән идара итеү", "abusefilter-list": "Бар һөҙгөстәр", "abusefilter-list-id": "Һөҙгөс идентификаторы", "abusefilter-list-status": "Статус", @@ -104,6 +100,7 @@ "abusefilter-disabled": "Ябыҡ", "abusefilter-hitcount": "$1 {{PLURAL:$1|эшләп китеү|эшләп китеүҙәр}}", "abusefilter-new": "Яңы һөҙгөс булдырырға", + "abusefilter-import-button": "Һөҙгөс индереү", "abusefilter-return": "Һөҙгөстәр менән идаралауға ҡайтырға", "abusefilter-status-global": "Дөйөм", "abusefilter-list-options": "Көйләүҙәр", @@ -133,7 +130,6 @@ "abusefilter-edit-oldwarning": "<strong>Һеҙ был һөҙгөстөң иҫке өлгөһөн үҙгәртәһегеҙ.\nКилтерелгән статистика — һөҙгөстөң һуңғы өлгөһө өсөн.\nӘгәр үҙгәртеүҙәрегеҙҙе һаҡлаһағыҙ, һеҙ әле үҙгәрткән өлгөнән һуңғы барлыҡ үҙгәртеүҙәрҙең өҫтөнә яҙҙырасаҡһығыҙ.</strong> •\n[[Special:AbuseFilter/history/$2|Һөҙгөстөң тарихы битенә кире ҡайтырға]].", "abusefilter-edit-status-label": "Статистика:", "abusefilter-edit-status": " {{PLURAL:$1|һуңғы $1 ғәмәленән|һуңғы $1 ғәмәлдәренән}} был фильтр $2-гә ($3%) тап килә.", - "abusefilter-edit-status-profile": "Һуңғы $1 {{PLURAL:$1|1=ғәмәлдән}} был һөҙгөс $2 ғәмәл менән ($3%) тап килә.\nУның уртаса башҡарылыу ваҡыты — $4 мс, ул сикләү шартынан $5 {{PLURAL:$5|шарт}} ҡуллана.", "abusefilter-edit-new": "Яңы һөҙгөс", "abusefilter-edit-save": "Һөҙгөстө һаҡларға", "abusefilter-edit-id": "Һөҙгөс идентификаторы:", @@ -270,18 +266,18 @@ "abusefilter-edit-builder-vars-all-links": "Яңы эстәлектәге бөтә тышҡы һылтанмалар", "abusefilter-edit-builder-vars-added-links": "Үҙгәртеүҙә өҫтәлгән бөтә тышҡы һылтанмалар", "abusefilter-edit-builder-vars-removed-links": "Үҙгәртеүҙә юйылған бөтә тышҡы һылтанмалар", - "abusefilter-edit-builder-vars-old-text": "Элекке викитекст, битте үҙгәрткәнгә тиклем", - "abusefilter-edit-builder-vars-new-text": "Яңы викитекст, битте үҙгәрткәндән һуң", + "abusefilter-edit-builder-vars-old-wikitext": "Элекке викитекст, битте үҙгәрткәнгә тиклем", + "abusefilter-edit-builder-vars-new-wikitext": "Яңы викитекст, битте үҙгәрткәндән һуң", "abusefilter-edit-builder-vars-new-pst": "Яңы биттең һаҡлар алдынан үҙгәртелгән викитексы", "abusefilter-edit-builder-vars-diff-pst": "Мөхәррирләү барышында унификацияланған, һаҡлау алдынан үҙгәртелгән diff үҙгәрештәр", "abusefilter-edit-builder-vars-addedlines-pst": "Мөхәррирләү барышында өҫтәлгән, һаҡлау алдынан үҙгәртелгән юлдар", - "abusefilter-edit-builder-vars-new-text-stripped": "Биттең яңы эстәлеге, билдәләрҙән таҙартылған", + "abusefilter-edit-builder-vars-new-text": "Биттең яңы эстәлеге, билдәләрҙән таҙартылған", "abusefilter-edit-builder-vars-new-html": "Яңы өлгөнөң HTML-сығанағы", "abusefilter-edit-builder-vars-restrictions-edit": "Биттең үҙгәртеүҙәрҙән һаҡланыу дәрәжәһе", "abusefilter-edit-builder-vars-restrictions-move": "Биттең исемен үҙгәртеүҙәрҙән һаҡланыу дәрәжәһе", "abusefilter-edit-builder-vars-restrictions-create": "Битте һаҡларға", "abusefilter-edit-builder-vars-restrictions-upload": "Файл һаҡлауын йөкләргә", - "abusefilter-edit-builder-vars-old-text-stripped": "Биттең элекке эстәлеге, билдәләрҙән таҙартылған", + "abusefilter-edit-builder-vars-old-text": "Биттең элекке эстәлеге, билдәләрҙән таҙартылған", "abusefilter-edit-builder-vars-old-links": "Биттәге һылтанмалар, үҙгәртеүгә тиклем", "abusefilter-edit-builder-vars-old-html": "Иҫке биттең викитексты, HTML-ға үҙгәртелгән", "abusefilter-edit-builder-vars-minor-edit": "Үҙгәртеү \"әҙ үҙгәртеүҙәр\" тип билдәләнгәнме, юҡмы", @@ -380,7 +376,6 @@ "abusefilter-topnav-examine": "Һуңғы үҙгәртеүҙәрҙе ҡарап сығыу", "abusefilter-topnav-log": "Урынһыҙ файҙаланыуҙар яҙмалары журналы", "abusefilter-topnav-tools": "Төҙәтеү ҡоралдары", - "abusefilter-topnav-import": "Һөҙгөс индереү", "abusefilter-log-name": "Урынһыҙ файҙаланыуҙар һөҙгөсө яҙмалары журналы", "abusefilter-log-header": "Был журналға һөҙгөстәргә керетелгән үҙгәртеүҙәрҙең тасуирламаһы яҙыла.\nТулыраҡ мәғлүмәт өсөн һуңғы һөҙгөстәрҙе үҙгәртеүҙәр [[Special:AbuseFilter/history|исемлеген]] ҡарағыҙ.", "abusefilter-log-noresults": "Һөҙөмтә юҡ", diff --git a/AbuseFilter/i18n/ban.json b/AbuseFilter/i18n/ban.json new file mode 100644 index 00000000..6b8c5087 --- /dev/null +++ b/AbuseFilter/i18n/ban.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "NoiX180" + ] + }, + "abusefilter-log-search-impact-saved": "Wantah uahan maraksa", + "abusefilter-list-edit": "Uah" +} diff --git a/AbuseFilter/i18n/bar.json b/AbuseFilter/i18n/bar.json index a6067ca4..4d669c95 100644 --- a/AbuseFilter/i18n/bar.json +++ b/AbuseFilter/i18n/bar.json @@ -5,8 +5,6 @@ ] }, "abusefilter-desc": "Wendt autómaatiche \"Heuristiken\" auf Änderrungen å", - "abusefilter": "Missbrauchsfüter-Eihstöungen", - "abuselog": "Missbrauchsfüter-Lógbiaché", "abusefilter-intro": "Griass Enk auf da Missbrauchsfüterter-Management-Ówerflächen.\nDa Missbrauchsfüter is a autómaatischer Mechanismus, der autómaatische Heiristiken auf olle Änderrungen auhwendt.\nDé Ówerflächen zoagt a Listen voh olle definierden Füter und dalaabts, dé z' vaändern.", "abusefilter-log-search-user": "Benutzer:", "abusefilter-log-search-title": "Titel:", diff --git a/AbuseFilter/i18n/bcc.json b/AbuseFilter/i18n/bcc.json new file mode 100644 index 00000000..f43a9201 --- /dev/null +++ b/AbuseFilter/i18n/bcc.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Sultanselim baloch" + ] + }, + "abusefilter-edit-builder-vars-new-text": "نۏکݔں تاکء نبشتہ بے پدگاری اِنت۔" +} diff --git a/AbuseFilter/i18n/bcl.json b/AbuseFilter/i18n/bcl.json index fda347f9..49e99437 100644 --- a/AbuseFilter/i18n/bcl.json +++ b/AbuseFilter/i18n/bcl.json @@ -1,6 +1,7 @@ { "@metadata": { "authors": [ + "Brazal.dang", "Filipinayzd", "Geopoet", "Matma Rex", @@ -8,8 +9,8 @@ ] }, "abusefilter-desc": "Pinapadanay an awtomatikong gana sa boot na mga pagliliwat", - "abusefilter": "Saraan sa abuso nin kasalansanan", - "abuselog": "Talaan nin abuso", + "abusefilter": "Pagmamaneho kan saraan nin abuso", + "abuselog": "Talaan nin saraan sa abuso", "abusefilter-intro": "Marhay na pag-abot sa olay-panlaog sa manihamento kan Saraan nin Abuso.\nAn Saraan nin Abuso sarong awtomatikong mekanismo nin panuklob na awtomatikong pinag-aaplikar na gana sa boot sa gabos na aksyon.\nIning olay-panlaog minapahiling nin listahan kan pinagpapasabot na mga saraan, asin minatugot na sinda modipikaron.", "abusefilter-warning": "'''Patanid''': Ining aksyon awtomatikong pinagpamidbid bilang pano nin kadelikaduhan.\nAn bakong konstraktibong mga pagliliwat tulos-tulos na pinagbabalik, asin an bantadan o pauro-otrong pagliliwat na bakong konstraktibo magreresulta sa pagkukubkod kan sadire mong panindog o estada kan IP.\nKun ika nagtutubod na ining aksyon konstraktibo, \nmapuwede mong isumite ini giraray tanganing ikumpirma ini.\nSarong halipoton na deskripsyon kan patakaran nin abuso na an saimong aksyon nainuknó iyo an: $1", "abusefilter-disallowed": "Ining aksyon awtomatikong pinagpamidbid na pano nin kadelikaduhan, asin kaya dae pinagtutugutan.\nKun ika nagtutubod na an saimong aksyon konstraktibo, pakipasabot sa administrador kun ano an saimong pinagprubaran na gigibohon.\nSarong halipoton na deskripsyon kan patakaran nin abuso na an saimong aksyon nainuknó iyo an: $1", @@ -24,7 +25,7 @@ "right-abusefilter-view": "Patanaw kan mga saraan nin abuso", "right-abusefilter-log": "Tanawon an talaan nin abuso", "right-abusefilter-log-detail": "Tanawon an detalyadong mga entrada sa talaan nin abuso", - "right-abusefilter-private": "Tanawon an pribadong datos na yaon sa talaan nin abuso", + "right-abusefilter-privatedetails": "Tanawon an pribadong datos na yaon sa talaan nin abuso", "right-abusefilter-modify-restricted": "Hirahon an mga saraan nin abuso na igwang ipinagpapangalad na mga aksyon", "right-abusefilter-revert": "Ibuwelta an gabos na mga kaliwatan kan itinaong saraan nin abuso", "right-abusefilter-view-private": "Tanawon an mga saraan nin abuso na pinagmarkahan na pribado", @@ -36,20 +37,35 @@ "action-abusefilter-view": "Tanawon an mga saraan nin abuso", "action-abusefilter-log": "Tanawon an talaan nin abuso", "action-abusefilter-log-detail": "Tanawon an detalyadong mga entrada sa talaan nin abuso", - "action-abusefilter-private": "Tanawon an pribadong datos sa laog kan talaan nin abuso", + "action-abusefilter-privatedetails": "Tanawon an pribadong datos sa laog kan talaan nin abuso", "action-abusefilter-modify-restricted": "Hirahon an mga saraan nin abuso na igwang ipinapangalad na mga aksyon", "action-abusefilter-revert": "isulit sa dati an gabos na mga pagbàgo na itinao kan saraan nin abuso", "action-abusefilter-view-private": "Tanawon an mga saraan nin abuso na markadong pribado", - "abusefilter-log": "Talaan nin saraan sa abuso", + "action-abusefilter-hidden-log": "Tanawon an itinagong entrada sa talaan kan abuso", + "action-abusefilter-modify-global": "Muknaon o modipikaron an pankinaban na mga saraan nin abuso", "abusefilter-log-summary": "Ining talaan nagpapahiling nin sarong listahan kan gabos na mga aksyon na nadakop kan mga saraan", "abusefilter-log-search": "Hanapon an talaan nin abuso", "abusefilter-log-search-user": "Paragamit:", - "abusefilter-log-search-filter": "ID nin Saraan:", + "abusefilter-log-search-group": "Grupo nin saraan:", + "abusefilter-log-search-group-any": "Dawà ano", + "abusefilter-log-search-filter": "ID kan Saraan:", "abusefilter-log-search-title": "Titulo:", "abusefilter-log-search-wiki": "Wiki:", + "abusefilter-log-search-impact-all": "Gabos na aksyon", + "abusefilter-log-search-impact-saved": "Mga itinagamang pagbabago sana", + "abusefilter-log-search-impact-not-saved": "Mayong itinagamang pagbabago", + "abusefilter-log-search-entries-label": "Bisibilidad:", + "abusefilter-log-search-entries-all": "Gabos na entrada", + "abusefilter-log-search-entries-hidden": "Nakatagong entrada sana", + "abusefilter-log-search-entries-visible": "Mga nahihiling na entrada sana", + "abusefilter-log-search-action-other": "An iba", + "abusefilter-log-search-action-any": "Dawà ano", + "abusefilter-log-search-action-taken-label": "Ginibong aksyon:", + "abusefilter-log-search-action-taken-any": "Dawà ano", "abusefilter-log-search-submit": "Hanapon", - "abusefilter-log-entry": "$1: $2 nagkiblit kan saraan nin abuso, pinaghihimo an aksyon na \"$3\" sa $4.\nPinaghimong aksyon: $5;\nDeskripsyon kan saraan: $6", - "abusefilter-log-detailedentry-meta": "$1: $2 pinagkiblit an $3, pinaghihimo an aksyon na \"$4\" sa $5.\nPinaghimong aksyon: $6;\nDeskripsyon kan saraan: $7 ($8)", + "abusefilter-log-entry": "$1: $2 {{GENDER:$8|nagkiblit}} kan saraan nin abuso, {{GENDER:$8|pinaghihimo}} an aksyon na \"$3\" sa $4.\nPinaghimong aksyon: $5;\nDeskripsyon kan saraan: $6", + "abusefilter-log-entry-withdiff": "$1: $2 {{GENDER:$8|nagkiblit}} kan saraan nin abuso, {{GENDER:$8|pinaghihimo}} an aksyon na \"$3\" sa $4.\nPinaghimong aksyon: $5;\nDeskripsyon kan saraan: $6 ($7)", + "abusefilter-log-detailedentry-meta": "$1: $2 {{GENDER:$9|pinagkiblit}} an $3, {{GENDER:$9|pinaghihimo}} an aksyon na \"$4\" sa $5.\nPinaghimong aksyon: $6;\nDeskripsyon kan saraan: $7 ($8)", "abusefilter-log-detailedentry-global": "pankinabang na saraan $1", "abusefilter-log-detailedentry-local": "saraan $1", "abusefilter-log-detailslink": "mga detalye", @@ -59,25 +75,34 @@ "abusefilter-log-details-var": "Kapilyan", "abusefilter-log-details-val": "Kantidad", "abusefilter-log-details-vars": "Mga parametro nin aksyon", - "abusefilter-log-details-private": "Pribadong datos", + "abusefilter-log-details-privatedetails": "Pribadong datos", "abusefilter-log-details-ip": "Pinaggikanan na estada nin IP", + "abusefilter-log-details-checkuser": "Rikisahon an paragamit", "abusefilter-log-noactions": "Mayo man", "abusefilter-log-details-diff": "Mga kaliwatan na pinaghimo sa pagliliwat", "abusefilter-log-linkoncontribs": "talaan nin abuso", - "abusefilter-log-linkoncontribs-text": "Talaan nin abuso para kaining paragamit", - "abusefilter-log-hidden": "(itinagong entrada)", + "abusefilter-log-linkoncontribs-text": "Talaan nin abuso para kaining {{GENDER:$1|paragamit}}", + "abusefilter-log-linkonhistory": "Tanawon an talaan nin abuso", + "abusefilter-log-linkonhistory-text": "Hilingon an mga katalaanan nin abuso para sa pahinang ini", "abusefilter-log-hidden-implicit": "(itinago nin huli ta an rebisyon pinagpura na)", "abusefilter-log-cannot-see-details": "Ika mayong permiso na hilingon an mga detalye kaining entrada.", + "abusefilter-log-cannot-see-privatedetails": "Ika mayong permiso na hilingon an mga detalye kaining entrada.", "abusefilter-log-details-hidden": "Ika da makakahiling sa mga detalye kaining entrada nin huli ta ini itinago sa paghiling nin publiko.", "abusefilter-log-hide-legend": "Itago an entrada nin talaan", "abusefilter-log-hide-id": "ID kan entrada sa talaan:", "abusefilter-log-hide-hidden": "Itago ining entrada sa paghiling kan publiko", "abusefilter-log-hide-reason": "Rason:", + "abusefilter-log-hide-reason-other": "Iba pa/kadugangan na rason:", "abusefilter-log-hide-forbidden": "Ika mayong permiso na magtago kan mga entrada sa talaan nin abuso.", - "logentry-abusefilter-hit": "$1 kiniblit an $4, pinaghihimo an aksyon na \"$5\" sa $3. Pinaghimong mga aksyon: $6 ($7)", - "abusefilter-management": "Pagmamaneho kan saraan nin abuso", + "abusefilter-log-entry-suppress": "$1 {{GENDER:$2|itago}} $3", + "abusefilter-log-entry-unsuppress": "$1 {{GENDER:$2|halion sa pagkatago}} $3", + "logentry-abusefilter-hit": "$1 {{GENDER:$2|kiniblit}} an $4, {{GENDER:$2|pinaghihimo}} an aksyon na \"$5\" sa $3. Pinaghimong mga aksyon: $6 ($7)", + "log-action-filter-abusefilter": "Tipo kan pagbago kan pansara:", + "log-action-filter-abusefilter-create": "Bagong pagmukna kan pansara", + "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|hilingon}}an pribadong mga detalye para sa $3", "abusefilter-list": "Gabos na mga saraan", "abusefilter-list-id": "ID kan Saraan", + "abusefilter-list-pattern": "Pangarugan", "abusefilter-list-status": "Estado", "abusefilter-list-public": "Pampublikong paglaladawan", "abusefilter-list-consequences": "Mga kaaabtan", @@ -93,8 +118,10 @@ "abusefilter-enabled": "Pinagpa-andar", "abusefilter-deleted": "Pinagpura", "abusefilter-disabled": "Pinagpauntok", + "abusefilter-throttled": "Pangutnol", "abusefilter-hitcount": "$1 {{PLURAL:$1|igo|mga igo}}", "abusefilter-new": "Magmukna nin baguhong saraan", + "abusefilter-import-button": "Importaron an saraan", "abusefilter-return": "Magbuwelta sa manihamento nin saraan", "abusefilter-status-global": "Pankinaban", "abusefilter-list-options": "Mga Pagpipilian", @@ -103,7 +130,7 @@ "abusefilter-list-options-deleted-hide": "Itago an pinagpurang mga saraan", "abusefilter-list-options-deleted-show": "Balihon an pinagpurang mga saraan", "abusefilter-list-options-scope": "Ipahiling an mga saraan gikan sa:", - "abusefilter-list-options-scope-local": "Lokal na wiki", + "abusefilter-list-options-scope-local": "Lokal patakaran sana", "abusefilter-list-options-scope-global": "Pankinaban na mga patakaran", "abusefilter-list-options-hidedisabled": "Itago na pinagpauntok na mga saraan", "abusefilter-list-options-submit": "Panumpay", @@ -122,12 +149,12 @@ "abusefilter-edit-subtitle-new": "Saraan nin pagmumukna", "abusefilter-edit-oldwarning": "<makusugon>Ika nagliliwat kan lumaong bersyon kaining saraan.\nAn estadistikong pinagsambit para sa pinakahuring bersyon kan saraan.\nKun saimong naitagama an saimong mga kaliwatan, saimong sasalambawan an gabos na mga kaliwatan magpoon pa sa rebisyon na saimong pinagliliwat. </makusugon> •\n[[Special:AbuseFilter/history/$2|Magbalik pasiring sa historiya kaining saraan]].", "abusefilter-edit-status-label": "Estadistika:", - "abusefilter-edit-status": "Kan nakaaging $1 {{PLURAL:$1|aksyon|mga aksyon}}, ining saraan nakapagtampad sa $2 ($3%).", - "abusefilter-edit-status-profile": "Kan nakaaging $1 {{PLURAL:$1|aksyon|mga aksyon}}, ini saraan nakapag-ampad sa $2 ($3%).\nSa katahawan, an oras nin padalagan $4 ms, asin ini minakonsumo nin $5 {{PLURAL:$5|kondisyon|mga kondisyon}} kan limitasyon sa kondisyon.", + "abusefilter-edit-status": "Kan nakaaging $1 {{PLURAL:$1|aksyon|mga aksyon}}, ini saraan nakapag-ampad sa $2 ($3%).\nSa katahawan, an oras nin padalagan $4 ms, asin ini minakonsumo nin $5 {{PLURAL:$5|kondisyon|mga kondisyon}} kan limitasyon sa kondisyon.", "abusefilter-edit-new": "Baguhong saraan", "abusefilter-edit-save": "Itagama an saraan", "abusefilter-edit-id": "Pansarà nin ID", "abusefilter-edit-description": ":''(pampublikong pagpapahiling)''", + "abusefilter-edit-field-description": "Deskripsyon", "abusefilter-edit-group": "Grupo nin saraan", "abusefilter-edit-flags": "Mga bandera", "abusefilter-edit-enabled": "Paandaron ining saraan", @@ -135,7 +162,8 @@ "abusefilter-edit-hidden": "Tagoon an mga detalye kaining saraan sa pampublikong pagtanaw", "abusefilter-edit-global": "Pankinaban na saraan", "abusefilter-edit-rules": "Mga Kondisyon:", - "abusefilter-edit-notes": "Mga Giromdomon:\n:''(pribado)''", + "abusefilter-edit-field-conditions": "mga kondisyon", + "abusefilter-edit-notes": "Mga Giromdomon:", "abusefilter-edit-lastmod": "Pinakahuring pagbabago kan saraan:", "abusefilter-edit-lastmod-text": "$1 ni $2", "abusefilter-edit-hitcount": "Mga igo nin saraan:", @@ -146,20 +174,35 @@ "abusefilter-edit-action-degroup": "Minapahale sa paragamit gikan sa gabos na grupo na igwang pribilihiyo", "abusefilter-edit-action-block": "Kubkubon and paragamit asin/o IP na estada gikan sa pagliliwat", "abusefilter-edit-action-throttle": "Minakiblit nin mga aksyon sana kun an paragamit nakatibaklo nin sarong limit sa rata", - "abusefilter-edit-action-rangeblock": "Kubkubon an /16 gangha gikan sa mga pinaggigikanan nin paragamit", + "abusefilter-edit-action-rangeblock": "Kubkubon an masunod na sakop kan IP base sa mga pinaggigikanan nin paragamit", "abusefilter-edit-action-tag": "I-tag an pagliliwat para sa kadagdagan na pagrepaso", "abusefilter-edit-throttle-count": "Numero kan mga aksyon na ipapasunod:", "abusefilter-edit-throttle-period": "Peryodo nin panahon (kada mga Segundo):", "abusefilter-edit-throttle-groups": "Pangrupong ngutnol sa paagi nin:\n:''(saro kada linya, ibanhan nin kudlit)''", - "abusefilter-edit-throttle-range": "/16 saklaw", - "abusefilter-edit-throttle-editcount": "Hirahón an bilang", + "abusefilter-edit-throttle-groups-help": "Hilingon $1.", + "abusefilter-edit-throttle-groups-help-text": "an dokumentasyon sa mediawiki.org", + "abusefilter-throttle-ip": "estada kan IP", + "abusefilter-throttle-user": "panindog kan paragamit", + "abusefilter-throttle-range": "/16 sakop", + "abusefilter-throttle-creationdate": "Petsa kan pagmukna nin panindog", + "abusefilter-throttle-editcount": "Bilang nin pagliwat", + "abusefilter-throttle-site": "buong sityo", + "abusefilter-throttle-page": "pahina", + "abusefilter-throttle-none": "(mayo)", "abusefilter-edit-warn-message": "Pansistemang mensahe na gamiton para sa patanid:", "abusefilter-edit-warn-other": "Iba pang mensahe", - "abusefilter-edit-warn-other-label": "Pangaran nin pahina kan ibang mensahe:\n:''(mayo nin MediaWiki enot-panigmit)''", + "abusefilter-edit-warn-other-label": "Pangaran nin pahina kan ibang mensahe:\n:''(mayo nin \"MediaWiki:\" enot-panigmit)''", "abusefilter-edit-warn-actions": "Mga gibohon:", - "abusefilter-edit-warn-preview": "Tanawon mga pinagpili na mensahe", + "abusefilter-edit-warn-preview": "Tanawon/Itago an mga pinagpili na mensahe", "abusefilter-edit-warn-edit": "Muknaon/Liwaton pinagpili na mensahe", - "abusefilter-edit-tag-tag": "Mga tatak na gamiton [[Espesyal:Mga tag|Mga tag]]:", + "abusefilter-edit-disallow-other": "Iba pang mensahe", + "abusefilter-edit-disallow-other-label": "Pangaran nin pahina kan ibang mensahe:\n:''(mayo nin \"MediaWiki:\" enot-panigmit)''", + "abusefilter-edit-disallow-actions": "Mga aksyon", + "abusefilter-edit-disallow-preview": "Tanawon/Itago an mga pinagpili na mensahe", + "abusefilter-edit-disallow-edit": "Muknaon/Liwaton pinagpili na mensahe", + "abusefilter-edit-tag-tag": "Mga [[Special:Tags|tatak]] na gamiton:", + "abusefilter-block-anon": "Kubkubon an dae bistadong paragamit sana", + "abusefilter-block-user": "bagaton an mga rehistradong paragamit", "abusefilter-edit-denied": "Ika dae makakahiling sa mga detalye kaining saraan, nin huli ta ini itinago gikan sa paghiling nin publiko.", "abusefilter-edit-main": "Mga parametro nin saraan", "abusefilter-edit-done-subtitle": "An saraan pinagliwat", @@ -176,7 +219,7 @@ "abusefilter-edit-export": "Eksportaron ining saraan pasiring sa ibang wiki", "abusefilter-edit-syntaxok": "Mayong sintaks na mga kasalaan an namansayan.", "abusefilter-edit-syntaxerr": "Sintaks na kasalaan namansayan: $1", - "abusefilter-edit-bad-tags": "Sa or dakol kan mga tatak na saimong pinagkaag bakong balido.\nAn mga tatak dapat na halipot, asin sinda dapat mayong espesyal na mga karakter.", + "abusefilter-edit-bad-tags": "Saro o dakol kan mga tatak na saimong pinagkaag bakong balido.\nAn mga tatak dapat na halipot, asin sinda dapat mayong espesyal na mga karakter.", "abusefilter-edit-notallowed": "Ika daeng permiso na magmukna o magliwat kan mga saraan nin abuso", "abusefilter-edit-notallowed-global": "Ika mayong permiso na magmukna o magliwat kan pankinaban na mga saraan nin abuso", "abusefilter-edit-notallowed-global-custom-msg": "An kustombre kan mga mensahe nin patanid bakong suportado para sa pankinabanon na mga saraan", @@ -260,19 +303,19 @@ "abusefilter-edit-builder-vars-all-links": "Gabos na panluwas na kasugpunan yaon sa baguhon na teksto", "abusefilter-edit-builder-vars-added-links": "Gabos na panluwas na kasugpunan pinagdagdag sa pagliwat", "abusefilter-edit-builder-vars-removed-links": "Gabos na panluwas na kasugpunan pinaghale sa pagliwat", - "abusefilter-edit-builder-vars-old-text": "Wiki-teksto kan lumaong pahina, bago pa man an pagliwat", - "abusefilter-edit-builder-vars-new-text": "Wiki-teksto kan baguhon na pahina, matapos na magliwat", + "abusefilter-edit-builder-vars-old-wikitext": "Wiki-teksto kan lumaong pahina, bago pa man an pagliwat", + "abusefilter-edit-builder-vars-new-wikitext": "Wiki-teksto kan baguhon na pahina, matapos na magliwat", "abusefilter-edit-builder-vars-new-pst": "Bagong pahina kan wikiteksto, enot na tinagama pinagbago", - "abusefilter-edit-builder-vars-new-text-stripped": "Teksto kan baguhon na pahina, hinukwasan kan arin man ma markang patindog", + "abusefilter-edit-builder-vars-new-text": "Teksto kan baguhon na pahina, hinukwasan kan arin man ma markang patindog", "abusefilter-edit-builder-vars-new-html": "Panabuton and ginikanan kan HTML kan baguhong rebisyon", "abusefilter-edit-builder-vars-restrictions-edit": "Liwaton an grado nin proteksyon kan pahina", "abusefilter-edit-builder-vars-restrictions-move": "Balyuhon an grade nin proteksyon kan pahina", "abusefilter-edit-builder-vars-restrictions-create": "Magmukna nin proteksyon kan pahina", "abusefilter-edit-builder-vars-restrictions-upload": "Ikarga an proteksyon kan sagunson", - "abusefilter-edit-builder-vars-old-text-stripped": "An lumang teksto nin pahina, pinagtanggalan nin arinman na markang panindog", + "abusefilter-edit-builder-vars-old-text": "An lumang teksto nin pahina, pinagtanggalan nin arinman na markang panindog", "abusefilter-edit-builder-vars-old-links": "Mga kasugponan na yaon sa pahina, bago pa man an pagliwat", - "abusefilter-edit-builder-vars-old-html": "An lumang pahina nin wikitext, pinagpakahulugan sa HTML", - "abusefilter-edit-builder-vars-minor-edit": "Dawa na bako an pagliwat markado bilang menor", + "abusefilter-edit-builder-vars-old-html": "An lumang pahina nin wikitext, pinagpakahulugan sa HTML (dai na ginagamit)", + "abusefilter-edit-builder-vars-minor-edit": "Dawa na bako an pagliwat markado bilang menor (dai na ginagamit)", "abusefilter-edit-builder-vars-file-sha1": "SHA1 pinutulan kan mga laman nin sagunson", "abusefilter-filter-log": "Dae pa sana nahahaloy na mga kaliwatan kan saraan", "abusefilter-history": "Historiya nin kaliwatan para sa Saraan nin Abuso #$1", @@ -302,11 +345,11 @@ "abusefilter-exception-unclosedstring": "Dae nakaseradong pisî na nagpopoon sa panggurit na $1.", "abusefilter-exception-invalidoperator": "Imbaliding operador \"$2\" sa panggurit na $1.", "abusefilter-exception-unrecognisedtoken": "Bakong rekonisadong pangilip \"$2\" sa panggurit na $1.", - "abusefilter-exception-noparams": "Mayong mga parametrong itinao tanganing humirô sa \"$2\" sa panggurit na $1.", + "abusefilter-exception-noparams": "Mayong mga parametrong itinao tanganing humirô sa \"$2\" sa panggurit na $1. Hinahalat $3 {{PLURAL:$3|argument|argumento}}.", "abusefilter-exception-dividebyzero": "Iligal na pagprubar na bangaon an $2 sa paagi nin sero sa panggurit na $1.", "abusefilter-exception-unrecognisedvar": "Bakong rekonisadong kapilyangan na $2 sa panggurit na $1.", "abusefilter-exception-notenoughargs": "Bakong igong mga argumento tanganing humirô $2 na pinag-apod sa panggurit na $1.\nPinag-asahan na $3{{PLURAL:$3|argumento|mga argumento}}, an nakua $4", - "abusefilter-exception-regexfailure": "Kasalaan sa regular na ekspresyon na \"$3\" sa panggurit na $1:\"$2\"", + "abusefilter-exception-regexfailure": "Sala sa regular na ekspresyon na \"$2\" sa panggurit na $1:", "abusefilter-exception-overridebuiltin": "Iligal na pagsasalambaw kan nakasuknat na kapilyangan \"$2\" sa panggurit na $1.", "abusefilter-exception-outofbounds": "Naghahagad kan dae pa nakamuknang lista nin aytem na $2 (listang sukol = $3) sa panggurit na $1.", "abusefilter-exception-notarray": "Naghahagad palangkay nin aytem kan bakong palangkay sa panggurit na $1.", @@ -320,7 +363,7 @@ "abusefilter-action-disallow": "Dae tinutugot", "abusefilter-revert-title": "Balikon an gabos na mga kaliwatan sa paagi kan saraan na $1", "abusefilter-revert-intro": "Ining porma minatugot saimo na balikon an gabos na mga kaliwatan na hinimo sa paagi kan saraan nin abuso nin huli sa saraan na $1.\nPaki-ingati tabi an paggagamit kaining palindô.", - "abusefilter-revert-preview-item": "$1:$2 pinaghimong $3 sa $4.\nAn aksyon mapupuwedeng balikon: $5($6)", + "abusefilter-revert-preview-item": "$1:$2 {{GENDER:$7|pinaghimong}} $3 sa $4.\nAn aksyon mapupuwedeng balikon: $5($6)", "abusefilter-revert-search-legend": "Pilion an aksyon kan saraan nin abuso na mapupuwedeng balikon", "abusefilter-revert-periodstart": "Poon kan peryodo:", "abusefilter-revert-periodend": "Tapos kan peryodo:", @@ -366,7 +409,6 @@ "abusefilter-topnav-examine": "Mansayon an nakaaging mga pagliliwat", "abusefilter-topnav-log": "Katalaanan nin Abuso", "abusefilter-topnav-tools": "Mga Gamit Panhirog", - "abusefilter-topnav-import": "Importaron an saraan", "abusefilter-log-name": "Katalaanan kan Saraan nin Abuso", "abusefilter-log-header": "Ining katalaanan nagpapatanaw nin sarong sumaryo nin mga kaliwatan na hinimo sa mga saraan.\nPara sa kabilogang detalye, hilngon an [[Special:AbuseFilter/history|an listahan]] kan pinakahurihan na kaliwatan nin saraan.", "abusefilter-log-noresults": "Mayo nin mga resulta", diff --git a/AbuseFilter/i18n/be-tarask.json b/AbuseFilter/i18n/be-tarask.json index a57256c8..ad0bd2b3 100644 --- a/AbuseFilter/i18n/be-tarask.json +++ b/AbuseFilter/i18n/be-tarask.json @@ -1,21 +1,24 @@ { "@metadata": { "authors": [ + "Artsiom91", "Cesco", "EugeneZelenko", "Jim-by", + "Matma Rex", + "Nerogaf", "Red Winged Duck", "Renessaince", + "StasDash", "Wizardist", - "Zedlik", - "Matma Rex", - "Artsiom91" + "Zedlik" ] }, "abusefilter-desc": "Прыстасоўвае аўтаматычную эўрыстыку да рэдагаваньняў.", - "abusefilter": "Канфігурацыя фільтру злоўжываньняў", - "abuselog": "Журнал злоўжываньняў", + "abusefilter": "Кіраваньне фільтрам злоўжываньняў", + "abuselog": "Журнал фільтру злоўжываньняў", "abusefilter-intro": "Сардэчна запрашаем на старонку кіраваньня фільтрам злоўжываньняў.\nФільтар злоўжываньняў — аўтаматычны праграмны мэханізм ўжываньня аўтаматычных эўрыстык для ўсіх дзеяньняў.\nІнтэрфэйс паказвае сьпіс усталяваных фільтраў і дае магчымасьць іх зьмены.", + "abusefilter-mustviewprivateoredit": "З прычынаў бясьпекі толькі ўдзельнікі з правамі прагляду прыватых фільтраў злоўжываньняў ці мадыфікацыі фільтраў могуць карыстацца гэтым інтэрфэйсам.", "abusefilter-warning": "'''Увага''': гэтае дзеяньне будзе аўтаматычна лічыцца шкодным.\nНеканструктыўныя дзеяньні будуць скасаваныя,\nа значныя ці неаднаразовыя неканструктыўныя рэдагаваньні прывядуць да блякаваньня вашага рахунку ці кампутара.\nКалі вы лічыце гэтае дзеяньне канструктыўным, вам неабходна пацьвердзіць яго яшчэ раз.\nКароткі сьпіс злоўжываньняў, зь якімі суадносіцца вашае дзеяньне: $1", "abusefilter-disallowed": "Гэтае дзеяньне было аўтаматычна ідэнтыфікаванае як шкоднае і таму было забароненае.\nКалі Вы ўпэўненыя, што гэта карыснае рэдагаваньне, калі ласка, зьвяжыцеся з адміністратарам і растлумачце яму, што Вы спрабуеце зрабіць.\nКароткае апісаньне шкоды, зь якой супала Вашае дзеяньне: $1", "abusefilter-blocked-display": "Гэтае дзеяньне было аўтаматычна ідэнтыфікаванае як шкоднае і Вам было забароненае яго выкананьне.\nАкрамя гэтага, у мэтах абароны {{GRAMMAR:родны|{{SITENAME}}}}, Ваш рахунак і ўсе зьвязаныя зь ім ІР-адрасы былі заблякаваныя.\nКалі гэта адбылася памылкова, калі ласка, зьвяжыцеся з адміністратарам.\nКароткае апісаньне шкоды, зь якой супала Вашае дзеяньне: $1", @@ -24,12 +27,14 @@ "abusefilter-blocker": "Фільтар злоўжываньняў", "abusefilter-blockreason": "Аўтаматычна заблякаваны фільтрам злоўжываньняў. Апісаньне адпаведнага правіла: $1", "abusefilter-degroupreason": "Фільтар злоўжываньняў аўтаматычна зьняў правы. Апісаньне правіла: $1", + "abusefilter-blockautopromotereason": "Фільтар злоўжываньняў аўтаматычна адклаў аўтапрасоўваньне.\nАпісаньне правіла: $1", "abusefilter-accountreserved": "Назва гэтага рахунку зарэзэрвананая для выкарыстаньня фільтрам злоўжываньняў.", - "right-abusefilter-modify": "зьмена фільтраў злоўжываньняў", + "right-abusefilter-modify": "Стварыць ці зьмяніць фільтары злоўжываньняў", "right-abusefilter-view": "прагляд фільтраў злоўжываньняў", "right-abusefilter-log": "прагляд журнала злоўжываньняў", "right-abusefilter-log-detail": "прагляд падрабязных запісаў у журнале злоўжываньняў", - "right-abusefilter-private": "Паказаць прыватныя зьвесткі ў журнале злоўжываньняў", + "right-abusefilter-privatedetails": "Паказаць прыватныя зьвесткі ў журнале злоўжываньняў", + "right-abusefilter-privatedetails-log": "Прагляд журналу доступу да асабістых зьвестак фільтру злоўжываньняў", "right-abusefilter-modify-restricted": "зьмена фільтраў злоўжываньняў з абмежавальнымі дзеяньнямі", "right-abusefilter-revert": "адкат усіх зьменаў, зробленых фільтрам злоўжываньняў", "right-abusefilter-view-private": "прагляд фільтраў злоўжываньняў пазначаных як прыватныя", @@ -41,17 +46,37 @@ "action-abusefilter-view": "паказаць фільтры злоўжываньняў", "action-abusefilter-log": "прагляд журнала злоўжываньняў", "action-abusefilter-log-detail": "паказаць падрабязнасьці запісаў журналу злоўжываньняў", - "action-abusefilter-private": "паказаць прыватныя зьвесткі ў журнале злоўжываньняў", + "action-abusefilter-privatedetails": "паказаць прыватныя зьвесткі ў журнале злоўжываньняў", + "action-abusefilter-privatedetails-log": "прагляд журналу доступу да асабістых зьвестак фільтру злоўжываньняў", "action-abusefilter-modify-restricted": "зьмяніць фільтры злоўжываньняў з абмежаванымі дзеяньнямі", "action-abusefilter-revert": "скасаваць усе зьмены, зробленыя пазначаным фільтрам злоўжываньняў", "action-abusefilter-view-private": "паказаць фільтры злоўжываньняў пазначаныя як прыватныя", - "abusefilter-log": "Журнал фільтру злоўжываньняў", + "action-abusefilter-log-private": "прагляд журналаў фільтраў злоўжываньняў, пазначаных як прыватныя", + "action-abusefilter-hide-log": "схаваць запісы ў журнале злоўжываньняў", + "action-abusefilter-hidden-log": "паказваць схаваныя запісы ў журнале злоўжываньняў", + "action-abusefilter-modify-global": "стварэньне ці зьмену глябальных фільтраў злоўжываньняў", "abusefilter-log-summary": "Гэты журнал паказвае сьпіс усіх дзеяньняў, якія былі выяўленыя фільтрамі.", "abusefilter-log-search": "Пошук у журнале злоўжываньняў", "abusefilter-log-search-user": "Удзельнік:", - "abusefilter-log-search-filter": "Ідэнтыфікатары фільтру (падзеленыя вэртыкальнымі рысамі):", + "abusefilter-log-search-group": "Група фільтраў:", + "abusefilter-log-search-group-any": "Любыя", + "abusefilter-log-search-filter": "Ідэнтыфікатары фільтру:", + "abusefilter-log-search-filter-help": "Аддзяліце вэртыкальнымі рысамі, прэфіксам «$1» для глябальных фільтраў", "abusefilter-log-search-title": "Назва:", "abusefilter-log-search-wiki": "Вікі:", + "abusefilter-log-search-impact": "Уплыў:", + "abusefilter-log-search-impact-all": "Усе дзеяньні", + "abusefilter-log-search-impact-saved": "Толькі захаваныя зьмены", + "abusefilter-log-search-impact-not-saved": "Без захаваных зьменаў", + "abusefilter-log-search-entries-label": "Бачнасьць:", + "abusefilter-log-search-entries-all": "Усе запісы", + "abusefilter-log-search-entries-hidden": "Толькі схаваныя запісы", + "abusefilter-log-search-entries-visible": "Толькі бачныя запісы", + "abusefilter-log-search-action-label": "Дзеяньне запуску:", + "abusefilter-log-search-action-other": "Іншае", + "abusefilter-log-search-action-any": "Любы", + "abusefilter-log-search-action-taken-label": "Прынятыя меры:", + "abusefilter-log-search-action-taken-any": "Любы", "abusefilter-log-search-submit": "Шукаць", "abusefilter-log-entry": "$1: $2 {{GENDER:$8|выклікаў|выклікала}} фільтар злоўжываньняў пры выкананьні дзеяньня «$3» на старонцы $4.\nПрынятыя меры: $5;\nАпісаньне фільтру: $6", "abusefilter-log-entry-withdiff": "$1: $2 {{GENDER:$8|выклікаў|выклікала}} фільтар пры выкананьні дзеяньня «$3» на старонцы $4.\nЗробленыя захады: $5;\nАпісаньне фільтру: $6 ($7)", @@ -65,26 +90,46 @@ "abusefilter-log-details-var": "Зьменная", "abusefilter-log-details-val": "Значэньне", "abusefilter-log-details-vars": "Парамэтры дзеяньня", - "abusefilter-log-details-private": "Дэталі прыватнага журналу", + "abusefilter-log-details-privatedetails": "Дэталі прыватнага журналу", "abusefilter-log-details-ip": "Выходны ІР-адрас", + "abusefilter-log-details-checkuser": "Праверыць удзельніка", "abusefilter-log-noactions": "няма", "abusefilter-log-details-diff": "Зьмены, зробленыя ў рэдагаваньні", "abusefilter-log-linkoncontribs": "журнал злоўжываньняў", "abusefilter-log-linkoncontribs-text": "Журнал злоўжываньняў {{GENDER:$1|гэтага ўдзельніка|гэтай удзельніцы}}", - "abusefilter-log-hidden": "(запіс схаваны)", + "abusefilter-log-linkonhistory": "прагляд журналу злоўжываньняў", + "abusefilter-log-linkonhistory-text": "Паказаць журналы злоўжываньняў для гэтай старонкі", + "abusefilter-log-linkonundelete": "прагляд журналу злоўжываньняў", + "abusefilter-log-linkonundelete-text": "Паказаць журналы злоўжываньняў для гэтай старонкі", "abusefilter-log-hidden-implicit": "(схаваная, бо вэрсія была выдаленая)", "abusefilter-log-cannot-see-details": "Вы ня маеце права глядзець падрабязнасьці гэтага запісу.", + "abusefilter-log-cannot-see-privatedetails": "Вы ня маеце правоў на прагляд падрабязнасьцяў гэтага запісу.", + "abusefilter-log-nonexistent": "Запісу з указаным ідэнтыфікатарам не існуе.", "abusefilter-log-details-hidden": "Вы ня можаце праглядзець падрабязнасьці гэтага запісу,\nтаму што ён схаваны ад публічнага прагляду.", + "abusefilter-log-details-hidden-implicit": "Вы ня можаце праглядзець падрабязнасьці гэтага запісу, так як суадносная яму вэрсія схаваная ад публічнага прагляду.", "abusefilter-log-private-not-included": "Адзін ці болей ідэнтыфікатараў фільтру, пазначаных вамі, зьяўляюцца прыватнымі. Праз тое, што вы ня можаце праглядаць зьвесткі прыватных фільтраў, гэтыя фільтры ня будуць выкарыстаныя пры пошуку.", "abusefilter-log-hide-legend": "Схаваць запіс у журнале", "abusefilter-log-hide-id": "Ідэнтыфікатар запісу ў журнале:", "abusefilter-log-hide-hidden": "Схаваць гэты запіс ад публічнага прагляду", "abusefilter-log-hide-reason": "Прычына:", + "abusefilter-log-hide-reason-other": "Іншая/дадатковая прычына:", "abusefilter-log-hide-forbidden": "Вы ня маеце права хаваць запісы\nў журнале злоўжываньняў.", + "abusefilter-log-entry-suppress": "$1 {{GENDER:$2|схаваў|схавала}} $3", + "abusefilter-log-entry-unsuppress": "$1 {{GENDER:$2|адкрыў|адкрыла}} $3", "logentry-abusefilter-hit": "$1 {{#GENDER:$2|выклікаў|выклікала}} спрацоўваньне фільтру $4 пры выкананьні дзеяньня «$5» на старонцы $3. Прынятыя меры: $6 ($7)", - "abusefilter-management": "Кіраваньне фільтрам злоўжываньняў", + "log-action-filter-abusefilter": "Тып зьмены фільтру:", + "log-action-filter-abusefilter-create": "Стварэньне новага фільтру", + "log-action-filter-abusefilter-modify": "Зьмяненьне фільтру", + "log-action-filter-suppress-abuselog": "Прыхаваньне журналу злоўжываньняў", + "log-action-filter-rights-blockautopromote": "Блякаваньне аўтапрасоўваньня", + "log-action-filter-rights-restoreautopromote": "Аднаўленьне аўтапрасоўваньня", + "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|атрымаў|атрымала}} доступ да асабістых зьвестак $3", + "logentry-rights-blockautopromote": "$1 {{GENDER:$2|заблякаваў|заблякавала}} аўтапрасоўваньне {{GENDER:$4|$3}} на пэрыяд $5", + "logentry-rights-restoreautopromote": "$1 {{GENDER:$2|аднавіў|аднавіла}} здольнасьць аўтапрасоўваньня {{GENDER:$4|$3}}", + "abusefilterprivatedetails-log-name": "Журнал доступу да асабістых зьвестак фільтру злоўжываньняў", "abusefilter-list": "Усе фільтры", "abusefilter-list-id": "Ідэнтыфікатар фільтру", + "abusefilter-list-pattern": "Узор", "abusefilter-list-status": "Статус", "abusefilter-list-public": "Публічнае апісаньне", "abusefilter-list-consequences": "Наступствы", @@ -100,8 +145,10 @@ "abusefilter-enabled": "Уключаны", "abusefilter-deleted": "Выдалены", "abusefilter-disabled": "Выключаны", + "abusefilter-throttled": "абмежаваны", "abusefilter-hitcount": "$1 {{PLURAL:$1|выкананьне|выкананьні|выкананьняў}}", "abusefilter-new": "Стварыць новы фільтар", + "abusefilter-import-button": "Імпартаваць фільтар", "abusefilter-return": "Вярнуцца да кіраваньня фільтрам", "abusefilter-status-global": "Глябальны", "abusefilter-list-options": "Парамэтры", @@ -112,7 +159,18 @@ "abusefilter-list-options-scope": "Паказаць фільтры:", "abusefilter-list-options-scope-local": "Толькі лякальныя правілы", "abusefilter-list-options-scope-global": "Толькі глябальныя правілы", + "abusefilter-list-options-scope-all": "Мясцовыя і глябальныя правілы", + "abusefilter-list-options-further-options": "Іншыя налады:", "abusefilter-list-options-hidedisabled": "Схаваць выключаныя фільтры", + "abusefilter-list-options-hideprivate": "Схаваць асабістыя фільтры", + "abusefilter-list-options-searchfield": "Знайсьці сярод правілаў:", + "abusefilter-list-options-searchpattern": "Уставіць узор", + "abusefilter-list-options-searchoptions": "Рэжым пошуку:", + "abusefilter-list-options-search-like": "Просты запыт", + "abusefilter-list-options-search-rlike": "Звычайны выраз", + "abusefilter-list-options-search-irlike": "Рэгулярны выраз, адчувальны да рэгістру", + "abusefilter-list-invalid-searchmode": "Пазначаны рэжым пошуку недапушчальны.", + "abusefilter-list-regexerror": "Падчас пошуку адбылася памылка: сынтаксычная памылка рэгулярнага выразу.", "abusefilter-list-options-submit": "Абнавіць", "abusefilter-tools-text": "Тут знаходзяцца інструмэнты, якія могуць быць карыснымі ў фармуляваньні і праверцы фільтраў злоўжываньняў.", "abusefilter-tools-expr": "Праверка выразаў", @@ -120,21 +178,26 @@ "abusefilter-tools-reautoconfirm": "Аднавіць статус аўтаматычнага пацьверджаньня", "abusefilter-tools-reautoconfirm-user": "Удзельнік:", "abusefilter-tools-reautoconfirm-submit": "Паўторнае аўтаматычнае пацьверджаньне", + "abusefilter-tools-restoreautopromote": "Аўтапрасоўваньне адноўленае інструмэнтамі Фільтру злоўжываньняў.", "abusefilter-reautoconfirm-none": "{{GENDER:$1|Гэты ўдзельнік|Гэтая ўдзельніца}} ня мае адключанага статусу аўтаматычнага пацьверджаньня.", "abusefilter-reautoconfirm-notallowed": "Вам не дазволена аднаўляць статус аўтаматычнага пацьверджаньня.", "abusefilter-reautoconfirm-done": "Адноўлены статус аўтаматычнага пацьверджаньня рахунку", - "abusefilter-status": "З $1 {{PLURAL:$1|апошняга дзеяньня|апошніх дзеяньняў|апошніх дзеяньняў}}, $2 ($3%) {{PLURAL:$2|трапіла|трапілі|трапілі}} пад абмежаваньне $4, а $5 ($6%) {{PLURAL:$5|адпавядае|адпавядаюць|адпавядаюць}} аднаму з уключаных цяпер фільтраў.", + "abusefilter-status": "З $1 {{PLURAL:$1|апошняга дзеяньня|апошніх дзеяньняў}} $2 ($3%) {{PLURAL:$2|трапіла|трапілі}} пад абмежаваньне $4, а $5 ($6%) {{PLURAL:$5|адпавядае|адпавядаюць}} аднаму з уключаных цяпер фільтраў.", "abusefilter-edit": "Рэдагаваньне фільтру злоўжываньняў", "abusefilter-edit-subtitle": "Рэдагаваньне фільтру $1", "abusefilter-edit-subtitle-new": "Стварэньне фільтру", + "abusefilter-edit-token-not-match": "Рэдагаваньне не захаванае! Калі ласка, захавайце яшчэ раз.", "abusefilter-edit-oldwarning": "<strong>Вы рэдагуеце старую вэрсію гэтага фільтру.\nСтатыстыка падаецца для самай новай вэрсіі фільтру.\nКалі Вы захаваеце Вашыя зьмены, Вы скасуеце ўсе зьмены зробленыя раней.</strong> •\n[[Special:AbuseFilter/history/$2|Вярнуцца да гісторыі гэтага фільтру]].", + "abusefilter-edit-oldwarning-view": "<strong>Вы праглядаеце старую вэрсію гэтага фільтру.\nПрыведзеныя статыстычныя зьвесткі адносяцца да самай апошняй вэрсіі фільтру.</strong> •\n[[Special:AbuseFilter/history/$2|Вярнуцца да гісторыі гэтага фільтру]].", "abusefilter-edit-status-label": "Статыстыка:", - "abusefilter-edit-status": "З $1 {{PLURAL:$1|апошняга дзеяньня|апошніх дзеяньняў}} $2 ($3%) {{PLURAL:$2|адпавядала гэтаму фільтру|адпавядалі гэтаму фільтру}}.", - "abusefilter-edit-status-profile": "З $1 {{PLURAL:$1|апошняга дзеяньня|апошніх дзеяньняў}} $2 ($3%) {{PLURAL:$2|адпавядала гэтаму фільтру|адпавядалі гэтаму фільтру}}.\nУ сярэднім, выкананьне фільтру працягвалася $4 мс і выкарыстоўвала $5 {{PLURAL:$5|умову|умовы|умоваў}} зь ліміту ўмоваў.", + "abusefilter-edit-status": "З $1 {{PLURAL:$1|апошняга дзеяньня|апошніх дзеяньняў}} $2 ($3%) {{PLURAL:$2|адпавядала гэтаму фільтру|адпавядалі гэтаму фільтру}}.\nУ сярэднім яго выкананьне займала $4 мс і ён выкарыстоўваў $5 {{PLURAL:$5|умову|умовы|умоваў}} зь ліміту ўмоваў.", + "abusefilter-edit-throttled-warning": "'''Увага:''' гэты фільтар быў аўтаматычна пазначаны шкодным. Дзеля мераў бясьпекі наступныя дзеяньні ня будуць выкананыя ($1). Калі ласка, праверце і [[mw:Extension:AbuseFilter/Conditions|аптымізуйце]] вашыя ўмовы, каб зьняць гэтае абмежаваньне", "abusefilter-edit-new": "Новы фільтар", "abusefilter-edit-save": "Захаваць фільтар", "abusefilter-edit-id": "Ідэнтыфікатар фільтру:", + "abusefilter-edit-switch-editor": "Пераключыць рэдактар", "abusefilter-edit-description": "Апісаньне:\n:''(агульнадаступнае)''", + "abusefilter-edit-field-description": "апісаньне", "abusefilter-edit-group": "Група фільтраў:", "abusefilter-edit-flags": "Сьцягі:", "abusefilter-edit-enabled": "Уключыць гэты фільтар", @@ -142,6 +205,7 @@ "abusefilter-edit-hidden": "Схаваць падрабязнасьці гэтага фільтру ад агульнага прагляду", "abusefilter-edit-global": "Глябальны фільтар", "abusefilter-edit-rules": "Умовы:", + "abusefilter-edit-field-conditions": "умовы", "abusefilter-edit-notes": "Заўвагі:", "abusefilter-edit-lastmod": "Апошняя зьмена фільтру:", "abusefilter-edit-lastmod-text": "$1 удзельнікам $2", @@ -152,24 +216,53 @@ "abusefilter-edit-action-blockautopromote": "Зьняць з удзельніка статус аўтаматычнага пацьверджаньня", "abusefilter-edit-action-degroup": "Выдаліць удзельніка з усіх прывілеяваных групаў", "abusefilter-edit-action-block": "Заблякаваць удзельніка і/ці ІР-адрас", + "abusefilter-edit-action-blocktalk": "Заблякаваць удзельніку і/ці IP-адрасу магчымасьць рэдагаваць уласную старонку гутарак", "abusefilter-edit-action-throttle": "Выконваць дзеяньні, толькі калі ўдзельнік перайшоў дапушчальны ўзровень", "abusefilter-edit-action-rangeblock": "Заблякаваць адпаведны IP-дыяпазон, зь якога працуе ўдзельнік", "abusefilter-edit-action-tag": "Пазначыць рэдагаваньне для далейшай праверкі.", "abusefilter-edit-throttle-count": "Колькасьць дазволеных дзеяньняў:", "abusefilter-edit-throttle-period": "Пэрыяд часу (у сэкундах):", "abusefilter-edit-throttle-groups": "Звужэньне па групах:", + "abusefilter-edit-throttle-groups-help": "Глядзіце $1.", + "abusefilter-edit-throttle-groups-help-text": "дакумэнтацыю на mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Падзяліце коскамі, каб злучыць праз І, і разрывамі радкоў, каб злучыць праз АБО", + "abusefilter-edit-throttle-placeholder": "Аддзяліце коскамі, каб злучыць празь І, і ўстаўляйце па адным, каб злучыць праз АБО", + "abusefilter-throttle-ip": "IP-адрас", + "abusefilter-throttle-user": "рахунак удзельніка", + "abusefilter-throttle-range": "Дыяпазон /16", + "abusefilter-throttle-creationdate": "дата стварэньня рахунку", + "abusefilter-throttle-editcount": "колькасьць рэдагаваньняў", + "abusefilter-throttle-site": "увесь сайт", + "abusefilter-throttle-page": "старонка", + "abusefilter-throttle-none": "(няма)", + "abusefilter-throttle-details": "Дазволіць $1 {{PLURAL:$1|дзеяньне|дзеяньні|дзеяньняў}} кожныя $2 {{PLURAL:$2|сэкунда|сэкунды|сэкундаў}}, абмяжоўваць групамі па: $3", "abusefilter-edit-warn-message": "Сыстэмнае паведамленьне для папярэджаньня:", "abusefilter-edit-warn-other": "Іншае паведамленьне", "abusefilter-edit-warn-other-label": "Назва старонкі іншага паведамленьня:\n:''(бяз прэфіксу «MediaWiki:»)''", "abusefilter-edit-warn-actions": "Дзеяньні:", "abusefilter-edit-warn-preview": "Паказаць/схаваць папярэдні прагляд абранага паведамленьня", "abusefilter-edit-warn-edit": "Стварыць/рэдагаваць выбранае паведамленьне", + "abusefilter-edit-disallow-message": "Сыстэмнае паведамленьне для забароны:", + "abusefilter-edit-disallow-other": "Іншае паведамленьне", + "abusefilter-edit-disallow-other-label": "Назва старонкі іншага паведамленьня:\n:''(бяз прэфіксу «MediaWiki:»)''", + "abusefilter-edit-disallow-actions": "Дзеяньні:", + "abusefilter-edit-disallow-preview": "Паказаць/схаваць папярэдні прагляд абранага паведамленьня", + "abusefilter-edit-disallow-edit": "Стварыць/Рэдагаваць абранае паведамленьне", "abusefilter-edit-tag-tag": "Ужываемыя [[Special:Tags|тэгі]]:", + "abusefilter-edit-tag-placeholder": "Дадаць меткі (па адной або праз коску)", + "abusefilter-edit-tag-hidden-placeholder": "Дадаць меткі (праз коску)", + "abusefilter-edit-block-anon-durations": "Працягласьць блякаваньня для ананімных удзельнікаў:", + "abusefilter-edit-block-user-durations": "Працягласьць блякаваньня для зарэгістраваных карыстальнікаў:", + "abusefilter-block-anon": "Блякаваць ананімных удзельнікаў", + "abusefilter-block-user": "блякаваць зарэгістраваных удзельнікаў", + "abusefilter-block-talk": "старонка абмеркаваньня заблякаваная", "abusefilter-edit-denied": "Вы ня можаце праглядзець дэталі гэтага фільтру, таму што яны схаваныя ад агульнага прагляду.", "abusefilter-edit-main": "Парамэтры фільтру", "abusefilter-edit-done-subtitle": "Фільтар быў адрэдагаваны", "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Вашыя зьмены]] [[Special:AbuseFilter/$1|фільтру $3]] былі захаваныя.", "abusefilter-edit-badsyntax": "У пазначаным фільтры знойдзеная сынтаксычная памылка.\nПаведамленьне парсэра: <pre>$1</pre>", + "abusefilter-edit-missingfields": "Наступныя палі зьяўляюцца абавязковымі й павінны быць запоўнены: $1", + "abusefilter-edit-deleting-enabled": "Вы ня можаце пазначыць дзейны фільтар як выдалены.", "abusefilter-edit-restricted": "Вы ня можаце рэдагаваць гэты фільтар, таму што ён утрымлівае адно ці болей абмежаваных дзеяньняў.\nКалі ласка, зьвярніцеся да ўдзельніка з адпаведнымі правамі, каб дадаць абмежаванае дзеяньне.", "abusefilter-edit-viewhistory": "Паказаць гісторыю гэтага фільтру", "abusefilter-edit-history": "Гісторыя:", @@ -181,10 +274,18 @@ "abusefilter-edit-export": "Экспартаваць гэты фільтар у іншую вікі", "abusefilter-edit-syntaxok": "Сынтаксычныя памылкі ня знойдзеныя.", "abusefilter-edit-syntaxerr": "Знойдзеная сынтаксычная памылка: $1", + "abusefilter-edit-warn-leave": "Калі вы зачыніце гэтую старонку, усе зьмены да гэтага фільтру будуць страчаныя.", "abusefilter-edit-bad-tags": "Адна ці болей пазначаных вамі метак — няслушная.\nМеткі павінны быць кароткімі, і яны ня мусяць утрымліваць спэцыяльныя сымбалі і ня мусяць быць зарэзэрваваныя іншым праграмным забесьпячэньнем. Паспрабуйце абраць новую назву меткі.", "abusefilter-edit-notallowed": "Вы ня маеце правоў на стварэньне альбо рэдагаваньне фільтраў злоўжываньняў", "abusefilter-edit-notallowed-global": "Вы ня маеце правоў на стварэньне альбо рэдагаваньне глябальных фільтраў злоўжываньняў", - "abusefilter-edit-notallowed-global-custom-msg": "Пабочныя папярэджаньні ў глябальных фільтрах не падтрымліваюцца", + "abusefilter-edit-notallowed-global-custom-msg": "Пабочныя папярэджаньні ці забараняльныя паведамленьні ў глябальных фільтрах не падтрымліваюцца", + "abusefilter-edit-invalid-warn-message": "Папераджальнае паведамленьне ня можа быць пустым.", + "abusefilter-edit-invalid-disallow-message": "Паведамленьне забароны ня можа быць парожнім.", + "abusefilter-edit-invalid-throttlecount": "Лічыльнік дзеяньняў рэгулявальніка павінен быць станоўчым цэлым лікам.", + "abusefilter-edit-invalid-throttleperiod": "Пэрыяд рэгулятару мусіць быць дадатным лікам.", + "abusefilter-edit-empty-throttlegroups": "Мусіць быць абрана хаця б адна група рэгулятару.", + "abusefilter-edit-duplicated-throttlegroups": "Групы рэгулятараў ня могуць мець дублікатаў.", + "abusefilter-edit-invalid-throttlegroups": "Названыя групы дросэляў недапушчальныя.", "abusefilter-edit-builder-select": "Выберыце парамэтар, каб дадаць яго", "abusefilter-edit-builder-group-op-arithmetic": "Арытмэтычныя апэратары", "abusefilter-edit-builder-op-arithmetic-addition": "Складаньне (+)", @@ -195,7 +296,9 @@ "abusefilter-edit-builder-op-arithmetic-pow": "Ступень (**)", "abusefilter-edit-builder-group-op-comparison": "Апэратары параўнаньня", "abusefilter-edit-builder-op-comparison-equal": "Значэньне, роўнае (==)", + "abusefilter-edit-builder-op-comparison-equal-strict": "Значэньне й тып, роўныя (===)", "abusefilter-edit-builder-op-comparison-notequal": "Значэньне, ня роўнае (!=)", + "abusefilter-edit-builder-op-comparison-notequal-strict": "Значэньне й тып, ня роўныя (!==)", "abusefilter-edit-builder-op-comparison-lt": "Меней чым (<)", "abusefilter-edit-builder-op-comparison-gt": "Болей чым (>)", "abusefilter-edit-builder-op-comparison-lte": "Меней ці роўныя (<=)", @@ -212,29 +315,37 @@ "abusefilter-edit-builder-misc-contains": "Левы радок ўтрымлівае правы радок (contains)", "abusefilter-edit-builder-misc-stringlit": "Радок сымбаляў (\"\")", "abusefilter-edit-builder-misc-tern": "Тэрнарны апэратар (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Умова (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Умова (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "Кароткая ўмова (калі X, то Y канец)", "abusefilter-edit-builder-group-funcs": "Функцыі", "abusefilter-edit-builder-funcs-length": "Даўжыня радку (length)", "abusefilter-edit-builder-funcs-lcase": "У малыя літары (lcase)", "abusefilter-edit-builder-funcs-ucase": "У вялікія літары (ucase)", "abusefilter-edit-builder-funcs-ccnorm": "Нармалізацыя шматзначных сымбаляў (ccnorm)", + "abusefilter-edit-builder-funcs-ccnorm-contains-any": "Нармалізаваць і знайсьці радок для некалькіх падрадкоў у рэжыме OR (ccnorm_contains_any)", + "abusefilter-edit-builder-funcs-ccnorm-contains-all": "Нармалізацыя і пошук радка для некалькіх падрадкоў у рэжыме І (ccnorm_contains_all)", "abusefilter-edit-builder-funcs-rmdoubles": "Выдаленьне сымбаляў, што паўтараюцца (rmdoubles)", "abusefilter-edit-builder-funcs-specialratio": "Спэцыяльных сымбаляў / усяго сымбаляў (specialratio)", "abusefilter-edit-builder-funcs-norm": "Нармалізацыя (norm)", "abusefilter-edit-builder-funcs-count": "Колькасьць уключэньняў радку Х у радок Y (count)", "abusefilter-edit-builder-funcs-rcount": "Колькасьць адпаведнасьцяў рэгулярнаму выразу X у радку Y (rcount)", + "abusefilter-edit-builder-funcs-get_matches": "Масіў рэгулярных выразаў адпавядае тэксту для кожнай групы захопу (get_matches)", "abusefilter-edit-builder-funcs-rmwhitespace": "Выдаліць прагалы (rmwhitespace)", "abusefilter-edit-builder-funcs-rmspecials": "Выдаліць спэцыяльныя сымбалі (rmspecials)", "abusefilter-edit-builder-funcs-ip_in_range": "Ці знаходзіцца IP-адрас ў дыяпазоне? (ip_in_range)", "abusefilter-edit-builder-funcs-contains-any": "Радок пошуку для шматлікіх падрадкоў у OR-рэжыме. (contains_any)", + "abusefilter-edit-builder-funcs-contains-all": "Радок пошуку для некалькіх падрадкоў у рэжыме І. (contains_all)", + "abusefilter-edit-builder-funcs-equals-to-any": "Праверце, ці роўны дадзены аргумэнт (===) любому з наступных аргумэнтаў (equals_to_any)", "abusefilter-edit-builder-funcs-substr": "Падрадок (substr)", "abusefilter-edit-builder-funcs-strpos": "Пазыцыя падрадку ў радку (strpos)", "abusefilter-edit-builder-funcs-str_replace": "Замена падрадку ў радку (str_replace)", "abusefilter-edit-builder-funcs-rescape": "Экранаваньне радка як літэрал у рэгулярных выразах (rescape)", "abusefilter-edit-builder-funcs-set_var": "Устанавіць зьменную (set_var)", + "abusefilter-edit-builder-funcs-sanitize": "Нармалізацыя HTML-аб’ектаў у сымбалі юнікоду (sanitize)", "abusefilter-edit-builder-group-vars": "Зьменныя", "abusefilter-edit-builder-vars-accountname": "Назва рахунку (on account creation)", "abusefilter-edit-builder-vars-timestamp": "Unix-час зьмены", + "abusefilter-edit-builder-vars-timestamp-expanded": "Часовая метка журналу", "abusefilter-edit-builder-vars-action": "Дзеяньне", "abusefilter-edit-builder-vars-addedlines": "Колькасьць радкоў, дададзеных пры рэдагаваньні", "abusefilter-edit-builder-vars-delta": "Зьмена памеру пад час рэдагаваньня", @@ -249,14 +360,17 @@ "abusefilter-edit-builder-vars-page-ns": "Прастора назваў старонкі", "abusefilter-edit-builder-vars-page-title": "Назва старонкі (без прасторы назваў)", "abusefilter-edit-builder-vars-page-prefixedtitle": "Поўная назва старонкі", + "abusefilter-edit-builder-vars-page-age": "Узрост старонкі (у сэкундах)", "abusefilter-edit-builder-vars-movedfrom-id": "Ідэнтыфікатар крыніцы перанесенай старонкі", "abusefilter-edit-builder-vars-movedfrom-ns": "Прастора назваў крыніцы перанесенай старонкі", "abusefilter-edit-builder-vars-movedfrom-title": "Назва крыніцы перанесенай старонкі", "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "Поўная назва крыніцы перанесенай старонкі", + "abusefilter-edit-builder-vars-movedfrom-age": "Узрост крынічнай старонкі пры перайменаваньні (у сэкундах)", "abusefilter-edit-builder-vars-movedto-id": "Ідэнтыфікатар мэтавай старонкі пераносу", "abusefilter-edit-builder-vars-movedto-ns": "Прастора назваў мэтавай старонкі пераносу", "abusefilter-edit-builder-vars-movedto-title": "Назва мэтавай старонкі пераносу", "abusefilter-edit-builder-vars-movedto-prefixedtitle": "Поўная назва мэтавай старонкі пераносу", + "abusefilter-edit-builder-vars-movedto-age": "Узрост мэтавай старонкі пры перайменаваньні (у сэкундах)", "abusefilter-edit-builder-vars-user-editcount": "Колькасьць рэдагаваньняў удзельніка", "abusefilter-edit-builder-vars-user-age": "Узрост рахунку ўдзельніка", "abusefilter-edit-builder-vars-user-name": "Назва рахунку ўдзельніка", @@ -266,28 +380,45 @@ "abusefilter-edit-builder-vars-user-emailconfirm": "Час пацьверджаньня адрасу электроннай пошты", "abusefilter-edit-builder-vars-recent-contributors": "Апошнія дзесяць удзельнікаў, якія рэдагавалі старонку", "abusefilter-edit-builder-vars-first-contributor": "Першы рэдактар старонкі", + "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "Апошнія дзесяць карыстальнікаў, якія рабілі ўнёсак у крынічную старонку перайменаваньня", + "abusefilter-edit-builder-vars-movedfrom-first-contributor": "Першы карыстальнік, які рабіў унёсак у крынічную старонку перайменаваньня", + "abusefilter-edit-builder-vars-movedto-recent-contributors": "Апошнія дзесяць карыстальнікаў, якія рэдагавалі старонку, куды адбываецца перанос", + "abusefilter-edit-builder-vars-movedto-first-contributor": "Першы карыстальнік старонкі, які правіў старонку, куды адбываецца перанос", "abusefilter-edit-builder-vars-all-links": "Усе вонкавыя спасылкі ў новым тэксьце", "abusefilter-edit-builder-vars-added-links": "Усе вонкавыя спасылкі дададзеныя ў рэдагаваньні", "abusefilter-edit-builder-vars-removed-links": "Усе вонкавыя спасылкі выдаленыя ў рэдагаваньні", - "abusefilter-edit-builder-vars-old-text": "Стары вікітэкст, да рэдагаваньня (больш не выкарыстоўваецца)", - "abusefilter-edit-builder-vars-new-text": "Новы вікі-тэкст, пасьля рэдагаваньня", + "abusefilter-edit-builder-vars-old-wikitext": "Вікітэкст старой старонкі, да рэдагаваньня", + "abusefilter-edit-builder-vars-new-wikitext": "Вікі-тэкст новай старонкі, пасьля рэдагаваньня", "abusefilter-edit-builder-vars-new-pst": "Вікітэкст новай старонкі, трансфармаваны перад захаваньнем", "abusefilter-edit-builder-vars-diff-pst": "Уніфікаваная розьніца зьменаў у працэсе рэдагаваньня, ператвораная перад захаваньнем", "abusefilter-edit-builder-vars-addedlines-pst": "Радкі, дададзеныя пры рэдагаваньні, ператвораныя перад захаваньнем", - "abusefilter-edit-builder-vars-new-text-stripped": "Новы тэкст старонкі, ачышчаны ад усіх пазнакаў", + "abusefilter-edit-builder-vars-new-text": "Новы тэкст старонкі, ачышчаны ад усіх пазнакаў", "abusefilter-edit-builder-vars-new-html": "Разабраны HTML-код новай вэрсіі", "abusefilter-edit-builder-vars-restrictions-edit": "Узровень абароны старонкі ад рэдагаваньняў", "abusefilter-edit-builder-vars-restrictions-move": "Узровень абароны старонкі ад пераносаў", "abusefilter-edit-builder-vars-restrictions-create": "Абарона старонкі ад стварэньня", "abusefilter-edit-builder-vars-restrictions-upload": "Абарона файла ад загрузкі", - "abusefilter-edit-builder-vars-old-text-stripped": "Стары зьмест старонкі, пазбаўлены ад усіх пазнакаў", + "abusefilter-edit-builder-vars-movedfrom-restrictions-edit": "Узровень абароны крынічнай старонкі ад рэдагаваньняў", + "abusefilter-edit-builder-vars-movedfrom-restrictions-move": "Узровень абароны крынічнай старонкі ад пераносаў", + "abusefilter-edit-builder-vars-movedfrom-restrictions-create": "Абарона ад стварэньня старонкі, якая пераносіцца", + "abusefilter-edit-builder-vars-movedfrom-restrictions-upload": "Ахова пры загрузцы файла, які пераносіцца", + "abusefilter-edit-builder-vars-movedto-restrictions-edit": "Узровень абароны мэтавай старонкі ад рэдагаваньняў", + "abusefilter-edit-builder-vars-movedto-restrictions-move": "Узровень абароны мэтавай старонкі ад пераносаў", + "abusefilter-edit-builder-vars-movedto-restrictions-create": "Абарона ад стварэньня старонкі, якая пераносіцца", + "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Ахова пры загрузцы файла, які пераносіцца", + "abusefilter-edit-builder-vars-old-text": "Стары зьмест старонкі, пазбаўлены ўсёй разьметкі (больш не выкарыстоўваецца)", "abusefilter-edit-builder-vars-old-links": "Спасылкі на старонцы перад рэдагаваньнем", "abusefilter-edit-builder-vars-old-html": "Стары вікітэкст старонкі, ператвораны ў фармат HTML (больш не выкарыстоўваецца)", - "abusefilter-edit-builder-vars-minor-edit": "Ці пазначана рэдагаваньне як дробнае", + "abusefilter-edit-builder-vars-minor-edit": "Ці пазначана рэдагаваньне як дробнае (больш не выкарыстоўваецца)", "abusefilter-edit-builder-vars-file-sha1": "SHA1-хэш зьместу файлаў", "abusefilter-edit-builder-vars-file-size": "Памер файлу ў байтах", "abusefilter-edit-builder-vars-file-mime": "MIME-тып файлу", "abusefilter-edit-builder-vars-file-mediatype": "Мэдыя-тып файлу", + "abusefilter-edit-builder-vars-file-width": "Шырыня файлу ў піксэлях", + "abusefilter-edit-builder-vars-file-height": "Вышыня файлу ў піксэлях", + "abusefilter-edit-builder-vars-file-bits-per-channel": "Глыбіня колеру ў файле", + "abusefilter-edit-builder-vars-wiki-name": "Імя базы дадзеных вікі-сайту", + "abusefilter-edit-builder-vars-wiki-language": "Код мовы на wiki", "abusefilter-filter-log": "Апошнія зьмены фільтру", "abusefilter-history": "Гісторыя зьменаў фільтру злоўжываньняў $1", "abusefilter-history-foruser": "Зьмены зробленыя $1", @@ -306,6 +437,7 @@ "abusefilter-history-filterid": "Фільтар", "abusefilter-history-select-legend": "Удакладніць пошук", "abusefilter-history-select-user": "Удзельнік:", + "abusefilter-history-select-filter": "Ідэнтыфікатар фільтру:", "abusefilter-history-select-submit": "Удакладніць", "abusefilter-history-diff": "Зьмены", "abusefilter-history-error-hidden": "Запытаны Вамі фільтар схаваны, і Вы ня можаце паглядзець яго гісторыю.", @@ -320,10 +452,16 @@ "abusefilter-exception-dividebyzero": "Спроба дзяленьня $2 на нуль у пазыцыі $1.", "abusefilter-exception-unrecognisedvar": "Нераспазнаная зьменная $2 у пазыцыі $1", "abusefilter-exception-notenoughargs": "Недастаткова аргумэнтаў для функцыі $2, якая выклікаецца ў пазыцыі $1.\nЧакаецца $3 {{PLURAL:$3|аргумэнт|аргумэнты|аргумэнтаў}}, атрымана $4", + "abusefilter-exception-toomanyargs": "Зашмат аргумэнтаў для функцыі $2, выкліканай на пазыцыі $1.\nЧакаецца ня больш за $3 {{PLURAL:$3|аргумэнт|аргумэнты|аргумэнтаў}}, {{PLURAL:$4|атрыманы|атрыманыя}} $4", "abusefilter-exception-regexfailure": "Памылка ў рэгулярным выразе «$2» у пазыцыі $1.", - "abusefilter-exception-overridebuiltin": "Недазволеная перавызначэньне ўбудаванай зьменнай «$2» ў пазыцыі $1.", + "abusefilter-exception-overridebuiltin": "Недазволенае перавызначэньне ўбудаванай зьменнай «$2» ў пазыцыі $1.", "abusefilter-exception-outofbounds": "Запыт няіснага элемэнту сьпісу $2 (памер сьпісу = $3) у пазыцыі $1.", + "abusefilter-exception-negativeindex": "Адмоўныя індэксы ў масівах не дапускаюцца. Атрыманы індэкс «$2» на пазыцыі $1.", "abusefilter-exception-notarray": "Запыт элемэнту масіву для аб’екту, які не зьяўляецца масівам, у пазыцыі $1.", + "abusefilter-exception-unclosedcomment": "Незакрыты камэнтар на пазыцыі $1.", + "abusefilter-exception-invalidiprange": "Няслушны IP-дыяпазон «$2», пададзены на пазыцыі $1.", + "abusefilter-exception-disabledvar": "Зьменная $2 на пазыцыі $1 больш не выкарыстоўваецца.", + "abusefilter-exception-variablevariable": "set і set_var патрабуюць, каб першы аргумэнт быў радковым літаралам, памылка ў сымбалі $1.", "abusefilter-action-tag": "Метка", "abusefilter-action-throttle": "Абмежаваць", "abusefilter-action-warn": "Папярэдзіць", @@ -341,6 +479,7 @@ "abusefilter-revert-search": "Выбар дзеяньняў", "abusefilter-revert-filter": "Ідэнтыфікатар фільтру:", "abusefilter-revert-preview-intro": "Ніжэй знаходзяцца дзеяньні, выкананыя фільтрам злоўжываньняў, якія будуць адмененыя гэтым дзеяньнем.\nКалі ласка, праверце іх уважліва і націсьніце «{{int:abusefilter-revert-confirm}}», каб пацьвердзіць ваш выбар.", + "abusefilter-revert-confirm-legend": "Пацьвердзіць адкат", "abusefilter-revert-confirm": "Пацьвердзіць", "abusefilter-revert-success": "Вы адкацілі ўсе дзеяньні, выкананыя фільтрам злоўжываньняў [[Special:AbuseFilter/$1|filter $2]].", "abusefilter-revert-reason": "Аўтаматычны адкат усіх дзеяньняў, выкананых фільтрам злоўжываньняў $1.\nПададзеная прычына: $2", @@ -352,12 +491,20 @@ "abusefilter-test-submit": "Праверыць", "abusefilter-test-load": "Загрузіць", "abusefilter-test-user": "Зьмены зробленыя ўдзельнікам:", + "abusefilter-test-nobots": "Схаваць рэдагаваньні робатаў", "abusefilter-test-period-start": "Зьмены зробленыя пасьля:", "abusefilter-test-period-end": "Зьмены зробленыя перад:", "abusefilter-test-page": "Зьмены, зробленыя на старонцы:", "abusefilter-test-shownegative": "Паказаць зьмены, якія не супадаюць зь фільтрам", "abusefilter-test-syntaxerr": "Фільтар, які Вы ўвялі, утрымлівае сынтаксычную памылку.\nВы можаце атрымаць поўнае тлумачэньне, калі націсьніце на кнопку «{{int:abusefilter-edit-check}}».", "abusefilter-test-badtitle": "Загаловак старонкі, які вы ўвялі, зьяўляецца няслушным. Магчыма, ён утрымлівае адзін ці некалькі сымбаляў, якія нельга выкарыстоўваць у назвах.", + "abusefilter-test-action": "Тып дзеяньня:", + "abusefilter-test-search-type-all": "Усе дзеяньні", + "abusefilter-test-search-type-edit": "Зьмены", + "abusefilter-test-search-type-move": "Пераносы", + "abusefilter-test-search-type-delete": "Выдаленьні", + "abusefilter-test-search-type-upload": "Загрузкі", + "abusefilter-test-search-type-createaccount": "Стварэньне рахункаў", "abusefilter-changeslist-examine": "праверыць", "abusefilter-examine": "Праверыць індывідуальныя зьмены", "abusefilter-examine-intro": "Гэтая старонка дазваляе Вам праверыць зьменныя, створаныя фільтрам злоўжываньняў для індывідуальных зьменаў, і праверыць іх на фільтрах.", @@ -377,13 +524,16 @@ "abusefilter-examine-noresults": "Нічога ня знойдзена па запыту з пададзенымі Вамі парамэтрамі.", "abusefilter-topnav": "'''Навігацыя фільтру злоўжываньняў'''", "abusefilter-topnav-home": "Пачатак", + "abusefilter-topnav-recentchanges": "Апошнія зьмены фільтру", "abusefilter-topnav-test": "Пакетнае тэставаньне", "abusefilter-topnav-examine": "Праверка апошніх рэдагаваньняў", "abusefilter-topnav-log": "Журнал злоўжываньняў", "abusefilter-topnav-tools": "Інструмэнты для наладкі", - "abusefilter-topnav-import": "Імпартаваць фільтар", "abusefilter-log-name": "Журнал фільтру злоўжываньняў", "abusefilter-log-header": "Гэты журнал паказвае кароткае апісаньне зьменаў у фільтрах.\nПоўную інфармацыю можна знайсьці ў [[Special:AbuseFilter/history|сьпісе]] апошніх зьменаў фільтраў.", + "abusefilter-logentry-create": "$1 {{GENDER:$2|стварыў|стварыла}} $4 ($5)", + "abusefilter-logentry-modify": "$1 {{GENDER:$2|зьмяніў|зьмяніла}} $4 ($5)", + "abusefilter-log-invalid-filter": "Некаторыя з пазначаных фільтарамі тэгаў няслушныя.", "abusefilter-log-noresults": "Вынікаў няма", "abusefilter-diff-title": "Адрозьненьні паміж вэрсіямі", "abusefilter-diff-item": "Элемэнт", @@ -396,5 +546,19 @@ "abusefilter-diff-next": "Наступныя зьмены", "abusefilter-import-intro": "Вы можаце выкарыстоўваць гэты інтэрфэйс для імпарту фільтраў зь іншых вікі.\nУ крынічнай вікі націсьніце «{{int:abusefilter-edit-export}}» у разьдзеле «{{int:abusefilter-edit-tools}}» інтэрфэйсу рэдагаваньня.\nСкапіруйце з узьнікшага тэкставага поля, і ўстаўце у гэта тэкставае поле, потым націсьніце «{{int:abusefilter-import-submit}}»,", "abusefilter-import-submit": "Імпартаваць зьвесткі", - "abusefilter-group-default": "Перадвызначаная" + "abusefilter-import-invalid-data": "Дадзеныя, якія вы спрабавалі імпартаваць, недапушчальныя", + "abusefilter-group-default": "Перадвызначаная", + "abusefilter-http-error": "Узьнікла памылка HTTP: $1", + "abusefilter-view-privatedetails-submit": "Паказаць асабістыя падрабязнасьці", + "abusefilter-view-privatedetails-legend": "Паказаць асабістыя падрабязнасьці", + "abusefilter-view-privatedetails-reason": "Прычына доступу да прыватных зьвестак:", + "abusefilter-log-details-id": "Ідэнтыфікатар журнала", + "abusefilter-invalid-request": "Няправільны запыт! Вы павінны атрымаць доступ да асабістых зьвестак журналу праз форму ў [[Special:AbuseLog/$1]] і пазначыць прычыну.", + "abusefilter-invalid-request-noid": "Няправільны запыт! Вы павінны атрымаць доступ да асабістых зьвестак журналу праз форму на старонцы зьвестак пра журнал злоўжываньняў і пазначыць прычыну.", + "log-description-abusefilterprivatedetails": "Гэты журнал паказвае сьпіс выпадкаў, калі карыстальнік зьвяртаўся да асабістых зьвестак журналу злоўжываньняў.", + "abusefilter-noreason": "Папярэджаньне: каб праглядзець прыватныя зьвесткі гэтага журналу, вы мусіце падаць прычыну.", + "abusefilter-log-ip-not-available": "Недаступна", + "abusefilter-tag-reserved": "Тэг <code>abusefilter-condition-limit</code> зарэзэрваваны для ўнутранага выкарыстаньня AbuseFilter.", + "tag-abusefilter-condition-limit": "дасягнутае абмежаваньне ўмовы", + "tag-abusefilter-condition-limit-description": "Рэдагаваньні або іншыя падзеі, якія ня могуць быць правераны ўсімі актыўнымі \n[[Special:AbuseFilter|фільтрамі злоўжываньняў]] ([[mw:Extension:AbuseFilter/Conditions|дапамога]])." } diff --git a/AbuseFilter/i18n/be.json b/AbuseFilter/i18n/be.json index bc36bfea..4e35cd24 100644 --- a/AbuseFilter/i18n/be.json +++ b/AbuseFilter/i18n/be.json @@ -1,17 +1,18 @@ { "@metadata": { "authors": [ + "Artsiom91", "LexArt", - "Тест", "Mikalai Udodau", + "Movses", + "Vlad5250", "Дзяніс Тутэйшы", - "Artsiom91", - "Movses" + "Тест" ] }, "abusefilter-desc": "Прымяняе аўтаматычную эўрыстыку да правак.", - "abusefilter": "Настройкі фільтра злоўжыванняў", - "abuselog": "Журнал злоўжыванняў", + "abusefilter": "Кіраванне фільтрам злоўжыванняў", + "abuselog": "Журнал фільтра злоўжыванняў", "abusefilter-disallowed": "Гэтае дзеянне было аўтаматычна кваліфікаванае як шкоднае і таму было забароненае. Калі Вы ўпэўненыя, што гэта карыснае дзеянне, калі ласка, звяжыцеся з адміністратарам і растлумачце яму, што Вы спрабуеце зрабіць. Кароткае апісанне правіла злоўжывання, якому адпавядае Вашае дзеянне: $1", "abusefilter-degrouped": "Гэтае дзеянне было аўтаматычна кваліфікаванае як шкоднае. Такім чынам, дзеянне было забароненае і, у выніку таго, што Ваш уліковы запіс трапіў пад падазрэнне, з яго былі знятыя ўсе правы. Калі Вы ўпэўнены, што гэта адбылося памылкова, калі ласка, звяжыцеся з бюракратам і растлумачце яму Вашыя дзеянні, тады Вашыя правы могуць быць адноўленыя. Кароткае апісанне правіла злоўжывання, якому адпавядае Вашае дзеянне: $1", "abusefilter-autopromote-blocked": "Гэтае дзеянне было аўтаматычна кваліфікаванае як шкоднае і было забароненае. Акрамя таго, у мэтах бяспекі, з Вашага ўліковага запісу часова знятыя некаторыя правы, якія звычайна даюцца падчас рэгістрацыі. Кароткае апісанне правіла злоўжывання, з якой супала Вашае дзеянне: $1", @@ -19,29 +20,98 @@ "abusefilter-blockreason": "Аўтаматычна заблакавана фільтрам злоўжыванняў.\nАпісанне адпаведнага правіла: $1", "abusefilter-degroupreason": "Фільтр злоўжыванняў аўтаматычна зняў правы.\nАпісанне правіла: $1", "abusefilter-accountreserved": "Гэты ўліковы запіс зарэзерваваны для выкарыстоўвання фільтрам злоўжыванняў.", + "right-abusefilter-modify": "Змена фільтраў злоўжыванняў", + "right-abusefilter-view": "Прагляд фільтраў злоўжыванняў", "right-abusefilter-log": "Глядзець журнал злоўжыванняў", - "abusefilter-log": "Журнал фільтра злоўжыванняў", + "right-abusefilter-log-detail": "Прагляд падрабязных запісаў у журнале злоўжыванняў", + "right-abusefilter-privatedetails": "Прагляд прыватных звестак ў журнале злоўжыванняў", + "right-abusefilter-privatedetails-log": "Прагляд журналу доступу да асабістых звестак фільтру злоўжыванняў", + "right-abusefilter-revert": "Адкат змяненняў, вырабленых фільтрам злоўжыванняў", + "right-abusefilter-hide-log": "Хаванне запісаў у журнале злоўжыванняў", + "right-abusefilter-hidden-log": "Прагляд схаваных запісаў у журнале злоўжыванняў", + "right-abusefilter-modify-global": "Стварэнне ці змяненне глабальных фільтраў злоўжыванняў", + "action-abusefilter-modify": "змяніць фільтры злоўжыванняў", + "action-abusefilter-view": "паказаць фільтры злоўжыванняў", + "action-abusefilter-log": "прагляд журнала злоўжыванняў", + "action-abusefilter-log-detail": "паказаць падрабязнасці запісаў журналу злоўжыванняў", + "action-abusefilter-privatedetails": "паказаць прыватныя звесткі ў журнале злоўжыванняў", + "action-abusefilter-privatedetails-log": "прагляд журналу доступу да асабістых звестак фільтру злоўжыванняў", + "action-abusefilter-revert": "скасаваць усе змены, зробленыя пазначаным фільтрам злоўжыванняў", + "action-abusefilter-hide-log": "схаваць запісы у журнале злоўжыванняў", + "action-abusefilter-hidden-log": "паказаць схаваныя запісы у журнале злоўжыванняў", + "action-abusefilter-modify-global": "стварэнне ці змяненне глабальных фільтраў злоўжыванняў", + "abusefilter-log-search": "Пошук у журнале злоўжыванняў", "abusefilter-log-search-user": "Удзельнік:", - "abusefilter-log-search-filter": "ID фільтраў (падзеленыя сімвалам вертыкальнай лініі):", + "abusefilter-log-search-group": "Група фільтраў:", + "abusefilter-log-search-filter": "ID фільтраў:", "abusefilter-log-search-title": "Загаловак:", + "abusefilter-log-search-wiki": "Вікі:", + "abusefilter-log-search-impact": "Уплыў:", + "abusefilter-log-search-entries-label": "Бачнасць:", + "abusefilter-log-search-action-other": "Іншае", + "abusefilter-log-search-submit": "Пошук", + "abusefilter-log-detailedentry-global": "глабальны фільтр $1", + "abusefilter-log-detailedentry-local": "фільтр $1", + "abusefilter-log-detailslink": "падрабязнасці", + "abusefilter-log-diff": "розн.", "abusefilter-log-hidelink": "настроіць бачнасць", "abusefilter-log-details-legend": "Падрабязнасці запісу журнала $1", + "abusefilter-log-details-var": "Пераменная", + "abusefilter-log-details-val": "Значэнне", + "abusefilter-log-details-vars": "Параметры дзеяння", + "abusefilter-log-noactions": "няма", "abusefilter-log-linkoncontribs": "журнал злоўжыванняў", + "abusefilter-log-linkoncontribs-text": "Запісы журнала злоўжыванняў для {{GENDER:$1|гэтага удзельніка|гэтай удзельніцы}}", + "abusefilter-log-linkonhistory": "прагляд журнала злоўжыванняў", + "abusefilter-log-linkonhistory-text": "Прагляд журнала злоўжыванняў для гэтай старонкі", + "abusefilter-log-linkonundelete": "прагляд журнала злоўжыванняў", + "abusefilter-log-linkonundelete-text": "Прагляд журнала злоўжыванняў для гэтай старонкі", + "abusefilter-log-cannot-see-details": "Вы не маеце права глядзець падрабязнасці гэтага запісу.", + "abusefilter-log-cannot-see-privatedetails": "Вы не маеце права глядзець асабовыя падрабязнасці гэтага запісу.", + "abusefilter-log-details-hidden": "Вы не можаце праглядзець дэталі гэтага запісу, таму што яны схаваныя ад агульнага прагляду.", + "abusefilter-log-hide-legend": "Схаваць запіс журнала", "abusefilter-log-hide-reason": "Прычына:", + "abusefilter-log-hide-reason-other": "Іншая/дадатковая прычына:", + "abusefilter-log-hide-forbidden": "Вы не маеце дазволу хаваць запісы ў журнале злоўжыванняў.", "log-action-filter-abusefilter": "Тып змены фільтра:", + "log-action-filter-abusefilter-create": "Стварэнне новага фільтра", + "log-action-filter-abusefilter-modify": "Змяненне фільтра", + "log-action-filter-suppress-abuselog": "Задушэнне журнала злоўжыванняў", + "abusefilterprivatedetails-log-name": "Журнал доступу да асабістых звестак фільтру злоўжыванняў", + "abusefilter-list": "Усе фільтры", + "abusefilter-list-id": "ID фільтра", + "abusefilter-list-pattern": "Узор", + "abusefilter-list-status": "Статус", + "abusefilter-list-public": "Агульнадаступнае апісанне", + "abusefilter-list-visibility": "Бачнасць", "abusefilter-list-edit": "Правіць", + "abusefilter-list-details": "Падрабязнасці", + "abusefilter-list-limit": "Колькасць на старонцы:", + "abusefilter-list-lastmodified": "Апошняе змяненне", + "abusefilter-list-group": "Група фільтра", + "abusefilter-hidden": "Прыватны", + "abusefilter-unhidden": "Публічны", "abusefilter-deleted": "Выдалена", "abusefilter-disabled": "Выключаны", "abusefilter-new": "Стварыць новы фільтр", + "abusefilter-status-global": "Глабальны", + "abusefilter-list-options": "Настройкі", + "abusefilter-list-options-deleted": "Выдаленыя фільтры:", + "abusefilter-list-options-deleted-only": "Паказаць толькі выдаленыя фільтры", + "abusefilter-list-options-deleted-hide": "Схаваць выдаленыя фільтры", + "abusefilter-list-options-deleted-show": "Паказаць і выдаленыя фільтры", + "abusefilter-list-options-scope": "Паказаць фільтры:", "abusefilter-list-options-scope-local": "Толькі лакальныя правілы", + "abusefilter-list-options-scope-global": "Толькі глабальныя правілы", + "abusefilter-list-options-scope-all": "Лакальныя і глабальныя правілы", "abusefilter-list-options-submit": "Абнавіць", + "abusefilter-tools-reautoconfirm-user": "Удзельнік:", "abusefilter-edit": "Правіць фільтр злоўжыванняў", "abusefilter-edit-subtitle": "Змена фільтра $1", "abusefilter-edit-subtitle-new": "Стварэнне фільтру", "abusefilter-edit-oldwarning": "<strong>Вы рэдагуеце старую вэрсію гэтага фільтру. Статыстыка падаецца для апошнія версіі фільтру. Калі Вы захаваеце Вашыя змены, Вы скасуеце ўсе змены зробленыя раней.</strong> • [[Special:AbuseFilter/history/$2|Вярнуцца да гісторыі гэтага фільтру]].", "abusefilter-edit-status-label": "Статыстыка:", "abusefilter-edit-status": "З $1 {{PLURAL:$1|апошняга дзеяння|апошніх дзеянняў}} $2 ($3%) адпавядалі гэтаму фільтру.", - "abusefilter-edit-status-profile": "З $1 {{PLURAL:$1|апошняга дзеяння|апошніх дзеянняў}} $2 ($3%) адпавядалі гэтаму фільтру. У сярэднім, выкананне фільтру працягвалася $4 мс і выкарыстоўвала $5 {{PLURAL:$5|умову|умовы|умоў}} з ліміту ўмоў.", "abusefilter-edit-throttled-warning": "'''Увага:''' Гэты фільтр быў аўтаматычна пазначаны як шкодны. У якасці меры бяспекі наступныя дзеянні не будуць выкананы ($1). Калі ласка, праверце і [[mw:Extension:AbuseFilter/Conditions|аптымізуйце]] Вашыя ўмовы, каб зняць гэтае абмежаванне", "abusefilter-edit-new": "Новы фільтр", "abusefilter-edit-save": "Запісаць фільтр", @@ -51,7 +121,9 @@ "abusefilter-edit-field-description": "апісанне", "abusefilter-edit-group": "Група фільтраў:", "abusefilter-edit-flags": "Сцягі:", + "abusefilter-edit-enabled": "Уключыць гэты фільтр", "abusefilter-edit-deleted": "Пазначыць як выдалены", + "abusefilter-edit-hidden": "Схаваць падрабязнасці гэтага фільтра ад звычайных удзельнікаў", "abusefilter-edit-global": "Глабальны фільтр", "abusefilter-edit-rules": "Умовы:", "abusefilter-edit-field-conditions": "умовы", @@ -71,13 +143,24 @@ "abusefilter-edit-throttle-count": "Колькасць дазволеных дзеянняў:", "abusefilter-edit-throttle-period": "Перыяд часу:", "abusefilter-edit-throttle-groups": "Звужэнне паводле груп:\n:''(па адным на радку, падзяляць коскамі)''", + "abusefilter-throttle-ip": "IP-адрас", + "abusefilter-throttle-user": "рахунак удзельніка", + "abusefilter-throttle-range": "дыяпазон /16", + "abusefilter-throttle-creationdate": "дата стварэння рахунка", + "abusefilter-throttle-page": "старонка", + "abusefilter-throttle-none": "(няма)", "abusefilter-edit-warn-message": "Сістэмнае паведамленне для папярэджання:", "abusefilter-edit-warn-other": "Іншае паведамленне", "abusefilter-edit-warn-other-label": "Назва старонкі іншага паведамлення:\n:''(без прасторы назваў MediaWiki)''", "abusefilter-edit-warn-actions": "Дзеянні:", - "abusefilter-edit-warn-preview": "Папярэдні прагляд выбранага паведамлення", + "abusefilter-edit-warn-preview": "Паказаць/схаваць папярэдні прагляд выбранага паведамлення", "abusefilter-edit-warn-edit": "Стварыць/Правіць выбранае паведамленне", - "abusefilter-edit-tag-tag": "Ужывальныя [[Special:Tags|біркі]] (па адной на радок):", + "abusefilter-edit-disallow-message": "Сістэмнае паведамленне для забароны:", + "abusefilter-edit-disallow-other": "Іншае паведамленне", + "abusefilter-edit-disallow-actions": "Дзеянні:", + "abusefilter-edit-disallow-preview": "Паказаць/схаваць папярэдні прагляд выбранага паведамлення", + "abusefilter-edit-disallow-edit": "Стварыць/Правіць выбранае паведамленне", + "abusefilter-edit-tag-tag": "Ужывальныя [[Special:Tags|біркі]]:", "abusefilter-edit-block-anon-durations": "Працягласць блакіроўкі для ананімных удзельнікаў:", "abusefilter-edit-block-user-durations": "Працягласць блакіроўкі для зарэгістраваных удзельнікаў:", "abusefilter-block-anon": "Блакаваць ананімных удзельнікаў", @@ -201,12 +284,12 @@ "abusefilter-edit-builder-vars-all-links": "Усе вонкавыя спасылкі ў новым тэксце", "abusefilter-edit-builder-vars-added-links": "Усе вонкавыя спасылкі, дададзеныя ў праўцы", "abusefilter-edit-builder-vars-removed-links": "Усе вонкавыя спасылкі, выдаленыя ў праўцы", - "abusefilter-edit-builder-vars-old-text": "Стары вікітэкст старонкі, да праўкі", - "abusefilter-edit-builder-vars-new-text": "Новы вікітэкст, пасля праўкі", + "abusefilter-edit-builder-vars-old-wikitext": "Стары вікітэкст старонкі, да праўкі", + "abusefilter-edit-builder-vars-new-wikitext": "Новы вікітэкст, пасля праўкі", "abusefilter-edit-builder-vars-new-pst": "Вікітэкст новай старонкі, зменены перад захаваннем", "abusefilter-edit-builder-vars-diff-pst": "Уніфікаваная розніца змен у праўцы, змененая перад захаваннем", "abusefilter-edit-builder-vars-addedlines-pst": "Радкі, дададзеныя пры рэдагаванні, змененыя перад захаваннем", - "abusefilter-edit-builder-vars-new-text-stripped": "Новы тэкст старонкі, ачышчаны ад усёй разметкі", + "abusefilter-edit-builder-vars-new-text": "Новы тэкст старонкі, ачышчаны ад усёй разметкі", "abusefilter-edit-builder-vars-new-html": "Разабраны HTML-код новай версіі", "abusefilter-edit-builder-vars-restrictions-edit": "Узровень абароны старонкі ад правак", "abusefilter-edit-builder-vars-restrictions-move": "Узровень абароны старонкі ад пераносаў", @@ -219,7 +302,7 @@ "abusefilter-edit-builder-vars-movedto-restrictions-move": "Узровень абароны пераносу старонкі, куды адбываецца перанос", "abusefilter-edit-builder-vars-movedto-restrictions-create": "Ахова на стварэнне старонкі, куды адбываецца перанос", "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Ахова пры загрузцы файла, куды адбываецца перанос", - "abusefilter-edit-builder-vars-old-text-stripped": "Стары змест старонкі, пазбаўлены ад усёй разметкі", + "abusefilter-edit-builder-vars-old-text": "Стары змест старонкі, пазбаўлены ад усёй разметкі", "abusefilter-edit-builder-vars-old-links": "Спасылкі на старонцы, перад праўкай", "abusefilter-edit-builder-vars-old-html": "Стары вікітэкст старонкі, пераўтвораны ў фармат HTML", "abusefilter-edit-builder-vars-minor-edit": "Ці пазначана праўка як дробная", @@ -230,21 +313,48 @@ "abusefilter-edit-builder-vars-file-width": "Шырыня файла ў пікселах", "abusefilter-edit-builder-vars-file-height": "Вышыня файла ў пікселах", "abusefilter-edit-builder-vars-file-bits-per-channel": "Глыбіня колеру ў файле", + "abusefilter-filter-log": "Апошнія змяненні фільтраў", + "abusefilter-history-hidden": "Схаваны", + "abusefilter-history-global": "Глабальны", "abusefilter-history-timestamp": "Час", + "abusefilter-history-user": "Удзельнік", + "abusefilter-history-public": "Адкрытае апісанне фільтра", "abusefilter-history-flags": "Сцягі", + "abusefilter-history-filter": "Правілы фільтра", "abusefilter-history-comments": "Каментары", + "abusefilter-history-actions": "Дзеянні", + "abusefilter-history-deleted": "Выдалены", + "abusefilter-history-filterid": "Фільтр", + "abusefilter-history-select-user": "Удзельнік:", + "abusefilter-history-select-filter": "ID фільтра:", + "abusefilter-history-diff": "Змены", "abusefilter-action-tag": "Бірка", "abusefilter-action-throttle": "Абмежаваць", - "abusefilter-action-warn": "Папярэдзіць", + "abusefilter-action-warn": "Папярэджанне", "abusefilter-action-blockautopromote": "Заблакаваць аўтаматычнае наданне правоў", "abusefilter-action-block": "Заблакаваць", "abusefilter-action-degroup": "Выдаліць з груп", "abusefilter-action-rangeblock": "Заблакаваць дыяпазон", "abusefilter-action-disallow": "Не дазволіць", - "abusefilter-revert-filter": "Фільтр:", + "abusefilter-revert-filter": "ID фільтра:", "abusefilter-revert-confirm": "Пацвердзіць", + "abusefilter-revert-reasonfield": "Прычына:", + "abusefilter-test-load": "Загрузіць", + "abusefilter-test-action": "Тып дзеяння:", + "abusefilter-test-search-type-edit": "Праўкі", + "abusefilter-test-search-type-move": "Пераносы", + "abusefilter-test-search-type-delete": "Выдаленні", + "abusefilter-test-search-type-upload": "Укладанні", + "abusefilter-test-search-type-createaccount": "Стварэнні рахункаў", "abusefilter-changeslist-examine": "праверыць", + "abusefilter-examine-legend": "Выбар змяненняў", + "abusefilter-examine-user": "Удзельнік:", + "abusefilter-examine-title": "Назва старонкі:", + "abusefilter-examine-submit": "Пошук", "abusefilter-topnav": "'''Навігацыя па Фільтру злоўжывання'''", + "abusefilter-topnav-home": "Галоўная", + "abusefilter-topnav-recentchanges": "Апошнія змяненні фільтраў", + "abusefilter-topnav-log": "Журнал злоўжыванняў", "abusefilter-log-name": "Журнал фільтра злоўжыванняў", "abusefilter-log-header": "У гэты журнал запісваюцца апісанні змен, зробленых у фільтрах. Падрабязнасці можна знайсці ў [[Special:AbuseFilter/history|спісе]] апошніх змен фільтраў.", "abusefilter-diff-title": "Розніца паміж версіямі", @@ -256,6 +366,7 @@ "abusefilter-diff-backhistory": "Вярнуцца да гісторыі фільтру", "abusefilter-diff-prev": "Старэйшая змена", "abusefilter-diff-next": "Навейшая змена", + "abusefilter-group-default": "Па змоўчанні", "tag-abusefilter-condition-limit": "дасягнуты ліміт умовы", "tag-abusefilter-condition-limit-description": "Парўкі або іншыя падзеі, якія не могуць быць выбраныя ніводным з актыўных [[Special:AbuseFilter|фільтраў злоўжыванняў]] ([[mw:Extension:AbuseFilter/Conditions|даведка]])." } diff --git a/AbuseFilter/i18n/bg.json b/AbuseFilter/i18n/bg.json index 164945b7..be382329 100644 --- a/AbuseFilter/i18n/bg.json +++ b/AbuseFilter/i18n/bg.json @@ -2,58 +2,67 @@ "@metadata": { "authors": [ "DCLXVI", + "Matma Rex", + "ShockD", "Simona", "Spiritia", + "StanProg", "Stanqo", + "Ted Masters", "Turin", - "Петър Петров", - "පසිඳු කාවින්ද", - "StanProg", + "Vlad5250", "Vodnokon4e", - "Matma Rex", - "ShockD", - "Vlad5250" + "Петър Петров", + "පසිඳු කාවින්ද" ] }, "abusefilter-desc": "Прилага автоматични евристики към редакциите.", - "abusefilter": "Конфигуриране на филтъра срещу злоупотреби", - "abuselog": "Дневник на злоупотребите", + "abusefilter": "Управление на филтъра срещу злоупотреби", + "abuselog": "Дневник на филтъра срещу злоупотреби", "abusefilter-intro": "Добре дошли в административния интерфейс на Филтъра срещу злоупотреби.\nФилтърът срещу злоупотреби е автоматизиран софтуерен механизъм за прилагане на евристични оценки към разнообразни действия.\nТози интерфейс показва списък на дефинираните филтри с възможност те да бъдат променяни.", + "abusefilter-mustviewprivateoredit": "От съображения за сигурност, този интерфейс може да се ползва само от потребители с права на достъп за преглед и промяна на непубличните филтри срещу злоупотреби.", "abusefilter-warning": "<strong>Внимание:</strong> Извършваното действие беше автоматично разпознато като вредоносно.\nНеконструктивните действия бързо биват премахвани, а демонстративното или упоритото вредене може да доведе до блокиране на потребителската ви сметка или IP адрес.\nАко вярвате, че тази редакция е конструктивна, можете да натиснете бутона „Съхраняване“, за да я запазите.\nКратко описание на правилото, по което вашето действие беше разпознато: $1", "abusefilter-disallowed": "Извършваното действие беше автоматично разпознато като вредно и не беше съхранено.\nАко вярвате, че действието ви е било конструктивно, моля, уведомете администраторите относно намеренията си.\nКратко описание на правилото, по което вашето действие беше разпознато: $1", "abusefilter-blocked-display": "Извършваното действие беше автоматично разпознато като вредно и беше спряно.\nВ допълнение, с цел защита на {{SITENAME}}, вашата потребителска сметка и IP адрес бяха блокирани.\nАко смятате, че тази реакция на системата е погрешна, моля, свържете се с администратор.\nКратко описание на правилото, по което вашето действие беше разпознато: $1", "abusefilter-degrouped": "Извършваното действие беше автоматично разпознато като вредно и беше спряно. В допълнение, настоящата потребителска сметка прилича на открадната и поради това беше лишена от всички потребителски привилегии.\nАко смятате, че тази реакция на системата е погрешна, моля свържете се с бюрократ, обяснете действията си и привилегиите ви може да бъдат възстановени.\nКратко описание на правилото, по което вашето действие беше разпознато: $1", "abusefilter-autopromote-blocked": "Извършваното действие беше автоматично разпознато като вредно и беше спряно.\nЗа допълнителна защита, някои привилегии, които обикновено се дават на редовните потребители, временно бяха отнети от вашата потребителска сметка.\nКратко описание на правилото, по което вашето действие беше разпознато: $1", "abusefilter-blocker": "Филтър срещу злоупотреби", - "abusefilter-blockreason": "Автоматично блокиране, извършено от филтъра срещу злоупотребите.\nОписание на причината: $1", - "abusefilter-degroupreason": "Автоматично отнемане на права, извършено от филтъра срещу злоупотребите.\nПричина: $1", + "abusefilter-blockreason": "Автоматично блокиране, извършено от филтъра срещу злоупотребите.\nОписание на съответстващото правило: $1", + "abusefilter-degroupreason": "Автоматично отнемане на права, извършено от филтъра срещу злоупотребите.\nОписание на правилото: $1", "abusefilter-accountreserved": "Това име на сметка е запазено за употреба от филтъра срещу злоупотреби.", - "right-abusefilter-modify": "Промяна на филтрите срещу злоупотреби", + "right-abusefilter-modify": "Създаване или промяна на филтрите срещу злоупотреби", "right-abusefilter-view": "Преглед на филтрите срещу злоупотреби", "right-abusefilter-log": "Преглед на дневника на злоупотребите", "right-abusefilter-log-detail": "Преглед на подробните записи в дневника на злоупотребите", - "right-abusefilter-private": "Преглед на скритите данни в дневника на злоупотребите", + "right-abusefilter-privatedetails": "Преглед на скритите данни в дневника на злоупотребите", + "right-abusefilter-privatedetails-log": "Преглед на достъп до лични данни от дневника на Филтъра срещу злоупотреби", "right-abusefilter-modify-restricted": "Промяна на филтрите срещу злоупотреби с ограничени действия", - "right-abusefilter-revert": "Възвръщане на всички промени, направени от филтъра срещу злоупотреби", + "right-abusefilter-revert": "Връщане на всички промени, направени от филтъра срещу злоупотреби", "right-abusefilter-view-private": "Преглед на означените като скрити филтри срещу злоупотреби", "right-abusefilter-log-private": "Преглед на записите в дневника на означените като скрити филтри срещу злоупотреби", - "right-abusefilter-hide-log": "Скриване на записи в дневника на злоупотребите", - "right-abusefilter-hidden-log": "Преглед на скритите записи в дневника на злоупотребите", + "right-abusefilter-hide-log": "Скриване на записи от дневника на злоупотребите", + "right-abusefilter-hidden-log": "Преглед на скритите записи от дневника на злоупотребите", "right-abusefilter-modify-global": "Създаване или промяна на глобалните филтри срещу злоупотреби", "action-abusefilter-modify": "промяна на филтрите срещу злоупотреби", "action-abusefilter-view": "преглед на филтрите срещу злоупотреби", "action-abusefilter-log": "преглед на дневника на злоупотребите", "action-abusefilter-log-detail": "подробен преглед на дневника на злоупотребите", - "action-abusefilter-private": "преглед на личните данни в дневника на злоупотребите", + "action-abusefilter-privatedetails": "преглед на личните данни в дневника на злоупотребите", + "action-abusefilter-privatedetails-log": "преглед на достъп до лични данни от дневника на Филтъра срещу злоупотреби", "action-abusefilter-modify-restricted": "промяна на филтрите срещу злоупотреби с ограничени действия", "action-abusefilter-revert": "възвръщане на всички промени, направени от даден филтър", "action-abusefilter-view-private": "Преглед на означените като скрити филтри срещу злоупотреби", "action-abusefilter-log-private": "Преглед на дневниците на означените като скрити филтри срещу злоупотреби", - "abusefilter-log": "Дневник на филтъра срещу злоупотреби", + "action-abusefilter-hide-log": "скриване на записи от дневника на злоупотребите", + "action-abusefilter-hidden-log": "преглед на скритите записи от дневника на злоупотребите", + "action-abusefilter-modify-global": "създаване или промяна на глобалните филтри срещу злоупотреби", "abusefilter-log-summary": "Този дневник показва списъка на всички действия, прехванати от филтрите.", - "abusefilter-log-search": "Търсене в Дневника на злоупотребите", + "abusefilter-log-search": "Търсене в дневника на злоупотребите", "abusefilter-log-search-user": "Потребител:", - "abusefilter-log-search-filter": "Идентификатори на филтър (разделени с вертикална линия):", + "abusefilter-log-search-group": "Група на филтъра:", + "abusefilter-log-search-group-any": "Всички", + "abusefilter-log-search-filter": "Идентификатори на филтър:", + "abusefilter-log-search-filter-help": "Разделете с вертикална черта, използвайте представката „$1“ за глобални филтри", "abusefilter-log-search-title": "Заглавие:", "abusefilter-log-search-wiki": "Уики:", "abusefilter-log-search-impact": "Въздействие:", @@ -64,6 +73,9 @@ "abusefilter-log-search-entries-all": "Всички записи", "abusefilter-log-search-entries-hidden": "Само скрити записи", "abusefilter-log-search-entries-visible": "Само видими записи", + "abusefilter-log-search-action-label": "Задействащо действие:", + "abusefilter-log-search-action-other": "Друго", + "abusefilter-log-search-action-any": "Всички", "abusefilter-log-search-action-taken-label": "Предприето действие:", "abusefilter-log-search-action-taken-any": "Всички", "abusefilter-log-search-submit": "Търсене", @@ -79,7 +91,7 @@ "abusefilter-log-details-var": "Променлива", "abusefilter-log-details-val": "Стойност", "abusefilter-log-details-vars": "Параметри на действието", - "abusefilter-log-details-private": "Скрити данни от дневника", + "abusefilter-log-details-privatedetails": "Лични данни в дневника", "abusefilter-log-details-ip": "Изходящ IP адрес", "abusefilter-log-details-checkuser": "Проверяващ", "abusefilter-log-noactions": "няма", @@ -87,24 +99,34 @@ "abusefilter-log-linkoncontribs": "дневник на злоупотребите", "abusefilter-log-linkoncontribs-text": "Дневник на злоупотребите за {{GENDER:$1|този потребител}}", "abusefilter-log-linkonhistory": "преглед на филтъра срещу злоупотреби", - "abusefilter-log-hidden": "(скрит запис)", + "abusefilter-log-linkonhistory-text": "Преглед на дневника на злоупотреби за страницата", + "abusefilter-log-linkonundelete": "преглед на филтъра срещу злоупотреби", + "abusefilter-log-linkonundelete-text": "Преглед на дневника на злоупотреби за страницата", "abusefilter-log-hidden-implicit": "(скрито заради изтрита версия)", "abusefilter-log-cannot-see-details": "Нямате права за преглед на детайлите на този запис.", + "abusefilter-log-cannot-see-privatedetails": "Нямате права за преглед на скритите детайли на този запис.", "abusefilter-log-nonexistent": "Не съществува запис с посоченото ID.", "abusefilter-log-details-hidden": "Не можете да прегледате детайлите за този запис, защото той е непубличен.", + "abusefilter-log-details-hidden-implicit": "Не можете да прегледате детайлите за този запис, защото свързаната с него версия е скрита.", "abusefilter-log-private-not-included": "Един или повече идентификатори на филтъра, които посочихте, са скрити. Тъй като не е разрешено да видите детайли за скритите филтри, тези филтри не са включени в търсенето.", "abusefilter-log-hide-legend": "Скриване на записа в дневника", "abusefilter-log-hide-id": "Идентификатор на запис от дневника:", "abusefilter-log-hide-hidden": "Скриване на този запис от публичен преглед", "abusefilter-log-hide-reason": "Причина:", + "abusefilter-log-hide-reason-other": "Друга/допълнителна причина:", "abusefilter-log-hide-forbidden": "Нямате необходимите права да скривате записи от дневника на злоупотребите.", + "abusefilter-log-entry-suppress": "$1 {{GENDER:$2|скри}} $3", + "abusefilter-log-entry-unsuppress": "$1 {{GENDER:$2|откри}} $3", "logentry-abusefilter-hit": "$1: {{GENDER:$2|задейства}} $4, {{GENDER:$2|извършвайки}} действие „$5“ на $3.\nПредприети действия: $6 ($7)", "log-action-filter-abusefilter": "Вид промяна на филтъра:", "log-action-filter-abusefilter-create": "Създаване на нов филтър", "log-action-filter-abusefilter-modify": "Промяна на филтъра", - "abusefilter-management": "Управление на филтъра срещу злоупотреби", + "log-action-filter-suppress-abuselog": "Подтискане на дневника за злоупотреби", + "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|осъществи достъп до}} личнните данни за $3", + "abusefilterprivatedetails-log-name": "Дневник на достъп до лични данни от Филтъра срещу злоупотреби", "abusefilter-list": "Всички филтри", "abusefilter-list-id": "ID на филтър", + "abusefilter-list-pattern": "Шаблон", "abusefilter-list-status": "Статут", "abusefilter-list-public": "Публично описание", "abusefilter-list-consequences": "Последствия", @@ -120,8 +142,10 @@ "abusefilter-enabled": "Включен", "abusefilter-deleted": "Изтрит", "abusefilter-disabled": "Изключен", + "abusefilter-throttled": "ограничен", "abusefilter-hitcount": "$1 {{PLURAL:$1|съвпадение|съвпадения}}", "abusefilter-new": "Създаване на нов филтър", + "abusefilter-import-button": "Внасяне на филтър", "abusefilter-return": "Назад към управлението на филтъра", "abusefilter-status-global": "На глобално ниво", "abusefilter-list-options": "Настройки", @@ -133,13 +157,16 @@ "abusefilter-list-options-scope-local": "Само локални правила", "abusefilter-list-options-scope-global": "Само глобални правила", "abusefilter-list-options-scope-all": "Локални и глобални правила", - "abusefilter-list-options-further-options": "Други опции:", + "abusefilter-list-options-further-options": "Други настройки:", "abusefilter-list-options-hidedisabled": "Скриване на изключените филтри", - "abusefilter-list-options-hideprivate": "Скриване на приватните филтри", + "abusefilter-list-options-hideprivate": "Скриване на частните филтри", + "abusefilter-list-options-searchfield": "Търсене в правилата:", + "abusefilter-list-options-searchpattern": "Вмъкване на шаблон", "abusefilter-list-options-searchoptions": "Режим на търсене", "abusefilter-list-options-search-like": "Обикновена заявка", "abusefilter-list-options-search-rlike": "Регулярен израз", "abusefilter-list-options-search-irlike": "Нечувствителен към регистъра регулярен израз", + "abusefilter-list-regexerror": "Възникна грешка по време на търсенето: Синтактична греша в регулярния израз.", "abusefilter-list-options-submit": "Обновяване", "abusefilter-tools-text": "Тук има някои инструменти, които може да са полезни за създаване или поправяне на филтри срещу злоупотреби.", "abusefilter-tools-expr": "Проверка на изрази", @@ -154,10 +181,11 @@ "abusefilter-edit": "Редактиране на филтъра за злоупотреби", "abusefilter-edit-subtitle": "Редактиране на филтър $1", "abusefilter-edit-subtitle-new": "Създаване на филтър", - "abusefilter-edit-oldwarning": "<strong>Редактирате остаряла версия на този филтър. Посочените статистики са за последната версия на филтъра. Ако съхраните промените си, ще отмените всички промени, направени след версията, която редактирате.</strong> • [[Special:AbuseFilter/history/$2|Връщане към историята на филтъра]]", + "abusefilter-edit-token-not-match": "Редакцията не беше съхранена! Моля, опитайте отново.", + "abusefilter-edit-oldwarning": "<strong>Редактирате остаряла версия на този филтър.\nПосочените статистики са за последната версия на филтъра.\nАко съхраните промените си, ще отмените всички промени, направени след версията, която редактирате.</strong> • [[Special:AbuseFilter/history/$2|Връщане към историята на филтъра]]", "abusefilter-edit-status-label": "Статистики:", - "abusefilter-edit-status": "От {{PLURAL:$1|последното действие|последните $1 действия}}, този филтър съвпадна с $2 от тях ($3%).", - "abusefilter-edit-status-profile": "От {{PLURAL:$1|последното едно действие|последните $1 действия}}, този филтър съвпадна с $2 от тях ($3%).\nСредното му време за изпълнение е $4 ms и използва $5 от общия брой допустими условия.", + "abusefilter-edit-status": "От {{PLURAL:$1|последното действие|последните $1 действия}}, този филтър съвпадна с $2 от тях ($3%).\nСредното му време на изпълнение е $4 ms, а изразходва $5 {{PLURAL:$5|условие|условия}} от лимита за условия.", + "abusefilter-edit-throttled-warning": "'''Внимание:''' Този филтър беше автоматично отбелязан като вреден. Като мярка за безопасност, следните действия няма да бъдат извършени ($1). Моля, прегледайте и [[mw:Extension:AbuseFilter/Conditions|оптимизирайте]] условията си, за да премахнете това ограничение.", "abusefilter-edit-new": "Нов филтър", "abusefilter-edit-save": "Съхраняване на филтъра", "abusefilter-edit-id": "Идентификатор на филтър:", @@ -179,63 +207,84 @@ "abusefilter-edit-consequences": "Действия при съвпадение", "abusefilter-edit-action-warn": "Извършване на следните действия след предупреждение на потребителя", "abusefilter-edit-action-disallow": "Ограничаване на потребителя да извърши въпросното действие", - "abusefilter-edit-action-blockautopromote": "Отнемане на привилегията „Автоматично одобрен потребител“ (autoconfirmed)", + "abusefilter-edit-action-blockautopromote": "Отнемане на привилегията „Автоматично одобрен потребител“", "abusefilter-edit-action-degroup": "Изключване на потребителя от всички привилегировани групи", "abusefilter-edit-action-block": "Блокиране на потребителя и/или IP адреса", - "abusefilter-edit-action-throttle": "Изпълнение на действията само ако потребителят превиши определена честота на редакциите", + "abusefilter-edit-action-blocktalk": "Блокиране на потребителя и/или IP адреса от редактиране на собствената беседа", + "abusefilter-edit-action-throttle": "Изпълнение на действията само, ако потребителят превиши определена честота на редакциите", "abusefilter-edit-action-rangeblock": "Блокиране на съответния IP-диапазон, към който принадлежи потребителят", - "abusefilter-edit-action-tag": "Отбелязване на редакцията за понататъшно преглеждане", + "abusefilter-edit-action-tag": "Отбелязване на редакцията за по нататъшно преглеждане", "abusefilter-edit-throttle-count": "Брой позволени действия:", "abusefilter-edit-throttle-period": "Период от време (в секунди):", "abusefilter-edit-throttle-groups": "Ограничаване по групи:", - "abusefilter-edit-throttle-ip": "IP адрес", - "abusefilter-edit-throttle-user": "Потребителска сметка", - "abusefilter-edit-throttle-range": "/16-диапазон", - "abusefilter-edit-throttle-creationdate": "Сървърно време на създаването на сметката", - "abusefilter-edit-throttle-editcount": "Брой редакции", - "abusefilter-edit-throttle-site": "Целият сайт", - "abusefilter-edit-throttle-page": "Страница", + "abusefilter-edit-throttle-groups-help": "Вж. $1.", + "abusefilter-edit-throttle-groups-help-text": "документацията на mediawiki.org", + "abusefilter-throttle-ip": "IP-адрес", + "abusefilter-throttle-user": "потребителска сметка", + "abusefilter-throttle-range": "/16-диапазон", + "abusefilter-throttle-creationdate": "дата на създаване на сметката", + "abusefilter-throttle-editcount": "брой редакции", + "abusefilter-throttle-site": "целият сайт", + "abusefilter-throttle-page": "страница", + "abusefilter-throttle-none": "(няма)", "abusefilter-edit-warn-message": "Използвано системно съобщение за предупреждение:", "abusefilter-edit-warn-other": "Друго съобщение", - "abusefilter-edit-warn-other-label": "Наименование на друго системно съобщение:\n:''(без представката MediaWiki)''", + "abusefilter-edit-warn-other-label": "Наименование на страница на друго съобщение:\n:''(без представката „MediaWiki:“)''", "abusefilter-edit-warn-actions": "Действия:", "abusefilter-edit-warn-preview": "Показване/Скриване прегледа на избраното съобщение", "abusefilter-edit-warn-edit": "Създаване или редактиране на избраното съобщение", + "abusefilter-edit-disallow-message": "Използвано системно съобщение за забрана:", + "abusefilter-edit-disallow-other": "Друго съобщение", + "abusefilter-edit-disallow-other-label": "Наименование на друго системно съобщение:\n:''(без представката „MediaWiki:“)''", + "abusefilter-edit-disallow-actions": "Действия:", + "abusefilter-edit-disallow-preview": "Показване/Скриване прегледа на избраното съобщение", + "abusefilter-edit-disallow-edit": "Създаване/редактиране на избраното съобщение", "abusefilter-edit-tag-tag": "[[Special:Tags|Етикети]] за прилагане:", + "abusefilter-edit-tag-placeholder": "Добавяне на етикети (един по един или разделени със запетая)", + "abusefilter-edit-tag-hidden-placeholder": "Добавяне на етикети (разделени със запетая)", + "abusefilter-edit-block-anon-durations": "Продължителност на блокирането за анонимни потребители:", + "abusefilter-edit-block-user-durations": "Продължителност на блокирането за регистрирани потребители:", "abusefilter-block-anon": "Блокиране на анонимни потребители", "abusefilter-block-user": "блокиране на регистрирани потребители", - "abusefilter-block-talk": "дискусионната страница е блокирана", + "abusefilter-block-talk": "беседата е блокирана", "abusefilter-edit-denied": "Не може да видите детайлите на този филтър, тъй като са скрити от публичен достъп.", "abusefilter-edit-main": "Параметри на филтъра", "abusefilter-edit-done-subtitle": "Филтърът беше редактиран", "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Вашите промени]] във [[Special:AbuseFilter/$1|филтър $3]] бяха съхранени успешно.", - "abusefilter-edit-badsyntax": "В зададения филтър има синтактична грешка. Резултатът от парсера е: <pre>$1</pre>", + "abusefilter-edit-badsyntax": "В зададения филтър има синтактична грешка.\nРезултатът от анализатора е: <pre>$1</pre>", + "abusefilter-edit-missingfields": "Следните полета са задължителни и трябва да бъдат попълнени: $1", + "abusefilter-edit-deleting-enabled": "Не може да отбелязвате активен филтър като изтрит.", "abusefilter-edit-restricted": "Не може да редактирате този филтър, понеже той съдържа едно или повече действия, ограничени по потребителска група.\nМоля, помолете потребител със съответните права за работа с такива действия да извърши промяната вместо вас.", "abusefilter-edit-viewhistory": "Преглед на историята на този филтър", "abusefilter-edit-history": "История:", "abusefilter-edit-check": "Проверка на синтаксиса", "abusefilter-edit-badfilter": "Избраният филтър не съществува", - "abusefilter-edit-revert": "Връщане (отмяна) на действията, направени от филтъра", + "abusefilter-edit-revert": "Отмяна на действията, направени от филтъра", "abusefilter-edit-tools": "Инструменти:", "abusefilter-edit-test-link": "Тестване на филтъра спрямо последните промени", "abusefilter-edit-export": "Експортиране на този филтър към друго уики", "abusefilter-edit-syntaxok": "Не са открити синтактични грешки.", "abusefilter-edit-syntaxerr": "Открита синтактична грешка: $1", + "abusefilter-edit-warn-leave": "Ако напуснете тази страницата, ще изгубите направените промени на филтъра.", "abusefilter-edit-bad-tags": "Един или повече от указаните етикети са невалидни.\nЕтикетите трябва да са кратки, да не съдържат специални символи и да не са запазени за друг софтуер. Изберете друго име за етикета.", "abusefilter-edit-notallowed": "Нямате права да създавате или редактирате филтъра срещу злоупотреби", "abusefilter-edit-notallowed-global": "Нямате права да създавате или редактирате глобални филтри срещу злоупотреби", - "abusefilter-edit-notallowed-global-custom-msg": "Потребителските предупредителни съобщения не се поддържат за глобалните филтри", + "abusefilter-edit-notallowed-global-custom-msg": "Глобалните филтри не поддържат потребителски или забранителни предупреждения", + "abusefilter-edit-invalid-warn-message": "Предупредителното съобщение не може да бъде празно.", + "abusefilter-edit-invalid-disallow-message": "Съобщението за забрана не може да бъде оставено празно.", "abusefilter-edit-builder-select": "Изберете опция и я добавете след курсора", "abusefilter-edit-builder-group-op-arithmetic": "Аритметични оператори", "abusefilter-edit-builder-op-arithmetic-addition": "Събиране (+)", "abusefilter-edit-builder-op-arithmetic-subtraction": "Изваждане (-)", "abusefilter-edit-builder-op-arithmetic-multiplication": "Умножение (*)", "abusefilter-edit-builder-op-arithmetic-divide": "Деление (/)", - "abusefilter-edit-builder-op-arithmetic-modulo": "Пресмятане по модул (%)", + "abusefilter-edit-builder-op-arithmetic-modulo": "Деление по модул (%)", "abusefilter-edit-builder-op-arithmetic-pow": "Повдигане на степен (**)", "abusefilter-edit-builder-group-op-comparison": "Оператори за сравнение", "abusefilter-edit-builder-op-comparison-equal": "Стойност равна на (==)", + "abusefilter-edit-builder-op-comparison-equal-strict": "Стойност и тип равни на (===)", "abusefilter-edit-builder-op-comparison-notequal": "Стойност, различна от (!=)", + "abusefilter-edit-builder-op-comparison-notequal-strict": "Стойност и тип, различни от (!==)", "abusefilter-edit-builder-op-comparison-lt": "По-малко от (<)", "abusefilter-edit-builder-op-comparison-gt": "По-голямо от (>)", "abusefilter-edit-builder-op-comparison-lte": "По-малко или равно на (<=)", @@ -244,37 +293,44 @@ "abusefilter-edit-builder-op-bool-not": "Не (!)", "abusefilter-edit-builder-op-bool-and": "И (&)", "abusefilter-edit-builder-op-bool-or": "Или (|)", + "abusefilter-edit-builder-op-bool-xor": "Изключващо ИЛИ (^)", "abusefilter-edit-builder-group-misc": "Разни", - "abusefilter-edit-builder-misc-in": "Съдържа се в низа (in)", + "abusefilter-edit-builder-misc-in": "съдържа се в низа (in)", "abusefilter-edit-builder-misc-like": "Съвпада с шаблон (like)", "abusefilter-edit-builder-misc-rlike": "Съвпада с регулярен израз (rlike)", "abusefilter-edit-builder-misc-irlike": "Съответства на регулярния израз, без значение от малки и главни букви (irlike)", "abusefilter-edit-builder-misc-contains": "Левият низ съдържа десния низ (contains)", "abusefilter-edit-builder-misc-stringlit": "Низов литерал (\"\")", "abusefilter-edit-builder-misc-tern": "Третичен оператор (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Условен оператор (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Условен оператор (if X then Y else Z end)", "abusefilter-edit-builder-group-funcs": "Функции", "abusefilter-edit-builder-funcs-length": "Дължина на низ (length)", "abusefilter-edit-builder-funcs-lcase": "Замяна на всички главни букви с малки (lcase)", "abusefilter-edit-builder-funcs-ucase": "Замяна на всички малки букви с главни (ucase)", "abusefilter-edit-builder-funcs-ccnorm": "Нормализация на знаци, които могат да бъдат сбъркани (ccnorm)", + "abusefilter-edit-builder-funcs-ccnorm-contains-any": "Нормализиране и търсене в низ на множество поднизове в режим OR (ccnorm_contains_any)", + "abusefilter-edit-builder-funcs-ccnorm-contains-all": "Нормализиране и търсене в низ на множество поднизове в режим AND (ccnorm_contains_all)", "abusefilter-edit-builder-funcs-rmdoubles": "Премахване на двойни знаци (rmdoubles)", "abusefilter-edit-builder-funcs-specialratio": "Брой специални знаци/ общ брой знаци (specialratio)", "abusefilter-edit-builder-funcs-norm": "Нормализация (norm)", "abusefilter-edit-builder-funcs-count": "Брой пъти, в които низът X се среща в низа Y (count)", "abusefilter-edit-builder-funcs-rcount": "Брой срещания на регулярния израз X в низа Y (rcount)", + "abusefilter-edit-builder-funcs-get_matches": "Масив от съвпадения на регулярен израз в текст за всяка група (get_matches)", "abusefilter-edit-builder-funcs-rmwhitespace": "Премахване на интервали (rmwhitespace)", "abusefilter-edit-builder-funcs-rmspecials": "Премахване на специалните знаци (rmspecials)", "abusefilter-edit-builder-funcs-ip_in_range": "Проверка за IP-адрес в диапазона (ip_in_range)", - "abusefilter-edit-builder-funcs-contains-any": "Съдържа някой от следните низове (contains_any)", + "abusefilter-edit-builder-funcs-contains-any": "Търсене в низ за няколко подниза в режим OR (contains_any)", + "abusefilter-edit-builder-funcs-contains-all": "Търсене в низ на няколко подниза в режим AND (contains_all)", "abusefilter-edit-builder-funcs-substr": "Подниз (substr)", "abusefilter-edit-builder-funcs-strpos": "Място на подниз в низ (strpos)", "abusefilter-edit-builder-funcs-str_replace": "Замяна на подниз с низ (str_replace)", "abusefilter-edit-builder-funcs-rescape": "Изваждане на низ като литерал в регулярен израз (rescape)", "abusefilter-edit-builder-funcs-set_var": "Инициализиране на променлива (set_var)", + "abusefilter-edit-builder-funcs-sanitize": "Нормализиране на HTML единиците в уникод знаци (sanitize)", "abusefilter-edit-builder-group-vars": "Променливи", "abusefilter-edit-builder-vars-accountname": "Име на сметка (при създаването на сметката)", "abusefilter-edit-builder-vars-timestamp": "Дата и час на редакцията", + "abusefilter-edit-builder-vars-timestamp-expanded": "Време и дата на дневника", "abusefilter-edit-builder-vars-action": "Действие", "abusefilter-edit-builder-vars-addedlines": "Брой добавени редове в редакцията", "abusefilter-edit-builder-vars-delta": "Промяна в обема при редакция", @@ -289,14 +345,17 @@ "abusefilter-edit-builder-vars-page-ns": "Именно пространство на страницата", "abusefilter-edit-builder-vars-page-title": "Заглавие на страницата (без именно пространство)", "abusefilter-edit-builder-vars-page-prefixedtitle": "Пълно заглавие на страницата", + "abusefilter-edit-builder-vars-page-age": "Възраст на страницата (в секунди)", "abusefilter-edit-builder-vars-movedfrom-id": "Идентификатор на изходната за преместването страница", "abusefilter-edit-builder-vars-movedfrom-ns": "Именно пространство на изходната за преместването страница", "abusefilter-edit-builder-vars-movedfrom-title": "Заглавие на изходната страница за преместването", "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "Пълно заглавие на изходната страница за преместването", + "abusefilter-edit-builder-vars-movedfrom-age": "Възраст на изходната страница при преместване (в секунди)", "abusefilter-edit-builder-vars-movedto-id": "Идентификатор на целевата за преместването страница", "abusefilter-edit-builder-vars-movedto-ns": "Именно пространство на целевата за преместването страница", "abusefilter-edit-builder-vars-movedto-title": "Заглавие на целевата страница за преместването", "abusefilter-edit-builder-vars-movedto-prefixedtitle": "Пълно заглавие на целевата страница за преместването", + "abusefilter-edit-builder-vars-movedto-age": "Възраст на целевата страница при преместване (в секунди)", "abusefilter-edit-builder-vars-user-editcount": "Брой редакции на потребителя", "abusefilter-edit-builder-vars-user-age": "Възраст на потребителската сметка", "abusefilter-edit-builder-vars-user-name": "Име на потребителската сметка", @@ -306,34 +365,37 @@ "abusefilter-edit-builder-vars-user-emailconfirm": "Дата и час на потвърждаване на електронната поща", "abusefilter-edit-builder-vars-recent-contributors": "Последните десет потребители, допринесли към страницата", "abusefilter-edit-builder-vars-first-contributor": "Първият потребител с принос в страницата", + "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "Последните десет потребителя редактирали изходния код на преместена страница", + "abusefilter-edit-builder-vars-movedfrom-first-contributor": "Първият потребител редактирал изходния код на преместена страница", "abusefilter-edit-builder-vars-all-links": "Всички външни препратки в новия текст", "abusefilter-edit-builder-vars-added-links": "Всички външни препратки, добавени при редакцията", "abusefilter-edit-builder-vars-removed-links": "Всички външни препратки, премахнати при редакцията", - "abusefilter-edit-builder-vars-old-text": "Стар уикитекст преди редакцията", - "abusefilter-edit-builder-vars-new-text": "Нов уикитекст след редакцията", + "abusefilter-edit-builder-vars-old-wikitext": "Уикитекст на старата страница, преди редактирането", + "abusefilter-edit-builder-vars-new-wikitext": "Уикитекст на новата страница, след редактирането", "abusefilter-edit-builder-vars-new-pst": "Нов уикитекст на страницата, преобразуван преди съхранение", "abusefilter-edit-builder-vars-diff-pst": "Унифицирани разлики на промените, причинени от редакция, преобразувани преди съхранение", "abusefilter-edit-builder-vars-addedlines-pst": "Редове, добавени при редактиране, преобразувани преди съхранение", - "abusefilter-edit-builder-vars-new-text-stripped": "Нов текст на страницата, без форматиране", + "abusefilter-edit-builder-vars-new-text": "Нов текст на страницата, без форматиране", "abusefilter-edit-builder-vars-new-html": "Разпознат HTML код на новата редакция", "abusefilter-edit-builder-vars-restrictions-edit": "Ниво на защита срещу редактиране на страницата", - "abusefilter-edit-builder-vars-restrictions-move": "Ниво на защита срещу местене на страницата", - "abusefilter-edit-builder-vars-restrictions-create": "Създаване на защита за страницата", - "abusefilter-edit-builder-vars-old-text-stripped": "Стар текст на страницата, без форматиране", + "abusefilter-edit-builder-vars-restrictions-move": "Ниво на защита срещу преместване на страницата", + "abusefilter-edit-builder-vars-restrictions-create": "Защита от създаване на страницата", + "abusefilter-edit-builder-vars-restrictions-upload": "Защита за качване на файла", + "abusefilter-edit-builder-vars-old-text": "Стар текст на страницата, без форматиране (не се използва)", "abusefilter-edit-builder-vars-old-links": "Препратки в страницата преди редакцията", - "abusefilter-edit-builder-vars-old-html": "Стар уикитекст, разпознат като HTML код", - "abusefilter-edit-builder-vars-minor-edit": "Отбелязана ли е редакцията като малка промяна или не", + "abusefilter-edit-builder-vars-old-html": "Стар уикитекст, преобразуван в HTML код (вече не се използва)", + "abusefilter-edit-builder-vars-minor-edit": "Отбелязана ли е редакцията като малка промяна или не (не се използва повече)", "abusefilter-edit-builder-vars-file-sha1": "SHA1 хеш стойност на съдържанието на файла", "abusefilter-edit-builder-vars-file-size": "Размер на файла в байтове", "abusefilter-edit-builder-vars-file-mime": "MIME тип на файла", "abusefilter-edit-builder-vars-file-mediatype": "Медиен тип на файла", "abusefilter-edit-builder-vars-file-width": "Ширина на файла в пиксели", "abusefilter-edit-builder-vars-file-height": "Височина на файла в пиксели", - "abusefilter-filter-log": "Последни промени на филтъра", + "abusefilter-filter-log": "Последни промени на филтрите", "abusefilter-history": "История на промените на защитен филтър #$1", "abusefilter-history-foruser": "Промени от $1", - "abusefilter-history-hidden": "скрит", - "abusefilter-history-enabled": "включен", + "abusefilter-history-hidden": "Скрит", + "abusefilter-history-enabled": "Включен", "abusefilter-history-global": "Общ", "abusefilter-history-timestamp": "Време", "abusefilter-history-user": "Потребител", @@ -355,17 +417,20 @@ "abusefilter-exception-expectednotfound": "Очакваното $2 при знак $1 не беше открито (вместо това открито $3 $4).", "abusefilter-exception-unrecognisedkeyword": "Неразпозната ключова дума $2, започваща от знака $1.", "abusefilter-exception-unexpectedtoken": "Неочакван идентификатор „$3“ (от тип $2) при знак $1.", - "abusefilter-exception-unclosedstring": "Незатворен низ, започващ от знака $1.", + "abusefilter-exception-unclosedstring": "Незатворен низ, започващ от знак $1.", "abusefilter-exception-invalidoperator": "Невалиден оператор „$2“ при знака $1.", "abusefilter-exception-unrecognisedtoken": "Неразпознат идентификатор \"$2\" при знак $1.", - "abusefilter-exception-noparams": "Липсват параметри за функцията „$2“ при знака $1.", + "abusefilter-exception-noparams": "Липсват параметри за функцията „$2“ при знак $1.\n{{PLURAL:$3|Очаква се $3 аргумент|Очакват се $3 аргумента}}.", "abusefilter-exception-dividebyzero": "Непозволен опит $2 да се раздели на нула при знак $1.", "abusefilter-exception-unrecognisedvar": "Неразпозната променлива $2 при знака $1", "abusefilter-exception-notenoughargs": "Недостатъчно аргументи за изпълнението на функция $2, извикана на знак $1.\n{{PLURAL:$3|Очакван е|Очаквани са}} $3 {{PLURAL:$3|аргумент|аргумента}}, {{PLURAL:$4|получен е|получени са}} $4", - "abusefilter-exception-regexfailure": "Грешка в регулярния израз „$3“ при знак $1: „$2“", - "abusefilter-exception-overridebuiltin": "Непозволено предефиниране на вградената променлива „$2“ при знак $1.", - "abusefilter-exception-outofbounds": "Опит да се извика несъществуващ елемент $2 от списък (с размер = $3) при знак $1.", + "abusefilter-exception-regexfailure": "Грешка в регулярния израз „$2“ при знак $1.", + "abusefilter-exception-overridebuiltin": "Непозволено предефиниране на вградения идентификатор „$2“ при знак $1.", + "abusefilter-exception-outofbounds": "Опит да се осъществи достъп до несъществуващ елемент $2 на масив (елементи в масива = $3) при знак $1.", "abusefilter-exception-notarray": "Неуспешен опит за извикане на елемент от масив при знак $1.", + "abusefilter-exception-unclosedcomment": "Незатворен коментар, започващ от знак $1.", + "abusefilter-exception-invalidiprange": "Посочен е невалиден IP-диапазон „$2“ от знак $1.", + "abusefilter-exception-disabledvar": "Променливата $2 при знак $1 вече не се използва.", "abusefilter-action-tag": "Етикет", "abusefilter-action-throttle": "Ограничение", "abusefilter-action-warn": "Предупреждение", @@ -383,17 +448,19 @@ "abusefilter-revert-search": "Избор на действия", "abusefilter-revert-filter": "ID на филтъра:", "abusefilter-revert-preview-intro": "По-долу е даден списък от действията, предприети от филтъра срещу злоупотреби, които ще бъдат върнати с това действие.\nМоля, внимателно ги проверете, и щракнете „{{int:abusefilter-revert-confirm}}“, за да потвърдите избора си.", + "abusefilter-revert-confirm-legend": "Потвърждаване на връщането", "abusefilter-revert-confirm": "Потвърждаване", "abusefilter-revert-success": "Вие върнахте всички действия, предприети от филтъра срещу злоупотреби, поради [[Special:AbuseFilter/$1|филтър $2]].", "abusefilter-revert-reason": "Автоматична отмяна на всички действия, извършени от филтъра срещу злоупотребите, по причина филтър $1.\nПосочена причина: $2", "abusefilter-revert-reasonfield": "Причина:", "abusefilter-test": "Тестване на филтъра спрямо предишни редакции", - "abusefilter-test-intro": "Тази страница позволява да се провери филтър, въведен в долната кутия спрямо {{PLURAL:$1|последната|последните}} $1 {{PLURAL:$1|промяна|промени}}.\nЗа да заредите съществуващ филтър, въведете идентификатора му в кутията под текстовата кутия за редактиране и щракнете на бутона „Зареждане“.", + "abusefilter-test-intro": "Тази страница позволява да се провери филтър, въведен в долната кутия спрямо {{PLURAL:$1|последната|последните}} $1 {{PLURAL:$1|промяна|промени}}.\nЗа да заредите съществуващ филтър, въведете идентификатора му в кутията под текстовата кутия за редактиране и щракнете на бутона „{{int:abusefilter-test-load}}“.", "abusefilter-test-legend": "Изпробване на филтъра", "abusefilter-test-load-filter": "Зареждане на филтър с ID:", "abusefilter-test-submit": "Изпробване", "abusefilter-test-load": "Зареждане", "abusefilter-test-user": "Промени от потребител:", + "abusefilter-test-nobots": "Скриване на бот-редакции", "abusefilter-test-period-start": "Промени, направени след това:", "abusefilter-test-period-end": "Промени, направени преди това:", "abusefilter-test-page": "Промени по страницата:", @@ -426,13 +493,13 @@ "abusefilter-examine-noresults": "Не бяха намерени резултати за предоставените параметри за търсенето.", "abusefilter-topnav": "Навигация на филтъра", "abusefilter-topnav-home": "Начало", + "abusefilter-topnav-recentchanges": "Последни промени на филтрите", "abusefilter-topnav-test": "Групово изпробване", "abusefilter-topnav-examine": "Проверка на минали редакции", "abusefilter-topnav-log": "Дневник на злоупотребите", "abusefilter-topnav-tools": "Инструменти за проследяване на грешки", - "abusefilter-topnav-import": "Внасяне на филтър", "abusefilter-log-name": "Дневник на филтъра срещу злоупотреби", - "abusefilter-log-header": "Този дневник показва резюме на промените, направени във филтрите. За всички подробности, вижте [[Special:AbuseFilter/history|списъка]] с последните промени по филтрите.", + "abusefilter-log-header": "Този дневник показва резюме на промените, направени във филтрите.\nЗа всички подробности, вижте [[Special:AbuseFilter/history|списъка]] с последните промени по филтрите.", "abusefilter-logentry-create": "$1 {{GENDER:$2|създаде}} $4 ($5)", "abusefilter-logentry-modify": "$1 {{GENDER:$2|промени}} $4 ($5)", "abusefilter-log-noresults": "Няма резултати", @@ -447,8 +514,17 @@ "abusefilter-diff-next": "По-нова промяна", "abusefilter-import-intro": "Можете да използвате този интерфейс, за да импортирате филтри от други уикита.\nВ уикито-източник щракнете връзката \"{{int:abusefilter-edit-export}}\" под заглавието \"{{int:abusefilter-edit-tools}}\" в интерфейса за редактиране.\nКопирайте съдържанието от текстовата кутия, която ще се появи, и го поставете в тази текстова кутия. След това щракнете на \"{{int:abusefilter-import-submit}}\".", "abusefilter-import-submit": "Внасяне на данни", + "abusefilter-import-invalid-data": "Данните, които опитвате да внесете, не са валидни", "abusefilter-group-default": "По подразбиране", "abusefilter-http-error": "Възникна HTTP грешка: $1", + "abusefilter-view-privatedetails-submit": "Преглед на личните данни", + "abusefilter-view-privatedetails-legend": "Преглед на скрити данни", + "abusefilter-view-privatedetails-reason": "Причина за достъп до личните данни:", "abusefilter-log-details-id": "Номер на записа", - "abusefilter-log-ip-not-available": "Недостъпен" + "abusefilter-invalid-request": "Невалидна заявка! Трябва да осъществите достъп до непубличните записи през формуляра на [[Special:AbuseLog/$1]] и да посочите причина.", + "abusefilter-invalid-request-noid": "Невалидна заявка! Трябва да осъществите достъп до непубличните записи през формуляра на съответната страница и да посочите причина.", + "abusefilter-noreason": "Предупреждение: За да видите личните данни в този дневник, ще трябва да посочите причина.", + "abusefilter-log-ip-not-available": "Недостъпен", + "abusefilter-tag-reserved": "Етикетът <code>abusefilter-condition-limit</code> е запазен за вътрешна обработка от филтъра на злоупотребите.", + "tag-abusefilter-condition-limit": "границата на условието е достигната" } diff --git a/AbuseFilter/i18n/bgn.json b/AbuseFilter/i18n/bgn.json index 2bb4d311..cc9e5fa6 100644 --- a/AbuseFilter/i18n/bgn.json +++ b/AbuseFilter/i18n/bgn.json @@ -11,7 +11,6 @@ "abusefilter-log-diff": "فرق", "abusefilter-log-details-val": "اندازه گ", "abusefilter-log-noactions": "(هیچ)", - "abusefilter-log-hidden": "(چیهرین مورد)", "abusefilter-log-hide-reason": "دلیل:", "abusefilter-list": "موچین فیلتران", "abusefilter-list-id": "فیلتر ئی آی دی", diff --git a/AbuseFilter/i18n/bn.json b/AbuseFilter/i18n/bn.json index 575ae4dc..4ad770f9 100644 --- a/AbuseFilter/i18n/bn.json +++ b/AbuseFilter/i18n/bn.json @@ -2,45 +2,59 @@ "@metadata": { "authors": [ "Aftab1995", + "Aftabuzzaman", "Bellayet", "Ehsanulhb", "Leemon2010", + "Masumrezarock100", "Nasir8891", "Samritmaity", "Wikitanvir", - "Aftabuzzaman", + "YahyA", "আজিজ", "আফতাবুজ্জামান" ] }, "abusefilter-desc": "সম্পাদনায় স্বয়ংক্রিয় অনুসন্ধানমূলক পদ্ধতি প্রযোজ্য।", - "abusefilter": "অপব্যবহার ছাঁকনির কনফিগারেশন", - "abuselog": "অপব্যবহার লগ", + "abusefilter": "অপব্যবহার ছাঁকনি ব্যবস্থাপনা", + "abuselog": "অপব্যবহার ছাঁকনি লগ", + "abusefilter-intro": "অপব্যবহার ছাঁকনি পরিচালনা ইন্টারফেসে আপনাকে স্বাগতম।\nঅপব্যবহার ছাঁকনিটি হল সমস্ত ক্রিয়ায় স্বয়ংক্রিয় অনুসন্ধানী প্রয়োগ করার একটি স্বয়ংক্রিয় সফ্টওয়্যার প্রক্রিয়া।\nএই ইন্টারফেসটি সংজ্ঞায়িত ছাঁকনিগুলির একটি তালিকা দেখায় এবং এগুলি সংশোধন করার অনুমতি দেয়।", + "abusefilter-mustviewprivateoredit": "নিরাপত্তার কারণে, কেবলমাত্র ব্যক্তিগত অপব্যবহার ছাঁকনি দেখার বা ছাঁকনি সংশোধন করার অধিকারযুক্ত থাকা ব্যবহারকারীরা এই ইন্টারফেসটি ব্যবহার করতে পারেন।", + "abusefilter-warning": "'''সতর্কতা:''' এই ক্রিয়াটি স্বয়ংক্রিয়ভাবে ক্ষতিকারক হিসাবে চিহ্নিত করা হয়েছে।\nঅগঠনমূলক ক্রিয়াগুলি দ্রুত প্রত্যাবর্তন করা হবে,\nএবং গুরুতর বা পুনরাবৃত্তিমূলক অসংলগ্ন সম্পাদনা করলে আপনার অ্যাকাউন্ট বা আইপি ঠিকানাকে অবরুদ্ধ করা হবে।\nযদি আপনি এই ক্রিয়াটি গঠনমূলক বলে বিশ্বাস করেন, তবে এটি নিশ্চিত করতে আপনি এটি আবার জমা দিতে পারেন।\nআপনার ক্রিয়াটির সাথে মিলিত হওয়া অপব্যবহারের নিয়মের একটি সংক্ষিপ্ত বিবরণ হলো: $1", "abusefilter-disallowed": "এই কর্মটি স্বয়ংক্রিয়ভাবে ক্ষতিকারক হিসাবে সনাক্ত করা হয়েছে, এবং তাই এটি আটকানো হয়েছে।\nআপনি যদি বিশ্বাস করেন যে আপনার পদক্ষেপ গঠনমূলক ছিল, তাহলে আপনি কি করার চেষ্টা করছেন তা প্রশাসককে জানান।\nঅপব্যবহারের নিয়মের একটি সংক্ষিপ্ত বিবরণ যার সাথে আপনার কর্ম মিলেছে: $1", + "abusefilter-blocked-display": "এই ক্রিয়াটি স্বয়ংক্রিয়ভাবে ক্ষতিকারক হিসাবে চিহ্নিত করা হয়েছে,\nএবং এটি কার্যকর করা থেকে আপনাকে বাধা দেওয়া হয়েছে।\nএছাড়াও, {{SITENAME}} রক্ষা করতে, আপনার ব্যবহারকারীর অ্যাকাউন্ট এবং সমস্ত সম্পর্কিত আইপি ঠিকানাকে সম্পাদনা থেকে অবরুদ্ধ করা হয়েছে।\nএটি যদি ত্রুটিযুক্ত হয়ে থাকে, তবে দয়া করে কোনও প্রশাসকের সাথে যোগাযোগ করুন।\nআপনার ক্রিয়াটির সাথে মিলিত হওয়া অপব্যবহারের নিয়মের একটি সংক্ষিপ্ত বিবরণ হলো: $1", "abusefilter-blocker": "অপব্যবহার ছাঁকনি", + "abusefilter-blockreason": "অপব্যবহার ছাঁকনি দ্বারা স্বয়ংক্রিয়ভাবে অবরুদ্ধ করা হয়েছে।\nমিলে যাওয়া নিয়মের বিবরণ: $1", "abusefilter-accountreserved": "অপব্যবহার ছাঁকনির জন্য এই একাউন্ট নামটি সংরক্ষিত।", - "right-abusefilter-modify": "অপব্যবহার ছাঁকনি পরিবর্তন", + "right-abusefilter-modify": "অপব্যবহার ছাঁকনি তৈরি বা পরিবর্তন করা", "right-abusefilter-view": "অপব্যবহার ছাঁকনি দেখুন", "right-abusefilter-log": "অপব্যবহার লগ দেখা", "right-abusefilter-log-detail": "অপব্যবহার লগটি বিস্তারিতভাবে দেখাও", - "right-abusefilter-private": "অপব্যবহার লগে ব্যক্তিগত তথ্যাদি দেখাও", + "right-abusefilter-privatedetails": "অপব্যবহার লগে ব্যক্তিগত তথ্যাদি দেখাও", "right-abusefilter-modify-restricted": "সীমাবদ্ধ কার্য সহকারে অপব্যবহার ছাঁকনি পরিবর্তন করা", "right-abusefilter-revert": "প্রদানকৃত অপব্যবহার ছাঁকনির সকল পরিবর্তন বাতিল করা", "right-abusefilter-view-private": "ব্যক্তিগত হিসেবে চিহ্নিত অপব্যবহার ছাঁকনি দেখুন", "right-abusefilter-hide-log": "অপব্যবহার লগের সংযোজন লুকাও", - "right-abusefilter-hidden-log": "লুকায়িত অপব্যবহার লগের সংযোজনটি দেখাও", + "right-abusefilter-hidden-log": "লুকানো অপব্যবহার লগের ভুক্তিগুলি দেখুন", "action-abusefilter-modify": "অপব্যবহার ছাঁকনি পরিবর্তন করার", "action-abusefilter-view": "অপব্যবহার ছাঁকনি দেখার", "action-abusefilter-log": "অপব্যবহার লগ দেখার", "action-abusefilter-log-detail": "অপব্যবহার লগের সংযোজন বিস্তারিতভাবে দেখাও", - "action-abusefilter-private": "অপব্যবহার লগে ব্যক্তিগত তথ্যাদি দেখাও", + "action-abusefilter-privatedetails": "অপব্যবহার লগে ব্যক্তিগত তথ্যাদি দেখাও", "action-abusefilter-modify-restricted": "সীমাবদ্ধ কার্য সহকারে অপব্যবহার ছাঁকনি পরিবর্তন করার", "action-abusefilter-revert": "প্রদানকৃত অপব্যবহার ছাঁকনির সকল পরিবর্তন বাতিল করার", "action-abusefilter-view-private": "ব্যক্তিগত হিসেবে চিহ্নিত অপব্যবহার ছাঁকনি দেখার", - "abusefilter-log": "অপব্যবহার ছাঁকনি লগ", + "action-abusefilter-log-private": "ব্যক্তিগত হিসেবে চিহ্নিত করা অপব্যবহার ছাঁকনির লগ দেখার", + "action-abusefilter-hide-log": "অপব্যবহার লগের ভুক্তিগুলি লুকানোর", + "action-abusefilter-hidden-log": "লুকানো অপব্যবহার লগের ভুক্তিগুলি দেখার", + "action-abusefilter-modify-global": "বৈশ্বিক অপব্যবহার ছাঁকনিগুলি তৈরি বা সংশোধন করার", + "abusefilter-log-summary": "এই লগটি ছাঁকনি দ্বারা ধরা সমস্ত কর্মের একটি তালিকা দেখায়।", "abusefilter-log-search": "অপব্যবহার লগে অনুসন্ধান করুন", "abusefilter-log-search-user": "ব্যবহারকারী:", - "abusefilter-log-search-filter": "ছাঁকনির আইডি (পাইপ দিয়ে আলাদা):", + "abusefilter-log-search-group": "দল ছাঁকুন:", + "abusefilter-log-search-group-any": "যেকোন", + "abusefilter-log-search-filter": "ছাঁকনির আইডি:", + "abusefilter-log-search-filter-help": "উলম্ব দণ্ড দিয়ে আলাদা করুন, বৈশ্বিক ছাঁকনির জন্য সাথে \"$1\" উপসর্গ দিন", "abusefilter-log-search-title": "শিরোনাম:", "abusefilter-log-search-wiki": "উইকি:", "abusefilter-log-search-impact": "প্রভাব:", @@ -51,10 +65,14 @@ "abusefilter-log-search-entries-all": "সকল ভুক্তি", "abusefilter-log-search-entries-hidden": "লুকানো ভুক্তি শুধুমাত্র", "abusefilter-log-search-entries-visible": "দৃশ্যমান ভুক্তি শুধুমাত্র", + "abusefilter-log-search-action-label": "সক্রিয় করা কর্ম:", "abusefilter-log-search-action-other": "অন্য", + "abusefilter-log-search-action-any": "যেকোন", "abusefilter-log-search-action-taken-label": "গৃহীত পদক্ষেপ:", "abusefilter-log-search-action-taken-any": "যেকোন", "abusefilter-log-search-submit": "অনুসন্ধান", + "abusefilter-log-entry": "$1: $2 $4 পাতায় \"$3\" কর্ম {{GENDER:$8|সঞ্চালন}} করার সময় একটি অপব্যবহার ছাঁকনি {{GENDER:$8|সক্রিয়}} করেছেন।\nগৃহীত পদক্ষেপ: $5;\nছাঁকনির বিবরণ: $6", + "abusefilter-log-entry-withdiff": "$1: $2 $4 পাতায় \"$3\" কর্ম {{GENDER:$8|সঞ্চালন}} করার সময় একটি অপব্যবহার ছাঁকনি {{GENDER:$8|সক্রিয়}} করেছেন।\nগৃহীত পদক্ষেপ: $5;\nছাঁকনির বিবরণ: $6 ($7)", "abusefilter-log-detailedentry-meta": "$1: $2 $5 পাতায় \"$4\" কর্ম {{GENDER:$9|সঞ্চালন}} করার সময় $3 {{GENDER:$9|সক্রিয়}} করেছেন।\nগৃহীত পদক্ষেপ: $6;\nছাঁকনির বিবরণ: $7 ($8)", "abusefilter-log-detailedentry-global": "বৈশ্বিক ছাঁকনি $1", "abusefilter-log-detailedentry-local": "ছাঁকনি নং $1", @@ -65,7 +83,7 @@ "abusefilter-log-details-var": "চলক", "abusefilter-log-details-val": "মান", "abusefilter-log-details-vars": "অ্যাকশন প্যারামিটার", - "abusefilter-log-details-private": "ব্যক্তিগত লগের বিস্তারিত", + "abusefilter-log-details-privatedetails": "ব্যক্তিগত লগের বিস্তারিত", "abusefilter-log-details-ip": "আইপি ঠিকানা সংরক্ষন করা হচ্ছে", "abusefilter-log-details-checkuser": "ব্যবহারকারী পরীক্ষণ", "abusefilter-log-noactions": "কিছু নয়", @@ -73,7 +91,11 @@ "abusefilter-log-linkoncontribs": "অপব্যবহার লগ", "abusefilter-log-linkoncontribs-text": "{{GENDER:$1|এই ব্যবহারকারীর}} জন্য অপব্যবহার লগ", "abusefilter-log-linkonhistory": "অপব্যবহার লগ দেখুন", - "abusefilter-log-hidden": "(সংযোজন লুকায়িত)", + "abusefilter-log-linkonhistory-text": "এই পাতার জন্য অপব্যবহার লগ দেখুন", + "abusefilter-log-linkonundelete": "অপব্যবহার লগ দেখুন", + "abusefilter-log-linkonundelete-text": "এই পাতার জন্য অপব্যবহার লগ দেখুন", + "abusefilter-log-cannot-see-details": "আপনার এই ভুক্তির বিস্তারিত দেখার অনুমতি নেই।", + "abusefilter-log-cannot-see-privatedetails": "আপনার এই ভুক্তির বিস্তারিত দেখার অনুমতি নেই।", "abusefilter-log-details-hidden": "আপনি এই সংযোজনটি বিস্তারিত দেখতে পারবেন না, কারণ এটি জনসাধারণের প্রদর্শনের থেকে লুকানো রয়েছে।", "abusefilter-log-hide-legend": "লগ সংযোজন লুকাও", "abusefilter-log-hide-id": "লগ সংযোজনের আইডি:", @@ -81,7 +103,12 @@ "abusefilter-log-hide-reason": "কারণ:", "abusefilter-log-hide-reason-other": "অন্যান্য/অতিরিক্ত কারণ:", "abusefilter-log-hide-forbidden": "আপনার অপব্যবহার লগ সংযোজন লুকানোর অধিকার নেই।", - "abusefilter-management": "অপব্যবহার ছাঁকনি ব্যবস্থাপনা", + "abusefilter-log-entry-suppress": "$1 $3 {{GENDER:$2|আড়াল করেছেন}}", + "log-action-filter-abusefilter": "ছাঁকনি পরিবর্তনের ধরন:", + "log-action-filter-abusefilter-create": "নতুন ছাঁকনি তৈরি", + "log-action-filter-abusefilter-modify": "ছাঁকনি সম্পাদনা", + "logentry-abusefilterprivatedetails-access": "$1 $3-এর জন্য ব্যক্তিগত বিবরণ {{GENDER:$2|প্রবেশ করেছেন}}", + "abusefilterprivatedetails-log-name": "অপব্যবহার ছাঁকনিতে ব্যক্তিগত বিবরণে প্রবেশাধিকারের লগ", "abusefilter-list": "সকল ছাঁকনি", "abusefilter-list-id": "ছাঁকনির আইডি", "abusefilter-list-status": "অবস্থা", @@ -101,6 +128,7 @@ "abusefilter-disabled": "নিস্ক্রিয়", "abusefilter-hitcount": "$1টি {{PLURAL:$1|হিট}}", "abusefilter-new": "নতুন ছাঁকনি তৈরি করুন", + "abusefilter-import-button": "ছাঁকনি আমদানি করুন", "abusefilter-return": "ছাঁকনি ব্যবস্থাপনায় ফিরে যান", "abusefilter-status-global": "বৈশ্বিক", "abusefilter-list-options": "অপশন", @@ -108,23 +136,27 @@ "abusefilter-list-options-deleted-only": "শুধুমাত্র অপসারিত ছাঁকনিগুলো দেখান", "abusefilter-list-options-deleted-hide": "অপসারিত ছাঁকনিগুলো লুকান", "abusefilter-list-options-deleted-show": "অপসারিত ছাঁকনিগুলো যোগ করুন", + "abusefilter-list-options-scope": "ছাঁকনিগুলি দেখান:", "abusefilter-list-options-scope-local": "স্থানীয় নিয়ম শুধুমাত্র", "abusefilter-list-options-scope-global": "বৈশ্বিক নিয়ম শুধুমাত্র", "abusefilter-list-options-scope-all": "স্থানীয় এবং বৈশ্বিক নিয়ম", "abusefilter-list-options-further-options": "আরও বিকল্প:", "abusefilter-list-options-hidedisabled": "নিষ্ক্রিয় ছাঁকনিগুলো লুকান", + "abusefilter-list-options-searchfield": "নিয়মের মধ্যে অনুসন্ধান করুন:", "abusefilter-list-options-searchoptions": "অনুসন্ধান মোড:", + "abusefilter-list-options-search-rlike": "রেগুলার এক্সপ্রেশন", "abusefilter-list-options-submit": "হালনাগাদ", "abusefilter-tools-expr": "এক্সপ্রেশন পরীক্ষক", "abusefilter-tools-submitexpr": "মূল্যায়ন করুন", "abusefilter-tools-reautoconfirm-user": "ব্যবহারকারী:", "abusefilter-tools-reautoconfirm-submit": "পুনরায়-স্বয়ংক্রিয়ভাবে নিশ্চিত", - "abusefilter-status": "বিগত $1টি {{PLURAL:$1|কার্যে}}, $2টি ($3%) শর্তের সীমা $4-এ পৌঁছেছে, এবং $5টি ($6%) বর্তমানে সক্রিয় ছাঁকনিগুলির একটির সাথে মিলেছে।", + "abusefilter-status": "বিগত $1টি {{PLURAL:$1|কার্যে}}, $2টি ($3%) শর্তের সীমা $4-এ পৌঁছেছে, এবং $5টি ($6%) বর্তমানে সক্রিয় ছাঁকনিগুলির অন্তত একটির সাথে মিলেছে।", "abusefilter-edit": "অপব্যবহার ছাঁকনি সম্পাদনা করছেন", - "abusefilter-edit-subtitle": "$1 ছাঁকনি সম্পাদনা করছেন", + "abusefilter-edit-subtitle": "$1 নং ছাঁকনি সম্পাদনা করছেন", "abusefilter-edit-subtitle-new": "ছাঁকনি তৈরি করছেন", + "abusefilter-edit-token-not-match": "সম্পাদনাটি সংরক্ষণ করা হয়নি! আবার সংরক্ষণ করুন।", "abusefilter-edit-status-label": "পরিসংখ্যান:", - "abusefilter-edit-status": "বিগত $1টি {{PLURAL:$1|কার্যে}}, এই ছাঁকনিটি $2 বার ($3%) মিলেছে।", + "abusefilter-edit-status": "বিগত $1টি {{PLURAL:$1|কার্যে}}, এই ছাঁকনিটি $2 বার ($3%) মিলেছে। গড়ে, এটি চলার সময় $4 মি.সে. এবং এটি শর্তসীমার $5টি {{PLURAL:$5|শর্ত}} ব্যয় করেছে।", "abusefilter-edit-new": "নতুন ছাঁকনি", "abusefilter-edit-save": "ছাঁকনি সংরক্ষণ করুন", "abusefilter-edit-id": "ছাঁকনির আইডি:", @@ -143,22 +175,50 @@ "abusefilter-edit-lastmod": "ছাঁকনি সর্বশেষ পরিবর্তিত হয়েছিলো:", "abusefilter-edit-lastmod-text": "$1 তারিখে $2 কর্তৃক", "abusefilter-edit-hitcount": "ছাঁকনির হিট:", - "abusefilter-edit-consequences": "মিল পাওয়া গেলে যে পদক্ষেপ নেয়া হয়েছে", - "abusefilter-edit-throttle-period": "সময়:", - "abusefilter-edit-throttle-ip": "আইপি ঠিকানা", - "abusefilter-edit-throttle-editcount": "সম্পাদনা গণনা", - "abusefilter-edit-throttle-page": "পাতা", + "abusefilter-edit-consequences": "মিল পাওয়া গেলে যে পদক্ষেপ নেয়া হবে", + "abusefilter-edit-action-blockautopromote": "ব্যবহারকারীর স্বয়ংনিশ্চিতকৃত স্থিতি বাতিল করুন", + "abusefilter-edit-action-tag": "আরও পর্যালোচনার জন্য সম্পাদনা ট্যাগ করুন", + "abusefilter-edit-throttle-period": "সময়কাল (সেকেন্ডে):", + "abusefilter-edit-throttle-groups-help": "$1 দেখুন।", + "abusefilter-edit-throttle-groups-help-text": "mediawiki.org সাইটে নথিপত্র", + "abusefilter-throttle-ip": "আইপি ঠিকানা", + "abusefilter-throttle-user": "ব্যবহারকারী অ্যাকাউন্ট", + "abusefilter-throttle-range": "পরিসীমা /16", + "abusefilter-throttle-creationdate": "অ্যাকাউন্ট সৃষ্টির তারিখ", + "abusefilter-throttle-editcount": "সম্পাদনা গণনা", + "abusefilter-throttle-site": "সম্পূর্ণ সাইট", + "abusefilter-throttle-page": "পাতা", + "abusefilter-throttle-none": "(কিছু না)", + "abusefilter-edit-warn-message": "সতর্কতা প্রদানের জন্য ব্যবহৃত সিস্টেম বার্তা:", "abusefilter-edit-warn-other": "অন্য বার্তা", + "abusefilter-edit-warn-other-label": "অন্য বার্তার পাতার নাম:\n:''(\"মিডিয়াউইকি:\" উপসর্গ ছাড়া)''", "abusefilter-edit-warn-actions": "কার্যসমূহ:", - "abusefilter-edit-warn-preview": "নির্বাচিত বার্তার প্রাকদর্শন", + "abusefilter-edit-warn-preview": "নির্বাচিত বার্তার প্রাকদর্শন দেখান/লুকান", "abusefilter-edit-warn-edit": "নির্বাচিত বার্তা তৈরি/সম্পাদনা করুন", + "abusefilter-edit-disallow-message": "প্রত্যাখ্যান করতে ব্যবহার করার জন্য সিস্টেম বার্তা:", + "abusefilter-edit-disallow-other": "অন্য বার্তা", + "abusefilter-edit-disallow-other-label": "অন্য বার্তার পাতার নাম:\n:''(\"মিডিয়াউইকি:\" উপসর্গ ছাড়া)''", + "abusefilter-edit-disallow-actions": "কার্যসমূহ", + "abusefilter-edit-disallow-preview": "নির্বাচিত বার্তার প্রাকদর্শন দেখান/লুকান", + "abusefilter-edit-disallow-edit": "নির্বাচিত বার্তা তৈরি/সম্পাদনা করুন", "abusefilter-edit-tag-tag": "যোগের জন্য [[Special:Tags|ট্যাগ]]:", + "abusefilter-edit-tag-placeholder": "ট্যাগ যুক্ত করুন (একের পর এক অথবা কমা দিয়ে আলাদাকৃত)", + "abusefilter-edit-tag-hidden-placeholder": "ট্যাগ যুক্ত করুন (কমা দিয়ে আলাদাকৃত)", + "abusefilter-edit-block-anon-durations": "বেনামী ব্যবহারকারীদের অবরুদ্ধ সময়কাল:", + "abusefilter-edit-block-user-durations": "নিবন্ধিত ব্যবহারীদের বাধার সময়কাল:", + "abusefilter-block-anon": "বেনামী ব্যবহারকারীদের বাধা দিন", + "abusefilter-block-user": "নিবন্ধিত ব্যবহারকারীদের বাধা দিন", + "abusefilter-block-talk": "আলাপ পাতা অবরুদ্ধ", "abusefilter-edit-main": "ছাঁকনির প্যারামিটারসমূহ", "abusefilter-edit-done-subtitle": "ছাঁকনি সম্পাদিত হয়েছে", "abusefilter-edit-viewhistory": "এই ছাঁকনির ইতিহাস দেখুন", "abusefilter-edit-history": "ইতিহাস:", + "abusefilter-edit-check": "শব্দবিন্যাস পরীক্ষা করুন", "abusefilter-edit-tools": "সরঞ্জাম:", + "abusefilter-edit-test-link": "সাম্প্রতিক সম্পাদনাগুলির সাথে এই ছাঁকনি পরীক্ষা করুন", "abusefilter-edit-export": "এই ছাঁকনিটি অন্য উইকিতে রপ্তানি করুন", + "abusefilter-edit-syntaxok": "কোন শব্দবিন্যাস ত্রুটি পাওয়া যায়নি।", + "abusefilter-edit-syntaxerr": "সিনট্যাক্স ত্রুটি সনাক্ত হয়েছে: $1", "abusefilter-edit-builder-op-arithmetic-addition": "যোগ (+)", "abusefilter-edit-builder-op-arithmetic-subtraction": "বিয়োগ (-)", "abusefilter-edit-builder-op-arithmetic-multiplication": "গুন (*)", @@ -184,6 +244,7 @@ "abusefilter-edit-builder-group-funcs": "ফাংশন", "abusefilter-edit-builder-funcs-length": "স্ট্রিংয়ের দৈর্ঘ্য (length)", "abusefilter-edit-builder-funcs-ccnorm-contains-any": "OR মোডে একাধিক উপস্ট্রিংয়ের জন্য একটি স্ট্রিং স্বাভাবিক করুন ও অনুসন্ধান করুন (ccnorm_contains_any)", + "abusefilter-edit-builder-funcs-norm": "স্বাভাবিকীকরণ (norm)", "abusefilter-edit-builder-funcs-set_var": "চলক নির্ধারণ (set_var)", "abusefilter-edit-builder-group-vars": "চলক", "abusefilter-edit-builder-vars-accountname": "অ্যাকাউন্টের নাম (অ্যাকাউন্ট তৈরির সময়)", @@ -214,13 +275,13 @@ "abusefilter-edit-builder-vars-all-links": "নতুন লেখায় থাকা সকল বহিঃসংযোগ", "abusefilter-edit-builder-vars-added-links": "সম্পাদনায় যুক্ত করা সকল বহিঃসংযোগ", "abusefilter-edit-builder-vars-removed-links": "সম্পাদনায় অপসারণ করা সকল বহিঃসংযোগ", - "abusefilter-edit-builder-vars-old-text": "সম্পাদনার পূর্বে, পুরোনো পাতার উইকিটেক্সট", - "abusefilter-edit-builder-vars-new-text": "সম্পাদনার পর, নতুন পাতার উইকিটেক্সট", + "abusefilter-edit-builder-vars-old-wikitext": "সম্পাদনার পূর্বে, পুরোনো পাতার উইকিপাঠ্য", + "abusefilter-edit-builder-vars-new-wikitext": "সম্পাদনার পর, নতুন পাতার উইকিপাঠ্য", "abusefilter-edit-builder-vars-restrictions-edit": "পাতার সুরক্ষা পর্যায় সম্পাদনা", "abusefilter-filter-log": "সাম্প্রতিক ছাঁকনি পরিবর্তন", "abusefilter-history": "$1 নং অপব্যবহার ছাঁকনির পরিবর্তনের ইতিহাস", "abusefilter-history-foruser": "$1 কর্তৃক পরিবর্তন হয়েছে", - "abusefilter-history-hidden": "লুকায়িত", + "abusefilter-history-hidden": "লুকানো", "abusefilter-history-enabled": "সক্রিয় করা", "abusefilter-history-global": "বৈশ্বিক", "abusefilter-history-timestamp": "সময়", @@ -249,7 +310,11 @@ "abusefilter-revert-reasonfield": "কারণ:", "abusefilter-test-submit": "পরীক্ষণ", "abusefilter-test-load": "লোড", + "abusefilter-test-user": "এ ব্যবহারকারীর করা পরিবর্তন:", "abusefilter-test-nobots": "বটের করা সম্পাদনা লুকান", + "abusefilter-test-period-start": "এ তারিখের পর করা পরিবর্তন:", + "abusefilter-test-period-end": "এ তারিখের আগে করা পরিবর্তন:", + "abusefilter-test-page": "এ পাতায় করা পরিবর্তন:", "abusefilter-test-action": "কার্যের ধরন:", "abusefilter-test-search-type-all": "সব কার্য", "abusefilter-test-search-type-edit": "সম্পাদনা", @@ -257,6 +322,7 @@ "abusefilter-test-search-type-delete": "অপসারণ", "abusefilter-test-search-type-upload": "আপলোড", "abusefilter-test-search-type-createaccount": "অ্যাকাউন্ট সৃষ্টি", + "abusefilter-changeslist-examine": "পরীক্ষা করুন", "abusefilter-examine-legend": "পরিবর্তন নির্বাচন", "abusefilter-examine-diff": "পরিবর্তনের ইউআরএল:", "abusefilter-examine-user": "ব্যবহারকারী:", @@ -264,10 +330,11 @@ "abusefilter-examine-submit": "অনুসন্ধান", "abusefilter-topnav": "'''অপব্যবহার ছাঁকনি পরিভ্রমণ'''", "abusefilter-topnav-home": "প্রধান পাতা", + "abusefilter-topnav-recentchanges": "সাম্প্রতিক ছাঁকনি পরিবর্তন", "abusefilter-topnav-examine": "অতীতের সম্পাদনাগুলি পরীক্ষা করুন", "abusefilter-topnav-log": "অপব্যবহার লগ", - "abusefilter-topnav-import": "ছাঁকনি আমদানি করুন", "abusefilter-log-name": "অপব্যবহার ছাঁকনি লগ", + "abusefilter-log-header": "এই লগটি ছাঁকনিগুলিতে করা পরিবর্তনসমূহের সংক্ষিপ্ত বিবরণ দেখায়।\nবিস্তারিত দেখার জন্য, সাম্প্রতিক ছাঁকনি পরিবর্তনের [[Special:AbuseFilter/history|তালিকাটি]] দেখুন।", "abusefilter-logentry-modify": "$1 $4 {{GENDER:$2|সম্পাদনা করেছেন}} ($5)", "abusefilter-log-noresults": "ফলাফল নাই", "abusefilter-diff-title": "সংস্করণগুলির মধ্যে পার্থক্য", @@ -276,8 +343,13 @@ "abusefilter-diff-pattern": "ছাঁকনির শর্তসমূহ", "abusefilter-diff-backhistory": "ছাঁকনির ইতিহাসে ফিরে যান", "abusefilter-diff-prev": "পুরানো পরিবর্তন", + "abusefilter-diff-next": "নতুনতর পরিবর্তন", "abusefilter-import-submit": "উপাত্ত আমদানী", "abusefilter-group-default": "পূর্বনির্ধারিত", "abusefilter-http-error": "একটি HTTP ত্রুটি ঘটেছে: $1।", + "abusefilter-view-privatedetails-submit": "ব্যক্তিগতের বিস্তারিত দেখুন", + "abusefilter-view-privatedetails-legend": "ব্যক্তিগতের বিস্তারিত দেখুন", + "abusefilter-view-privatedetails-reason": "ব্যক্তিগতের বিস্তারিত দেখার কারণ:", + "abusefilter-log-details-id": "লগ আইডি", "abusefilter-log-ip-not-available": "উপলব্ধ নয়" } diff --git a/AbuseFilter/i18n/br.json b/AbuseFilter/i18n/br.json index 4c4abf5b..5137d27a 100644 --- a/AbuseFilter/i18n/br.json +++ b/AbuseFilter/i18n/br.json @@ -4,14 +4,14 @@ "Fohanno", "Fulup", "Gwendal", + "Matma Rex", "VIGNERON", - "Y-M D", - "Matma Rex" + "Y-M D" ] }, "abusefilter-desc": "Lakaat a ra hentennoù klask emgefre da dalvezout evit ar c'hemmoù", - "abusefilter": "Kefluniadur ar siloù a-enep ar gwallimplij", - "abuselog": "Marilh ar siloù a-enep ar gwallimplij", + "abusefilter": "Merañ ar sil a-enep ar gwallimplij", + "abuselog": "Marilh ar sil a-enep ar gwallimplij", "abusefilter-intro": "Degemer mat en etrefas merañ ar siloù drougimplij.\nUr gwikedre meziantel emgefre eo ar sil a-enep an drougimplij. Talvezout a ra da lakaat hentennoù klask emgefre raktermenet evit pep ober.\nDiskouez a ra an etrefas-mañ ur roll eus ar siloù termenet, hag aotren a ra degas kemmoù enno.", "abusefilter-warning": "'''Diwallit''': an ober-mañ a zo anavezet evit bezañ noazus.\nAr c'hemmoù diyaus a vo nullet raktal,\nstanket e vo ho kont pe ho chomlec'h IP ma skrivit bleupajoù lies pe dismegañsus.\nMa soñjit eo ar c'hemm yaus, galloud a rit kinnig anezhañ en-dro evit kadarnaat.\nUn diskrivadur berr eus ar reolenn drougimplij dinoet gantañ ho ober : $1", "abusefilter-disallowed": "Anavezet eo an ober-mañ evit bezañ noazus,\nharzet eo bet dre-se.\nMa soñj deoc'h e oa reizh ho kemm, trugarez da vont e darempred gant ur merour, a lavarit ar pezh ho poa c'hoant d'ober.\nSetu un deskrivadur berr eus ar reolenn diskoachañ an drougimplij eo bet dinoet ganti hoc'h oberiadenn : $1", @@ -26,7 +26,7 @@ "right-abusefilter-view": "Gwelet ar siloù a-enep ar gwallimplij", "right-abusefilter-log": "Gwelet marilh ar siloù a-enep ar gwallimplij", "right-abusefilter-log-detail": "Gwelet ar c'hasadennoù dre ar munud evit marilh ar siloù a-enep ar gwallimplij", - "right-abusefilter-private": "Gwelet ar roadennoù prevez er marilh a-enep ar gwallimplij", + "right-abusefilter-privatedetails": "Gwelet ar roadennoù prevez er marilh a-enep ar gwallimplij", "right-abusefilter-modify-restricted": "Kemmañ ar siloù a-enep ar gwallimplij gant oberoù bevennet", "right-abusefilter-revert": "Disteurel holl kemmoù graet gant ur sil drougimplij", "right-abusefilter-view-private": "Gwelet ar siloù gwallimplij merket evel prevez", @@ -36,17 +36,21 @@ "action-abusefilter-view": "Gwelet ar siloù a-enep ar gwallimplij", "action-abusefilter-log": "Gwelet marilh ar siloù a-enep ar gwallimplij", "action-abusefilter-log-detail": "gwelet ar c'hasadennoù dre ar munud evit marilh ar siloù a-enep ar gwallimplij", - "action-abusefilter-private": "gwelet ar roadennoù prevez e marilh ar siloù a-enep ar gwallimplij", + "action-abusefilter-privatedetails": "gwelet ar roadennoù prevez e marilh ar siloù a-enep ar gwallimplij", "action-abusefilter-modify-restricted": "kemmañ ar siloù a-enep ar gwallimplij gant oberoù bevennet", "action-abusefilter-revert": "disteurel holl kemmoù graet gant ur sil gwallimplij roet", "action-abusefilter-view-private": "gwelet ar siloù enep ar gwallimplij merket evel prevez", - "abusefilter-log": "Marilh ar sil a-enep ar gwallimplij", "abusefilter-log-summary": "Diskouez a ra ar marilh-mañ ur roll eus an oberezhioù dinoet gant ar siloù.", "abusefilter-log-search": "Klask e marilh ar siloù a-enep ar gwallimplij", "abusefilter-log-search-user": "Implijer :", + "abusefilter-log-search-group": "Strollad siloù :", + "abusefilter-log-search-group-any": "Ne vern pehini", "abusefilter-log-search-filter": "Niv. ar sil :", "abusefilter-log-search-title": "Titl :", "abusefilter-log-search-wiki": "Wiki :", + "abusefilter-log-search-action-other": "All", + "abusefilter-log-search-action-any": "Ne vern pehini", + "abusefilter-log-search-action-taken-label": "Diarbenn kemeret :", "abusefilter-log-search-submit": "Klask", "abusefilter-log-entry": "$1: $2 en deus lañset ur sil gwallimplij, e-kerzh an ober \"$3\" war $4.\nOberoù kemeret : $5;\nDiskrivadenn ar sil : $6", "abusefilter-log-detailedentry-meta": "$1 : $2 en deus lañset ar $3, e-kerzh an ober \"$4\" war $5.\nOberoù kemeret : $6;\nDiskrivadenn ar sil : $7 ($8)", @@ -59,13 +63,12 @@ "abusefilter-log-details-var": "Argemmenn", "abusefilter-log-details-val": "Talvoudenn", "abusefilter-log-details-vars": "Arventennoù an oberezh", - "abusefilter-log-details-private": "Titouroù prevez", + "abusefilter-log-details-privatedetails": "Titouroù prevez", "abusefilter-log-details-ip": "Chomlec'h IP a orin", "abusefilter-log-noactions": "netra", "abusefilter-log-details-diff": "Kemmoù graet er c'hemm", "abusefilter-log-linkoncontribs": "Marilh ar siloù a-enep ar gwallimplij", "abusefilter-log-linkoncontribs-text": "Marilh ar siloù a-enep ar gwallimplij evit an implijer-mañ", - "abusefilter-log-hidden": "(moned kuzhet)", "abusefilter-log-hidden-implicit": "(kuzhet abalamour m'eo bet diverket ar reizhadenn)", "abusefilter-log-cannot-see-details": "N'hoc'h ket aotreet da welet ar munudoù evit an enmont-mañ.", "abusefilter-log-details-hidden": "Ne c'helloc'h ket gwelet munudoù ar moned-mañ dre ma 'z eo kuzhet d'ar selloù publik.", @@ -74,9 +77,9 @@ "abusefilter-log-hide-hidden": "Kuzhat ar moned-mañ eus ar selloù publik", "abusefilter-log-hide-reason": "Abeg :", "abusefilter-log-hide-forbidden": "N'hoc'h eus ket ar gwir da guzhat enmontoù e deizlevr ar gwallimplij.", - "abusefilter-management": "Merañ ar sil a-enep ar gwallimplij", "abusefilter-list": "An holl siloù", "abusefilter-list-id": "Niv. ar sil", + "abusefilter-list-pattern": "Patrom", "abusefilter-list-status": "Statud", "abusefilter-list-public": "Deskrivadur foran", "abusefilter-list-consequences": "Heuliadoù", @@ -94,6 +97,7 @@ "abusefilter-disabled": "Diweredekaet", "abusefilter-hitcount": "$1 {{PLURAL:$1|dizhadenn|tizhadenn}}", "abusefilter-new": "Sevel ur sil nevez", + "abusefilter-import-button": "Enporzhiañ ur sil", "abusefilter-return": "Distreiñ d'ar merañ siloù", "abusefilter-status-global": "Hollek", "abusefilter-list-options": "Dibarzhioù", @@ -101,14 +105,22 @@ "abusefilter-list-options-deleted-only": "Diskouez ar siloù dilamet hepken", "abusefilter-list-options-deleted-hide": "Kuzhar ar siloù dilamet", "abusefilter-list-options-deleted-show": "Enklozañ ar siloù dilamet", - "abusefilter-list-options-scope": "Diskouez ar siloù adalek :", - "abusefilter-list-options-scope-local": "Wiki lec'hel", - "abusefilter-list-options-scope-global": "Reolennoù hollek", + "abusefilter-list-options-scope": "Diskouez ar siloù :", + "abusefilter-list-options-scope-local": "Reolennoù lec'hel hepken", + "abusefilter-list-options-scope-global": "Reolennoù hollek hepken", + "abusefilter-list-options-scope-all": "Reolennoù lec'hel hag hollek", + "abusefilter-list-options-further-options": "Dibarzhioù all :", "abusefilter-list-options-hidedisabled": "Kuzhat ar siloù diweredekaet", + "abusefilter-list-options-hideprivate": "Kuzhat ar siloù prevez", + "abusefilter-list-options-searchfield": "Klask e diabarzh ar reolennoù :", + "abusefilter-list-options-searchpattern": "Ensoc'hañ ur patrom", + "abusefilter-list-options-searchoptions": "Mod klask :", + "abusefilter-list-options-search-like": "Reked eeun", "abusefilter-list-options-submit": "Hizivaat", "abusefilter-tools-text": "Sed aze binviji hag a c'hell servij evit da geriañ ha da zidraenañ ar siloù gwallimplij.", "abusefilter-tools-expr": "Amprouer an estaoladennoù", "abusefilter-tools-submitexpr": "Priziañ", + "abusefilter-tools-syntax-error": "Direizh eo ereadur ar sil~.", "abusefilter-tools-reautoconfirm": "Adsevel ar stad emkadarnet", "abusefilter-tools-reautoconfirm-user": "Implijer :", "abusefilter-tools-reautoconfirm-submit": "Gwiriañ emgefre adarre", @@ -122,11 +134,11 @@ "abusefilter-edit-oldwarning": "<strong>O embann emaoc'h ur stumm kozh eus ar sil-mañ.\nAr stadegoù diskouezet a zo evit ar stumm diwezhañ eus ar sil.\nMa enrollit ho kemmoù, e flastrit holl ar c'hemmoù bet graet abaoe ar stumm emaoc'h o kemm.</strong> •\n[[Special:AbuseFilter/history/$2|Distreiñ da istor ar sil-mañ]].", "abusefilter-edit-status-label": "Stadegoù :", "abusefilter-edit-status": "E-barzh an {{PLURAL:$1|ober diwezhañ|$1 ober diwezhañ}}, ar sil-mañ en deus dinoet $2 ($3%).", - "abusefilter-edit-status-profile": "E-barzh an {{PLURAL:$1|ober diwezhañ|$1 ober diwezhañ}}, ar sil-mañ en deus dinoet $2 ($3%).\nDre geidenn, an padelezh da lañsañ anezhañ a zo $4ms, hag implijout a ra $5 {{PLURAL:$5|amplegad|amplegad}} eus termen an amplegadoù.", "abusefilter-edit-new": "Sil nevez", "abusefilter-edit-save": "Enrollañ ar sil", "abusefilter-edit-id": "Niv. ar sil :", "abusefilter-edit-description": "Deskrivadur :\n: ''(a-wel d'an holl)''", + "abusefilter-edit-field-description": "deskrivadur", "abusefilter-edit-group": "Strollad siloù :", "abusefilter-edit-flags": "Bannieloù :", "abusefilter-edit-enabled": "Gweredekaat ar sil-mañ", @@ -150,13 +162,23 @@ "abusefilter-edit-throttle-count": "Niver a oberiadennoù aotreet :", "abusefilter-edit-throttle-period": "Prantad amzer :", "abusefilter-edit-throttle-groups": "Stollañ ar merañ dre :\n:''(unan dre linenn, ha dispartiet gant virgulennoù)''", + "abusefilter-edit-throttle-groups-help": "Gwelet $1.", + "abusefilter-throttle-ip": "Chomlec'h IP", + "abusefilter-throttle-user": "Kont implijer", + "abusefilter-throttle-site": "al lec'hienn a-bezh", + "abusefilter-throttle-page": "pajenn", + "abusefilter-throttle-none": "(hini ebet)", "abusefilter-edit-warn-message": "Kemenn reizhiad da implijout da gemenn-diwall :", "abusefilter-edit-warn-other": "Kemennadenn all", "abusefilter-edit-warn-other-label": "Anv pajenn ur gemenadenn all :\n''(hep ar rakger MediaWiki)''", "abusefilter-edit-warn-actions": "Oberoù :", "abusefilter-edit-warn-preview": "Rakwelet ar gemennadenn dibabet", "abusefilter-edit-warn-edit": "Krouiñ/Kemmañ ar gemennadenn diuzet", + "abusefilter-edit-disallow-other": "Kemennadenn all", "abusefilter-edit-tag-tag": "Balizenn da arloañ (unan dre linenn) :", + "abusefilter-block-anon": "Stankañ an implijerien dizanv", + "abusefilter-block-user": "stankañ an implijerien enrollet", + "abusefilter-block-talk": "pajenn gaozeal stanket", "abusefilter-edit-denied": "Ne c'helloc'h ket gwelet munudoù ar sil-mañ dre ma 'z eo kuzhet d'ar selloù publik.", "abusefilter-edit-main": "Arventennoù ar sil", "abusefilter-edit-done-subtitle": "Sil aozet", @@ -256,15 +278,15 @@ "abusefilter-edit-builder-vars-all-links": "An holl liammoù diavaez en destenn nevez", "abusefilter-edit-builder-vars-added-links": "An holl liammoù diavaez ouzhpennet er c'hemmoù", "abusefilter-edit-builder-vars-removed-links": "Lamet eo bet an holl liammoù diavaez en aozadenn", - "abusefilter-edit-builder-vars-old-text": "Testenn kozh ar bajenn, a-raok ar c'hemm", - "abusefilter-edit-builder-vars-new-text": "Testenn nevez ar bajenn, goude ar c'hemm", - "abusefilter-edit-builder-vars-new-text-stripped": "Testenn nevez ar bajenn, hep tamm furmad ebet", + "abusefilter-edit-builder-vars-old-wikitext": "Testenn kozh ar bajenn, a-raok ar c'hemm", + "abusefilter-edit-builder-vars-new-wikitext": "Testenn nevez ar bajenn, goude ar c'hemm", + "abusefilter-edit-builder-vars-new-text": "Testenn nevez ar bajenn, hep tamm furmad ebet", "abusefilter-edit-builder-vars-new-html": "Mammenn HTML parset eus ar stumm nevez", "abusefilter-edit-builder-vars-restrictions-edit": "Live gwareziñ ar bajenn evit an aozañ", "abusefilter-edit-builder-vars-restrictions-move": "Live gwareziñ ar bajenn evit adenvel anezhi", "abusefilter-edit-builder-vars-restrictions-create": "Krouiñ gwarez ar bajenn", "abusefilter-edit-builder-vars-restrictions-upload": "Kargañ gwarez ar restr", - "abusefilter-edit-builder-vars-old-text-stripped": "Testenn kozh ar bajenn, hep tamm furmad ebet", + "abusefilter-edit-builder-vars-old-text": "Testenn kozh ar bajenn, hep tamm furmad ebet", "abusefilter-edit-builder-vars-old-links": "Liammoù er bajenn, a-raok an aozadenn", "abusefilter-edit-builder-vars-old-html": "Wikitestenn eus ar bajenn kent, parset e HTML", "abusefilter-edit-builder-vars-minor-edit": "Ma 'z eo ar c'hemm anavezet e-giz bihan pe get", @@ -361,7 +383,6 @@ "abusefilter-topnav-examine": "Studiañ ar c'hemmoù a-raok", "abusefilter-topnav-log": "Marilh ar gwallimplij", "abusefilter-topnav-tools": "Ostilhoù dizreinañ", - "abusefilter-topnav-import": "Enporzhiañ ur sil", "abusefilter-log-name": "Marilh ar sil a-enep ar gwallimplij", "abusefilter-log-header": "An deizlevr-mañ a ziskouez un diverradenn eus ar c'hemmoù graet d'ar siloù.\nEvit gouzout hiroc'h, gwelout [[Special:AbuseFilter/history|listenn]] eus kemmoù diwezhañ ar sil.", "abusefilter-log-noresults": "Disoc'h ebet", diff --git a/AbuseFilter/i18n/bs.json b/AbuseFilter/i18n/bs.json index 3fe1d183..40b46d8f 100644 --- a/AbuseFilter/i18n/bs.json +++ b/AbuseFilter/i18n/bs.json @@ -1,22 +1,24 @@ { "@metadata": { "authors": [ + "BadDog", "CERminator", "Edinwiki", + "KWiki", + "Matma Rex", "Palapa", "Seha", + "Semso98", "Sociologist", - "KWiki", "Srdjan m", - "Semso98", - "Matma Rex", - "BadDog" + "Srđan", + "Vlad5250" ] }, "abusefilter-desc": "Dodaje automatske heuristike izmjenama.", - "abusefilter": "Konfiguracija filtera za zloupotrebu", - "abuselog": "Log zloupotrebe", - "abusefilter-intro": "Dobrodošli u interfejs upravljanja filterom zloupotreba.\nFilter zloupotreba je automatizirani softverski mehanizam za pravljenje automatskih heuristika za sve akcije.\nOvaj interfejs prikazuje spisak napravljenih filtera i omogućuje Vam da ih prilagodite.", + "abusefilter": "Upravljanje filterom protiv zloupotrebe", + "abuselog": "Zapisnik filtera protiv zloupotrebe", + "abusefilter-intro": "Dobro došli u interfejs upravljanja filterom zloupotreba.\nFilter zloupotreba je automatizirani softverski mehanizam za pravljenje automatskih heuristika za sve radnje.\nOvaj interfejs prikazuje spisak napravljenih filtera i omogućuje Vam da ih prilagodite.", "abusefilter-warning": "'''Upozorenje''': Ova je akcija automatski identificirana kao opasna.\nRadnje s lošim namjerama će biti brzo uklonjene,\ni zlonamjerne i destruktivne izmjene rezultiraju blokiranjem Vašeg korisničkog računa ili Vašeg računara.\nAko mislite da je ovo konstruktivna izmjena, onda je još jednom sačuvajte da bi bila dodana.\nOpis pravila zloupotrebe koje ste možda izmjenom prekršili je vidljiv ovdje: $1", "abusefilter-disallowed": "Ova akcija je automatski identificirana kao štetna, i kao takva onemogućena.\nAko vjerujete da je Vaša izmjena konstruktivna, molimo Vas da kontaktirate administratora, i da ga obavijestite o onome šta namjeravate uraditi.\nKratki opis pravila ponašanja koje ogovara Vašoj akciji je: $1", "abusefilter-blocked-display": "Ova akcija je automatski identificirana kao opasna,\ni kao takva onemogućena da se izvrši.\nDodatno, da bi se zaštitio {{SITENAME}}, Vaš korisnički račun i sve pripadajuće IP adrese su blokirane za uređivanje.\nAko se desila greška, molimo da kontaktirate administratora.\nKratki opis prekršenih pravila koja odgovaraju Vašoj akciji je: $1", @@ -30,7 +32,7 @@ "right-abusefilter-view": "Pregledanje filtera protiv zloupotrebe", "right-abusefilter-log": "Pregledanje zapisnika zloupotrebe", "right-abusefilter-log-detail": "Pregledanje detaljnih podataka u zapisniku zloupotrebe", - "right-abusefilter-private": "Pogledaj privatne podatke u logu zloupotrebe.", + "right-abusefilter-privatedetails": "Pogledaj privatne podatke u logu zloupotrebe.", "right-abusefilter-modify-restricted": "Mijenjanje filtera zloupotrebe sa ograničenim akcijama", "right-abusefilter-revert": "Vrati sve izmjene date od filtera zloupotreba", "right-abusefilter-view-private": "Pregled filtera zloupotrebe koji su označeni kao lični", @@ -42,13 +44,12 @@ "action-abusefilter-view": "pregledate filtere protiv zloupotrebe", "action-abusefilter-log": "pregledate zapisnik zloupotrebe", "action-abusefilter-log-detail": "pregledate detaljne unose u zapisniku zloupotrebe", - "action-abusefilter-private": "vidi privatne podatke u zapisniku zloupotreba", + "action-abusefilter-privatedetails": "vidi privatne podatke u zapisniku zloupotreba", "action-abusefilter-modify-restricted": "izmijeni filtere zloupotrebe sa ograničenim akcijama", "action-abusefilter-revert": "vrati sve izmjene po datom filteru zloupotrebe", "action-abusefilter-view-private": "pregledate filtere zloupotrebe koji su označeni kao lični", - "abusefilter-log": "Log filtera zloupotrebe", "abusefilter-log-summary": "Ovaj zapisnik prikazuje spisak svih akcija koje su zadržali filteri.", - "abusefilter-log-search": "Pretraži log zloupotrebe", + "abusefilter-log-search": "Pretraga zapisnika zloupotrebe", "abusefilter-log-search-user": "Korisnik:", "abusefilter-log-search-filter": "Filtriraj ID-ove (odvoji sa cijevima):", "abusefilter-log-search-title": "Naslov:", @@ -66,15 +67,15 @@ "abusefilter-log-details-var": "Varijabla (promjenjiva)", "abusefilter-log-details-val": "Vrijednost", "abusefilter-log-details-vars": "Parametri akcije", - "abusefilter-log-details-private": "Privatni podaci", + "abusefilter-log-details-privatedetails": "Privatni podaci", "abusefilter-log-details-ip": "Izvorna IP adresa", "abusefilter-log-noactions": "ništa", "abusefilter-log-details-diff": "Izmjene napravljene pri uređivanju", "abusefilter-log-linkoncontribs": "zapisnik zloupotrebe", "abusefilter-log-linkoncontribs-text": "Zapisnik zloupotrebe za {{GENDER:$1|ovog korisnika|ovu korisnicu}}", "abusefilter-log-linkonhistory": "prikaži zapisnik zloupotrebe", - "abusefilter-log-hidden": "(stavka sakrivena)", - "abusefilter-log-hidden-implicit": "(sakriveno jer je izmjena obrisana)", + "abusefilter-log-linkonhistory-text": "Pogledajte zapisnik zloupotrebe ove stranice", + "abusefilter-log-hidden-implicit": "(sakriveno jer je izmjena izbrisana)", "abusefilter-log-cannot-see-details": "Nemate dopuštenje da vidite detalje ovog unosa.", "abusefilter-log-details-hidden": "Možda nećete vidjeti detalje ove stavke, zato što je sakrivena za javni pregled.", "abusefilter-log-hide-legend": "Sakrij stavku zapisnika", @@ -83,7 +84,6 @@ "abusefilter-log-hide-reason": "Razlog:", "abusefilter-log-hide-forbidden": "Nemate dopuštenje da sakrivate stavke zapisnika zloupotrebe.", "logentry-abusefilter-hit": "$1 je {{GENDER:$2|aktivirao|aktivirala}} filter $4, izvodeći radnju \"$5\" na stranici $3. Poduzete radnje: $6 ($7)", - "abusefilter-management": "Upravljanje filterom protiv zloupotrebe", "abusefilter-list": "Svi filteri", "abusefilter-list-id": "ID filtera", "abusefilter-list-status": "Stanje", @@ -99,21 +99,24 @@ "abusefilter-hidden": "Privatno", "abusefilter-unhidden": "Javno", "abusefilter-enabled": "Uključen/a", - "abusefilter-deleted": "Obrisan/a", + "abusefilter-deleted": "Izbrisan", "abusefilter-disabled": "Isključeno", "abusefilter-hitcount": "$1 {{PLURAL:$1|pogodak|pogotka|pogodaka}}", "abusefilter-new": "Napravi novi filter", + "abusefilter-import-button": "Filter uvoza", "abusefilter-return": "Nazad na upravljanje filterima", "abusefilter-status-global": "Globalni", "abusefilter-list-options": "Opcije", - "abusefilter-list-options-deleted": "Obrisani filteri:", - "abusefilter-list-options-deleted-only": "Prikaži samo obrisane filtere", - "abusefilter-list-options-deleted-hide": "Sakrij obrisane filtere", - "abusefilter-list-options-deleted-show": "Pripoji i obrisane filtere", + "abusefilter-list-options-deleted": "Izbrisani filteri:", + "abusefilter-list-options-deleted-only": "Prikaži samo izbrisane filtere", + "abusefilter-list-options-deleted-hide": "Sakrij izbrisane filtere", + "abusefilter-list-options-deleted-show": "Uključi i izbrisane filtere", "abusefilter-list-options-scope": "Prikaži filtere:", "abusefilter-list-options-scope-local": "Samo lokalna pravila", "abusefilter-list-options-scope-global": "Samo globalna pravila", + "abusefilter-list-options-further-options": "Dodatne opcije:", "abusefilter-list-options-hidedisabled": "Sakrij isključene filtere", + "abusefilter-list-options-hideprivate": "Sakrij privatne filtere", "abusefilter-list-options-submit": "Ažuriraj", "abusefilter-tools-text": "Ovdje imate neke alate koji su korisni za formuliranje i prepravku filtera za zloupotrebu.", "abusefilter-tools-expr": "Tester širenja", @@ -131,7 +134,6 @@ "abusefilter-edit-oldwarning": "<strong>Mijenjate staru verziju ovog filtera.\nNavedene statistike odnose se na najnoviju verziju filtera.\nAko sačuvate izmjenu obrisat ćete sve izmjene napravljene od verzije koju uređujete.</strong> •\n[[Special:AbuseFilter/history/$2|Vrati se na historiju ovog filtera]]", "abusefilter-edit-status-label": "Statistike:", "abusefilter-edit-status": "Od {{PLURAL:$1|posljednje $1 akcije|posljednje $1 akcije|posljednjih $1 akcija}} ovaj filter je pogođen $2 puta ($3%).", - "abusefilter-edit-status-profile": "Od {{PLURAL:$1|posljednje $1 akcije|posljednje $1 akcije|posljednjih $1 akcija}} ovaj filter je pogođen $2 puta ($3%). Prosječno, njegovo vrijeme pokretanja je $4ms, a utrošio je $5 {{PLURAL:$5|uvjet|uvjeta}} unutar ograničenja uvjeta.", "abusefilter-edit-new": "Novi filter", "abusefilter-edit-save": "Sačuvaj filter", "abusefilter-edit-id": "ID filtera:", @@ -139,13 +141,13 @@ "abusefilter-edit-group": "Grupa filtera", "abusefilter-edit-flags": "Zastave:", "abusefilter-edit-enabled": "Uključi ovaj filter", - "abusefilter-edit-deleted": "Markiraj kao obrisano", + "abusefilter-edit-deleted": "Označi kao izbrisano", "abusefilter-edit-hidden": "Sakrij detalje ovog filter za javne preglede", "abusefilter-edit-global": "Globalni filter", "abusefilter-edit-rules": "Uslovi:", "abusefilter-edit-notes": "Note:", "abusefilter-edit-lastmod": "Filter posljednji put modificiran:", - "abusefilter-edit-lastmod-text": "$1 od strane $2", + "abusefilter-edit-lastmod-text": "$1; {{GENDER:$5|izmijenio|izmijenila}} $2", "abusefilter-edit-hitcount": "Pogotci filtera:", "abusefilter-edit-consequences": "Radnje koje se poduzimaju pri slaganju", "abusefilter-edit-action-warn": "Pokreću se ove akcije nakon upozorenja korisniku", @@ -168,7 +170,7 @@ "abusefilter-edit-tag-tag": "[[Special:Tags|Oznake]] za primjenu (jedna po redu):", "abusefilter-edit-denied": "Možda nećete vidjeti detalje ovog filtera, zato što su sakriveni za javni pregled.", "abusefilter-edit-main": "Parametri filtera", - "abusefilter-edit-done-subtitle": "Filter izmjenjen", + "abusefilter-edit-done-subtitle": "Filter je izmijenjen", "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Vaše izmjene]] na [[Special:AbuseFilter/$1|filteru $3]] su sačuvane.", "abusefilter-edit-badsyntax": "Sintaksna greška u filteru koji ste označili. Posljednji izgled gramatičke definicije bio je:\n<pre>$1</pre>", "abusefilter-edit-restricted": "Ne možete uređivati ovaj filter, jer on sadrži jednu ili više ograničenih akcija.\nZamolite korisnika sa dopuštenjima za dodavanje ograničenih akcija da napravi izmjene umjesto Vas.", @@ -268,16 +270,16 @@ "abusefilter-edit-builder-vars-all-links": "Svi linkovi kao tekst nove stranice", "abusefilter-edit-builder-vars-added-links": "Linkovi dodani na stranicu", "abusefilter-edit-builder-vars-removed-links": "Linkovi uklonjeni sa stranice", - "abusefilter-edit-builder-vars-old-text": "Stari wikitekst stranice, prije uređivanja", - "abusefilter-edit-builder-vars-new-text": "Nova stranica wikiteksta, nakon uređivanja", + "abusefilter-edit-builder-vars-old-wikitext": "Stari wikitekst stranice, prije uređivanja", + "abusefilter-edit-builder-vars-new-wikitext": "Nova stranica wikiteksta, nakon uređivanja", "abusefilter-edit-builder-vars-new-pst": "Novi wikitekst stranice, prilagođeno za sačuvanje", - "abusefilter-edit-builder-vars-new-text-stripped": "Tekst nove stranice, bez ikakvih obilježavanja", + "abusefilter-edit-builder-vars-new-text": "Tekst nove stranice, bez ikakvih obilježavanja", "abusefilter-edit-builder-vars-new-html": "Parsirani HTML izvor nove izmjene", "abusefilter-edit-builder-vars-restrictions-edit": "Uredi nivo zaštite stranice", "abusefilter-edit-builder-vars-restrictions-move": "Premjesti nivo zaštite stranice", "abusefilter-edit-builder-vars-restrictions-create": "Zaštita za pravljenje stranice", "abusefilter-edit-builder-vars-restrictions-upload": "Zaštita za postavljanje datoteke", - "abusefilter-edit-builder-vars-old-text-stripped": "Tekst sa stare stranice, uklonjene sve oznake", + "abusefilter-edit-builder-vars-old-text": "Tekst sa stare stranice, uklonjene sve oznake", "abusefilter-edit-builder-vars-old-links": "Linkovi na stranici, prije uređivanja", "abusefilter-edit-builder-vars-old-html": "Wikitekst stare stranice, parsiran u HTML", "abusefilter-edit-builder-vars-minor-edit": "Da li je izmjena označena kao mala ili ne", @@ -296,7 +298,7 @@ "abusefilter-history-comments": "Komentari", "abusefilter-history-actions": "Akcije", "abusefilter-history-backedit": "Vrati se stranici za izmjenu filtera", - "abusefilter-history-deleted": "Obrisano", + "abusefilter-history-deleted": "Izbrisan", "abusefilter-history-filterid": "Filter", "abusefilter-history-select-legend": "Pročisti pretragu", "abusefilter-history-select-user": "Korisnik:", @@ -333,7 +335,7 @@ "abusefilter-revert-periodstart": "Početak perioda:", "abusefilter-revert-periodend": "Kraj perioda:", "abusefilter-revert-search": "Odaberi akcije", - "abusefilter-revert-filter": "Filter:", + "abusefilter-revert-filter": "ID filtera:", "abusefilter-revert-preview-intro": "Ispod su prikazane akcije koje je poduzeo filter zloupotreba koje će se vratiti putem ove akcije.\nMolimo da ih pažljivo provjerite, te kliknete \"{{int:abusefilter-revert-confirm}}\" da potvrdite Vaš odabir.", "abusefilter-revert-confirm": "Potvrdi", "abusefilter-revert-success": "Vratili ste sve akcije koje je poduzeo filter zloupotreba zbog [[Special:AbuseFilter/$1|filtera $2]].", @@ -374,7 +376,6 @@ "abusefilter-topnav-examine": "Ispitaj prošle izmjene", "abusefilter-topnav-log": "Zapisnik zloupotrebe", "abusefilter-topnav-tools": "Alati za debugiranje", - "abusefilter-topnav-import": "Filter uvoza", "abusefilter-log-name": "Zapisnik filtera zloupotrebe", "abusefilter-log-header": "Ovaj zapisnik prikazuje sažetak izmjena napravljenih na filterima.\nZa sve detalje, pogledajte [[Special:AbuseFilter/history|spisak]] nedavnih izmjena filtera.", "abusefilter-logentry-modify": "$1 {{GENDER:$2|izmijenio|izmijenila}} je $4 ($5)", diff --git a/AbuseFilter/i18n/ca.json b/AbuseFilter/i18n/ca.json index 818926ca..395d045e 100644 --- a/AbuseFilter/i18n/ca.json +++ b/AbuseFilter/i18n/ca.json @@ -6,8 +6,14 @@ "Arnaugir", "Ciencia Al Poder", "El libre", + "Fitoschido", "Gemmaa", + "Jaumeortola", + "Jmarchn", "Loupeter", + "Macofe", + "Matma Rex", + "Mguix", "Papapep", "Paucabot", "Pintor Smeargle", @@ -17,33 +23,29 @@ "Sociologist", "Solde", "Ssola", - "Vriullop", - "Fitoschido", - "Jmarchn", "Toniher", - "Macofe", - "Jaumeortola", - "Matma Rex" + "Townie", + "Vriullop" ] }, "abusefilter-desc": "Aplica heurística automàtica a les edicions", - "abusefilter": "Configuració del filtre d’abusos", - "abuselog": "Registre del filtre d’abusos", + "abusefilter": "Gestió del filtre antiabusos", + "abuselog": "Registre del filtre antiabusos", "abusefilter-intro": "Benvinguts a la interfície de gestió del filtre d'abusos.\nAquest filtre és un mecanisme del programari per aplicar heurística automàtica a totes les accions.\nAquesta interfície mostra una llista dels filtres definits i permet modificar-los.", "abusefilter-warning": "'''Atenció:''' Aquesta acció ha estat identificada automàticament com a perniciosa.\nLes edicions no constructives seran revertides ràpidament,\ni la reiterada edició de forma no constructiva comportarà el blocatge del vostre compte o adreça IP.\nSi creieu que aquesta acció és constructiva, podeu tornar-la a enviar per a confirmar-la.\nUna breu descripció de la regla d'abús que ha identificat la vostra acció és: $1", "abusefilter-disallowed": "Aquesta acció ha estat automàticament identificada com a nociva i per tant rebutjada.\nSi creieu que la vostra acció era constructiva, si us plau informeu un administrador de què estàveu intentant fer.\nUna breu descripció de la regla d'abús amb què coincidia la vostra acció és: $1", "abusefilter-blocked-display": "Aquesta acció s'ha identificat automàticament com perjudicials\n i li ha impedit executar-lo.\nA més a més, per protegir {{SITENAME}}, el seu compte d'usuari i tots associats adreces d'IP s'han blocat des d'edició.\nSi això s'ha produït en l'error, si us plau en contacte amb un administrador.\nUna breu descripció de la regla de l'abús que coincidien amb la seva acció és:$1", "abusefilter-degrouped": "Aquesta acció s'ha identificat automàticament com a perillosa.\nTenim sospites que el vostre compte ha estat compromès i hem revocat tots els vostres drets.\nSi creieu que això és un error, contacteu amb un buròcrata amb una explicació d'aquesta acció i es podrien restablir els vostres drets.\nUna breu descripció de la regla de l'abús que coincidien amb la vostra acció és: $1", "abusefilter-autopromote-blocked": "Aquesta acció s'ha identificat automàticament com perjudicial, i ha estat deshabilitat.\nA més a més, com a mesura de seguretat, alguns privilegis concedits habitualment per establir comptes han estat revocats temporalment del seu compte.\nUna breu descripció de la regla de l'abús que coincidien amb la seva acció és:$1", - "abusefilter-blocker": "Filtre d’abusos", + "abusefilter-blocker": "Filtre antiabusos", "abusefilter-blockreason": "Blocat automàticament pel filtre d'abús.\nDescripció de la regla aplicada: $1", "abusefilter-degroupreason": "Drets retirats automàticament pel filtre d'abús.\nDescripció de la regla: $1", "abusefilter-accountreserved": "Aquest compte està reservat per al seu ús pel filtre d'abús.", - "right-abusefilter-modify": "Modificar els filtres d'abús", + "right-abusefilter-modify": "Crear o modificar filtres antiabusos", "right-abusefilter-view": "Veure filtres d'abús", "right-abusefilter-log": "Veure el registre d'abusos", "right-abusefilter-log-detail": "Veure entrades detallades del registre d'abusos", - "right-abusefilter-private": "Veure dades privades al registre d'abusos", + "right-abusefilter-privatedetails": "Veure dades privades al registre d'abusos", "right-abusefilter-modify-restricted": "Modificar els filtres d'abús amb accions restringides", "right-abusefilter-revert": "Revertir totes les modificacions efectuades per un filtre d'abús concret", "right-abusefilter-view-private": "Veure filtres d'abús marcats com a privats", @@ -55,17 +57,31 @@ "action-abusefilter-view": "Veure filtres d'abús", "action-abusefilter-log": "veure el registre d'abusos", "action-abusefilter-log-detail": "veure entrades detallades del registre d'abusos", - "action-abusefilter-private": "veure dades privades al registre d'abusos", + "action-abusefilter-privatedetails": "veure dades privades al registre d'abusos", "action-abusefilter-modify-restricted": "modifica els filtres d'abús amb accions restringides", "action-abusefilter-revert": "reverteix tots els canvis d'un filtre d'abús donat", "action-abusefilter-view-private": "veure filtres d'abús marcats com a privats", - "abusefilter-log": "Registre del filtre d’abusos", "abusefilter-log-summary": "Aquest registre mostra una llista de totes les accions detectades pels filtres.", "abusefilter-log-search": "Cerca al registre d'abusos", "abusefilter-log-search-user": "Usuari:", - "abusefilter-log-search-filter": "Identificadors de filtres (separats amb barres verticals):", + "abusefilter-log-search-group": "Grup de filtre:", + "abusefilter-log-search-group-any": "Qualsevol", + "abusefilter-log-search-filter": "Identificadors de filtres:", "abusefilter-log-search-title": "Títol:", "abusefilter-log-search-wiki": "Wiki:", + "abusefilter-log-search-impact": "Impacte:", + "abusefilter-log-search-impact-all": "Totes les accions", + "abusefilter-log-search-impact-saved": "Només els canvis desats", + "abusefilter-log-search-impact-not-saved": "Sense canvis desats", + "abusefilter-log-search-entries-label": "Visibilitat:", + "abusefilter-log-search-entries-all": "Totes les entrades", + "abusefilter-log-search-entries-hidden": "Només les entrades amagades", + "abusefilter-log-search-entries-visible": "Només les entrades visibles", + "abusefilter-log-search-action-label": "Acció disparadora:", + "abusefilter-log-search-action-other": "Una altra", + "abusefilter-log-search-action-any": "Qualsevol", + "abusefilter-log-search-action-taken-label": "Acció adoptada:", + "abusefilter-log-search-action-taken-any": "Qualsevol", "abusefilter-log-search-submit": "Cerca", "abusefilter-log-entry": "$1: $2 {{GENDER:$8|ha disparat}} un filtre d'abusos {{GENDER:$8|durant}} l'acció «$3» a $4.\nAccions preses: $5;\nDescripció del filtre: $6", "abusefilter-log-detailedentry-meta": "$1: $2 {{GENDER:$9|ha disparat}} el $3 {{GENDER:$9|durant}} l'acció «$4» a $5.\nAccions preses: $6;\nDescripció del filtre: $7 ($8)", @@ -78,27 +94,32 @@ "abusefilter-log-details-var": "Variable", "abusefilter-log-details-val": "Valor", "abusefilter-log-details-vars": "Paràmetres de l'acció", - "abusefilter-log-details-private": "Dades privades", + "abusefilter-log-details-privatedetails": "Detalls del registre privat", "abusefilter-log-details-ip": "Adreça IP d'origen", + "abusefilter-log-details-checkuser": "Verifica l'usuari", "abusefilter-log-noactions": "cap", + "abusefilter-log-noactions-filter": "Cap", "abusefilter-log-details-diff": "Canvis fets en l'edició", "abusefilter-log-linkoncontribs": "registre d'abusos", "abusefilter-log-linkoncontribs-text": "Registre d'abusos d'{{GENDER:$1|aquest usuari|aquesta usuària}}", - "abusefilter-log-hidden": "(entrada amagada)", "abusefilter-log-hidden-implicit": "(ocult perquè s'ha suprimit la revisió)", "abusefilter-log-cannot-see-details": "No tens permisos per veure els detalls d'aquesta entrada.", - "abusefilter-log-details-hidden": "No podeu veure els detalls d’aquesta entrada ja que està restringit el seu accés públic.", + "abusefilter-log-cannot-see-privatedetails": "No tens permís per a veure detalls privats d'aquesta entrada.", + "abusefilter-log-details-hidden": "No podeu veure els detalls d’aquesta entrada ja que n’està restringit l’accés públic.", + "abusefilter-log-details-hidden-implicit": "No podeu veure els detalls d'aquesta entrada perquè la seva revisió associada està oculta a la vista pública.", + "abusefilter-log-private-not-included": "Una o més de les identificacions de filtre que va especificar són privades. A causa de que no se't permet veure els detalls dels filtres privats, no s'han buscat aquests filtres.", "abusefilter-log-hide-legend": "Amaga entrada de registre", "abusefilter-log-hide-id": "ID de l'entrada de registre:", "abusefilter-log-hide-hidden": "Amaga aquesta entrada de la vista pública", "abusefilter-log-hide-reason": "Motiu:", + "abusefilter-log-hide-reason-other": "Motiu diferent o addicional:", "abusefilter-log-hide-forbidden": "No teniu permisos per ocultar entrades al registre d'abusos.", "log-action-filter-abusefilter": "Tipus de canvi de filtre:", "log-action-filter-abusefilter-create": "Creació d’un filtre nou", "log-action-filter-abusefilter-modify": "Modificació de filtre", - "abusefilter-management": "Gestió del filtre d’abusos", "abusefilter-list": "Tots els filtres", "abusefilter-list-id": "Núm.", + "abusefilter-list-pattern": "Patró", "abusefilter-list-status": "Estat", "abusefilter-list-public": "Descripció pública", "abusefilter-list-consequences": "Conseqüències", @@ -116,6 +137,7 @@ "abusefilter-disabled": "Deshabilitat", "abusefilter-hitcount": "$1 vegad{{PLURAL:$1|a|es}}", "abusefilter-new": "Creau un nou filtre", + "abusefilter-import-button": "Importa un filtre", "abusefilter-return": "Torna a la gestió del filtre", "abusefilter-status-global": "Global", "abusefilter-list-options": "Opcions", @@ -126,30 +148,40 @@ "abusefilter-list-options-scope": "Mostra els filtres:", "abusefilter-list-options-scope-local": "Només normes locals", "abusefilter-list-options-scope-global": "Només normes globals", + "abusefilter-list-options-further-options": "Altres opcions:", "abusefilter-list-options-hidedisabled": "Oculta filtres deshabilitats", "abusefilter-list-options-hideprivate": "Amaga els filtres privats", + "abusefilter-list-options-searchpattern": "Insereix un patró", "abusefilter-list-options-searchoptions": "Mode de cerca:", + "abusefilter-list-options-search-like": "Consulta simple", + "abusefilter-list-options-search-rlike": "Expressió regular", + "abusefilter-list-options-search-irlike": "Expressió regular que no distingeix majúscules", + "abusefilter-list-invalid-searchmode": "El mode de cerca especificat no és vàlid.", + "abusefilter-list-regexerror": "S’ha produït un problema en cercar: hi ha un error de sintaxi a l’expressió regular.", "abusefilter-list-options-submit": "Actualitza", "abusefilter-tools-text": "Aquí hi ha algunes eines que poden ser útils en la formulació i depuració dels filtres d'abusos.", "abusefilter-tools-expr": "Provador d'expressions", "abusefilter-tools-submitexpr": "Avalua", + "abusefilter-tools-syntax-error": "La sintaxi del filtre no és vàlida.", "abusefilter-tools-reautoconfirm": "Restaura l'estat autoconfirmat", "abusefilter-tools-reautoconfirm-user": "Usuari:", "abusefilter-tools-reautoconfirm-submit": "Reautoconfirma", "abusefilter-reautoconfirm-none": "Que l'usuari no ha tingut {{GENDER:$1| his|her|their}} autoconfirmed estat suspès.", "abusefilter-reautoconfirm-notallowed": "No estàs autoritzat/da a recuperar un estat autoconfirmat.", "abusefilter-reautoconfirm-done": "S'ha restaurat l'estat de compte autoconfirmat", - "abusefilter-status": "De {{PLURAL:$1|la darrera acció|les darreres $1 accions}}, $2 ($3%) ha{{PLURAL:$2||n}} sobrepassat el límit de $4 condicions autoritzades, i $5 ($6%) ha{{PLURAL:$5||n}} disparat algun dels filtres actualment activats.", - "abusefilter-edit": "Edició del filtre d’abusos", + "abusefilter-status": "De {{PLURAL:$1|la darrera acció|les darreres $1 accions}}, $2 ($3%) ha{{PLURAL:$2||n}} sobrepassat el límit de $4 condicions autoritzades, i $5 ($6%) ha{{PLURAL:$5||n}} ajustat a algun dels filtres actualment activats.", + "abusefilter-edit": "Edició del filtre antiabusos", "abusefilter-edit-subtitle": "Edició del filtre $1", "abusefilter-edit-subtitle-new": "Creació d’un filtre", + "abusefilter-edit-token-not-match": "No s'ha desat la modificació. Torneu a desar-la.", "abusefilter-edit-oldwarning": "<strong>Esteu editant una versió vella d'aquest filtre.\nLes estadístiques indicades són de la versió més recent del filtre.\nSi deseu els vostres canvis, revertireu tots els canvis posteriors a aquesta versió.</strong> •\n[[Special:AbuseFilter/history/$2|Torna a l'historial d'aquest filtre]].", + "abusefilter-edit-oldwarning-view": "<strong>Estàs veient una versió antiga d'aquest filtre.\nLes estadístiques citades són de la versió més recent de l'filtre.</strong> •\n[[Special:AbuseFilter/history/$2|Torna a l'historial d'aquest filtre]].", "abusefilter-edit-status-label": "Estadístiques:", - "abusefilter-edit-status": "De {{PLURAL:$1|la darrera acció|les $1 darreres accions}} aquest filtre n'ha detectat $2 ($3%).", - "abusefilter-edit-status-profile": "De {{PLURAL:$1|la darrera acció|les $1 darreres accions}} aquest filtre n'ha detectat $2 ($3%).\nDe mitjana, la seva durada d'execució és de $4 ms i utilitza $5 {{PLURAL:$5|condició|condicions}} del límit total.", + "abusefilter-edit-status": "Des de {{PLURAL:$1|la darrera acció|les darreres accions}} aquest filtre n'ha detectat $2 ($3%).\nDe promedi, el seu temps d'execució és de $4 ms, i consumeix $5 {{PLURAL:$5| condició | condicions}} del límit de la condició.", "abusefilter-edit-new": "Nou filtre", "abusefilter-edit-save": "Desa filtre", "abusefilter-edit-id": "Núm. del filtre:", + "abusefilter-edit-switch-editor": "Canvia l'editor", "abusefilter-edit-description": "Descripció:\n:''(visible públicament)''", "abusefilter-edit-field-description": "descripció", "abusefilter-edit-group": "Grup del filtre:", @@ -171,23 +203,43 @@ "abusefilter-edit-action-degroup": "Retira l'usuari/a de tots els grups de privilegis", "abusefilter-edit-action-block": "Bloca les edicions de l'usuari o adreça IP", "abusefilter-edit-action-throttle": "Desencadena les accions només si l'usuari sobrepassa un límit de reiteracions", - "abusefilter-edit-action-rangeblock": "Bloca el rang /16 que origina l'usuari", + "abusefilter-edit-action-rangeblock": "Bloca l’interval d’IP respectiu del que origina l’usuari", "abusefilter-edit-action-tag": "Marca l'edició per a una revisió posterior", "abusefilter-edit-throttle-count": "Nombre d'accions a permetre:", - "abusefilter-edit-throttle-period": "Període de temps:", - "abusefilter-edit-throttle-groups": "Agrupar la reiteració per:\n:''(un per línia, separat per comes)''", + "abusefilter-edit-throttle-period": "Període de temps (en segons):", + "abusefilter-edit-throttle-groups": "Agrupar la reiteració per:", + "abusefilter-throttle-ip": "Adreça IP", + "abusefilter-throttle-user": "compte d’usuari", + "abusefilter-throttle-range": "interval /16", + "abusefilter-throttle-creationdate": "data de creació del compte", + "abusefilter-throttle-editcount": "recompte d’edicions", + "abusefilter-throttle-site": "tot el lloc web", + "abusefilter-throttle-page": "pàgina", + "abusefilter-throttle-none": "(cap)", "abusefilter-edit-warn-message": "Missatge del sistema a usar com a avís:", "abusefilter-edit-warn-other": "Un altre missatge", "abusefilter-edit-warn-other-label": "Nom de la pàgina de l’altre missatge:\n:''(sense el prefix «MediaWiki»)''", "abusefilter-edit-warn-actions": "Accions:", - "abusefilter-edit-warn-preview": "Previsualitza el missatge seleccionat", + "abusefilter-edit-warn-preview": "Mostra/amaga la previsualització del missatge seleccionat", "abusefilter-edit-warn-edit": "Crea o modifica el missatge seleccionat", - "abusefilter-edit-tag-tag": "[[Special:Tags|Etiquetes]] a aplicar (una per línia):", - "abusefilter-edit-denied": "No podeu veure els detalls d’aquest filtre ja que està restringit el seu accés públic.", + "abusefilter-edit-disallow-other": "Un altre missatge", + "abusefilter-edit-disallow-actions": "Accions:", + "abusefilter-edit-disallow-preview": "Mostra/amaga la previsualització del missatge seleccionat", + "abusefilter-edit-disallow-edit": "Crea/modifica el missatge seleccionat", + "abusefilter-edit-tag-tag": "[[Special:Tags|Etiquetes]] a aplicar:", + "abusefilter-edit-tag-placeholder": "Afegeix etiquetes (una per una o separades per comes)", + "abusefilter-edit-tag-hidden-placeholder": "Afegeix etiquetes (separades per comes)", + "abusefilter-edit-block-anon-durations": "Durada del blocatge per a usuaris anònims:", + "abusefilter-edit-block-user-durations": "Durada del blocatge per a usuaris registrats:", + "abusefilter-block-anon": "Bloca els usuaris anònims", + "abusefilter-block-talk": "pàgina de discussió blocada", + "abusefilter-edit-denied": "No podeu veure els detalls d’aquest filtre ja que n’està restringit l’accés públic.", "abusefilter-edit-main": "Paràmetres de filtre", "abusefilter-edit-done-subtitle": "Filtre editat", "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Els vostres canvis]] al [[Special:AbuseFilter/$1|filtre $3]] s'han desat correctament.", "abusefilter-edit-badsyntax": "Hi ha un error de sintaxi en el filtre que heu especificat.\nLa producció de l'analitzador era:<pre>$1</pre>", + "abusefilter-edit-missingfields": "Els camps següents són necessaris i cal omplir-los: $1", + "abusefilter-edit-deleting-enabled": "No podeu marcar un filtre actiu com a eliminat.", "abusefilter-edit-restricted": "No podeu modificar aquest filtre perquè conté una o més accions restringides.\nDemaneu a un usuari amb permís per a afegir accions restringides que faci el canvi.", "abusefilter-edit-viewhistory": "Mostra l'historial d'aquest filtre", "abusefilter-edit-history": "Historial:", @@ -202,6 +254,7 @@ "abusefilter-edit-bad-tags": "Una o més de les etiquetes que heu especificat no és vàlida.\nLes etiquetes han de ser curtes, no han de contenir caràcters especials i no han d'estar reservades per un altre programa. Proveu-ho amb un altre nom.", "abusefilter-edit-notallowed": "No teniu permisos per crear o modificar filtres d'abusos", "abusefilter-edit-notallowed-global": "No teniu permís per crear o editar els filtres d’abusos globals", + "abusefilter-edit-invalid-warn-message": "No es pot deixar el missatge d'avís en blanc.", "abusefilter-edit-builder-select": "Seleccionau una opció per afegir-la al cursor", "abusefilter-edit-builder-group-op-arithmetic": "Operadors aritmètics", "abusefilter-edit-builder-op-arithmetic-addition": "Suma (+)", @@ -211,8 +264,10 @@ "abusefilter-edit-builder-op-arithmetic-modulo": "Mòdul (%)", "abusefilter-edit-builder-op-arithmetic-pow": "Potència (**)", "abusefilter-edit-builder-group-op-comparison": "Operadors de comparació", - "abusefilter-edit-builder-op-comparison-equal": "Igual a (==)", - "abusefilter-edit-builder-op-comparison-notequal": "Diferent a (!=)", + "abusefilter-edit-builder-op-comparison-equal": "Valor igual a (==)", + "abusefilter-edit-builder-op-comparison-equal-strict": "Valor i tipus igual a (===)", + "abusefilter-edit-builder-op-comparison-notequal": "Valor no igual a (!=)", + "abusefilter-edit-builder-op-comparison-notequal-strict": "Valor i tipus no igual a (!==)", "abusefilter-edit-builder-op-comparison-lt": "Menor que (<)", "abusefilter-edit-builder-op-comparison-gt": "Major que (>)", "abusefilter-edit-builder-op-comparison-lte": "Menor o igual que (<=)", @@ -229,7 +284,7 @@ "abusefilter-edit-builder-misc-contains": "La cadena de l'esquerra conté la cadena de la dreta (contains)", "abusefilter-edit-builder-misc-stringlit": "Cadena literal (\"\")", "abusefilter-edit-builder-misc-tern": "Operador ternari (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Condicional (si X llavors Y sinó Z)", + "abusefilter-edit-builder-misc-cond": "Condicional (if X then Y else Z end)", "abusefilter-edit-builder-group-funcs": "Funcions", "abusefilter-edit-builder-funcs-length": "Longitud de la cadena (length)", "abusefilter-edit-builder-funcs-lcase": "A minúscules (lcase)", @@ -243,7 +298,7 @@ "abusefilter-edit-builder-funcs-rmwhitespace": "Elimina els espais en blanc (rmwhitespace)", "abusefilter-edit-builder-funcs-rmspecials": "Suprimeix els caràcters especials (rmspecials)", "abusefilter-edit-builder-funcs-ip_in_range": "Està la IP dins l’interval? (ip_in_range)", - "abusefilter-edit-builder-funcs-contains-any": "Cerca Cadena per a subcadenes múltiples (contains_any)", + "abusefilter-edit-builder-funcs-contains-any": "Cerca una cadena per a subcadenes múltiples en mode OR. (contains_any)", "abusefilter-edit-builder-funcs-substr": "Subcadena (substr)", "abusefilter-edit-builder-funcs-strpos": "Posició de la subcadena a la cadena (strpos)", "abusefilter-edit-builder-funcs-str_replace": "Reemplaçar subcadena per cadena (str_replace)", @@ -254,9 +309,11 @@ "abusefilter-edit-builder-vars-action": "Acció", "abusefilter-edit-builder-vars-addedlines": "Línies afegides en l'edició", "abusefilter-edit-builder-vars-delta": "Canvi de mida en l'edició", - "abusefilter-edit-builder-vars-diff": "Dif. unificat dels canvis fets en l'edició", + "abusefilter-edit-builder-vars-diff": "Diferències unificades dels canvis fets en l’edició", "abusefilter-edit-builder-vars-newsize": "Mida nova de la pàgina", "abusefilter-edit-builder-vars-oldsize": "Mida anterior de la pàgina", + "abusefilter-edit-builder-vars-old-content-model": "Model de contingut anterior", + "abusefilter-edit-builder-vars-new-content-model": "Model de contingut nou", "abusefilter-edit-builder-vars-removedlines": "Línies eliminades en la modificació", "abusefilter-edit-builder-vars-summary": "Resum de l'edició", "abusefilter-edit-builder-vars-page-id": "ID de la pàgina", @@ -282,19 +339,24 @@ "abusefilter-edit-builder-vars-all-links": "Tots els enllaços externs al nou text", "abusefilter-edit-builder-vars-added-links": "Tots els enllaços externs afegits en l'edició", "abusefilter-edit-builder-vars-removed-links": "Tots els enllaços externs esborrats en l'edició", - "abusefilter-edit-builder-vars-old-text": "Text anterior de la pàgina, abans de l'edició", - "abusefilter-edit-builder-vars-new-text": "Nou text de la pàgina, després de l'edició", - "abusefilter-edit-builder-vars-new-text-stripped": "Nova pàgina de text, sense cap format", + "abusefilter-edit-builder-vars-old-wikitext": "Wikitext de l'antiga pàgina, abans de la modificació", + "abusefilter-edit-builder-vars-new-wikitext": "Nova pàgina wikitext, després de l'edició", + "abusefilter-edit-builder-vars-new-text": "Nova pàgina de text, sense cap format", "abusefilter-edit-builder-vars-new-html": "Font HTML analitzada de la nova revisió", "abusefilter-edit-builder-vars-restrictions-edit": "Nivell de protecció per a edicions de la pàgina", "abusefilter-edit-builder-vars-restrictions-move": "Nivell de protecció per a reanomenaments de la pàgina", "abusefilter-edit-builder-vars-restrictions-create": "Nivell de protecció per a la creació de la pàgina", "abusefilter-edit-builder-vars-restrictions-upload": "Nivell de protecció per carregar un fitxer", - "abusefilter-edit-builder-vars-old-text-stripped": "Antiga pàgina de text, sense qualsevol format", + "abusefilter-edit-builder-vars-old-text": "Wikitext anterior de la pàgina, sense cap format (ja no s'utilitza)", "abusefilter-edit-builder-vars-old-links": "Enllaços a la pàgina, abans de l'edició", - "abusefilter-edit-builder-vars-old-html": "Antiga pàgina de wikitext, passada a HTML", - "abusefilter-edit-builder-vars-minor-edit": "Si l'edició s'ha marcat com a menor o no", + "abusefilter-edit-builder-vars-old-html": "Antiga pàgina de wikitext, passada a HTML (ja no es fa servir)", + "abusefilter-edit-builder-vars-minor-edit": "Si l'edició es marca com a menor o no (ja no es fa servir)", "abusefilter-edit-builder-vars-file-sha1": "Identificació SHA1 dels continguts de l'arxiu", + "abusefilter-edit-builder-vars-file-size": "Mida del fitxer en bytes", + "abusefilter-edit-builder-vars-file-mime": "Tipus MIME del fitxer", + "abusefilter-edit-builder-vars-file-mediatype": "Tipus de mitjà del fitxer", + "abusefilter-edit-builder-vars-file-width": "Amplada del fitxer en píxels", + "abusefilter-edit-builder-vars-file-height": "Alçària del fitxer en píxels", "abusefilter-filter-log": "Canvis recents als filtres", "abusefilter-history": "Historial de les modificacions del filtre d'abusos #$1", "abusefilter-history-foruser": "Canvis per $1", @@ -315,7 +377,7 @@ "abusefilter-history-select-user": "Usuari:", "abusefilter-history-select-submit": "Afina", "abusefilter-history-diff": "Canvis", - "abusefilter-history-error-hidden": "El filtre que heu demanat s’ha amagat, i no podeu veure’n l’historial.", + "abusefilter-history-error-hidden": "El filtre que heu demanat s'ha amagat, i no podeu veure'n l'historial.", "abusefilter-exception-unexpectedatend": "Inesperat \"$2\" al caràcter $1.", "abusefilter-exception-expectednotfound": "S'esperava un $2 a les de caràcter $1 , que no es troba (s'ha trobat $3 $4 en el seu lloc).", "abusefilter-exception-unrecognisedkeyword": "Paraula clau no reconeguda $2 al caràcter $1 .", @@ -323,15 +385,16 @@ "abusefilter-exception-unclosedstring": "Cadena no tancada que comença al caràcter $1.", "abusefilter-exception-invalidoperator": "Operador no vàlid \"$2\" al caràcter $1.", "abusefilter-exception-unrecognisedtoken": "No es reconeix el símbol \"$2\" al caràcter $1.", - "abusefilter-exception-noparams": "No hi ha paràmetres donats a la funció \"$2\" al caràcter $1.", + "abusefilter-exception-noparams": "No es va proporcionar cap paràmetre en la funció \"$2\" en el caràcter $1.\nS' {{PLURAL:$3|esperava $3 argument|esperaven $3 arguments}}.", "abusefilter-exception-dividebyzero": "Intent il·legal per dividir $2 per zero al caràcter $1.", "abusefilter-exception-unrecognisedvar": "Variable no reconeguda $2 al caràcter $1", "abusefilter-exception-notenoughargs": "No hi ha prou arguments per funcionar $2 anomenat a caràcter $1 .\n\tEspera que $3 {{PLURAL:$3| argument|arguments}}, got $4", - "abusefilter-exception-regexfailure": "Error en l'expressió regular \"$3\" al caràcter $1: \"$2\"", - "abusefilter-exception-overridebuiltin": "Anul·lació incorrecta de la variable incorporada «$2» al caràcter $1.", - "abusefilter-exception-outofbounds": "S'està sol·licitant l'element inexistent llista $2 (llista de mida = $3 ) a les de caràcter $1 .", + "abusefilter-exception-regexfailure": "Error en l’expressió regular «$2» al caràcter $1.", + "abusefilter-exception-overridebuiltin": "Anul·lació incorrecta de la identificació incorporada «$2» al caràcter $1.", + "abusefilter-exception-outofbounds": "Sol·licitant un article $2 inexistent de la matriu (grandària de la matriu = $3) al caràcter $1.", "abusefilter-exception-notarray": "Sol. licitant element de matriu de no-matriu a caràcter $1 .", "abusefilter-exception-invalidiprange": "S’ha proporcionat l’interval d’IP no vàlid «$2» al caràcter $1.", + "abusefilter-exception-disabledvar": "Ja no es fa servir la variable $2 al caràcter $1.", "abusefilter-action-tag": "Etiqueta", "abusefilter-action-throttle": "Limitador", "abusefilter-action-warn": "Avisa", @@ -339,16 +402,17 @@ "abusefilter-action-block": "Bloca", "abusefilter-action-degroup": "Elimina dels grups", "abusefilter-action-rangeblock": "Interval del blocatge", - "abusefilter-action-disallow": "No permetre", + "abusefilter-action-disallow": "No ho permetis", "abusefilter-revert-title": "Reverteix tots els canvis fets pel filtre $1", "abusefilter-revert-intro": "Aquest formulari permet vostè tornar tots els canvis realitzats pel filtre d'abús a causa de filtre de $1 .\nSi us plau, l'exercici cura en l'ús d'aquesta eina.", - "abusefilter-revert-preview-item": "$1: $2 made a $3 on $4.\nAccions de ser tornat: $5 ( $6 )", + "abusefilter-revert-preview-item": "$1 : $2 {{GENDER:$7|fet}} a $3 en $4.\nAccions a revocar : $5 ($6)", "abusefilter-revert-search-legend": "Selecciona les accions del filtre d'abusos per revertir", "abusefilter-revert-periodstart": "Inici del període:", "abusefilter-revert-periodend": "Fi del període:", "abusefilter-revert-search": "Seleccionau les accions", - "abusefilter-revert-filter": "Filtre:", + "abusefilter-revert-filter": "ID del filtre:", "abusefilter-revert-preview-intro": "A continuació es presenten les mesures adoptades pel filtre d'abús que es revertiran amb aquesta acció.\nComproveu-les amb cura i feu clic a \"{{int:abusefilter-revert-confirm}}\" per a confirmar la vostra selecció.", + "abusefilter-revert-confirm-legend": "Confirma la reversió", "abusefilter-revert-confirm": "Confirma", "abusefilter-revert-success": "Heu revertit totes les accions del filtre d'abusos generades pel [[Special:AbuseFilter/$1|filtre $2]].", "abusefilter-revert-reason": "Automatic tornar de totes les mesures adoptades pel filtre d'abús a causa de filtre de $1 .\nMotiu donat:$2", @@ -360,12 +424,20 @@ "abusefilter-test-submit": "Prova", "abusefilter-test-load": "Carrega", "abusefilter-test-user": "Canvis per usuari:", + "abusefilter-test-nobots": "Amaga les edicions de robots", "abusefilter-test-period-start": "Canvis fets després de:", "abusefilter-test-period-end": "Canvis fets abans de:", "abusefilter-test-page": "Canvis fets a la pàgina:", "abusefilter-test-shownegative": "Mostra els canvis que no coincideixen amb el filtre", "abusefilter-test-syntaxerr": "El filtre que heu escrit conté un error de sintaxi.\nVostè pot rebre una explicació completa fent clic al botó de \"{{int:abusefilter-edit-check}}\".", "abusefilter-test-badtitle": "El títol de la pàgina que heu introduït no era vàlid. Pot contenir un o més caràcters que no es poden utilitzar en els títols.", + "abusefilter-test-action": "Tipus d’acció:", + "abusefilter-test-search-type-all": "Totes les accions", + "abusefilter-test-search-type-edit": "Edicions", + "abusefilter-test-search-type-move": "Canvis de nom", + "abusefilter-test-search-type-delete": "Supressions", + "abusefilter-test-search-type-upload": "Pujades", + "abusefilter-test-search-type-createaccount": "Creacions de comptes", "abusefilter-changeslist-examine": "examinar", "abusefilter-examine": "Examinar els canvis individuals", "abusefilter-examine-intro": "Aquesta pàgina us permet examinar les variables generades pel filtre d'abusos per a una modificació concreta i provar-les amb els filtres.", @@ -383,27 +455,30 @@ "abusefilter-examine-notfound": "El canvi que heu demanat no es pot trobar.", "abusefilter-examine-incompatible": "El canvi que heu demanat no és compatible amb el filtre d'abusos", "abusefilter-examine-noresults": "No s'ha trobat cap resultat per als paràmetres de cerca que heu proporcionat.", - "abusefilter-topnav": "'''Navegació del filtre d’abusos'''", + "abusefilter-topnav": "'''Navegació del filtre antiabusos'''", "abusefilter-topnav-home": "Inici", "abusefilter-topnav-test": "Test en sèrie", "abusefilter-topnav-examine": "Examinar les edicions", "abusefilter-topnav-log": "Registre d'abusos", "abusefilter-topnav-tools": "Eines de depuració", - "abusefilter-topnav-import": "Importa un filtre", - "abusefilter-log-name": "Registre del filtre d’abusos", + "abusefilter-log-name": "Registre del filtre antiabusos", "abusefilter-log-header": "Aquest registre mostra un resum dels canvis fets als filtres.\nPer a més detalls, vegeu [[Special:AbuseFilter/history|la llista]] de canvis recents dels filtres.", "abusefilter-log-noresults": "No hi ha resultats", "abusefilter-diff-title": "Diferències entre versions", - "abusefilter-diff-item": "Ítem", + "abusefilter-diff-item": "Element", "abusefilter-diff-version": "Versió de $1 {{GENDER:$3|per}} $2", "abusefilter-diff-info": "Informació bàsica", "abusefilter-diff-pattern": "Condicions del filtre", - "abusefilter-diff-invalid": "No es pot portar les versions sol·licitada", + "abusefilter-diff-invalid": "No s’han pogut recuperar les versions sol·licitades", "abusefilter-diff-backhistory": "Torna a l'historial del filtre", - "abusefilter-diff-prev": "Vell canvi", - "abusefilter-diff-next": "Nou canvi", + "abusefilter-diff-prev": "Canvi més vell", + "abusefilter-diff-next": "Canvi més recent", "abusefilter-import-intro": "Podeu utilitzar aquesta interfície per importar filtres d'altres wikis.\nEn el wiki d'origen, feu clic a «{{int:abusefilter-edit-export}}» sota «{{int:abusefilter-edit-tools}}» en la interfície d'edició.\nCopieu del quadre de text que apareix i enganxeu-lo a aquest quadre de text, a continuació feu clic a «{{int:abusefilter-import-submit}}».", "abusefilter-import-submit": "Importa dades", "abusefilter-group-default": "Per defecte", - "abusefilter-http-error": "S’ha produït un error d’HTTP: $1." + "abusefilter-http-error": "S’ha produït un error d’HTTP: $1.", + "abusefilter-view-privatedetails-submit": "Mostra els detalls privats", + "abusefilter-view-privatedetails-legend": "Mostra els detalls privats", + "abusefilter-noreason": "Atenció: heu d’indicar un motiu per a veure els detalls privats d’aquest registre.", + "abusefilter-log-ip-not-available": "No disponible" } diff --git a/AbuseFilter/i18n/ce.json b/AbuseFilter/i18n/ce.json index d9ba5c6a..77d3383c 100644 --- a/AbuseFilter/i18n/ce.json +++ b/AbuseFilter/i18n/ce.json @@ -1,28 +1,30 @@ { "@metadata": { "authors": [ + "Matma Rex", "Sasan700", - "Умар", "Исмаил Садуев", - "Matma Rex" + "Умар" ] }, "abusefilter-desc": "Нисдарийн тӀе литтарш тоха йиш хуьлуьйту.", - "abusefilter": "Зулам луьттург нисдар", - "abuselog": "Зуламаш долу тéптар", + "abusefilter": "Зулам литтаран урхалла", + "abuselog": "Зулам литтаран тептар", "abusefilter-intro": "Марша догӀийла, зулам луьттурган Урхаллин агӀон тӀе.\nЗулам луьттург, декъашхоша деш долу, зуламан дуьхьала, шаьшха болх бо гӀирс бу.\nКхузахь балийна, массо а, литтарийн могӀам, хийца аьтто а болуш.", - "abusefilter-warning": "''Тидаме'''. ХӀара динарг, шаьшха къастийна ца оьшуш санна.\nХӀоттам боцу нийсдарш хира ду, сиха дӀадаьхна,\nморса йа, дуккха хӀоттам боцу нийсдарш дича, хьан декъашхочун дӀаяздар ле IP-адресна блоктухур ю.\nХьо тешна валахь, хӀара нийсдара хӀоттам болуш хиларна, юхаъ «ДӀайахьийта» тӀе таӀа йе.\nАш дечуьнца догӀуш хилар бакъонца билгалла даьккхина: $1", + "abusefilter-warning": "''Тидаме'''. ХӀара динарг, шаьшха къастийна ца оьшуш санна.\nХӀоттам боцу нийсдарш хира ду, сиха дӀадаьхна,\nморса йа, дуккха хӀоттам боцу нийсдарш дича, хьан декъашхочун агӀо я IP-адресна блоктухур ю.\nХьо тешна валахь, хӀара нийсдара хӀоттам болуш хиларна, юхаъ «ДӀайахьийта» тӀе таӀа йе.\nАш дечуьнца догӀуш хилар бакъонца билгалла даьккхина: $1", "abusefilter-disallowed": "ХӀара динарг, шаьшха зуламе санна къастийна,\nцун дера ца магийна.\nНагахь, шу тешна делахь, хӀара нийсдар хӀоттам болуш хиларна, дехар до, куьйгалхочуьнга дийцар, шу дан гӀертарг.\nЗуламах лаьцна хаам, аш дечуьнца догӀуш хилар билгалла даьккхина: $1", "abusefilter-blocked-display": "ХӀара дешдерг автоматически зулам санна билгалдина,\nхьуна и кхочушдан ца маго.\nЦул совнаха ларор Ӏалашонца {{grammar:genitive|{{SITENAME}}}} хьан дӀаздарна а цуьнца долу IP-адресна а блоктоьхна.\nХьайна и иштта дац аьлла хетахь, дехар до куьйгалхочунга язде.\nБилгалйина литтаран зуламах доца лаьцна, хӀинца ахьа динчух: $1", + "abusefilter-autopromote-blocked": "ХӀара дешдерг автоматически зулам санна билгалдина, цундела юхадаьккхина.\nЦул совнаха ларор Ӏалашонца хьан дӀаздарна а цуьнца долу IP-адресна а бакъонаш дӀаяьхна.\nЛиттаран зуламах доца лаьцна, хӀинца ахьа динчух: $1", "abusefilter-blocker": "Зулам луьттург", "abusefilter-blockreason": "Зулам литтаро автоматически блоктоьхна. Цунах лаьцна: $1", "abusefilter-degroupreason": "Зулам литтаро бакъонаш авто-схьаяьхна. Бакъонах лаьцна: $1", - "abusefilter-accountreserved": "ХӀара декъашхочун дӀаяздар билгал дина зулам литтаро лела да.", + "abusefilter-accountreserved": "ХӀара декъашхочун агӀо билгал дина зулам литтаро лела да.", "right-abusefilter-modify": "зулам литтаран хийцам", "right-abusefilter-view": "зулам литтарршка хьажар", "right-abusefilter-log": "зулам литтаран тептаре хьажар", "right-abusefilter-log-detail": "зулам литтаран тептар чура ма-дарра долу дӀаяздаршка хьажар", - "right-abusefilter-private": "Долара хаамашка тептар чохь хьажар", + "right-abusefilter-privatedetails": "Долара хаамашка тептар чохь хьажар", + "right-abusefilter-privatedetails-log": "Долара хаамийн тептаре хьажаре тӀекхаьчича зулам ца леладойту луьттург.", "right-abusefilter-modify-restricted": "дихкина долу зулам литтарш хийцар", "right-abusefilter-revert": "зулам литтарс бина хийцамаш юхабахар", "right-abusefilter-view-private": "къайлаха долу зуламан литтаршка хьажар", @@ -34,22 +36,33 @@ "action-abusefilter-view": "зулам литтарршка хьажар", "action-abusefilter-log": "зулам литтаран тептаре хьажар", "action-abusefilter-log-detail": "зулам литтаран тептаре ма-дарра долу хьажар", - "action-abusefilter-private": "зулам литтаран тептар чура долара хаамашка хьажар", + "action-abusefilter-privatedetails": "зулам литтаран тептар чура долара хаамашка хьажар", "action-abusefilter-modify-restricted": "дихкина долу зулам литтарш хийцар", "action-abusefilter-revert": "зулам литтарс бина хийцамаш юхабаха", "action-abusefilter-view-private": "къайлаха долу зулам литтаршка хьажар", - "abusefilter-log": "Зулам литтаран тептар", "abusefilter-log-summary": "ХӀокху тептар чохь гойту литтаран карийнарш.", "abusefilter-log-search": "Зуламан тептар чохь лахар", "abusefilter-log-search-user": "Декъашхо:", - "abusefilter-log-search-filter": "ID литтаран:", + "abusefilter-log-search-group": "Литтаран тоба:", + "abusefilter-log-search-group-any": "Муьлха а", + "abusefilter-log-search-filter": "Литтаран ID:", "abusefilter-log-search-title": "Корта:", "abusefilter-log-search-wiki": "Википроект:", + "abusefilter-log-search-impact": "Ӏаткъам:", + "abusefilter-log-search-impact-all": "Массо дийриш", + "abusefilter-log-search-impact-saved": "Ӏалашбина хийцамаш бен", + "abusefilter-log-search-impact-not-saved": "Ӏалашбанза хийцамаш бен", + "abusefilter-log-search-entries-label": "Гуш хилар:", + "abusefilter-log-search-entries-all": "Дерриге дӀаяздарш", + "abusefilter-log-search-action-other": "Кхиерш", + "abusefilter-log-search-action-any": "муьлха а", + "abusefilter-log-search-action-taken-label": "Динарш:", + "abusefilter-log-search-action-taken-any": "Ерриге", "abusefilter-log-search-submit": "Лахар", "abusefilter-log-entry": "$1: $2 зулам литтаре болх балийтина, дийнарг «$3» агӀона $4 чохь.\nКхочушъ дийнарг: $5.\nЛиттарах лаьцна: $6", "abusefilter-log-entry-withdiff": "$1: $2 зулам литтаре болх балийтина, дийнарг «$3» агӀона $4 чохь.\nКхочушъ дийнарг: $5.\nЛиттарах лаьцна: $6 ($7)", "abusefilter-log-detailedentry-meta": "$1: $2 болх бола балийтина $3, дийнарг «$4» агӀона $5 чохь.\nКхочушъ дийнарг: $6.\nЛиттарах лаьцна: $7 ($8)", - "abusefilter-log-detailedentry-global": "глобальни луьттург $1", + "abusefilter-log-detailedentry-global": "глобалан луьттург $1", "abusefilter-log-detailedentry-local": "луьттург $1", "abusefilter-log-detailslink": "мадарра", "abusefilter-log-diff": "хийц.", @@ -58,13 +71,15 @@ "abusefilter-log-details-var": "Хийцаме", "abusefilter-log-details-val": "МаьӀна", "abusefilter-log-details-vars": "Дечунна параметраш", - "abusefilter-log-details-private": "Долара хаамаш", + "abusefilter-log-details-privatedetails": "Долара хаамаш", "abusefilter-log-details-ip": "ДӀадохуьйту IP-адрес", + "abusefilter-log-details-checkuser": "Декъашхочунга хьажа", "abusefilter-log-noactions": "цаоьшу", "abusefilter-log-details-diff": "Нисдар чохь бина хийцамаш", "abusefilter-log-linkoncontribs": "зуламаш долу тéптар", "abusefilter-log-linkoncontribs-text": "ХӀокху декъашхочун тептар чур зуламан дӀаяздарш", - "abusefilter-log-hidden": "(дӀаяздар хьулдина)", + "abusefilter-log-linkonhistory": "литтарийн тептаре хьажар", + "abusefilter-log-linkonundelete": "зулам литтаран тептаре хьажар", "abusefilter-log-hidden-implicit": "(нисдар дӀадаккхар бахьнехь хьулдина)", "abusefilter-log-cannot-see-details": "ХӀокху дӀаяздаре мадарра хьажа хьа бакъо яц.", "abusefilter-log-details-hidden": "Хьокху дӀаяздаре мадарра хьажа хьа таро яц и хьулдар бахьнехь.", @@ -73,10 +88,11 @@ "abusefilter-log-hide-hidden": "Къайладаккха хӀара дӀаяздар", "abusefilter-log-hide-reason": "Бахьана:", "abusefilter-log-hide-forbidden": "Зуламан тептар чура дӀаяздарш къайладаха хьа бакъо яц.", + "abusefilter-log-entry-suppress": "$1 {{GENDER:$2|къайладаьккхина}} $3", "logentry-abusefilter-hit": "$1 {{#gender:$1|болх бола балийтина}} литтаре $4, кхочушъ дийнарг «$5» агӀона $3 чохь. Дийнарг: $6 ($7)", - "abusefilter-management": "Зулам литтаран урхалла", "abusefilter-list": "Дерриг литтарш", - "abusefilter-list-id": "ID литтаран", + "abusefilter-list-id": "Литтаран ID", + "abusefilter-list-pattern": "Паттерн", "abusefilter-list-status": "Хьал", "abusefilter-list-public": "Массарна гуш долу дийцар", "abusefilter-list-consequences": "ТӀаьхье", @@ -92,10 +108,12 @@ "abusefilter-enabled": "Юкъадалийна", "abusefilter-deleted": "ДӀаяьккхина", "abusefilter-disabled": "ДӀадайина", + "abusefilter-throttled": "дихкина", "abusefilter-hitcount": "$1 {{PLURAL:$1|болх бар}}", "abusefilter-new": "Кхолла керла луьттург", + "abusefilter-import-button": "Литтаран импорт", "abusefilter-return": "Юха гӀо литтарийн урхале", - "abusefilter-status-global": "Глобальни", + "abusefilter-status-global": "Глобалан", "abusefilter-list-options": "Параметраш", "abusefilter-list-options-deleted": "ДӀадаьхина долу литтарш:", "abusefilter-list-options-deleted-only": "ДӀадаьхина литтарш бен ца гойту", @@ -103,10 +121,16 @@ "abusefilter-list-options-deleted-show": "Гайта дӀадаьхина литтарш", "abusefilter-list-options-scope": "Гайта литтарш чура:", "abusefilter-list-options-scope-local": "ХӀара википроект", - "abusefilter-list-options-scope-global": "Глобальни бакъонаш", - "abusefilter-list-options-scope-all": "Локальни а, глобальни а бакъонаш", + "abusefilter-list-options-scope-global": "Глобалан бакъонаш", + "abusefilter-list-options-scope-all": "Локалан а, глобалан а бакъонаш", + "abusefilter-list-options-further-options": "Кхин болу нисдаран гӀирс:", "abusefilter-list-options-hidedisabled": "ДӀадайина литтарш дӀахьулданн", + "abusefilter-list-options-hideprivate": "Къайладаха приватан литтарш", + "abusefilter-list-options-searchpattern": "Чуйилла паттерн", "abusefilter-list-options-searchoptions": "Лахаран раж:", + "abusefilter-list-options-search-like": "Атта дехар", + "abusefilter-list-options-search-rlike": "Рожера алар", + "abusefilter-list-options-search-irlike": "Регистрна цахаалуш рожера алар", "abusefilter-list-options-submit": "Карлаяккха", "abusefilter-tools-text": "Кхузахь бу зулуман литтарш кепе дало гӀо деш болу гӀисрсаш.", "abusefilter-tools-expr": "Гайтам хьажар", @@ -114,27 +138,27 @@ "abusefilter-tools-reautoconfirm": "МеттахӀотае статус «autoconfirmed»", "abusefilter-tools-reautoconfirm-user": "Декъашхо:", "abusefilter-tools-reautoconfirm-submit": "Юху ша тӀелацар", - "abusefilter-reautoconfirm-none": "ХӀокху {{GENDER:$1|декъашхочун}} дӀаяздар ша бакъдеш йолу статус йолуш ю.", + "abusefilter-reautoconfirm-none": "ХӀокху {{GENDER:$1|декъашхочун}} агӀо ша бакъдеш йолу статус йолуш ю.", "abusefilter-reautoconfirm-notallowed": "Шабакъдар статус меттахӀотто хьуна ца магийна.", - "abusefilter-reautoconfirm-done": "Декъашхочун дӀаяздар шабакъаран статус меттахӀоттина.", + "abusefilter-reautoconfirm-done": "Декъашхочун агӀо автобакъаран статус меттахӀоттина.", "abusefilter-status": "$1 нах {{PLURAL:$1|1=тӀехьара динарг|тӀехьара динарш}}, $2 ($3%) {{PLURAL:$2|нисделла}} литтаран дӀакъовлар чу хӀокху $4 хьолехь, кхин $5 ($6%) {{PLURAL:$5|цхьаьнадогӀуш}} ду хӀинца долуш долу цхьан литтаран дӀакъовларца.", "abusefilter-edit": "Зулам литтаран хийцамбар", "abusefilter-edit-subtitle": "Литтаран хийцам $1", "abusefilter-edit-subtitle-new": "Литтаран хьал", "abusefilter-edit-status-label": "Статистика:", "abusefilter-edit-status": "{{PLURAL:$1|ТӀеххьара $1 диначух}}, хӀара луьттург цхьаьнайогӀуш ю $2 ($3%).", - "abusefilter-edit-status-profile": "{{PLURAL:$1|ТӀехьара $1 диначух|ТӀехьара $1 диначарах|ТӀехьара $1 диначарах}}, хӀара литтар цхьаьнадогӀуш ду $2 ($3%).\nЦунна белхан юккъера хан — $4 мс, иза цхьаьнайогӀуш ю $5 {{PLURAL:$5|хьолаца}}.", "abusefilter-edit-new": "Керла луьттург", "abusefilter-edit-save": "Ӏалашъе луьттург", - "abusefilter-edit-id": "ID литтаран", - "abusefilter-edit-switch-editor": "Тадерг кхечутӀеерзор", + "abusefilter-edit-id": "Литтаран ID:", + "abusefilter-edit-switch-editor": "Редактор кхечутӀеерзор", "abusefilter-edit-description": "Цуьнах лаьцна:\n:''(Массарна гуш)''", + "abusefilter-edit-field-description": "цуьнах лаьцна", "abusefilter-edit-group": "Литтаран тоба:", "abusefilter-edit-flags": "Байракхаш:", "abusefilter-edit-enabled": "Доладалийта хӀара луьттург", "abusefilter-edit-deleted": "Билгалъе дӀаяьккхина", "abusefilter-edit-hidden": "Ма гайта ма-дарра бакъонаш йоцачу декъашхошна", - "abusefilter-edit-global": "глобальни луьттург", + "abusefilter-edit-global": "глобалан луьттург", "abusefilter-edit-rules": "Хьал:", "abusefilter-edit-notes": "Билгалдахарш:", "abusefilter-edit-lastmod": "Тlаьххьара литтаран хийцам:", @@ -143,21 +167,38 @@ "abusefilter-edit-consequences": "Кхочушбеш болу барам", "abusefilter-edit-action-warn": "Кхочушде декъашхочунга дӀахьедар динчултӀехьа", "abusefilter-edit-action-disallow": "Бехкам-бе декъашхочо дечунна", - "abusefilter-edit-action-blockautopromote": "Схьаяккха декъашхочун дӀаяздар ша бакъдеш йолу статус", + "abusefilter-edit-action-blockautopromote": "Схьаяккха декъашхочун агӀо ша бакъдеш йолу статус", "abusefilter-edit-action-degroup": "ДӀаваккха (яккха) декъашхо тобашан юкъар", "abusefilter-edit-action-block": "Блоктоха декъашхочун я IP-адресан", + "abusefilter-edit-action-blocktalk": "Блоктоха декъашхочун/я IP-адресна шен дийцаре агӀонан хийцамаш ца байтархьама", "abusefilter-edit-action-throttle": "Кхочушде декъашхочо тӀех дукха зулум деш делахь", "abusefilter-edit-action-rangeblock": "Декъашхочо болхбеш йолу диапазонан /16 блоктоха.", "abusefilter-edit-action-tag": "Билгалде нисдар кхин хьажа", "abusefilter-edit-throttle-count": "Шордина динаршан дуккхалла:", "abusefilter-edit-throttle-period": "Хенан дакъа:", + "abusefilter-edit-throttle-groups-help": "Хьажа $1.", + "abusefilter-throttle-ip": "IP-адрес", + "abusefilter-throttle-user": "декъашхочун агӀо", + "abusefilter-throttle-range": "Диапазон /16", + "abusefilter-throttle-creationdate": "ДӀаяздар кхоьллина терахь", + "abusefilter-throttle-editcount": "Нисдарийн ларар", + "abusefilter-throttle-site": "Ерриг сайт", + "abusefilter-throttle-page": "агӀо", + "abusefilter-throttle-none": "(хӀан-хӀа)", "abusefilter-edit-warn-message": "ДӀахьедарна системин хаамаш:", "abusefilter-edit-warn-other": "Кхин хаам", - "abusefilter-edit-warn-other-label": "Кхечу хааман агӀон цӀе:\n:''(MediaWiki префикс йоцуш)''", + "abusefilter-edit-warn-other-label": "Кхечу хааман агӀонан цӀе:\n:''(MediaWiki префикс йоцуш)''", "abusefilter-edit-warn-actions": "Дийраш:", "abusefilter-edit-warn-preview": "Хаьржина хаам хьалха муха бу хьажар", "abusefilter-edit-warn-edit": "Къайлабаккха/Хийца хаьржина хаам", + "abusefilter-edit-disallow-other": "Кхин хаам", + "abusefilter-edit-disallow-actions": "Дийраш:", "abusefilter-edit-tag-tag": "Лелош йолу [[Special:Tags|билгалонаш]] (могӀанна цхьац):", + "abusefilter-edit-block-anon-durations": "Анониман декъашхошна блоктохаран хенан йохалла:", + "abusefilter-edit-block-user-durations": "ДӀабазбелачу декъашхошна блоктохаран хенан йохалла:", + "abusefilter-block-anon": "Блоктоха анониман декъашхошна", + "abusefilter-block-user": "блоктоха дӀабазбелачу декъашхошна", + "abusefilter-block-talk": "дийцаре агӀона блоктоьхна", "abusefilter-edit-main": "Литтаран параметраш", "abusefilter-edit-done-subtitle": "Луьттург нисйина", "abusefilter-edit-done": "Ахьа [[Special:AbuseFilter/$1|$3 литтаран]] [[Special:AbuseFilter/history/$1/diff/prev/$2|хийцамаш]] кхиамца Ӏалашбина.", @@ -170,6 +211,7 @@ "abusefilter-edit-export": "Экспорт де хӀара луьттург кхечу вики чу", "abusefilter-edit-syntaxok": "Синтаксисан гӀалаташ ца карийна.", "abusefilter-edit-syntaxerr": "Синтаксисан гӀалаташ карийна: $1", + "abusefilter-edit-bad-tags": "Язйиначух цхьаъ я массийта билгало нийса яц.\nБилгалонаш нийса хила еза, юкъахь хила ца еза леррина символаш я резервйина кхечу программийн лртторо хила ца еза. Билгалонан керла цӀе язйина хьажа", "abusefilter-edit-notallowed-global": "Хьан бакъонаш яц зулам литтарш кхолла я хийца", "abusefilter-edit-builder-select": "ТӀетоха харжа пункт", "abusefilter-edit-builder-group-op-arithmetic": "Арифметикан оператораш", @@ -204,17 +246,23 @@ "abusefilter-edit-builder-funcs-length": "МогӀан бохалла (length)", "abusefilter-edit-builder-funcs-lcase": "Лахара регистр (lcase)", "abusefilter-edit-builder-funcs-ucase": "Лакхара регистр", - "abusefilter-edit-builder-funcs-ccnorm": "Дукху маьӀнаш долу символаш (ccnorm) нисяр", + "abusefilter-edit-builder-funcs-ccnorm": "Дукху маьӀнаш долу символаш (ccnorm) нисъяр", + "abusefilter-edit-builder-funcs-ccnorm-contains-all": "Массийта кӀелара могӀаршна могӀа лартӀе бало а, каро а рожехь AND (ccnorm_contains_all)", "abusefilter-edit-builder-funcs-rmdoubles": "Цхьатерра символаш (rmdoubles) дӀаяхар", "abusefilter-edit-builder-funcs-specialratio": "Леррина символаш / массо символаш (specialratio)", "abusefilter-edit-builder-funcs-norm": "ЛартӀа далор (norm)", "abusefilter-edit-builder-funcs-count": "Бухара могӀан юькъатухучера дукхалла X могӀан чохь Y (count)", + "abusefilter-edit-builder-funcs-get_matches": "Рожера дешнийн массив цхьаьнайогӀуш ду хӀора (get_matches) тобан йозананца", + "abusefilter-edit-builder-funcs-rmwhitespace": "Яккъаш (rmwhitespace) дӀаяхар", "abusefilter-edit-builder-funcs-rmspecials": "ДӀаяха леррина символаш (rmspecials)", + "abusefilter-edit-builder-funcs-ip_in_range": "Диапазонехь (ip_in_range) IP хилар", "abusefilter-edit-builder-funcs-contains-any": "МогӀанан юкъахь ю кхунах (contains_any) муьлха цхьаъ", + "abusefilter-edit-builder-funcs-contains-all": "МогӀанан юкъахь массийта кӀелара могӀарш ду рожехь AND. (contains_all)", "abusefilter-edit-builder-funcs-substr": "Бухара могӀа (substr)", "abusefilter-edit-builder-funcs-strpos": "(strpos) могӀамехь могӀа болу меттиг", "abusefilter-edit-builder-funcs-str_replace": "(str_replace) могӀамехь бухара могӀа хийцар", "abusefilter-edit-builder-funcs-set_var": "ДӀахӀоттае хийцалун (set_var)", + "abusefilter-edit-builder-funcs-sanitize": "Юникод (sanitize) чура HTML символаш лартӀе ялор", "abusefilter-edit-builder-group-vars": "Хийцаме", "abusefilter-edit-builder-vars-accountname": "Декъашхочун дӀаяздаран цӀе (кхуллучу хенахь)", "abusefilter-edit-builder-vars-timestamp": "Хийцам бина Unix-хан", @@ -245,27 +293,27 @@ "abusefilter-edit-builder-vars-user-rights": "Декъашхочун йолу бакъонаш", "abusefilter-edit-builder-vars-user-blocked": "Блоктоьхна юй", "abusefilter-edit-builder-vars-user-emailconfirm": "Электронан поштан адрес бакъдина хан", - "abusefilter-edit-builder-vars-recent-contributors": "ТӀаьххьара агӀона хийцамаш бина итт декъашхо", + "abusefilter-edit-builder-vars-recent-contributors": "ТӀаьххьара агӀонан хийцамаш бина итт декъашхо", "abusefilter-edit-builder-vars-first-contributor": "Дуьххьара агӀонгахь къахьегнарг", "abusefilter-edit-builder-vars-all-links": "Йозанан арахьара хьажоргаш", "abusefilter-edit-builder-vars-added-links": "Нисдар чохь тӀетоьхина ерриге арахьара хьажоргаш", "abusefilter-edit-builder-vars-removed-links": "Нисдар чохь дӀаяхна арахьара хьажоргаш", - "abusefilter-edit-builder-vars-old-text": "Шира викийоза, агӀо нисяле", - "abusefilter-edit-builder-vars-new-text": "Керла викийоза, агӀо нисйинчул тӀехьа", - "abusefilter-edit-builder-vars-new-text-stripped": "АгӀона керла йоза, цӀандина билгалонах", + "abusefilter-edit-builder-vars-old-wikitext": "Шира викийоза, агӀо нисяле", + "abusefilter-edit-builder-vars-new-wikitext": "Керла викийоза, агӀо нисйинчул тӀехьа", + "abusefilter-edit-builder-vars-new-text": "АгӀона керла йоза, цӀандина билгалонах", "abusefilter-edit-builder-vars-new-html": "Керла версин вовшахъяккхина HTML-код", "abusefilter-edit-builder-vars-restrictions-edit": "АгӀона нисдарийн дуьхьала диначу гӀораллийн барам", "abusefilter-edit-builder-vars-restrictions-move": "АгӀона цӀе хийца ца яйта диначу гӀораллийн барам", "abusefilter-edit-builder-vars-restrictions-create": "АгӀо кхолларна гӀорала", "abusefilter-edit-builder-vars-restrictions-upload": "Файл чуяхар лардар", - "abusefilter-edit-builder-vars-old-links": "Нисяле хийла хьажоргаш", + "abusefilter-edit-builder-vars-old-links": "Нисъяле хила хьажоргаш", "abusefilter-edit-builder-vars-minor-edit": "«Жима хийцам» аьлла билгала дина дуй нисдар", - "abusefilter-filter-log": "Литтаран тӀаьххьара бина хийцамаш", + "abusefilter-filter-log": "Литтарийн тӀаьххьара бина хийцамаш", "abusefilter-history": "Зулам литтаран хийцамашан истори #$1", "abusefilter-history-foruser": "Хийцамаш бина $1", "abusefilter-history-hidden": "къайлаяьккхина", "abusefilter-history-enabled": "юкъадалийна", - "abusefilter-history-global": "Глобальни", + "abusefilter-history-global": "Глобалан", "abusefilter-history-timestamp": "Хан", "abusefilter-history-user": "Декъашхо", "abusefilter-history-public": "Литтаран тӀекхочуш болу хаам", @@ -278,6 +326,7 @@ "abusefilter-history-filterid": "Луьттург", "abusefilter-history-select-legend": "Лахар дӀанисдар", "abusefilter-history-select-user": "Декъашхо:", + "abusefilter-history-select-filter": "Литтаран ID:", "abusefilter-history-select-submit": "Билгалдаккха", "abusefilter-history-diff": "Хийцамаш", "abusefilter-exception-unrecognisedkeyword": "Дойзуш доцу оьшуш долу дош $2 оцу меттигца $1.", @@ -306,10 +355,17 @@ "abusefilter-test-submit": "Хьажа", "abusefilter-test-load": "Чуяккха", "abusefilter-test-user": "Декъашхочо бина хийцамаш:", + "abusefilter-test-nobots": "Ботийн нисдарш къайладаха", "abusefilter-test-period-start": "ТӀаьхьа хийцамаш бина хан:", "abusefilter-test-period-end": "Хьалхо хийцамаш бина хан:", "abusefilter-test-page": "Хийцамаш бийна агӀо:", "abusefilter-test-shownegative": "Литтаран юкъахь боцу хийцамаш гайта", + "abusefilter-test-action": "Дечуьнна тайпа:", + "abusefilter-test-search-type-all": "Массо дийриш", + "abusefilter-test-search-type-edit": "Нисдарш", + "abusefilter-test-search-type-move": "ЦӀе хийцар", + "abusefilter-test-search-type-delete": "ДӀаяккхар", + "abusefilter-test-search-type-upload": "Чуйаьхарш", "abusefilter-changeslist-examine": "хьажа", "abusefilter-examine": "Хийцамашка къестош хьажар", "abusefilter-examine-intro": "ХӀокху агӀоно йиш хуьлуьйту зулуман литтаро кхолийна хийцамашка хьажа нисдарш къестош.", @@ -329,13 +385,15 @@ "abusefilter-examine-noresults": "Жоп дехарца хӀума ца карийна оцу параметаршца.", "abusefilter-topnav": "Зуламан литтаран навигаци", "abusefilter-topnav-home": "Юьхьигé", + "abusefilter-topnav-recentchanges": "Литтарийн тӀаьххьара бина хийцамаш", "abusefilter-topnav-test": "Зеран гулам", "abusefilter-topnav-examine": "Хийцамашка къестош хьажар", "abusefilter-topnav-log": "Зуламаш долу тéптар", "abusefilter-topnav-tools": "Нисяран гӀирс", - "abusefilter-topnav-import": "Литтаран импорт", "abusefilter-log-name": "Зулам литтаран тептар", "abusefilter-log-header": "ХӀокху тептар чохь гойту литтаран чохь бина хийцамаш.\nМадарра [[Special:AbuseFilter/history|хьажа тӀеххьара бина литтаран хийцамашка]].", + "abusefilter-logentry-create": "$1 {{GENDER:$2|кхоьллина}} $4 ($5)", + "abusefilter-logentry-modify": "$1 {{GENDER:$2|хийцина}} $4 ($5)", "abusefilter-log-noresults": "ХӀума ца карийна", "abusefilter-diff-title": "Версийн башхалла", "abusefilter-diff-item": "Элемент", @@ -344,10 +402,17 @@ "abusefilter-diff-pattern": "Литтаран хьал", "abusefilter-diff-invalid": "Йохуш йолу версеш схьаэца цало", "abusefilter-diff-backhistory": "ЮхагӀо литтаран истори йолче", - "abusefilter-diff-prev": "Шира хийцамаш", + "abusefilter-diff-prev": "Хьалхара нисдар", "abusefilter-diff-next": "Керла хийцамаш", "abusefilter-import-intro": "ХӀокху агӀонехь хьан йиш ю кхечу вики чура литтарш импорт дан.\nДӀайолалун вики чохь «{{int:abusefilter-edit-tools}}» чохь тӀетаӀе «{{int:abusefilter-edit-export}}».\nЧулацаман копи якхкхе хӀокху агӀона чу йилина тӀетаӀе «{{int:abusefilter-import-submit}}».", "abusefilter-import-submit": "Хаамаш импорт бе", "abusefilter-group-default": "Ӏадйитаран кеп", - "abusefilter-http-error": "Даьлла гӀалат HTTP: $1" + "abusefilter-http-error": "Даьлла гӀалат HTTP: $1", + "abusefilter-view-privatedetails-submit": "Шен хаамашка хьажар", + "abusefilter-view-privatedetails-legend": "Шен хаамашка хьажар", + "abusefilter-view-privatedetails-reason": "Шен хаамийн тӀекхачаран бахьна:", + "abusefilter-log-details-id": "Тептаран ID", + "abusefilter-log-ip-not-available": "ТӀекхочехь яц", + "tag-abusefilter-condition-limit": "доза тохар", + "tag-abusefilter-condition-limit-description": "Массо жигара [[Special:AbuseFilter|зуламан литтаршна]] далуш доцург ([[mw:Extension:AbuseFilter/Conditions|гӀо]])." } diff --git a/AbuseFilter/i18n/ckb.json b/AbuseFilter/i18n/ckb.json index 3515ec27..63728d65 100644 --- a/AbuseFilter/i18n/ckb.json +++ b/AbuseFilter/i18n/ckb.json @@ -1,16 +1,18 @@ { "@metadata": { "authors": [ + "Arya sarhan", "Asoxor", "Calak", - "Pirehelokan", "Matma Rex", - "Sarchia", "Muhammed taha", + "Pirehelokan", + "Sarchia", "Épine" ] }, - "abuselog": "پاڵوێنەی کەڵکاوەژوو", + "abusefilter": "بەڕێوەبردنی پاڵوێنەی کەڵکاوەژوو", + "abuselog": "لۆگی پاڵوێنەی کەڵکاوەژوو", "abusefilter-intro": "بەخێربێی بۆ پەڕەی بەڕیوەبردنی پاڵوێنەی کەڵکاوەژوو.\nپاڵوێنەی کەڵکاوەژوو ڕێوشوێنێکی نەرمامێرییە بۆ بەکاربردنی پێزانینە خۆگەڕەکان لە سەر ھەموو کردەوەکان.\nئەم پەڕەیە پێرستی ھەموو پاڵوێنەکان نیشان دەدات و ڕێگە دەدات گۆڕانکارییان تێدا بکرێت.", "abusefilter-blocker": "پاڵوێنەی کەڵکاوەژوو", "abusefilter-accountreserved": "ئەم ناوە بەکارھێنەرییە بۆ کەڵک وەرگرتن لە پاڵوێنەی کەڵکاوەژوودا گیراوەتەوە.", @@ -27,13 +29,20 @@ "action-abusefilter-modify": "دەستکاریی پاڵوێنەکانی کەڵکاوەژوو", "action-abusefilter-view": "دیتنی پاڵوێنەکانی کەڵکاوەژوو", "action-abusefilter-log": "دیتنی لۆگی کەڵکاوەژوو", - "abusefilter-log": "لۆگی پاڵوێنەی کەڵکاوەژوو", "abusefilter-log-summary": "ئەم لۆگە پێرستێک لە ھەموو کردەوەکانی پاڵوێنەکان نیشان دەدات.", "abusefilter-log-search": "گەڕانی لۆگی کەڵکاوەژوو", "abusefilter-log-search-user": "بەکارھێنەر:", + "abusefilter-log-search-group-any": "ھەر", "abusefilter-log-search-filter": "پێناسەی پاڵوێنە:", "abusefilter-log-search-title": "ناونیشان:", "abusefilter-log-search-wiki": "ویکی:", + "abusefilter-log-search-impact-all": "ھەموو کارەکان", + "abusefilter-log-search-impact-saved": "تەنھا گۆڕینەکان پاشەکەوت کرا", + "abusefilter-log-search-impact-not-saved": "بەبێ گۆڕینەکان پاشەکەوت کرا", + "abusefilter-log-search-entries-label": "دەرکەوتن:", + "abusefilter-log-search-action-other": "ھیتر", + "abusefilter-log-search-action-any": "ھەر", + "abusefilter-log-search-action-taken-any": "ھەر", "abusefilter-log-search-submit": "بگەڕێ", "abusefilter-log-entry": "$1: $2 پاڵوێنەیەکی کەڵکاوەژووی چالاککرد، خەریکی کردەوەی «$3» لەسەر $4 بوو.\nکردەوەی بەڕێوەچوو: $5؛\nتێبینیی پاڵوێنە: $6", "abusefilter-log-detailedentry-meta": "$1: $2 $3ی چالاککرد، خەریکی کردەوەی «$4» لەسەر $5 بوو.\nکردەوەی بەڕێوەچوو: $6؛\nتێبینیی پاڵوێنە: $7 ($8)", @@ -45,12 +54,11 @@ "abusefilter-log-details-var": "بگۆڕ", "abusefilter-log-details-val": "نرخ", "abusefilter-log-details-vars": "پارامەترەکانی کردەوە", - "abusefilter-log-details-private": "زانیاریی تاکەکەسی", - "abusefilter-log-noactions": "ھیچ", + "abusefilter-log-details-checkuser": "پشکنەری بەکارھێنەر", + "abusefilter-log-noactions": "ھیچیان", "abusefilter-log-linkoncontribs": "پاڵوێنەی کەڵکاوەژوو", - "abusefilter-log-linkoncontribs-text": "پاڵوێنەی کەڵکاوەژوو بۆ ئەم بەکارھێنەرە", + "abusefilter-log-linkoncontribs-text": "پاڵوێنەی کەڵکاوەژوو بۆ {{GENDER:$1|ئەم بەکارھێنەرە}}", "abusefilter-log-linkonhistory": "دیتنی لۆگی کەڵکاوەژوو", - "abusefilter-log-hidden": "(بابەتی شاردراو)", "abusefilter-log-hidden-implicit": "(شاردراوەتەوە چون پێداچوونەوە سڕدراوەتەوە)", "abusefilter-log-cannot-see-details": "ناتوانی وردەکارییەکانی ئەم بابەتە ببینی.", "abusefilter-log-details-hidden": "ناتوانی وردەکارییەکانی ئەم بابەتە ببینی، چونکوو لەبەر چاوی گشتی شاردراوەتەوە.", @@ -59,7 +67,6 @@ "abusefilter-log-hide-reason": "هۆکار:", "abusefilter-log-hide-forbidden": "ناتوانی بابەتەکانی لۆگی کەڵکاوەژوو بشارییەوە.", "logentry-abusefilter-hit": "$1 $4ی چالاککرد، خەریکی کردەوەی «$5» لەسەر $3 بوو. کردەوەی بەڕێوەچوو: $6 ($7)", - "abusefilter-management": "بەڕێوەبردنی پاڵوێنەی کەڵکاوەژوو", "abusefilter-list": "ھەموو پاڵوێنەکان", "abusefilter-list-id": "پێناسەی پاڵوێنە", "abusefilter-list-status": "ڕەوش", @@ -79,6 +86,7 @@ "abusefilter-disabled": "ڕێگەپێنەدراو", "abusefilter-hitcount": "$1 {{PLURAL:$1|جار|جار}}", "abusefilter-new": "پاڵوێنەیەکی نوێ دروست بکە", + "abusefilter-import-button": "ھاوردنی پاڵوێنە", "abusefilter-return": "بگەڕێوە بۆ بەڕێوبەرایەتیی پاڵوێنە", "abusefilter-status-global": "سەرانسەری", "abusefilter-list-options": "ھەڵبژاردەکان", @@ -88,22 +96,28 @@ "abusefilter-list-options-deleted-show": "پاڵوێنە سڕدراوەکان لەخۆبگرەوە", "abusefilter-list-options-scope": "پاڵوێنەکان نیشان بدە:", "abusefilter-list-options-scope-local": "تەنھا ڕێسا خۆماڵییەکان", + "abusefilter-list-options-scope-global": "تەنیا ڕێسا سەرانسەرییەکان", + "abusefilter-list-options-further-options": "ھەڵبژاردەی زیاتر:", "abusefilter-list-options-hidedisabled": "پاڵوێنە ناچالاکەکان بشارەوە", + "abusefilter-list-options-searchfield": "گەڕان بەناو ڕێساکاندا:", + "abusefilter-list-options-searchpattern": "نەخشەیەک دانێ", + "abusefilter-list-options-searchoptions": "شێوازی گەڕان:", "abusefilter-list-options-submit": "نوێکردنەوە", "abusefilter-tools-text": "لێرەدا ھەندێک ئامراز ھەیە کە لەوانەیە بەکەڵک بێت بۆ ڕێسلمەندکردن و سڕینەوەی ھەڵەکانی پاڵوێنەکانی کەڵکاوەژوو.", "abusefilter-tools-expr": "تاقیکەری دەستەواژە", "abusefilter-tools-submitexpr": "ھەڵسەنگاندن", "abusefilter-tools-reautoconfirm": "گەڕاندنەوەی ڕەوشی پەسندکراوی خۆگەڕ", "abusefilter-tools-reautoconfirm-user": "بەکارھێنەر:", + "abusefilter-status": "یەکێک لە دوایین $1 کردەوەکان، $2 ($3٪) بە سنووری مەرجی $4 گەیشتوون، و $5 ($6٪) لەگەڵ یەکێک لەو پاڵوێنە چالاکانە بەریەککەوتوون.", "abusefilter-edit-subtitle": "دەستکاریی پاڵوێنەی $1", "abusefilter-edit-subtitle-new": "دروستکردنی پاڵوێنە", "abusefilter-edit-status-label": "ئامارەکان:", "abusefilter-edit-status": "لە دوایین $1 {{PLURAL:$1|کردەوە}}دا، ئەم پاڵوێنەیە لەگەڵ $2 ($3٪) گونجاوە.", - "abusefilter-edit-status-profile": "لە دوایین $1 {{PLURAL:$1|کردەوە}}دا، ئەم پاڵوێنەیە لەگەڵ $2 ($3٪) گونجاوە.\nبە شێوەی ناونجی، کاتی جێبەجێبوونی $4 میلی چرکەیە و $5 {{PLURAL:$5|مەرج}} لە سنووری مەرجی بەکاربردووە.", "abusefilter-edit-new": "پاڵوێنەیەکی نوێ", "abusefilter-edit-save": "پاڵوێنە پاشەکەوت بکە", "abusefilter-edit-id": "پێناسەی پاڵوێنە:", "abusefilter-edit-description": "وەسف:\n:''(بۆ ھەموو کەس دەبینرێ)''", + "abusefilter-edit-field-description": "وەسف", "abusefilter-edit-group": "گرووپی پاڵوێنە:", "abusefilter-edit-flags": "ئاڵاکان:", "abusefilter-edit-enabled": "ئەم پاڵوێنەیە چالاک بکە", @@ -111,15 +125,27 @@ "abusefilter-edit-hidden": "وردەکارییەکانی ئەم پاڵوێنەیە لەبەر چاوی گشتی لا ببە", "abusefilter-edit-global": "پاڵوێنەی سەرانسەری", "abusefilter-edit-rules": "مەرجەکان:", + "abusefilter-edit-field-conditions": "مەرجەکان", "abusefilter-edit-notes": "تێبینییەکان:", "abusefilter-edit-lastmod": "پاڵوێنە دواجار گۆڕدراوە لە:", "abusefilter-edit-lastmod-text": "$1 بەدەستی $2", + "abusefilter-edit-throttle-groups-help": "$1 بینین.", + "abusefilter-throttle-ip": "ناونیشانی ئایپی", + "abusefilter-throttle-user": "ھەژماری بەکارھێنەر", + "abusefilter-throttle-creationdate": "داتای دروستکردنی ھەژمار", + "abusefilter-throttle-editcount": "ژمارەی دەستکارییەکان", + "abusefilter-throttle-page": "پەڕە", + "abusefilter-throttle-none": "(ھیچ)", "abusefilter-edit-warn-message": "پەیامی سیستەم بۆ بەکارھێنان لە وشیارکردنەوەدا:", "abusefilter-edit-warn-other": "پەیامی تر", - "abusefilter-edit-warn-other-label": "ناوی پەڕەی پەیامی تر:\n:''(بێ پێشگری میدیاویکی)''", + "abusefilter-edit-warn-other-label": "ناوی پەڕەی پەیامی تر:\n:''(بێ پێشگری \"میدیاویکی:\")''", "abusefilter-edit-warn-actions": "کردەوەکان:", "abusefilter-edit-warn-preview": "پێشبینینی پەیامی ھەڵبژێردراو نیشانبدە", "abusefilter-edit-warn-edit": "پەیامی ھەڵبژێردراو دروست/دەستکاری بکە", + "abusefilter-edit-disallow-other": "پەیامی تر", + "abusefilter-edit-disallow-other-label": "ناوی پەڕەی پەیامی تر:\n:''(بێ پێشگری \"میدیاویکی:\")''", + "abusefilter-edit-disallow-actions": "کردەوەکان", + "abusefilter-edit-disallow-edit": "پەیامی ھەڵبژێردراو دەستکاری بکە/دروست بکە", "abusefilter-edit-tag-tag": "[[Special:Tags|تاگەکان]] بۆ چەسپاندن (ھەر کامیان لە دێڕێکدا):", "abusefilter-edit-denied": "ناتوانی وردەکارییەکانی ئەم پاڵوێنەیە ببینی، چونکوو لەبەر چاوی گشتی شاردراوەتەوە.", "abusefilter-edit-main": "پارامەترەکانی پاڵوێنە", @@ -164,9 +190,11 @@ "abusefilter-edit-builder-vars-page-ns": "بۆشاییی ناوی پەڕە", "abusefilter-edit-builder-vars-page-title": "سەرناوی پەڕە (بەبێ بۆشاییی ناو)", "abusefilter-edit-builder-vars-page-prefixedtitle": "سەرناوی تەواوی پەڕە", + "abusefilter-edit-builder-vars-movedfrom-title": "ناونیشانی گواستنەوەی سەرچاوەی پەڕە", "abusefilter-edit-builder-vars-user-editcount": "ژمارەی دەستکارییەکانی بەکارھێنەر", - "abusefilter-edit-builder-vars-user-age": "تەمەنی ھەژماری بەکارھێنەر", + "abusefilter-edit-builder-vars-user-age": "تەمەنی ھەژماری بەکارھێنەرەکە", "abusefilter-edit-builder-vars-user-name": "ناوی ھەژماری بەکارھێنەر", + "abusefilter-edit-builder-vars-new-wikitext": "پەڕەی نوێی ویکیدەق، پاش دەستکاری", "abusefilter-filter-log": "دوایین گۆڕانکارییەکانی پاڵوێنە", "abusefilter-history": "مێژووی گۆڕانکاری بۆ پاڵوێنەی کەڵکاوەژوو #$1", "abusefilter-history-foruser": "گۆڕانکارییەکان لە لایەن $1", @@ -196,7 +224,7 @@ "abusefilter-action-disallow": "بەرگرتن", "abusefilter-revert-title": "ھەموو گۆڕانکارییەکان لە لایەن پاڵوێنەی $1ەوە بگەڕێنەوە", "abusefilter-revert-search": "ھەڵبژاردنی کردەوەکان", - "abusefilter-revert-filter": "پاڵوێنە:", + "abusefilter-revert-filter": "پێناسەی پاڵوێنە:", "abusefilter-revert-confirm": "پشتدار بکەرەوە", "abusefilter-revert-reasonfield": "ھۆکار:", "abusefilter-test": "ئەم پاڵوێنەیە لەسەر دەستکارییەکانی پێشوو تاقی بکەوە", @@ -208,6 +236,12 @@ "abusefilter-test-period-start": "گۆڕانکارییەکانی پاش:", "abusefilter-test-period-end": "گۆڕانکارییەکانی پێش:", "abusefilter-test-page": "گۆڕانکارییەکانی پەڕەی:", + "abusefilter-test-search-type-all": "ھەموو کارەکان", + "abusefilter-test-search-type-edit": "دەستکارییەکان", + "abusefilter-test-search-type-move": "گوێزەرەوەکان", + "abusefilter-test-search-type-delete": "پەیوەندیەکان", + "abusefilter-test-search-type-upload": "بارکردنەکان", + "abusefilter-test-search-type-createaccount": "دروستکردنی ھەژمار", "abusefilter-changeslist-examine": "تاقیکردنەوە", "abusefilter-examine": "تاقیکردنەوەی یەکەیەکەی گۆڕانکارییەکان", "abusefilter-examine-legend": "ھەڵبژاردنی گۆڕانکارییەکان", @@ -224,8 +258,9 @@ "abusefilter-topnav-examine": "تاقیکردنەوەی دەستکارییەکانی پێشوو", "abusefilter-topnav-log": "لۆگی کەڵکاوەژوو", "abusefilter-topnav-tools": "ئامرازەکانی سڕینەوەی کەموکووڕی", - "abusefilter-topnav-import": "ھاوردنی پاڵوێنە", "abusefilter-log-name": "لۆگی پاڵوێنەی کەڵکاوەژوو", + "abusefilter-logentry-create": "$1 {{GENDER:$2|دروستکرا}} $4 ($5)", + "abusefilter-logentry-modify": "$1 {{GENDER:$2|دەستکاریی}} $4ی کرد ($5)", "abusefilter-log-noresults": "هیچ ئەنجامێک نییە", "abusefilter-diff-title": "جیاوازیی نێوان پێداچوونەوەکان", "abusefilter-diff-item": "بابەت", diff --git a/AbuseFilter/i18n/cs.json b/AbuseFilter/i18n/cs.json index 3728d242..e794f071 100644 --- a/AbuseFilter/i18n/cs.json +++ b/AbuseFilter/i18n/cs.json @@ -2,27 +2,27 @@ "@metadata": { "authors": [ "Chmee2", + "Cvanca", + "Danny B.", + "Dvorapa", + "Ilimanaq29", + "Martin Urbanec", + "Matma Rex", "Matěj Grabovský", "Matěj Suchánek", "Michaelbrabec", "Mormegil", + "Patriccck", "Paxt", "Tchoř", - "Vks", - "Cvanca", + "Teslaton", "Urbanecm", - "Matma Rex", - "Martin Urbanec", - "Dvorapa", - "Danny B.", - "Ilimanaq29", - "Patriccck", - "Teslaton" + "Vks" ] }, "abusefilter-desc": "Podrobuje editace automatickým heuristikám", - "abusefilter": "Konfigurace filtrů zneužití", - "abuselog": "Protokol zneužití", + "abusefilter": "Správa filtrů zneužití", + "abuselog": "Protokol filtrů zneužití", "abusefilter-intro": "Vítejte v rozhraní pro správu filtrů zneužití.\nFiltry zneužití jsou automatický softwarový mechanismus, prostřednictvím kterého se všechny operace testují pomocí automatických heuristik.\nV tomto rozhraní můžete vidět seznam definovaných filtrů a měnit je.", "abusefilter-mustviewprivateoredit": "Z bezpečnostních důvodů mohou toto rozhraní používat pouze uživatelé s oprávněním spravovat filtry zneužití nebo prohlížet tajné filtry.", "abusefilter-warning": "'''Upozornění:''' Tato činnost byla automaticky identifikována jako škodlivá.\nNeužitečné aktivity budou rychle revertovány, v opakovaných nebo závažných případech mohou být váš uživatelský účet či IP adresa zablokovány.\nPokud považujete svou editaci za správnou, můžete ji potvrdit opětovným kliknutím na Uložit změny.\nStručný popis pravidla, které vaši činnost označilo za škodlivou: $1", @@ -33,13 +33,14 @@ "abusefilter-blocker": "Filtr zneužití", "abusefilter-blockreason": "Automaticky zablokováno filtrem zneužití.\nPopis použitého pravidla: $1", "abusefilter-degroupreason": "Práva automaticky odebrána filtrem zneužití.\nPopis pravidla: $1", + "abusefilter-blockautopromotereason": "Automatické potvrzení automaticky pozastaveno filtrem zneužití.\nPopis pravidla: $1", "abusefilter-accountreserved": "Toto uživatelské jméno je vyhrazeno pro filtr zneužití.", - "right-abusefilter-modify": "Upravování filtrů zneužití", + "right-abusefilter-modify": "Vytváření nebo upravování filtrů zneužití", "right-abusefilter-view": "Prohlížení filtrů zneužití", "right-abusefilter-log": "Prohlížení protokolu zneužití", "right-abusefilter-log-detail": "Prohlížení podrobností v protokolu zneužití", - "right-abusefilter-private": "Prohlížení tajných údajů v protokolu zneužití", - "right-abusefilter-private-log": "Prohlížení záznamů přístupu k soukromým detailům filtrů zneužití", + "right-abusefilter-privatedetails": "Prohlížení tajných údajů v protokolu zneužití", + "right-abusefilter-privatedetails-log": "Prohlížení záznamů přístupu k soukromým detailům filtrů zneužití", "right-abusefilter-modify-restricted": "Upravování filtrů zneužití s omezenými opatřeními", "right-abusefilter-revert": "Revertování všech změn provedených vybraným filtrem zneužití", "right-abusefilter-view-private": "Prohlížení filtrů zneužití označených jako tajné", @@ -51,17 +52,22 @@ "action-abusefilter-view": "prohlížet si filtry zneužití", "action-abusefilter-log": "prohlížet si protokol zneužití", "action-abusefilter-log-detail": "prohlížet si podrobnosti v protokolu zneužití", - "action-abusefilter-private": "prohlížet si tajné údaje v protokolu zneužití", - "action-abusefilter-private-log": "prohlížet si záznamy přístupu k soukromým detailům filtrů zneužití", + "action-abusefilter-privatedetails": "prohlížet si tajné údaje v protokolu zneužití", + "action-abusefilter-privatedetails-log": "prohlížet si záznamy přístupu k soukromým detailům filtrů zneužití", "action-abusefilter-modify-restricted": "upravovat filtry zneužití s omezenými opatřeními", "action-abusefilter-revert": "revertovat všechny změny provedené vybraným filtrem zneužití", "action-abusefilter-view-private": "prohlížet si filtry zneužití označené jako tajné", "action-abusefilter-log-private": "prohlížet protokoly filtrů zneužití označených jako tajné", - "abusefilter-log": "Protokol filtrů zneužití", + "action-abusefilter-hide-log": "skrývat záznamy v protokolu zneužití", + "action-abusefilter-hidden-log": "prohlížet si skryté záznamy v protokolu zneužití", + "action-abusefilter-modify-global": "vytvářet nebo editovat globální filtry zneužití", "abusefilter-log-summary": "Tento protokol obsahuje seznam všech operací zachycených filtry.", "abusefilter-log-search": "Hledat v protokolu zneužití", "abusefilter-log-search-user": "Uživatel:", - "abusefilter-log-search-filter": "ID filtrů (oddělte svislítky):", + "abusefilter-log-search-group": "Skupina filtrů:", + "abusefilter-log-search-group-any": "Kterákoliv", + "abusefilter-log-search-filter": "ID filtrů:", + "abusefilter-log-search-filter-help": "Oddělte svislítky, u globálních filtrů začněte „$1“", "abusefilter-log-search-title": "Název:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-impact": "Účinek:", @@ -90,7 +96,7 @@ "abusefilter-log-details-var": "Proměnná", "abusefilter-log-details-val": "Hodnota", "abusefilter-log-details-vars": "Parametry akce", - "abusefilter-log-details-private": "Soukromé detaily záznamu", + "abusefilter-log-details-privatedetails": "Soukromé detaily", "abusefilter-log-details-ip": "Zdrojová IP adresa", "abusefilter-log-details-checkuser": "Zkontrolovat uživatele", "abusefilter-log-noactions": "žádná", @@ -99,10 +105,11 @@ "abusefilter-log-linkoncontribs-text": "Protokol zneužití pro {{GENDER:$1|tohoto uživatele|tuto uživatelku}}", "abusefilter-log-linkonhistory": "zobrazit záznamy filtrů zneužití", "abusefilter-log-linkonhistory-text": "Zobrazit záznamy filtrů zneužití k této stránce", - "abusefilter-log-hidden": "(skrytý záznam)", + "abusefilter-log-linkonundelete": "zobrazit záznamy filtrů zneužití", + "abusefilter-log-linkonundelete-text": "Zobrazit záznamy filtrů zneužití k této stránce", "abusefilter-log-hidden-implicit": "(skryto, protože byla odstraněna revize)", "abusefilter-log-cannot-see-details": "Nemáte oprávnění k prohlížení podrobností tohoto záznamu.", - "abusefilter-log-cannot-see-private-details": "Nemáte dovoleno prohlížet si soukromé detaily tohoto záznamu.", + "abusefilter-log-cannot-see-privatedetails": "Nemáte dovoleno prohlížet si soukromé detaily tohoto záznamu.", "abusefilter-log-nonexistent": "Záznam s uvedeným ID neexistuje.", "abusefilter-log-details-hidden": "U tohoto záznamu si nemůžete prohlédnout podrobnosti, protože byly před veřejností skryty.", "abusefilter-log-details-hidden-implicit": "U tohoto záznamu si nemůžete prohlédnout podrobnosti, protože s ním související revize byla skryta před veřejností.", @@ -120,9 +127,12 @@ "log-action-filter-abusefilter-create": "Vytvoření nového filtru", "log-action-filter-abusefilter-modify": "Úprava filtru", "log-action-filter-suppress-abuselog": "Utajení záznamu filtru zneužití", + "log-action-filter-rights-blockautopromote": "Zablokování automatického potvrzení", + "log-action-filter-rights-restoreautopromote": "Obnova automatického potvrzení", "logentry-abusefilterprivatedetails-access": "$1 si {{GENDER:$2|prohlédl|prohlédla}} soukromé detaily k $3", + "logentry-rights-blockautopromote": "$1 {{GENDER:$2|zablokoval|zablokovala}} automatické potvrzení {{GENDER:$4|uživatele|uživatelky}} $3 na dobu $5", + "logentry-rights-restoreautopromote": "$1 {{GENDER:$2|obnovil|obnovila}} možnost automatického potvrzení {{GENDER:$4|uživatele|uživatelky}} $3", "abusefilterprivatedetails-log-name": "Kniha přístupů k soukromým detailům filtrů zneužití", - "abusefilter-management": "Správa filtrů zneužití", "abusefilter-list": "Všechny filtry", "abusefilter-list-id": "ID filtru", "abusefilter-list-pattern": "Výraz", @@ -144,6 +154,7 @@ "abusefilter-throttled": "omezený", "abusefilter-hitcount": "$1 {{PLURAL:$1|zásah|zásahy|zásahů}}", "abusefilter-new": "Vytvořit nový filtr", + "abusefilter-import-button": "Import filtru", "abusefilter-return": "Vrátit se na správu filtrů", "abusefilter-status-global": "Globální", "abusefilter-list-options": "Možnosti", @@ -164,26 +175,29 @@ "abusefilter-list-options-search-like": "Obyčejný výraz", "abusefilter-list-options-search-rlike": "Regulární výraz", "abusefilter-list-options-search-irlike": "Regulární výraz nerozlišující velikost písmen", + "abusefilter-list-invalid-searchmode": "Uvedený způsob hledání je neplatný.", "abusefilter-list-regexerror": "Při hledání došlo k chybě: Chyba v syntaxi regulárního výrazu.", "abusefilter-list-options-submit": "Aktualizovat", "abusefilter-tools-text": "Zde jsou uvedeny některé nástroje, které se mohou hodit při přípravě a ladění filtrů zneužití.", "abusefilter-tools-expr": "Testování výrazů", "abusefilter-tools-submitexpr": "Vyhodnotit", + "abusefilter-tools-syntax-error": "Filtr má chybnou syntaxi.", "abusefilter-tools-reautoconfirm": "Obnovit příznak schváleného uživatele", "abusefilter-tools-reautoconfirm-user": "Uživatel:", "abusefilter-tools-reautoconfirm-submit": "Obnovit schválení", + "abusefilter-tools-restoreautopromote": "Automatické potvrzení obnoveno skrze nástroje filtrů zneužití.", "abusefilter-reautoconfirm-none": "{{GENDER:$1|Tomuto uživateli|Této uživatelce|Tomuto uživateli}} nebyl příznak schváleného uživatele odebrán.", "abusefilter-reautoconfirm-notallowed": "Nemáte oprávnění obnovovat příznak schváleného uživatele.", "abusefilter-reautoconfirm-done": "Příznak schváleného uživatele byl obnoven", - "abusefilter-status": "{{PLURAL:$1|Při poslední operaci|Z posledních $1 operací}} {{PLURAL:$2|překročila|překročily|překročilo}} $2 ($3 %) limit $4 podmínek a $5 ($6 %) {{PLURAL:$5|byla zachycena|byly zachyceny|bylo zachyceno}} jedním ze zapnutých filtrů.", + "abusefilter-status": "{{PLURAL:$1|Při poslední operaci|Z posledních $1 operací}} {{PLURAL:$2|překročila|překročily|překročilo}} $2 ($3 %) limit $4 podmínek a $5 ($6 %) {{PLURAL:$5|byla zachycena|byly zachyceny|bylo zachyceno}} alespoň jedním ze zapnutých filtrů.", "abusefilter-edit": "Editace filtru zneužití", "abusefilter-edit-subtitle": "Editace filtru $1", "abusefilter-edit-subtitle-new": "Vytvoření filtru", "abusefilter-edit-token-not-match": "Editace nebyla uložena! Prosím zkuste to znovu.", "abusefilter-edit-oldwarning": "<strong>Editujete starší verzi tohoto filtru. Uvedené statistiky platí pro aktuální verzi. Pokud uložíte své změny, přepíšete všechny novější úpravy.</strong> • [[Special:AbuseFilter/history/$2|Vrátit se na historii tohoto filtru]].", + "abusefilter-edit-oldwarning-view": "<strong>Prohlížíte si starší verzi tohoto filtru. Uvedené statistiky platí pro aktuální verzi.</strong> • [[Special:AbuseFilter/history/$2|Vrátit se na historii tohoto filtru]].", "abusefilter-edit-status-label": "Statistika:", - "abusefilter-edit-status": "Z {{PLURAL:$1|1 poslední operace|posledních $1 operací}} tomuto filtru {{PLURAL:$2|odpovídala|odpovídaly|odpovídalo}} $2 ($3 %).", - "abusefilter-edit-status-profile": "Z {{PLURAL:$1|1 poslední operace|posledních $1 operací}} tomuto filtru {{PLURAL:$2|odpovídala|odpovídaly|odpovídalo}} $2 ($3 %).\nPrůměrná doba běhu filtru je $4 ms, filtr potřebuje $5 z dovoleného počtu podmínek.", + "abusefilter-edit-status": "Z {{PLURAL:$1|1 poslední operace|posledních $1 operací}} tomuto filtru {{PLURAL:$2|odpovídala|odpovídaly|odpovídalo}} $2 ($3 %).\nPrůměrná doba běhu filtru je $4 ms, filtr potřebuje $5 z dovoleného počtu podmínek.", "abusefilter-edit-throttled-warning": "'''Varování:''' Tento filtr byl automaticky označen jako škodlivý. Z bezpečnostních důvodů nebudou vykonávány následující akce: $1. Pro odstranění tohoto omezení prosím zkontrolujte a [[mw:Extension:AbuseFilter/Conditions|optimalizujte]] podmínky.", "abusefilter-edit-new": "Nový filtr", "abusefilter-edit-save": "Uložit filtr", @@ -216,13 +230,18 @@ "abusefilter-edit-throttle-count": "Počet dovolených akcí:", "abusefilter-edit-throttle-period": "Časový interval (v sekundách):", "abusefilter-edit-throttle-groups": "Limity počítat odděleně pro:", - "abusefilter-edit-throttle-ip": "IP adresa", - "abusefilter-edit-throttle-user": "Uživatelský účet", - "abusefilter-edit-throttle-range": "Rozsah /16", - "abusefilter-edit-throttle-creationdate": "Serverový čas vytvoření účtu", - "abusefilter-edit-throttle-editcount": "Počet editací", - "abusefilter-edit-throttle-site": "Celý web", - "abusefilter-edit-throttle-page": "Stránka", + "abusefilter-edit-throttle-groups-help": "Viz $1.", + "abusefilter-edit-throttle-groups-help-text": "dokumentaci na mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Pro spojení pomocí AND oddělujte čárkami, pro spojení pomocí OR oddělujte řádkovými zlomy", + "abusefilter-edit-throttle-placeholder": "Pro spojení pomocí AND oddělujte čárkami, pro spojení pomocí OR vkládejte jeden po druhém", + "abusefilter-throttle-ip": "IP adresa", + "abusefilter-throttle-user": "uživatelský účet", + "abusefilter-throttle-range": "rozsah /16", + "abusefilter-throttle-creationdate": "datum založení účtu", + "abusefilter-throttle-editcount": "počet editací", + "abusefilter-throttle-site": "celý web", + "abusefilter-throttle-page": "stránka", + "abusefilter-throttle-none": "(žádné)", "abusefilter-throttle-details": "Dovolit $1 {{PLURAL:$1|akci|akce|akcí}} {{PLURAL:$2|každou sekundu|každé $2 sekundy|každých $2 sekund}}, limity počítané pro: $3", "abusefilter-edit-warn-message": "Systémové hlášení zobrazené jako varování:", "abusefilter-edit-warn-other": "Jiné hlášení", @@ -239,9 +258,9 @@ "abusefilter-edit-tag-tag": "[[Special:Tags|Značky]], které se mají přidat:", "abusefilter-edit-tag-placeholder": "Přidat značky (samostatně nebo oddělené čárkami)", "abusefilter-edit-tag-hidden-placeholder": "Přidat značky (oddělené čárkami)", - "abusefilter-edit-block-anon-durations": "Doba trvání bloku pro anonymní uživatele:", + "abusefilter-edit-block-anon-durations": "Doba trvání bloku pro neregistrované uživatele:", "abusefilter-edit-block-user-durations": "Doba trvání bloku pro registrované uživatele:", - "abusefilter-block-anon": "Blokovat anonymní uživatele", + "abusefilter-block-anon": "Blokovat neregistrované uživatele", "abusefilter-block-user": "Blokovat registrované uživatele", "abusefilter-block-talk": "diskusní stránka blokována", "abusefilter-edit-denied": "Nemůžete se podívat na detaily tohoto filtru, protože není veřejný", @@ -262,10 +281,18 @@ "abusefilter-edit-export": "Export tohoto filtru pro jinou wiki", "abusefilter-edit-syntaxok": "Nebyly nalezeny žádné syntaktické chyby.", "abusefilter-edit-syntaxerr": "Nalezena syntaktická chyba: $1", + "abusefilter-edit-warn-leave": "Opuštěním této stránky ztratíte jakékoliv změny tohoto filtru.", "abusefilter-edit-bad-tags": "Jedna či více uvedených značek nejsou platné.\nZnačky by měly být krátké, nesmějí obsahovat žádné zvláštní znaky a nesmějí být obsazené softwarem. Zkuste značce vybrat jiný název.", "abusefilter-edit-notallowed": "Nemáte oprávnění vytvářet nebo editovat filtry zneužití", "abusefilter-edit-notallowed-global": "Nemáte oprávnění vytvářet nebo editovat globální filtry zneužití", - "abusefilter-edit-notallowed-global-custom-msg": "U globálních filtrů nejsou podporována vlastní varovná hlášení.", + "abusefilter-edit-notallowed-global-custom-msg": "U globálních filtrů nejsou podporována vlastní varovná či zákazová hlášení", + "abusefilter-edit-invalid-warn-message": "Varovné hlášení nelze ponechat prázdné.", + "abusefilter-edit-invalid-disallow-message": "Zákazové hlášení nelze ponechat prázdné.", + "abusefilter-edit-invalid-throttlecount": "Počet dovolených akcí musí být kladné celé číslo.", + "abusefilter-edit-invalid-throttleperiod": "Časový interval musí být kladné celé číslo.", + "abusefilter-edit-empty-throttlegroups": "Musí být vybrána alespoň jedna skupina.", + "abusefilter-edit-duplicated-throttlegroups": "Skupiny nemohou být uvedeny duplicitně.", + "abusefilter-edit-invalid-throttlegroups": "Uvedené skupiny nejsou platné.", "abusefilter-edit-builder-select": "Vyberte položku, bude přidána na místo, kde je kurzor", "abusefilter-edit-builder-group-op-arithmetic": "Aritmetické operátory", "abusefilter-edit-builder-op-arithmetic-addition": "Sčítání (+)", @@ -295,7 +322,8 @@ "abusefilter-edit-builder-misc-contains": "Řetězec vpravo je obsažen v řetězci vlevo (contains)", "abusefilter-edit-builder-misc-stringlit": "Řetězcový literál (\"\")", "abusefilter-edit-builder-misc-tern": "Ternární operátor (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Podmínka (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Podmínka (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "Krátká podmínka (if X then Y end)", "abusefilter-edit-builder-group-funcs": "Funkce", "abusefilter-edit-builder-funcs-length": "Délka řetězce (length)", "abusefilter-edit-builder-funcs-lcase": "Převést na malá písmena (lcase)", @@ -366,12 +394,12 @@ "abusefilter-edit-builder-vars-all-links": "Všechny externí odkazy ve výsledném textu", "abusefilter-edit-builder-vars-added-links": "Všechny externí odkazy přidané při editaci", "abusefilter-edit-builder-vars-removed-links": "Všechny externí odkazy odstraněné při editaci", - "abusefilter-edit-builder-vars-old-text": "Původní zdrojový text stránky před editací (už se nepoužívá)", - "abusefilter-edit-builder-vars-new-text": "Nový zdrojový text stránky po editaci", + "abusefilter-edit-builder-vars-old-wikitext": "Původní zdrojový text stránky před editací", + "abusefilter-edit-builder-vars-new-wikitext": "Nový zdrojový text stránky po editaci", "abusefilter-edit-builder-vars-new-pst": "Wikitext nové stránky po transformaci před uložením", "abusefilter-edit-builder-vars-diff-pst": "Unifikovaný rozdíl změn způsobených editací, po transformaci před uložením", "abusefilter-edit-builder-vars-addedlines-pst": "Řádky přidané při editaci, po transformaci před uložením", - "abusefilter-edit-builder-vars-new-text-stripped": "Nový text stránky zbavený formátování", + "abusefilter-edit-builder-vars-new-text": "Nový text stránky zbavený formátování", "abusefilter-edit-builder-vars-new-html": "Vygenerovaný HTML kód nové verze", "abusefilter-edit-builder-vars-restrictions-edit": "Úroveň zamčení stránky pro editaci", "abusefilter-edit-builder-vars-restrictions-move": "Úroveň zamčení stránky pro přesun", @@ -385,10 +413,10 @@ "abusefilter-edit-builder-vars-movedto-restrictions-move": "Úroveň zamčení stránky, na kterou se přesouvá, pro přesun", "abusefilter-edit-builder-vars-movedto-restrictions-create": "Úroveň zamčení stránky, na kterou se přesouvá, pro založení stránky", "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Úroveň zamčení stránky, na kterou se přesouvá, pro načtení souboru", - "abusefilter-edit-builder-vars-old-text-stripped": "Původní text stránky bez všech značek", + "abusefilter-edit-builder-vars-old-text": "Původní text stránky bez všech značek (už se nepoužívá)", "abusefilter-edit-builder-vars-old-links": "Odkazy na stránce před editací", "abusefilter-edit-builder-vars-old-html": "Původní text stránky naformátovaný do HTML (už se nepoužívá)", - "abusefilter-edit-builder-vars-minor-edit": "Zda byla editace označena jako malá", + "abusefilter-edit-builder-vars-minor-edit": "Zda byla editace označena jako malá (už se nepoužívá)", "abusefilter-edit-builder-vars-file-sha1": "SHA-1 otisk obsahu souboru", "abusefilter-edit-builder-vars-file-size": "Velikost souboru v bajtech", "abusefilter-edit-builder-vars-file-mime": "MIME typ souboru", @@ -396,6 +424,8 @@ "abusefilter-edit-builder-vars-file-width": "Šířka souboru v pixelech", "abusefilter-edit-builder-vars-file-height": "Výška souboru v pixelech", "abusefilter-edit-builder-vars-file-bits-per-channel": "Barevná hloubka souboru v bitech na barevný kanál", + "abusefilter-edit-builder-vars-wiki-name": "Databázový název wiki", + "abusefilter-edit-builder-vars-wiki-language": "Kód jazyka wiki", "abusefilter-filter-log": "Poslední změny filtrů", "abusefilter-history": "Historie změn filtru zneužití #$1", "abusefilter-history-foruser": "Změny provedené uživatelem $1", @@ -429,13 +459,16 @@ "abusefilter-exception-dividebyzero": "Neplatný pokus o dělení čísla $2 nulou na pozici $1.", "abusefilter-exception-unrecognisedvar": "Neznámá proměnná $2 na pozici $1", "abusefilter-exception-notenoughargs": "Nedostatek parametrů při volání funkce $2 na pozici $1.\n{{PLURAL:$3|Očekáván 1 parametr|Očekávány $3 parametry|Očekáváno $3 parametrů}}, volání používá $4.", - "abusefilter-exception-regexfailure": "Chyba v regulárním výrazu „$3“ na znaku $1: „$2“", + "abusefilter-exception-toomanyargs": "Nedostatek parametrů při volání funkce $2 na pozici $1.\n{{PLURAL:$3|Očekáván nejvýše 1 parametr|Očekávány nejvýše $3 parametry|Očekáváno nejvýše $3 parametrů}}, volání používá $4.", + "abusefilter-exception-regexfailure": "Chyba v regulárním výrazu „$2“ na pozici $1.", "abusefilter-exception-overridebuiltin": "Nedovolené předefinování vestavěné proměnné „$2“ na pozici $1.", "abusefilter-exception-outofbounds": "Na pozici $1 požadována neexistující $2. položka pole (velikost pole = $3).", + "abusefilter-exception-negativeindex": "Záporné indexy v polích nejsou dovoleny. Použit index „$2“ na pozici $1.", "abusefilter-exception-notarray": "Na pozici $1 požadován prvek pole po proměnné, která není pole.", - "abusefilter-exception-unclosedcomment": "Neuzavřený komentář na znaku $1.", + "abusefilter-exception-unclosedcomment": "Neuzavřený komentář na pozici $1.", "abusefilter-exception-invalidiprange": "Neplatný rozsah IP adres „$2“ na pozici $1.", "abusefilter-exception-disabledvar": "Proměnná $2 na pozici $1 se už nepoužívá.", + "abusefilter-exception-variablevariable": "set a set_var očekávají, že první argument bude řetězcový literál, nalezeno na pozici $1.", "abusefilter-action-tag": "Značka", "abusefilter-action-throttle": "Omezení", "abusefilter-action-warn": "Varování", @@ -453,7 +486,7 @@ "abusefilter-revert-search": "Vybrat operace", "abusefilter-revert-filter": "ID filtru:", "abusefilter-revert-preview-intro": "Níže jsou uvedeny operace provedené filtrem zneužití, které budou tímto vráceny.\nPečlivě je zkontrolujte a kliknutím na „{{int:abusefilter-revert-confirm}}“ můžete jejich vrácení schválit.", - "abusefilter-revert-confirm-legend": "Potvrdit revert", + "abusefilter-revert-confirm-legend": "Potvrdit vrácení zpět", "abusefilter-revert-confirm": "Potvrdit", "abusefilter-revert-success": "Všechny operace, které filtr zneužití provedl na základě [[Special:AbuseFilter/$1|filtru $2]], byly vráceny.", "abusefilter-revert-reason": "Automatické vrácení všech operací, které filtr zneužití provedl kvůli filtru $1.\nUvedený důvod: $2", @@ -498,15 +531,16 @@ "abusefilter-examine-noresults": "Podle zadaných parametrů nebyly nalezeny žádné výsledky.", "abusefilter-topnav": "'''Navigace po filtru zneužití'''", "abusefilter-topnav-home": "Hlavní stránka", + "abusefilter-topnav-recentchanges": "Poslední změny filtrů", "abusefilter-topnav-test": "Hromadné testování", "abusefilter-topnav-examine": "Prozkoumat minulé editace", "abusefilter-topnav-log": "Protokol filtrů zneužití", "abusefilter-topnav-tools": "Ladicí nástroje", - "abusefilter-topnav-import": "Import filtru", "abusefilter-log-name": "Kniha filtrů zneužití", "abusefilter-log-header": "Tento protokol obsahuje přehled změn filtrů.\nÚplné podrobnosti naleznete v [[Special:AbuseFilter/history|seznamu posledních změn filtrů]].", "abusefilter-logentry-create": "$1 {{GENDER:$2|vytvořil|vytvořila}} $4 ($5)", "abusefilter-logentry-modify": "$1 {{GENDER:$2|upravil|upravila|upravil(a)}} $4 ($5)", + "abusefilter-log-invalid-filter": "Některá uvedená ID filtrů jsou neplatná.", "abusefilter-log-noresults": "Žádné výsledky", "abusefilter-diff-title": "Rozdíly mezi verzemi", "abusefilter-diff-item": "Položka", @@ -519,11 +553,12 @@ "abusefilter-diff-next": "Novější změna", "abusefilter-import-intro": "Pomocí tohoto rozhraní můžete importovat filtry z jiných wiki.\nNa zdrojové wiki klikněte v editačním rozhraní na „{{int:abusefilter-edit-export}}“ v sekci „{{int:abusefilter-edit-tools}}“.\nZkopírujte si text, který se objeví v rámečku, vložte ho do tohoto formuláře a klikněte na „{{int:abusefilter-import-submit}}“.", "abusefilter-import-submit": "Importovat data", + "abusefilter-import-invalid-data": "Data, která jste se {{GENDER:|pokusil|pokusila|pokusili}} naimportovat, nejsou platná", "abusefilter-group-default": "Výchozí", "abusefilter-http-error": "Došlo k chybě HTTP: $1.", - "abusefilter-view-private-submit": "Zobrazit soukromé detaily", - "abusefilter-view-private": "Zobrazit soukromé detaily", - "abusefilter-view-private-reason": "Důvod přístupu k soukromým detailům:", + "abusefilter-view-privatedetails-submit": "Zobrazit soukromé detaily", + "abusefilter-view-privatedetails-legend": "Zobrazit soukromé detaily", + "abusefilter-view-privatedetails-reason": "Důvod přístupu k soukromým detailům:", "abusefilter-log-details-id": "ID protokolovacího záznamu", "abusefilter-invalid-request": "Neplatný požadavek! K soukromým detailům záznamu musíte jít skrze formulář na stránce [[Special:AbuseLog/$1]] a musíte uvést důvod.", "abusefilter-invalid-request-noid": "Neplatný požadavek! K soukromým detailům záznamu musíte jít skrze formulář na stránce podrobností záznamu zneužití a musíte uvést důvod.", diff --git a/AbuseFilter/i18n/cv.json b/AbuseFilter/i18n/cv.json index 11fef7cd..8b6b4cdd 100644 --- a/AbuseFilter/i18n/cv.json +++ b/AbuseFilter/i18n/cv.json @@ -1,13 +1,12 @@ { "@metadata": { "authors": [ - "Salam", + "Chuvash", "Chuvash2014", - "Chuvash" + "Salam" ] }, "abuselog": "Фильтрсен журналĕ", - "abusefilter-log": "Фильтрсен журналĕ", "abusefilter-log-search": "Фильтрсен журналĕнче шырани", "abusefilter-log-search-user": "Усă куракан:", "abusefilter-log-search-filter": "Ала идентификаторӗ", @@ -23,7 +22,7 @@ "abusefilter-log-details-var": "Улшӑнакан", "abusefilter-log-details-val": "Пӗлтерӗш", "abusefilter-log-details-vars": "Ӗҫ ӗнерленӗвӗсем", - "abusefilter-log-details-private": "Харпӑр пӗлӗмлӗхӗ", + "abusefilter-log-details-privatedetails": "Харпӑр пӗлӗмлӗхӗ", "abusefilter-log-details-ip": "Хутшӑнаканӑн IP адресӗ", "abusefilter-log-noactions": "ҫук", "abusefilter-log-details-diff": "Улшӑнури улӑштарӑвӗсем", diff --git a/AbuseFilter/i18n/cy.json b/AbuseFilter/i18n/cy.json index a6928d14..bbf56234 100644 --- a/AbuseFilter/i18n/cy.json +++ b/AbuseFilter/i18n/cy.json @@ -8,8 +8,7 @@ ] }, "abusefilter-desc": "Yn gosod tybiaethau i olygiadau'n awtomatig", - "abusefilter": "Ffurfweddiad hidlydd camddefnydd", - "abuselog": "Log camddefnydd", + "abuselog": "Log hidlydd camddefnydd", "abusefilter-intro": "Croeso i'r rhyngwyneb rheoli'r Hidlydd Camddefnydd.\nMeddalwedd awtomatig sy'n ymateb yn dybiaethol i bobl gweithred yw'r Hildydd Camddefnydd.\nMae'r rhyngwyneb hwn yn arddangos rhestr o hidlyddion penodedig, sy'n eu galluogi i gael eu haddasu.", "abusefilter-warning": "'''Rhybudd:''' Mae'r weithred hon wedi'i dyfarnu'n awtomatig fel gweithred niweidiol.\nBydd golygiadau anadeiladol yn cael eu gwrthdroi'n syth, a bydd cyfrif neu gyfeiriad IP defnyddwyr sy'n parhau i olygu'n anadeiladol yn cael eu blocio.\nOs ydych o'r farn fod y weithred hon yn adeiladol, gallwch ei chyflwyno unwaith eto er mwyn ei chadarnhau.\nDisgrifiad byr o'r rheol camddefnydd y mae'ch gweithred chi yn cyfateb ag ef yw: $1", "abusefilter-disallowed": "Clustnododd y meddalwedd y weithred hon yn un niweidiol, felly ni weithredwyd hi.\nOs ydych yn meddwl bod y weithred o ddefnydd, rhowch wybod i weinyddwr am ddiben y weithred.\nDyma ddisgrifiad byr o'r rheol camddefnydd yr oedd y weithred yn cyfateb iddi: $1", @@ -20,7 +19,7 @@ "right-abusefilter-view": "Gweler hidlyddion camddefnydd", "right-abusefilter-log": "Gweler y log camddefnydd", "right-abusefilter-log-detail": "Gweler cofnodion manwl y log camddefnydd", - "right-abusefilter-private": "Gweler data preifat yn y log camddefnydd", + "right-abusefilter-privatedetails": "Gweler data preifat yn y log camddefnydd", "right-abusefilter-modify-restricted": "Addasu hidlyddion camddefnydd gyda gweithredoedd cyfyngedig.", "right-abusefilter-revert": "Gwrthdroi pob newid a wnaed gan hidlydd camddefnydd penodol", "right-abusefilter-view-private": "Gweler hidlyddion camddefnydd a nodwyd yn breifat", @@ -30,11 +29,10 @@ "action-abusefilter-view": "gweler hidlyddion camddefnydd", "action-abusefilter-log": "gweler y log camddefnydd", "action-abusefilter-log-detail": "gweler cofnodion manwl y log camddefnydd", - "action-abusefilter-private": "gweler data preifat yn y log camddefnydd", + "action-abusefilter-privatedetails": "gweler data preifat yn y log camddefnydd", "action-abusefilter-modify-restricted": "addasu hidlyddion camddefnydd gyda gweithredoedd cyfyngedig.", "action-abusefilter-revert": "gwrthdroi pob newid a wnaed gan hidlydd camddefnydd penodol", "action-abusefilter-view-private": "gweler hidlyddion camddefnydd a nodwyd yn breifat", - "abusefilter-log": "Log hidlydd camddefnydd", "abusefilter-log-summary": "Dengys y log hwn restr o'r holl weithredodd a nodwyd gan yr hidlyddion.", "abusefilter-log-search": "Chwilier y log camddefnydd", "abusefilter-log-search-user": "Defnyddiwr:", @@ -48,13 +46,12 @@ "abusefilter-log-details-legend": "Manylion ar gyfer cofnodion log $1", "abusefilter-log-details-var": "Newidyn", "abusefilter-log-details-val": "Gwerth", - "abusefilter-log-details-private": "Data preifat", + "abusefilter-log-details-privatedetails": "Data preifat", "abusefilter-log-details-ip": "Cyfeiriad IP gwreiddiol", "abusefilter-log-noactions": "Dim", "abusefilter-log-details-diff": "Gwnaed newidiadau yn y golygiad", "abusefilter-log-linkoncontribs": "log camddefnydd", "abusefilter-log-linkoncontribs-text": "Log camddefnydd ar gyfer {{GENDER:$1|y defnyddiwr hwn}}", - "abusefilter-log-hidden": "(cofnod cuddiedig)", "abusefilter-log-details-hidden": "Ni allwch weld manylion y cofnod hwn am ei fod wedi ei guddio o'r golwg.", "abusefilter-log-hide-legend": "Cuddio cofnod log", "abusefilter-log-hide-reason": "Rheswm:", diff --git a/AbuseFilter/i18n/da.json b/AbuseFilter/i18n/da.json index 4c3e962a..223b0c45 100644 --- a/AbuseFilter/i18n/da.json +++ b/AbuseFilter/i18n/da.json @@ -3,27 +3,29 @@ "authors": [ "Aputtu", "Byrial", + "Cgtdk", "Christian List", "Claus chr", "Fnielsen", "Froztbyte", "Hylle", + "Joedalton", + "Jorn Ari", + "Kranix", "Lhademmor", + "MGA73", + "Matma Rex", "Peter Alberti", + "Saederup92", "Sarrus", "Steenth", "Tjernobyl", - "MGA73", - "Matma Rex", - "Cgtdk", - "Jorn Ari", - "Joedalton", - "Saederup92" + "Weblars" ] }, "abusefilter-desc": "Anvender automatiske heuristikker på redigeringer", - "abusefilter": "Konfiguration af misbrugsfilter", - "abuselog": "Misbrugslog", + "abusefilter": "Håndtering af misbrugsfilter", + "abuselog": "Log for misbrugsfilter", "abusefilter-intro": "Velkommen til grænsefladen for håndtering af misbrugsfilteret.\nMisbrugsfilteret er en automatisk mekanisme i softwaren som udfører automatisk tjek af alle handlinger.\nDenne grænseflade viser en liste over definerede filtre, og gør det muligt at ændre dem.", "abusefilter-warning": "'''Advarsel:''' Denne handling er automatisk blevet identificeret som skadelig.\nIkke-konstruktive redigeringer bliver fjernet hurtigt,\nog forstyrrende eller gentagende ikke-konstruktive redigeringer vil føre til at din konto eller IP-adresse bliver blokeret.\nHvis du mener at dette er en konstruktiv handling, så klik på \"Gem\" igen for at bekræfte.\nHer er kortfattet beskrivelse af misbrugsreglen som din handling udløste: $1", "abusefilter-disallowed": "Denne handling er automatisk blevet identificeret som skadelig,\nog er derfor ikke tilladt.\nHvis du mener at din redigering var konstruktiv, så kontakt venligst en administrator, og informer denne om hvad du forsøgte at gøre.\nHer er en kortfattet beskrivelse af misbrugsreglen som din handling udløste: $1", @@ -34,12 +36,12 @@ "abusefilter-blockreason": "Automatisk blokeret af misbrugsfilter.\nBeskrivelse af den udløste regel: $1", "abusefilter-degroupreason": "Rettigheder fjernet automatisk af misbrugsfilter.\nRegelbeskrivelse: $1", "abusefilter-accountreserved": "Dette kontonavn er reserveret til brug af misbrugsfilteret.", - "right-abusefilter-modify": "Redigér misbrugsfiltre", + "right-abusefilter-modify": "Opret eller redigér misbrugsfiltre", "right-abusefilter-view": "Se misbrugsfiltre", "right-abusefilter-log": "Se misbrugsloggen", "right-abusefilter-log-detail": "Se detaljerede poster i misbrugsloggen", - "right-abusefilter-private": "Se privat information i misbrugsloggen", - "right-abusefilter-private-log": "Se misbrugsfiltret for private oplysningers adgangslog", + "right-abusefilter-privatedetails": "Se privat information i misbrugsloggen", + "right-abusefilter-privatedetails-log": "Se misbrugsfiltret for private oplysningers adgangslog", "right-abusefilter-modify-restricted": "Ændre misbrugsfiltre med begrænsede handlinger", "right-abusefilter-revert": "Tilbagerul alle ændringer udført af et bestemt misbrugsfilter", "right-abusefilter-view-private": "Se misbrugsfiltre markeret som private", @@ -51,20 +53,25 @@ "action-abusefilter-view": "se misbrugsfiltre", "action-abusefilter-log": "se misbrugsloggen", "action-abusefilter-log-detail": "vis detaljerede poster i misbrugsloggen", - "action-abusefilter-private": "se privat information i misbrugsloggen", + "action-abusefilter-privatedetails": "se privat information i misbrugsloggen", "action-abusefilter-modify-restricted": "ændre misbrugsfiltre med begrænsede handlinger", "action-abusefilter-revert": "tilbagerulle alle ændringer udført af et bestemt misbrugsfilter", "action-abusefilter-view-private": "se misbrugsfiltre markeret som private", - "abusefilter-log": "Log for misbrugsfilter", "abusefilter-log-summary": "Denne log viser en liste over alle handlinger som filtrene har opfanget.", "abusefilter-log-search": "Søg i misbrugsloggen", "abusefilter-log-search-user": "Bruger:", - "abusefilter-log-search-filter": "Filter-id'er (adskil med lodrette streger):", + "abusefilter-log-search-group-any": "Enhver", + "abusefilter-log-search-filter": "Filter-id'er:", "abusefilter-log-search-title": "Titel:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-impact-all": "Alle handlinger", "abusefilter-log-search-impact-saved": "Kun gemte ændringer", + "abusefilter-log-search-impact-not-saved": "Uden gemte ændringer", "abusefilter-log-search-entries-label": "Synlighed:", + "abusefilter-log-search-action-other": "Andet", + "abusefilter-log-search-action-any": "Enhver", + "abusefilter-log-search-action-taken-label": "Handling udført:", + "abusefilter-log-search-action-taken-any": "Enhver", "abusefilter-log-search-submit": "Søg", "abusefilter-log-entry": "$1: $2 udløste et misbrugsfilter med handlingen \"$3\" på $4.\nForanstaltninger: $5.\nFilterbeskrivelse: $6", "abusefilter-log-entry-withdiff": "$1: $2 udløste et misbrugsfilter med handlingen \"$3\" på $4.\nForanstaltninger: $5;\nFilterbeskrivelse: $6 ($7)", @@ -78,16 +85,17 @@ "abusefilter-log-details-var": "Variabel", "abusefilter-log-details-val": "Værdi", "abusefilter-log-details-vars": "Handlingsparametre", - "abusefilter-log-details-private": "Privat log information", + "abusefilter-log-details-privatedetails": "Privat log information", "abusefilter-log-details-ip": "Ophavs-IP", "abusefilter-log-noactions": "ingen", + "abusefilter-log-noactions-filter": "Ingen", "abusefilter-log-details-diff": "Ændringer udført i redigeringen", "abusefilter-log-linkoncontribs": "misbrugslog", - "abusefilter-log-linkoncontribs-text": "Misbrugslog for denne bruger", - "abusefilter-log-hidden": "(post skjult)", + "abusefilter-log-linkoncontribs-text": "Misbrugslog for {{GENDER:$1|denne bruger}}", + "abusefilter-log-linkonhistory": "vis misbrugsloggen", "abusefilter-log-hidden-implicit": "(skjult da versionen er blevet slettet)", "abusefilter-log-cannot-see-details": "Du har ikke tilladelse til at se detaljer om denne post.", - "abusefilter-log-cannot-see-private-details": "Du har ikke tilladelse til at se private oplysninger om denne andgang", + "abusefilter-log-cannot-see-privatedetails": "Du har ikke tilladelse til at se private oplysninger om denne andgang", "abusefilter-log-details-hidden": "Du kan ikke se detaljerne for denne post, fordi den er skjult for offentligheden", "abusefilter-log-hide-legend": "Skjul loghandlig", "abusefilter-log-hide-id": "Loghandlings-id:", @@ -96,7 +104,6 @@ "abusefilter-log-hide-forbidden": "Du har ikke rettigheder til at skjule poster i misbrugsfilteret", "logentry-abusefilter-hit": "$1 udløste $4 med handlingen \"$5\" på $3. Tiltag: $6 ($7)", "abusefilterprivatedetails-log-name": "Misbrugsfilter for private oplysningers adgangslog", - "abusefilter-management": "Håndtering af misbrugsfilter", "abusefilter-list": "Alle filtre", "abusefilter-list-id": "Filter-ID", "abusefilter-list-pattern": "Mønster", @@ -117,6 +124,7 @@ "abusefilter-disabled": "Deaktiveret", "abusefilter-hitcount": "$1 {{PLURAL:$1|træf|træf}}", "abusefilter-new": "Opret et nyt filter", + "abusefilter-import-button": "Importer filter", "abusefilter-return": "Vend tilbage til filterhåndtering", "abusefilter-status-global": "Globalt", "abusefilter-list-options": "Indstillinger", @@ -128,7 +136,9 @@ "abusefilter-list-options-scope-local": "Kun lokale regler", "abusefilter-list-options-scope-global": "Kun globale regler", "abusefilter-list-options-scope-all": "Lokale og globale regler", + "abusefilter-list-options-further-options": "Yderligere indstillinger:", "abusefilter-list-options-hidedisabled": "Skjul deaktiverede filtre", + "abusefilter-list-options-searchpattern": "Indsæt et mønster", "abusefilter-list-options-submit": "Opdatér", "abusefilter-tools-text": "Her er nogle værktøjer som kan være nyttige til at formulere og fejlsøge misbrugsfiltre.", "abusefilter-tools-expr": "Udtrykstester", @@ -146,7 +156,6 @@ "abusefilter-edit-oldwarning": "<strong>Du redigerer en gammel version af dette filter.\nDen citerede statistik er for den seneste version af filteret.\nHvis du gemmer dine ændringer, overskriver du alle ændringer siden den version du redigerer.</strong> •\n[[Special:AbuseFilter/history/$2|Vend tilbage til dette filters historik]].", "abusefilter-edit-status-label": "Statistik:", "abusefilter-edit-status": "Af {{PLURAL:$1|den sidste handling|de sidste $1 handlinger}} har dette filter matchet $2 ($3 %).", - "abusefilter-edit-status-profile": "Af {{PLURAL:$1|den sidste handling|de sidste $1 handlinger}} har dette filter matchet $2 ($3 %).\nI gennemsnit er operationstiden $4 ms, og det optager $5 {{PLURAL:$5|tilstand|tilstande}} af tilstandsgrænsen.", "abusefilter-edit-new": "Nyt filter", "abusefilter-edit-save": "Gem filter", "abusefilter-edit-id": "Filter-ID:", @@ -175,20 +184,26 @@ "abusefilter-edit-throttle-count": "Antal tilladte handlinger:", "abusefilter-edit-throttle-period": "Tidsrum (i sekunder):", "abusefilter-edit-throttle-groups": "Gruppebegrænsning efter:\n:''(én pr. linje, kombiner med kommaer)''", - "abusefilter-edit-throttle-ip": "IP-adresse", - "abusefilter-edit-throttle-user": "Brugerkonto", - "abusefilter-edit-throttle-site": "Hele siden", - "abusefilter-edit-throttle-page": "Side", + "abusefilter-edit-throttle-groups-help": "Se $1.", + "abusefilter-throttle-ip": "IP-adresse", + "abusefilter-throttle-user": "brugerkonto", + "abusefilter-throttle-site": "hele siden", + "abusefilter-throttle-page": "side", + "abusefilter-throttle-none": "(ingen)", "abusefilter-edit-warn-message": "Systemmeddelelse som skal bruges til advarsel:", "abusefilter-edit-warn-other": "Anden meddelelse", - "abusefilter-edit-warn-other-label": "Sidenavn på anden meddelelse:\n:''(uden MediaWiki-præfiks)''", + "abusefilter-edit-warn-other-label": "Sidenavn på anden meddelelse:\n:''(uden \"MediaWiki:\" præfiks)''", "abusefilter-edit-warn-actions": "Handlinger:", "abusefilter-edit-warn-preview": "Forhåndsvis valgt meddelelse", "abusefilter-edit-warn-edit": "Opret/redigér valgt meddelelse", + "abusefilter-edit-disallow-other": "Anden meddelelse", + "abusefilter-edit-disallow-actions": "Handlinger:", + "abusefilter-edit-disallow-edit": "Opret/redigér valgte meddelelse", "abusefilter-edit-tag-tag": "Mærker som skal anvendes (et pr. linje):", "abusefilter-edit-block-anon-durations": "Varighed på blokeringen for anonyme brugere:", - "abusefilter-block-anon": "Bloker onyme brugere", + "abusefilter-block-anon": "Bloker anonyme brugere", "abusefilter-block-user": "bloker registrerede brugere", + "abusefilter-block-talk": "blokeret fra at redigere sin egen diskussionside", "abusefilter-edit-denied": "Du kan ikke se detaljerne i dette filter, da det er skjult for offentligheden.", "abusefilter-edit-main": "Filterparametre", "abusefilter-edit-done-subtitle": "Filter redigeret", @@ -219,7 +234,9 @@ "abusefilter-edit-builder-op-arithmetic-pow": "Potens (**)", "abusefilter-edit-builder-group-op-comparison": "Sammenligningsoperatører", "abusefilter-edit-builder-op-comparison-equal": "Værdien er lig med (==)", + "abusefilter-edit-builder-op-comparison-equal-strict": "Værdien og typen er lig med (===)", "abusefilter-edit-builder-op-comparison-notequal": "Værdien er ikke lig med (!=)", + "abusefilter-edit-builder-op-comparison-notequal-strict": "Værdien og typen er ikke lig med (!==)", "abusefilter-edit-builder-op-comparison-lt": "Mindre end (<)", "abusefilter-edit-builder-op-comparison-gt": "Større end (>)", "abusefilter-edit-builder-op-comparison-lte": "Mindre end eller lig med (<=)", @@ -236,7 +253,7 @@ "abusefilter-edit-builder-misc-contains": "Venstre streng indeholder højre streng (contains)", "abusefilter-edit-builder-misc-stringlit": "Ordret streng (\"\")", "abusefilter-edit-builder-misc-tern": "Trefoldig operator (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Betinget (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Betinget (if X then Y else Z end)", "abusefilter-edit-builder-group-funcs": "Funktioner", "abusefilter-edit-builder-funcs-length": "Strenglængde (length)", "abusefilter-edit-builder-funcs-lcase": "Konverter til små bogstaver (lcase)", @@ -266,12 +283,15 @@ "abusefilter-edit-builder-vars-diff": "Samlet diff af ændringer foretaget i redigering", "abusefilter-edit-builder-vars-newsize": "Ny sidestørrelse", "abusefilter-edit-builder-vars-oldsize": "Gammel sidestørrelse", + "abusefilter-edit-builder-vars-old-content-model": "Gammel indholdsmodel", + "abusefilter-edit-builder-vars-new-content-model": "Ny indholdsmodel", "abusefilter-edit-builder-vars-removedlines": "Linjer fjernet i redigering", "abusefilter-edit-builder-vars-summary": "Redigeringssammenfatning", "abusefilter-edit-builder-vars-page-id": "Side-ID", "abusefilter-edit-builder-vars-page-ns": "Sidens navnerum", "abusefilter-edit-builder-vars-page-title": "Sidetitel (uden navnerum)", "abusefilter-edit-builder-vars-page-prefixedtitle": "Fuld sidetitel", + "abusefilter-edit-builder-vars-page-age": "Sidens alder (i sekunder)", "abusefilter-edit-builder-vars-movedfrom-id": "Side-ID på kildeside ved flytning", "abusefilter-edit-builder-vars-movedfrom-ns": "Navnerum på kildeside ved flytning", "abusefilter-edit-builder-vars-movedfrom-title": "Titel på kildeside ved flytning", @@ -284,26 +304,33 @@ "abusefilter-edit-builder-vars-user-age": "Brugerkontoens alder", "abusefilter-edit-builder-vars-user-name": "Brugerkontoens navn", "abusefilter-edit-builder-vars-user-groups": "Grupper (heriblandt implicitte) som brugeren er i", + "abusefilter-edit-builder-vars-user-rights": "Rettigheder som en bruger har", "abusefilter-edit-builder-vars-user-blocked": "Hvorvidt brugeren er blokeret", "abusefilter-edit-builder-vars-user-emailconfirm": "Tidspunkt e-mailadressen blev bekræftet", "abusefilter-edit-builder-vars-recent-contributors": "Seneste ti brugere som har bidraget til siden", "abusefilter-edit-builder-vars-all-links": "Alle eksterne henvisninger i den nye tekst", "abusefilter-edit-builder-vars-added-links": "Alle eksterne henvisninger tilføjet i redigeringen", "abusefilter-edit-builder-vars-removed-links": "Alle eksterne henvisninger fjernet i redigeringen", - "abusefilter-edit-builder-vars-old-text": "Den gamle sides wikitekst, før redigeringen", - "abusefilter-edit-builder-vars-new-text": "Den nye sides wikitekst, efter redigeringen", + "abusefilter-edit-builder-vars-old-wikitext": "Den gamle sides wikitekst, før redigeringen", + "abusefilter-edit-builder-vars-new-wikitext": "Den nye sides wikitekst, efter redigeringen", "abusefilter-edit-builder-vars-new-pst": "Ny side wikitekst, transformeret før den er gemt", - "abusefilter-edit-builder-vars-new-text-stripped": "Ny sidetekst, uden opmarkering", + "abusefilter-edit-builder-vars-new-text": "Ny sidetekst, uden opmarkering", "abusefilter-edit-builder-vars-new-html": "Tolket HTML-kildekode for den nye revision", "abusefilter-edit-builder-vars-restrictions-edit": "Beskyttelsesniveau for redigering af siden", "abusefilter-edit-builder-vars-restrictions-move": "Beskyttelsesniveau for flytning af siden", "abusefilter-edit-builder-vars-restrictions-create": "Beskyt siden mod oprettelse", "abusefilter-edit-builder-vars-restrictions-upload": "Upload beskyttelse af filen", - "abusefilter-edit-builder-vars-old-text-stripped": "Gammel sidetekst, uden opmarkering", + "abusefilter-edit-builder-vars-old-text": "Gammel sidetekst, uden opmarkering", "abusefilter-edit-builder-vars-old-links": "Henvisninger på siden, før redigeringen", "abusefilter-edit-builder-vars-old-html": "Den gamle sides wikitekst, tolket til HTML", - "abusefilter-edit-builder-vars-minor-edit": "Om redigeringen er markeret som mindre ændring", + "abusefilter-edit-builder-vars-minor-edit": "Om redigeringen er markeret som mindre ændring (bruges ikke længere)", "abusefilter-edit-builder-vars-file-sha1": "SHA1-hash af filindhold", + "abusefilter-edit-builder-vars-file-size": "Filstørrelsen i bytes", + "abusefilter-edit-builder-vars-file-mime": "Filens MIME-type", + "abusefilter-edit-builder-vars-file-mediatype": "Filens medietype", + "abusefilter-edit-builder-vars-file-width": "Filens bredde i pixels", + "abusefilter-edit-builder-vars-file-height": "Filens højde i pixels", + "abusefilter-edit-builder-vars-wiki-language": "Sprogkoden for wikien", "abusefilter-filter-log": "Seneste filterændringer", "abusefilter-history": "Ændringshistorik for misbrugsfilter #$1", "abusefilter-history-foruser": "Ændringer af $1", @@ -322,6 +349,7 @@ "abusefilter-history-filterid": "Filter", "abusefilter-history-select-legend": "Uddyb søgning", "abusefilter-history-select-user": "Bruger:", + "abusefilter-history-select-filter": "Filter-ID:", "abusefilter-history-select-submit": "Uddyb", "abusefilter-history-diff": "Ændringer", "abusefilter-history-error-hidden": "Filteret som du efterspurgte er skjult, og du kan ikke se dets historik.", @@ -332,14 +360,15 @@ "abusefilter-exception-unclosedstring": "Åben streng begyndende ved tegn $1.", "abusefilter-exception-invalidoperator": "Ugyldig operator \"$2\" ved tegn $1.", "abusefilter-exception-unrecognisedtoken": "Ukendt token \"$2\" ved tegn $1.", - "abusefilter-exception-noparams": "Ingen parametre givet til funktion \"$2\" ved tegn $1.", + "abusefilter-exception-noparams": "Ingen parametre givet til funktion \"$2\" ved tegn $1.\nForventede $3 {{PLURAL:$3|argument|argumenter}}.", "abusefilter-exception-dividebyzero": "Ulovligt forsøg på at dividere $2 med nul ved tegn $1.", "abusefilter-exception-unrecognisedvar": "Ukendt variabel $2 ved tegn $1.", "abusefilter-exception-notenoughargs": "Funktionskaldet $2 ved tegn $1 havde ikke nok argumenter.\nForventede {{PLURAL:$3|et argument|$3 argumenter}}, fik $4", - "abusefilter-exception-regexfailure": "Fejl i det regulære udtryk \"$3\" ved tegn $1: \"$2\"", + "abusefilter-exception-regexfailure": "Fejl i det regulære udtryk \"$2\" ved tegn $1.", "abusefilter-exception-overridebuiltin": "Ulovlig overskrivning af den indbyggede variabel \"$2\" ved tegnet $1.", "abusefilter-exception-outofbounds": "Anmoder om ikke-eksisterende listeelement $2 (listens størrelse = $3) ved tegnet $1.", "abusefilter-exception-notarray": "Efterspørger tabelelement fra en ikke-tabel ved tegn $1.", + "abusefilter-exception-unclosedcomment": "Ikke-lukket kommentar ved tegnet $1.", "abusefilter-action-tag": "Mærke", "abusefilter-action-throttle": "Begrænsning af ændringshastighed", "abusefilter-action-warn": "Advar", @@ -357,6 +386,7 @@ "abusefilter-revert-search": "Vælg handlinger", "abusefilter-revert-filter": "Filter ID:", "abusefilter-revert-preview-intro": "Nedenfor er de handlinger, som misbrugsfilteret har udført, der vil blive tilbagerullet af denne handling.\nKontrollér dem omhyggeligt, og klik på \"{{int:abusefilter-revert-confirm}}\" for at bekræfte dit valg.", + "abusefilter-revert-confirm-legend": "Bekræft tibagerulnignen", "abusefilter-revert-confirm": "Bekræft", "abusefilter-revert-success": "Du har tilbagerullet alle handlinger udført af misbrugsfilteret på grund af [[Special:AbuseFilter/$1|filter $2]].", "abusefilter-revert-reason": "Automatisk tilbagerulning af alle handlinger udført af misbrugsfilteret på grund af filter $1.\nBegrundelse: $2", @@ -374,6 +404,7 @@ "abusefilter-test-page": "Ændringer udført på side:", "abusefilter-test-shownegative": "Vis ændringer som ikke matcher filteret", "abusefilter-test-syntaxerr": "Det filter, du angav indeholdt en fejl i syntaksen.\nDu kan modtage en fuld forklaring ved at klikke på knappen \"{{int:abusefilter-edit-check}}\".", + "abusefilter-test-action": "Handlingstype:", "abusefilter-test-search-type-all": "Alle handlinger", "abusefilter-test-search-type-edit": "Redigeringer", "abusefilter-test-search-type-move": "Flytninger", @@ -402,9 +433,9 @@ "abusefilter-topnav-examine": "Undersøg tidligere ændringer", "abusefilter-topnav-log": "Misbrugslog", "abusefilter-topnav-tools": "Fejlsøgningsværktøjer", - "abusefilter-topnav-import": "Importer filter", "abusefilter-log-name": "Log for misbrugsfilter", "abusefilter-log-header": "Denne log viser en oversigt over ændringer i filtre.\nFor fuldstændige oplysninger, se [[Special:AbuseFilter/history|listen]] over de seneste ændringer for filtre.", + "abusefilter-logentry-create": "$1 {{GENDER:$2|oprettede}} $4 ($5)", "abusefilter-log-noresults": "Ingen resultater", "abusefilter-diff-title": "Forskelle mellem versioner", "abusefilter-diff-item": "Element", @@ -418,9 +449,10 @@ "abusefilter-import-intro": "Du kan bruge denne grænseflade til at importere filtre fra andre wiki-websteder direkte.\nKlik på kilde wiki, \"{{int:abusefilter-edit-export}}\" under \"{{int:abusefilter-edit-tools}}\" i redigeringsgrænsefladen.\nKopiere fra tekstfeltet der vises, og indsætte det i denne tekstboks, og klik derefter på \"{{int:abusefilter-import-submit}}\".", "abusefilter-import-submit": "Importer data", "abusefilter-group-default": "Standard", - "abusefilter-view-private-submit": "Se private oplysninger", - "abusefilter-view-private": "Se private oplysninger", - "abusefilter-view-private-reason": "Grund for adgang til private oplysninger:", + "abusefilter-http-error": "Der opstod en HTTP fejl: $1", + "abusefilter-view-privatedetails-submit": "Se private oplysninger", + "abusefilter-view-privatedetails-legend": "Se private oplysninger", + "abusefilter-view-privatedetails-reason": "Grund for adgang til private oplysninger:", "abusefilter-log-details-id": "Log ID", "log-description-abusefilterprivatedetails": "Denne log viser en liste over gange, hvor en bruger havde adgang til de private oplysninger i en misbrugslog.", "abusefilter-noreason": "Advarsel: For at se de private oplysninger i denne log, skal du angive en grund.", diff --git a/AbuseFilter/i18n/dag.json b/AbuseFilter/i18n/dag.json new file mode 100644 index 00000000..93af7f93 --- /dev/null +++ b/AbuseFilter/i18n/dag.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Musahfm" + ] + }, + "abusefilter-log-search-filter-help-central": "Zaŋmi papunim waligi li" +} diff --git a/AbuseFilter/i18n/de-ch.json b/AbuseFilter/i18n/de-ch.json index cb6ef9d0..326bdebe 100644 --- a/AbuseFilter/i18n/de-ch.json +++ b/AbuseFilter/i18n/de-ch.json @@ -1,12 +1,13 @@ { "@metadata": { "authors": [ + "Doc Taxon", "Filzstift", "Geitost" ] }, - "abusefilter-log-entry": "$1: $2 löste durch die Aktion «$3» auf «$4» einen Missbrauchsfilter aus.\nFilteraktion: «$5»;\nFilterbeschreibung: «$6»", - "abusefilter-log-detailedentry-meta": "$1: $2 löste durch die Aktion «$4» auf die Seite «$5» den $3 aus.\nErgriffene Massnahmen: $6;\nFilterbeschreibung: $7 ($8)", + "abusefilter-log-entry": "$1: $2 löste durch die Aktion «$3» auf der Seite «$4» einen Missbrauchsfilter aus.\nFilteraktion: «$5»;\nFilterbeschreibung: «$6»", + "abusefilter-log-detailedentry-meta": "$1: $2 {{GENDER:$9|löste}} durch die Aktion «$4» auf der Seite «$5» den $3 aus.\nErgriffene Maßnahmen: $6;\nFilterbeschreibung: $7 ($8)", "abusefilter-edit-action-blockautopromote": "Den Status «Automatisch bestätigter Benutzer» entziehen.", "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Deine Änderungen]] am [[Special:AbuseFilter/$1|Filter «$3»]] wurden erfolgreich gespeichert.", "abusefilter-edit-builder-funcs-rmwhitespace": "Leerschläge entfernen (rmwhitespace)" diff --git a/AbuseFilter/i18n/de.json b/AbuseFilter/i18n/de.json index ff1b9fcf..d2943b71 100644 --- a/AbuseFilter/i18n/de.json +++ b/AbuseFilter/i18n/de.json @@ -4,34 +4,38 @@ "Cedric31", "ChrisiPK", "Church of emacs", + "Daimona Eaytoy", + "Doc Taxon", + "FriedhelmW", "Geitost", "Giftpflanze", + "Inkowik", + "J. 'mach' wust", "Kghbln", "Leithian", + "Luke081515", "MF-Warburg", + "MGChecker", + "Matma Rex", "Merlissimo", "Metalhead64", + "Mglaser", "Pill", + "Predatorix", "Purodha", "Revolus", "Servien", "The Evil IP address", + "ToBeFree", "Umherirrender", "W (aka Wuzur)", + "WikiBayer", "Wikifan", - "Xqt", - "Luke081515", - "J. 'mach' wust", - "Predatorix", - "Inkowik", - "Matma Rex", - "MGChecker", - "Daimona Eaytoy", - "ToBeFree" + "Xqt" ] }, "abusefilter-desc": "Wendet Heuristiken automatisch auf Bearbeitungen an", - "abusefilter": "Missbrauchsfilter-Einstellungen", + "abusefilter": "Missbrauchsfilter-Verwaltung", "abuselog": "Missbrauchsfilter-Logbuch", "abusefilter-intro": "Willkommen auf der Missbrauchsfilter-Management-Oberfläche.\nDer Missbrauchsfilter ist ein automatischer Mechanismus, welcher automatische Heuristiken auf alle Änderungen anwendet.\nDiese Oberfläche zeigt eine Liste aller definierten Filter und erlaubt es, diese zu verändern.", "abusefilter-mustviewprivateoredit": "Aus Sicherheitsgründen können nur Benutzer mit dem Recht auf Einsicht in private Missbrauchsfilter oder Veränderung der Filter diese Oberfläche verwenden.", @@ -43,13 +47,14 @@ "abusefilter-blocker": "Missbrauchsfilter", "abusefilter-blockreason": "Du wurdest durch einen Missbrauchsfilter automatisch gesperrt. Beschreibung der zutreffenden Regel: $1", "abusefilter-degroupreason": "Deine Berechtigungen wurden durch einen Missbrauchsfilter automatisch beschränkt.\nBeschreibung der Regel: $1", + "abusefilter-blockautopromotereason": "Autopromotion automatisch durch Missbrauchsfilter verzögert.\nRegelbeschreibung: $1", "abusefilter-accountreserved": "Dieser Benutzername ist für den Missbrauchsfilter reserviert.", - "right-abusefilter-modify": "Missbrauchsfilter bearbeiten", + "right-abusefilter-modify": "Missbrauchsfilter erstellen oder bearbeiten", "right-abusefilter-view": "Missbrauchsfilter ansehen", "right-abusefilter-log": "Missbrauchsfilter-Logbuch einsehen", "right-abusefilter-log-detail": "Erweitertes Missbrauchsfilter-Logbuch einsehen", - "right-abusefilter-private": "Private Daten im Missbrauchsfilter-Logbuch einsehen", - "right-abusefilter-private-log": "Das Missbrauchsfilter-Private-Einzelheiten-Zugriffs-Logbuch ansehen", + "right-abusefilter-privatedetails": "Private Daten im Missbrauchsfilter-Logbuch einsehen", + "right-abusefilter-privatedetails-log": "Das Missbrauchsfilter-Private-Einzelheiten-Zugriffs-Logbuch ansehen", "right-abusefilter-modify-restricted": "Missbrauchsfilter mit privilegierten Aktionen bearbeiten", "right-abusefilter-revert": "Alle Bearbeitungen durch einen bestimmten Missbrauchsfilter rückgängig machen", "right-abusefilter-view-private": "Als privat markierten Missbrauchsfilter einsehen", @@ -61,17 +66,23 @@ "action-abusefilter-view": "Missbrauchsfilter anzusehen", "action-abusefilter-log": "das Missbrauchsfilter-Logbuch einzusehen", "action-abusefilter-log-detail": "das erweiterte Missbrauchsfilter-Logbuch einzusehen", - "action-abusefilter-private": "private Daten im Missbrauchsfilter-Logbuch einzusehen", - "action-abusefilter-private-log": "das Missbrauchsfilter-Private-Einzelheiten-Zugriffs-Logbuch anzusehen", + "action-abusefilter-privatedetails": "private Daten im Missbrauchsfilter-Logbuch einzusehen", + "action-abusefilter-privatedetails-log": "das Missbrauchsfilter-Private-Einzelheiten-Zugriffs-Logbuch anzusehen", "action-abusefilter-modify-restricted": "Missbrauchsfilter mit privilegierten Aktionen zu bearbeiten", "action-abusefilter-revert": "alle Änderungen durch einen bestimmten Missbrauchsfilter rückgängig zu machen", "action-abusefilter-view-private": "Missbrauchsfilter einzusehen, die als privat markiert wurden", "action-abusefilter-log-private": "Missbrauchsfilter-Logbücher anzusehen, die als privat markiert wurden", - "abusefilter-log": "Missbrauchsfilter-Logbuch", + "action-abusefilter-hide-log": "Einträge aus dem Missbrauchsfilter-Logbuch auszublenden", + "action-abusefilter-hidden-log": "versteckte Einträge im Missbrauchsfilter-Logbuch einzusehen", + "action-abusefilter-modify-global": "globale Missbrauchsfilter zu erstellen oder zu verändern", "abusefilter-log-summary": "Dieses Logbuch zeigt eine Liste aller Aktionen, die durch einen Filter aufgefangen wurden.", "abusefilter-log-search": "Missbrauchsfilter-Logbuch durchsuchen", "abusefilter-log-search-user": "Benutzer:", - "abusefilter-log-search-filter": "Filterkennungen (durch senkrechte Striche getrennt):", + "abusefilter-log-search-group": "Gruppe filtern:", + "abusefilter-log-search-group-any": "Alle", + "abusefilter-log-search-filter": "Filterkennungen:", + "abusefilter-log-search-filter-help": "$1 - Das von globalen Filtern verwendete Präfix", + "abusefilter-log-search-filter-help-central": "Getrennt mit Pipes", "abusefilter-log-search-title": "Titel:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-impact": "Auswirkung:", @@ -82,15 +93,15 @@ "abusefilter-log-search-entries-all": "Alle Einträge", "abusefilter-log-search-entries-hidden": "Nur versteckte Einträge", "abusefilter-log-search-entries-visible": "Nur sichtbare Einträge", - "abusefilter-log-search-action-label": "Ausgelöste Aktion:", + "abusefilter-log-search-action-label": "Auslösende Aktion:", "abusefilter-log-search-action-other": "Andere", "abusefilter-log-search-action-any": "Alle", "abusefilter-log-search-action-taken-label": "Aufgezeichnete Aktion:", "abusefilter-log-search-action-taken-any": "Jede", "abusefilter-log-search-submit": "Suchen", - "abusefilter-log-entry": "$1: $2 {{GENDER:$8|löste}} durch die Aktion „$3“ auf „$4“ einen Missbrauchsfilter aus.\nFilteraktion: „$5“;\nFilterbeschreibung: „$6“", + "abusefilter-log-entry": "$1: $2 {{GENDER:$8|löste}} durch die Aktion „$3“ auf der Seite „$4“ einen Missbrauchsfilter aus.\nFilteraktion: „$5“;\nFilterbeschreibung: „$6“", "abusefilter-log-entry-withdiff": "$1: $2 hat mit der Aktion „$3“ auf der Seite $4 einen Missbrauchsfilter {{GENDER:$8|ausgelöst}}.\nUnternommene Aktionen: $5;\nFilterbeschreibung: $6 ($7)", - "abusefilter-log-detailedentry-meta": "$1: $2 {{GENDER:$9|löste}} durch die Aktion „$4“ auf die Seite „$5“ den $3 aus.\nErgriffene Maßnahmen: $6;\nFilterbeschreibung: $7 ($8)", + "abusefilter-log-detailedentry-meta": "$1: $2 {{GENDER:$9|löste}} durch die Aktion „$4“ auf der Seite „$5“ den $3 aus.\nErgriffene Maßnahmen: $6;\nFilterbeschreibung: $7 ($8)", "abusefilter-log-detailedentry-global": "globalen Filter $1", "abusefilter-log-detailedentry-local": "Filter $1", "abusefilter-log-detailslink": "Details", @@ -100,19 +111,21 @@ "abusefilter-log-details-var": "Variable", "abusefilter-log-details-val": "Wert", "abusefilter-log-details-vars": "Aktionsparameter", - "abusefilter-log-details-private": "Private Eintragseinzelheiten", + "abusefilter-log-details-privatedetails": "Private Eintragseinzelheiten", "abusefilter-log-details-ip": "IP-Adresse des Verursachers", "abusefilter-log-details-checkuser": "Benutzer prüfen", "abusefilter-log-noactions": "keine", + "abusefilter-log-noactions-filter": "Keine", "abusefilter-log-details-diff": "Änderungen durch diese Bearbeitung", "abusefilter-log-linkoncontribs": "Missbrauchsfilter-Logbuch", "abusefilter-log-linkoncontribs-text": "Missbrauchsfilter-Logbuch für {{GENDER:$1|diesen Benutzer|diese Benutzerin}}", "abusefilter-log-linkonhistory": "Missbrauchsfilter-Logbuch ansehen", "abusefilter-log-linkonhistory-text": "Missbrauchsfilter-Logbuch für diese Seite ansehen", - "abusefilter-log-hidden": "(Eintrag versteckt)", + "abusefilter-log-linkonundelete": "Missbrauchsfilter-Logbuch ansehen", + "abusefilter-log-linkonundelete-text": "Missbrauchsfilter-Logbuch für diese Seite ansehen", "abusefilter-log-hidden-implicit": "(versteckt, da die Version gelöscht wurde)", "abusefilter-log-cannot-see-details": "Du hast nicht die Berechtigung, Einzelheiten zur dieser Eingabe einzusehen.", - "abusefilter-log-cannot-see-private-details": "Du hast keine Berechtigung, um private Einzelheiten für diesen Eintrag einzusehen.", + "abusefilter-log-cannot-see-privatedetails": "Du hast keine Berechtigung, um private Einzelheiten für diesen Eintrag einzusehen.", "abusefilter-log-nonexistent": "Ein Eintrag mit der angegebenen Kennung ist nicht vorhanden.", "abusefilter-log-details-hidden": "Du kannst die Details dieses Eintrags nicht einsehen, da sie vor der Öffentlichkeit verborgen sind.", "abusefilter-log-details-hidden-implicit": "Du kannst die Einzelheiten für diesen Eintrag nicht einsehen, da die dazugehörige Version für die öffentliche Einsicht versteckt ist.", @@ -130,9 +143,12 @@ "log-action-filter-abusefilter-create": "Erstellung eines neuen Filters", "log-action-filter-abusefilter-modify": "Filteränderung", "log-action-filter-suppress-abuselog": "Unterdrückung des Missbrauchfilter-Logbuchs", + "log-action-filter-rights-blockautopromote": "Autopromote Sperre", + "log-action-filter-rights-restoreautopromote": "Autopromote wiederherstellen", "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|hat}} auf private Einzelheiten für $3 zugegriffen", + "logentry-rights-blockautopromote": "$1 {{GENDER:$2|sperrte}} die Autopromotion von {{GENDER:$4|$3}} für einen Zeitraum von $5", + "logentry-rights-restoreautopromote": "$1 {{GENDER:$2|stellte}} die Autopromotion-Fähigkeit von {{GENDER:$4|$3}} wieder her", "abusefilterprivatedetails-log-name": "Missbrauchsfilter-Private-Einzelheiten-Zugriffs-Logbuch", - "abusefilter-management": "Missbrauchsfilter-Verwaltung", "abusefilter-list": "Alle Filter", "abusefilter-list-id": "Filterkennung", "abusefilter-list-pattern": "Muster", @@ -154,6 +170,7 @@ "abusefilter-throttled": "gedrosselt", "abusefilter-hitcount": "{{PLURAL:$1|Ein Treffer|$1 Treffer}}", "abusefilter-new": "Neuen Filter erstellen", + "abusefilter-import-button": "Filter importieren", "abusefilter-return": "Zurück zur Missbrauchsfilter-Verwaltung", "abusefilter-status-global": "Global", "abusefilter-list-options": "Optionen", @@ -174,26 +191,29 @@ "abusefilter-list-options-search-like": "Einfache Anfrage", "abusefilter-list-options-search-rlike": "Regulärer Ausdruck", "abusefilter-list-options-search-irlike": "Schreibungsunabhängiger regulärer Ausdruck", + "abusefilter-list-invalid-searchmode": "Der angegebene Suchmodus ist ungültig.", "abusefilter-list-regexerror": "Bei der Suche ist ein Fehler aufgetreten: Syntaxfehler im regulären Ausdruck.", "abusefilter-list-options-submit": "Aktualisieren", "abusefilter-tools-text": "Auf dieser Seite finden sich einige Werkzeuge, die beim Erstellen von Missbrauchsfiltern und bei der Fehlersuche hilfreich sein können.", "abusefilter-tools-expr": "Expression-Tester", "abusefilter-tools-submitexpr": "Prüfen", + "abusefilter-tools-syntax-error": "Der Filter hat eine ungültige Syntax.", "abusefilter-tools-reautoconfirm": "„Automatisch bestätigte Benutzer“-Status wiederherstellen", "abusefilter-tools-reautoconfirm-user": "Benutzer:", "abusefilter-tools-reautoconfirm-submit": "Wieder zum automatisch bestätigten Benutzer machen", + "abusefilter-tools-restoreautopromote": "Autopromotion mit Hilfe der AbuseFilter-Werkzeuge wiederhergestellt", "abusefilter-reautoconfirm-none": "{{GENDER:$1|Diesem Benutzer|Dieser Benutzerin}} ist der „Automatisch bestätigte Benutzer“-Status nicht entzogen worden.", "abusefilter-reautoconfirm-notallowed": "Du bist nicht berechtigt, Benutzer wieder zu automatisch bestätigten Benutzern zu machen.", "abusefilter-reautoconfirm-done": "„Automatisch bestätigte Benutzer“-Status wurde wiederhergestellt", - "abusefilter-status": "Von {{PLURAL:$1|der letzten Aktion|den letzten $1 Aktionen}} {{PLURAL:$2|hat eine|haben $2}} ($3 %) den Grenzwert von $4 erreicht.\n{{PLURAL:$5|Eine Aktion|$5 Aktionen}} ($6 %) {{PLURAL:$5|wurde|wurden}} von einem der aktivierten Filter erkannt.", + "abusefilter-status": "Von {{PLURAL:$1|der letzten Aktion|den letzten $1 Aktionen}} {{PLURAL:$2|hat eine|haben $2}} ($3 %) den Grenzwert von $4 erreicht.\n{{PLURAL:$5|Eine Aktion|$5 Aktionen}} ($6 %) {{PLURAL:$5|wurde|wurden}} von mindestens einem der aktivierten Filter erkannt.", "abusefilter-edit": "Missbrauchsfilter bearbeiten", "abusefilter-edit-subtitle": "Bearbeite Filter $1", "abusefilter-edit-subtitle-new": "Filter erstellen", "abusefilter-edit-token-not-match": "Die Bearbeitung wurde nicht gespeichert! Bitte erneut versuchen.", "abusefilter-edit-oldwarning": "<strong>Du bearbeitest nicht die aktuelle, sondern eine ältere Version dieses Filters. Die Statistik gilt nur für die letzte Version des Filters. Wenn du speicherst, wird diese als aktuelle Version neu gespeichert. </strong> • [[Special:AbuseFilter/history/$2|Zurück zur Versionsgeschichte des Filters]]", + "abusefilter-edit-oldwarning-view": "<strong>Du siehst eine alte Version dieses Filters. Die angeführten Statistiken beziehen sich auf die neueste Version des Filters.</strong> •\n[[Special:AbuseFilter/history/$2|Zurück zu der Versionsgeschichte des Filters]].", "abusefilter-edit-status-label": "Statistik:", - "abusefilter-edit-status": "Von {{PLURAL:$1|der letzten Aktion|den letzten $1 Aktionen}} {{PLURAL:$2|wurde eine|wurden $2}} ($3 %) von diesem Filter erkannt.", - "abusefilter-edit-status-profile": "Von {{PLURAL:$1|der letzten Aktion|den letzten $1 Aktionen}} {{PLURAL:$2|wurde eine|wurden $2}} ($3 %) von diesem Filter erkannt.\nIm Durchschnitt betrug die Bearbeitungszeit $4 ms und sie benötigten {{PLURAL:$5|eine Bedingung|$5 Bedingungen}} der erlaubten Höchstzahl.", + "abusefilter-edit-status": "Von {{PLURAL:$1|der letzten Aktion|den letzten $1 Aktionen}} {{PLURAL:$2|wurde eine|wurden $2}} ($3 %) von diesem Filter erkannt.\nIm Durchschnitt beträgt ihre Ausführungszeit $4 ms und sie verbraucht {{PLURAL:$5|eine Bedingung|$5 Bedingungen}} der Bedingungsgrenze.", "abusefilter-edit-throttled-warning": "'''Warnung:''' Dieser Filter wurde automatisch als schädlich markiert. Aus Sicherheitsgründen werden die folgenden Aktionen nicht ausgeführt ($1). Bitte überprüfe und [[mw:Extension:AbuseFilter/Conditions|optimiere]] deine Bedingungen, um diese Beschränkung aufzuheben.", "abusefilter-edit-new": "Neuer Filter", "abusefilter-edit-save": "Filter speichern", @@ -226,13 +246,18 @@ "abusefilter-edit-throttle-count": "Anzahl erlaubter Aktionen:", "abusefilter-edit-throttle-period": "Zeitraum (in Sekunden):", "abusefilter-edit-throttle-groups": "Drosselung gruppieren nach:", - "abusefilter-edit-throttle-ip": "IP-Adresse", - "abusefilter-edit-throttle-user": "Benutzerkonto", - "abusefilter-edit-throttle-range": "/16-Bereich", - "abusefilter-edit-throttle-creationdate": "Serverzeit der Benutzerkontenerstellung", - "abusefilter-edit-throttle-editcount": "Bearbeitungszähler", - "abusefilter-edit-throttle-site": "Die gesamte Website", - "abusefilter-edit-throttle-page": "Seite", + "abusefilter-edit-throttle-groups-help": "Siehe $1.", + "abusefilter-edit-throttle-groups-help-text": "die Dokumentation auf mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Mit Kommata trennen, um mit AND zu verbinden und mit Zeilenumbrüchen, um mit OR zu verbinden.", + "abusefilter-edit-throttle-placeholder": "Mit Kommata trennen, um mit AND zu verbinden und füge nacheinander ein, um mit OR zu verbinden.", + "abusefilter-throttle-ip": "IP-Adresse", + "abusefilter-throttle-user": "Benutzerkonto", + "abusefilter-throttle-range": "/16-Bereich", + "abusefilter-throttle-creationdate": "Datum der Benutzerkontenerstellung", + "abusefilter-throttle-editcount": "Bearbeitungszähler", + "abusefilter-throttle-site": "Gesamte Website", + "abusefilter-throttle-page": "Seite", + "abusefilter-throttle-none": "(keine)", "abusefilter-throttle-details": "{{PLURAL:$1|Eine Aktion|$1 Aktionen}} {{PLURAL:$2|jede Sekunde|alle $2 Sekunden}} erlauben, Drosselungen gruppieren nach: $3", "abusefilter-edit-warn-message": "Systemnachricht für die Warnung:", "abusefilter-edit-warn-other": "Andere Systemnachricht", @@ -272,10 +297,18 @@ "abusefilter-edit-export": "Diesen Filter in ein anderes Wiki exportieren", "abusefilter-edit-syntaxok": "Keine Syntaxfehler gefunden.", "abusefilter-edit-syntaxerr": "Syntaxfehler gefunden: $1", + "abusefilter-edit-warn-leave": "Durch das Verlassen der Seite gehen alle Änderungen an diesem Filter verloren.", "abusefilter-edit-bad-tags": "Eine oder mehrere der angegebenen Markierungen sind nicht gültig.\nMarkierungen sollten kurz sein, sie dürfen keine Sonderzeichen enthalten und nicht durch eine andere Software reserviert sein. Versuche, einen neuen Markierungsnamen auszuwählen.", "abusefilter-edit-notallowed": "Es ist dir nicht erlaubt, Missbrauchsfilter zu erstellen oder zu bearbeiten", "abusefilter-edit-notallowed-global": "Du bist nicht berechtigt, globale Missbrauchsfilter zu erstellen oder zu verändern.", - "abusefilter-edit-notallowed-global-custom-msg": "Benutzerdefinierte Warnnachrichten werden für globale Filter nicht unterstützt.", + "abusefilter-edit-notallowed-global-custom-msg": "Benutzerdefinierte Warn- oder Verbotsnachrichten werden für globale Filter nicht unterstützt.", + "abusefilter-edit-invalid-warn-message": "Die Warnnachricht kann nicht leer gelassen werden.", + "abusefilter-edit-invalid-disallow-message": "Die Verbieten-Nachricht kann nicht leer gelassen werden.", + "abusefilter-edit-invalid-throttlecount": "Der Drosselungsaktionszähler muss eine positive Ganzzahl haben.", + "abusefilter-edit-invalid-throttleperiod": "Die Drosselungsperiode muss eine positive Ganzzahl haben.", + "abusefilter-edit-empty-throttlegroups": "Es muss mindestens eine Drosselungsgruppe ausgewählt werden.", + "abusefilter-edit-duplicated-throttlegroups": "Drosselungsgruppen können keine Duplikate haben.", + "abusefilter-edit-invalid-throttlegroups": "Die angegebenen Drosselungsgruppen sind ungültig.", "abusefilter-edit-builder-select": "Wähle eine Option aus, um sie am Cursor einzufügen", "abusefilter-edit-builder-group-op-arithmetic": "Arithmetische Operatoren", "abusefilter-edit-builder-op-arithmetic-addition": "Addition (+)", @@ -305,7 +338,8 @@ "abusefilter-edit-builder-misc-contains": "Linke Zeichenkette beinhaltet rechte Zeichenkette (contains)", "abusefilter-edit-builder-misc-stringlit": "Feste Zeichenkette (\"\")", "abusefilter-edit-builder-misc-tern": "Kurze Operatoren (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Konditional (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Konditional (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "Kurze Bedingung (if X then Y end)", "abusefilter-edit-builder-group-funcs": "Funktionen", "abusefilter-edit-builder-funcs-length": "Länge der Zeichenfolge (length)", "abusefilter-edit-builder-funcs-lcase": "In Kleinbuchstaben konvertieren (lcase)", @@ -376,12 +410,12 @@ "abusefilter-edit-builder-vars-all-links": "Alle externen Links im neuen Text", "abusefilter-edit-builder-vars-added-links": "Alle durch die Bearbeitung hinzugefügten externen Links", "abusefilter-edit-builder-vars-removed-links": "Alle durch die Bearbeitung entfernten externen Links", - "abusefilter-edit-builder-vars-old-text": "Alter Wikitext der Seite, vor der Bearbeitung (nicht mehr in Verwendung)", - "abusefilter-edit-builder-vars-new-text": "Neuer Wikitext der Seite, nach der Bearbeitung", + "abusefilter-edit-builder-vars-old-wikitext": "Alter Wikitext der Seite, vor der Bearbeitung", + "abusefilter-edit-builder-vars-new-wikitext": "Neuer Wikitext der Seite, nach der Bearbeitung", "abusefilter-edit-builder-vars-new-pst": "Neuer Seitenwikitext, vor dem Speichern umgewandelt", "abusefilter-edit-builder-vars-diff-pst": "Vereinigter Änderungsunterschied nach Bearbeitung, vor dem Speichern umgewandelt", "abusefilter-edit-builder-vars-addedlines-pst": "Zeilen in der Bearbeitung hinzugefügt, vor dem Speichern umgewandelt", - "abusefilter-edit-builder-vars-new-text-stripped": "Neuer Seitentext, von jeglicher Textauszeichnung befreit", + "abusefilter-edit-builder-vars-new-text": "Neuer Seitentext, von jeglicher Textauszeichnung befreit", "abusefilter-edit-builder-vars-new-html": "HTML-Quelltext der neuen Version", "abusefilter-edit-builder-vars-restrictions-edit": "Bearbeiten-Schutzstufe der Seite", "abusefilter-edit-builder-vars-restrictions-move": "Verschieben-Schutzstufe der Seite", @@ -395,10 +429,10 @@ "abusefilter-edit-builder-vars-movedto-restrictions-move": "Verschiebe-Schutzstatus der Verschiebe-Zielseite", "abusefilter-edit-builder-vars-movedto-restrictions-create": "Erstellschutz der Verschiebe-Zielseite", "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Hochladeschutz der Verschiebe-Zieldatei", - "abusefilter-edit-builder-vars-old-text-stripped": "Alter Seitentext, von jeglicher Textauszeichnung befreit", + "abusefilter-edit-builder-vars-old-text": "Alter Seitentext, von jeglicher Textauszeichnung befreit (nicht mehr in Verwendung)", "abusefilter-edit-builder-vars-old-links": "Links der Seite, vor der Bearbeitung", "abusefilter-edit-builder-vars-old-html": "HTML-Quelltext der alten Version (nicht mehr in Verwendung)", - "abusefilter-edit-builder-vars-minor-edit": "Bearbeitung wurde als Kleinigkeit markiert", + "abusefilter-edit-builder-vars-minor-edit": "Ob die Bearbeitung als geringfügig markiert ist oder nicht (nicht mehr in Verwendung)", "abusefilter-edit-builder-vars-file-sha1": "SHA1-Hash von Dateiinhalt", "abusefilter-edit-builder-vars-file-size": "Dateigröße in Bytes", "abusefilter-edit-builder-vars-file-mime": "MIME-Typ der Datei", @@ -406,6 +440,8 @@ "abusefilter-edit-builder-vars-file-width": "Breite der Datei in Pixel", "abusefilter-edit-builder-vars-file-height": "Höhe der Datei in Pixel", "abusefilter-edit-builder-vars-file-bits-per-channel": "Bits pro Farbkanal der Datei", + "abusefilter-edit-builder-vars-wiki-name": "Datenbankname des Wikis", + "abusefilter-edit-builder-vars-wiki-language": "Sprachcode des Wikis", "abusefilter-filter-log": "Missbrauchsfilter-Änderungen", "abusefilter-history": "Versionsgeschichte für Missbrauchsfilter $1", "abusefilter-history-foruser": "Änderungen von $1", @@ -439,13 +475,16 @@ "abusefilter-exception-dividebyzero": "Division von $2 durch Null bei Zeichen $1.", "abusefilter-exception-unrecognisedvar": "Unerkannte Variable $2 bei Zeichen $1", "abusefilter-exception-notenoughargs": "Der Funktion $2 wurden an Zeichen $1 zu wenige Argumente übergeben.\nEs {{PLURAL:$3|wurde $3 Argument|wurden $3 Argumente}} erwartet, übergeben {{PLURAL:$4|wurde $4|wurden $4}}.", + "abusefilter-exception-toomanyargs": "Zu viele Argumente für die Funktion $2, die bei Zeichen $1 aufgerufen wird.\nErwartet wurden höchstens $3 {{PLURAL:$3|Argument|Argumente}}, übertragen $4", "abusefilter-exception-regexfailure": "Fehler im regulären Ausdruck „$2“ an Zeichen $1.", "abusefilter-exception-overridebuiltin": "Verbotenes Überschreiben der eingebauten Variable „$2“ an Zeichen $1.", "abusefilter-exception-outofbounds": "Anforderung des nicht vorhandenen Anordnungseintrages $2 (Anordnungsgröße: $3) an Zeichen $1.", + "abusefilter-exception-negativeindex": "Negative Indizes sind in Arrays nicht erlaubt. Hat den Index „$2“ bei Zeichen $1.", "abusefilter-exception-notarray": "Anforderung eines Arrayelements aus einem Nicht-Array bei Zeichen „$1“.", "abusefilter-exception-unclosedcomment": "Nicht abgeschlossener Kommentar bei Zeichen $1.", "abusefilter-exception-invalidiprange": "Ungültigen IP-Adressbereich „$2“ bei Zeichen $1 angegeben.", "abusefilter-exception-disabledvar": "Die Variable $2 bei Zeichen $1 ist nicht mehr in Verwendung.", + "abusefilter-exception-variablevariable": "set und set_var erwarten, dass das erste Argument ein Zeichenkettenliteral ist, gefunden bei Zeichen $1.", "abusefilter-action-tag": "Markierung", "abusefilter-action-throttle": "Drosseln", "abusefilter-action-warn": "Warnen", @@ -508,15 +547,16 @@ "abusefilter-examine-noresults": "Es wurden keine Ergebnisse für die angegebenen Suchparameter gefunden.", "abusefilter-topnav": "'''Missbrauchsfilter-Navigation'''", "abusefilter-topnav-home": "Startseite", + "abusefilter-topnav-recentchanges": "Letzte Filteränderungen", "abusefilter-topnav-test": "Regeln testen", "abusefilter-topnav-examine": "Untersuchung der letzten Änderungen", "abusefilter-topnav-log": "Logbuch", "abusefilter-topnav-tools": "Debugging", - "abusefilter-topnav-import": "Filter importieren", "abusefilter-log-name": "Missbrauchsfilter-Logbuch", "abusefilter-log-header": "Dieses Logbuch zeigt eine Zusammenfassung der Änderungen an Filtern.\nGenauere Einzelheiten sind in [[Special:AbuseFilter/history|der Liste]] der letzten Änderungen an Filtern zu finden.", "abusefilter-logentry-create": "$1 {{GENDER:$2|erstellte}} $4 ($5)", "abusefilter-logentry-modify": "$1 {{GENDER:$2|veränderte}} $4 ($5)", + "abusefilter-log-invalid-filter": "Einige der angegebenen Filter-IDs sind ungültig.", "abusefilter-log-noresults": "Keine Ergebnisse", "abusefilter-diff-title": "Unterschied zwischen Versionen", "abusefilter-diff-item": "Element", @@ -529,11 +569,12 @@ "abusefilter-diff-next": "Neuere Änderung", "abusefilter-import-intro": "Du kannst diese Schnittstelle verwenden, um Filter aus anderen Wikis zu importieren.\nKlicke im Quellwiki auf die Schaltfläche „{{int:abusefilter-edit-export}}“ innerhalb von „{{int:abusefilter-edit-tools}}“.\nKopiere den dort erscheinenden Code, füge ihn hier ein und klicke dann auf die Schaltfläche „{{int:abusefilter-import-submit}}“.", "abusefilter-import-submit": "Daten importieren", + "abusefilter-import-invalid-data": "Die Daten, die du versucht hast zu importieren, sind nicht gültig", "abusefilter-group-default": "Standard", "abusefilter-http-error": "Ein HTTP-Fehler ist aufgetreten: $1.", - "abusefilter-view-private-submit": "Private Einzelheiten ansehen", - "abusefilter-view-private": "Private Einzelheiten ansehen", - "abusefilter-view-private-reason": "Grund für den Zugriff auf private Einzelheiten:", + "abusefilter-view-privatedetails-submit": "Private Einzelheiten ansehen", + "abusefilter-view-privatedetails-legend": "Private Einzelheiten ansehen", + "abusefilter-view-privatedetails-reason": "Grund für den Zugriff auf private Einzelheiten:", "abusefilter-log-details-id": "Logbuchkennung", "abusefilter-invalid-request": "Ungültige Anfrage! Du musst auf private Logbucheinzelheiten mit dem Formular auf [[Special:AbuseLog/$1]] zugreifen und einen Grund angeben.", "abusefilter-invalid-request-noid": "Ungültige Anfrage! Du musst auf private Eintragseinzelheiten mit dem Formular auf der Missbrauchsfilter-Einzelheitenseite zugreifen und einen Grund angeben.", diff --git a/AbuseFilter/i18n/diq.json b/AbuseFilter/i18n/diq.json index b66f3975..2b072eda 100644 --- a/AbuseFilter/i18n/diq.json +++ b/AbuseFilter/i18n/diq.json @@ -1,67 +1,89 @@ { "@metadata": { "authors": [ + "1917 Ekim Devrimi", + "Asmen", "Aspar", "Erdemaslancan", + "Gambollar", "Gorizon", + "Gırd", + "Kumkumuk", "Marmase", - "Mirzali", - "Xoser", "Matma Rex", - "Kumkumuk", - "1917 Ekim Devrimi", - "Gırd", - "Gambollar", - "Asmen" + "Mirzali", + "Orbot707", + "Xoser" ] }, "abusefilter-desc": "Vurnayışa rê terzê otomatik vınakari dezge keno", - "abusefilter": "Vıraştışê gırwenayışê xırabi", - "abuselog": "Qeydê parzumi", + "abusefilter": "İdareyê parzûnê tecizi", + "abuselog": "Rocekê parzûnê tecizi", "abusefilter-intro": "Îdareyê filitreyê abuseyî şima xeyr ameyî.\nFilitreyê abuseyî yew softwareyê otomatikî ke otomatik heuristics applikasyon keno.\nEna pele yew listeyê filitreyî mucneno u vurnayîşan rê destur dano.", "abusefilter-warning": "'''Balantış''': Eno hereket otomatikmen zerarın tesbit bi yo.\nVurnayışê zerarıni be lez do peyd bıgêri yo,\nu vurnayışo xırabın ya zi zerarın neticey xo hesabê şıma de vêneno ya zi afresa IP ya şıma bloqe bena.\nŞıma ke fıkıriyenê no vurnayış hewlo, şenê be tesdiq kerdış ney qeyd kerê.\nSuistımal kerdışê qeydey sero yew arezekerdışo kılmo ke hereketê şıma eyar keno: $1", "abusefilter-disallowed": "Eno kerdış otomatikmên zey zerarın ameyo motış u coka izıne nêameya gırewtış.\nEger şıma bawer kenê ke enê kerdış biyo hewl, şıma se kerdêne , reca bena ke yew admin ra xebere bıdê.\nYew şınasnayışo kılmo ke be ixlalê şıma ra bestiyeno, zey wıni mocniyeno: $1", "abusefilter-blocked-display": "Ena hereket hewl niyo u zerar dano,\naye ra ti niekeno qeyd bike.\nEyni zemun de, qe pawitişê {{SITENAME}}î hesab u IPyê tu blok biyo.\nEka ti van ma yew ğeletî keno, yew îdare kerdoğê sîteyî rê mesaj bişirave.\nYew deskripsiyonê hereketê tu zerarin: $1", "abusefilter-degrouped": "Ena hereket hewl niya u zerar dana.\nEger ke destur şıma çini yo u heqanê şıma yê pêron ma şıma ra grot o. \nEka şıma van ma yew ğeletey kerd o, ju idarekarê sita rê mesaj bırışê. Eka yew ğelet esto, ma heqanê şıma pêron fına peyser dam.\nJu şınasiya hereketa şıma ya zerarın: $1", "abusefilter-autopromote-blocked": "Ena hereket hewl niyo u zerar dano u aye ra destur tu çini yo.\nQe pawitişê sîte, heqanê tu yê nime ma ti ra grewt.\nYew deskripsiyonê hereketê tu zerarin: $1", - "abusefilter-blocker": "Filtreyê peygoşi", + "abusefilter-blocker": "Parzûnê tecizi", "abusefilter-blockreason": "Filtre de peygoşkerdışira otomatikmen vındarneya.\nŞertê şınasiye: $1", "abusefilter-degroupreason": "Filtreyê peygoşkerdışi ra heki otomatikmen wedaryay.\nŞertê şınasiye: $1", "abusefilter-accountreserved": "Nameyê nê hesabî Filtreyê peygoş kerdışi xo karfiyo deye istifyayo.", - "right-abusefilter-modify": "Filtreyê peygoşi bıvurnê", - "right-abusefilter-view": "Filtreyê peygoş kerıdşi bıvinê", + "right-abusefilter-modify": "Parzûnê suistimali bıvurnê u vırazê", + "right-abusefilter-view": "Parzûnanê suistimali bıvêne", "right-abusefilter-log": "Rocekanê peygoş kerdışa bıvinê", "right-abusefilter-log-detail": "Teferruatanê cıkewtışanê peygoş kerdışa bıvin", - "right-abusefilter-private": "Xısusi melamata rocekan de peyoşkerdışa bıvinê", - "right-abusefilter-modify-restricted": "Filitreyê abuseyî bivurne, pê aksiyonê restrictî", - "right-abusefilter-revert": "Vurnayîşî ke pê filitreyê abuseyî biy, inan reyna biyar", - "right-abusefilter-view-private": "Filitreyê abuse yê xasî bivine", + "right-abusefilter-privatedetails": "Xısusi melamata rocekan de peyoşkerdışa bıvinê", + "right-abusefilter-privatedetails-log": "Resayışanê xısusiyanê parzûnê suistimali bıvêne", + "right-abusefilter-modify-restricted": "Parzûnê suistimali be fealiyetanê qedexan bıvurne", + "right-abusefilter-revert": "Vurnayışanê ke terefê parzûnê suistimali ra biyê, pêro peyser biya", + "right-abusefilter-view-private": "Xısusi nısan bıyaye parzûnê tecızi bıvênên", "right-abusefilter-log-private": "Xısusi qeydê parzunê ke şıma nışan kerdê ena mocneno", - "right-abusefilter-hide-log": "Logê abuseyi de vurnayişi binumne", - "right-abusefilter-hidden-log": "Logê abuse yê numnayî bivine", - "right-abusefilter-modify-global": "Global filtrya nenga vıraz yana timar ke", - "action-abusefilter-modify": "filitreyê abuseyî bivurne", - "action-abusefilter-view": "Filitreyê abuseyî bivine", - "action-abusefilter-log": "Rocekanê peygoş kerdışa bıvinê", - "action-abusefilter-log-detail": "Qeydé detayan de rocekan de nenga bıvin", - "action-abusefilter-private": "Bağse malumaté qeydané nenga bıvin", - "action-abusefilter-modify-restricted": "filitreyê abuseyî bivurne, pê aksiyonê restrictî", + "right-abusefilter-hide-log": "Rocekê nengan de vurnayışanê dekerda bınınne", + "right-abusefilter-hidden-log": "Nımniyaye qeydanê cıkewtışanê ar karnayışê bıvênê", + "right-abusefilter-modify-global": "Parzûnê tecıziyê globali vırazê ya zi bıvurne", + "action-abusefilter-modify": "parzûnê suistimali bıvurne", + "action-abusefilter-view": "parzûnê suistimali bıvêne", + "action-abusefilter-log": "parzûnê suistimali bıvêne", + "action-abusefilter-log-detail": "qeydê detayan de parzûnê suistimali bıvêne", + "action-abusefilter-privatedetails": "melumatê xısusiyan qeydanê parzûnê suistimali de bıvêne", + "action-abusefilter-privatedetails-log": "resayışanê xısusiyanê parzûnê suistimali bıvêne", + "action-abusefilter-modify-restricted": "vurnayışê parzûnê tecizi be karanê menbiyayeyan ra", "action-abusefilter-revert": "vurnayîşî ke pê filitreyê abuseyî biy, inan reyna biyar", - "action-abusefilter-view-private": "Filitreyê abuse yê xasî bivine", + "action-abusefilter-view-private": "Xısusi nısan bıyaye parzûnê tecızi bıvênên", "action-abusefilter-log-private": "Xısusi qeydê parzunê ke şıma nışan kerdê ena mosneno", - "abusefilter-log": "Rocekê filtre de peygoş kerdışan", + "action-abusefilter-hide-log": "Rocekê nengan de vurnayışa bınınne", + "action-abusefilter-hidden-log": "Rocekê kewtekanê nımnaye nengan bımocne", + "action-abusefilter-modify-global": "Global parzûnê nenga vıraz yana timar ke", "abusefilter-log-summary": "Ena log de yew di hereket estê ke pê filitreyî tepişiyo.", "abusefilter-log-search": "Bıgeyr qeydé rocekan dé nenga", "abusefilter-log-search-user": "Karber:", - "abusefilter-log-search-filter": "Kamiya parzûni (boriyan ra ciya):", + "abusefilter-log-search-group": "Parzûnê grube:", + "abusefilter-log-search-group-any": "Qet", + "abusefilter-log-search-filter": "Kamiya parzûni:", + "abusefilter-log-search-filter-help": "Pê boriyana cayo, seba umumi parzûna veroley \"$1\"", + "abusefilter-log-search-filter-help-central": "Pê boriyana abırne", "abusefilter-log-search-title": "Sername:", "abusefilter-log-search-wiki": "Wiki:", + "abusefilter-log-search-impact": "Tesir:", + "abusefilter-log-search-impact-all": "Aksiyoni pêro", + "abusefilter-log-search-impact-saved": "Teyna vurnayışanê qeyd bıyaya", + "abusefilter-log-search-impact-not-saved": "Bê vurnayışanê qeyd bıyaya", + "abusefilter-log-search-entries-label": "Asayış:", + "abusefilter-log-search-entries-all": "Dekerdışi pêro", + "abusefilter-log-search-entries-hidden": "Teyna dekerdışê dızdeyına", + "abusefilter-log-search-entries-visible": "Teyna asaye dekerdışi", + "abusefilter-log-search-action-label": "Kerdena tesiri:", + "abusefilter-log-search-action-other": "Zewbi", + "abusefilter-log-search-action-any": "Qet", + "abusefilter-log-search-action-taken-label": "Gêriyaye aksiyon:", + "abusefilter-log-search-action-taken-any": "Qet", "abusefilter-log-search-submit": "Cı geyre", "abusefilter-log-entry": "$1: $2 filtraya nengan akerd, $4 de {{GENDER:$8|hereketê}} \"$3\"i kerd.\nHereket: $5;\nŞınasiya filtra: $6", "abusefilter-log-entry-withdiff": "$1: $2 avrêca nenga akerda, ser $4 de {{GENDER:$8|hereketê}} \"$3\"i {{GENDER:$8|kerd ser}} .\nHereket: $5;\nŞılasnayışa avrêci: $6($7)", "abusefilter-log-detailedentry-meta": "$1: $2 kerd $3, ser $5 de {{GENDER:$9|hereketê}} \"$4\"i {{GENDER:$9|kerd ser }} .\nHereket: $6;\nŞınasiya parzumi: $7 ($8)", "abusefilter-log-detailedentry-global": "parzûno global $1", - "abusefilter-log-detailedentry-local": "filitreyê $1î", + "abusefilter-log-detailedentry-local": "parzûnê $1", "abusefilter-log-detailslink": "teferruati", "abusefilter-log-diff": "ferq", "abusefilter-log-hidelink": "vinayişi eyar bike", @@ -69,85 +91,122 @@ "abusefilter-log-details-var": "Vurnayiye", "abusefilter-log-details-val": "Erc", "abusefilter-log-details-vars": "Parametereyê hereketî", - "abusefilter-log-details-private": "Datayê xasî", + "abusefilter-log-details-privatedetails": "Detayê rocekanê xısusa", "abusefilter-log-details-ip": "Adresê IPyê oricinalî", - "abusefilter-log-noactions": "ne", + "abusefilter-log-details-checkuser": "Teftişwan", + "abusefilter-log-noactions": "çıniyo", + "abusefilter-log-noactions-filter": "Adet yew", "abusefilter-log-details-diff": "Ena nuşteyî de vurnayîşî", - "abusefilter-log-linkoncontribs": "Qeydê parzumi", - "abusefilter-log-linkoncontribs-text": "Qeydé karberi roceka nengan", - "abusefilter-log-hidden": "(vurnayiş numnayeye)", + "abusefilter-log-linkoncontribs": "qeydê suistimali", + "abusefilter-log-linkoncontribs-text": "Seba {{GENDER:$1|nê karbe}} roceka xırab karkerdışi", + "abusefilter-log-linkonhistory": "Roceka istismari bıvinê", + "abusefilter-log-linkonhistory-text": "Seba na pela roceka nengan bımocne", + "abusefilter-log-linkonundelete": "Roceka nengan bıvênê", + "abusefilter-log-linkonundelete-text": "Seba na pela roceka nengan bımocne", "abusefilter-log-hidden-implicit": "(nımteyo deye rewizyon besterneya)", "abusefilter-log-cannot-see-details": "Miyan kewtıştê enay rê mısade çıno.", + "abusefilter-log-cannot-see-privatedetails": "Xısusi detayanê nê meqaley vinayışi rê mısade çıniyo", "abusefilter-log-nonexistent": "ID'a Kerdeki Dekeweki ya zey pê niya.", "abusefilter-log-details-hidden": "Ti nieşkeno detayanê ena filitre bivîne, çunkî ena filitre kamu ra nimniyayo.", + "abusefilter-log-details-hidden-implicit": "Eleqeyın revizyon esteriyayo coki ra şıma nêşenê detaya bıvênê", "abusefilter-log-private-not-included": "Nışanyaye kamiya filtreyan bağseyê. Şıma wazenê ke detayanê fiktreya bıvinê yana Cıgeyre se eno mıkum niyo, çıkı cı geyrayış red biyo icazet nêdeya yo", "abusefilter-log-hide-legend": "Miyan kewtışa bınımne", - "abusefilter-log-hide-id": "Huviyetê logê vurnayişi:", - "abusefilter-log-hide-hidden": "Ena vurnayişi şar ra binumne", + "abusefilter-log-hide-id": "Numreyê qeydê cıkewtışi:", + "abusefilter-log-hide-hidden": "Enê vurnayışi pêroyıne ra bınımne", "abusefilter-log-hide-reason": "Sebeb:", - "abusefilter-log-hide-forbidden": "Tu ra destur cini ke logê xirabi bikefilne.", + "abusefilter-log-hide-reason-other": "Sebebo bin/ilaweyın:", + "abusefilter-log-hide-forbidden": "Şıma rê desturê qeydê parzûnê tecizi nımnayışi çıniyo.", + "abusefilter-log-entry-suppress": "$1 {{GENDER:$2|bınım}} $3", + "abusefilter-log-entry-unsuppress": "$1 {{GENDER:$2|menım}} $3", "logentry-abusefilter-hit": "Sebebê $1'i $4 {{GENDER:$2|bı}} , \"$5\" kerdo $3 {{GENDER:$2|ser}} . verkewtışê ke gêriyayê: $6 ($7)", - "abusefilter-management": "idarayê filitreyê abuseyî", + "log-action-filter-abusefilter": "Tewrê parzûni vurnayış:", + "log-action-filter-abusefilter-create": "Filtreyo newe vıraştış", + "log-action-filter-abusefilter-modify": "Vurnayışê parzûni", + "log-action-filter-suppress-abuselog": "Seveknayışê parzûnê tecizbiyayışi", + "log-action-filter-rights-blockautopromote": "Bloqey Otopromoti", + "log-action-filter-rights-restoreautopromote": "Otopromot peyd barkerê", + "logentry-abusefilterprivatedetails-access": "$1, seba $3 detayanê xısusiya {{GENDER:$2|resayê}}", + "logentry-rights-blockautopromote": "$1 otopromot {{GENDER:$4|$3}} seba tay zemani rê $5 {{GENDER:$2|kerdo bloqe }}", + "logentry-rights-restoreautopromote": "$1, {{GENDER:$4|$3}} hunerê otopromotion {{GENDER:$2|peyser bar kerdo }}", + "abusefilterprivatedetails-log-name": "Xısusi resayışê detayanê roceka rengan", "abusefilter-list": "Parzûni pêro", - "abusefilter-list-id": "IDyê Filitreyî", + "abusefilter-list-id": "Kamiya parzûni", + "abusefilter-list-pattern": "Qalıb", "abusefilter-list-status": "Weziyet", - "abusefilter-list-public": "Deskripsiyonê şarî", + "abusefilter-list-public": "Melumato umumi", "abusefilter-list-consequences": "Qerar", - "abusefilter-list-visibility": "Vinayîşî", - "abusefilter-list-hitcount": "Amarê reytingi", - "abusefilter-list-edit": "Bıvırne", + "abusefilter-list-visibility": "Asayış", + "abusefilter-list-hitcount": "Amarê isabeti", + "abusefilter-list-edit": "Bıvurne", "abusefilter-list-details": "Teferruati", - "abusefilter-list-limit": "Amarî ser yew pel:", - "abusefilter-list-lastmodified": "Vurnayîşê tewr penî", + "abusefilter-list-limit": "Amarê her pele:", + "abusefilter-list-lastmodified": "Vurnayışo verên", "abusefilter-list-group": "Parzûnê grube", "abusefilter-hidden": "Xısusi", "abusefilter-unhidden": "Şar", - "abusefilter-enabled": "Aktifiyaye", + "abusefilter-enabled": "Feal", "abusefilter-deleted": "Esteriya", "abusefilter-disabled": "Astengın", + "abusefilter-throttled": "veng bırna", "abusefilter-hitcount": "$1 {{PLURAL:$1|cıgêno|cıgênê}}", "abusefilter-new": "Yew filitreyê newî viraze", + "abusefilter-import-button": "Filitre împort bike", "abusefilter-return": "Peyser şo idareyê parzûni", "abusefilter-status-global": "Global", - "abusefilter-list-options": "Weçinegi", + "abusefilter-list-options": "Weçinıteki", "abusefilter-list-options-deleted": "Filtreyan ke wedariya", - "abusefilter-list-options-deleted-only": "Teyna filitreyê wedariyayî bimucne", - "abusefilter-list-options-deleted-hide": "Filitreyê wedariyayî binimne", - "abusefilter-list-options-deleted-show": "Filitreyê wedariyayî de biker", - "abusefilter-list-options-scope": "Avrêci tiya ra bıasne:", + "abusefilter-list-options-deleted-only": "Teyna parzûnanê esteriyayan bımocne", + "abusefilter-list-options-deleted-hide": "Parzûnanê esteriyayan bınımne", + "abusefilter-list-options-deleted-show": "Parzûnanê esterıteyan daxıl kerê", + "abusefilter-list-options-scope": "Parzûni bımocne:", "abusefilter-list-options-scope-local": "Tenya qeydeyê mehaliyi", - "abusefilter-list-options-scope-global": "Twyna global rolan", - "abusefilter-list-options-scope-all": "Rolê lokal u globali", + "abusefilter-list-options-scope-global": "Teyna qeydeyê globali", + "abusefilter-list-options-scope-all": "Qeydeyê lokal û globali", + "abusefilter-list-options-further-options": "Weçinıtışê bini:", "abusefilter-list-options-hidedisabled": "Filitreyê qefilnaye binimne", - "abusefilter-list-options-submit": "Rocane ke", + "abusefilter-list-options-hideprivate": "Parzûnanê xısusiyan bınımne", + "abusefilter-list-options-searchfield": "Şertan miyan de cı geyre:", + "abusefilter-list-options-searchpattern": "Yew qalıb cı ke", + "abusefilter-list-options-searchoptions": "Modê cıgeyrayışi:", + "abusefilter-list-options-search-like": "Persayışo dûz", + "abusefilter-list-options-search-rlike": "Persayışo nizami", + "abusefilter-list-options-search-irlike": "Persayışo ke herfanê gırd-qıcan rê hesaso", + "abusefilter-list-invalid-searchmode": "Wazıyaye mode cıgeyrayışi çıniyo", + "abusefilter-list-regexerror": "Demê cıgeyrayışi dê xeta veciyê:İfadeyê normal de xetay çekuya", + "abusefilter-list-options-submit": "Rocane kerê", "abusefilter-tools-text": "wexta ke filtreya suistimali formule bena nê hacet lazım beni.", - "abusefilter-tools-expr": "Testê ifadi", - "abusefilter-tools-submitexpr": "Bercınê", + "abusefilter-tools-expr": "Testê ifadeyi", + "abusefilter-tools-submitexpr": "Bıercne", + "abusefilter-tools-syntax-error": "Ena filter de yew rêza xelat esta.", "abusefilter-tools-reautoconfirm": "Weziyetê xob xo araşt kerdışi peyser biya", "abusefilter-tools-reautoconfirm-user": "Karber:", "abusefilter-tools-reautoconfirm-submit": "Reyna otoconfirme bike", + "abusefilter-tools-restoreautopromote": "Otomatik şınastiye, hacetê nengana peyser gêriya", "abusefilter-reautoconfirm-none": "halê otomatik-tesdiqkerdış {{GENDER:$1|karberi|karberi|karberan}} battal nêbı.", "abusefilter-reautoconfirm-notallowed": "desthelatiyê şıma çino şıma otomatik-tesdiqkerdış biyari.", "abusefilter-reautoconfirm-done": "halê otomatik-tesdiqkerdışê hesabi tepiya ameyo", - "abusefilter-status": "$1 {{PLURAL:$1|karo|karo}} peyin de, $2 (%$3) filtre $4 resa sinorê şerti u $5 (%$6) kar yew filtreya aktif de hemcıt bı.", - "abusefilter-edit": "Filtreya nengan timar kerış", - "abusefilter-edit-subtitle": "Filitreyê $1î ho vurneno", - "abusefilter-edit-subtitle-new": "Vıraştışê parzûni", + "abusefilter-status": "$1 {{PLURAL:$1|karo|karanê}} peyin de, $2 (%$3) filtre $4 resa sinorê şerti u {{PRULAR:$5|rest limit|testê limita}} (%$6) kar yew filtreya aktif de hemcıt bı.", + "abusefilter-edit": "Parzûnê tecizi vurniyeno", + "abusefilter-edit-subtitle": "Parzûnê $1 vurneno", + "abusefilter-edit-subtitle-new": "Parzûn vıraziyeno", + "abusefilter-edit-token-not-match": "Vurnayış nêşevekneyayo! Kerem ke, fına bışevekne.", "abusefilter-edit-oldwarning": "<strong>şıma (hê) revizyonê no filtreyi vurneni.\nnê istatiski qey na filtreya.\n.</strong> •\n[[Special:AbuseFilter/history/$2|agêr hal-verinê na filtre]].", "abusefilter-edit-status-label": "İstatistiki:", - "abusefilter-edit-status": "{{PLURAL:$1|Karo peyên|Karanê peyenan}} $1 de, karo $2 nısbetê ($3%) de nê parzûn ra piya bi be yew.", - "abusefilter-edit-status-profile": "{{PLURAL:$1|Karo peyên|Karanê peyenan}} $1 de, karo $2 nısbetê ($3%) de nê parzûn ra piya bi be yew.\nMudetê karê miyanêniyo ke $4ms domneno, sinorê şerti $5 qedneno.", - "abusefilter-edit-new": "Filtreyê newî", + "abusefilter-edit-status": "$1 {{PLURAL:$1|Karo peyên|Karê peyêni}} miyan de, no filtre $2 (%$3) ra ameyo pê.\nNısbeten, zemanê guriyayışi $4 ms'yo u sindorê şerti texmini $5 {{PLURAL:$5|şert|şerti}} xerc kenê.", + "abusefilter-edit-new": "Parzûno newe", "abusefilter-edit-save": "Parzumi qeyd ke", - "abusefilter-edit-id": "IDyê filitreyî", - "abusefilter-edit-description": "Deskripsiyon:\n:''(herkes eşkenî bivîne)''", + "abusefilter-edit-id": "Kamiya parzûni:", + "abusefilter-edit-switch-editor": "Vurnayoği bıvurne", + "abusefilter-edit-description": "Şınasnayış:\n:''(her kes şeno bıvino)''", + "abusefilter-edit-field-description": "Şınasnayış", "abusefilter-edit-group": "Parzûnê grube:", - "abusefilter-edit-flags": "Îkazî:", + "abusefilter-edit-flags": "Temeyi:", "abusefilter-edit-enabled": "Ena filitre a bike", "abusefilter-edit-deleted": "Nîşanê wedariyaye da", "abusefilter-edit-hidden": "Detayanê ena filitre şar ra binumne", "abusefilter-edit-global": "Global avrêc", "abusefilter-edit-rules": "Şartî:", + "abusefilter-edit-field-conditions": "Şerti", "abusefilter-edit-notes": "Noti:", "abusefilter-edit-lastmod": "Ena filitre ke twer peni de vurnaye biya:", "abusefilter-edit-lastmod-text": "pê $2, $1", @@ -159,23 +218,48 @@ "abusefilter-edit-action-degroup": "Ena karber grupan ra wedarne", "abusefilter-edit-action-block": "Karber yaz zi adresê karberi bloke ke", "abusefilter-edit-action-throttle": "Eka karber yew limit ra zafyer şino, enê herketan biker", - "abusefilter-edit-action-rangeblock": "Mabeynê karberiyo /16ıne kılit ke", - "abusefilter-edit-action-tag": "Qe kontrole raverî ena vurnayîşî etiket bike", + "abusefilter-edit-action-rangeblock": "Mabeynê kamiya ke karber cı ra ameyo, ey kılit ke", + "abusefilter-edit-action-tag": "Çımsernayoğ ravêrberdışi rê vurnayışi etiket kerê", "abusefilter-edit-throttle-count": "Amarê hereketan ke destur guret:", - "abusefilter-edit-throttle-period": "Wext:", - "abusefilter-edit-throttle-groups": ":''(her satır re yew heb, pê virgul piyawanê-piya besnê)''", + "abusefilter-edit-throttle-period": "Periyodê zemani (saniye):", + "abusefilter-edit-throttle-groups": "Kışta grube kerden :", + "abusefilter-edit-throttle-groups-help": "$1 bıvêne.", + "abusefilter-edit-throttle-groups-help-text": "Dokumantasyonê mediawiki.org", + "abusefilter-throttle-ip": "Adresa IPy", + "abusefilter-throttle-user": "Hesabê karberi", + "abusefilter-throttle-range": "/16 sope", + "abusefilter-throttle-creationdate": "Tarixê hesab akerdışi", + "abusefilter-throttle-editcount": "hesabi bıvurne", + "abusefilter-throttle-site": "pela tame", + "abusefilter-throttle-page": "Pele", + "abusefilter-throttle-none": "(çıniyo)", "abusefilter-edit-warn-message": "Mesajê sistemî ke qe îkaz kerdişî viraziyo:", "abusefilter-edit-warn-other": "mesajo bin", - "abusefilter-edit-warn-other-label": "nameyê pelê mesaji yo binı:\n:''(wa prefixê medyawiki çinibo)''", + "abusefilter-edit-warn-other-label": "Namey pela mesacê bini:\n:\"(bê prefixê \"medyawiki:\")\"", "abusefilter-edit-warn-actions": "Kerdışi:", - "abusefilter-edit-warn-preview": "Verqaytê mesacê weçinıteyi", + "abusefilter-edit-warn-preview": "Verqaytê mesacê weçinıteyi bımocne/bınımne", "abusefilter-edit-warn-edit": "Mesacê weçinıteyi vıraze/bıvurne", - "abusefilter-edit-tag-tag": "[[Special:Tags|Etiketan]] tetbiq ke (herg xetrê yu) :", + "abusefilter-edit-disallow-message": "Mesajê sistemiyo ke qe iqaz kerdışi viraziyo:", + "abusefilter-edit-disallow-other": "Mesacê bini", + "abusefilter-edit-disallow-other-label": "Mesacê binê namey pele :\n:''(bê verbendê \"MediaWiki:\")''", + "abusefilter-edit-disallow-actions": "Kerdışi:", + "abusefilter-edit-disallow-preview": "Verqaytê weçineyayo mesaci bımocne/bınımnê", + "abusefilter-edit-disallow-edit": "Weçinaye mesaci vıraze/bıvurne", + "abusefilter-edit-tag-tag": "[[Special:Tags|Etiketan]] tetbiq ke:", + "abusefilter-edit-tag-placeholder": "Etiketa cı kerê (jew jew ya na pê virgula)", + "abusefilter-edit-tag-hidden-placeholder": "Etiketi dekerê (virgula abıriyayo)", + "abusefilter-edit-block-anon-durations": "Seba karberanê anoniman rê demê bloqey :", + "abusefilter-edit-block-user-durations": "Karberanê qeydınan rê demê bloqey:", + "abusefilter-block-anon": "Karberanê anonima bloqe bıkerê", + "abusefilter-block-user": "karberanê qeydbiyayeyan kılit ke", + "abusefilter-block-talk": "Pela mesaci bloqeyına", "abusefilter-edit-denied": "Ti nieşkeno detayanê ena filitre bivîne, çunkî ena filitre kamu ra nimniyayo.", "abusefilter-edit-main": "Parametreyan filitre bike", "abusefilter-edit-done-subtitle": "Vurnayîşî filitre bike", "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Vırnayışê şıma]] [[Special:AbuseFilter/$1|filtra $3]] rê ameyo seveknayış.", "abusefilter-edit-badsyntax": "filtreya ke şıma nişane kerdo tede xetay sentaksi esta.\nwesikay arêdayoxi: <pre>$1</pre>", + "abusefilter-edit-missingfields": "Cayê cêri mecburiyê u mecburen êdê pır bê:$1", + "abusefilter-edit-deleting-enabled": "Aktiv yew parzûni şıma nêşenê esteriyaye nışan bıkerê", "abusefilter-edit-restricted": "şıma nêeşkeni na filtre bıvurni çunke tede karo qedexebiyaye esto.", "abusefilter-edit-viewhistory": "Tarixê ena filitre bivîne", "abusefilter-edit-history": "Tarix:", @@ -187,10 +271,18 @@ "abusefilter-edit-export": "Ena filitre yew nw wîkî rê împort bike", "abusefilter-edit-syntaxok": "ğelatê syntax çin o", "abusefilter-edit-syntaxerr": "Ğeletê syntax esto: $1", - "abusefilter-edit-bad-tags": "etiketê ke şıma nişane kerdo tede nemeqbuli esti.\ngani etiketi kılm bıbi u tede karakterê xususi çinibi.", + "abusefilter-edit-warn-leave": "Pela ra veciyayış, ena parzun de vırnayışa vıni kerdışi rê sebeb beno", + "abusefilter-edit-bad-tags": "Etiketê ke şıma nışanê kerdo tede nemeqbuli esti.\nGani etiketi kılm bıbi u tede karakterê xususi çınê bo u yewna software ra rezerve wa nêbo. Yewna namey etiketi weçinıtışi bıcerrebnê", "abusefilter-edit-notallowed": "desturê şıma çino şıma filtreya suistimali vırazi ya zi bıvurni", "abusefilter-edit-notallowed-global": "desturê şıma çino şıma filtreya nenga vırazi ya zi bıvurni", - "abusefilter-edit-notallowed-global-custom-msg": "Masecé bağse ikazan qandé global avréca tesdiq névinené", + "abusefilter-edit-notallowed-global-custom-msg": "Mesacê xısusiyê iqaz û qedexeyan seba parzûnê gıloveri ra tesdiq nêvênenê.", + "abusefilter-edit-invalid-warn-message": "Mesacê iqazi veng nêbeno", + "abusefilter-edit-invalid-disallow-message": "Şıkê mesaci veng nêbeno", + "abusefilter-edit-invalid-throttlecount": "Amarê hereketê perperık wa amara pozitif bo", + "abusefilter-edit-invalid-throttleperiod": "hereketê perperık wa amara pozitif bo", + "abusefilter-edit-empty-throttlegroups": "Tewr cêri ra yew gruba perperık wa weçineyo", + "abusefilter-edit-duplicated-throttlegroups": "Kopyayı perperıka nêbeno", + "abusefilter-edit-invalid-throttlegroups": "Beşı kerde gruba perperık ravêrdi niya", "abusefilter-edit-builder-select": "İmleçte eklemek için bir seçenek seçin", "abusefilter-edit-builder-group-op-arithmetic": "Operasyonê arîtmetîkî", "abusefilter-edit-builder-op-arithmetic-addition": "De kerdiş (+)", @@ -200,8 +292,10 @@ "abusefilter-edit-builder-op-arithmetic-modulo": "Se de (%)", "abusefilter-edit-builder-op-arithmetic-pow": "Ser (**)", "abusefilter-edit-builder-group-op-comparison": "Operatoranê miqayeseyî", - "abusefilter-edit-builder-op-comparison-equal": "Fit (==)", - "abusefilter-edit-builder-op-comparison-notequal": "Fit niyo (!=)", + "abusefilter-edit-builder-op-comparison-equal": "Erc hendo (==)", + "abusefilter-edit-builder-op-comparison-equal-strict": "Erc u hendo (===)", + "abusefilter-edit-builder-op-comparison-notequal": "Hendê pê niyo (!=)", + "abusefilter-edit-builder-op-comparison-notequal-strict": "Erc u tewr hendê pê niyo (!==)", "abusefilter-edit-builder-op-comparison-lt": "Tayêr (<)", "abusefilter-edit-builder-op-comparison-gt": "Zafyer (>)", "abusefilter-edit-builder-op-comparison-lte": "tayêr ya zi fit (<=)", @@ -219,7 +313,8 @@ "abusefilter-edit-builder-misc-contains": "Sol dizi sağ diziyi içeriyor (contains)", "abusefilter-edit-builder-misc-stringlit": "Literalê stringî (\"\")", "abusefilter-edit-builder-misc-tern": "Operatorê ternaryî (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Kordinator (eka X o wext Y ya zi Z)", + "abusefilter-edit-builder-misc-cond": "Şertın (Eka X dıme Y ya zi Z qediyeno)", + "abusefilter-edit-builder-misc-cond-short": "Şertıno kılm (Eka X ya zi Y qediyena)", "abusefilter-edit-builder-group-funcs": "Fonksiyonî", "abusefilter-edit-builder-funcs-length": "Derganîyê stringî (dergî)", "abusefilter-edit-builder-funcs-lcase": "Herfê qickekî (lcase)", @@ -233,7 +328,7 @@ "abusefilter-edit-builder-funcs-rmwhitespace": "cayê sipe wedarne (rmwhitespace)", "abusefilter-edit-builder-funcs-rmspecials": "Karekteranê xasî wedarne (rmspecials)", "abusefilter-edit-builder-funcs-ip_in_range": "Eka IP range de? (ip_in_range)", - "abusefilter-edit-builder-funcs-contains-any": "Bınlayanê zafın rê layan bıgeyrê (contains_any)", + "abusefilter-edit-builder-funcs-contains-any": "Kodê OR yewra zêde bın ratek de rateka cıgeyrayışi (contains_any)", "abusefilter-edit-builder-funcs-substr": "Substring (substr)", "abusefilter-edit-builder-funcs-strpos": "Lay de caygey bınlayan (strpos)", "abusefilter-edit-builder-funcs-str_replace": "Pê stringî, substringî degiş bike (str_replace)", @@ -242,6 +337,7 @@ "abusefilter-edit-builder-group-vars": "Vurnegeri", "abusefilter-edit-builder-vars-accountname": "Nameyê hesabî (ser hesab viraştîşî)", "abusefilter-edit-builder-vars-timestamp": "Vurnayîşê unix pulê wextî", + "abusefilter-edit-builder-vars-timestamp-expanded": "Roceka demğay", "abusefilter-edit-builder-vars-action": "Kerdış", "abusefilter-edit-builder-vars-addedlines": "Dizeyan ke nuşte de debiyo", "abusefilter-edit-builder-vars-delta": "Vurnayîşê ebatî ke nuştiş de", @@ -253,17 +349,20 @@ "abusefilter-edit-builder-vars-removedlines": "Dizeyan ke nuşte de wedarne", "abusefilter-edit-builder-vars-summary": "Qissayê vurnayîşî/sebeb", "abusefilter-edit-builder-vars-page-id": "Nımrey pela", - "abusefilter-edit-builder-vars-page-ns": "Cayê namey perre", + "abusefilter-edit-builder-vars-page-ns": "Cayê nameyê pele", "abusefilter-edit-builder-vars-page-title": "Sernameyê ripelî (bê cayênameyî)", "abusefilter-edit-builder-vars-page-prefixedtitle": "Sernamey pêro perre", + "abusefilter-edit-builder-vars-page-age": "Serra pela (pê saniyana)", "abusefilter-edit-builder-vars-movedfrom-id": "Perra IDyê çımey kırıştışi", "abusefilter-edit-builder-vars-movedfrom-ns": "Cayê nameyî ke ripelê çimeyî ke neqil biyo", "abusefilter-edit-builder-vars-movedfrom-title": "Sernameyê ripelê çimeyî ke neqil biyo", "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "Sernameyê ripelê çimeyî ke neqil biyo", + "abusefilter-edit-builder-vars-movedfrom-age": "Çımey serra pela berê (pê saniyana)", "abusefilter-edit-builder-vars-movedto-id": "IDyê ripelî ke ripelê destinasyonî ke neqil biyo", "abusefilter-edit-builder-vars-movedto-ns": "Cayênameyî ripelê destinasyonî ke neqil biyo", "abusefilter-edit-builder-vars-movedto-title": "Sernameyê ripelê destinasyonî ke neqil biyo", "abusefilter-edit-builder-vars-movedto-prefixedtitle": "Sernameyê ripelê destinasyonî ke neqil biyo", + "abusefilter-edit-builder-vars-movedto-age": "Hedefê serra pela berê (pê saniyana)", "abusefilter-edit-builder-vars-user-editcount": "Amarê karberi bıvurne", "abusefilter-edit-builder-vars-user-age": "Serra hesabê karberi", "abusefilter-edit-builder-vars-user-name": "Namey hesabê karberi", @@ -273,24 +372,30 @@ "abusefilter-edit-builder-vars-user-emailconfirm": "Wextê ke adresê emaîlî konfirme biy", "abusefilter-edit-builder-vars-recent-contributors": "Des karberê penî ser ena ripel de hebitiyê", "abusefilter-edit-builder-vars-first-contributor": "İştiraka sıfti ya karberi", + "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "Seba pela kırıştışi rê iştırak kerde peyên des karberi", + "abusefilter-edit-builder-vars-movedfrom-first-contributor": "Seba pela kırıştışi rê iştırak kerde peyên karberi", + "abusefilter-edit-builder-vars-movedto-recent-contributors": "Seba pela hedefi kırıştışi rê iştırak kerde peyên des karberi", + "abusefilter-edit-builder-vars-movedto-first-contributor": "Seba pela hedefi kırıştışi rê iştırak kerde peyên karberi", "abusefilter-edit-builder-vars-all-links": "Nuşteyê newey de gıreyê teberi pêro", "abusefilter-edit-builder-vars-added-links": "Vurnayîşê newe de linkanê hericiyan ê de biy", "abusefilter-edit-builder-vars-removed-links": "Vurnayîşê newe de linkanê hericiyan ê wedariyaye", - "abusefilter-edit-builder-vars-old-text": "Wîkîtextê ripel kihan, verniyê vurnayîşî", - "abusefilter-edit-builder-vars-new-text": "pelê wikimetni yo newe: badê vurnayiş", + "abusefilter-edit-builder-vars-old-wikitext": "Vurnayış ra ver, pela wikimetıniya kehane", + "abusefilter-edit-builder-vars-new-wikitext": "Pela newiye wikimetina, bahdê vurnayışi", "abusefilter-edit-builder-vars-new-pst": "Wiki metina perda newi, çerğé verqayt bi", "abusefilter-edit-builder-vars-diff-pst": "Vurnayışi ra timar kerdışê ferqê Yewbiyayışi, nêferqızya yo", "abusefilter-edit-builder-vars-addedlines-pst": "Vurnayışê xate debya, babetna bıyo qeyd", - "abusefilter-edit-builder-vars-new-text-stripped": "Nuştêyê pel ê newî, te de markup çini yo", + "abusefilter-edit-builder-vars-new-text": "Nuştêyê pel ê newî, te de markup çini yo", "abusefilter-edit-builder-vars-new-html": "Yeni revizyonun derlenmiş HTML kaynağı", "abusefilter-edit-builder-vars-restrictions-edit": "Seviyeyê kilit kerdişê pele", "abusefilter-edit-builder-vars-restrictions-move": "Seviyeyê berdişê pele", "abusefilter-edit-builder-vars-restrictions-create": "Sıtarkerdışê na pele vıraze", "abusefilter-edit-builder-vars-restrictions-upload": "Sıtarkerdışê pele bar ke", - "abusefilter-edit-builder-vars-old-text-stripped": "Nuştêyê pel ê kihanî, te de markup çini yo", + "abusefilter-edit-builder-vars-movedfrom-restrictions-edit": "Sewiyey şeveknayışê pela çımey bıvurnê", + "abusefilter-edit-builder-vars-movedfrom-restrictions-move": "Sewiyey şeveknayışê pela çımey berê", + "abusefilter-edit-builder-vars-old-text": "Nuşteyê pela kıhane, tede nişan çıniyo (endi nêgureniyeno)", "abusefilter-edit-builder-vars-old-links": "gıreyê ke pel deyi, verê vurnayişi", - "abusefilter-edit-builder-vars-old-html": "pelê vikimetni yo kehen, qey HTML arêdiya", - "abusefilter-edit-builder-vars-minor-edit": "vurnayiş bı qıci işaret beno nê nêbeno", + "abusefilter-edit-builder-vars-old-html": "Pela wikimetiniya kehen, HTML rê agozneyê (Hêni faal niya)", + "abusefilter-edit-builder-vars-minor-edit": "Vurnayışo qıco ke işaret bi ya zi nêbiyo (endi nêvêrrno)", "abusefilter-edit-builder-vars-file-sha1": "Tedeesteyê dosya yê SHA1 hashî", "abusefilter-edit-builder-vars-file-size": "Ebata bayta dosya", "abusefilter-edit-builder-vars-file-mime": "MIME babeta dosya", @@ -298,11 +403,13 @@ "abusefilter-edit-builder-vars-file-width": "Herayeya pikselê dosya", "abusefilter-edit-builder-vars-file-height": "Berzeya pikselê dosya", "abusefilter-edit-builder-vars-file-bits-per-channel": "Şo reng kenala dosya", - "abusefilter-filter-log": "Vurnayîşanê penî ke ser filitre", + "abusefilter-edit-builder-vars-wiki-name": "Database namey wiki", + "abusefilter-edit-builder-vars-wiki-language": "Kodê zıwanê wiki", + "abusefilter-filter-log": "Vurnayışê parzûniyê peyêni", "abusefilter-history": "qey filtreya suistimali #$1vurnayişê hal-verini", "abusefilter-history-foruser": "$1 ra vurnayîşan", "abusefilter-history-hidden": "Nımıte", - "abusefilter-history-enabled": "A biya", + "abusefilter-history-enabled": "Feal", "abusefilter-history-global": "Global", "abusefilter-history-timestamp": "Wext", "abusefilter-history-user": "Karber", @@ -313,9 +420,10 @@ "abusefilter-history-actions": "Kerdışi", "abusefilter-history-backedit": "Peyser şo vurnayoğê parzûni", "abusefilter-history-deleted": "Esteriya", - "abusefilter-history-filterid": "Avrêc", + "abusefilter-history-filterid": "Parzûn", "abusefilter-history-select-legend": "Cı geyrayışi amyayeney fi", "abusefilter-history-select-user": "Karber:", + "abusefilter-history-select-filter": "Kamiya parzûni:", "abusefilter-history-select-submit": "Amyayeney fi", "abusefilter-history-diff": "Vurnayışi", "abusefilter-history-error-hidden": "filtreya ke şıma waşto nımteyo u şıma nêeşkeni hal-verinê aye bıvini.", @@ -326,19 +434,20 @@ "abusefilter-exception-unclosedstring": "$1 karakterinde başlayan kapanmamış dizi", "abusefilter-exception-invalidoperator": "Karektarê $1î de operatorê çewtî \"$2\".", "abusefilter-exception-unrecognisedtoken": "Karektarê $1î de unrecognised token \"$2\".", - "abusefilter-exception-noparams": "fonksiyonê \"$2\" i re no $1 karakter de çı parametrecı nêdiya.", + "abusefilter-exception-noparams": "Karakterê $1 de gurey \"$2\" deyaye parametre çıno.\n$3 {{PLURAL:$3|argumano paweno|argumani pawênê}} .", "abusefilter-exception-dividebyzero": "karakterê $1'i de pê $2 sıfır re teqsim kerdış .", "abusefilter-exception-unrecognisedvar": "karakterê $1'i de parametreya nêşınasnaye $2", "abusefilter-exception-notenoughargs": "$1 karakterinde çağrılan $2 fonksiyonu için yeterli değişken yok.\n$3 {{PLURAL:$3|değişken|değişken}} bekleniyordu, $4 alındı", - "abusefilter-exception-regexfailure": "ifadeya \"$3\" de karakter $1'i de xeta: \"$2\"", - "abusefilter-exception-overridebuiltin": "$1 karakterinde \"$2\" yerleşik değişkeninin kuraldışı geçersiz kılınması.", - "abusefilter-exception-outofbounds": "$1 karakterindeki mevcut olmayan liste öğesi $2 (liste boyutu = $3) isteniyor.", + "abusefilter-exception-regexfailure": "Nizami ifadeyê \"$2\" xetay karakterê $1", + "abusefilter-exception-overridebuiltin": "Cabıyaye karakterê $1 de şınastoğê \"$2\" xırab kerdo", + "abusefilter-exception-outofbounds": "Çınêbiyayê obcey rêza $2 (ebatê rêze = $3), karakterê $1 ra waziyeno.", "abusefilter-exception-notarray": "Ser karekterê $1î, wazeno adetê array ê nearrayî.", + "abusefilter-exception-unclosedcomment": "Karakterê $1 de vatışo ke izah nebiyo", "abusefilter-action-tag": "Etiket", "abusefilter-action-throttle": "Taynkerdış", "abusefilter-action-warn": "Îkaz", "abusefilter-action-blockautopromote": "Wedarnayışi acı asıknı", - "abusefilter-action-block": "Wedarnê", + "abusefilter-action-block": "Kılit ke", "abusefilter-action-degroup": "Gruban ra wedarne", "abusefilter-action-rangeblock": "Blokê menzili", "abusefilter-action-disallow": "Destur med", @@ -349,8 +458,9 @@ "abusefilter-revert-periodstart": "Periyod ke başli ken:", "abusefilter-revert-periodend": "Periyod ke qediyen:", "abusefilter-revert-search": "Hereketan biweçine", - "abusefilter-revert-filter": "Avrêc:", + "abusefilter-revert-filter": "Kamiya parzûni:", "abusefilter-revert-preview-intro": "Cérdé, na icraat qeydé nengan sera édé peysr bıgériyé.\nReca keme qontrol keré u weçınişa ğo \"{{int:abusefilter-revert-confirm}}\" bıploğné.", + "abusefilter-revert-confirm-legend": "Peyd gırotışi tesdiq kerê", "abusefilter-revert-confirm": "Tesdiq ke", "abusefilter-revert-success": "[[Special:AbuseFilter/$1|$2 filtresinden]] dolayı suistimal filtresi tarafından alınan tüm eylemleri geri aldınız.", "abusefilter-revert-reason": "$1 filtresinden dolayı suistimal filtresi tarafından alınan tüm eylemlerin otomatik geri alımı.\nVerilen sebep: $2", @@ -362,12 +472,20 @@ "abusefilter-test-submit": "Test", "abusefilter-test-load": "Bar ke", "abusefilter-test-user": "Vurnayîşê eno karber:", + "abusefilter-test-nobots": "Vurnayışê boti bınımnê", "abusefilter-test-period-start": "Vurnayişan ke peni de biyê:", "abusefilter-test-period-end": "Vurnayişan ke verni de biyê:", "abusefilter-test-page": "Vurnayişan ser pelan:", "abusefilter-test-shownegative": "Vurnayîşan ke filitre match nikena înan bimucne", "abusefilter-test-syntaxerr": "Filitreyê tu de yew ğeletê syntaxî esto.\nQe yew deskripsiyonê ğeletî, \"{{int:abusefilter-edit-check}}\" rê bitexne.", "abusefilter-test-badtitle": "Sernamey perer nêravêrde yo. Eno zerrek yu yana zeder peran dı dehana veror karıya yo.", + "abusefilter-test-action": "Babeta aksiyoni:", + "abusefilter-test-search-type-all": "Aksiyoni pêro", + "abusefilter-test-search-type-edit": "Vurnayışi", + "abusefilter-test-search-type-move": "Berdışi", + "abusefilter-test-search-type-delete": "Esternayışi", + "abusefilter-test-search-type-upload": "Barkerdışi", + "abusefilter-test-search-type-createaccount": "Vıraştışê hesabi", "abusefilter-changeslist-examine": "kontrol bike", "abusefilter-examine": "Vurnayişanê şexsî kontrol bike", "abusefilter-examine-intro": "Ena pele ti ra yardim keno ke ti eşkeno variableyan kontrol bike u filitre test bike.", @@ -387,25 +505,34 @@ "abusefilter-examine-noresults": "Parametreyê cıgeyrayışiyê ke to saye kerdi, inan miyan de netice çıniyo.", "abusefilter-topnav": "'''Pusulayê Filtre dê peygoş kerdışa'''", "abusefilter-topnav-home": "Keye", + "abusefilter-topnav-recentchanges": "Vurnayışê parzûniyê peyêni", "abusefilter-topnav-test": "Testê batchî", - "abusefilter-topnav-examine": "Vurnayîşê verinî analiz bike", - "abusefilter-topnav-log": "Roceke peygoş kerdışa", + "abusefilter-topnav-examine": "Vurnayışanê verênan analiz ke", + "abusefilter-topnav-log": "Qeydê suistimali", "abusefilter-topnav-tools": "Hacetê texmîr kerdişî", - "abusefilter-topnav-import": "Filitre împort bike", "abusefilter-log-name": "Qeydé filtran dé nengan", "abusefilter-log-header": "Ena log yew qisse mucneno ke ey de vurnayîşê filitreyî esta.\nQe detayanê hemî, bivine [[Special:AbuseFilter/history|liste]]yê vurnayîşê filitreyî.", + "abusefilter-logentry-create": "$1 {{GENDER:$2|vıraşt}} $4 ($5)", + "abusefilter-logentry-modify": "$1 {{GENDER:$2|vurneya}} $4 ($5)", "abusefilter-log-noresults": "Netice çıno", "abusefilter-diff-title": "Benatê versiyonan de ferqan", "abusefilter-diff-item": "Unsur", "abusefilter-diff-version": "{{GENDER:$3|Rêza}} $2 ra versiyoni $1", - "abusefilter-diff-info": "Seron zanayış", + "abusefilter-diff-info": "Melumato bıngehên", "abusefilter-diff-pattern": "Kondisyonê filitre", "abusefilter-diff-invalid": "Nêşeno versiyono ke waziyeno ey bıgêro.", "abusefilter-diff-backhistory": "Peyser şo parzûnê tarixi", "abusefilter-diff-prev": "vırnayışey vereyni", "abusefilter-diff-next": "Vırnayışy newyeni", "abusefilter-import-intro": "Ti eşkeno ser ena ripel de wîkîyî binan ra filitre împort bike.\nWîkî çimeyî de bine \"{{int:abusefilter-edit-tools}}\" de \"{{int:abusefilter-edit-export}}\" klik bike.\nKutiyê nuştîşî kopye bike u ena kutiyê nuştîş rê na pa u klik bike \"{{int:abusefilter-import-submit}}\".", - "abusefilter-import-submit": "Malumata zerre ke", + "abusefilter-import-submit": "Melumatan zerre ke", + "abusefilter-import-invalid-data": "Dataye ke şımayê kenê ke azere kerê ravêrde niyê", "abusefilter-group-default": "Hesabiyaye", - "abusefilter-http-error": "Yew xırabeya HTTP'i biyo: $1" + "abusefilter-http-error": "Yew xırabeya HTTP'i biyo: $1", + "abusefilter-view-privatedetails-submit": "Detayanê xısusiya bıvênê", + "abusefilter-view-privatedetails-legend": "Detayanê xısusiya bıvinê", + "abusefilter-view-privatedetails-reason": "Sebebê resayışê detayanê xısusiya:", + "abusefilter-log-details-id": "Kamiya qeydi", + "abusefilter-log-ip-not-available": "Çıniyo", + "tag-abusefilter-condition-limit": "reşt sinorê şerti" } diff --git a/AbuseFilter/i18n/dsb.json b/AbuseFilter/i18n/dsb.json index 13fb23af..6558741d 100644 --- a/AbuseFilter/i18n/dsb.json +++ b/AbuseFilter/i18n/dsb.json @@ -2,14 +2,14 @@ "@metadata": { "authors": [ "Derbeth", - "Michawiki", "Matma Rex", - "Matěj Suchánek" + "Matěj Suchánek", + "Michawiki" ] }, "abusefilter-desc": "Nałožujo awtomatisku heuristiku na změny.", - "abusefilter": "Konfiguracija znjewužywańskego filtra", - "abuselog": "Protokol znjewužywanjow", + "abusefilter": "Zastojanje znjewužywańskich filtrow", + "abuselog": "Protokol znjewužywańskich filtrow", "abusefilter-intro": "Witaj do pówjercha zastojanja znjewužywańskich filtrow.\nZnjewužywański filter jo awtomatizěrowany softwarowy mechanizm za nałoženje awtomatiskeje heuristiki na wše akcije.\nToś ten pówjerch pokazujo lisćinu definěrowanych filtrow a zmóžnja je změniś.", "abusefilter-warning": "'''Warnowanje''': Toś ta akcija jo se awtomatiski identificěrowała ako škódna.\nNjekonstruktiwne změny budu se spěšnje anulěrowaś, a njesromne abo wóspjetowane njekonstruktiwne wobźěłowanje buźo k tomu wjasć, až twójo konto abo twója IP-adresa se blokěrujo.\nJolic se mysliš, až toś ta akcija jo konstruktiwna, móžoš ju znowego składowaś, aby ju wobkšuśił. \nKrotke wopisanje znjewužywańskego pšawidła, kótaremuž twója akcija wótpowědujo, jo: $1", "abusefilter-disallowed": "Toś ta akcija jo se awtomatiski identificěrowała ako škódna, a togodla znjemóžniła.\nJolic se měniš, až twója akcija jo była konstruktiwna, informěruj administratora, což sy wopytał cyniś.\nKrotke wopisanje znjewužywańskego pšawidła, kótaremuž twója akcija wótpowědujo, jo: $1", @@ -24,7 +24,7 @@ "right-abusefilter-view": "Znjewužywańske filtry se woglědaś", "right-abusefilter-log": "Protokol znjewužywanjow zwobrazniś", "right-abusefilter-log-detail": "Detailěrowane zapiski protokola znjewužywanjow zwbrazniś", - "right-abusefilter-private": "Priwatne daty w protokolu znjewužywanjow zwobrazniś", + "right-abusefilter-privatedetails": "Priwatne daty w protokolu znjewužywanjow zwobrazniś", "right-abusefilter-modify-restricted": "Znjewužywańske filtry z wobgranicowanymi akcijami změniś", "right-abusefilter-revert": "Wše změny wót danego znjewužywańskego filtra anulěrowaś", "right-abusefilter-view-private": "Znjewužiwańske filtry se woglědaś, kótarež su ako priwatne markěrowane", @@ -36,11 +36,10 @@ "action-abusefilter-view": "znjewužywańske filtry se woglědaś", "action-abusefilter-log": "znjewužywański protokol se woglědaś", "action-abusefilter-log-detail": "nadrobne zapiski znjewužywańskego protokola se woglědaś", - "action-abusefilter-private": "priwatne daty w znjewužywańskem protokolu se woglědaś", + "action-abusefilter-privatedetails": "priwatne daty w znjewužywańskem protokolu se woglědaś", "action-abusefilter-modify-restricted": "znjewužywańske filtry z wobgranicowanymi akcijami změniś", "action-abusefilter-revert": "wše změny pśez dany znjewužywański filter pśewobrośiś", "action-abusefilter-view-private": "znjewužywańske filtry se woglědaś, kótarež su ako priwatne markěrowane", - "abusefilter-log": "Protokol znjewužywańskich filtrow", "abusefilter-log-summary": "Toś ten protokol pokazujo liscínu wšych pśez filtry pópadnjonych akcijow.", "abusefilter-log-search": "Protokol znjewužywanjow pytaś", "abusefilter-log-search-user": "Wužywaŕ:", @@ -60,13 +59,12 @@ "abusefilter-log-details-var": "Wariabla", "abusefilter-log-details-val": "Gódnota", "abusefilter-log-details-vars": "Akcijne parametry", - "abusefilter-log-details-private": "Priwatne daty", + "abusefilter-log-details-privatedetails": "Priwatne daty", "abusefilter-log-details-ip": "Wuchadna adresa IP", "abusefilter-log-noactions": "žeden", "abusefilter-log-details-diff": "Pśi wobźěłanju cynjone změny", "abusefilter-log-linkoncontribs": "znjewužywański protokol", "abusefilter-log-linkoncontribs-text": "Znjwužywański protokol za toś togo wužywarja", - "abusefilter-log-hidden": "(zapisk schowany)", "abusefilter-log-hidden-implicit": "(schowany, dokulaž wersija jo se wulašowała)", "abusefilter-log-cannot-see-details": "Njamaš pšawo se drobnostki toś togo zapiska woglědaś.", "abusefilter-log-details-hidden": "Njamóžoš drobnostki za toś ten zapisk pokazaś, dokulaž jo pśed zjawnosću schowany.", @@ -77,7 +75,6 @@ "abusefilter-log-hide-reason": "Pśicyna:", "abusefilter-log-hide-forbidden": "Njamaš pšawo zapiski znjewužywańskego protokola schowaś.", "logentry-abusefilter-hit": "$1 jo pśi wuwjeźenju akcije \"$5\" na $3 $4 zapušćił. Statkowanje: $6 ($7)", - "abusefilter-management": "Zastojanje znjewužywańskich filtrow", "abusefilter-list": "Wše filtry", "abusefilter-list-id": "ID filtra", "abusefilter-list-status": "Status", @@ -97,6 +94,7 @@ "abusefilter-disabled": "Znjemóžnjony", "abusefilter-hitcount": "$1 {{PLURAL:$1|trjefaŕ|trjefarja|trjefarje|trjefarjow}}", "abusefilter-new": "Nowy filter napóraś", + "abusefilter-import-button": "Filter importěrowaś", "abusefilter-return": "Slědk k zastojanjoju filtrow", "abusefilter-status-global": "Globalny", "abusefilter-list-options": "Opcije", @@ -125,7 +123,6 @@ "abusefilter-edit-oldwarning": "<strong>Wobźěłujoš staru wersiju toś togo filtra.\nStatistiske pódaśa su za nejnowšu wersiju filtra.\nJolic składujoš swóje změny, buźoš wše změny pśepisowaś, kótarež sy cynił wót wersije, kótaruž wobźěłujoš.</strong> •\n[[Special:AbuseFilter/history/$2|Slědk k stawiznam toś togo filtra]].", "abusefilter-edit-status-label": "Statistika:", "abusefilter-edit-status": "Ze {{PLURAL:$1|slědneje akcije|slědneju $1 akcijowu|slědnych $1 akcijow|slědnych $1 akcijow}} toś ten filter jo spóznał $2 ($3 %). Jogo cas wužywanja jo pśerěznje $4 ms a docynja $5 {{PLURAL:$5|wuměnjenje|wuměnjeni|wuměnjenja|wuměnjenjow}} limita wuměnjenjow.", - "abusefilter-edit-status-profile": "Ze {{PLURAL:$1|slědneje akcije|slědneju $1 akcijowu|slědnych $1 akcijow|slědnych $1 akcijow}} toś ten filter jo spóznał $2 ($3 %). Jogo cas wužywanja jo pśerěznje $4 ms a docynja $5 {{PLURAL:$5|wuměnjenje|wuměnjeni|wuměnjenja|wuměnjenjow}} limita wuměnjenjow.", "abusefilter-edit-new": "Nowy filter", "abusefilter-edit-save": "Filter składowaś", "abusefilter-edit-id": "ID filtra:", @@ -260,18 +257,18 @@ "abusefilter-edit-builder-vars-all-links": "Wše eksterne wótkaze w nowem teksće", "abusefilter-edit-builder-vars-added-links": "Wše eksterne wótkaze, kótarež su se pśidali pśez změnu", "abusefilter-edit-builder-vars-removed-links": "Wše eksterne wótkaze, kótarež su se wótpórali pśez změnu", - "abusefilter-edit-builder-vars-old-text": "Stary wikitekst boka, do wobźěłanja", - "abusefilter-edit-builder-vars-new-text": "Nowy wikitekst boka, pó wobźěłanju", + "abusefilter-edit-builder-vars-old-wikitext": "Stary wikitekst boka, do wobźěłanja", + "abusefilter-edit-builder-vars-new-wikitext": "Nowy wikitekst boka, pó wobźěłanju", "abusefilter-edit-builder-vars-new-pst": "Nowy wikitekst boka, pśed składowanim pśetwórjony", "abusefilter-edit-builder-vars-diff-pst": "Zjadnośony rozdźěl změnow pó wobźěłowanju, pśed składowanim pśetwórjony", "abusefilter-edit-builder-vars-addedlines-pst": "Smužki pśidane we wobźěłowanju, pśed składowanim pśetwórjone", - "abusefilter-edit-builder-vars-new-text-stripped": "Nowy tekst boka, bźez wobznamjenjeńskego teksta", + "abusefilter-edit-builder-vars-new-text": "Nowy tekst boka, bźez wobznamjenjeńskego teksta", "abusefilter-edit-builder-vars-new-html": "Analyzěrowane HTML-žrědło noweje wersije", "abusefilter-edit-builder-vars-restrictions-edit": "Šćitny schójźeńk za wobźěłowanje boka", "abusefilter-edit-builder-vars-restrictions-move": "Šćitny schóźeńk za pśesuwanje boka", "abusefilter-edit-builder-vars-restrictions-create": "Napórański šćit boka", "abusefilter-edit-builder-vars-restrictions-upload": "Nagrawański šćit dataje", - "abusefilter-edit-builder-vars-old-text-stripped": "Tekst starego boka, bźez wobznamjenjenjow", + "abusefilter-edit-builder-vars-old-text": "Tekst starego boka, bźez wobznamjenjenjow", "abusefilter-edit-builder-vars-old-links": "Wótkaze w boku, pśed wobźěłanim", "abusefilter-edit-builder-vars-old-html": "Wikitekst starego boka, do HTML analyzěrowany", "abusefilter-edit-builder-vars-minor-edit": "Lěc změna markěrujo se ako snadna abo nic", @@ -369,7 +366,6 @@ "abusefilter-topnav-examine": "Zachadne změny pśekontrolěrowaś", "abusefilter-topnav-log": "Znjewužywański protokol", "abusefilter-topnav-tools": "Rědy za wótpóranje zmólkow", - "abusefilter-topnav-import": "Filter importěrowaś", "abusefilter-log-name": "Protokol znjewužywańskego filtra", "abusefilter-log-header": "Toś ten protokol pokazujo zespominanje změnow, kótarež su se pśewjadli na filtrach.\nZa połne drobnostki glědaj [[Special:AbuseFilter/history|lisćinu]] nejnowšych filtrowych změnow.", "abusefilter-log-noresults": "Žedne wuslědki", diff --git a/AbuseFilter/i18n/dtp.json b/AbuseFilter/i18n/dtp.json index 4650e20d..9b08c0e9 100644 --- a/AbuseFilter/i18n/dtp.json +++ b/AbuseFilter/i18n/dtp.json @@ -6,8 +6,6 @@ ] }, "abusefilter-desc": "Pokianu huristik mimpoporion hilo niditan", - "abusefilter": "Manahas sinalaguno nuludan", - "abuselog": "Log sinalaguno", "abusefilter-intro": "Kopiwosian mongoi id kouroso mangaraja Manahas Sinalaguno.\nManahas Sinalaguno nopo nga doungkaralano kumaraja dit posusuangon momoripori iri numaan pokionuo id huristik mimpoporion montok oinsanan it maan.\nKouroso diti popokito do lis panahas potumboyo, om pabanar dilo do maan modipaito.", "abusefilter-warning": "'''Ponorohon''': Kinaraja diti noporianan nointutunan do kikoligogon.\nNiditan di awu nopongo maan pogulio do tiinu,\nom opinsugutan nu nopo do awu momongo niditan nga karaag do akaun nu toi ko maan antabai porotokol intonit ''IP''nu.\nOtumbayaan ko nopo do nopongo iti niditannu, maai nopo kaagu kotiko Pootodo do papatatap dilo.\nKointalangan do sinalaguno diti kooturan di kohompit do niditannu nopo nga oboyo do: $1", "abusefilter-disallowed": "Kinaraja diti noporianan nointutunan do kikoligogon, om ilo no do awu pasagaon.\nNiditan di awu nopongo maan pogulio do tiinu,\nOtumbayaan ko nopo do nopongo iti niditannu, maai gia sunudai it mintatamong do nunu daa umbalan nu momonsoi. Kointalangan do sinalaguno diti kooturan di kohompit do kinarajanu nopo nga oboyo do: $1", diff --git a/AbuseFilter/i18n/dty.json b/AbuseFilter/i18n/dty.json index cdcc444f..cef66885 100644 --- a/AbuseFilter/i18n/dty.json +++ b/AbuseFilter/i18n/dty.json @@ -1,8 +1,8 @@ { "@metadata": { "authors": [ - "राम प्रसाद जोशी", - "Nirajan pant" + "Nirajan pant", + "राम प्रसाद जोशी" ] }, "abusefilter-edit-badfilter": "तमीले खुलायाको फिल्टर उपलब्ध छैन ।", diff --git a/AbuseFilter/i18n/ee.json b/AbuseFilter/i18n/ee.json index d2b10dd3..2df2e63c 100644 --- a/AbuseFilter/i18n/ee.json +++ b/AbuseFilter/i18n/ee.json @@ -1,6 +1,7 @@ { "@metadata": { "authors": [ + "Aguve", "Enock4seth", "Natsubee" ] @@ -16,6 +17,7 @@ "abusefilter-deleted": "Wo tutui", "abusefilter-tools-reautoconfirm-user": "Ezãla", "abusefilter-edit-status-label": "Akɔntawo", + "abusefilter-throttle-none": "(ɖekeo)", "abusefilter-edit-warn-preview": "Kpɔ du tatia do ŋgɔ", "abusefilter-edit-warn-edit": "Ŋlɔ/trɔ du tatia", "abusefilter-edit-history": "Xoxoawo", diff --git a/AbuseFilter/i18n/el.json b/AbuseFilter/i18n/el.json index c4371e8d..628e4890 100644 --- a/AbuseFilter/i18n/el.json +++ b/AbuseFilter/i18n/el.json @@ -5,26 +5,28 @@ "Badseed", "Consta", "Crazymadlover", + "Fitoschido", "Flyax", "Geraki", "Glavkos", "K sal 15", + "KATRINE1992", "Konsnos", "Lou", + "Matma Rex", + "Nikosgranturismogt", + "Norhorn", "Omnipaedista", "Protnet", "ZaDiak", - "Αντιγόνη", - "Matma Rex", - "KATRINE1992", - "Nikosgranturismogt" + "Αντιγόνη" ] }, "abusefilter-desc": "Εφαρμόζει αυτόματη ανίχνευση σε επεξεργασίες", - "abusefilter": "Διαμόρφωση φίλτρου καταχρήσεων", - "abuselog": "Ιστορικό καταχρήσεων", + "abusefilter": "Διαχείριση φίλτρου καταχρήσεων", + "abuselog": "Ιστορικό φίλτρων καταχρήσεων", "abusefilter-intro": "Καλωσήρθατε στη διεπαφή διαχείρισης του Φίλτρου Καταχρήσεων.\nΤο Φίλτρο Καταχρήσεων είναι ένα αυτοματοποιημένο λογισμικό που εφαρμόζει αυτόματες ευρετικές μεθόδους σε όλες τις ενέργειες.\nΑυτή η διεπαφή παρουσιάζει μία σειρά καθορισμένων φίλτρων και επιτρέπει την μετατροπή τους.", - "abusefilter-warning": "''' Προειδοποίηση:''' αυτή η ενέργεια έχει αυτόματα εντοπιστεί ως επιβλαβής.\nΜη εποικοδομητικές επεξεργασίες θα αναστραφούν γρήγορα,\nκαι σκανδαλώδεις ή κατ ' επανάληψη μη εποικοδομητικές επεξεργασίες θα οδηγήσουν το λογαριασμό σας ή τη διεύθυνση IP σας να αποκλειστεί.\nΕάν πιστεύετε ότι αυτή η ενέργεια είναι εποικοδομητική, μπορείτε να την υποβάλετε και πάλι για να την επιβεβαιώσετε.\nΕίναι μια σύντομη περιγραφή της παραβίασης με την οποία η ενέργειά σας ταιριάζει είναι: $1", + "abusefilter-warning": "'''Προειδοποίηση:''' αυτή η ενέργεια έχει αυτόματα εντοπιστεί ως επιβλαβής.\nΜη εποικοδομητικές ενέργειες θα αναστραφούν γρήγορα,\nκαι σκανδαλώδεις ή κατ' επανάληψη μη εποικοδομητικές επεξεργασίες θα οδηγήσουν το λογαριασμό σας ή τη διεύθυνση IP σας να αποκλειστεί.\nΕάν πιστεύετε ότι αυτή η ενέργεια είναι εποικοδομητική, μπορείτε να την υποβάλετε και πάλι για να την επιβεβαιώσετε.\nΕίναι μια σύντομη περιγραφή της παραβίασης με την οποία η ενέργειά σας ταιριάζει είναι: $1", "abusefilter-disallowed": "Αυτή η ενέργεια ταυτοποιήθηκε αυτόματα ως επιβλαβής, και άρα απαγορεύεται.\nΑν πιστεύετε ότι αυτή η επεξεργασία είναι εποικοδομητική, παρακαλώ επικοινωνήστε με έναν διαχειριστή, και πληροφορήστε τον για το τι προσπαθείτε να κάνετε.\nΜια σύντομη περιγραφή του κανόνα καταχρήσεων στο οποίο αντιστοιχήθηκε η ενέργειά σας είναι η εξής: $1", "abusefilter-blocked-display": "Αυτή η ενέργεια ταυτοποιήθηκε αυτόματα ως επιβλαβής,\nκαι αποτραπήκατε από το να την εκτελέσετε.\nΕπιπλέον, για να προστατευθεί το {{SITENAME}}, ο λογαριασμός χρήστη σας και όλες οι σχετιζόμενες διευθύνσεις IP έχουν φραγεί από τη δυνατότητα επεξεργασίας.\nΑν πιστεύετε ότι έχει γίνει κάποιο λάθος, παρακαλούμε επικοινωνήστε με κάποιον διαχειριστή.\nΜια σύντομη περιγραφή του κανόνα καταχρήσεων στο οποίο αντιστοίχησε η ενέργειά σας είναι η εξής: $1", "abusefilter-degrouped": "Αυτή η ενέργεια αναγνωρίστηκε ως επιβλαβής αυτόματα.\nΣυνεπώς απαγορεύεται, και εφόσον ο λογαριασμός σας μάλλον έχει εκτεθεί, όλα τα δικαιώματά του ανακλήθηκαν.\nΑν πιστεύετε ότι έχει γίνει κάποιο λάθος, παρακαλούμε επικοινωνήστε με κάποιο γραφειοκράτη εξηγώντας το τι προσπαθείτε να κάνετε και τα δικαιώματά σας θα αποκατασταθούν.\nΜια σύντομη περιγραφή του κανόνα καταχρήσεων με τον οποίο βρήκε αντιστοιχία η ενέργειά σας είναι η εξής: $1", @@ -33,32 +35,33 @@ "abusefilter-blockreason": "Αυτόματη φραγή από το φίλτρο κατάχρησης.\nΠεριγραφή του σχετικού κανόνα: $1", "abusefilter-degroupreason": "Τα δικαιώματα αφαιρέθηκαν αυτόματα από το φίλτρο κατάχρησης.\nΠεριγραφή κανόνα: $1", "abusefilter-accountreserved": "Αυτό το όνομα λογαριασμού είναι δεσμευμένο για χρήση από το φίλτρο κατάχρησης.", - "right-abusefilter-modify": "Τροποποίηση φίλτρων καταχρήσεων", + "right-abusefilter-modify": "Δημιουργία ή τροποποίηση φίλτρων κατάχρησης", "right-abusefilter-view": "Προβολή φίλτρων καταχρήσεων", "right-abusefilter-log": "Εμφάνιση ιστορικού καταχρήσεων", "right-abusefilter-log-detail": "Εμφάνιση λεπτομερειακών καταχωρήσεων του ιστορικού καταχρήσεων", - "right-abusefilter-private": "Εμφάνιση προσωπικών δεδομένων στο ιστορικό καταχρήσεων", + "right-abusefilter-privatedetails": "Εμφάνιση προσωπικών δεδομένων στο ιστορικό καταχρήσεων", "right-abusefilter-modify-restricted": "Τροποποίηση φίλτρων καταχρήσεων με περιορισμένες ενέργειες", "right-abusefilter-revert": "Αναστροφή όλων των αλλαγών από ένα δεδομένο φίλτρο καταχρήσεων", "right-abusefilter-view-private": "Προβολἠ φίλτρων κατάχρησης που έχουν σημανθεί ως ιδιωτικά", - "right-abusefilter-hide-log": "Απόκρυψε τις καταχωρήσεις στο αρχείο καταγραφής παραβιάσεων", + "right-abusefilter-hide-log": "Απόκρυψη των καταχωρήσεων στο αρχείο καταγραφής παραβιάσεων", "right-abusefilter-hidden-log": "Εμφάνιση των κρυμμένων καταχωρήσεων του ιστορικού παραβιάσεων", "right-abusefilter-modify-global": "Δημιουργία ή τροποποίηση καθολικών φίλτρων κατάχρησης", "action-abusefilter-modify": "τροποποίηση φίλτρων καταχρήσεων", "action-abusefilter-view": "προβάλετε φίλτρα καταχρήσεων", "action-abusefilter-log": "εμφάνιση του φίλτρου καταχρήσεων", "action-abusefilter-log-detail": "εμφάνιση λεπτομερειακών καταχωρήσεων φίλτρων καταχρήσεων", - "action-abusefilter-private": "εμφάνιση απόρρητων δεδομένων στο φίλτρο κατάχρησεων", + "action-abusefilter-privatedetails": "εμφάνιση απόρρητων δεδομένων στο φίλτρο κατάχρησεων", "action-abusefilter-modify-restricted": "τροποποίηση φίλτρων κατάχρησεων με περιορισμένες ενέργειες", "action-abusefilter-revert": "αναστροφή όλων των αλλαγών από ένα δεδομένο φίλτρο κατάχρησεων", "action-abusefilter-view-private": "προβολἠ φίλτρων κατάχρησης που έχουν σημανθεί ως ιδιωτικά", - "abusefilter-log": "Ιστορικό φίλτρων καταχρήσεων", "abusefilter-log-summary": "Αυτό το ιστορικό εμφανίζει μία λίστα όλων των ενεργειών που συνελήφθησαν από τα φίλτρα.", "abusefilter-log-search": "Αναζήτηση φίλτρου καταχρήσεων", "abusefilter-log-search-user": "Χρήστης:", - "abusefilter-log-search-filter": "Αναγνωριστικά φίλτρου (διαχωρισμένα με την κατακόρυφη κάθετο):", + "abusefilter-log-search-filter": "Αναγνωριστικά φίλτρων:", "abusefilter-log-search-title": "Τίτλος:", "abusefilter-log-search-wiki": "Wiki:", + "abusefilter-log-search-impact-saved": "Αποθηκευμένες αλλαγές μόνο", + "abusefilter-log-search-impact-not-saved": "Χωρίς τις αποθηκευμένες αλλαγές", "abusefilter-log-search-entries-label": "Ορατότητα:", "abusefilter-log-search-entries-all": "Όλες οι καταχωρήσεις", "abusefilter-log-search-entries-hidden": "Κρυμμένες καταχωρήσεις μόνο", @@ -68,8 +71,8 @@ "abusefilter-log-search-action-taken-label": "Δράση που λήφθηκε:", "abusefilter-log-search-action-taken-any": "Οποιοδήποτε", "abusefilter-log-search-submit": "Αναζήτηση", - "abusefilter-log-entry": "$1: Ο $2 προκάλεσε ένα φίλτρο καταχρήσεων, εκτελώντας την ενέργεια \"$3\" στο $4.\nΕνέργειες που λήφθηκαν: $5;\nΠεριγραφή φίλτρου: $6", - "abusefilter-log-detailedentry-meta": "$1: Ο $2 προκάλεσε το $3, εκτελώντας την ενέργεια \"$4\" στο $5.\nΕνέργειες που λήφθηκαν: $6;\nΠεριγραφή φίλτρου: $7 ($8)", + "abusefilter-log-entry": "$1: {{GENDER:$8|Ο|Η}} $2 ενεργοποίησε ένα φίλτρο καταχρήσεων, εκτελώντας την ενέργεια «$3» στο $4.\nΕνέργειες που λήφθηκαν: $5;\nΠεριγραφή φίλτρου: $6", + "abusefilter-log-detailedentry-meta": "$1: {{GENDER:$9|Ο|Η}} $2 ενεργοποίησε το $3, εκτελώντας την ενέργεια \"$4\" στο $5.\nΕνέργειες που λήφθηκαν: $6;\nΠεριγραφή φίλτρου: $7 ($8)", "abusefilter-log-detailedentry-global": "καθολικό φίλτρο $1", "abusefilter-log-detailedentry-local": "φίλτρο $1", "abusefilter-log-detailslink": "λεπτομέρειες", @@ -79,13 +82,13 @@ "abusefilter-log-details-var": "Μεταβλητή", "abusefilter-log-details-val": "Τιμή", "abusefilter-log-details-vars": "Παράμετροι ενεργειών", - "abusefilter-log-details-private": "Ιδιωτικές λεπτομέρειες μητρώου", + "abusefilter-log-details-privatedetails": "Ιδιωτικές λεπτομέρειες μητρώου", "abusefilter-log-details-ip": "Διεύθυνση IP της προέλευσης", + "abusefilter-log-details-checkuser": "Έλεγχος χρήστη", "abusefilter-log-noactions": "καμία", "abusefilter-log-details-diff": "Αλλαγές που πραγματοποιήθηκαν κατά την επεξεργασία", "abusefilter-log-linkoncontribs": "καταγραφές καταχρήσεων", - "abusefilter-log-linkoncontribs-text": "Καταγραφές καταχρήσεων για αυτόν τον χρήστη", - "abusefilter-log-hidden": "(κρυφή εγγραφή)", + "abusefilter-log-linkoncontribs-text": "Καταγραφές καταχρήσεων για {{GENDER:$1|αυτόν τον χρήστη|αυτή τη χρήστρια}}", "abusefilter-log-hidden-implicit": "(κρυφά επειδή αναθεώρηση έχει διαγραφεί)", "abusefilter-log-cannot-see-details": "Δεν έχετε δικαιώματα για να δείτε λεπτομέρειες σχετικά με αυτή την εγγραφή.", "abusefilter-log-details-hidden": "Δεν μπορείτε να δείτε τις λεπτομέρειες για αυτήν την καταχώρηση, διότι είναι κρυμμένες από τη δημόσια θέα.", @@ -94,7 +97,6 @@ "abusefilter-log-hide-hidden": "Απόκρυψη αυτής της εγγραφής από την κοινή θέα", "abusefilter-log-hide-reason": "Αιτία:", "abusefilter-log-hide-forbidden": "Δεν έχετε άδεια για να κρύψετε τις καταχωρήσεις κατάχρησης του αρχείου καταγραφής", - "abusefilter-management": "Διαχείριση φίλτρου καταχρήσεων", "abusefilter-list": "Όλα τα φίλτρα", "abusefilter-list-id": "Ταυτότητα φίλτρου", "abusefilter-list-status": "Κατάσταση", @@ -114,6 +116,7 @@ "abusefilter-disabled": "Απενεργοποιημένο", "abusefilter-hitcount": "$1 {{PLURAL:$1|αποτέλεσμα|αποτελέσματα}}", "abusefilter-new": "Δημιουργία νέου φίλτρου", + "abusefilter-import-button": "Εισαγωγή φίλτρου", "abusefilter-return": "Επιστροφή στη διαχείριση φίλτρων", "abusefilter-status-global": "Καθολικό", "abusefilter-list-options": "Επιλογές", @@ -135,20 +138,21 @@ "abusefilter-tools-text": "Εδώ βρίσκονται κάποια εργαλεία τα οποία ενδέχεται να είναι χρἠσιμα στην διατύπωση και την εκσφαλμἀτωση φίλτρων καταχρἠσεων.", "abusefilter-tools-expr": "Ελεγκτής εκφράσεων", "abusefilter-tools-submitexpr": "Εκτίμηση", + "abusefilter-tools-syntax-error": "Το φίλτρο έχει μη έγκυρη σύνταξη.", "abusefilter-tools-reautoconfirm": "αποκατάσταση αυτομάτως επιβεβαιωμένης κατάστασης", "abusefilter-tools-reautoconfirm-user": "Χρήστης:", "abusefilter-tools-reautoconfirm-submit": "Αυτόματη επιβεβαίωση ξανά", "abusefilter-reautoconfirm-none": "Η ιδιότητα αυτοεπιβεβαιωμένου χρήστη {{GENDER:$1|αυτού του χρήστη|αυτής της χρήστριας|αυτών των χρηστών}} δεν ανεστάλη.", "abusefilter-reautoconfirm-notallowed": "Δεν σας επιτρέπεται η αποκατάσταση της αυτόματης επιβεβαίωσης", "abusefilter-reautoconfirm-done": "Η αυτομάτως επιβεβαιωμένη κατάσταση του λογαριασμού αποκαταστάθηκε", - "abusefilter-status": "Από {{PLURAL:$1|την τελευταία|τις τελευταίες}} $1 {{PLURAL:$1|ενέργεια|ενέργειες}}, $2 ($3%) {{PLURAL:$2|έχει|έχουν}} φτάσει το προϋποτιθέμενο όριο $4, και $5 ($6%) {{PLURAL:$5|έχει|έχουν}} ταιριάξει με ένα από τα φίλτρα που είναι ενεργοποιημένα.", + "abusefilter-status": "Από {{PLURAL:$1|την τελευταία|τις τελευταίες}} $1 {{PLURAL:$1|ενέργεια|ενέργειες}}, $2 ($3%) {{PLURAL:$2|έχει|έχουν}} φτάσει το καθορισμένο όριο $4 και $5 ($6%) {{PLURAL:$5|έχει|έχουν}} ταιριάξει με ένα από τα φίλτρα που είναι ενεργοποιημένα.", "abusefilter-edit": "Επεξεργασία φίλτρου κατάχρησης", "abusefilter-edit-subtitle": "Επεξεργασία φίλτρου $1", "abusefilter-edit-subtitle-new": "Δημιουργία φίλτρου", + "abusefilter-edit-token-not-match": "Η επεξεργασία δεν αποθηκεύτηκε! Παρακαλούμε αποθηκεύστε ξανά.", "abusefilter-edit-oldwarning": "<strong>Επεξεργάζεστε μια παλιά έκδοση αυτού του φίλτρου.\nΟι στατιστικές που αναφέρονται είναι για την πιο πρόσφατη έκδοση του φίλτρου.\nΑν αποθηκεύσετε τις αλλαγές σας, θα παρακάμψετε όλες τι επεξεργασίες από την έκδοση που επεξεργάζεστε.</strong> •\n[[Special:AbuseFilter/history/$2|Επιστροφή στο ιστορικό του φίλτρου]].", "abusefilter-edit-status-label": "Στατιστικά:", - "abusefilter-edit-status": "Από {{PLURAL:$1|τη $1 τελευταία ενέργεια|τις $1 τελευταίες ενέργειες}}, αυτό το φίλτρο έχει αντιστοιχίσει $2 ($3%).", - "abusefilter-edit-status-profile": "Από {{PLURAL:$1|τη $1 τελευταία ενέργεια|τις $1 τελευταίες ενέργειες}}, αυτό το φίλτρο έχει αντιστοιχίσει $2 ($3%).\nΣτο μέσο όρο, ο χρόνος απόκρισης της είναι $4ms, και καταναλώνει $5 {{PLURAL:$5|όρο|όρους}} από το όριο όρων.", + "abusefilter-edit-status": "Από {{PLURAL:$1|τη $1 τελευταία ενέργεια|τις $1 τελευταίες ενέργειες}}, αυτό το φίλτρο έχει αντιστοιχίσει $2 ($3%).\nΚατά μέσο όρο, ο χρόνος απόκρισης είναι $4 ms, και καταναλώνει $5 {{PLURAL:$5|όρο|όρους}} από το όριο όρων.", "abusefilter-edit-new": "Νέο φίλτρο", "abusefilter-edit-save": "Αποθήκευση φίλτρου", "abusefilter-edit-id": "Ταυτότητα φίλτρου:", @@ -167,7 +171,7 @@ "abusefilter-edit-lastmod": "Το φίλτρο τροποποιήθηκε τελευταία φορά:", "abusefilter-edit-lastmod-text": "$1 από $2", "abusefilter-edit-hitcount": "Αποτελέσματα φίλτρου:", - "abusefilter-edit-consequences": "Εκτέλεση της ένεργειας όταν εντοπισθεί το αποτέλεσμα", + "abusefilter-edit-consequences": "Ενέργειες που θα εκτελεστούν όταν ταιριάξει", "abusefilter-edit-action-warn": "Πρόκληση τέτοιων ενεργειών αφού δοθεί στον χρήστη μια προειδοποίηση", "abusefilter-edit-action-disallow": "Αποτροπή του χρήστη από την εκτέλεση της συγκεκριμένης ενέργειας", "abusefilter-edit-action-blockautopromote": "Ανάκληση της ιδιότητας αυτοεπιβεβαιωμένου χρήστη", @@ -178,22 +182,24 @@ "abusefilter-edit-action-tag": "Σήμανση της επεξεργασίας με ετικέτα για περαιτέρω επιθεώρηση", "abusefilter-edit-throttle-count": "Αριθμός επιτρεπόμενων ενεργειών:", "abusefilter-edit-throttle-period": "Χρονική περίοδος (σε δευτερόλεπτα):", - "abusefilter-edit-throttle-groups": "Εμπόδιση ομάδας από:\n:''(ένα ανά γραμμή, συνδυασμός με κόμματα)''", - "abusefilter-edit-throttle-ip": "Διεύθυνση IP", - "abusefilter-edit-throttle-user": "Λογαριασμός χρήστη", - "abusefilter-edit-throttle-range": "εύρος /16", - "abusefilter-edit-throttle-editcount": "Καταμέτρηση επεξεργασιών", - "abusefilter-edit-throttle-site": "Ολόκληρη η ιστοσελίδα", - "abusefilter-edit-throttle-page": "Σελίδα", + "abusefilter-edit-throttle-groups": "Εμπόδιση ομάδας από:", + "abusefilter-edit-throttle-groups-help": "Δείτε $1.", + "abusefilter-edit-throttle-groups-help-text": "την τεκμηρίωση στο mediawiki.org", + "abusefilter-throttle-ip": "Διεύθυνση IP", + "abusefilter-throttle-user": "λογαριασμός χρήστη", + "abusefilter-throttle-range": "εύρος /16", + "abusefilter-throttle-editcount": "καταμέτρηση επεξεργασιών", + "abusefilter-throttle-site": "ολόκληρο ιστότοπο", + "abusefilter-throttle-page": "σελίδα", "abusefilter-edit-warn-message": "Μήνυμα συστήματος για χρησιμοποίηση για προειδοποίηση:", "abusefilter-edit-warn-other": "Άλλο μήνυμα", - "abusefilter-edit-warn-other-label": "Όνομα σελίδας άλλου μηνύματος:\n:''(χωρίς πρόθεμα MediaWiki)''", + "abusefilter-edit-warn-other-label": "Όνομα σελίδας άλλου μηνύματος:\n:''(χωρίς πρόθεμα «MediaWiki:»)''", "abusefilter-edit-warn-actions": "Ενέργειες:", - "abusefilter-edit-warn-preview": "Προεπισκόπηση του επιλεγμένου μηνύματος", + "abusefilter-edit-warn-preview": "Εμφάνιση/απόκρυψη προεπισκόπησης του επιλεγμένου μηνύματος", "abusefilter-edit-warn-edit": "Δημιουργία/Επεξεργασία επιλεγμένων μηνυμάτων", "abusefilter-edit-disallow-other": "Άλλο μήνυμα", "abusefilter-edit-disallow-actions": "Ενέργειες:", - "abusefilter-edit-tag-tag": "Ετικέτες για να επικολληθούν (μία ανά γραμμή):", + "abusefilter-edit-tag-tag": "[[Special:Tags|Ετικέτες]] για να επικολληθούν:", "abusefilter-edit-tag-hidden-placeholder": "Προσθήκη ετικετών (το κόμμα χωρίζεται)", "abusefilter-edit-denied": "Δεν μπορείτε να δείτε τις λεπτομέρειες αυτού του φίλτρου, γιατί αυτές έχουν αποκρυφθεί από τη δημόσια θέα.", "abusefilter-edit-main": "Παράμετροι φίλτρου", @@ -242,7 +248,7 @@ "abusefilter-edit-builder-misc-contains": "Η αριστερή συμβολοσειρά περιέχει τη δεξιά συμβολοσειρά (contains)", "abusefilter-edit-builder-misc-stringlit": "Αλφαριθμητική τιμή (\"\")", "abusefilter-edit-builder-misc-tern": "Τριαδικός τελεστής (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Υποθετικό (εάν X ειδάλλως Y ή Z)", + "abusefilter-edit-builder-misc-cond": "Υποθετικό (if X then Y else Z end)", "abusefilter-edit-builder-group-funcs": "Λειτουργίες", "abusefilter-edit-builder-funcs-length": "Μήκος ορμαθού (length)", "abusefilter-edit-builder-funcs-lcase": "Μετατροπή σε μικρογράμματη γραφή (lcase)", @@ -298,18 +304,18 @@ "abusefilter-edit-builder-vars-all-links": "Όλες οι εξωτερικές συνδέσεις στο νέο κείμενο", "abusefilter-edit-builder-vars-added-links": "Όλες οι εξωτερικές συνδέσεις που προστέθηκαν στην επεξεργασία", "abusefilter-edit-builder-vars-removed-links": "Όλες οι εξωτερικές συνδέσεις που αφαιρέθηκαν στην επεξεργασία", - "abusefilter-edit-builder-vars-old-text": "Παλιό βικικείμενο σελίδας, πριν την επεξεργασία (δεν είναι πλέον σε χρήση)", - "abusefilter-edit-builder-vars-new-text": "Νέα σελίδα βικικειμένου, μετά την επεξεργασία", - "abusefilter-edit-builder-vars-new-text-stripped": "Νέο κείμενο σελίδας, γυμνό από κάθε σημείωση (markup)", + "abusefilter-edit-builder-vars-old-wikitext": "Παλιό wikitext σελίδας, πριν την επεξεργασία", + "abusefilter-edit-builder-vars-new-wikitext": "Νέα σελίδα βικικειμένου, μετά την επεξεργασία", + "abusefilter-edit-builder-vars-new-text": "Νέο κείμενο σελίδας, γυμνό από κάθε σημείωση (markup)", "abusefilter-edit-builder-vars-new-html": "Λεξιανάλυση της πηγής HTML της νέας αναθεώρησης", "abusefilter-edit-builder-vars-restrictions-edit": "Επεξεργασία του επιπέδου προστασίας της σελίδας", "abusefilter-edit-builder-vars-restrictions-move": "Μετακίνηση του επιπέδου προστασίας της σελίδας", "abusefilter-edit-builder-vars-restrictions-create": "Δημιουργία προστασίας της σελίδας", "abusefilter-edit-builder-vars-restrictions-upload": "Προστασία ανεβάσματος του αρχείου", - "abusefilter-edit-builder-vars-old-text-stripped": "Παλιό κείμενο σελίδας, χώρις κάποια σύνταξη markup", + "abusefilter-edit-builder-vars-old-text": "Παλιό κείμενο σελίδας, χωρίς κάποια σύνταξη markup (δεν χρησιμοποιείται πλέον)", "abusefilter-edit-builder-vars-old-links": "Σύνδεσμοι στην σελίδα πριν από την επεξεργασία", "abusefilter-edit-builder-vars-old-html": "Παλιό βικικείμενο σελίδας, λεξιαναλυμένο σε HTML (δεν είναι πλέον σε χρήση)", - "abusefilter-edit-builder-vars-minor-edit": "Εάν ή όχι η επεξεργασία σημειώνεται ως μικροεπεξεργασία", + "abusefilter-edit-builder-vars-minor-edit": "Εάν ή όχι η επεξεργασία σημειώνεται ως μικροεπεξεργασία (δεν χρησιμοποιείται πλέον)", "abusefilter-edit-builder-vars-file-sha1": "SHA1 hash των περιεχομένων του αρχείου", "abusefilter-edit-builder-vars-file-size": "Το μέγεθος του αρχείου σε bytes", "abusefilter-filter-log": "Πρόσφατες αλλαγές φίλτρων", @@ -344,7 +350,7 @@ "abusefilter-exception-dividebyzero": "Παράνομη προσπάθεια να διαχωριστεί τοe $2 μέσω μηδέν στον χαρακτήρα $1.", "abusefilter-exception-unrecognisedvar": "Μη αναγνωρίσιμη μεταβλητή $2 στον χαρακτήρα $1.", "abusefilter-exception-notenoughargs": "Όχι αρκετά ορίσματα στη συνάρτηση $2 που κλήθηκε στον χαρακτήρα $1.\n$3 {{PLURAL:$3|αναμενόμενο κατηγορούμενο|αναμενόμενα κατηγορούμενα}}, $4 αποκτημένα.", - "abusefilter-exception-regexfailure": "Σφάλμα στην κανονική έκφραση \"$3\" στον χαρακτήρα $1: \"$2\"", + "abusefilter-exception-regexfailure": "Σφάλμα στην κανονική έκφραση \"$2\" στον χαρακτήρα $1.", "abusefilter-exception-overridebuiltin": "Παράνομη τοπική υπερκάλυψη της ενσωματωμένης μεταβλητής \"$2\" στον χαρακτήρα $1.", "abusefilter-exception-outofbounds": "Η ζήτηση μη υπαρχόντων αντικειμένων λίστας $2 (μέγεθος λίστας = $3) στο χαρακτήρα $1.", "abusefilter-exception-notarray": "Αίτηση για ένα αντικείμενο μέσα σε κάτι διαφορετικό από πίνακα στον χαρακτήρα $1.", @@ -384,7 +390,7 @@ "abusefilter-test-page": "Αλλαγές στις οποίες υποβλήθηκε η σελίδα:", "abusefilter-test-shownegative": "Εμφάνιση αλλαγών που δεν αντιστοιχούν στο φίλτρο", "abusefilter-test-syntaxerr": "Το φίλτρο που δώσατε περιέχει ένα συντακτικό λάθος.\nΜπορείτε να λάβετε μια πλήρη εξήγηση πατώντας το κουμπί \"{{int:abusefilter-edit-check}}\".", - "abusefilter-test-action": "Τύπος ενέργειας", + "abusefilter-test-action": "Τύπος ενέργειας:", "abusefilter-test-search-type-all": "Όλες οι ενέργειες", "abusefilter-test-search-type-edit": "Επεξεργασίες", "abusefilter-test-search-type-move": "Κινήσεις", @@ -414,7 +420,6 @@ "abusefilter-topnav-examine": "Εξέταση περασμένων επεξεργασιών", "abusefilter-topnav-log": "Ιστορικό καταχρήσεων", "abusefilter-topnav-tools": "Εργαλεία εκσφαλμάτωσης", - "abusefilter-topnav-import": "Εισαγωγή φίλτρου", "abusefilter-log-name": "Ιστορικό Φίλτρου Καταχρήσεων", "abusefilter-log-header": "Αυτή η καταγραφή εμφανίζει μια σύνοψη από αλλαγές που έγιναν στα φίλτρα.\nΓια πλήρεις λεπτομέρειες, δείτε [[Special:AbuseFilter/history|τη λίστα]] των πρόσφατων αλλαγών φίλτρου.", "abusefilter-log-noresults": "Κανένα αποτέλεσμα", diff --git a/AbuseFilter/i18n/en-gb.json b/AbuseFilter/i18n/en-gb.json index 43ffba89..82dee1d7 100644 --- a/AbuseFilter/i18n/en-gb.json +++ b/AbuseFilter/i18n/en-gb.json @@ -1,15 +1,14 @@ { "@metadata": { "authors": [ - "Shirayuki", + "Bjh21", + "Caliburn", "Chase me ladies, I'm the Cavalry", - "Caliburn" + "Shirayuki" ] }, "abusefilter-desc": "Applies automatic heuristics to edits", - "abusefilter": "Abuse filter configuration", - "abuselog": "Abuse log", - "right-abusefilter-modify": "Modify abuse filters", + "right-abusefilter-modify": "Create or modify abuse filters", "abusefilter-log-search-user": "User:", "abusefilter-edit-builder-funcs-ccnorm": "Normalise confusable characters (ccnorm)", "abusefilter-edit-builder-funcs-norm": "Normalise (norm)", diff --git a/AbuseFilter/i18n/en.json b/AbuseFilter/i18n/en.json index 9cd8e22e..03e72ff9 100644 --- a/AbuseFilter/i18n/en.json +++ b/AbuseFilter/i18n/en.json @@ -6,8 +6,8 @@ ] }, "abusefilter-desc": "Applies automatic heuristics to edits", - "abusefilter": "Abuse filter configuration", - "abuselog": "Abuse log", + "abusefilter": "Abuse filter management", + "abuselog": "Abuse filter log", "abusefilter-intro": "Welcome to the Abuse Filter management interface.\nThe Abuse Filter is an automated software mechanism of applying automatic heuristics to all actions.\nThis interface shows a list of defined filters, and allows them to be modified.", "abusefilter-mustviewprivateoredit": "For security reasons, only users with the right to view private abuse filters or modify filters may use this interface.", "abusefilter-warning": "'''Warning:''' This action has been automatically identified as harmful.\nUnconstructive actions will be quickly reverted,\nand egregious or repeated unconstructive editing will result in your account or IP address being blocked.\nIf you believe this action to be constructive, you may submit it again to confirm it.\nA brief description of the abuse rule which your action matched is: $1", @@ -18,13 +18,14 @@ "abusefilter-blocker": "Abuse filter", "abusefilter-blockreason": "Automatically blocked by abuse filter.\nDescription of matched rule: $1", "abusefilter-degroupreason": "Rights automatically stripped by abuse filter.\nRule description: $1", + "abusefilter-blockautopromotereason": "Autopromotion automatically delayed by abuse filter.\nRule description: $1", "abusefilter-accountreserved": "This account name is reserved for use by the abuse filter.", - "right-abusefilter-modify": "Modify abuse filters", + "right-abusefilter-modify": "Create or modify abuse filters", "right-abusefilter-view": "View abuse filters", "right-abusefilter-log": "View the abuse log", "right-abusefilter-log-detail": "View detailed abuse log entries", - "right-abusefilter-private": "View private data in the abuse log", - "right-abusefilter-private-log": "View the AbuseFilter private details access log", + "right-abusefilter-privatedetails": "View private data in the abuse log", + "right-abusefilter-privatedetails-log": "View the AbuseFilter private details access log", "right-abusefilter-modify-restricted": "Modify abuse filters with restricted actions", "right-abusefilter-revert": "Revert all changes by a given abuse filter", "right-abusefilter-view-private": "View abuse filters marked as private", @@ -36,17 +37,23 @@ "action-abusefilter-view": "view abuse filters", "action-abusefilter-log": "view the abuse log", "action-abusefilter-log-detail": "view detailed abuse log entries", - "action-abusefilter-private": "view private data in the abuse log", - "action-abusefilter-private-log": "view the AbuseFilter private details access log", + "action-abusefilter-privatedetails": "view private data in the abuse log", + "action-abusefilter-privatedetails-log": "view the AbuseFilter private details access log", "action-abusefilter-modify-restricted": "modify abuse filters with restricted actions", "action-abusefilter-revert": "revert all changes by a given abuse filter", "action-abusefilter-view-private": "view abuse filters marked as private", "action-abusefilter-log-private": "view logs of abuse filters marked as private", - "abusefilter-log": "Abuse filter log", + "action-abusefilter-hide-log": "hide entries in the abuse log", + "action-abusefilter-hidden-log": "view hidden abuse log entries", + "action-abusefilter-modify-global": "create or modify global abuse filters", "abusefilter-log-summary": "This log shows a list of all actions caught by the filters.", "abusefilter-log-search": "Search the abuse log", "abusefilter-log-search-user": "User:", - "abusefilter-log-search-filter": "Filter IDs (separate with pipes):", + "abusefilter-log-search-group": "Filter group:", + "abusefilter-log-search-group-any": "Any", + "abusefilter-log-search-filter": "Filter IDs:", + "abusefilter-log-search-filter-help": "Separate with pipes, prefix with \"$1\" for global filters", + "abusefilter-log-search-filter-help-central": "Separate with pipes", "abusefilter-log-search-title": "Title:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-impact": "Impact:", @@ -75,19 +82,21 @@ "abusefilter-log-details-var": "Variable", "abusefilter-log-details-val": "Value", "abusefilter-log-details-vars": "Action parameters", - "abusefilter-log-details-private": "Private log details", + "abusefilter-log-details-privatedetails": "Private log details", "abusefilter-log-details-ip": "Originating IP address", "abusefilter-log-details-checkuser": "Check user", "abusefilter-log-noactions": "none", + "abusefilter-log-noactions-filter": "None", "abusefilter-log-details-diff": "Changes made in edit", "abusefilter-log-linkoncontribs": "abuse log", "abusefilter-log-linkoncontribs-text": "Abuse log for {{GENDER:$1|this user}}", "abusefilter-log-linkonhistory": "view abuse log", "abusefilter-log-linkonhistory-text": "View abuse log for this page", - "abusefilter-log-hidden": "(entry hidden)", + "abusefilter-log-linkonundelete": "view abuse log", + "abusefilter-log-linkonundelete-text": "View abuse log for this page", "abusefilter-log-hidden-implicit": "(hidden because revision has been deleted)", "abusefilter-log-cannot-see-details": "You do not have permission to see details of this entry.", - "abusefilter-log-cannot-see-private-details": "You do not have permission to see private details of this entry.", + "abusefilter-log-cannot-see-privatedetails": "You do not have permission to see private details of this entry.", "abusefilter-log-nonexistent": "An entry with the provided ID does not exist.", "abusefilter-log-details-hidden": "You cannot view the details for this entry because it is hidden from public view.", "abusefilter-log-details-hidden-implicit": "You cannot view the details for this entry because its associated revision is hidden from public view.", @@ -105,9 +114,12 @@ "log-action-filter-abusefilter-create": "New filter creation", "log-action-filter-abusefilter-modify": "Filter modification", "log-action-filter-suppress-abuselog": "Abuse log suppression", + "log-action-filter-rights-blockautopromote": "Autopromote block", + "log-action-filter-rights-restoreautopromote": "Autopromote restore", "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|accessed}} private details for $3", + "logentry-rights-blockautopromote": "$1 {{GENDER:$2|blocked}} the autopromotion of {{GENDER:$4|$3}} for a period of $5", + "logentry-rights-restoreautopromote": "$1 {{GENDER:$2|restored}} the autopromotion capability of {{GENDER:$4|$3}}", "abusefilterprivatedetails-log-name": "AbuseFilter private details access log", - "abusefilter-management": "Abuse filter management", "abusefilter-list": "All filters", "abusefilter-list-id": "Filter ID", "abusefilter-list-pattern": "Pattern", @@ -129,6 +141,7 @@ "abusefilter-throttled": "throttled", "abusefilter-hitcount": "$1 {{PLURAL:$1|hit|hits}}", "abusefilter-new": "Create a new filter", + "abusefilter-import-button": "Import filter", "abusefilter-return": "Return to filter management", "abusefilter-status-global": "Global", "abusefilter-list-options": "Options", @@ -149,26 +162,29 @@ "abusefilter-list-options-search-like": "Plain query", "abusefilter-list-options-search-rlike": "Regular expression", "abusefilter-list-options-search-irlike": "Case-insensitive regular expression", + "abusefilter-list-invalid-searchmode": "The specified search mode is not valid.", "abusefilter-list-regexerror": "An error has occurred while searching: Regular expression syntax error.", "abusefilter-list-options-submit": "Update", "abusefilter-tools-text": "Here are some tools which may be useful in formulating and debugging abuse filters.", "abusefilter-tools-expr": "Expression tester", "abusefilter-tools-submitexpr": "Evaluate", + "abusefilter-tools-syntax-error": "The filter has invalid syntax.", "abusefilter-tools-reautoconfirm": "Restore autoconfirmed status", "abusefilter-tools-reautoconfirm-user": "User:", "abusefilter-tools-reautoconfirm-submit": "Re-autoconfirm", + "abusefilter-tools-restoreautopromote": "Autopromotion restored via AbuseFilter tools.", "abusefilter-reautoconfirm-none": "That user has not had {{GENDER:$1|his|her|their}} autoconfirmed status suspended.", "abusefilter-reautoconfirm-notallowed": "You are not allowed to restore autoconfirmed status.", "abusefilter-reautoconfirm-done": "Account's autoconfirmed status has been restored", - "abusefilter-status": "Of the last $1 {{PLURAL:$1|action|actions}}, $2 ($3%) {{PLURAL:$2|has|have}} reached the condition limit of $4, and $5 ($6%) {{PLURAL:$5|has|have}} matched one of the filters currently enabled.", + "abusefilter-status": "Of the last $1 {{PLURAL:$1|action|actions}}, $2 ($3%) {{PLURAL:$2|has|have}} reached the condition limit of $4, and $5 ($6%) {{PLURAL:$5|has|have}} matched at least one of the filters currently enabled.", "abusefilter-edit": "Editing abuse filter", "abusefilter-edit-subtitle": "Editing filter $1", "abusefilter-edit-subtitle-new": "Creating filter", "abusefilter-edit-token-not-match": "The edit wasn't saved! Please save again.", "abusefilter-edit-oldwarning": "<strong>You are editing an old version of this filter.\nThe statistics quoted are for the most recent version of the filter.\nIf you save your changes, you will overwrite all changes since the revision you are editing.</strong> •\n[[Special:AbuseFilter/history/$2|Return to this filter's history]].", + "abusefilter-edit-oldwarning-view": "<strong>You are viewing an old version of this filter.\nThe statistics quoted are for the most recent version of the filter.</strong> •\n[[Special:AbuseFilter/history/$2|Return to this filter's history]].", "abusefilter-edit-status-label": "Statistics:", - "abusefilter-edit-status": "Of the last $1 {{PLURAL:$1|action|actions}}, this filter has matched $2 ($3%).", - "abusefilter-edit-status-profile": "Of the last $1 {{PLURAL:$1|action|actions}}, this filter has matched $2 ($3%).\nOn average, its run time is $4 ms, and it consumes $5 {{PLURAL:$5|condition|conditions}} of the condition limit.", + "abusefilter-edit-status": "Of the last $1 {{PLURAL:$1|action|actions}}, this filter has matched $2 ($3%).\nOn average, its run time is $4 ms, and it consumes $5 {{PLURAL:$5|condition|conditions}} of the condition limit.", "abusefilter-edit-throttled-warning": "'''Warning:''' This filter was automatically flagged as harmful. As a safety measure, the following actions will not execute ($1). Please review and [[mw:Extension:AbuseFilter/Conditions|optimize]] your conditions to remove this restriction", "abusefilter-edit-new": "New filter", "abusefilter-edit-save": "Save filter", @@ -201,6 +217,8 @@ "abusefilter-edit-throttle-count": "Number of actions to allow:", "abusefilter-edit-throttle-period": "Period of time (in seconds):", "abusefilter-edit-throttle-groups": "Group throttle by:", + "abusefilter-edit-throttle-groups-help": "See $1.", + "abusefilter-edit-throttle-groups-help-text": "the documentation on mediawiki.org", "abusefilter-edit-throttle-hidden-placeholder": "Split with commas to join with AND, and with linebreaks to join with OR", "abusefilter-edit-throttle-placeholder": "Split with commas to join with AND, and insert one by one to join with OR", "abusefilter-throttle-ip": "IP address", @@ -210,6 +228,7 @@ "abusefilter-throttle-editcount": "edit count", "abusefilter-throttle-site": "whole site", "abusefilter-throttle-page": "page", + "abusefilter-throttle-none": "(none)", "abusefilter-throttle-details": "Allow $1 {{PLURAL:$1|action|actions}} every $2 {{PLURAL:$2|second|seconds}}, group throttle by: $3", "abusefilter-edit-warn-message": "System message to use for warning:", "abusefilter-edit-warn-other": "Other message", @@ -249,10 +268,13 @@ "abusefilter-edit-export": "Export this filter to another wiki", "abusefilter-edit-syntaxok": "No syntax errors detected.", "abusefilter-edit-syntaxerr": "Syntax error detected: $1", + "abusefilter-edit-warn-leave": "Leaving the page will cause you to lose any change made to this filter.", "abusefilter-edit-bad-tags": "One or more of the tags you specified is not valid.\nTags should be short, they must not contain special characters, and they must not be reserved by other software. Try choosing a new tag name.", "abusefilter-edit-notallowed": "You are not permitted to create or edit abuse filters", "abusefilter-edit-notallowed-global": "You are not permitted to create or edit global abuse filters", - "abusefilter-edit-notallowed-global-custom-msg": "Custom warning messages are not supported for global filters", + "abusefilter-edit-notallowed-global-custom-msg": "Custom warning or disallow messages are not supported for global filters", + "abusefilter-edit-invalid-warn-message": "The warning message cannot be left empty.", + "abusefilter-edit-invalid-disallow-message": "The disallow message cannot be left empty.", "abusefilter-edit-invalid-throttlecount": "The throttle action count must be a positive integer.", "abusefilter-edit-invalid-throttleperiod": "The throttle period must be a positive integer.", "abusefilter-edit-empty-throttlegroups": "At least one throttle group must be selected.", @@ -288,7 +310,8 @@ "abusefilter-edit-builder-misc-contains": "Left string contains right string (contains)", "abusefilter-edit-builder-misc-stringlit": "String literal (\"\")", "abusefilter-edit-builder-misc-tern": "Ternary operator (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Conditional (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Conditional (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "Short conditional (if X then Y end)", "abusefilter-edit-builder-group-funcs": "Functions", "abusefilter-edit-builder-funcs-length": "String length (length)", "abusefilter-edit-builder-funcs-lcase": "To lower case (lcase)", @@ -359,12 +382,12 @@ "abusefilter-edit-builder-vars-all-links": "All external links in the new text", "abusefilter-edit-builder-vars-added-links": "All external links added in the edit", "abusefilter-edit-builder-vars-removed-links": "All external links removed in the edit", - "abusefilter-edit-builder-vars-old-text": "Old page wikitext, before the edit (no more in use)", - "abusefilter-edit-builder-vars-new-text": "New page wikitext, after the edit", + "abusefilter-edit-builder-vars-old-wikitext": "Old page wikitext, before the edit", + "abusefilter-edit-builder-vars-new-wikitext": "New page wikitext, after the edit", "abusefilter-edit-builder-vars-new-pst": "New page wikitext, pre-save transformed", "abusefilter-edit-builder-vars-diff-pst": "Unified diff of changes made by edit, pre-save transformed", "abusefilter-edit-builder-vars-addedlines-pst": "Lines added in edit, pre-save transformed", - "abusefilter-edit-builder-vars-new-text-stripped": "New page text, stripped of any markup", + "abusefilter-edit-builder-vars-new-text": "New page text, stripped of any markup", "abusefilter-edit-builder-vars-new-html": "Parsed HTML source of the new revision", "abusefilter-edit-builder-vars-restrictions-edit": "Edit protection level of the page", "abusefilter-edit-builder-vars-restrictions-move": "Move protection level of the page", @@ -378,10 +401,10 @@ "abusefilter-edit-builder-vars-movedto-restrictions-move": "Move protection level of move destination page", "abusefilter-edit-builder-vars-movedto-restrictions-create": "Create protection of move destination page", "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Upload protection of move destination file", - "abusefilter-edit-builder-vars-old-text-stripped": "Old page text, stripped of any markup", + "abusefilter-edit-builder-vars-old-text": "Old page text, stripped of any markup (no longer in use)", "abusefilter-edit-builder-vars-old-links": "Links in the page, before the edit", - "abusefilter-edit-builder-vars-old-html": "Old page wikitext, parsed into HTML (no more in use)", - "abusefilter-edit-builder-vars-minor-edit": "Whether or not the edit is marked as minor", + "abusefilter-edit-builder-vars-old-html": "Old page wikitext, parsed into HTML (no longer in use)", + "abusefilter-edit-builder-vars-minor-edit": "Whether or not the edit is marked as minor (no longer in use)", "abusefilter-edit-builder-vars-file-sha1": "SHA1 hash of file contents", "abusefilter-edit-builder-vars-file-size": "Size of the file in bytes", "abusefilter-edit-builder-vars-file-mime": "MIME type of the file", @@ -389,6 +412,8 @@ "abusefilter-edit-builder-vars-file-width": "Width of the file in pixels", "abusefilter-edit-builder-vars-file-height": "Height of the file in pixels", "abusefilter-edit-builder-vars-file-bits-per-channel": "Bits per color channel of the file", + "abusefilter-edit-builder-vars-wiki-name": "Database name of the wiki", + "abusefilter-edit-builder-vars-wiki-language": "Language code of the wiki", "abusefilter-filter-log": "Recent filter changes", "abusefilter-history": "Change history for Abuse Filter #$1", "abusefilter-history-foruser": "Changes by $1", @@ -422,13 +447,16 @@ "abusefilter-exception-dividebyzero": "Illegal attempt to divide $2 by zero at character $1.", "abusefilter-exception-unrecognisedvar": "Unrecognized variable $2 at character $1.", "abusefilter-exception-notenoughargs": "Not enough arguments to function $2 called at character $1.\nExpected $3 {{PLURAL:$3|argument|arguments}}, got $4", + "abusefilter-exception-toomanyargs": "Too many arguments to function $2 called at character $1.\nExpected at most $3 {{PLURAL:$3|argument|arguments}}, got $4", "abusefilter-exception-regexfailure": "Error in regular expression \"$2\" at character $1.", - "abusefilter-exception-overridebuiltin": "Illegal overriding of built-in variable \"$2\" at character $1.", + "abusefilter-exception-overridebuiltin": "Illegal overriding of built-in identifier \"$2\" at character $1.", "abusefilter-exception-outofbounds": "Requesting non-existent array item $2 (array size = $3) at character $1.", + "abusefilter-exception-negativeindex": "Negative indexes are not allowed in arrays. Got index \"$2\" at character $1.", "abusefilter-exception-notarray": "Requesting array item of non-array at character $1.", "abusefilter-exception-unclosedcomment": "Unclosed comment at character $1.", "abusefilter-exception-invalidiprange": "Invalid IP range \"$2\" provided at character $1.", - "abusefilter-exception-disabledvar": "Variable $2 at character $1 is no more in use.", + "abusefilter-exception-disabledvar": "Variable $2 at character $1 is no longer in use.", + "abusefilter-exception-variablevariable": "set and set_var expect the first argument to be a string literal, found at character $1.", "abusefilter-action-tag": "Tag", "abusefilter-action-throttle": "Throttle", "abusefilter-action-warn": "Warn", @@ -491,15 +519,16 @@ "abusefilter-examine-noresults": "No results were found for the search parameters you provided.", "abusefilter-topnav": "'''Abuse Filter navigation'''", "abusefilter-topnav-home": "Home", + "abusefilter-topnav-recentchanges": "Recent filter changes", "abusefilter-topnav-test": "Batch testing", "abusefilter-topnav-examine": "Examine past edits", "abusefilter-topnav-log": "Abuse log", "abusefilter-topnav-tools": "Debugging tools", - "abusefilter-topnav-import": "Import filter", "abusefilter-log-name": "Abuse filter log", "abusefilter-log-header": "This log shows a summary of changes made to filters.\nFor full details, see [[Special:AbuseFilter/history|the list]] of recent filter changes.", "abusefilter-logentry-create": "$1 {{GENDER:$2|created}} $4 ($5)", "abusefilter-logentry-modify": "$1 {{GENDER:$2|modified}} $4 ($5)", + "abusefilter-log-invalid-filter": "Some of the specified filter IDs are invalid.", "abusefilter-log-noresults": "No results", "abusefilter-diff-title": "Differences between versions", "abusefilter-diff-item": "Item", @@ -512,11 +541,12 @@ "abusefilter-diff-next": "Newer change", "abusefilter-import-intro": "You can use this interface to import filters from other wikis.\nOn the source wiki, click \"{{int:abusefilter-edit-export}}\" under \"{{int:abusefilter-edit-tools}}\" on the editing interface.\nCopy from the textbox that appears, and paste it into this textbox, then click \"{{int:abusefilter-import-submit}}\".", "abusefilter-import-submit": "Import data", + "abusefilter-import-invalid-data": "The data you tried to import is not valid", "abusefilter-group-default": "Default", "abusefilter-http-error": "An HTTP error occurred: $1.", - "abusefilter-view-private-submit": "View private details", - "abusefilter-view-private": "View private details", - "abusefilter-view-private-reason": "Reason for accessing private details:", + "abusefilter-view-privatedetails-submit": "View private details", + "abusefilter-view-privatedetails-legend": "View private details", + "abusefilter-view-privatedetails-reason": "Reason for accessing private details:", "abusefilter-log-details-id": "Log ID", "abusefilter-invalid-request": "Invalid request! You must access private log details through the form on [[Special:AbuseLog/$1]] and provide a reason.", "abusefilter-invalid-request-noid": "Invalid request! You must access private log details through the form on the abuse log details page and provide a reason.", diff --git a/AbuseFilter/i18n/eo.json b/AbuseFilter/i18n/eo.json index 5663b9c5..7eccb595 100644 --- a/AbuseFilter/i18n/eo.json +++ b/AbuseFilter/i18n/eo.json @@ -4,21 +4,26 @@ "AVRS", "Amikeco", "Blahma", + "Fitoschido", "KuboF", + "Lucas", + "Matma Rex", + "Mirin", "Objectivesea", + "Psychoslave", + "Rafaneta", + "Robin van der Vliet", + "Surfo", + "Taylor", "Tlustulimu", "Tradukisto", "Yekrats", - "Matma Rex", - "Robin van der Vliet", - "Rafaneta", - "Psychoslave", - "Lucas" + "Zarisi" ] }, "abusefilter-desc": "Aplikas aŭtomatan heŭristikon al redaktoj.", - "abusefilter": "Konfiguri filtrilon de misuzado", - "abuselog": "Protokolo pri misuzado", + "abusefilter": "Administrado de filtriloj de misuzo", + "abuselog": "Protokolo pri Filtrilo de Misuzo", "abusefilter-intro": "Bonvenon al la administra interfaco de la Misuzada Filtrilo.\nLa Misuzada Filtrilo estas aŭtomata programara ilo por apliki aŭtomata heŭristiko al ĉiuj agoj.\nĈi tiu interfaco montras liston de difinitaj filtriloj, kaj permesas ilin esti modifita.", "abusefilter-warning": "'''Averto''': Ĉi tiu ago estis aŭtomate identigita kiel malhelpema.\nMalkonstruktivaj redaktoj rapide estos malfaritaj,\nkaj ĉi tia ega aŭ ripetita malkonstruktiva redaktado rezultos, ke via konto aŭ komputilo estos forbarita.\nSe vi kredas ke ĉi tiu redakto estas ja konstruktiva, vi povas klaki Konservi denove por konfirmi ĝin.\nMallonga priskribo pri la regulo de misuzado kiun via ago kongruis estas: $1", "abusefilter-disallowed": "Ĉi tiu ago estis aŭtomate identigita kiel damaĝa, kaj do estis malpermesita.\nSe vi kredas ke via redakto estis konstruktiva, bonvolu kontakti administranton, kaj informi lin pri kion vi provis fari.\nMallonga priskribo de la misuza regulo, kiun via ago kongruis, estas: $1", @@ -33,7 +38,7 @@ "right-abusefilter-view": "Rigardi filtrilojn de misuzo", "right-abusefilter-log": "Rigardi la protokolon de misuzo", "right-abusefilter-log-detail": "Rigardi detalojn en la protokolo de misuzo", - "right-abusefilter-private": "Rigardi privatajn datenojn en la protokolo de misuzo", + "right-abusefilter-privatedetails": "Rigardi privatajn datenojn en la protokolo de misuzo", "right-abusefilter-modify-restricted": "Modifi misuzadajn filtrilojn kun limigitaj agoj", "right-abusefilter-revert": "Malfari ĉiujn ŝanĝojn de elektota misuzada filtrilo", "right-abusefilter-view-private": "Vidi misuzadajn filtrilojn markitajn kiel privatajn", @@ -45,17 +50,25 @@ "action-abusefilter-view": "vidi misuzadajn filtrilojn", "action-abusefilter-log": "vidi la protokolon pri misuzado", "action-abusefilter-log-detail": "vidi detalojn el linioj de protokolo pri misuzado", - "action-abusefilter-private": "vidi privatajn datenojn en la protokolo de misuzado", + "action-abusefilter-privatedetails": "vidi privatajn datenojn en la protokolo de misuzado", "action-abusefilter-modify-restricted": "modifi misuzadajn filtrilojn kun limigitaj agoj", "action-abusefilter-revert": "malfari ĉiujn ŝanĝojn de donita misuzada filtrilo", "action-abusefilter-view-private": "vidi misuzadajn filtrilojn markitajn kiel privatajn", - "abusefilter-log": "Protokolo pri Filtrilo de Misuzo", "abusefilter-log-summary": "Ĉi tiu protokolo montras liston de ĉiuj agoj kaptitaj de la filtriloj.", "abusefilter-log-search": "Serĉi la protokolon de misuzo", "abusefilter-log-search-user": "Uzanto:", + "abusefilter-log-search-group-any": "Ajna", "abusefilter-log-search-filter": "Identigo de filtrilo (apartiĝi per vertikalaj strekoj):", "abusefilter-log-search-title": "Titolo:", "abusefilter-log-search-wiki": "Vikio:", + "abusefilter-log-search-impact": "Efiko:", + "abusefilter-log-search-impact-all": "Ĉiuj agoj", + "abusefilter-log-search-impact-saved": "Nur konservitaj ŝanĝoj", + "abusefilter-log-search-impact-not-saved": "Sen konservitaj ŝanĝoj", + "abusefilter-log-search-entries-label": "Videbleco:", + "abusefilter-log-search-action-other": "Alia", + "abusefilter-log-search-action-any": "Ajna", + "abusefilter-log-search-action-taken-any": "Ajna", "abusefilter-log-search-submit": "Serĉi", "abusefilter-log-entry": "$1: $2 ekagigis misuzadan filtrilon, farante agon \"$3\" en $4.\nAgoj faritaj: $5;\nFiltrila priskribo: $6", "abusefilter-log-detailedentry-meta": "$1: $2 ŝpronis $3, farante agon \"$4\" en $5.\nAgoj fariĝis: $6;\nFiltrila priskribo: $7 ($8)", @@ -68,13 +81,15 @@ "abusefilter-log-details-var": "Variablo", "abusefilter-log-details-val": "Valoro", "abusefilter-log-details-vars": "Parametroj de ago", - "abusefilter-log-details-private": "Privataj datenoj", + "abusefilter-log-details-privatedetails": "Privataj datenoj", "abusefilter-log-details-ip": "Originala IP-adreso", + "abusefilter-log-details-checkuser": "Kontroli uzanton", "abusefilter-log-noactions": "neniu", "abusefilter-log-details-diff": "Ŝanĝoj faritaj en redaktoj", "abusefilter-log-linkoncontribs": "protokolo pri misuzado", "abusefilter-log-linkoncontribs-text": "Protokolaĵoj en la Protokolo pri Misuzado por ĉi tiu uzanto", - "abusefilter-log-hidden": "(linio kaŝita)", + "abusefilter-log-linkonhistory": "vidi la protokolon pri misuzado", + "abusefilter-log-linkonhistory-text": "Vidi la protokolojn por ĉi tiu paĝo", "abusefilter-log-hidden-implicit": "(kaŝita ĉar revizio estis forigita)", "abusefilter-log-cannot-see-details": "Vi ne havas rajton por vidi detalojn de ĉi tiuj konkursaĵoj.", "abusefilter-log-details-hidden": "Vi ne rajtas vidi detalojn pri ĉi tiu protokolero, ĉar ĝi estas kaŝita de publika vido.", @@ -82,11 +97,15 @@ "abusefilter-log-hide-id": "Identigo de protokolero:", "abusefilter-log-hide-hidden": "Kaŝi ĉi tiun protokoleron de publika vido", "abusefilter-log-hide-reason": "Kialo:", + "abusefilter-log-hide-reason-other": "Alia/plua kialo:", "abusefilter-log-hide-forbidden": "Vi ne havas permeson kaŝi liniojn en la protokolo de misuzado.", + "abusefilter-log-entry-suppress": "$1 {{GENDER:$2|kaŝis}} protokoleron $3", + "abusefilter-log-entry-unsuppress": "$1 {{GENDER:$2|malkaŝis}} protokoleron $3", "logentry-abusefilter-hit": "$1 ekagis $4, farante agon \"$5\" ĉe $3. Agoj faritaj: $6 ($7)", - "abusefilter-management": "Administrado de filtriloj de misuzo", + "log-action-filter-abusefilter-create": "Kreado de nova filtrilo", "abusefilter-list": "Ĉiuj filtriloj", "abusefilter-list-id": "Identigo de Filtrilo", + "abusefilter-list-pattern": "Filtroŝablono", "abusefilter-list-status": "Statuso", "abusefilter-list-public": "Publika priskribo", "abusefilter-list-consequences": "Konsekvencoj", @@ -104,6 +123,7 @@ "abusefilter-disabled": "Malŝalta", "abusefilter-hitcount": "$1 {{PLURAL:$1|trovo|trovoj}}", "abusefilter-new": "Krei novan filtrilon", + "abusefilter-import-button": "Importi filtrilon", "abusefilter-return": "Reiri al filtrila administrado", "abusefilter-status-global": "Ĝenerala", "abusefilter-list-options": "Opcioj", @@ -112,9 +132,16 @@ "abusefilter-list-options-deleted-hide": "Kaŝi forigitajn filtrilojn", "abusefilter-list-options-deleted-show": "Inkluzivi forigitajn filtrilojn", "abusefilter-list-options-scope": "Montri filtrilojn el:", - "abusefilter-list-options-scope-local": "Loka vikio", - "abusefilter-list-options-scope-global": "Ĝeneralaj reguloj", + "abusefilter-list-options-scope-local": "Lokaj reguloj nur", + "abusefilter-list-options-scope-global": "Ĝeneralaj reguloj nur", + "abusefilter-list-options-further-options": "Aliaj opcioj:", "abusefilter-list-options-hidedisabled": "Kaŝi malŝaltitajn filtrilojn", + "abusefilter-list-options-hideprivate": "Kaŝi privatajn filtrilojn", + "abusefilter-list-options-searchoptions": "Serĉa reĝimo:", + "abusefilter-list-options-search-like": "Simpla serĉo", + "abusefilter-list-options-search-rlike": "Regula esprimo", + "abusefilter-list-options-search-irlike": "Usklecoblinda regula esprimo", + "abusefilter-list-regexerror": "Okazis eraro dum la serĉo. Sintaksa eraro en regula esprimo.", "abusefilter-list-options-submit": "Ĝisdatigi", "abusefilter-tools-text": "Jen iloj kiuj eble estos utilaj formigi kaj sencimigi misuzadajn filtrilojn.", "abusefilter-tools-expr": "Esprimo-testilo", @@ -132,11 +159,12 @@ "abusefilter-edit-oldwarning": "<strong>Vi redaktas malnovan version de ĉi tiu filtrilo.\nĈi tiuj statistikoj estas por la plej lasta versio de la filtrilo.\nSe vi konservos ŝanĝojn, vi anstataŭigos ĉiujn ŝanĝojn ekde la versio, kiun vi redaktas.</strong> •\n[[Special:AbuseFilter/history/$2|Reiri al la historio de ĉi tiu filtrilo]].", "abusefilter-edit-status-label": "Statistikoj:", "abusefilter-edit-status": "El la {{PLURAL:$1|lasta 1 ago|lastaj $1 agoj}}, ĉi tiu filtrilo kongruis $2 ($3%).", - "abusefilter-edit-status-profile": "El la {{PLURAL:$1|lasta 1 ago|lastaj $1 agoj}}, ĉi tiu filtrilo kongruis $2 ($3%).\nAveraĝe, ĝia plenumtempo estas $4ms, kaj ĝi konsumas $5 {{PLURAL:$5|kondiĉon|kondiĉojn}} de la kondiĉa limo.", "abusefilter-edit-new": "Nova filtrilo", "abusefilter-edit-save": "Konservi filtrilon", "abusefilter-edit-id": "Identigo de filtrilo:", + "abusefilter-edit-switch-editor": "Transŝalti redaktilon", "abusefilter-edit-description": "Priskribo:\n:''(publike videbla)''", + "abusefilter-edit-field-description": "priskribo", "abusefilter-edit-group": "Grupo de filtrado:", "abusefilter-edit-flags": "Flagoj:", "abusefilter-edit-enabled": "Ŝalti ĉi tiun filtrilon", @@ -144,29 +172,46 @@ "abusefilter-edit-hidden": "Kaŝi detalojn pri ĉi tiu filtrilo de publika vido", "abusefilter-edit-global": "Filtrilo ĝenerala", "abusefilter-edit-rules": "Kondiĉoj:", + "abusefilter-edit-field-conditions": "kondiĉoj", "abusefilter-edit-notes": "Notoj:", "abusefilter-edit-lastmod": "Filtri laste modifitajn:", "abusefilter-edit-lastmod-text": "$1 de $2", "abusefilter-edit-hitcount": "Filtrilaj trafoj:", - "abusefilter-edit-consequences": "Agoj farotaj kiam kongrua", + "abusefilter-edit-consequences": "Agoj farendaj kiam kongrua", "abusefilter-edit-action-warn": "Plenumi ĉi tiun agojn post averti la uzanton", "abusefilter-edit-action-disallow": "Preventi la uzanton fari tian agon", "abusefilter-edit-action-blockautopromote": "Maldoni la aŭtomate konfirmitan statuson de uzanto", "abusefilter-edit-action-degroup": "Forigi la uzanton de ĉiuj altrajtaj grupoj", "abusefilter-edit-action-block": "Forbari la uzanton kaj/aŭ IP-adreson de redaktado", + "abusefilter-edit-action-blocktalk": "Bloki uzanton aŭ IP-adreson de eblo redakti sian propran diskutpaĝon", "abusefilter-edit-action-throttle": "Plenumi agojn nur se la uzanto atingas rapidlimon", "abusefilter-edit-action-rangeblock": "Forbari la /16 intervalon kie la uzanto originas", "abusefilter-edit-action-tag": "Flagi la redakton por plua kontrolado", "abusefilter-edit-throttle-count": "Nombro de agoj por permisigi", "abusefilter-edit-throttle-period": "Tempdaŭro:", "abusefilter-edit-throttle-groups": "Trafike limigi de:\n:''(po unu por linio, kombini per komoj)''", + "abusefilter-edit-throttle-groups-help": "Vidu la paĝon $1.", + "abusefilter-edit-throttle-groups-help-text": "la dokumentaro ĉe mediawiki.org", + "abusefilter-throttle-ip": "IP-adreso", + "abusefilter-throttle-user": "konto de uzanto", + "abusefilter-throttle-range": "intervalo /16", + "abusefilter-throttle-creationdate": "dato de kreado de konto", + "abusefilter-throttle-editcount": "nombro de redaktoj", + "abusefilter-throttle-site": "tuta retejo", + "abusefilter-throttle-page": "paĝo", + "abusefilter-throttle-none": "(nenio)", "abusefilter-edit-warn-message": "Sistema mesaĝo por uzi kiel averto:", "abusefilter-edit-warn-other": "Alia mesaĝo", "abusefilter-edit-warn-other-label": "Paĝa nomo de alia mesaĝo:\n:''(sen prefikso de MediaWiki)''", "abusefilter-edit-warn-actions": "Agoj:", "abusefilter-edit-warn-preview": "Antaŭvidi elektitan mesaĝon", "abusefilter-edit-warn-edit": "Krei/Redakti elektitan mesaĝon", + "abusefilter-edit-disallow-other": "Alia mesaĝo", + "abusefilter-edit-disallow-actions": "Agoj:", "abusefilter-edit-tag-tag": "Etikedoj por aldoni (po unu por linio):", + "abusefilter-edit-tag-hidden-placeholder": "Aldoni etikedojn (apartigitajn de komoj)", + "abusefilter-block-anon": "Forbari anonimulojn", + "abusefilter-block-user": "forbari registritajn uzantojn", "abusefilter-edit-denied": "Vi ne rajtas vidi detalojn pri ĉi tiu filtrilo, ĉar ĝi estas kaŝita de publika vido", "abusefilter-edit-main": "Filtraj parametroj", "abusefilter-edit-done-subtitle": "Filtrilo redaktita", @@ -196,8 +241,10 @@ "abusefilter-edit-builder-op-arithmetic-modulo": "Modulo (%)", "abusefilter-edit-builder-op-arithmetic-pow": "Potenco (**)", "abusefilter-edit-builder-group-op-comparison": "Komparaj operacioj", - "abusefilter-edit-builder-op-comparison-equal": "Egalas (==)", - "abusefilter-edit-builder-op-comparison-notequal": "Malegalas (!=)", + "abusefilter-edit-builder-op-comparison-equal": "Valoro egalas (==)", + "abusefilter-edit-builder-op-comparison-equal-strict": "Valoro kaj datentipo egalas (===)", + "abusefilter-edit-builder-op-comparison-notequal": "Valoro malegalas (!=)", + "abusefilter-edit-builder-op-comparison-notequal-strict": "Valoro kaj datentipo malegalas (!==)", "abusefilter-edit-builder-op-comparison-lt": "Pli malgranda ol (<)", "abusefilter-edit-builder-op-comparison-gt": "Pli granda ol (>)", "abusefilter-edit-builder-op-comparison-lte": "Malpli granda ol aŭ egala", @@ -209,8 +256,8 @@ "abusefilter-edit-builder-group-misc": "Diversaĵoj", "abusefilter-edit-builder-misc-in": "enhava en bitĉeno (in)", "abusefilter-edit-builder-misc-like": "Kongruas paternon (like)", - "abusefilter-edit-builder-misc-rlike": "Kongruas regularan esprimon (rlike)", - "abusefilter-edit-builder-misc-irlike": "Kongruas regularan esprimon, usklec-maldistinge (irlike)", + "abusefilter-edit-builder-misc-rlike": "Kongruas regulan esprimon (rlike)", + "abusefilter-edit-builder-misc-irlike": "Kongruas regulan esprimon, usklec-maldistinge (irlike)", "abusefilter-edit-builder-misc-contains": "Maldekstra signoĉeno enhavas dekstran signoĉenon (contains)", "abusefilter-edit-builder-misc-stringlit": "Signoĉena literalo (\"\")", "abusefilter-edit-builder-misc-tern": "Ternara operacio (X ? Y : Z)", @@ -224,7 +271,7 @@ "abusefilter-edit-builder-funcs-specialratio": "Specialaj signoj / ĉiuj signoj (specialratio)", "abusefilter-edit-builder-funcs-norm": "Normigi (norm)", "abusefilter-edit-builder-funcs-count": "Nombro de fojoj ke bitĉeno X aperas en bitĉeno Y (count)", - "abusefilter-edit-builder-funcs-rcount": "Kiom da fojoj regulara esprimo X aperas en signoĉeno Y (rcount)", + "abusefilter-edit-builder-funcs-rcount": "Kiom da fojoj regula esprimo X aperas en signoĉeno Y (rcount)", "abusefilter-edit-builder-funcs-rmwhitespace": "Forigi blankspacon (rmwhitespace)", "abusefilter-edit-builder-funcs-rmspecials": "Forigi specialajn signojn (rmspecials)", "abusefilter-edit-builder-funcs-ip_in_range": "Ĉu IP-adreso estas en intervalo? (ip_in_range)", @@ -234,8 +281,9 @@ "abusefilter-edit-builder-funcs-str_replace": "Anstataŭigi subsignoĉeno per signoĉeno (str_replace)", "abusefilter-edit-builder-funcs-rescape": "Kodŝanĝa signoĉeno kiel laŭlitera en regex (rescape)", "abusefilter-edit-builder-funcs-set_var": "Agordi variablon (set_var)", + "abusefilter-edit-builder-funcs-sanitize": "Normigi HTML-entojn en Unikodajn skribsignojn (seninfektigi)", "abusefilter-edit-builder-group-vars": "Variabloj", - "abusefilter-edit-builder-vars-accountname": "Salutnomo (dum konta kreado)", + "abusefilter-edit-builder-vars-accountname": "Uzantnomo (dum konta kreado)", "abusefilter-edit-builder-vars-timestamp": "Uniksa tempindiko de ŝanĝo", "abusefilter-edit-builder-vars-action": "Ago", "abusefilter-edit-builder-vars-addedlines": "Linioj aldonitaj en redakto", @@ -243,12 +291,15 @@ "abusefilter-edit-builder-vars-diff": "Unigita diferenco de ŝanĝoj faritaj de redakto", "abusefilter-edit-builder-vars-newsize": "Nova grandeco de paĝo", "abusefilter-edit-builder-vars-oldsize": "Malnova grandeco de paĝo", + "abusefilter-edit-builder-vars-old-content-model": "Malnova enhavomodelo", + "abusefilter-edit-builder-vars-new-content-model": "Nova enhavomodelo", "abusefilter-edit-builder-vars-removedlines": "Linioj forigitaj en redakto", "abusefilter-edit-builder-vars-summary": "Redakta resumo/kialo", "abusefilter-edit-builder-vars-page-id": "Paĝa identigo", "abusefilter-edit-builder-vars-page-ns": "Paĝa nomspaco", "abusefilter-edit-builder-vars-page-title": "Paĝa titolo (sen nomspaco)", "abusefilter-edit-builder-vars-page-prefixedtitle": "Plena paĝa titolo", + "abusefilter-edit-builder-vars-page-age": "Aĝo de la paĝo (en sekundoj)", "abusefilter-edit-builder-vars-movedfrom-id": "Paĝa identigo de movota fonta paĝo", "abusefilter-edit-builder-vars-movedfrom-ns": "Nomspaco de movada fontpaĝo", "abusefilter-edit-builder-vars-movedfrom-title": "Titolo de mova fonta paĝo", @@ -268,20 +319,26 @@ "abusefilter-edit-builder-vars-all-links": "Ĉiuj ekteraj ligiloj en la nova teksto", "abusefilter-edit-builder-vars-added-links": "Ĉiuj eksteraj ligiloj aldonitaj en la redakto", "abusefilter-edit-builder-vars-removed-links": "Ĉiuj eksteraj ligiloj forigitaj en la redakto", - "abusefilter-edit-builder-vars-old-text": "Malnova paĝa vikiteksto, antaŭ la redakto", - "abusefilter-edit-builder-vars-new-text": "Nova paĝo de vikiteksto, post la redakto", + "abusefilter-edit-builder-vars-old-wikitext": "Malnova paĝa vikiteksto, antaŭ la redakto", + "abusefilter-edit-builder-vars-new-wikitext": "Nova paĝo de vikiteksto, post la redakto", "abusefilter-edit-builder-vars-new-pst": "Nova vikiteksto de paĝo, transformita antaŭ la konservado", - "abusefilter-edit-builder-vars-new-text-stripped": "Nova paĝa teksto, forviŝita de iuj marklingvaĵoj", + "abusefilter-edit-builder-vars-new-text": "Nova paĝa teksto, forviŝita de iuj marklingvaĵoj", "abusefilter-edit-builder-vars-new-html": "Sintakse analizita HTML-fonto de la nova revizio", "abusefilter-edit-builder-vars-restrictions-edit": "Ŝanĝi protektnivelon de la paĝo", "abusefilter-edit-builder-vars-restrictions-move": "Movprotekta nivelo de la paĝo", "abusefilter-edit-builder-vars-restrictions-create": "Kread-protekto de ĉi tiu paĝo", "abusefilter-edit-builder-vars-restrictions-upload": "Alŝut-protekto de ĉi tiu dosiero", - "abusefilter-edit-builder-vars-old-text-stripped": "Teksto de malnova paĝo, sen iu ajn marklingvo", + "abusefilter-edit-builder-vars-old-text": "Teksto de malnova paĝo, sen iu ajn marklingvo", "abusefilter-edit-builder-vars-old-links": "Ligiloj en la paĝo, antaŭ la redakto", "abusefilter-edit-builder-vars-old-html": "Malnova paĝa vikiteksto, sintakse reformigita en HTML", "abusefilter-edit-builder-vars-minor-edit": "Ĉu aŭ ne la redakto estas markita kiel eta", "abusefilter-edit-builder-vars-file-sha1": "SHA1-haketo de dosiera enhavo", + "abusefilter-edit-builder-vars-file-size": "Grando de la dosiero en bajtoj", + "abusefilter-edit-builder-vars-file-mime": "MIME-tipo de la dosiero", + "abusefilter-edit-builder-vars-file-mediatype": "Aŭdvidaĵa tipo de la dosiero", + "abusefilter-edit-builder-vars-file-width": "Larĝo de la dosiero en bilderoj", + "abusefilter-edit-builder-vars-file-height": "Alto de la dosiero en bilderoj", + "abusefilter-edit-builder-vars-file-bits-per-channel": "Nombro de bitoj en kolorkanalo de la dosiero", "abusefilter-filter-log": "Lastaj filtrilaj ŝanĝoj", "abusefilter-history": "ŝanĝada historio por Misuzada Filtrilo #$1", "abusefilter-history-foruser": "Ŝanĝoj de $1", @@ -300,6 +357,7 @@ "abusefilter-history-filterid": "Filtro", "abusefilter-history-select-legend": "Rafini serĉon", "abusefilter-history-select-user": "Uzanto:", + "abusefilter-history-select-filter": "Identigo de filtrilo:", "abusefilter-history-select-submit": "Rafini", "abusefilter-history-diff": "Ŝanĝoj", "abusefilter-history-error-hidden": "La filtrilo kiun vi petis estas kaŝita, kaj vi ne povas vidi ĝian historion.", @@ -308,16 +366,18 @@ "abusefilter-exception-unrecognisedkeyword": "Nekonata ŝlosilvorto $2 ĉe signo $1.", "abusefilter-exception-unexpectedtoken": "Neatentita tokeno \"$3\" (de tipo $2) ĉe signo $1.", "abusefilter-exception-unclosedstring": "Malfermita signoĉeno komencante ĉe signo $1.", - "abusefilter-exception-invalidoperator": "Malvalida operatoro \"$2\" ĉe signo $1.", + "abusefilter-exception-invalidoperator": "Nevalida operatoro \"$2\" ĉe signo $1.", "abusefilter-exception-unrecognisedtoken": "Nekonata tokeno \"$2\" ĉe signo $1.", "abusefilter-exception-noparams": "Neniuj parametroj donitaj al funkcio \"$2\" ĉe signo $1.", "abusefilter-exception-dividebyzero": "Malpermesita provo dividigi $2 de nulo ĉe signo $1.", "abusefilter-exception-unrecognisedvar": "Nekonata variablo $2 ĉe signo $1", "abusefilter-exception-notenoughargs": "Ne sufiĉaj argumentoj por funkcio $2 vokita ĉe signo $1.\nAtentis $3 {{PLURAL:$3|argumenton|argumentojn}}, ricevis $4", - "abusefilter-exception-regexfailure": "Eraro en regulara esprimo \"$3\" ĉe signo $1: \"$2\"", + "abusefilter-exception-regexfailure": "Eraro en regula esprimo \"$2\" ĉe signo $1.", "abusefilter-exception-overridebuiltin": "Malpermesita transpasado de integrita variablo \"$2\" ĉe signo $1.", "abusefilter-exception-outofbounds": "Petante mankantan listeron $2 (lista grandeco = $3) ĉe signo $1.", "abusefilter-exception-notarray": "Petante tabelan eron de netabelaĵo ĉe signo $1.", + "abusefilter-exception-unclosedcomment": "Ne fermita komento ĉe skribsigno $1.", + "abusefilter-exception-invalidiprange": "Nevalida IP-adresa intervalo \"$2\" proviziĝis ĉe skribsigno $1.", "abusefilter-action-tag": "Etikedo", "abusefilter-action-throttle": "Trafik-limigilo", "abusefilter-action-warn": "Averti", @@ -333,8 +393,9 @@ "abusefilter-revert-periodstart": "Komenco de periodo:", "abusefilter-revert-periodend": "Fino de periodo:", "abusefilter-revert-search": "Elekti agojn", - "abusefilter-revert-filter": "Filtrilo:", + "abusefilter-revert-filter": "Identigo de filtrilo:", "abusefilter-revert-preview-intro": "Malsupre estas la agoj de la misuza filtrilo, kiuj estos malfarataj per ĉi tiu ago.\nBonvolu kontroli ilin zorgeme kaj klaku sur „{{int:abusefilter-revert-confirm}}“, por konfirmi vian elekton.", + "abusefilter-revert-confirm-legend": "Konfirmi la malfaron", "abusefilter-revert-confirm": "Konfirmi", "abusefilter-revert-success": "Vi malfaris ĉiujn agojn faritajn de la misuzada filtrilo de [[Special:AbuseFilter/$1|filtrilo $2]].", "abusefilter-revert-reason": "Aŭtomata restarigo de ĉiuj agoj faritaj de la misuzada filtrilo pro filtrilo $1.\nKialo donita: $2", @@ -346,11 +407,19 @@ "abusefilter-test-submit": "Testi", "abusefilter-test-load": "Ŝarĝi", "abusefilter-test-user": "Ŝanĝoj de uzanto:", + "abusefilter-test-nobots": "Kaŝi robotajn redaktojn", "abusefilter-test-period-start": "Ŝanĝoj faritaj post:", "abusefilter-test-period-end": "Ŝanĝoj faritaj antaŭ:", "abusefilter-test-page": "Ŝanĝoj faritaj al paĝo:", "abusefilter-test-shownegative": "Montri ŝanĝojn ne kongrantajn la filtrilon", "abusefilter-test-syntaxerr": "La filtrilo, kiun vi enigis, enhavis sintaksan eraron.\nVi povas ricevi plenan eksplikon per klakado al la butono \"{{int:abusefilter-edit-check}}\".", + "abusefilter-test-action": "Speco de ago:", + "abusefilter-test-search-type-all": "Ĉiuj agoj", + "abusefilter-test-search-type-edit": "Redaktoj", + "abusefilter-test-search-type-move": "Movoj", + "abusefilter-test-search-type-delete": "Forigoj", + "abusefilter-test-search-type-upload": "Alŝutoj", + "abusefilter-test-search-type-createaccount": "Kontokreoj", "abusefilter-changeslist-examine": "vidi", "abusefilter-examine": "Rigardi individuajn ŝanĝojn", "abusefilter-examine-intro": "Ĉi tiu paĝo permesas al vi rigardi la variablojn generitajn de la Misuzada Filtrilo por individua ŝanĝo, kaj testi ĝin per filtriloj.", @@ -364,19 +433,21 @@ "abusefilter-examine-test-button": "Testi filtrilon", "abusefilter-examine-match": "La filtrilo kongruis ĉi tiun ŝanĝon.", "abusefilter-examine-nomatch": "La filtrilo ne kongruis ĉi tiun ŝanĝon.", - "abusefilter-examine-syntaxerror": "La filtrilo havas malvalidan sintakson.", + "abusefilter-examine-syntaxerror": "La filtrilo havas nevalidan sintakson.", "abusefilter-examine-notfound": "La ŝango petita ne eblis esti trovita.", "abusefilter-examine-incompatible": "Via petita ŝanĝo ne estas subtenata de la Misuzada Filtrilo", "abusefilter-examine-noresults": "Neniuj rezultoj estis trovitaj de la serĉ-parametroj donitaj.", "abusefilter-topnav": "'''Navigado de Misuza Filtrilo'''", "abusefilter-topnav-home": "Hejmo", + "abusefilter-topnav-recentchanges": "Lastatempaj ŝanĝoj pri filtriloj", "abusefilter-topnav-test": "Stapla testado", "abusefilter-topnav-examine": "Vidi antaŭajn redaktojn", "abusefilter-topnav-log": "Protokolo de Misuzado", "abusefilter-topnav-tools": "Sencimigadaj iloj", - "abusefilter-topnav-import": "Importi filtrilon", "abusefilter-log-name": "Protokolo pri misuzadaj filtriloj", "abusefilter-log-header": "Ĉi tiu protokolo montras resumon de ŝanĝoj faritaj al filtriloj.\nPor plenaj detaloj, vidu [[Special:AbuseFilter/history|la liston]] de lastaj filtrilaj ŝanĝoj.", + "abusefilter-logentry-create": "$4 {{GENDER:$2|estis kreita}} de $1 ($5)", + "abusefilter-logentry-modify": "$4 {{GENDER:$2|estis modifita}} de $1 ($5)", "abusefilter-log-noresults": "Mankas rezultoj", "abusefilter-diff-title": "Diferencoj inter versioj", "abusefilter-diff-item": "Ero", @@ -389,5 +460,11 @@ "abusefilter-diff-next": "Pli malfrua ŝanĝo", "abusefilter-import-intro": "Vi povas uzi ĉi tiun interfacon por enporti filtrilojn de aliaj vikioj.\nEn la fonta vikio, klaku \"{{int:abusefilter-edit-export}}\" sub \"{{int:abusefilter-edit-tools}}\" en la redakta interfaco.\nKopiu de la tekstujo kiu aperas, kaj gluu ĝin en ĉi tiun tekstujon, kaj klaku \"{{int:abusefilter-import-submit}}\".", "abusefilter-import-submit": "Importi datenojn", - "abusefilter-group-default": "Defaŭlta" + "abusefilter-group-default": "Defaŭlta", + "abusefilter-http-error": "Okazis HTTP-eraro: $1.", + "abusefilter-view-privatedetails-submit": "Vidi privatajn detalojn", + "abusefilter-view-privatedetails-legend": "Vidi privatajn detalojn", + "abusefilter-view-privatedetails-reason": "Kialo por akiri privatajn detalojn:", + "abusefilter-log-details-id": "Identigilo de Protokolero", + "abusefilter-log-ip-not-available": "Ne Havebla" } diff --git a/AbuseFilter/i18n/es-formal.json b/AbuseFilter/i18n/es-formal.json index 058dcb87..0e5eb329 100644 --- a/AbuseFilter/i18n/es-formal.json +++ b/AbuseFilter/i18n/es-formal.json @@ -1,10 +1,14 @@ { "@metadata": { "authors": [ + "Fitoschido", "MarcoAurelio" ] }, "abusefilter-intro": "Sea bienvenido a la interfaz de administración del filtro antiabusos.\nEl filtro antiabusos es un programa que aplica heurística a todas las ediciones.\nLa intrerfaz muestra una lista de filtros definidos, y le permite modificarlos.", "abusefilter-warning": "'''Atención:''' Esta acción ha sido automáticamente identificada como dañina.\nLas ediciones contraproducentes son rápidamente revertidas y los sucesivos intentos de persistir en su adición resultarán en que su cuenta y/o direcciones IP sean bloqueadas.\nSi usted cree que la edición era constructiva, puede volver a intentar enviarla para confirmarla.\nUna breve referencia de la regla del filtro antiabusos que su edición ha disparado es: $1", - "abusefilter-disallowed": "Esta acción ha sido automáticamente identificada como dañina y su ejecución ha sido deshabilitada.\nSi usted cree que su acción por contra resultaba constructiva por favor informe a un administrador acerca de lo que usted intentaba realizar.\nUna breve descripción de la regla del filtro antiabusos que se ha disparado es: $1" + "abusefilter-disallowed": "Esta acción ha sido automáticamente identificada como dañina y su ejecución ha sido deshabilitada.\nSi usted cree que su acción por contra resultaba constructiva por favor informe a un administrador acerca de lo que usted intentaba realizar.\nUna breve descripción de la regla del filtro antiabusos que se ha disparado es: $1", + "abusefilter-log-details-hidden": "No puede ver detalles de esta entrada porque su acceso público está restringido.", + "abusefilter-edit-throttle-groups-help": "Consulte $1.", + "abusefilter-edit-denied": "No puede ver detalles de este filtro porque su acceso público está restringido." } diff --git a/AbuseFilter/i18n/es.json b/AbuseFilter/i18n/es.json index 38928e15..4418aeb5 100644 --- a/AbuseFilter/i18n/es.json +++ b/AbuseFilter/i18n/es.json @@ -2,59 +2,65 @@ "@metadata": { "authors": [ "-jem-", + "Agusbou2015", "Aleator", "Alvaro qc", + "AlvaroMolina", "Armando-Martin", + "Astroemi", "Baiji", "Benfutbol10", "BicScope", "Carlitosag", "Ciencia Al Poder", "Crazymadlover", + "Daimona Eaytoy", "Dalton2", + "DannyS712", "Dferg", + "Dgstranz", "Fitoschido", + "Fortega", + "Hasley", "Ihojose", "Imre", + "Indiralena", "Invadinado", + "Jelou", + "Josecurioso", "Locos epraix", "Luis Felipe Schenone", + "Macofe", "Manuelt15", + "Marcelo9987", "MarcoAurelio", + "Matma Rex", "McDutchie", "Miguel2706", "Mor", + "Ninovolador", "Pertile", "PieRRoMaN", "Platonides", + "PoLuX124", "Ralgis", "Remember the dot", + "RicardoSGZ", + "Ryo567", "Sanbec", "Savh", "Sethladan", + "Sophivorus", "TheBITLINK", + "Themasterriot", + "Tiberius1701", "Tifinaghes", "Translationista", - "Vivaelcelta", - "Themasterriot", - "Macofe", - "Ryo567", - "AlvaroMolina", - "Matma Rex", - "Indiralena", - "Dgstranz", - "Sophivorus", - "Fortega", - "Josecurioso", - "RicardoSGZ", - "Daimona Eaytoy", - "Astroemi", - "Agusbou2015", - "Jelou" + "Vivaelcelta" ] }, "abusefilter-desc": "Aplica heurísticas automáticas a las ediciones", - "abusefilter": "Configuración del filtro antiabusos", + "abusefilter": "Administración del filtro antiabusos", "abuselog": "Registro del filtro antiabusos", "abusefilter-intro": "Te damos la bienvenida a la interfaz de administración del filtro antiabusos.\nEl filtro antiabusos es un mecanismo de software automatizado que aplica heurística a todas las acciones.\nEsta interfaz muestra una lista de filtros definidos, que pueden ser modificados.", "abusefilter-mustviewprivateoredit": "Por razones de seguridad, solamente los usuarios con derechos para ver filtros antiabuso privados o modificar filtros pueden usar esta interfaz.", @@ -66,13 +72,14 @@ "abusefilter-blocker": "Filtro antiabusos", "abusefilter-blockreason": "Bloqueado automáticamente por el filtro antiabusos.\nDescripción del filtro que se ha disparado: $1", "abusefilter-degroupreason": "Permisos de usuario automáticamente revocados por el filtro antiabusos.\nDescripción de la regla disparada: $1", + "abusefilter-blockautopromotereason": "El filtro antiabusos ha demorado la recepción automática de ciertos permisos de usuario.\nDescripción de la regla que se ha disparado: $1", "abusefilter-accountreserved": "Este nombre de cuenta está reservado para su uso por el filtro antiabusos.", - "right-abusefilter-modify": "Modificar filtros antiabusos", + "right-abusefilter-modify": "Crear o modificar filtros antiabusos", "right-abusefilter-view": "Ver filtros antiabusos", "right-abusefilter-log": "Ver el registro del filtro antiabusos", "right-abusefilter-log-detail": "Ver entradas del registro detalladas del filtro antiabusos", - "right-abusefilter-private": "Ver datos privados en el registro del filtro antiabusos", - "right-abusefilter-private-log": "Ver el registro de acceso a datos privados del filtro antiabusos", + "right-abusefilter-privatedetails": "Ver datos privados en el registro del filtro antiabusos", + "right-abusefilter-privatedetails-log": "Ver el registro de acceso a datos privados del filtro antiabusos", "right-abusefilter-modify-restricted": "Modificar filtros antiabusos con acciones restringidas", "right-abusefilter-revert": "Revertir todos los cambios realizados por un determinado filtro antiabusos", "right-abusefilter-view-private": "Ver filtros antiabusos marcados como privados", @@ -84,17 +91,23 @@ "action-abusefilter-view": "ver los filtros antiabusos", "action-abusefilter-log": "ver registro del filtro antiabusos", "action-abusefilter-log-detail": "ver entradas detalladas del filtro antiabusos", - "action-abusefilter-private": "ver datos privados en el registro del filtro antiabusos", - "action-abusefilter-private-log": "ver el registro de acceso a datos privados del filtro antiabusos", + "action-abusefilter-privatedetails": "ver datos privados en el registro del filtro antiabusos", + "action-abusefilter-privatedetails-log": "ver el registro de acceso a datos privados del filtro antiabusos", "action-abusefilter-modify-restricted": "modificar filtros antiabusos con acciones restringidas", "action-abusefilter-revert": "revertir todos los cambios realizados por un determinado filtro antiabusos", "action-abusefilter-view-private": "ver filtros antiabusos marcados como privados", "action-abusefilter-log-private": "ver registros de filtros antiabusos marcados como privados", - "abusefilter-log": "Registro del filtro antiabusos", + "action-abusefilter-hide-log": "ocultar entradas del registro de abusos", + "action-abusefilter-hidden-log": "ver entradas ocultas del registro de abusos", + "action-abusefilter-modify-global": "crear o modificar filtros antiabusos globales", "abusefilter-log-summary": "Este registro muestra una lista de todas las acciones detectadas por los filtros.", "abusefilter-log-search": "Buscar en el registro del filtro antiabusos", "abusefilter-log-search-user": "Usuario:", - "abusefilter-log-search-filter": "Ids. de filtros (separar con barras verticales):", + "abusefilter-log-search-group": "Filtrar grupo:", + "abusefilter-log-search-group-any": "Cualquiera", + "abusefilter-log-search-filter": "Identificadores de los filtros:", + "abusefilter-log-search-filter-help": "Separar con plecas; prefijar con «$1» para filtros globales", + "abusefilter-log-search-filter-help-central": "Separar con plecas", "abusefilter-log-search-title": "Título:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-impact": "Impacto:", @@ -105,6 +118,7 @@ "abusefilter-log-search-entries-all": "Todas las entradas", "abusefilter-log-search-entries-hidden": "Solo las entradas ocultas", "abusefilter-log-search-entries-visible": "Solo las entradas visibles", + "abusefilter-log-search-action-label": "Acción disparadora:", "abusefilter-log-search-action-other": "Otro", "abusefilter-log-search-action-any": "Cualquiera", "abusefilter-log-search-action-taken-label": "Medida adoptada:", @@ -116,27 +130,29 @@ "abusefilter-log-detailedentry-global": "filtro global $1", "abusefilter-log-detailedentry-local": "filtro $1", "abusefilter-log-detailslink": "detalles", - "abusefilter-log-diff": "dif", + "abusefilter-log-diff": "difs.", "abusefilter-log-hidelink": "ajustar visibilidad", "abusefilter-log-details-legend": "Detalles de la entrada del registro $1", "abusefilter-log-details-var": "Variable", "abusefilter-log-details-val": "Valor", "abusefilter-log-details-vars": "Parámetros de acción", - "abusefilter-log-details-private": "Datos privados del registro", + "abusefilter-log-details-privatedetails": "Datos privados del registro", "abusefilter-log-details-ip": "Dirección IP originante", "abusefilter-log-details-checkuser": "Verificar usuario", "abusefilter-log-noactions": "ninguna", + "abusefilter-log-noactions-filter": "Ninguno", "abusefilter-log-details-diff": "Cambios hechos en la edición", "abusefilter-log-linkoncontribs": "registro del filtro antiabusos", - "abusefilter-log-linkoncontribs-text": "Registro del filtro antiabusos para {{GENDER:$1|este usuario|esta usuaria}}", + "abusefilter-log-linkoncontribs-text": "Registro del filtro antiabusos de {{GENDER:$1|este usuario|esta usuaria}}", "abusefilter-log-linkonhistory": "ver registro de abusos", "abusefilter-log-linkonhistory-text": "Ver el registro de abusos de esta página", - "abusefilter-log-hidden": "(entrada oculta)", + "abusefilter-log-linkonundelete": "ver registro de abusos", + "abusefilter-log-linkonundelete-text": "Ver el registro de abusos de esta página", "abusefilter-log-hidden-implicit": "(oculto porque se ha eliminado la revisión)", "abusefilter-log-cannot-see-details": "No tienes permiso para ver los detalles de esta entrada.", - "abusefilter-log-cannot-see-private-details": "No tienes permiso para ver los detalles privados de esta entrada.", + "abusefilter-log-cannot-see-privatedetails": "No tienes permiso para ver los detalles privados de esta entrada.", "abusefilter-log-nonexistent": "No existe ninguna entrada con el identificador proporcionado.", - "abusefilter-log-details-hidden": "No puedes ver los detalles de esta entrada porque esta es privada.", + "abusefilter-log-details-hidden": "No puedes ver detalles de esta entrada porque su acceso público está restringido.", "abusefilter-log-details-hidden-implicit": "No puedes ver los detalles para esta entrada porque su revisión asociada no es visible al público.", "abusefilter-log-private-not-included": "Uno o más de los identificadores de filtro que has especificado son privados. Debido a que no tienes permitido ver los detalles de los filtros privados, estos filtros no se han buscado.", "abusefilter-log-hide-legend": "Ocultar entrada del registro", @@ -152,9 +168,12 @@ "log-action-filter-abusefilter-create": "Creación de filtro nuevo", "log-action-filter-abusefilter-modify": "Modificación de filtro", "log-action-filter-suppress-abuselog": "Supresiones del filtro antiabusos", + "log-action-filter-rights-blockautopromote": "Bloque de autopromoción", + "log-action-filter-rights-restoreautopromote": "Restaurar autopromoción", "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|accedió}} a los detalles privados de $3", + "logentry-rights-blockautopromote": "$1 {{GENDER:$2|bloqueó}} la recepción automática de ciertos permisos de usuario a {{GENDER:$4|$3}} por un periodo de $5", + "logentry-rights-restoreautopromote": "$1 {{GENDER:$2|restauró}} la capacidad de recibir ciertos permisos de usuario de manera automática a {{GENDER:$4|$3}}", "abusefilterprivatedetails-log-name": "Registro de acceso a datos privados del filtro antiabusos", - "abusefilter-management": "Administración del filtro antiabusos", "abusefilter-list": "Todos los filtros", "abusefilter-list-id": "Identificación de filtro", "abusefilter-list-pattern": "Patrón", @@ -176,6 +195,7 @@ "abusefilter-throttled": "limitado", "abusefilter-hitcount": "$1 {{PLURAL:$1|detección|detecciones}}", "abusefilter-new": "Crear un filtro nuevo", + "abusefilter-import-button": "Importar filtro", "abusefilter-return": "Regresar a la gestión de filtros", "abusefilter-status-global": "Global", "abusefilter-list-options": "Opciones", @@ -196,26 +216,29 @@ "abusefilter-list-options-search-like": "Consulta simple", "abusefilter-list-options-search-rlike": "Expresión regular", "abusefilter-list-options-search-irlike": "Expresión regular sin distinción de uso de mayúsculas", + "abusefilter-list-invalid-searchmode": "El modo de búsqueda especificado no es válido.", "abusefilter-list-regexerror": "Se produjo un problema al buscar: hay un error de sintaxis en la expresión regular.", "abusefilter-list-options-submit": "Actualizar", "abusefilter-tools-text": "Aquí hay algunas herramientas que pueden ser útiles formulando y reparando filtros antiabusos.", "abusefilter-tools-expr": "Probador de expresiones", "abusefilter-tools-submitexpr": "Evaluar", + "abusefilter-tools-syntax-error": "El filtro no tiene una sintaxis válida.", "abusefilter-tools-reautoconfirm": "Restaurar el estado autoconfirmado", "abusefilter-tools-reautoconfirm-user": "Usuario:", "abusefilter-tools-reautoconfirm-submit": "Autoconfirmar de nuevo", + "abusefilter-tools-restoreautopromote": "Recepción automática de permisos de usuario restaurada a través de las herramientas de AbuseFilter.", "abusefilter-reautoconfirm-none": "A {{GENDER:$1|este usuario|esta usuaria}} no se le ha suspendido su estado autoconfirmado.", "abusefilter-reautoconfirm-notallowed": "No tienes autorización para restaurar el permiso autoconfirmado a los usuarios.", "abusefilter-reautoconfirm-done": "El estado autoconfirmado de la cuenta ha sido restaurado", - "abusefilter-status": "De {{PLURAL:$1|la última acción|las últimas $1 acciones}}, $2 ($3 %) {{PLURAL:$2|ha|han}} alcanzado el límite de $4 condiciones, y $5 ($6 %) {{PLURAL:$5|ha|han}} coincidido con alguno de los filtros activados actualmente.", + "abusefilter-status": "De {{PLURAL:$1|la última acción|las últimas $1 acciones}}, $2 ($3 %) {{PLURAL:$2|ha|han}} alcanzado el límite de $4 condiciones, y $5 ($6 %) {{PLURAL:$5|ha|han}} coincidido con al menos uno de los filtros activados actualmente.", "abusefilter-edit": "Editar el filtro antiabusos", "abusefilter-edit-subtitle": "Editando filtro $1", "abusefilter-edit-subtitle-new": "Creando un filtro", "abusefilter-edit-token-not-match": "¡La edición no fue guardada! Por favor vuelve a intentarlo.", "abusefilter-edit-oldwarning": "<strong>Estás editando una versión antigua de este filtro.\nLas estadísticas citadas son para la versión más reciente del filtro.\nSi grabas tus cambios, sobrescribirás todos los cambios realizados desde la revisión que estás editando.</strong> •\n[[Special:AbuseFilter/history/$2|Volver al historial de este filtro]].", + "abusefilter-edit-oldwarning-view": "<strong>Estás viendo una versión antigua de este filtro.\nLas estadísticas citadas son de la versión más reciente del filtro.</strong> •\n[[Special:AbuseFilter/history/$2|Volver al historial de este filtro]].", "abusefilter-edit-status-label": "Estadísticas:", - "abusefilter-edit-status": "De {{PLURAL:$1|la última acción|las últimas $1 acciones}}, este filtro ha coincidido con $2 ($3 %).", - "abusefilter-edit-status-profile": "De {{PLURAL:$1|la última acción|las últimas $1 acciones}}, este filtro ha coincidido con $2 ($3 %).\nEn promedio, su tiempo de ejecución es de $4 ms, y consume $5 {{PLURAL:$5|condición|condiciones}} del límite de condiciones.", + "abusefilter-edit-status": "De {{PLURAL:$1|la última acción|las últimas $1 acciones}}, este filtro ha coincidido con $2 ($3 %).\nComo promedio, su tiempo de ejecución es de $4 y consume $5 {{PLURAL:$5|condición|condiciones}} del límite de condiciones.", "abusefilter-edit-throttled-warning": "'''Atención:''' este filtro se marcó automáticamente como perjudicial. Como medida de seguridad, no se ejecutarán las acciones siguientes ($1). Revisa y [[mw:Extension:AbuseFilter/Conditions|optimiza]] las condiciones para eliminar esta restricción", "abusefilter-edit-new": "Filtro nuevo", "abusefilter-edit-save": "Guardar filtro", @@ -235,33 +258,44 @@ "abusefilter-edit-lastmod": "Última modificación del filtro:", "abusefilter-edit-lastmod-text": "$1 por $2", "abusefilter-edit-hitcount": "Detecciones del filtro:", - "abusefilter-edit-consequences": "Medidas que tomar cuando las condiciones coincidan", + "abusefilter-edit-consequences": "Medidas a tomar cuando las condiciones coincidan", "abusefilter-edit-action-warn": "Desencadenar estas acciones tras alertar al usuario", - "abusefilter-edit-action-disallow": "Prevenir al usuario de realizar la acción en cuestión", + "abusefilter-edit-action-disallow": "Evitar que el usuario realice la acción en cuestión", "abusefilter-edit-action-blockautopromote": "Revocar el estado autoconfirmado del usuario", "abusefilter-edit-action-degroup": "Retirar al usuario todos los permisos de su cuenta", "abusefilter-edit-action-block": "Bloquear al usuario o dirección IP", "abusefilter-edit-action-blocktalk": "Bloquear al usuario o dirección IP impidiendo que pueda usar su página de discusión", - "abusefilter-edit-action-throttle": "Disparar el filtro solamente si el usuario sobrepasa un cierto límite de ritmo de edición", + "abusefilter-edit-action-throttle": "Disparar el filtro solo si el usuario supera un límite de velocidad", "abusefilter-edit-action-rangeblock": "Bloquear el intervalo de IP respectivo del cual proviene el usuario", "abusefilter-edit-action-tag": "Marcar la edición para una revisión posterior", "abusefilter-edit-throttle-count": "Número de acciones a permitir:", "abusefilter-edit-throttle-period": "Período (en segundos):", "abusefilter-edit-throttle-groups": "Agrupar limitador por:", - "abusefilter-edit-throttle-ip": "Dirección IP", - "abusefilter-edit-throttle-user": "Cuenta de usuario", - "abusefilter-edit-throttle-range": "Rango /16", - "abusefilter-edit-throttle-creationdate": "Hora del servidor en la que se produjo la creación de cuenta", - "abusefilter-edit-throttle-editcount": "Recuento de ediciones", - "abusefilter-edit-throttle-site": "El sitio entero", - "abusefilter-edit-throttle-page": "Página", + "abusefilter-edit-throttle-groups-help": "Consulta $1.", + "abusefilter-edit-throttle-groups-help-text": "la documentación en mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Separa las condiciones con comas para unirlas con AND (Y) y con saltos de línea para unirlas con OR (O)", + "abusefilter-edit-throttle-placeholder": "Separa las condiciones con comas para unirlas con AND (Y) e insértalas una a una para unirlas con OR (O)", + "abusefilter-throttle-ip": "dirección IP", + "abusefilter-throttle-user": "cuenta de usuario", + "abusefilter-throttle-range": "rango /16", + "abusefilter-throttle-creationdate": "fecha de creación de la cuenta", + "abusefilter-throttle-editcount": "número de ediciones", + "abusefilter-throttle-site": "el sitio entero", + "abusefilter-throttle-page": "página", + "abusefilter-throttle-none": "(ninguno)", "abusefilter-throttle-details": "Permitir $1 {{PLURAL:$1|acción|acciones}} cada $2 {{PLURAL:$2|segundo|segundos}}, límite agrupado por: $3", - "abusefilter-edit-warn-message": "Mensaje del sistema para usar por la advertencia:", + "abusefilter-edit-warn-message": "Mensaje del sistema para la advertencia:", "abusefilter-edit-warn-other": "Otro mensaje", - "abusefilter-edit-warn-other-label": "Nombre de página de otro mensaje:\n:''(sin prefijo MediaWiki)''", + "abusefilter-edit-warn-other-label": "Nombre de página de otro mensaje:\n:''(sin el prefijo «MediaWiki:»)''", "abusefilter-edit-warn-actions": "Acciones:", - "abusefilter-edit-warn-preview": "Mostrar/Ocultar el mensaje seleccionado", - "abusefilter-edit-warn-edit": "Crear o editar el mensaje seleccionado", + "abusefilter-edit-warn-preview": "Mostrar/Ocultar mensaje seleccionado", + "abusefilter-edit-warn-edit": "Crear/Editar mensaje seleccionado", + "abusefilter-edit-disallow-message": "Mensaje de sistema para prevenir la edición:", + "abusefilter-edit-disallow-other": "Otro mensaje", + "abusefilter-edit-disallow-other-label": "Nombre de la página del otro mensaje:\n:''(sin el prefijo «MediaWiki:»)''", + "abusefilter-edit-disallow-actions": "Acciones:", + "abusefilter-edit-disallow-preview": "Mostrar/Ocultar previsualización del mensaje seleccionado", + "abusefilter-edit-disallow-edit": "Crear/Editar mensaje seleccionado", "abusefilter-edit-tag-tag": "[[Special:Tags|Etiquetas]] que se aplicarán:", "abusefilter-edit-tag-placeholder": "Añadir etiquetas (una por una o separadas por comas)", "abusefilter-edit-tag-hidden-placeholder": "Añadir etiquetas (separadas por comas)", @@ -269,13 +303,13 @@ "abusefilter-edit-block-user-durations": "Duración del bloqueo para usuarios registrados:", "abusefilter-block-anon": "Bloquear usuarios anónimos", "abusefilter-block-user": "bloquear usuarios registrados", - "abusefilter-block-talk": "no puede editar su página de discusión", - "abusefilter-edit-denied": "No puedes ver detalles de este filtro porque es privado", + "abusefilter-block-talk": "página de discusión bloqueada", + "abusefilter-edit-denied": "No puedes ver detalles de este filtro porque su acceso público está restringido.", "abusefilter-edit-main": "Parámetros de filtro", "abusefilter-edit-done-subtitle": "Filtro editado", - "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Tus cambios]] al [[Special:AbuseFilter/$1|filtro $3]] han sido guardados.", + "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Tus cambios]] en el [[Special:AbuseFilter/$1|filtro $3]] han sido guardados.", "abusefilter-edit-badsyntax": "Hay un error de sintaxis en el filtro que especificaste.\nEl resultado del analizador fue: <pre>$1</pre>", - "abusefilter-edit-missingfields": "Los siguientes campos son requeridos: $1", + "abusefilter-edit-missingfields": "Los siguientes campos son obligatorios: $1", "abusefilter-edit-deleting-enabled": "No puedes marcar un filtro activo como borrado.", "abusefilter-edit-restricted": "No puedes editar este filtro, porque contiene una o más acciones restringidas.\nPor favor, solicita a un usuario con permisos suficientes para agregar acciones restringidas que haga el cambio por ti.", "abusefilter-edit-viewhistory": "Ver el historial de este filtro", @@ -288,10 +322,18 @@ "abusefilter-edit-export": "Exportar este filtro a otro wiki", "abusefilter-edit-syntaxok": "No se detectaron errores de sintaxis.", "abusefilter-edit-syntaxerr": "Se detectó un error de sintaxis: $1", + "abusefilter-edit-warn-leave": "Si abandonas la página se perderá cualquier modificación realizada al filtro.", "abusefilter-edit-bad-tags": "Una o más de las etiquetas que especificaste no son válidas.\nLas etiquetas deben ser breves, no deben contener caracteres especiales y no deben estar reservadas por otro programa. Prueba a elegir otro nombre de etiqueta.", "abusefilter-edit-notallowed": "No se te permite crear o editar filtros antiabusos", "abusefilter-edit-notallowed-global": "No se te permite crear o editar filtros antiabusos globales", - "abusefilter-edit-notallowed-global-custom-msg": "Los mensajes de alerta personalizados no admiten filtros globales", + "abusefilter-edit-notallowed-global-custom-msg": "Los mensajes de alerta personalizados no se admiten en los filtros globales", + "abusefilter-edit-invalid-warn-message": "El mensaje de alerta no puede dejarse vacío.", + "abusefilter-edit-invalid-disallow-message": "El mensaje de prohibición no puede dejarse vacío.", + "abusefilter-edit-invalid-throttlecount": "El recuento de acción del acelerador debe ser un número entero positivo.", + "abusefilter-edit-invalid-throttleperiod": "El período de aceleración debe ser un número entero positivo.", + "abusefilter-edit-empty-throttlegroups": "Debe seleccionarse al menos un grupo de limitación.", + "abusefilter-edit-duplicated-throttlegroups": "Los grupos de aceleración no pueden tener duplicados.", + "abusefilter-edit-invalid-throttlegroups": "Los grupos de aceleración especificados no son válidos.", "abusefilter-edit-builder-select": "Selecciona una opción para agregarla en el cursor", "abusefilter-edit-builder-group-op-arithmetic": "Operadores aritméticos", "abusefilter-edit-builder-op-arithmetic-addition": "Adición (+)", @@ -314,16 +356,17 @@ "abusefilter-edit-builder-op-bool-and": "Y (&)", "abusefilter-edit-builder-op-bool-or": "O (|)", "abusefilter-edit-builder-group-misc": "Miscelánea", - "abusefilter-edit-builder-misc-in": "Contenido en la cadena (in)", - "abusefilter-edit-builder-misc-like": "Coincide con patrón (like)", - "abusefilter-edit-builder-misc-rlike": "Coincide con expresión regular (rlike)", + "abusefilter-edit-builder-misc-in": "contenido en la cadena (in)", + "abusefilter-edit-builder-misc-like": "Coincide con el patrón (like)", + "abusefilter-edit-builder-misc-rlike": "Coincide con la expresión regular (rlike)", "abusefilter-edit-builder-misc-irlike": "Coincide con la expresión regular, no distingue entre mayúsculas y minúsculas (irlike)", "abusefilter-edit-builder-misc-contains": "La cadena izquierda contiene la cadena derecha (contains)", "abusefilter-edit-builder-misc-stringlit": "Cadena de caracteres literal (\"\")", "abusefilter-edit-builder-misc-tern": "Operador ternario (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Condicional (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Condicional (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "Condicional corto (if X then Y end)", "abusefilter-edit-builder-group-funcs": "Funciones", - "abusefilter-edit-builder-funcs-length": "Longitud de cadena de caracteres (length)", + "abusefilter-edit-builder-funcs-length": "Longitud de la cadena de caracteres (length)", "abusefilter-edit-builder-funcs-lcase": "A minúsculas (lcase)", "abusefilter-edit-builder-funcs-ucase": "A mayúsculas (ucase)", "abusefilter-edit-builder-funcs-ccnorm": "Normalizar caracteres confusos (ccnorm)", @@ -349,12 +392,12 @@ "abusefilter-edit-builder-funcs-sanitize": "Normalizar entidades HTML en caracteres unicode (sanitize)", "abusefilter-edit-builder-group-vars": "Variables", "abusefilter-edit-builder-vars-accountname": "Nombre de usuario (en la creación de la cuenta)", - "abusefilter-edit-builder-vars-timestamp": "Hora Unix del cambio", + "abusefilter-edit-builder-vars-timestamp": "Cronomarcador Unix del cambio", "abusefilter-edit-builder-vars-timestamp-expanded": "Fecha y hora del registro", "abusefilter-edit-builder-vars-action": "Acción", - "abusefilter-edit-builder-vars-addedlines": "Renglones añadidos en la edición", - "abusefilter-edit-builder-vars-delta": "Cambio en tamaño en revisión", - "abusefilter-edit-builder-vars-diff": "Diff unificado de cambios hechos durante la edición", + "abusefilter-edit-builder-vars-addedlines": "Líneas añadidas en la edición", + "abusefilter-edit-builder-vars-delta": "Cambio de tamaño en la edición", + "abusefilter-edit-builder-vars-diff": "Diff unificado de los cambios realizados por la edición", "abusefilter-edit-builder-vars-newsize": "Nuevo tamaño de la página", "abusefilter-edit-builder-vars-oldsize": "Antiguo tamaño de la página", "abusefilter-edit-builder-vars-old-content-model": "Modelo de contenido antiguo", @@ -366,11 +409,11 @@ "abusefilter-edit-builder-vars-page-title": "Título de página (sin espacio de nombres)", "abusefilter-edit-builder-vars-page-prefixedtitle": "Título completo de la página", "abusefilter-edit-builder-vars-page-age": "Antigüedad de la página (en segundos)", - "abusefilter-edit-builder-vars-movedfrom-id": "ID de la página fuente a trasladar", - "abusefilter-edit-builder-vars-movedfrom-ns": "Espacio de nombres de la página de origen que trasladar", - "abusefilter-edit-builder-vars-movedfrom-title": "Título de la página original del traslado", - "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "Título completo de la página original del traslado", - "abusefilter-edit-builder-vars-movedfrom-age": "Antigüedad de página origen del traslado (en segundos)", + "abusefilter-edit-builder-vars-movedfrom-id": "ID de la página original a trasladar", + "abusefilter-edit-builder-vars-movedfrom-ns": "Espacio de nombres de la página original a trasladar", + "abusefilter-edit-builder-vars-movedfrom-title": "Título de la página original a trasladar", + "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "Título completo de la página original a trasladar", + "abusefilter-edit-builder-vars-movedfrom-age": "Antigüedad de la página original a trasladar (en segundos)", "abusefilter-edit-builder-vars-movedto-id": "ID de la página de destino del traslado", "abusefilter-edit-builder-vars-movedto-ns": "Espacio de nombres de la página de destino del traslado", "abusefilter-edit-builder-vars-movedto-title": "Título de la página de destino del traslado", @@ -384,20 +427,20 @@ "abusefilter-edit-builder-vars-user-blocked": "Si el usuario esta bloqueado", "abusefilter-edit-builder-vars-user-emailconfirm": "El tiempo que hace que la dirección de correo electrónico fue confirmada", "abusefilter-edit-builder-vars-recent-contributors": "Últimos diez usuarios en contribuir en la página", - "abusefilter-edit-builder-vars-first-contributor": "Primer usuario en contribuir a la página", - "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "Últimos diez usuarios en contribuir en la página origen del traslado", - "abusefilter-edit-builder-vars-movedfrom-first-contributor": "Primeros diez usuarios en contribuir en la página origen del traslado", + "abusefilter-edit-builder-vars-first-contributor": "Primer usuario en contribuir en la página", + "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "Últimos diez usuarios en contribuir en la página original a trasladar", + "abusefilter-edit-builder-vars-movedfrom-first-contributor": "Primeros diez usuarios en contribuir en la página original a trasladar", "abusefilter-edit-builder-vars-movedto-recent-contributors": "Últimos diez usuarios en contribuir en la página destino del traslado", - "abusefilter-edit-builder-vars-movedto-first-contributor": "Últimos diez usuarios en contribuir en la página origen del traslado", - "abusefilter-edit-builder-vars-all-links": "Todos los vínculos externos en el nuevo texto", - "abusefilter-edit-builder-vars-added-links": "Todos los vínculos externos agregados en la edición", - "abusefilter-edit-builder-vars-removed-links": "Todos los vínculos externos eliminados en la edición", - "abusefilter-edit-builder-vars-old-text": "Antiguo wikitexto de la página, antes de la edición (ya no se usa)", - "abusefilter-edit-builder-vars-new-text": "Nuevo wikitexto de la página, después de la edición", - "abusefilter-edit-builder-vars-new-pst": "Nuevo wikitexto de la página, aplicando transformaciones pre-guardado", - "abusefilter-edit-builder-vars-diff-pst": "Diff unificado de cambios por edición, pre-guardado transformado", - "abusefilter-edit-builder-vars-addedlines-pst": "Líneas añadidas en la edición, la edición pre-guardada fue transformada.", - "abusefilter-edit-builder-vars-new-text-stripped": "Nuevo texto de página, libre de cualquier elemento de marcado", + "abusefilter-edit-builder-vars-movedto-first-contributor": "Últimos diez usuarios en contribuir en la página original a trasladar", + "abusefilter-edit-builder-vars-all-links": "Todos los enlaces externos en el nuevo texto", + "abusefilter-edit-builder-vars-added-links": "Todos los enlaces externos agregados en la edición", + "abusefilter-edit-builder-vars-removed-links": "Todos los enlaces externos eliminados en la edición", + "abusefilter-edit-builder-vars-old-wikitext": "Antiguo wikitexto de la página, antes de la edición", + "abusefilter-edit-builder-vars-new-wikitext": "Nuevo wikitexto de la página, después de la edición", + "abusefilter-edit-builder-vars-new-pst": "Nuevo wikitexto de la página, aplicando transformaciones preguardado", + "abusefilter-edit-builder-vars-diff-pst": "Diff unificado de cambios por edición, preguardado transformado", + "abusefilter-edit-builder-vars-addedlines-pst": "Líneas añadidas en la edición, la edición preguardada fue transformada", + "abusefilter-edit-builder-vars-new-text": "Nuevo texto de página, libre de cualquier elemento de marcado", "abusefilter-edit-builder-vars-new-html": "Fuente HTML analizada de la nueva revisión", "abusefilter-edit-builder-vars-restrictions-edit": "Nivel de protección para la edición de la página", "abusefilter-edit-builder-vars-restrictions-move": "Nivel de protección para el traslado de la página", @@ -411,10 +454,10 @@ "abusefilter-edit-builder-vars-movedto-restrictions-move": "Nivel de protección para el traslado de la página destino del traslado", "abusefilter-edit-builder-vars-movedto-restrictions-create": "Nivel de protección para el traslado de la página destino del traslado", "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Nivel de protección para la subida del archivo destino del traslado", - "abusefilter-edit-builder-vars-old-text-stripped": "Texto antiguo de la página, libre de cualquier elemento de marcado", - "abusefilter-edit-builder-vars-old-links": "Vínculos en la página, antes de la edición", + "abusefilter-edit-builder-vars-old-text": "Texto antiguo de la página, libre de cualquier elemento de marcado (ya no se usa)", + "abusefilter-edit-builder-vars-old-links": "Enlaces en la página, antes de la edición", "abusefilter-edit-builder-vars-old-html": "Antiguo wikitexto de la página, analizado en HTML (ya no se usa)", - "abusefilter-edit-builder-vars-minor-edit": "Si la edición ha sido marcada o no como menor", + "abusefilter-edit-builder-vars-minor-edit": "Si la edición ha sido marcada o no como menor (ya no se utiliza)", "abusefilter-edit-builder-vars-file-sha1": "Hash SHA1 del contenido del archivo", "abusefilter-edit-builder-vars-file-size": "Tamaño del archivo en bytes", "abusefilter-edit-builder-vars-file-mime": "Tipo MIME del archivo", @@ -422,6 +465,8 @@ "abusefilter-edit-builder-vars-file-width": "Anchura del archivo en píxeles", "abusefilter-edit-builder-vars-file-height": "Altura del archivo en píxeles", "abusefilter-edit-builder-vars-file-bits-per-channel": "Bits por canal de color del archivo", + "abusefilter-edit-builder-vars-wiki-name": "Nombre del wiki en la base de datos", + "abusefilter-edit-builder-vars-wiki-language": "Código de idioma del wiki", "abusefilter-filter-log": "Cambios recientes de filtros", "abusefilter-history": "Historial de cambios del filtro antiabusos n.º $1", "abusefilter-history-foruser": "Cambios por $1", @@ -440,7 +485,7 @@ "abusefilter-history-filterid": "Filtro", "abusefilter-history-select-legend": "Refinar búsqueda", "abusefilter-history-select-user": "Usuario:", - "abusefilter-history-select-filter": "Identificador del filtro:", + "abusefilter-history-select-filter": "Id. del filtro:", "abusefilter-history-select-submit": "Refinar", "abusefilter-history-diff": "Cambios", "abusefilter-history-error-hidden": "El filtro que has solicitado está oculto y no puedes ver su historial.", @@ -450,18 +495,21 @@ "abusefilter-exception-unexpectedtoken": "Token «$3» inesperado (de tipo $2) en el carácter $1.", "abusefilter-exception-unclosedstring": "Cadena no cerrada empezando en el carácter $1", "abusefilter-exception-invalidoperator": "Operador no válido «$2» en el carácter $1.", - "abusefilter-exception-unrecognisedtoken": "Token \"$2\" no reconocido en el carácter $1.", - "abusefilter-exception-noparams": "No se proporcionó ningún parámetro a la función «$2» en el carácter $1.\nSe {{PLURAL:$3|esperaba $3 argumento|esperaban $3 argumentos}}.", - "abusefilter-exception-dividebyzero": "Intento ilegal de dividir $2 entre cero en carácter $1.", + "abusefilter-exception-unrecognisedtoken": "Token «$2» no reconocido en el carácter $1.", + "abusefilter-exception-noparams": "No se proporcionó ningún parámetro en la función «$2» en el carácter $1.\nSe {{PLURAL:$3|esperaba $3 argumento|esperaban $3 argumentos}}.", + "abusefilter-exception-dividebyzero": "Intento ilegal de dividir $2 entre cero en el carácter $1.", "abusefilter-exception-unrecognisedvar": "Variable no reconocida $2 en el carácter $1", "abusefilter-exception-notenoughargs": "No se han proporcionado todos los argumentos necesarios a la función $2, que fue llamada en el carácter $1.\nSe {{PLURAL:$3|esperaba|esperaban}} $3 {{PLURAL:$3|argumento|argumentos}} y se {{PLURAL:$4|ha|han}} proporcionado $4.", - "abusefilter-exception-regexfailure": "Error en la expresión regular «$3» en el carácter $1: «$2»", - "abusefilter-exception-overridebuiltin": "Anulación incorrecta de la variable «$2» en el carácter $1.", + "abusefilter-exception-toomanyargs": "Demasiados argumentos para la función $2 llamada en el carácter $1.\nSe espera como máximo $3 {{PLURAL:$3|argumento|argumentos}}, se {{PLURAL:$4|proporcionó|proporcionaron}} $4", + "abusefilter-exception-regexfailure": "Error en la expresión regular «$2» en el carácter $1.", + "abusefilter-exception-overridebuiltin": "Anulación incorrecta del identificador incorporado «$2» en el carácter $1.", "abusefilter-exception-outofbounds": "Solicitando un elemento inexistente $2 en la matriz (tamaño de la matriz = $3) en el carácter $1.", + "abusefilter-exception-negativeindex": "No se permite el uso de índices negativos en los arrays. Hay un índice \"$2\" en el carácter $1.", "abusefilter-exception-notarray": "Solicitando un objeto de matriz en un objeto que no es una matriz, en el carácter $1.", "abusefilter-exception-unclosedcomment": "Comentario sin cerrar en el carácter $1.", "abusefilter-exception-invalidiprange": "Se proporcionó un intervalo de IP no válido, «$2», en el carácter $1.", - "abusefilter-exception-disabledvar": "La variable $2 en el carácter $1 no se encuentra en uso.", + "abusefilter-exception-disabledvar": "Ya no se utiliza la variable $2 en el carácter $1.", + "abusefilter-exception-variablevariable": "set y set_var esperan que el primer argumento sea un literal de cadena, que se encuentra en el carácter $1.", "abusefilter-action-tag": "Etiquetar", "abusefilter-action-throttle": "Limitar", "abusefilter-action-warn": "Advertir", @@ -473,7 +521,7 @@ "abusefilter-revert-title": "Revertir todos los cambios hechos por el filtro $1", "abusefilter-revert-intro": "Este formulario permite revertir todos los cambios hechos por el filtro antiabusos debido al filtro $1.\nPor favor ten cuidado al usar esta herramienta.", "abusefilter-revert-preview-item": "$1: $2 {{GENDER:$7|hizo}} un $3 en $4.\nAcciones a revertir: $5 ($6)", - "abusefilter-revert-search-legend": "Seleccionar acciones del filtro antiabusos a ser revertidas", + "abusefilter-revert-search-legend": "Seleccionar acciones del filtro antiabusos a revertir", "abusefilter-revert-periodstart": "Comienzo de periodo:", "abusefilter-revert-periodend": "Fin de periodo:", "abusefilter-revert-search": "Seleccionar acciones", @@ -485,7 +533,7 @@ "abusefilter-revert-reason": "Reversión automática de todas las acciones tomadas por el filtro antiabusos debido al filtro $1.\nRazón dada: $2", "abusefilter-revert-reasonfield": "Motivo:", "abusefilter-test": "Probar un filtro contra ediciones previas", - "abusefilter-test-intro": "Esta página te permite verificar un filtro introducido en la tabla de abajo contra {{PLURAL:$1|el último cambio|los últimos $1 cambios}}.\nPara cargar un filtro existente, escribe el ID del filtro dentro de la tabla debajo del texto de tabla, y pulsa en el botón «{{int:abusefilter-test-load}}».", + "abusefilter-test-intro": "Esta página te permite verificar un filtro introducido en el cuadro de abajo contra {{PLURAL:$1|el último cambio|los últimos $1 cambios}}.\nPara cargar un filtro existente, escribe el Id. del filtro en el cuadro debajo del cuadro de texto de edición y haga clic en «{{int:abusefilter-test-load}}».", "abusefilter-test-legend": "Prueba de filtro", "abusefilter-test-load-filter": "Cargar id. de filtro:", "abusefilter-test-submit": "Prueba", @@ -494,9 +542,9 @@ "abusefilter-test-nobots": "Ocultar ediciones de robots", "abusefilter-test-period-start": "Cambios hechos después:", "abusefilter-test-period-end": "Cambios hechos antes:", - "abusefilter-test-page": "Cambios hechos a la página:", + "abusefilter-test-page": "Cambios hechos en la página:", "abusefilter-test-shownegative": "Mostrar cambios que no coincidan con el filtro", - "abusefilter-test-syntaxerr": "El filtro que has ingresado contiene un error de sintaxis.\nPuedes recibir una explicación completa haciendo clic en el botón \"{{int:abusefilter-edit-check}}\".", + "abusefilter-test-syntaxerr": "El filtro que has introducido contiene un error de sintaxis.\nPuedes recibir una explicación completa haciendo clic en \"{{int:abusefilter-edit-check}}\".", "abusefilter-test-badtitle": "El título de página introducido no era válido. Puede contener uno o más caracteres que no se pueden utilizar en títulos.", "abusefilter-test-action": "Tipo de acción:", "abusefilter-test-search-type-all": "Todas las acciones", @@ -513,46 +561,48 @@ "abusefilter-examine-user": "Usuario:", "abusefilter-examine-title": "Título de página:", "abusefilter-examine-submit": "Buscar", - "abusefilter-examine-vars": "Variables generadas para este cambio", + "abusefilter-examine-vars": "Variables generadas por este cambio", "abusefilter-examine-test": "Probar este cambio contra un filtro", "abusefilter-examine-test-button": "Probar filtro", - "abusefilter-examine-match": "El filtro coincidió con este cambio.", - "abusefilter-examine-nomatch": "El filtro no coincidió con este cambio.", - "abusefilter-examine-syntaxerror": "El filtro tiene una sintaxis no válida", + "abusefilter-examine-match": "El filtro coincide con este cambio.", + "abusefilter-examine-nomatch": "El filtro no coincide con este cambio.", + "abusefilter-examine-syntaxerror": "El filtro no tiene una sintaxis válida", "abusefilter-examine-notfound": "El cambio que has solicitado no ha podido ser encontrado.", "abusefilter-examine-incompatible": "El cambio solicitado no es compatible con el filtro antiabusos", "abusefilter-examine-noresults": "No se ha encontrado ningún resultado para los parámetros de búsqueda que has proporcionado.", "abusefilter-topnav": "'''Barra de navegación del filtro antiabusos'''", "abusefilter-topnav-home": "Inicio", + "abusefilter-topnav-recentchanges": "Cambios recientes de filtros", "abusefilter-topnav-test": "Prueba de filtros", "abusefilter-topnav-examine": "Examinar ediciones pasadas", "abusefilter-topnav-log": "Registro de abusos", - "abusefilter-topnav-tools": "Herramientas de reparación", - "abusefilter-topnav-import": "Importar filtro", + "abusefilter-topnav-tools": "Herramientas de depuración", "abusefilter-log-name": "Registro del filtro antiabusos", - "abusefilter-log-header": "Este registro muestra un resumen de cambios hechos a los filtros.\nPara detalles completos, ver [[Special:AbuseFilter/history|la lista]] de cambios recientes de filtros.", - "abusefilter-logentry-create": "$1 {{GENDER:$2|creó}} $4 ($5)", + "abusefilter-log-header": "Este registro muestra un resumen de los cambios realizados en los filtros.\nPara más detalles, ver [[Special:AbuseFilter/history|la lista]] de cambios recientes de filtros.", + "abusefilter-logentry-create": "$1 {{GENDER:$2|creó}} el $4 ($5)", "abusefilter-logentry-modify": "$1 {{GENDER:$2|modificó}} el $4 ($5)", + "abusefilter-log-invalid-filter": "Algunos de los identificadores de filtro especificados no son válidos.", "abusefilter-log-noresults": "No hay resultados", "abusefilter-diff-title": "Diferencias entre versiones", "abusefilter-diff-item": "Elemento", "abusefilter-diff-version": "Versión desde $1 {{GENDER:$3|por}} $2", "abusefilter-diff-info": "Información básica", "abusefilter-diff-pattern": "Condiciones de filtro", - "abusefilter-diff-invalid": "Incapaz de traer la versiones solicitadas", + "abusefilter-diff-invalid": "No se pueden recuperar las versiones solicitadas", "abusefilter-diff-backhistory": "Regresar al historial del filtro", "abusefilter-diff-prev": "Cambio anterior", "abusefilter-diff-next": "Cambio siguiente", - "abusefilter-import-intro": "Puedes usar esta interfaz para importar filtros de otros wikis.\nEn el wiki fuente, pulsa en «{{int:abusefilter-edit-export}}» bajo «{{int:abusefilter-edit-tools}}» en la interfaz de edición.\nCopia desde el cuadro de texto que aparece, y pégalo dentro de este cuadro de texto, luego pulsa en «{{int:abusefilter-import-submit}}».", + "abusefilter-import-intro": "Puedes usar esta interfaz para importar filtros de otros wikis.\nEn el wiki original, pulsa en «{{int:abusefilter-edit-export}}» bajo «{{int:abusefilter-edit-tools}}» en la interfaz de edición.\nCopia desde el cuadro de texto que aparece y pégalo dentro de este cuadro de texto, luego clic en «{{int:abusefilter-import-submit}}».", "abusefilter-import-submit": "Importar datos", + "abusefilter-import-invalid-data": "Los datos que se intentaron importar no son válidos", "abusefilter-group-default": "Predeterminado", "abusefilter-http-error": "Se produjo un error de HTTP: $1.", - "abusefilter-view-private-submit": "Ver detalles privados", - "abusefilter-view-private": "Ver detalles privados", - "abusefilter-view-private-reason": "Razón para acceder a los detalles privados:", - "abusefilter-log-details-id": "Identificador del registro", - "abusefilter-invalid-request": "Solicitud inválida. Debes acceder a los detalles privados del registro a través del formulario en [[Special:AbuseLog/$1]] y consignar una razón para ello.", - "abusefilter-invalid-request-noid": "Solicitud inválida. Debes acceder a los detalles privados del registro a través del formulario en el registro del filtro antiabusos y consignar una razón.", + "abusefilter-view-privatedetails-submit": "Ver detalles privados", + "abusefilter-view-privatedetails-legend": "Ver detalles privados", + "abusefilter-view-privatedetails-reason": "Razón para acceder a los detalles privados:", + "abusefilter-log-details-id": "Id. del registro", + "abusefilter-invalid-request": "¡Solicitud no válida! Debes acceder a los detalles privados del registro a través del formulario en [[Special:AbuseLog/$1]] y consignar una razón para ello.", + "abusefilter-invalid-request-noid": "¡Solicitud no válida! Debes acceder a los detalles privados del registro a través del formulario en el registro del filtro antiabusos y proporcionar una razón.", "log-description-abusefilterprivatedetails": "Este registro muestra un listado de ocasiones en el que un usuario accedió a los datos privados de un registro del filtro antiabusos.", "abusefilter-noreason": "Aviso: Para ver los datos privados del registro debes proporcionar una razón.", "abusefilter-log-ip-not-available": "No disponible", diff --git a/AbuseFilter/i18n/et.json b/AbuseFilter/i18n/et.json index 63e12125..49fe25b2 100644 --- a/AbuseFilter/i18n/et.json +++ b/AbuseFilter/i18n/et.json @@ -2,17 +2,17 @@ "@metadata": { "authors": [ "Avjoska", + "Cumbril", + "Matma Rex", "Morel", "Oop", - "Pikne", - "Matma Rex", - "Cumbril" + "Pikne" ] }, "abusefilter-desc": "Rakendab muudatuste juures automaatset heuristikat.", - "abusefilter": "Väärtarvitusfiltri häälestus", - "abuselog": "Väärtarvituslogi", - "abusefilter-intro": "Tere tulemast väärtarvitusfiltri haldamisliidesesse.\nVäärtarvitusfilter on mehhanism, mis rakendab kõigi muudatuste juures automaatset heuristikat.\nLiidesega saab vaadata määratletud filtrite loendit ja filtreid muuta.", + "abusefilter": "Väärtarvitusfiltrite haldamine", + "abuselog": "Väärtarvitusfiltrite logi", + "abusefilter-intro": "Tere tulemast väärtarvitusfiltrite haldamisliidesesse.\nVäärtarvitusfilter on mehhanism, mis rakendab kõigi muudatuste juures automaatset heuristikat.\nLiidesega saab vaadata määratletud filtrite loendit ja filtreid muuta.", "abusefilter-warning": "'''Hoiatus''': See toiming on automaatselt kahjulikuks arvatud.\nEbaasjalikud tegevused pööratakse kiiresti tagasi\nning korduvate ja halvimate muudatuste tagajärjel blokeeritakse su konto või IP-aadress.\nKui arvad selle toimingu asjaliku olevat, võid kinnituseks selle uuesti salvestada.\nSinu toimingule vastanud väärtarvitusfiltri reegli lühikirjeldus: $1", "abusefilter-disallowed": "See toiming on automaatselt kahjulikuks arvatud ja on seetõttu keelatud.\nKui arvad toimingu asjaliku olevat, võta palun teha soovitud muudatuse asjus administraatoriga ühendust.\nSinu toimingule vastanud väärtarvitusfiltri reegli lühikirjeldus: $1", "abusefilter-blocked-display": "See toiming on automaatselt kahjulikuks arvatud\nja sul ei lastud seda sooritada.\nKaitsmaks {{GRAMMAR:partitive|{{SITENAME}}}} on lisaks sellele sinu konto ja kõikide seostuvate IP-aadresside redigeerimisõigus blokeeritud.\nKui tegu on eksitusega, võta palun ühendust administraatoriga.\nSinu toimingule vastanud väärtarvitusfiltri reegli lühikirjeldus: $1", @@ -22,34 +22,39 @@ "abusefilter-blockreason": "Väärtarvitusfilter blokeeris su automaatselt.\nVastava reegli kirjeldus: $1", "abusefilter-degroupreason": "Väärtarvitusfilter eemaldas automaatselt su kasutajaõigused.\nReegli kirjeldus: $1", "abusefilter-accountreserved": "Seda kasutajanime hoitakse väärtarvitusfiltrile.", - "right-abusefilter-modify": "Muuta väärtarvitusfiltreid", + "right-abusefilter-modify": "Koostada või muuta väärtarvitusfiltreid", "right-abusefilter-view": "Vaadata väärtarvitusfiltreid", "right-abusefilter-log": "Vaadata väärtarvituslogi", "right-abusefilter-log-detail": "Vaadata väärtarvituslogi üksikasjalikke sissekandeid", - "right-abusefilter-private": "Vaadata väärtarvituslogis isiklikke andmeid", - "right-abusefilter-private-log": "Vaadata väärtarvitusfiltri isiklike üksikasjade juurdepääsu logi", + "right-abusefilter-privatedetails": "Vaadata väärtarvituslogis isiklikke andmeid", + "right-abusefilter-privatedetails-log": "Vaadata väärtarvitusfiltrite isiklike üksikasjade juurdepääsu logi", "right-abusefilter-modify-restricted": "Muuta piirangutega toimingute abil väärtarvitusfiltreid", "right-abusefilter-revert": "Tühistada kõik kindla väärtarvitusfiltri tehtud muudatused", "right-abusefilter-view-private": "Vaadata kinniseks märgitud väärtarvitusfiltreid", "right-abusefilter-log-private": "Vaadata kinniseks märgitud väärtarvitusfiltrite sissekandeid", - "right-abusefilter-hide-log": "Peita väärtarvitusfiltri logisissekandeid", - "right-abusefilter-hidden-log": "Vaadata peidetud väärtarvitusfiltri logisissekandeid", - "right-abusefilter-modify-global": "Luua või muuta globaalseid filtreid", + "right-abusefilter-hide-log": "Peita sissekandeid väärtarvituslogis", + "right-abusefilter-hidden-log": "Vaadata väärtarvituslogi peidetud sissekandeid", + "right-abusefilter-modify-global": "Koostada või muuta globaalseid filtreid", "action-abusefilter-modify": "muuta väärtarvitusfiltreid", "action-abusefilter-view": "vaadata väärtarvitusfiltreid", "action-abusefilter-log": "vaadata väärtarvituslogi", "action-abusefilter-log-detail": "vaadata väärtarvituslogi üksikasjalikke sissekandeid", - "action-abusefilter-private": "vaadata väärtarvituslogis isiklikke andmeid", - "action-abusefilter-private-log": "vaadata väärtarvitusfiltri isiklike üksikasjade juurdepääsu logi", + "action-abusefilter-privatedetails": "vaadata väärtarvituslogis isiklikke andmeid", + "action-abusefilter-privatedetails-log": "vaadata väärtarvitusfiltrite isiklike üksikasjade juurdepääsu logi", "action-abusefilter-modify-restricted": "muuta piirangutega toimingute abil väärtarvitusfiltreid", "action-abusefilter-revert": "tühistada kõiki kindla väärtarvitusfiltri tehtud muudatusi", "action-abusefilter-view-private": "vaadata kinniseks märgitud filtreid", "action-abusefilter-log-private": "vaadata kinniseks märgitud väärtarvitusfiltrite logisid", - "abusefilter-log": "Väärtarvitusfiltri logi", + "action-abusefilter-hide-log": "väärtarvituslogi sissekandeid peita", + "action-abusefilter-hidden-log": "vaadata väärtarvituslogi peidetud sissekandeid", + "action-abusefilter-modify-global": "koostada ega muuta globaalseid väärtarvitusfiltreid", "abusefilter-log-summary": "Selles logis on loetletud tegevused, mille filtrid on tabanud.", "abusefilter-log-search": "Otsimine väärtarvituslogist", "abusefilter-log-search-user": "Kasutaja:", - "abusefilter-log-search-filter": "Filtrite ID-d (eraldatud püstkriipsudega):", + "abusefilter-log-search-group": "Filtrirühm:", + "abusefilter-log-search-group-any": "Mis tahes", + "abusefilter-log-search-filter": "Filtrite ID-d:", + "abusefilter-log-search-filter-help": "Eraldatud püstkriipsudega, globaalsed filtrid eesliitega \"$1\".", "abusefilter-log-search-title": "Pealkiri:", "abusefilter-log-search-wiki": "Viki:", "abusefilter-log-search-impact": "Mõju ulatus:", @@ -78,7 +83,7 @@ "abusefilter-log-details-var": "Muutuja", "abusefilter-log-details-val": "Väärtus", "abusefilter-log-details-vars": "Toimingu parameetrid", - "abusefilter-log-details-private": "Isiklikud logiüksikasjad", + "abusefilter-log-details-privatedetails": "Isiklikud logiüksikasjad", "abusefilter-log-details-ip": "Põhjustaja IP-aadress", "abusefilter-log-noactions": "ei midagi", "abusefilter-log-details-diff": "Redigeerimisega tehtud muudatused", @@ -86,10 +91,11 @@ "abusefilter-log-linkoncontribs-text": "Väärtarvituslogi selle {{GENDER:$1|kasutaja}} jaoks", "abusefilter-log-linkonhistory": "vaata väärtarvituslogi", "abusefilter-log-linkonhistory-text": "Vaata väärtarvituslogi selle lehekülje kohta", - "abusefilter-log-hidden": "sissekanne peidetud", + "abusefilter-log-linkonundelete": "vaata väärtarvituslogi", + "abusefilter-log-linkonundelete-text": "Vaata väärtarvituslogi sissekandeid selle lehekülje kohta", "abusefilter-log-hidden-implicit": "(peidetud, sest redaktsioon on kustutatud)", "abusefilter-log-cannot-see-details": "Sul pole õigust näha üksikasju selle sissekande kohta.", - "abusefilter-log-cannot-see-private-details": "Sul pole lubatud näha selle sissekande isiklikke üksikasju.", + "abusefilter-log-cannot-see-privatedetails": "Sul pole lubatud näha selle sissekande isiklikke üksikasju.", "abusefilter-log-nonexistent": "Toodud ID-ga sissekanne puudub.", "abusefilter-log-details-hidden": "Sa ei saa selle sissekande üksikasju vaadata, sest see on üldsuse eest peidetud.", "abusefilter-log-private-not-included": "Määratud identifikaatoritest vähemalt üks vastab kinnisele filtrile. Kuna sul pole lubatud vaadata kinniste filtrite andmeid, siis neid filtreid ei otsitud.", @@ -97,14 +103,16 @@ "abusefilter-log-hide-id": "Logisissekande ID:", "abusefilter-log-hide-hidden": "Peida see sissekanne üldsuse eest", "abusefilter-log-hide-reason": "Põhjus:", - "abusefilter-log-hide-forbidden": "Sul pole õigust peita väärtarvitusfiltri logisissekandeid.", + "abusefilter-log-hide-reason-other": "Muu või täiendav põhjus:", + "abusefilter-log-hide-forbidden": "Sul pole õigust peita väärtarvituslogi sissekandeid.", + "abusefilter-log-entry-suppress": "$1 {{GENDER:$2|peitis}} logisissekande $3", + "abusefilter-log-entry-unsuppress": "$1 {{GENDER:$2|tühistas}} logisissekande $3 peitmise", "logentry-abusefilter-hit": "$1 {{GENDER:$2|vallandas}} filtri $4, {{GENDER:$2|sooritades}} leheküljel $3 tegevust \"$5\". Toiming: $6 ($7)", "log-action-filter-abusefilter": "Filtri muudatuse tüüp:", "log-action-filter-abusefilter-create": "Uue filtri koostamine", "log-action-filter-abusefilter-modify": "Filtri muutmine", "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|pöördus}} logisissekande $3 isiklike üksikasjade poole", - "abusefilterprivatedetails-log-name": "Väärtarvitusfiltri isiklike üksikasjade juurdepääsu logi", - "abusefilter-management": "Väärtarvitusfiltri haldamine", + "abusefilterprivatedetails-log-name": "Väärtarvitusfiltrite isiklike üksikasjade juurdepääsu logi", "abusefilter-list": "Kõik filtrid", "abusefilter-list-id": "Filtri ID", "abusefilter-list-status": "Olek", @@ -124,6 +132,7 @@ "abusefilter-disabled": "Keelatud", "abusefilter-hitcount": "$1 {{PLURAL:$1|tabamus|tabamust}}", "abusefilter-new": "Koosta uus filter", + "abusefilter-import-button": "Filtri importimine", "abusefilter-return": "Naase filtri haldamise juurde", "abusefilter-status-global": "Globaalne", "abusefilter-list-options": "Sätted", @@ -148,20 +157,21 @@ "abusefilter-tools-text": "Siin on mõned tööriistad, mis võivad olla väärtarvitusfiltrite koostamise ja veatõrje juures kasulikud.", "abusefilter-tools-expr": "Avaldiste katsetamine", "abusefilter-tools-submitexpr": "Leia väärtus", + "abusefilter-tools-syntax-error": "Selle filtri süntaks on vigane.", "abusefilter-tools-reautoconfirm": "Automaatselt kinnitatud kasutaja ennistamine", "abusefilter-tools-reautoconfirm-user": "Kasutaja:", "abusefilter-tools-reautoconfirm-submit": "Ennista automaatselt kinnitatud kasutaja õigused", "abusefilter-reautoconfirm-none": "Sellelt kasutajalt pole automaatselt kinnitatud kasutaja õiguseid ära võetud.", "abusefilter-reautoconfirm-notallowed": "Sul pole lubatud automaatselt kinnitatud kasutaja õiguseid tagasi anda.", "abusefilter-reautoconfirm-done": "Kontole on automaatselt kinnitatud kasutaja õigused tagasi antud", - "abusefilter-status": "Viimasest {{PLURAL:$1|ühest toimingust|$1 toimingust}} {{PLURAL:$2|üks|$2}} ($3%) on küündinud tingimuste ülemmäärani $4. {{PLURAL:$5|Üks toiming|$5 toimingut}} ($6%) on vastanud ühele praegu töötavale filtrile.", + "abusefilter-status": "Viimasest {{PLURAL:$1|ühest toimingust|$1 toimingust}} {{PLURAL:$2|üks|$2}} ($3%) on küündinud tingimuste ülemmäärani $4. {{PLURAL:$5|Üks toiming|$5 toimingut}} ($6%) on vastanud vähemalt ühele praegu töötavale filtrile.", "abusefilter-edit": "Väärtarvitusfiltri muutmine", "abusefilter-edit-subtitle": "Filtri $1 muutmine", "abusefilter-edit-subtitle-new": "Filtri koostamine", + "abusefilter-edit-token-not-match": "Muudatust ei salvestatud! Palun proovi uuesti.", "abusefilter-edit-oldwarning": "<strong>Muudad selle filtri vana versiooni.\nAllpool toodud arvandmed käivad filtri uusima versiooni kohta.\nKui oma muudatused salvestad, kirjutad üle kõik redigeeritavast redaktsioonist uuemad muudatused. </strong> •\n[[Special:AbuseFilter/history/$2|Naase selle filtri ajaloo juurde]].", "abusefilter-edit-status-label": "Arvandmed:", - "abusefilter-edit-status": "Viimasest {{PLURAL:$1|ühest toimingust|$1 toimingust}} on sellele filtrile vastanud $2 ($3%).", - "abusefilter-edit-status-profile": "Viimasest {{PLURAL:$1|ühest toimingust|$1 toimingust}} on sellele filtrile vastanud $2 ($3%).\nKeskmiselt on selle filtri tööaeg $4 ms ja see kasutab tingimuste ülemmäära {{PLURAL:$5|üht tingimust|$5 tingimust}}.", + "abusefilter-edit-status": "Viimasest {{PLURAL:$1|ühest toimingust|$1 toimingust}} on sellele filtrile vastanud $2 ($3%).\nFiltri keskmine tööaeg on $4 ja see kasutab tingimuste ülemmäärast $5 {{PLURAL:$5|tingimust}}.", "abusefilter-edit-new": "Uus filter", "abusefilter-edit-save": "Salvesta filter", "abusefilter-edit-id": "Filtri ID:", @@ -193,13 +203,18 @@ "abusefilter-edit-throttle-count": "Lubatud toimingute määr:", "abusefilter-edit-throttle-period": "Ajavahemik (sekundites):", "abusefilter-edit-throttle-groups": "Pärssimise rühmitusalus:", - "abusefilter-edit-throttle-ip": "IP-aadress", - "abusefilter-edit-throttle-user": "Kasutajakonto", - "abusefilter-edit-throttle-range": "/16-vahemik", - "abusefilter-edit-throttle-creationdate": "Serveriaeg konto loomisel", - "abusefilter-edit-throttle-editcount": "Redigeerimise arv", - "abusefilter-edit-throttle-site": "Kogu sait", - "abusefilter-edit-throttle-page": "Lehekülg", + "abusefilter-edit-throttle-groups-help": "Vaata $1.", + "abusefilter-edit-throttle-groups-help-text": "dokumentatsiooni saidil mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Eralda komaga (ühendaja AND) ja reavahetustega (ühendaja OR)", + "abusefilter-edit-throttle-placeholder": "Eralda komaga (ühendaja AND) ja lisa ükshaaval (ühendaja OR)", + "abusefilter-throttle-ip": "IP-aadress", + "abusefilter-throttle-user": "kasutajakonto", + "abusefilter-throttle-range": "/16-vahemik", + "abusefilter-throttle-creationdate": "konto loomise kuupäev", + "abusefilter-throttle-editcount": "redigeerimise arv", + "abusefilter-throttle-site": "kogu sait", + "abusefilter-throttle-page": "lehekülg", + "abusefilter-throttle-details": "Luba {{PLURAL:$1|üks toiming|$1 toimingut}} {{PLURAL:$2|igas sekundis|$1 sekundi jooksul}}; pärssimise rühmitusalused: $3", "abusefilter-edit-warn-message": "Hoiatusena kasutatav süsteemisõnum:", "abusefilter-edit-warn-other": "Muu sõnum", "abusefilter-edit-warn-other-label": "Muu sõnumi lehekülje pealkiri:\n:''(eesliiteta \"MediaWiki\")''", @@ -222,6 +237,8 @@ "abusefilter-edit-done-subtitle": "Filter muudetud", "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Muudatused]], mille tegid [[Special:AbuseFilter/$1|filtrile $3]], on edukalt salvestatud.", "abusefilter-edit-badsyntax": "Määratletud filtris on süntaksiviga.\nParseri väljund oli: <pre>$1</pre>", + "abusefilter-edit-missingfields": "Järgmised väljad on nõutavad ja peavad olema täidetud: $1", + "abusefilter-edit-deleting-enabled": "Aktiivset filtrit ei saa kustutatuks märkida.", "abusefilter-edit-restricted": "Sa ei saa seda filtrit muuta, sest see sisaldab üht või enamat piiratud ligipääsuga toimingut.\nPalu muudatus teha kasutajal, kellel on õigus lisada piiratud ligipääsuga toiminguid.", "abusefilter-edit-viewhistory": "Vaata selle filtri ajalugu", "abusefilter-edit-history": "Ajalugu:", @@ -233,10 +250,18 @@ "abusefilter-edit-export": "Ekspordi see filter teise vikisse", "abusefilter-edit-syntaxok": "Süntaksitõrkeid ei leitud.", "abusefilter-edit-syntaxerr": "Leiti süntaksitõrge: $1", + "abusefilter-edit-warn-leave": "Kui lahkud sellelt leheküljelt, lähevad kõik filtris tehtud muudatused kaotsi.", "abusefilter-edit-bad-tags": "Mõni määratud märgistest on sobimatu.\nMärgised peaks olema lühikesed, nad ei tohi sisaldada erimärke ja neid ei tohi kasutada muu tarkvara. Proovi valida märgisele uus nimi.", - "abusefilter-edit-notallowed": "Sul pole lubatud väärtarvitusfiltreid luua ega muuta.", + "abusefilter-edit-notallowed": "Sul pole lubatud väärtarvitusfiltreid koostada ega muuta.", "abusefilter-edit-notallowed-global": "Sul pole lubatud globaalseid filtreid luua ega muuta.", - "abusefilter-edit-notallowed-global-custom-msg": "Globaalsed filtrid ei toeta kohandatud hoiatussõnumeid.", + "abusefilter-edit-notallowed-global-custom-msg": "Globaalsed filtrid ei toeta kohandatud hoiatus- ega keelamissõnumeid.", + "abusefilter-edit-invalid-warn-message": "Seda hoiatussõnumit ei saa tühjaks jätta.", + "abusefilter-edit-invalid-disallow-message": "Seda keelamissõnumit ei saa tühjaks jätta.", + "abusefilter-edit-invalid-throttlecount": "Pärsitavate toimingute määr peab olema positiivne täisarv.", + "abusefilter-edit-invalid-throttleperiod": "Pärssimise ajavahemiku väärtus peab olema positiivne täisarv.", + "abusefilter-edit-empty-throttlegroups": "Valida tuleb vähemalt üks pärssimise rühmitusalus.", + "abusefilter-edit-duplicated-throttlegroups": "Pärssimise rühmitusalus ei saa olla topelt.", + "abusefilter-edit-invalid-throttlegroups": "Pärssimiseks valitud rühmitusalused pole kehtivad.", "abusefilter-edit-builder-select": "Vali kursori kohale lisatav", "abusefilter-edit-builder-group-op-arithmetic": "Aritmeetilised tehted", "abusefilter-edit-builder-op-arithmetic-addition": "Liitmine (+)", @@ -265,7 +290,8 @@ "abusefilter-edit-builder-misc-contains": "Vasakpoolne sõne sisaldab parempoolset sõne (contains)", "abusefilter-edit-builder-misc-stringlit": "Sõneliteraal (\"\")", "abusefilter-edit-builder-misc-tern": "Kolmendoperaator (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Loogikaavaldis (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Loogikaavaldis (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "Lühike loogikaavaldis (if X then Y end)", "abusefilter-edit-builder-group-funcs": "Funktsioonid", "abusefilter-edit-builder-funcs-length": "Sõne pikkus (length)", "abusefilter-edit-builder-funcs-lcase": "Väiketähesta (lcase)", @@ -336,12 +362,12 @@ "abusefilter-edit-builder-vars-all-links": "Kõik uues tekstis sisalduvad välislingid", "abusefilter-edit-builder-vars-added-links": "Kõik muudatusega lisatud välislingid", "abusefilter-edit-builder-vars-removed-links": "Kõik muudatusega eemaldatud välislingid", - "abusefilter-edit-builder-vars-old-text": "Muudatuse-eelse lehekülje vikitekst (ei ole enam kasutuses)", - "abusefilter-edit-builder-vars-new-text": "Muudatuse-järgse lehekülje vikitekst", + "abusefilter-edit-builder-vars-old-wikitext": "Muudatuse-eelse lehekülje vikitekst", + "abusefilter-edit-builder-vars-new-wikitext": "Muudatuse-järgse lehekülje vikitekst", "abusefilter-edit-builder-vars-new-pst": "Lehekülje uus vikitekst, salvestamiseelne tekst teisendatud", "abusefilter-edit-builder-vars-diff-pst": "Tehtud muudatuste ühenderinevused, salvestamiseelne tekst teisendatud", "abusefilter-edit-builder-vars-addedlines-pst": "Muudatusega lisatud read, salvestamiseelne tekst teisendatud", - "abusefilter-edit-builder-vars-new-text-stripped": "Uus lehekülje tekst igasuguse märgistuseta", + "abusefilter-edit-builder-vars-new-text": "Uus lehekülje tekst igasuguse märgistuseta", "abusefilter-edit-builder-vars-new-html": "Uue redaktsiooni liigendatud HTML-lähtekood", "abusefilter-edit-builder-vars-restrictions-edit": "Lehekülje redigeerimiskaitsetase", "abusefilter-edit-builder-vars-restrictions-move": "Lehekülje teisaldamiskaitsetase", @@ -355,10 +381,10 @@ "abusefilter-edit-builder-vars-movedto-restrictions-move": "Teisaldamise sihtlehekülje teisaldamiskaitse tase", "abusefilter-edit-builder-vars-movedto-restrictions-create": "Teisaldamise sihtlehekülje alustamiskaitse tase", "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Teisaldamise sihtfaili üleslaadimiskaitse tase", - "abusefilter-edit-builder-vars-old-text-stripped": "Vana lehekülje tekst igasuguse märgistuseta", + "abusefilter-edit-builder-vars-old-text": "Vana lehekülje tekst igasuguse märgistuseta (ei ole enam kasutuses)", "abusefilter-edit-builder-vars-old-links": "Muudatuse-eelsel leheküljel olnud lingid", "abusefilter-edit-builder-vars-old-html": "Lehekülje vana HTML-koodiks liigendaud vikitekst (ei ole enam kasutuses)", - "abusefilter-edit-builder-vars-minor-edit": "Kas märgitud pisimuudatuseks?", + "abusefilter-edit-builder-vars-minor-edit": "Kas märgitud pisimuudatuseks (ei ole enam kasutuses)", "abusefilter-edit-builder-vars-file-sha1": "Faili sisu SHA1-räsi", "abusefilter-edit-builder-vars-file-size": "Faili suurus baitides", "abusefilter-edit-builder-vars-file-mime": "Faili MIME tüüp", @@ -366,7 +392,9 @@ "abusefilter-edit-builder-vars-file-width": "Faili laius pikslites", "abusefilter-edit-builder-vars-file-height": "Faili kõrgus pikslites", "abusefilter-edit-builder-vars-file-bits-per-channel": "Bitte faili värvuskanali kohta", - "abusefilter-filter-log": "Viimased filtri muudatused", + "abusefilter-edit-builder-vars-wiki-name": "Viki andmebaasinimi", + "abusefilter-edit-builder-vars-wiki-language": "Viki keelekood", + "abusefilter-filter-log": "Viimased filtrite muudatused", "abusefilter-history": "$1. väärtarvitusfiltri muudatuste ajalugu", "abusefilter-history-foruser": "Kasutaja $1 muudatused", "abusefilter-history-hidden": "Peidetud", @@ -400,7 +428,7 @@ "abusefilter-exception-unrecognisedvar": "Tundmatu muutuja \"$2\" $1. märgi juures", "abusefilter-exception-notenoughargs": "Funktsiooni $2 jaoks ei kutsutud märgi $1 juures piisavalt argumente.\nOodati {{PLURAL:$3|üht|$3}} argumenti, oli aga $4", "abusefilter-exception-regexfailure": "Tõrge regulaaravaldises \"$2\" $1. märgi juures.", - "abusefilter-exception-overridebuiltin": "Sisseehitatud muutuja \"$2\" reeglitevastane ülekirjutus märgi $1 juures.", + "abusefilter-exception-overridebuiltin": "Sisseehitatud identifikaatori \"$2\" reeglitevastane ülekirjutus märgi $1 juures.", "abusefilter-exception-outofbounds": "Päring olematu massiiviüksuse $2 (massiivi suurus: $3) kohta $1. märgi juures.", "abusefilter-action-tag": "Märgista", "abusefilter-action-throttle": "Pärsi", @@ -461,17 +489,18 @@ "abusefilter-examine-notfound": "Soovitud muudatust ei leitud.", "abusefilter-examine-incompatible": "Väärtarvitusfilter ei toeta soovitud muudatust.", "abusefilter-examine-noresults": "Antud parameetritega otsimisele ei leitud vasteid.", - "abusefilter-topnav": "'''Väärtarvitusfiltri navigatsioon'''", + "abusefilter-topnav": "'''Väärtarvitusfiltrite navigatsioon'''", "abusefilter-topnav-home": "Pealeht", + "abusefilter-topnav-recentchanges": "Viimased filtrite muudatused", "abusefilter-topnav-test": "Paki katsetamine", "abusefilter-topnav-examine": "Varasemate muudatuste uurimine", "abusefilter-topnav-log": "Väärtarvituslogi", "abusefilter-topnav-tools": "Veatõrjeriistad", - "abusefilter-topnav-import": "Filtri importimine", - "abusefilter-log-name": "Väärtarvitusfiltri logi", + "abusefilter-log-name": "Väärtarvitusfiltrite logi", "abusefilter-log-header": "Selles logis kuvatakse kokkuvõte filtrite muudatustest.\nÜksikasjad leiad hiljutiste filtrimuudatuste [[Special:AbuseFilter/history|loendist]].", "abusefilter-logentry-create": "$1 {{GENDER:$2|koostas}} $4 ($5)", "abusefilter-logentry-modify": "$1 {{GENDER:$2|muutis}} $4 sätteid ($5)", + "abusefilter-log-invalid-filter": "Osa määratud filtrite identifikaatoritest on vigased.", "abusefilter-log-noresults": "Tulemusi pole", "abusefilter-diff-title": "Erinevused versioonide vahel", "abusefilter-diff-item": "Üksus", @@ -486,11 +515,11 @@ "abusefilter-import-submit": "Impordi andmed", "abusefilter-group-default": "Tavaline", "abusefilter-http-error": "Esines HTTP-tõrge: $1.", - "abusefilter-view-private-submit": "Vaata isiklikke üksikasju", - "abusefilter-view-private": "Isiklike üksikasjade vaatamine", - "abusefilter-view-private-reason": "Põhjus isiklike üksikasjade juurde pääseda:", + "abusefilter-view-privatedetails-submit": "Vaata isiklikke üksikasju", + "abusefilter-view-privatedetails-legend": "Isiklike üksikasjade vaatamine", + "abusefilter-view-privatedetails-reason": "Põhjus isiklike üksikasjade juurde pääseda:", "abusefilter-log-details-id": "Logisissekande ID", - "log-description-abusefilterprivatedetails": "Siin on logitud korrad, mil kasutaja pöördub väärtarvitusfiltri isiklike üksikasjade poole.", + "log-description-abusefilterprivatedetails": "Siin on logitud korrad, mil kasutaja pöördub väärtarvitusfiltrite isiklike üksikasjade poole.", "abusefilter-noreason": "Hoiatus: Selleks et näha selle logi isiklikke üksikasju, pead esitama põhjuse.", "tag-abusefilter-condition-limit": "Tingimuste ülempiir käes", "tag-abusefilter-condition-limit-description": "Redaktsioonid või muud sündmused, mida polnud võimalik kõigi aktiivsete [[Special:AbuseFilter|väärtarvitusfiltritega]] kontrollida ([[mw:Extension:AbuseFilter/Conditions|spikker]])." diff --git a/AbuseFilter/i18n/eu.json b/AbuseFilter/i18n/eu.json index 7478d674..c323649b 100644 --- a/AbuseFilter/i18n/eu.json +++ b/AbuseFilter/i18n/eu.json @@ -3,41 +3,81 @@ "authors": [ "Abel2es", "An13sa", + "Egonichan", + "Isabel.losaneko", + "Joseba", "Joxemai", "Kobazulo", + "Manex", + "Mikel Ibaiba", + "Sator", "Subi", "Theklan", "Unai Fdz. de Betoño", "Xabier Armendaritz", - "පසිඳු කාවින්ද", - "Sator", - "Mikel Ibaiba" + "පසිඳු කාවින්ද" ] }, "abusefilter-desc": "Edizioei heuristika automatikoa aplikatzen die", - "abusefilter": "Gehiegikerien iragazkiaren konfigurazioa", - "abuselog": "Gehiegikerien erregistroa", + "abusefilter": "Gehiegikeria iragazkiaren kudeaketa", + "abuselog": "Gehiegikeria iragazki loga", + "abusefilter-intro": "Ongi etorri gehiegikerien aurkako iragazkia kudeatzeko interfazera. Gehiegikerien aurkako iragazkia software automatizatu bat da, ekintza guztiei heuristika aplikatzen diena. \nInterfaze honek iragazki definituen zerrenda erakusten du, eta iragazkiak aldatzeko aukera ematen du.", + "abusefilter-mustviewprivateoredit": "Segurtasun arrazoiengatik, gehiegizko erabilera iragazkiak ikusteko edo iragazkiak aldatzeko baimena daukaten erabiltzaileek erabili behar dute interfaze hau.", + "abusefilter-warning": "'''Adi:''' Ekintza hau automatikoki kaltegarritzat identifikatu da. Konstruktiboak ez diren ekintzak laster itzularaziko dira lehengo egoerara. Edizio kaltegarriak egiten badituzu, zure kontuari edo IP helbideari blokeoa ezarriko zaio. Ekintza hau konstruktiboa dela uste baduzu, berriz gorde ditzakezu aldaketak, berresteko. Hona hemen zure ekintzarekin abiarazi den gehiegikerien aurkako arauaren azalpen labur bat: $1", + "abusefilter-disallowed": "Ekintza hau automatikoki kaltegarritzat identifikatu da; beraz, ez da onartu. Zure ekintza konstruktiboa zela uste baduzu, jakinaraz iezaiozu administratzaileari ea zer egiten saiatzen ari zinen. Hona hemen zure ekintzarekin abiarazi den gehiegikerien aurkako arauaren azalpen labur bat: $1", "abusefilter-blocker": "Gehiegikeria iragazkia", - "right-abusefilter-modify": "Gehiegikeria iragazkiak aldatu", + "abusefilter-blockreason": "Automatikoki blokeatu du gehiegikerien iragazkiak. Aplikatu den arauaren deskribapena: $1", + "abusefilter-degroupreason": "Abusuen iragazkiak automatikoki ezabatutako eskubideak.\nArauaren deskribapena: $1", + "abusefilter-blockautopromotereason": "Autopromozioa automatikoki atzeratu da abusuen iragazkiaren bidez.\nArauaren deskribapena: $1", + "abusefilter-accountreserved": "Kontu izen hori bere erabilerarako erreserbatuta dago abusuen iragazkien bidez.", + "right-abusefilter-modify": "Abusu-iragazkiak sortu edo aldatu.", "right-abusefilter-view": "Gehiegikeria iragazkiak ikusi", "right-abusefilter-log": "Gehiegikeria loga ikusi", "right-abusefilter-log-detail": "Gehiegikeria log sarrera detailatua ikusi", - "right-abusefilter-private": "Ikusi datu pribatuak gehiegikeria logean", + "right-abusefilter-privatedetails": "Ikusi datu pribatuak gehiegikeria logean", + "right-abusefilter-privatedetails-log": "Ikusi AbuseFilter-en xehetasun pribatuen sarrera-erregistroa", + "right-abusefilter-modify-restricted": "Neurrigabekerizko iragazkiak eraldatu ekintza murriztuekin", + "right-abusefilter-revert": "Aldaketa guztiak desegin emandako abusu-iragazki baten bidez.", + "right-abusefilter-view-private": "Pribatutzat markatuak dauden neurrigabekeriko iragazkiak ikusi", + "right-abusefilter-log-private": "Ikusi modu pribatuan markatutako abusu-iragazkien sarrera-erregistroak.", + "right-abusefilter-hide-log": "Ezkutatu sarrerak abusuen erregistroan", + "right-abusefilter-hidden-log": "Erakutsi ezkutatutako abusuen sarrera-erregistroak.", + "right-abusefilter-modify-global": "Neurrigabekeriko iragazki globalak sortu edo eraldatu", "action-abusefilter-modify": "gehiegikeria iragazkiak aldatu", "action-abusefilter-view": "Gehiegikeria iragazkiak ikusi", "action-abusefilter-log": "Gehiegikeria loga ikusi", "action-abusefilter-log-detail": "Gehiegikeria log sarrera detailatuak ikusi", - "action-abusefilter-private": "Ikusi datu pribatuak gehiegikeria logean", - "abusefilter-log": "Gehiegikeria iragazki loga", + "action-abusefilter-privatedetails": "Ikusi datu pribatuak gehiegikeria logean", + "action-abusefilter-privatedetails-log": "Ikusi AbuseFilter-en xehetasun pribatuen sarrera-erregistroa", + "action-abusefilter-modify-restricted": "Abusu-iragazkiak aldatu ekintza murriztuekin", + "action-abusefilter-revert": "Aldaketa guztiak desegin emandako abusu-iragazki baten bidez.", + "action-abusefilter-view-private": "Erakutsi pribatutzat markatuta dauden abusu iragazkiak", + "action-abusefilter-log-private": "Ikusi pribatutzat markatutako abusu-iragazkien sarrera-erregistroak", + "action-abusefilter-hide-log": "Ezkutatu sarrerak abusuen erregistroan", + "action-abusefilter-hidden-log": "Erakutsi ezkutatutako abusuen sarrera-erregistroak.", + "action-abusefilter-modify-global": "Abusu iragazki globalak sortu edo aldatu", + "abusefilter-log-summary": "Erregistro honek iragazkiek atzemandako ekintza guztien zerrenda erakusten du.", "abusefilter-log-search": "Bilatu gehiegikeria loga", "abusefilter-log-search-user": "Lankide:", - "abusefilter-log-search-filter": "ID iragazkia (barra bertikalekin banatu):", + "abusefilter-log-search-group": "Iragazi taldea:", + "abusefilter-log-search-group-any": "Edozein", + "abusefilter-log-search-filter": "ID iragazkia:", + "abusefilter-log-search-filter-help": "Bereizi hodiekin \"$1\" duen aurrizkia iragazki globaletarako", "abusefilter-log-search-title": "Izenburua:", "abusefilter-log-search-wiki": "Wiki:", + "abusefilter-log-search-impact": "Eragina:", + "abusefilter-log-search-impact-all": "Ekintza guztiak", + "abusefilter-log-search-impact-saved": "Soilik aldaketak gorde", + "abusefilter-log-search-impact-not-saved": "Aldaketak gorde gabe", "abusefilter-log-search-entries-label": "Ikusgarritasuna:", "abusefilter-log-search-entries-all": "Sarrera guztiak", "abusefilter-log-search-entries-hidden": "Ezkutuko sarrerak soilik", "abusefilter-log-search-entries-visible": "Ikusi daitezkeen sarrerak soilik", + "abusefilter-log-search-action-label": "Ekintza abiarazlea:", + "abusefilter-log-search-action-other": "Beste bat", + "abusefilter-log-search-action-any": "Edozein", + "abusefilter-log-search-action-taken-label": "Kontuan hartutako ekintzak:", + "abusefilter-log-search-action-taken-any": "Edozein", "abusefilter-log-search-submit": "Bilatu", "abusefilter-log-detailedentry-global": "$1 iragazi globala", "abusefilter-log-detailedentry-local": "$1 iragazkia", @@ -48,17 +88,43 @@ "abusefilter-log-details-var": "Aldagarria", "abusefilter-log-details-val": "Balioa", "abusefilter-log-details-vars": "Ekintzaren parametroak", - "abusefilter-log-details-private": "Datu pribatuak", + "abusefilter-log-details-privatedetails": "Erregistroko datu pribatuak", "abusefilter-log-details-ip": "IP helbide sortzailea", + "abusefilter-log-details-checkuser": "Erabiltzailea aztertu", "abusefilter-log-noactions": "bat ere ez", "abusefilter-log-details-diff": "Aldaketan egindako aldaketak", "abusefilter-log-linkoncontribs": "gehiegikerien erregistroa", "abusefilter-log-linkoncontribs-text": "{{GENDER:$1|erabiltzaile honentzako}} gehiegikerien erregistroa", - "abusefilter-log-hidden": "(sarrera ezkutatua)", + "abusefilter-log-linkonhistory": "ikusi gehiegikerien erregistroa", + "abusefilter-log-linkonhistory-text": "Orrialde onetarako neurrigabekerizko erregistroak ikusi", + "abusefilter-log-linkonundelete": "Abusu-erregistroa ikusi", + "abusefilter-log-linkonundelete-text": "Orrialde honetarako abusu-erregistroak ikusi", + "abusefilter-log-hidden-implicit": "(ezkutatua, berrikuspena ezabatu delako)", + "abusefilter-log-cannot-see-details": "Ez daukazu sarbide honetako xehetasunak ikusteko baimenik", + "abusefilter-log-cannot-see-privatedetails": "Ez daukazu sarrera honetako xehetasun pribatuak ikusteko baimenik", + "abusefilter-log-nonexistent": "Erregistratutako ID-a ez da existitzen", + "abusefilter-log-details-hidden": "Ezin dituzu sarrera honetako xehetasunak ikusi publikoki ikustea debekatuak daudelako", + "abusefilter-log-details-hidden-implicit": "Ezin dituzu sarrera honetako xehetasunak ikusi, dagokion berrikuspena publikoki ikusi ez dadin ezkutuan dagoelako.", + "abusefilter-log-private-not-included": "Adierazi dituzun irgazkien IDetako bat edo gehiago pribatua da. Iragazki pribatuen xehetasunak ikusteko baimenik ez daukazunez, ezin dituzu iragazki hauek bilatu.", + "abusefilter-log-hide-legend": "Ezkutatu sarrera erregistroa", + "abusefilter-log-hide-id": "Sarrera erregistro IDa:", + "abusefilter-log-hide-hidden": "Ezkutatu sarrera hau publikoki ikusi ez dadin", "abusefilter-log-hide-reason": "Arrazoia:", - "abusefilter-management": "Gehiegikeria iragazkiaren kudeaketa", + "abusefilter-log-hide-reason-other": "Beste arrazoiak/arrazoi gehigarriak", + "abusefilter-log-hide-forbidden": "Ez daukazu neurrigabekerizko erregistroak ezkutatzeko baimenik", + "abusefilter-log-entry-suppress": "$1 {{MOTA:$2|ezkutatu}} $3", + "abusefilter-log-entry-unsuppress": "$1(e)k $3 {{GENDER:$2|bistan jarri du}}", + "log-action-filter-abusefilter": "Iragazki aldaketa mota:", + "log-action-filter-abusefilter-create": "Iragazki berria sortu", + "log-action-filter-abusefilter-modify": "Iragazki aldaketa", + "log-action-filter-suppress-abuselog": "Abusu-erregistroaren ezabatzea", + "log-action-filter-rights-blockautopromote": "Autopromote blokea", + "log-action-filter-rights-restoreautopromote": "Autopromotearen errekuperazioa", + "logentry-abusefilterprivatedetails-access": "$1(e)k $3ko datu pribatuak {{GENDER:$2|atzitu ditu}}", + "abusefilterprivatedetails-log-name": "AbuseFilter-en xehetasun pribatuen sarrera-erregistroa", "abusefilter-list": "Iragazki guztiak", "abusefilter-list-id": "Iragazkiaren IDa", + "abusefilter-list-pattern": "Eredua", "abusefilter-list-status": "Egoera", "abusefilter-list-public": "Deskribapen publikoa", "abusefilter-list-consequences": "Ondorioak", @@ -74,8 +140,10 @@ "abusefilter-enabled": "Gaitua", "abusefilter-deleted": "Ezabatuta", "abusefilter-disabled": "Ezgaitua", + "abusefilter-throttled": "Bizkortu", "abusefilter-hitcount": "{{PLURAL:$1|hit 1|$1 hit}}", "abusefilter-new": "Iragazki berria sortu", + "abusefilter-import-button": "Iragazkia inportatu", "abusefilter-return": "Iragazi kudeatzailera bueltatu", "abusefilter-status-global": "Globala", "abusefilter-list-options": "Aukerak", @@ -87,47 +155,123 @@ "abusefilter-list-options-scope-local": "Arau lokalak soilik", "abusefilter-list-options-scope-global": "Arau globalak soilik", "abusefilter-list-options-scope-all": "Arau lokal eta globalak", + "abusefilter-list-options-further-options": "Aukera gehiago:", "abusefilter-list-options-hidedisabled": "Ezkutatu ezgaitutako iragazkiak", + "abusefilter-list-options-hideprivate": "Ezkutatu iragazki pribatuak", + "abusefilter-list-options-searchfield": "Bilatu araurik gabe:", + "abusefilter-list-options-searchpattern": "Patroi bat gehitu", + "abusefilter-list-options-searchoptions": "Bilaketa modua:", + "abusefilter-list-options-search-like": "Kontsulta arrunta", + "abusefilter-list-options-search-rlike": "Espresio erregularra", + "abusefilter-list-options-search-irlike": "Letra larrien eta xeheen arteko bereizketarik gabeko adierazpen erregularra", + "abusefilter-list-invalid-searchmode": "Bilatzeko modu espezifikoa baliogabea da", + "abusefilter-list-regexerror": "Bilaketan zehar errore bat gertatu da: Espresio erregularraren sintaxi errorea", "abusefilter-list-options-submit": "Eguneratu", + "abusefilter-tools-text": "Hona hemen abusuen iragazkiak formulatu eta arazteko baliagarriak izan daitezkeen zenbait tresna.", "abusefilter-tools-expr": "Espresio frogagailua", "abusefilter-tools-submitexpr": "Ebaluatu", "abusefilter-tools-reautoconfirm": "Berrezarri autokonfirmazio egoera", "abusefilter-tools-reautoconfirm-user": "Lankidea:", "abusefilter-tools-reautoconfirm-submit": "Berriro autokonfirmatu", + "abusefilter-tools-restoreautopromote": "AbuseFilterren tresnen bidez errekuperatutako autosustapena.", + "abusefilter-reautoconfirm-notallowed": "Ez duzu baimenik autobaieztatutako egoera berrezartzeko.", + "abusefilter-reautoconfirm-done": "Kontuaren baieztapen automatikoaren egoera berreskuratu da", "abusefilter-edit": "Gehiegikeria iragazia aldatzen", "abusefilter-edit-subtitle": "$1 iragazkia editatzen", "abusefilter-edit-subtitle-new": "Iragazkiaren sorrera", + "abusefilter-edit-token-not-match": "Editatu duzuna ez da gorde! Mesedez gorde berriro", "abusefilter-edit-status-label": "Estatistikak:", "abusefilter-edit-new": "Iragazki berria", "abusefilter-edit-save": "Iragazkia gorde", "abusefilter-edit-id": "Iragazkiaren identifikazioa (ID):", + "abusefilter-edit-switch-editor": "Editorez aldatu", "abusefilter-edit-description": "Deskribapena:\n:''(publikoki ikusgai)''", + "abusefilter-edit-field-description": "deskribapena", "abusefilter-edit-group": "Iragazi taldea:", "abusefilter-edit-flags": "Markak:", "abusefilter-edit-enabled": "Gaitu iragazki hau", "abusefilter-edit-deleted": "Markatu ezabatua gisa", + "abusefilter-edit-hidden": "Filtro honen zehaztasunak izkutatu publikotik", "abusefilter-edit-global": "Iragazi globala", "abusefilter-edit-rules": "Baldintzak:", + "abusefilter-edit-field-conditions": "baldintzak", "abusefilter-edit-notes": "Oharrak:", "abusefilter-edit-lastmod": "Iragazia azkenekoz aldatua:", "abusefilter-edit-lastmod-text": "$1 $2-(e)n bidez", + "abusefilter-edit-consequences": "Bat egiten dutenean burutu beharreko ekintzak", + "abusefilter-edit-action-warn": "Erabiltzaileari arriskua ohartarazi ondoren ekintza hauek abiarazi", + "abusefilter-edit-action-disallow": "Erabiltzaileak ekintza hori egin dezan saihestu.", + "abusefilter-edit-action-blockautopromote": "Erabiltzailearen baieztapen egoera ezeztatu", + "abusefilter-edit-action-degroup": "Abantailak dituzten taldeetatik erabiltzailea ezabatu", "abusefilter-edit-action-block": "Erabiltzailea eta/edo IP helbidea blokeatu ediziorik egin ez dezan", + "abusefilter-edit-action-blocktalk": "Erabiltzailea eta/edo IP helbidea blokeatu bere elkarrizketa orritik", + "abusefilter-edit-action-throttle": "Aktibatu ekintzak erabiltzaileak abiadura-muga bat gainditzen badu bakarrik", + "abusefilter-edit-action-rangeblock": "Blokeatu erabiltzailearen jatorria den IP barrutia", + "abusefilter-edit-action-tag": "Edizioa etiketatu etorkizuneko berrikuspenetarako", "abusefilter-edit-throttle-count": "Baimendu beharreko ekintza kopurua", - "abusefilter-edit-throttle-period": "Denbora periodoa:", + "abusefilter-edit-throttle-period": "Denbora periodoa (segundoetan):", + "abusefilter-edit-throttle-groups": "Azeleragailua honela multzokatu:", + "abusefilter-edit-throttle-groups-help": "$1 ikusi:", + "abusefilter-edit-throttle-groups-help-text": "mediawiki.org dokumentazioa ikusi", + "abusefilter-edit-throttle-hidden-placeholder": "Zatitu komekin AND -ekin lotzeko, eta lerro-jauziekin OR -ekin lotzeko", + "abusefilter-edit-throttle-placeholder": "Zatitu komekin AND -ekin lotzeko, eta txertatu banan-banan OR -ekin lotzeko", + "abusefilter-throttle-ip": "IP helbidea", + "abusefilter-throttle-user": "Erabiltzaile kontua", + "abusefilter-throttle-range": "/16 tartea", + "abusefilter-throttle-creationdate": "Kontua sortzeko data", + "abusefilter-throttle-editcount": "Kontagailua editatu", + "abusefilter-throttle-site": "webgune osoa", + "abusefilter-throttle-page": "orrialdea", + "abusefilter-throttle-none": "(bat ere ez)", + "abusefilter-edit-warn-message": "Oharpenetan erabiltzeko sistema-mezua:", "abusefilter-edit-warn-other": "Beste mezu bat", + "abusefilter-edit-warn-other-label": "Beste mezuen orrialde-izena:\n:\"(\"MediaWiki:\" aurrizkia gabe)\"", "abusefilter-edit-warn-actions": "Ekintzak:", - "abusefilter-edit-warn-preview": "Hautatutako mezuaren aurrebista erakutsi", + "abusefilter-edit-warn-preview": "Hautatutako mezuaren aurrebista erakutsi/ezkutatu", "abusefilter-edit-warn-edit": "Sortu/Editatu hautatutako mezua", + "abusefilter-edit-disallow-message": "Ukapenetan erabiltzeko sistema-mezua:", + "abusefilter-edit-disallow-other": "Beste mezu bat", + "abusefilter-edit-disallow-other-label": "Beste mezu batzuentzako orrialdearen izena: \"(MediaWiki\" atzizkirik gabe)\"", + "abusefilter-edit-disallow-actions": "Ekintzak:", + "abusefilter-edit-disallow-preview": "Hautatutako mezuaren aurreikuspena erakutsi/ezkutatu", + "abusefilter-edit-disallow-edit": "Sortu/Editatu aukeratutako mezuak", + "abusefilter-edit-tag-placeholder": "Etiketak gehitu (Banan-banan edo koma batez bananduak)", + "abusefilter-edit-tag-hidden-placeholder": "Etiketak gehitu (koma batez bereizita)", + "abusefilter-edit-block-anon-durations": "Erabiltzaile anonimoentzat iraupena blokeatu", + "abusefilter-edit-block-user-durations": "Erregistratutako erabiltzaileentzat iraupena blokeatu", + "abusefilter-block-anon": "Erabiltzaile anonimoak blokeatu", + "abusefilter-block-user": "Erregistratutako erabiltzaileak blokeatu", + "abusefilter-block-talk": "Elkarrizketa orrialdea blokeatu", + "abusefilter-edit-denied": "Agian ezin dituzu iragazki honetako xehetasunak ikusi ikuspegi publikotik ezkutatuta daudelako", "abusefilter-edit-main": "Iragazkiaren parametroak", "abusefilter-edit-done-subtitle": "Iragazia aldatua", + "abusefilter-edit-badsyntax": "Sintaxi errore bat dago zuk zehaztutako iragazkian.\nAnalizatzailearen irteera hau izan da: <pre> $ 1 </pre>", + "abusefilter-edit-missingfields": "Hurrengo eremuak beharrezkoak dira eta bete egin behar dira: $1", + "abusefilter-edit-deleting-enabled": "Ezin duzu iragazki aktibo bat ezabatu gisa markatu.", + "abusefilter-edit-restricted": "Iragazki honek ekintza murrizturen bat dauka eta ezin duzu editatu. Mesedez, eskatu baimena duen erabiltzaile bati aldaketa zure partez egiteko.", "abusefilter-edit-viewhistory": "Iragazki honen historia begiratu", "abusefilter-edit-history": "Historia:", "abusefilter-edit-check": "Egiaztatu sintaxia", + "abusefilter-edit-badfilter": "Zehaztu duzun iragazkia ez da existitzen", + "abusefilter-edit-revert": "Iragazki honek eragindako aldaketak desegin", "abusefilter-edit-tools": "Tresnak:", + "abusefilter-edit-test-link": "Iragazki hau azken aldaketekin probatu", "abusefilter-edit-export": "Esportatu iragazki hau beste wiki batera", "abusefilter-edit-syntaxok": "Ez da sintaxi-errorerik aurkitu", "abusefilter-edit-syntaxerr": "Sintaxi-errorea detektatu da: $1", - "abusefilter-edit-bad-tags": "Emandako etiketaren bat edo gehiago ez da baliogarria. Etiketak laburragoak izan behar dira, ezin dituzte karaktere berezirik eduki, eta beste software batek ezin izan ditu erreserbatu. Saiatu beste tiketa izen batekin", + "abusefilter-edit-warn-leave": "Orrialdea uzten baduzu iragazki honetarako egin dituzun aldaketa guztiak galduko dituzu", + "abusefilter-edit-bad-tags": "Emandako etiketaren bat edo gehiago ez da baliogarria. Etiketak laburragoak izan behar dute, ezin dituzte karaktere berezirik eduki, eta beste software batek ezin izan ditu erreserbatu. Saiatu beste etiketa izen batekin", + "abusefilter-edit-notallowed": "Ez duzu neurrigabekerizko iragazkiak sortzeko edo editatzeko baimenik", + "abusefilter-edit-notallowed-global": "Ez duzu neurrigabekerizko iragazkiak sortzeko edo editatzeko baimenik", + "abusefilter-edit-notallowed-global-custom-msg": "Ohartarazpenen edo baztertzeko mezu pertsonalizatuak ez dira bateragarriak iragazki globalekin", + "abusefilter-edit-invalid-warn-message": "Ohartarazpen-mezua ezin da hutsik utzi.", + "abusefilter-edit-invalid-disallow-message": "Ukapen-mezua ezin da hutsik utzi.", + "abusefilter-edit-invalid-throttlecount": "Azeleragailuaren akzio-zenbaketak zenbaki oso positibo bat izan behar du.", + "abusefilter-edit-invalid-throttleperiod": "Azelerazio aldiak zenbaki oso positibo bat izan behar du.", + "abusefilter-edit-empty-throttlegroups": "Gutxienez azelerazio talde bat hautatu behar da.", + "abusefilter-edit-duplicated-throttlegroups": "Talde azeleratzaileek ezin dute bikoizketarik izan.", + "abusefilter-edit-invalid-throttlegroups": "Zehaztutako azelerazio taldeak ez dira baliozkoak.", + "abusefilter-edit-builder-select": "Hautatu aukera bat kurtsoreari gehitzeko", "abusefilter-edit-builder-group-op-arithmetic": "Eragile aritmetikoak", "abusefilter-edit-builder-op-arithmetic-addition": "Batuketa (+)", "abusefilter-edit-builder-op-arithmetic-subtraction": "Kenketa (-)", @@ -136,8 +280,10 @@ "abusefilter-edit-builder-op-arithmetic-modulo": "Modulua (%)", "abusefilter-edit-builder-op-arithmetic-pow": "Berreketa (**)", "abusefilter-edit-builder-group-op-comparison": "Konparaziozko eragileak", - "abusefilter-edit-builder-op-comparison-equal": "Berdintza (==)", - "abusefilter-edit-builder-op-comparison-notequal": "Desberdintza (!=)", + "abusefilter-edit-builder-op-comparison-equal": "Balio berdina (==)", + "abusefilter-edit-builder-op-comparison-equal-strict": "Balio eta mota berdina (===)", + "abusefilter-edit-builder-op-comparison-notequal": "Balio ezberdina (!=)", + "abusefilter-edit-builder-op-comparison-notequal-strict": "Balio eta mota ezberdina (!==)", "abusefilter-edit-builder-op-comparison-lt": "Txikiago baino (<)", "abusefilter-edit-builder-op-comparison-gt": "Handiago baino (>)", "abusefilter-edit-builder-op-comparison-lte": "Txikiago baino edo berdin (<=)", @@ -147,37 +293,122 @@ "abusefilter-edit-builder-op-bool-and": "Eta (&)", "abusefilter-edit-builder-op-bool-or": "Edo (|)", "abusefilter-edit-builder-group-misc": "Denetarik", + "abusefilter-edit-builder-misc-in": "Karaktere-katearen barruan (in)", + "abusefilter-edit-builder-misc-like": "Bat datozenen patroia (like)", + "abusefilter-edit-builder-misc-rlike": "Bat dator adierazpen erregularrarekin (rlike)", + "abusefilter-edit-builder-misc-irlike": "Bat dator adierazpen erregularrarekin, maiuskulekiko eta minuskulekiko ez sentikorra (irlike)", + "abusefilter-edit-builder-misc-contains": "Ezkerreko karaktere-kateak eskuineko karaktere katea dauka", "abusefilter-edit-builder-misc-stringlit": "Karaktere-kate osoa (\"\")", "abusefilter-edit-builder-misc-tern": "Eragile hirutarra (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Baldintza (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Baldintza (baldin X orduan Y bestela Z amaiera)", + "abusefilter-edit-builder-misc-cond-short": "Baldintza motza (baldin X orduan Y amaiera)", "abusefilter-edit-builder-group-funcs": "Funtzioak", "abusefilter-edit-builder-funcs-length": "Karaktere-katearen luzera (length)", + "abusefilter-edit-builder-funcs-lcase": "Minuskula jartzeko (lcase)", + "abusefilter-edit-builder-funcs-ucase": "Maiuskula jartzeko (ucase)", + "abusefilter-edit-builder-funcs-ccnorm": "Karaktere nahasgarriak normalizatu (ccnorm)", + "abusefilter-edit-builder-funcs-rmdoubles": "Ezabatu karaktere bikoiztuak (rmdoubles)", + "abusefilter-edit-builder-funcs-specialratio": "Karaktere bereziak / Karaktere guztiak (specialratio)", "abusefilter-edit-builder-funcs-norm": "Normalizatu (norm)", + "abusefilter-edit-builder-funcs-count": "Y karaktere-katean agertzen den X karaktere-kate kopurua", + "abusefilter-edit-builder-funcs-rcount": "Y karaktere-katean agertzen den X karaktere-kate kopurua (rcount)", + "abusefilter-edit-builder-funcs-get_matches": "Testu baten barruko adierazpen erregularren bat-etortzeen matrizea, kaptura-talde bakoitzerako (get_matches)", "abusefilter-edit-builder-funcs-rmwhitespace": "Kendu zuriunea (rmwhitespace)", "abusefilter-edit-builder-funcs-rmspecials": "Kendu karaktere bereziak (rmspecials)", "abusefilter-edit-builder-funcs-ip_in_range": "IPa tartearen barruan dago? (ip_in_range)", + "abusefilter-edit-builder-funcs-contains-any": "Hainbat azpikateetarako kateak bilatu OR moduan. (contains_any)", + "abusefilter-edit-builder-funcs-contains-all": "Hainbat azpikateetarako kateak bilatu AND moduan. (contains_all)", + "abusefilter-edit-builder-funcs-equals-to-any": "Egiaztatu emandako argumentu bat (===) argumentu hauetako baten berdina den (equals_to_any)", "abusefilter-edit-builder-funcs-substr": "Azpikatea (substr)", "abusefilter-edit-builder-funcs-strpos": "Azpikatearen kokalekua katean (strpos)", + "abusefilter-edit-builder-funcs-str_replace": "Ordezkatu azpikatea katearekin (str_replace)", "abusefilter-edit-builder-funcs-set_var": "Ezarri aldagaia (set_var)", + "abusefilter-edit-builder-funcs-sanitize": "Normalizatu HTML entitateak unicode karaktereetan (sanitize)", "abusefilter-edit-builder-group-vars": "Aldagaiak", + "abusefilter-edit-builder-vars-accountname": "Kontuaren izena ( eta kontuaren sorkuntza)", + "abusefilter-edit-builder-vars-timestamp": "Unix aldatzeko denbora-marka", + "abusefilter-edit-builder-vars-timestamp-expanded": "Erregistroaren data", "abusefilter-edit-builder-vars-action": "Ekintza", + "abusefilter-edit-builder-vars-addedlines": "Lerroak gehituta edizioan", + "abusefilter-edit-builder-vars-delta": "Tamaina-aldaketa edizioan", + "abusefilter-edit-builder-vars-diff": "Editatzeak egindako aldaketen diferentzia bateratua", "abusefilter-edit-builder-vars-newsize": "Orrialdearen tamaina berria", "abusefilter-edit-builder-vars-oldsize": "Orrialdearen tamaina zaharra", + "abusefilter-edit-builder-vars-old-content-model": "Eduki eredu zaharra", + "abusefilter-edit-builder-vars-new-content-model": "Eduki eredu berria", + "abusefilter-edit-builder-vars-removedlines": "Lerroak ezabatuta edizioan", "abusefilter-edit-builder-vars-summary": "Aldaketaren laburpena edo arrazoia", "abusefilter-edit-builder-vars-page-id": "Orriaren IDa", "abusefilter-edit-builder-vars-page-ns": "Orri izen-tartea", + "abusefilter-edit-builder-vars-page-title": "Orriaren izenburua (izen espaziorik gabe)", "abusefilter-edit-builder-vars-page-prefixedtitle": "Orrialdearen izenburu osoa", + "abusefilter-edit-builder-vars-page-age": "Orrialdearen urtea (segundotan)", + "abusefilter-edit-builder-vars-movedfrom-id": "Mugitzeko iturri-orrialdearen IDa", + "abusefilter-edit-builder-vars-movedfrom-ns": "Mugitzeko iturri-orrialdearen izen-eremua", + "abusefilter-edit-builder-vars-movedfrom-title": "Mugitzeko iturri-orrialdearen izenburua", + "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "Mugitzeko iturri-orrialdearen izenburu osoa", + "abusefilter-edit-builder-vars-movedfrom-age": "Mugitzeko iturri-orrialdearen adina (segundotan)", + "abusefilter-edit-builder-vars-movedto-id": "Mugitzeko helburu-orrialdearen IDa", + "abusefilter-edit-builder-vars-movedto-ns": "Mugitzeko helburu-orrialdearen izen-eremua", + "abusefilter-edit-builder-vars-movedto-title": "Mugitzeko helburu-orrialdearen izenburua", + "abusefilter-edit-builder-vars-movedto-prefixedtitle": "Mugitzeko helburu-orrialdearen izenburu osoa", + "abusefilter-edit-builder-vars-movedto-age": "Mugitzeko helburu-orrialdearen adina (segundotan)", "abusefilter-edit-builder-vars-user-editcount": "Erabiltzailearen edizioen kontagailua", "abusefilter-edit-builder-vars-user-age": "Lankide kontuaren adina", "abusefilter-edit-builder-vars-user-name": "Lankide kontuaren izena", "abusefilter-edit-builder-vars-user-groups": "Lankidearen taldeak (inplizituak barne)", + "abusefilter-edit-builder-vars-user-rights": "Erabiltzaileak dituen eskubideak", + "abusefilter-edit-builder-vars-user-blocked": "Erabiltzailea blokeatua bada", "abusefilter-edit-builder-vars-user-emailconfirm": "E-posta egiaztatu zenetik igarotako denbora", + "abusefilter-edit-builder-vars-recent-contributors": "Orrialde honetan ekarpena egin duten azken hamar erabiltzaileak", + "abusefilter-edit-builder-vars-first-contributor": "Orrialdeari laguntza eman dioten lehen erabiltzaileak", + "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "Iturri-orrialdea mugitzen lagundu duten azken hamar erabiltzaileak", + "abusefilter-edit-builder-vars-movedfrom-first-contributor": "Iturri-orrialdea mugitzen lagundu duten lehen hamar erabiltzaileak", + "abusefilter-edit-builder-vars-movedto-recent-contributors": "Helburu-orrialdea mugitzen lagundu duten azken hamar erabiltzaileak", + "abusefilter-edit-builder-vars-movedto-first-contributor": "Helburu-orrialdea mugitzen lagundu duten lehen hamar erabiltzaileak", + "abusefilter-edit-builder-vars-all-links": "Kanpo esteka guztiak testu berrian", + "abusefilter-edit-builder-vars-added-links": "kanpo-esteka guztiak gehitu dira edizioan", + "abusefilter-edit-builder-vars-removed-links": "Kanpo-esteka guztiak ezbatu dira ediziotik", + "abusefilter-edit-builder-vars-old-wikitext": "wikitext orrialde zaharra, editazioa baino lehen", + "abusefilter-edit-builder-vars-new-wikitext": "Wikitext orrialde berria, edizioa eta gero", + "abusefilter-edit-builder-vars-new-pst": "Wikitext orrialde berria, aurre-gordetzea aldatuta", + "abusefilter-edit-builder-vars-addedlines-pst": "Editatzean gehitutako lerroak, aurre-gordetzea aldatua", + "abusefilter-edit-builder-vars-new-text": "Orrialdeko testu berria, edozein markatze kenduta", + "abusefilter-edit-builder-vars-new-html": "Berrikuspen berriaren HTML iturri aztertua", + "abusefilter-edit-builder-vars-restrictions-edit": "Orrialdearen babes-maila editatu", + "abusefilter-edit-builder-vars-restrictions-move": "Orrialdearen babes-maila mugitu", + "abusefilter-edit-builder-vars-restrictions-create": "Orrialdearen babesa sortu", + "abusefilter-edit-builder-vars-restrictions-upload": "Fitxategiaren babesa igo", + "abusefilter-edit-builder-vars-movedfrom-restrictions-edit": "Mugitzeko iturri-orrialdearen babes-maila editatu", + "abusefilter-edit-builder-vars-movedfrom-restrictions-move": "Mugitzeko iturri-orrialdearen babesa mugitu", + "abusefilter-edit-builder-vars-movedfrom-restrictions-create": "Mugitzeko iturri-orrialdearen babesa sortu", + "abusefilter-edit-builder-vars-movedfrom-restrictions-upload": "Mugitzeko iturri-fitxategiaren babesa igo", + "abusefilter-edit-builder-vars-movedto-restrictions-edit": "Mugitzeko helburu-orrialdearen babes-maila editatu", + "abusefilter-edit-builder-vars-movedto-restrictions-move": "Mugitzeko helburu-orrialdearen babesa mugitu", + "abusefilter-edit-builder-vars-movedto-restrictions-create": "Mugitzeko helburu-orrialdearen babesa sortu", + "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Mugitzeko helburu-fitxategiaren babesa igo", + "abusefilter-edit-builder-vars-old-text": "Aurreko orrialdeko testua, edozein markatze kenduta (jada ez da erabiltzen)", + "abusefilter-edit-builder-vars-old-links": "Estekak orrialdean, edizioa baino lehen", + "abusefilter-edit-builder-vars-old-html": "Aurreko orrialdeko wikitestua, HTML -n analizatua (jada ez da erabiltzen)", + "abusefilter-edit-builder-vars-minor-edit": "Edizioa txikiago gisa markatuta egon ala ez (jada ez da erabiltzen)", + "abusefilter-edit-builder-vars-file-sha1": "SHA1 fitxategiaren edukiaren hash -a", + "abusefilter-edit-builder-vars-file-size": "Fitxategiaren tamaina bytetan", + "abusefilter-edit-builder-vars-file-mime": "MIME fitxategi-mota", + "abusefilter-edit-builder-vars-file-mediatype": "Fitxategiaren multimedia mota", "abusefilter-edit-builder-vars-file-width": "Fitxategiaren zabalera pixeletan", + "abusefilter-edit-builder-vars-file-height": "Fitxategiaren altuera pixeletan", + "abusefilter-edit-builder-vars-file-bits-per-channel": "Fitxategiaren kolore kanaleko bitak", + "abusefilter-edit-builder-vars-wiki-name": "wikiko datu-basearen izena", + "abusefilter-edit-builder-vars-wiki-language": "Wikiko hizkuntzaren kodea", + "abusefilter-filter-log": "Azken iragazki aldaketak", + "abusefilter-history": "Aldatu historia Abusu-Iragazki -rako #$1", + "abusefilter-history-foruser": "$1 aldaketak", "abusefilter-history-hidden": "ezkutatua", "abusefilter-history-enabled": "Gaitua", "abusefilter-history-global": "Globala", "abusefilter-history-timestamp": "Ordua", "abusefilter-history-user": "Erabiltzailea", + "abusefilter-history-public": "Iragazki publikoen deskribapena", "abusefilter-history-flags": "Markak", "abusefilter-history-filter": "Iragazi araua", "abusefilter-history-comments": "Iruzkinak", @@ -185,42 +416,107 @@ "abusefilter-history-backedit": "Iragazi kudeatzailera bueltatu", "abusefilter-history-deleted": "Ezabatua", "abusefilter-history-filterid": "Iragazkia", + "abusefilter-history-select-legend": "Bilaketa zehatza", "abusefilter-history-select-user": "Lankide:", + "abusefilter-history-select-filter": "Iragazkiaren IDa:", + "abusefilter-history-select-submit": "Findu", "abusefilter-history-diff": "Aldaketak", + "abusefilter-history-error-hidden": "Eskatutako iragazkia ezkutuan dago eta ezin duzu bere historia ikusi", + "abusefilter-exception-unexpectedatend": "Ustekabeko $2 $1 karakterean.", + "abusefilter-exception-expectednotfound": "Ustekabeko $2 $1 karakterean, ez da aurkitu ($3 aurkitua $4 beharrean).", + "abusefilter-exception-unrecognisedkeyword": "$1 karakterean errekonozitu gabeko $2 hitz-gakoa.", + "abusefilter-exception-unexpectedtoken": "Ustekabeko \"$3\" tokena ($2 motakoa) $1 karakterean.", + "abusefilter-exception-unclosedstring": "$1 karakterean hasten den itxi gabeko katea.", + "abusefilter-exception-invalidoperator": "$2 operadore baliogabea $1 karakterean", + "abusefilter-exception-unrecognisedtoken": "Errekonozitu gabeko \"$2\" tokena $1 karakterean.", + "abusefilter-exception-dividebyzero": "$2 zeroz zatitzeko legez kanpoko saiakera $1 karakterean.", + "abusefilter-exception-unrecognisedvar": "Errekonozitu gabeko $2 aldagaia $1 karakterean.", + "abusefilter-exception-regexfailure": "Errorea \"$2\" adierazpen erregularreko $1 karakterean.", + "abusefilter-exception-overridebuiltin": "Atxikitutako \"$2\" identifikatzailearen legez kanpoko berridaztea $1 karakterean.", + "abusefilter-exception-negativeindex": "Indize negatiboak ez dira onartzen array -etan. \"$2\" indizea lortu da $1 karakterean.", + "abusefilter-exception-notarray": "Array motako elementu bat eskatu da array motakoa ez den egitura batean, $1 karakterean.", + "abusefilter-exception-unclosedcomment": "Itxi gabeko iruzkina $1 karakterean.", + "abusefilter-exception-invalidiprange": "Baliogabea den \"$2\" IP barrutia $1 karakterean ematen da.", + "abusefilter-exception-disabledvar": "$2 aldagaia $1 karakterean jada ez da erabiltzen.", "abusefilter-action-tag": "Etiketa", + "abusefilter-action-throttle": "Azeleragailua", "abusefilter-action-warn": "Abisatu", + "abusefilter-action-blockautopromote": "Autosustapena desgaitu", "abusefilter-action-block": "Blokeatu", "abusefilter-action-degroup": "Taldeetatik kendu", + "abusefilter-action-rangeblock": "Barruti-blokea", "abusefilter-action-disallow": "Debekatu", + "abusefilter-revert-title": "Desegin aldaketa guztiak $1 iragazkiarekin", + "abusefilter-revert-search-legend": "Desegingo diren abusu-iragazkietako ekintzak hautatu", "abusefilter-revert-periodstart": "Periodoaren hasiera:", "abusefilter-revert-periodend": "Periodoaren amaiera:", "abusefilter-revert-search": "Ekintzak hautatu", - "abusefilter-revert-filter": "Iragazkia:", + "abusefilter-revert-filter": "Iragazkiaren IDa:", + "abusefilter-revert-confirm-legend": "Desegitea baieztatu", "abusefilter-revert-confirm": "Berretsi", "abusefilter-revert-reasonfield": "Arrazoia:", + "abusefilter-test": "Aurreko edizioen aurkako iragazki bat probatu", + "abusefilter-test-legend": "Iragazki probak", + "abusefilter-test-load-filter": "Kargatu iragazkiaren ID:", "abusefilter-test-submit": "Froga", "abusefilter-test-load": "Kargatu", "abusefilter-test-user": "Erabiltzaileak egindako aldaketak:", + "abusefilter-test-nobots": "Ezkutatu bot edizioak", "abusefilter-test-period-start": "Geroago egindako aldaketak:", "abusefilter-test-period-end": "Lehenago egindako aldaketak:", "abusefilter-test-page": "Orriari egindako aldaketak:", + "abusefilter-test-shownegative": "Erakutsi iragazkiarekin bat egiten ez duten aldaketak", + "abusefilter-test-action": "Ekintza mota:", + "abusefilter-test-search-type-all": "Ekintza guztiak", + "abusefilter-test-search-type-edit": "Edizioak", + "abusefilter-test-search-type-move": "Aldaketak", + "abusefilter-test-search-type-delete": "Ezabaketak", + "abusefilter-test-search-type-upload": "Kargatzeak", + "abusefilter-test-search-type-createaccount": "Kontu sorkuntzak", "abusefilter-changeslist-examine": "aztertu", + "abusefilter-examine": "Aztertu banakako aldaketak", "abusefilter-examine-legend": "Aldaketak aukeratu", + "abusefilter-examine-diff": "URL desberdina:", "abusefilter-examine-user": "Lankide:", "abusefilter-examine-title": "Orriaren izenburua:", "abusefilter-examine-submit": "Bilatu", "abusefilter-examine-vars": "Aldaketa honetarako sortutako aldagaiak.", + "abusefilter-examine-test": "Aldaketa hau iragazki baten aurka probatu", + "abusefilter-examine-test-button": "Iragazkia probatu", + "abusefilter-examine-match": "Iragazkiak aldaketa honekin bat egiten du.", + "abusefilter-examine-nomatch": "Iragazkiak ez du aldaketa honekin bat egiten.", + "abusefilter-examine-syntaxerror": "Iragazki honek baliozkoa ez den sintaxia dauka", + "abusefilter-examine-notfound": "Eskatutako aldaketa ezin da aurkitu.", + "abusefilter-examine-incompatible": "Eskatutako aldaketa ez da abusu-iragazkiaren bateragarria", + "abusefilter-examine-noresults": "Ez da emaitzik aurkitu emandako bilaketa parametroetarako.", + "abusefilter-topnav": "\"Abusu-Iragazkiaren nabigazioa\"", "abusefilter-topnav-home": "Hasiera", + "abusefilter-topnav-recentchanges": "Azken iragazki aldaketak", + "abusefilter-topnav-test": "Lotekako proba", "abusefilter-topnav-examine": "Aztertu aurreko aldaketak", + "abusefilter-topnav-log": "Abusuen erregistroa", "abusefilter-topnav-tools": "Arazketarako tresnak", - "abusefilter-topnav-import": "Iragazkia inportatu", + "abusefilter-log-name": "Abusu-iragazkien erregistroa", + "abusefilter-log-invalid-filter": "Zehaztutako iragazkien ID batzuk baliogabeak dira.", "abusefilter-log-noresults": "Emaitzik ez", "abusefilter-diff-title": "Bertsioen arteko aldeak", "abusefilter-diff-item": "Elementua", "abusefilter-diff-info": "Oinarrizko informazioa", + "abusefilter-diff-pattern": "Iragazki baldintzak", + "abusefilter-diff-invalid": "Eskatutako bertsioak ezin dira berreskuratu", + "abusefilter-diff-backhistory": "Iragazki historiara itzuli", "abusefilter-diff-prev": "Aldaketa zaharragoa", "abusefilter-diff-next": "Aldaketa berriagoa", + "abusefilter-import-intro": "Interfaze hau erabil dezakezu beste wikietako iragazkiak inportatzeko. \nWiki iturrian, editatzeko interfazean,\"{{int:abusefilter-edit-tools}}\" azpian klikatu \"{{int:abusefilter-edit-export}}\". \nKopiatu agertzen den testua, eta itsatsi testu-lauki honetan, gero egin klik \"{{int:abusefilter-import-submit}}\"", "abusefilter-import-submit": "Datuak inportatu", + "abusefilter-import-invalid-data": "inportatu nahi dituzun datuak baliogabeak dira", "abusefilter-group-default": "Lehenetsia", - "abusefilter-http-error": "HTTP errorea gertatu da: $1." + "abusefilter-http-error": "HTTP errorea gertatu da: $1.", + "abusefilter-view-privatedetails-submit": "Ikusi zehaztasun pribatuak", + "abusefilter-view-privatedetails-legend": "Ikusi xehetasun pribatuak", + "abusefilter-view-privatedetails-reason": "Xehetasun pribatuak atzitzeko arrazoia:", + "abusefilter-log-details-id": "Erregistroaren IDa", + "abusefilter-noreason": "Abisua: Erregistro honen xehetasun pribatuak ikusteko arrazoi bat eman behar duzu.", + "abusefilter-log-ip-not-available": "Ez dago erabilgarri", + "tag-abusefilter-condition-limit": "Baldintzaren muga gaaindituta" } diff --git a/AbuseFilter/i18n/fa.json b/AbuseFilter/i18n/fa.json index f429b251..26b90133 100644 --- a/AbuseFilter/i18n/fa.json +++ b/AbuseFilter/i18n/fa.json @@ -1,38 +1,46 @@ { "@metadata": { "authors": [ + "Ahmad252", + "Alifakoor", "Alireza", + "Alireza Ivaz", + "Alirezaaa", + "Amir1arch", + "Arian Ar", "Armin1392", "Calak", "Dalba", "Ebraminio", "Erdemaslancan", + "FarsiNevis", + "Fatemi127", "Hooshmand.hasannia", + "Hosseinblue", "Huji", + "Jeeputer", "Ladsgroup", "Leyth", "Mahdiz", + "Matma Rex", + "Mehran", "Mjbmr", "Omidh", "Pouyana", "Reza1615", + "Rtemis", "Sahim", "Wayiran", "ZxxZxxZ", "جواد", - "Rtemis", - "Alirezaaa", - "Mehran", - "Hosseinblue", - "Matma Rex", - "Alifakoor", - "Fatemi127" + "درفش کاویانی" ] }, "abusefilter-desc": "اکتشافات خودکاری را بر روی ویرایشهای انجام میدهد.", - "abusefilter": "پیکربندی پالایهٔ خرابکاری", - "abuselog": "سیاهه خرابکاری", - "abusefilter-intro": "به صفحهٔ مدیریت پالایهٔ خرابکاری خوشآمدید.\nپالایهٔ خرابکاری سازوکاری نرمافزاری برای اعمال اکتشافات خودکار روی تمامی اعمال است.\nاین صفحه تمام پالایههای تعریفشده را فهرست و امکان تغییر آنها را فراهم میکند.", + "abusefilter": "مدیریت پالایهٔ خرابکاری", + "abuselog": "سیاههٔ پالایهٔ خرابکاری", + "abusefilter-intro": "به صفحهٔ مدیریت پالایهٔ خرابکاری خوش آمدید.\n«پالایهٔ خرابکاری» مکانیسمی نرمافزاری برای اِعمال یافتارهای خودکار بر روی همهٔ کنشها است.\nاین صفحه فهرست همهٔ پالایههای تعریفشده را نشان میدهد و امکان تغییر آنها را فراهم میآورد.", + "abusefilter-mustviewprivateoredit": "به دلایل امنیتی، تنها کسانی میتوانند از این رابط استفاده کنند که دسترسی مشاهده یا تغییر پالایههای مخفی را داشته باشند.", "abusefilter-warning": "'''هشدار''': این کار به طور خودکار نادرست تشخیص دادهشدهاست.\nویرایشهای غیرسازنده به سرعت واگردانی خواهند شد،\nو ویرایشهای مخرب یا تکرار ویرایشهای غیرسازنده منجر به بسته شدن حساب یا نشانی آیپی شما خواهد شد.\nاگر مطمئنید که این عمل مفید است، برای تأیید آن باید آن را دوباره ارسال کنید.\nخلاصهای از توضیح قانون جلوگیری از خرابکاری که با کار شما مطابقت دارد چنین است: $1", "abusefilter-disallowed": "این کار به طور خودکار نادرست تشخیص داده شدهاست و بنابراین نامجاز است.\nاگر فکر میکنید که عملتان درست بودهاست لطفاً به یکی از مدیران بگویید که چه میخواهید بکنید.\nخلاصهای از توضیح قانون جلوگیری از خرابکاری که با کار شما مطابقت دارد چنین است: $1", "abusefilter-blocked-display": "این کار به طور خودکار نادرست تشخیص دادهشده است، و شما از اجرای آن منع شدید.\nبه علاوه، برای حفاظت از {{SITENAME}}، حساب شما و آیپیهای مرتبط با آن به طور خودکار بسته شدهاند.\nاگر فکر میکنید اشتباهی شده با یکی از مدیران تماس بگیرید.\nخلاصهای از توضیح قانون جلوگیری از خرابکاری که با کار شما مطابقت دارد چنین است: $1", @@ -41,13 +49,14 @@ "abusefilter-blocker": "پالایهٔ خرابکاری", "abusefilter-blockreason": "به طور خودکار توسط پالایهٔ خرابکاری بسته شد.\nتوضیح قانون مطابقتیافته: $1", "abusefilter-degroupreason": "دسترسی کاربر به طور خودکار توسط پالایهٔ خرابکاری گرفته شد.\nتوضیح قانون: $1", + "abusefilter-blockautopromotereason": "تأییدشدگی خودکار برای این کاربر به تأخیر انداخته شد.\nتوضیح قانون: $1", "abusefilter-accountreserved": "این نام کاربری برای استفاده توسط پالایهٔ خرابکاری کنار گذاشته شدهاست.", - "right-abusefilter-modify": "تغییر پالایهٔ خرابکاری", - "right-abusefilter-view": "مشاهدهٔ پالایه خرابکاری", + "right-abusefilter-modify": "ایجاد یا تغییر پالایههای خرابکاری", + "right-abusefilter-view": "مشاهدهٔ پالایههای خرابکاری", "right-abusefilter-log": "مشاهدهٔ سیاههٔ خرابکاری", "right-abusefilter-log-detail": "مشاهدهٔ سیاههٔ خرابکاری به همراه جزئیات", - "right-abusefilter-private": "مشاهدهٔ اطلاعات خصوصی در سیاههٔ خرابکاری", - "right-abusefilter-private-log": "نمایش جزئیات خصوصی سیاههٔ دسترسی به پالایهٔ سوءاستفاده", + "right-abusefilter-privatedetails": "مشاهدهٔ اطلاعات خصوصی در سیاههٔ خرابکاری", + "right-abusefilter-privatedetails-log": "نمایش جزئیات خصوصی سیاههٔ دسترسی به پالایهٔ سوءاستفاده", "right-abusefilter-modify-restricted": "ویرایش پالایههای خرابکاری دارای اقدامات محدودکننده", "right-abusefilter-revert": "واگردانی تمام تغییرات توسط یک پالایهٔ خرابکاری", "right-abusefilter-view-private": "مشاهدهٔ پالایههای خرابکاری علامت خورده به عنوان خصوصی", @@ -59,17 +68,22 @@ "action-abusefilter-view": "مشاهدهٔ پالایههای خرابکاری", "action-abusefilter-log": "مشاهدهٔ سیاههٔ خرابکاری", "action-abusefilter-log-detail": "مشاهدهٔ سیاههٔ خرابکاری به همراه جزئیات", - "action-abusefilter-private": "مشاهدهٔ اطلاعات خصوصی در سیاههٔ خرابکاری", - "action-abusefilter-private-log": "مشاهده سیاههٔ دسترسی به جزئیات خصوصی سیاههٔ خرابکاری", + "action-abusefilter-privatedetails": "مشاهدهٔ اطلاعات خصوصی در سیاههٔ خرابکاری", + "action-abusefilter-privatedetails-log": "مشاهده سیاههٔ دسترسی به جزئیات خصوصی سیاههٔ خرابکاری", "action-abusefilter-modify-restricted": "ویرایش پالایههای خرابکاری دارای اقدامات محدودکننده", "action-abusefilter-revert": "واگردانی تمام تغییرات توسط یک پالایهٔ خرابکاری", "action-abusefilter-view-private": "مشاهدهٔ پالایههای خرابکاری علامت خورده به عنوان خصوصی", - "action-abusefilter-log-private": "دیدن سیاهههای پالایهٔ خرابکاری که خصوصی هستند", - "abusefilter-log": "سیاههٔ پالایهٔ خرابکاری", + "action-abusefilter-log-private": "دیدن سیاهههای پالایههای خرابکاری که خصوصی هستند", + "action-abusefilter-hide-log": "پنهان کردن موارد در سیاهه خرابکاری", + "action-abusefilter-hidden-log": "دیدن سیاهههای خرابکاری پنهانشده", + "action-abusefilter-modify-global": "ایجاد یا ویرایش پالایههای خرابکاری سراسری", "abusefilter-log-summary": "این سیاهه فهرستی از تمام کارهایی که توسط پالایهها گرفته شده را نشان میدهد.", "abusefilter-log-search": "جستجو در سیاههٔ خرابکاری", "abusefilter-log-search-user": "کاربر:", - "abusefilter-log-search-filter": "شناسهٔ پالایه (با خط عمودی جدا کنید):", + "abusefilter-log-search-group": "گروه پالایه:", + "abusefilter-log-search-group-any": "هر کدام", + "abusefilter-log-search-filter": "شناسه(ها)ی پالایه:", + "abusefilter-log-search-filter-help": "با خط تیره جدا کنید، و برای پالایههای سراسری از پیشوند «$1» استفاده کنید", "abusefilter-log-search-title": "عنوان:", "abusefilter-log-search-wiki": "ویکی:", "abusefilter-log-search-impact": "تأثیر:", @@ -80,6 +94,7 @@ "abusefilter-log-search-entries-all": "تمام ورودیها", "abusefilter-log-search-entries-hidden": "فقط ورودیهای پنهان", "abusefilter-log-search-entries-visible": "فقط ورودیهای آشکار", + "abusefilter-log-search-action-label": "کنش فعالکنندهٔ پالایه:", "abusefilter-log-search-action-other": "سایر", "abusefilter-log-search-action-any": "هر کدام", "abusefilter-log-search-action-taken-label": "اقدام صورتگرفته:", @@ -97,7 +112,7 @@ "abusefilter-log-details-var": "متغیر", "abusefilter-log-details-val": "مقدار", "abusefilter-log-details-vars": "پارامترهای عمل", - "abusefilter-log-details-private": "جزئیات خصوصی سیاهه", + "abusefilter-log-details-privatedetails": "جزئیات خصوصی سیاهه", "abusefilter-log-details-ip": "آدرس آیپی اصلی", "abusefilter-log-details-checkuser": "بازرسی کاربر", "abusefilter-log-noactions": "هیچ", @@ -106,12 +121,14 @@ "abusefilter-log-linkoncontribs-text": "سیاههٔ خرابکاریها برای {{GENDER:$1|این کاربر}}", "abusefilter-log-linkonhistory": "مشاهدهٔ سیاههٔ خرابکاری", "abusefilter-log-linkonhistory-text": "نمایش سیاههٔ خرابکاری این صفحه", - "abusefilter-log-hidden": "(مورد پنهان)", + "abusefilter-log-linkonundelete": "مشاهدهٔ سیاههٔ خرابکاری", + "abusefilter-log-linkonundelete-text": "نمایش سیاههٔ خرابکاری این صفحه", "abusefilter-log-hidden-implicit": "(پنهانشده چون نسخه حذف شده است)", "abusefilter-log-cannot-see-details": "برای مشاهده جزئیات این مورد دسترسی ندارید.", - "abusefilter-log-cannot-see-private-details": "شما اجازهٔ دیدن جزئیات خصوصی این مورد را ندارید.", + "abusefilter-log-cannot-see-privatedetails": "شما اجازهٔ دیدن جزئیات خصوصی این مورد را ندارید.", "abusefilter-log-nonexistent": "ورودیای با شناسهٔ ارائهشده وجود ندارد.", "abusefilter-log-details-hidden": "شما نمیتوانید جزئیات این مورد را ببینید چون از دید عموم مخفی شدهاست.", + "abusefilter-log-details-hidden-implicit": "شما نمیتوانید جزئیات این مورد را ببینید چون از دید عموم مخفی شدهاست.", "abusefilter-log-private-not-included": "یک یا چند مورد از شناسههای پالایهای که انتخاب کردهاید خصوصی هستند. به این دلیل که شما مجاز به دیدن جزئیات پالایههای خصوصی نیستند، این فیلترها جستجو نشدند.", "abusefilter-log-hide-legend": "پنهان کردن مورد در سیاهه", "abusefilter-log-hide-id": "شناسه مورد در سیاهه:", @@ -125,9 +142,13 @@ "log-action-filter-abusefilter": "نوع تغییر پالایه", "log-action-filter-abusefilter-create": "ایجاد پالایهٔ جدید", "log-action-filter-abusefilter-modify": "تغییر پالایه", + "log-action-filter-suppress-abuselog": "فرونشانی سیاهه خرابکاری", + "log-action-filter-rights-blockautopromote": "جلوگیری از تأییدشدگی خودکار", + "log-action-filter-rights-restoreautopromote": "احیای تأییدشدگی خودکار", "logentry-abusefilterprivatedetails-access": "$1 به جزئیات خصوصی $3 {{GENDER:$2|دسترسی یافت}}", + "logentry-rights-blockautopromote": "$1 تأییدشدگی خودکار {{GENDER:$4|$3}} را برای مدت $5 را {{GENDER:$2|به تأخیر انداخت}}", + "logentry-rights-restoreautopromote": "$1 امکان تأییدشدگی خودکار {{GENDER:$4|$3}} را {{GENDER:$2|احیا کرد}}", "abusefilterprivatedetails-log-name": "سیاههٔ دسترسی به جزئیات خصوصی سیاههٔ خرابکاری", - "abusefilter-management": "مدیریت پالایهٔ خرابکاری", "abusefilter-list": "تمام پالایهها", "abusefilter-list-id": "شناسهٔ پالایه", "abusefilter-list-pattern": "\nالگو", @@ -149,6 +170,7 @@ "abusefilter-throttled": "سرعتگیری شده", "abusefilter-hitcount": "$1 مورد پیدا {{PLURAL:$1|شد|شد}}", "abusefilter-new": "ایجاد یک پالایهٔ تازه", + "abusefilter-import-button": "درونریزی پالایه", "abusefilter-return": "بازگشت به مدیریت پالایه", "abusefilter-status-global": "سراسری", "abusefilter-list-options": "تنظیمات", @@ -166,29 +188,30 @@ "abusefilter-list-options-searchfield": "جستجو در قواعد:", "abusefilter-list-options-searchpattern": "افزودن یک الگو", "abusefilter-list-options-searchoptions": "حالت جستجو:", - "abusefilter-list-options-search-like": "پرسمان تخت", + "abusefilter-list-options-search-like": "پرسمان ساده", "abusefilter-list-options-search-rlike": "عبارت باقاعده", "abusefilter-list-options-search-irlike": "عبارت باقاعده حساس به بزرگی و کوچکی حروف", + "abusefilter-list-invalid-searchmode": "حالت جستجوی مشخص شده معتبر نیست.", "abusefilter-list-regexerror": "خطایی در زمان جستجو رخ داد: خطا در ساختار عبارت با قاعده.", - "abusefilter-list-options-submit": "بهروزرسانی", + "abusefilter-list-options-submit": "روزآمدسازی", "abusefilter-tools-text": "اینجا ابزارهایی برای قاعدهمندکردن و اشکالزدایی پالایههای خرابکاری قرار دارند.", "abusefilter-tools-expr": "آزمایشگر عبارت", "abusefilter-tools-submitexpr": "ارزیابی", "abusefilter-tools-reautoconfirm": "بازگرداندن وضعیت تأییدشده", "abusefilter-tools-reautoconfirm-user": "کاربر:", "abusefilter-tools-reautoconfirm-submit": "تأیید دوباره", + "abusefilter-tools-restoreautopromote": "تأییدشدگی خودکار توسط ابزارهای پالایهٔ خرابکاری احیا شد.", "abusefilter-reautoconfirm-none": "کاربر وضعیت تأییدشده {{GENDER:$1|خود}} را از دست ندادهاست.", "abusefilter-reautoconfirm-notallowed": "شما اجازه ندارید حالت تأییدشده را بازگردانید.", "abusefilter-reautoconfirm-done": "وضعیت تأییدشدهٔ حساب بازگردانده شد.", - "abusefilter-status": "از میان $1 {{PLURAL:$1|عمل|عمل}} آخر، $2 مورد ($3٪) به ظرفیت شرایط $4 {{PLURAL:$2|رسید|رسیدند}}، و $5 مورد ($6٪) با یکی از پالایههایی که در حال حاضر فعال است مطابقت {{PLURAL:$5|داشت|داشتند}}.", + "abusefilter-status": "از میان $1 {{PLURAL:$1|عمل}} آخر، $2 مورد ($3٪) به ظرفیت شرایط $4 {{PLURAL:$2|رسید|رسیدند}}، و $5 مورد ($6٪) با دست کم یکی از پالایههایی که در حال حاضر فعال است مطابقت {{PLURAL:$5|داشت|داشتند}}.", "abusefilter-edit": "ویرایش پالایهٔ خرابکاری", "abusefilter-edit-subtitle": "ویرایش پالایهٔ $1", "abusefilter-edit-subtitle-new": "ایجاد پالایه", "abusefilter-edit-token-not-match": "ویرایش قابل ذخیره شدن نیست! لطفا دوباره سعی کنید.", "abusefilter-edit-oldwarning": "<strong>شما مشغول ویرایش کردن بر روی نسخهٔ قدیمی از پالایه هستید.\nآمار نقل شده بر اساس آخرین نسخهٔ پالایه است.\nاگر دکمه ذخیره را بفشارید تمام تغییرات بعد از نسخهای که ویرایش میکنید را رونویسی خواهید کرد.</strong> •\n[[Special:AbuseFilter/history/$2|بازگشت به تاریخچهٔ این پالایه]].", "abusefilter-edit-status-label": "آمار:", - "abusefilter-edit-status": "از بین $1 {{PLURAL:$1|عمل|عمل}} گذشته، این پالایه با $2 مورد ($3٪) مطابقت داشت.", - "abusefilter-edit-status-profile": "از آخرین $1 {{PLURAL:$1|عمل|عمل}}، این پالایه با $2 ($3٪) مطابقت داشت.\nبه طور متوسط این پالایه در مدت $4 میلیثانیه اجرا میشود و $5 شرط از ظرفیت شرایط را مصرف میکند.", + "abusefilter-edit-status": "از میان $1 {{PLURAL:$1|عمل}} آخر، این پالایه با $2 مورد ($3٪) مطابقت داشت.\nبه طور میانگین، زمان اجرای این پالایه $4 میلیثانیه است و $5 {{PLURAL:$5|مورد}} از ظرفیت شرایط را مصرف میکند.", "abusefilter-edit-throttled-warning": "'''هشدار:''' این پالایه به صورت خودکار مضر تشخیص داده شد. به منظور حفظ امنیت، اقدامهای روبهرو اجرا نخواهند شد ($1). لطفاً شرطهای پالایه را بررسی و [[mw:Extension:AbuseFilter/Conditions|بهینهسازی]] کنید تا این محدودیت برداشته شود", "abusefilter-edit-new": "پالایهای تازه", "abusefilter-edit-save": "ذخیرهسازی پالایه", @@ -221,19 +244,26 @@ "abusefilter-edit-throttle-count": "تعداد اقدامات مجاز:", "abusefilter-edit-throttle-period": "تناوب زمانی (به ثانیه):", "abusefilter-edit-throttle-groups": "کنترل گروه توسط:", - "abusefilter-edit-throttle-ip": "نشانی آیپی", - "abusefilter-edit-throttle-user": "حساب کاربری", - "abusefilter-edit-throttle-range": "بازه /16", - "abusefilter-edit-throttle-creationdate": "زمان سرور هنگام ایجاد حساب", - "abusefilter-edit-throttle-editcount": "شمارش ویرایشها", - "abusefilter-edit-throttle-site": "کل وبگاه", - "abusefilter-edit-throttle-page": "صفحه", + "abusefilter-edit-throttle-groups-help": "$1 را ببینید.", + "abusefilter-edit-throttle-groups-help-text": "مستندات در mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "برای ترکیب «این و آن» از کاما، و برای ترکیب «این یا آن» از رفتن به سطر جدید استفاده کنید", + "abusefilter-edit-throttle-placeholder": "برای ترکیب «این و آن» از کاما، و برای ترکیب «این یا آن» از وارد کردن تک تک موارد جدید استفاده کنید", + "abusefilter-throttle-ip": "نشانی آیپی", + "abusefilter-throttle-user": "حساب کاربری", + "abusefilter-throttle-range": "بازه /۱۶", + "abusefilter-throttle-creationdate": "تاریخ ایجاد حساب کاربری", + "abusefilter-throttle-editcount": "شمارش ویرایشها", + "abusefilter-throttle-site": "همهٔ وبگاه", + "abusefilter-throttle-page": "صفحه", + "abusefilter-throttle-none": "(هیچ)", + "abusefilter-throttle-details": "اجازهٔ $1 {{PLURAL:$1|عمل}} در هر $2 {{PLURAL:$2|ثانیه}} را بده، و سرعتگیری را بر اساس این گروه انجام بده: $3", "abusefilter-edit-warn-message": "پیغام سامانه برای استفاده در هشدار:", "abusefilter-edit-warn-other": "پیامهای دیگر", - "abusefilter-edit-warn-other-label": "نام صفحهٔ حاوی پیامهای دیگر:\n: ''(بدون پیشوند مدیاویکی)''", + "abusefilter-edit-warn-other-label": "نام صفحهٔ حاوی پیامهای دیگر:\n: ''(بدون پیشوند «مدیاویکی»)''", "abusefilter-edit-warn-actions": "اقدامات:", "abusefilter-edit-warn-preview": "نمایش/نهفتن پیشنمایش پیام انتخابشده", "abusefilter-edit-warn-edit": "ایجاد/ویرایش پیام انتخابشده", + "abusefilter-edit-disallow-message": "پیغام سامانه برای استفاده در خطا:", "abusefilter-edit-disallow-other": "پیامهای دیگر", "abusefilter-edit-disallow-other-label": "نام صفحهٔ حاوی پیامهای دیگر:\n:''(بدون پیشوند مدیاویکی)''", "abusefilter-edit-disallow-actions": "اقدامات:", @@ -252,6 +282,7 @@ "abusefilter-edit-done-subtitle": "پالایه ویرایش شد", "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|تغییرات شما]] در [[Special:AbuseFilter/$1|پالایه $3]] ذخیره شدهاست.", "abusefilter-edit-badsyntax": "یک خطای نحوی در پالایهای که مشخص کردید وجود دارد.\nخروجی تحلیلگر این بود: <pre>$1</pre>", + "abusefilter-edit-missingfields": "این موارد الزامی هستند و باید پر شوند: $1", "abusefilter-edit-deleting-enabled": "امکان حذف یک پالایه فعال وجود ندارد.", "abusefilter-edit-restricted": "شما نمیتوانید این پالایه را ویرایش کنید، چون حاوی یک یا چند اقدام محدودشده است.\nلطفاً به منظور انجام تغییر، از یک کاربر با دسترسی اقدامهای محدودشده درخواست کنید.", "abusefilter-edit-viewhistory": "نمایش تاریخچهٔ این پالایه", @@ -264,10 +295,18 @@ "abusefilter-edit-export": "برونبری این پالایه برای یک ویکی دیگر", "abusefilter-edit-syntaxok": "خطای نحوی پیدا نشد.", "abusefilter-edit-syntaxerr": "خطای نحوی پیدا شد: $1", + "abusefilter-edit-warn-leave": "ترک کردن صفحه باعث میشود که تغییراتی که در این پالایه دادید از دست برود", "abusefilter-edit-bad-tags": "یک یا چند برچسب که شما مشخص کردید معتبر نیستند.\nبرچسبها بهتر است کوتاه باشند، آنها نباید شامل نویسههای ویژه باشند و همچنین نباید در دیگر نرمافزارها رزرو شده باشند. برچسب دیگری انتخاب کنید.", "abusefilter-edit-notallowed": "شما اجازه ندارید که پالایههای خرابکاری بسازید یا ویرایش کنید", "abusefilter-edit-notallowed-global": "شما اجازه ندارید که پالایههای خرابکاری سراسری را بسازید یا ویرایش کنید", - "abusefilter-edit-notallowed-global-custom-msg": "پیامهای هشدار سفارشی برای فیلترهای سراسری پشتیبانی نمیشوند", + "abusefilter-edit-notallowed-global-custom-msg": "پیامهای هشدار یا جلوگیری سفارشی برای فیلترهای سراسری پشتیبانی نمیشوند", + "abusefilter-edit-invalid-warn-message": "پیام هشدار نمیتواند خالی باشد.", + "abusefilter-edit-invalid-disallow-message": "پیام جلوگیری نمیتواند خالی باشد.", + "abusefilter-edit-invalid-throttlecount": "شمار اقدامات باید یک عدد صحیح مثبت باشد.", + "abusefilter-edit-invalid-throttleperiod": "تناوب زمانی باید یک عدد صحیح مثبت باشد.", + "abusefilter-edit-empty-throttlegroups": "دست کم یک گروه باید برای سرعتگیری انتخاب بشود.", + "abusefilter-edit-duplicated-throttlegroups": "گروههای سرعتگیری نباید شامل موارد تکراری باشد.", + "abusefilter-edit-invalid-throttlegroups": "گروهی که برای سرعتگیری انتخاب شده نامجاز است.", "abusefilter-edit-builder-select": "گزینهای را انتخاب کنید تا در محل نشانگر اضافه شود", "abusefilter-edit-builder-group-op-arithmetic": "عملگرهای حسابی", "abusefilter-edit-builder-op-arithmetic-addition": "افزودن (+)", @@ -317,11 +356,13 @@ "abusefilter-edit-builder-funcs-ip_in_range": "آیا آیپی در این محدوده است؟ (ip_in_range)", "abusefilter-edit-builder-funcs-contains-any": "جستجوی رشته برای چند زیررشته با استفاده از شرط «یا» (contains_any)", "abusefilter-edit-builder-funcs-contains-all": "جستجوی رشته برای چند زیررشته با استفاده از شرط «و» (contains_any)", + "abusefilter-edit-builder-funcs-equals-to-any": "بررسی این که مقدار یک پارامتر با دست کم یکی از پارامترهای بعدی برابر (===) است (equals_to_any)", "abusefilter-edit-builder-funcs-substr": "زیررشته (substr)", "abusefilter-edit-builder-funcs-strpos": "موقعیت زیررشته در رشته (strpos)", "abusefilter-edit-builder-funcs-str_replace": "جایگزینی زیررشته با رشته (str_replace)", "abusefilter-edit-builder-funcs-rescape": "گریز تحتالفظی متن به صورت یک عبارت باقاعده (rescape)", "abusefilter-edit-builder-funcs-set_var": "نشاندن متغیر (set_var)", + "abusefilter-edit-builder-funcs-sanitize": "قاعدهمندسازی موجودیتهای اچتیامال به نویسههای یونیکد (sanitize)", "abusefilter-edit-builder-group-vars": "متغیرها", "abusefilter-edit-builder-vars-accountname": "نام کاربری (در زمان ایجاد حساب کاربری)", "abusefilter-edit-builder-vars-timestamp": "زمان یونیکسی تغییر", @@ -360,15 +401,19 @@ "abusefilter-edit-builder-vars-user-emailconfirm": "نشانی ایمیل زمان تأیید شد", "abusefilter-edit-builder-vars-recent-contributors": "آخرین ده کاربری که در صفحه مشارکت کردهاند", "abusefilter-edit-builder-vars-first-contributor": "اولین کاربری که در صفحه مشارکت کردهاست", + "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "آخرین ده کاربری که در صفحهٔ مبدأ انتقال مشارکت کردهاند", + "abusefilter-edit-builder-vars-movedfrom-first-contributor": "نخستین کاربری که در صفحهٔ مبدأ انتقال مشارکت کردهاست", + "abusefilter-edit-builder-vars-movedto-recent-contributors": "آخرین ده کاربری که در صفحهٔ مقصد انتقال مشارکت کردهاند", + "abusefilter-edit-builder-vars-movedto-first-contributor": "نخستین کاربری که در صفحهٔ مقصد انتقال مشارکت کردهاست", "abusefilter-edit-builder-vars-all-links": "تمام پیوندهای خارجی در متن تازه", "abusefilter-edit-builder-vars-added-links": "تمام پیوندهای خارجی اضافه شده در ویرایش", "abusefilter-edit-builder-vars-removed-links": "تمام پیوندهای خارجی حذف شده در ویرایش", - "abusefilter-edit-builder-vars-old-text": "ویکیمتن قدیمی صفحه، قبل از ویرایش (دیگر استفاده نمیشود)", - "abusefilter-edit-builder-vars-new-text": "ویکیمتن تازه صفحه، بعد از ویرایش", + "abusefilter-edit-builder-vars-old-wikitext": "ویکیمتن قدیمی صفحه، قبل از ویرایش", + "abusefilter-edit-builder-vars-new-wikitext": "ویکیمتن تازه صفحه، بعد از ویرایش", "abusefilter-edit-builder-vars-new-pst": "صفحهٔ تازه ویکیمتن، پیش از ذخیره تغییر یافت", "abusefilter-edit-builder-vars-diff-pst": "یکی کردن تفاوت تغییرات ساخته شده توسط ویرایش، از قبل ذخیره شده تبدیل شده", "abusefilter-edit-builder-vars-addedlines-pst": "خطوط اضافه شده در ویرایش، از قبل ذخیره شده تبدیل شده", - "abusefilter-edit-builder-vars-new-text-stripped": "متن جدید صفحه، بدون نشانهگذاریها", + "abusefilter-edit-builder-vars-new-text": "متن جدید صفحه، بدون نشانهگذاریها", "abusefilter-edit-builder-vars-new-html": "کد اچتیامال تجزیه شده از نسخه جدید", "abusefilter-edit-builder-vars-restrictions-edit": "سطح محافظت صفحه برای ویرایش", "abusefilter-edit-builder-vars-restrictions-move": "سطح محافظت صفحه برای انتقال", @@ -376,10 +421,16 @@ "abusefilter-edit-builder-vars-restrictions-upload": "حفاظت پرونده در برابر بارگذاری", "abusefilter-edit-builder-vars-movedfrom-restrictions-edit": "سطح محافظت صفحه برای صفحه مبدا انتقال", "abusefilter-edit-builder-vars-movedfrom-restrictions-move": "انتقال سطح محافظت صفحه مبدا انتقال", - "abusefilter-edit-builder-vars-old-text-stripped": "متن قبلی صفحه، بدون نشانهگذاریها", + "abusefilter-edit-builder-vars-movedfrom-restrictions-create": "سطح حفاظت صفحهٔ مبدأ انتقال در برابر ایجاد", + "abusefilter-edit-builder-vars-movedfrom-restrictions-upload": "سطح حفاظت پروندهٔ مبدأ انتقال در برابر بارگذاری", + "abusefilter-edit-builder-vars-movedto-restrictions-edit": "سطح حفاظت صفحهٔ مقصد انتقال در برابر ویرایش", + "abusefilter-edit-builder-vars-movedto-restrictions-move": "سطح حفاظت صفحهٔ مقصد انتقال در برابر انتقال", + "abusefilter-edit-builder-vars-movedto-restrictions-create": "سطح حفاظت صفحهٔ مقصد انتقال در برابر ایجاد", + "abusefilter-edit-builder-vars-movedto-restrictions-upload": "سطح حفاظت پروندهٔ مقصد انتقال در برابر بارگذاری", + "abusefilter-edit-builder-vars-old-text": "متن قبلی صفحه، بدون نشانهگذاریها", "abusefilter-edit-builder-vars-old-links": "پیوندهای صفحه، قبل از ویرایش", "abusefilter-edit-builder-vars-old-html": "ویکیمتن قدیمی صفحه، تجزیه شده به اچتیامال (دیگر استفاده نمیشود)", - "abusefilter-edit-builder-vars-minor-edit": "نشانهگذاری شدن ویرایش به عنوان جزئی", + "abusefilter-edit-builder-vars-minor-edit": "نشانهگذاری شدن ویرایش به عنوان جزئی (دیگر استفاده نمیشود)", "abusefilter-edit-builder-vars-file-sha1": "درهمسازی محتویات پرونده با SHA1", "abusefilter-edit-builder-vars-file-size": "اندازهٔ پرونده به بایت", "abusefilter-edit-builder-vars-file-mime": "نوع MIME پرونده", @@ -387,6 +438,8 @@ "abusefilter-edit-builder-vars-file-width": "عرض پرونده به پیکسل", "abusefilter-edit-builder-vars-file-height": "ارتفاع پرونده به پیکسل", "abusefilter-edit-builder-vars-file-bits-per-channel": "تعداد بیت در هر کانال رنگ پرونده", + "abusefilter-edit-builder-vars-wiki-name": "نام دادگان ویکی", + "abusefilter-edit-builder-vars-wiki-language": "کد زبان ویکی", "abusefilter-filter-log": "تغییرات اخیر پالایهها", "abusefilter-history": "تاریخچهٔ تغییرهای پالایهٔ خرابکاری #$1", "abusefilter-history-foruser": "تغییرات توسط $1", @@ -416,14 +469,18 @@ "abusefilter-exception-unclosedstring": "رشتهٔ بستهنشده با شروع از نویسهٔ $1.", "abusefilter-exception-invalidoperator": "عملگر نامعتبر «$2» در نویسهٔ $1.", "abusefilter-exception-unrecognisedtoken": "نشانهٔ ناشناختهٔ «$2» در نویسهٔ $1.", - "abusefilter-exception-noparams": "هیچ پارامتری به تابع «$2» در نویسهٔ $1 داده نشدهاست.", + "abusefilter-exception-noparams": "هیچ پارامتری به تابع «$2» در نویسهٔ $1 داده نشدهاست.\n{{PLURAL:$3|آرگومان|آرگومانهای}} $3 موردانتظار بود.", "abusefilter-exception-dividebyzero": "تلاش غیر مجاز برای تقسیم $2 بر صفر در نویسهٔ $1.", "abusefilter-exception-unrecognisedvar": "متغیر ناشناختهٔ $2 در نویسهٔ $1.", "abusefilter-exception-notenoughargs": "پارامترهای دادهشده به تابع $2 در نویسهٔ $1 کافی نبود.\nانتظار $3 {{PLURAL:$3|پارامتر}} میرفت، $4 پارامتر بهدست آمد", - "abusefilter-exception-regexfailure": "خطا در عبارات باقاعده «$3» در نویسهٔ $1: «$2»", + "abusefilter-exception-toomanyargs": "آرگومانهای بیشازحد به تابع $2 در نویسهٔ $1 داده شدهاست.\nحداکثر $3 آرگومان موردانتظار بود، $4تا دریافت شد.", + "abusefilter-exception-regexfailure": "خطا در عبارت باقاعده «$2» در نویسهٔ $1.", "abusefilter-exception-overridebuiltin": "رونویسی غیر مجاز متغیر توکار «$2» در نویسه $1.", "abusefilter-exception-outofbounds": "درخواست مورد ناموجود $2 از فهرست (اندازهٔ فهرست = $3) در نویسهٔ $1.", "abusefilter-exception-notarray": "درخواست مورد آرایه از غیر آرایه در نویسه $1.", + "abusefilter-exception-unclosedcomment": "نظر بستهنشده در نویسهٔ $1.", + "abusefilter-exception-invalidiprange": "بازهٔ نامعتبر آیپی «$2» در نویسهٔ $1 وارد شده.", + "abusefilter-exception-disabledvar": "متغیر $2 در نویسهٔ $1 دیگر مورداستفاده نیست.", "abusefilter-action-tag": "برچسب", "abusefilter-action-throttle": "محدودیت سرعت", "abusefilter-action-warn": "هشدار", @@ -443,7 +500,7 @@ "abusefilter-revert-preview-intro": "در زیر اقدامات صورت گرفته توسط پالایهٔ خرابکاری آمده است که توسط این اقدام واگرادنی میشود.\nلطفاً با دقت آنها را بررسی کنید، و به منظور تأیید انتخاب، روی «{{int:abusefilter-revert-confirm}}» کلیک نمایید.", "abusefilter-revert-confirm-legend": "تأیید واگردانی", "abusefilter-revert-confirm": "تأیید", - "abusefilter-revert-success": "شما همهٔ اقدامهای صورت گرفته توسط پالایهٔ خرابکاری به دلیل [[Special:AbuseFilter/$1|پالایهٔ $2]] را واگردانی کردهاید.", + "abusefilter-revert-success": "شما همهٔ اقدامهای صورت گرفته توسط پالایهٔ خرابکاری را به دلیل [[Special:AbuseFilter/$1|پالایهٔ $2]] واگردانی کردهاید.", "abusefilter-revert-reason": "واگردانی خودکار همهٔ اقدامهای صورتگرفته توسط پالایهٔ خرابکاری به دلیل پالایهٔ $1.\nعلت دادهشده: $2", "abusefilter-revert-reasonfield": "دلیل:", "abusefilter-test": "آزمودن پالایه در برابر ویرایشهای قبلی", @@ -486,15 +543,16 @@ "abusefilter-examine-noresults": "برای پارامترهای جستجویی که ارائه کردید هیچ نتیجهای یافت نشد.", "abusefilter-topnav": "'''ناوبری پالایهٔ خرابکاری'''", "abusefilter-topnav-home": "خانه", + "abusefilter-topnav-recentchanges": "تغییرات اخیر پالایهها", "abusefilter-topnav-test": "آزمودن دستهای", "abusefilter-topnav-examine": "آزمودن ویرایشهای قبلی", "abusefilter-topnav-log": "سیاههٔ خرابکاری", "abusefilter-topnav-tools": "ابزارهای اشکالزدایی", - "abusefilter-topnav-import": "درونریزی پالایه", "abusefilter-log-name": "سیاههٔ پالایهٔ خرابکاری", "abusefilter-log-header": "این سیاهه خلاصهای از تغییرات پالایهها را نمایش میدهد.\nبرای جزئیات کامل [[Special:AbuseFilter/history|فهرست]] تغییرات اخیر پالایهها را ببینید.", "abusefilter-logentry-create": "$1 $4 را {{GENDER:$2|ایجاد کرد}} ($5)", - "abusefilter-logentry-modify": "$1 {{GENDER:$2|تغییر داد}} $4 ($5)", + "abusefilter-logentry-modify": "$1 $4 را {{GENDER:$2|تغییر داد}} ($5)", + "abusefilter-log-invalid-filter": "برخی از شناسههای مشخصشدهٔ پالایه نامعتبر هستند.", "abusefilter-log-noresults": "بدون نتیجه", "abusefilter-diff-title": "تفاوت بین نسخهها", "abusefilter-diff-item": "مورد", @@ -507,17 +565,19 @@ "abusefilter-diff-next": "تغییر جدیدتر", "abusefilter-import-intro": "شما میتوانید از این رابط برای واردکردن پالایهها از دیگر ویکیها استفاده کنید.\nدر ویکی مبدأ روی «{{int:abusefilter-edit-export}}» زیر «{{int:abusefilter-edit-tools}}» در رابط ویرایشی کلیک کنید.\nاز جعبهٔ متنی که نشان داده میشود کپی کرده و در این جعبهٔ متن بچسبانید، سپس روی «{{int:abusefilter-import-submit}}» کلیک کنید.", "abusefilter-import-submit": "درونریزی اطلاعات", + "abusefilter-import-invalid-data": "دادههایی که شما در تلاش برای درونریزیشان هستید، معتبر نیستند.", "abusefilter-group-default": "پیشفرض", "abusefilter-http-error": "خطای اچتیتیپی رخ داد: $1", - "abusefilter-view-private-submit": "نمایش جزئیات خصوصی", - "abusefilter-view-private": "نمایش جزئیات خصوصی", - "abusefilter-view-private-reason": "دلیل برای دسترسی به جزئیات خصوصی:", + "abusefilter-view-privatedetails-submit": "نمایش جزئیات خصوصی", + "abusefilter-view-privatedetails-legend": "نمایش جزئیات خصوصی", + "abusefilter-view-privatedetails-reason": "دلیل برای دسترسی به جزئیات خصوصی:", "abusefilter-log-details-id": "سیاهه شناسه", "abusefilter-invalid-request": "درخواست غیرمجاز! شما باید جزئیات خصوصی پالایه را از طریق فرمی که در [[Special:AbuseLog/$1]] است درخواست کنید و دلیلی ارائه کنید.", "abusefilter-invalid-request-noid": "درخواست غیرمجاز! شما باید جزئیات خصوصی پالایه را از طریق فرمی که در صفحهٔ جزئیات سیاهه است درخواست کنید و دلیلی ارائه کنید.", "log-description-abusefilterprivatedetails": "این سیاهه فهرستی از مواردی را نشان میدهد که کاربری به جزئیات خصوصی یک سیاهه خرابکاری دسترسی یافتهاست.", "abusefilter-noreason": "هشدار: برای دیدن جزئیات خصوصی این پالایه باید دلیلی ارائه کنید.", "abusefilter-log-ip-not-available": "موجود نیست", + "abusefilter-tag-reserved": "تگ <code>abusefilter-condition-limit</code> برای استفادهٔ داخلی توسط پالایهٔ ویرایش در نظر گرفته شده.", "tag-abusefilter-condition-limit": "محدودیت تعداد شرایط حاصل شد", "tag-abusefilter-condition-limit-description": "ویرایشها یا عملکردهای دیگری که توسط تمام [[Special:AbuseFilter|پالایههای]] فعال بررسی نشدند ([[mw:Extension:AbuseFilter/Conditions|راهنما]])." } diff --git a/AbuseFilter/i18n/fi.json b/AbuseFilter/i18n/fi.json index 061c90a3..d3183ddc 100644 --- a/AbuseFilter/i18n/fi.json +++ b/AbuseFilter/i18n/fi.json @@ -1,32 +1,37 @@ { "@metadata": { "authors": [ + "01miki10", "Cimon Avaro", "Crt", + "Cxz", "Harriv", "Ilaiho", + "Kyykaarme", + "Matma Rex", "Nedergard", "Nike", "Olli", "Pxos", + "Pyscowicz", + "Rueter", "Samoasambia", "Silvonen", "Snidata", "Str4nd", "Stryn", + "Surjection", + "Valtlait", "VezonThunder", "Vililikku", + "Vlad5250", "Zache", - "ZeiP", - "Matma Rex", - "01miki10", - "Pyscowicz", - "Surjection" + "ZeiP" ] }, "abusefilter-desc": "Mahdollistaa muokkauksien suodattamisen automaattisella heuristiikalla.", - "abusefilter": "Väärinkäyttösuodattimen asetukset", - "abuselog": "Väärinkäyttöloki", + "abusefilter": "Väärinkäyttösuodattimen hallinta", + "abuselog": "Väärinkäyttösuodattimen loki", "abusefilter-intro": "Tervetuloa väärinkäyttösuodattimen hallintakäyttöliittymään.\nVäärinkäyttösuodatin (Abuse Filter) on automaattinen ohjelmistomekanismi, joka soveltaa automaattista heuristiikkaa kaikkiin toimintoihin.\nTämä käyttöliittymä näyttää luettelon määritetyistä suodattimista ja antaa mahdollisuuden muuttaa niiden asetuksia.", "abusefilter-mustviewprivateoredit": "Turvallisuussyistä vain käyttäjät, joilla on oikeus nähdä yksityisiä väärinkäyttösuodattimia tai muokata suodattimia, saavat käyttää tätä käyttöliittymää.", "abusefilter-warning": "'''Varoitus''': Tämä toiminto on automaattisesti tunnistettu haitalliseksi.\nEpäasialliset toiminnot kumotaan nopeasti ja törkeä tai toistuva häiriköinti johtaa tunnuksesi tai IP-osoitteesi estämiseen.\nJos tämä toiminto on mielestäsi asiallinen, napsauta Tallenna-painiketta uudelleen.\nLyhyt kuvaus säännöstä, jota sovellettiin: $1", @@ -37,13 +42,13 @@ "abusefilter-blocker": "Väärinkäyttösuodatin", "abusefilter-blockreason": "Automaattisesti estetty väärinkäyttösuodattimella.\nToimintoa vastaavan säännön kuvaus: $1", "abusefilter-degroupreason": "Oikeudet automaattisesti poistettu väärinkäyttösuodattimen toimesta.\nSäännön kuvaus: $1", - "abusefilter-accountreserved": "Tämä käyttäjätunnus on varattu väärinkäyttösuodattimen käyttöön.", - "right-abusefilter-modify": "Muokata väärinkäyttösuodattimia", + "abusefilter-accountreserved": "Tämä käyttäjänimi on varattu väärinkäyttösuodattimen käyttöön.", + "right-abusefilter-modify": "Luoda tai muokata väärinkäyttösuodattimia", "right-abusefilter-view": "Nähdä väärinkäyttösuodattimien sisältö", "right-abusefilter-log": "Nähdä väärinkäyttöloki", "right-abusefilter-log-detail": "Nähdä yksityiskohtaisia lokimerkintöjä väärinkäyttölokissa", - "right-abusefilter-private": "Tarkastella yksityisiä tietoja väärinkäyttölokissa", - "right-abusefilter-private-log": "Nähdä väärinkäyttösuodattimien yksityisen tiedon pääsyloki", + "right-abusefilter-privatedetails": "Tarkastella yksityisiä tietoja väärinkäyttölokissa", + "right-abusefilter-privatedetails-log": "Nähdä väärinkäyttösuodattimien yksityisen tiedon pääsyloki", "right-abusefilter-modify-restricted": "Muokata väärinkäyttösuodattimia, joissa on rajoitettuja toimintoja", "right-abusefilter-revert": "Peruuttaa kaikki muutokset, jotka on tehnyt määritelty väärinkäyttösuodatin", "right-abusefilter-view-private": "Nähdä ne väärinkäyttösuodattimet, jotka on merkitty yksityisiksi", @@ -55,17 +60,21 @@ "action-abusefilter-view": "nähdä väärinkäyttösuodattimien sisältöä", "action-abusefilter-log": "nähdä väärinkäyttölokia", "action-abusefilter-log-detail": "nähdä tarkempia tietoja väärinkäyttölokista", - "action-abusefilter-private": "tarkastella yksityisiä tietoja väärinkäyttölokista", - "action-abusefilter-private-log": "nähdä väärinkäyttösuodattimien yksityisen tiedon pääsylokia", + "action-abusefilter-privatedetails": "tarkastella yksityisiä tietoja väärinkäyttölokista", + "action-abusefilter-privatedetails-log": "nähdä väärinkäyttösuodattimien yksityisen tiedon pääsylokia", "action-abusefilter-modify-restricted": "muokata väärinkäyttösuodattimia, joissa on rajoitettuja toimintoja", "action-abusefilter-revert": "palauttaa kaikkia muutoksia valitulla väärinkäyttösuodattimella", "action-abusefilter-view-private": "nähdä niitä väärinkäyttösuodattimia, jotka on merkitty yksityisiksi", "action-abusefilter-log-private": "tarkastella yksityisten väärinkäyttösuodattimien lokitietoja", - "abusefilter-log": "Väärinkäyttösuodattimen loki", + "action-abusefilter-hide-log": "piilottaa kohteita väärinkäyttölokissa", + "action-abusefilter-hidden-log": "nähdä piilotettuja kohteita väärinkäyttölokissa", + "action-abusefilter-modify-global": "luoda tai muokata järjestelmänlaajuisia väärinkäyttösuodattimia", "abusefilter-log-summary": "Tämä loki näyttää luettelon kaikista suodattimiin tarttuneista toiminnoista.", "abusefilter-log-search": "Etsi väärinkäyttölokista", "abusefilter-log-search-user": "Käyttäjä:", - "abusefilter-log-search-filter": "Suodattimen numero (erota pystyviivoilla):", + "abusefilter-log-search-group": "Suodatinryhmä:", + "abusefilter-log-search-group-any": "Kaikki", + "abusefilter-log-search-filter": "Suodattimen numero:", "abusefilter-log-search-title": "Kohteen nimi:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-impact": "Vaikutus:", @@ -94,7 +103,7 @@ "abusefilter-log-details-var": "Muuttuja", "abusefilter-log-details-val": "Arvo", "abusefilter-log-details-vars": "Toimintoparametrit", - "abusefilter-log-details-private": "Yksityiset lokitiedot", + "abusefilter-log-details-privatedetails": "Yksityiset lokitiedot", "abusefilter-log-details-ip": "Alkuperäinen IP-osoite", "abusefilter-log-details-checkuser": "Osoitepaljastin", "abusefilter-log-noactions": "ei mitään", @@ -103,10 +112,11 @@ "abusefilter-log-linkoncontribs-text": "Väärinkäyttöloki {{GENDER:$1|tälle käyttäjälle}}", "abusefilter-log-linkonhistory": "näytä väärinkäyttöloki", "abusefilter-log-linkonhistory-text": "Näytä tämän sivun väärinkäyttöloki", - "abusefilter-log-hidden": "(merkintä on piilotettu)", + "abusefilter-log-linkonundelete": "näytä väärinkäyttöloki", + "abusefilter-log-linkonundelete-text": "Näytä tämän sivun väärinkäyttöloki", "abusefilter-log-hidden-implicit": "(piilotettu, koska versio on poistettu)", "abusefilter-log-cannot-see-details": "Sinulla ei ole oikeutta nähdä tämän lokimerkinnän tietoja.", - "abusefilter-log-cannot-see-private-details": "Sinulla ei ole lupaa tarkastella tämän lokimerkinnän yksityisiä tietoja.", + "abusefilter-log-cannot-see-privatedetails": "Sinulla ei ole lupaa tarkastella tämän lokimerkinnän yksityisiä tietoja.", "abusefilter-log-details-hidden": "Et voi nähdä tämän lokimerkinnän tietoja, koska merkintä on piilotettu eikä ole julkisesti näkyvissä.", "abusefilter-log-details-hidden-implicit": "Et voi nähdä tämän lokimerkinnän tietoja, koska siihen liittyvä versio on piilotettu eikä ole julkisesti näkyvissä.", "abusefilter-log-private-not-included": "Yksi tai useampi määrittämäsi suodattimen numero on suljettu ulkopuolisilta. Koska sinulla ei ole lupaa nähdä yksityisten suodattimien tietoja, näitä suodattimia ei ole haettu.", @@ -114,14 +124,16 @@ "abusefilter-log-hide-id": "Lokimerkinnän tunnusnumero:", "abusefilter-log-hide-hidden": "Piilota tämä merkintä julkiselta näkymiseltä", "abusefilter-log-hide-reason": "Syy:", + "abusefilter-log-hide-reason-other": "Muu syy tai tarkennus:", "abusefilter-log-hide-forbidden": "Sinulla ei ole oikeutta piilottaa väärinkäyttölokin merkintöjä.", - "logentry-abusefilter-hit": "$1 {{GENDER:$2|laukaisi}} suodattimen $4 {{GENDER:$2|suorittaessaan}} toiminnon \"$5\" kohteessa $3. Toimenpiteet: $6 ($7)", + "abusefilter-log-entry-suppress": "$1 {{GENDER:$2|piilotti}} lokin $3", + "logentry-abusefilter-hit": "$1 {{GENDER:$2|laukaisi}} suodattimen $4 {{GENDER:$2|suorittaessaan}} toiminnon ”$5” kohteessa $3. Toimenpiteet: $6 ($7)", "log-action-filter-abusefilter": "Suodattimen muutoksen tyyppi:", "log-action-filter-abusefilter-create": "Uuden suodattimen luonti", "log-action-filter-abusefilter-modify": "Suodattimen muokkaus", + "log-action-filter-suppress-abuselog": "Väärinkäyttölokin häivytys", "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|katsoi}} lokin $3 yksityiset tiedot", "abusefilterprivatedetails-log-name": "Väärinkäyttösuodattimen yksityisen tiedon pääsyloki", - "abusefilter-management": "Väärinkäyttösuodattimen hallinta", "abusefilter-list": "Kaikki suodattimet", "abusefilter-list-id": "Suodatin nro", "abusefilter-list-status": "Tila", @@ -139,8 +151,10 @@ "abusefilter-enabled": "Käytössä", "abusefilter-deleted": "Poistettu", "abusefilter-disabled": "Poistettu käytöstä", + "abusefilter-throttled": "rajoitettu", "abusefilter-hitcount": "$1 {{PLURAL:$1|osuma|osumaa}}", "abusefilter-new": "Luo uusi suodatin", + "abusefilter-import-button": "Tuo suodatin", "abusefilter-return": "Palaa suodattimien hallintaan", "abusefilter-status-global": "Järjestelmänlaajuinen", "abusefilter-list-options": "Valinnat", @@ -152,8 +166,10 @@ "abusefilter-list-options-scope-local": "Vain paikalliset säännöt", "abusefilter-list-options-scope-global": "Vain järjestelmänlaajuiset säännöt", "abusefilter-list-options-scope-all": "Paikalliset ja järjestelmänlaajuiset säännöt", + "abusefilter-list-options-further-options": "Muut valinnat:", "abusefilter-list-options-hidedisabled": "Piilota käytöstä poistetut suodattimet", "abusefilter-list-options-hideprivate": "Piilota yksityiset suodattimet", + "abusefilter-list-options-searchoptions": "Hakutila:", "abusefilter-list-options-search-rlike": "Säännöllinen lauseke", "abusefilter-list-options-submit": "Päivitä", "abusefilter-tools-text": "Tässä on työkaluja, jotka saattavat olla hyödyllisiä väärinkäyttösuodattimien muodostamisessa ja niiden virheenjäljityksessä.", @@ -165,14 +181,14 @@ "abusefilter-reautoconfirm-none": "Tätä käyttäjää ei ole poistettu ryhmästä ''automaattisesti hyväksytyt käyttäjät (autoconfirmed)''", "abusefilter-reautoconfirm-notallowed": "Sinulla ei ole oikeutta palauttaa käyttäjätunnusta ryhmään ''automaattisesti hyväksytyt käyttäjät (autoconfirmed)''", "abusefilter-reautoconfirm-done": "Käyttäjätunnus on nyt palautettu ryhmään ''automaattisesti hyväksytyt käyttäjät (autoconfirmed)''", - "abusefilter-status": "Viimeisestä $1 {{PLURAL:$1|toiminnosta}} $2 ($3 %) on {{PLURAL:$2|saavuttanut}} ehtorajan $4, ja $5 ($6 %) on {{PLURAL:$5|täsmännyt}} johonkin tällä hetkellä käytössä olevista suodattimista.", + "abusefilter-status": "Viimeisestä $1 {{PLURAL:$1|toiminnosta}} $2 ($3 %) on {{PLURAL:$2|saavuttanut}} ehtorajan $4, ja $5 ($6 %) on {{PLURAL:$5|täsmännyt}} ainakin yhteen tällä hetkellä käytössä olevista suodattimista.", "abusefilter-edit": "Muokataan väärinkäyttösuodatinta", "abusefilter-edit-subtitle": "Muokataan suodatinta $1", "abusefilter-edit-subtitle-new": "Luodaan suodatinta", + "abusefilter-edit-token-not-match": "Muokkausta ei tallennettu! Ole hyvä ja tallenna uudestaan.", "abusefilter-edit-oldwarning": "<strong>Muokkaat tämän suodattimen vanhaa versiota.\nAnnetut tilastot ovat suodattimen uusimmalle versiolle.\nJos tallennat muutoksesi, tuhoat samalla kaikki tämän version jälkeen tehdyt muutokset.</strong> •\n[[Special:AbuseFilter/history/$2|Palaa suodattimen historiaan]].", "abusefilter-edit-status-label": "Tilastot:", - "abusefilter-edit-status": "Viimeisestä $1 {{PLURAL:$1|toiminnosta}} tämä suodatin täsmäsi $2 kertaa ($3 %).", - "abusefilter-edit-status-profile": "Viimeisestä $1 toiminnosta tämä suodatin täsmäsi $2 kertaa ($3 %).\nKeskimäärin sen ajoaika on $4 ms, ja se kuluttaa $5 {{PLURAL:$5|ehdon|ehtoa}} ehtorajasta.", + "abusefilter-edit-status": "Viimeisestä $1 {{PLURAL:$1|toiminnosta}} tämä suodatin täsmäsi $2 kertaa ($3 %).\nSen keskimääräinen suoritusaika on $4 ms ja se käyttää $5 {{PLURAL:$5|ehdon|ehtoa}} ehtorajasta.", "abusefilter-edit-throttled-warning": "'''Varoitus:''' Tämä suodatin merkittiin automaattisesti haitalliseksi. Turvallisuussyistä seuraavia toimintoja ei suoriteta ($1). Tarkista ja [[mw:Extension:AbuseFilter/Conditions|optimoi]] ehtosi poistaaksesi tämän rajoituksen", "abusefilter-edit-new": "Uusi suodatin", "abusefilter-edit-save": "Tallenna suodatin", @@ -205,18 +221,28 @@ "abusefilter-edit-throttle-count": "Toimintojen sallittu määrä:", "abusefilter-edit-throttle-period": "Aikaväli (sekunteina):", "abusefilter-edit-throttle-groups": "Ryhmän määritys:", - "abusefilter-edit-throttle-ip": "IP-osoite", - "abusefilter-edit-throttle-user": "Käyttäjätunnus", - "abusefilter-edit-throttle-range": "/16-alue", - "abusefilter-edit-throttle-editcount": "Muokkausmäärä", - "abusefilter-edit-throttle-site": "Koko sivusto", - "abusefilter-edit-throttle-page": "Sivu", + "abusefilter-edit-throttle-groups-help": "Katso $1.", + "abusefilter-edit-throttle-groups-help-text": "ohjeistus sivustolta mediawiki.org", + "abusefilter-throttle-ip": "IP-osoite", + "abusefilter-throttle-user": "käyttäjätunnus", + "abusefilter-throttle-range": "/16-alue", + "abusefilter-throttle-creationdate": "tunnuksen luontipäivä", + "abusefilter-throttle-editcount": "muokkausmäärä", + "abusefilter-throttle-site": "koko sivusto", + "abusefilter-throttle-page": "sivu", + "abusefilter-throttle-none": "(ei mitään)", "abusefilter-edit-warn-message": "Varoitukseen käytettävä järjestelmäviesti:", "abusefilter-edit-warn-other": "Muu viesti", - "abusefilter-edit-warn-other-label": "Muun viestin sivun otsikko:\n:''(ilman Järjestelmäviesti-etuliitettä)''", + "abusefilter-edit-warn-other-label": "Muun viestin sivun otsikko:\n:''(ilman \"Järjestelmäviesti:\"-etuliitettä)''", "abusefilter-edit-warn-actions": "Toiminnot:", "abusefilter-edit-warn-preview": "Näytä/piilota valitun viestin esikatselu", "abusefilter-edit-warn-edit": "Luo tai muokkaa valittua viestiä", + "abusefilter-edit-disallow-message": "Estämiseen käytettävä järjestelmäviesti:", + "abusefilter-edit-disallow-other": "Muu viesti", + "abusefilter-edit-disallow-other-label": "Muun viestin sivun otsikko:\n:''(ilman \"Järjestelmäviesti:\"-etuliitettä)''", + "abusefilter-edit-disallow-actions": "Toiminnot:", + "abusefilter-edit-disallow-preview": "Näytä/piilota valitun viestin esikatselu", + "abusefilter-edit-disallow-edit": "Luo tai muokkaa valittua viestiä", "abusefilter-edit-tag-tag": "Käytettävät [[Special:Tags|merkkaukset]]:", "abusefilter-edit-tag-placeholder": "Lisää merkkauksia (yksitellen tai pilkulla erotettuna)", "abusefilter-edit-tag-hidden-placeholder": "Lisää merkkauksia (pilkulla erotettuna)", @@ -230,6 +256,7 @@ "abusefilter-edit-done-subtitle": "Suodatinta muokattu", "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Muutokset]] [[Special:AbuseFilter/$1|suodattimeen $3]] tallennettiin onnistuneesti.", "abusefilter-edit-badsyntax": "Määrittämässäsi suodattimessa on syntaksivirhe.\nJäsentimen palaute: <pre>$1</pre>", + "abusefilter-edit-missingfields": "Seuraavat kentät ovat pakollisia ja tulee täyttää: $1", "abusefilter-edit-deleting-enabled": "Et voi merkitä aktiivista suodatinta poistetuksi.", "abusefilter-edit-restricted": "Et voi muuttaa tätä suodatinta, koska se sisältää yhden tai useamman rajoitetun toiminnon.\nPyydä rajoitettujen toimintojen lisäämiseen tarvittavien oikeuksien haltijalta, että tämä tekee muutoksen puolestasi.", "abusefilter-edit-viewhistory": "Näytä tämän suodattimen historia", @@ -242,10 +269,13 @@ "abusefilter-edit-export": "Vie tämä suodatin toiseen wikiin", "abusefilter-edit-syntaxok": "Ei syntaksivirheitä havaittu.", "abusefilter-edit-syntaxerr": "Syntaksivirhe havaittu: $1", - "abusefilter-edit-bad-tags": "Yksi tai useampi määrittämistäsi merkkauksista (tags) ei kelpaa.\nMerkkausten tulisi olla lyhyitä ja ilman erikoismerkkejä.", + "abusefilter-edit-warn-leave": "Sivulta poistuminen kadottaa kaikki tähän suodattimeen tekemäsi muutokset.", + "abusefilter-edit-bad-tags": "Yksi tai useampi määrittämistäsi merkkauksista (tags) ei kelpaa.\nMerkkausten tulisi olla lyhyitä, niissä ei saa olla erikoismerkkejä ja ne eivät voi olla varattuna muun ohjelman käyttöön. Yritä valita uusi nimi merkkaukselle.", "abusefilter-edit-notallowed": "Sinulla ei ole oikeutta luoda tai muokata väärinkäyttösuodattimia", "abusefilter-edit-notallowed-global": "Sinulla ei ole oikeutta luoda tai muokata järjestelmänlaajuisia väärinkäyttösuodattimia", - "abusefilter-edit-notallowed-global-custom-msg": "Räätälöityjä varoitusviestejä ei voi liittää järjestelmänlaajuisiin suodattimiin", + "abusefilter-edit-notallowed-global-custom-msg": "Räätälöityjä varoitus- ja estämisviestejä ei voi liittää järjestelmänlaajuisiin suodattimiin", + "abusefilter-edit-invalid-warn-message": "Varoitusviesti ei voi olla tyhjä.", + "abusefilter-edit-invalid-disallow-message": "Estämisviesti ei voi olla tyhjä.", "abusefilter-edit-builder-select": "Valitse tästä vaihtoehto joka lisätään kohdistimen jälkeen", "abusefilter-edit-builder-group-op-arithmetic": "Aritmeettiset operaattorit", "abusefilter-edit-builder-op-arithmetic-addition": "Lisäys (+)", @@ -255,8 +285,10 @@ "abusefilter-edit-builder-op-arithmetic-modulo": "Jakojäännös (%)", "abusefilter-edit-builder-op-arithmetic-pow": "Potenssi (**)", "abusefilter-edit-builder-group-op-comparison": "Vertailuoperaattorit", - "abusefilter-edit-builder-op-comparison-equal": "Yhtäläinen (==)", - "abusefilter-edit-builder-op-comparison-notequal": "Eroava (!=)", + "abusefilter-edit-builder-op-comparison-equal": "Yhtäläinen arvo (==)", + "abusefilter-edit-builder-op-comparison-equal-strict": "Yhtäläinen arvo ja tyyppi (===)", + "abusefilter-edit-builder-op-comparison-notequal": "Eroava arvo (!=)", + "abusefilter-edit-builder-op-comparison-notequal-strict": "Eroava arvo ja tyyppi (!==)", "abusefilter-edit-builder-op-comparison-lt": "Pienempi kuin (<)", "abusefilter-edit-builder-op-comparison-gt": "Suurempi kuin (>)", "abusefilter-edit-builder-op-comparison-lte": "Pienempi tai yhtä suuri kuin (<=)", @@ -273,7 +305,7 @@ "abusefilter-edit-builder-misc-contains": "Vasen merkkijono sisältää oikean merkkijonon (contains)", "abusefilter-edit-builder-misc-stringlit": "Merkkijonovakio (\"\")", "abusefilter-edit-builder-misc-tern": "Ehto-operaattori (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Ehtolause (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Ehtolause (if X then Y else Z end)", "abusefilter-edit-builder-group-funcs": "Funktiot", "abusefilter-edit-builder-funcs-length": "Merkkijonon pituus (length)", "abusefilter-edit-builder-funcs-lcase": "Muuta pienaakkosiksi (lcase)", @@ -287,7 +319,8 @@ "abusefilter-edit-builder-funcs-rmwhitespace": "Poista tyhjä tila (rmwhitespace)", "abusefilter-edit-builder-funcs-rmspecials": "Poista erikoismerkit (rmspecials)", "abusefilter-edit-builder-funcs-ip_in_range": "Onko IP-osoite osoiteavaruudessa? (ip_in_range)", - "abusefilter-edit-builder-funcs-contains-any": "Etsi merkkijonosta osamerkkijonoja (contains_any)", + "abusefilter-edit-builder-funcs-contains-any": "Etsi merkkijonosta osamerkkijonoja OR-tilassa. (contains_any)", + "abusefilter-edit-builder-funcs-contains-all": "Etsi merkkijonosta osamerkkijonoja AND-tilassa. (contains_all)", "abusefilter-edit-builder-funcs-substr": "Osamerkkijono (substr)", "abusefilter-edit-builder-funcs-strpos": "Osamerkkijonon sijainti merkkijonossa (strpos)", "abusefilter-edit-builder-funcs-str_replace": "Korvaa osamerkkijono merkkijonolla (str_replace)", @@ -296,6 +329,7 @@ "abusefilter-edit-builder-group-vars": "Muuttujat", "abusefilter-edit-builder-vars-accountname": "Käyttäjätunnus (tunnuksen luomisessa)", "abusefilter-edit-builder-vars-timestamp": "Muutoksen Unix-aikaleima", + "abusefilter-edit-builder-vars-timestamp-expanded": "Lokin aikaleima", "abusefilter-edit-builder-vars-action": "Toiminto", "abusefilter-edit-builder-vars-addedlines": "Muokkauksessa lisättyjen rivien määrä", "abusefilter-edit-builder-vars-delta": "Koon muutos muokkauksessa", @@ -337,12 +371,12 @@ "abusefilter-edit-builder-vars-all-links": "Kaikki ulkoiset linkit uudessa tekstissä", "abusefilter-edit-builder-vars-added-links": "Kaikki muokkauksessa lisätyt ulkoiset linkit", "abusefilter-edit-builder-vars-removed-links": "Kaikki muokkauksessa poistetut ulkoiset linkit", - "abusefilter-edit-builder-vars-old-text": "Sivun vanha wikiteksti, ennen muokkausta (ei enää käytössä)", - "abusefilter-edit-builder-vars-new-text": "Sivun uusi wikiteksti, muokkauksen jälkeen", - "abusefilter-edit-builder-vars-new-pst": "Uuden sivun wikiteksti, \"pre-save transformed\"", + "abusefilter-edit-builder-vars-old-wikitext": "Sivun vanha wikiteksti, ennen muokkausta", + "abusefilter-edit-builder-vars-new-wikitext": "Sivun uusi wikiteksti, muokkauksen jälkeen", + "abusefilter-edit-builder-vars-new-pst": "Uuden sivun wikiteksti, ”pre-save transformed”", "abusefilter-edit-builder-vars-diff-pst": "Yhdistetty eroavaisuus (diffi) muutoksista, jotka on tehty muokkauksessa, \"pre-save transformed\"", "abusefilter-edit-builder-vars-addedlines-pst": "Muokkauksessa lisätyt rivit, \"pre-save transformed\"", - "abusefilter-edit-builder-vars-new-text-stripped": "Sivun uusin tekstimuoto, riisuttuna kaikista koodimerkinnöistä", + "abusefilter-edit-builder-vars-new-text": "Sivun uusin tekstimuoto, riisuttuna kaikista koodimerkinnöistä", "abusefilter-edit-builder-vars-new-html": "Jäsennetty uuden version HTML-lähdekoodi", "abusefilter-edit-builder-vars-restrictions-edit": "Sivun muokkaussuojauksen taso", "abusefilter-edit-builder-vars-restrictions-move": "Sivun siirtosuojauksen taso", @@ -356,17 +390,19 @@ "abusefilter-edit-builder-vars-movedto-restrictions-move": "Siirron kohdesivun siirtosuojaus", "abusefilter-edit-builder-vars-movedto-restrictions-create": "Siirron kohdesivun luontisuojaus", "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Siirron kohdesivun tallennussuojaus", - "abusefilter-edit-builder-vars-old-text-stripped": "Sivun vanhempi teksti, riisuttuna koodimerkinnöistä", + "abusefilter-edit-builder-vars-old-text": "Sivun vanhempi teksti, riisuttuna koodimerkinnöistä (ei enää käytössä)", "abusefilter-edit-builder-vars-old-links": "Linkit sivulla ennen muokkausta", "abusefilter-edit-builder-vars-old-html": "Vanha sivun wikiteksti jäsennettynä HTML:ksi (ei enää käytössä)", - "abusefilter-edit-builder-vars-minor-edit": "Onko muokkaus merkitty pieneksi muutokseksi vai ei", + "abusefilter-edit-builder-vars-minor-edit": "Onko muokkaus merkitty pieneksi muutokseksi vai ei (ei enää käytössä)", "abusefilter-edit-builder-vars-file-sha1": "Tiedoston sisällön SHA1-tiiviste", "abusefilter-edit-builder-vars-file-size": "Tiedoston koko tavuina", "abusefilter-edit-builder-vars-file-mime": "Tiedoston MIME-tyyppi", "abusefilter-edit-builder-vars-file-mediatype": "Tiedoston mediatyyppi", "abusefilter-edit-builder-vars-file-width": "Tiedoston leveys pikseleissä", "abusefilter-edit-builder-vars-file-height": "Tiedoston korkeus pikseleissä", - "abusefilter-filter-log": "Suodattimien viimeisimmät muutokset", + "abusefilter-edit-builder-vars-wiki-name": "Wikin tietokannan nimi", + "abusefilter-edit-builder-vars-wiki-language": "Wikin kielikoodi", + "abusefilter-filter-log": "Suodattimiin tehdyt uusimmat muutokset", "abusefilter-history": "Muutoshistoria väärinkäyttösuodattimelle numero $1", "abusefilter-history-foruser": "Käyttäjän $1 muokkaukset", "abusefilter-history-hidden": "Piilotettu", @@ -388,23 +424,24 @@ "abusefilter-history-select-submit": "Tarkenna", "abusefilter-history-diff": "Muutokset", "abusefilter-history-error-hidden": "Pyytämäsi suodatin on piilotettu näkyvistä, etkä voi tarkastella sen historiaa.", - "abusefilter-exception-unexpectedatend": "Odottamaton ”$2” merkissä $1.", + "abusefilter-exception-unexpectedatend": "Odottamaton ”$2” merkin $1 kohdalla.", "abusefilter-exception-expectednotfound": "Odotettiin koodia $2 merkin $1 kohdalla, ei löytynyt. (Sen sijaan löytyi $3 $4.)", "abusefilter-exception-unrecognisedkeyword": "Tunnistamaton avainsana $2 merkissä $1.", - "abusefilter-exception-unexpectedtoken": "Odottamaton sane ”$3” (tyyppiä $2) kohdassa $1.", + "abusefilter-exception-unexpectedtoken": "Odottamaton sane ”$3” (tyyppiä $2) merkin $1 kohdalla.", "abusefilter-exception-unclosedstring": "Sulkematon merkkijono alkaen merkistä $1.", - "abusefilter-exception-invalidoperator": "Virheellinen operaattori ”$2” merkissä $1.", - "abusefilter-exception-unrecognisedtoken": "Tunnistamaton sane ”$2” kohdassa $1.", - "abusefilter-exception-noparams": "Parametreja ei annettu funktiolle ”$2” merkissä $1.\nOdotettiin $3 {{PLURAL:$3|argumenttia}}.", + "abusefilter-exception-invalidoperator": "Virheellinen operaattori ”$2” merkin $1 kohdalla.", + "abusefilter-exception-unrecognisedtoken": "Tunnistamaton sane ”$2” merkin $1 kohdalla.", + "abusefilter-exception-noparams": "Parametreja ei annettu funktiolle ”$2” merkin $1 kohdalla.\nOdotettiin $3 {{PLURAL:$3|argumenttia}}.", "abusefilter-exception-dividebyzero": "Laiton yritys jakaa $2 nollalla merkissä $1.", "abusefilter-exception-unrecognisedvar": "Tunnistamaton muuttuja $2 merkissä $1", "abusefilter-exception-notenoughargs": "Funktiolle $2 ei annettu tarpeeksi argumentteja kutsuttaessa merkissä $1.\nOdotettu $3 {{PLURAL:$3|argumenttia|argumenttia}}, saatu $4.", - "abusefilter-exception-regexfailure": "Virhe säännöllisessä lausekkeessa ”$3” merkin $1 kohdalla: ”$2”", - "abusefilter-exception-overridebuiltin": "Laiton sisäänrakennetun muuttujan ”$2” päällekirjoitus merkissä $1.", + "abusefilter-exception-regexfailure": "Virhe säännöllisessä lausekkeessa ”$2” merkin $1 kohdalla.", + "abusefilter-exception-overridebuiltin": "Laiton sisäänrakennetun tunnisteen ”$2” ylikirjoitus merkin $1 kohdalla.", "abusefilter-exception-outofbounds": "Pyydetty olematonta listaelementtiä $2 (listan koko on $3) merkissä $1.", + "abusefilter-exception-negativeindex": "Negatiiviset indeksit eivät ole sallittuja taulukoissa. Saatiin indeksi ”$2” merkin $1 kohtalla.", "abusefilter-exception-notarray": "Pyydetty taulukkoelementtiä ei-taulukolta merkissä $1.", "abusefilter-exception-unclosedcomment": "Sulkematon kommentti merkissä $1.", - "abusefilter-exception-invalidiprange": "Virheellinen IP-osoiteavaruus \"$2\" merkissä $1.", + "abusefilter-exception-invalidiprange": "Virheellinen IP-osoiteavaruus ”$2” merkin $1 kohdalla.", "abusefilter-exception-disabledvar": "Muuttuja $2 merkissä $1 ei ole enää käytössä.", "abusefilter-action-tag": "Merkkaa", "abusefilter-action-throttle": "Rajoita", @@ -416,13 +453,14 @@ "abusefilter-action-disallow": "Älä salli", "abusefilter-revert-title": "Peruuta kaikki suodattimen $1 tekemät muutokset", "abusefilter-revert-intro": "Tämä lomake antaa sinun peruuttaa kaikki muutokset, jotka väärinkäyttösuodatin on tehnyt suodattimen $1 ehtojen perusteella.\nKäytä tätä työkalua varoen.", - "abusefilter-revert-preview-item": "$1: käyttäjä $2 {{GENDER:$7|käytti}} toimintoa \"$3\" kohteessa $4.\nPeruttavat toimenpiteet ovat: $5 ($6)", + "abusefilter-revert-preview-item": "$1: käyttäjä $2 {{GENDER:$7|käytti}} toimintoa ”$3” kohteessa $4.\nPeruttavat toimenpiteet ovat: $5 ($6)", "abusefilter-revert-search-legend": "Valitse suodattimen toimenpiteet, jotka haluat peruuttaa", "abusefilter-revert-periodstart": "Aikaväli alkaa:", "abusefilter-revert-periodend": "Aikaväli loppuu:", "abusefilter-revert-search": "Valitse toimenpiteet", "abusefilter-revert-filter": "Suodatin nro:", "abusefilter-revert-preview-intro": "Alla ovat ne väärinkäyttösuodattimen suorittamat toimenpiteet, jotka peruutetaan tällä toiminnolla.\nTarkista ne huolellisesti ja paina \"{{int:abusefilter-revert-confirm}}\", niin toimenpiteet peruutetaan.", + "abusefilter-revert-confirm-legend": "Vahvista kumoaminen", "abusefilter-revert-confirm": "Vahvista", "abusefilter-revert-success": "Olet peruuttanut kaikki toimenpiteet, jotka väärinkäyttösuodatin teki [[Special:AbuseFilter/$1|suodattimen $2]] ehtojen mukaisesti.", "abusefilter-revert-reason": "Kaikkien toimenpiteiden automaattinen peruuttaminen, jotka väärinkäyttösuodatin oli tehnyt suodattimen $1 ehtojen mukaisesti.\nAnnettu syy: $2", @@ -441,6 +479,13 @@ "abusefilter-test-shownegative": "Näytä muutokset, jotka eivät täsmää suodattimen kanssa", "abusefilter-test-syntaxerr": "Suodatin, jonka syötit, sisälsi syntaksivirheen.\nLisätietoja saat napsauttamalla painiketta ”{{int:abusefilter-edit-check}}”.", "abusefilter-test-badtitle": "Syöttämäsi sivun nimi ei kelpaa. Siinä saattaa olla yksi tai useampia sellaisia kirjainmerkkejä, joita ei voi käyttää sivujen nimissä.", + "abusefilter-test-action": "Toimenpiteen tyyppi:", + "abusefilter-test-search-type-all": "Kaikki toimenpiteet", + "abusefilter-test-search-type-edit": "Muokkaukset", + "abusefilter-test-search-type-move": "Siirrot", + "abusefilter-test-search-type-delete": "Poistot", + "abusefilter-test-search-type-upload": "Tallennukset", + "abusefilter-test-search-type-createaccount": "Käyttäjätunnusten luonnit", "abusefilter-changeslist-examine": "tutki", "abusefilter-examine": "Tutki yksittäisiä muutoksia", "abusefilter-examine-intro": "Tällä sivulla voit tutkia väärinkäyttösuodattimen muuttujia yksittäisen muutoksen suhteen ja testata sitä suodattimilla.", @@ -460,11 +505,11 @@ "abusefilter-examine-noresults": "Antamillasi hakuehdoilla ei löytynyt yhtään tulosta.", "abusefilter-topnav": "'''Väärinkäyttösuodattimen valikko'''", "abusefilter-topnav-home": "Etusivu", + "abusefilter-topnav-recentchanges": "Uusimmat muutokset suodattimiin", "abusefilter-topnav-test": "Suodatinsääntöjen testaus", "abusefilter-topnav-examine": "Tutki aiempia muokkauksia", "abusefilter-topnav-log": "Väärinkäyttöloki", "abusefilter-topnav-tools": "Vianjäljitystyökalut", - "abusefilter-topnav-import": "Tuo suodatin", "abusefilter-log-name": "Väärinkäyttösuodattimen loki", "abusefilter-log-header": "Tässä lokissa esitetään yhteenveto suodattimiin tehdyistä muutoksista.\nLisätietoja saat suodattimen [[Special:AbuseFilter/history|viimeisimpien muutosten luettelosta]].", "abusefilter-logentry-create": "$1 {{GENDER:$2|loi}} kohteen $4 ($5)", @@ -483,11 +528,13 @@ "abusefilter-import-submit": "Tuo tiedot", "abusefilter-group-default": "Yleinen", "abusefilter-http-error": "Tapahtui HTTP-virhe: $1.", - "abusefilter-view-private-submit": "Näytä yksityiskohdat", - "abusefilter-view-private": "Näytä yksityiskohdat", - "abusefilter-view-private-reason": "Syy yksityiskohtien näyttämiseen:", + "abusefilter-view-privatedetails-submit": "Näytä yksityiset tiedot", + "abusefilter-view-privatedetails-legend": "Näytä yksityiskohdat", + "abusefilter-view-privatedetails-reason": "Syy yksityiskohtien näyttämiseen:", "abusefilter-log-details-id": "Lokin tunnistenumero", + "abusefilter-noreason": "Varoitus: Nähdäksesi tämän lokin yksityiset tiedot sinun on annettava syy.", "abusefilter-log-ip-not-available": "Ei saatavissa", "abusefilter-tag-reserved": "Tämä <code>abusefilter-condition-limit</code> merkintä on varattu Väärinkäyttösuodattimen sisäiseen käyttöön.", - "tag-abusefilter-condition-limit": "ehtojen raja-arvo on saavutettu" + "tag-abusefilter-condition-limit": "ehtojen raja-arvo on saavutettu", + "tag-abusefilter-condition-limit-description": "Muokkaukset tai muut tapahtumat, joita ei voitu käydä läpi kaikilla aktiivisilla [[Special:AbuseFilter|väärinkäyttösuodattimilla]] ([[mw:Extension:AbuseFilter/Conditions|ohje]])." } diff --git a/AbuseFilter/i18n/fit.json b/AbuseFilter/i18n/fit.json new file mode 100644 index 00000000..5ffacb27 --- /dev/null +++ b/AbuseFilter/i18n/fit.json @@ -0,0 +1,17 @@ +{ + "@metadata": { + "authors": [ + "Pyscowicz" + ] + }, + "abusefilter-log-detailslink": "tarkat tieot", + "abusefilter-edit-status-label": "Statistiikit:", + "abusefilter-edit-action-tag": "Markeeraa mookkaus lisätarkastelun kohteeksi", + "abusefilter-throttle-user": "käyttäjäkonttu", + "abusefilter-edit-builder-vars-new-html": "Jäsennetty uuen versuunin HTML-lähekooti", + "abusefilter-edit-builder-vars-wiki-language": "Wikin kielikooti", + "abusefilter-history-foruser": "Käyttäjän $1 mookkaukset", + "abusefilter-action-tag": "Markeeraa", + "abusefilter-diff-info": "Perustieot", + "abusefilter-group-default": "Ylheinen" +} diff --git a/AbuseFilter/i18n/fo.json b/AbuseFilter/i18n/fo.json index 65d3d564..5d2cfb4f 100644 --- a/AbuseFilter/i18n/fo.json +++ b/AbuseFilter/i18n/fo.json @@ -5,8 +5,8 @@ ] }, "abusefilter-desc": "Brúkar sjálvvirkandi filtur til rættingar", - "abusefilter": "Konfigurasjón av misnýtslufilturi", - "abuselog": "Misnýtsluloggur", + "abusefilter": "Stýring av misnýtslufilturi", + "abuselog": "Loggur fyri misnýtslufiltur", "abusefilter-intro": "Vælkomin til markamótið til handfaring av misnýtslufilturinum.\nMisnýtslufilturið er ein sjálvvirkandi mekanisma í ritbúnaðinum, sum fremur sjálvvirkandi eftirlit við øllum sum fer fram.\nHetta markamótið vísir ein lista við útgreinaðum filtrum, og ger tað møguligt at broyta tey.", "abusefilter-warning": "'''Ávaring:''' Henda handlingin er sjálvvirkandi blivin sædd sum skaðilig.\nRættingar ið ikki eru konstruktivar verða skjótt afturstillaðar, \nog ekstremar ella endurtiknar ikki brúkbarar rættingar fara at føra til at tín IP adressa verður sperrað.\nUm tú meinar, at tað ið tú ger er konstuktivt, so kanst tú goyma enna einaferð fyri at vátta tað.\nEin stutt frágreiðing um tann misnýtsluregulin, ið tín handling passaði saman við er: $1", "abusefilter-disallowed": "Henda gerð er sjálvvirkandi blivin fráboðað sum skaðilig, og verður tí ikki loyvd.\nUm tú meinar, at tað ið tú gjørdi var brúkbart, vinarliga boða so einum administatori frá um tað ið tú ætlaði tær at gera.\nEin stutt frágreiðing um misnýtsluregulin, sum tín gerð passaði saman við er: $1", @@ -20,7 +20,7 @@ "right-abusefilter-view": "Vís misnýtslu filtur", "right-abusefilter-log": "Vís misnýtslu loggin", "right-abusefilter-log-detail": "Vís í smálutum postar í misnýtslu loggunum", - "right-abusefilter-private": "Vís privat dáta í misnýtslulogginum", + "right-abusefilter-privatedetails": "Vís privat dáta í misnýtslulogginum", "right-abusefilter-modify-restricted": "Broyt misnýtslu filturini við avmarkaðum gerningum", "right-abusefilter-revert": "Afturrulla allar broytingar sum eitt ávíst misnýtslufiltur hevur gjørt", "right-abusefilter-view-private": "Vís misnýtslu filtur markaði sum privat", @@ -32,8 +32,7 @@ "action-abusefilter-view": "vís misnýtslufiltur", "action-abusefilter-log": "vís misnýtslu loggin", "action-abusefilter-log-detail": "vís smálutir í misnýtslu loggunum", - "action-abusefilter-private": "vís privat dáta í misnýtslu logginum", - "abusefilter-log": "Loggur fyri misnýtslufiltur", + "action-abusefilter-privatedetails": "vís privat dáta í misnýtslu logginum", "abusefilter-log-summary": "Hesin loggurin vísir ein lista við øllum hendingum, sum misnýtslufilturi hevur fangað.", "abusefilter-log-search": "Leita í misnýtslulogginum", "abusefilter-log-search-user": "Brúkari:", @@ -49,13 +48,12 @@ "abusefilter-log-hidelink": "tilpassa sjónligheit", "abusefilter-log-details-legend": "Smálutir um loggpunkt $1", "abusefilter-log-details-val": "Virði", - "abusefilter-log-details-private": "Privat dáta", + "abusefilter-log-details-privatedetails": "Privat dáta", "abusefilter-log-details-ip": "Upphavs IP adressa", "abusefilter-log-noactions": "ongin", "abusefilter-log-details-diff": "Broytingar gjørdar í rætting", "abusefilter-log-linkoncontribs": "Misnýtsluloggur", "abusefilter-log-linkoncontribs-text": "Misnýtslulogur fyri henda brúkaran", - "abusefilter-log-hidden": "(postur fjaldur)", "abusefilter-log-hidden-implicit": "(fjalt, tí at versjónin er blivin sletttað)", "abusefilter-log-cannot-see-details": "Tú hevur ikki loyvi til at síggja smálutir um henda postin.", "abusefilter-log-details-hidden": "Tú kanst ikki síggja smálutir um henda postin, tí hann verður ikki vístur alment.", @@ -65,7 +63,6 @@ "abusefilter-log-hide-reason": "Orsøk:", "abusefilter-log-hide-forbidden": "Tú hevur ikki loyvi til at fjala misnýtsluloggpostar.", "logentry-abusefilter-hit": "$1 útloysti $4, sum førir til handling \"$5\" á $3. Tiltøk sett í verk: $6 ($7)", - "abusefilter-management": "Stýring av misnýtslufilturi", "abusefilter-list": "Øll filtur", "abusefilter-list-id": "Filtur ID", "abusefilter-list-status": "Status", diff --git a/AbuseFilter/i18n/fr.json b/AbuseFilter/i18n/fr.json index f67799d4..42d58b67 100644 --- a/AbuseFilter/i18n/fr.json +++ b/AbuseFilter/i18n/fr.json @@ -1,150 +1,167 @@ { "@metadata": { "authors": [ + "0x010C", + "Alno", "ChrisPtDe", "Cquoi", "Crochet.david", "DavidL", "Dr Brains", + "Elfix", "Gomoko", "Grondin", "Hello71", + "Hercule", "IAlex", "Isildur", "Jean-Frédéric", "Kropotkine 113", + "Linedwell", "Ltrlg", + "Macofe", + "Manu1400", + "Matma Rex", + "Matěj Suchánek", "McDutchie", "Metroitendo", + "Nicolapps", + "Niridya", + "Od1n", + "Orlodrim", "Peter17", "PieRRoMaN", + "Pols12", "Robby", "Sherbrooke", + "Thibaut120094", "Tititou36", + "TomT0m", "Urhixidur", "VIGNERON", "Verdy p", - "Wyz", - "Zetud", - "Orlodrim", - "0x010C", - "Nicolapps", - "Linedwell", - "Hercule", - "Macofe", - "TomT0m", "Wladek92", - "Elfix", - "Matma Rex", - "Thibaut120094", - "Matěj Suchánek" + "Wyz", + "Zetud" ] }, "abusefilter-desc": "Applique des heuristiques automatiques aux modifications", - "abusefilter": "Configuration du filtre antiabus", - "abuselog": "Journal des filtres antiabus", - "abusefilter-intro": "Bienvenue dans l'interface de gestion des filtres antiabus.\nLe filtre antiabus est un mécanisme logiciel automatisé qui permet d'appliquer des heuristiques prédéfinies à toutes les actions.\nCette interface présente une liste des filtres définis, et donne la possibilité de les modifier.", + "abusefilter": "Gestion du filtre anti-abus", + "abuselog": "Journal des déclenchements du filtre anti-abus", + "abusefilter-intro": "Bienvenue dans l’interface de gestion des filtres anti-abus.\nLe filtre anti-abus est un mécanisme logiciel automatisé qui permet d’appliquer des heuristiques prédéfinies à toutes les actions.\nCette interface présente une liste des filtres définis et donne la possibilité de les modifier.", "abusefilter-mustviewprivateoredit": "Pour des raisons de sécurité, seuls les utilisateurs avec le droit de voir les filtres d’abus privés ou de modifier les filtres peuvent utiliser cette interface.", - "abusefilter-warning": "'''Avertissement :''' cette action a été automatiquement identifiée comme nuisible.\nLes actions non constructives seront rapidement annulées et les modifications non constructives répétées ou outrageantes provoqueront le blocage de votre compte ou de votre adresse IP.\nSi vous estimez que cette action est constructive, vous pouvez la soumettre une nouvelle fois pour la confirmer.\nVoici une brève description de la règle de filtrage antiabus ayant détecté votre action : $1", - "abusefilter-disallowed": "Cette action a été automatiquement identifiée comme nuisible, et a donc été empêchée.\nSi vous pensez que votre action était constructive, veuillez contacter un administrateur et l'informer de ce que vous avez essayé de faire.\nVoici une brève description de la règle de filtrage antiabus ayant détecté votre action : $1", - "abusefilter-blocked-display": "Cette action a été automatiquement identifée comme nuisible\net vous avez déjà été empêché de l'exécuter.\nDe plus, pour protéger {{SITENAME}}, votre compte utilisateur et toutes les adresses IP associées ont été bloqués contre toute modification.\nSi ceci est dû à une erreur, veuillez contacter un administrateur.\nVoici une brève description de la règle de filtrage antiabus ayant détecté votre action : $1", - "abusefilter-degrouped": "Cette action a été automatiquement identifiée comme nuisible.\nEn conséquence, elle a été interdite et, puisque votre compte est suspecté de compromission, tous vos droits ont été retirés.\nSi vous pensez que cela est dû à une erreur, veuillez contacter un bureaucrate avec une explication de cette action afin de rétablir vos droits.\nVoici une brève description de la règle de filtrage antiabus ayant détecté votre action : $1", - "abusefilter-autopromote-blocked": "Cette action a été automatiquement identifiée comme nuisible et a donc été empêchée.\nEn conséquence, à titre de mesure de sécurité, quelques privilèges accordés d'habitude pour les comptes établis ont été retirés temporairement de votre compte.\nVoici une brève description de la règle de filtrage antiabus ayant détecté votre action : $1", - "abusefilter-blocker": "Filtre antiabus", - "abusefilter-blockreason": "Bloqué automatiquement par le filtre antiabus.\nDescription de la règle associée : $1", - "abusefilter-degroupreason": "Droits automatiquement retirés par le filtre antiabus.\nDescription de la règle associée : $1", - "abusefilter-accountreserved": "Ce nom de compte est réservé à l'usage du filtre antiabus.", - "right-abusefilter-modify": "Modifier les filtres antiabus", - "right-abusefilter-view": "Voir les filtres antiabus", - "right-abusefilter-log": "Voir le journal des filtres antiabus", - "right-abusefilter-log-detail": "Voir les entrées détaillées du journal antiabus", - "right-abusefilter-private": "Voir les données privées dans le journal antiabus", - "right-abusefilter-private-log": "Afficher les détails confidentiels du journal d’accès de AbuseFilter", - "right-abusefilter-modify-restricted": "Modifier les filtres antiabus qui ont des actions restreintes", - "right-abusefilter-revert": "Révoquer toutes les modifications effectuées par un filtre antiabus donné", - "right-abusefilter-view-private": "Voir les filtres d'abus marqués comme privé", - "right-abusefilter-log-private": "Voir les entrées du journal des filtres antiabus marquées comme privées", - "right-abusefilter-hide-log": "Masquer des entrées dans le journal des abus", - "right-abusefilter-hidden-log": "Voir les entrées masquées du journal antiabus", - "right-abusefilter-modify-global": "Créer ou modifier les filtres globaux d'abus", - "action-abusefilter-modify": "modifier les filtres antiabus", - "action-abusefilter-view": "voir les filtres antiabus", - "action-abusefilter-log": "voir le journal des filtres antiabus", - "action-abusefilter-log-detail": "voir les entrées détaillées du journal des filtres antiabus", - "action-abusefilter-private": "voir les données privées dans le journal des filtres antiabus", - "action-abusefilter-private-log": "afficher le journal des accès aux détails confidentiels de AbuseFilter", - "action-abusefilter-modify-restricted": "modifier les filtres antiabus avec des actions restreintes", - "action-abusefilter-revert": "révoquer toutes les modifications selon un filtre antiabus donné", - "action-abusefilter-view-private": "voir les filtres antiabus marqués comme privés", - "action-abusefilter-log-private": "voir les entrées du journal des filtres antiabus marqués comme privés", - "abusefilter-log": "Journal des déclenchements du filtre antiabus", + "abusefilter-warning": "'''Avertissement :''' cette action a été automatiquement identifiée comme nuisible.\nLes actions non constructives seront rapidement annulées\net les modifications non constructives répétées ou outrageantes provoqueront le blocage de votre compte ou de votre adresse IP.\nSi vous estimez que cette action est constructive, vous pouvez la soumettre une nouvelle fois pour la confirmer.\nVoici une brève description de la règle de filtrage anti-abus ayant détecté votre action : $1", + "abusefilter-disallowed": "Cette action a été automatiquement identifiée comme nuisible et a donc été bloquée.\nSi vous pensez que votre action était constructive, veuillez contacter un administrateur et l’informer de ce que vous avez essayé de faire.\nVoici une brève description de la règle de filtrage anti-abus ayant détecté votre action : $1", + "abusefilter-blocked-display": "Cette action a été automatiquement identifiée comme nuisible\net vous avez déjà été empêché de l’exécuter.\nDe plus, pour protéger {{SITENAME}}, votre compte utilisateur et toutes les adresses IP associées ont été bloqués contre toute modification.\nSi ceci est dû à une erreur, veuillez contacter un administrateur.\nVoici une brève description de la règle de filtrage anti-abus ayant détecté votre action : $1", + "abusefilter-degrouped": "Cette action a été automatiquement identifiée comme nuisible.\nEn conséquence, elle a été interdite et, puisque votre compte est suspecté de compromission, tous vos droits ont été retirés.\nSi vous pensez que cela est dû à une erreur, veuillez contacter un bureaucrate avec une explication de cette action afin de rétablir vos droits.\nVoici une brève description de la règle de filtrage anti-abus ayant détecté votre action : $1", + "abusefilter-autopromote-blocked": "Cette action a été automatiquement identifiée comme nuisible et a donc été bloquée.\nEn conséquence, à titre de mesure de sécurité, quelques privilèges accordés d’habitude pour les comptes établis ont été retirés temporairement de votre compte.\nVoici une brève description de la règle de filtrage anti-abus déclenchée par votre action : $1", + "abusefilter-blocker": "Filtre anti-abus", + "abusefilter-blockreason": "Bloqué automatiquement par le filtre anti-abus.\nDescription de la règle déclenchée : $1", + "abusefilter-degroupreason": "Droits automatiquement retirés par le filtre anti-abus.\nDescription de la règle associée : $1", + "abusefilter-blockautopromotereason": "Autopromotion automatiquement différée par le filtre anti-abus.\nDescription de la règle : $1", + "abusefilter-accountreserved": "Ce nom de compte est réservé à l’usage du filtre anti-abus.", + "right-abusefilter-modify": "Créer ou modifier les filtres anti-abus", + "right-abusefilter-view": "Voir les filtres anti-abus", + "right-abusefilter-log": "Voir le journal des filtres anti-abus", + "right-abusefilter-log-detail": "Voir les entrées détaillées du journal anti-abus", + "right-abusefilter-privatedetails": "Voir les données privées dans le journal anti-abus", + "right-abusefilter-privatedetails-log": "Afficher les détails confidentiels du journal d’accès de AbuseFilter", + "right-abusefilter-modify-restricted": "Modifier les filtres anti-abus qui ont des actions restreintes", + "right-abusefilter-revert": "Révoquer toutes les modifications effectuées par un filtre anti-abus donné", + "right-abusefilter-view-private": "Voir les filtres anti-abus marqués comme privés", + "right-abusefilter-log-private": "Voir les entrées du journal des filtres anti-abus marqués comme privés", + "right-abusefilter-hide-log": "Masquer des entrées dans le journal anti-abus", + "right-abusefilter-hidden-log": "Voir les entrées masquées du journal anti-abus", + "right-abusefilter-modify-global": "Créer ou modifier des filtres anti-abus globaux", + "action-abusefilter-modify": "modifier les filtres anti-abus", + "action-abusefilter-view": "voir les filtres anti-abus", + "action-abusefilter-log": "voir le journal des filtres anti-abus", + "action-abusefilter-log-detail": "voir les entrées détaillées du journal des filtres anti-abus", + "action-abusefilter-privatedetails": "voir les données privées dans le journal des filtres anti-abus", + "action-abusefilter-privatedetails-log": "afficher le journal des accès aux détails confidentiels de AbuseFilter", + "action-abusefilter-modify-restricted": "modifier les filtres anti-abus avec des actions restreintes", + "action-abusefilter-revert": "révoquer toutes les modifications d’un filtre anti-abus donné", + "action-abusefilter-view-private": "voir les filtres anti-abus marqués comme privés", + "action-abusefilter-log-private": "voir les entrées du journal des filtres anti-abus marqués comme privés", + "action-abusefilter-hide-log": "masquer des enregistrements dans le journal anti-abus", + "action-abusefilter-hidden-log": "voir les enregistrements masqués du journal anti-abus", + "action-abusefilter-modify-global": "créer ou modifier les filtres globaux anti-abus", "abusefilter-log-summary": "Ce journal affiche une liste des actions détectées par les filtres.", - "abusefilter-log-search": "Rechercher dans le journal des filtres antiabus", - "abusefilter-log-search-user": "Utilisateur :", - "abusefilter-log-search-filter": "IDs de filtre (séparés par des barres verticales) :", - "abusefilter-log-search-title": "Titre :", - "abusefilter-log-search-wiki": "Wiki :", - "abusefilter-log-search-impact": "Impact:", + "abusefilter-log-search": "Rechercher dans le journal des filtres anti-abus", + "abusefilter-log-search-user": "Utilisateur :", + "abusefilter-log-search-group": "Groupe du filtre :", + "abusefilter-log-search-group-any": "Peu importe", + "abusefilter-log-search-filter": "ID de filtre :", + "abusefilter-log-search-filter-help": "Séparez à l’aide de barres verticales, préfixez avec « $1 » pour les filtres globaux", + "abusefilter-log-search-filter-help-central": "Séparer avec des barres verticales", + "abusefilter-log-search-title": "Titre :", + "abusefilter-log-search-wiki": "Wiki :", + "abusefilter-log-search-impact": "Impact :", "abusefilter-log-search-impact-all": "Toutes les actions", "abusefilter-log-search-impact-saved": "Modifications sauvegardées uniquement", "abusefilter-log-search-impact-not-saved": "Sans sauvegarder les modifications", - "abusefilter-log-search-entries-label": "Visibilité :", + "abusefilter-log-search-entries-label": "Visibilité :", "abusefilter-log-search-entries-all": "Toutes les entrées", "abusefilter-log-search-entries-hidden": "Entrées masquées uniquement", "abusefilter-log-search-entries-visible": "Entrées visibles uniquement", - "abusefilter-log-search-action-label": "Action déclenchée:", + "abusefilter-log-search-action-label": "Action déclenchée :", "abusefilter-log-search-action-other": "Autre", "abusefilter-log-search-action-any": "Tous", - "abusefilter-log-search-action-taken-label": "Mesure prise :", + "abusefilter-log-search-action-taken-label": "Mesure prise :", "abusefilter-log-search-action-taken-any": "N’importe laquelle", "abusefilter-log-search-submit": "Rechercher", - "abusefilter-log-entry": "$1 : $2 {{GENDER:$8|a déclenché}} un filtre antiabus, en {{GENDER:$8|effectuant}} l’action « $3 » sur $4.\nActions entreprises : $5 ;\nDescription du filtre : $6", - "abusefilter-log-entry-withdiff": "$1: $2 {{GENDER:$8|a déclenché}} un filtre antiabus, {{GENDER:$8|en effectuant}} l’action « $3 » sur $4.\nAction entreprise : $5 ;\nDescription du filtre : $6 ($7)", - "abusefilter-log-detailedentry-meta": "$1 : $2 {{GENDER:$9|a déclenché}} le $3, {{GENDER:$9|en effectuant}} l’action « $4 » sur $5.\nActions entreprises : $6 ;\nDescription du filtre : $7 ($8)", + "abusefilter-log-entry": "$1 : $2{{GENDER:$8|}} a déclenché un filtre anti-abus en effectuant l’action « $3 » sur $4.\nActions entreprises : $5 ;\nDescription du filtre : $6", + "abusefilter-log-entry-withdiff": "$1 : $2{{GENDER:$8|}} a déclenché un filtre anti-abus en effectuant l’action « $3 » sur $4.\nActions entreprises : $5 ;\nDescription du filtre : $6 ($7)", + "abusefilter-log-detailedentry-meta": "$1 : $2{{GENDER:$9|}} a déclenché le filtre $3 en effectuant l’action « $4 » sur $5.\nActions entreprises : $6 ;\nDescription du filtre : $7 ($8)", "abusefilter-log-detailedentry-global": "filtre global $1", - "abusefilter-log-detailedentry-local": "filtre antiabus $1", + "abusefilter-log-detailedentry-local": "filtre $1", "abusefilter-log-detailslink": "détails", "abusefilter-log-diff": "diff", "abusefilter-log-hidelink": "ajuster la visibilité", - "abusefilter-log-details-legend": "Détails pour l'entrée $1 du journal", + "abusefilter-log-details-legend": "Détails pour l’entrée $1 du journal", "abusefilter-log-details-var": "Variable", "abusefilter-log-details-val": "Valeur", - "abusefilter-log-details-vars": "Paramètres de l'action", - "abusefilter-log-details-private": "Données confidentiels du journal", - "abusefilter-log-details-ip": "Adresse IP d'origine", + "abusefilter-log-details-vars": "Paramètres de l’action", + "abusefilter-log-details-privatedetails": "Détails du journal confidentiel", + "abusefilter-log-details-ip": "Adresse IP d’origine", "abusefilter-log-details-checkuser": "Vérifier l’utilisateur", "abusefilter-log-noactions": "néant", + "abusefilter-log-noactions-filter": "Aucun", "abusefilter-log-details-diff": "Changements faits lors de la modification", "abusefilter-log-linkoncontribs": "journal des abus", - "abusefilter-log-linkoncontribs-text": "Journal des abus de ce{{GENDER:$1|t utilisateur|tte utilisatrice}}", + "abusefilter-log-linkoncontribs-text": "Journal des abus de cet{{GENDER:$1||te}} utilisat{{GENDER:$1|eur|rice}}", "abusefilter-log-linkonhistory": "voir le journal des abus", "abusefilter-log-linkonhistory-text": "Voir le journal des abus pour cette page", - "abusefilter-log-hidden": "(entrée masquée)", - "abusefilter-log-hidden-implicit": "(masquée car la version a été supprimée)", - "abusefilter-log-cannot-see-details": "Vous n'avez pas le droit de voir les détails de cette entrée.", - "abusefilter-log-cannot-see-private-details": "Vous n’avez pas le droit de voir les détails confidentiels de cette entrée.", + "abusefilter-log-linkonundelete": "voir le journal des abus", + "abusefilter-log-linkonundelete-text": "Voir le journal des abus pour cette page", + "abusefilter-log-hidden-implicit": "(masqué car la version a été supprimée)", + "abusefilter-log-cannot-see-details": "Vous n’avez pas le droit de voir les détails de cette entrée.", + "abusefilter-log-cannot-see-privatedetails": "Vous n’avez pas le droit de voir les détails privés de cette entrée.", "abusefilter-log-nonexistent": "Il n’existe pas d’entrée associée à l’identifiant spécifié.", - "abusefilter-log-details-hidden": "Vous ne pouvez pas afficher les détails pour cette entrée parce qu'elle est cachée à la vue du public.", - "abusefilter-log-details-hidden-implicit": "Vous ne pouvez pas afficher les détails de cette entrée parce que sa révision associée n’est pas visible publiquement.", - "abusefilter-log-private-not-included": "Un ou plusieurs des IDs de filtre que vous avez spécifiés sont privés. Comme vous n’êtes pas autorisé à voir les détails des filtres privés, ces filtres n’ont pas été inclus dans la recherche.", - "abusefilter-log-hide-legend": "Masquer l'entrée dans les journaux", - "abusefilter-log-hide-id": "Identifiant de l'entrée de journal :", + "abusefilter-log-details-hidden": "Vous ne pouvez pas afficher les détails pour cette entrée parce qu’elle est cachée à la vue du public.", + "abusefilter-log-details-hidden-implicit": "Vous ne pouvez pas afficher les détails de cette entrée parce que sa révision associée est cachée à la vue du public.", + "abusefilter-log-private-not-included": "Un ou plusieurs IDs de filtre que vous avez spécifiés sont privés. Comme vous n’êtes pas autorisé à voir les détails des filtres privés, ces filtres n’ont pas été inclus dans la recherche.", + "abusefilter-log-hide-legend": "Masquer l’entrée dans les journaux", + "abusefilter-log-hide-id": "Identifiant de l’entrée de journal :", "abusefilter-log-hide-hidden": "Masquer cette entrée à la vue du public", - "abusefilter-log-hide-reason": "Motif :", - "abusefilter-log-hide-reason-other": "Motif autre ou supplémentaire :", - "abusefilter-log-hide-forbidden": "Vous n'avez pas le droit de masquer des entrées du journal des abus.", - "abusefilter-log-entry-suppress": "$1 {{GENDER:$2|a masqué}} $3", - "abusefilter-log-entry-unsuppress": "$1 {{GENDER:$2|a démasqué}} $3", - "logentry-abusefilter-hit": "$1 {{GENDER:$2|a déclenché}} $4, {{GENDER:$2|en effectuant}} l’action « $5 » sur $3. Actions entreprises : $6 ($7)", - "log-action-filter-abusefilter": "Type de modification de filtre :", + "abusefilter-log-hide-reason": "Motif :", + "abusefilter-log-hide-reason-other": "Motif autre ou supplémentaire :", + "abusefilter-log-hide-forbidden": "Vous n’avez pas le droit de masquer des entrées du journal des abus.", + "abusefilter-log-entry-suppress": "$1{{GENDER:$2|}} a masqué $3", + "abusefilter-log-entry-unsuppress": "$1{{GENDER:$2|}} a démasqué $3", + "logentry-abusefilter-hit": "$1{{GENDER:$2|}} a déclenché le filtre $4, en effectuant l’action « $5 » sur $3. Actions entreprises : $6 ($7)", + "log-action-filter-abusefilter": "Type de modification de filtre :", "log-action-filter-abusefilter-create": "Création de nouveaux filtres", - "log-action-filter-abusefilter-modify": "Filtrer les notifications", + "log-action-filter-abusefilter-modify": "Modification de filtre", "log-action-filter-suppress-abuselog": "Suppression du journal anti-abus", - "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|a accédé}} aux détails confidentiels pour $3", + "log-action-filter-rights-blockautopromote": "Blocage d’autopromotion", + "log-action-filter-rights-restoreautopromote": "Rétablissement d’autopromotion", + "logentry-abusefilterprivatedetails-access": "$1{{GENDER:$2|}} a accédé aux détails confidentiels pour $3", + "logentry-rights-blockautopromote": "{{GENDER:$2|$1}} a bloqué l’autopromotion de {{GENDER:$4|$3}} pour une période de $5", + "logentry-rights-restoreautopromote": "$1{{GENDER:$2|}} a rétabli la possibilité d’autopromotion de $3{{GENDER:$4|}}", "abusefilterprivatedetails-log-name": "Détails confidentiels du journal d’accès de AbuseFilter", - "abusefilter-management": "Gestion du filtre antiabus", "abusefilter-list": "Tous les filtres", - "abusefilter-list-id": "N° filtre", + "abusefilter-list-id": "ID du filtre", "abusefilter-list-pattern": "Motif", "abusefilter-list-status": "État", "abusefilter-list-public": "Description publique", @@ -153,7 +170,7 @@ "abusefilter-list-hitcount": "Nombre de détections", "abusefilter-list-edit": "Modifier", "abusefilter-list-details": "Détails", - "abusefilter-list-limit": "Nombre par page :", + "abusefilter-list-limit": "Nombre par page :", "abusefilter-list-lastmodified": "Dernière modification", "abusefilter-list-group": "Groupe du filtre", "abusefilter-hidden": "Privé", @@ -164,129 +181,146 @@ "abusefilter-throttled": "limité", "abusefilter-hitcount": "$1 détection{{PLURAL:$1||s}}", "abusefilter-new": "Créer un nouveau filtre", + "abusefilter-import-button": "Importer un filtre", "abusefilter-return": "Revenir à la gestion des filtres", "abusefilter-status-global": "Global", "abusefilter-list-options": "Options", - "abusefilter-list-options-deleted": "Filtres supprimés :", + "abusefilter-list-options-deleted": "Filtres supprimés :", "abusefilter-list-options-deleted-only": "Ne montrer que les filtres supprimés", "abusefilter-list-options-deleted-hide": "Masquer les filtres supprimés", "abusefilter-list-options-deleted-show": "Inclure les filtres supprimés", - "abusefilter-list-options-scope": "Afficher les filtres :", + "abusefilter-list-options-scope": "Afficher les filtres :", "abusefilter-list-options-scope-local": "Règles locales uniquement", "abusefilter-list-options-scope-global": "Règles globales uniquement", "abusefilter-list-options-scope-all": "Règles locales et globales", - "abusefilter-list-options-further-options": "Autres options :", + "abusefilter-list-options-further-options": "Autres options :", "abusefilter-list-options-hidedisabled": "Masquer les filtres désactivés", "abusefilter-list-options-hideprivate": "Cacher les filtres privés", - "abusefilter-list-options-searchfield": "Rechercher dans les règles :", + "abusefilter-list-options-searchfield": "Rechercher dans les règles :", "abusefilter-list-options-searchpattern": "Insérer un motif", - "abusefilter-list-options-searchoptions": "Mode de recherche :", + "abusefilter-list-options-searchoptions": "Mode de recherche :", "abusefilter-list-options-search-like": "Requête simple", - "abusefilter-list-options-search-rlike": "Expression régulière", - "abusefilter-list-options-search-irlike": "Expression régulière insensible à la casse", - "abusefilter-list-regexerror": "Une erreur s’est produite lors de la recherche : Erreur de syntaxe de l’expression régulière.", + "abusefilter-list-options-search-rlike": "Expression rationnelle", + "abusefilter-list-options-search-irlike": "Expression rationnelle insensible à la casse", + "abusefilter-list-invalid-searchmode": "Le mode de recherche spécifié n’est pas valide.", + "abusefilter-list-regexerror": "Une erreur s’est produite lors de la recherche : erreur de syntaxe de l’expression rationnelle.", "abusefilter-list-options-submit": "Mettre à jour", - "abusefilter-tools-text": "Voici quelques outils qui peuvent être utiles dans la formulation et le déboguage des filtres antiabus.", - "abusefilter-tools-expr": "Testeur d'expressions", + "abusefilter-tools-text": "Voici quelques outils qui peuvent être utiles dans la formulation et le débogage des filtres anti-abus.", + "abusefilter-tools-expr": "Testeur d’expressions", "abusefilter-tools-submitexpr": "Évaluer", - "abusefilter-tools-reautoconfirm": "Rétablir l'état autoconfirmé", - "abusefilter-tools-reautoconfirm-user": "Utilisateur :", + "abusefilter-tools-syntax-error": "Le filtre a une syntaxe non valide.", + "abusefilter-tools-reautoconfirm": "Rétablir l’état autoconfirmé", + "abusefilter-tools-reautoconfirm-user": "Utilisateur :", "abusefilter-tools-reautoconfirm-submit": "Autoconfirmer à nouveau", - "abusefilter-reautoconfirm-none": "Le statut autoconfirmé de {{GENDER:$1|cet utilisateur|cette utilisatrice}} n'a pas été suspendu.", - "abusefilter-reautoconfirm-notallowed": "Vous ne pouvez pas rétablir l'état autoconfirmé.", - "abusefilter-reautoconfirm-done": "L'état autoconfirmé du compte utilisateur a été rétabli", - "abusefilter-status": "{{PLURAL:$1|Dans la dernière action|Parmi les $1 dernières actions}}, $2 ($3 %) {{PLURAL:$2|a|ont}} atteint la limite des $4 conditions autorisées. Et $5 ($6 %) {{PLURAL:$5|a été détectée|ont été détectées}} par l'un des filtres actuellement activés.", - "abusefilter-edit": "Modifier le filtre d'abus", + "abusefilter-tools-restoreautopromote": "Autopromotion rétablie via les outils AbuseFilter.", + "abusefilter-reautoconfirm-none": "Le statut autoconfirmé de cet{{GENDER:$1||te}} utilisat{{GENDER:$1|eur|rice}} n’a pas été suspendu.", + "abusefilter-reautoconfirm-notallowed": "Vous n’êtes pas habilité à rétablir l’état autoconfirmé.", + "abusefilter-reautoconfirm-done": "L’état autoconfirmé du compte utilisateur a été rétabli", + "abusefilter-status": "{{PLURAL:$1|Dans la dernière action|Parmi les $1 dernières actions}}, $2 ($3 %) {{PLURAL:$2|a|ont}} atteint la limite des $4 conditions autorisées. Et $5 ($6 %) {{PLURAL:$5|a été détectée|ont été détectées}} par au moins l’un des filtres actuellement activés.", + "abusefilter-edit": "Modifier le filtre anti-abus", "abusefilter-edit-subtitle": "Modification du filtre $1", "abusefilter-edit-subtitle-new": "Créer un filtre", - "abusefilter-edit-token-not-match": "Les modifications n'ont pas été enregistrées ! Veuillez sauvegarder à nouveau.", - "abusefilter-edit-oldwarning": "<strong>Vous êtes en train de modifier une ancienne version de ce filtre.\nLes statistiques affichées concernent la version la plus récente de celui-ci.\nSi vous enregistrez vos modifications, vous allez écraser tous les changements intervenus depuis la version que vous modifiez.</strong> •\n[[Special:AbuseFilter/history/$2|Revenir à l’historique de ce filtre]]", - "abusefilter-edit-status-label": "Statistiques :", - "abusefilter-edit-status": "{{PLURAL:$1|Dans la dernière action|Parmi les $1 dernières actions}}, ce filtre a été déclenché $2 fois ($3 %).", - "abusefilter-edit-status-profile": "{{PLURAL:$1|Dans la dernière action|Parmi les $1 dernières actions}}, ce filtre a été déclenché $2 fois ($3 %).\nEn moyenne, la durée d'exécution de ce filtre est de $4 ms et il utilise $5 condition{{PLURAL:$5||s}} de la limite des conditions.", - "abusefilter-edit-throttled-warning": "'''Attention :''' Ce filtre a été marqué automatiquement comme nuisible. Par mesure de sûreté, les actions suivantes ne seront pas exécutées ($1). Veuillez relire et [[mw:Extension:AbuseFilter/Conditions|optimiser]] vos conditions pour supprimer cette restriction", + "abusefilter-edit-token-not-match": "Les modifications n’ont pas été enregistrées ! Veuillez sauvegarder à nouveau.", + "abusefilter-edit-oldwarning": "<strong>Vous êtes en train de modifier une ancienne version de ce filtre.\nLes statistiques affichées concernent la version la plus récente de celui-ci.\nSi vous enregistrez vos modifications, vous allez écraser tous les changements intervenus depuis la version que vous modifiez.</strong> •\n[[Special:AbuseFilter/history/$2|Revenir à l’historique de ce filtre]]", + "abusefilter-edit-oldwarning-view": "<strong>Vous visualisez une ancienne version de ce filtre.\nLes statistiques citées concernent la plus récente version du filtre.</strong> ●\n[[Special:AbuseFilter/history/$2|Retour à l’historique de ce filtre]].", + "abusefilter-edit-status-label": "Statistiques :", + "abusefilter-edit-status": "{{PLURAL:$1|Dans la dernière action|Parmi les $1 dernières actions}}, ce filtre a été déclenché $2 fois ($3 %).\nEn moyenne, sa durée d’exécution est de $4 ms, et il consomme $5 {{PLURAL:$5|condition|conditions}} de la limite de conditions.", + "abusefilter-edit-throttled-warning": "'''Attention :''' ce filtre a été marqué automatiquement comme nuisible. Par mesure de sûreté, les actions suivantes ne seront pas exécutées ($1). Veuillez relire et [[mw:Extension:AbuseFilter/Conditions|optimiser]] vos conditions pour supprimer cette restriction", "abusefilter-edit-new": "Nouveau filtre", "abusefilter-edit-save": "Enregistrer le filtre", - "abusefilter-edit-id": "N° filtre :", - "abusefilter-edit-switch-editor": "Basculer d’éditeur", + "abusefilter-edit-id": "Nº du filtre :", + "abusefilter-edit-switch-editor": "Changer d’éditeur", "abusefilter-edit-description": "Description :\n: ''(visible publiquement)''", "abusefilter-edit-field-description": "description", - "abusefilter-edit-group": "Groupe du filtre :", - "abusefilter-edit-flags": "Drapeaux :", + "abusefilter-edit-group": "Groupe du filtre :", + "abusefilter-edit-flags": "Drapeaux :", "abusefilter-edit-enabled": "Activer ce filtre", "abusefilter-edit-deleted": "Marquer comme supprimé", - "abusefilter-edit-hidden": "Cacher les détails de ce filtre à la vue publique", + "abusefilter-edit-hidden": "Masquer les détails de ce filtre dans la vue publique", "abusefilter-edit-global": "Filtre global", - "abusefilter-edit-rules": "Conditions :", + "abusefilter-edit-rules": "Conditions :", "abusefilter-edit-field-conditions": "conditions", - "abusefilter-edit-notes": "Notes :", + "abusefilter-edit-notes": "Notes :", "abusefilter-edit-lastmod": "Dernière modification du filtre :", "abusefilter-edit-lastmod-text": "$1 par $2", - "abusefilter-edit-hitcount": "Nombre de détections du filtre :", - "abusefilter-edit-consequences": "Actions entreprises si élément trouvé", - "abusefilter-edit-action-warn": "Déclencher ces actions après avoir donné un avertissement à l'utilisateur", - "abusefilter-edit-action-disallow": "Empêcher l'utilisateur d'effectuer l'action en question", - "abusefilter-edit-action-blockautopromote": "Révoquer l'état autoconfirmé du compte utilisateur", - "abusefilter-edit-action-degroup": "Retirer l'utilisateur de tous les groupes privilégiés", + "abusefilter-edit-hitcount": "Nombre de détections :", + "abusefilter-edit-consequences": "Actions entreprises en cas de détection", + "abusefilter-edit-action-warn": "Déclencher ces actions après avoir présenté un avertissement à l’utilisateur", + "abusefilter-edit-action-disallow": "Empêcher l’utilisateur d’effectuer l’action en question", + "abusefilter-edit-action-blockautopromote": "Révoquer l’état autoconfirmé du compte utilisateur", + "abusefilter-edit-action-degroup": "Retirer l’utilisateur de tous les groupes privilégiés", "abusefilter-edit-action-block": "Bloquer en écriture l’utilisateur ou l’adresse IP", "abusefilter-edit-action-blocktalk": "Empêcher l’utilisateur ou l’adresse IP de modifier sa propre page de discussion", - "abusefilter-edit-action-throttle": "Déclencher les actions uniquement si l'utilisateur a dépassé un taux limite", + "abusefilter-edit-action-throttle": "Déclencher les actions uniquement si l’utilisateur a dépassé un taux limite", "abusefilter-edit-action-rangeblock": "Bloquer la plage IP respective d’où provient l’utilisateur.", - "abusefilter-edit-action-tag": "Baliser la modification pour une relecture ultérieure.", - "abusefilter-edit-throttle-count": "Nombre d'actions autorisées :", - "abusefilter-edit-throttle-period": "Laps de temps (en secondes) :", - "abusefilter-edit-throttle-groups": "Grouper la modération par :", - "abusefilter-edit-throttle-ip": "Adresse IP", - "abusefilter-edit-throttle-user": "Compte utilisateur", - "abusefilter-edit-throttle-range": "intervalle /16", - "abusefilter-edit-throttle-creationdate": "Référence horaire du serveur lors de la création du compte", - "abusefilter-edit-throttle-editcount": "Compteur de modifications", - "abusefilter-edit-throttle-site": "Tout le site", - "abusefilter-edit-throttle-page": "Page", - "abusefilter-throttle-details": "Permettre $1 {{PLURAL:$1|une action|des actions}} toutes les {{PLURAL:$2|secondes|$2 secondes}}, en groupant les goulots par : $3", - "abusefilter-edit-warn-message": "Message système à utiliser pour l'avertissement :", + "abusefilter-edit-action-tag": "Baliser la modification pour une relecture ultérieure", + "abusefilter-edit-throttle-count": "Nombre d’actions autorisées :", + "abusefilter-edit-throttle-period": "Laps de temps (en secondes) :", + "abusefilter-edit-throttle-groups": "Grouper la limitation par :", + "abusefilter-edit-throttle-groups-help": "Voir $1.", + "abusefilter-edit-throttle-groups-help-text": "la documentation sur mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Séparer avec des virgules pour des conditions simultanées (conjointes avec un ET) ou avec des sauts de ligne pour des conditions inclusives (jointes avec un OU)", + "abusefilter-edit-throttle-placeholder": "Séparer avec des virgules les conditions simultanées (conjointes avec un ET) ou insérez une par une les conditions inclusives (jointes avec un OU)", + "abusefilter-throttle-ip": "Adresse IP", + "abusefilter-throttle-user": "compte utilisateur", + "abusefilter-throttle-range": "plage /16", + "abusefilter-throttle-creationdate": "date de création du compte", + "abusefilter-throttle-editcount": "compteur de modifications", + "abusefilter-throttle-site": "tout le site", + "abusefilter-throttle-page": "page", + "abusefilter-throttle-none": "(aucun)", + "abusefilter-throttle-details": "Permettre $1 action{{PLURAL:$1||s}} {{PLURAL:$2|par seconde|toutes les $2 secondes}}, en groupant les limites par : $3", + "abusefilter-edit-warn-message": "Message système à utiliser pour l’avertissement :", "abusefilter-edit-warn-other": "Autre message", - "abusefilter-edit-warn-other-label": "Nom de page d’un autre message :\n:''(sans le préfixe « MédiaWiki »)''", - "abusefilter-edit-warn-actions": "Actions :", - "abusefilter-edit-warn-preview": "Afficher/Masquer l'aperçu du message sélectionné", + "abusefilter-edit-warn-other-label": "Nom de page d’un autre message :\n: ''(sans le préfixe « MediaWiki: »)''", + "abusefilter-edit-warn-actions": "Actions :", + "abusefilter-edit-warn-preview": "Afficher/masquer l’aperçu du message sélectionné", "abusefilter-edit-warn-edit": "Créer ou modifier le message sélectionné", - "abusefilter-edit-disallow-message": "Message système à utiliser pour interdire :", + "abusefilter-edit-disallow-message": "Message système à utiliser pour interdire :", "abusefilter-edit-disallow-other": "Autre message", - "abusefilter-edit-disallow-other-label": "Nom de la page d’un autre message :\n:''(sans le préfixe « MediaWiki: »)''", - "abusefilter-edit-disallow-actions": "Actions :", - "abusefilter-edit-disallow-preview": "Afficher/Masquer l’aperçu du message sélectionné", + "abusefilter-edit-disallow-other-label": "Nom de la page d’un autre message :\n: ''(sans le préfixe « MediaWiki: »)''", + "abusefilter-edit-disallow-actions": "Actions :", + "abusefilter-edit-disallow-preview": "Afficher/masquer l’aperçu du message sélectionné", "abusefilter-edit-disallow-edit": "Créer/Modifier le message sélectionné", - "abusefilter-edit-tag-tag": "[[Special:Tags|Balises]] à appliquer :", - "abusefilter-edit-tag-placeholder": "Ajouter des balises (une par une, séparées par une virgule)", + "abusefilter-edit-tag-tag": "[[Special:Tags|Balises]] à appliquer :", + "abusefilter-edit-tag-placeholder": "Ajouter des balises (une par une ou séparées par une virgule)", "abusefilter-edit-tag-hidden-placeholder": "Ajouter des balises (séparées par des virgules)", - "abusefilter-edit-block-anon-durations": "Durée de blocage pour les utilisateurs anonymes :", - "abusefilter-edit-block-user-durations": "Durée de blocage pour les utilisateurs enregistrés :", + "abusefilter-edit-block-anon-durations": "Durée de blocage pour les utilisateurs anonymes :", + "abusefilter-edit-block-user-durations": "Durée de blocage pour les utilisateurs enregistrés :", "abusefilter-block-anon": "Bloquer les utilisateurs anonymes", "abusefilter-block-user": "bloquer les utilisateurs enregistrés", "abusefilter-block-talk": "page de discussion bloquée", - "abusefilter-edit-denied": "Vous ne pouvez pas voir les détails de ce filtre, parce qu’il est caché à la vue du public", + "abusefilter-edit-denied": "Vous ne pouvez pas voir les détails de ce filtre, parce qu’il est caché à la vue du public.", "abusefilter-edit-main": "Paramètres du filtre", "abusefilter-edit-done-subtitle": "Filtre modifié", - "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Vos modifications]] au [[Special:AbuseFilter/$1|filtre $3]] ont été enregistrées.", - "abusefilter-edit-badsyntax": "Le filtre que vous avez spécifié comporte une erreur de syntaxe.\nLe résultat de l'analyseur syntaxique était : <pre>$1</pre>", - "abusefilter-edit-missingfields": "Les champs suivants sont nécessaires et doivent être remplis : $1", + "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Vos modifications]] du [[Special:AbuseFilter/$1|filtre $3]] ont été enregistrées.", + "abusefilter-edit-badsyntax": "Le filtre que vous avez spécifié comporte une erreur de syntaxe.\nLe résultat de l’analyseur syntaxique était : <pre>$1</pre>", + "abusefilter-edit-missingfields": "Les champs suivants sont nécessaires et doivent être remplis : $1", "abusefilter-edit-deleting-enabled": "Vous ne pouvez pas marquer un filtre actif comme supprimé.", - "abusefilter-edit-restricted": "Vous ne pouvez pas modifier ce filtre parce qu'il contient une ou plusieurs actions restreintes.\nDemandez à un utilisateur autorisé à ajouter des actions restreintes d'effectuer la modification pour vous.", + "abusefilter-edit-restricted": "Vous ne pouvez pas modifier ce filtre parce qu’il contient une ou plusieurs actions restreintes.\nDemandez à un autre utilisateur, autorisé à ajouter des actions restreintes, d’effectuer la modification pour vous.", "abusefilter-edit-viewhistory": "Voir l’historique de ce filtre", - "abusefilter-edit-history": "Historique :", + "abusefilter-edit-history": "Historique :", "abusefilter-edit-check": "Vérifier la syntaxe", - "abusefilter-edit-badfilter": "Le filtre que vous avez spécifié n'existe pas", + "abusefilter-edit-badfilter": "Le filtre que vous avez spécifié n’existe pas", "abusefilter-edit-revert": "Révoquer les actions entreprises par ce filtre", - "abusefilter-edit-tools": "Outils :", + "abusefilter-edit-tools": "Outils :", "abusefilter-edit-test-link": "Tester ce filtre sur les modifications récentes", "abusefilter-edit-export": "Exporter ce filtre vers un autre wiki", "abusefilter-edit-syntaxok": "Aucune erreur de syntaxe détectée.", - "abusefilter-edit-syntaxerr": "Erreur de syntaxe détectée : $1", - "abusefilter-edit-bad-tags": "Au moins une des balises que vous avez spécifiées n’est pas valide.\nLes balises doivent être courtes, ne pas contenir de caractères spéciaux, ni être réservées par d’autres logiciels. Essayez en choisissant un autre nom de balise", - "abusefilter-edit-notallowed": "Vous n'êtes pas autorisé à créer ou modifier des filtres antiabus", - "abusefilter-edit-notallowed-global": "Vous n'avez pas le droit de créer ou de modifier les filtres globaux d'abus", - "abusefilter-edit-notallowed-global-custom-msg": "Les messages d’avertissement personnalisés ne sont pas pris en charge pour les filtres globaux", - "abusefilter-edit-builder-select": "Sélectionnez une option pour l'ajouter au curseur", + "abusefilter-edit-syntaxerr": "Erreur de syntaxe détectée : $1", + "abusefilter-edit-warn-leave": "En quittant cette page vous perdrez toute modification apportée à ce filtre.", + "abusefilter-edit-bad-tags": "Au moins une des balises que vous avez spécifiées n’est pas valide.\nLes balises doivent être courtes, ne pas contenir de caractères spéciaux, ni être réservées par d’autres logiciels. Essayez en choisissant un autre nom de balise.", + "abusefilter-edit-notallowed": "Vous n’êtes pas autorisé{{GENDER:||e}} à créer ou à modifier des filtres anti-abus.", + "abusefilter-edit-notallowed-global": "Vous n’êtes pas autorisé{{GENDER:||e}} à créer ou à modifier des filtres anti-abus globaux.", + "abusefilter-edit-notallowed-global-custom-msg": "Les messages personnalisés d’avertissement ou d’interdiction ne sont pas pris en charge pour les filtres globaux", + "abusefilter-edit-invalid-warn-message": "Le message d’avertissement ne peut pas être laissé vide.", + "abusefilter-edit-invalid-disallow-message": "Le message d’interdiction ne peut pas être laissé vide.", + "abusefilter-edit-invalid-throttlecount": "Le compteur d’action de limitation doit être un entier positif.", + "abusefilter-edit-invalid-throttleperiod": "La période de limitation doit être un entier positif.", + "abusefilter-edit-empty-throttlegroups": "Au moins un groupe de limitation doit être sélectionné.", + "abusefilter-edit-duplicated-throttlegroups": "Les groupes de limitation ne doivent avoir aucun doublon.", + "abusefilter-edit-invalid-throttlegroups": "Les groupes de limitations spécifiés ne sont pas valides.", + "abusefilter-edit-builder-select": "Sélectionnez une option pour l’ajouter à la position du curseur", "abusefilter-edit-builder-group-op-arithmetic": "Opérateurs arithmétiques", "abusefilter-edit-builder-op-arithmetic-addition": "Addition (+)", "abusefilter-edit-builder-op-arithmetic-subtraction": "Soustraction (-)", @@ -298,7 +332,7 @@ "abusefilter-edit-builder-op-comparison-equal": "Valeur égale à (==)", "abusefilter-edit-builder-op-comparison-equal-strict": "Valeur et type égaux à (===)", "abusefilter-edit-builder-op-comparison-notequal": "Valeur non égale à (!=)", - "abusefilter-edit-builder-op-comparison-notequal-strict": "Valeur et type différents de (!==)", + "abusefilter-edit-builder-op-comparison-notequal-strict": "Valeur et type non égaux à (!==)", "abusefilter-edit-builder-op-comparison-lt": "Inférieur à (<)", "abusefilter-edit-builder-op-comparison-gt": "Supérieur à (>)", "abusefilter-edit-builder-op-comparison-lte": "Inférieur ou égal à (<=)", @@ -310,12 +344,13 @@ "abusefilter-edit-builder-group-misc": "Divers", "abusefilter-edit-builder-misc-in": "Contenu dans la chaîne de caractères (in)", "abusefilter-edit-builder-misc-like": "Correspond au motif (like)", - "abusefilter-edit-builder-misc-rlike": "Correspond à l'expression rationnelle (rlike)", - "abusefilter-edit-builder-misc-irlike": "Filtre avec des expressions rationnelles, sans tenir compte de la casse (irlike)", + "abusefilter-edit-builder-misc-rlike": "Correspond à l’expression rationnelle (rlike)", + "abusefilter-edit-builder-misc-irlike": "Correspond à l’expression rationnelle, en ignorant la casse (irlike)", "abusefilter-edit-builder-misc-contains": "La chaîne de gauche contient la chaîne de droite (contains)", "abusefilter-edit-builder-misc-stringlit": "Chaîne littérale (\"\")", "abusefilter-edit-builder-misc-tern": "Opérateur ternaire (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Conditionnel (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Conditionnel (si X alors Y sinon Z fin)", + "abusefilter-edit-builder-misc-cond-short": "Conditionnel court (si X alors Y fin)", "abusefilter-edit-builder-group-funcs": "Fonctions", "abusefilter-edit-builder-funcs-length": "Longueur de la chaîne de caractères (length)", "abusefilter-edit-builder-funcs-lcase": "Convertir en minuscules (lcase)", @@ -323,24 +358,24 @@ "abusefilter-edit-builder-funcs-ccnorm": "Normaliser les caractères prêtant à confusion (ccnorm)", "abusefilter-edit-builder-funcs-ccnorm-contains-any": "Normaliser et rechercher dans une chaîne de multiples sous-chaînes avec le critère OU (ccnorm_contains_any)", "abusefilter-edit-builder-funcs-ccnorm-contains-all": "Normaliser et rechercher dans une chaîne des multiples sous-chaînes avec le critère ET (ccnorm_contains_all)", - "abusefilter-edit-builder-funcs-rmdoubles": "Enlever les caractères doubles (rmdoubles)", + "abusefilter-edit-builder-funcs-rmdoubles": "Enlever les caractères redoublés (rmdoubles)", "abusefilter-edit-builder-funcs-specialratio": "Caractères spéciaux / total des caractères (specialratio)", "abusefilter-edit-builder-funcs-norm": "Normaliser (norm)", - "abusefilter-edit-builder-funcs-count": "Nombre d'occurrences de la chaîne de caractères X dans la chaîne Y (count)", - "abusefilter-edit-builder-funcs-rcount": "Nombre de fois que l'expression rationnelle X apparaît dans la chaîne Y (rcount)", + "abusefilter-edit-builder-funcs-count": "Nombre d’occurrences de la chaîne de caractères X dans la chaîne Y (count)", + "abusefilter-edit-builder-funcs-rcount": "Nombre de fois où l’expression rationnelle X apparaît dans la chaîne Y (rcount)", "abusefilter-edit-builder-funcs-get_matches": "Tableau de correspondance d’expressions rationnelles avec un texte pour chaque groupe de capture (get_matches)", "abusefilter-edit-builder-funcs-rmwhitespace": "Supprimer les espaces (rmwhitespace)", "abusefilter-edit-builder-funcs-rmspecials": "Supprimer les caractères spéciaux (rmspecials)", - "abusefilter-edit-builder-funcs-ip_in_range": "L'adresse IP est-elle dans la plage ? (ip_in_range)", + "abusefilter-edit-builder-funcs-ip_in_range": "L’adresse IP est-elle dans la plage ? (ip_in_range)", "abusefilter-edit-builder-funcs-contains-any": "Rechercher dans une chaîne des multiples sous-chaînes avec le critère OU (contains_any).", "abusefilter-edit-builder-funcs-contains-all": "Rechercher dans une chaîne des multiples sous-chaînes avec le critère ET (contains_all).", - "abusefilter-edit-builder-funcs-equals-to-any": "Vérifier si un argument donné est égal (===) à l'un des arguments suivants (equals_to_any)", + "abusefilter-edit-builder-funcs-equals-to-any": "Vérifier si un argument donné est égal (===) à l’un des arguments suivants (equals_to_any)", "abusefilter-edit-builder-funcs-substr": "Sous-chaîne (substr)", "abusefilter-edit-builder-funcs-strpos": "Position de la sous-chaîne dans la chaîne (strpos)", "abusefilter-edit-builder-funcs-str_replace": "Remplacer la sous-chaîne par la chaîne (str_replace)", - "abusefilter-edit-builder-funcs-rescape": "Échapper la chaîne comme littérale dans l'expression rationnelle (rescape)", + "abusefilter-edit-builder-funcs-rescape": "Échapper la chaîne comme littérale dans l’expression rationnelle (rescape)", "abusefilter-edit-builder-funcs-set_var": "Définir la variable (set_var)", - "abusefilter-edit-builder-funcs-sanitize": "Normaliser les entités HTML en caractères unicode (assainir)", + "abusefilter-edit-builder-funcs-sanitize": "Normaliser les entités HTML en caractères Unicode (assainir)", "abusefilter-edit-builder-group-vars": "Variables", "abusefilter-edit-builder-vars-accountname": "Nom du compte (lors de la création du compte)", "abusefilter-edit-builder-vars-timestamp": "Horodatage Unix de la modification", @@ -353,71 +388,73 @@ "abusefilter-edit-builder-vars-oldsize": "Ancienne taille de la page", "abusefilter-edit-builder-vars-old-content-model": "Ancien modèle de contenu", "abusefilter-edit-builder-vars-new-content-model": "Nouveau modèle de contenu", - "abusefilter-edit-builder-vars-removedlines": "Lignes supprimées lors de la modification", + "abusefilter-edit-builder-vars-removedlines": "Lignes supprimées par la modification", "abusefilter-edit-builder-vars-summary": "Résumé/motif de la modification", - "abusefilter-edit-builder-vars-page-id": "Numéro de la page", + "abusefilter-edit-builder-vars-page-id": "ID de la page", "abusefilter-edit-builder-vars-page-ns": "Espace de noms de la page", - "abusefilter-edit-builder-vars-page-title": "Titre de la page (sans l'espace de noms)", + "abusefilter-edit-builder-vars-page-title": "Titre de la page (sans l’espace de noms)", "abusefilter-edit-builder-vars-page-prefixedtitle": "Titre complet de la page", "abusefilter-edit-builder-vars-page-age": "Age de la page (en secondes)", - "abusefilter-edit-builder-vars-movedfrom-id": "Numéro de la page d'origine à renommer", - "abusefilter-edit-builder-vars-movedfrom-ns": "Espace de noms de la page d'origine à renommer", - "abusefilter-edit-builder-vars-movedfrom-title": "Titre de la page d'origine à renommer", - "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "Titre entier de la page d'origine à renommer", + "abusefilter-edit-builder-vars-movedfrom-id": "ID de la page d’origine à renommer", + "abusefilter-edit-builder-vars-movedfrom-ns": "Espace de noms de la page d’origine à renommer", + "abusefilter-edit-builder-vars-movedfrom-title": "Titre de la page d’origine à renommer", + "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "Titre entier de la page d’origine à renommer", "abusefilter-edit-builder-vars-movedfrom-age": "Âge de la page source déplacée (en secondes)", "abusefilter-edit-builder-vars-movedto-id": "Numéro de la page de destination du renommage", "abusefilter-edit-builder-vars-movedto-ns": "Espace de noms de la page de destination du renommage", "abusefilter-edit-builder-vars-movedto-title": "Titre de la page de destination du renommage", "abusefilter-edit-builder-vars-movedto-prefixedtitle": "Titre entier de la page de destination du renommage", "abusefilter-edit-builder-vars-movedto-age": "Âge de la page de destination du déplacement (en secondes)", - "abusefilter-edit-builder-vars-user-editcount": "Compteur de modifications de l'utilisateur", - "abusefilter-edit-builder-vars-user-age": "Âge du compte utilisateur", - "abusefilter-edit-builder-vars-user-name": "Nom du compte d’utilisateur", - "abusefilter-edit-builder-vars-user-groups": "Groupes (y compris implicites) dont l'utilisateur est membre", - "abusefilter-edit-builder-vars-user-rights": "Droits qu’a un utilisateur", - "abusefilter-edit-builder-vars-user-blocked": "Si l'utilisateur est bloqué", - "abusefilter-edit-builder-vars-user-emailconfirm": "Temps depuis la confirmation de l'adresse courriel", + "abusefilter-edit-builder-vars-user-editcount": "Compteur de modifications de l’utilisateur", + "abusefilter-edit-builder-vars-user-age": "Âge du compte de l’utilisateur", + "abusefilter-edit-builder-vars-user-name": "Nom du compte de l’utilisateur", + "abusefilter-edit-builder-vars-user-groups": "Groupes (y compris les implicites) dont l’utilisateur est membre", + "abusefilter-edit-builder-vars-user-rights": "Droits dont dispose l’utilisateur", + "abusefilter-edit-builder-vars-user-blocked": "Si l’utilisateur est bloqué", + "abusefilter-edit-builder-vars-user-emailconfirm": "Temps depuis la confirmation de l’adresse courriel", "abusefilter-edit-builder-vars-recent-contributors": "Les dix derniers contributeurs de la page", "abusefilter-edit-builder-vars-first-contributor": "Premier utilisateur à contribuer à cette page", - "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "Dix derniers utilisateurs ayant contribué à la page source déplacée", + "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "Dix derniers utilisateurs ayant contribué au déplacement de la page source", "abusefilter-edit-builder-vars-movedfrom-first-contributor": "Premier utilisateur à contribuer à la page source déplacée", "abusefilter-edit-builder-vars-movedto-recent-contributors": "Dix derniers utilisateurs ayant contribué à la page destination déplacée", "abusefilter-edit-builder-vars-movedto-first-contributor": "Premier utilisateur à contribuer à la page destination déplacée", "abusefilter-edit-builder-vars-all-links": "Tous les liens externes dans le nouveau texte", "abusefilter-edit-builder-vars-added-links": "Tous les liens externes ajoutés dans la modification", "abusefilter-edit-builder-vars-removed-links": "Tous les liens externes retirés lors de la modification", - "abusefilter-edit-builder-vars-old-text": "Wikitexte de l’ancienne page, avant la modification (n'est plus utilisé)", - "abusefilter-edit-builder-vars-new-text": "Nouveau texte de la page, après la modification", - "abusefilter-edit-builder-vars-new-pst": "Wikitexte de la nouvelle page, transformé avant enregistrement", - "abusefilter-edit-builder-vars-diff-pst": "Différence unifiée des modifications effectuées dans l’aperçu avant enregistrement transformé", + "abusefilter-edit-builder-vars-old-wikitext": "Texte wiki de l’ancienne page, avant la modification", + "abusefilter-edit-builder-vars-new-wikitext": "Texte wiki de la nouvelle page, après la modification", + "abusefilter-edit-builder-vars-new-pst": "Texte wiki de la nouvelle page, transformé avant enregistrement", + "abusefilter-edit-builder-vars-diff-pst": "Différence unifiée des changements, transformés dans l’aperçu avant l’enregistrement de la modification", "abusefilter-edit-builder-vars-addedlines-pst": "Lignes ajoutées dans l’aperçu avant enregistrement de la modification", - "abusefilter-edit-builder-vars-new-text-stripped": "Nouveau texte de la page, sans aucun balisage", - "abusefilter-edit-builder-vars-new-html": "Source HTML analysée de la nouvelle version", - "abusefilter-edit-builder-vars-restrictions-edit": "Protection contre la modification", - "abusefilter-edit-builder-vars-restrictions-move": "Protection contre le renommage", - "abusefilter-edit-builder-vars-restrictions-create": "Protection contre la création", - "abusefilter-edit-builder-vars-restrictions-upload": "Protection contre le téléversement", + "abusefilter-edit-builder-vars-new-text": "Texte de la nouvelle page, nettoyé de tout balisage", + "abusefilter-edit-builder-vars-new-html": "Code source HTML généré pour la nouvelle version", + "abusefilter-edit-builder-vars-restrictions-edit": "Modifier le niveau de protection de la page", + "abusefilter-edit-builder-vars-restrictions-move": "Renommer le niveau de protection de la page", + "abusefilter-edit-builder-vars-restrictions-create": "Protection contre la création de page", + "abusefilter-edit-builder-vars-restrictions-upload": "Protection contre le téléversement du fichier", "abusefilter-edit-builder-vars-movedfrom-restrictions-edit": "Modifier le niveau de protection de la page source déplacée", - "abusefilter-edit-builder-vars-movedfrom-restrictions-move": "Déplacer le niveau de protection de la page source déplacée", + "abusefilter-edit-builder-vars-movedfrom-restrictions-move": "Niveau de protection contre le déplacement de la page source déplacée", "abusefilter-edit-builder-vars-movedfrom-restrictions-create": "Créer la protection de la page source déplacée", - "abusefilter-edit-builder-vars-movedfrom-restrictions-upload": "Télécharger la protection du fichier source déplacé", + "abusefilter-edit-builder-vars-movedfrom-restrictions-upload": "Niveau de protection contre le téléversement du fichier source déplacé", "abusefilter-edit-builder-vars-movedto-restrictions-edit": "Modifier le niveau de protection de la page de destination déplacée", - "abusefilter-edit-builder-vars-movedto-restrictions-move": "Déplacer le niveau de protection de la page de destination déplacée", + "abusefilter-edit-builder-vars-movedto-restrictions-move": "Niveau de protection contre le déplacement de la page de destination déplacée", "abusefilter-edit-builder-vars-movedto-restrictions-create": "Créer la protection de la page de destination déplacée", - "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Télécharger la protection du fichier de destination déplacé", - "abusefilter-edit-builder-vars-old-text-stripped": "Texte de l'ancienne page, dépourvu de toute mise en forme", + "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Niveau de protection contre le téléversement du fichier de destination déplacé", + "abusefilter-edit-builder-vars-old-text": "Texte de l’ancienne page, nettoyé de tout balisage (n’est plus utilisé)", "abusefilter-edit-builder-vars-old-links": "Liens dans la page, avant la modification", - "abusefilter-edit-builder-vars-old-html": "Wikitexte de l’ancienne page, analysé en HTML (n'est plus plus utilisé)", - "abusefilter-edit-builder-vars-minor-edit": "Si la modification est marquée comme mineure ou non", - "abusefilter-edit-builder-vars-file-sha1": "hachage SHA1 du contenu du fichier", + "abusefilter-edit-builder-vars-old-html": "Texte wiki de l’ancienne page, analysé en HTML (n’est plus plus utilisé)", + "abusefilter-edit-builder-vars-minor-edit": "Si la modification est marquée comme mineure ou pas (n’est plus utilisé)", + "abusefilter-edit-builder-vars-file-sha1": "Hachage SHA1 du contenu du fichier", "abusefilter-edit-builder-vars-file-size": "Taille du fichier en octets", "abusefilter-edit-builder-vars-file-mime": "Type MIME du fichier", "abusefilter-edit-builder-vars-file-mediatype": "Type de média pour ce fichier", "abusefilter-edit-builder-vars-file-width": "Largeur du fichier en pixels", "abusefilter-edit-builder-vars-file-height": "Hauteur du fichier en pixels", "abusefilter-edit-builder-vars-file-bits-per-channel": "Nombre de bits par canal de couleur dans le fichier", + "abusefilter-edit-builder-vars-wiki-name": "Nom de la base de données du wiki", + "abusefilter-edit-builder-vars-wiki-language": "Code de langue du wiki", "abusefilter-filter-log": "Modifications récentes des filtres", - "abusefilter-history": "Historique des modifications du filtre antiabus n° $1", + "abusefilter-history": "Historique des modifications du filtre anti-abus nº $1", "abusefilter-history-foruser": "Modifications par $1", "abusefilter-history-hidden": "Masqué", "abusefilter-history-enabled": "Activé", @@ -433,29 +470,32 @@ "abusefilter-history-deleted": "Supprimé", "abusefilter-history-filterid": "Filtre", "abusefilter-history-select-legend": "Affiner la recherche", - "abusefilter-history-select-user": "Utilisateur :", - "abusefilter-history-select-filter": "ID du filtre :", + "abusefilter-history-select-user": "Utilisateur :", + "abusefilter-history-select-filter": "ID du filtre :", "abusefilter-history-select-submit": "Affiner", "abusefilter-history-diff": "Changements", - "abusefilter-history-error-hidden": "Le filtre que vous avez demandé est caché, et vous ne pouvez pas afficher son historique.", + "abusefilter-history-error-hidden": "Le filtre que vous avez demandé est masqué et vous ne pouvez pas afficher son historique.", "abusefilter-exception-unexpectedatend": "« $2 » inattendu au caractère $1.", - "abusefilter-exception-expectednotfound": "Un $2 manquant était attendu au caractère $1 ($3 $4 trouvé à la place).", + "abusefilter-exception-expectednotfound": "Un $2 manquant était attendu au caractère nº $1 ($3 $4 trouvé à la place).", "abusefilter-exception-unrecognisedkeyword": "Mot-clé $2 non reconnu au caractère $1.", "abusefilter-exception-unexpectedtoken": "Élément inattendu « $3 » (de type $2) au caractère $1.", "abusefilter-exception-unclosedstring": "Chaîne non fermée débutant au caractère $1.", "abusefilter-exception-invalidoperator": "Opérateur invalide « $2 » au caractère $1.", "abusefilter-exception-unrecognisedtoken": "Élément non reconnu « $2 » au caractère $1.", - "abusefilter-exception-noparams": "Aucun paramètre fourni pour la fonction « $2 » au caractère $1. $3 argument{{PLURAL:$3| attendu|s attendus}}.", + "abusefilter-exception-noparams": "Aucun paramètre fourni pour la fonction « $2 » au caractère nº $1. $3 argument{{PLURAL:$3||s}} attendu{{PLURAL:$3||s}}.", "abusefilter-exception-dividebyzero": "Division illégale de $2 par zéro au caractère $1.", - "abusefilter-exception-unrecognisedvar": "Variable non reconnue $2 au caractère $1", - "abusefilter-exception-notenoughargs": "Pas assez de paramètres pour la fonction $2 appelée au caractère $1.\n$3 {{PLURAL:$3|argument demandé|arguments demandés}}, $4 obtenu{{PLURAL:$4||s}}", - "abusefilter-exception-regexfailure": "Erreur dans l'expression régulière « $2 » au caractère $1 .", - "abusefilter-exception-overridebuiltin": "Écrasement interdit de la variable disponible par défaut « $2 » au caractère $1.", - "abusefilter-exception-outofbounds": "Demande d’élément de tableau $2 inexistant (taille du tableau = $3) au caractère $1.", - "abusefilter-exception-notarray": "Demande d'un élément de tableau appliquée à un non-tableau au caractère $1.", - "abusefilter-exception-unclosedcomment": "Commentaire non fermé au caractère $1.", - "abusefilter-exception-invalidiprange": "Intervalle d'adresses IP fourni invalide \"$2\" au caractère $1.", - "abusefilter-exception-disabledvar": "La variable $2 au caractère $1 n’est plus utilisée.", + "abusefilter-exception-unrecognisedvar": "Variable non reconnue $2 au caractère nº $1.", + "abusefilter-exception-notenoughargs": "Pas assez de paramètres pour la fonction $2 appelée au caractère nº $1.\n$3 argument{{PLURAL:$3||s}} demandé{{PLURAL:$3||s}}, $4 obtenu{{PLURAL:$4||s}}.", + "abusefilter-exception-toomanyargs": "Trop d’arguments pour la fonction $2 appelée au caractère $1.\n$3 {{PLURAL:$3|argument|arguments}} au plus attendus, $4 obtenus", + "abusefilter-exception-regexfailure": "Erreur dans l’expression rationnelle « $2 » au caractère nº $1 .", + "abusefilter-exception-overridebuiltin": "Écrasement interdit de l’identifiant prédéfini « $2 » au caractère nº $1.", + "abusefilter-exception-outofbounds": "Demande d’élément de tableau $2 inexistant (taille du tableau = $3) au caractère nº $1.", + "abusefilter-exception-negativeindex": "Les indices négatifs ne sont pas autorisés dans les tableaux. Indice « $2 » obtenu au caractère $1.", + "abusefilter-exception-notarray": "Demande d’un élément de tableau pour un non-tableau au caractère nº $1.", + "abusefilter-exception-unclosedcomment": "Commentaire non fermé au caractère nº $1.", + "abusefilter-exception-invalidiprange": "Plage d’adresses IP fournie non valide « $2 » au caractère nº $1.", + "abusefilter-exception-disabledvar": "La variable $2 au caractère nº $1 n’est plus utilisée.", + "abusefilter-exception-variablevariable": "set et set_var s’attendent à ce que le premier argument soit une chaîne littérale, trouvée au caractère $1.", "abusefilter-action-tag": "Baliser", "abusefilter-action-throttle": "Limiter les modifications", "abusefilter-action-warn": "Avertir l’utilisateur", @@ -465,34 +505,34 @@ "abusefilter-action-rangeblock": "Bloquer la plage", "abusefilter-action-disallow": "Interdire la modification", "abusefilter-revert-title": "Révoquer toutes les modifications par le filtre $1", - "abusefilter-revert-intro": "Ce formulaire vous permet de révoquer toutes les modifications faites par le filtre antiabus $1.\nVeuillez faire très attention en utilisant cet outil.", - "abusefilter-revert-preview-item": "$1 : $2 {{GENDER:$7|a fait}} $3 sur $4.\nActions à révoquer : $5 ($6)", - "abusefilter-revert-search-legend": "Sélectionnez les actions à révoquer du filtre antiabus", - "abusefilter-revert-periodstart": "Début de la période :", - "abusefilter-revert-periodend": "Fin de la période :", + "abusefilter-revert-intro": "Ce formulaire vous permet de révoquer toutes les modifications faites par le filtre anti-abus $1.\nVeuillez faire très attention en utilisant cet outil.", + "abusefilter-revert-preview-item": "$1 : $2{{GENDER:$7|}} a effectué l’action « $3 » sur $4.\nActions à révoquer : $5 ($6)", + "abusefilter-revert-search-legend": "Sélectionnez les actions à révoquer du filtre anti-abus", + "abusefilter-revert-periodstart": "Début de la période :", + "abusefilter-revert-periodend": "Fin de la période :", "abusefilter-revert-search": "Sélectionner les actions", - "abusefilter-revert-filter": "ID de filtre :", - "abusefilter-revert-preview-intro": "Voici les actions réalisées par le filtre antiabus, qui seront révoquées par cette action.\nVeuillez les vérifier attentivement, puis cliquez sur « {{int:abusefilter-revert-confirm}} » pour valider votre sélection.", + "abusefilter-revert-filter": "ID du filtre :", + "abusefilter-revert-preview-intro": "Voici les actions réalisées par le filtre anti-abus, qui seront révoquées par cette action.\nVeuillez les vérifier attentivement, puis cliquez sur « {{int:abusefilter-revert-confirm}} » pour valider votre sélection.", "abusefilter-revert-confirm-legend": "Confirmer le retour", "abusefilter-revert-confirm": "Confirmer", - "abusefilter-revert-success": "Vous avez révoqué avec succès toutes les actions entreprises par le filtre antiabus et déclenchées par le [[Special:AbuseFilter/$1|filtre $2]].", - "abusefilter-revert-reason": "Révocation automatique de toutes les actions entreprises par le filtre antiabus et déclenchées par le filtre $1.\nMotif donné : $2", - "abusefilter-revert-reasonfield": "Motif :", + "abusefilter-revert-success": "Vous avez révoqué avec succès toutes les actions entreprises par le filtre anti-abus et déclenchées par le [[Special:AbuseFilter/$1|filtre $2]].", + "abusefilter-revert-reason": "Révocation automatique de toutes les actions entreprises par le filtre anti-abus et déclenchées par le filtre $1.\nMotif donné : $2", + "abusefilter-revert-reasonfield": "Motif :", "abusefilter-test": "Tester un filtre sur les précédentes modifications", - "abusefilter-test-intro": "Cette page vous permet d’appliquer un filtre saisi dans la zone de texte ci-dessous {{PLURAL:$1|à la dernière modification|aux $1 dernières modifications}}.\nPour charger un filtre existant, entrez son identifiant dans le champ sous la zone de texte et cliquez sur le bouton « {{int:abusefilter-test-load}} ».", - "abusefilter-test-legend": "Test de filtre", - "abusefilter-test-load-filter": "Charger le filtre numéro :", + "abusefilter-test-intro": "Cette page vous permet d’appliquer un filtre saisi dans la zone de texte ci-dessous {{PLURAL:$1|à la|aux}} dernière{{PLURAL:$1||s}} modification{{PLURAL:$1||s}}.\nPour charger un filtre existant, entrez son identifiant dans le champ sous la zone de texte et cliquez sur le bouton « {{int:abusefilter-test-load}} ».", + "abusefilter-test-legend": "Test du filtre", + "abusefilter-test-load-filter": "Charger le filtre avec l’ID :", "abusefilter-test-submit": "Tester", "abusefilter-test-load": "Charger", - "abusefilter-test-user": "Modifications par l'utilisateur :", + "abusefilter-test-user": "Modifications par l’utilisateur :", "abusefilter-test-nobots": "Masquer les modifications faites par robot", - "abusefilter-test-period-start": "Changements faits après :", - "abusefilter-test-period-end": "Changements faits avant :", - "abusefilter-test-page": "Modifications apportées à la page :", + "abusefilter-test-period-start": "Modifications effectuées après :", + "abusefilter-test-period-end": "Modifications effectuées avant :", + "abusefilter-test-page": "Modifications effectuées à la page :", "abusefilter-test-shownegative": "Afficher les modifications non prises en compte par le filtre", - "abusefilter-test-syntaxerr": "Le filtre que vous avez saisi contient une erreur de syntaxe.\nVous pouvez recevoir une explication complète en cliquant sur le bouton « {{int:abusefilter-edit-check}} ».", + "abusefilter-test-syntaxerr": "Le filtre que vous avez saisi contient une erreur de syntaxe.\nVous pouvez recevoir une explication complète en cliquant sur le bouton « {{int:abusefilter-edit-check}} ».", "abusefilter-test-badtitle": "La titre de page que vous avez saisi n’est pas valide. Il se peut qu’il contienne un ou plusieurs caractères interdits dans les titres.", - "abusefilter-test-action": "Type d’action :", + "abusefilter-test-action": "Type d’action :", "abusefilter-test-search-type-all": "Toutes les actions", "abusefilter-test-search-type-edit": "Modifications", "abusefilter-test-search-type-move": "Déplacements", @@ -500,57 +540,59 @@ "abusefilter-test-search-type-upload": "Téléversements", "abusefilter-test-search-type-createaccount": "Créations de compte", "abusefilter-changeslist-examine": "examiner", - "abusefilter-examine": "Examiner des modifications individuelles", - "abusefilter-examine-intro": "Cette page vous permet d'examiner les variables générées pour une modification individuelle par le filtre antiabus et de les tester avec les filtres.", + "abusefilter-examine": "Examiner les modifications individuelles", + "abusefilter-examine-intro": "Cette page vous permet d’examiner les variables générées par le filtre anti-abus pour une modification individuelle et de les tester avec les filtres.", "abusefilter-examine-legend": "Sélectionner les modifications", - "abusefilter-examine-diff": "URL du diff :", - "abusefilter-examine-user": "Utilisateur :", - "abusefilter-examine-title": "Titre de la page :", + "abusefilter-examine-diff": "URL du diff :", + "abusefilter-examine-user": "Utilisateur :", + "abusefilter-examine-title": "Titre de la page :", "abusefilter-examine-submit": "Rechercher", "abusefilter-examine-vars": "Variables générées pour cette modification", "abusefilter-examine-test": "Tester cette modification avec un filtre", "abusefilter-examine-test-button": "Tester le filtre", "abusefilter-examine-match": "Cette modification a été détectée par le filtre.", - "abusefilter-examine-nomatch": "Cette modification n'a pas été détectée par le filtre.", + "abusefilter-examine-nomatch": "Cette modification n’a pas été détectée par le filtre.", "abusefilter-examine-syntaxerror": "Le filtre a une syntaxe incorrecte", - "abusefilter-examine-notfound": "La modification que vous avez demandée n'a pas été trouvée.", - "abusefilter-examine-incompatible": "La modification que vous avez demandée n’est pas prise en charge par le filtre antiabus.", - "abusefilter-examine-noresults": "Aucun résultat n'a été trouvé pour les paramètres de recherche que vous avez fourni.", - "abusefilter-topnav": "'''Navigation du filtre antiabus'''", + "abusefilter-examine-notfound": "La modification que vous avez demandée n’a pas été trouvée.", + "abusefilter-examine-incompatible": "La modification que vous avez demandée n’est pas prise en charge par le filtre anti-abus.", + "abusefilter-examine-noresults": "Aucun résultat n’a été trouvé pour les paramètres de recherche que vous avez fournis.", + "abusefilter-topnav": "'''Navigation du filtre anti-abus'''", "abusefilter-topnav-home": "Accueil", - "abusefilter-topnav-test": "Test en série", + "abusefilter-topnav-recentchanges": "Modifications récentes des filtres", + "abusefilter-topnav-test": "Test par lot", "abusefilter-topnav-examine": "Examiner les modifications précédentes", - "abusefilter-topnav-log": "Journal antiabus", - "abusefilter-topnav-tools": "Outils de déboguage", - "abusefilter-topnav-import": "Importer un filtre", - "abusefilter-log-name": "Journal des modifications du filtre antiabus", + "abusefilter-topnav-log": "Journal anti-abus", + "abusefilter-topnav-tools": "Outils de débogage", + "abusefilter-log-name": "Journal du filtre anti-abus", "abusefilter-log-header": "Ce journal affiche un résumé des modifications faites aux filtres.\nPour plus de détails, voyez [[Special:AbuseFilter/history|la liste]] des modifications récentes du filtre.", - "abusefilter-logentry-create": "$1 a {{GENDER:$2|créé}} $4 ($5)", - "abusefilter-logentry-modify": "$1 {{GENDER:$2|a modifié}} $4 ($5)", + "abusefilter-logentry-create": "$1{{GENDER:$2|}} a créé $4 ($5)", + "abusefilter-logentry-modify": "$1{{GENDER:$2|}} a modifié $4 ($5)", + "abusefilter-log-invalid-filter": "Certains des identificateurs de filtres indiqués ne sont pas valides.", "abusefilter-log-noresults": "Aucun résultat", "abusefilter-diff-title": "Différences entre les versions", "abusefilter-diff-item": "Article", - "abusefilter-diff-version": "Version du $1 {{GENDER:$3|par}} $2", + "abusefilter-diff-version": "Version du $1 par $2{{GENDER:$3|}}", "abusefilter-diff-info": "Informations de base", "abusefilter-diff-pattern": "Conditions du filtre", - "abusefilter-diff-invalid": "Impossible de retrouver les versions demandées", + "abusefilter-diff-invalid": "Impossible de récupérer les versions demandées", "abusefilter-diff-backhistory": "Retour à l’historique du filtre", "abusefilter-diff-prev": "Changement antérieur", "abusefilter-diff-next": "Changement ultérieur", - "abusefilter-import-intro": "Vous pouvez utiliser cette interface pour importer des filtres en provenance d'autres wikis.\nSur le wiki d'origine, cliquez sur « {{int:abusefilter-edit-export}} » dans « {{int:abusefilter-edit-tools}} » depuis l'interface d'édition.\nCopiez la zone de texte qui s'affiche et collez-le dans cette zone de texte, puis cliquez sur « {{int:abusefilter-import-submit}} »,", + "abusefilter-import-intro": "Vous pouvez utiliser cette interface pour importer des filtres en provenance d’autres wikis.\nSur le wiki d’origine, cliquez sur « {{int:abusefilter-edit-export}} » dans « {{int:abusefilter-edit-tools}} » depuis l’interface de modification.\nCopiez la zone de texte qui s’affiche et collez-le dans cette zone de texte, puis cliquez sur « {{int:abusefilter-import-submit}} ».", "abusefilter-import-submit": "Importer des données", + "abusefilter-import-invalid-data": "Les données que vous essayez d’importer ne sont pas valides", "abusefilter-group-default": "Par défaut", - "abusefilter-http-error": "Une erreur HTTP s’est produite : $1.", - "abusefilter-view-private-submit": "Afficher les détails confidentiels", - "abusefilter-view-private": "Afficher les détails confidentiels", - "abusefilter-view-private-reason": "Motif pour accéder aux détails confidentiels :", + "abusefilter-http-error": "Une erreur HTTP s’est produite : $1.", + "abusefilter-view-privatedetails-submit": "Afficher les détails confidentiels", + "abusefilter-view-privatedetails-legend": "Afficher les détails confidentiels", + "abusefilter-view-privatedetails-reason": "Motif pour accéder aux détails confidentiels :", "abusefilter-log-details-id": "ID du journal", - "abusefilter-invalid-request": "Demande non valide ! Vous devez accéder aux détails confidentiels du journal d’accès via le formulaire sur [[Special:AbuseLog/$1]] et indiquer un motif.", - "abusefilter-invalid-request-noid": "Demande non valide ! Vous devez accéder aux détails confidentiels du journal via le formulaire sur la page de détails du journal des abus et indiquer un motif.", - "log-description-abusefilterprivatedetails": "Ce journal affiche une liste des horodatages auxquels un utilisateur a accédé aux détails confidentiels d’un journal d’abus.", - "abusefilter-noreason": "Avertissement : Pour voir les détails confidentiels de ce journal, vous devez indiquer un motif.", + "abusefilter-invalid-request": "Demande non valide ! Vous devez accéder aux détails confidentiels du journal d’accès via le formulaire sur [[Special:AbuseLog/$1]] et indiquer un motif.", + "abusefilter-invalid-request-noid": "Demande non valide ! Vous devez accéder aux détails confidentiels du journal via le formulaire sur la page de détails du journal des abus et indiquer un motif.", + "log-description-abusefilterprivatedetails": "Ce journal affiche une liste des dates et heures où un utilisateur a accédé aux détails confidentiels d’un journal d’abus.", + "abusefilter-noreason": "Avertissement : pour voir les détails confidentiels de ce journal, vous devez indiquer un motif.", "abusefilter-log-ip-not-available": "Non disponible", - "abusefilter-tag-reserved": "La balise <code>abusefilter-condition-limit</code> est réservée à l'usage interne du filtre anti-abus.", - "tag-abusefilter-condition-limit": "limite de condition atteinte", + "abusefilter-tag-reserved": "La balise <code>abusefilter-condition-limit</code> est réservée à l’usage interne du filtre anti-abus.", + "tag-abusefilter-condition-limit": "Limite de condition atteinte", "tag-abusefilter-condition-limit-description": "Modifications ou autres événements qui ne peuvent pas être vérifiés par tous les [[Special:AbuseFilter|filtres d’abus]] actifs ([[mw:Extension:AbuseFilter/Conditions|aide]])." } diff --git a/AbuseFilter/i18n/frp.json b/AbuseFilter/i18n/frp.json index 52850a11..3583a35d 100644 --- a/AbuseFilter/i18n/frp.json +++ b/AbuseFilter/i18n/frp.json @@ -3,13 +3,14 @@ "authors": [ "Cedric31", "ChrisPtDe", - "McDutchie", - "Matma Rex" + "Fitoschido", + "Matma Rex", + "McDutchie" ] }, "abusefilter-desc": "Aplique des heristiques ôtomatiques ux changements.", - "abusefilter": "Configuracion du filtro d’abus", - "abuselog": "Jornal des abus", + "abusefilter": "Administracion du filtro d’abus", + "abuselog": "Jornal du filtro d’abus", "abusefilter-intro": "Benvegnua dens l’entèrface d’administracion des filtros d’abus.\nLo filtro d’abus est un mècanismo programeria ôtomatisâ que pèrmèt d’aplicar des heristiques prèdèfenies a totes les accions.\nCela entèrface presente una lista des filtros dèfenis, et pués balye la possibilitât de los changiér.", "abusefilter-warning": "'''Avèrtissement :''' cela accion at étâ identifiâ ôtomaticament coment nuésibla.\nLos changements pas constructifs seront rêdo anulâs,\net pués les bètises rèpètâs ou ben que font enjura provoqueront lo blocâjo de voutron compto ou ben de voutra adrèce IP.\nSe vos éte de sûr que voutron changement est constructif, vos lo pouede tornar sometre por lo confirmar.\nVê-que una côrta dèscripcion de la règlla de filtracion d’abus qu’at dècelâ voutra accion : $1", "abusefilter-disallowed": "Cela accion at étâ identifiâ ôtomaticament coment nuésibla et at vêr étâ empachiê.\nSe vos éte de sûr que voutron changement ére constructif, vos volyéd veriér vers un administrator et pués l’enformar de cen que vos éd tâchiê de fâre.\nVê-que una côrta dèscripcion de la règlla de filtracion d’abus qu’at dècelâ voutra accion : $1", @@ -24,7 +25,7 @@ "right-abusefilter-view": "Vêre los filtros d’abus", "right-abusefilter-log": "Vêre lo jornal des abus", "right-abusefilter-log-detail": "Vêre les entrâs dètalyês du jornal des abus", - "right-abusefilter-private": "Vêre les balyês privâs dens lo jornal des abus", + "right-abusefilter-privatedetails": "Vêre les balyês privâs dens lo jornal des abus", "right-abusefilter-modify-restricted": "Changiér los filtros d’abus avouéc des accions rètrentes", "right-abusefilter-revert": "Rèvocar tôs los changements fêts per un filtro d’abus balyê", "right-abusefilter-view-private": "Vêre los filtros d’abus marcâs coment privâs", @@ -34,11 +35,10 @@ "action-abusefilter-view": "vêre los filtros d’abus", "action-abusefilter-log": "vêre lo jornal des abus", "action-abusefilter-log-detail": "vêre les entrâs dètalyês du jornal des abus", - "action-abusefilter-private": "vêre les balyês privâs dens lo jornal des abus", + "action-abusefilter-privatedetails": "vêre les balyês privâs dens lo jornal des abus", "action-abusefilter-modify-restricted": "changiér los filtros d’abus avouéc des accions rètrentes", "action-abusefilter-revert": "rèvocar tôs los changements fêts per un filtro d’abus balyê", "action-abusefilter-view-private": "vêre los filtros d’abus marcâs coment privâs", - "abusefilter-log": "Jornal du filtro d’abus", "abusefilter-log-summary": "Ceti jornal montre una lista de les accions dècelâs per los filtros.", "abusefilter-log-search": "Rechèrchiér dens lo jornal des abus", "abusefilter-log-search-user": "Usanciér :", @@ -57,13 +57,11 @@ "abusefilter-log-details-var": "Variâbla", "abusefilter-log-details-val": "Valor", "abusefilter-log-details-vars": "Paramètres de l’accion", - "abusefilter-log-details-private": "Balyês privâs", "abusefilter-log-details-ip": "Adrèce IP d’origina", "abusefilter-log-noactions": "niona", "abusefilter-log-details-diff": "Changements fêts dens lo changement", "abusefilter-log-linkoncontribs": "jornal des abus", "abusefilter-log-linkoncontribs-text": "Jornal des abus a ceti usanciér", - "abusefilter-log-hidden": "(entrâ cachiê)", "abusefilter-log-hidden-implicit": "(cachiêye perce que la vèrsion est étâye suprimâye)", "abusefilter-log-cannot-see-details": "Vos avéd pas la pèrmission de vêre los dètalys de cel’entrâ.", "abusefilter-log-details-hidden": "Vos pouede pas vêre los dètalys por cela entrâ perce qu’el est cachiê a la vua du publico.", @@ -72,7 +70,6 @@ "abusefilter-log-hide-hidden": "Cachiér cela entrâ a la vua du publico", "abusefilter-log-hide-reason": "Rêson :", "abusefilter-log-hide-forbidden": "Vos avéd pas la pèrmission de cachiér des entrâs du jornal des abus.", - "abusefilter-management": "Administracion du filtro d’abus", "abusefilter-list": "Tôs los filtros", "abusefilter-list-id": "Numerô du filtro", "abusefilter-list-status": "Ètat", @@ -92,6 +89,7 @@ "abusefilter-disabled": "Dèsactivâ", "abusefilter-hitcount": "$1 dètèccion{{PLURAL:$1||s}}", "abusefilter-new": "Fâre un filtro novél", + "abusefilter-import-button": "Importar un filtro", "abusefilter-return": "Tornar a l’administracion des filtros", "abusefilter-status-global": "Globâl", "abusefilter-list-options": "Chouèx", @@ -119,7 +117,6 @@ "abusefilter-edit-oldwarning": "<strong>Vos éte aprés changiér una vielye vèrsion de cél filtro.\nLes statistiques montrâs regârdont la vèrsion la ples novèla de ceti.\nSe vos encartâd voutros changements, vos voléd ècllafar tôs los changements arrevâs dês la vèrsion que vos changiéd.</strong> •\n[[Special:AbuseFilter/history/$2|Tornar a l’historico de cél filtro]].", "abusefilter-edit-status-label": "Statistiques :", "abusefilter-edit-status": "{{PLURAL:$1|Dens la dèrriére accion|Entre-mié les $1 dèrriéres accions}}, cél filtro nen at dècelâ $2 ($3 %).", - "abusefilter-edit-status-profile": "{{PLURAL:$1|Dens la dèrriére accion|Entre-mié les $1 dèrriéres accions}}, cél filtro nen at dècelâ $2 ($3 %).\nEn moyena, lo temps d’ègzécucion de cél filtro est de $4 ms et pués utilise $5 condicion{{PLURAL:$5||s}} de la limita de les condicions.", "abusefilter-edit-new": "Filtro novél", "abusefilter-edit-save": "Encartar lo filtro", "abusefilter-edit-id": "Numerô du filtro :", @@ -250,15 +247,15 @@ "abusefilter-edit-builder-vars-all-links": "Tôs los lims de defôr dens lo tèxto novél", "abusefilter-edit-builder-vars-added-links": "Tôs los lims de defôr apondus dens lo changement", "abusefilter-edit-builder-vars-removed-links": "Tôs los lims de defôr enlevâs dens lo changement", - "abusefilter-edit-builder-vars-old-text": "Viely vouiquitèxto de la pâge, devant lo changement", - "abusefilter-edit-builder-vars-new-text": "Vouiquitèxto de la pâge novél, aprés lo changement", - "abusefilter-edit-builder-vars-new-text-stripped": "Tèxto de la pâge novél, sen gins de balisâjo", + "abusefilter-edit-builder-vars-old-wikitext": "Viely vouiquitèxto de la pâge, devant lo changement", + "abusefilter-edit-builder-vars-new-wikitext": "Vouiquitèxto de la pâge novél, aprés lo changement", + "abusefilter-edit-builder-vars-new-text": "Tèxto de la pâge novél, sen gins de balisâjo", "abusefilter-edit-builder-vars-new-html": "Sôrsa HTML parsâ de la novèla vèrsion", "abusefilter-edit-builder-vars-restrictions-edit": "Nivél de protèccion des changements de la pâge", "abusefilter-edit-builder-vars-restrictions-move": "Nivél de protèccion des changements de nom de la pâge", "abusefilter-edit-builder-vars-restrictions-create": "Protèccion de creacion de la pâge", "abusefilter-edit-builder-vars-restrictions-upload": "Protèccion de tèlèchargement du fichiér", - "abusefilter-edit-builder-vars-old-text-stripped": "Viely tèxto de la pâge, sen gins de balisâjo", + "abusefilter-edit-builder-vars-old-text": "Viely tèxto de la pâge, sen gins de balisâjo", "abusefilter-edit-builder-vars-old-links": "Lims dens la pâge, devant lo changement", "abusefilter-edit-builder-vars-old-html": "Viely vouiquitèxto de la pâge, parsâ en HTML", "abusefilter-edit-builder-vars-minor-edit": "Se lo changement est marcâ coment petiôt ou nan", @@ -295,7 +292,7 @@ "abusefilter-exception-dividebyzero": "Division ilègâla de $2 per zérô u caractèro $1.", "abusefilter-exception-unrecognisedvar": "Variâbla pas recognua $2 u caractèro $1", "abusefilter-exception-notenoughargs": "Pas prod de paramètres por la fonccion $2 apelâ u caractèro $1.\n$3 {{PLURAL:$3|argument demandâ|arguments demandâs}}, $4 avu{{PLURAL:$4||s}}", - "abusefilter-exception-regexfailure": "Èrror dens l’èxprèssion racionèla « $3 » u caractèro $1 : « $2 »", + "abusefilter-exception-regexfailure": "Èrror dens l’èxprèssion racionèla « $2 » u caractèro $1.", "abusefilter-exception-overridebuiltin": "Ècllafâ dèfendua de la variâbla disponibla per dèfôt « $2 » u caractèro $1.", "abusefilter-exception-outofbounds": "Demanda de l’èlèment pas ègzistent $2 (talye de la lista = $3) u caractèro $1.", "abusefilter-exception-notarray": "Demanda d’un èlèment dens ôtra chousa qu’un tablô u caractèro $1.", @@ -355,7 +352,6 @@ "abusefilter-topnav-examine": "Ègzamenar los changements devant", "abusefilter-topnav-log": "Jornal des abus", "abusefilter-topnav-tools": "Outils de dècofierâjo", - "abusefilter-topnav-import": "Importar un filtro", "abusefilter-log-name": "Jornal du filtro d’abus", "abusefilter-log-header": "Ceti jornal montre un rèsumâ des changements fêts ux filtros.\nPor més de dètalys, vêde la [[Special:AbuseFilter/history|lista]] des dèrriérs changements du filtro.", "abusefilter-log-noresults": "Gins de rèsultat", diff --git a/AbuseFilter/i18n/frr.json b/AbuseFilter/i18n/frr.json index ef9b48d4..27aacf72 100644 --- a/AbuseFilter/i18n/frr.json +++ b/AbuseFilter/i18n/frr.json @@ -4,18 +4,16 @@ "Murma174" ] }, - "abusefilter": "Masbrük-filter", - "abuselog": "Masbrük-filter logbuk", + "abusefilter": "Masbrük-filter auersicht", + "abuselog": "Masbrükfilter-logbuk", "abusefilter-blocker": "Masbrük-filter", "right-abusefilter-log": "Masbrükfilter-logbuk uunluke", "right-abusefilter-log-detail": "Ütjwidjet masbrükfilter-logbuk uunluke", "action-abusefilter-log": "at masbrükfilter-logbuk uuntulukin", "action-abusefilter-log-detail": "det ütjwidjet masbrükfilter-logbuk uuntulukin", - "abusefilter-log": "Masbrükfilter-logbuk", "abusefilter-log-search": "Masbrükfilter-logbuk trochschük", "abusefilter-log-linkoncontribs": "Masbrükfilter-logbuk", "abusefilter-log-linkoncontribs-text": "Masbrükfilter-logbuk för didiar brüker", - "abusefilter-management": "Masbrük-filter auersicht", "abusefilter-list": "Aaltumaal", "abusefilter-topnav": "'''Masbrük-filter nawigatjuun'''", "abusefilter-log-name": "Masbrükfilter-logbuk", diff --git a/AbuseFilter/i18n/fy.json b/AbuseFilter/i18n/fy.json index 43bbff80..fcbac0c7 100644 --- a/AbuseFilter/i18n/fy.json +++ b/AbuseFilter/i18n/fy.json @@ -1,15 +1,15 @@ { "@metadata": { "authors": [ + "PiefPafPier", "Pyt", - "Snakesteuben", + "Robin van der Vliet", "Robin0van0der0vliet", - "PiefPafPier", - "Robin van der Vliet" + "Snakesteuben" ] }, "abusefilter-desc": "Fiert automatyske heuristyske analyse út op bewurkings", - "abusefilter": "Ynstellings foar it misbrûkfilter", + "abuselog": "Misbrûkfilterloch", "abusefilter-blocker": "Misbrûkfilter", "abusefilter-accountreserved": "Dizze meidochnamme wurdt frijholden foar it misbrûkfilter.", "abusefilter-log-search-user": "Meidogger:", @@ -21,6 +21,10 @@ "abusefilter-log-details-var": "Fariabel", "abusefilter-log-details-val": "Wearde", "abusefilter-log-noactions": "gjin", + "abusefilter-log-linkoncontribs": "misbrûkloch", + "abusefilter-log-linkoncontribs-text": "It misbrûkloch foar dizze {{GENDER:$1|meidogger|meidochster}}", + "abusefilter-log-linkonhistory": "misbrûkloch besjen", + "abusefilter-log-linkonhistory-text": "It misbrûkloch foar dizze side besjen", "abusefilter-log-hide-reason": "Reden:", "abusefilter-list-status": "Status", "abusefilter-list-edit": "Bewurkje", @@ -32,7 +36,7 @@ "abusefilter-status-global": "Globaal", "abusefilter-list-options": "Opsjes", "abusefilter-list-options-submit": "Bywurkje", - "abusefilter-tools-reautoconfirm-user": "Brûker:", + "abusefilter-tools-reautoconfirm-user": "Meidogger:", "abusefilter-edit-status-label": "Statistiken:", "abusefilter-edit-new": "Nije filter", "abusefilter-edit-save": "Filter bewarje", @@ -60,11 +64,15 @@ "abusefilter-history-global": "Globaal", "abusefilter-history-timestamp": "Tiid", "abusefilter-history-user": "Meidogger", - "abusefilter-history-select-user": "Brûker:", + "abusefilter-history-select-user": "Meidogger:", "abusefilter-revert-reasonfield": "Reden:", "abusefilter-examine-user": "Meidogger:", "abusefilter-examine-submit": "Sykje", + "abusefilter-topnav-log": "Misbrûkloch", + "abusefilter-log-name": "Misbrûkfilterloch", "abusefilter-diff-title": "Ferskillen tusken ferzjes", "abusefilter-group-default": "Standert", - "abusefilter-http-error": "Der is in HTTP-flater bard: $1." + "abusefilter-http-error": "Der is in HTTP-flater bard: $1.", + "tag-abusefilter-condition-limit": "bepalingslimyt berikt", + "tag-abusefilter-condition-limit-description": "Bewurkings as oare barrens dy't net kontrolearre wurde koene troch alle aktive [[Special:AbuseFilter|misbrûkfilters]] ([[mw:Extension:AbuseFilter/Conditions|help]])." } diff --git a/AbuseFilter/i18n/gan-hans.json b/AbuseFilter/i18n/gan-hans.json index 43fa6f00..beef58e3 100644 --- a/AbuseFilter/i18n/gan-hans.json +++ b/AbuseFilter/i18n/gan-hans.json @@ -1,5 +1,7 @@ { - "@metadata": [], + "@metadata": { + "authors": [] + }, "abusefilter-log-search-submit": "寻吖", "abusefilter-examine-submit": "寻吖" } diff --git a/AbuseFilter/i18n/gcr.json b/AbuseFilter/i18n/gcr.json new file mode 100644 index 00000000..99106358 --- /dev/null +++ b/AbuseFilter/i18n/gcr.json @@ -0,0 +1,14 @@ +{ + "@metadata": { + "authors": [ + "LeGuyanaisPure", + "Léon973" + ] + }, + "right-abusefilter-log": "Wè jòrnal-a di filt anti abi-ya", + "action-abusefilter-log": "wè jòrnal-a di filt anti abi-ya", + "abusefilter-log-linkoncontribs": "jòrnal di abi-ya", + "abusefilter-log-linkonhistory": "wè jòrnal-a di abi-ya", + "abusefilter-log-linkonhistory-text": "Wè jòrnal-a di abi-ya pou sa paj", + "abusefilter-log-linkonundelete": "wè jòrnal-a di abi-ya" +} diff --git a/AbuseFilter/i18n/gl.json b/AbuseFilter/i18n/gl.json index 3473467d..a9232a05 100644 --- a/AbuseFilter/i18n/gl.json +++ b/AbuseFilter/i18n/gl.json @@ -1,18 +1,21 @@ { "@metadata": { "authors": [ - "Elisardojm", - "Toliño", "Banjo", + "Breogan2008", + "Elisardojm", + "Fitoschido", + "Iváns", + "Maria zaos", "Matma Rex", - "Navhy", - "Maria zaos" + "Toliño" ] }, "abusefilter-desc": "Aplica heurísticas automáticas ás edicións", - "abusefilter": "Configuración do filtro de abusos", - "abuselog": "Rexistro de abusos", + "abusefilter": "Xestión do filtro de abusos", + "abuselog": "Rexistro do filtro de abusos", "abusefilter-intro": "Benvido á interface do xestor do filtro de abusos.\nO filtro de abusos é un software mecánico automático que aplica heurísticas automáticas a tódalas accións.\nEsta interface amosa unha lista dos filtros definidos e permite que estes sexan modificados.", + "abusefilter-mustviewprivateoredit": "Por razóns de seguridade, só os usuarios con dereitos para ver filtros de abuso privados ou modificar filtros poden usar esta interface.", "abusefilter-warning": "'''Atención:''' Esta acción foi identificada automaticamente como prexudicial.\nAs accións non construtivas serán revertidas decontado,\ne a repetición destas edicións dará como resultado o bloqueo da súa conta ou do seu enderezo IP.\nSe cre que esta acción é construtiva, pode enviala outra vez para confirmalo.\nVelaquí hai unha breve descrición da regra de abuso coa que coincide a súa acción: $1", "abusefilter-disallowed": "Esta acción foi identificada automaticamente como prexudicial e por iso non está permitida.\nSe cre que a súa acción foi construtiva, por favor, informe a un administrador do que estaba intentando facer.\nVelaquí hai unha breve descrición da regra de abuso coa que coincide a súa acción: $1", "abusefilter-blocked-display": "Esta acción foi identificada automaticamente como prexudicial\ne impedíuselle que a executase.\nAdemais, para protexer a {{SITENAME}}, a súa conta de usuario e todos os enderezos IP asociados foron bloqueados fronte á edición.\nSe isto ocorreu por erro, por favor, póñase en contacto cun administrador.\nVelaquí hai unha breve descrición da regra de abuso coa que coincide a súa acción: $1", @@ -21,12 +24,14 @@ "abusefilter-blocker": "Filtro de abusos", "abusefilter-blockreason": "Bloqueado automaticamente polo filtro de abusos. Descrición da coincidencia da regra: $1", "abusefilter-degroupreason": "Os dereitos foron retirados automaticamente polo filtro de abusos. Descrición da regra: $1", + "abusefilter-blockautopromotereason": "Autopromoción atrasada automaticamente polo filtro de abusos. Descrición da regra: $1", "abusefilter-accountreserved": "Este nome de conta está reservado para ser usado polo filtro de abusos.", "right-abusefilter-modify": "Modificar os filtros de abusos", "right-abusefilter-view": "Ver os filtros de abusos", "right-abusefilter-log": "Ver o rexistro de abusos", "right-abusefilter-log-detail": "Ver os detalles das entradas do rexistro de abusos", - "right-abusefilter-private": "Ver os datos privados no rexistro de abusos", + "right-abusefilter-privatedetails": "Ver os datos privados no rexistro de abusos", + "right-abusefilter-privatedetails-log": "Ver o rexistro de consulta dos detalles privados do filtro de abusos", "right-abusefilter-modify-restricted": "Modificar os filtros de abusos con accións restrinxidas", "right-abusefilter-revert": "Reverter todos os cambios dun filtro de abusos dado", "right-abusefilter-view-private": "Ver os filtros de abusos marcados como privados", @@ -38,16 +43,22 @@ "action-abusefilter-view": "ver os filtros de abusos", "action-abusefilter-log": "ver o rexistro de abusos", "action-abusefilter-log-detail": "ver as entradas detalladas do rexistro de abusos", - "action-abusefilter-private": "ver os datos privados do rexistro de abusos", + "action-abusefilter-privatedetails": "ver os datos privados do rexistro de abusos", + "action-abusefilter-privatedetails-log": "ver o rexistro de consultas dos detalles privados do filtro de abusos", "action-abusefilter-modify-restricted": "modificar o filtro de abusos con accións restrinxidas", "action-abusefilter-revert": "reverter todo os cambios feitos por un filtro de abusos", "action-abusefilter-view-private": "ver os filtros de abusos marcados como privados", "action-abusefilter-log-private": "ver rexistros de filtros de abusos marcados como privados", - "abusefilter-log": "Rexistro do filtro de abusos", + "action-abusefilter-hide-log": "Agochar entradas no rexistro de abusos", + "action-abusefilter-hidden-log": "Ver as entradas agochadas do rexistro de abusos", + "action-abusefilter-modify-global": "Crear ou modificar os filtros globais de abusos", "abusefilter-log-summary": "Este rexistro amosa unha lista de tódalas accións capturadas polos filtros.", "abusefilter-log-search": "Procurar no rexistro de abusos", "abusefilter-log-search-user": "Usuario:", - "abusefilter-log-search-filter": "Identificadores dos filtros (separados por barras verticais):", + "abusefilter-log-search-group": "Grupo de filtros:", + "abusefilter-log-search-group-any": "Calquera", + "abusefilter-log-search-filter": "Identificadores de filtros:", + "abusefilter-log-search-filter-help": "Separado con tubos, prefixo con $1 para filtros globais", "abusefilter-log-search-title": "Título:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-impact": "Impacto:", @@ -58,6 +69,9 @@ "abusefilter-log-search-entries-all": "Todas as entradas", "abusefilter-log-search-entries-hidden": "Só as entradas ocultas", "abusefilter-log-search-entries-visible": "Só as entradas visibles", + "abusefilter-log-search-action-label": "Acción desencadeante:", + "abusefilter-log-search-action-other": "Outras", + "abusefilter-log-search-action-any": "Calquera", "abusefilter-log-search-action-taken-label": "Acción feita:", "abusefilter-log-search-action-taken-any": "Calquera", "abusefilter-log-search-submit": "Procurar", @@ -73,7 +87,7 @@ "abusefilter-log-details-var": "Variable", "abusefilter-log-details-val": "Valor", "abusefilter-log-details-vars": "Parámetros de acción", - "abusefilter-log-details-private": "Detalles do rexistro privado", + "abusefilter-log-details-privatedetails": "Detalles do rexistro privado", "abusefilter-log-details-ip": "Enderezo IP de orixe", "abusefilter-log-details-checkuser": "Verificación de usuario", "abusefilter-log-noactions": "ningunha", @@ -82,22 +96,34 @@ "abusefilter-log-linkoncontribs-text": "Rexistro de abusos para {{GENDER:$1|este usuario}}", "abusefilter-log-linkonhistory": "ver rexistro de abusos", "abusefilter-log-linkonhistory-text": "Ver o rexistro de abusos para esta páxina", - "abusefilter-log-hidden": "(entrada agochada)", + "abusefilter-log-linkonundelete": "ver o rexistro de abusos", + "abusefilter-log-linkonundelete-text": "Ver o rexistro de abusos para esta páxina", "abusefilter-log-hidden-implicit": "(agochado porque se borrou a revisión)", "abusefilter-log-cannot-see-details": "Non ten os permisos necesarios para ver os detalles desta entrada.", + "abusefilter-log-cannot-see-privatedetails": "Non ten os permisos necesarios para ver os detalles privados desta entrada.", "abusefilter-log-nonexistent": "Non existe ningunha entrada co ID proporcionado.", "abusefilter-log-details-hidden": "Non pode ollar os detalles desta entrada porque está agochada da vista pública.", + "abusefilter-log-details-hidden-implicit": "Non pode ollar os detalles desta entrada porque a súa revisión asociada está agochada da vista pública.", "abusefilter-log-private-not-included": "Un ou varios dos filtros especificados son privados. Dado que non ten os permisos necesarios para consultar os detalles dos filtros privados, estes filtros non aparecen nos resultados da procura.", "abusefilter-log-hide-legend": "Agochar a entrada no rexistro", "abusefilter-log-hide-id": "ID da entrada no rexistro:", "abusefilter-log-hide-hidden": "Agochar esta entrada da vista pública", "abusefilter-log-hide-reason": "Motivo:", + "abusefilter-log-hide-reason-other": "Outro motivo/motivo adicional:", "abusefilter-log-hide-forbidden": "Non ten os permisos necesarios para agochar entradas do rexistro de abusos.", + "abusefilter-log-entry-suppress": "$1 {{GENDER:$2|agochou}} $3", + "abusefilter-log-entry-unsuppress": "$1 {{GENDER:$2|revelou}} $3", "logentry-abusefilter-hit": "$1 {{GENDER:$2|accionou}} $4, ao {{GENDER:$2|levar}} a cabo a acción \"$5\" na páxina \"$3\". Medidas tomadas: $6 ($7)", "log-action-filter-abusefilter": "Tipo de cambio de filtro:", "log-action-filter-abusefilter-create": "Creación de novo filtro", "log-action-filter-abusefilter-modify": "Modificación de filtro", - "abusefilter-management": "Xestión do filtro de abusos", + "log-action-filter-suppress-abuselog": "Supresión do rexistro de abusos", + "log-action-filter-rights-blockautopromote": "Bloqueo de promoción automática", + "log-action-filter-rights-restoreautopromote": "Restauración da promoción automática", + "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|accedeu}} ós detalles privados de $3", + "logentry-rights-blockautopromote": "$1{{GENDER:$2|bloqueou}} a autopromoción de {{GENDER:$4|$3}} por un período de $5", + "logentry-rights-restoreautopromote": "$1{{GENDER:$2|restaurou}} a capacidade de autopromoción de {{GENDER:$4|$3}}", + "abusefilterprivatedetails-log-name": "Rexistro de consulta dos detalles privados do filtro de abusos", "abusefilter-list": "Todos os filtros", "abusefilter-list-id": "ID do filtro", "abusefilter-list-pattern": "Padrón", @@ -116,8 +142,10 @@ "abusefilter-enabled": "Activado", "abusefilter-deleted": "Borrado", "abusefilter-disabled": "Desactivado", + "abusefilter-throttled": "limitado", "abusefilter-hitcount": "$1 {{PLURAL:$1|detección|deteccións}}", "abusefilter-new": "Crear un novo filtro", + "abusefilter-import-button": "Importar un filtro", "abusefilter-return": "Volver ao xestor de filtros", "abusefilter-status-global": "Global", "abusefilter-list-options": "Opcións", @@ -138,6 +166,8 @@ "abusefilter-list-options-search-like": "Consulta sinxela", "abusefilter-list-options-search-rlike": "Expresión corrente", "abusefilter-list-options-search-irlike": "Expresión corrente insensíbel ó emprego de letras maiúsculas", + "abusefilter-list-invalid-searchmode": "O modo de procura especificado non é válido", + "abusefilter-list-regexerror": "Ocorreu un erro durante a procura: Erro de sintaxe na expresión regular.", "abusefilter-list-options-submit": "Actualizar", "abusefilter-tools-text": "Aquí hai algunhas ferramentas que poden ser de utilidade na formulación e depuración dos filtros de abusos.", "abusefilter-tools-expr": "Verificador de expresións", @@ -145,6 +175,7 @@ "abusefilter-tools-reautoconfirm": "Restaurar o estado de autoconfirmación", "abusefilter-tools-reautoconfirm-user": "Usuario:", "abusefilter-tools-reautoconfirm-submit": "Volver autoconfirmar", + "abusefilter-tools-restoreautopromote": "Autopromoción restaurada a través das ferramentas do filtro de abusos", "abusefilter-reautoconfirm-none": "{{GENDER:$1|Ese usuario|Esa usuaria}} non tivo o seu estado de autoconfirmación suspendido.", "abusefilter-reautoconfirm-notallowed": "Non ten os permisos necesarios para restaurar o estado de autoconfirmación.", "abusefilter-reautoconfirm-done": "Restaurouse o estado de autoconfirmación da conta", @@ -152,10 +183,10 @@ "abusefilter-edit": "Editando o filtro de abusos", "abusefilter-edit-subtitle": "Editando o filtro $1", "abusefilter-edit-subtitle-new": "Creando un filtro", + "abusefilter-edit-token-not-match": "A edición non foi gardada! Por favor, gárdea de novo.", "abusefilter-edit-oldwarning": "<strong>Está a editar unha versión vella deste filtro.\nAs estatísticas citadas son da versión máis recente do filtro.\nSe garda os seus cambios, sobrescribirá todos os cambios desde a revisión que está editando.</strong> •\n[[Special:AbuseFilter/history/$2|Volver ao historial deste filtro]].", "abusefilter-edit-status-label": "Estatísticas:", - "abusefilter-edit-status": "{{PLURAL:$1|Da última acción|Das $1 últimas accións}}, este filtro coincidiu con $2 (o $3%).", - "abusefilter-edit-status-profile": "{{PLURAL:$1|Da última acción|Das $1 últimas accións}}, este filtro coincidiu con $2 (o $3%).\nDe media, o seu tempo de execución é de $4ms, e consome {{PLURAL:$5|unha condición|$5 condicións}} do límite de condicións.", + "abusefilter-edit-status": "{{PLURAL:$1|Da última acción|Das $1 últimas accións}}, este filtro coincidiu con $2 (o $3%).\nDe media, o seu tempo é $4 ms, e consome $5 {{PLURAL:$5|condición|condicións}} do límite de condicións.", "abusefilter-edit-throttled-warning": "'''Atención:''' Este filtro foi marcado automáticamente como prexudicial. Como medida de seguridade, as seguintes accións non se executarán ($1). Por favor revisa e [[mw:Extension:AbuseFilter/Conditions|optimiza]] as túas condicións para eliminar esta restrición", "abusefilter-edit-new": "Novo filtro", "abusefilter-edit-save": "Gardar o filtro", @@ -187,27 +218,47 @@ "abusefilter-edit-action-tag": "Etiquetar a edición para unha revisión posterior", "abusefilter-edit-throttle-count": "Número de accións a permitir:", "abusefilter-edit-throttle-period": "Período de tempo (en segundos):", - "abusefilter-edit-throttle-groups": "Grupo acelerado por:\n:''(un por liña, combinar con comas)''", - "abusefilter-edit-throttle-ip": "Enderezo IP", - "abusefilter-edit-throttle-user": "Conta de usuario/a", - "abusefilter-edit-throttle-range": "rango /16", - "abusefilter-edit-throttle-page": "Páxina", + "abusefilter-edit-throttle-groups": "Grupo limitado por:", + "abusefilter-edit-throttle-groups-help": "Ver $1.", + "abusefilter-edit-throttle-groups-help-text": "A documentación en mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Separar con comas para unir con AND, e con saltos de liña para unicr con OR", + "abusefilter-edit-throttle-placeholder": "Separar con comas para unir con AND, e inserir unha a unha para unir con OR", + "abusefilter-throttle-ip": "enderezo IP", + "abusefilter-throttle-user": "conta de usuario", + "abusefilter-throttle-range": "rango /16", + "abusefilter-throttle-creationdate": "data de creación da conta", + "abusefilter-throttle-editcount": "total de edicións", + "abusefilter-throttle-site": "todo o sitio", + "abusefilter-throttle-page": "páxina", + "abusefilter-throttle-none": "(ningunha)", + "abusefilter-throttle-details": "Permitir $1 {{PLURAL:$1|acción|accións}} cada $2 {{PLURAL:$2|segundo|segundos}}, agrupar o limitador por: $3", "abusefilter-edit-warn-message": "Mensaxe do sistema a usar para a advertencia:", "abusefilter-edit-warn-other": "Outra mensaxe", - "abusefilter-edit-warn-other-label": "Nome da páxina doutra mensaxe:\n:''(sen o prefixo MediaWiki)''", + "abusefilter-edit-warn-other-label": "Nome da páxina doutra mensaxe:\n:''(sen o prefixo \"MediaWiki:\")''", "abusefilter-edit-warn-actions": "Accións:", "abusefilter-edit-warn-preview": "Amosar/Agochar vista previa da mensaxe seleccionada", "abusefilter-edit-warn-edit": "Crear/Editar a mensaxe seleccionada", + "abusefilter-edit-disallow-message": "Mensaxe do sistema usada para o rexeitamento:", + "abusefilter-edit-disallow-other": "Outra mensaxe", + "abusefilter-edit-disallow-other-label": "Nome da páxina doutra mensaxe:\n:''(sen o prefixo \"MediaWiki:\")''", + "abusefilter-edit-disallow-actions": "Accións:", + "abusefilter-edit-disallow-preview": "Amosar/Agochar vista previa da mensaxe seleccionada", + "abusefilter-edit-disallow-edit": "Crear/Editar a mensaxe seleccionada", "abusefilter-edit-tag-tag": "[[Special:Tags|Etiquetas]] a aplicar:", + "abusefilter-edit-tag-placeholder": "Engade etiquetas (unha por unha ou separadas por comas)", + "abusefilter-edit-tag-hidden-placeholder": "Engade etiquetas (separadas por comas)", "abusefilter-edit-block-anon-durations": "Duración do bloqueo pra os usuarios anónimos:", "abusefilter-edit-block-user-durations": "Duración do bloqueo pra os usuarios rexistados:", "abusefilter-block-anon": "Bloquear usuarios anónimos", "abusefilter-block-user": "Bloquear usuarios rexistrados", + "abusefilter-block-talk": "páxina de conversa bloqueada", "abusefilter-edit-denied": "Poida que non vexa os detalles deste filtro porque está agochado da vista pública.", "abusefilter-edit-main": "Parámetros do filtro", "abusefilter-edit-done-subtitle": "Filtro editado", "abusefilter-edit-done": "Gardáronse correctamente [[Special:AbuseFilter/history/$1/diff/prev/$2|os cambios]] que fixo no [[Special:AbuseFilter/$1|filtro $3]].", "abusefilter-edit-badsyntax": "Hai un erro de sintaxe no filtro que especificou. A función analítica de saída foi: <pre>$1</pre>", + "abusefilter-edit-missingfields": "Os campos seguintes son requiridos e deben ser enchidos: $1", + "abusefilter-edit-deleting-enabled": "Non podes marcar un filtro activo como eliminado", "abusefilter-edit-restricted": "Non pode editar este filtro, dado que contén unha ou máis accións restrinxidas.\nPor favor, pregúntelle a un usuario cos permisos necesarios para engadir accións restrinxidas se pode facer o cambio por vostede.", "abusefilter-edit-viewhistory": "Ver o historial deste filtro", "abusefilter-edit-history": "Historial:", @@ -219,10 +270,18 @@ "abusefilter-edit-export": "Exportar este filtro a outro wiki", "abusefilter-edit-syntaxok": "Non se detectaron erros de sintaxe.", "abusefilter-edit-syntaxerr": "Detectouse un erro de sintaxe: $1", - "abusefilter-edit-bad-tags": "Unha ou máis das etiquetas que especificou non é/son válida(s).\nAs etiquetas deberían ser curtas, non conter caracteres especiais, e non deben estar reservadas por outros programas. Probe de novo con outro nome de etiqueta.", + "abusefilter-edit-warn-leave": "Abandonar a páxina causará a perda de tódalas alteracións feitas a este filtro.", + "abusefilter-edit-bad-tags": "Unha ou máis das etiquetas que especificou non son válidas.\nAs etiquetas deben ser curtas, non conter caracteres especiais, e non deben estar reservadas por outros programas. Proba de novo con outro nome de etiqueta.", "abusefilter-edit-notallowed": "Non ten os permisos necesarios para crear ou editar filtros de abusos", "abusefilter-edit-notallowed-global": "Non ten os permisos necesarios para crear ou editar filtros de abusos globais", - "abusefilter-edit-notallowed-global-custom-msg": "Os filtros globais non soportan as mensaxes de aviso personalizadas", + "abusefilter-edit-notallowed-global-custom-msg": "As mensaxes de advertencia ou rexeitamento personalizados no son compatibles cos filtros globais", + "abusefilter-edit-invalid-warn-message": "A mensaxe de aviso non pode ficar baleira.", + "abusefilter-edit-invalid-disallow-message": "A mensaxe de rexeitamento non pode ficar baleira.", + "abusefilter-edit-invalid-throttlecount": "O reconto de accións debe ser un número enteiro positivo.", + "abusefilter-edit-invalid-throttleperiod": "O período de aceleración debe ser un número enteiro positivo.", + "abusefilter-edit-empty-throttlegroups": "Cando menos un grupo de acelerador debe ser seleccionado.", + "abusefilter-edit-duplicated-throttlegroups": "Os grupos de acelerador non poden ter duplicados.", + "abusefilter-edit-invalid-throttlegroups": "Os grupos de acelerador especificados non son válidos.", "abusefilter-edit-builder-select": "Seleccione unha opción para engadila ao cursor", "abusefilter-edit-builder-group-op-arithmetic": "Operadores aritméticos", "abusefilter-edit-builder-op-arithmetic-addition": "Suma (+)", @@ -252,13 +311,15 @@ "abusefilter-edit-builder-misc-contains": "A cadea da esquerda contén a cadea da dereita (contains)", "abusefilter-edit-builder-misc-stringlit": "Comiñas (\"\")", "abusefilter-edit-builder-misc-tern": "Operador ternario (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Condicional (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Condicional (se X entón Y máis Z fin)", + "abusefilter-edit-builder-misc-cond-short": "Condicional curto (se X entón Y fin)", "abusefilter-edit-builder-group-funcs": "Funcións", "abusefilter-edit-builder-funcs-length": "Lonxitude da cadea de caracteres (length)", "abusefilter-edit-builder-funcs-lcase": "Caracteres en minúsculas (lcase)", "abusefilter-edit-builder-funcs-ucase": "Caracteres en maiúsculas (ucase)", "abusefilter-edit-builder-funcs-ccnorm": "Normalizar os caracteres confusos (ccnorm)", - "abusefilter-edit-builder-funcs-ccnorm-contains-any": "Normalizar e procurar unha cadea de texto para subcadeas múltiples (ccnorm_contains_any)", + "abusefilter-edit-builder-funcs-ccnorm-contains-any": "Normalizar e procurar unha cadea de texto para subcadeas múltiples en modo OU (ccnorm_contains_any)", + "abusefilter-edit-builder-funcs-ccnorm-contains-all": "Normalizar e procurar unha cadea de texto para subcadeas múltiples en modo E (ccnorm_contains_all)", "abusefilter-edit-builder-funcs-rmdoubles": "Eliminar os caracteres dobres (rmdoubles)", "abusefilter-edit-builder-funcs-specialratio": "Caracteres especiais / caracteres totais (specialratio)", "abusefilter-edit-builder-funcs-norm": "Normalizar (norm)", @@ -269,11 +330,14 @@ "abusefilter-edit-builder-funcs-rmspecials": "Eliminar os caracteres especiais (rmspecials)", "abusefilter-edit-builder-funcs-ip_in_range": "Quere ver se o enderezo IP está no rango? (ip_in_range)", "abusefilter-edit-builder-funcs-contains-any": "Procurar a cadea para múltiples subcadeas (contains_any)", + "abusefilter-edit-builder-funcs-contains-all": "Procurar a cadea para múltiples subcadeas en modo E (contains_all)", + "abusefilter-edit-builder-funcs-equals-to-any": "Verificar se un argumento dado é igual (===) a algún dos seguintes argumentos (equals_to_any)", "abusefilter-edit-builder-funcs-substr": "Subcadea (substr)", "abusefilter-edit-builder-funcs-strpos": "Posición da subcadea na cadea (strpos)", "abusefilter-edit-builder-funcs-str_replace": "Substituír a subcadea pola cadea (str_replace)", "abusefilter-edit-builder-funcs-rescape": "Cadea de escape literal na expresión regular (rescape)", "abusefilter-edit-builder-funcs-set_var": "Configurar a variable (set_var)", + "abusefilter-edit-builder-funcs-sanitize": "Normalizar as entidades de HTML en caracteres Unicode (sanitize)", "abusefilter-edit-builder-group-vars": "Variables", "abusefilter-edit-builder-vars-accountname": "Nome da conta (na creación de contas)", "abusefilter-edit-builder-vars-timestamp": "Hora Unix do cambio", @@ -292,14 +356,17 @@ "abusefilter-edit-builder-vars-page-ns": "Espazo de nomes da páxina", "abusefilter-edit-builder-vars-page-title": "Título da páxina (sen o espazo de nomes)", "abusefilter-edit-builder-vars-page-prefixedtitle": "Título completo da páxina", + "abusefilter-edit-builder-vars-page-age": "Idade de páxina (en segundos)", "abusefilter-edit-builder-vars-movedfrom-id": "ID da páxina que vai ser movida", "abusefilter-edit-builder-vars-movedfrom-ns": "Espazo de nomes da páxina que non vai ser movida", "abusefilter-edit-builder-vars-movedfrom-title": "Título da páxina que vai ser movida", "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "Nome completo da páxina que vai ser movida", + "abusefilter-edit-builder-vars-movedfrom-age": "Idade de páxina de orixe do movemento (en segundos)", "abusefilter-edit-builder-vars-movedto-id": "ID da páxina de destino da páxina que vai ser movida", "abusefilter-edit-builder-vars-movedto-ns": "Espazo de nomes do destino da páxina que vai ser movida", "abusefilter-edit-builder-vars-movedto-title": "Nome do destino da páxina que vai ser movida", "abusefilter-edit-builder-vars-movedto-prefixedtitle": "Nome completo do destino da páxina que vai ser movida", + "abusefilter-edit-builder-vars-movedto-age": "Idade da páxina de destino do movemento (en segundos)", "abusefilter-edit-builder-vars-user-editcount": "Contador de edicións do usuario", "abusefilter-edit-builder-vars-user-age": "Idade da conta de usuario", "abusefilter-edit-builder-vars-user-name": "Nome da conta de usuario", @@ -309,24 +376,36 @@ "abusefilter-edit-builder-vars-user-emailconfirm": "Data de confirmación do enderezo de correo electrónico", "abusefilter-edit-builder-vars-recent-contributors": "Os últimos dez editores do artigo", "abusefilter-edit-builder-vars-first-contributor": "Primeiro editor en editar a páxina", + "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "Últimos dez usuarios que colaboraron na páxina de orixe do movemento", + "abusefilter-edit-builder-vars-movedfrom-first-contributor": "Primeiro usuario que colaborou na páxina de orixe do movemento", + "abusefilter-edit-builder-vars-movedto-recent-contributors": "Últimos dez usuarios que contribuíron na páxina de destino do movemento", + "abusefilter-edit-builder-vars-movedto-first-contributor": "Primeiro usuario que colaborou na páxina de destino do movemento", "abusefilter-edit-builder-vars-all-links": "Todas as ligazóns externas do novo texto", "abusefilter-edit-builder-vars-added-links": "Todas as ligazóns externas engadidas na edición", "abusefilter-edit-builder-vars-removed-links": "Todas as ligazóns externas eliminadas na edición", - "abusefilter-edit-builder-vars-old-text": "Texto wiki vello da páxina, antes da edición", - "abusefilter-edit-builder-vars-new-text": "Texto wiki novo da páxina, despois da edición", + "abusefilter-edit-builder-vars-old-wikitext": "Texto wiki anterior da páxina, antes da edición", + "abusefilter-edit-builder-vars-new-wikitext": "Texto wiki novo da páxina, despois da edición", "abusefilter-edit-builder-vars-new-pst": "Texto wiki novo da páxina, transformado antes de gardar", "abusefilter-edit-builder-vars-diff-pst": "Diferenza unificada das modificacións feitas pola edición, transformada antes de gardar", "abusefilter-edit-builder-vars-addedlines-pst": "Liñas engadidas na edición, transformadas antes de gardar", - "abusefilter-edit-builder-vars-new-text-stripped": "Texto novo da páxina, sen ningunha marca", + "abusefilter-edit-builder-vars-new-text": "Texto novo da páxina, sen ningunha marca", "abusefilter-edit-builder-vars-new-html": "Fonte HTML transformada na nova revisión", "abusefilter-edit-builder-vars-restrictions-edit": "Nivel de protección de edición da páxina", "abusefilter-edit-builder-vars-restrictions-move": "Nivel de protección de traslado da páxina", "abusefilter-edit-builder-vars-restrictions-create": "Protección de creación desta páxina", "abusefilter-edit-builder-vars-restrictions-upload": "Protección de carga deste ficheiro", - "abusefilter-edit-builder-vars-old-text-stripped": "Texto vello da páxina, carente de calquera marca", + "abusefilter-edit-builder-vars-movedfrom-restrictions-edit": "Nivel de proteción de edicións da páxina de orixe do movemento", + "abusefilter-edit-builder-vars-movedfrom-restrictions-move": "Nivel de protección de movementos da páxina de orixe do movemento", + "abusefilter-edit-builder-vars-movedfrom-restrictions-create": "Protección da creación da páxina de orixe do movemento", + "abusefilter-edit-builder-vars-movedfrom-restrictions-upload": "Protección de carga do ficheiro de orixe do movemento", + "abusefilter-edit-builder-vars-movedto-restrictions-edit": "Nivel de protección de edicións da páxina de destino do movemento", + "abusefilter-edit-builder-vars-movedto-restrictions-move": "Nivel de protección de movementos da páxina de destino do movemento", + "abusefilter-edit-builder-vars-movedto-restrictions-create": "Protección de creación da páxina de destino do movemento", + "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Protección de carga do ficheiro de destino do movemento", + "abusefilter-edit-builder-vars-old-text": "Texto vello da páxina, carente de calquera marca", "abusefilter-edit-builder-vars-old-links": "Ligazóns na páxina antes da edición", - "abusefilter-edit-builder-vars-old-html": "Texto wiki vello da páxina, analizado en HTML", - "abusefilter-edit-builder-vars-minor-edit": "Se a edición está marcada como menor ou non", + "abusefilter-edit-builder-vars-old-html": "Texto wiki anterior da páxina, convertido en HTML (xa non é empregado)", + "abusefilter-edit-builder-vars-minor-edit": "Se a edición está marcada ou non como menor (xa non é empregado)", "abusefilter-edit-builder-vars-file-sha1": "Hash SHA1 dos contidos do ficheiro", "abusefilter-edit-builder-vars-file-size": "Tamaño do ficheiro en bytes", "abusefilter-edit-builder-vars-file-mime": "Tipo MIME do ficheiro", @@ -334,6 +413,8 @@ "abusefilter-edit-builder-vars-file-width": "Ancho do ficheiro en píxeles", "abusefilter-edit-builder-vars-file-height": "Altura do ficheiro en píxeles", "abusefilter-edit-builder-vars-file-bits-per-channel": "Número de bits por canle de cor do ficheiro", + "abusefilter-edit-builder-vars-wiki-name": "Nome de base de datos do wiki", + "abusefilter-edit-builder-vars-wiki-language": "Código de lingua do wiki", "abusefilter-filter-log": "Cambios recentes nos filtros", "abusefilter-history": "Historial de cambios do filtro de abusos nº$1", "abusefilter-history-foruser": "Cambios feitos por $1", @@ -363,14 +444,20 @@ "abusefilter-exception-unclosedstring": "Cadea de caracteres sen pechar que comeza no carácter $1.", "abusefilter-exception-invalidoperator": "Operador \"$2\" inválido no carácter $1.", "abusefilter-exception-unrecognisedtoken": "Pase \"$2\" non recoñecido no carácter $1.", - "abusefilter-exception-noparams": "Non se lle deu ningún parámetro á función \"$2\" no carácter $1.", + "abusefilter-exception-noparams": "Non foram engadidos parámetros á función \"$2\", na posición $1.\n{{PLURAL:$3|Era esperado $3 argumento|Eran esperados $3 argumentos}}.", "abusefilter-exception-dividebyzero": "Intento ilegal de dividir $2 entre cero no carácter $1.", "abusefilter-exception-unrecognisedvar": "Variable $2 descoñecida no carácter $1", "abusefilter-exception-notenoughargs": "Non hai argumentos dabondo para a función $2 chamada no carácter $1.\n{{PLURAL:$3|Agardábase o argumento|Agardábanse os argumentos}} $3, obtívose $4", - "abusefilter-exception-regexfailure": "Erro na expresión regular \"$3\" no carácter $1: \"$2\"", - "abusefilter-exception-overridebuiltin": "Ignorancia ilegal da variable incorporada \"$2\" no carácter $1.", - "abusefilter-exception-outofbounds": "O elemento $2 solicitado da lista non existe (tamaño da lista = $3) no carácter $1.", + "abusefilter-exception-toomanyargs": "Foron engadidos demasiados argumentos á función $2 chamada no carácter $1.\nEra esperado un máximo de $3 {{PLURAL:$3|argumento|argumentos}}; foron engadidos $4", + "abusefilter-exception-regexfailure": "Erro na expresión regular \"$2\" no carácter $1.", + "abusefilter-exception-overridebuiltin": "Sobreescritura ilegal do identificador integrado \"$2\" no carácter $1.", + "abusefilter-exception-outofbounds": "Foi solicitada a entrada $2 que non existe na matriz (tamaño da matriz = $3) na posición $1.", + "abusefilter-exception-negativeindex": "Os índices negativos non están permitidos nas matrices. Obtivo o índice \"$2\" no carácter $1.", "abusefilter-exception-notarray": "Conxunto de elementos solicitados de non conxunto no carácter $1.", + "abusefilter-exception-unclosedcomment": "Comentario por pechar, no carácter $1.", + "abusefilter-exception-invalidiprange": "Foi fornecida unha gama IP inválida \"$2\" no carácter $1.", + "abusefilter-exception-disabledvar": "A variable $2 na posición $1 deixou de ser usada.", + "abusefilter-exception-variablevariable": "Non son permitidas variables variantes; foron encontradas no carácter $1.", "abusefilter-action-tag": "Etiquetar", "abusefilter-action-throttle": "Limitar", "abusefilter-action-warn": "Avisar", @@ -388,6 +475,7 @@ "abusefilter-revert-search": "Seleccionar as accións", "abusefilter-revert-filter": "ID do filtro:", "abusefilter-revert-preview-intro": "A continuación están as accións levadas a cabo polo filtro de abusos que serán revertidas con esta acción.\nPor favor, compróbeas con coidado e prema en \"{{int:abusefilter-revert-confirm}}\" para confirmar a súa selección.", + "abusefilter-revert-confirm-legend": "Confirmar a reversión", "abusefilter-revert-confirm": "Confirmar", "abusefilter-revert-success": "Reverteu todas as accións feitas polo [[Special:AbuseFilter/$1|filtro de abusos $2]].", "abusefilter-revert-reason": "Reversión automática de todas as accións feitas polo filtro de abusos $1.\nMotivo dado: $2", @@ -406,6 +494,7 @@ "abusefilter-test-shownegative": "Amosar os cambios que non coincidan co filtro", "abusefilter-test-syntaxerr": "O filtro que introduciu contiña un erro na súa sintaxe.\nPode obter unha explicación completa premendo no botón \"{{int:abusefilter-edit-check}}\".", "abusefilter-test-badtitle": "O título de páxina que inseriu non é válido. Se cadra, contén un ou máis caracteres que non se poden usar nos títulos.", + "abusefilter-test-action": "Tipo de acción:", "abusefilter-test-search-type-all": "Todas as accións", "abusefilter-test-search-type-edit": "Edicións", "abusefilter-test-search-type-move": "Movementos", @@ -431,15 +520,16 @@ "abusefilter-examine-noresults": "Non se atoparon resultados para os parámetros de procura que facilitou.", "abusefilter-topnav": "'''Navegación do filtro de abusos'''", "abusefilter-topnav-home": "Inicio", + "abusefilter-topnav-recentchanges": "Cambios recentes nos filtros", "abusefilter-topnav-test": "Conxunto de probas", "abusefilter-topnav-examine": "Examinar as edicións pasadas", "abusefilter-topnav-log": "Rexistro de abusos", "abusefilter-topnav-tools": "Ferramentas de depuración", - "abusefilter-topnav-import": "Importar un filtro", "abusefilter-log-name": "Rexistro do filtro de abusos", "abusefilter-log-header": "Este rexistro amosa un resumo dos cambios feitos aos filtros.\nPara obter máis detalles, vaia [[Special:AbuseFilter/history|á lista]] dos cambios feitos recentemente nos filtros.", "abusefilter-logentry-create": "$1 {{GENDER:$2|creou}} $4 ($5)", "abusefilter-logentry-modify": "$1 {{GENDER:$2|modificou}} $4 ($5)", + "abusefilter-log-invalid-filter": "Algúns dos identificadores de filtro especificados non son válidos.", "abusefilter-log-noresults": "Non hai resultados", "abusefilter-diff-title": "Diferenzas entre versións", "abusefilter-diff-item": "Elemento", @@ -452,9 +542,19 @@ "abusefilter-diff-next": "Edición máis nova", "abusefilter-import-intro": "Pode empregar esta interface para importar filtros doutros wikis.\nNo wiki de orixe, prema en \"{{int:abusefilter-edit-export}}\" baixo a opción \"{{int:abusefilter-edit-tools}}\" na interface de edición.\nCopie a caixa de texto que aparece e péguea nestoutra caixa de texto, logo prema en \"{{int:abusefilter-import-submit}}\",", "abusefilter-import-submit": "Importar os datos", + "abusefilter-import-invalid-data": "Os datos que intentou importar non son válidos", "abusefilter-group-default": "Predeterminado", "abusefilter-http-error": "Produciuse un erro HTTP: $1", - "abusefilter-view-private-submit": "Ver detalles privados", - "abusefilter-view-private": "Ver detalles privados", - "abusefilter-log-ip-not-available": "Non dispoñíbel" + "abusefilter-view-privatedetails-submit": "Ver detalles privados", + "abusefilter-view-privatedetails-legend": "Ver detalles privados", + "abusefilter-view-privatedetails-reason": "Motivo para aceder aos detalles privados:", + "abusefilter-log-details-id": "Identificador de rexistro", + "abusefilter-invalid-request": "Petición inválida! Debe acceder aos detalles privados do rexistro a través do formulario en [[Special:AbuseLog/$1]] e fornecer un motivo.", + "abusefilter-invalid-request-noid": "Petición inválida! Debe acceder aos detalles privados do rexistro a través do formulario na páxina dos detalles do rexisto de abusos e fornecer un motivo.", + "log-description-abusefilterprivatedetails": "Este rexistro amosa unha lista das veces que o usuario consultou os detalles privados dun rexistro de abusos.", + "abusefilter-noreason": "Aviso: Para ver os detalles privados deste rexistro, debe fornecer un motivo.", + "abusefilter-log-ip-not-available": "Non dispoñíbel", + "abusefilter-tag-reserved": "O elemento <code>abusefilter-condition-limit</code> está reservado para uso interno polo Filtro de Abusos.", + "tag-abusefilter-condition-limit": "limite de condicións atinxido", + "tag-abusefilter-condition-limit-description": "Edicións ou outros acontecementos que non puideron ser verificados por todos os [[Special:AbuseFilter|filtros de abuso]] activos ([[mw:Extension:AbuseFilter/Conditions|axuda]])." } diff --git a/AbuseFilter/i18n/gom-latn.json b/AbuseFilter/i18n/gom-latn.json new file mode 100644 index 00000000..27afaefc --- /dev/null +++ b/AbuseFilter/i18n/gom-latn.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "The Discoverer" + ] + }, + "abusefilter-log-search-impact-saved": "Fokot samballeleo bodol dakhoi", + "abusefilter-log-search-action-taken-any": "Khuimcheim", + "tag-abusefilter-condition-limit": "ottiche xime kodden pavlam", + "tag-abusefilter-condition-limit-description": "Sompadon vo her vostu jeo sogllea kriaxil [[Special:AbuseFilter|vaitt upeg gallnneanchean]] topasunk zavnk na ([[mw:Extension:AbuseFilter/Conditions|adar]])." +} diff --git a/AbuseFilter/i18n/grc.json b/AbuseFilter/i18n/grc.json index 3e71fe4d..ead8ff31 100644 --- a/AbuseFilter/i18n/grc.json +++ b/AbuseFilter/i18n/grc.json @@ -6,10 +6,8 @@ "Omnipaedista" ] }, - "abusefilter": "Διαμόρφωσις διηθητηρίου καταχρήσεων", - "abuselog": "Κατάλογος καταχρήσεων", + "abuselog": "Κατάλογος διηθητηρίου καταχρήσεων", "abusefilter-blocker": "Διηθητήριον καταχρήσεων", - "abusefilter-log": "Κατάλογος διηθητηρίου καταχρήσεων", "abusefilter-log-search-user": "Χρώμενος:", "abusefilter-log-search-title": "Ἐπιγραφή:", "abusefilter-log-search-submit": "Ζητεῖν", @@ -18,7 +16,7 @@ "abusefilter-log-detailslink": "λεπτομέρειαι", "abusefilter-log-details-var": "Μεταβλητή", "abusefilter-log-details-val": "Τιμή", - "abusefilter-log-details-private": "Ἰδιωτικὰ δεδομένα", + "abusefilter-log-details-privatedetails": "Ἰδιωτικὰ δεδομένα", "abusefilter-log-noactions": "οὐδέν", "abusefilter-log-linkoncontribs": "κατάλογος καταχρήσεων", "abusefilter-list": "Ἅπαντα τὰ διηθητήρια", diff --git a/AbuseFilter/i18n/gsw.json b/AbuseFilter/i18n/gsw.json index e1cfe5a3..fdd9bd88 100644 --- a/AbuseFilter/i18n/gsw.json +++ b/AbuseFilter/i18n/gsw.json @@ -4,13 +4,13 @@ "Als-Chlämens", "Als-Holder", "J. 'mach' wust", - "Melancholie", - "Matma Rex" + "Matma Rex", + "Melancholie" ] }, "abusefilter-desc": "Wändet automatischi Heurischtike uf Änderigen aa.", - "abusefilter": "Missbruuchsfilter-Yystellige", - "abuselog": "Missbruuchs-Logbuech", + "abusefilter": "Missbruuchsfilter-Verwaltig", + "abuselog": "Missbruuchsfilter-Logbuech", "abusefilter-intro": "Willchu uf dr Hauptsyte vu dr Missbruuchsfilter-Verwaltig.\nDr Missbruuchsfilter isch e automatische Software-Mechanismus, wu automatische Heurischtike an allene Aktion durfiert.\nDie Syte zeigt e Lischte vu definierte Filter. D Filter chenne uf däre Syte au gänderert wäre.", "abusefilter-warning": "'''Obacht''': Die Aktion isch automatisch as schädlig erkannt wore.\nUnkonschtruktivi Byyträg wäre zmeischt zimli schnäll usegnuh. In widerholte un bsundersch schlimme Fäll wird Dyy Benutzerkonto bzw. Dyyni IP-Adräss gsperrt.\nWänn Du dänksch, ass Dyyni Änderig konschtruktiv gsi isch, chasch si aber bstätige, indäm Du nomol uf „{{int:savearticle}}“ drucksch.\n\nChurzbschryybig vu dr verletzte Regle: '''$1'''", "abusefilter-disallowed": "Die Aktion isch automatisch as schädlig erkannt wore un isch wäge däm nit durgfiert wore.\nWänn Du dänksch, ass Dyyni Änderig konschtruktiv gsi isch, wänd Di bitte an e Ammann un schryyb em, was Du mit Dyynere Änderig hesch welle.\n\nChurzbschryybig vu dr verletzte Regle: $1", @@ -25,7 +25,7 @@ "right-abusefilter-view": "Missbruuchsfilter aaluege", "right-abusefilter-log": "Missbruuchs-Logbuech aaluege", "right-abusefilter-log-detail": "Detailliert Missbruuchs-Logbuech aaluege", - "right-abusefilter-private": "Privati Date im Missbruuchs-Logbuech aaluege", + "right-abusefilter-privatedetails": "Privati Date im Missbruuchs-Logbuech aaluege", "right-abusefilter-modify-restricted": "Filter ändere mit bschränkte Aktione", "right-abusefilter-revert": "Alli Änderige vum Missbruchsfilter, wu aagee isch, zruggsetze", "right-abusefilter-view-private": "D Missbruchfilter aaluege, wu as privat markiert sin", @@ -36,11 +36,10 @@ "action-abusefilter-view": "Missbruuchsfilter aaluege", "action-abusefilter-log": "Missbruuchsfilterlogbuech aaluege", "action-abusefilter-log-detail": "Detaillierti Yyträg im Missbruuchsfilterlogbuech aaluege", - "action-abusefilter-private": "Privati Date im Missbruuchsfilterlogbuech aaluege", + "action-abusefilter-privatedetails": "Privati Date im Missbruuchsfilterlogbuech aaluege", "action-abusefilter-modify-restricted": "Missbruuchsfilter ändere mit yygschränkte Aktione", "action-abusefilter-revert": "Alli Änderige vun eme Missbruuchsfilter zrucksetze", "action-abusefilter-view-private": "d Missbruchsfilter aaluege, wu as privat markiert sin", - "abusefilter-log": "Missbruuchsfilter-Logbuech", "abusefilter-log-summary": "Des Logbuech zeigt alli Aktione, wu vu dr Filter usegfilteret wore sin.", "abusefilter-log-search": "Im Missbruuchs-Logbuech sueche", "abusefilter-log-search-user": "Benutzer:", @@ -59,13 +58,11 @@ "abusefilter-log-details-var": "Variable", "abusefilter-log-details-val": "Wärt", "abusefilter-log-details-vars": "Aktionsparameter", - "abusefilter-log-details-private": "Privati Date", "abusefilter-log-details-ip": "IP-Adräss vum Verursacher", "abusefilter-log-noactions": "keini", "abusefilter-log-details-diff": "Änderige, wu in dr Bearbeitig gmacht wore sin", "abusefilter-log-linkoncontribs": "Missbruchs-Logbuech", "abusefilter-log-linkoncontribs-text": "Missbruchs-Logbuech fir dää Benuzter", - "abusefilter-log-hidden": "(Yytrag versteckt)", "abusefilter-log-hidden-implicit": "(versteckt, wel d Version glescht woren isch)", "abusefilter-log-cannot-see-details": "Du derfsch d Einzelheite zue däre Yygab nit aaluege.", "abusefilter-log-details-hidden": "Du chasch d Detail vu däm Yytrag nit bschaue, wel si uusbländet sin fir d Effentligkeit.", @@ -75,7 +72,6 @@ "abusefilter-log-hide-reason": "Grund:", "abusefilter-log-hide-forbidden": "Du derfsch d Yytreg vum Missbruuchsfilter-Logbuech nit uusblände.", "logentry-abusefilter-hit": "$1 het bim Ussfüere vo de Aktion „$5“ uff $3 de Filter $4 ussglöst. Usswirkig: $6 ($7)", - "abusefilter-management": "Missbruuchsfilter-Verwaltig", "abusefilter-list": "Alli Filter", "abusefilter-list-id": "Filter-ID", "abusefilter-list-status": "Status", @@ -95,6 +91,7 @@ "abusefilter-disabled": "Deaktiviert", "abusefilter-hitcount": "{{PLURAL:$1|1 Träffer|$1 Träffer}}", "abusefilter-new": "E neje Filter aalege", + "abusefilter-import-button": "Filter importiere", "abusefilter-return": "Zrugg zue dr Missbruuchsfilter-Verwaltig", "abusefilter-status-global": "Wältwyt", "abusefilter-list-options": "Optione", @@ -122,7 +119,6 @@ "abusefilter-edit-oldwarning": "<strong>Du bearbeitsch nit di aktuäll, sundere ne elteri Version vu däm Filter. D Statischtik giltet nume fir di letscht Version vum Filter. Wänn Du spycheresch, wird die as aktuälli Version nej gspycheret. </strong> • [[Special:AbuseFilter/history/$2|Zrugg zue dr Versionsgeschicht vum Filter]]", "abusefilter-edit-status-label": "Statischtike:", "abusefilter-edit-status": "Vu dr letschte {{PLURAL:$1|Aktion|$1 Aktione}} {{PLURAL:$2|isch|sin}} $2 ($3 %) vu däm Filter gchännt wore. Im Durschnitt het dr Filter e Laufzyt vu $4 ms, un är het $5 {{PLURAL:$5|Bedingig|Bedingige}} vum Bedingigslimit brucht.", - "abusefilter-edit-status-profile": "Vu dr letschte {{PLURAL:$1|Aktion|$1 Aktione}} {{PLURAL:$2|isch|sin}} $2 ($3 %) vu däm Filter gchännt wore. Im Durschnitt het dr Filter e Laufzyt vu $4 ms, un är het $5 {{PLURAL:$5|Bedingig|Bedingige}} vum Bedingigslimit brucht.", "abusefilter-edit-new": "Neje Filter", "abusefilter-edit-save": "Filter spychere", "abusefilter-edit-id": "Filter-ID:", @@ -253,15 +249,15 @@ "abusefilter-edit-builder-vars-all-links": "Alli extärne Links im neje Täxt", "abusefilter-edit-builder-vars-added-links": "Alle extärne Links, wu dur d Bearbeitig zuegfiegt wore sin", "abusefilter-edit-builder-vars-removed-links": "All extärne Links, wu dur d Bearbeitig usegnuh wore sin", - "abusefilter-edit-builder-vars-old-text": "Dr alt Sytetäxt vor dr Bearbeitig", - "abusefilter-edit-builder-vars-new-text": "Neje Sytetäxt no dr Bearbeitig", - "abusefilter-edit-builder-vars-new-text-stripped": "Neje Sytetäxt ohni Markierige", + "abusefilter-edit-builder-vars-old-wikitext": "Dr alt Sytetäxt vor dr Bearbeitig", + "abusefilter-edit-builder-vars-new-wikitext": "Neje Sytetäxt no dr Bearbeitig", + "abusefilter-edit-builder-vars-new-text": "Neje Sytetäxt ohni Markierige", "abusefilter-edit-builder-vars-new-html": "HTML-Quälltäxt vu dr neje Version", "abusefilter-edit-builder-vars-restrictions-edit": "Schutzstatus vu däre Syte", "abusefilter-edit-builder-vars-restrictions-move": "Schutzstatus vu däre Syte verschiebe", "abusefilter-edit-builder-vars-restrictions-create": "Syteschutz aalege", "abusefilter-edit-builder-vars-restrictions-upload": "Uffeladschutz vu dr Datei", - "abusefilter-edit-builder-vars-old-text-stripped": "Alte Sytetäkscht, wu alli Markierige uusegnuu sin", + "abusefilter-edit-builder-vars-old-text": "Alte Sytetäkscht, wu alli Markierige uusegnuu sin", "abusefilter-edit-builder-vars-old-links": "Links in dr Syte, vor dr Bearbeitig", "abusefilter-edit-builder-vars-old-html": "Alte Sytetäkscht, parsed in HTML", "abusefilter-edit-builder-vars-minor-edit": "Eb d Bearbeitig as \"chly\" markiert wird oder nit", @@ -358,7 +354,6 @@ "abusefilter-topnav-examine": "Letschti Bearbeitige priefe", "abusefilter-topnav-log": "Missbruuchsfilter-Logbuech", "abusefilter-topnav-tools": "Wärchzyyg debugge", - "abusefilter-topnav-import": "Filter importiere", "abusefilter-log-name": "Missbruuchsfilter-Logbuech", "abusefilter-log-header": "Des Logbuech zeigt d Änderige, wu an Filter gmacht wore sin.\nFir meh Detail lueg d [[Special:AbuseFilter/history|Lischt vu dr letschte Filteränderige]].", "abusefilter-log-noresults": "Kei Ergebniss", diff --git a/AbuseFilter/i18n/gu.json b/AbuseFilter/i18n/gu.json index e36346e3..8ddd888e 100644 --- a/AbuseFilter/i18n/gu.json +++ b/AbuseFilter/i18n/gu.json @@ -10,20 +10,18 @@ ] }, "abusefilter-desc": "સંપાદનો પર સ્વચલિત સંશોધનાત્મક પ્રણાલી લાગુ કરે છે", - "abusefilter": "દુરુપયોગ ગળણી રૂપરેખા", - "abuselog": "દુરુપયોગ નોંધ", + "abuselog": "દુરુપયોગ ગળણી નોંધ", "abusefilter-blocker": "દુરુપયોગ ગળણી", "right-abusefilter-modify": "દુરુપયોગ ગાળકોમાં ફેરફાર કરો", "right-abusefilter-view": "દુરુપયોગ ગળણી જુઓ", "right-abusefilter-log": "દુરુપયોગ લોગ જુઓ", "right-abusefilter-log-detail": "વિસ્તૃત દુરુપયોગ લોગ નોંધ જુઓ", - "right-abusefilter-private": "દુરુપયોગ લોગમાં ખાનગી માહિતી જુઓ", + "right-abusefilter-privatedetails": "દુરુપયોગ લોગમાં ખાનગી માહિતી જુઓ", "action-abusefilter-modify": "દુરુપયોગ ગાળકોમાં ફેરફાર કરો", "action-abusefilter-view": "દુરુપયોગ ગળણી જુઓ", "action-abusefilter-log": "દુરુપયોગ લોગ જુઓ", "action-abusefilter-log-detail": "વિસ્તૃત દુરુપયોગ લોગ નોંધ જુઓ", - "action-abusefilter-private": "દુરુપયોગ લોગમાં ખાનગી માહિતી જુઓ", - "abusefilter-log": "દુરુપયોગ ગળણી નોંધ", + "action-abusefilter-privatedetails": "દુરુપયોગ લોગમાં ખાનગી માહિતી જુઓ", "abusefilter-log-search": "દુરુપયોગ નોંધ શોધો", "abusefilter-log-search-user": "સભ્ય:", "abusefilter-log-search-filter": "ગાળક ઓળખો (પાઇપ્સ વડે જુદી પાડેલ):", @@ -39,13 +37,12 @@ "abusefilter-log-details-var": "ચલ", "abusefilter-log-details-val": "કિંમત", "abusefilter-log-details-vars": "ક્રિયા પરિણામો", - "abusefilter-log-details-private": "અંગત માહિતી", + "abusefilter-log-details-privatedetails": "અંગત માહિતી", "abusefilter-log-details-ip": "આરંભિક IP સરનામું", "abusefilter-log-noactions": "કોઇ નહીં", "abusefilter-log-details-diff": "સંપાદનમાં કરેલ ફેરફારો", "abusefilter-log-linkoncontribs": "દુરુપયોગ નોંધ", "abusefilter-log-linkoncontribs-text": "આ સભ્ય માટેની દુરુપયોગ નોંધ", - "abusefilter-log-hidden": "(દાખલો છુપાયેલ)", "abusefilter-log-hide-legend": "લૉગ દાખલો છુપાવો", "abusefilter-log-hide-reason": "કારણ:", "abusefilter-list": "બધાં ગળણાં", @@ -67,6 +64,7 @@ "abusefilter-disabled": "નિષ્ક્રિય કરેલ", "abusefilter-hitcount": "$1 {{PLURAL:$1|હિટ|હિટ્સ}}", "abusefilter-new": "નવું ગાળક બનાવો", + "abusefilter-import-button": "આયાત ગાળક", "abusefilter-return": "ગાળક વ્યવસ્થાપનમાં પાછા જાઓ", "abusefilter-status-global": "વૈશ્વિક", "abusefilter-list-options": "વિકલ્પો", @@ -163,7 +161,6 @@ "abusefilter-topnav-test": "જથ્થાબંધ ચકાસણી", "abusefilter-topnav-examine": "અગાઉના સંપાદનો ચકાસો", "abusefilter-topnav-log": "દુરુપયોગ નોંધ", - "abusefilter-topnav-import": "આયાત ગાળક", "abusefilter-log-name": "દુરુપયોગ ગળણી નોંધ", "abusefilter-log-noresults": "કોઇ પરિણામો નહી", "abusefilter-diff-item": "વસ્તુ", diff --git a/AbuseFilter/i18n/ha.json b/AbuseFilter/i18n/ha.json index ace78f40..586e2f99 100644 --- a/AbuseFilter/i18n/ha.json +++ b/AbuseFilter/i18n/ha.json @@ -1,5 +1,7 @@ { - "@metadata": [], + "@metadata": { + "authors": [] + }, "abusefilter-log-search-submit": "Nema", "abusefilter-log-hide-reason": "Dalili:", "abusefilter-examine-submit": "Nema" diff --git a/AbuseFilter/i18n/he.json b/AbuseFilter/i18n/he.json index 89ac1fad..ef7222c4 100644 --- a/AbuseFilter/i18n/he.json +++ b/AbuseFilter/i18n/he.json @@ -2,40 +2,46 @@ "@metadata": { "authors": [ "Amire80", + "Daimona Eaytoy", + "Esh77", "Guycn2", + "Inkbug", + "Matma Rex", "Ofrahod", "Rotemliss", + "Steeve815", "StuB", "YaronSh", "Yonidebest", "אור שפירא", + "דגש חזק", "דולב", + "חיים", "ערן", - "Inkbug", - "Matma Rex", - "Esh77" + "פוילישער" ] }, "abusefilter-desc": "החלת בדיקות אוטומטיות על עריכות", "abusefilter": "ניהול מסנני ההשחתות", - "abuselog": "יומן השחתות", + "abuselog": "יומן מסנן ההשחתות", "abusefilter-intro": "ברוך בואך לממשק הניהול של מסנן ההשחתות.\nמסנן ההשחתות הוא אמצעי אוטומטי להפעלת בדיקות אוטומטיות על כל הפעולות.\nממשק זה מציג רשימה של מסננים שהוגדרו, ומאפשר לשנות אותם.", "abusefilter-mustviewprivateoredit": "מסיבות של אבטחה, רק משתמשים עם ההרשאה לצפות במסנני השחתות פרטיים או לערוך מסננים יכולים להשתמש בממשק הזה.", "abusefilter-warning": "'''אזהרה:''' פעולה זו זוהתה באופן אוטומטי כמזיקה.\nפעולות שאינן מועילות תשוחזרנה במהרה,\nועריכות גסות או חזרה על עריכות לא מועילות תגרומנה לחסימה של החשבון או של כתובת ה־IP שלך.\nאם לדעתך הפעולה הזאת מועילה, ניתן לאשר אותה באמצעות שליחה חוזרת.\nתיאור קצר של החוק שפעולתך הפרה: $1", "abusefilter-disallowed": "פעולה זו זוהתה באופן אוטומטי כמזיקה, ולכן לא אופשרה.\nאם לדעתך הפעולה שלך הייתה מועילה, באפשרותך ליצור קשר עם מפעיל מערכת ולהודיע לו מה ניסית לעשות.\nתיאור קצר של החוק שפעולתך הפרה: $1", "abusefilter-blocked-display": "פעולה זו זוהתה באופן אוטומטי כמזיקה,\nולכן אין באפשרותך לבצע אותה.\nבנוסף, כדי להגן על {{SITENAME}}, חשבון המשתמש שלך וכל כתובות ה־IP המשויכות אליו נחסמו מעריכה.\nאם זה אירע בטעות, נא ליצור קשר עם מפעיל מערכת.\nתיאור קצר של החוק שפעולתך הפרה: $1", - "abusefilter-degrouped": "פעולה זו זוהתה באופן אוטומטי כמזיקה.\nכתוצאה מכך, היא לא אופשרה, ומאחר שיש חשד שחשבונך נפרץ, כל ההרשאות שלך נשללו.\nאם לדעתך מדובר בשגיאה, נא ליצור קשר עם ביורוקרט עם הסבר של הפעולה הזאת, וייתכן שההרשאות שלך תשוחזרנה.\nתיאור קצר של החוק שפעולתך הפרה: $1", + "abusefilter-degrouped": "פעולה זו זוהתה באופן אוטומטי כמזיקה.\nכתוצאה מכך, היא לא אופשרה, ומאחר שיש חשד שחשבונך נפרץ, כל ההרשאות שלך נשללו.\nאם לדעתך מדובר בשגיאה, נא ליצור קשר עם בירוקרט עם הסבר של הפעולה הזאת, וייתכן שההרשאות שלך תשוחזרנה.\nתיאור קצר של החוק שפעולתך הפרה: $1", "abusefilter-autopromote-blocked": "פעולה זו זוהתה באופן אוטומטי כמזיקה, ולכן לא אופשרה.\nבנוסף, כאמצעי בטיחות, מספר הרשאות שניתנות למשתמשים ותיקים נשללו באופן זמני מהחשבון שלך.\nתיאור קצר של החוק שפעולתך הפרה: $1", "abusefilter-blocker": "מסנן השחתות", "abusefilter-blockreason": "חסימה אוטומטית של מסנן ההשחתות.\nתיאור החוק התואם: $1", "abusefilter-degroupreason": "ההרשאות נשללו אוטומטית על־ידי מסנן ההשחתות.\nתיאור החוק: $1", + "abusefilter-blockautopromotereason": "קידום אוטומטי נדחה על־ידי מסנן ההשחתה.\nתיאור החוק: $1", "abusefilter-accountreserved": "שם המשתמש הזה שמור לשימושו של מסנן ההשחתות.", - "right-abusefilter-modify": "שינוי מסנני השחתות", + "right-abusefilter-modify": "יצירה או שינוי של מסנני השחתות", "right-abusefilter-view": "צפייה במסנני השחתות", "right-abusefilter-log": "צפייה ביומן ההשחתות", "right-abusefilter-log-detail": "צפייה ביומן ההשחתות המפורט", - "right-abusefilter-private": "צפייה בנתונים פרטיים ביומן ההשחתות", - "right-abusefilter-private-log": "הצגת יומן גישה לנתונים פרטיים של מסנן ההשחתות", + "right-abusefilter-privatedetails": "צפייה בנתונים פרטיים ביומן ההשחתות", + "right-abusefilter-privatedetails-log": "הצגת יומן גישה לנתונים פרטיים של מסנן ההשחתות", "right-abusefilter-modify-restricted": "שינוי מסנני השחתות עם פעולות מוגבלות", "right-abusefilter-revert": "שחזור כל השינויים שבוצעו על־ידי מסנן השחתות מסוים", "right-abusefilter-view-private": "צפייה במסנני השחתות שסומנו כפרטיים", @@ -47,17 +53,23 @@ "action-abusefilter-view": "לצפות במסנני השחתות", "action-abusefilter-log": "לצפות ביומן ההשחתות", "action-abusefilter-log-detail": "לצפות ביומן ההשחתות המפורט", - "action-abusefilter-private": "לצפות בנתונים פרטיים ביומן ההשחתות", - "action-abusefilter-private-log": "להציג את יומן הגישה לנתונים פרטיים של מסנן ההשחתות", + "action-abusefilter-privatedetails": "לצפות בנתונים פרטיים ביומן ההשחתות", + "action-abusefilter-privatedetails-log": "להציג את יומן הגישה לנתונים פרטיים של מסנן ההשחתות", "action-abusefilter-modify-restricted": "לשנות מסנני השחתות עם פעולות מוגבלות", "action-abusefilter-revert": "לשחזר את כל השינויים שבוצעו על־ידי מסנן השחתות מסוים", "action-abusefilter-view-private": "לצפות במסנני השחתות שסומנו כפרטיים", "action-abusefilter-log-private": "לצפות ביומנים של מסנני השחתות שסומנו כפרטיים", - "abusefilter-log": "יומן מסנן ההשחתות", + "action-abusefilter-hide-log": "להסתיר רשומות ביומן השחתות", + "action-abusefilter-hidden-log": "להציג רשומות יומן השחתות מוסתרות", + "action-abusefilter-modify-global": "ליצור או לשנות מסנני השחתות גלובליים", "abusefilter-log-summary": "יומן זה מציג רשימה של כל הפעולות שנתפסו על־ידי המסננים.", "abusefilter-log-search": "חיפוש ביומן ההשחתות", "abusefilter-log-search-user": "משתמש:", - "abusefilter-log-search-filter": "מספרי מסננים (מופרדים בתווי '|'):", + "abusefilter-log-search-group": "קבוצת מסננים:", + "abusefilter-log-search-group-any": "הכול", + "abusefilter-log-search-filter": "מספרי מסננים:", + "abusefilter-log-search-filter-help": "יש להפריד עם תווי מקל, ועם תחילית \"$1\" למסננים גלובליים", + "abusefilter-log-search-filter-help-central": "להפריד בתווי מקל", "abusefilter-log-search-title": "כותרת:", "abusefilter-log-search-wiki": "אתר ויקי:", "abusefilter-log-search-impact": "השפעה:", @@ -86,19 +98,21 @@ "abusefilter-log-details-var": "משתנה", "abusefilter-log-details-val": "ערך", "abusefilter-log-details-vars": "פרמטרים לפעולה", - "abusefilter-log-details-private": "נתוני יומן פרטי", + "abusefilter-log-details-privatedetails": "נתוני יומן פרטי", "abusefilter-log-details-ip": "כתובת ה־IP המקורית", "abusefilter-log-details-checkuser": "בדיקת משתמש", "abusefilter-log-noactions": "אין", + "abusefilter-log-noactions-filter": "ללא", "abusefilter-log-details-diff": "שינויים שבוצעו בעריכה", "abusefilter-log-linkoncontribs": "יומן מסנן ההשחתות", "abusefilter-log-linkoncontribs-text": "יומן ההשחתות עבור {{GENDER:$1|משתמש זה|משתמשת זו}}", "abusefilter-log-linkonhistory": "הצגת יומן ההשחתות", "abusefilter-log-linkonhistory-text": "הצגת יומן ההשחתות עבור דף זה", - "abusefilter-log-hidden": "(רשומה מוסתרת)", + "abusefilter-log-linkonundelete": "הצגת יומן ההשחתות", + "abusefilter-log-linkonundelete-text": "הצגת יומן ההשחתות עבור דף זה", "abusefilter-log-hidden-implicit": "(הוסתר כי הגרסה נמחקה)", - "abusefilter-log-cannot-see-details": "אין לך הרשאה לראות את פרטי הרשומה הזו.", - "abusefilter-log-cannot-see-private-details": "אין לך הרשאה לראות את הנתונים הפרטיים של הרשומה הזאת.", + "abusefilter-log-cannot-see-details": "אין לך הרשאה לראות את פרטי הרשומה הזאת.", + "abusefilter-log-cannot-see-privatedetails": "אין לך הרשאה לראות את הנתונים הפרטיים של הרשומה הזאת.", "abusefilter-log-nonexistent": "רשומה עם המזהה שניתן אינה קיימת", "abusefilter-log-details-hidden": "אין באפשרותך לצפות בפרטים של רשומה זו כי היא הוסתרה מעיני הציבור.", "abusefilter-log-details-hidden-implicit": "אין באפשרותך לצפות בפרטים של רשומה זו משום שהגרסה המשויכת אליה מוסתרת מהציבור.", @@ -116,9 +130,12 @@ "log-action-filter-abusefilter-create": "יצירת מסנן חדש", "log-action-filter-abusefilter-modify": "שינוי מסנן", "log-action-filter-suppress-abuselog": "העלמת יומן סינון השחתות", + "log-action-filter-rights-blockautopromote": "חסימת קידום אוטומטי", + "log-action-filter-rights-restoreautopromote": "שחזור קידום אוטומטי", "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|ניגש|ניגשה}} לנתונים פרטיים עבור $3", + "logentry-rights-blockautopromote": "$1 {{GENDER:$2|חסם|חסמה}} את הקידום האוטומטי של {{GENDER:$4|$3}} לתקופה של $5", + "logentry-rights-restoreautopromote": "$1 {{GENDER:$2|שחזר|שחזרה}} את האפשרות לקידום אוטומטי של {{GENDER:$4|$3}}", "abusefilterprivatedetails-log-name": "יומן גישה לנתונים פרטיים של מסנן ההשחתות", - "abusefilter-management": "ניהול מסנני ההשחתות", "abusefilter-list": "כל המסננים", "abusefilter-list-id": "מספר המסנן", "abusefilter-list-pattern": "תבנית", @@ -137,9 +154,10 @@ "abusefilter-enabled": "מופעל", "abusefilter-deleted": "מחוק", "abusefilter-disabled": "מבוטל", - "abusefilter-throttled": "בוטל באופן אוטומטי", + "abusefilter-throttled": "הוגבל", "abusefilter-hitcount": "{{PLURAL:$1|פעולה אחת סוננה|$1 פעולות סוננו}}", "abusefilter-new": "יצירת מסנן חדש", + "abusefilter-import-button": "ייבוא מסנן", "abusefilter-return": "חזרה לניהול המסננים", "abusefilter-status-global": "גלובלי", "abusefilter-list-options": "אפשרויות", @@ -160,26 +178,29 @@ "abusefilter-list-options-search-like": "שאילתה רגילה", "abusefilter-list-options-search-rlike": "ביטוי רגולרי", "abusefilter-list-options-search-irlike": "ביטוי רגולרי שאינו תלוי־רישיות", + "abusefilter-list-invalid-searchmode": "מצב החיפוש שצוין אינו תקין.", "abusefilter-list-regexerror": "אירעה שגיאה בעת החיפוש: שגיאה בתחביר הביטוי הרגולרי.", "abusefilter-list-options-submit": "עדכון", "abusefilter-tools-text": "להלן מספר כלים שעשויים להיות שימושיים בניסוח ובניפוי השגיאות של מסנני ההשחתות.", "abusefilter-tools-expr": "בודק הביטויים", "abusefilter-tools-submitexpr": "הערכה", + "abusefilter-tools-syntax-error": "המסנן מכיל תחביר בלתי־תקין.", "abusefilter-tools-reautoconfirm": "סימון המשתמש מחדש כמשתמש ותיק", "abusefilter-tools-reautoconfirm-user": "משתמש:", "abusefilter-tools-reautoconfirm-submit": "סימון מחדש", + "abusefilter-tools-restoreautopromote": "קידום אוטומטי שוחזר באמצעות כלי מסנן ההשחתה.", "abusefilter-reautoconfirm-none": "{{GENDER:$1|למשתמש זה|למשתמשת זו}} לא בוטלו הרשאות {{GENDER:$1|המשתמש הוותיק|המשתמשת הוותיקה}}.", "abusefilter-reautoconfirm-notallowed": "אין לך הרשאה להחזיר את הרשאות המשתמש הוותיק של המשתמש.", "abusefilter-reautoconfirm-done": "החשבון סומן מחדש כמשתמש ותיק", - "abusefilter-status": "מתוך {{PLURAL:$1|הפעולה האחרונה|$1 הפעולות האחרונות}}, {{PLURAL:$2|אחת ($3%) הגיעה|$2 ($3%) הגיעו}} לגבול התנאי של $4, {{PLURAL:$5|ואחת ($6%) התאימה|ו־$5 ($6%) התאימו}} לאחד מהמסננים הפעילים כעת.", + "abusefilter-status": "מתוך {{PLURAL:$1|הפעולה האחרונה|$1 הפעולות האחרונות}}, {{PLURAL:$2|אחת ($3%) הגיעה|$2 ($3%) הגיעו}} לגבול התנאי של $4, {{PLURAL:$5|ואחת ($6%) התאימה|ו־$5 ($6%) התאימו}} לפחות לאחד מהמסננים הפעילים כעת.", "abusefilter-edit": "עריכת מסנן השחתות", "abusefilter-edit-subtitle": "עריכת מסנן $1", "abusefilter-edit-subtitle-new": "יצירת מסנן", "abusefilter-edit-token-not-match": "העריכה לא נשמרה! נא לשמור שוב.", "abusefilter-edit-oldwarning": "<strong>זוהי גרסה ישנה של מסנן זה.\nהסטטיסטיקות המופיעות הן עבור הגרסה העדכנית ביותר של המסנן.\nשמירת השינויים שלך תדרוס את כל השינויים מאז הגרסה הזאת.</strong> • [[Special:AbuseFilter/history/$2|חזרה להיסטוריית הגרסאות של מסנן זה]].", + "abusefilter-edit-oldwarning-view": "<strong>אתם צופים בגרסה ישנה של המסנן הזה.\nהסטטיסטיקה שמצוטטת מתייחסת לגרסה האחרונה של המסנן.</strong> •\n[[Special:AbuseFilter/history/$2|חזרה להיסטוריה של המסנן הזה]].", "abusefilter-edit-status-label": "סטטיסטיקות:", - "abusefilter-edit-status": "מתוך {{PLURAL:$1|הפעולה האחרונה|$1 הפעולות האחרונות}}, מסנן זה התאים ל־$2 ($3%).", - "abusefilter-edit-status-profile": "מתוך {{PLURAL:$1|הפעולה האחרונה|$1 הפעולות האחרונות}}, מסנן זה התאים ל־$2 ($3%).\nבממוצע, זמן הריצה שלו הוא $4 מילישניות, והוא משתמש ב{{PLURAL:$5|תנאי אחד|־$5 תנאים}} מתוך מגבלת התנאים.", + "abusefilter-edit-status": "מתוך {{PLURAL:$1|הפעולה האחרונה|$1 הפעולות האחרונות}}, מסנן זה התאים ל־$2 ($3%).\nבממוצע, זמן הריצה שלו היה $4 מ\"ש, והוא צורך {{PLURAL:$5|תנאי אחד|$5 תנאים}} מתוך מגבלת התנאים.", "abusefilter-edit-throttled-warning": "'''אזהרה:''' המסנן הזה סומן אוטומטית בתור מזיק. בתור אמצעי זהירות, הפעולות הבאות לא תתבצענה ($1). נא לסקור ו[[mw:Extension:AbuseFilter/Conditions|לשפר]] את התנאים שלך כדי להסיר את המגבלה הזאת", "abusefilter-edit-new": "מסנן חדש", "abusefilter-edit-save": "שמירת המסנן", @@ -200,7 +221,7 @@ "abusefilter-edit-lastmod-text": "$1 על־ידי $2", "abusefilter-edit-hitcount": "פעולות שסוננו:", "abusefilter-edit-consequences": "אילו פעולות לבצע בעת ההתאמה", - "abusefilter-edit-action-warn": "לגרום לביצוע הפעולות האלה לאחר הזהרת המשתמש", + "abusefilter-edit-action-warn": "לגרום לביצוע הפעולות האלה לאחר אזהרת המשתמש", "abusefilter-edit-action-disallow": "למנוע מהמשתמש לבצע את הפעולה הזאת", "abusefilter-edit-action-blockautopromote": "לשלול מהמשתמש את הרשאות המשתמש הוותיק", "abusefilter-edit-action-degroup": "לשלול את כל ההרשאות של המשתמש", @@ -212,13 +233,18 @@ "abusefilter-edit-throttle-count": "מספר הפעולות המותרות:", "abusefilter-edit-throttle-period": "משך הזמן (בשניות):", "abusefilter-edit-throttle-groups": "הגבלת פעילות לפי קבוצה:", - "abusefilter-edit-throttle-ip": "כתובת IP", - "abusefilter-edit-throttle-user": "חשבון משתמש", - "abusefilter-edit-throttle-range": "טווח /16", - "abusefilter-edit-throttle-creationdate": "הזמן בשרת של יצירת החשבון", - "abusefilter-edit-throttle-editcount": "מספר עריכות", - "abusefilter-edit-throttle-site": "כל האתר", - "abusefilter-edit-throttle-page": "דף", + "abusefilter-edit-throttle-groups-help": "ר' $1.", + "abusefilter-edit-throttle-groups-help-text": "התיעוד באתר mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "יש להפריד בפסיקים כדי לצרף עם AND, ובירידות שורה כדי לצרף עם OR", + "abusefilter-edit-throttle-placeholder": "יש להפריד בפסיקים כדי לצרף עם AND, ולהכניס אחד־אחד כדי לצרף עם OR", + "abusefilter-throttle-ip": "כתובת IP", + "abusefilter-throttle-user": "חשבון משתמש", + "abusefilter-throttle-range": "טווח /16", + "abusefilter-throttle-creationdate": "תאריך יצירת החשבון", + "abusefilter-throttle-editcount": "מספר העריכות", + "abusefilter-throttle-site": "כל האתר", + "abusefilter-throttle-page": "דף", + "abusefilter-throttle-none": "(לא כלום)", "abusefilter-throttle-details": "{{PLURAL:$1|מותרת פעולה אחת|מותרות $1 פעולות}} בכל {{PLURAL:$2|שנייה|$2 שניות}}, הקבוצות המוגבלות: $3", "abusefilter-edit-warn-message": "הודעת המערכת המשמשת לאזהרה:", "abusefilter-edit-warn-other": "הודעה אחרת", @@ -258,10 +284,18 @@ "abusefilter-edit-export": "ייצוא מסנן זה לאתר ויקי אחר", "abusefilter-edit-syntaxok": "לא נמצאו שגיאות תחביר.", "abusefilter-edit-syntaxerr": "נמצאה שגיאת תחביר: $1", + "abusefilter-edit-warn-leave": "עזיבת הד הזה תגרום לאובדן כל השינויים שנעשו למסנן הזה.", "abusefilter-edit-bad-tags": "ציינת תג בלתי־תקין.\nהתגים אמורים להיות קצרים, הם לא יכולים להכיל תווים מיוחדים והם לא יכולים להיות שמורים לתוכנה אחרת. נא לנסות לבחור שם חדש לתג.", "abusefilter-edit-notallowed": "אין לך הרשאה ליצור או לערוך מסנני השחתות", "abusefilter-edit-notallowed-global": "אין לך הרשאה ליצור או לערוך מסנני השחתות גלובליים", - "abusefilter-edit-notallowed-global-custom-msg": "הודעות אזהרה מותאמות אישית אינן נתמכות עבור מסננים גלובליים", + "abusefilter-edit-notallowed-global-custom-msg": "הודעות אזהרה אן איסור מותאמות אישית אינן נתמכות עבור מסננים גלובליים", + "abusefilter-edit-invalid-warn-message": "אי־אפשר להשאיר את הודעת האזהרה ריקה.", + "abusefilter-edit-invalid-disallow-message": "אי־אפשר להשאיר את הודעת המניעה ריקה.", + "abusefilter-edit-invalid-throttlecount": "מניין פעולות ההגבלה חייב להיות מספר שלם חיובי.", + "abusefilter-edit-invalid-throttleperiod": "תקופת ההגבלה צריכה להיות מספר שלם חיובי", + "abusefilter-edit-empty-throttlegroups": "יש לבחור לפחות קבוצת הגבלה אחת.", + "abusefilter-edit-duplicated-throttlegroups": "קבוצות ההגבלה אינן יכולות להכיל פריטים כפולים", + "abusefilter-edit-invalid-throttlegroups": "קבוצות ההגבלה שסופקו אינן תקינות.", "abusefilter-edit-builder-select": "יש לבחור באפשרות כדי להוסיף אותה", "abusefilter-edit-builder-group-op-arithmetic": "אופרטורים חשבוניים", "abusefilter-edit-builder-op-arithmetic-addition": "חיבור (+)", @@ -292,6 +326,7 @@ "abusefilter-edit-builder-misc-stringlit": "מחרוזת מילולית (\"\")", "abusefilter-edit-builder-misc-tern": "האופרטור המשולש (X ? Y : Z)", "abusefilter-edit-builder-misc-cond": "תנאי (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond-short": "תנאי קצר (if X then Y end)", "abusefilter-edit-builder-group-funcs": "פונקציות", "abusefilter-edit-builder-funcs-length": "אורך המחרוזת (length)", "abusefilter-edit-builder-funcs-lcase": "המרה לאותיות קטנות (lcase)", @@ -362,12 +397,12 @@ "abusefilter-edit-builder-vars-all-links": "כל הקישורים החיצוניים בטקסט החדש", "abusefilter-edit-builder-vars-added-links": "כל הקישורים החיצוניים שנוספו בעריכה", "abusefilter-edit-builder-vars-removed-links": "כל הקישורים החיצוניים שהוסרו בעריכה", - "abusefilter-edit-builder-vars-old-text": "טקסט הדף הישן, לפני העריכה (לא בשימוש יותר)", - "abusefilter-edit-builder-vars-new-text": "טקסט הדף החדש, לאחר העריכה", + "abusefilter-edit-builder-vars-old-wikitext": "קוד הוויקי של הדף הישן, לפני העריכה", + "abusefilter-edit-builder-vars-new-wikitext": "קוד הוויקי של הדף החדש, אחרי העריכה", "abusefilter-edit-builder-vars-new-pst": "קוד הוויקי של הדף החדש, מומר לפני שמירה", "abusefilter-edit-builder-vars-diff-pst": "הצגת השינויים שנעשו בעריכה, בצורת השוואה מאוחדת, עם התמרה לפני שמירה", "abusefilter-edit-builder-vars-addedlines-pst": "שורות שנוספו בעריכה, עם התמרה לפני עריכה", - "abusefilter-edit-builder-vars-new-text-stripped": "טקסט הדף החדש, ללא סימני HTML", + "abusefilter-edit-builder-vars-new-text": "טקסט הדף החדש, ללא סימני HTML", "abusefilter-edit-builder-vars-new-html": "מקור ה־HTML המפוענח של הגרסה החדשה", "abusefilter-edit-builder-vars-restrictions-edit": "רמת ההגנה על עריכת הדף", "abusefilter-edit-builder-vars-restrictions-move": "רמת ההגנה על העברת הדף", @@ -381,10 +416,10 @@ "abusefilter-edit-builder-vars-movedto-restrictions-move": "רמת ההגנה מפני העברה של דף היעד בהעברה", "abusefilter-edit-builder-vars-movedto-restrictions-create": "הגנה מפני יצירה של דף היעד בהעברה", "abusefilter-edit-builder-vars-movedto-restrictions-upload": "הגנה מפני העלאה של קובץ היעד בהעברה", - "abusefilter-edit-builder-vars-old-text-stripped": "טקסט הדף הישן, ללא שום שפת סימון", + "abusefilter-edit-builder-vars-old-text": "טקסט הדף הישן, ללא שום שפת סימון", "abusefilter-edit-builder-vars-old-links": "קישורים בדף, לפני העריכה", "abusefilter-edit-builder-vars-old-html": "טקסט הוויקי של הדף הישן, מפוענח ל־HTML (לא בשימוש יותר)", - "abusefilter-edit-builder-vars-minor-edit": "האם עריכה זו מסומנת כמשנית או לא", + "abusefilter-edit-builder-vars-minor-edit": "האם עריכה זו מסומנת כמשנית או לא (כבר לא בשימוש)", "abusefilter-edit-builder-vars-file-sha1": "גיבוב SHA1 של תוכן הקובץ", "abusefilter-edit-builder-vars-file-size": "גודל הקובץ בבתים", "abusefilter-edit-builder-vars-file-mime": "סוג ה־MIME של הקובץ", @@ -392,6 +427,8 @@ "abusefilter-edit-builder-vars-file-width": "רוחב הקובץ בפיקסלים", "abusefilter-edit-builder-vars-file-height": "גובה הקובץ בפיקסלים", "abusefilter-edit-builder-vars-file-bits-per-channel": "ביטים לערוץ צבע של הקובץ", + "abusefilter-edit-builder-vars-wiki-name": "שם מסד הנתונים של הוויקי", + "abusefilter-edit-builder-vars-wiki-language": "קוד השפה של הוויקי", "abusefilter-filter-log": "שינויים אחרונים במסננים", "abusefilter-history": "היסטוריית השינויים של מסנן ההשחתות #$1", "abusefilter-history-foruser": "שינויים שבוצעו על־ידי $1", @@ -407,7 +444,7 @@ "abusefilter-history-actions": "פעולות", "abusefilter-history-backedit": "חזרה לעריכת המסנן", "abusefilter-history-deleted": "נמחק", - "abusefilter-history-filterid": "מסמן", + "abusefilter-history-filterid": "מסנן", "abusefilter-history-select-legend": "עידון החיפוש", "abusefilter-history-select-user": "משתמש:", "abusefilter-history-select-filter": "מספר המסנן:", @@ -425,14 +462,17 @@ "abusefilter-exception-dividebyzero": "ניסיון בלתי־חוקי לחלק את $2 באפס בתו מספר $1.", "abusefilter-exception-unrecognisedvar": "משתנה בלתי־מזוהה $2 בתו מספר $1", "abusefilter-exception-notenoughargs": "לא הועברו מספיק ארגומנטים לפונקציה $2 שנקראה בתו מספר $1.\nיש צורך {{PLURAL:$3|בארגומנט אחד|ב־$3 ארגומנטים}}, {{PLURAL:$4|התקבל אחד|התקבלו $4}}", + "abusefilter-exception-toomanyargs": "יותר מדי ארגומנטים לפונקציה $2 שנקראה בתו $1.\n{{PLURAL:$3|היה אמור להיות ארגומנט אחד|היו אמורים להיות $3 ארגומנטים}} לכל היותר, אבל הפועל היו $4", "abusefilter-exception-regexfailure": "שגיאה בביטוי הרגולרי \"$2\" בתו מספר $1.", - "abusefilter-exception-overridebuiltin": "דריסה בלתי־תקינה של המשתנה המובנה \"$2\" בתו מספר $1.", + "abusefilter-exception-overridebuiltin": "דריסה בלתי־תקינה של המזהה המובנה \"$2\" בתו מספר $1.", "abusefilter-exception-outofbounds": "בקשת פריט מערך בלתי קיים $2 (גודל המערך = $3) בתו מספר $1.", + "abusefilter-exception-negativeindex": "אינדקסים שליליים אינם מותרים במערכים. הגיע אינדקס \"$2\" בתו $1.", "abusefilter-exception-notarray": "ביקשו פריט מערך מלא־מערך בתו מספר $1.", "abusefilter-exception-unclosedcomment": "הערה בלתי־סגורה בתו מספר $1.", "abusefilter-exception-invalidiprange": "טווח IP שגוי \"$2\" בתו מספר $1.", "abusefilter-exception-disabledvar": "המשתנה $2 בתו מספר $1 אינו בשימוש יותר.", - "abusefilter-action-tag": "לתייג", + "abusefilter-exception-variablevariable": "set ו־set_var מצפים לכך שהארגומנט הראשון יהיה מחרוזת מפורשת, נמצאו בתו $1.", + "abusefilter-action-tag": "תיוג", "abusefilter-action-throttle": "הגבלת תדירות פעולה", "abusefilter-action-warn": "אזהרה", "abusefilter-action-blockautopromote": "ביטול שיוך אוטומטי לקבוצות", @@ -494,15 +534,16 @@ "abusefilter-examine-noresults": "לא נמצאו תוצאות עבור הפרמטרים שסיפקת לחיפוש.", "abusefilter-topnav": "'''ניווט במסנן ההשחתות'''", "abusefilter-topnav-home": "הדף הראשי", + "abusefilter-topnav-recentchanges": "שינויים אחרונים במסנן", "abusefilter-topnav-test": "בדיקת מסנן", "abusefilter-topnav-examine": "בדיקת עריכות קודמות", "abusefilter-topnav-log": "יומן ההשחתות", "abusefilter-topnav-tools": "כלי ניפוי שגיאות", - "abusefilter-topnav-import": "ייבוא מסנן", "abusefilter-log-name": "יומן מסנן ההשחתות", "abusefilter-log-header": "יומן זה מציג סיכום של השינויים שבוצעו במסנני ההשחתות.\nלפרטים מלאים, ראו את [[Special:AbuseFilter/history|רשימת]] השינויים האחרונים במסננים.", "abusefilter-logentry-create": "$1 {{GENDER:$2|יצר|יצרה}} את $4 ($5)", "abusefilter-logentry-modify": "$1 {{GENDER:$2|שינה|שינתה}} את $4 ($5)", + "abusefilter-log-invalid-filter": "חלק ממזהי המסננים שצוינו אינם תקינים.", "abusefilter-log-noresults": "אין תוצאות", "abusefilter-diff-title": "הבדלים בין גרסאות", "abusefilter-diff-item": "פריט", @@ -515,11 +556,12 @@ "abusefilter-diff-next": "שינוי חדש יותר", "abusefilter-import-intro": "באפשרותך להשתמש בממשק זה כדי לייבא מסננים מאתרי ויקי אחרים.\nבאתר המקור, יש ללחוץ על \"{{int:abusefilter-edit-export}}\" תחת \"{{int:abusefilter-edit-tools}}\" בממשק העריכה.\nלאחר מכן יש להעתיק מתיבת הטקסט המופיעה שם, ולהדביק את הטקסט בתיבת הטקסט הזאת, ואז ללחוץ על \"{{int:abusefilter-import-submit}}\".", "abusefilter-import-submit": "ייבוא הנתונים", + "abusefilter-import-invalid-data": "הנתונים שניסית לייצא אינם תקינים", "abusefilter-group-default": "ברירת המחדל", "abusefilter-http-error": "אירעה שגיאת HTTP: $1", - "abusefilter-view-private-submit": "הצגת נתונים פרטיים", - "abusefilter-view-private": "הצגת נתונים פרטיים", - "abusefilter-view-private-reason": "סיבה לגישה לנתונים הפרטיים:", + "abusefilter-view-privatedetails-submit": "הצגת נתונים פרטיים", + "abusefilter-view-privatedetails-legend": "הצגת נתונים פרטיים", + "abusefilter-view-privatedetails-reason": "סיבה לגישה לנתונים הפרטיים:", "abusefilter-log-details-id": "מזהה יומן", "abusefilter-invalid-request": "בקשתך הייתה בלתי־חוקית! יש לגשת לנתוני היומן הפרטיים באמצעות הטופס שבדף [[Special:AbuseLog/$1]] ולהקליד סיבה.", "abusefilter-invalid-request-noid": "בקשתך הייתה בלתי־חוקית! יש לגשת לנתוני היומן הפרטיים באמצעות הטופס שבדף הנתונים של יומן ההשחתות ולהקליד סיבה.", diff --git a/AbuseFilter/i18n/hi.json b/AbuseFilter/i18n/hi.json index 8fc0d746..0fe03625 100644 --- a/AbuseFilter/i18n/hi.json +++ b/AbuseFilter/i18n/hi.json @@ -1,28 +1,32 @@ { "@metadata": { "authors": [ + "Abijeet Patro", "Akansha", "Ansumang", + "ArmouredCyborg", + "BaRaN6161 TURK", "Bhawani Gautam", "Bhawani Gautam Rhk", + "Hindustanilanguage", + "Innocentbunny", "Kaustubh", "Kumar", - "Siddhartha Ghai", - "Wikiuser13", - "संजीव कुमार", - "Hindustanilanguage", "Matma Rex", - "Sfic", - "Sachinkatiyar", - "ArmouredCyborg", - "Innocentbunny", "Nitin1485", - "Smtchahal" + "Prong$31", + "Sachinkatiyar", + "Sfic", + "Siddhartha Ghai", + "Smtchahal", + "Wikiuser13", + "गोपाल", + "संजीव कुमार" ] }, "abusefilter-desc": "संपादनों पर स्वतः शोध प्रणाली का प्रयोग लागू करता है", - "abusefilter": "दुरुपयोग फ़िल्टर विन्यास", - "abuselog": "दुरुपयोग लॉग", + "abusefilter": "दुरुपयोग फ़िल्टर प्रबंधन", + "abuselog": "दुरुपयोग फ़िल्टर लॉग", "abusefilter-intro": "दुरुपयोग फ़िल्टर प्रबंधन अंतरफल में आपका स्वागत है।\nदुरुपयोग फ़िल्टर सभी कार्यों पर स्वतः शोध प्रणाली लागू करने का एक स्वचालित सॉफ़्टवेयर है।\nयह अंतरफल परिभाषित फ़िल्टरों की एक सूची दिखाता है, और यहाँ पर उन्हें संपादित किया जा सकता है।", "abusefilter-warning": "'''चेतावनी''': इस कार्य को स्वचालित रूप से हानिकारक पाया गया है।\nअरचनात्मक संपादनों को शीघ्र पूर्ववत कर दिया जाएगा,\nऔर बार-बार अरचनात्मक और हानिकारक संपादन करने पर आपके सदस्य खाते अथवा आइ॰पी पते को अवरोधित भी किया जा सकता है।\nयदि आपका मानना है कि यह कार्य रचनात्मक है, तो इसे सहेजने के लिये फिर से \"पृष्ठ सहेजें\" का बटन दबाएँ।\nआपके संपादन को पकड़ने वाले नियम का संक्षिप्त विवरण है: $1", "abusefilter-disallowed": "इस कार्य को स्वचालित रूप से हानिकारक पाया गया है, अतः इसे करने की अनुमति नहीं है।\nयदि आपका मानना है कि आपका कार्य रचनात्मक था, अपने कार्य की जानकारी कृपया किसी प्रबंधक को दें।\nआपके संपादन को पकड़ने वाले नियम का संक्षिप्त विवरण है: $1", @@ -33,11 +37,11 @@ "abusefilter-blockreason": "दुरुपयोग फ़िल्टर द्वारा स्वचालित रूप से अवरुद्ध।\nपकड़ने वाले नियम का संक्षिप्त विवरण है: $1", "abusefilter-degroupreason": "सदस्य अधिकार दुरुपयोग फ़िल्टर द्वारा स्वचालित रूप से वापिस ले लिये गए हैं।\nपकड़ने वाले नियम का संक्षिप्त विवरण है: $1", "abusefilter-accountreserved": "यह सदस्य नाम दुरुपयोग फ़िल्टर के उपयोग के लिए आरक्षित है।", - "right-abusefilter-modify": "दुरुपयोग फ़िल्टर संशोधित करें", + "right-abusefilter-modify": "दुरुपयोग फ़िल्टर बनाएँ अथवा संशोधित करें", "right-abusefilter-view": "दुरुपयोग फ़िल्टर देखें", "right-abusefilter-log": "दुरुपयोग लॉग देखें", "right-abusefilter-log-detail": "दुरुपयोग लॉग की प्रविष्टियाँ विस्तार में देखें", - "right-abusefilter-private": "दुरुपयोग लॉग में निजी डेटा देखें", + "right-abusefilter-privatedetails": "दुरुपयोग लॉग में निजी डेटा देखें", "right-abusefilter-modify-restricted": "दुरुपयोग फ़िल्टर को प्रतिबन्धित कार्यों सहित सम्पादित करें", "right-abusefilter-revert": "किसी एक दिए गए दुरुपयोग फ़िल्टर द्वारा किये सभी परिवर्तनों को वापिस लें", "right-abusefilter-view-private": "वो दुरुपयोग फ़िल्टर देखें जिन्हें निजी चिन्हित किया गया है", @@ -49,14 +53,14 @@ "action-abusefilter-view": "दुरुपयोग फ़िल्टर देखें", "action-abusefilter-log": "दुरुपयोग लॉग देखें", "action-abusefilter-log-detail": "दुरुपयोग लॉग की प्रविष्टियाँ विस्तार में देखें", - "action-abusefilter-private": "दुरुपयोग लॉग में निजी डेटा देखें", + "action-abusefilter-privatedetails": "दुरुपयोग लॉग में निजी डेटा देखें", "action-abusefilter-modify-restricted": "दुरुपयोग फ़िल्टर को प्रतिबन्धित कार्यों सहित सम्पादित करें", "action-abusefilter-revert": "किसी एक दिए गए दुरुपयोग फ़िल्टर द्वारा किये सभी परिवर्तनों को वापिस लें", "action-abusefilter-view-private": "वो दुरुपयोग फ़िल्टर देखें जिन्हें निजी चिन्हित किया गया है", - "abusefilter-log": "दुरुपयोग फ़िल्टर लॉग", "abusefilter-log-summary": "यह लॉग फ़िल्टरों द्वारा पकड़े गए सभी कार्यों की सूची दिखाता है।", "abusefilter-log-search": "दुरुपयोग लॉग खोज", "abusefilter-log-search-user": "सदस्य:", + "abusefilter-log-search-group-any": "कोई", "abusefilter-log-search-filter": "फ़िल्टर IDs (पाइप के साथ अलग):", "abusefilter-log-search-title": "शीर्षक:", "abusefilter-log-search-wiki": "विकी:", @@ -64,6 +68,8 @@ "abusefilter-log-search-entries-label": "दृश्यता:", "abusefilter-log-search-entries-all": "सभी प्रविष्टियाँ", "abusefilter-log-search-entries-hidden": "केवल छुपी प्रविष्टियां", + "abusefilter-log-search-action-other": "अन्य", + "abusefilter-log-search-action-any": "कोई भी", "abusefilter-log-search-action-taken-any": "कोई", "abusefilter-log-search-submit": "खोज", "abusefilter-log-entry": "$1: $2 द्वारा $4 पर किये कार्य \"$3\" को दुरुपयोग फ़िल्टर ने पकड़ा।\nफ़िल्टर द्वारा उठाया गया कदम: $5;\nफ़िल्टर विवरण: $6", @@ -77,16 +83,15 @@ "abusefilter-log-details-var": "प्राचल", "abusefilter-log-details-val": "मूल्य", "abusefilter-log-details-vars": "कार्य के प्राचल", - "abusefilter-log-details-private": "निजी डेटा", + "abusefilter-log-details-privatedetails": "निजी लॉग विवरण", "abusefilter-log-details-ip": "स्रोत आइ॰पी पता", "abusefilter-log-noactions": "कोई नहीं", "abusefilter-log-details-diff": "सम्पादन में किये बदलाव", "abusefilter-log-linkoncontribs": "दुरुपयोग लॉग", "abusefilter-log-linkoncontribs-text": "{{GENDER:$1|इस सदस्य}} के लिए दुरुपयोग लॉग", - "abusefilter-log-hidden": "(प्रविष्टि छिपी हुई)", "abusefilter-log-hidden-implicit": "(प्रविष्टि छुपाई गई है क्योंकि अवतरण हटा दिया गया है)", "abusefilter-log-cannot-see-details": "आपके पास इस प्रविष्टि का विस्तृत विवरण देखने की अनुमति नहीं है", - "abusefilter-log-cannot-see-private-details": "आपको इस प्रविष्टि के निजी विवरण देखने की अनुमति नहीं है।", + "abusefilter-log-cannot-see-privatedetails": "आपको इस प्रविष्टि के निजी विवरण देखने की अनुमति नहीं है।", "abusefilter-log-details-hidden": "आप इस प्रविष्टि का विस्तृत विवरण नहीं देख सकते हैं क्योंकि इसे सार्वजनिक दृष्टि से छुपाया गया है", "abusefilter-log-hide-legend": "लॉग प्रविष्टि छुपाएँ", "abusefilter-log-hide-id": "लॉग प्रविष्टि आइ॰डी:", @@ -95,7 +100,6 @@ "abusefilter-log-hide-forbidden": "आपके पास दुरुपयोग लॉग प्रविष्टियाँ छुपाने की अनुमति नहीं है।", "logentry-abusefilter-hit": "$1 ने $3 पर \"$5\" किया जिसे $4 ने पकड़ा और निम्न कदम उठाया: $6 ($7)", "logentry-abusefilterprivatedetails-access": "$1 $3 के व्यक्तिगत विवरण तक {{{{GENDER:$2|पहुँचा}}", - "abusefilter-management": "दुरुपयोग फ़िल्टर प्रबंधन", "abusefilter-list": "सभी फ़िल्टर", "abusefilter-list-id": "फ़िल्टर आइ॰डी", "abusefilter-list-status": "स्थिति", @@ -115,6 +119,7 @@ "abusefilter-disabled": "अक्षम किया गया", "abusefilter-hitcount": "$1 {{PLURAL:$1|हिट|हिट}}", "abusefilter-new": "नया फ़िल्टर बनाएँ", + "abusefilter-import-button": "आयात फ़िल्टर", "abusefilter-return": "फ़िल्टर प्रबंधन को लौटें", "abusefilter-status-global": "वैश्विक", "abusefilter-list-options": "विकल्प", @@ -144,7 +149,6 @@ "abusefilter-edit-oldwarning": "<strong>आप फ़िल्टर का एक पुराना अवतरण सम्पादित कर रहे हैं।\nदिये गए आँकड़े फ़िल्टर के नवीनतम अवतरण के लिये हैं।\nयदि आप अपने बदलाव संजोते हैं, आप इस अवतरण के बाद हुए सभी बदलावों को खारिज कर देंगे।</strong>•\n[[Special:AbuseFilter/history/$2|इस फ़िल्टर के इतिहास को लौटें]]।", "abusefilter-edit-status-label": "आँकड़े:", "abusefilter-edit-status": "पिछले $1 {{PLURAL:$1|कार्य|कार्यों}} में से इस फ़िल्टर द्वारा $2 ($3%) पकड़े गए हैं।", - "abusefilter-edit-status-profile": "पिछले $1 {{PLURAL:$1|कार्य|कार्यों}} में से इस फ़िल्टर द्वारा $2 ($3%) पकड़े गए हैं।\nइसका औसत रन-टाइम $4 ms है, और यह शर्त सीमा में से $5 {{PLURAL:$5|शर्त|शर्तों}} का प्रयोग करता है।", "abusefilter-edit-new": "नया फ़िल्टर", "abusefilter-edit-save": "फ़िल्टर सहेजें", "abusefilter-edit-id": "फ़िल्टर आइ॰डी:", @@ -170,7 +174,7 @@ "abusefilter-edit-action-throttle": "कदम तभी उठाएँ अगर सदस्य रेट सीमा के पार जाए", "abusefilter-edit-action-tag": "समिक्षा के किए बदलाव को टैग करें", "abusefilter-edit-throttle-count": "संख्या जितने कार्यों की अनुमति देनी है:", - "abusefilter-edit-throttle-period": "समय की अवधि:", + "abusefilter-edit-throttle-period": "समय की अवधि (सेकेंड में):", "abusefilter-edit-warn-message": "चेतावनी के लिये प्रयोग किया जाने वाला अंतरफल संदेश:", "abusefilter-edit-warn-other": "अन्य संदेश", "abusefilter-edit-warn-other-label": "अन्य संदेश का पृष्ठ नाम:\n:''(मीडियाविकी उपसर्ग के बिना)''", @@ -280,18 +284,18 @@ "abusefilter-edit-builder-vars-all-links": "नए टेक्स्ट में सभी बाहरी कड़ियाँ", "abusefilter-edit-builder-vars-added-links": "सम्पादन में जोड़ी गई सभी बाहरी कड़ियाँ", "abusefilter-edit-builder-vars-removed-links": "सम्पादन में हटाई गई सभी बाहरी कड़ियाँ", - "abusefilter-edit-builder-vars-old-text": "पुराने पृष्ठ विकिलेख, सम्पादन से पहले", - "abusefilter-edit-builder-vars-new-text": "नया पृष्ठ विकिलेख, सम्पादन के बाद", + "abusefilter-edit-builder-vars-old-wikitext": "पुराने पृष्ठ विकिलेख, सम्पादन से पहले", + "abusefilter-edit-builder-vars-new-wikitext": "नया पृष्ठ विकिलेख, सम्पादन के बाद", "abusefilter-edit-builder-vars-new-pst": "नए पष्ठ का विकि-पाठ, सहेजने से पूर्व तबदील", "abusefilter-edit-builder-vars-diff-pst": "सम्पादन से हुए बदलावों का एकत्रित अंतर, सहेजने से पूर्व तबदील", "abusefilter-edit-builder-vars-addedlines-pst": "सम्पादन में वाक्य जोड़े गए, सहेजने से पूर्व तबदील", - "abusefilter-edit-builder-vars-new-text-stripped": "नए पृष्ठ का पाठ, किसी भी मार्क-अप से खाली", + "abusefilter-edit-builder-vars-new-text": "नए पृष्ठ का पाठ, किसी भी मार्क-अप से खाली", "abusefilter-edit-builder-vars-new-html": "नए संशोधन के स्रोत का एचटीएमएल पार्स किया गया", "abusefilter-edit-builder-vars-restrictions-edit": "पृष्ठ का सुरक्षा स्तर बदलें", "abusefilter-edit-builder-vars-restrictions-move": "पृष्ठ का स्थानान्तरण सुरक्षा स्तर", "abusefilter-edit-builder-vars-restrictions-create": "इस पृष्ठ का सुरक्षा स्तर बनाएँ", "abusefilter-edit-builder-vars-restrictions-upload": "इस फ़ाइल का सुरक्षा स्तर अपलोड करें", - "abusefilter-edit-builder-vars-old-text-stripped": "पुराने पृष्ठ का पाठ, किसी भी मार्क-अप से खाली", + "abusefilter-edit-builder-vars-old-text": "पुराने पृष्ठ का पाठ, किसी भी मार्क-अप से खाली", "abusefilter-edit-builder-vars-old-links": "सम्पादन से पहले पृष्ठ में कड़ियाँ", "abusefilter-edit-builder-vars-old-html": "पुराने पृष्ठ का विकि-पाठ एचटीएमएल में पार्स किया गया", "abusefilter-edit-builder-vars-minor-edit": "सम्पादन को मामूली चिन्हित किया गया है या नहीं", @@ -384,9 +388,8 @@ "abusefilter-topnav-examine": "पूर्व बदलाव परीक्षा करें", "abusefilter-topnav-log": "दुरुपयोग लॉग", "abusefilter-topnav-tools": "डिबगिंग उपकरण", - "abusefilter-topnav-import": "आयात फ़िल्टर", "abusefilter-log-name": "दुरुपयोग फ़िल्टर लॉग", - "abusefilter-logentry-modify": "$1 {{लिंग:$2|संशोधित}} $4 ($5)", + "abusefilter-logentry-modify": "$1 {{GENDER:$2|संशोधित}} $4 ($5)", "abusefilter-log-noresults": "कोई परिणाम नहीं", "abusefilter-diff-title": "अवतरणों के बीच अंतर", "abusefilter-diff-item": "आइटम", @@ -400,9 +403,9 @@ "abusefilter-import-submit": "डेटा आयात करें", "abusefilter-group-default": "डिफ़ॉल्ट", "abusefilter-http-error": "एच॰टी॰टी॰पी त्रुटि हुई है: $1 ।", - "abusefilter-view-private-submit": "व्यक्तिगत विवरण देखें", - "abusefilter-view-private": "व्यक्तिगत विवरण देखें", - "abusefilter-view-private-reason": "निजी विवरण तक पहुंचने का कारण", + "abusefilter-view-privatedetails-submit": "व्यक्तिगत विवरण देखें", + "abusefilter-view-privatedetails-legend": "व्यक्तिगत विवरण देखें", + "abusefilter-view-privatedetails-reason": "निजी विवरण तक पहुंचने का कारण", "abusefilter-invalid-request-noid": "अमान्य अनुरोध! आपको दुर्व्यवहार लॉग विवरण पृष्ठ पर फ़ॉर्म के माध्यम से निजी लॉग विवरण एक्सेस करना होगा और एक कारण प्रदान करना होगा।", "abusefilter-log-ip-not-available": "उपलब्ध नहीं है" } diff --git a/AbuseFilter/i18n/hr.json b/AbuseFilter/i18n/hr.json index a85e57e7..9d656872 100644 --- a/AbuseFilter/i18n/hr.json +++ b/AbuseFilter/i18n/hr.json @@ -1,18 +1,20 @@ { "@metadata": { "authors": [ + "Bugoslav", "Dalibor Bosits", "Ex13", + "Ivi104", "MaGa", + "Matma Rex", "Roberta F.", "SpeedyGonsales", - "Matma Rex", - "Bugoslav" + "Vlad5250" ] }, "abusefilter-desc": "Primjenjuje automatsku heuristiku na uređivanja", - "abusefilter": "Konfiguracija filtra zloporaba", - "abuselog": "Evidencija zloporaba", + "abusefilter": "Upravljanje filtrima zloporaba", + "abuselog": "Evidencija filtra zloporaba", "abusefilter-intro": "Dobro došli u sučelje za upravljanje Filtrom protiv zloporaba.\nOvaj je Filtar automatizirani softverski mehanizam koji primjenjuje automatsku heuristiku na sve radnje.\nOvo sučelje prikazuje popis definiranih filtara, te Vam omogućava da ih promijenite.", "abusefilter-warning": "'''Upozorenje:''' Ova radnja automatski je identificirana kao štetna.\nNesvrhovite radnje bit će brzo uklonjene,\na prekomjerno ili ponovljeno nesvrhovito uređivanje će uzrokovati da će vaš račun ili IP adresa biti blokirana.\nUkoliko vjerujete da je vaše uređivanje smisleno, možete ga ponovo poslati da ga potvrdite.\nKratak opis pravila sprječavanja zloporaba koji se podudara s vašim uređivanjem je: $1", "abusefilter-disallowed": "Ova je radnja automatski identificirana kao štetna, pa je stoga onemogućena.\nAko vjerujete da je Vaše uređivanje smisleno, molimo kontaktirajte administratora i obavijestite ga o tome što ste pokušali načiniti.\nKratki opis pravila sprječavanja zlouporabe koji se podudara s Vašim uređivanjem je: $1", @@ -23,11 +25,11 @@ "abusefilter-blockreason": "Automatski ste blokirani filtrom protiv zloporabe.\nOpis pravila koje kršite: $1", "abusefilter-degroupreason": "Prava automatski poništena filtrom zloporabe.\nOpis pravila: $1", "abusefilter-accountreserved": "Ovaj je suradnički račun rezerviran za uporabu filtra zloporaba.", - "right-abusefilter-modify": "Izmijeni filtre zloporaba", + "right-abusefilter-modify": "Stvaranje ili promjena filtara zloporaba", "right-abusefilter-view": "Prikaži filtre zloporabe", "right-abusefilter-log": "Vidi evidenciju zloporaba", "right-abusefilter-log-detail": "Vidi detaljni pregled evidencije zloporaba", - "right-abusefilter-private": "Prikaži privatne podatke u evidenciji zloporaba", + "right-abusefilter-privatedetails": "Prikaži privatne podatke u evidenciji zloporaba", "right-abusefilter-modify-restricted": "Izmijeni filtre zloporaba s ograničenim akcijama", "right-abusefilter-revert": "Vrati sve promjene koje zadovoljavaju dani filtar", "right-abusefilter-view-private": "Prikaži filtre zloporaba označene kao privatne", @@ -39,16 +41,16 @@ "action-abusefilter-view": "vidi filtre zloporabe", "action-abusefilter-log": "pregled evidencije zloporabe", "action-abusefilter-log-detail": "detaljan prikaz evidencije zloporaba", - "action-abusefilter-private": "prikaz privatnih podataka u evidenciji zloporaba", + "action-abusefilter-privatedetails": "prikaz privatnih podataka u evidenciji zloporaba", "action-abusefilter-modify-restricted": "promijeni filtre zloporaba s ograničenim akcijama", "action-abusefilter-revert": "vratiti sve promjene uzrokovane filtrom protiv zloporaba", "action-abusefilter-view-private": "prikaži filtre zloporaba označene kao privatne", "action-abusefilter-log-private": "Prikaži filtre zloporaba označene kao privatne", - "abusefilter-log": "Evidencija filtra zloporaba", "abusefilter-log-summary": "Ova evidencija prikazuje popis svih aktivnosti uhvaćenih filtrima.", "abusefilter-log-search": "Pretraži evidenciju zloporabe", "abusefilter-log-search-user": "Suradnik:", - "abusefilter-log-search-filter": "ID-ovi filtra (razdjeljivač je znak štapića):", + "abusefilter-log-search-filter": "ID-ovi filtra:", + "abusefilter-log-search-filter-help": "Razdijelite pomoću znaka štapića »|« kao razdjeljivača, predmetnuti uz »$1« za globalne filtre", "abusefilter-log-search-title": "Naslov:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-impact": "Obuhvaćanje:", @@ -77,7 +79,7 @@ "abusefilter-log-details-var": "Varijabla", "abusefilter-log-details-val": "Vrijednost", "abusefilter-log-details-vars": "Parametri postupka", - "abusefilter-log-details-private": "Detalji privatne evidencije", + "abusefilter-log-details-privatedetails": "Privatni detalji evidencije", "abusefilter-log-details-ip": "Izvorna IP adresa", "abusefilter-log-details-checkuser": "Provjeri suradnika", "abusefilter-log-noactions": "ništa", @@ -85,9 +87,12 @@ "abusefilter-log-linkoncontribs": "evidencija zloporaba", "abusefilter-log-linkoncontribs-text": "Evidencija zloporaba za {{GENDER:$1|ovoga suradnika|ovu suradnicu}}", "abusefilter-log-linkonhistory": "Vidi evidencije filtra zloporaba", - "abusefilter-log-hidden": "(zapis je skriven)", + "abusefilter-log-linkonhistory-text": "Pogledajte evidencije zloupotrebe ove stranice", + "abusefilter-log-linkonundelete": "vidi evidenciju zloporabe", + "abusefilter-log-linkonundelete-text": "Pogledajte evidencije zloupotrebe za ovu stranicu", "abusefilter-log-hidden-implicit": "(skriveno jer je inačica obrisana)", "abusefilter-log-cannot-see-details": "Nemate dopuštenje vidjeti potankosti ovog zapisa.", + "abusefilter-log-cannot-see-privatedetails": "Nemate dopuštenje vidjeti privatne potankosti ovoga zapisa.", "abusefilter-log-nonexistent": "Stavka s naznačenom identifikacijskom oznakom (ID) ne postoji.", "abusefilter-log-details-hidden": "Ne možete vidjeti detalje ovog unosa jer je skriven od javnog pogleda.", "abusefilter-log-hide-legend": "Sakrij zapis u evidenciji", @@ -95,8 +100,9 @@ "abusefilter-log-hide-hidden": "Sakrij ovaj zapis od javnog pristupa", "abusefilter-log-hide-reason": "Razlog:", "abusefilter-log-hide-forbidden": "Nemate dopuštenje za skrivanje zapisa iz evidencije zloporaba.", + "abusefilter-log-entry-suppress": "$1 {{GENDER:$2|skrio|skrila}} je $3", + "abusefilter-log-entry-unsuppress": "$1 {{GENDER:$2|vratio|vratila}} je $3", "logentry-abusefilter-hit": "$1 {{GENDER:$2|pokrenuo|pokrenula}} je $4 {{GENDER:$2|izvršivši}} »$5« na $3. Poduzete radnje: $6 ($7)", - "abusefilter-management": "Upravljanje filtrima zloporaba", "abusefilter-list": "Svi filtri", "abusefilter-list-id": "ID filtra", "abusefilter-list-status": "Stanje", @@ -116,6 +122,7 @@ "abusefilter-disabled": "Onemogućeno", "abusefilter-hitcount": "$1 {{PLURAL:$1|pogodak|pogotka|pogodaka}}", "abusefilter-new": "Novi filtar", + "abusefilter-import-button": "Uvoz filtra", "abusefilter-return": "Vrati se na upravljanje filtrima zloporaba", "abusefilter-status-global": "Globalno", "abusefilter-list-options": "Opcije", @@ -127,7 +134,9 @@ "abusefilter-list-options-scope-local": "Samo lokalna pravila", "abusefilter-list-options-scope-global": "Samo globalna pravila", "abusefilter-list-options-scope-all": "Lokalna i globalna pravila", + "abusefilter-list-options-further-options": "Dodatne opcije:", "abusefilter-list-options-hidedisabled": "Sakrij onemogućene filtre", + "abusefilter-list-options-hideprivate": "Skrij privatne filtre", "abusefilter-list-options-submit": "Osvježi", "abusefilter-tools-text": "Nekoliko alata koji mogu biti korisni kod formuliranja i uklanjanja grešaka filtra zloporaba.", "abusefilter-tools-expr": "Testiranje filtra", @@ -145,10 +154,10 @@ "abusefilter-edit-oldwarning": "<strong>Uređujete staru inačicu ovog filtra.\nIskazane su statistike za najnoviju inačicu filtra.\nAko spremite svoje promjene, prebrisati ćete sve promjene nastale od inačice koju upravo uređujete.</strong> •\n[[Special:AbuseFilter/history/$2|Povratak na povijest stranice ovog filtra]].", "abusefilter-edit-status-label": "Statistike:", "abusefilter-edit-status": "Od {{PLURAL:$1|posljednje akcije|posljednje $1 akcije|posljednjih $1 akcija}}, ovaj se filtar poklopio s njih $2 ($3 %).", - "abusefilter-edit-status-profile": "Od {{PLURAL:$1|posljednje akcije|posljednje $1 akcije|posljednjih $1 akcija}}, ovaj se filtar poklopio s njih $2 ($3 %).\nU prosjeku, njegovo je vrijeme izvođenja $4 ms, a upotrijebi $5 {{PLURAL:$5|uvjet|uvjeta}} od ukupno zadanih uvjeta.", "abusefilter-edit-new": "Novi filtar", "abusefilter-edit-save": "Snimi filtar", "abusefilter-edit-id": "ID filtra:", + "abusefilter-edit-switch-editor": "Zamijeni uređivač", "abusefilter-edit-description": "Opis:\n:''(javno vidljivo)''", "abusefilter-edit-group": "Skupina filtara:", "abusefilter-edit-flags": "Zastavice:", @@ -173,17 +182,24 @@ "abusefilter-edit-throttle-count": "Broj omogućenih akcija:", "abusefilter-edit-throttle-period": "Vremensko razdoblje (u sekundama):", "abusefilter-edit-throttle-groups": "Skupno usporavanje prema:", + "abusefilter-throttle-ip": "IP-adresa", + "abusefilter-throttle-user": "suradnički račun", + "abusefilter-throttle-range": "opseg /16", + "abusefilter-throttle-creationdate": "datum otvaranja računa", + "abusefilter-throttle-editcount": "broj uređivanja", "abusefilter-edit-warn-message": "Poruka sustava koja će biti rabljena za upozorenje:", "abusefilter-edit-warn-other": "Ostale poruke", "abusefilter-edit-warn-other-label": "Ime stranice druge poruke:\n:''(bez MediaWiki prefiksa)''", "abusefilter-edit-warn-actions": "Akcije:", "abusefilter-edit-warn-preview": "Prikaži/sakrij pretpregled odabrane poruke", "abusefilter-edit-warn-edit": "Kreiraj/Uredi odabranu poruku", + "abusefilter-edit-disallow-preview": "Prikaži/skrij pretpregled izabrane poruke", + "abusefilter-edit-disallow-edit": "Stvori/uredi izabranu poruku", "abusefilter-edit-tag-tag": "[[Special:Tags|Oznake]] za primjenu:", "abusefilter-edit-denied": "Možda ne ćete vidjeti detalje ovoga filtra, zato što je skriven od javnog prikaza.", "abusefilter-edit-main": "Parametri filtra", "abusefilter-edit-done-subtitle": "Filtar je uređen", - "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Vaše su izmjene]][[Special:AbuseFilter/$1|filtra $3]] spremljene.", + "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Vaše su izmjene]] [[Special:AbuseFilter/$1|filtra $3]] spremljene.", "abusefilter-edit-badsyntax": "Sintaktička pogrješka u filtru koji ste naveli. Izlaz iz ''parsera'' bio je:\n<pre>$1</pre>", "abusefilter-edit-restricted": "Ne možete uređivati ovaj filtar, jer on sadrži jednu ili više ograničenih akcija.\nZamolite suradnika s pravima dodavanja ograničenih akcija da napravi izmjene umjesto Vas.", "abusefilter-edit-viewhistory": "Vidi povijest filtra", @@ -278,15 +294,15 @@ "abusefilter-edit-builder-vars-all-links": "Sve vanjske poveznice u novom tekstu", "abusefilter-edit-builder-vars-added-links": "Sve vanjske poveznice dodane uređivanjem", "abusefilter-edit-builder-vars-removed-links": "Sve vanjske poveznice uklonjene uređivanjem", - "abusefilter-edit-builder-vars-old-text": "Sadržaj stranice prije uređivanja", - "abusefilter-edit-builder-vars-new-text": "Novi sadržaj stranica, poslije uređivanja", - "abusefilter-edit-builder-vars-new-text-stripped": "Novi sadržaj stranice, bez ''markup tagova'' (HTML ili XML)", + "abusefilter-edit-builder-vars-old-wikitext": "Sadržaj stranice prije uređivanja", + "abusefilter-edit-builder-vars-new-wikitext": "Novi sadržaj stranica, poslije uređivanja", + "abusefilter-edit-builder-vars-new-text": "Novi sadržaj stranice, bez ''markup tagova'' (HTML ili XML)", "abusefilter-edit-builder-vars-new-html": "Raščlanjen HTML izvor nove revizije", "abusefilter-edit-builder-vars-restrictions-edit": "Uredi razinu zaštite stranice", "abusefilter-edit-builder-vars-restrictions-move": "Premještena razina zaštite stranice", "abusefilter-edit-builder-vars-restrictions-create": "Zaštiti stranicu", "abusefilter-edit-builder-vars-restrictions-upload": "Zaštiti datoteku", - "abusefilter-edit-builder-vars-old-text-stripped": "Stari sadržaj stranice, bez ''markup tagova'' (HTML ili XML)", + "abusefilter-edit-builder-vars-old-text": "Stari sadržaj stranice, bez ''markup tagova'' (HTML ili XML)", "abusefilter-edit-builder-vars-old-links": "Poveznice na stranici, prije uređivanja", "abusefilter-edit-builder-vars-old-html": "Wikitekst stare stranice, \"parsiran\" u HTML", "abusefilter-edit-builder-vars-minor-edit": "Bez obzira da li je uređivanje označeno kao malo ili ne", @@ -342,7 +358,7 @@ "abusefilter-revert-periodstart": "Početak razdoblja:", "abusefilter-revert-periodend": "Kraj razdoblja:", "abusefilter-revert-search": "Odaberite radnje", - "abusefilter-revert-filter": "Filtar:", + "abusefilter-revert-filter": "Filtar ID-a:", "abusefilter-revert-preview-intro": "U nastavku se nalaze akcije koje je napravio filtar sprječavanja zloporaba koji će biti uklonjene ovom akcijom.\nMolimo provjerite ih pažljivo, i kliknite na \"Potvrdi\" kako biste potvrdili svoj izbor.", "abusefilter-revert-confirm": "Potvrdi", "abusefilter-revert-success": "Vratili ste radnje poduzete od strane filtra zloporabe tijekom [[Special:AbuseFilter/$1|filtriranja $2]].", @@ -352,7 +368,7 @@ "abusefilter-test-intro": "Ova stranica omogućava provjeru filtra unešenog u donji okvir s {{PLURAL:$1|posljednjim $1 uređivanjem|posljednjih $1 uređivanja}}.\nZa učitavanje postojećeg filtra, upišite ID filtra u okvir ispod okvira za uređenjivanje i kliknite tipku \"Učitaj\".", "abusefilter-test-legend": "Testiranje filtra", "abusefilter-test-load-filter": "Učitaj ID filtra:", - "abusefilter-test-submit": "Test", + "abusefilter-test-submit": "Testiraj", "abusefilter-test-load": "Učitaj", "abusefilter-test-user": "Izmjene prema suradnicima:", "abusefilter-test-nobots": "Sakrij uređivanja botova", @@ -378,7 +394,7 @@ "abusefilter-examine-submit": "Traži", "abusefilter-examine-vars": "Varijable generirane za ovu izmjenu", "abusefilter-examine-test": "Testiraj ovu izmjenu s filtrom", - "abusefilter-examine-test-button": "Testni filtar", + "abusefilter-examine-test-button": "Testiraj filtar", "abusefilter-examine-match": "Filtar je pronašao ovu promjenu.", "abusefilter-examine-nomatch": "Filtar nije pronašao ovu izmjenu.", "abusefilter-examine-syntaxerror": "Filtar ima neispravnu sintaksu", @@ -387,11 +403,11 @@ "abusefilter-examine-noresults": "Ništa nije pronađeno za parametre pretraživanja koje ste unijeli.", "abusefilter-topnav": "'''Navigacija filtra zloporaba'''", "abusefilter-topnav-home": "Početna stranica", + "abusefilter-topnav-recentchanges": "Nedavne promjene filtra", "abusefilter-topnav-test": "Testiranje", "abusefilter-topnav-examine": "Pregledajte prošla uređivanja", "abusefilter-topnav-log": "Evidencija zlouporaba", "abusefilter-topnav-tools": "Alati za ispravljanje pogrešaka (''debugging'')", - "abusefilter-topnav-import": "Uvoz filtra", "abusefilter-log-name": "Evidencija filtra zloporaba", "abusefilter-log-header": "Evidencija prikazuje sažetak promjena koje su napravljene filtrima.\nZa detaljnije informacije, vidi [[Special:AbuseFilter/history|popis]] nedavnih izmjena filtara.", "abusefilter-logentry-create": "$1 je {{GENDER:$2|stvorio|stvorila}} $4 ($5)", @@ -410,9 +426,9 @@ "abusefilter-import-submit": "Uvoz podataka", "abusefilter-group-default": "Zadano", "abusefilter-http-error": "HTTP-pogrješka: $1.", - "abusefilter-view-private-submit": "Vidi privatne detalje", - "abusefilter-view-private": "Vidi privatne detalje", - "abusefilter-view-private-reason": "Razlog pristupu privatnim detaljima:", + "abusefilter-view-privatedetails-submit": "Vidi privatne detalje", + "abusefilter-view-privatedetails-legend": "Vidi privatne detalje", + "abusefilter-view-privatedetails-reason": "Razlog pristupu privatnim detaljima:", "abusefilter-log-details-id": "Evidencijski ID", "abusefilter-log-ip-not-available": "Nije dostupno", "tag-abusefilter-condition-limit": "dostignuta granica uvjeta", diff --git a/AbuseFilter/i18n/hrx.json b/AbuseFilter/i18n/hrx.json index c3136259..e12c4efa 100644 --- a/AbuseFilter/i18n/hrx.json +++ b/AbuseFilter/i18n/hrx.json @@ -6,7 +6,7 @@ ] }, "abusefilter-desc": "Wennet automatische Heuristike uff Beoorbeitunge an", - "abusefilter": "Missbrauchsfilter-Einstellunge", + "abusefilter": "Missbrauchsfilter-Verwaltung", "abuselog": "Missbrauchsfilter-Logbuch", "abusefilter-intro": "Willkomme uff der Missbrauchsfilter-Management-Oberfläch.\nDer Missbrauchsfilter ist en automatischer Mechanismus, wo automatische Heiristike uff all Ännrunge oonwenne tut.\nDie Oberfläch zeicht en List von aller definierte Filter und erlaubt das man die verännre tut.", "abusefilter-warning": "'''Achtung:''' Die Aktion woard als potentiell unkonstruktiv erkannt.\nSolche Beiträch werre meascht seahr schnell entfernt. In wiederholte und besonnersch schlimme Fälle weard dein Benutzerkonto bzw. dein IP-Adress gesperrt.\nWenns du meenst, dass die Aktion sinnvoll ist, kannst du se zum Beschtätiche erneit speichre.\nKoorzbeschreibung von der verletzte Rechel: $1", @@ -22,7 +22,7 @@ "right-abusefilter-view": "Missbrauchsfilter oonsiehn", "right-abusefilter-log": "Missbrauchsfilter-Logbuch insiehn", "right-abusefilter-log-detail": "Erweitertes Missbrauchsfilter-Logbuch insiehn", - "right-abusefilter-private": "Privat Date im Missbrauchsfilter-Logbuch insiehn", + "right-abusefilter-privatedetails": "Privat Date im Missbrauchsfilter-Logbuch insiehn", "right-abusefilter-modify-restricted": "Missbrauchsfilter mit privilegierte Aktione beoorbeite", "right-abusefilter-revert": "Alle Beoorbeitunge doorrich en bestimmte Missbrauchsfilter rückgängich mache", "right-abusefilter-view-private": "Als privat markierte Missbrauchsfilter insiehn", @@ -34,11 +34,10 @@ "action-abusefilter-view": "Missbrauchsfilter oonzusiehn", "action-abusefilter-log": "das Missbrauchsfilter-Logbuch inzusiehn", "action-abusefilter-log-detail": "das erweiterte Missbrauchsfilter-Logbuch inzusiehn", - "action-abusefilter-private": "private Date im Missbrauchsfilter-Logbuch inzusiehn", + "action-abusefilter-privatedetails": "private Date im Missbrauchsfilter-Logbuch inzusiehn", "action-abusefilter-modify-restricted": "Missbrauchsfilter mit privilegierte Aktione zu beoorbeite", "action-abusefilter-revert": "all Ännrunge doorrich en bestimmte Missbrauchsfilter rückgängich mache", "action-abusefilter-view-private": "Missbrauchsfilter ongucke, die wo als wie privat markiert worre", - "abusefilter-log": "Missbrauchsfilter-Logbuch", "abusefilter-log-summary": "Das Logbuch zeicht en List von aller Aktione, wo doorrich en Filter uffgefang worre.", "abusefilter-log-search": "Missbrauchsfilter-Logbuch doorrichsuche", "abusefilter-log-search-user": "Benutzer:", @@ -57,19 +56,17 @@ "abusefilter-log-details-var": "Variable", "abusefilter-log-details-val": "Weart", "abusefilter-log-details-vars": "Aktionsparameter", - "abusefilter-log-details-private": "Private Date", + "abusefilter-log-details-privatedetails": "Private Date", "abusefilter-log-details-ip": "IP-Adress von der Verursacher", "abusefilter-log-noactions": "ken", "abusefilter-log-details-diff": "Ännrunge doorrich die Beoorbeitung", "abusefilter-log-linkoncontribs": "Missbrauchsfilter-Logbuch", "abusefilter-log-linkoncontribs-text": "Missbrauchsfilter-Logbuch für den Benutzer", - "abusefilter-log-hidden": "(Eintrooch versteckt)", "abusefilter-log-hidden-implicit": "(versteckt, weil die Version abgewischt woard)", "abusefilter-log-hide-legend": "Logbucheintrag verstecke", "abusefilter-log-hide-id": "Logbuch-Eintrags-ID:", "abusefilter-log-hide-hidden": "Den Eintrooch voar der Öffentlichkeit verberriche", "abusefilter-log-hide-reason": "Grund:", - "abusefilter-management": "Missbrauchsfilter-Verwaltung", "abusefilter-list": "Alle Filter", "abusefilter-list-id": "Filterkennung", "abusefilter-list-status": "Status", @@ -89,6 +86,7 @@ "abusefilter-disabled": "Deaktiviert", "abusefilter-hitcount": "{{PLURAL:$1|En Treffer|$1 Treffer}}", "abusefilter-new": "Neie Filter erstelle", + "abusefilter-import-button": "Filter importiere", "abusefilter-return": "Zurück zur Missbrauchsfilter-Verwaltung", "abusefilter-status-global": "Global", "abusefilter-list-options": "Optione", @@ -231,16 +229,16 @@ "abusefilter-edit-builder-vars-all-links": "Alle externe Links im neie Text", "abusefilter-edit-builder-vars-added-links": "Alle dorrich die Beoorbeitung hinzugefüchte externe Links", "abusefilter-edit-builder-vars-removed-links": "Alle dorrich die Beoorbeitung von entfernte externe Links", - "abusefilter-edit-builder-vars-old-text": "Alter Wikitext von der Seit, vor der Beoorbeitung", - "abusefilter-edit-builder-vars-new-text": "Neier Wikitext von der Seit, noh der Beoorbeitung", + "abusefilter-edit-builder-vars-old-wikitext": "Alter Wikitext von der Seit, vor der Beoorbeitung", + "abusefilter-edit-builder-vars-new-wikitext": "Neier Wikitext von der Seit, noh der Beoorbeitung", "abusefilter-edit-builder-vars-new-pst": "Neier Seitewikitext, voar dem Speichre umgewandelt", - "abusefilter-edit-builder-vars-new-text-stripped": "Neier Seitetext, von jechlicher Textauszeichnung befreit", + "abusefilter-edit-builder-vars-new-text": "Neier Seitetext, von jechlicher Textauszeichnung befreit", "abusefilter-edit-builder-vars-new-html": "Der neie Version sein HTML-Quelltext", "abusefilter-edit-builder-vars-restrictions-edit": "Beoorbeite-Schutzstuf von der Seit", "abusefilter-edit-builder-vars-restrictions-move": "Verschieb der Seit sein Schutzstuf", "abusefilter-edit-builder-vars-restrictions-create": "Der Seit sein Erstellschutz", "abusefilter-edit-builder-vars-restrictions-upload": "Der Datei sein Hochloodeschutz", - "abusefilter-edit-builder-vars-old-text-stripped": "Alter Seitetext, von jeglicher Textauszeichnung befreit", + "abusefilter-edit-builder-vars-old-text": "Alter Seitetext, von jeglicher Textauszeichnung befreit", "abusefilter-edit-builder-vars-old-links": "Der Seit sein Links, voar der Beoorbeitung", "abusefilter-edit-builder-vars-old-html": "Der alte Version sein HTML-Quelltext", "abusefilter-edit-builder-vars-minor-edit": "Beoorbeitung woard als wie Klenichkeit markiert", @@ -321,7 +319,6 @@ "abusefilter-topnav-examine": "Unnersuchung von der letzte Ännrunge", "abusefilter-topnav-log": "Logbuch", "abusefilter-topnav-tools": "Debugging", - "abusefilter-topnav-import": "Filter importiere", "abusefilter-log-name": "Missbrauchsfilter-Logbuch", "abusefilter-log-noresults": "Ken Ergebnisse", "abusefilter-diff-title": "Unnerschied zwischich Versione", diff --git a/AbuseFilter/i18n/hsb.json b/AbuseFilter/i18n/hsb.json index 11ae34d7..086593d3 100644 --- a/AbuseFilter/i18n/hsb.json +++ b/AbuseFilter/i18n/hsb.json @@ -1,14 +1,14 @@ { "@metadata": { "authors": [ - "Michawiki", "J budissin", - "Matma Rex" + "Matma Rex", + "Michawiki" ] }, "abusefilter-desc": "Nałožuje awtomatisku heuristiku na změny.", - "abusefilter": "Konfiguracija znjewužiwanskeho filtra", - "abuselog": "Protokol znjewužiwanjow", + "abusefilter": "Zrjadowanje znjewužiwanskich filtrow", + "abuselog": "Protokol znjewužiwanskich filtrow", "abusefilter-intro": "Witaj do powjercha zrjadowanja znjewužiwanskich filtrow.\nZnjewužiwanski filter je awtomatizowany softwarowy mechanizm za nałoženje awtomatiskeje heuristiki na wšě akcije.\nPowjerch pokazuje lisćinu definowanych filtrow a dowola je změnić.", "abusefilter-warning": "'''Warnowanje''': Tuta akcija bu awtomatisce jako škódna identifikowana.\nNjekonstruktiwne změny budu so spěšnje cofnyć, a njesłyšane abo wospjetowane wobdźěłowanje budźe k tomu wjesć, zo twoje konto abo twoja IP-adresa so blokuje.\nJeli maš tutu akciju za konstruktiwnu, móžeš znowa skkadować, zo by ju wobkrućił. \nKrótke wopisanje znjewužiwanskeho prawidła, kotremuž twoja akcija wotpowěduje, je: $1", "abusefilter-disallowed": "Tuta akcija bu awtomatisce jako škódna identifikowana a tohodla znjemóžnjena.\nJeli wěriš, zo twoja akcija je konstruktiwna była, informuj prošu administratora, štož sy spytał činić.\nKrótke wopisanje znjewužiwanskeho prawidła, kotremuž twoja akcija wotpowěduje, je: $1", @@ -23,7 +23,7 @@ "right-abusefilter-view": "Znjewužiwanske filtry sej wobhladać", "right-abusefilter-log": "Protokol znjewužiwanjow zwobraznić", "right-abusefilter-log-detail": "Podrobne zapiski protokola znjewužiwanjow zwobraznić", - "right-abusefilter-private": "Priwatne daty w protokol znjewužiwanjow zwobraznić", + "right-abusefilter-privatedetails": "Priwatne daty w protokol znjewužiwanjow zwobraznić", "right-abusefilter-modify-restricted": "Znjewužiwanske filtry z wobmjezowanymi akcijemi změnić", "right-abusefilter-revert": "Wšě změny wot dateho wužiwanskeho filtra cofnyć", "right-abusefilter-view-private": "Znjewužiwanske filtry sej wobhladać, kotrež su jako priwatne markěrowane", @@ -35,11 +35,10 @@ "action-abusefilter-view": "znjewužiwanske filtry sej wobhladać", "action-abusefilter-log": "znjewužiwanski protokol sej wobhladać", "action-abusefilter-log-detail": "podrobne zapiski znjewužiwanskeho protokola sej wobhladać", - "action-abusefilter-private": "priwatne daty w znjewužiwanskim protokolu sej wobhladać", + "action-abusefilter-privatedetails": "priwatne daty w znjewužiwanskim protokolu sej wobhladać", "action-abusefilter-modify-restricted": "znjewužiwanske filtry z wobmjezowanymi akcijemi změnić", "action-abusefilter-revert": "wšě změny přez daty znjewužiwanski filter wobroćić", "action-abusefilter-view-private": "znjewužiwanske filtry sej wobhladać, kotrež su jako priwatne markěrowane", - "abusefilter-log": "Protokol znjewužiwanskich filtrow", "abusefilter-log-summary": "Tutón protokol pokazuje lisćinu wšěch přez filtry popadnjene akcijow.", "abusefilter-log-search": "Protokol znjewužiwanjow přepytać", "abusefilter-log-search-user": "Wužiwar:", @@ -59,13 +58,12 @@ "abusefilter-log-details-var": "Wariabla", "abusefilter-log-details-val": "Hódnota", "abusefilter-log-details-vars": "Akciske parametry", - "abusefilter-log-details-private": "Priwatne daty", + "abusefilter-log-details-privatedetails": "Priwatne daty", "abusefilter-log-details-ip": "Wuchadna adresa IP", "abusefilter-log-noactions": "žadyn", "abusefilter-log-details-diff": "Při wobdźěłanju činjene změny", "abusefilter-log-linkoncontribs": "znjewužiwanski protokol", "abusefilter-log-linkoncontribs-text": "Znjewužiwanski protokol za tutoho wužiwarja", - "abusefilter-log-hidden": "(zapisk schowany)", "abusefilter-log-hidden-implicit": "(schowany, dokelž wersija je so zhašała)", "abusefilter-log-cannot-see-details": "Nimaš prawo sej podrobnosće tutoho zapiska wobhladać.", "abusefilter-log-details-hidden": "Njemóžeš sej podrobnosće za tutón zapisk wobhladać, dokelž je před zjawnosću schowany.", @@ -76,7 +74,6 @@ "abusefilter-log-hide-reason": "Přičina:", "abusefilter-log-hide-forbidden": "Nimaš prawo zapiski znjewužiwanskeho protokola schować.", "logentry-abusefilter-hit": "$1 je při wuwjedźenju akcije \"$5\" na $3 $4 zahibał. Skutkowanje: $6 ($7)", - "abusefilter-management": "Zrjadowanje znjewužiwanskich filtrow", "abusefilter-list": "wšě filtry", "abusefilter-list-id": "ID filtra", "abusefilter-list-status": "Status", @@ -96,6 +93,7 @@ "abusefilter-disabled": "Znjemóžnjeny", "abusefilter-hitcount": "$1 {{PLURAL:$1|trjecheny|trjechenej|trjechene|trjechenych}}", "abusefilter-new": "Nowy filter wutworić", + "abusefilter-import-button": "Fitler importować", "abusefilter-return": "Wróćo k zrjadowanju filtrow", "abusefilter-status-global": "Globalny", "abusefilter-list-options": "Opcije", @@ -124,7 +122,6 @@ "abusefilter-edit-oldwarning": "<strong>Wobdźěłuješ staru wersiju tutoho filtra.\nStatistiske podaća su jenož za najnowšu wersiju filtra.\nJeli swoje změny składuješ, budźeš wšě změny wot wersije, kotruž wobdźěłuješ, přepisować.</strong> •\n[[Special:AbuseFilter/history/$2|Wróćo k stawiznam tutoho filtra]].", "abusefilter-edit-status-label": "Statistika:", "abusefilter-edit-status": "Z {{PLURAL:$1|poslednjeje akcije|poslednjeju $1 akcijow|poslednich $1 akcijow|poslednich $1 akcijow}} je tutón filter $2 ($3%) spóznał. Jeho přerězny běžny čas je $4 ms a spjelnja $5 {{PLURAL:$5|wuměnjenje|wuměnjeni|wuměnjenja|wuměnjenjow}} limita wuměnjenjow.", - "abusefilter-edit-status-profile": "Z {{PLURAL:$1|poslednjeje akcije|poslednjeju $1 akcijow|poslednich $1 akcijow|poslednich $1 akcijow}} je tutón filter $2 ($3%) spóznał. Jeho přerězny běžny čas je $4 ms a spjelnja $5 {{PLURAL:$5|wuměnjenje|wuměnjeni|wuměnjenja|wuměnjenjow}} limita wuměnjenjow.", "abusefilter-edit-new": "Nowy filter", "abusefilter-edit-save": "Filter składować", "abusefilter-edit-id": "ID filtra:", @@ -261,18 +258,18 @@ "abusefilter-edit-builder-vars-all-links": "Wšě eksterne wotkzay w nowym teksće", "abusefilter-edit-builder-vars-added-links": "Wšě přez změnu přidate eksterne wotkazy", "abusefilter-edit-builder-vars-removed-links": "Wšě přez změnu wotstronjene eksterne wotkazy", - "abusefilter-edit-builder-vars-old-text": "Stary wikitekst strony do změny", - "abusefilter-edit-builder-vars-new-text": "Nowy wikitekst strony po změnje", + "abusefilter-edit-builder-vars-old-wikitext": "Stary wikitekst strony do změny", + "abusefilter-edit-builder-vars-new-wikitext": "Nowy wikitekst strony po změnje", "abusefilter-edit-builder-vars-new-pst": "Nowy wikitekst strony, před składowanjom přetworjeny", "abusefilter-edit-builder-vars-diff-pst": "Zjednoćeny rozdźěl změnow po wobdźěłowanju, před składowanjom přetworjeny", "abusefilter-edit-builder-vars-addedlines-pst": "Linki přidate we wobdźěłowanju, před składowanjom přetworjene", - "abusefilter-edit-builder-vars-new-text-stripped": "Nowy tekst strony, bjez woznamjenjenskeho teksta", + "abusefilter-edit-builder-vars-new-text": "Nowy tekst strony, bjez woznamjenjenskeho teksta", "abusefilter-edit-builder-vars-new-html": "Analyzowane HTML-žórło noweje wersije", "abusefilter-edit-builder-vars-restrictions-edit": "Škitnu runinu strony wobdźěłać", "abusefilter-edit-builder-vars-restrictions-move": "Škitnu runinu strony přesunyć", "abusefilter-edit-builder-vars-restrictions-create": "Wutworjenski škit strony", "abusefilter-edit-builder-vars-restrictions-upload": "Nahrawanski škit dataje", - "abusefilter-edit-builder-vars-old-text-stripped": "Tekst stareje strony, bjez woznamjenjenjow", + "abusefilter-edit-builder-vars-old-text": "Tekst stareje strony, bjez woznamjenjenjow", "abusefilter-edit-builder-vars-old-links": "Wotkazy w stronje, před wobdźěłanjom", "abusefilter-edit-builder-vars-old-html": "Wikitekst stareje strony, do HTML analyzowany", "abusefilter-edit-builder-vars-minor-edit": "Hač změna so jako snadna markěruje abo nic", @@ -348,6 +345,7 @@ "abusefilter-test-shownegative": "Změny pokazać, kotrež filtrej njewotpowěduja", "abusefilter-test-syntaxerr": "Filter, kotryž sy zapodał, je syntaksowy zmylk wobsahował.\nPřez kliknjenje na tłóčatko \"{{int:abusefilter-edit-check}}\" móžeš połne wujasnjenje dóstać.", "abusefilter-test-badtitle": "Titul strony, kotryž sy zapodał, je njepłaćiwy był. Wobsahuje snano znamješka, kotrež njehodźa so w titulu wužiwać.", + "abusefilter-test-search-type-upload": "Nahrate dataje", "abusefilter-changeslist-examine": "přepytować", "abusefilter-examine": "Jednotliwe změny přepytować", "abusefilter-examine-intro": "Tuta strona ći zmóžnja wariable přepytać, kotrež buchu wot znjewužiwanskeho filtra za jednotliwu změnu spłodźene a ju přećiwo filtram testować.", @@ -371,7 +369,6 @@ "abusefilter-topnav-examine": "Zańdźene změny přepruwować", "abusefilter-topnav-log": "Protokol znjewužiwanjow", "abusefilter-topnav-tools": "Nastroje za wotstronjenje zmylkow", - "abusefilter-topnav-import": "Fitler importować", "abusefilter-log-name": "Protokol znjewužiwanskich filtrow", "abusefilter-log-header": "Tutón protokol pokazuje zjeće změnow, kotrež buchu na filtrach přewjedźene.\nZa dospołne podrobnosće hlej [[Special:AbuseFilter/history|lisćinu]] njedawnych filtrowych změnow.", "abusefilter-log-noresults": "Žane wuslědki", diff --git a/AbuseFilter/i18n/ht.json b/AbuseFilter/i18n/ht.json index 81b09d45..f3cdd1b4 100644 --- a/AbuseFilter/i18n/ht.json +++ b/AbuseFilter/i18n/ht.json @@ -4,7 +4,5 @@ "Masterches" ] }, - "abusefilter-desc": "Aplike avètisman otomatik lè genyen modifikasyon", - "abusefilter": "Konfigirasyon filt tout abi yo", - "abuselog": "Jounal pou abi yo" + "abusefilter-desc": "Aplike avètisman otomatik lè genyen modifikasyon" } diff --git a/AbuseFilter/i18n/hu.json b/AbuseFilter/i18n/hu.json index 073625c6..9d3e76c3 100644 --- a/AbuseFilter/i18n/hu.json +++ b/AbuseFilter/i18n/hu.json @@ -2,23 +2,26 @@ "@metadata": { "authors": [ "Bdamokos", + "Bencemac", "Bináris", + "Csega", "Dani", "Dj", "Dunee", "Glanthor Reviol", + "Matma Rex", "Misibacsi", + "Samat", "Tacsipacsi", "Tgr", - "Samat", - "Matma Rex", "Wolf Rex" ] }, "abusefilter-desc": "Automatikus heurisztikát alkalmaz a szerkesztésekre.", - "abusefilter": "Vandálszűrő beállítása", + "abusefilter": "Vandálszűrő-kezelés", "abuselog": "Vandálszűrő-napló", "abusefilter-intro": "Üdvözölünk a Vandálszűrő kezelőfelületén.\nA Vandálszűrő egy automatizált szoftver, ami minden műveletnél automatikus heurisztikát alkalmaz.\nItt tekintheted át és módosíthatod a szűrőket.", + "abusefilter-mustviewprivateoredit": "Biztonsági okokból csak azok a szerkesztők használhatják ezt a felületet, akik rendelkeznek a privát vandálszűrők megtekintéséhez és a szűrők szerkesztéséhez szükséges jogokkal.", "abusefilter-warning": "'''Figyelmeztetés:''' ez a művelet károsnak lett minősítve.\nA nem építő jellegű műveletek gyorsan vissza lesznek vonva,\na többszöri ilyen jellegű szerkesztés a felhasználói fiók vagy az IP-cím blokkolását vonja maga után.\nHa biztos vagy benne, hogy a szerkesztésed építő jellegű, kattints az Elküld gombra a megerősítéshez.\nA visszaélési szabály rövid leírása, amelynek az általad végzett művelet megfelelt: $1", "abusefilter-disallowed": "Ez a művelet automatikusan károsnak lett minősítve, így\nnem hajtható végre.\nHa úgy gondolod, hogy az általad végzett művelet építő jellegű, lépj kapcsolatba egy adminisztrátorral, és jelezd neki, hogy mit szerettél volna csinálni.\nA visszaélési szabály rövid leírása, amelynek az általad végzett művelet megfelelt: $1", "abusefilter-blocked-display": "Ez a művelet automatikusan károsnak lett minősítve,\nígy nem hajtható végre.\nA(z) {{SITENAME}} védelme érdekében a szerkesztői fiókodat és az összes hozzátartozó IP címet blokkoltuk.\nHa úgy gondolod, hogy a blokkolás egy rendszerhiba eredménye volt, lépj kapcsolatba egy adminisztrátorral, és jelezd neki, hogy mit szerettél volna csinálni.\nA visszaélési szabály rövid leírása, amelynek az általad végzett művelet megfelelt: $1", @@ -28,12 +31,12 @@ "abusefilter-blockreason": "A Vandálszűrő automatikusan blokkolt.\nA visszaélési szabály rövid leírása, amelynek az elvégzett művelet megfelel: $1", "abusefilter-degroupreason": "A Vandálszűrő automatikusan visszavonta a jogokat.\nA visszaélési szabály rövid leírása: $1", "abusefilter-accountreserved": "Ez a szerkesztői fiók a Vandálszűrőnek van fenntartva.", - "right-abusefilter-modify": "vandálszűrők módosítása", + "right-abusefilter-modify": "Vandálszűrők létrehozása vagy módosítása", "right-abusefilter-view": "vandálszűrők megtekintése", "right-abusefilter-log": "a Vandálszűrő naplójának megtekintése", "right-abusefilter-log-detail": "Részletes Vandálszűrő-naplóbejegyzések", - "right-abusefilter-private": "személyes adatok megtekintése a Vandálszűrő naplójában", - "right-abusefilter-private-log": "a Vandálszűrő privát részletei naplójának megtekintése", + "right-abusefilter-privatedetails": "személyes adatok megtekintése a Vandálszűrő naplójában", + "right-abusefilter-privatedetails-log": "a Vandálszűrő privát részletei naplójának megtekintése", "right-abusefilter-modify-restricted": "vandálszűrők módosítása korlátozott hozzáféréssel", "right-abusefilter-revert": "Egy adott vandálszűrő által okozott összes változtatás visszavonása", "right-abusefilter-view-private": "privátként megjelölt vandálszűrők megtekintése", @@ -45,16 +48,22 @@ "action-abusefilter-view": "vandálszűrők megtekintése", "action-abusefilter-log": "a Vandálszűrő naplójának megtekintése", "action-abusefilter-log-detail": "a Vandálszűrő részletes naplójának megtekintése", - "action-abusefilter-private": "a Vandálszűrő naplójának privát adatokat tartalmazó részének megtekintése", - "action-abusefilter-private-log": "a Vandálszűrő privát részletei naplójának megtekintése", + "action-abusefilter-privatedetails": "a Vandálszűrő naplójának privát adatokat tartalmazó részének megtekintése", + "action-abusefilter-privatedetails-log": "a Vandálszűrő privát részletei naplójának megtekintése", "action-abusefilter-modify-restricted": "vandálszűrők korlátozott szerkesztése", "action-abusefilter-revert": "egy adott vandálszűrő módosításainak visszavonása", "action-abusefilter-view-private": "privátként megjelölt vandálszűrők megtekintése", - "abusefilter-log": "Vandálszűrő-napló", + "action-abusefilter-log-private": "privátként megjelölt vandálszűrők naplóbejegyzéseinek megtekintése", + "action-abusefilter-hide-log": "bejegyzések elrejtése a vandálszűrő naplójában", + "action-abusefilter-hidden-log": "vandálszűrő naplójának rejtett bejegyzéseinek megtekintése", + "action-abusefilter-modify-global": "globális vandálszűrők létrehozása vagy módosítása", "abusefilter-log-summary": "Ezen a lapon láthatóak a vandálszűrők által elkapott műveletek.", "abusefilter-log-search": "Keresés a Vandálszűrő naplójában", "abusefilter-log-search-user": "Szerkesztő:", - "abusefilter-log-search-filter": "Szűrőazonosítók (függőleges vonallal elválasztva):", + "abusefilter-log-search-group": "Szűrőcsoport:", + "abusefilter-log-search-group-any": "Bármely", + "abusefilter-log-search-filter": "Szűrőazonosítók:", + "abusefilter-log-search-filter-help": "Függőleges vonallal elválasztva, globális szűrők esetén „$1” előtaggal", "abusefilter-log-search-title": "Cím:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-impact": "Hatás:", @@ -65,6 +74,9 @@ "abusefilter-log-search-entries-all": "Minden bejegyzés", "abusefilter-log-search-entries-hidden": "Csak rejtett bejegyzések", "abusefilter-log-search-entries-visible": "Csak látható bejegyzések", + "abusefilter-log-search-action-label": "Kiváltó művelet:", + "abusefilter-log-search-action-other": "egyéb", + "abusefilter-log-search-action-any": "mind", "abusefilter-log-search-action-taken-label": "Végzett művelet:", "abusefilter-log-search-action-taken-any": "Mind", "abusefilter-log-search-submit": "Keresés", @@ -80,29 +92,40 @@ "abusefilter-log-details-var": "Változó", "abusefilter-log-details-val": "Érték", "abusefilter-log-details-vars": "Műveletparaméterek", - "abusefilter-log-details-private": "Személyes adatok", + "abusefilter-log-details-privatedetails": "Privát naplórészletek", "abusefilter-log-details-ip": "IP-cím", + "abusefilter-log-details-checkuser": "IP-ellenőr", "abusefilter-log-noactions": "nem történt", "abusefilter-log-details-diff": "Szerkesztés során elvégzett változtatások", "abusefilter-log-linkoncontribs": "vandálszűrő naplója", "abusefilter-log-linkoncontribs-text": "A {{GENDER:$1|szerkesztő}} Vandálszűrő-naplója", - "abusefilter-log-hidden": "(bejegyzés elrejtve)", + "abusefilter-log-linkonhistory": "Vandálszűrő-naplók megtekintése", + "abusefilter-log-linkonhistory-text": "A laphoz tartozó Vandálszűrő-naplók bejegyzéseinek megtekintése", + "abusefilter-log-linkonundelete": "Vandálszűrő-napló megtekintése", + "abusefilter-log-linkonundelete-text": "A laphoz tartozó Vandálszűrő-napló megtekintése", "abusefilter-log-hidden-implicit": "(rejtett mivel a változat törölve lett)", "abusefilter-log-cannot-see-details": "Nincs jogosultságod a bejegyzés részleteinek megjelenítéséhez.", + "abusefilter-log-cannot-see-privatedetails": "Nincs jogosultságod a bejegyzés privát részleteinek megjelenítéséhez.", + "abusefilter-log-nonexistent": "A megadott azonosítóhoz nem található tétel.", "abusefilter-log-details-hidden": "Ennek a tételnek a láthatósága \"rejtett\", ezért a nyilvánosság számára nem látható.", + "abusefilter-log-details-hidden-implicit": "Nem nézheted meg a tétel részleteit, mert a kapcsolódó lapváltozat a nyilvánosság elől el lett rejtve.", "abusefilter-log-private-not-included": "Egy vagy több szűrőazonosító privát. Mivel nem engedélyezett számodra a privát szűrők részleteinek megtekintése, ezek a szűrők ki lettek hagyva a keresésből.", "abusefilter-log-hide-legend": "Naplóbejegyzés elrejtése", "abusefilter-log-hide-id": "A tétel azonosítója:", "abusefilter-log-hide-hidden": "Ennek a tételnek az elrejtése a nyilvánosság elől.", "abusefilter-log-hide-reason": "Indoklás:", + "abusefilter-log-hide-reason-other": "Más/további ok:", "abusefilter-log-hide-forbidden": "Nincs jogosultságod elrejteni ezeket a tételeket.", + "abusefilter-log-entry-suppress": "$1 {{GENDER:$2|elrejtette}} $3", + "abusefilter-log-entry-unsuppress": "$1 {{GENDER:$2|láthatóvá tette}} $3", "logentry-abusefilter-hit": "$1 „$5” műveletével {{GENDER:$2|beindította}} a(z) $4 vandálszűrőt a(z) $3 oldalon. Elvégzett intézkedések: $6 ($7)", "log-action-filter-abusefilter": "Szűrőváltoztatás típusa:", "log-action-filter-abusefilter-create": "Új szűrő létrehozása", "log-action-filter-abusefilter-modify": "Szűrő módosítása", - "abusefilter-management": "Vandálszűrő-kezelés", + "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|hozzáfért}} a(z) $3. naplóbejegyzés privát részleteihez", "abusefilter-list": "Az összes szűrő", "abusefilter-list-id": "Szűrőazonosító", + "abusefilter-list-pattern": "Minta", "abusefilter-list-status": "Állapot", "abusefilter-list-public": "Publikus leírás", "abusefilter-list-consequences": "Következmények", @@ -120,6 +143,7 @@ "abusefilter-disabled": "Kikapcsolva", "abusefilter-hitcount": "$1 ×", "abusefilter-new": "Új szűrő", + "abusefilter-import-button": "Szűrő importálása", "abusefilter-return": "Vissza a szűrők áttekintéséhez", "abusefilter-status-global": "Globális", "abusefilter-list-options": "Beállítások", @@ -131,7 +155,14 @@ "abusefilter-list-options-scope-local": "Csak helyi szabályok", "abusefilter-list-options-scope-global": "Csak globális szabályok", "abusefilter-list-options-scope-all": "Helyi és globális szabályok", + "abusefilter-list-options-further-options": "További lehetőségek:", "abusefilter-list-options-hidedisabled": "Kikapcsolt szűrők elrejtése", + "abusefilter-list-options-hideprivate": "Privát szűrők elrejtése", + "abusefilter-list-options-searchpattern": "Minta megadása", + "abusefilter-list-options-searchoptions": "Keresési mód:", + "abusefilter-list-options-search-rlike": "Reguláris kifejezés", + "abusefilter-list-options-search-irlike": "Kis- és nagybetűket nem megkülönböztető reguláris kifejezés", + "abusefilter-list-regexerror": "Hiba történt a keresés során: reguláris kifejezés szintaktikai hibája.", "abusefilter-list-options-submit": "Frissítés", "abusefilter-tools-text": "Egy pár eszköz a vandálszűrők kialakításához és hibakereséséhez.", "abusefilter-tools-expr": "Expression tesztelő", @@ -146,14 +177,16 @@ "abusefilter-edit": "Vandálszűrő szerkesztése", "abusefilter-edit-subtitle": "A(z) $1 szűrő szerkesztése", "abusefilter-edit-subtitle-new": "Szűrő létrehozása", + "abusefilter-edit-token-not-match": "A szerkesztés nem lett elmentve! Kérlek, mentsd el újra.", "abusefilter-edit-oldwarning": "<strong>Most a szűrő egyik régebbi változatát szerkeszted. A megjelölt statisztikák a szűrő jelenlegi állapotát tükrözik. Ha elmented a változtatásokat, akkor azzal az összes köztes változatot felülírod.</strong> • [[Special:AbuseFilter/history/$2|Vissza a szűrő laptörténetébe]].", "abusefilter-edit-status-label": "Statisztikák:", - "abusefilter-edit-status": "{{PLURAL:$1|A legutolsó művelet esetén|Az utolsó $1 műveletnél}} ez a szűrő $2 ($3%) alkalommal talált egyezést.", - "abusefilter-edit-status-profile": "{{PLURAL:$1|A legutolsó művelet esetén|Az utolsó $1 műveletnél}} ez a szűrő $2 ($3%) alkalommal talált egyezést.\nAz átlagos futási ideje $4 ms volt, és {{PLURAL:$5|egy|$5}} feltételt használt fel a feltételhatárból.", + "abusefilter-edit-status": "{{PLURAL:$1|A legutolsó művelet esetén|Az utolsó $1 műveletnél}} ez a szűrő $2 ($3%) alkalommal talált egyezést. Az átlagos futtatási idő $4 ms volt, és $5 feltételt fogyasztott el.", "abusefilter-edit-new": "Új szűrő", "abusefilter-edit-save": "Szűrő mentése", "abusefilter-edit-id": "Szűrő azonosítója:", + "abusefilter-edit-switch-editor": "Szerkesztő váltása", "abusefilter-edit-description": "Leírás:\n:''(mindenki számára látható)''", + "abusefilter-edit-field-description": "leírás", "abusefilter-edit-group": "Szűrőcsoport:", "abusefilter-edit-flags": "Tulajdonságok:", "abusefilter-edit-enabled": "A szűrő bekapcsolása", @@ -161,6 +194,7 @@ "abusefilter-edit-hidden": "A szűrő adatainak elrejtése", "abusefilter-edit-global": "Globális szűrő", "abusefilter-edit-rules": "Feltételek:", + "abusefilter-edit-field-conditions": "feltételek", "abusefilter-edit-notes": "Megjegyzések:", "abusefilter-edit-lastmod": "Utoljára módosította:", "abusefilter-edit-lastmod-text": "$2, $1-kor", @@ -171,24 +205,52 @@ "abusefilter-edit-action-blockautopromote": "A szerkesztő autoconfirmed állapotának visszavonása", "abusefilter-edit-action-degroup": "A szerkesztő összes jogosultságának eltávolítása", "abusefilter-edit-action-block": "Szerkesztő vagy IP-cím blokkolása", + "abusefilter-edit-action-blocktalk": "Felhasználó és/vagy IP-cím megakadályozása, hogy szerkeszthesse vitalapját.", "abusefilter-edit-action-throttle": "Műveletek végrehajtása akkor, ha a szerkesztő átlép egy határt", - "abusefilter-edit-action-rangeblock": "A /16-os tartomány blokkolása, ahonnan a szerkesztő származik.", + "abusefilter-edit-action-rangeblock": "Azon IP-tartomány blokkolása, ahonnan a szerkesztő származik", "abusefilter-edit-action-tag": "Szerkesztés felcímkézése későbbi ellenőrzésre.", "abusefilter-edit-throttle-count": "Engedélyezett műveletek száma:", - "abusefilter-edit-throttle-period": "Időtartam:", + "abusefilter-edit-throttle-period": "Időtartam (másodpercben):", "abusefilter-edit-throttle-groups": "Érintett csoportok:\n:''(soronként egy, csoportosítás vesszővel)''", + "abusefilter-edit-throttle-groups-help": "Lásd $1.", + "abusefilter-edit-throttle-groups-help-text": "a dokumentációt a MediaWiki.org weboldalon", + "abusefilter-edit-throttle-hidden-placeholder": "Vesszővel elválasztva összefűzés ÉS-ként, sortöréssel VAGY-ként", + "abusefilter-edit-throttle-placeholder": "Vesszővel elválasztva összefűzés ÉS-ként, egyenként beillesztve VAGY-ként", + "abusefilter-throttle-ip": "IP-címek", + "abusefilter-throttle-user": "felhasználói fiók", + "abusefilter-throttle-range": "/16-os tartomány", + "abusefilter-throttle-creationdate": "felhasználói fiók létrehozásának dátuma", + "abusefilter-throttle-editcount": "szerkesztésszám", + "abusefilter-throttle-site": "egész oldal", + "abusefilter-throttle-page": "lap", + "abusefilter-throttle-none": "(nincs)", "abusefilter-edit-warn-message": "Figyelmeztetéshez használt rendszerüzenet:", "abusefilter-edit-warn-other": "Más üzenet", - "abusefilter-edit-warn-other-label": "A másik rendszerüzenet neve:\n:''(a MediaWiki-előtag nélkül)''", + "abusefilter-edit-warn-other-label": "A másik rendszerüzenet neve:\n:''('MediaWiki:' előtag nélkül)''", "abusefilter-edit-warn-actions": "Műveletek:", - "abusefilter-edit-warn-preview": "Kiválasztott üzenet előnézete", + "abusefilter-edit-warn-preview": "A kiválasztott üzenet előnézetének elrejtése/megjelenítése", "abusefilter-edit-warn-edit": "Kiválasztott üzenet létrehozása / szerkesztése", - "abusefilter-edit-tag-tag": "[[Special:Tags|Címkék]] (soronként egy):", + "abusefilter-edit-disallow-message": "A megtagadáshoz használt rendszerüzenet:", + "abusefilter-edit-disallow-other": "Egyéb üzenet", + "abusefilter-edit-disallow-other-label": "A másik rendszerüzenet neve:\n:''('MediaWiki:' előtag nélkül)''", + "abusefilter-edit-disallow-actions": "Műveletek:", + "abusefilter-edit-disallow-preview": "A kiválasztott üzenet előnézetének elrejtése/megjelenítése", + "abusefilter-edit-disallow-edit": "Kiválasztott üzenet létrehozása / szerkesztése", + "abusefilter-edit-tag-tag": "Alkalmazandó [[Special:Tags|címkék]]:", + "abusefilter-edit-tag-placeholder": "Címkék hozzáadása (egyenként vagy vesszővel elválasztva)", + "abusefilter-edit-tag-hidden-placeholder": "Címkék hozzáadása (vesszővel elválasztva)", + "abusefilter-edit-block-anon-durations": "A blokkolás időtartalma anonim szerkesztő esetén:", + "abusefilter-edit-block-user-durations": "A blokkolás időtartalma regisztrált szerkesztő esetén:", + "abusefilter-block-anon": "Anonim felhasználók blokkolása", + "abusefilter-block-user": "Regisztrált felhasználók blokkolása", + "abusefilter-block-talk": "vitalap blokkolva", "abusefilter-edit-denied": "Nem tekintheted meg a szűrő tulajdonságait, mert el vannak rejtve a nyilvánosság elől.", "abusefilter-edit-main": "A szűrő tulajdonságai", "abusefilter-edit-done-subtitle": "A szűrő módosítva", "abusefilter-edit-done": "Sikeresen [[Special:AbuseFilter/history/$1/diff/prev/$2|megváltoztattad]] a(z) [[Special:AbuseFilter/$1|$3]] szűrő tulajdonságait.", "abusefilter-edit-badsyntax": "Szintaktikai hiba található az általad megadott szűrőben.\nAz elemző kimenete a következő volt: <pre>$1</pre>", + "abusefilter-edit-missingfields": "A következő mezők kitöltése kötelező: $1", + "abusefilter-edit-deleting-enabled": "Nem jelölhetsz egy aktív szűrőt töröltnek.", "abusefilter-edit-restricted": "Nem szerkesztheted a szűrőt, mert az egy vagy több korlátozott hozzáférésű műveletet tartalmaz.\nKérj meg egy megfelelő jogosultságokkal rendelkező szerkesztőt, hogy végezze el számodra a változtatást.", "abusefilter-edit-viewhistory": "A szűrő előzményeinek megtekintése", "abusefilter-edit-history": "Előzmények:", @@ -200,9 +262,13 @@ "abusefilter-edit-export": "Szűrő exportálása egy másik wikibe", "abusefilter-edit-syntaxok": "Nincs szintaktikai hiba.", "abusefilter-edit-syntaxerr": "Szintaktikai hiba: $1", + "abusefilter-edit-warn-leave": "Az oldal elhagyásával elvesznek a szűrőn végzett változtatásaid.", "abusefilter-edit-bad-tags": "Egy vagy több megadott címke nem érvényes.\nA címkéknek rövidnek kell lenniük, nem tartalmazhatnak speciális karaktereket, és nem lehetnek más szoftver számára fenntartottak. Próbálj új címkenevet választani.", "abusefilter-edit-notallowed": "Nincs engedélyed visszaélési szabályok létrehozására vagy módosítására", "abusefilter-edit-notallowed-global": "Nincs engedélyed globális vandálszűrők létrehozására vagy módosítására", + "abusefilter-edit-notallowed-global-custom-msg": "Az egyedi figyelmeztetések vagy a megtagadáshoz használt üzenetek nem támogatottak a globális szűrőknél.", + "abusefilter-edit-invalid-warn-message": "A figyelmeztető üzenet nem lehet üres.", + "abusefilter-edit-invalid-disallow-message": "A megtagadáshoz használt üzenet nem lehet üres.", "abusefilter-edit-builder-select": "A kurzornál való beszúráshoz válassz egy opciót", "abusefilter-edit-builder-group-op-arithmetic": "Aritmetikai operátorok", "abusefilter-edit-builder-op-arithmetic-addition": "összeadás (+)", @@ -212,8 +278,10 @@ "abusefilter-edit-builder-op-arithmetic-modulo": "maradékképzés (%)", "abusefilter-edit-builder-op-arithmetic-pow": "hatványozás (**)", "abusefilter-edit-builder-group-op-comparison": "Összehasonlító operátorok", - "abusefilter-edit-builder-op-comparison-equal": "egyenlő (==)", - "abusefilter-edit-builder-op-comparison-notequal": "nem egyenlő (!=)", + "abusefilter-edit-builder-op-comparison-equal": "Az érték egyenlő a következővel (==)", + "abusefilter-edit-builder-op-comparison-equal-strict": "Az érték és a típus egyenlő a következővel (===)", + "abusefilter-edit-builder-op-comparison-notequal": "Az érték nem egyenlő a következővel (!=)", + "abusefilter-edit-builder-op-comparison-notequal-strict": "Az érték és atípus nem egyenlő a következővel (!==)", "abusefilter-edit-builder-op-comparison-lt": "kisebb (<)", "abusefilter-edit-builder-op-comparison-gt": "nagyobb (>)", "abusefilter-edit-builder-op-comparison-lte": "kisebb vagy egyenlő (<=)", @@ -230,7 +298,8 @@ "abusefilter-edit-builder-misc-contains": "A baloldali sztring tartalmazza a jobboldali sztringet (contains)", "abusefilter-edit-builder-misc-stringlit": "sztring literál (\"\")", "abusefilter-edit-builder-misc-tern": "ternáris operátor (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "feltételes (ha X akkor Y egyébként Z)", + "abusefilter-edit-builder-misc-cond": "Feltételes (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "Rövid feltételes (if X then Y)", "abusefilter-edit-builder-group-funcs": "Függvények", "abusefilter-edit-builder-funcs-length": "sztring hossza (length)", "abusefilter-edit-builder-funcs-lcase": "kisbetűssé alakítás (lcase)", @@ -244,37 +313,46 @@ "abusefilter-edit-builder-funcs-rmwhitespace": "felesleges szóközök eltávolítása (rmwhitespace)", "abusefilter-edit-builder-funcs-rmspecials": "különleges karakterek eltávolítása (rmspecials)", "abusefilter-edit-builder-funcs-ip_in_range": "a megadott IP-tartományba tartozik? (ip_in_range)", - "abusefilter-edit-builder-funcs-contains-any": "sztringben több részsztring keresése (contains_any)", + "abusefilter-edit-builder-funcs-contains-any": "Sztringben több részsztring keresése VAGY módban. (contains_any)", + "abusefilter-edit-builder-funcs-contains-all": "Sztringben több részsztring keresése ÉS módban. (contains_all)", + "abusefilter-edit-builder-funcs-equals-to-any": "A megadott argumentum vizsgálata, hogy egyenlő-e (===) az alábbiak közül valamelyikkel (equals_to_any)", "abusefilter-edit-builder-funcs-substr": "részsztring (substr)", "abusefilter-edit-builder-funcs-strpos": "részsztring helye a sztringen belül (strpos)", "abusefilter-edit-builder-funcs-str_replace": "részsztring cseréje a sztringre (str_replace)", "abusefilter-edit-builder-funcs-rescape": "Sztring átalakítása szöveggé a regex-ben (rescape)", "abusefilter-edit-builder-funcs-set_var": "változó értékének megadása (set_var)", + "abusefilter-edit-builder-funcs-sanitize": "HTML egységek szabványosítása Unicode karakterekké (sanitize)", "abusefilter-edit-builder-group-vars": "Változók", "abusefilter-edit-builder-vars-accountname": "szerkesztői fiók neve (fióklétrehozáskor)", "abusefilter-edit-builder-vars-timestamp": "a változás Unix-időbélyege", + "abusefilter-edit-builder-vars-timestamp-expanded": "A napló időbélyege", "abusefilter-edit-builder-vars-action": "művelet", - "abusefilter-edit-builder-vars-addedlines": "a szerkesztés során hozzáadott sorok száma", + "abusefilter-edit-builder-vars-addedlines": "Szerkesztés során hozzáadott sorok", "abusefilter-edit-builder-vars-delta": "a szerkesztés során történt méretváltozás", - "abusefilter-edit-builder-vars-diff": "a szerkesztés során történt változások Unified diffje", + "abusefilter-edit-builder-vars-diff": "A szerkesztés során történt változások Unified diffje", "abusefilter-edit-builder-vars-newsize": "új lapméret", "abusefilter-edit-builder-vars-oldsize": "régi lapméret", - "abusefilter-edit-builder-vars-removedlines": "a szerkesztés során eltávolított sorok száma", + "abusefilter-edit-builder-vars-old-content-model": "Korábbi tartalommodell", + "abusefilter-edit-builder-vars-new-content-model": "Új tartalommodell", + "abusefilter-edit-builder-vars-removedlines": "Szerkesztés során eltávolított sorok", "abusefilter-edit-builder-vars-summary": "szerkesztési összefoglaló", "abusefilter-edit-builder-vars-page-id": "oldalazonosító", "abusefilter-edit-builder-vars-page-ns": "lap névtere", "abusefilter-edit-builder-vars-page-title": "lap címe (névtér nélkül)", "abusefilter-edit-builder-vars-page-prefixedtitle": "a lap teljes címe", + "abusefilter-edit-builder-vars-page-age": "Oldal életkora (másodpercben)", "abusefilter-edit-builder-vars-movedfrom-id": "átnevezésnél a forráslap azonosítója", "abusefilter-edit-builder-vars-movedfrom-ns": "átnevezésnél a forráslap névtere", "abusefilter-edit-builder-vars-movedfrom-title": "átnevezésnél a forráslap címe", "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "átnevezésnél a forráslap teljes címe", + "abusefilter-edit-builder-vars-movedfrom-age": "Az átnevezendő lap életkora (másodpercben)", "abusefilter-edit-builder-vars-movedto-id": "átnevezésnél a céllap azonosítója", "abusefilter-edit-builder-vars-movedto-ns": "átnevezésnél a céllap névtere", "abusefilter-edit-builder-vars-movedto-title": "átnevezésnél a céllap címe", "abusefilter-edit-builder-vars-movedto-prefixedtitle": "átnevezésnél a céllap teljes címe", + "abusefilter-edit-builder-vars-movedto-age": "A céllap életkora (másodpercben)", "abusefilter-edit-builder-vars-user-editcount": "a szerkesztő szerkesztéseinek száma", - "abusefilter-edit-builder-vars-user-age": "a szerkesztő életkora", + "abusefilter-edit-builder-vars-user-age": "A felhasználó fiókjának életkora", "abusefilter-edit-builder-vars-user-name": "a szerkesztő neve", "abusefilter-edit-builder-vars-user-groups": "a szerkesztő csoportjai (beleértve az implicit csoportokat is)", "abusefilter-edit-builder-vars-user-rights": "Felhasználó jogai", @@ -282,23 +360,44 @@ "abusefilter-edit-builder-vars-user-emailconfirm": "az e-mail-cím megerősítésének ideje", "abusefilter-edit-builder-vars-recent-contributors": "a lap utolsó tíz szerkesztője", "abusefilter-edit-builder-vars-first-contributor": "Az első közreműködő ezen az oldalon", + "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "Az átnevezendő lap utolsó tíz szerkesztője", + "abusefilter-edit-builder-vars-movedfrom-first-contributor": "Az átnevezendő lap első közreműködője", + "abusefilter-edit-builder-vars-movedto-recent-contributors": "A céllap utolsó tíz szerkesztője", + "abusefilter-edit-builder-vars-movedto-first-contributor": "A céllap első közreműködője", "abusefilter-edit-builder-vars-all-links": "az új szövegben lévő összes hivatkozás", "abusefilter-edit-builder-vars-added-links": "hozzáadott hivatkozások", "abusefilter-edit-builder-vars-removed-links": "eltávolított hivatkozások", - "abusefilter-edit-builder-vars-old-text": "a régi wikiszöveg", - "abusefilter-edit-builder-vars-new-text": "az új wikiszöveg", - "abusefilter-edit-builder-vars-new-text-stripped": "az új wikiszöveg, jelölőnyelv nélkül", + "abusefilter-edit-builder-vars-old-wikitext": "A korábbi oldal wikiszövege a szerkesztés előtt", + "abusefilter-edit-builder-vars-new-wikitext": "Az új oldal wikiszövege szerkesztés után", + "abusefilter-edit-builder-vars-new-pst": "Az új oldal wikiszövege, mentés előtti állapotba alakítva", + "abusefilter-edit-builder-vars-diff-pst": "A szerkesztés során történt változások Unified diffje, mentés előtti állapotba alakítva", + "abusefilter-edit-builder-vars-addedlines-pst": "Szerkesztés során hozzáadott sorok, mentés előtti állapotba alakítva", + "abusefilter-edit-builder-vars-new-text": "az új wikiszöveg, jelölőnyelv nélkül", "abusefilter-edit-builder-vars-new-html": "az új változat HTML-lé alakított kódja", - "abusefilter-edit-builder-vars-restrictions-edit": "a lap védelmi szintje (szerkesztésnél)", - "abusefilter-edit-builder-vars-restrictions-move": "a lap védelmi szintje (átnevezésnél)", + "abusefilter-edit-builder-vars-restrictions-edit": "A lap védelmi szintje (szerkesztésnél)", + "abusefilter-edit-builder-vars-restrictions-move": "A lap védelmi szintje (átnevezésnél)", "abusefilter-edit-builder-vars-restrictions-create": "a lap védelmi szintje (létrehozáskor)", "abusefilter-edit-builder-vars-restrictions-upload": "fájl védelmi szinte (feltöltéskor)", - "abusefilter-edit-builder-vars-old-text-stripped": "A régi lap szövege, jelölőnyelv nélkül", + "abusefilter-edit-builder-vars-movedfrom-restrictions-edit": "Az átnevezendő lap védelmi szintje (szerkesztésnél)", + "abusefilter-edit-builder-vars-movedfrom-restrictions-move": "Az átnevezendő lap védelmi szintje (átnevezésnél)", + "abusefilter-edit-builder-vars-movedfrom-restrictions-create": "Az átnevezendő lap védelmi szintje (létrehozáskor)", + "abusefilter-edit-builder-vars-movedfrom-restrictions-upload": "Az átnevezendő fájl védelmi szintje (feltöltéskor)", + "abusefilter-edit-builder-vars-movedto-restrictions-edit": "A céllap védelmi szintje (szerkesztésnél)", + "abusefilter-edit-builder-vars-movedto-restrictions-move": "A céllap védelmi szintje (átnevezésnél)", + "abusefilter-edit-builder-vars-movedto-restrictions-create": "A céllap védelmi szintje (létrehozáskor)", + "abusefilter-edit-builder-vars-movedto-restrictions-upload": "A célfájl védelmi szintje (feltöltéskor)", + "abusefilter-edit-builder-vars-old-text": "A régi lap szövege, jelölőnyelv nélkül", "abusefilter-edit-builder-vars-old-links": "Az oldal hivatkozásai a szerkesztés előtt", - "abusefilter-edit-builder-vars-old-html": "A régi oldal wikiszövege HTML-ben", - "abusefilter-edit-builder-vars-minor-edit": "Apró változtatás?", + "abusefilter-edit-builder-vars-old-html": "A korábbi oldal wikiszövege HTML-ben (már nincs használatban)", + "abusefilter-edit-builder-vars-minor-edit": "Apró változtatás? (már nincs használatban)", "abusefilter-edit-builder-vars-file-sha1": "A fájl tartalmának SHA1 hash-se", "abusefilter-edit-builder-vars-file-size": "A fájl mérete bájtokban", + "abusefilter-edit-builder-vars-file-mime": "a fájl MIME-típusa", + "abusefilter-edit-builder-vars-file-mediatype": "a fájl médiatípusa", + "abusefilter-edit-builder-vars-file-width": "A fájl szélessége pixelben", + "abusefilter-edit-builder-vars-file-height": "A fájl magassága pixelben", + "abusefilter-edit-builder-vars-wiki-name": "Wiki adatbázisneve", + "abusefilter-edit-builder-vars-wiki-language": "Wiki nyelvkódja", "abusefilter-filter-log": "Friss változtatások a szűrőkön", "abusefilter-history": "A(z) $1 azonosítójú szűrő módosításainak előzménye", "abusefilter-history-foruser": "$1 módosításai", @@ -317,6 +416,7 @@ "abusefilter-history-filterid": "Szűrő", "abusefilter-history-select-legend": "Keresés szűkítése", "abusefilter-history-select-user": "Szerkesztő:", + "abusefilter-history-select-filter": "Szűrő azonosítója:", "abusefilter-history-select-submit": "Szűkítés", "abusefilter-history-diff": "Változások", "abusefilter-history-error-hidden": "A kért szűrő rejtett, ezért az előzményeket nem nézheted meg.", @@ -327,14 +427,17 @@ "abusefilter-exception-unclosedstring": "Lezáratlan sztring kezdődik a(z) $1. karaktertől.", "abusefilter-exception-invalidoperator": "Érvénytelen operátor („$2”) a(z) $1. karakternél.", "abusefilter-exception-unrecognisedtoken": "Érvénytelen token („$2”) a(z) $1. karakternél.", - "abusefilter-exception-noparams": "Nem lett átadva paraméter a(z) „$2” függvény számára a(z) $1. karakternél.", + "abusefilter-exception-noparams": "Nem lett átadva paraméter a(z) „$2” függvény számára a(z) $1. karakternél.\nVárt argumentumok száma: $3.", "abusefilter-exception-dividebyzero": "$2 nullával való osztása a(z) $1. karakternél.", "abusefilter-exception-unrecognisedvar": "Ismeretlen változó ($2) a(z) $1. karakternél", "abusefilter-exception-notenoughargs": "A(z) $1 karakternél meghívott $2 függvénynek nincsen elég argumentuma: $3 helyett $4 van.", - "abusefilter-exception-regexfailure": "A(z) „$3” regex hibás a(z) $1. karakternél: „$2”", + "abusefilter-exception-regexfailure": "Hiba a reguláris kifejezés $1. karakterénél: „$2”", "abusefilter-exception-overridebuiltin": "A(z) $1. karakternél a „$2” beépített változó felülírása nem engedélyezett.", "abusefilter-exception-outofbounds": "A(z) $1. karakternél nem létező, $2. számú listatagra található hivatkozás, de az egész lista csak $3 hosszú.", "abusefilter-exception-notarray": "A(z) $1. karakternél a függvény tömbbe nem tartozó tömbtagot kér.", + "abusefilter-exception-unclosedcomment": "Lezáratlan komment a(z) $1. számú karakternél.", + "abusefilter-exception-invalidiprange": "Érvénytelen IP-tartomány („$2”) a(z) $1. karakternél.", + "abusefilter-exception-disabledvar": "A(z) $2 változó a(z) $1. karakternél már nincs használatban.", "abusefilter-action-tag": "felcímkézés", "abusefilter-action-throttle": "Szerkesztési sebesség", "abusefilter-action-warn": "figyelmeztetés", @@ -345,13 +448,14 @@ "abusefilter-action-disallow": "Megtagadás", "abusefilter-revert-title": "A(z) $1. szűrő által okozott változtatások visszavonása", "abusefilter-revert-intro": "Ez az űrlap lehetővé teszi számodra, hogy visszaállíts minden olyan változtatást, amit a vandálszűrő hajtott végre a(z) $1. szűrő alapján.\nBánj óvatosan az eszköz használatakor.", - "abusefilter-revert-preview-item": "$1: $2 a $4 lapon ($3)\nVisszavonásra váló műveletek: $5 ($6)", + "abusefilter-revert-preview-item": "$1: $2 $3 műveletet {{GENDER:$7|végzett}} a(z) $4 lapon.\nVisszavonásra váró műveletek: $5 ($6)", "abusefilter-revert-search-legend": "Visszavonandó vandálszűrő műveletek kiválasztása", "abusefilter-revert-periodstart": "Időszak kezdete:", "abusefilter-revert-periodend": "Időszak vége:", "abusefilter-revert-search": "Műveletek kiválasztása", - "abusefilter-revert-filter": "Szűrő:", + "abusefilter-revert-filter": "Szűrő azonosítója:", "abusefilter-revert-preview-intro": "Ez a művelet a vandálszűrő alábbi műveleteit fogja visszavonni.\nAlaposan nézd át, hogy mi fog történni, és csak utána kattints a „{{int:abusefilter-revert-confirm}}” gombra.", + "abusefilter-revert-confirm-legend": "Visszaállítás megerősítése", "abusefilter-revert-confirm": "Megerősítés", "abusefilter-revert-success": "A(z) [[Special:AbuseFilter/$1|$2 szűrő]] miatt visszavontad a vandálszűrő összes műveletét.", "abusefilter-revert-reason": "A(z) $1 szűrő miatt a vandálszűrő összes művelete automatikus visszavonásra kerül.\nIndoklás: $2", @@ -363,12 +467,20 @@ "abusefilter-test-submit": "Na mutasd!", "abusefilter-test-load": "Betöltés", "abusefilter-test-user": "Szerkesztő változtatásai:", + "abusefilter-test-nobots": "Botszerkesztések elrejtése", "abusefilter-test-period-start": "Ez utáni változtatások:", "abusefilter-test-period-end": "Ez előtti változtatások:", "abusefilter-test-page": "Az oldal változtatásai:", "abusefilter-test-shownegative": "A szűrőn fenn nem akadt változtatások megmutatása", "abusefilter-test-syntaxerr": "A beírt szűrőd szintaktikai hibát tartalmaz.\nA hiba részletes leírásához kattints az „{{int:abusefilter-edit-check}}” gombra.", "abusefilter-test-badtitle": "A megadott cím érvénytelen. Egy vagy több olyan karaktert tartalmaz, amely nem lehet címben.", + "abusefilter-test-action": "Művelet típusa:", + "abusefilter-test-search-type-all": "Minden művelet", + "abusefilter-test-search-type-edit": "Szerkesztések", + "abusefilter-test-search-type-move": "Átnevezések", + "abusefilter-test-search-type-delete": "Törlések", + "abusefilter-test-search-type-upload": "Feltöltések", + "abusefilter-test-search-type-createaccount": "Felhasználói fiókok létrehozása", "abusefilter-changeslist-examine": "megvizsgál", "abusefilter-examine": "Egyedi változtatások megvizsgálása", "abusefilter-examine-intro": "Ezen az oldalon megnézheted, hogy a vandálszűrő egy adott változtatásra milyen változókat generál, majd ezeket átfuttathatod a szűrőkön.", @@ -388,13 +500,15 @@ "abusefilter-examine-noresults": "A megadott keresési paraméterre nincsen eredmény.", "abusefilter-topnav": "'''Vandálszűrő navigáció'''", "abusefilter-topnav-home": "Főoldal", + "abusefilter-topnav-recentchanges": "Friss változtatások a szűrőkön", "abusefilter-topnav-test": "Kötegelt vizsgálatok", "abusefilter-topnav-examine": "Korábbi szerkesztések megvizsgálása", "abusefilter-topnav-log": "Vandálszűrő naplója", "abusefilter-topnav-tools": "Hibakereső eszközök", - "abusefilter-topnav-import": "Szűrő importálása", "abusefilter-log-name": "Vandálszűrő naplója", "abusefilter-log-header": "Ebben a naplóban a szűrőkön végzett változtatások története található. A részletekhez lásd [[Special:AbuseFilter/history|a friss szűrőváltoztatások]] oldalát.", + "abusefilter-logentry-create": "$1 {{GENDER:$2|létrehozta}}: $4 ($5)", + "abusefilter-logentry-modify": "$1 {{GENDER:$2|módosította}}: $4 ($5)", "abusefilter-log-noresults": "Nincs találat", "abusefilter-diff-title": "Változatok közötti különbségek", "abusefilter-diff-item": "Tétel", @@ -407,6 +521,16 @@ "abusefilter-diff-next": "Újabb változás", "abusefilter-import-intro": "Ezen a felületen más wikikben készült szűrőket lehet importálni.\nA forráswikin a „{{int:abusefilter-edit-tools}}” alatt kattints az „{{int:abusefilter-edit-export}}” gombra.\nA megjelent szövegdoboz tartalmát ebbe a szövegdobozba másold át, majd kattints az „{{int:abusefilter-import-submit}}” gombra.", "abusefilter-import-submit": "Adatok importálása", + "abusefilter-import-invalid-data": "Az általad importálni próbált adat érvénytelen", "abusefilter-group-default": "Alapértelmezett", - "abusefilter-http-error": "HTTP hiba történt: $1" + "abusefilter-http-error": "HTTP hiba történt: $1", + "abusefilter-view-privatedetails-submit": "Privát részletek megtekintése", + "abusefilter-view-privatedetails-legend": "Privát részletek megtekintése", + "abusefilter-view-privatedetails-reason": "Privát részletekhez való hozzáférés oka:", + "abusefilter-log-details-id": "Naplóazonosító", + "abusefilter-noreason": "Figyelmeztetés: ezen naplóbejegyzés privát részleteihez való hozzáféréshez indoklást kell megadnod.", + "abusefilter-log-ip-not-available": "Nem elérhető", + "abusefilter-tag-reserved": "Az <code>abusefilter-condition-limit</code> címke a Vandálszűrő belső használatára van fenntartva.", + "tag-abusefilter-condition-limit": "feltételhatár elérve", + "tag-abusefilter-condition-limit-description": "Szerkesztések vagy egyéb események, amelyek nem lettek ellenőrizve az összes aktív [[Special:AbuseFilter|Vandálszűrő]] által ([[mw:Extension:AbuseFilter/Conditions|segítség]])." } diff --git a/AbuseFilter/i18n/hy.json b/AbuseFilter/i18n/hy.json index 8a544924..0774e755 100644 --- a/AbuseFilter/i18n/hy.json +++ b/AbuseFilter/i18n/hy.json @@ -1,10 +1,61 @@ { "@metadata": { "authors": [ + "Kareyac", "Vadgt", "Xelgen" ] }, "abusefilter-disallowed": "Այս գործողությունը կանխվեց ավտոմատ համակարգի կողմից, որպես վնասակար։\nԵթե կարծում եք, որ Ձեր կատարած գործողությունը կառուցողական է, խնդրում ենք ադմինիստրատորներից մեկին տեղյակ պահել, թե ինչ էիք մտադիր անել։ \nԿանոնի հակիրճ նկարագրությունը հետևյալն է՝ $1", - "abusefilter-edit-notes": "Նշումներ՝" + "abusefilter-log-search-user": "Մասնակից.", + "abusefilter-log-search-wiki": "Վիքի.", + "abusefilter-log-search-action-other": "Այլ", + "abusefilter-log-search-submit": "Որոնել", + "abusefilter-log-detailslink": "մանրամասներ", + "abusefilter-log-diff": "տարբ", + "abusefilter-log-hide-reason": "Պատճառ՝", + "abusefilter-list-status": "Կարգավիճակ", + "abusefilter-list-edit": "Խմբագրել", + "abusefilter-list-details": "Մանրամասներ", + "abusefilter-deleted": "Ջնջված", + "abusefilter-list-options-submit": "Թարմացնել", + "abusefilter-tools-reautoconfirm-user": "Մասնակից.", + "abusefilter-edit-status-label": "Վիճակագրություն՝", + "abusefilter-edit-new": "Նոր զտիչ", + "abusefilter-edit-save": "Հիշել զտիչը", + "abusefilter-edit-id": "Զտիչի ID՝", + "abusefilter-edit-switch-editor": "Փոխել զտիչը", + "abusefilter-edit-field-description": "նկարագրություն", + "abusefilter-edit-group": "Զտիչի խումբը՝", + "abusefilter-edit-flags": "Դրոշներ՝", + "abusefilter-edit-notes": "Նշումներ՝", + "abusefilter-edit-throttle-groups-help": "Տես $1", + "abusefilter-throttle-page": "էջ", + "abusefilter-edit-history": "Պատմություն.", + "abusefilter-edit-tools": "Գործիքներ.", + "abusefilter-edit-builder-op-bool-and": "և (&)", + "abusefilter-edit-builder-op-bool-or": "կամ (|)", + "abusefilter-edit-builder-vars-action": "Գործողություն", + "abusefilter-edit-builder-vars-page-id": "Էջի ID-ն", + "abusefilter-history-hidden": "Թաքցված", + "abusefilter-history-timestamp": "ժամանակ", + "abusefilter-history-user": "Մասնակից", + "abusefilter-history-flags": "Դրոշներ", + "abusefilter-history-comments": "Մեկնաբանություններ", + "abusefilter-history-actions": "Գործողություններ", + "abusefilter-history-deleted": "Ջնջված", + "abusefilter-history-filterid": "Զտիչ", + "abusefilter-history-diff": "Փոփոխություններ", + "abusefilter-revert-confirm": "Հաստատել", + "abusefilter-revert-reasonfield": "Պատճառ՝", + "abusefilter-test-submit": "Ստուգել", + "abusefilter-test-load": "Բեռնել", + "abusefilter-test-search-type-edit": "Խմբագրումներ", + "abusefilter-examine-user": "Մասնակից.", + "abusefilter-examine-title": "Էջի վերնագիր.", + "abusefilter-examine-submit": "Որոնել", + "abusefilter-topnav-home": "Գլխավոր էջ", + "abusefilter-diff-item": "Տարր", + "abusefilter-diff-info": "Հիմնական տեղեկություններ", + "abusefilter-group-default": "Լռելյայն" } diff --git a/AbuseFilter/i18n/hyw.json b/AbuseFilter/i18n/hyw.json new file mode 100644 index 00000000..2dbb8f3a --- /dev/null +++ b/AbuseFilter/i18n/hyw.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "Kareyac" + ] + }, + "abusefilter-log-search-action-other": "Ուրիշ", + "abusefilter-log-search-action-any": "Որեւէ", + "abusefilter-log-search-submit": "Որոնել", + "abusefilter-list-edit": "Խմբագրել" +} diff --git a/AbuseFilter/i18n/ia.json b/AbuseFilter/i18n/ia.json index 835ff9cd..8e39928f 100644 --- a/AbuseFilter/i18n/ia.json +++ b/AbuseFilter/i18n/ia.json @@ -1,14 +1,15 @@ { "@metadata": { "authors": [ - "McDutchie", - "Matma Rex" + "Matma Rex", + "McDutchie" ] }, "abusefilter-desc": "Applica heuristicas automatic al modificationes.", - "abusefilter": "Configuration del filtros anti-abuso", - "abuselog": "Registro de abusos", + "abusefilter": "Gestion del filtro anti-abuso", + "abuselog": "Registro del filtro anti-abuso", "abusefilter-intro": "Benvenite al interfacie de gestion del filtro anti-abuso.\nLe filtro anti-abuso es un mechanismo automatic de software pro applicar heuristicas automatic a tote le actiones.\nIste interfacie monstra un lista de filtros definite, e permitte modificar los.", + "abusefilter-mustviewprivateoredit": "Pro motivos de securitate, solmente le usatores con le permission de vider le filtros anti-abuso private o modificar le filtros pote usar iste interfacie.", "abusefilter-warning": "'''Attention:''' Iste action ha essite automaticamente identificate como damnose.\nTote actiones non constructive essera rapidemente revertite,\ne le modification non constructive flagrante o repetite resultara in le blocada de tu conto o adresse IP.\nSi tu crede que iste action es constructive, tu pote submitter lo de novo pro confirmar lo.\nEcce un breve description del regula anti-abuso que detegeva tu action: $1", "abusefilter-disallowed": "Iste action ha essite automaticamente identificate como damnose,\ne per consequente es prohibite.\nSi tu crede que tu action esseva constructive, per favor informa un administrator de lo que tu tentava facer.\nUn breve description del regula anti-abuso correspondente a tu action es: $1", "abusefilter-blocked-display": "Iste action ha essite automaticamente identificate como nocive,\ne tu ha essite impedite de executar lo.\nIn addition, pro proteger {{SITENAME}}, tu conto de usator e tote le adresses IP associate ha essite blocate de facer modificationes.\nSi isto ha occurrite in error, per favor contacta un administrator.\nUn breve description del regula anti-abuso correspondente con tu action es: $1", @@ -17,12 +18,14 @@ "abusefilter-blocker": "Filtro anti-abuso", "abusefilter-blockreason": "Automaticamente blocate per le filtro anti-abuso. Description del regula correspondente: $1", "abusefilter-degroupreason": "Derectos automaticamente retirate per le filtro anti-abuso. Description del regula: $1", + "abusefilter-blockautopromotereason": "Autopromotion automaticamente differite per le filtro anti-abuso. Description del regula: $1", "abusefilter-accountreserved": "Le nomine de iste conto es reservate pro uso per le filtro anti-abuso.", - "right-abusefilter-modify": "Modificar filtros anti-abuso", + "right-abusefilter-modify": "Crear o modificar filtros anti-abuso", "right-abusefilter-view": "Vider filtros anti-abuso", "right-abusefilter-log": "Vider le registro de abusos", "right-abusefilter-log-detail": "Vider entratas detaliate del registro de abusos", - "right-abusefilter-private": "Vider datos private in le registro de abusos", + "right-abusefilter-privatedetails": "Vider datos private in le registro de abusos", + "right-abusefilter-privatedetails-log": "Vider le registro de accesso a datos private del filtro anti-abuso", "right-abusefilter-modify-restricted": "Modificar le filtros anti-abuso con actiones restringite", "right-abusefilter-revert": "Reverter tote le modificationes facite per un filtro anti-abuso specific", "right-abusefilter-view-private": "Vider filtros anti-abuso marcate como private", @@ -34,22 +37,37 @@ "action-abusefilter-view": "vider le filtros anti-abuso", "action-abusefilter-log": "vider le registro de abusos", "action-abusefilter-log-detail": "vider entratas in detalio del registro de abusos", - "action-abusefilter-private": "vider datos private in le registro de abusos", + "action-abusefilter-privatedetails": "vider datos private in le registro de abusos", + "action-abusefilter-privatedetails-log": "vider le registro de accesso a datos private del filtro anti-abuso", "action-abusefilter-modify-restricted": "modificar le filtros anti-abuso con actiones restringite", "action-abusefilter-revert": "reverter tote le modificationes facite per un filtro anti-abuso specific", "action-abusefilter-view-private": "vider filtros anti-abuso marcate como private", "action-abusefilter-log-private": "vider registros de filtros anti-abuso marcate como private", - "abusefilter-log": "Registro del filtro anti-abuso", + "action-abusefilter-hide-log": "celar entratas in le registro de abusos", + "action-abusefilter-hidden-log": "vider entratas celate del registro de abusos", + "action-abusefilter-modify-global": "crear o modificar filtros anti-abuso global", "abusefilter-log-summary": "Iste registro monstra un lista de tote le actiones attrappate per le filtros anti-abuso.", "abusefilter-log-search": "Cercar in le registro de abusos", "abusefilter-log-search-user": "Usator:", - "abusefilter-log-search-filter": "IDs de filtro (separar con barras vertical):", + "abusefilter-log-search-group": "Gruppo de filtros:", + "abusefilter-log-search-group-any": "Qualcunque", + "abusefilter-log-search-filter": "IDs de filtro:", + "abusefilter-log-search-filter-help": "Separar con barras vertical, prefixar \"$1\" pro filtros global", "abusefilter-log-search-title": "Titulo:", "abusefilter-log-search-wiki": "Wiki:", + "abusefilter-log-search-impact": "Impacto:", + "abusefilter-log-search-impact-all": "Tote le actiones", + "abusefilter-log-search-impact-saved": "Modificationes salveguardate solmente", + "abusefilter-log-search-impact-not-saved": "Sin modificationes salveguardate", "abusefilter-log-search-entries-label": "Visibilitate:", "abusefilter-log-search-entries-all": "Tote le entratas", "abusefilter-log-search-entries-hidden": "Solmente entratas celate", "abusefilter-log-search-entries-visible": "Solmente entratas visibile", + "abusefilter-log-search-action-label": "Action que ha activate le filtro:", + "abusefilter-log-search-action-other": "Altere", + "abusefilter-log-search-action-any": "Qualcunque", + "abusefilter-log-search-action-taken-label": "Action prendite:", + "abusefilter-log-search-action-taken-any": "Qualcunque", "abusefilter-log-search-submit": "Cercar", "abusefilter-log-entry": "$1: $2 {{GENDER:$8|ha provocate}} un filtro anti-abuso, {{GENDER:$8|executante}} le action \"$3\" sur $4.\nActiones prendite: $5;\nDescription del filtro: $6", "abusefilter-log-entry-withdiff": "$1: $2 {{GENDER:$8|ha provocate}} un filtro anti-abuso, {{GENDER:$8|executante}} le action \"$3\" sur $4\nActiones prendite: $5;\nDescription del filtro: $6 ($7)", @@ -63,30 +81,46 @@ "abusefilter-log-details-var": "Variabile", "abusefilter-log-details-val": "Valor", "abusefilter-log-details-vars": "Parametros del action", - "abusefilter-log-details-private": "Detalios private del registro", + "abusefilter-log-details-privatedetails": "Detalios private del registro", "abusefilter-log-details-ip": "Adresse IP de origine", + "abusefilter-log-details-checkuser": "Verificar usator", "abusefilter-log-noactions": "nihil", "abusefilter-log-details-diff": "Modificationes effectuate", "abusefilter-log-linkoncontribs": "registro de abusos", "abusefilter-log-linkoncontribs-text": "Registro del abusos de {{GENDER:$1|iste usator}}", - "abusefilter-log-hidden": "(entrata celate)", + "abusefilter-log-linkonhistory": "vider le registro de abusos", + "abusefilter-log-linkonhistory-text": "Vider le registro de abusos pro iste pagina", + "abusefilter-log-linkonundelete": "vider le registro de abusos", + "abusefilter-log-linkonundelete-text": "Vider le registro de abusos pro iste pagina", "abusefilter-log-hidden-implicit": "(celate perque le version ha essite delite)", "abusefilter-log-cannot-see-details": "Tu non ha le permission de vider le detalios de iste entrata.", + "abusefilter-log-cannot-see-privatedetails": "Tu non ha le permission de vider le detalios private de iste entrata.", "abusefilter-log-nonexistent": "Non existe un entrata con le ID fornite.", "abusefilter-log-details-hidden": "Tu non pote vider le detalios de iste entrata, proque illo es celate al vista del publico.", + "abusefilter-log-details-hidden-implicit": "Tu non pote vider le detalios de iste entrata perque su version associate es celate al vista del publico.", "abusefilter-log-private-not-included": "Un o plure IDs de filtro specificate es private. Pois que tu non es autorisate a vider le detalios de filtros private, iste filtros non ha essite cercate.", "abusefilter-log-hide-legend": "Celar entrata de registro", "abusefilter-log-hide-id": "ID del entrata:", "abusefilter-log-hide-hidden": "Celar iste entrata al vista del publico", "abusefilter-log-hide-reason": "Motivo:", + "abusefilter-log-hide-reason-other": "Motivo altere/additional:", "abusefilter-log-hide-forbidden": "Tu non ha le permission de celar\nentratas del registro de abusos.", "abusefilter-log-entry-suppress": "$1 {{GENDER:$2|ha celate}} $3", "abusefilter-log-entry-unsuppress": "$1 {{GENDER:$2|ha restaurate}} $3", "logentry-abusefilter-hit": "$1 {{GENDER:$2|ha provocate}} $4, exequente le action \"$5\" sur $3. Actiones prendite: $6 ($7)", + "log-action-filter-abusefilter": "Typo de cambio de filtro:", + "log-action-filter-abusefilter-create": "Creation de nove filtro", + "log-action-filter-abusefilter-modify": "Modification de filtro", "log-action-filter-suppress-abuselog": "Suppression de registro de abusos", - "abusefilter-management": "Gestion del filtro anti-abuso", + "log-action-filter-rights-blockautopromote": "Blocada de autopromotion", + "log-action-filter-rights-restoreautopromote": "Restauration de autopromotion", + "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|accedeva}} le detalios private de $3", + "logentry-rights-blockautopromote": "$1 {{GENDER:$2|blocava}} le autopromotion de {{GENDER:$4|$3}} pro un periodo de $5", + "logentry-rights-restoreautopromote": "$1 {{GENDER:$2|restaurava}} le possibilitate de autopromotion pro {{GENDER:$4|$3}}", + "abusefilterprivatedetails-log-name": "Registro de accesso al detalios private del filtro anti-abuso", "abusefilter-list": "Tote le filtros", "abusefilter-list-id": "ID del filtro", + "abusefilter-list-pattern": "Patrono", "abusefilter-list-status": "Stato", "abusefilter-list-public": "Description public", "abusefilter-list-consequences": "Consequentias", @@ -102,8 +136,10 @@ "abusefilter-enabled": "Activate", "abusefilter-deleted": "Delite", "abusefilter-disabled": "Disactivate", + "abusefilter-throttled": "limitate", "abusefilter-hitcount": "$1 {{PLURAL:$1|visita|visitas}}", "abusefilter-new": "Crear un nove filtro", + "abusefilter-import-button": "Importar filtro", "abusefilter-return": "Retornar al gestion de filtros", "abusefilter-status-global": "Global", "abusefilter-list-options": "Optiones", @@ -115,7 +151,17 @@ "abusefilter-list-options-scope-local": "Solmente regulas local", "abusefilter-list-options-scope-global": "Solmente regulas global", "abusefilter-list-options-scope-all": "Regulas local e global", + "abusefilter-list-options-further-options": "Altere optiones:", "abusefilter-list-options-hidedisabled": " Celar le filtros disactivate", + "abusefilter-list-options-hideprivate": "Celar filtros private", + "abusefilter-list-options-searchfield": "Cerca intra regulas:", + "abusefilter-list-options-searchpattern": "Inserer un patrono", + "abusefilter-list-options-searchoptions": "Modo de recerca:", + "abusefilter-list-options-search-like": "Consulta simple", + "abusefilter-list-options-search-rlike": "Expression regular", + "abusefilter-list-options-search-irlike": "Expression regular sin distinction inter majusculas e minusculas", + "abusefilter-list-invalid-searchmode": "Le modo de recerca specificate non es valide.", + "abusefilter-list-regexerror": "Un error ha occurrite durante le recerca: Error de syntaxe in expression regular", "abusefilter-list-options-submit": "Actualisar", "abusefilter-tools-text": "Ecce alcun instrumentos utile pro formular e corriger le filtros anti-abuso.", "abusefilter-tools-expr": "Verificator de expressiones", @@ -123,22 +169,26 @@ "abusefilter-tools-reautoconfirm": "Restaurar le stato autoconfirmate", "abusefilter-tools-reautoconfirm-user": "Usator:", "abusefilter-tools-reautoconfirm-submit": "Re-autoconfirmar", + "abusefilter-tools-restoreautopromote": "Autopromotion restaurate via le instrumentos del filtro anti-abuso.", "abusefilter-reautoconfirm-none": "Le stato autoconfirmate de iste {{GENDER:$1|usator|usatrice|usator}} non ha essite suspendite.", "abusefilter-reautoconfirm-notallowed": "Tu non es autorisate a restaurar le stato autonconfirmate.", "abusefilter-reautoconfirm-done": "Le stato autoconfirmate del conto ha essite restaurate", - "abusefilter-status": "Inter le ultime $1 {{PLURAL:$1|action|actiones}}, $2 ($3%) ha attingite le limite de $4 conditiones autorisate, e $5 ($6%) ha correspondite a un del filtros actualmente active.", + "abusefilter-status": "Inter le ultime $1 {{PLURAL:$1|action|actiones}}, $2 ($3%) ha attingite le limite de $4 conditiones autorisate, e $5 ($6%) ha essite detegite per al minus un del filtros actualmente active.", "abusefilter-edit": "Modificar filtro anti-abuso", "abusefilter-edit-subtitle": "Modification del filtro $1", "abusefilter-edit-subtitle-new": "Creation de filtro", + "abusefilter-edit-token-not-match": "Le modification non ha essite salveguardate! Per favor, salveguarda de novo.", "abusefilter-edit-oldwarning": "<strong>Tu modifica al momento un version ancian de iste filtro.\nLe statisticas monstrate es pro le version currente del filtro.\nSi tu immagazina tu modificationes, tu superscribera tote le modificationes facite post le version que tu modifica.</strong> •\n[[Special:AbuseFilter/history/$2|Retornar al historia de iste filtro]].", + "abusefilter-edit-oldwarning-view": "<strong>Tu vide un version ancian de iste filtro.\nLe statisticas citate es pro le version le plus recente del filtro.</strong> •\n[[Special:AbuseFilter/history/$2|Retornar al historia de iste filtro]].", "abusefilter-edit-status-label": "Statisticas:", - "abusefilter-edit-status": "Del ultime $1 {{PLURAL:$1|action|actiones}}, iste filtro ha correspondite a $2 ($3%).", - "abusefilter-edit-status-profile": "Del ultime $1 {{PLURAL:$1|action|actiones}}, iste filtro ha correspondite a $2 ($3%).\nIn media, su durata de execution es $4ms, e illo consume $5 {{PLURAL:$5|condition|conditiones}} ex le limite de conditiones.", + "abusefilter-edit-status": "Del ultime $1 {{PLURAL:$1|action|actiones}}, iste filtro ha correspondite a $2 ($3%).\nIn media, su durata de execution es $4ms, e illo consume $5 {{PLURAL:$5|condition|conditiones}} ex le limite de conditiones.", "abusefilter-edit-throttled-warning": "'''Attention:''' Iste filtro ha essite automaticamente marcate como nocive. Como mesura de securitate, le sequente actiones non essera exequite ($1). Per favor, revide e [[mw:Extension:AbuseFilter/Conditions|optimisa]] tu conditiones pro remover this restriction", "abusefilter-edit-new": "Nove filtro", "abusefilter-edit-save": "Salveguardar filtro", "abusefilter-edit-id": "ID del filtro:", + "abusefilter-edit-switch-editor": "Cambiar de editor", "abusefilter-edit-description": "Description:\n:''(visibile al publico)''", + "abusefilter-edit-field-description": "description", "abusefilter-edit-group": "Gruppo de filtros:", "abusefilter-edit-flags": "Bandieras:", "abusefilter-edit-enabled": "Activar iste filtro", @@ -146,6 +196,7 @@ "abusefilter-edit-hidden": "Celar del publico le detalios de iste filtro", "abusefilter-edit-global": "Filtro global", "abusefilter-edit-rules": "Conditiones:", + "abusefilter-edit-field-conditions": "conditiones", "abusefilter-edit-notes": "Notas:", "abusefilter-edit-lastmod": "Ultime modification del filtro:", "abusefilter-edit-lastmod-text": "$1 per $2", @@ -156,25 +207,53 @@ "abusefilter-edit-action-blockautopromote": "Revocar le stato autoconfirmate del usator", "abusefilter-edit-action-degroup": "Remover le usator de tote le gruppos privilegiate", "abusefilter-edit-action-block": "Blocar le usator e/o adresse IP de facer modificationes", + "abusefilter-edit-action-blocktalk": "Impedir que le usator e/o adresse IP modifica su proprie pagina de discussion", "abusefilter-edit-action-throttle": "Interprender actiones solmente si le usator excede un limite de frequentia", "abusefilter-edit-action-rangeblock": "Blocar le intervallo IP respective del qual le usator proveni.", "abusefilter-edit-action-tag": "Etiquettar le modification pro revision ulterior.", "abusefilter-edit-throttle-count": "Numero de actiones a permitter:", "abusefilter-edit-throttle-period": "Periodo de tempore (in secundas):", - "abusefilter-edit-throttle-groups": "Gruppar le limites de frequentia per:", + "abusefilter-edit-throttle-groups": "Gruppar limites per:", + "abusefilter-edit-throttle-groups-help": "Vide $1.", + "abusefilter-edit-throttle-groups-help-text": "le documentation sur mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Separar con commas pro unir con AND, e con saltos de linea pro unir con OR", + "abusefilter-edit-throttle-placeholder": "Separar con commas pro unir con AND, e inserer un a un pro unir con OR", + "abusefilter-throttle-ip": "Adresse IP", + "abusefilter-throttle-user": "conto de usator", + "abusefilter-throttle-range": "gamma /16", + "abusefilter-throttle-creationdate": "data de creation del conto", + "abusefilter-throttle-editcount": "numero de modificationes", + "abusefilter-throttle-site": "tote le sito", + "abusefilter-throttle-page": "pagina", + "abusefilter-throttle-none": "(nulle)", + "abusefilter-throttle-details": "Permitter $1 {{PLURAL:$1|action|actiones}} cata $2 {{PLURAL:$2|secunda|secundas}}, pro le gruppos: $3", "abusefilter-edit-warn-message": "Message de systema pro usar qua advertimento:", "abusefilter-edit-warn-other": "Altere message", - "abusefilter-edit-warn-other-label": "Nomine de pagina de un altere message:\n:''(sin prefixo MediaWiki)''", + "abusefilter-edit-warn-other-label": "Nomine de pagina de un altere message:\n:''(sin prefixo \"MediaWiki:\")''", "abusefilter-edit-warn-actions": "Actiones:", "abusefilter-edit-warn-preview": "Monstrar/Celar le previsualisation del message seligite", "abusefilter-edit-warn-edit": "Crear/modificar le messages seligite", + "abusefilter-edit-disallow-message": "Message de systema pro usar pro prohibir:", + "abusefilter-edit-disallow-other": "Altere message", + "abusefilter-edit-disallow-other-label": "Nomine de pagina de un altere message:\n:''(sin prefixo \"MediaWiki:\")''", + "abusefilter-edit-disallow-actions": "Actiones:", + "abusefilter-edit-disallow-preview": "Monstrar/Celar le previsualisation del message seligite", + "abusefilter-edit-disallow-edit": "Crear/modificar le messages seligite", "abusefilter-edit-tag-tag": "[[Special:Tags|Etiquettas]] a applicar:", + "abusefilter-edit-tag-placeholder": "Adder etiquettas (un a un, o separate per commas)", "abusefilter-edit-tag-hidden-placeholder": "Adder etiquettas (separate per commas)", + "abusefilter-edit-block-anon-durations": "Duration del blocada pro usatores anonyme:", + "abusefilter-edit-block-user-durations": "Duration del blocada pro usatores registrate:", + "abusefilter-block-anon": "Blocar usatores anonyme", + "abusefilter-block-user": "blocar usatores registrate", + "abusefilter-block-talk": "pagina de discussion blocate", "abusefilter-edit-denied": "Tu non pote vider le detalios de iste filtro, perque illo es celate al vista public.", "abusefilter-edit-main": "Parametros del filtro", "abusefilter-edit-done-subtitle": "Filtro modificate", "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Tu modificationes]] al [[Special:AbuseFilter/$1|filtro $3]] ha essite salveguardate.", "abusefilter-edit-badsyntax": "Il ha un error de syntaxe in le filtro que tu specificava. Le resultato del analysator syntactic esseva: <pre>$1</pre>", + "abusefilter-edit-missingfields": "Le sequente campos es obligatori e debe esser plenate: $1", + "abusefilter-edit-deleting-enabled": "Non es possibile marcar un filtro active como delite.", "abusefilter-edit-restricted": "Tu non pote modificar iste filtro, proque illo contine un o plus actiones restringite.\nPer favor demanda a un usator con le permission de adder actiones restringite de facer le modification pro te.", "abusefilter-edit-viewhistory": "Vider le historia de iste filtro", "abusefilter-edit-history": "Historia:", @@ -186,10 +265,18 @@ "abusefilter-edit-export": "Exportar iste filtro verso un altere wiki", "abusefilter-edit-syntaxok": "Nulle error de syntaxe detegite.", "abusefilter-edit-syntaxerr": "Error de syntaxe detegite: $1", + "abusefilter-edit-warn-leave": "Quitar le pagina causara le perdita de tote le modificationes que tu ha apportate a iste filtro.", "abusefilter-edit-bad-tags": "Un o plus del etiquettas que tu specificava non es valide.\nLe etiquettas debe esser curte, non debe continer characteres special, e non debe esser reservate per altere software. Essaya eliger un altere nomine de etiquetta.", "abusefilter-edit-notallowed": "Tu non ha le permission de crear o modificar filtros anti-abuso.", "abusefilter-edit-notallowed-global": "Tu non ha le permission de crear o modificar filtros anti-abuso global", - "abusefilter-edit-notallowed-global-custom-msg": "Messages de aviso personalisate non es supportate pro filtros global", + "abusefilter-edit-notallowed-global-custom-msg": "Messages personalisate de aviso o de prohibition non es supportate pro filtros global", + "abusefilter-edit-invalid-warn-message": "Le message de advertimento non pote esser lassate vacue.", + "abusefilter-edit-invalid-disallow-message": "Le message de prohibition non pote esser lassate vacue.", + "abusefilter-edit-invalid-throttlecount": "Le numero de actiones del limitator debe esser un numero integre positive.", + "abusefilter-edit-invalid-throttleperiod": "Le periodo de limitation debe esser un numero integre positive.", + "abusefilter-edit-empty-throttlegroups": "Al minus un gruppo de limitation debe esser seligite.", + "abusefilter-edit-duplicated-throttlegroups": "Le gruppos de limitation non pote haber duplicatos.", + "abusefilter-edit-invalid-throttlegroups": "Le gruppos de limitation specificate non es valide.", "abusefilter-edit-builder-select": "Selige un option pro inserer lo al puncto del cursor", "abusefilter-edit-builder-group-op-arithmetic": "Operatores arithmetic", "abusefilter-edit-builder-op-arithmetic-addition": "Addition (+)", @@ -200,7 +287,9 @@ "abusefilter-edit-builder-op-arithmetic-pow": "Potentia (**)", "abusefilter-edit-builder-group-op-comparison": "Operatores de comparation", "abusefilter-edit-builder-op-comparison-equal": "Valor equal a (==)", + "abusefilter-edit-builder-op-comparison-equal-strict": "Valor e typo equal a (===)", "abusefilter-edit-builder-op-comparison-notequal": "Valor non equal a (!=)", + "abusefilter-edit-builder-op-comparison-notequal-strict": "Valor e typo non equal a (!==)", "abusefilter-edit-builder-op-comparison-lt": "Minus que (<)", "abusefilter-edit-builder-op-comparison-gt": "Plus que (>)", "abusefilter-edit-builder-op-comparison-lte": "Minus que o equal a (<=)", @@ -217,29 +306,37 @@ "abusefilter-edit-builder-misc-contains": "Le catena sinistre contine le catena derecte (contains)", "abusefilter-edit-builder-misc-stringlit": "Serie litteral de characteres (\"\")", "abusefilter-edit-builder-misc-tern": "Operator ternari (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Conditional (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Conditional (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "Conditional curte (if X then Y end)", "abusefilter-edit-builder-group-funcs": "Functiones", "abusefilter-edit-builder-funcs-length": "Longor del serie de characteres (length)", "abusefilter-edit-builder-funcs-lcase": "Verso minusculas (lcase)", "abusefilter-edit-builder-funcs-ucase": "Verso majusculas (ucase)", "abusefilter-edit-builder-funcs-ccnorm": "Normalisa le characters confundibile (ccnorm)", + "abusefilter-edit-builder-funcs-ccnorm-contains-any": "Normalisar un catena de characteres e cercar in illo multiple subcatenas in modo \"O\" (ccnorm_contains_any)", + "abusefilter-edit-builder-funcs-ccnorm-contains-all": "Normalisar un catena de characteres e cercar in illo multiple subcatenas in modo \"E\" (ccnorm_contains_all)", "abusefilter-edit-builder-funcs-rmdoubles": "Elimina le characteres duple (rmdoubles)", "abusefilter-edit-builder-funcs-specialratio": "Characteres special / total del characteres (specialratio)", "abusefilter-edit-builder-funcs-norm": "Normalisa (norm)", "abusefilter-edit-builder-funcs-count": "Numero de vices que le serie de characteres X appare in le serie Y (count)", "abusefilter-edit-builder-funcs-rcount": "Numero de vices que le regex X appare in le catena de characteres Y (rcount)", + "abusefilter-edit-builder-funcs-get_matches": "Matrice de correspondentias regex intra un texto pro cata gruppo de captura (get_matches)", "abusefilter-edit-builder-funcs-rmwhitespace": "Remover spatio blanc (rmwhitespace)", "abusefilter-edit-builder-funcs-rmspecials": "Remover characteres special (rmspecials)", "abusefilter-edit-builder-funcs-ip_in_range": "Es le IP in le intervallo? (ip_in_range)", - "abusefilter-edit-builder-funcs-contains-any": "Cercar multiple subcatenas in catena (contains_any)", + "abusefilter-edit-builder-funcs-contains-any": "Cercar un de plure subcatenas in le catena. (contains_any)", + "abusefilter-edit-builder-funcs-contains-all": "Cercar in le catena multiple subcatenas in modo \"AND\". (contains_all)", + "abusefilter-edit-builder-funcs-equals-to-any": "Verificar si un argumento date es equal (===) a alcun del argumentos sequente (equals_to_any)", "abusefilter-edit-builder-funcs-substr": "Subcatena (substr)", "abusefilter-edit-builder-funcs-strpos": "Position del subcatena in le catena (strpos)", "abusefilter-edit-builder-funcs-str_replace": "Reimplaciar le subcatena per le catena (str_replace)", "abusefilter-edit-builder-funcs-rescape": "Escappar catena como litteral in expression regular (rescape)", "abusefilter-edit-builder-funcs-set_var": "Definir variabile (set_var)", + "abusefilter-edit-builder-funcs-sanitize": "Normalisar entitates HTML in characteres Unicode (sanitize)", "abusefilter-edit-builder-group-vars": "Variabiles", "abusefilter-edit-builder-vars-accountname": "Nomine del conto (al creation del conto)", "abusefilter-edit-builder-vars-timestamp": "Data e hora del modification in formato de Unix", + "abusefilter-edit-builder-vars-timestamp-expanded": "Data e hora del registro", "abusefilter-edit-builder-vars-action": "Action", "abusefilter-edit-builder-vars-addedlines": "Lineas addite durante le modification", "abusefilter-edit-builder-vars-delta": "Cambio del grandor durante le modification", @@ -274,24 +371,36 @@ "abusefilter-edit-builder-vars-user-emailconfirm": "Quando le adresse de e-mail esseva confirmate", "abusefilter-edit-builder-vars-recent-contributors": "Le ultime dece usatores que contribueva a iste pagina", "abusefilter-edit-builder-vars-first-contributor": "Le prime usator a contribuer al pagina", + "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "Le ultime dece usatores que contribueva a renominar le pagina de origine", + "abusefilter-edit-builder-vars-movedfrom-first-contributor": "Le prime usator que contribueva a renominar le pagina de origine", + "abusefilter-edit-builder-vars-movedto-recent-contributors": "Le ultime dece usatores que contribueva a renominar le pagina de destination", + "abusefilter-edit-builder-vars-movedto-first-contributor": "Le prime usator que contribueva a renominar le pagina de destination", "abusefilter-edit-builder-vars-all-links": "Tote le ligamines externe in le nove texto", "abusefilter-edit-builder-vars-added-links": "Tote le ligamines externe addite in le modification", "abusefilter-edit-builder-vars-removed-links": "Tote le ligamines externe eliminate in le modification", - "abusefilter-edit-builder-vars-old-text": "Le wikitexto ancian del pagina, ante le modification", - "abusefilter-edit-builder-vars-new-text": "Le wikitexto nove del pagina, post le modification", + "abusefilter-edit-builder-vars-old-wikitext": "Le wikitexto ancian del pagina, ante le modification", + "abusefilter-edit-builder-vars-new-wikitext": "Le wikitexto nove del pagina, post le modification", "abusefilter-edit-builder-vars-new-pst": "Wikitexto del nove pagina, transformate ante salveguarda", "abusefilter-edit-builder-vars-diff-pst": "Differentia unificate de cambiamentos per modification, transformate ante salveguarda", "abusefilter-edit-builder-vars-addedlines-pst": "Lineas addite in le modification, transformate ante salveguarda", - "abusefilter-edit-builder-vars-new-text-stripped": "Nove texto del pagina, disproviste de marcation", + "abusefilter-edit-builder-vars-new-text": "Nove texto del pagina, disproviste de marcation", "abusefilter-edit-builder-vars-new-html": "Codice-fonte del nove version transformate in HTML", "abusefilter-edit-builder-vars-restrictions-edit": "Nivello de protection pro le modification del pagina", "abusefilter-edit-builder-vars-restrictions-move": "Nivello de protection pro le renomination del pagina", "abusefilter-edit-builder-vars-restrictions-create": "Protection pro le creation del pagina", "abusefilter-edit-builder-vars-restrictions-upload": "Protection pro incargar le file", - "abusefilter-edit-builder-vars-old-text-stripped": "Le texto ancian del pagina, disfacite de omne notation", + "abusefilter-edit-builder-vars-movedfrom-restrictions-edit": "Modificar le nivello de protection del pagina de origine del renomination", + "abusefilter-edit-builder-vars-movedfrom-restrictions-move": "Displaciar le nivello de protection del pagina de origine del renomination", + "abusefilter-edit-builder-vars-movedfrom-restrictions-create": "Protection de creation del pagina de origine del renomination", + "abusefilter-edit-builder-vars-movedfrom-restrictions-upload": "Protection de incargamento del file de origine dle renomination", + "abusefilter-edit-builder-vars-movedto-restrictions-edit": "Nivello de protection de modification del pagina de destination del renomination", + "abusefilter-edit-builder-vars-movedto-restrictions-move": "Nivello de protection de renomination del pagina de destination del renomination", + "abusefilter-edit-builder-vars-movedto-restrictions-create": "Protection de creation del pagina de destination del renomination", + "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Protection de incargamento del file de destination del renomination", + "abusefilter-edit-builder-vars-old-text": "Le texto ancian del pagina, disfacite de omne notation (non plus in uso)", "abusefilter-edit-builder-vars-old-links": "Ligamines in le pagina, ante le modification", - "abusefilter-edit-builder-vars-old-html": "Le wikitexto ancian del pagina, convertite in HTML", - "abusefilter-edit-builder-vars-minor-edit": "Si le modification es marcate como minor", + "abusefilter-edit-builder-vars-old-html": "Le wikitexto ancian del pagina, convertite in HTML (non plus in uso)", + "abusefilter-edit-builder-vars-minor-edit": "Si le modification es marcate como minor (non plus in uso)", "abusefilter-edit-builder-vars-file-sha1": "Hash SHA1 del contento del file", "abusefilter-edit-builder-vars-file-size": "Dimension del file in bytes", "abusefilter-edit-builder-vars-file-mime": "Typo MIME del file", @@ -299,6 +408,8 @@ "abusefilter-edit-builder-vars-file-width": "Latitude del file in pixels", "abusefilter-edit-builder-vars-file-height": "Altitude del file in pixels", "abusefilter-edit-builder-vars-file-bits-per-channel": "Bits per canal de color del file", + "abusefilter-edit-builder-vars-wiki-name": "Nomine del wiki in le base de datos", + "abusefilter-edit-builder-vars-wiki-language": "Codice de lingua del wiki", "abusefilter-filter-log": "Modificationes recente de filtros", "abusefilter-history": "Historia de modificationes del filtro anti-abuso $1", "abusefilter-history-foruser": "Modificationes per $1", @@ -317,26 +428,33 @@ "abusefilter-history-filterid": "Filtro", "abusefilter-history-select-legend": "Affinar le recerca", "abusefilter-history-select-user": "Usator:", + "abusefilter-history-select-filter": "ID del filtro:", "abusefilter-history-select-submit": "Affinar", "abusefilter-history-diff": "Cambios", "abusefilter-history-error-hidden": "Le filtro que tu ha requestate es celate, e tu non pote vider su historia.", "abusefilter-exception-unexpectedatend": "\"$2\" non expectate al character $1.", "abusefilter-exception-expectednotfound": "Un $2 es expectate al character $1 ma non es trovate (trovava le $3 $4 in su loco).", "abusefilter-exception-unrecognisedkeyword": "Parola-clave $2 non recognoscite al character $1.", - "abusefilter-exception-unexpectedtoken": "Indicio non expectate \"$3\" (del typo $2) al character $1.", + "abusefilter-exception-unexpectedtoken": "Token non expectate \"$3\" (del typo $2) al character $1.", "abusefilter-exception-unclosedstring": "Catena de characteres non terminate a partir del character $1.", "abusefilter-exception-invalidoperator": "Operator invalide \"$2\" al character $1.", - "abusefilter-exception-unrecognisedtoken": "Indicio \"$2\" non recognoscite al character $1.", - "abusefilter-exception-noparams": "Nulle parametros passate al function \"$2\" al character $1.", + "abusefilter-exception-unrecognisedtoken": "Token \"$2\" non recognoscite al character $1.", + "abusefilter-exception-noparams": "Nulle parametros passate al function \"$2\" al character $1.\nSe expectava $3 {{PLURAL:$3|argumento|argumentos}}.", "abusefilter-exception-dividebyzero": "Tentativa incorrecte de divider $2 per zero al character $1.", "abusefilter-exception-unrecognisedvar": "Variabile non recognoscite $2 al character $1", "abusefilter-exception-notenoughargs": "Non satis de parametros pro le function $2 appellate al character $1.\nExpectava $3 {{PLURAL:$3|parametro|parametros}}, recipeva $4.", - "abusefilter-exception-regexfailure": "Error in le expression regular \"$3\" al character $1: \"$2\"", - "abusefilter-exception-overridebuiltin": "Supplantation invalide del variabile incorporate \"$2\" al character $1.", - "abusefilter-exception-outofbounds": "Requesta de un elemento de lista non existente $2 (grandor del lista = $3) al character $1.", + "abusefilter-exception-toomanyargs": "Troppo de parametros pro le function $2 appellate al character $1.\nExpectava un maximo de $3 {{PLURAL:$3|parametro|parametros}}, recipeva $4.", + "abusefilter-exception-regexfailure": "Error in le expression regular \"$2\" al character $1.", + "abusefilter-exception-overridebuiltin": "Impossibile supplantar le identificator interne \"$2\" al character $1.", + "abusefilter-exception-outofbounds": "Requesta de un elemento de array non existente $2 (dimension del array = $3) al character $1.", + "abusefilter-exception-negativeindex": "Le indices negative non es permittite in arrays. Indice \"$2\" incontrate al character $1.", "abusefilter-exception-notarray": "Requesta de un elemento de array ab un variabile non array al character $1.", + "abusefilter-exception-unclosedcomment": "Commento non claudite al character $1.", + "abusefilter-exception-invalidiprange": "Intervallo IP \"$2\" non valide al character $1.", + "abusefilter-exception-disabledvar": "Le variabile $2 al character $1 non es plus in uso.", + "abusefilter-exception-variablevariable": "set e set_var require que le prime argumento es un catena litteral, trovate al character $1.", "abusefilter-action-tag": "Etiquettar", - "abusefilter-action-throttle": "Limitar frequentia", + "abusefilter-action-throttle": "Limitator", "abusefilter-action-warn": "Advertir", "abusefilter-action-blockautopromote": "Blocar autopromotion", "abusefilter-action-block": "Blocar", @@ -350,8 +468,9 @@ "abusefilter-revert-periodstart": "Initio del periodo:", "abusefilter-revert-periodend": "Fin del periodo:", "abusefilter-revert-search": "Selige actiones", - "abusefilter-revert-filter": "Filtro:", + "abusefilter-revert-filter": "ID del filtro:", "abusefilter-revert-preview-intro": "Ecce le actiones interprendite per le filtro anti-abuso que essera revertite per iste action.\nPer favor verifica los conscientiosemente, e clicca sur \"{{int:abusefilter-revert-confirm}}\" pro confirmar tu selection.", + "abusefilter-revert-confirm-legend": "Confirmar le reversion", "abusefilter-revert-confirm": "Confirmar", "abusefilter-revert-success": "Tu ha revertite tote le actiones interprendite per le filtro anti-abuso secundo [[Special:AbuseFilter/$1|le filtro $2]].", "abusefilter-revert-reason": "Reversion automatic de tote le actiones interprendite per le filtro anti-abuso secundo le filtro $1.\nMotivo date: $2", @@ -363,12 +482,20 @@ "abusefilter-test-submit": "Testar", "abusefilter-test-load": "Cargar", "abusefilter-test-user": "Modificationes per le usator:", + "abusefilter-test-nobots": "Celar modificationes facite per robot", "abusefilter-test-period-start": "Modificationes facite post:", "abusefilter-test-period-end": "Modificationes facite ante:", "abusefilter-test-page": "Modificationes facite al pagina:", "abusefilter-test-shownegative": "Monstrar modificationes que non corresponde al filtro", "abusefilter-test-syntaxerr": "Le filtro inserite contine un error de syntaxe.\nPro reciper un explication complete, clicca sur le button \"{{int:abusefilter-edit-check}}\".", "abusefilter-test-badtitle": "Le titulo de pagina specificate non es valide. Illo contine forsan alcun characteres que non pote esser usate in titulos.", + "abusefilter-test-action": "Typo de action:", + "abusefilter-test-search-type-all": "Tote le actiones", + "abusefilter-test-search-type-edit": "Modificationes", + "abusefilter-test-search-type-move": "Renominationes", + "abusefilter-test-search-type-delete": "Deletiones", + "abusefilter-test-search-type-upload": "Incargamentos", + "abusefilter-test-search-type-createaccount": "Creationes de contos", "abusefilter-changeslist-examine": "examinar", "abusefilter-examine": "Examinar modificationes individual", "abusefilter-examine-intro": "Iste pagina permitte examinar le variabiles generate per le filtro anti-abuso pro un modification individual, e testar lo contra le filtros.", @@ -388,13 +515,16 @@ "abusefilter-examine-noresults": "Nulle resultato ha essite trovate pro le parametros de recerca que tu ha fornite.", "abusefilter-topnav": "'''Navigation per le filtro anti-abuso'''", "abusefilter-topnav-home": "Initio", + "abusefilter-topnav-recentchanges": "Modificationes recente de filtros", "abusefilter-topnav-test": "Test in serie", "abusefilter-topnav-examine": "Examinar modificationes precedente", "abusefilter-topnav-log": "Registro de abusos", "abusefilter-topnav-tools": "Instrumentos pro reparar defectos", - "abusefilter-topnav-import": "Importar filtro", "abusefilter-log-name": "Registro del filtro anti-abuso", "abusefilter-log-header": "Iste registro monstra un summario del modificationes facite al filtros.\nPro detalios complete, vide [[Special:AbuseFilter/history|le lista]] de cambios recente al filtros.", + "abusefilter-logentry-create": "$1 {{GENDER:$2|creava}} $4 ($5)", + "abusefilter-logentry-modify": "$1 {{GENDER:$2|modificava}} $4 ($5)", + "abusefilter-log-invalid-filter": "Alcunes del IDs de filtro specificate es invalide.", "abusefilter-log-noresults": "Nulle resultato", "abusefilter-diff-title": "Differentias inter versiones", "abusefilter-diff-item": "Entrata", @@ -407,6 +537,19 @@ "abusefilter-diff-next": "Cambiamento sequente", "abusefilter-import-intro": "Iste interfacie es pro importar filtros ex altere wikis.\nIn le wiki de origine, clicca \"{{int:abusefilter-edit-export}}\" sub \"{{int:abusefilter-edit-tools}}\" in le interfacie de modification.\nCopia le contento del quadro de texto que appare, e colla lo in iste quadro de texto, pois clicca \"{{int:abusefilter-import-submit}}\".", "abusefilter-import-submit": "Importar datos", + "abusefilter-import-invalid-data": "Le datos que tu tentava importar non es valide", "abusefilter-group-default": "Predefinite", - "abusefilter-http-error": "Un error HTTP occurreva: $1." + "abusefilter-http-error": "Un error HTTP occurreva: $1.", + "abusefilter-view-privatedetails-submit": "Vider detalios private", + "abusefilter-view-privatedetails-legend": "Vider detalios private", + "abusefilter-view-privatedetails-reason": "Motivo pro acceder al detalios private:", + "abusefilter-log-details-id": "ID de registro", + "abusefilter-invalid-request": "Requesta invalide! Tu debe acceder al detalios private del registro per medio del formulario sur [[Special:AbuseLog/$1]] e fornir un motivo.", + "abusefilter-invalid-request-noid": "Requesta invalide! Tu debe acceder al detalios private del registro per medio del formulario sur le pagina de detalios del registro de abusos e fornir un motivo.", + "log-description-abusefilterprivatedetails": "Iste registro monstra un lista de accessos de un usator al detalios private de un registro de abusos.", + "abusefilter-noreason": "Attention: Pro vider le detalios private de iste registro, tu debe fornir un motivo.", + "abusefilter-log-ip-not-available": "Non disponibile", + "abusefilter-tag-reserved": "Le etiquetta <code>abusefilter-condition-limit</code> es reservate pro uso interne per AbuseFilter.", + "tag-abusefilter-condition-limit": "limite de conditiones attingite", + "tag-abusefilter-condition-limit-description": "Modificationes o altere eventos que non poteva esser verificate per tote le [[Special:AbuseFilter|filtros anti-abuso]] active ([[mw:Extension:AbuseFilter/Conditions|adjuta]])." } diff --git a/AbuseFilter/i18n/id.json b/AbuseFilter/i18n/id.json index 7f6b0313..f7177a24 100644 --- a/AbuseFilter/i18n/id.json +++ b/AbuseFilter/i18n/id.json @@ -1,27 +1,36 @@ { "@metadata": { "authors": [ + "Aldnonymous", + "Arifin.wijaya", + "ArlandGa", "Bennylin", + "C5st4wr6ch", + "Diki Ananta", "Farras", + "Fitoschido", + "Hidayatsrf", "Irwangatot", "IvanLanin", "Iwan Novirion", + "J Nia30", "Kenrick95", - "Rex", - "Rv77ax", - "C5st4wr6ch", - "Arifin.wijaya", "Matma Rex", + "Pebaryan", "Rachmat.Wahidi", "Rachmat04", - "Hidayatsrf" + "Rex", + "Rv77ax", + "Sumbukompor", + "Veracious" ] }, "abusefilter-desc": "Memberlakukan pemeriksaan heuristik otomatis atas kontribusi pengguna.", - "abusefilter": "Konfigurasi filter penyalahgunaan", - "abuselog": "Catatan penyalahgunaan", + "abusefilter": "Manajemen filter penyalahgunaan", + "abuselog": "Catatan filter penyalahgunaan", "abusefilter-intro": "Selamat datang di antarmuka pengelola Filter Penyalahgunaan.\nFilter Penyalahgunaan adalah sebuah mekanisme perangkat lunak yang mengaplikasikan heuristik otomatis terhadap semua tindakan. Antarmuka ini menampilkan sebuah daftar filter yang telah ditetapkan, dan filter-filter ini dapat dimodifikasi.", - "abusefilter-warning": "'''Peringatan''': Tindakan ini secara otomatis telah diidentifikasi sebagai tindakan yang merusak.\nSuntingan yang tidak bermanfaat akan segera dibatalkan,\ndan suntingan yang tidak jelas serta berulang-ulang akan berakibat dengan diblokirnya akun ataupun alamat IP Anda.\nJika Anda yakin bahwa suntingan anda adalah suntingan yang bermanfaat, Anda bisa mengklik Kirim sekali lagi untuk mengkonfirmasinya.\nKeterangan singkat tentang peraturan penyalahgunaan yang berkaitan dengan tindakan Anda adalah: $1", + "abusefilter-mustviewprivateoredit": "Demi alasan keamanan, hanya pengguna-pengguna dengan hak untuk melihat atau mengubah filter penyalahgunaan pribadi yang dapat menggunakan antarmuka ini.", + "abusefilter-warning": "'''Peringatan''': Tindakan ini secara otomatis telah diidentifikasi sebagai tindakan yang merusak.\nTindakan yang takkonstruktif akan segera dipulihkan,\ndan suntingan yang tidak jelas serta berulang-ulang akan mengakibatkan akun atau alamat IP Anda diblokir.\nJika Anda yakin bahwa tindakan ini konstruktif, Anda bisa mengajukannya sekali lagi untuk mengonfirmasinya.\nKeterangan singkat tentang peraturan penyalahgunaan yang berkaitan dengan tindakan Anda yakni: $1", "abusefilter-disallowed": "Aksi ini secara otomatis telah diidentifikasi sebagai tindakan yang merusak,\ndan karenanya ditolak.\nJika Anda yakin bahwa suntingan anda adalah suntingan yang bermanfaat, silakan hubungi pengurus, dan informasikan apa yang sedang Anda lakukan.\nKeterangan singkat tentang peraturan penyalahgunaan yang berkaitan dengan aksi Anda adalah: $1", "abusefilter-blocked-display": "Tindakan ini secara otomatis telah diidentifikasi sebagai tindakan yang merusak,\ndan sistem telah mencegah tindakan anda tersebut.\nSebagai tambahan, untuk melindungi {{SITENAME}}, akun pengguna anda dan semua alamat IP yang terkait telah diblokir.\nJika menurut anda ini terjadi karena kesalahan, silakan hubungi pengurus.\nKeterangan singkat tentang peraturan penyalahgunaan yang berkaitan dengan tindakan anda adalah: $1", "abusefilter-degrouped": "Tindakan ini secara otomatis telah diidentifikasi sebagai tindakan yang merusak.\nKonsekuensinya, tindakan ini telah ditolak, dan karena akun anda dianggap mencurigakan, semua hak akses anda telah dicabut.\nJika anda yakin bahwa ini adalah kesalahan, silahkan hubungi seorang birokrat guna menjelaskan tindakan anda, dan kemungkinan hak-hak anda dapat dipulihkan.\nKeterangan singkat tentang peraturan penyalahgunaan yang berkaitan dengan tindakan anda adalah: $1", @@ -30,11 +39,11 @@ "abusefilter-blockreason": "Diblokir secara otomatis oleh filter penyalahgunaan.\nKeterangan mengenai peraturan terkait: $1", "abusefilter-degroupreason": "Hak akses telah dicabut secara otomatis oleh filter penyalahgunaan.\nKeterangan mengenai peraturan terkait: $1", "abusefilter-accountreserved": "Nama akun ini telah dicadangkan untuk digunakan oleh filter penyalahgunaan.", - "right-abusefilter-modify": "Memodifikasi filter penyalahgunaan", + "right-abusefilter-modify": "Membuat atau memodifikasi filter penyalahgunaan", "right-abusefilter-view": "Menampilkan filter penyalahgunaan", "right-abusefilter-log": "Menampilkan catatan penyalahgunaan", "right-abusefilter-log-detail": "Menampilkan entri catatan penyalahgunaan secara rinci", - "right-abusefilter-private": "Menampilkan data pribadi dalam catatan penyalahgunaan", + "right-abusefilter-privatedetails": "Menampilkan data pribadi dalam catatan penyalahgunaan", "right-abusefilter-modify-restricted": "Memodifikasi filter penyalahgunaan dengan tindakan terbatas", "right-abusefilter-revert": "Mengembalikan semua perubahan yang dilakukan oleh suatu filter penyalahgunaan yang ditentukan", "right-abusefilter-view-private": "Lihat penyaringan penyalahgunaan yang ditandai sebagai pribadi", @@ -46,17 +55,33 @@ "action-abusefilter-view": "tampilkan filter penyalahgunaan", "action-abusefilter-log": "tampilkan catatan penyalahgunaan", "action-abusefilter-log-detail": "tampilkan entri catatan penyalahgunaan secara rinci", - "action-abusefilter-private": "tampilkan data privat dalam catatan penyalahgunaan", + "action-abusefilter-privatedetails": "tampilkan data privat dalam catatan penyalahgunaan", "action-abusefilter-modify-restricted": "modifikasi filter penyalahgunaan dengan tindakan terbatas", "action-abusefilter-revert": "kembalikan semua perubahan dengan filter penyalahgunaan yang berikan.", "action-abusefilter-view-private": "lihat filter penyalahgunaan ditandai sebagai pribadi", - "abusefilter-log": "Catatan filter penyalahgunaan", + "action-abusefilter-hide-log": "sembunyikan entri dalam catatan penyalahgunaan", + "action-abusefilter-hidden-log": "lihat entri catatan penyalahgunaan tersembunyi", + "action-abusefilter-modify-global": "buat atau ubah filter penyalahgunaan global", "abusefilter-log-summary": "Catatan ini menampilkan daftar tindakan yang ditangkap oleh filter penyalahgunaan.", "abusefilter-log-search": "Pencarian catatan penyalahgunaan", "abusefilter-log-search-user": "Pengguna:", - "abusefilter-log-search-filter": "ID filter (pisahkan dengan tanda pipa):", + "abusefilter-log-search-group-any": "Apa saja", + "abusefilter-log-search-filter": "ID filter:", "abusefilter-log-search-title": "Judul:", "abusefilter-log-search-wiki": "Wiki:", + "abusefilter-log-search-impact": "Dampak:", + "abusefilter-log-search-impact-all": "Semua aksi", + "abusefilter-log-search-impact-saved": "Hanya menyimpan perubahan", + "abusefilter-log-search-impact-not-saved": "Tanpa menyimpan perubahan", + "abusefilter-log-search-entries-label": "Visibilitas", + "abusefilter-log-search-entries-all": "Semua entri", + "abusefilter-log-search-entries-hidden": "Hanya entri tersembunyi", + "abusefilter-log-search-entries-visible": "Hanya entri kasat mata", + "abusefilter-log-search-action-label": "Aksi pemicu:", + "abusefilter-log-search-action-other": "Lainnya", + "abusefilter-log-search-action-any": "Apa saja", + "abusefilter-log-search-action-taken-label": "Aksi dilakukan:", + "abusefilter-log-search-action-taken-any": "Apa saja", "abusefilter-log-search-submit": "Cari", "abusefilter-log-entry": "$1: $2 memicu salah satu filter penyalahgunaan, dengan melakukan \"$3\" pada $4.\nTindakan yang diambil: $5;\nKeterangan filter: $6", "abusefilter-log-entry-withdiff": "$1: $2 memicu salah satu filter penyalahgunaan, dengan melakukan \"$3\" pada $4.\nTindakan yang diambil: $5;\nKeterangan filter: $6 ($7)", @@ -70,26 +95,35 @@ "abusefilter-log-details-var": "Variabel", "abusefilter-log-details-val": "Nilai", "abusefilter-log-details-vars": "Parameter tindakan", - "abusefilter-log-details-private": "Data pribadi", + "abusefilter-log-details-privatedetails": "Rincian log privat", "abusefilter-log-details-ip": "Alamat IP asal", + "abusefilter-log-details-checkuser": "Periksa pengguna", "abusefilter-log-noactions": "tidak ada", "abusefilter-log-details-diff": "Perubahan dalam suntingan", "abusefilter-log-linkoncontribs": "catatan penyalahgunaan", - "abusefilter-log-linkoncontribs-text": "Catatan penyalahgunaan untuk pengguna ini", - "abusefilter-log-hidden": "(entri disembunyikan)", + "abusefilter-log-linkoncontribs-text": "Log penyalahgunaan untuk {{GENDER:$1|pengguna ini}}", + "abusefilter-log-linkonhistory": "lihat log penyalahgunaan", + "abusefilter-log-linkonhistory-text": "lihat log penyalahgunaan untuk halaman ini", + "abusefilter-log-linkonundelete": "lihat log penyalahgunaan", + "abusefilter-log-linkonundelete-text": "lihat log penyalahgunaan untuk halaman ini", "abusefilter-log-hidden-implicit": "(disembunyikan karena revisi telah dihapus)", "abusefilter-log-cannot-see-details": "Anda tidak diizinkan untuk melihat rincian entri ini.", + "abusefilter-log-cannot-see-privatedetails": "Anda tidak memiliki izin untuk melihat rincian privat dari entri ini.", + "abusefilter-log-nonexistent": "Entry dengan ID tersebut tidak ada", "abusefilter-log-details-hidden": "Anda tidak dapat melihat rincian entri ini karena telah disembunyikan dari publik.", + "abusefilter-log-details-hidden-implicit": "Anda tidak dapat melihat rincian entri ini karena menyangkut revisi yang disembunyikan dari pandangan publik.", "abusefilter-log-private-not-included": "Satu atau lebih filter ID yang Anda tentukan adalah pribadi. Karena Anda tidak diizinkan untuk melihat rincian filter pribadi, filter-filter ini tidak akan dicari.", "abusefilter-log-hide-legend": "Sembunyikan entri log", "abusefilter-log-hide-id": "ID entri log:", "abusefilter-log-hide-hidden": "Sembunyikan entri ini dari publik", "abusefilter-log-hide-reason": "Alasan:", + "abusefilter-log-hide-reason-other": "Alasan lain/tambahan:", "abusefilter-log-hide-forbidden": "Anda tidak memiliki izin untuk menyembunyikan\nentri catatan penyalahgunaan.", "logentry-abusefilter-hit": "$1 memicu $4, melakukan tindakan \"$5\" terhadap $3. Tindakan yang dilakukan: $6 ($7)", - "abusefilter-management": "Manajemen filter penyalahgunaan", + "log-action-filter-rights-blockautopromote": "Pemblokiran promosi otomatis", "abusefilter-list": "Semua filter", "abusefilter-list-id": "ID filter", + "abusefilter-list-pattern": "Pola", "abusefilter-list-status": "Status", "abusefilter-list-public": "Keterangan publik", "abusefilter-list-consequences": "Konsekuensi", @@ -107,6 +141,7 @@ "abusefilter-disabled": "Dinonaktifkan", "abusefilter-hitcount": "$1 {{PLURAL:$1|suntingan|suntingan}}", "abusefilter-new": "Buat sebuah filter baru", + "abusefilter-import-button": "Impor penyaring", "abusefilter-return": "Kembali ke manajemen filter", "abusefilter-status-global": "Global", "abusefilter-list-options": "Pengaturan", @@ -114,14 +149,24 @@ "abusefilter-list-options-deleted-only": "Tampilkan hanya filter yang dihapus", "abusefilter-list-options-deleted-hide": "Sembunyikan filter yang dihapus", "abusefilter-list-options-deleted-show": "Termasuk filter yang dihapus", - "abusefilter-list-options-scope": "Tampilkan filter dari:", - "abusefilter-list-options-scope-local": "Wiki lokal", - "abusefilter-list-options-scope-global": "Aturan global", + "abusefilter-list-options-scope": "Tampilkan filter:", + "abusefilter-list-options-scope-local": "Hanya peraturan lokal", + "abusefilter-list-options-scope-global": "Hanya peraturan global", + "abusefilter-list-options-scope-all": "Peraturan lokal dan global", + "abusefilter-list-options-further-options": "Opsi lanjutan:", "abusefilter-list-options-hidedisabled": "Sembunyikan filter yang dinon-aktifkan", + "abusefilter-list-options-hideprivate": "Sembunyikan penyaring pribadi", + "abusefilter-list-options-searchpattern": "Masukkan pola", + "abusefilter-list-options-searchoptions": "Modus pencarian:", + "abusefilter-list-options-search-like": "Kueri biasa", + "abusefilter-list-options-search-rlike": "Ekspresi reguler", + "abusefilter-list-options-search-irlike": "Ekspresi reguler bebas kapitalisasi", + "abusefilter-list-regexerror": "Terjadi kesalahan ketika mencari: Kesalahan sintaks ekspresi reguler.", "abusefilter-list-options-submit": "Mutakhirkan", "abusefilter-tools-text": "Berikut adalah beberapa peralatan yang mungkin berguna untuk merumuskan dan menguji coba filter penyalahgunaan.", "abusefilter-tools-expr": "Penguji ekspresi", "abusefilter-tools-submitexpr": "Evaluasi", + "abusefilter-tools-syntax-error": "Penyaringan berisi sintaksis yang tidak sah", "abusefilter-tools-reautoconfirm": "Mengembalikan status konfirmasi otomatis", "abusefilter-tools-reautoconfirm-user": "Pengguna :", "abusefilter-tools-reautoconfirm-submit": "Konfirmasi otomatis kembali", @@ -132,14 +177,16 @@ "abusefilter-edit": "Menyunting filter penyalahgunaan", "abusefilter-edit-subtitle": "Menyunting filter $1", "abusefilter-edit-subtitle-new": "Membuat filter", + "abusefilter-edit-token-not-match": "Suntingan belum tersimpan! silakan simpan lagi.", "abusefilter-edit-oldwarning": "<strong>Anda sedang menyunting versi lama filter ini.\nStatistik yang dikutip adalah untuk versi terkini filter ini.\nJika hasil suntingan terhadap versi lama ini disimpan, maka Anda akan menimpa semua perubahan yang terjadi sejak revisi yang Anda sunting ini.</strong> • [[Special:AbuseFilter/history/$2|Kembali ke versi terdahulu filter ini]]", "abusefilter-edit-status-label": "Statistik:", "abusefilter-edit-status": "Dari $1 {{PLURAL:$1|tindakan|tindakan}} terakhir, terdapat $2 ($3%) kecocokan dengan filter ini.", - "abusefilter-edit-status-profile": "Dari $1 {{PLURAL:$1|tindakan|tindakan}} terakhir, terdapat $2 ($3%) kecocokan dengan filter ini.\nSecara rata-rata, waktu yang dibutuhkan adalah $4ms dan mengkonsumsi $5 {{PLURAL:$5||}}kondisi dari batas kondisi.", "abusefilter-edit-new": "Filter baru", "abusefilter-edit-save": "Simpan filter", "abusefilter-edit-id": "ID filter:", + "abusefilter-edit-switch-editor": "Mengganti penyuntingan", "abusefilter-edit-description": "Keterangan:\n:''(dapat dilihat secara publik)''", + "abusefilter-edit-field-description": "Deskripsi", "abusefilter-edit-group": "Grup filter:", "abusefilter-edit-flags": "Tanda:", "abusefilter-edit-enabled": "Aktifkan filter ini", @@ -147,6 +194,7 @@ "abusefilter-edit-hidden": "Sembunyikan rincian filter ini dari publik", "abusefilter-edit-global": "Penyaring global", "abusefilter-edit-rules": "Kondisi:", + "abusefilter-edit-field-conditions": "Kondisi", "abusefilter-edit-notes": "Catatan:", "abusefilter-edit-lastmod": "Filter terakhir diubah:", "abusefilter-edit-lastmod-text": "$1 oleh $2", @@ -158,23 +206,41 @@ "abusefilter-edit-action-degroup": "Hapus pengguna dari semua kelompok hak-hak istimewa.", "abusefilter-edit-action-block": "Blokir pengguna dan alamat IP dari menyunting", "abusefilter-edit-action-throttle": "Picu tindakan hanya jika pengguna melampaui batasan tertentu", - "abusefilter-edit-action-rangeblock": "Blokir selebar /16 dari asal pengguna", + "abusefilter-edit-action-rangeblock": "Blokir kisaran IP masing-masing tempat asal pengguna", "abusefilter-edit-action-tag": "Tandai suntingan untuk ditinjau lagi nanti", "abusefilter-edit-throttle-count": "Jumlah tindakan yang diizinkan:", - "abusefilter-edit-throttle-period": "Periode waktu:", + "abusefilter-edit-throttle-period": "Periode waktu (detik):", "abusefilter-edit-throttle-groups": "Kelompokkan katup menurut:\n:''(satu per baris, kombinasi dengan koma)''", + "abusefilter-edit-throttle-groups-help": "Lihat $1.", + "abusefilter-edit-throttle-groups-help-text": "dokumentasi di mediawiki.org", + "abusefilter-throttle-ip": "Alamat IP", + "abusefilter-throttle-user": "akun pengguna", + "abusefilter-throttle-range": "/16 range", + "abusefilter-throttle-creationdate": "tanggal pembuatan akun", + "abusefilter-throttle-editcount": "Jumlah suntingan", + "abusefilter-throttle-site": "Keseluruhan situs", + "abusefilter-throttle-page": "laman", + "abusefilter-throttle-none": "(tidak ada)", "abusefilter-edit-warn-message": "Pesan sistem yang digunakan untuk memberi peringatan:", "abusefilter-edit-warn-other": "Pesan lainnya", - "abusefilter-edit-warn-other-label": "Nama halaman dari pesan lain;\n:''(tanpa awalan MediaWiki)''", + "abusefilter-edit-warn-other-label": "Nama halaman dari pesan lain;\n:''(tanpa awalan ''MediaWiki:'')''", "abusefilter-edit-warn-actions": "Tindakan:", - "abusefilter-edit-warn-preview": "Pratayang pesan yang dipilih", + "abusefilter-edit-warn-preview": "Tampilkan/Sembunyikan pesan terpilih", "abusefilter-edit-warn-edit": "Buat/Sunting pesan yang dipilih", + "abusefilter-edit-disallow-other": "Pesan lainnya", + "abusefilter-edit-disallow-actions": "Tindakan:", "abusefilter-edit-tag-tag": "Tag yang digunakan (satu per baris):", + "abusefilter-edit-block-user-durations": "Durasi pemblokiran untuk pengguna terdaftar", + "abusefilter-block-anon": "Blokir pengguna anonim", + "abusefilter-block-user": "Blokir pengguna terdaftar", + "abusefilter-block-talk": "Halaman pembicaraan diblokir", "abusefilter-edit-denied": "Anda tidak dapat melihat rincian filter ini, karena rincian filter telah disembunyikan dari publik.", "abusefilter-edit-main": "Parameter filter", "abusefilter-edit-done-subtitle": "Filter telah disunting", "abusefilter-edit-done": "Anda berhasil menyimpan [[Special:AbuseFilter/history/$1/diff/prev/$2|perubahan]] [[Special:AbuseFilter/$1|filter $3]].", "abusefilter-edit-badsyntax": "Terdapat kesalahan sintaksis dalam filter yang Anda masukkan. Hasil dari parser adalah:\n<pre>$1</pre>", + "abusefilter-edit-missingfields": "Kolom isian berikut wajib diisi: $1", + "abusefilter-edit-deleting-enabled": "Anda tidak dapat menandai filter aktif sebagai terhapus.", "abusefilter-edit-restricted": "Anda tidak dapat menyunting filter ini, karena mengandung satu atau lebih tindakan yang dibatasi.\nMintalah kepada pengguna yang memiliki hak akses untuk menyunting tindakan yang dibatasi ini.", "abusefilter-edit-viewhistory": "Lihat sejarah filter ini", "abusefilter-edit-history": "Versi:", @@ -186,7 +252,8 @@ "abusefilter-edit-export": "Ekspor filter ini ke wiki lain", "abusefilter-edit-syntaxok": "Tidak terdeteksi kesalahan sintaks.", "abusefilter-edit-syntaxerr": "Kesalahan sintaks terdeteksi: $1", - "abusefilter-edit-bad-tags": "Satu atau lebih dari penanda yang anda tentukan tidak sah.\nPenanda harus pendek, dan seharusnya tidak berisi karakter khusus.", + "abusefilter-edit-warn-leave": "Meninggalkan halaman akan membatalkan perubahan pada filter ini.", + "abusefilter-edit-bad-tags": "Satu atau lebih dari penanda yang Anda tentukan tidak sah.\nPenanda seharusnya pendek, tidak berisi karakter khusus, dan tidak dapat dipesan oleh perangkat lunak lain. Cobalah memilih nama penanda baru.", "abusefilter-edit-notallowed": "Anda tidak diizinkan untuk membuat atau mengedit filter penyalahgunaan", "abusefilter-edit-notallowed-global": "Anda tidak diizinkan membuat atau menyunting filter penyalahgunaan global", "abusefilter-edit-notallowed-global-custom-msg": "Pesan peringatan kustom tidak didukung untuk filter global", @@ -217,7 +284,7 @@ "abusefilter-edit-builder-misc-contains": "Karakter kiri berisi karakter yang tepat (contains)", "abusefilter-edit-builder-misc-stringlit": "Karakter harfiah (\"\")", "abusefilter-edit-builder-misc-tern": "Operator terner (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Bersyarat (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Bersyarat (if X then Y else Z end)", "abusefilter-edit-builder-group-funcs": "Fungsi", "abusefilter-edit-builder-funcs-length": "Panjang karakter (length)", "abusefilter-edit-builder-funcs-lcase": "Menjadi huruf kecil (lcase)", @@ -240,53 +307,74 @@ "abusefilter-edit-builder-group-vars": "Variabel", "abusefilter-edit-builder-vars-accountname": "Nama pengguna (pada pembuatan akun)", "abusefilter-edit-builder-vars-timestamp": "Perubahan waktu Unix", + "abusefilter-edit-builder-vars-timestamp-expanded": "Cap waktu log", "abusefilter-edit-builder-vars-action": "Tindakan", "abusefilter-edit-builder-vars-addedlines": "Garis ditambahkan pada suntingan", "abusefilter-edit-builder-vars-delta": "Ukuran berubah pada suntingan", "abusefilter-edit-builder-vars-diff": "perbedaan yang mirip dari perubahan karena penyuntingan", "abusefilter-edit-builder-vars-newsize": "Ukuran halaman baru", "abusefilter-edit-builder-vars-oldsize": "Ukuran halaman lama", + "abusefilter-edit-builder-vars-old-content-model": "Model konten lama", + "abusefilter-edit-builder-vars-new-content-model": "Model konten baru", "abusefilter-edit-builder-vars-removedlines": "Garis dihilangkan dalam penyunting", "abusefilter-edit-builder-vars-summary": "Ringkasan suntingan/alasan", "abusefilter-edit-builder-vars-page-id": "ID Halaman", "abusefilter-edit-builder-vars-page-ns": "Ruangnama halaman", "abusefilter-edit-builder-vars-page-title": "Judul Halaman (tanpa ruangnama)", "abusefilter-edit-builder-vars-page-prefixedtitle": "Judul halaman lengkap", + "abusefilter-edit-builder-vars-page-age": "Usia halaman (detik)", "abusefilter-edit-builder-vars-movedfrom-id": "ID Halaman dari pemindahan halaman sumber", "abusefilter-edit-builder-vars-movedfrom-ns": "Ruangnama dari pemindahan halaman sumber", "abusefilter-edit-builder-vars-movedfrom-title": "Judul dari pemindahan halaman sumber", "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "Judul lengkap dari pemindahan halaman sumber", + "abusefilter-edit-builder-vars-movedfrom-age": "Pindahkan usia halaman sumber (detik)", "abusefilter-edit-builder-vars-movedto-id": "ID halaman dari pemindahan halaman tujuan", "abusefilter-edit-builder-vars-movedto-ns": "Ruangnama dari pemindahan halaman tujuan", "abusefilter-edit-builder-vars-movedto-title": "Judul dari pemindahan halaman tujuan", "abusefilter-edit-builder-vars-movedto-prefixedtitle": "Judul lengkap dari pemindahan halaman tujuan", + "abusefilter-edit-builder-vars-movedto-age": "Pindahkan usia halaman tujuan (detik)", "abusefilter-edit-builder-vars-user-editcount": "Jumlah suntingan pengguna", - "abusefilter-edit-builder-vars-user-age": "Umur pengguna", + "abusefilter-edit-builder-vars-user-age": "Usia akun pengguna", "abusefilter-edit-builder-vars-user-name": "Nama pengguna", "abusefilter-edit-builder-vars-user-groups": "Kelompok (selengkapnya) pengguna dalam", "abusefilter-edit-builder-vars-user-rights": "Hak bahwa pengguna memiliki", "abusefilter-edit-builder-vars-user-blocked": "Apakah pengguna diblokir", "abusefilter-edit-builder-vars-user-emailconfirm": "Waktu konfirmasi alamat surel", "abusefilter-edit-builder-vars-recent-contributors": "Sepuluh pengguna terakhir kontributor halaman", + "abusefilter-edit-builder-vars-first-contributor": "Pengguna pertama yang berkontribusi pada halaman ini", + "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "Sepuluh pengguna terakhir yang berkontribusi untuk memindahkan halaman sumber", + "abusefilter-edit-builder-vars-movedfrom-first-contributor": "Penguna pertama yang berkontribusi memindahkan halaman sumber", + "abusefilter-edit-builder-vars-movedto-recent-contributors": "Sepuluh pengguna terakhir yang berkontribusi memindahkan halaman tujuan", + "abusefilter-edit-builder-vars-movedto-first-contributor": "Pengguna pertama yang berkontribusi memindahkan halaman tujuan", "abusefilter-edit-builder-vars-all-links": "Semua pranala luar dalam teks baru", "abusefilter-edit-builder-vars-added-links": "Semua pranala luar ditambahkan dalam penyuntingan", "abusefilter-edit-builder-vars-removed-links": "Semua pranala luar yang dihapus dalam penyuntingan", - "abusefilter-edit-builder-vars-old-text": "Teks wiki yang lama, sebelum penyuntingan", - "abusefilter-edit-builder-vars-new-text": "Teks wiki halaman baru, setelah penyuntingan", + "abusefilter-edit-builder-vars-old-wikitext": "Teks wiki yang lama, sebelum penyuntingan", + "abusefilter-edit-builder-vars-new-wikitext": "Teks wiki halaman baru, setelah penyuntingan", "abusefilter-edit-builder-vars-new-pst": "Halaman baru teks wiki, pemindahan pra-penyimpanan", "abusefilter-edit-builder-vars-diff-pst": "Perbedaan kompak dari perubahan yang dilakukan oleh suntingan, pra-simpan berubah", "abusefilter-edit-builder-vars-addedlines-pst": "Baris ditambahkan dalam suntingan, pra-simpan berubah", - "abusefilter-edit-builder-vars-new-text-stripped": "Teks halaman baru, menghilangkan markah apa pun", + "abusefilter-edit-builder-vars-new-text": "Teks halaman baru, menghilangkan markah apa pun", "abusefilter-edit-builder-vars-new-html": "Pengurai sumber HTML dari revisi baru", "abusefilter-edit-builder-vars-restrictions-edit": "Sunting tingkat pelindungan halaman", "abusefilter-edit-builder-vars-restrictions-move": "buang tingkat pelindungan halaman", "abusefilter-edit-builder-vars-restrictions-create": "Buat perlindungan berkas", "abusefilter-edit-builder-vars-restrictions-upload": "Unggah perlindungan berkas", - "abusefilter-edit-builder-vars-old-text-stripped": "Teks halaman lama, menghilangkan markah apa pun", + "abusefilter-edit-builder-vars-movedfrom-restrictions-edit": "Sunting tingkat perlindungan untuk memindahkan halaman sumber", + "abusefilter-edit-builder-vars-movedfrom-restrictions-move": "Pindahkan tingkat perlindungan pemindahan halaman sumber", + "abusefilter-edit-builder-vars-old-text": "Teks halaman lama, menghilangkan markah apa pun", "abusefilter-edit-builder-vars-old-links": "Pranala dalam halaman, sebelum penyuntingan", - "abusefilter-edit-builder-vars-old-html": "Halaman lama tekswiki, uraikan ke HTML", - "abusefilter-edit-builder-vars-minor-edit": "Ada atau tidak penyuntingan ditandai sebagai suntingan kecil", + "abusefilter-edit-builder-vars-old-html": "Halaman lama teks wiki, uraikan ke HTML (tak lagi digunakan)", + "abusefilter-edit-builder-vars-minor-edit": "Ada atau tidak penyuntingan ditandai sebagai suntingan kecil (tak lagi digunakan)", "abusefilter-edit-builder-vars-file-sha1": "SHA1 hash dari isi berkas", + "abusefilter-edit-builder-vars-file-size": "Ukuran berkas dalam bita", + "abusefilter-edit-builder-vars-file-mime": "Jenis MIME berkas", + "abusefilter-edit-builder-vars-file-mediatype": "Jenis media berkas", + "abusefilter-edit-builder-vars-file-width": "Lebar berkas dalam piksel", + "abusefilter-edit-builder-vars-file-height": "Tinggi berkas dalam piksel", + "abusefilter-edit-builder-vars-file-bits-per-channel": "Bit per kanal warna berkas", + "abusefilter-edit-builder-vars-wiki-name": "Nama basis data wiki", + "abusefilter-edit-builder-vars-wiki-language": "Kode bahasa wiki", "abusefilter-filter-log": "Perubahan filter terbaru", "abusefilter-history": "Sejarah perubahan Filter Penyalahgunaan #$1", "abusefilter-history-foruser": "Diubah oleh $1", @@ -338,8 +426,9 @@ "abusefilter-revert-periodstart": "Periode mulai:", "abusefilter-revert-periodend": "Periode selesai:", "abusefilter-revert-search": "Pilih tindakan", - "abusefilter-revert-filter": "Penyaring:", + "abusefilter-revert-filter": "ID filter:", "abusefilter-revert-preview-intro": "Berikut adalah tindakan yang dilakukan oleh filter penyalahgunaan yang akan dikembalikan oleh tindakan ini.\nHarap periksa dengan saksama, dan klik \"{{int:abusefilter-revert-confirm}}\" untuk mengkonfirmasikan pilihan Anda.", + "abusefilter-revert-confirm-legend": "Konfirmasikan pengembalian", "abusefilter-revert-confirm": "Konfirmasi", "abusefilter-revert-success": "Anda telah mengembalikan semua tindakan yang dilakukan filter penyalahgunaan karena [[Special:AbuseFilter/$1|filter $2]].", "abusefilter-revert-reason": "Pengembalian otomatis terhadap semua tindakan yang dilakukan filter penyalahgunaan karena filter $1.\nAlasan yang diberikan: $2", @@ -351,12 +440,20 @@ "abusefilter-test-submit": "Ujicoba", "abusefilter-test-load": "Muatkan", "abusefilter-test-user": "Diubah oleh pengguna:", + "abusefilter-test-nobots": "Sembunyikan suntingan bot", "abusefilter-test-period-start": "Perubahan dilakukan setelah:", "abusefilter-test-period-end": "Perubahan dilakukan sebelum:", "abusefilter-test-page": "Perubahan dilakukan pada halaman:", "abusefilter-test-shownegative": "Lihat perubahan yang tidak sama dengan penyaringan", "abusefilter-test-syntaxerr": "Penyaringan yang Anda masukkan mengandung kesalahan sintaks.\nAnda dapat menerima penjelasan lengkap dengan menekan tombol \"{{int:abusefilter-edit-check}}\".", "abusefilter-test-badtitle": "Judul halaman yang dimasukkan tidak sah. Ini mungkin juga mengandung satu atau lebih karakter yang tidak dapat digunakan dalam judul.", + "abusefilter-test-action": "Jenis tindakan", + "abusefilter-test-search-type-all": "Semua tindakan", + "abusefilter-test-search-type-edit": "Suntingan", + "abusefilter-test-search-type-move": "Pemindahan", + "abusefilter-test-search-type-delete": "Penghapusan", + "abusefilter-test-search-type-upload": "Unggahan", + "abusefilter-test-search-type-createaccount": "Pembuatan akun", "abusefilter-changeslist-examine": "periksa", "abusefilter-examine": "Teliti perubahan tersendiri", "abusefilter-examine-intro": "Halaman ini memungkinkan Anda untuk memeriksa variabel yang dihasilkan Filter Penyalahgunaan untuk suatu perubahan individu, dan mengujinya terhadap filter.", @@ -376,11 +473,11 @@ "abusefilter-examine-noresults": "Tidak ada hasil yang ditemukan untuk pencarian dengan parameter yang anda sediakan.", "abusefilter-topnav": "'''Navigasi Filter Penyalahgunaan '''", "abusefilter-topnav-home": "Utama", + "abusefilter-topnav-recentchanges": "Perubahan filter terbaru", "abusefilter-topnav-test": "Tumpak uji coba", "abusefilter-topnav-examine": "Memeriksa suntingan terdahulu", "abusefilter-topnav-log": "Catatan penyalahgunaan", "abusefilter-topnav-tools": "Alat Debugging", - "abusefilter-topnav-import": "Impor penyaring", "abusefilter-log-name": "Catatan penyaringan penyalahgunaan", "abusefilter-log-header": "Log ini memberikan ringkasan perubahan yang dilakukan terhadap filter.\nUntuk detail lengkap, lihat [[Special:AbuseFilter/history|daftar]] perubahan filter terbaru.", "abusefilter-log-noresults": "Tidak ada hasil", @@ -395,5 +492,6 @@ "abusefilter-diff-next": "Perubahan terbaru", "abusefilter-import-intro": "Anda dapat menggunakan antarmuka ini untuk mengimpor filter dari wiki lain.\nPada wiki asal, klik \"{{int:abusefilter-edit-export}}\" di bawah \"{{int:abusefilter-edit-tools}}\" pada antarmuka penyuntingan.\nSalin dari kotak teks yang muncul, dan tempelkan di kotak teks ini, lalu klik \"{{int:abusefilter-import-submit}}\".", "abusefilter-import-submit": "Impor data", - "abusefilter-group-default": "Baku" + "abusefilter-group-default": "Baku", + "abusefilter-log-ip-not-available": "Tidak Tersedia" } diff --git a/AbuseFilter/i18n/ie.json b/AbuseFilter/i18n/ie.json new file mode 100644 index 00000000..9a58a5dc --- /dev/null +++ b/AbuseFilter/i18n/ie.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "OIS" + ] + }, + "abusefilter-edit-builder-vars-wiki-language": "Li code de lingue del wiki" +} diff --git a/AbuseFilter/i18n/ike-latn.json b/AbuseFilter/i18n/ike-latn.json index edeb7091..eb8fbb5d 100644 --- a/AbuseFilter/i18n/ike-latn.json +++ b/AbuseFilter/i18n/ike-latn.json @@ -1,4 +1,6 @@ { - "@metadata": [], + "@metadata": { + "authors": [] + }, "abusefilter-list-edit": "Suqusiqpaa" } diff --git a/AbuseFilter/i18n/ilo.json b/AbuseFilter/i18n/ilo.json index 661f1447..f9177322 100644 --- a/AbuseFilter/i18n/ilo.json +++ b/AbuseFilter/i18n/ilo.json @@ -6,8 +6,8 @@ ] }, "abusefilter-desc": "Agipakat kadagiti automatiko a panagsolbar iti parikut kadagiti panagurnos", - "abusefilter": "Kompigurasion ti sagat ti panagabuso", - "abuselog": "Listaan ti panagabuso", + "abusefilter": "Panangasiwa ti sagat ti panagabuso", + "abuselog": "Listaan ti sagat ti panagabuso", "abusefilter-intro": "Naragsak nga isasangbay ditoy interface ti pangasiwaan ti Sagat ti Panagabuso.\nTi Sagat ti Panagabuso ket automatiko a mekanismo ti sopwer nga agikabil ti automatiko a panagsolbar ti amin a parikut kadagiti amin a tignay.\nDaytoy nga interface ket ipakitana dagiti listaan dagiti naipalawag a sagat, ken mangipalubos kaniada a mabaliwan.", "abusefilter-warning": "'''Ballaag''': Daytoy a tignay ket automatiko a nainaganan a makadangran.\nDagiti saan a nasayaat a panagurnos ket napardasto a maisubli,\nken dagiti dakes unay wenno naulit a dakes a panagurnos ket pakaresultaan ti pannakaserra ti pakabilangam wenno ti IP nga adresmo.\nNo namatmatika a daytoy a tignay ket nasayaat, mabalinmo nga ited manen tapno mapasingkedam.\nTi ababa a deskripsion iti alagaden ti panagabuso nga inaramidmo a naipada ket: $1", "abusefilter-disallowed": "Daytoy a tignay ket automatiko a nainaganan a makadangran, ken iti kasta saan a maipalubos.\nNo namatmatika a ti tignaymo ket nasayaat, pangngaasi nga ipakaammom iti administrador no ania ti padpadasem nga ar-aramiden.\nTi ababa a deskripsion iti alagaden ti panagabuso nga inaramidmo a naipada ket: $1", @@ -22,7 +22,7 @@ "right-abusefilter-view": "Kitaen dagiti sagat ti panagabuso", "right-abusefilter-log": "Kitaen ti listaan ti panagabuso", "right-abusefilter-log-detail": "Kitaen dagiti naisalaysay a naikabil dita listaan ti panagabuso", - "right-abusefilter-private": "Kitaen ti pribado a datos idiay listaan ti panagabuso", + "right-abusefilter-privatedetails": "Kitaen ti pribado a datos idiay listaan ti panagabuso", "right-abusefilter-modify-restricted": "Baliwan dagiti sagat ti panagabuso nga addaan kadagiti nagawidan a tignay", "right-abusefilter-revert": "Isubli amin a binaliwan babaen ti maysa a sagat ti panagabuso", "right-abusefilter-view-private": "Kitaen dagiti sagat ti panagabuso a namarkaan a kas pribado", @@ -34,11 +34,10 @@ "action-abusefilter-view": "kitaen dagiti sagat ti panagabuso", "action-abusefilter-log": "kitaen ti listaan ti panagabuso", "action-abusefilter-log-detail": "kitaen dagiti naisalaysay a naikabil iti listaan ti panagabuso", - "action-abusefilter-private": "kitaen ti pribado a datos iti listaan ti panagabuso", + "action-abusefilter-privatedetails": "kitaen ti pribado a datos iti listaan ti panagabuso", "action-abusefilter-modify-restricted": "baliwan dagiti sagat ti panagabuso nga addaan kadagiti nagawidan a tignay", "action-abusefilter-revert": "isubli amin a nasukatan babaen ti maysa a naited a sagat ti panagabuso", "action-abusefilter-view-private": "kitaen dagiti sagat ti panagabuso a namarkaan a kas pribado", - "abusefilter-log": "Listaan ti sagat ti panagabuso", "abusefilter-log-summary": "Daytoy a listaan ket ipakitana amin dagiti tignay a naala babaen dagiti sagat.", "abusefilter-log-search": "Agbiruk iti listaan ti panagabuso", "abusefilter-log-search-user": "Agar-aramat:", @@ -58,13 +57,12 @@ "abusefilter-log-details-var": "Sabsabali a kita", "abusefilter-log-details-val": "Pateg", "abusefilter-log-details-vars": "Dagiti parametro ti tignay", - "abusefilter-log-details-private": "Dagiti salasay ti pribado a listaan", + "abusefilter-log-details-privatedetails": "Dagiti salasay ti pribado a listaan", "abusefilter-log-details-ip": "Tinaudan nga adres ti IP", "abusefilter-log-noactions": "awan", "abusefilter-log-details-diff": "Dagiti binaliwan a naaramid ti inurnos", "abusefilter-log-linkoncontribs": "listaan ti panagabuso", "abusefilter-log-linkoncontribs-text": "Listaan ti panagabuso para iti daytoy nga agar-aramat", - "abusefilter-log-hidden": "(nailemmeng ti naikabil)", "abusefilter-log-hidden-implicit": "(nailemmeng gapu ti panagbalbaliw ket naikkaten)", "abusefilter-log-cannot-see-details": "Awan ti pammalubosmo a makakita kadagiti salaysay iti daytoy a naikabil.", "abusefilter-log-details-hidden": "Saanmo a makita dagiti salaysay iti daytoy a naikabil gaputa nailemmeng manipud ti publiko a panagkita.", @@ -75,7 +73,6 @@ "abusefilter-log-hide-reason": "Rason:", "abusefilter-log-hide-forbidden": "Awan ti pammalubosmo nga agilemmeng kadagiti naikabil iti listaan ti panagabuso.", "logentry-abusefilter-hit": "Nakalbit ni $1 ti $4, a nagar-aramid ti tignay iti \"$5\" iti $3. Dagiti naaramid a tignay: $6 ($7)", - "abusefilter-management": "Panangasiwa ti sagat ti panagabuso", "abusefilter-list": "Amin a sagat", "abusefilter-list-id": "ID ti sagat", "abusefilter-list-status": "Kasasaad", @@ -95,6 +92,7 @@ "abusefilter-disabled": "Nabaldado", "abusefilter-hitcount": "$1 {{PLURAL:$1|a natumpaan|kadagiti natumpaan}}", "abusefilter-new": "Agpartuat iti baro a sagat", + "abusefilter-import-button": "Agala iti sagat", "abusefilter-return": "Agsubli iti panangasiwa ti sagat", "abusefilter-status-global": "Global", "abusefilter-list-options": "Dagiti pagpilian", @@ -124,7 +122,6 @@ "abusefilter-edit-oldwarning": "<strong>Agur-urnoska iti daan a bersion ti sagat.\nDagiti estadistika a naibaga ket ti agdama a bersion ti sagat.\nNo idulinmo dagiti binaliwan, masuratamto manen amin a binaliwam manipud ti rebison nga ur-urnosem.</strong> •\n[[Special:AbuseFilter/history/$2|Agsubli idiay pakasaritaan ti sagat]].", "abusefilter-edit-status-label": "Estadistika:", "abusefilter-edit-status": "Iti naudi a $1 a {{PLURAL:$1|tignay|tigtignay}}, daytoy a sagat ket nakaipada iti $2 ($3%) .", - "abusefilter-edit-status-profile": "Iti naudi a $1 a {{PLURAL:$1|tignay|tigtignay}}, daytoy a sagat ket nakaipada iti $2 ($3%) .\nIti pagtengngaan, ti kabayag a panagandarna ket $4 ms, ken mangibus iti $5 a {{PLURAL:$5|kasasaad|kaskasaad}} iti patingga ti kasasaad.", "abusefilter-edit-new": "Baro a sagat", "abusefilter-edit-save": "Idulin ti sagat", "abusefilter-edit-id": "ID ti sagat:", @@ -266,18 +263,18 @@ "abusefilter-edit-builder-vars-all-links": "Dagiti amin nga akinruar a silpo iti baro a teksto", "abusefilter-edit-builder-vars-added-links": "Dagiti amin nga akinruar a silpo a nainayon iti inurnos", "abusefilter-edit-builder-vars-removed-links": "Dagiti amin nga akinruar a silpo a naikkat iti inurnos", - "abusefilter-edit-builder-vars-old-text": "Daan a panid a wikitext, sakbay nga inurnos", - "abusefilter-edit-builder-vars-new-text": "Baro a panid a wikitext, kalpasan nga inurnos", + "abusefilter-edit-builder-vars-old-wikitext": "Daan a panid a wikitext, sakbay nga inurnos", + "abusefilter-edit-builder-vars-new-wikitext": "Baro a panid a wikitext, kalpasan nga inurnos", "abusefilter-edit-builder-vars-new-pst": "Baro a panid a wikitext, a nabaliwan sakbay a naidulin", "abusefilter-edit-builder-vars-diff-pst": "Naipagkaykaysa a pagiddiatan kadagiti binaliwan babaen ti inurnos, a nabaliwan sakbay a naidulin", "abusefilter-edit-builder-vars-addedlines-pst": "Dagiti nainayon a linia iti inurnos, a nabaliwan sakbay a naidulin", - "abusefilter-edit-builder-vars-new-text-stripped": "Baro a teksto ti panid, a naikkatan iti ania man a naimarka", + "abusefilter-edit-builder-vars-new-text": "Baro a teksto ti panid, a naikkatan iti ania man a naimarka", "abusefilter-edit-builder-vars-new-html": "Nawaswas a taudan ti HTML iti baro a rebision", "abusefilter-edit-builder-vars-restrictions-edit": "Agpang ti panagsalaknib ti panagurnos iti panid", "abusefilter-edit-builder-vars-restrictions-move": "Agpang ti panagsalaknib ti panagiyalis iti panid", "abusefilter-edit-builder-vars-restrictions-create": "Agpartuat ti panagsalaknib iti panid", "abusefilter-edit-builder-vars-restrictions-upload": "Agikarga ti panagsalaknib iti papeles", - "abusefilter-edit-builder-vars-old-text-stripped": "Daan a teksto ti panid, a naikkatan iti ania man a naimarka", + "abusefilter-edit-builder-vars-old-text": "Daan a teksto ti panid, a naikkatan iti ania man a naimarka", "abusefilter-edit-builder-vars-old-links": "Dagiti silpo iti panid, sakbay ti panagurnos", "abusefilter-edit-builder-vars-old-html": "Daan a wikitext ti panid, a nawaswas iti HTML", "abusefilter-edit-builder-vars-minor-edit": "No wenno saan a ti inurnos ket namarkaan a kas bassit", @@ -381,7 +378,6 @@ "abusefilter-topnav-examine": "Sukimaten dagiti napalabas nga inurnos", "abusefilter-topnav-log": "Listaan ti panagabuso", "abusefilter-topnav-tools": "Ramramit a pagsimpa", - "abusefilter-topnav-import": "Agala iti sagat", "abusefilter-log-name": "Listaan ti Sagat ti Panagabuso", "abusefilter-log-header": "Daytoy a listaan ket agiparang ti pakapukpukan dagiti binaliwan nga inaramid para kadagiti sagat.\nPara kadagiti napno a salaysay, kitaen [[Special:AbuseFilter/history|ti listaan]] dagiti kaudian panagbaliw iti sagat.", "abusefilter-log-noresults": "Awan dagiti resulta", diff --git a/AbuseFilter/i18n/inh.json b/AbuseFilter/i18n/inh.json index d5c215d2..79e349ca 100644 --- a/AbuseFilter/i18n/inh.json +++ b/AbuseFilter/i18n/inh.json @@ -1,10 +1,10 @@ { "@metadata": { "authors": [ + "Adam-Yourist", "Amire80", "Sapral Mikail", - "Умар", - "Adam-Yourist" + "Умар" ] }, "right-abusefilter-view": "боарамал сов леладеш долча хIамай фильтрага хьажар", @@ -16,11 +16,12 @@ "abusefilter-log-search-filter": "Фильтрай ID (урагIа така хьаракаца йикъа):", "abusefilter-log-search-submit": "Хьалаха", "abusefilter-log-detailedentry-local": "луттарг $1", + "abusefilter-log-linkoncontribs": "харцахьа даь хIамаш тIадола тептар", "abusefilter-log-hide-reason": "Бахьан:", "abusefilter-list-edit": "Нийсде", "abusefilter-tools-reautoconfirm-user": "Доакъашхо:", "abusefilter-edit-flags": "Байракхаш:", - "abusefilter-edit-history": "Истори:", + "abusefilter-edit-history": "Тархьар:", "abusefilter-edit-tools": "Кечалаш:", "abusefilter-edit-builder-op-arithmetic-pow": "ЛагӀа (**)", "abusefilter-edit-builder-vars-page-id": "ОагIон ID", @@ -33,9 +34,11 @@ "abusefilter-history-select-user": "Доакъашхо:", "abusefilter-history-diff": "Хувцамаш", "abusefilter-action-tag": "Хьисап", + "abusefilter-revert-confirm": "Бакъде", "abusefilter-examine-user": "Доакъашхо:", "abusefilter-examine-title": "ОагIон цIи:", "abusefilter-examine-submit": "Хьалáха", - "abusefilter-diff-info": "Кертера дараш", + "abusefilter-topnav-log": "Харцахьа даь хIамаш тIадола тептар", + "abusefilter-diff-info": "Керттера бола хоам", "abusefilter-group-default": "Юххьанцара хиннача тайпара" } diff --git a/AbuseFilter/i18n/io.json b/AbuseFilter/i18n/io.json index 31539b6a..ce82fd63 100644 --- a/AbuseFilter/i18n/io.json +++ b/AbuseFilter/i18n/io.json @@ -1,50 +1,61 @@ { "@metadata": { "authors": [ - "Malafaya", - "Robin van der Vliet", + "Joao Xavier", "Lakaoso", - "Joao Xavier" + "Malafaya", + "Robin van der Vliet" ] }, "abusefilter-desc": "Aplikas automatala heuristiko a la redakturi", - "abusefilter": "Figuro dil filtrilo pri misuzo", - "abuselog": "Protokolo pri misuzo", "abusefilter-intro": "Bonveno a la kontrol interfacio dil filtrilo di misuzo. La filtrilo di misuzo esas automatala mekanismo di softwaro qua aplikas automatala heuristiko ad omna agadi.\n\nIca interfacio* montras listo pri definita filtrili, e permisas modifikar li.", - "right-abusefilter-modify": "Modifikar filtrili pri misuzo", + "abusefilter-degrouped": "Ica agado automatale identifikesis kom danjerosa.\nDo, ol ne permisesis, e pro existar suspekto pri transakto per vua konto, omna ek vua yuri revokesis.\nSe vu kredas ke to esas eroro, voluntez kontaktar burokrato ed explikar ica agado, do vua yuri restauresos.\nKurta deskripto pri la reguli kontre abuzi qua koincidas kun vua agado esas: $1.", + "right-abusefilter-modify": "Krear o modifikar filtrili pri misuzo", "right-abusefilter-view": "Vidar filtrili di misuzo", + "action-abusefilter-log": "Videz l'enrejistruri pri misuzo", "action-abusefilter-log-detail": "Videz detaloza registri di informi pri misuzo", "abusefilter-log-summary": "Ica protokolo montras listo pri omna agadi kaptita dal filtrili.", "abusefilter-log-search": "Serchez la protokolo pri misuzo", "abusefilter-log-search-user": "Uzero:", "abusefilter-log-search-filter": "Identigo di filtrili (separita per vertikala streki):", "abusefilter-log-search-title": "Titulo:", + "abusefilter-log-search-impact-all": "Omna agadi", + "abusefilter-log-search-impact-saved": "Nur konservita modifikuri", + "abusefilter-log-search-action-taken-any": "Irga", "abusefilter-log-search-submit": "Serchez", "abusefilter-log-noactions": "nula", "abusefilter-log-linkoncontribs": "Protokolo pri misuzo", "abusefilter-log-linkoncontribs-text": "Registro pri misuzi da {{GENDER:$1|ica uzero}}", + "abusefilter-log-linkonhistory": "videz l'enrejistruri pri misuzo", "abusefilter-log-hide-reason": "Motivo:", "abusefilter-list": "Omna filtrili", "abusefilter-list-status": "Stando", + "abusefilter-list-public": "Publika deskripto", "abusefilter-list-edit": "Redaktar", "abusefilter-list-lastmodified": "Lasta modifikuro", "abusefilter-hidden": "Privata", "abusefilter-unhidden": "Publika", + "abusefilter-disabled": "Permiso revokita", "abusefilter-new": "Krear nova filtrilo", + "abusefilter-import-button": "Importar filtrilo", "abusefilter-list-options": "Selekti", "abusefilter-list-options-deleted-only": "Montrar nur filtrili efacita", "abusefilter-list-options-scope-local": "Nur lokala reguli", + "abusefilter-list-options-searchoptions": "Modo di serchado:", "abusefilter-tools-reautoconfirm-user": "Uzero:", "abusefilter-edit-status-label": "Statistiko:", "abusefilter-edit-new": "Nova filtrilo", "abusefilter-edit-save": "Registragar filtrilo", + "abusefilter-edit-description": "Deskripto:\n:''(publike videbla)''", "abusefilter-edit-rules": "Kondicioni:", "abusefilter-edit-lastmod-text": "$1 da $2", + "abusefilter-edit-action-rangeblock": "Blokusar la serio di IP-adresi de ube l'uzero originis", "abusefilter-edit-warn-other": "Altra mesajo", "abusefilter-edit-done-subtitle": "La filtrilo redaktesas", "abusefilter-edit-history": "Versionaro:", "abusefilter-edit-check": "Verifikar sintaxo", "abusefilter-edit-tools": "Utensili:", + "abusefilter-edit-bad-tags": "Un o plusa etiketi quon vu mencionis esas nevalida.\nEtiketi mustas esar kurta e ne kontenar specala karakteri, e li ne povas esar vorti rezervata da altra softwaro. Voluntez krear altra nomo por l'etiketo.", "abusefilter-edit-builder-select": "Indikez selekto por adjuntar a la kursoro", "abusefilter-edit-builder-op-arithmetic-addition": "Adiciono (+)", "abusefilter-edit-builder-op-arithmetic-subtraction": "Sustraciono (-)", @@ -61,8 +72,10 @@ "abusefilter-edit-builder-vars-newsize": "Nova grandeso di la pagino", "abusefilter-edit-builder-vars-oldsize": "Antea grandeso (en bicoki*) di la pagino", "abusefilter-edit-builder-vars-recent-contributors": "Lasta 10 uzeri qui redaktis la pagino", - "abusefilter-edit-builder-vars-new-text": "Nova pagino di Wikitexto, pos la redakto", + "abusefilter-edit-builder-vars-new-wikitext": "Nova pagino di Wikitexto, pos la redakto", "abusefilter-edit-builder-vars-new-pst": "Nova Wikitexto di la pagino, modifikita ante konservo", + "abusefilter-edit-builder-vars-minor-edit": "Se la redakturo markizesis o ne kom minora (ja ne uzesas)", + "abusefilter-edit-builder-vars-file-size": "Dimensiono dil arkivo, en bicoki*", "abusefilter-filter-log": "Recenta modifiki en la filtrili", "abusefilter-history-foruser": "Chanji da $1", "abusefilter-history-global": "Globala", @@ -74,8 +87,14 @@ "abusefilter-history-select-user": "Uzero:", "abusefilter-history-diff": "Chanji", "abusefilter-action-tag": "Etiketo", + "abusefilter-action-blockautopromote": "Blokusar automatala promoco", + "abusefilter-action-block": "Blokusar", "abusefilter-action-degroup": "Forigar ek grupi", + "abusefilter-action-rangeblock": "Blokusez serio di IP-adresi", + "abusefilter-action-disallow": "Despermisar", "abusefilter-revert-filter": "Filtrilo:", + "abusefilter-revert-confirm": "Konfirmez", + "abusefilter-revert-reason": "Automatale desfacez omna agadi dal filtrilo pri abuzo, pro la filtro $1.\nMotivo: $2", "abusefilter-test": "Probar filtrilo kontre antea redakturi", "abusefilter-test-intro": "Ica pagino permisas vu probar filtrilo kontre l'antea $1 {{PLURAL:$1|modifiko|modifiki}} en la buxo adinfre.\nPor charjar existanta filtrilo, skribez la nomo dil filtrilo en la buxo infre la redakto-buxo, e pose kliktez la butono \"{{int:abusefilter-test-load}}\".", "abusefilter-test-legend": "Probo di filtrili", @@ -87,15 +106,19 @@ "abusefilter-test-period-end": "Modifiki facita ante:", "abusefilter-test-page": "Modifiki facita en la pagino:", "abusefilter-test-shownegative": "Montrez chanji qui esas diferanta de la filtrilo", + "abusefilter-test-search-type-all": "Omna agadi", "abusefilter-examine-user": "Uzero:", - "abusefilter-examine-title": "titulo di pagino:", + "abusefilter-examine-title": "Titulo di pagino:", "abusefilter-examine-submit": "Serchez", "abusefilter-examine-test-button": "Probez filtrilo", + "abusefilter-topnav-home": "Chefpagino", + "abusefilter-topnav-recentchanges": "Recenta modifikuri en la filtrili", "abusefilter-topnav-test": "Probar grupo", "abusefilter-topnav-examine": "Vidar antea redakti", "abusefilter-topnav-log": "Protokolo ('log') pri misuzo", "abusefilter-topnav-tools": "Utensili por 'debug'", - "abusefilter-topnav-import": "Importar filtrilo", "abusefilter-log-header": "Ca protokolo ('log') montras rezumo di modifikuri en la filtrili.\nPor plusa detali, videz [[Special:AbuseFilter/history|la listo di recenta chanji en la filtrili]].", - "abusefilter-diff-version": "Versiono ye $1 {{GENDER:$3|da}} $2" + "abusefilter-log-noresults": "Nula rezulti", + "abusefilter-diff-version": "Versiono ye $1 {{GENDER:$3|da}} $2", + "abusefilter-group-default": "Normala" } diff --git a/AbuseFilter/i18n/is.json b/AbuseFilter/i18n/is.json index b88d7d01..7cae4811 100644 --- a/AbuseFilter/i18n/is.json +++ b/AbuseFilter/i18n/is.json @@ -1,15 +1,15 @@ { "@metadata": { "authors": [ + "Matma Rex", + "Maxí", "S.Örvarr.S", "Snævar", - "Matma Rex", - "Sveinn í Felli", - "Maxí" + "Sveinn í Felli" ] }, "abusefilter-desc": "Beitir sjálfvirkri brjóstvitsfræði á breytingar.", - "abusefilter": "Stillingar misnotkunar síunnar", + "abusefilter": "Stjórn misnotkunar síunnar", "abuselog": "Misnotkunarskrá", "abusefilter-intro": "Velkominn í viðmót Misnotkunar síunnar.\nSían er sjálfvirkt tæki sem gerir sjálfvirkar brjóstvitsfræði athuganir á allar breytingar.\nÞetta viðmót sýnir lista yfir skilgreindar síur og leyfir breytingar á þeim.", "abusefilter-warning": "'''Viðvörun:''' Þessi aðgerð hefur sjálfvirkt verið merkt sem skaðleg.\nSkaðlegar aðgerðir verða snögglega teknar til baka,\nog svívirðilegar eða síendurteknar breytingar leiða til banns á notenda eða vistfangi þínu.\nEf þú telur að þessi aðgerð sé uppbyggileg, þá mátt þú senda hana aftur til að staðfesta hana.\nStutt lýsing um misnotkunar síuna sem breyting þín passaði við er: $1", @@ -17,7 +17,7 @@ "abusefilter-blocked-display": "Þessi aðgerð hefur sjálfvirkt verið merkt sem skaðleg og því er bannað að framkvæma hana.\nAð auki, til þess að verja {{SITENAME}}, hefur notendanafn þitt og það vistfang sem þú notaðir síðast verið bannað.\nEf villa leiddi þig hingað, hafðu þá samband við möppudýr.\nStutt lýsing um misnotkunar síuna sem breyting þín passaði við er: $1", "abusefilter-degrouped": "Þessi aðgerð hefur sjálfvirkt verið merkt sem skaðleg.\nÞví hefur henni verið hafnað og fyrst að grunur er um að aðgangur þinn sé í hættu hafa réttindi þín verið afturkölluð.\nEf villa leiddi þig hingað, hafðu þá samband við möppudýr með útskýringu um hvað þú reyndir að gera og mögulega færð þú réttindi þín aftur.\nStutt lýsing um misnotkunar síuna sem breyting þín passaði við er: $1", "abusefilter-autopromote-blocked": "Þessi aðgerð hefur sjálfvirkt verið merkt sem skaðleg og því hefur henni verið hafnað.\nAð auki, sem öryggisráðstöfun, hafa þau réttindi sem eru sjálfvirkt gefin notendum verið afturkölluð tímabundið.\nStutt lýsing um misnotkunar síuna sem breyting þín passaði við er: $1", - "abusefilter-blocker": "Misnotkunar sía", + "abusefilter-blocker": "Misnotkunarsía", "abusefilter-blockreason": "Sjálfvirkt hafnað af misnotkunar síunni.\nLýsing misnotkunar síunnar sem passaði við breytinguna: $1", "abusefilter-degroupreason": "Réttindi afturkölluð sjálfkrafa af misnotkunar síunni.\nLýsing síunnar: $1", "abusefilter-accountreserved": "Þetta notendanafn er frátekið fyrir misnotkunar síuna.", @@ -25,7 +25,7 @@ "right-abusefilter-view": "Skoða misnotkunar síur", "right-abusefilter-log": "Skoða misnotkunarskránna", "right-abusefilter-log-detail": "Skoða ítarlegar færslur í misnotkunarskránni", - "right-abusefilter-private": "Skoða persónuleg gögn í misnotkunarskránni", + "right-abusefilter-privatedetails": "Skoða persónuleg gögn í misnotkunarskránni", "right-abusefilter-modify-restricted": "Breyta misnotkunar síum með takmarkandi aðgerðum", "right-abusefilter-revert": "Taka til baka allar breytingar sem voru gerðar af misnotkunar síu", "right-abusefilter-view-private": "Sjá faldar misnotkunarsíur", @@ -36,11 +36,10 @@ "action-abusefilter-view": "skoða misnotkunar síur", "action-abusefilter-log": "skoða misnotkunarskránna", "action-abusefilter-log-detail": "skoða ítarlegar færslur í misnotkunarskránni", - "action-abusefilter-private": "skoða persónuleg gögn í misnotkunarskránni", + "action-abusefilter-privatedetails": "skoða persónuleg gögn í misnotkunarskránni", "action-abusefilter-modify-restricted": "breyta misnotkunar síum með takmarkandi aðgerðum", "action-abusefilter-revert": "taka til baka allar breytingar sem voru gerðar af misnotkunar síu", "action-abusefilter-view-private": "skoða faldar misnotkunarsíur", - "abusefilter-log": "Misnotkunarskrá", "abusefilter-log-summary": "Þetta er listi yfir allar aðgerðir sem passa við misnotkunar síurnar.", "abusefilter-log-search": "Leita í misnotkunarskránni", "abusefilter-log-search-user": "Notandi:", @@ -62,12 +61,10 @@ "abusefilter-log-details-var": "Breyta", "abusefilter-log-details-val": "Gildi", "abusefilter-log-details-vars": "Stiki aðgerðar", - "abusefilter-log-details-private": "Ítarlegt úr einkaannál", "abusefilter-log-details-ip": "Upprunalegt vistfang", "abusefilter-log-noactions": "engar", "abusefilter-log-linkoncontribs": "misnotkunarskrá", "abusefilter-log-linkoncontribs-text": "Misnotkunarskrá fyrir {{GENDER:$1|þennan notanda}}", - "abusefilter-log-hidden": "(falin færsla)", "abusefilter-log-hidden-implicit": "(falið vegna þess að breytingum hefur verið eytt)", "abusefilter-log-cannot-see-details": "Þú hefur ekki leyfi til þess að sjá atriði þessarar innfærslu.", "abusefilter-log-details-hidden": "Þú getur ekki skoðað nánari upplýsingar um þessa færslu því hún er falin.", @@ -77,7 +74,6 @@ "abusefilter-log-hide-reason": "Ástæða:", "abusefilter-log-hide-forbidden": "Þú hefur engin réttindi til að fela færslur í misnotkunar skránni", "logentry-abusefilter-hit": "$1 {{GENDER:$2|hrundi}} af stað misnotkunar síu $4, með breytingunni \"$5\" á $3. Framkvæmdi aðgerðirnar $6 ($7)", - "abusefilter-management": "Stjórn misnotkunar síunnar", "abusefilter-list": "Allar síur", "abusefilter-list-id": "Einkenni", "abusefilter-list-status": "Staða", @@ -95,6 +91,7 @@ "abusefilter-deleted": "Eytt", "abusefilter-disabled": "Óvirk", "abusefilter-new": "Búa til nýja misnotkunar síu", + "abusefilter-import-button": "Flytja inn síu", "abusefilter-return": "Aftur á stjórn misnotkunar síunnar", "abusefilter-status-global": "Altæk", "abusefilter-list-options": "Möguleikar", @@ -113,10 +110,9 @@ "abusefilter-status": "Yfir síðustu $1 {{PLURAL:$1|aðgerð|aðgerðir}}, $2 ($3%) {{PLURAL:$2|hefur|hafa}} náð skilyrðunum $4, og $5 ($6%) {{PLURAL:$5|hefur|hafa}} passað við eina af þeim síum sem eru virkar.", "abusefilter-edit-subtitle": "Breyti síu $1", "abusefilter-edit-subtitle-new": "Býr til síu", - "abusefilter-edit-oldwarning": "<strong>ATH: Þú ert að breyta gamalli útgáfu þessarar síu.\nSú tölfræði sem vitnað er í er fyrir nýjustu útgáfu síunnar.\nEf þú vistar breytingarnar munu allar breytingar sem gerðar hafa verið á henni frá þeirri útgáfu vera fjarlægðar ef þú vistar.</strong>\n[[Special:AbuseFilter/history/$2|Fara aftur á breytingarskrá síunnar]]", + "abusefilter-edit-oldwarning": "<strong>ATH: Þú ert að breyta gamalli útgáfu þessarar síu.\nSú tölfræði sem vitnað er í er fyrir nýjustu útgáfu síunnar.\nEf þú vistar breytingarnar munu allar breytingar sem gerðar hafa verið á henni frá þeirri útgáfu vera fjarlægðar ef þú vistar.</strong>\n[[Special:AbuseFilter/history/$2|Fara aftur á breytingaskrá síunnar]]", "abusefilter-edit-status-label": "Tölfræði:", "abusefilter-edit-status": "Af síðustu $1 {{PLURAL:$1|aðgerð|aðgerðum}} hefur þessi sía passað við $2 ($3%).", - "abusefilter-edit-status-profile": "Af síðustu $1 {{PLURAL:$1|aðgerð|aðgerðum}} hefur þessi sía passað við $2 ($3%).\nAð meðaltali tekur vinnsla síunnar $4 ms og eyðir $5 {{PLURAL:$5|skilyrði|skilyrðum}} af hámarksfjölda skilyrða.", "abusefilter-edit-new": "Ný sía", "abusefilter-edit-save": "Vista síu", "abusefilter-edit-id": "Síu einkenni:", @@ -124,7 +120,7 @@ "abusefilter-edit-group": "Síuhópur:", "abusefilter-edit-flags": "Merkingar:", "abusefilter-edit-enabled": "Virkja þessa síu", - "abusefilter-edit-deleted": "Merkja sem eydda", + "abusefilter-edit-deleted": "Merkja sem eytt", "abusefilter-edit-hidden": "Fela nánari upplýsingar um þessa síu", "abusefilter-edit-global": "Altæk sía", "abusefilter-edit-rules": "Skilyrði:", @@ -140,14 +136,14 @@ "abusefilter-edit-action-rangeblock": "Fjöldabanna vistföng út frá vistfangi notandans", "abusefilter-edit-action-tag": "Merkja breytinguna til frekari skoðunar", "abusefilter-edit-throttle-count": "Fjöldi aðgerða sem eru leyfðir:", - "abusefilter-edit-throttle-period": "Tímalengd:", + "abusefilter-edit-throttle-period": "Tímabil (í sekúndum):", "abusefilter-edit-warn-message": "Kerfisskilaboð sem verða notuð til viðvörunar:", "abusefilter-edit-warn-other": "Önnur skilaboð", "abusefilter-edit-warn-other-label": "Nafn viðvörunarskilaboðanna:\n:''(í nafnrýminu Strengir)''", "abusefilter-edit-warn-actions": "Aðgerðir:", - "abusefilter-edit-warn-preview": "Forskoða valin skilaboð", + "abusefilter-edit-warn-preview": "Birta/Fela forskoðun valinna skilaboða", "abusefilter-edit-warn-edit": "Stofna/Breyta völdum skilaboðum", - "abusefilter-edit-tag-tag": "[[Special:Tags|Tög]] sem eiga að gilda (eitt á línu):", + "abusefilter-edit-tag-tag": "[[Special:Tags|Merki]] sem á að beita:", "abusefilter-edit-denied": "Þú getur ekki skoðað nánari upplýsingar um þessa síu, því hún er falin.", "abusefilter-edit-main": "Stikar síunnar", "abusefilter-edit-done-subtitle": "Síu breytt", @@ -164,7 +160,7 @@ "abusefilter-edit-export": "Flytja síuna á annan wiki", "abusefilter-edit-syntaxok": "Engar málskipunar villur fundust.", "abusefilter-edit-syntaxerr": "Málskipunar villa fannst: $1", - "abusefilter-edit-bad-tags": "Eitt eða fleiri merkjanna sem þú hefur tilgreint eru ógild.\nMerki eiga að vera stutt, þau mega ekki innihalda sértákn og þau ættu aldrei að vera frátekin fyrir annan hugbúnað. Reyndu að velja eitthvað annað heiti.", + "abusefilter-edit-bad-tags": "Eitt eða fleiri merkjanna sem þú hefur tilgreint eru ógild.\nMerki eiga að vera stutt, þau mega ekki innihalda sértákn og þau ættu aldrei að vera frátekin fyrir annan hugbúnað. Reyndu að velja eitthvað annað heiti á merkið.", "abusefilter-edit-notallowed": "Þú getur ekki breytt eða stofnað misnotkunar síu.", "abusefilter-edit-builder-select": "Veldu möguleika til að bæta honum við bendilinn.", "abusefilter-edit-builder-group-op-arithmetic": "Reikningsaðgerðir", @@ -175,8 +171,8 @@ "abusefilter-edit-builder-op-arithmetic-modulo": "Leif (%)", "abusefilter-edit-builder-op-arithmetic-pow": "Veldi (**)", "abusefilter-edit-builder-group-op-comparison": "Samanburðarvirkjar", - "abusefilter-edit-builder-op-comparison-equal": "Jafnt og (==)", - "abusefilter-edit-builder-op-comparison-notequal": "Ekki jafnt og (!=)", + "abusefilter-edit-builder-op-comparison-equal": "Gildi er jafnt og (==)", + "abusefilter-edit-builder-op-comparison-notequal": "Gildi er ekki jafnt og (!=)", "abusefilter-edit-builder-op-comparison-lt": "Minna en (<)", "abusefilter-edit-builder-op-comparison-gt": "Stærra en (>)", "abusefilter-edit-builder-op-comparison-lte": "Minna en eða jafnt og (<=)", @@ -189,7 +185,7 @@ "abusefilter-edit-builder-group-funcs": "Föll", "abusefilter-edit-builder-funcs-length": "Strengjalengd (length)", "abusefilter-edit-builder-group-vars": "Breytur", - "abusefilter-edit-builder-vars-timestamp": "Unix-tímastimpill breytingar", + "abusefilter-edit-builder-vars-timestamp": "Unix-tímamerki breytingar", "abusefilter-edit-builder-vars-action": "Aðgerð", "abusefilter-edit-builder-vars-addedlines": "Línum viðbætt í breytingu", "abusefilter-edit-builder-vars-newsize": "Ný skrárstærð", @@ -222,8 +218,8 @@ "abusefilter-history-select-submit": "Endurskilgreina", "abusefilter-history-diff": "Breytingar", "abusefilter-history-error-hidden": "Sían sem þú óskaðir eftir er falin og þú getur ekki skoðað breytingarsögu hennar.", - "abusefilter-exception-unrecognisedtoken": "Óþekktur tóki \"$2\" á staf $1", - "abusefilter-exception-noparams": "Enginn stiki gefinn fyrir aðgerðina \"$2\" á stafnum $1", + "abusefilter-exception-unrecognisedtoken": "Óþekkt teikn \"$2\" við staf $1", + "abusefilter-exception-noparams": "Engin færibreyta gefin fyrir aðgerðina \"$2\" við staf $1.", "abusefilter-exception-dividebyzero": "Ómögulegt að deila $2 með núlli á stafnum $1", "abusefilter-exception-unrecognisedvar": "Óþekkt breyta $2 á staf $1", "abusefilter-exception-notenoughargs": "Of fáar frumbreytur fyrir aðgerðina $2 á stafnum $1.\nBjóst við $3 {{PLURAL:$3|breytu|breytum}} en fékk $4", @@ -241,7 +237,7 @@ "abusefilter-revert-periodstart": "Upphafstímabil:", "abusefilter-revert-periodend": "Endatímabil:", "abusefilter-revert-search": "Velja aðgerðir", - "abusefilter-revert-filter": "Sía:", + "abusefilter-revert-filter": "Auðkenni síu:", "abusefilter-revert-preview-intro": "Fyrir neðan eru þær aðgerðir misnotkunnarsíunnar sem taka á til baka.\nFarðu vandlega yfir listann og ýttu á „{{int:abusefilter-revert-confirm}}” til að staðfesta valið þitt.", "abusefilter-revert-confirm": "staðfesta", "abusefilter-revert-success": "Þú hefur tekið aftur allar breytingar misnotkunar [[Special:AbuseFilter/$1|síunnar $2]]", @@ -280,7 +276,6 @@ "abusefilter-topnav-examine": "Prófa síðustu breytingar", "abusefilter-topnav-log": "Misnotkunarskrá", "abusefilter-topnav-tools": "Kembiforrit", - "abusefilter-topnav-import": "Flytja inn síu", "abusefilter-log-name": "Misnotkunar síu skrá", "abusefilter-log-noresults": "Engar niðurstöður", "abusefilter-diff-title": "Munur milli útgáfa", @@ -288,7 +283,7 @@ "abusefilter-diff-version": "Útgáfa frá $1 {{GENDER:$3|eftir}} $2", "abusefilter-diff-info": "Grunnupplýsingar", "abusefilter-diff-invalid": "Mistókst að sækja þær útgáfur sem þú óskaðir eftir", - "abusefilter-diff-backhistory": "Aftur í breytingarskrá síunnar", + "abusefilter-diff-backhistory": "Aftur í breytingaskrá síunnar", "abusefilter-diff-next": "Nýlegri breytingar", "abusefilter-import-submit": "Flytja inn gögn", "abusefilter-group-default": "Sjálfgefið", diff --git a/AbuseFilter/i18n/it.json b/AbuseFilter/i18n/it.json index d1bc9ae7..8f42a730 100644 --- a/AbuseFilter/i18n/it.json +++ b/AbuseFilter/i18n/it.json @@ -1,87 +1,94 @@ { "@metadata": { "authors": [ + "Alexmar983", + "Ankabel", + "ArTrix", "Beta16", "Blaisorblade", "BrokenArrow", "Brownout", + "Chiara.Graziani1991", + "Daimona Eaytoy", "Darth Kule", "F. Cosoleto", + "Fitoschido", "Gianfranco", + "Greis", + "Horcrux92", + "Macofe", + "Matma Rex", "Melos", "Nemo bis", - "Pietrodn", - "Valepert", - "Ximo17", - "Ankabel", - "Chiara.Graziani1991", "Nivit", + "Pietrodn", "Ricordisamoa", - "Macofe", - "Alexmar983", - "Matma Rex", - "Greis", - "Horcrux92", - "Daimona Eaytoy", - "Fitoschido", - "ArTrix", "Sarah Bernabei", - "Wim b" + "Valepert", + "Wim b", + "Ximo17" ] }, "abusefilter-desc": "Applica un'euristica automatica alle modifiche.", - "abusefilter": "Configurazione del filtro anti abusi", + "abusefilter": "Gestione del filtro anti abusi", "abuselog": "Registro del filtro anti abusi", "abusefilter-intro": "Benvenuti nell'interfaccia di gestione del filtro anti abusi.\nIl filtro anti abusi è un sistema automatizzato per l'applicazione di euristiche automatiche a tutte le azioni.\nL'interfaccia mostra un elenco dei filtri definiti e ne consente la modifica.", "abusefilter-mustviewprivateoredit": "Per motivi di sicurezza, solo gli utenti con il diritto di visualizzare i filtri anti abusi privati o di modificare i filtri possono utilizzare questa interfaccia.", "abusefilter-warning": "'''Attenzione:''' questa azione è stata ritenuta pericolosa in base a una verifica automatica.\nLe azioni non costruttive verranno prontamente annullate; l'inserimento palese o ripetuto di contributi non costruttivi darà luogo al blocco dell'utenza o del tuo indirizzo IP.\nSe si ritiene che l'azione in questione sia costruttiva, devi inviarla nuovamente per confermarla.\nQuesta è una breve descrizione della regola di sicurezza che è stata violata: $1", - "abusefilter-disallowed": "Questa azione è stata ritenuta pericolosa e quindi impedita in base a una verifica automatica.\nSe si ritiene che l'azione in questione sia costruttiva, contattare un amministratore e informarlo su ciò che si stava tentando di fare.\nQuesta è una breve descrizione della regola di sicurezza che è stata violata: $1", - "abusefilter-blocked-display": "Questa azione è stata ritenuta pericolosa e quindi impedita in base a una verifica automatica.\nInoltre, allo scopo di proteggere {{SITENAME}} l'utenza coinvolta e tutti gli indirizzi IP ad essa associati sono stati bloccati e non possono più effettuare modifiche.\nSe si ritiene che si tratti di un errore, si prega di contattare un amministratore.\nQuesta è una breve descrizione della regola di sicurezza che è stata violata: $1", + "abusefilter-disallowed": "Questa azione è stata ritenuta pericolosa e quindi impedita in base a una verifica automatica.\nSe si ritiene che l'azione in questione sia costruttiva, contattare un amministratore e informarlo su ciò che si stava tentando di fare.\nQuesta è una breve descrizione della regola che è stata violata: $1", + "abusefilter-blocked-display": "Questa azione è stata ritenuta pericolosa e quindi impedita in base a una verifica automatica.\nInoltre, allo scopo di proteggere {{SITENAME}}, la tua utenza e tutti gli indirizzi IP ad essa associati sono stati bloccati e non possono più effettuare modifiche.\nSe ritieni che si tratti di un errore, si prega di contattare un amministratore.\nQuesta è una breve descrizione della regola che è stata violata: $1", "abusefilter-degrouped": "Questa azione è stata ritenuta pericolosa in base a una verifica automatica.\nL'azione è quindi stata impedita e tutti i diritti connessi all'utenza sono stati revocati, in quanto vi è il rischio che la stessa sia stata compromessa.\nSe si ritiene che vi sia un errore, si prega di contattare un burocrate per spiegare le ragioni di quest'azione; i diritti connessi all'utenza potrebbero essere ripristinati.\nQuesta è una breve descrizione della regola di sicurezza che è stata violata: $1", "abusefilter-autopromote-blocked": "Questa azione è stata ritenuta pericolosa e quindi impedita in base a una verifica automatica.\nInoltre, come misura di sicurezza sono stati temporaneamente revocati all'utenza coinvolta alcuni dei privilegi che di norma vengono concessi alle utenze conosciute.\nQuesta è una breve descrizione della regola di sicurezza che è stata violata: $1", "abusefilter-blocker": "Filtro anti abusi", "abusefilter-blockreason": "Bloccato automaticamente dal filtro anti abusi.\nDescrizione della regola corrispondente: $1", "abusefilter-degroupreason": "Diritti rimossi automaticamente dal filtro anti abusi. Descrizione della regola: $1", + "abusefilter-blockautopromotereason": "Autopromozione ritardata automaticamente dal filtro anti abusi.\nDescrizione della regola: $1", "abusefilter-accountreserved": "Questo nome utente è riservato al filtro anti abusi.", - "right-abusefilter-modify": "Modifica i filtri anti abusi", + "right-abusefilter-modify": "Crea o modifica i filtri anti abusi", "right-abusefilter-view": "Visualizza i filtri anti abusi", "right-abusefilter-log": "Visualizza il registro del filtro anti abusi", "right-abusefilter-log-detail": "Visualizza voci dettagliate del registro del filtro anti abusi", - "right-abusefilter-private": "Visualizza i dati privati nel registro del filtro anti abusi", - "right-abusefilter-private-log": "Visualizza i dettagli privati del registro di accesso del filtro anti abusi", + "right-abusefilter-privatedetails": "Visualizza i dati privati nel registro del filtro anti abusi", + "right-abusefilter-privatedetails-log": "Visualizza i dettagli privati del registro di accesso del filtro anti abusi", "right-abusefilter-modify-restricted": "Modifica i filtri anti abusi con le azioni riservate", "right-abusefilter-revert": "Annulla tutti i cambiamenti di un determinato filtro anti abusi", "right-abusefilter-view-private": "Visualizza i filtri anti abusi segnati come privati", "right-abusefilter-log-private": "Visualizza gli elementi del registro degli abusi contrassegnati come privati", - "right-abusefilter-hide-log": "Nasconde voci nel registro degli abusi", + "right-abusefilter-hide-log": "Nasconde voci nel registro del filtro anti abusi", "right-abusefilter-hidden-log": "Visualizza voci nascoste del registro del filtro anti abusi", - "right-abusefilter-modify-global": "Crea o modifica i filtri globali anti abusi", + "right-abusefilter-modify-global": "Crea o modifica i filtri anti abusi globali", "action-abusefilter-modify": "modificare i filtri anti abusi", "action-abusefilter-view": "visualizzare i filtri anti abusi", "action-abusefilter-log": "visualizzare il registro del filtro anti abusi", "action-abusefilter-log-detail": "visualizzare le voci di dettaglio del registro del filtro anti abusi", - "action-abusefilter-private": "visualizzare le informazioni riservate nel registro del filtro anti abusi", - "action-abusefilter-private-log": "visualizzare i dettagli privati del registro di accesso del filtro anti abusi", + "action-abusefilter-privatedetails": "visualizzare le informazioni riservate nel registro del filtro anti abusi", + "action-abusefilter-privatedetails-log": "visualizzare i dettagli privati del registro di accesso del filtro anti abusi", "action-abusefilter-modify-restricted": "modificare i filtri anti abusi con le azioni riservate", "action-abusefilter-revert": "ripristinare tutte le modifiche apportate da un determinato filtro anti abusi", "action-abusefilter-view-private": "visualizzare i filtri anti abusi segnati come privati", "action-abusefilter-log-private": "visualizzare i registri dei filtri anti abusi contrassegnati come privati", - "abusefilter-log": "Registro del filtro anti abusi", + "action-abusefilter-hide-log": "nascondere voci nel registro del filtro anti abusi", + "action-abusefilter-hidden-log": "visualizzare voci nascoste del registro del filtro anti abusi", + "action-abusefilter-modify-global": "creare o modificare i filtri anti abusi globali", "abusefilter-log-summary": "Questo registro mostra un elenco di tutte le azioni che hanno attivato uno o più filtri.", "abusefilter-log-search": "Cerca nel registro del filtro anti abusi", "abusefilter-log-search-user": "Utente:", - "abusefilter-log-search-filter": "ID filtri (separati da barre verticali):", + "abusefilter-log-search-group": "Gruppo filtri:", + "abusefilter-log-search-group-any": "Qualsiasi", + "abusefilter-log-search-filter": "ID filtri:", + "abusefilter-log-search-filter-help": "Separa con barre verticali, utilizzando il prefisso \"$1\" per i filtri globali", + "abusefilter-log-search-filter-help-central": "Separa con barre verticali", "abusefilter-log-search-title": "Titolo:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-impact": "Impatto:", "abusefilter-log-search-impact-all": "Tutte le azioni", - "abusefilter-log-search-impact-saved": "Solo modifiche salvate", - "abusefilter-log-search-impact-not-saved": "Senza modifiche salvate", + "abusefilter-log-search-impact-saved": "Solo cambiamenti salvati", + "abusefilter-log-search-impact-not-saved": "Senza cambiamenti salvati", "abusefilter-log-search-entries-label": "Visibilità:", "abusefilter-log-search-entries-all": "Tutte le voci", "abusefilter-log-search-entries-hidden": "Solo le voci nascoste", "abusefilter-log-search-entries-visible": "Solo le voci visibili", - "abusefilter-log-search-action-label": "Azione compiuta:", + "abusefilter-log-search-action-label": "Azione che ha attivato il filtro:", "abusefilter-log-search-action-other": "Altro", "abusefilter-log-search-action-any": "Qualsiasi", "abusefilter-log-search-action-taken-label": "Azione intrapresa:", @@ -90,7 +97,7 @@ "abusefilter-log-entry": "$1: $2 {{GENDER:$8|ha provocato}} l'attivazione di un filtro anti abusi con l'azione \"$3\" su $4.\nAzioni intraprese: $5;\nDescrizione del filtro: $6", "abusefilter-log-entry-withdiff": "$1: $2 {{GENDER:$8|ha provocato}} l'attivazione di un filtro anti abusi con l'azione \"$3\" su $4.\nAzioni intraprese: $5;\nDescrizione del filtro: $6 ($7)", "abusefilter-log-detailedentry-meta": "$1: $2 {{GENDER:$9|ha attivato}} $3 con l'azione \"$4\" su $5.\nAzioni intraprese: $6;\nDescrizione del filtro: $7 ($8)", - "abusefilter-log-detailedentry-global": "filtro globale $1", + "abusefilter-log-detailedentry-global": "il filtro globale $1", "abusefilter-log-detailedentry-local": "il filtro $1", "abusefilter-log-detailslink": "dettagli", "abusefilter-log-diff": "diff", @@ -99,19 +106,21 @@ "abusefilter-log-details-var": "Variabile", "abusefilter-log-details-val": "Valore", "abusefilter-log-details-vars": "Parametri dell'azione", - "abusefilter-log-details-private": "Dettagli registro privati", + "abusefilter-log-details-privatedetails": "Dettagli del registro privati", "abusefilter-log-details-ip": "Indirizzo IP di origine", "abusefilter-log-details-checkuser": "Check user", "abusefilter-log-noactions": "nessuna", + "abusefilter-log-noactions-filter": "Nessuna", "abusefilter-log-details-diff": "Modifiche effettuate", "abusefilter-log-linkoncontribs": "filtro anti abusi", "abusefilter-log-linkoncontribs-text": "Registro del filtro anti abusi relativo a {{GENDER:$1|questo utente}}", "abusefilter-log-linkonhistory": "visualizza il registro del filtro anti abusi", "abusefilter-log-linkonhistory-text": "Visualizza il registro del filtro anti abusi per questa pagina", - "abusefilter-log-hidden": "(voce nascosta)", + "abusefilter-log-linkonundelete": "visualizza il registro del filtro anti abusi", + "abusefilter-log-linkonundelete-text": "Visualizza il registro del filtro anti abusi per questa pagina", "abusefilter-log-hidden-implicit": "(nascosto perché la versione è stata eliminata)", "abusefilter-log-cannot-see-details": "Non si dispone dei permessi necessari per vedere i dettagli di questa voce del registro.", - "abusefilter-log-cannot-see-private-details": "Non si dispone dei permessi necessari per vedere i dettagli di questa voce del registro.", + "abusefilter-log-cannot-see-privatedetails": "Non si dispone dei permessi necessari per vedere i dettagli di questa voce del registro.", "abusefilter-log-nonexistent": "Una voce con l'ID specificato non esiste.", "abusefilter-log-details-hidden": "Non è possibile visualizzare i dettagli di questa voce, in quanto nascosta al pubblico.", "abusefilter-log-details-hidden-implicit": "Non è possibile visualizzare i dettagli di questa voce in quanto riferita a una revisione nascosta al pubblico.", @@ -129,9 +138,12 @@ "log-action-filter-abusefilter-create": "Creazione di un nuovo filtro", "log-action-filter-abusefilter-modify": "Modifica del filtro", "log-action-filter-suppress-abuselog": "Soppressione registro abusi", + "log-action-filter-rights-blockautopromote": "Blocchi autopromozione", + "log-action-filter-rights-restoreautopromote": "Ripristini autopromozione", "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|ha acceduto}} ai dettagli privati di $3", - "abusefilterprivatedetails-log-name": "Registro di accesso ai dettagli privati del filtro anti abusi", - "abusefilter-management": "Gestione del filtro anti abusi", + "logentry-rights-blockautopromote": "$1 {{GENDER:$2|ha bloccato}} l'autopromozione di {{GENDER:$4|$3}} per un periodo di $5", + "logentry-rights-restoreautopromote": "$1 {{GENDER:$2|ha ripristinato}} la possibilità di autopromozione di {{GENDER:$4|$3}}", + "abusefilterprivatedetails-log-name": "Accessi ai dettagli privati del filtro anti abusi", "abusefilter-list": "Tutti i filtri", "abusefilter-list-id": "ID filtro", "abusefilter-list-pattern": "Pattern", @@ -153,6 +165,7 @@ "abusefilter-throttled": "azioni disattivate automaticamente", "abusefilter-hitcount": "$1 {{PLURAL:$1|corrispondenza|corrispondenze}}", "abusefilter-new": "Crea un nuovo filtro", + "abusefilter-import-button": "Importa filtro", "abusefilter-return": "Torna alla gestione dei filtri", "abusefilter-status-global": "Globale", "abusefilter-list-options": "Opzioni", @@ -173,26 +186,29 @@ "abusefilter-list-options-search-like": "Testo semplice", "abusefilter-list-options-search-rlike": "Espressione regolare", "abusefilter-list-options-search-irlike": "Espressione regolare senza distinzione tra maiuscole e minuscole", + "abusefilter-list-invalid-searchmode": "La modalità di ricerca specificata non è valida.", "abusefilter-list-regexerror": "Si è verificato un errore durante la ricerca: errore di sintassi nell'espressione regolare.", "abusefilter-list-options-submit": "Aggiorna", "abusefilter-tools-text": "Di seguito sono riportati alcuni strumenti utili per la costruzione e la verifica dei filtri anti abusi.", "abusefilter-tools-expr": "Verifica espressioni", "abusefilter-tools-submitexpr": "Valuta", - "abusefilter-tools-reautoconfirm": "Ripristina lo stato di autoconfirmed", + "abusefilter-tools-syntax-error": "La sintassi del filtro non è valida.", + "abusefilter-tools-reautoconfirm": "Ripristina lo stato di autoconvalidato", "abusefilter-tools-reautoconfirm-user": "Utente:", "abusefilter-tools-reautoconfirm-submit": "Ripristina autoconfirm", - "abusefilter-reautoconfirm-none": "Lo stato di autoconfirmed dell'utente non è stato sospeso.", - "abusefilter-reautoconfirm-notallowed": "Non è consentito ripristinare lo stato di autoconfirmed.", - "abusefilter-reautoconfirm-done": "Lo stato di autoconfirmed dell'utenza è stato ripristinato", - "abusefilter-status": "Fra le ultime $1 {{PLURAL:$1|azione|azioni}}, $2 ($3 %) {{PLURAL:$2|ha|hanno}} raggiunto il limite di $4 condizioni e $5 ($6 %) {{PLURAL:$5|ha|hanno}} attivato uno dei filtri attualmente attivi.", + "abusefilter-tools-restoreautopromote": "Autopromozione ripristinata dagli strumenti del filtro anti abusi.", + "abusefilter-reautoconfirm-none": "Lo stato di autoconvalidato dell'utente non è stato sospeso.", + "abusefilter-reautoconfirm-notallowed": "Non è consentito ripristinare lo stato di autoconvalidato.", + "abusefilter-reautoconfirm-done": "Lo stato di autoconvalidato dell'utenza è stato ripristinato", + "abusefilter-status": "Fra le ultime $1 {{PLURAL:$1|azione|azioni}}, $2 ($3 %) {{PLURAL:$2|ha|hanno}} raggiunto il limite di $4 condizioni e $5 ($6 %) {{PLURAL:$5|ha|hanno}} attivato almeno uno dei filtri attualmente attivi.", "abusefilter-edit": "Modifica filtro anti abusi", "abusefilter-edit-subtitle": "Modifica del filtro $1", "abusefilter-edit-subtitle-new": "Creazione filtro", "abusefilter-edit-token-not-match": "La modifica non è stata salvata! Per favore, prova di nuovo.", "abusefilter-edit-oldwarning": "<strong>Si sta modificando una versione obsoleta di questo filtro.\nLe statistiche citate si riferiscono alla versione più recente del filtro.\nSalvando le modifiche verranno annullati tutti i cambiamenti apportati da questa versione in poi.</strong> •\n[[Special:AbuseFilter/history/$2|Ritorna alla cronologia del filtro]].", + "abusefilter-edit-oldwarning-view": "<strong>Si sta visualizzando una versione obsoleta di questo filtro.\nLe statistiche citate si riferiscono alla versione più recente del filtro.</strong> •\n[[Special:AbuseFilter/history/$2|Ritorna alla cronologia del filtro]].", "abusefilter-edit-status-label": "Statistiche:", - "abusefilter-edit-status": "Rispetto {{PLURAL:$1|all'azione più recente|alle $1 azioni più recenti}}, questo filtro ha trovato $2 {{PLURAL:$2|corrispondenza|corrispondenze}} ($3 %).", - "abusefilter-edit-status-profile": "Rispetto {{PLURAL:$1|all'azione più recente|alle $1 azioni più recenti}}, questo filtro ha trovato $2 {{PLURAL:$2|corrispondenza|corrispondenze}} ($3 %).\nIl suo tempo medio di esecuzione è di $4 ms, e impiega $5 {{PLURAL:$5|condizione|condizioni}} del limite di condizioni.", + "abusefilter-edit-status": "Rispetto {{PLURAL:$1|all'azione più recente|alle $1 azioni più recenti}}, questo filtro ha trovato $2 {{PLURAL:$2|corrispondenza|corrispondenze}} ($3 %).\nIn media, il suo tempo di esecuzione è di $4 ms e consuma $5 {{PLURAL:$5|condizione|condizioni}} del limite delle condizioni.", "abusefilter-edit-throttled-warning": "Attenzione: questo filtro è stato automaticamente identificato come pericoloso. Come misura di sicurezza, le azioni seguenti non saranno eseguite ($1). Per favore controlla e [[mw:Extension:AbuseFilter/Conditions|ottimizza]] le condizioni per rimuovere questa restrizione.", "abusefilter-edit-new": "Nuovo filtro", "abusefilter-edit-save": "Salva filtro", @@ -215,23 +231,28 @@ "abusefilter-edit-consequences": "Azioni da intraprendere in caso di corrispondenza", "abusefilter-edit-action-warn": "Attiva le azioni selezionate dopo aver avvisato l'utente", "abusefilter-edit-action-disallow": "Impedisci all'utente di effettuare l'azione in questione", - "abusefilter-edit-action-blockautopromote": "Revoca lo stato di autoconfermato dell'utente", + "abusefilter-edit-action-blockautopromote": "Revoca lo stato di autoconvalidato dell'utente", "abusefilter-edit-action-degroup": "Rimuovi l'utente da tutti i gruppi privilegiati", "abusefilter-edit-action-block": "Blocca l'utenza o indirizzo IP", "abusefilter-edit-action-blocktalk": "Impedisci all'utente o indirizzo IP di modificare la sua pagina di discussione", "abusefilter-edit-action-throttle": "Attiva le azioni solo se l'utente supera un limite predeterminato", "abusefilter-edit-action-rangeblock": "Bloccare il rispettivo intervallo IP di origine dell'utente", - "abusefilter-edit-action-tag": "Evidenzia la modifica per una verifica ulteriore", + "abusefilter-edit-action-tag": "Etichetta la modifica per una verifica ulteriore", "abusefilter-edit-throttle-count": "Numero di azioni da consentire:", "abusefilter-edit-throttle-period": "Periodo di tempo (in secondi):", "abusefilter-edit-throttle-groups": "Criteri di raggruppamento per il rallentamento:", - "abusefilter-edit-throttle-ip": "Indirizzo IP", - "abusefilter-edit-throttle-user": "Account utente", - "abusefilter-edit-throttle-range": "Range /16", - "abusefilter-edit-throttle-creationdate": "Orario del server della creazione dell'account", - "abusefilter-edit-throttle-editcount": "Conteggio delle modifiche", - "abusefilter-edit-throttle-site": "Tutto il sito", - "abusefilter-edit-throttle-page": "Pagina", + "abusefilter-edit-throttle-groups-help": "Vedi $1.", + "abusefilter-edit-throttle-groups-help-text": "la documentazione su mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Separare con la virgola per raggruppare in AND, e con ritorni a capo per raggruppare in OR", + "abusefilter-edit-throttle-placeholder": "Separare con la virgola per raggruppare in AND, e inserire uno ad uno per raggruppare in OR", + "abusefilter-throttle-ip": "indirizzo IP", + "abusefilter-throttle-user": "account utente", + "abusefilter-throttle-range": "range /16", + "abusefilter-throttle-creationdate": "data di creazione dell'utenza", + "abusefilter-throttle-editcount": "conteggio delle modifiche", + "abusefilter-throttle-site": "tutto il sito", + "abusefilter-throttle-page": "pagina", + "abusefilter-throttle-none": "(nessuno)", "abusefilter-throttle-details": "Permetti $1 {{PLURAL:$1|azione|azioni}} ogni {{PLURAL:$2|secondo|$2 secondi}}, criteri di raggruppamento: $3", "abusefilter-edit-warn-message": "Messaggio di sistema da usare come avviso:", "abusefilter-edit-warn-other": "Altro messaggio", @@ -271,10 +292,18 @@ "abusefilter-edit-export": "Esporta questo filtro a un'altra wiki", "abusefilter-edit-syntaxok": "Nessun errore di sintassi rilevato.", "abusefilter-edit-syntaxerr": "Errore di sintassi rilevato: $1", + "abusefilter-edit-warn-leave": "Lasciando la pagina perderai tutte le modifiche apportate a questo filtro.", "abusefilter-edit-bad-tags": "Una o più etichette specificate non sono valide.\nLe etichette devono essere corte, non contenere caratteri speciali e non devono essere riservate da altri programmi. Prova a scegliere un altro nome.", "abusefilter-edit-notallowed": "Non sei autorizzato a creare o modificare i filtri del filtro anti abusi", "abusefilter-edit-notallowed-global": "Non sei autorizzato a creare o modificare i filtri globali del filtro anti abusi", "abusefilter-edit-notallowed-global-custom-msg": "I messaggi di avviso personalizzati non sono supportati per i filtri globali", + "abusefilter-edit-invalid-warn-message": "Il messaggio di avviso non può essere lasciato vuoto.", + "abusefilter-edit-invalid-disallow-message": "Il messaggio usato per impedire l'azione non può essere lasciato vuoto.", + "abusefilter-edit-invalid-throttlecount": "Il numero di azioni da consentire deve essere un intero positivo.", + "abusefilter-edit-invalid-throttleperiod": "Il periodo di tempo per il rallentamento deve essere un intero positivo.", + "abusefilter-edit-empty-throttlegroups": "Deve essere specificato almeno un criterio di raggruppamento per il rallentamento.", + "abusefilter-edit-duplicated-throttlegroups": "I criteri di raggruppamento per il rallentamento non possono avere duplicati.", + "abusefilter-edit-invalid-throttlegroups": "I criteri di raggruppamento per il rallentamento specificati non sono validi.", "abusefilter-edit-builder-select": "Scegliere un'opzione per aggiungerla nella posizione del cursore", "abusefilter-edit-builder-group-op-arithmetic": "Operatori aritmetici", "abusefilter-edit-builder-op-arithmetic-addition": "Addizione (+)", @@ -305,7 +334,8 @@ "abusefilter-edit-builder-misc-contains": "La stringa di sinistra contiene quella di destra (contains)", "abusefilter-edit-builder-misc-stringlit": "Stringa (\"\")", "abusefilter-edit-builder-misc-tern": "Operatore ternario (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Condizionale (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Condizionale (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "Condizionale corto (if X then Y end)", "abusefilter-edit-builder-group-funcs": "Funzioni", "abusefilter-edit-builder-funcs-length": "Lunghezza stringa (length)", "abusefilter-edit-builder-funcs-lcase": "Converti in minuscolo (lcase)", @@ -376,12 +406,12 @@ "abusefilter-edit-builder-vars-all-links": "Tutti i collegamenti esterni nel nuovo testo", "abusefilter-edit-builder-vars-added-links": "Tutti i collegamenti esterni aggiunti dalla modifica", "abusefilter-edit-builder-vars-removed-links": "Tutti i collegamenti esterni rimossi dalla modifica", - "abusefilter-edit-builder-vars-old-text": "Vecchio wikitesto della pagina, precedente alla modifica (non più in uso)", - "abusefilter-edit-builder-vars-new-text": "Nuovo wikitesto della pagina, successivo alla modifica", + "abusefilter-edit-builder-vars-old-wikitext": "Vecchio wikitesto della pagina, precedente alla modifica", + "abusefilter-edit-builder-vars-new-wikitext": "Nuovo wikitesto della pagina, successivo alla modifica", "abusefilter-edit-builder-vars-new-pst": "Nuovo testo sorgente della pagina, successivo alla trasformazione presalvataggio", "abusefilter-edit-builder-vars-diff-pst": "Diff unificato delle modifiche apportate, successivo alla trasformazione presalvataggio", "abusefilter-edit-builder-vars-addedlines-pst": "Linee aggiunte nella modifica, successivo alla trasformazione presalvataggio", - "abusefilter-edit-builder-vars-new-text-stripped": "Nuovo testo della pagina, con il markup rimosso", + "abusefilter-edit-builder-vars-new-text": "Nuovo testo della pagina, con il markup rimosso", "abusefilter-edit-builder-vars-new-html": "Sorgente HTML elaborato della nuova versione", "abusefilter-edit-builder-vars-restrictions-edit": "Livello di protezione della pagina per le modifiche", "abusefilter-edit-builder-vars-restrictions-move": "Livello di protezione della pagina per gli spostamenti", @@ -395,10 +425,10 @@ "abusefilter-edit-builder-vars-movedto-restrictions-move": "Livello di protezione dallo spostamento della pagina destinazione dello spostamento", "abusefilter-edit-builder-vars-movedto-restrictions-create": "Livello di protezione dalla creazione della pagina destinazione dello spostamento", "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Livello di protezione dal caricamento del file destinazione dello spostamento", - "abusefilter-edit-builder-vars-old-text-stripped": "Vecchio testo della pagina, privo di qualsiasi formattazione", + "abusefilter-edit-builder-vars-old-text": "Vecchio testo della pagina, privo di qualsiasi formattazione (non più in uso)", "abusefilter-edit-builder-vars-old-links": "Collegamenti nella pagina, prima della modifica", "abusefilter-edit-builder-vars-old-html": "Vecchio wikitesto della pagina, interpretato in HTML (non più in uso)", - "abusefilter-edit-builder-vars-minor-edit": "Indica se la modifica è minore o meno", + "abusefilter-edit-builder-vars-minor-edit": "Indica se la modifica è minore o meno (non più in uso)", "abusefilter-edit-builder-vars-file-sha1": "Hash SHA1 del contenuto del file", "abusefilter-edit-builder-vars-file-size": "Dimensione del file in byte", "abusefilter-edit-builder-vars-file-mime": "Tipo MIME del file", @@ -406,6 +436,8 @@ "abusefilter-edit-builder-vars-file-width": "Larghezza del file in pixel", "abusefilter-edit-builder-vars-file-height": "Altezza del file in pixel", "abusefilter-edit-builder-vars-file-bits-per-channel": "Bit per canale di colore del file", + "abusefilter-edit-builder-vars-wiki-name": "Nome del database del wiki", + "abusefilter-edit-builder-vars-wiki-language": "Codice della lingua del wiki", "abusefilter-filter-log": "Ultime modifiche ai filtri", "abusefilter-history": "Cronologia delle modifiche al filtro anti abusi n. $1", "abusefilter-history-foruser": "Modifiche apportate da $1", @@ -439,13 +471,16 @@ "abusefilter-exception-dividebyzero": "Tentativo di dividere $2 per zero in corrispondenza del carattere $1.", "abusefilter-exception-unrecognisedvar": "Variabile $2 non riconosciuta in corrispondenza del carattere $1.", "abusefilter-exception-notenoughargs": "Argomenti per la funzione $2 chiamata al carattere $1 non sufficienti.\n{{PLURAL:$3|Previsto $3 argomento|Previsti $3 argomenti}}, {{PLURAL:$4|ottenuto|ottenuti}} $4", + "abusefilter-exception-toomanyargs": "Troppi parametri passati alla funzione $2 chiamata al carattere $1.\n{{PLURAL:$3|Previsto|Previsti}} al più $3 {{PLURAL:$3|parametro|parametri}}, ricevuti $4", "abusefilter-exception-regexfailure": "Errore nell'espressione regolare \"$2\" al carattere $1.", - "abusefilter-exception-overridebuiltin": "Sovrascrittura illegale di variabile predefinita \"$2\" al carattere $1.", - "abusefilter-exception-outofbounds": "Richiesta di voce inesistente dell'array $2 (dimensione array = $3) al carattere $1.", + "abusefilter-exception-overridebuiltin": "Sovrascrittura illegale di identificativo predefinito \"$2\" al carattere $1.", + "abusefilter-exception-outofbounds": "Richiesta di elemento inesistente dell'array $2 (dimensione array = $3) al carattere $1.", + "abusefilter-exception-negativeindex": "Gli indici negativi negli array non sono consentiti. Trovato indice \"$2\" al carattere $1.", "abusefilter-exception-notarray": "Richiesta di un elemento di array da un non array al carattere $1.", "abusefilter-exception-unclosedcomment": "Commento non chiuso in corrispondenza del carattere $1.", "abusefilter-exception-invalidiprange": "Intervallo IP \"$2\" non valido al carattere $1", "abusefilter-exception-disabledvar": "La variabile $2 al carattere $1 non è più utilizzabile.", + "abusefilter-exception-variablevariable": "Il primo argomento di set e set_var deve essere stringa, trovato al carattere $1.", "abusefilter-action-tag": "Etichetta", "abusefilter-action-throttle": "Rallenta", "abusefilter-action-warn": "Avvisa", @@ -508,15 +543,16 @@ "abusefilter-examine-noresults": "I parametri di ricerca specificati non hanno prodotto alcun risultato.", "abusefilter-topnav": "'''Filtro anti abusi – Navigazione'''", "abusefilter-topnav-home": "Home", + "abusefilter-topnav-recentchanges": "Ultime modifiche ai filtri", "abusefilter-topnav-test": "Verifica in batch", "abusefilter-topnav-examine": "Esamina le modifiche precedenti", "abusefilter-topnav-log": "Registro del filtro anti abusi", "abusefilter-topnav-tools": "Strumenti di debug", - "abusefilter-topnav-import": "Importa filtro", "abusefilter-log-name": "Filtro anti abusi", "abusefilter-log-header": "Il registro mostra un riassunto delle modifiche effettuate sui filtri.\nPer i dettagli completi, consultare [[Special:AbuseFilter/history|l'elenco]] delle modifiche più recenti agli stessi.", "abusefilter-logentry-create": "$1 {{GENDER:$2|ha creato}} $4 ($5)", "abusefilter-logentry-modify": "$1 {{GENDER:$2|ha modificato}} $4 ($5)", + "abusefilter-log-invalid-filter": "Alcuni degli ID filtro specificati non sono validi.", "abusefilter-log-noresults": "Nessun risultato", "abusefilter-diff-title": "Differenze tra le versioni", "abusefilter-diff-item": "Elemento", @@ -527,13 +563,14 @@ "abusefilter-diff-backhistory": "Torna alla cronologia dei filtri", "abusefilter-diff-prev": "Differenza precedente", "abusefilter-diff-next": "Differenza successiva", - "abusefilter-import-intro": "È possibile utilizzare questa interfaccia per importare filtri da altri siti wiki.\nSul sito wiki d'origine, fare clic su \"{{int:abusefilter-edit-export}}\" sotto \"{{int:abusefilter-edit-tools}}\" nell'interfaccia di modifica.\nCopiare dalla casella che appare e copiare in questa casella, quindi fare clic su \"{{int:abusefilter-import-submit}}\".", + "abusefilter-import-intro": "È possibile utilizzare questa interfaccia per importare filtri da altri siti wiki.\nSul sito wiki d'origine, fare clic su \"{{int:abusefilter-edit-export}}\" sotto \"{{int:abusefilter-edit-tools}}\" nell'interfaccia di modifica.\nCopiare dalla casella che appare e incollare in questa casella, quindi fare clic su \"{{int:abusefilter-import-submit}}\".", "abusefilter-import-submit": "Importa dati", + "abusefilter-import-invalid-data": "I dati che hai provato a importare non sono validi", "abusefilter-group-default": "Predefinito", "abusefilter-http-error": "Si è verificato un errore HTTP: $1.", - "abusefilter-view-private-submit": "Visualizza i dettagli privati", - "abusefilter-view-private": "Visualizza i dettagli privati", - "abusefilter-view-private-reason": "Motivazione per visualizzare i dettagli privati:", + "abusefilter-view-privatedetails-submit": "Visualizza i dettagli privati", + "abusefilter-view-privatedetails-legend": "Visualizza i dettagli privati", + "abusefilter-view-privatedetails-reason": "Motivazione per visualizzare i dettagli privati:", "abusefilter-log-details-id": "ID registro", "abusefilter-invalid-request": "Richiesta non valida! È necessario accedere ai dettagli privati del registro tramite il modulo su [[Special:AbuseLog/$1]] e fornire una motivazione.", "abusefilter-invalid-request-noid": "Richiesta non valida! È necessario accedere ai dettagli privati del registro attraverso il modulo sulla pagina dei dettagli del registro abusi fornendo una motivazione.", diff --git a/AbuseFilter/i18n/ja.json b/AbuseFilter/i18n/ja.json index b2cbae17..a3f40fe9 100644 --- a/AbuseFilter/i18n/ja.json +++ b/AbuseFilter/i18n/ja.json @@ -1,34 +1,45 @@ { "@metadata": { "authors": [ + "2nd-player", + "Aefgh39622", + "Afaz", "Aotake", + "Azeha", "Fievarsty", "Fryed-peach", "Hosiryuhosi", + "Hzy980512", + "Kkairri", + "Marine-Blue", + "Matma Rex", "Mizusumashi", "Muttley", "Ohgi", + "Omotecho", + "Otokoume", "Penn Station", - "Shirayuki", - "Yanajin66", - "青子守歌", + "Reiwa period", "Rxy", + "Shirayuki", + "Siglite3", + "Suchichi02", + "Sujiniku", + "Suyama", "Takot", - "Otokoume", - "2nd-player", "W.CC", - "Sujiniku", - "Azeha", - "Matma Rex", - "Aefgh39622", - "Omotecho", + "Whym", + "Yanajin66", "Yusuke1109", - "Suyama" + "Yuukin0248", + "おはぐろ蜻蛉", + "そらたこ", + "青子守歌" ] }, "abusefilter-desc": "編集に対して、自動的な経験則を適用する", - "abusefilter": "不正利用フィルター設定", - "abuselog": "不正利用記録", + "abusefilter": "不正利用フィルター管理", + "abuselog": "不正利用フィルター記録", "abusefilter-intro": "不正利用フィルターの管理インターフェイスにようこそ。\n不正利用フィルターは、あらゆる操作に対して自動的な発見的方法を適用する、自動化されたソフトウェア機構です。\nこのインターフェイスでは、定義済みのフィルターを一覧表示してそれらを変更できます。", "abusefilter-mustviewprivateoredit": "セキュリティ上の理由から、不正利用フィルターを閲覧または変更できる権限を持つ利用者だけがこのインターフェイスを使用できます。", "abusefilter-warning": "'''警告:''' 行われた操作は自動的に有害と判断されました。\n建設的ではない操作は速やかに差し戻されます。\n被害程度が大きい破壊的編集や頻繁な破壊行為は、アカウントまたはIPアドレスのブロックにつながります。\n行なった操作が確かに建設的だと考える場合は、もう一度投稿してください。\n操作に対して発動した違反規則の概略は次の通りです: $1", @@ -39,35 +50,41 @@ "abusefilter-blocker": "不正利用フィルター", "abusefilter-blockreason": "不正利用フィルターによる自動的なブロック。\n発動した規則の説明: $1", "abusefilter-degroupreason": "不正利用フィルターによる自動的な権限の剥奪。\n規則の説明: $1", + "abusefilter-blockautopromotereason": "不正利用フィルターによる自動承認される権限の承認延長。\n規則の説明: $1", "abusefilter-accountreserved": "このアカウントは不正利用フィルターによる使用のため予約されています。", - "right-abusefilter-modify": "不正利用フィルターを変更", + "right-abusefilter-modify": "不正利用フィルターを作成/変更", "right-abusefilter-view": "不正利用フィルターを閲覧", "right-abusefilter-log": "不正利用記録を閲覧", "right-abusefilter-log-detail": "不正利用記録の詳細項目を閲覧", - "right-abusefilter-private": "不正利用記録内の非公開データを閲覧", - "right-abusefilter-private-log": "不正利用フィルター非公開記録の調査記録を閲覧", + "right-abusefilter-privatedetails": "不正利用記録内の非公開データを閲覧", + "right-abusefilter-privatedetails-log": "不正利用フィルター非公開記録の調査記録を閲覧", "right-abusefilter-modify-restricted": "制限された操作を含む不正利用フィルターを変更", "right-abusefilter-revert": "指定した不正利用フィルターによるすべての変更を差し戻す", "right-abusefilter-view-private": "非公開の不正利用フィルターを閲覧", "right-abusefilter-log-private": "非公開の不正利用フィルター記録を閲覧", "right-abusefilter-hide-log": "不正利用記録の項目を隠す", "right-abusefilter-hidden-log": "隠された不正利用記録を閲覧", - "right-abusefilter-modify-global": "グローバル不正利用フィルターを作成または変更", + "right-abusefilter-modify-global": "グローバル不正利用フィルターを作成/変更", "action-abusefilter-modify": "不正利用フィルターの変更", "action-abusefilter-view": "不正利用フィルターの閲覧", "action-abusefilter-log": "不正利用記録の閲覧", "action-abusefilter-log-detail": "不正利用記録の詳細項目の閲覧", - "action-abusefilter-private": "不正利用フィルターの非公開記録を調査", - "action-abusefilter-private-log": "不正利用フィルター非公開記録の調査記録を閲覧", + "action-abusefilter-privatedetails": "不正利用フィルターの非公開記録の調査", + "action-abusefilter-privatedetails-log": "不正利用フィルター非公開記録の調査記録の閲覧", "action-abusefilter-modify-restricted": "制限された操作を含む不正利用フィルターの変更", "action-abusefilter-revert": "指定した不正利用フィルターによるすべての変更の差し戻し", "action-abusefilter-view-private": "非公開の不正利用フィルターの閲覧", "action-abusefilter-log-private": "非公開の不正利用フィルター記録の閲覧", - "abusefilter-log": "不正利用フィルター記録", + "action-abusefilter-hide-log": "不正利用記録の項目を隠す", + "action-abusefilter-hidden-log": "隠された不正利用記録の閲覧", + "action-abusefilter-modify-global": "グローバル不正利用フィルターの作成/変更", "abusefilter-log-summary": "この記録はフィルターが発動した全操作の一覧を表示しています。", "abusefilter-log-search": "不正利用記録を検索", "abusefilter-log-search-user": "利用者:", - "abusefilter-log-search-filter": "フィルターID (\"|\" 区切り):", + "abusefilter-log-search-group": "フィルターグループ:", + "abusefilter-log-search-group-any": "任意", + "abusefilter-log-search-filter": "フィルターID:", + "abusefilter-log-search-filter-help": "パイプ記号で区切ります。グローバルフィルターは先頭に「$1」を付けます。", "abusefilter-log-search-title": "ページ名:", "abusefilter-log-search-wiki": "ウィキ:", "abusefilter-log-search-impact": "影響:", @@ -78,7 +95,10 @@ "abusefilter-log-search-entries-all": "すべての項目", "abusefilter-log-search-entries-hidden": "非表示項目のみ", "abusefilter-log-search-entries-visible": "表示項目のみ", + "abusefilter-log-search-action-label": "トリガーアクション:", "abusefilter-log-search-action-other": "その他", + "abusefilter-log-search-action-any": "任意", + "abusefilter-log-search-action-taken-label": "操作の種類:", "abusefilter-log-search-action-taken-any": "任意", "abusefilter-log-search-submit": "検索", "abusefilter-log-entry": "$1: $2 が $4 で「$3」操作を{{GENDER:$8|行い}}不正利用フィルターが発動しました。\n対処操作: $5、\nフィルター解説: $6", @@ -93,20 +113,23 @@ "abusefilter-log-details-var": "変数", "abusefilter-log-details-val": "値", "abusefilter-log-details-vars": "対処操作の設定", - "abusefilter-log-details-private": "非公開記録の詳細", + "abusefilter-log-details-privatedetails": "非公開記録の詳細", "abusefilter-log-details-ip": "発信元のIPアドレス", "abusefilter-log-details-checkuser": "利用者の調査", "abusefilter-log-noactions": "なし", "abusefilter-log-details-diff": "編集でなされた変更", "abusefilter-log-linkoncontribs": "不正利用記録", "abusefilter-log-linkoncontribs-text": "{{GENDER:$1|この利用者}}の不正利用記録", - "abusefilter-log-linkonhistory": "編集フィルター記録を表示", - "abusefilter-log-hidden": "(隠された項目)", + "abusefilter-log-linkonhistory": "不正利用記録を閲覧", + "abusefilter-log-linkonhistory-text": "このページの不正利用記録を表示", + "abusefilter-log-linkonundelete": "不正利用記録を閲覧", + "abusefilter-log-linkonundelete-text": "このページの不正利用記録を閲覧", "abusefilter-log-hidden-implicit": "(版が削除されているため非表示)", "abusefilter-log-cannot-see-details": "この項目の詳細を見る権限がありません。", - "abusefilter-log-cannot-see-private-details": "あなたは非公開記録を閲覧する権限がありません", + "abusefilter-log-cannot-see-privatedetails": "あなたは非公開記録を閲覧する権限がありません", "abusefilter-log-nonexistent": "指定された ID の項目は存在しません。", "abusefilter-log-details-hidden": "この項目は公開記録から隠されているため、あなたは詳細を閲覧できません。", + "abusefilter-log-details-hidden-implicit": "関連付けられている版は公開されていないため、このエントリの詳細を表示することはできません。", "abusefilter-log-private-not-included": "指定したフィルターIDのうち一つ以上はプライベート状態です。プライベートになっているフィルターの詳細を見ることは許可されていないため、これらのフィルターは検索されません。", "abusefilter-log-hide-legend": "記録項目を隠す", "abusefilter-log-hide-id": "記録項目ID:", @@ -114,13 +137,19 @@ "abusefilter-log-hide-reason": "理由:", "abusefilter-log-hide-reason-other": "その他、または追加の理由:", "abusefilter-log-hide-forbidden": "不正利用記録の項目を隠す権限がありません。", + "abusefilter-log-entry-suppress": "$1が$3を{{GENDER:$2|非表示にしました}}", + "abusefilter-log-entry-unsuppress": "$1が$3を{{GENDER:$2|非表示解除しました}}", "logentry-abusefilter-hit": "$1 が $3 で「$5」操作を{{GENDER:$2|行い}}、 $4 が{{GENDER:$2|作動}}しました。対処操作: $6 ($7)", "log-action-filter-abusefilter": "フィルター変更の種類:", "log-action-filter-abusefilter-create": "フィルターの新規作成", "log-action-filter-abusefilter-modify": "フィルターの変更", + "log-action-filter-suppress-abuselog": "不正利用記録の秘匿", + "log-action-filter-rights-blockautopromote": "自動昇格を阻止", + "log-action-filter-rights-restoreautopromote": "自動昇格を復元", "logentry-abusefilterprivatedetails-access": "$1 は $3 の非公開記録を{{GENDER:$2|取得しました}}。", + "logentry-rights-blockautopromote": "$1 が {{GENDER:$4|$3}} の自動昇格を $5 {{GENDER:$2|ブロック}}しました。", + "logentry-rights-restoreautopromote": "$1 が {{GENDER:$4|$3}} の自動昇格条件を{{GENDER:$2|復元}}しました。", "abusefilterprivatedetails-log-name": "不正利用フィルター非公開記録の調査記録", - "abusefilter-management": "不正利用フィルター管理", "abusefilter-list": "すべてのフィルター", "abusefilter-list-id": "フィルターID", "abusefilter-list-pattern": "パターン", @@ -139,8 +168,10 @@ "abusefilter-enabled": "有効", "abusefilter-deleted": "削除", "abusefilter-disabled": "無効", + "abusefilter-throttled": "速度を制限", "abusefilter-hitcount": "$1 {{PLURAL:$1|件}}の一致", "abusefilter-new": "フィルターの新規作成", + "abusefilter-import-button": "フィルターのインポート", "abusefilter-return": "フィルター管理に戻る", "abusefilter-status-global": "グローバル", "abusefilter-list-options": "オプション", @@ -152,30 +183,38 @@ "abusefilter-list-options-scope-local": "ローカル規則のみ", "abusefilter-list-options-scope-global": "グローバル規則のみ", "abusefilter-list-options-scope-all": "ローカルおよびグローバル規則", + "abusefilter-list-options-further-options": "その他のオプション:", "abusefilter-list-options-hidedisabled": "無効化されたフィルターを隠す", + "abusefilter-list-options-hideprivate": "非公開のフィルターを隠す", + "abusefilter-list-options-searchfield": "ルール内を検索:", "abusefilter-list-options-searchpattern": "パターンを挿入", "abusefilter-list-options-searchoptions": "検索モード:", + "abusefilter-list-options-search-like": "文字検索", "abusefilter-list-options-search-rlike": "正規表現", "abusefilter-list-options-search-irlike": "正規表現で大文字小文字を区別しない", + "abusefilter-list-invalid-searchmode": "指定した検索モードは無効です。", "abusefilter-list-regexerror": "検索中にエラーが発生しました。正規表現シンタックスエラー。", "abusefilter-list-options-submit": "更新", "abusefilter-tools-text": "不正利用フィルターの作成およびデバッグに役立つ場合があるツールです。", "abusefilter-tools-expr": "式の試験ツール", "abusefilter-tools-submitexpr": "評価", + "abusefilter-tools-syntax-error": "フィルターの構文が無効です。", "abusefilter-tools-reautoconfirm": "自動承認ステータスを復元", "abusefilter-tools-reautoconfirm-user": "利用者:", "abusefilter-tools-reautoconfirm-submit": "再自動承認", + "abusefilter-tools-restoreautopromote": "不正利用フィルターツールで自動昇格条件を復元。", "abusefilter-reautoconfirm-none": "その利用者は{{GENDER:$1|自動承認ステータス}}を停止されていません。", "abusefilter-reautoconfirm-notallowed": "あなたは自動承認ステータスを復元することが許可されていません。", "abusefilter-reautoconfirm-done": "利用者の自動承認ステータスが復元されました", - "abusefilter-status": "最近の$1{{PLURAL:$1|操作}}のうち、$2件($3%)が$4の条件制限に{{PLURAL:$2|達しました}}。$5件($6%)に対して、現在有効なフィルターの1つが{{PLURAL:$5|発動しました}}。", + "abusefilter-status": "最近の$1{{PLURAL:$1|操作}}のうち、$2件($3%)が$4の条件制限に{{PLURAL:$2|達しました}}。$5件($6%)に対して、少なくとも現在有効なフィルターの1つが{{PLURAL:$5|発動しました}}。", "abusefilter-edit": "不正利用フィルターを編集中", "abusefilter-edit-subtitle": "フィルター $1 を編集中", "abusefilter-edit-subtitle-new": "フィルターを作成中", + "abusefilter-edit-token-not-match": "編集は保存されませんでした! もう一度保存処理をしてください。", "abusefilter-edit-oldwarning": "<strong>あなたはこのフィルターの古い版を編集しています。引用されている統計は最新版のフィルターのものです。あなたの変更を保存すると、あなたが編集している版以降の変更をすべて上書きしてしまいます。</strong> • [[Special:AbuseFilter/history/$2|このフィルターの履歴に戻る]]", + "abusefilter-edit-oldwarning-view": "<strong>フィルターの古いバージョンを表示しています。\n提示されている統計は最新版のフィルターに基づくものです。</strong> •\n[[Special:AbuseFilter/history/$2|フィルターの変更履歴に戻る]]", "abusefilter-edit-status-label": "統計:", - "abusefilter-edit-status": "最近の$1{{PLURAL:$1|操作}}のうち、このフィルターは$2件($3%)に対して発動しました。", - "abusefilter-edit-status-profile": "最近の$1{{PLURAL:$1|操作}}のうち、このフィルターは$2件($3%)に対して発動しました。平均して、実行時間は$4ミリ秒で$5件の条件制限を消費しました。", + "abusefilter-edit-status": "最近の$1{{PLURAL:$1|操作}}のうち、このフィルターは$2件($3%)に対して発動しました。平均して、実行時間は$4ミリ秒で$5件の条件制限を消費しました。", "abusefilter-edit-throttled-warning": "'''警告:''' このフィルタは自動的に有害なフラグが立てられました。安全対策として、以下のアクションは実行されません($1)。\nこの制限を解除する条件を確認して[[mw:Extension:AbuseFilter/Conditions|最適化]]してください", "abusefilter-edit-new": "新規フィルター", "abusefilter-edit-save": "フィルターを保存", @@ -190,6 +229,7 @@ "abusefilter-edit-hidden": "このフィルターの詳細を公開しない", "abusefilter-edit-global": "グローバル フィルター", "abusefilter-edit-rules": "条件:", + "abusefilter-edit-field-conditions": "条件", "abusefilter-edit-notes": "メモ:", "abusefilter-edit-lastmod": "フィルターの最終変更:", "abusefilter-edit-lastmod-text": "$1に、$2による", @@ -200,31 +240,53 @@ "abusefilter-edit-action-blockautopromote": "利用者の自動承認ステータスを取り消す", "abusefilter-edit-action-degroup": "利用者をすべての特権グループから除く", "abusefilter-edit-action-block": "利用者および/またはIPアドレスを編集ブロックする", - "abusefilter-edit-action-blocktalk": "利用者やIPユーザーが自分のトークページを編集できないようにする", + "abusefilter-edit-action-blocktalk": "利用者やIP利用者が自分のトークページを編集できないようにする", "abusefilter-edit-action-throttle": "利用者が設定された速度限界を越えた場合のみ、対処操作を発動する", "abusefilter-edit-action-rangeblock": "利用者の発信元を該当する IP レンジでブロックする", "abusefilter-edit-action-tag": "後で再検討するために編集にタグを付ける", "abusefilter-edit-throttle-count": "許可される操作数:", - "abusefilter-edit-throttle-period": "期間:", - "abusefilter-edit-throttle-groups": "制限をグループ化する:\n:''(1行に1つ、複数項目はカンマ区切り)''", - "abusefilter-edit-throttle-ip": "IP アドレス", - "abusefilter-edit-throttle-user": "利用者アカウント", - "abusefilter-edit-throttle-creationdate": "アカウント作成時のサーバ時刻", - "abusefilter-edit-throttle-editcount": "編集回数", - "abusefilter-edit-throttle-site": "サイト全体", - "abusefilter-edit-throttle-page": "ページ", + "abusefilter-edit-throttle-period": "期間 (秒):", + "abusefilter-edit-throttle-groups": "制限をグループ化する:", + "abusefilter-edit-throttle-groups-help": "$1 を参照してください。", + "abusefilter-edit-throttle-groups-help-text": "mediawiki.orgのヘルプ文書", + "abusefilter-edit-throttle-hidden-placeholder": "カンマ区切りで AND文 とつなぎ、改行で OR文 とつなぐ。", + "abusefilter-edit-throttle-placeholder": "カンマ区切りで AND 文とつなぎ、1件ずつ追加して OR 文とつなぐ。", + "abusefilter-throttle-ip": "IP アドレス", + "abusefilter-throttle-user": "利用者アカウント", + "abusefilter-throttle-range": "/16 レンジ", + "abusefilter-throttle-creationdate": "アカウント作成日付", + "abusefilter-throttle-editcount": "編集回数", + "abusefilter-throttle-site": "サイト全体", + "abusefilter-throttle-page": "ページ", + "abusefilter-throttle-none": "(なし)", + "abusefilter-throttle-details": "毎 $2 {{PLURAL:$2|秒|秒}} $1 回の{{PLURAL:$1|操作|操作}}を許可、制限グループ化の値:$3", "abusefilter-edit-warn-message": "警告に使用するシステムメッセージ:", "abusefilter-edit-warn-other": "他のメッセージ", - "abusefilter-edit-warn-other-label": "他のメッセージのページ名:\n:''(接頭辞 MediaWiki は省く)''", + "abusefilter-edit-warn-other-label": "他のメッセージのページ名:\n:''(接頭辞 \"MediaWiki:\" は省く)''", "abusefilter-edit-warn-actions": "操作:", - "abusefilter-edit-warn-preview": "選択したメッセージをプレビュー", + "abusefilter-edit-warn-preview": "選択メッセージのプレビューを表示/非表示", "abusefilter-edit-warn-edit": "選択したメッセージを作成または編集", + "abusefilter-edit-disallow-message": "不許可に使用するシステムメッセージ:", + "abusefilter-edit-disallow-other": "他のメッセージ", + "abusefilter-edit-disallow-other-label": "他のメッセージのページ名:\n:''(接頭辞 \"MediaWiki:\" は省く)''", + "abusefilter-edit-disallow-actions": "操作:", + "abusefilter-edit-disallow-preview": "選択メッセージのプレビューを表示/非表示", + "abusefilter-edit-disallow-edit": "選択したメッセージを作成または編集", "abusefilter-edit-tag-tag": "適用する[[Special:Tags|タグ]]:", + "abusefilter-edit-tag-placeholder": "タグの追加 (1件ずつ、もしくはカンマ区切り)", + "abusefilter-edit-tag-hidden-placeholder": "タグの追加 (カンマ区切り)", + "abusefilter-edit-block-anon-durations": "匿名利用者のブロック期間:", + "abusefilter-edit-block-user-durations": "登録利用者のブロック期間:", + "abusefilter-block-anon": "匿名利用者をブロック", + "abusefilter-block-user": "登録利用者をブロック", + "abusefilter-block-talk": "自分のトークページの編集禁止", "abusefilter-edit-denied": "このフィルターは非公開とされているため、あなたは詳細を閲覧できません。", "abusefilter-edit-main": "フィルターの設定", "abusefilter-edit-done-subtitle": "フィルターを編集しました", "abusefilter-edit-done": "[[Special:AbuseFilter/$1|フィルター $3]]への[[Special:AbuseFilter/history/$1/diff/prev/$2|変更]]を保存しました。", "abusefilter-edit-badsyntax": "指定したフィルターには構文エラーがあります。\nパーサーからの出力: <pre>$1</pre>", + "abusefilter-edit-missingfields": "$1の入力は必須です。", + "abusefilter-edit-deleting-enabled": "稼動中のフィルターを削除することはできません。", "abusefilter-edit-restricted": "このフィルターは1つ以上の制限された操作を含んでいるため、あなたには編集できません。\n制限された操作を追加する権限のある利用者にあなたの望む変更をしてくれるよう頼んでください。", "abusefilter-edit-viewhistory": "このフィルターの履歴を閲覧", "abusefilter-edit-history": "履歴:", @@ -236,10 +298,18 @@ "abusefilter-edit-export": "このフィルターを別のウィキにエクスポートする", "abusefilter-edit-syntaxok": "構文エラーは検出されませんでした。", "abusefilter-edit-syntaxerr": "構文エラーを検出しました: $1", + "abusefilter-edit-warn-leave": "ページを離れると、このフィルターに加えた変更が失われます。", "abusefilter-edit-bad-tags": "指定したタグには無効なものが1つ以上あります。\nタグは短くする必要があり、特殊文字を含まず、他のソフトウェアと重複してはいけません。新しいタグ名を選択してみてください。", "abusefilter-edit-notallowed": "あなたは不正利用フィルターを作成または編集することが許可されていません", "abusefilter-edit-notallowed-global": "あなたはグローバル不正利用フィルターを作成または編集することが許可されていません", - "abusefilter-edit-notallowed-global-custom-msg": "グローバルフィルターはカスタムの警告メッセージには対応していません", + "abusefilter-edit-notallowed-global-custom-msg": "グローバルフィルターは警告メッセージや不許可メッセージのカスタマイズには対応していません", + "abusefilter-edit-invalid-warn-message": "警告メッセージは空白のままにはできません。", + "abusefilter-edit-invalid-disallow-message": "不許可メッセージは空白のままにはできません。", + "abusefilter-edit-invalid-throttlecount": "スロットルアクションカウントは正の整数である必要があります。", + "abusefilter-edit-invalid-throttleperiod": "スロットル期間は正の整数である必要があります。", + "abusefilter-edit-empty-throttlegroups": "少なくとも1つのスロットルグループを選択する必要があります。", + "abusefilter-edit-duplicated-throttlegroups": "スロットルグループは重複できません。", + "abusefilter-edit-invalid-throttlegroups": "指定されたスロットルグループは無効です。", "abusefilter-edit-builder-select": "カーソルの位置に追加するものを選択", "abusefilter-edit-builder-group-op-arithmetic": "算術演算子", "abusefilter-edit-builder-op-arithmetic-addition": "加算 (+)", @@ -249,8 +319,10 @@ "abusefilter-edit-builder-op-arithmetic-modulo": "剰余 (%)", "abusefilter-edit-builder-op-arithmetic-pow": "累乗 (**)", "abusefilter-edit-builder-group-op-comparison": "比較演算子", - "abusefilter-edit-builder-op-comparison-equal": "同値 (==)", - "abusefilter-edit-builder-op-comparison-notequal": "不等 (!=)", + "abusefilter-edit-builder-op-comparison-equal": "同じ値 (==)", + "abusefilter-edit-builder-op-comparison-equal-strict": "同じ値と型 (===)", + "abusefilter-edit-builder-op-comparison-notequal": "等しくない値 (!=)", + "abusefilter-edit-builder-op-comparison-notequal-strict": "等しくない値と型 (!==)", "abusefilter-edit-builder-op-comparison-lt": "未満 (<)", "abusefilter-edit-builder-op-comparison-gt": "超過 (>)", "abusefilter-edit-builder-op-comparison-lte": "以下 (<=)", @@ -268,49 +340,62 @@ "abusefilter-edit-builder-misc-contains": "左の文字列が右の文字列を含む (contains)", "abusefilter-edit-builder-misc-stringlit": "文字列リテラル (\"\")", "abusefilter-edit-builder-misc-tern": "三項演算子 (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "条件式 (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "条件式 (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "短縮条件式 (if X then Y end)", "abusefilter-edit-builder-group-funcs": "関数", "abusefilter-edit-builder-funcs-length": "文字列の長さ (length)", "abusefilter-edit-builder-funcs-lcase": "小文字化 (lcase)", "abusefilter-edit-builder-funcs-ucase": "大文字化 (ucase)", "abusefilter-edit-builder-funcs-ccnorm": "混乱しやすい文字を正規化 (ccnorm)", + "abusefilter-edit-builder-funcs-ccnorm-contains-any": "ORモードで文字列中で複数の部分文字列を正規化および検索 (ccnorm_contains_any)", + "abusefilter-edit-builder-funcs-ccnorm-contains-all": "ANDモードで文字列中で複数の部分文字列を正規化および検索 (ccnorm_contains_any)", "abusefilter-edit-builder-funcs-rmdoubles": "重複する文字を削除 (rmdoubles)", "abusefilter-edit-builder-funcs-specialratio": "特殊文字の数 / 全体の文字数 (specialratio)", "abusefilter-edit-builder-funcs-norm": "正規化 (norm)", "abusefilter-edit-builder-funcs-count": "文字列 X が文字列 Y 中に出現する回数 (count)", "abusefilter-edit-builder-funcs-rcount": "正規表現 X が文字列 Y に出現する回数 (rcount)", + "abusefilter-edit-builder-funcs-get_matches": "各キャプチャ グループのテキスト内での正規表現の一致の配列 (get_matches)", "abusefilter-edit-builder-funcs-rmwhitespace": "空白類を除去 (rmwhitespace)", "abusefilter-edit-builder-funcs-rmspecials": "特殊文字を除去 (rmspecials)", "abusefilter-edit-builder-funcs-ip_in_range": "IPアドレスがその範囲にあるか (ip_in_range)", - "abusefilter-edit-builder-funcs-contains-any": "文字列中で複数の部分文字列を検索 (contains_any)", + "abusefilter-edit-builder-funcs-contains-any": "ORモードで文字列中で複数の部分文字列を検索。(contains_any)", + "abusefilter-edit-builder-funcs-contains-all": "ANDモードで文字列中で複数の部分文字列を検索。(contains_all)", + "abusefilter-edit-builder-funcs-equals-to-any": "指定された引数が次の引数 (equals_to_any) のいずれかに等しい (===) かどうかを確認", "abusefilter-edit-builder-funcs-substr": "部分文字列 (substr)", "abusefilter-edit-builder-funcs-strpos": "文字列中での部分文字列の位置 (strpos)", "abusefilter-edit-builder-funcs-str_replace": "部分文字列を文字列で置換 (str_replace)", "abusefilter-edit-builder-funcs-rescape": "文字列を正規表現のリテラルとしてエスケープ (rescape)", "abusefilter-edit-builder-funcs-set_var": "変数を設定 (set_var)", + "abusefilter-edit-builder-funcs-sanitize": "HTMLエンティティをUnicode文字に正規化 (sanitize)", "abusefilter-edit-builder-group-vars": "変数", "abusefilter-edit-builder-vars-accountname": "アカウント名 (アカウント作成時のみ)", "abusefilter-edit-builder-vars-timestamp": "変更のUnixタイムスタンプ", + "abusefilter-edit-builder-vars-timestamp-expanded": "記録のタイムスタンプ", "abusefilter-edit-builder-vars-action": "操作", "abusefilter-edit-builder-vars-addedlines": "編集で追加された行", "abusefilter-edit-builder-vars-delta": "編集による変更サイズ", - "abusefilter-edit-builder-vars-diff": "編集による変更の統一差分", + "abusefilter-edit-builder-vars-diff": "編集で変更された部分の Unified diff 形式差分", "abusefilter-edit-builder-vars-newsize": "新しいページのサイズ", "abusefilter-edit-builder-vars-oldsize": "古いページのサイズ", + "abusefilter-edit-builder-vars-old-content-model": "古いコンテンツモデル", + "abusefilter-edit-builder-vars-new-content-model": "新しいコンテンツモデル", "abusefilter-edit-builder-vars-removedlines": "編集で削除された行", "abusefilter-edit-builder-vars-summary": "編集の要約や理由", "abusefilter-edit-builder-vars-page-id": "ページ ID", "abusefilter-edit-builder-vars-page-ns": "ページの名前空間", "abusefilter-edit-builder-vars-page-title": "ページ名 (名前空間を除く)", "abusefilter-edit-builder-vars-page-prefixedtitle": "完全なページ名", + "abusefilter-edit-builder-vars-page-age": "ページの生存期間 (秒)", "abusefilter-edit-builder-vars-movedfrom-id": "移動元のページID", "abusefilter-edit-builder-vars-movedfrom-ns": "移動元ページの名前空間", "abusefilter-edit-builder-vars-movedfrom-title": "移動元のページ名", "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "移動元の完全なページ名", + "abusefilter-edit-builder-vars-movedfrom-age": "移動元ページの存在歴(秒単位)", "abusefilter-edit-builder-vars-movedto-id": "移動先のページID", "abusefilter-edit-builder-vars-movedto-ns": "移動先ページの名前空間", "abusefilter-edit-builder-vars-movedto-title": "移動先のページ名", "abusefilter-edit-builder-vars-movedto-prefixedtitle": "移動先の完全なページ名", + "abusefilter-edit-builder-vars-movedto-age": "移動先ページの存在歴(秒単位)", "abusefilter-edit-builder-vars-user-editcount": "利用者の編集回数", "abusefilter-edit-builder-vars-user-age": "利用者アカウントの登録期間", "abusefilter-edit-builder-vars-user-name": "利用者のアカウント名", @@ -320,24 +405,36 @@ "abusefilter-edit-builder-vars-user-emailconfirm": "メールアドレスを確認した時刻", "abusefilter-edit-builder-vars-recent-contributors": "直前10人のページへの投稿者", "abusefilter-edit-builder-vars-first-contributor": "ページヘの最初の投稿者", + "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "移動元ページに貢献した最近の10人の利用者", + "abusefilter-edit-builder-vars-movedfrom-first-contributor": "移動元ページに貢献した1番目の利用者", + "abusefilter-edit-builder-vars-movedto-recent-contributors": "移動目標ページに貢献した最近の10人の利用者", + "abusefilter-edit-builder-vars-movedto-first-contributor": "移動先ページに貢献した1番目の利用者", "abusefilter-edit-builder-vars-all-links": "新しい本文中のすべての外部リンク", "abusefilter-edit-builder-vars-added-links": "編集で追加されたすべての外部リンク", "abusefilter-edit-builder-vars-removed-links": "編集で除去されたすべての外部リンク", - "abusefilter-edit-builder-vars-old-text": "編集前の古いウィキテキスト", - "abusefilter-edit-builder-vars-new-text": "編集後の新しいウィキテキスト", + "abusefilter-edit-builder-vars-old-wikitext": "編集前の古いウィキテキスト", + "abusefilter-edit-builder-vars-new-wikitext": "編集後の新しいウィキテキスト", "abusefilter-edit-builder-vars-new-pst": "保存前変換適用後の新しいウィキテキスト", - "abusefilter-edit-builder-vars-diff-pst": "編集による変更のUnified diff 形式差分 (pre-saveの変換前)", + "abusefilter-edit-builder-vars-diff-pst": "編集で変更された部分の Unified diff 形式差分(pre-save変換前)", "abusefilter-edit-builder-vars-addedlines-pst": "編集で追加された行 (pre-saveの変換前)", - "abusefilter-edit-builder-vars-new-text-stripped": "マークアップを除く新しい本文", + "abusefilter-edit-builder-vars-new-text": "マークアップを除く新しい本文", "abusefilter-edit-builder-vars-new-html": "新しい版のパース済みHTMLソース", "abusefilter-edit-builder-vars-restrictions-edit": "ページの編集保護レベル", "abusefilter-edit-builder-vars-restrictions-move": "ページの移動保護レベル", "abusefilter-edit-builder-vars-restrictions-create": "ページの作成保護レベル", "abusefilter-edit-builder-vars-restrictions-upload": "ファイルのアップロード保護レベル", - "abusefilter-edit-builder-vars-old-text-stripped": "マークアップを除く古い本文", + "abusefilter-edit-builder-vars-movedfrom-restrictions-edit": "移動元ページの編集保護レベル", + "abusefilter-edit-builder-vars-movedfrom-restrictions-move": "移動元ページの移動保護レベル", + "abusefilter-edit-builder-vars-movedfrom-restrictions-create": "移動元ページの作成保護レベル", + "abusefilter-edit-builder-vars-movedfrom-restrictions-upload": "移動元ファイルのアップロード保護レベル", + "abusefilter-edit-builder-vars-movedto-restrictions-edit": "移動先ページの保護レベルを編集", + "abusefilter-edit-builder-vars-movedto-restrictions-move": "移動先ページの移動保護レベル", + "abusefilter-edit-builder-vars-movedto-restrictions-create": "移動先ページの保護を作成", + "abusefilter-edit-builder-vars-movedto-restrictions-upload": "移動先ファイルのアップロード保護", + "abusefilter-edit-builder-vars-old-text": "マークアップを除いた、使用されていない古い本文", "abusefilter-edit-builder-vars-old-links": "編集前のページに含まれていたリンク", "abusefilter-edit-builder-vars-old-html": "古いウィキテキストから生成されたHTML", - "abusefilter-edit-builder-vars-minor-edit": "その編集が細部の編集かどうか", + "abusefilter-edit-builder-vars-minor-edit": "その編集が細部の編集かどうか (廃止)", "abusefilter-edit-builder-vars-file-sha1": "ファイルのSHA1ハッシュ", "abusefilter-edit-builder-vars-file-size": "ファイルのサイズ (バイト)", "abusefilter-edit-builder-vars-file-mime": "このファイルのMIMEタイプ", @@ -345,6 +442,8 @@ "abusefilter-edit-builder-vars-file-width": "ファイルのピクセル単位での幅", "abusefilter-edit-builder-vars-file-height": "ファイルのピクセル単位での高さ", "abusefilter-edit-builder-vars-file-bits-per-channel": "ファイルのカラーチャネル毎のビット数", + "abusefilter-edit-builder-vars-wiki-name": "ウィキのデータベース名", + "abusefilter-edit-builder-vars-wiki-language": "Wikiの言語コード", "abusefilter-filter-log": "フィルターの最近の更新", "abusefilter-history": "不正利用フィルター #$1 の変更履歴", "abusefilter-history-foruser": "$1 による変更", @@ -374,14 +473,19 @@ "abusefilter-exception-unclosedstring": "$1文字目から始まる文字列が閉じられていません。", "abusefilter-exception-invalidoperator": "$1文字目に無効な演算子「$2」があります。", "abusefilter-exception-unrecognisedtoken": "$1文字目に認識できないトークン「$2」があります。", - "abusefilter-exception-noparams": "$1文字目にある関数「$2」に引数が与えられていません。", + "abusefilter-exception-noparams": "$1文字目にある関数「$2」に引数が与えられていません。\n$3{{PLURAL:$3|引数}}が必要です。", "abusefilter-exception-dividebyzero": "$1文字目に$2に対するゼロ除算があります。", "abusefilter-exception-unrecognisedvar": "$1文字目に認識できない変数「$2」があります。", "abusefilter-exception-notenoughargs": "$1 文字目で呼び出されている関数 $2 の引数が不足しています。\n$3 個の{{PLURAL:$3|引数}}があるべきですが $4 個しかありません", + "abusefilter-exception-toomanyargs": "$1 文字目で呼び出されている関数 $2 の引数が多すぎます。\n最大 $3 個の{{PLURAL:$3|引数}}があるべきですが $4 個しかありません", "abusefilter-exception-regexfailure": "$1 文字目の正規表現「$2」にエラーがあります。", - "abusefilter-exception-overridebuiltin": "$1 文字目で、組み込みの変数「$2」に誤って上書きしてしまっています。", - "abusefilter-exception-outofbounds": "$1 文字目で、存在しない一覧項目 $2 (一覧のサイズは $3) を要求しています。", + "abusefilter-exception-overridebuiltin": "$1 文字目で、組み込みの識別子「$2」に誤って上書きしてしまっています。", + "abusefilter-exception-outofbounds": "$1 文字目で、存在しない配列 $2 (配列サイズは $3) を要求しています。", + "abusefilter-exception-negativeindex": "配列では負数のインデックスを使うことができません。位置$1でインデックス「$2」を取得しました。", "abusefilter-exception-notarray": "$1文字目で非配列の配列要素を要求しています。", + "abusefilter-exception-unclosedcomment": "文字$1におけるコメントは未定義です。", + "abusefilter-exception-invalidiprange": "$1文字目のIP範囲$2は無効です。", + "abusefilter-exception-disabledvar": "$1文字目の変数$2は廃止されました。", "abusefilter-action-tag": "タグ付け", "abusefilter-action-throttle": "速度を制限", "abusefilter-action-warn": "警告", @@ -397,7 +501,7 @@ "abusefilter-revert-periodstart": "期間始め:", "abusefilter-revert-periodend": "期間終わり:", "abusefilter-revert-search": "対処操作を選択", - "abusefilter-revert-filter": "フィルター識別子:", + "abusefilter-revert-filter": "フィルターID:", "abusefilter-revert-preview-intro": "以下は、この操作によって差し戻される、不正利用フィルターによる対処操作です。\n注意深く確認し、「{{int:abusefilter-revert-confirm}}」をクリックして選択を確定してください。", "abusefilter-revert-confirm-legend": "巻き戻しを確認", "abusefilter-revert-confirm": "確定", @@ -418,6 +522,13 @@ "abusefilter-test-shownegative": "フィルターに一致しない変更を表示する", "abusefilter-test-syntaxerr": "あなたが入力したフィルターには構文エラーがあります。\n「{{int:abusefilter-edit-check}}」ボタンをクリックして、完全な説明を得ることができます。", "abusefilter-test-badtitle": "入力したページ名は無効です。ページ名に使用できない文字を含んでいる可能性があります。", + "abusefilter-test-action": "操作の種類:", + "abusefilter-test-search-type-all": "すべての操作", + "abusefilter-test-search-type-edit": "編集", + "abusefilter-test-search-type-move": "移動", + "abusefilter-test-search-type-delete": "削除", + "abusefilter-test-search-type-upload": "アップロード", + "abusefilter-test-search-type-createaccount": "アカウント作成", "abusefilter-changeslist-examine": "分析", "abusefilter-examine": "個別の変更を分析する", "abusefilter-examine-intro": "このページでは不正利用フィルターが個別の編集に対して生成した変数を分析し、フィルターに対してそれを試験することができます。", @@ -437,15 +548,16 @@ "abusefilter-examine-noresults": "指定された検索条件に合致する結果はありませんでした。", "abusefilter-topnav": "'''不正利用フィルターのメニュー'''", "abusefilter-topnav-home": "ホーム", + "abusefilter-topnav-recentchanges": "フィルターの最近の更新", "abusefilter-topnav-test": "一括試験", "abusefilter-topnav-examine": "過去の編集の試験", "abusefilter-topnav-log": "不正利用記録", "abusefilter-topnav-tools": "デバッグ用ツール", - "abusefilter-topnav-import": "フィルターのインポート", "abusefilter-log-name": "不正利用フィルター記録", "abusefilter-log-header": "この記録はフィルターに対してなされた変更の要約を表示しています。全詳細は、最近のフィルターの変更[[Special:AbuseFilter/history|一覧]]をご覧ください。", - "abusefilter-logentry-create": "$1 が $4 を{{GENDER:$2|作成しました}} ($5)", + "abusefilter-logentry-create": "$1 が $4 ($5) を{{GENDER:$2|作成しました}}", "abusefilter-logentry-modify": "$1 が $4 ($5) を{{GENDER:$2|変更しました}}", + "abusefilter-log-invalid-filter": "指定したフィルターIDのいくつかが無効です。", "abusefilter-log-noresults": "結果なし", "abusefilter-diff-title": "版間での差分", "abusefilter-diff-item": "項目", @@ -457,18 +569,20 @@ "abusefilter-diff-prev": "古い変更", "abusefilter-diff-next": "新しい変更", "abusefilter-import-intro": "このインターフェイスを使用して、別のウィキからフィルターを取り込めます。\n取り込み元のウィキで、編集画面の「{{int:abusefilter-edit-tools}}」下にある「{{int:abusefilter-edit-export}}」をクリックします。\nそこで現れるテキストボックスの内容をコピーし、それをこのテキストボックスに貼り付けて、「{{int:abusefilter-import-submit}}」をクリックします。", - "abusefilter-import-submit": "取り込む", + "abusefilter-import-submit": "データを取り込む", + "abusefilter-import-invalid-data": "インポートしようとしたデータは無効です", "abusefilter-group-default": "既定", "abusefilter-http-error": "HTTPエラーが発生: $1", - "abusefilter-view-private-submit": "非公開記録を参照", - "abusefilter-view-private": "非公開記録を参照", - "abusefilter-view-private-reason": "非公開記録の調査理由", + "abusefilter-view-privatedetails-submit": "非公開記録を参照", + "abusefilter-view-privatedetails-legend": "非公開記録を参照", + "abusefilter-view-privatedetails-reason": "非公開記録の調査理由:", "abusefilter-log-details-id": "記録ID", "abusefilter-invalid-request": "無効なリクエスト! [[Special:AbuseLog/$1]]のフォームを使ってプライベートログの詳細にアクセスし、理由を提示する必要があります。", "abusefilter-invalid-request-noid": "無効なリクエスト! 不正利用ログの詳細ページのフォームからプライベートログの詳細にアクセスし、理由を提示する必要があります。", "log-description-abusefilterprivatedetails": "以下は不正利用フィルターの非公開記録を調査した日時の一覧です。", "abusefilter-noreason": "警告: 非公開記録を閲覧するには、理由を入力する必要があります", "abusefilter-log-ip-not-available": "参照不可", + "abusefilter-tag-reserved": "<code>abusefilter-condition-limit</code>タグはAbuseFilter内部使用のため保留されています。", "tag-abusefilter-condition-limit": "条件の上限に達しました", "tag-abusefilter-condition-limit-description": "[[Special:AbuseFilter|不正利用フィルター]]([[mw:Extension:AbuseFilter/Conditions|ヘルプ]])によって確認できなかった編集やその他のイベント。" } diff --git a/AbuseFilter/i18n/jv.json b/AbuseFilter/i18n/jv.json index a304f014..416033eb 100644 --- a/AbuseFilter/i18n/jv.json +++ b/AbuseFilter/i18n/jv.json @@ -1,17 +1,21 @@ { "@metadata": { "authors": [ + "Diki Ananta", + "Fitoschido", + "N219", "NoiX180", + "Sumbukompor", "පසිඳු කාවින්ද" ] }, "abusefilter-desc": "Patrapaké pamriksan heuristik otomatis ing besutan", - "abusefilter": "Setèlan saringan salah-guna", - "abuselog": "Log planggaran", - "abusefilter-intro": "Sunger Rawuh ing antarmuka panatan Saringan Planggaran.\nSaringan Planggaran kuwi mékanismé piranti alus otomatis kang matrapaké héuristik otomatis ing kabèh laku.\nAntarmuka iki nuduhaké daptar saringan kang wis ditemtokaké, lan nglilakaké kanggo diowah.", + "abusefilter": "Panatan saringan planggaran", + "abuselog": "Log saringan planggaran", + "abusefilter-intro": "Sunger Rawuh ing mukantara panatan Saringan Planggaran.\nSaringan Planggaran kuwi mékanismé piranti alus otomatis kang matrapaké héuristik otomatis ing kabèh laku.\nMukantara iki nuduhaké daptar saringan kang wis ditemtokaké, lan nglilakaké kanggo diowah.", "abusefilter-warning": "'''Pènget:''' Tumindak iki wis otomatis tinengeran mbebayani.\nTumindak kang ora konstruktif bakal gagé kabalèkaké, lan besutan kang ora cetha utawa mbolan-balèni bakal njalari akun utawa alamat IP-né panjenengan kablokir.\nYèn yakin tumindak iki konstruktif, panjenengan bisa kirim iki manèh saperlu konfirmasi.\nKaterangan ringkes ngenani palanggaran kang jumbuh karo tumindak panjenengan ya iku: $1", "abusefilter-disallowed": "Tumindak iki otomatis konangan mbebayani, mula ora diidinaké.\nManawa yakin tumindaké panjenengan konstruktif, mangga kandhani administrator apa kang arep panjenengan lakoni.\nKaterangan ringkes palanggaran kang jumbuh karo tumindaké panjenengan ya iku: $1", - "abusefilter-blocked-display": "Laku iki otomatis dianggep mbebayani,\nlan panjenengan ditolak déning sistem.\nMinangka tambahan, kanggo njagani {{SITENAME}}, akun panganggo lan kabèh kang ana kaitané karo alamat IP panjenengan wis diblokir saka mbesut.\nYèn iki amarga ana kasalahan, mangga hubungi pangurus.\nKatrangan ringkes aturan planggaran kang padha karo lakuné panjenengan: $1", + "abusefilter-blocked-display": "Laku iki otomatis dianggep mbebayani,\nlan panjenengan ditolak déning sistem.\nMinangka tambahan, kanggo njagani {{SITENAME}}, akun naraguna lan kabèh kang ana kaitané karo alamat IP panjenengan wis diblokir saka mbesut.\nYèn iki amarga ana kasalahan, mangga hubungi panata.\nKatrangan ringkes aturan planggaran kang padha karo lakuné panjenengan: $1", "abusefilter-autopromote-blocked": "Tumindak iki otomatis kaciri mbebayani, lan ora diidinaké.\nSaliyané iku, minangka upaya pangayoman, sawenèh hak kang ajeg kawènèhaké marang akun-akun kang ana bakal sawetara dijabut saka akun panjenengan.\nKaterangan ringkes ngenani palanggaran kang jumbuh tumindaké panjenengan ya iku: $1", "abusefilter-blocker": "Saringan planggaran", "abusefilter-blockreason": "Otomatis diblokir déning saringan planggaran.\nKatrangan ngenani aturan kang cocok: $1", @@ -21,7 +25,7 @@ "right-abusefilter-view": "Deleng saringan salah-guna", "right-abusefilter-log": "Deleng log salah-guna", "right-abusefilter-log-detail": "Deleng èntri log salah-guna kang rinci", - "right-abusefilter-private": "Deleng dhata priangga ing log salah-guna", + "right-abusefilter-privatedetails": "Deleng dhata priangga ing log salah-guna", "right-abusefilter-modify-restricted": "Owah saringan planggaran mawa laku kawatesi", "right-abusefilter-revert": "Balèkaké kabèh owahan déning saringan planggaran kang dimaksud", "right-abusefilter-view-private": "Deleng saringan salah-guna kang ditandhani minangka privat", @@ -32,17 +36,30 @@ "action-abusefilter-view": "deleng saringan salah-guna", "action-abusefilter-log": "deleng log salah-guna", "action-abusefilter-log-detail": "deleng èntri log salah-guna kang rinci", - "action-abusefilter-private": "deleng dhata priangga ing log salah-guna", + "action-abusefilter-privatedetails": "deleng dhata priangga ing log salah-guna", "action-abusefilter-modify-restricted": "owah saringan planggaran mawa laku kawatesi", "action-abusefilter-revert": "balèkaké kabèh owahan déning saringan planggaran kang dimaksud", "action-abusefilter-view-private": "deleng saringan salah-guna kang ditandhani minangka privat", - "abusefilter-log": "Log saringan planggaran", "abusefilter-log-summary": "Log iki nuduhaké daptar kabèh laku kang kacekel saringan.", "abusefilter-log-search": "Golèk log planggaran", - "abusefilter-log-search-user": "Panganggo:", - "abusefilter-log-search-filter": "ID saringan (dileti tandha pipa):", + "abusefilter-log-search-user": "Naraguna:", + "abusefilter-log-search-group": "Golonganing saringan:", + "abusefilter-log-search-group-any": "Apa baé", + "abusefilter-log-search-filter": "ID saringan:", + "abusefilter-log-search-filter-help": "Kapisah mawa pipa, ater-ater mawa \"$1\" tumrap saringan global", "abusefilter-log-search-title": "Sesirah:", "abusefilter-log-search-wiki": "Wiki:", + "abusefilter-log-search-impact": "Temahan:", + "abusefilter-log-search-impact-all": "Kabèh lelakon", + "abusefilter-log-search-impact-saved": "Mung owahan kang kasimpen", + "abusefilter-log-search-impact-not-saved": "Tanpa owahan kang kasimpen", + "abusefilter-log-search-entries-label": "Kakatonan:", + "abusefilter-log-search-entries-all": "Kabèh èntri", + "abusefilter-log-search-entries-hidden": "Mung èntri kang kadhelikaké", + "abusefilter-log-search-entries-visible": "Mung èntri kang katon", + "abusefilter-log-search-action-other": "Liyané", + "abusefilter-log-search-action-any": "Apa baé", + "abusefilter-log-search-action-taken-any": "Apa baé", "abusefilter-log-search-submit": "Golèk", "abusefilter-log-detailedentry-global": "saringan global $1", "abusefilter-log-detailedentry-local": "saringan $1", @@ -53,13 +70,12 @@ "abusefilter-log-details-var": "Variabel", "abusefilter-log-details-val": "Biji", "abusefilter-log-details-vars": "Paramèter laku", - "abusefilter-log-details-private": "Data priangga", + "abusefilter-log-details-privatedetails": "Rerincèning log priangga", "abusefilter-log-details-ip": "Alamat IP asli", "abusefilter-log-noactions": "ora ana", "abusefilter-log-details-diff": "Owahan sajeroning besutan", "abusefilter-log-linkoncontribs": "log planggaran", - "abusefilter-log-linkoncontribs-text": "Log salah-guna kanggo {{GENDER:$1|panganggo iki}}", - "abusefilter-log-hidden": "(èntri kadhelikaké)", + "abusefilter-log-linkoncontribs-text": "Log salah-guna kanggo {{GENDER:$1|naraguna iki}}", "abusefilter-log-hidden-implicit": "(kadhelikaké marga benahan wis dibusak)", "abusefilter-log-cannot-see-details": "Panjenengan ora kalilakaké ndeleng rerincèn èntri iki.", "abusefilter-log-details-hidden": "Panjenengan ora bisa ndeleng rerincèn èntri iki amarga kuwi kadhelikaké saka umum.", @@ -69,7 +85,6 @@ "abusefilter-log-hide-reason": "Alesan:", "abusefilter-log-hide-forbidden": "Panjenengan ora kalilakaké ndhelikaké èntri log planggaran.", "logentry-abusefilter-hit": "$1 {{GENDER:$2|njalari}} $4, {{GENDER:$2|ngayahi}} \"$5\" ing $3. Tumindak diayahi: $6 ($7)", - "abusefilter-management": "Panatan saringan planggaran", "abusefilter-list": "Kabèh saringan", "abusefilter-list-id": "ID saringan", "abusefilter-list-status": "Status", @@ -88,6 +103,7 @@ "abusefilter-deleted": "Dibusak", "abusefilter-disabled": "Mati", "abusefilter-new": "Gawé saringan anyar", + "abusefilter-import-button": "Impor saringan", "abusefilter-return": "Bali menyang tata saringan", "abusefilter-status-global": "Global", "abusefilter-list-options": "Pilihan", @@ -95,16 +111,22 @@ "abusefilter-list-options-deleted-only": "Tuduhaké saringan kabusak waé", "abusefilter-list-options-deleted-hide": "Dhelikaké saringan kabusak", "abusefilter-list-options-deleted-show": "Kalebukaké saringan kabusak", + "abusefilter-list-options-scope": "Tuduhaké saringan:", + "abusefilter-list-options-scope-local": "Mung aturan lokal", "abusefilter-list-options-scope-global": "Mligi aturan global", + "abusefilter-list-options-scope-all": "Aturan lokal lan global", + "abusefilter-list-options-further-options": "Opsi candhaké:", "abusefilter-list-options-hidedisabled": "Dhelikaké saringan kang dipatèni", + "abusefilter-list-options-hideprivate": "Dhelikaké saringan privat", + "abusefilter-list-options-searchfield": "Golèh ing dalem aturan:", "abusefilter-list-options-submit": "Anyari", "abusefilter-tools-text": "Iki sebagéyan prangkat kang mungkin migunani kanggo mormulasi lan njajal panyaring planggaran.", "abusefilter-tools-expr": "Panjajal èksprèsi", "abusefilter-tools-submitexpr": "Evaluasi", "abusefilter-tools-reautoconfirm": "Mbalèkaké status pepesthèn otomatis", - "abusefilter-tools-reautoconfirm-user": "Panganggo:", + "abusefilter-tools-reautoconfirm-user": "Naraguna:", "abusefilter-tools-reautoconfirm-submit": "Balèni pesthèkaké otomatis", - "abusefilter-reautoconfirm-none": "Status pepesthèn otomatis {{GENDER:$1|panganggo|panganggo|panganggo}} iki ora dijabut.", + "abusefilter-reautoconfirm-none": "Status pepesthèn otomatis {{GENDER:$1|naraguna|naraguna|naraguna}} iki ora dijabut.", "abusefilter-reautoconfirm-notallowed": "Panjenengan ora dililakaké mbalèkaké status pepesthèn otomatis.", "abusefilter-reautoconfirm-done": "Status pepesthèn akun wis dibalèkaké", "abusefilter-edit-subtitle": "Mbesut panyaringan $1", @@ -125,28 +147,36 @@ "abusefilter-edit-lastmod": "Saring owahan pungkasan:", "abusefilter-edit-lastmod-text": "$1 déning $2", "abusefilter-edit-consequences": "Tumindak kang diayahi yèn cocog", - "abusefilter-edit-action-disallow": "Alangi panganggo kang marai mandheg mangu", - "abusefilter-edit-action-blockautopromote": "Jabut status pepesthèn otomatis panganggo", - "abusefilter-edit-action-degroup": "Busek panganggo iki saka kabèh golongan mirunggan", - "abusefilter-edit-action-block": "Blokir panganggo lan/utawa alamat IP saka mbesut", + "abusefilter-edit-action-disallow": "Alangi naraguna kang marai mandheg mangu", + "abusefilter-edit-action-blockautopromote": "Jabut status pepesthèn otomatis naraguna", + "abusefilter-edit-action-degroup": "Busek naraguna iki saka kabèh golongan mirunggan", + "abusefilter-edit-action-block": "Blokir naraguna lan/utawa alamat IP saka mbesut", "abusefilter-edit-action-rangeblock": "Blokir jangkah /16 asalé panganggo", "abusefilter-edit-action-tag": "Tandhani besutan nedya dipriksa mengko", "abusefilter-edit-throttle-count": "Cacahé laku kang dililakaké:", - "abusefilter-edit-throttle-period": "Periode wektu:", + "abusefilter-edit-throttle-period": "Suwéné (ing sekon):", "abusefilter-edit-throttle-groups": "Pantha klep miturut:", + "abusefilter-throttle-ip": "alamat IP", + "abusefilter-throttle-user": "akun naraguna", + "abusefilter-throttle-creationdate": "tanggal gawéan akun", + "abusefilter-throttle-editcount": "cacah besutan", + "abusefilter-throttle-site": "saindenging situs", + "abusefilter-throttle-page": "kaca", + "abusefilter-throttle-none": "(ora ana)", "abusefilter-edit-warn-message": "Layang sistem kang dianggo kanggo pèngetan:", "abusefilter-edit-warn-other": "Layang liya", - "abusefilter-edit-warn-other-label": "Jeneng kaca saka layang liya:\n:''(tanpa ater-ater MediaWiki)''", + "abusefilter-edit-warn-other-label": "Jeneng kaca saka layang liya:\n:''(tanpa ater-ater \"MédiaWiki:\")''", "abusefilter-edit-warn-actions": "Laku:", "abusefilter-edit-warn-preview": "Tuduhaké/Dhelikaké pratuduh layang kang pinilih", "abusefilter-edit-warn-edit": "Gawé/Besut layang kang pinilih", - "abusefilter-edit-tag-tag": "[[Special:Tags|Tag]] kanggo cak-cakan (siji saben larik):", + "abusefilter-edit-disallow-other": "Layang liyané", + "abusefilter-edit-tag-tag": "[[Special:Tags|Tenger]] kang bisa kaenggo:", "abusefilter-edit-denied": "Panjenengan mungkin ora ndeleng rerincèn saka saringan iki amarga kuwi pancen didhelikaké saka umum.", "abusefilter-edit-main": "Paramètèr saringan", "abusefilter-edit-done-subtitle": "Saringan wis dibesut", "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Owahané panjenengan]] tumrap [[Special:AbuseFilter/$1|saringan $3]] wis disimpen.", "abusefilter-edit-badsyntax": "Ana masalah sintaksis ing saringan kang panjenengan lebokaké.\nWeton saka parser ya iku: <pre>$1</pre>", - "abusefilter-edit-restricted": "Panjenengan ora bisa mbesut saringan iki amarga isiné lelakon winates cacah siji utawa luwih.\nMangga takon marang siji panganggo kang kawogan saperlu muwuhi lelakon winates lan nggawèkaké owahan kanggo panjenengan.", + "abusefilter-edit-restricted": "Panjenengan ora bisa mbesut saringan iki amarga isiné lelakon winates cacah siji utawa luwih.\nMangga takon marang siji naraguna kang kawogan saperlu muwuhi lelakon winates lan nggawèkaké owahan kanggo panjenengan.", "abusefilter-edit-viewhistory": "Deleng sujarahé saringan iki", "abusefilter-edit-history": "Riwayah:", "abusefilter-edit-check": "Priksa sintaks", @@ -209,40 +239,40 @@ "abusefilter-edit-builder-vars-removedlines": "Larik kang dilih ing besutan", "abusefilter-edit-builder-vars-summary": "Alesan/ringkesané besutan", "abusefilter-edit-builder-vars-page-id": "ID kaca", - "abusefilter-edit-builder-vars-page-ns": "Bilik jeneng kaca", + "abusefilter-edit-builder-vars-page-ns": "Mandhala aran kaca", "abusefilter-edit-builder-vars-page-title": "Sesirah kaca (tanpa jagad aran)", "abusefilter-edit-builder-vars-page-prefixedtitle": "Sesirah kaca jangkep", "abusefilter-edit-builder-vars-movedfrom-id": "ID kaca pangalihé kaca sumber", - "abusefilter-edit-builder-vars-movedfrom-ns": "Mandala aran pangalih kaca sumber", + "abusefilter-edit-builder-vars-movedfrom-ns": "Mandhala aran pangalih kaca sumber", "abusefilter-edit-builder-vars-movedfrom-title": "Sesirah kaca sumber alihan", "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "Sesirah jangkep kaca sumber alihan", "abusefilter-edit-builder-vars-movedto-id": "ID kaca saka kaca papan patujon pamidhahan", - "abusefilter-edit-builder-vars-movedto-ns": "Mandala aran pangalihé kaca paran", + "abusefilter-edit-builder-vars-movedto-ns": "Mandhala aran pangalihing kaca jujugan", "abusefilter-edit-builder-vars-movedto-title": "Sesirah kaca tujuan alihan", "abusefilter-edit-builder-vars-movedto-prefixedtitle": "Sesirah jangkep kaca tujuan alihan", - "abusefilter-edit-builder-vars-user-editcount": "Cacah besutan panganggo", - "abusefilter-edit-builder-vars-user-age": "Yuswané akun panganggo", - "abusefilter-edit-builder-vars-user-name": "Jeneng akun panganggo", - "abusefilter-edit-builder-vars-user-groups": "Golongan (kabèh) kang panganggoné ana ing jeroné", + "abusefilter-edit-builder-vars-user-editcount": "Cacah besutan naraguna", + "abusefilter-edit-builder-vars-user-age": "Umuré akun naraguna", + "abusefilter-edit-builder-vars-user-name": "Jeneng akun naraguna", + "abusefilter-edit-builder-vars-user-groups": "Golongan (kabèh) kang naragunané ana ing jeroné", "abusefilter-edit-builder-vars-user-emailconfirm": "Wektu alamat layang èlèktronik dipesthèkaké", - "abusefilter-edit-builder-vars-recent-contributors": "Sepuluh panganggo pungkasan kang nyumbang ing kaca", + "abusefilter-edit-builder-vars-recent-contributors": "Sepuluh naraguna pungkasan kang nyumbang ing kaca", "abusefilter-edit-builder-vars-all-links": "Kabèh pranala njaba ing tèks anyar", "abusefilter-edit-builder-vars-added-links": "Kabèh pranala njaba katambahaké sajeroning besutan", "abusefilter-edit-builder-vars-removed-links": "Kabèh pranala njaba kabusak sajeroning besutan", - "abusefilter-edit-builder-vars-old-text": "Tèkswiki kaca lawas, sadurungé dibesut", - "abusefilter-edit-builder-vars-new-text": "Tèkswiki kaca anyar, sakisé dibesut", + "abusefilter-edit-builder-vars-old-wikitext": "Tèkswiki kaca lawas, sadurungé dibesut", + "abusefilter-edit-builder-vars-new-wikitext": "Tèkswiki kaca anyar, sakisé dibesut", "abusefilter-edit-builder-vars-restrictions-edit": "Besut tataran rereksan kaca", - "abusefilter-edit-builder-vars-restrictions-move": "Pindhah undhak panjagan kaca", + "abusefilter-edit-builder-vars-restrictions-move": "Lih undhak panjagan kaca", "abusefilter-edit-builder-vars-old-links": "Pranala ing njero kaca, sadurungé dibesut", "abusefilter-edit-builder-vars-minor-edit": "Ana utawa ora besutan kang ditandhai minangka besutan cilik", - "abusefilter-filter-log": "Owahan saringan paling anyar", + "abusefilter-filter-log": "Owahan saringan anyar dhéwé", "abusefilter-history": "Riwayah owahan saka Saringan Planggaran #$1", "abusefilter-history-foruser": "Owahan déning $1", "abusefilter-history-hidden": "Kadhelikaké", "abusefilter-history-enabled": "Murub", "abusefilter-history-global": "Global", "abusefilter-history-timestamp": "Wektu", - "abusefilter-history-user": "Panganggo", + "abusefilter-history-user": "Naraguna", "abusefilter-history-public": "Katrangan saringan umum", "abusefilter-history-flags": "Tenger", "abusefilter-history-filter": "Aturan saringan", @@ -252,7 +282,7 @@ "abusefilter-history-deleted": "Dibusak", "abusefilter-history-filterid": "Saringan", "abusefilter-history-select-legend": "Gegolèkan anyar-anyaran", - "abusefilter-history-select-user": "Panganggo:", + "abusefilter-history-select-user": "Naraguna:", "abusefilter-history-diff": "Owah-owahan", "abusefilter-history-error-hidden": "Saringan kang panjenengan jaluk didhelikaké, lan panjenengan ora bisa ndeleng riwayaté.", "abusefilter-exception-unexpectedatend": "\"$2\" ora dikarepaké ing karakter $1.", @@ -264,8 +294,8 @@ "abusefilter-exception-dividebyzero": "Upaya ilegal mbagi $2 mawa nol ing karakter $1.", "abusefilter-exception-unrecognisedvar": "Variabel $2 ora kaweruhan ing karakter $1", "abusefilter-exception-notenoughargs": "Ora cukup panemu kanggo fungsi $2 kang diceluk ing karakter $1.\nDikarepaké ana $3 {{PLURAL:$3|panemu|panemu}}, nemu $4", - "abusefilter-exception-regexfailure": "Kasalahan ing èksprèsi biasa \"$3\" ing karakter $1: \"$2\"", - "abusefilter-action-tag": "Tag", + "abusefilter-exception-regexfailure": "Kasalahan ing èksprèsi biasa \"$2\" ing karakter $1.", + "abusefilter-action-tag": "Tenger", "abusefilter-action-throttle": "Klep panutup", "abusefilter-action-warn": "Pèngetan", "abusefilter-action-blockautopromote": "Blokir tawa otomatis", @@ -292,7 +322,7 @@ "abusefilter-test-load-filter": "Emot ID saringan:", "abusefilter-test-submit": "Jajal", "abusefilter-test-load": "Emot", - "abusefilter-test-user": "Owahan déning panganggo:", + "abusefilter-test-user": "Owahan déning naraguna:", "abusefilter-test-period-start": "Owahan digawé sakwisé:", "abusefilter-test-period-end": "Owahan digawé sakdurungé:", "abusefilter-test-page": "Owahan digawé ing kaca:", @@ -303,7 +333,7 @@ "abusefilter-examine-intro": "Kaca iki nglilakaké panjenengan nguji variabèl saka Saringan Planggaran kanggo sawiji owahan individu, lan jajal tumrap saringan.", "abusefilter-examine-legend": "Pilih owahan", "abusefilter-examine-diff": "URL beda:", - "abusefilter-examine-user": "Panganggo:", + "abusefilter-examine-user": "Naraguna:", "abusefilter-examine-title": "Sesirah kaca:", "abusefilter-examine-submit": "Golèk", "abusefilter-examine-vars": "Variabèl kasilaké kanggo owahan iki", @@ -321,7 +351,6 @@ "abusefilter-topnav-examine": "Dadar besutan-besutan kapungkur", "abusefilter-topnav-log": "Log Planggaran", "abusefilter-topnav-tools": "Piranti debug", - "abusefilter-topnav-import": "Impor saringan", "abusefilter-log-name": "Log saringan palanggaran", "abusefilter-log-header": "Log iki nuduhaké ringkesan owah-owahan kang digawé tumrap saringan.\nKanggo rerincèn wutuhé, delengen [[Special:AbuseFilter/history|pratélan]] owah-owahan anyaré saringan.", "abusefilter-log-noresults": "Ora ana asilé", @@ -334,7 +363,7 @@ "abusefilter-diff-backhistory": "Balik menyang sajarahing saringan", "abusefilter-diff-prev": "Owahan luwih lawas", "abusefilter-diff-next": "Owahan luwih anyar", - "abusefilter-import-intro": "Panjenengan bisa nganggo antarmuka iki kanggo ngimpor saringan saka wiki liya.\nIng wiki sumber, klik \"{{int:abusefilter-edit-export}}\" sakisoré \"{{int:abusefilter-edit-tools}}\" ing antarmuka pambesutan.\nSalin saka kothak wedhi kang njedhul, lan tèmplèkaké ing kothak tèks, banjur klik \"{{int:abusefilter-import-submit}}\".", + "abusefilter-import-intro": "Panjenengan bisa nganggo mukantara iki kanggo ngimpor saringan saka wiki liya.\nIng wiki sumber, klik \"{{int:abusefilter-edit-export}}\" sakisoré \"{{int:abusefilter-edit-tools}}\" ing mukantara pambesutan.\nSalin saka kothak wedhi kang njedhul, lan tèmplèkaké ing kothak tèks, banjur klik \"{{int:abusefilter-import-submit}}\".", "abusefilter-import-submit": "Impor data", "abusefilter-group-default": "Gawan" } diff --git a/AbuseFilter/i18n/ka.json b/AbuseFilter/i18n/ka.json index 82dd4f6e..e0f4a56b 100644 --- a/AbuseFilter/i18n/ka.json +++ b/AbuseFilter/i18n/ka.json @@ -5,15 +5,15 @@ "David1010", "Dawid Deutschland", "Malafaya", - "Temuri rajavi", - "გიორგიმელა", + "Matma Rex", "Otogi", - "Matma Rex" + "Temuri rajavi", + "გიორგიმელა" ] }, "abusefilter-desc": "საშუალებას იძლევა რედაქტირებისას გამოიყენოს ევრისტიკული ფილტრები", - "abusefilter": "ბოროტად გამოყენების ფილტრის კონფიგურაცია", - "abuselog": "ბოროტად გამოყენების ჟურნალი", + "abusefilter": "ბოროტად გამოყენების ფილტრის მართვა", + "abuselog": "ბოროტად გამოყენების ფილტრის ჟურნალი", "abusefilter-intro": "კეთილი იყოს თქვენი მობრძანება ბოროტად გამოყენების ფილტრის მართვის გვერდზე. ბოროტად გამოყენების ფილტრი წარმოადგენს მომხმარებელთა მოქმედების შესაბამისად ავტომატიზირებულ მექანიზმს ავტომატური ევრისტიკული გამოყენებით. აქ მოყვანილია ყველა დაყენებული ფილტრის სია, რომელთა შეცვლა არის შესაძლებელი.", "abusefilter-warning": "'''ყურადღება''': ეს ქმედება ავტომატურად იქნა მიჩნეული არაკონსტრუქციულად.\nამგვარი ცვლილებები მეტწილად ძალიან სწრაფად უქმდება. ქმედების განმეორებისას უარეს შემთხვევაში თქვენი ანგარიში ან IP-მისამართი დაიბლოკება.\nთუ თქვენ მიგაჩნიათ, რომ თქვენი განხორციელებული მოქმედება სასარგებლოა, შეგიძლიათ მიღებით ხელმეორედ დაადასტუროთ ეს.\nდარღვევის მოკლე აღწერა: $1", "abusefilter-blocker": "ბოროტად გამოყენების ფილტრი", @@ -24,7 +24,7 @@ "right-abusefilter-view": "ბოროტად გამოყენების ფილტრის ხილვა", "right-abusefilter-log": "ბოროტად გამოყენების ფილტრის ჟურნალის ხილვა", "right-abusefilter-log-detail": "ბოროტად გამოყენების ფილტრის ჟურნალის ჩანაწერების ყურადღებით ხილვა", - "right-abusefilter-private": "ბოროტად გამოყენების ფილტრის ჟურნალის დამალული მონაცემების ხილვა", + "right-abusefilter-privatedetails": "ბოროტად გამოყენების ფილტრის ჟურნალის დამალული მონაცემების ხილვა", "right-abusefilter-modify-restricted": "ბოროტად გამოყენების ფილტრის რედაქტირება აკრძალული მოქმედებებით", "right-abusefilter-revert": "ბოროტად გამოყენების ფილტრის ნაჩვენები ყველა ცვლილების გაუქმება", "right-abusefilter-view-private": "მაჩვენე ბოროტად გამოყენების ფილტრები, რომლებიც მოინიშნა, როგორც კერძო", @@ -36,11 +36,10 @@ "action-abusefilter-view": "ბოროტად გამოყენების ფილტრების ხილვა", "action-abusefilter-log": "ბოროტად გამოყენების ფილტრის ჟურნალის ხილვა", "action-abusefilter-log-detail": "ბოროტად გამოყენების ფილტრის ჟურნალის ჩანაწერების ყურადღებით ხილვა", - "action-abusefilter-private": "პირადი მონაცემების ხილვა ბოროტად გამოყენების ფილტრის ჟურნალში", + "action-abusefilter-privatedetails": "პირადი მონაცემების ხილვა ბოროტად გამოყენების ფილტრის ჟურნალში", "action-abusefilter-modify-restricted": "ბოროტად გამოყენების ფილტრის რედაქტირება აკრძალული მოქმედებებით", "action-abusefilter-revert": "ბოროტად გამოყენების ფილტრის ნაჩვენები ყველა ცვლილების გაუქმება", "action-abusefilter-view-private": "მაჩვენე ბოროტად გამოყენების ფილტრები, რომლებიც მოინიშნა, როგორც პირადი", - "abusefilter-log": "ბოროტად გამოყენების ფილტრის ჟურნალი", "abusefilter-log-summary": "ეს ჟურნალი აჩვენებს ყველა იმ მოქმედების სიას, რომელიც ფილტრმა დაიჭირა.", "abusefilter-log-search": "ბოროტად გამოყენების ფილტრის ჟურნალის ძიება", "abusefilter-log-search-user": "მომხმარებელი:", @@ -64,7 +63,7 @@ "abusefilter-log-details-var": "ცვალებადი", "abusefilter-log-details-val": "მნიშვნელობა", "abusefilter-log-details-vars": "Action parameters", - "abusefilter-log-details-private": "კერძო მონაცემი", + "abusefilter-log-details-privatedetails": "კერძო მონაცემი", "abusefilter-log-details-ip": "გამავალი IP მისამართი", "abusefilter-log-noactions": "არცერთი", "abusefilter-log-details-diff": "რედაქტირებისას განხორციელებული ცვლილებები", @@ -72,7 +71,7 @@ "abusefilter-log-linkoncontribs-text": "ბოროტად გამოყენების ფილტრის ჟურნალი ამ მომხმარებლისათვის", "abusefilter-log-linkonhistory": "ბოროტად გამოყენების ფილტრის ჟურნალის გადახედვა", "abusefilter-log-linkonhistory-text": "ამ გვერდისთვის ბოროტად გამოყენების ჟურნალის ჩვენება", - "abusefilter-log-hidden": "(ცვლილება დამალულია)", + "abusefilter-log-linkonundelete-text": "ბოროტად გამოყენების ფილტრის ჟურნალის ჩვენება ამ გვერდზე", "abusefilter-log-hidden-implicit": "(დამალულია, რადგან შესწორება წაიშალა)", "abusefilter-log-cannot-see-details": "თქვენ არ გაქვთ ამ ჩანაწერის დეტალური ინფორმაციის ხილვის უფლება.", "abusefilter-log-details-hidden": "თქვენ ვერ იხილავთ დამატებით ინფორმაციას ამ ფილტრის შესახებ, რადგანაც ის დამალულია ჩვეულებრივი მომხმარებლებისთვის.", @@ -81,7 +80,6 @@ "abusefilter-log-hide-hidden": "ამ ცვლილების დამალვა საზოგადოებისათვის", "abusefilter-log-hide-reason": "მიზეზი:", "abusefilter-log-hide-forbidden": "თქვენ ბოროტად გამოყენების ფილტრის ჟურნალის ჩანაწერების დამალვის უფლება არა გაქვთ.", - "abusefilter-management": "ბოროტად გამოყენების ფილტრის მართვა", "abusefilter-list": "ყველა ფილტრი", "abusefilter-list-id": "ფილტრის ID", "abusefilter-list-status": "სტატუსი", @@ -101,6 +99,7 @@ "abusefilter-disabled": "გათიშულია", "abusefilter-hitcount": "$1 {{PLURAL:$1|ამოქმედებები|ამოქმედება|ამოქმედებები}}", "abusefilter-new": "ახალი ფილტრის შექმნა", + "abusefilter-import-button": "ფილტრის იმპორტი", "abusefilter-return": " ბოროტად გამოყენების ფილტრის მართვასთან დაბრუნება", "abusefilter-status-global": "გლობალური", "abusefilter-list-options": "პარამეტრები", @@ -138,7 +137,6 @@ "abusefilter-edit-oldwarning": "<strong>თქვენ ასწორებთ ფილტრის ძველ ვერსიას. სტატისტიკა ნაჩვენებია ფილტრის ბოლო ვერსიისთვის. თუ თქვენ შეინახავთ რედაქტირებას, მაშინ თქვენ გადააწერთ თქვენს მიერ შეტანილ ცვლილებებს.</strong> • [[Special:AbuseFilter/history/$2|დაბრუნება ფილტრის ისტორიაში]].", "abusefilter-edit-status-label": "სტატისტიკა:", "abusefilter-edit-status": "ბოლო {{PLURAL:$1|$1 მოქმედებიდან|#$1 მოქმედებებიდან}}, ეს ფილტრი შეესაბამება $2 ($3%).", - "abusefilter-edit-status-profile": "ბოლო {{PLURAL:$1|$1 მოქმედებიდან| მოქმედებებიდან}}, ეს ფილტრი შეესაბამება $2 ($3%).\nსამუშაოს საშუალო დრო — $4 მწ, ის იყენებს $5 {{PLURAL:$5|პირობა|პირობრბს}} პირობების ლიმიტიდან.", "abusefilter-edit-new": "ახალი ფილტრი", "abusefilter-edit-save": "ფილტრის შენახვა", "abusefilter-edit-id": "ფილტრის ID:", @@ -275,18 +273,18 @@ "abusefilter-edit-builder-vars-all-links": "ყველა გარე ბმული, ახალ ტექსტში", "abusefilter-edit-builder-vars-added-links": "ყველა გარე ბმული, ჩამატებული რედაქტირებისას", "abusefilter-edit-builder-vars-removed-links": "ყველა გარე ბმული, წაშლილი რედაქტირებისას", - "abusefilter-edit-builder-vars-old-text": "ძველი ვიკიტექსტი, რედაქტირებამდელი", - "abusefilter-edit-builder-vars-new-text": "ახალი ვიკიტექსტი, გვერდების შესწორებების შემდეგ", + "abusefilter-edit-builder-vars-old-wikitext": "ძველი ვიკიტექსტი, რედაქტირებამდელი", + "abusefilter-edit-builder-vars-new-wikitext": "ახალი ვიკიტექსტი, გვერდების შესწორებების შემდეგ", "abusefilter-edit-builder-vars-new-pst": "ახალი გვერდის ვიკიტექსტი, გარდაქმნილი შენახვამდე", "abusefilter-edit-builder-vars-diff-pst": "უნიფიცირებული diff ცვლილებები რედაქტირების პროცესში, გარდაქმნილი შენახვამდე", "abusefilter-edit-builder-vars-addedlines-pst": "სტრიქონები, დამატებული რედაქტირების დროს, გარდაქმნილი შენახვამდე", - "abusefilter-edit-builder-vars-new-text-stripped": "გვერდის ტექსტი ვიკიფიცირების გარეშე", + "abusefilter-edit-builder-vars-new-text": "გვერდის ტექსტი ვიკიფიცირების გარეშე", "abusefilter-edit-builder-vars-new-html": "ახალი გვერდის სხვადასხვა HTML კოდი", "abusefilter-edit-builder-vars-restrictions-edit": "გვერდის შესწორებათა დაცვის დონე", "abusefilter-edit-builder-vars-restrictions-move": "გვერდის გადრქმევების დაცვის დონე", "abusefilter-edit-builder-vars-restrictions-create": "გვერდის შექმნის დაცვა", "abusefilter-edit-builder-vars-restrictions-upload": "ფაილის ატვირთვის დაცვა", - "abusefilter-edit-builder-vars-old-text-stripped": "ძველი გვერდის ტექსტი ვიკიფიცირების გარეშე", + "abusefilter-edit-builder-vars-old-text": "ძველი გვერდის ტექსტი ვიკიფიცირების გარეშე", "abusefilter-edit-builder-vars-old-links": "ბმულები გვერდზე შესწორებამდე", "abusefilter-edit-builder-vars-old-html": "HTML-ად გადაკეთებული ძველი გვერდის ვიკიტექსტი", "abusefilter-edit-builder-vars-minor-edit": "თუ იყო რედაქტირება მონიშნული როგორც «მცირე შსწორება»", @@ -384,7 +382,6 @@ "abusefilter-topnav-examine": "ბოლო ცვლილებების შესწავლა", "abusefilter-topnav-log": "ბოროტად გამოყენების ჟურნალი", "abusefilter-topnav-tools": "გაუმჯობესების ხელსაწყოები", - "abusefilter-topnav-import": "ფილტრის იმპორტი", "abusefilter-log-name": "ბოროტად გამოყენების ფილტრის ჟურნალი", "abusefilter-log-header": "ამ ჟურნალში იწერება ფილტრებში შემოსული ცვლილებები\nიხილეთ დამატებითი ინფორმაცია ფილტრის ბოლო ცვლილებების [[Special:AbuseFilter/history|სიაში]].", "abusefilter-log-noresults": "შედეგები არაა", diff --git a/AbuseFilter/i18n/kab.json b/AbuseFilter/i18n/kab.json index 6104fabf..79563e47 100644 --- a/AbuseFilter/i18n/kab.json +++ b/AbuseFilter/i18n/kab.json @@ -5,8 +5,6 @@ ] }, "abusefilter-desc": "Ad yesnes tiseffuga tiwurmanin i teẓrigin.", - "abusefilter": "Tawila n imzizdig mgal tafuli", - "abuselog": "Aɣmis n tfuli", "abusefilter-log-search-user": "Aseqdac:", "abusefilter-log-search-title": "Azwel :", "abusefilter-log-search-wiki": "Awiki:", @@ -21,13 +19,12 @@ "abusefilter-log-details-var": "Amutti", "abusefilter-log-details-val": "Azal", "abusefilter-log-details-vars": "Isebdaden n tigawt", - "abusefilter-log-details-private": "ISefka usligen", + "abusefilter-log-details-privatedetails": "ISefka usligen", "abusefilter-log-details-ip": "Tansa IP taneṣlit", "abusefilter-log-noactions": "ulac", "abusefilter-log-details-diff": "Isnifal yettwagen di teẓrigt", "abusefilter-log-linkoncontribs": "aɣmis n tfuli", "abusefilter-log-linkoncontribs-text": "Aɣmis n tfuli i {{GENDER:$1|aseqdac-agi}}", - "abusefilter-log-hidden": "(anekcum yeffer)", "abusefilter-log-hidden-implicit": "(yeffer acku lqem yettwakkes)", "abusefilter-list-options": "Iɣewwaṛen", "abusefilter-list-options-deleted": "Imzizdigen yettwakksen:", diff --git a/AbuseFilter/i18n/khw.json b/AbuseFilter/i18n/khw.json index 8a487c11..09a54aac 100644 --- a/AbuseFilter/i18n/khw.json +++ b/AbuseFilter/i18n/khw.json @@ -4,7 +4,7 @@ "Rachitrali" ] }, - "abuselog": "غلط استعمالو لاگ ان کورے", + "abusefilter": "غلط استعمال فلٹرو انتظام", "abusefilter-blocker": "غلط استعمالو فلٹر کورے", "abusefilter-log-search-user": "یوزر", "abusefilter-log-search-title": "عنوان:", @@ -15,10 +15,9 @@ "abusefilter-log-hidelink": "پوشیکو ایڈجسٹ کورے", "abusefilter-log-details-var": "متغیر/Variable", "abusefilter-log-details-val": "قدر", - "abusefilter-log-details-private": "نجی اعداد و شمار", + "abusefilter-log-details-privatedetails": "نجی اعداد و شمار", "abusefilter-log-noactions": "کیاغ دی نیکی", "abusefilter-log-hide-reason": "وجہ:", - "abusefilter-management": "غلط استعمال فلٹرو انتظام", "abusefilter-list": "سف فلٹر", "abusefilter-list-status": "حیثیت", "abusefilter-list-visibility": "پوشیک", diff --git a/AbuseFilter/i18n/kjp.json b/AbuseFilter/i18n/kjp.json index af6ab9cf..c321e0da 100644 --- a/AbuseFilter/i18n/kjp.json +++ b/AbuseFilter/i18n/kjp.json @@ -4,10 +4,21 @@ "Rul1902" ] }, - "abuselog": "ကျံင်းဖၠံင်ပၞံင့်လ်ုၜး ဆ်ုမာၮါင်း", + "abusefilter-blocker": "သုံႋအင်းတ်ုဖၠ ယောဝ်ႋဆၟိုဝ်စဏေဝ့်", + "abusefilter-log-search-title": "ခေါဟ်တင်လ်ုဖး", + "abusefilter-log-search-submit": "မ်ုအင်းၰူ့", + "abusefilter-log-noactions": "အှ်ဏင်မိင်အေ", + "abusefilter-log-linkoncontribs": "သုံႋအင်းတ်ုဖၠ ဆ်ုမါဏါင်း", + "abusefilter-list-edit": "သံင့်ၜးၯဴ", "abusefilter-list-options-scope-local": "ဆ်ုလင်ဍာ ပၞံင့်လ်ုဖးလှ်", "abusefilter-edit-disallow-other": "ၰာႋၰံင် လိက်သုံ့ၜိင်း", "abusefilter-edit-disallow-actions": "ဆ်ုသုဂ်ကၠယ်လ်ုဖး:", "abusefilter-edit-tag-hidden-placeholder": "မာဍိုင် (မာနံင်လ်ုကော်မာ)", - "abusefilter-edit-builder-vars-page-prefixedtitle": "အခေါတ်ကျံင် ဍုဂ်ဍုဂ်ပါင်ပါင်" + "abusefilter-edit-history": "မေင်ႋစိင်:", + "abusefilter-edit-tools": "ခြီခြာ့လ်ုဖး", + "abusefilter-edit-builder-vars-page-prefixedtitle": "အခေါတ်ကျံင် ဍုဂ်ဍုဂ်ပါင်ပါင်", + "abusefilter-history-diff": "မ်ုအင်းလယ်လ်ုဖး", + "abusefilter-test-submit": "မ်ုစံင်ႋယောဝ်ႋ", + "abusefilter-examine-submit": "မ်ုအင်းၰူ့", + "abusefilter-topnav-log": "သုံႋအင်းတ်ုဖၠ ဆ်ုမါဏါင်း" } diff --git a/AbuseFilter/i18n/kk-cyrl.json b/AbuseFilter/i18n/kk-cyrl.json index 90afbed8..ff5e5292 100644 --- a/AbuseFilter/i18n/kk-cyrl.json +++ b/AbuseFilter/i18n/kk-cyrl.json @@ -2,13 +2,13 @@ "@metadata": { "authors": [ "Arystanbek", + "Batyrbek.kz", "GaiJin", - "Нұрлан Рахымжанов", - "Batyrbek.kz" + "Нұрлан Рахымжанов" ] }, - "abusefilter": "Қиянат жасауды сүзгілеу ішкіқұрылымы", - "abuselog": "Қиянат жасау журналы", + "abusefilter": "Қиянаттауды сүзгілеу сүзгіш басқармасы", + "abuselog": "Бұзақылық жасауды сүзгілеу журналы", "abusefilter-intro": "Қиянат жасауды сүзгілеу барлық әрекеттерді автоматты түрде сүзгілейтін автоматтандырылған бағдарламалық жасақтама механизмі. Бұл интерфейс нақты сүзгіштердің тізімін көретуде және оларды өзгеруге мүмкіндік береді.", "abusefilter-blocker": "Қиянат жасауды сүзгілеу", "abusefilter-blockreason": "Қиянаттауды сүзгілеу сүзгіші арқылы автоматты бұғатталды.\nЕрежеге сәйкес сипаттамасы:$1", @@ -16,7 +16,7 @@ "right-abusefilter-view": "Сүзгішті қарау", "right-abusefilter-log": "Қиянат жасау журналын қарау", "right-abusefilter-log-detail": "Бұзақылық жасау журнал жазбасынан толығырақ қарау", - "right-abusefilter-private": "Бұзақылық жасау журналынан жеке деректерін қарау", + "right-abusefilter-privatedetails": "Бұзақылық жасау журналынан жеке деректерін қарау", "right-abusefilter-modify-restricted": "Қиянаттауды сүзгілеу сүзгішінен шектеу әрекеттерін өзгерту", "right-abusefilter-revert": "Осы қиянаттауды сүзгілеу сүзгішіндегі барлық өзгертулерді қайтару", "right-abusefilter-view-private": "Жеке деп белгіленген қиянаттауды сүзгілеу сүзгішін қарау", @@ -28,11 +28,10 @@ "action-abusefilter-view": "қиянаттауды сүзгілеу сүзгішін қарау", "action-abusefilter-log": "Қиянат жасау журналын қарау", "action-abusefilter-log-detail": "бұзақылық жасау журнал жазбасынан толығырақ қарау", - "action-abusefilter-private": "бұзақылық жасау журналынан жеке деректерін қарау", + "action-abusefilter-privatedetails": "бұзақылық жасау журналынан жеке деректерін қарау", "action-abusefilter-modify-restricted": "қиянаттауды сүзгілеу сүзгішінен шектеу әрекеттерін өзгерту", "action-abusefilter-revert": "осы қиянаттауды сүзгілеу сүзгішіндегі барлық өзгертулерді қайтару", "action-abusefilter-view-private": "Жеке деп белгіленген қиянаттауды сүзгілеу сүзгіштерін қарау", - "abusefilter-log": "Бұзақылық жасауды сүзгілеу журналы", "abusefilter-log-summary": "Бұл журналда сүзгіштердің бұзақылық әрекеттерді табуына қатысты барлық әрекеттер тізімі көртетілген.", "abusefilter-log-search": "Қиянаттау журналынан іздеу", "abusefilter-log-search-user": "Қатысушы:", @@ -52,13 +51,12 @@ "abusefilter-log-details-var": "Айнымалылар", "abusefilter-log-details-val": "Мәні:", "abusefilter-log-details-vars": "Әрекет параметрлері", - "abusefilter-log-details-private": "Жеке деректері", + "abusefilter-log-details-privatedetails": "Жеке деректері", "abusefilter-log-details-ip": "Қайнар IP мекен жайы", "abusefilter-log-noactions": "ешқандай", "abusefilter-log-details-diff": "Өңдеп жасаған өзгерістері", "abusefilter-log-linkoncontribs": "Қиянат жасау журналы", "abusefilter-log-linkoncontribs-text": "Бұл қатысушының қиянат жасау журналы", - "abusefilter-log-hidden": "(жазба жасырылған)", "abusefilter-log-hidden-implicit": "(жасырылған себебі нұсқасы жойылған)", "abusefilter-log-cannot-see-details": "Бұл жазбаның егжей-тегжейін көруге рұқсатыңыз жоқ.", "abusefilter-log-details-hidden": "Бұл жазба барлық қатысушыларға көрінуі жасырылғандықтан егжей-тегжейін көре алмайсыз.", @@ -68,7 +66,6 @@ "abusefilter-log-hide-reason": "Себебі:", "abusefilter-log-hide-forbidden": "Қиянаттау журнал енгізілімдерін жасыруға рұқсатыңыз жоқ.", "logentry-abusefilter-hit": "$1 $4 сүзгісін шақырды, $3 бетіндегі орындалу әрекеті: «$5».\nҚолданылған шара: $6 ($7)", - "abusefilter-management": "Қиянаттауды сүзгілеу сүзгіш басқармасы", "abusefilter-list": "Барлық сүзгіштер", "abusefilter-list-id": "Сүзгіш сәйкестендіргіші:", "abusefilter-list-status": "Статусы", @@ -88,6 +85,7 @@ "abusefilter-disabled": "Ажыратылған", "abusefilter-hitcount": "$1", "abusefilter-new": "Жаңа сүзгіш бастау", + "abusefilter-import-button": "Сүзгішті импорттау", "abusefilter-return": "Сүзгіш басқармасына қайта оралу", "abusefilter-status-global": "Ғаламдық", "abusefilter-list-options": "Талғаулар", @@ -201,8 +199,8 @@ "abusefilter-edit-builder-vars-all-links": "Жаңа мәтінде барлық сыртқы сілтемелер", "abusefilter-edit-builder-vars-added-links": "Өңдемеде қосылған барлық сыртқы сілтемелер", "abusefilter-edit-builder-vars-removed-links": "Өңдемеде барлық сыртқы сілтемлер аласталған", - "abusefilter-edit-builder-vars-old-text": "Өңдемеден бұрынғы беттің ескі уикимәтіні", - "abusefilter-edit-builder-vars-new-text": "Өңдемеден кейінгі бетің жаңа уикимәтіні", + "abusefilter-edit-builder-vars-old-wikitext": "Өңдемеден бұрынғы беттің ескі уикимәтіні", + "abusefilter-edit-builder-vars-new-wikitext": "Өңдемеден кейінгі бетің жаңа уикимәтіні", "abusefilter-edit-builder-vars-restrictions-edit": "Беттің өңдеуден қорғау деңгейі", "abusefilter-edit-builder-vars-restrictions-move": "Беттің жылжытудан қорғау деңгейі", "abusefilter-edit-builder-vars-restrictions-create": "Беттің қорғауын жасау", @@ -267,7 +265,6 @@ "abusefilter-topnav-examine": "Соңғы өңдемелерді қарап шығу", "abusefilter-topnav-log": "Қиянат жасау журналы", "abusefilter-topnav-tools": "Дұрыстау құралдары", - "abusefilter-topnav-import": "Сүзгішті импорттау", "abusefilter-log-name": "Қиянаттауды сүзгілеу журналы", "abusefilter-log-header": "Бұл журналда сүзгіштердің жасалу өзгерістерінің түйіндемесі көрсетілген.\nТолық егжей-тегжейі үшін жуықтағы сүзгіш өзгерістері [[Special:AbuseFilter/history|тізімін]] қараңыз.", "abusefilter-log-noresults": "Нәтиже жоқ", diff --git a/AbuseFilter/i18n/km.json b/AbuseFilter/i18n/km.json index 2f35736b..9ed7d82d 100644 --- a/AbuseFilter/i18n/km.json +++ b/AbuseFilter/i18n/km.json @@ -1,6 +1,7 @@ { "@metadata": { "authors": [ + "Daimona Eaytoy", "Lovekhmer", "T-Rithy", "Thearith", @@ -8,9 +9,9 @@ "វ័ណថារិទ្ធ" ] }, - "abusefilter": "ការកំណត់រចនាសម្ព័ន្ឋតម្រងការបំពានច្បាប់", - "abuselog": "កំណត់ហេតុនៃការបំពានច្បាប់", - "abusefilter-blocker": "តម្រងការបំពានច្បាប់", + "abusefilter": "គ្រប់គ្រងតម្រងការបំពានច្បាប់", + "abuselog": "កំណត់ហេតុនៃតម្រងការបំពានច្បាប់", + "abusefilter-blocker": "តម្រងការបំពានច្បាប់", "abusefilter-blockreason": "ត្រូវបានរាំងខ្ទប់ជាស្វ័យប្រវត្តិដោយតម្រងការបំពានច្បាប់។ ច្បាប់ចែងថា៖ $1", "abusefilter-degroupreason": "សិទ្ឋិដែលត្រូវបានដកហូតជាស្វ័យប្រវត្តិដោយតម្រងការបំពានច្បាប់។ ច្បាប់ចែងថា៖ $1", "abusefilter-accountreserved": "ឈ្មោះគណនីនេះត្រូវបានរក្សាទុកសម្រាប់ឱ្យតម្រងការបំពានច្បាប់ប្រើប្រាស់។", @@ -18,15 +19,14 @@ "right-abusefilter-view": "មើលតម្រងការបំពានច្បាប់", "right-abusefilter-log": "មើលកំណត់ហេតុនៃការបំពានច្បាប់", "right-abusefilter-log-detail": "មើលកំណត់ហេតុលំអិតស្ដីពីការបំពានច្បាប់", - "right-abusefilter-private": "មើលទិន្នន័យឯកជននៅក្នុងកំណត់ហេតុនៃការបំពានច្បាប់", + "right-abusefilter-privatedetails": "មើលទិន្នន័យឯកជននៅក្នុងកំណត់ហេតុនៃការបំពានច្បាប់", "right-abusefilter-view-private": "មើលតម្រងការបំពានច្បាប់ដែលបានដាក់ជាឯកជន", "right-abusefilter-log-private": "មើលកំណត់ហេតុអំពីតម្រងការបំពានច្បាប់ដែលបានដាក់ជាឯកជន", "action-abusefilter-modify": "កែសម្រួលតម្រងការបំពានច្បាប់", "action-abusefilter-view": "មើលតម្រងការបំពានច្បាប់", "action-abusefilter-log": "មើលកំណត់ហេតុនៃការបំពានច្បាប់", "action-abusefilter-log-detail": "មើលកំណត់ហេតុលំអិតស្ដីពីការបំពានច្បាប់", - "action-abusefilter-private": "មើលទិន្នន័យឯកជននៅក្នុងកំណត់ហេតុនៃការបំពានច្បាប់", - "abusefilter-log": "កំណត់ហេតុនៃតម្រងការបំពានច្បាប់", + "action-abusefilter-privatedetails": "មើលទិន្នន័យឯកជននៅក្នុងកំណត់ហេតុនៃការបំពានច្បាប់", "abusefilter-log-search": "ស្វែងរកកំណត់ហេតុនៃការបំពានច្បាប់", "abusefilter-log-search-user": "អ្នកប្រើប្រាស់៖", "abusefilter-log-search-filter": "ID តម្រង៖", @@ -42,13 +42,13 @@ "abusefilter-log-details-var": "អញ្ញត្តិ", "abusefilter-log-details-val": "តម្លៃ", "abusefilter-log-details-vars": "ប៉ារ៉ាមែត្រសកម្មភាព", - "abusefilter-log-details-private": "ទិន្នន័យឯកជន", + "abusefilter-log-details-privatedetails": "ទិន្នន័យឯកជន", "abusefilter-log-details-ip": "អាសយដ្ឋាន IP ដើមហេតុ", + "abusefilter-log-details-checkuser": "ត្រួតពិនិត្យអ្នកប្រើប្រាស់", "abusefilter-log-noactions": "ទទេ", - "abusefilter-log-details-diff": "ការកែប្រែដែលបានធ្វើឡើង", + "abusefilter-log-details-diff": "បន្លាស់ប្ដូរដែលបានធ្វើឡើងក្នុងការកែប្រែ", "abusefilter-log-linkoncontribs": "កំណត់ហេតុនៃការបំពានច្បាប់", "abusefilter-log-hide-reason": "មូលហេតុ៖", - "abusefilter-management": "គ្រប់គ្រងតម្រងការបំពានច្បាប់", "abusefilter-list": "តម្រងទាំងអស់", "abusefilter-list-id": "ID តម្រង", "abusefilter-list-status": "ស្ថានភាព", @@ -68,6 +68,7 @@ "abusefilter-disabled": "មិនប្រើ", "abusefilter-hitcount": "$1 {{PLURAL:$1|ដង|ដង}}", "abusefilter-new": "បង្កើតតំរងថ្មី", + "abusefilter-import-button": "នាំចូលតម្រង", "abusefilter-return": "ត្រឡប់ទៅកាន់ការគ្រប់គ្រងនៃតម្រងការបំពានច្បាប់", "abusefilter-status-global": "សាកល", "abusefilter-list-options": "ជម្រើស", @@ -75,7 +76,7 @@ "abusefilter-list-options-deleted-only": "បង្ហាញតែតម្រងដែលបានលុបចោលប៉ុណ្ណោះ", "abusefilter-list-options-deleted-hide": "លាក់បាំងតម្រងដែលបានលុប", "abusefilter-list-options-deleted-show": "រាប់បញ្ចូលតម្រងដែលបានលុប", - "abusefilter-list-options-scope": "មើលតម្រងពីក្នុង៖", + "abusefilter-list-options-scope": "មើលតម្រង៖", "abusefilter-list-options-scope-local": "វិគីតំបន់", "abusefilter-list-options-scope-global": "ច្បាប់សាកល", "abusefilter-list-options-hidedisabled": "លាក់តម្រងអសកម្ម", @@ -89,6 +90,7 @@ "abusefilter-edit-save": "រក្សាទុកតម្រង", "abusefilter-edit-id": "ID តម្រង:", "abusefilter-edit-description": "ពណ៌នា:\n:''(អាចមើលបានជាសាធារណៈ)''", + "abusefilter-edit-field-description": "ការពិពណ៌នា", "abusefilter-edit-group": "ក្រុមតម្រង៖", "abusefilter-edit-flags": "ទង់៖", "abusefilter-edit-enabled": "បើកឱ្យប្រើតម្រងនេះ", @@ -96,11 +98,12 @@ "abusefilter-edit-hidden": "លាក់ព័ត៌មានលំអិតអំពីតម្រងនេះ មិនឱ្យមើលជាសាធារណៈ", "abusefilter-edit-global": "តម្រងសាកល", "abusefilter-edit-rules": "លក្ខខណ្ឌ:", + "abusefilter-edit-field-conditions": "លក្ខខណ្ឌ", "abusefilter-edit-notes": "សម្គាល់:", "abusefilter-edit-lastmod": "តម្រងដែលត្រូវបានកែប្រែចុងក្រោយ:", "abusefilter-edit-lastmod-text": "$1 ដោយ $2", "abusefilter-edit-action-block": "ហាមឃាត់អ្នកប្រើប្រាស់ និង/ឬអាសយដ្ឋានIPពីការកែប្រែ", - "abusefilter-edit-throttle-period": "រយៈពេល៖", + "abusefilter-edit-throttle-period": "រយៈពេល (ជាវិនាទី)៖", "abusefilter-edit-warn-message": "សារប្រព័ន្ធដែលប្រើប្រាស់សម្រាប់ការព្រមាន៖", "abusefilter-edit-warn-other": "សារផ្សេងទៀត", "abusefilter-edit-warn-other-label": "ឈ្មោះទំព័រនៃសារដទៃផ្សេងទៀត៖\n៖''(ដោយគ្មានបុព្វបទ MediaWiki)''", @@ -124,8 +127,10 @@ "abusefilter-edit-builder-op-arithmetic-modulo": "សំណល់ (%)", "abusefilter-edit-builder-op-arithmetic-pow": "ស្វ័យគុណ (**)", "abusefilter-edit-builder-group-op-comparison": "ប្រមាណវិធីប្រៀបធៀប", - "abusefilter-edit-builder-op-comparison-equal": "ស្មើនឹង (==)", - "abusefilter-edit-builder-op-comparison-notequal": "មិនស្មើនឹង (!=)", + "abusefilter-edit-builder-op-comparison-equal": "តម្លៃស្មើនឹង (==)", + "abusefilter-edit-builder-op-comparison-equal-strict": "តម្លៃនិងប្រភេទស្មើនឹង (===)", + "abusefilter-edit-builder-op-comparison-notequal": "តម្លៃមិនស្មើនឹង (!=)", + "abusefilter-edit-builder-op-comparison-notequal-strict": "តម្លៃនិងប្រភេទមិនស្មើនឹង (!==)", "abusefilter-edit-builder-op-comparison-lt": "តូចជាង (<)", "abusefilter-edit-builder-op-comparison-gt": "ធំជាង (>)", "abusefilter-edit-builder-op-comparison-lte": "តូចជាងឬស្មើ (<=)", @@ -161,7 +166,7 @@ "abusefilter-edit-builder-vars-user-editcount": "កែប្រែចំនួនអ្នកប្រើប្រាស់", "abusefilter-edit-builder-vars-user-age": "អាយុកាលគណនីអ្នកប្រើប្រាស់", "abusefilter-edit-builder-vars-user-name": "ឈ្មោះគណនីអ្នកប្រើប្រាស់", - "abusefilter-filter-log": "បំលាស់ប្ដូរតម្រងថ្មីៗ", + "abusefilter-filter-log": "បន្លាស់ប្ដូរតម្រងថ្មីៗ", "abusefilter-history-foruser": "បំលាស់ប្ដូរនានាដោយ $1", "abusefilter-history-hidden": "លាក់បាំង", "abusefilter-history-enabled": "ប្រើ", @@ -179,7 +184,7 @@ "abusefilter-history-select-legend": "ចម្រាញ់លទ្ធផលស្វែងរក", "abusefilter-history-select-user": "អ្នកប្រើប្រាស់៖", "abusefilter-history-select-submit": "ចម្រាញ់", - "abusefilter-history-diff": "បំលាស់ប្ដូរ", + "abusefilter-history-diff": "បន្លាស់ប្ដូរ", "abusefilter-action-tag": "ស្លាក", "abusefilter-action-warn": "ព្រមាន", "abusefilter-action-block": "ហាមឃាត់", @@ -193,12 +198,12 @@ "abusefilter-revert-reasonfield": "មូលហេតុ៖", "abusefilter-test-submit": "សាកល្បង", "abusefilter-test-load": "ផ្ទុក", - "abusefilter-test-user": "បំលាស់ប្ដូរដោយអ្នកប្រើប្រាស់៖", + "abusefilter-test-user": "បន្លាស់ប្ដូរដោយអ្នកប្រើប្រាស់៖", "abusefilter-test-period-start": "បំលាស់ប្ដូរដែលធ្វើឡើងក្រោយ៖", - "abusefilter-test-period-end": "បំលាស់ប្ដូរដែលធ្វើឡើងមុន៖", + "abusefilter-test-period-end": "បន្លាស់ប្ដូរដែលធ្វើឡើងមុន៖", "abusefilter-test-page": "បំលាស់ប្ដូរដែលធ្វើឡើងនៅលើទំព័រ៖", "abusefilter-changeslist-examine": "ត្រួតពិនិត្យ", - "abusefilter-examine-legend": "ជ្រើសរើសបំលាស់ប្ដូរផ្សេងៗ", + "abusefilter-examine-legend": "ជ្រើសរើសបន្លាស់ប្ដូរ", "abusefilter-examine-diff": "URL នៃភាពខុសគ្នា៖", "abusefilter-examine-user": "អ្នកប្រើប្រាស់៖", "abusefilter-examine-title": "ចំណងជើងទំព័រ៖", @@ -207,7 +212,6 @@ "abusefilter-examine-notfound": "បំលាស់ប្ដូរដែលអ្នកស្នើសុំមិនអាចរកឃើញទេ។", "abusefilter-topnav-home": "ទំព័រដើម", "abusefilter-topnav-log": "កំណត់ហេតុនៃការបំពានច្បាប់", - "abusefilter-topnav-import": "នាំចូលតម្រង", "abusefilter-log-name": "កំណត់ហេតុនៃតម្រងការបំពានច្បាប់", "abusefilter-log-noresults": "គ្មានលទ្ធផល", "abusefilter-diff-title": "ភាពខុសគ្នានៃកំណែនានា", diff --git a/AbuseFilter/i18n/kn.json b/AbuseFilter/i18n/kn.json index f8670360..a14564fa 100644 --- a/AbuseFilter/i18n/kn.json +++ b/AbuseFilter/i18n/kn.json @@ -2,12 +2,14 @@ "@metadata": { "authors": [ "Akoppad", + "Anoop rao", "Dimension10", "Nayvik", - "පසිඳු කාවින්ද", - "VASANTH S.N." + "VASANTH S.N.", + "පසිඳු කාවින්ද" ] }, + "abusefilter-disallowed": "ಈ ಕ್ರಿಯೆಯನ್ನು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಹಾನಿಕಾರಕವೆಂದು ಗುರುತಿಸಲಾಗಿದೆ, ಆದ್ದರಿಂದ ಈ ಸಂಪಾದನೆಯನ್ನು ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ. ನಿಮ್ಮ ಕ್ರಿಯೆಯು ರಚನಾತ್ಮಕವಾಗಿದೆ ಎಂದು ನೀವು ಭಾವಿಸಿದರೆ, ದಯವಿಟ್ಟು ನೀವು ಏನು ಮಾಡಲು ಪ್ರಯತ್ನಿಸುತ್ತಿದ್ದೀರಿ ಎಂಬುದನ್ನು [[Special:Listusers/sysop|ನಿರ್ವಾಹಕರಿಗೆ]] ತಿಳಿಸಿ. ನಿಮ್ಮ ಕ್ರಿಯೆಗೆ ಹೊಂದಿಕೆಯಾಗುವ ದುರುಪಯೋಗ ನಿಯಮದ ಸಂಕ್ಷಿಪ್ತ ವಿವರಣೆ: $1", "abusefilter-log-search-title": "ಶೀರ್ಷಿಕೆ:", "abusefilter-log-search-submit": "ಹುಡುಕು", "abusefilter-log-detailslink": "ವಿವರಗಳು", @@ -16,7 +18,7 @@ "abusefilter-log-details-var": "ಮಾರ್ಪಡಬಲ್ಲ", "abusefilter-log-details-val": "ಮೌಲ್ಯ", "abusefilter-log-details-vars": "ಕಾರ್ಯದ ಪರಿಮಿತಿಗಳು", - "abusefilter-log-details-private": "ಖಾಸಗಿ ದತ್ತಾಂಶ", + "abusefilter-log-details-privatedetails": "ಖಾಸಗಿ ದತ್ತಾಂಶ", "abusefilter-log-noactions": "ಯಾವುದೂ ಇಲ್ಲ", "abusefilter-log-details-diff": "ಸಂಪಾದನೆಯಲ್ಲಿ ಮಾಡಿದ ಬದಲಾವಣೆಗಳು", "abusefilter-log-linkoncontribs": "ದುರುಪಯೋಗದ ಅನುಕ್ರಮಣಿಕೆ", @@ -95,13 +97,13 @@ "abusefilter-edit-builder-vars-all-links": "ಹೊಸ ಪಠ್ಯದಲ್ಲಿ ಎಲ್ಲಾ ಬಾಹ್ಯ ಸಂಪರ್ಕ ಕೊಂಡಿಗಳು", "abusefilter-edit-builder-vars-added-links": "ಎಲ್ಲಾ ಬಾಹ್ಯ ಸಂಪರ್ಕ ಕೊಂಡಿಗಳು ತಿದ್ದು ಪಡಿಯಲ್ಲಿ ಸೇರಿಸಲಾಯಿತು", "abusefilter-edit-builder-vars-removed-links": "ಎಲ್ಲಾ ಬಾಹ್ಯ ಸಂಪರ್ಕ ಕೊಂಡಿಗಳನ್ನು ತಿದ್ದುಪಡಿಯಲ್ಲಿ ಅಳಿಸಲಾಗಿದೆ", - "abusefilter-edit-builder-vars-old-text": "ಹಳೇ wikitext ಪುಟ , ತಿದ್ದುಪಡಿಯ ಮೊದಲು", - "abusefilter-edit-builder-vars-new-text": "ಹೊಸ wikitext ಪುಟ , ತಿದ್ದುಪಡಿಯ ನಂತರ", + "abusefilter-edit-builder-vars-old-wikitext": "ಹಳೇ wikitext ಪುಟ , ತಿದ್ದುಪಡಿಯ ಮೊದಲು", + "abusefilter-edit-builder-vars-new-wikitext": "ಹೊಸ wikitext ಪುಟ , ತಿದ್ದುಪಡಿಯ ನಂತರ", "abusefilter-edit-builder-vars-restrictions-edit": "ಪುಟದ ಸಂರಕ್ಷಣೆ ಮಟ್ಟವನ್ನು ತಿದ್ದುಪಡಿಸಿ", "abusefilter-edit-builder-vars-restrictions-move": "ಪುಟದ ಸಂರಕ್ಷಣೆ ಮಟ್ಟವನ್ನು ಸರಿಸಿ", "abusefilter-edit-builder-vars-restrictions-create": "ಪುಟ ರಕ್ಷಣೆ ರಚಿಸಿ", "abusefilter-edit-builder-vars-restrictions-upload": "ಫೈಲ್ ರಕ್ಷಣೆ ನಕಲೇರಿಸಿ", - "abusefilter-edit-builder-vars-old-text-stripped": "ಹಳೆಯ ಪುಟ ಪಠ್ಯ, ಯಾವುದೇ ಮಾರ್ಕ್ಅಪ್ ತೆಗೆಯಲಾದ", + "abusefilter-edit-builder-vars-old-text": "ಹಳೆಯ ಪುಟ ಪಠ್ಯ, ಯಾವುದೇ ಮಾರ್ಕ್ಅಪ್ ತೆಗೆಯಲಾದ", "abusefilter-edit-builder-vars-old-links": "\nಪುಟದಲ್ಲಿನ ಸಂಪರ್ಕ ಕೊಂಡಿಗಳು, ತಿದ್ದುಪಡಿಯ ಮೊದಲು", "abusefilter-history-hidden": "ಅಡಗಿಸಲ್ಪಟ್ಟ", "abusefilter-history-enabled": "ಶಕ್ತಗೊಳಿಸಿದ", diff --git a/AbuseFilter/i18n/ko.json b/AbuseFilter/i18n/ko.json index 62b57a0d..967f29c8 100644 --- a/AbuseFilter/i18n/ko.json +++ b/AbuseFilter/i18n/ko.json @@ -2,33 +2,39 @@ "@metadata": { "authors": [ "Albamhandae", + "Alex00728", + "Bluemersen", "ChongDae", + "Delim", "Freebiekr", "Gapo", + "Garam", + "Hwangjy9", "Hym411", + "IRTC1015", + "Jango", + "Jerrykim306", "Klutzy", + "Ktrst", "Kwj2772", "LFM", + "Macofe", + "Matma Rex", + "MemphisA5", "Pakman", "Priviet", - "Yknok29", - "관인생략", - "아라", "Revi", - "IRTC1015", - "Alex00728", - "Macofe", - "Matma Rex", + "Son77391", "Ykhwong", - "Jerrykim306", - "Delim", - "Bluemersen", - "Tursetic", - "Garam" + "Yknok29", + "관인생략", + "렌즈", + "밝은소년", + "아라" ] }, "abusefilter-desc": "사용자 편집을 규칙에 따라 자동으로 검사합니다", - "abusefilter": "편집 필터 설정", + "abusefilter": "편집 필터 관리", "abuselog": "편집 필터 기록", "abusefilter-intro": "편집 필터 관리 인터페이스를 사용하는 여러분을 환영합니다.\n편집 필터는 모든 행위에 대해 문제가 있는지 자동으로 검사하는 소프트웨어입니다.\n이 인터페이스는 정의된 필터 목록을 나열하며, 나열된 필터는 수정할 수 있습니다.", "abusefilter-mustviewprivateoredit": "보안상의 이유로, 비공개 편집 필터를 보거나 필터 편집 권한을 가진 사용자만이 이 양식을 사용할 수 있습니다.", @@ -40,35 +46,42 @@ "abusefilter-blocker": "편집 필터", "abusefilter-blockreason": "편집 필터에 의해 자동으로 차단되었습니다.\n일치한 규칙에 대한 설명: $1", "abusefilter-degroupreason": "편집 필터에 의해 자동으로 권한이 해제되었습니다.\n규칙 설명: $1", + "abusefilter-blockautopromotereason": "편집 필터에 의해 자동으로 권한이 해제되었습니다.\n규칙 설명: $1", "abusefilter-accountreserved": "이 계정 이름은 편집 필터가 사용하도록 지정되어 있습니다.", - "right-abusefilter-modify": "편집 필터 수정", + "right-abusefilter-modify": "편집 필터를 만들거나 수정하기", "right-abusefilter-view": "편집 필터 보기", "right-abusefilter-log": "편집 필터 기록 보기", "right-abusefilter-log-detail": "편집 필터 기록의 자세한 내용 보기", - "right-abusefilter-private": "편집 필터 기록의 비공개 정보 보기", - "right-abusefilter-private-log": "편집 필터 비공개 상세 정보 접근 기록 보기", + "right-abusefilter-privatedetails": "편집 필터 기록의 비공개 정보 보기", + "right-abusefilter-privatedetails-log": "편집 필터 비공개 상세 정보 접근 기록 보기", "right-abusefilter-modify-restricted": "편집 필터의 제한된 기능 설정 바꾸기", "right-abusefilter-revert": "주어진 필터에 의한 모든 바뀜을 되돌리기", "right-abusefilter-view-private": "비공개된 필터 보기", "right-abusefilter-log-private": "비공개된 편집 필터 기록 보기", "right-abusefilter-hide-log": "편집 필터 기록의 항목 숨기기", "right-abusefilter-hidden-log": "숨겨진 편집 필터 기록 보기", - "right-abusefilter-modify-global": "전역 필터 만들거나 수정하기", + "right-abusefilter-modify-global": "전역 편집 필터를 만들거나 수정하기", "action-abusefilter-modify": "편집 필터를 수정할", "action-abusefilter-view": "편집 필터를 볼", "action-abusefilter-log": "편집 필터 기록을 볼", "action-abusefilter-log-detail": "편집 필터 기록에서 자세한 내용을 볼", - "action-abusefilter-private": "편집 필터 기록에서 비공개 내용을 볼", - "action-abusefilter-private-log": "편집 필터 비공개 상세 정보 접근 기록 보기", + "action-abusefilter-privatedetails": "편집 필터 기록에서 비공개 내용을 볼", + "action-abusefilter-privatedetails-log": "편집 필터 비공개 상세 정보 접근 기록 보기", "action-abusefilter-modify-restricted": "편집 필터의 제한된 기능 설정을 바꿀", "action-abusefilter-revert": "주어진 필터에 의한 모든 바뀜을 되돌릴", "action-abusefilter-view-private": "비공개된 필터를 볼", "action-abusefilter-log-private": "비공개된 필터의 기록을 볼", - "abusefilter-log": "편집 필터 기록", + "action-abusefilter-hide-log": "편집 필터 기록의 항목 숨기기", + "action-abusefilter-hidden-log": "숨겨진 편집 필터 기록 보기", + "action-abusefilter-modify-global": "전역 편집 필터를 만들거나 수정하기", "abusefilter-log-summary": "이 기록은 필터 규칙과 일치하는 모든 행위에 대한 목록을 보여줍니다.", "abusefilter-log-search": "편집 필터 기록 검색", "abusefilter-log-search-user": "사용자:", - "abusefilter-log-search-filter": "필터 ID (파이프로 구분):", + "abusefilter-log-search-group": "필터 그룹:", + "abusefilter-log-search-group-any": "모두", + "abusefilter-log-search-filter": "필터 ID:", + "abusefilter-log-search-filter-help": "파이프로 구분하되, 전역 필터의 경우 \"$1\" 두문자로 구별합니다", + "abusefilter-log-search-filter-help-central": "파이프로 구분", "abusefilter-log-search-title": "제목:", "abusefilter-log-search-wiki": "위키:", "abusefilter-log-search-impact": "결과:", @@ -97,19 +110,21 @@ "abusefilter-log-details-var": "변수", "abusefilter-log-details-val": "값", "abusefilter-log-details-vars": "명령 변수", - "abusefilter-log-details-private": "비공개 기록 상세 정보", + "abusefilter-log-details-privatedetails": "비공개 기록 상세 정보", "abusefilter-log-details-ip": "사용자의 IP 주소", "abusefilter-log-details-checkuser": "사용자 검사", "abusefilter-log-noactions": "없음", + "abusefilter-log-noactions-filter": "없음", "abusefilter-log-details-diff": "편집에서 바뀐 내용", "abusefilter-log-linkoncontribs": "편집 필터 기록", "abusefilter-log-linkoncontribs-text": "{{GENDER:$1|이 사용자}}의 편집 필터 기록", "abusefilter-log-linkonhistory": "편집 필터 기록 보기", "abusefilter-log-linkonhistory-text": "이 문서의 악용 기록 보기", - "abusefilter-log-hidden": "(항목 숨겨짐)", + "abusefilter-log-linkonundelete": "편집 필터 기록 보기", + "abusefilter-log-linkonundelete-text": "이 문서의 악용 기록 보기", "abusefilter-log-hidden-implicit": "(특정판이 삭제되어 숨겨짐)", "abusefilter-log-cannot-see-details": "이 항목의 자세한 내용을 볼 권한이 없습니다.", - "abusefilter-log-cannot-see-private-details": "이 항목의 비공개 상세 정보를 볼 권한이 없습니다.", + "abusefilter-log-cannot-see-privatedetails": "이 항목의 비공개 상세 정보를 볼 권한이 없습니다.", "abusefilter-log-nonexistent": "지정된 ID를 가진 항목이 존재하지 않습니다.", "abusefilter-log-details-hidden": "이 항목은 비공개로 설정되었기 때문에 이 항목의 자세한 사항을 볼 수 없습니다.", "abusefilter-log-details-hidden-implicit": "연결된 판이 비공개로 설정되었기 때문에 이 항목의 자세한 사항을 볼 수 없습니다.", @@ -127,9 +142,10 @@ "log-action-filter-abusefilter-create": "새 필터 만들기", "log-action-filter-abusefilter-modify": "필터 수정", "log-action-filter-suppress-abuselog": "악용 기록 숨기기", + "log-action-filter-rights-blockautopromote": "자동처리 차단", "logentry-abusefilterprivatedetails-access": "$1님이 $3의 비공개 상세 정보에 {{GENDER:$2|접근하였습니다}}", + "logentry-rights-blockautopromote": "$1님이 {{GENDER:$4|$3}}님의 자동 권한 상승을 $5 {{GENDER:$2|차단했습니다}}", "abusefilterprivatedetails-log-name": "편집 필터 비공개 상세 정보 접근 기록", - "abusefilter-management": "편집 필터 관리", "abusefilter-list": "모든 필터", "abusefilter-list-id": "필터 ID", "abusefilter-list-pattern": "패턴", @@ -151,6 +167,7 @@ "abusefilter-throttled": "속도 제한", "abusefilter-hitcount": "$1{{PLURAL:$1|회}}", "abusefilter-new": "새 필터 만들기", + "abusefilter-import-button": "필터 가져오기", "abusefilter-return": "필터 관리 페이지로 돌아가기", "abusefilter-status-global": "전역", "abusefilter-list-options": "설정", @@ -171,11 +188,13 @@ "abusefilter-list-options-search-like": "순수 쿼리", "abusefilter-list-options-search-rlike": "정규 표현식", "abusefilter-list-options-search-irlike": "대소문자 구별을 하지 않는 정규 표현식", + "abusefilter-list-invalid-searchmode": "지정된 검색 모드는 유효하지 않습니다.", "abusefilter-list-regexerror": "검색 중 오류가 발생했습니다: 정규 표현식 문법 오류.", "abusefilter-list-options-submit": "적용", "abusefilter-tools-text": "편집 필터를 제작하고 디버그하는 데 유용한 도구입니다.", "abusefilter-tools-expr": "구문 검사기", "abusefilter-tools-submitexpr": "시험", + "abusefilter-tools-syntax-error": "필터에 유효하지 않은 문법이 있습니다.", "abusefilter-tools-reautoconfirm": "자동 인증 상태를 복구", "abusefilter-tools-reautoconfirm-user": "사용자:", "abusefilter-tools-reautoconfirm-submit": "자동 인증 상태 복구", @@ -189,8 +208,7 @@ "abusefilter-edit-token-not-match": "편집이 저장되지 않았습니다! 다시 저장해 주십시오.", "abusefilter-edit-oldwarning": "<strong>이 필터의 이전 버전을 수정하고 있습니다.\n아래의 통계는 이 필터의 최신판에 대한 것입니다.\n변경 사항을 저장하면 편집하고 있는 판 이후의 모든 변경 사항을 덮어쓰게 됩니다.</strong> •\n[[Special:AbuseFilter/history/$2|이 필터의 역사로 돌아가기]].", "abusefilter-edit-status-label": "통계:", - "abusefilter-edit-status": "최근 {{PLURAL:$1|동작}} $1개 중 $2건($3%)이 이 필터와 일치하였습니다.", - "abusefilter-edit-status-profile": "최근 {{PLURAL:$1|동작}} $1개 중 $2건($3%)이 이 필터와 일치하였습니다.\n평균적으로 필터의 작동 시간은 $4밀리초이며, $5만큼의 {{PLURAL:$5|부하}}가 걸리고 있습니다.", + "abusefilter-edit-status": "최근 {{PLURAL:$1|동작}} $1개 중 $2건($3%)이 이 필터와 일치하였습니다.\n평균적으로 필터의 작동 시간은 $4밀리초이며, $5만큼의 {{PLURAL:$5|부하}}가 걸리고 있습니다.", "abusefilter-edit-throttled-warning": "'''경고''': 이 필터는 자동으로 유해한 것으로 표시되었습니다. 안전 장치로서 다음의 조치는 실행되지 않을 것입니다. ($1) 검토한 다음 조건을 [[mw:Extension:AbuseFilter/Conditions|최적화]]하여 이 제한을 제거하십시오.", "abusefilter-edit-new": "새 필터", "abusefilter-edit-save": "필터 저장하기", @@ -223,13 +241,18 @@ "abusefilter-edit-throttle-count": "허용할 동작 수:", "abusefilter-edit-throttle-period": "주기 (단위: 초):", "abusefilter-edit-throttle-groups": "속도 제한 묶기 기준:", - "abusefilter-edit-throttle-ip": "IP 주소", - "abusefilter-edit-throttle-user": "사용자 계정", - "abusefilter-edit-throttle-range": "/16 대역", - "abusefilter-edit-throttle-creationdate": "계정 만들기 서버 시간", - "abusefilter-edit-throttle-editcount": "편집 수", - "abusefilter-edit-throttle-site": "사이트 전반", - "abusefilter-edit-throttle-page": "문서", + "abusefilter-edit-throttle-groups-help": "$1를 참고하십시오.", + "abusefilter-edit-throttle-groups-help-text": "mediawiki.org 문서", + "abusefilter-edit-throttle-hidden-placeholder": "AND로 병합하려면 쉼표로 구분하고, OR로 병합하려면 줄을 나누십시오", + "abusefilter-edit-throttle-placeholder": "AND로 병합하려면 쉼표로 구분하고, OR로 병합하려면 하나씩 추가하십시오", + "abusefilter-throttle-ip": "IP 주소", + "abusefilter-throttle-user": "사용자 계정", + "abusefilter-throttle-range": "/16 대역", + "abusefilter-throttle-creationdate": "계정 생성일", + "abusefilter-throttle-editcount": "편집 수", + "abusefilter-throttle-site": "사이트 전반", + "abusefilter-throttle-page": "문서", + "abusefilter-throttle-none": "(없음)", "abusefilter-throttle-details": "$2{{PLURAL:$2|초}}당 {{PLURAL:$1|동작}} $1회를 허용, 속도 제한 단위: $3", "abusefilter-edit-warn-message": "경고할 때 사용할 시스템 메시지:", "abusefilter-edit-warn-other": "다른 메시지", @@ -269,10 +292,17 @@ "abusefilter-edit-export": "이 필터를 다른 위키로 내보내기", "abusefilter-edit-syntaxok": "감지된 구문 오류가 없습니다.", "abusefilter-edit-syntaxerr": "구문 오류가 감지되었습니다: $1", + "abusefilter-edit-warn-leave": "페이지를 떠나면 이 필터의 모든 변경사항을 잃게 됩니다.", "abusefilter-edit-bad-tags": "입력된 태그 중 올바르지 않은 값이 있습니다.\n태그는 짧고 특수 문자를 포함하지 않아야 하며, 다른 소프트웨어에 의해 확보되지 않은 것이어야 합니다. 다른 이름을 시도하시기 바랍니다.", "abusefilter-edit-notallowed": "필터를 만들거나 편집할 권한이 없습니다.", "abusefilter-edit-notallowed-global": "전역 필터를 만들거나 편집할 권한이 없습니다.", - "abusefilter-edit-notallowed-global-custom-msg": "전역 필터에는 사용자 정의 경고 메시지를 사용할 수 없습니다", + "abusefilter-edit-notallowed-global-custom-msg": "전역 필터의 경우 사용자 지정 경고 및 불허 메시지는 지원되지 않습니다", + "abusefilter-edit-invalid-warn-message": "경고 메시지는 비워둘 수 없습니다.", + "abusefilter-edit-invalid-disallow-message": "경고 메시지는 비워둘 수 없습니다.", + "abusefilter-edit-invalid-throttleperiod": "스로틀 기간은 양의 정수여야 합니다.", + "abusefilter-edit-empty-throttlegroups": "적어도 하나의 스로틀 그룹을 선택해야 합니다.", + "abusefilter-edit-duplicated-throttlegroups": "스로틀 그룹은 중복을 가질 수 없습니다.", + "abusefilter-edit-invalid-throttlegroups": "지정된 스로틀 그룹은 유효하지 않습니다.", "abusefilter-edit-builder-select": "커서가 있는 위치에 추가할 설정을 선택하세요.", "abusefilter-edit-builder-group-op-arithmetic": "산술 연산자", "abusefilter-edit-builder-op-arithmetic-addition": "더하기 (+)", @@ -303,7 +333,8 @@ "abusefilter-edit-builder-misc-contains": "왼쪽 문자열이 오른쪽 문자열을 포함 (contains)", "abusefilter-edit-builder-misc-stringlit": "문자열 그대로 (\"\")", "abusefilter-edit-builder-misc-tern": "3단 연산자 (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "조건부 (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "조건부 (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "짧은 조건부 (if X then Y end)", "abusefilter-edit-builder-group-funcs": "함수", "abusefilter-edit-builder-funcs-length": "문자열 길이 (length)", "abusefilter-edit-builder-funcs-lcase": "소문자로 변환 (lcase)", @@ -339,7 +370,7 @@ "abusefilter-edit-builder-vars-diff": "편집 전후의 차이", "abusefilter-edit-builder-vars-newsize": "새 문서 크기", "abusefilter-edit-builder-vars-oldsize": "이전 문서 크기", - "abusefilter-edit-builder-vars-old-content-model": "오래된 콘텐츠 모델", + "abusefilter-edit-builder-vars-old-content-model": "이전 콘텐츠 모델", "abusefilter-edit-builder-vars-new-content-model": "새 콘텐츠 모델", "abusefilter-edit-builder-vars-removedlines": "편집 중 제거된 줄", "abusefilter-edit-builder-vars-summary": "편집 요약/이유", @@ -374,12 +405,12 @@ "abusefilter-edit-builder-vars-all-links": "바뀐 글에 포함된 모든 외부 링크", "abusefilter-edit-builder-vars-added-links": "편집 중 추가된 모든 외부 링크", "abusefilter-edit-builder-vars-removed-links": "편집 중 제거된 모든 외부 링크", - "abusefilter-edit-builder-vars-old-text": "편집 전 과거 문서의 위키텍스트 (더 이상 쓰이지 않음)", - "abusefilter-edit-builder-vars-new-text": "편집 후 문서의 내용 (위키문법)", + "abusefilter-edit-builder-vars-old-wikitext": "편집 전 과거 문서의 위키텍스트", + "abusefilter-edit-builder-vars-new-wikitext": "편집 후 새 문서의 위키텍스트", "abusefilter-edit-builder-vars-new-pst": "새 문서 위키 텍스트, 변환을 미리 저장", "abusefilter-edit-builder-vars-diff-pst": "편집으로 인한 바뀐 내용의 차이가 통합됨, 미리 저장 변형됨", "abusefilter-edit-builder-vars-addedlines-pst": "줄이 편집 중 추가됨, 미리 저장 변형됨", - "abusefilter-edit-builder-vars-new-text-stripped": "편집 후 마크업을 제거한 문서 내용", + "abusefilter-edit-builder-vars-new-text": "편집 후 마크업을 제거한 문서 내용", "abusefilter-edit-builder-vars-new-html": "편집 후의 HTML 소스", "abusefilter-edit-builder-vars-restrictions-edit": "문서 편집 보호 수준", "abusefilter-edit-builder-vars-restrictions-move": "문서 이동 보호 수준", @@ -393,10 +424,10 @@ "abusefilter-edit-builder-vars-movedto-restrictions-move": "이동 대상 문서의 이동 보호 수준", "abusefilter-edit-builder-vars-movedto-restrictions-create": "이동 대상 문서의 만들기 보호 설정", "abusefilter-edit-builder-vars-movedto-restrictions-upload": "이동 대상 파일의 올리기 보호 설정", - "abusefilter-edit-builder-vars-old-text-stripped": "편집 전 마크업을 제거한 문서 내용", + "abusefilter-edit-builder-vars-old-text": "모든 마크업을 제거한 이전 문서 텍스트", "abusefilter-edit-builder-vars-old-links": "편집하기 전의 문서 링크", "abusefilter-edit-builder-vars-old-html": "HTML로 구문 분석된 과거 문서의 위키텍스트 (더 이상 쓰이지 않음)", - "abusefilter-edit-builder-vars-minor-edit": "사소한 편집으로 표시할지의 여부", + "abusefilter-edit-builder-vars-minor-edit": "사소한 편집으로 표시할지의 여부 (더 이상 쓰이지 않음)", "abusefilter-edit-builder-vars-file-sha1": "파일 내용의 SHA1 해시", "abusefilter-edit-builder-vars-file-size": "파일 크기 (바이트 단위)", "abusefilter-edit-builder-vars-file-mime": "파일의 MIME 타입", @@ -404,6 +435,8 @@ "abusefilter-edit-builder-vars-file-width": "파일의 너비 (단위: 픽셀)", "abusefilter-edit-builder-vars-file-height": "파일의 높이 (단위: 픽셀)", "abusefilter-edit-builder-vars-file-bits-per-channel": "파일의 컬러 채널 당 비트", + "abusefilter-edit-builder-vars-wiki-name": "위키의 데이터베이스 이름", + "abusefilter-edit-builder-vars-wiki-language": "위키의 언어 코드", "abusefilter-filter-log": "최근 필터의 바뀜", "abusefilter-history": "편집 필터 #$1의 편집 역사", "abusefilter-history-foruser": "$1의 편집", @@ -505,15 +538,16 @@ "abusefilter-examine-noresults": "제공한 검색 변수에서 결과가 없습니다.", "abusefilter-topnav": "'''편집 필터 둘러보기'''", "abusefilter-topnav-home": "처음", + "abusefilter-topnav-recentchanges": "최근 필터의 바뀜", "abusefilter-topnav-test": "필터 시험하기", "abusefilter-topnav-examine": "과거의 편집 검토하기", "abusefilter-topnav-log": "편집 필터 기록", "abusefilter-topnav-tools": "디버그 도구", - "abusefilter-topnav-import": "필터 가져오기", "abusefilter-log-name": "편집 필터 기록", "abusefilter-log-header": "이 기록은 필터가 바뀜 기록의 요약본을 보여줍니다.\n자세한 정보는 [[Special:AbuseFilter/history|필터의 최근 바뀜]]을 참조하십시오.", "abusefilter-logentry-create": "$1님이 $4 필터를 {{GENDER:$2|만들었습니다}} ($5)", "abusefilter-logentry-modify": "$1님이 $4 필터를 {{GENDER:$2|수정했습니다}} ($5)", + "abusefilter-log-invalid-filter": "특정 필터 ID의 일부가 유효하지 않습니다.", "abusefilter-log-noresults": "결과 없음", "abusefilter-diff-title": "버전 사이의 차이", "abusefilter-diff-item": "항목", @@ -526,11 +560,12 @@ "abusefilter-diff-next": "다음 바뀜", "abusefilter-import-intro": "이 양식을 통해 다른 위키에서 필터를 가져올 수 있습니다.\n필터가 있는 위키에서 필터 편집 화면의 \"{{int:abusefilter-edit-tools}}\"에서 \"{{int:abusefilter-edit-export}}\"를 클릭하십시오.\n나타나는 글상자의 내용을 복사한 후 붙여넣고, \"{{int:abusefilter-import-submit}}\"를 클릭하십시오.", "abusefilter-import-submit": "데이터 가져오기", + "abusefilter-import-invalid-data": "가져오려는 데이터가 유효하지 않습니다", "abusefilter-group-default": "기본값", "abusefilter-http-error": "HTTP 오류가 발생했습니다: $1", - "abusefilter-view-private-submit": "비공개 상세 정보 보기", - "abusefilter-view-private": "비공개 상세 정보 보기", - "abusefilter-view-private-reason": "비공개 상세 정보에 접근하는 이유:", + "abusefilter-view-privatedetails-submit": "비공개 상세 정보 보기", + "abusefilter-view-privatedetails-legend": "비공개 상세 정보 보기", + "abusefilter-view-privatedetails-reason": "비공개 상세 정보에 접근하는 이유:", "abusefilter-log-details-id": "기록 ID", "abusefilter-invalid-request": "잘못된 요청입니다! [[Special:AbuseLog/$1]]의 폼을 통해 비공개 상세 기록에 접근한 다음 이유를 제공해야 합니다.", "abusefilter-invalid-request-noid": "잘못된 요청입니다! 편집필터 기록 세부사항 문서를 통해 비공개 상세 기록에 접근한 다음 이유를 제공해야 합니다.", diff --git a/AbuseFilter/i18n/krc.json b/AbuseFilter/i18n/krc.json index 476842e7..4239f621 100644 --- a/AbuseFilter/i18n/krc.json +++ b/AbuseFilter/i18n/krc.json @@ -1,11 +1,10 @@ { "@metadata": { "authors": [ - "Iltever", - "Ernác" + "Ernác", + "Iltever" ] }, - "abuselog": "Джорукъдан чыгъыуланы журналы", "abusefilter-log-search-title": "Башлыкъ:", "abusefilter-log-search-wiki": "Википроект:", "abusefilter-log-search-submit": "Изле", diff --git a/AbuseFilter/i18n/ksh.json b/AbuseFilter/i18n/ksh.json index f21b4c70..10869939 100644 --- a/AbuseFilter/i18n/ksh.json +++ b/AbuseFilter/i18n/ksh.json @@ -1,13 +1,13 @@ { "@metadata": { "authors": [ - "Purodha", - "Matma Rex" + "Matma Rex", + "Purodha" ] }, "abusefilter-desc": "Dä Meßbruchsfelter deit Änderunge aan Sigge met Heurestikke pröfe.", - "abusefilter": "Ennschtällonge för der Meßbruchsfelter", - "abuselog": "Et Logbohch vum Meßbruchsfelter", + "abusefilter": "Meßbruchsfellter Verwallde", + "abuselog": "Logbooch fum Mißbruchsfelter", "abusefilter-intro": "Dach!\nHee kanns De Meßbruchsfelter verwallde, aanläje, ändere, fott maache, aan- un ußschallde.\nMeßbruchsfelter sin Projramme, woh mer automahtesch met heurestesche Meddel op de Metmaacher ier Akßuhne oppaß un automahtesch drop antwoodt.\n\nUnge es en Leß met de aanjlaate Felter, woh De eröm draan moodelle kanns.", "abusefilter-warning": "'''Opjepaß''': Mer han ene Automaht, dä hät dat, wat De jraad\naffjeschek häs, als wahscheinlesche Kappes odder Meßß ennjeschtohf.\nBeschtußte Änderonge wähde su odder su flöck retuhr jenumme.\nUßjemaate un besönders vill extra beschtußte Änderonge sorrje doför,\ndat Dinge Zohjang heh jeschpächt weed: Dinge Nahme als Metmaacher, odder\nde <i lang=\"en\">IP</i>-Addreß vun Dingem Kompjuhter, odder alle beeds sen dann betroffe.\nWann De ävver meins, dat Ding Änderong johd es — Automahte künne\nschlihßlesch och ens donävve lijje — dann donn räujesch noch ens op\n„{{int:savearticle}}“ kleke, öm dat ze beschtähtejje. Dann weet se aanjenumme.\nDäm Automat sing Rääjel koot explezeet, di do jejreffe hät, es: $1", "abusefilter-disallowed": "Unser Automaht för et Prööfe hät dat, wat De jraad affjescheck häs, als verbodde ennjeshtoof. Wann De ävver meins, dat Ding Änderong joot es —\nAutomahte künne ens donevve lijje — dann donn dat enem Wiki-Köbes\nverzälle, un schriiv och op, wat De donn wollts.\nDäm Automaht sing Rääjel koot explezeet, di do jegreffe hät, es: $1", @@ -22,7 +22,7 @@ "right-abusefilter-view": "Meßbruchsfeltere aanloore", "right-abusefilter-log": "De Meßbruchsfeltere ier Logbooch lesse", "right-abusefilter-log-detail": "En de Meßbruchsfeltere ierem Logbooch de Einzelheite beloore", - "right-abusefilter-private": "En de Meßbruchsfeltere ierem Logbooch de private Einzelheite beloore", + "right-abusefilter-privatedetails": "En de Meßbruchsfeltere ierem Logbooch de private Einzelheite beloore", "right-abusefilter-modify-restricted": "Meßbruchsfeltere met Akßjuhne änndere, di besönder Rääschde nühdesch han", "right-abusefilter-revert": "Alle Anderonge zeröck nämme, di ene beschtemmpte Meßbruchsfelter jemaat hät", "right-abusefilter-view-private": "Privaate Meßbruchsfelter aanloore", @@ -34,11 +34,10 @@ "action-abusefilter-view": "Do darfs kein Meßbruchsfeltere aanbeloore", "action-abusefilter-log": "De darfs nit en dä Meßbruchsfeltere ier Logbooch erin loore", "action-abusefilter-log-detail": "\nDe darfs nit en dä Meßbruchsfeltere ierem Logbooch en de Einzelheite erin loore", - "action-abusefilter-private": "De darfs nit en dä Meßbruchsfeltere ierem Logbooch en de private Date erin loore", + "action-abusefilter-privatedetails": "De darfs nit en dä Meßbruchsfeltere ierem Logbooch en de private Date erin loore", "action-abusefilter-modify-restricted": "De darfs nit aan Meßbruchsfeltere erömänndere, met Akßjuhne, di besönder Rääschde nühdesch han", "action-abusefilter-revert": "Do darfs nit alle Anderunge zeröck nämme, di ene beschtemmpte Meßbruchsfelter jemaat hät", "action-abusefilter-view-private": "privaate Meßbruchsfelter aanzeloore", - "abusefilter-log": "Logbooch fum Mißbruchsfelter", "abusefilter-log-summary": "Dat Logbohch zeijsch all dat, woh ene Meßbruchsfelter drop aanjeshpronge es.", "abusefilter-log-search": "Don em Meßbruchsfelter-Logbohch söke", "abusefilter-log-search-user": "Metmaacher:", @@ -58,13 +57,12 @@ "abusefilter-log-details-var": "Parrameeter\nNahme", "abusefilter-log-details-val": "Wäät", "abusefilter-log-details-vars": "Parrameetere för de Akßjuhne", - "abusefilter-log-details-private": "Private Date", + "abusefilter-log-details-privatedetails": "Private Date", "abusefilter-log-details-ip": "De IP-Address fun däm, dä et jweese wohr", "abusefilter-log-noactions": "kei", "abusefilter-log-details-diff": "De Änderonge", "abusefilter-log-linkoncontribs": "Logbooch vum Meßbruchsfelter", "abusefilter-log-linkoncontribs-text": "Logbooch fum Meßbruchsfelter för dä Metmaacher", - "abusefilter-log-hidden": "(verschtoche Enndraach)", "abusefilter-log-hidden-implicit": "(verschtoche, di Väsjohn es fottjeschmeße)", "abusefilter-log-cannot-see-details": "Do häs nit dat Rääsch, de Einzelheite vun heh däm Endraach ze beloore.", "abusefilter-log-details-hidden": "Do kanns de Einzelheite vun däm Enndraach nit beloore, weil dä för de Öffentleschkeit vershtoche es.", @@ -75,7 +73,6 @@ "abusefilter-log-hide-reason": "Jrond:", "abusefilter-log-hide-forbidden": "Do häs nit et Rääsch, Enndrääsch em Meßbruchsfelter singem Logbooch ze versteishe", "logentry-abusefilter-hit": "{{GENDER:$1|Dä|Et}|Dä Metmaacher|De|Dat} lhät met „$5“ op dä Sigg „$3“ dä Felter $4 usjelöös, un dä hät bewirk: $6 ($7)", - "abusefilter-management": "Meßbruchsfellter Verwallde", "abusefilter-list": "All Feltere", "abusefilter-list-id": "Felter-Räjel", "abusefilter-list-status": "Zostand", @@ -95,6 +92,7 @@ "abusefilter-disabled": "Ußjeschalldt", "abusefilter-hitcount": "{{PLURAL:$1|Eine Treffer|$1 Treffer|-nix-}}", "abusefilter-new": "En neuje Felter-Rääjel aanlähje", + "abusefilter-import-button": "Feltere Empotteere", "abusefilter-return": "Jangk retuhr noh dem Meßbruchsfelter singe Ennschtällonge", "abusefilter-status-global": "jemeinsam", "abusefilter-list-options": "Ennschtällonge", @@ -124,7 +122,6 @@ "abusefilter-edit-oldwarning": "<strong>Do bes hee en äldere Väsjohn vun däm Felter aam ändere.\nDe aanjejovve Schtatistike sin ävver för de neuste Väsjohn fun däm Felter.\nWann De Ding Änderonge afschpeishere deihß, dann sin all de Änderonge\nun Äjänzonge fott, di schpääder derbei jekumme sen.</strong> •\n[[Special:AbuseFilter/history/$2|Jangk zeröck op däm Felter sing Väsjohne]].", "abusefilter-edit-status-label": "Zahle un Schtatistike:", "abusefilter-edit-status": "{{PLURAL:$1|De letzte Akßjuhn woodt|Unger de letzte $1 Akßjuhne {{PLURAL:$2|woor_er ein, die|wooren_er $2, die|wood kein}}|Kein Akßjuhn woodt}} vun dämm Felter hee opjejreff{{PLURAL:$1|e|{{PLURAL:$2|e wood|e woode|e}}|e}}. Dat sinn_er $3% jewääse.", - "abusefilter-edit-status-profile": "{{PLURAL:$1|De letzte Akßjuhn woodt|Unger de letzte $1 Akßjuhne {{PLURAL:$2|woor_er ein, die|wooren_er $2, die|wood kein}}|Kein Akßjuhn woodt}} vun dämm Felter hee opjejreff{{PLURAL:$1|e|{{PLURAL:$2|e wood|e woode|e}}|e}}. Dat sinn_er $3% jewääse.\nEm Schnett deiht hä {{PLURAL:$4|ein Millisekund|$4 Millisekunde|kein Millisekund}} bruche, un {{PLURAL:$5|ein Bedengung|$5 Bedengunge|kei Bedengunge}} vun de zohjelohße hühßte Zahl.", "abusefilter-edit-new": "Neu Felter-Räjel", "abusefilter-edit-save": "Faßhallde", "abusefilter-edit-id": "Felter-Räjel-Nommer:", @@ -262,17 +259,17 @@ "abusefilter-edit-builder-vars-all-links": "All de Lengks noh ußserhallef vun däm Wikki en däm neuje Enhallt vun dä Sigg", "abusefilter-edit-builder-vars-added-links": "All di neue Lengks di en däm neue Enhallt vun dä Sigg dobei jekumme sen", "abusefilter-edit-builder-vars-removed-links": "All de Lengks noh druße, di met dä Änderong fott jenumme woode sen", - "abusefilter-edit-builder-vars-old-text": "Dä ahle Wikitex en dä Sigg, wie dä för em Ändere jewääse eß", - "abusefilter-edit-builder-vars-new-text": "Dä neue Wikitex vun dä Sigg, noh em Ändere", + "abusefilter-edit-builder-vars-old-wikitext": "Dä ahle Wikitex en dä Sigg, wie dä för em Ändere jewääse eß", + "abusefilter-edit-builder-vars-new-wikitext": "Dä neue Wikitex vun dä Sigg, noh em Ändere", "abusefilter-edit-builder-vars-new-pst": "Der Wikkitäx vun dä Sigg, ald zerääschjemaat för et Faßhallde", "abusefilter-edit-builder-vars-addedlines-pst": "De zohjeföhschte reihje, ald zerääschjemaat för et Faßhallde", - "abusefilter-edit-builder-vars-new-text-stripped": "Dä neue Tex op dä Sigg, ävver nackisch, oohne Ußzeischnunge", + "abusefilter-edit-builder-vars-new-text": "Dä neue Tex op dä Sigg, ävver nackisch, oohne Ußzeischnunge", "abusefilter-edit-builder-vars-new-html": "Dä Tex en dä neue Version vun dä Sigg, ävver ömjesaz en <i lang=\"en\">HTML</i>", "abusefilter-edit-builder-vars-restrictions-edit": "Dä Sigg iere Schotz jäje et Ändere", "abusefilter-edit-builder-vars-restrictions-move": "Dä Sigg iere Schotz jäje et Ömnenne", "abusefilter-edit-builder-vars-restrictions-create": "Schöz di Sigg jääje Neu-Aanlääje", "abusefilter-edit-builder-vars-restrictions-upload": "Der Schotz för et Huhlaade för di Dattei", - "abusefilter-edit-builder-vars-old-text-stripped": "Dä vörijje Tex op dä Sigg, ävver nackisch, oohne Ußzeischnunge", + "abusefilter-edit-builder-vars-old-text": "Dä vörijje Tex op dä Sigg, ävver nackisch, oohne Ußzeischnunge", "abusefilter-edit-builder-vars-old-links": "Lengks, di en dä ahle Sigg wore, noch för em Änndere", "abusefilter-edit-builder-vars-old-html": "Dä vörijje Wikitex op dä Sigg, ävver ömjemoodelt en <i lang=\"en\">HTML</i>", "abusefilter-edit-builder-vars-minor-edit": "Ov dat als en Mini-Änderong makkehrd es udder nit", @@ -376,7 +373,6 @@ "abusefilter-topnav-examine": "Övver de {{lcfirst:{{int:recentchanges}}}} pröfe", "abusefilter-topnav-log": "Logbohch övver der Meßbruchsfelter ier Wirke", "abusefilter-topnav-tools": "Werkzüch för Fähler ze fenge", - "abusefilter-topnav-import": "Feltere Empotteere", "abusefilter-log-name": "Et Logbohch övver de Meßbruchsfelter", "abusefilter-log-header": "En däm Logbohch heh fengks De de Änderonge aan de Feltere em Övverblek. Einzelheite sin en de\n[[Special:AbuseFilter/history|Leß met de neuste Änderunge aan Meßbruchsfeltere]].", "abusefilter-log-noresults": "Nix jefonge", diff --git a/AbuseFilter/i18n/ku-latn.json b/AbuseFilter/i18n/ku-latn.json index 54b73941..f1221870 100644 --- a/AbuseFilter/i18n/ku-latn.json +++ b/AbuseFilter/i18n/ku-latn.json @@ -1,9 +1,10 @@ { "@metadata": { "authors": [ + "Bikarhêner", "George Animal", "Ghybu", - "Bikarhêner" + "Guherto" ] }, "abusefilter-log-search-user": "Bikarhêner:", @@ -72,12 +73,12 @@ "abusefilter-action-block": "Asteng bike", "abusefilter-action-degroup": "Ji koman rake", "abusefilter-action-disallow": "Nehêle", - "abusefilter-revert-filter": "Fîltre:", + "abusefilter-revert-filter": "IDya Fîltreyê:", "abusefilter-revert-confirm": "Pesend bike", "abusefilter-revert-reasonfield": "Sedem:", "abusefilter-test-submit": "Test", "abusefilter-test-load": "Bar bike", - "abusefilter-examine-legend": "Guherandinan hilbijêre", + "abusefilter-examine-legend": "Guhertinan bibijêre", "abusefilter-examine-user": "Bikarhêner:", "abusefilter-examine-title": "Sernavê rûpelê:", "abusefilter-examine-submit": "Lêgerîn", diff --git a/AbuseFilter/i18n/kum.json b/AbuseFilter/i18n/kum.json new file mode 100644 index 00000000..22313ef2 --- /dev/null +++ b/AbuseFilter/i18n/kum.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "ArslanX" + ] + }, + "abusefilter-throttle-none": "(ёкъ)" +} diff --git a/AbuseFilter/i18n/la.json b/AbuseFilter/i18n/la.json index 428c6156..43ac61ba 100644 --- a/AbuseFilter/i18n/la.json +++ b/AbuseFilter/i18n/la.json @@ -2,15 +2,13 @@ "@metadata": { "authors": [ "Autokrator", + "Laurentianus", "Omnipaedista", - "UV", - "Laurentianus" + "UV" ] }, - "abusefilter": "Configuratio filtri iniuriarum", - "abuselog": "Acta iniuriarum", + "abuselog": "Acta filtri iniuriarum", "abusefilter-blocker": "Filtrum iniuriarum", - "abusefilter-log": "Acta filtri iniuriarum", "abusefilter-log-search-user": "Usor:", "abusefilter-log-search-title": "Titulus:", "abusefilter-log-search-submit": "Quaerere", diff --git a/AbuseFilter/i18n/lad.json b/AbuseFilter/i18n/lad.json index fcedbc6b..d7242573 100644 --- a/AbuseFilter/i18n/lad.json +++ b/AbuseFilter/i18n/lad.json @@ -5,8 +5,6 @@ ] }, "abusefilter-desc": "A los trocamientos, aplica maneras topadores (eurísticas)", - "abusefilter": "Konfiggurasyón del filtro contra-abusos", - "abuselog": "Rējistro del filtro antiabusos", "abusefilter-intro": "Buenas venidas a la interfaz de administrasyón de filtros de trocamientos.\nEl filtro de trocamientos es un mekanismo de software otomatizado que aplica maneras topaderas (eurísticas) a todas las aksyones.\nEsta interfaz mostra una lista de filtros dēfinidos i da permisyón de trocarlos.", "abusefilter-blocker": "Filtro contra-abusos", "abusefilter-blockreason": "Bloqueado de sí para sí, de la parte del filtro contra-abusos.\nDeskripsyón del filtro alcançado: $1", diff --git a/AbuseFilter/i18n/lb.json b/AbuseFilter/i18n/lb.json index c530d92d..f31167e1 100644 --- a/AbuseFilter/i18n/lb.json +++ b/AbuseFilter/i18n/lb.json @@ -2,29 +2,29 @@ "@metadata": { "authors": [ "Les Meloures", + "Matma Rex", "Robby", - "Soued031", - "Matma Rex" + "Soued031" ] }, "abusefilter-desc": "Applizéiert automatesch Heuristiken op Ännerungen", - "abusefilter": "Astellung vum Mëssbrauchsfilter", - "abuselog": "Lëscht vum Mëssbrauch", + "abusefilter": "Gestioun vum Mëssbrauchsfilter", + "abuselog": "Lëscht vun de Mëssbrauchs-Filteren", "abusefilter-intro": "Wëllkom op der Säit vum Mëssbrauchsfilter-Management.\nDe Mëssbrauchsfilter ass en automatesche Mechanismus deen et erlaabt automatesch Heuristiken op all Aktiounen unzewennen.\nDës Spezialsäit weist eng Lëscht vun definéierte Filteren an erlaabt et dës z'änneren.", "abusefilter-warning": "'''Opgepasst:''' Dës Aktioun gouf automatesch als geféierlech erkannt.\nAkltiounen déi net konstruktiv si ginn automatesch zeréckgsat,\na besonnesch schlëmmen oder widderhuelte Fäll gëtt Äre Benotzerkont oder Är IP-Adress gespaart.\nWann Dir mengt datt Är Ännerung konstruktiv ass, kënnt Dir nacheemol op \"Späichere\" klicke fir ze confirméieren.\nEng kuerz Beschreiwung vun der Mëssbrauchsregel op déi Är Aktioun reagéiert huet: $1", - "abusefilter-disallowed": "Dës Aktioun gouf automatesch als schiedlech erkannt,an dofir net zougelooss.\nWann Dir mengt datt Är Ännerung konstruktiv ass, da kontaktéiert w.e.g. en Administrateur, an informéiert deen iwwer dat wat Dir versicht hutt ze maachen.\nEng kuerz Beschreiwung vun der Mëssbrauchsregel, déi op är Aktioun reagéiert huet, ass: $1", - "abusefilter-blocked-display": "Dës Aktioun gouf automatesch als schiedlech identifizéiert,\nan Dir konnt se dowéinst net ausféieren.\nDes weideren, fir {{SITENAME}} ze protegéieren, gouf Äre Benotzerkont an all assoziéiert IP-Adressen automatesch fir all Ännerunge gespaart.\nWann dëst iertemlech geschitt ass da kontaktéiert w.e.g. en Administrateur.\nHei ass eng kuerz Beschreiwung vun der Mëssbrauchsregel op déi Är Aktioun gepasst huet: $1", - "abusefilter-degrouped": "Dës Aktioun gouf automatesch als schiedlech klasséiert.\nDowéinst gouf se net zougelooss a well Äre Benotzerkont dofir elo verdächteg ass, fir kompromettéiert ze sinn, goufen all Är Rechter zréckgezunn.\nWann Dir mengt datt dëst e Feeler ass da kontaktéiert w.e.g. e Bürokrat a gitt him eng Erklärung fir dës Aktioun, an Är Rechter ginn nees restauréiert.\nHei ass eng kuerz Beschreiwung vun der Mëssbrauchsregel op déi Är Akioun passt: $1", + "abusefilter-disallowed": "Dës Aktioun gouf automatesch als schiedlech erkannt,an dofir net zougelooss.\nWann Dir mengt datt Är Ännerung konstruktiv ass, da kontaktéiert wgl. en Administrateur, an informéiert deen iwwer dat wat Dir versicht hutt ze maachen.\nEng kuerz Beschreiwung vun der Mëssbrauchsregel, déi op är Aktioun reagéiert huet, ass: $1", + "abusefilter-blocked-display": "Dës Aktioun gouf automatesch als schiedlech identifizéiert,\nan Dir konnt se dowéinst net ausféieren.\nDes weideren, fir {{SITENAME}} ze protegéieren, gouf Äre Benotzerkont an all assoziéiert IP-Adressen automatesch fir all Ännerunge gespaart.\nWann dëst iertemlech geschitt ass da kontaktéiert wgl. en Administrateur.\nHei ass eng kuerz Beschreiwung vun der Mëssbrauchsregel op déi Är Aktioun gepasst huet: $1", + "abusefilter-degrouped": "Dës Aktioun gouf automatesch als schiedlech klasséiert.\nDowéinst gouf se net zougelooss a well Äre Benotzerkont dofir elo verdächteg ass, fir kompromettéiert ze sinn, goufen all Är Rechter zréckgezunn.\nWann Dir mengt datt dëst e Feeler ass da kontaktéiert wgl. e Bürokrat a gitt him eng Erklärung fir dës Aktioun, an Är Rechter ginn nees restauréiert.\nHei ass eng kuerz Beschreiwung vun der Mëssbrauchsregel op déi Är Akioun passt: $1", "abusefilter-autopromote-blocked": "Dës Aktioun gouf automatesch als geféierlech erkannt an net ausgefouert.\nZusäzlech goufen aus Sécherheetsgrënn e puer Rechter déi confirméiert Benotzerkonten hunn temporär vun ärem Benotzerkont zréckgeszunn.\nEng kuerz Beschreiwung vun der Mëssbrauchsregel op déi Är Aktioun reagéiert huet ass: $1", "abusefilter-blocker": "Filter vum Mëssbrauch", - "abusefilter-blockreason": "Automtesch gespaart duerch de Mëssbrauchsfilter. Beschreiwung vun der Regel déi benotzt gouf: $1", - "abusefilter-degroupreason": "Rechter goufen atomatesch duerch de Mëssbrauchsfilter ewechgeholl. Beschreiwung vun der Regel: $1", + "abusefilter-blockreason": "Automatesch gespaart duerch de Mëssbrauchsfilter. Beschreiwung vun der Reegel déi benotzt gouf: $1", + "abusefilter-degroupreason": "Rechter goufen automatesch duerch de Mëssbrauchsfilter ewechgeholl. Beschreiwung vun der Reegel: $1", "abusefilter-accountreserved": "Dësen Numm fir e Benotzerkont ass reservéiert fir vum Mëssbrauchsfilter benotzt ze ginn.", - "right-abusefilter-modify": "Mëssbrauchsfilteren änneren", + "right-abusefilter-modify": "Mëssbrauchsfilteren uleeën oder änneren", "right-abusefilter-view": "Mëssbrauchs-Filtere weisen", "right-abusefilter-log": "Lëscht vum Mëssbrauch weisen", "right-abusefilter-log-detail": "Detailléiert Versioun vum Mëssbrauchslog weisen", - "right-abusefilter-private": "Privat Donnéeën am Mëssbrauchsfilter weisen", + "right-abusefilter-privatedetails": "Privat Donnéeën am Mëssbrauchsfilter weisen", "right-abusefilter-modify-restricted": "Mëssbrauchsfiltere mat limitéierten Aktiounen änneren", "right-abusefilter-revert": "All Ännerungen vun engem bestëmmte Mëssbruachsfilter zrécksetzen", "right-abusefilter-view-private": "Mëssbrauchsfilter weisen déi als privat markéiert sinn", @@ -35,15 +35,14 @@ "action-abusefilter-view": "Mëssbrauchsfilteren ze kucken", "action-abusefilter-log": "d'Logbuch vum Mëssbrauch ze kucken", "action-abusefilter-log-detail": "dat detailéiert Logbuch vum Mëssbrauchsfilter weisen", - "action-abusefilter-private": "privat Donnéeën am Mëssbrauchsfilter weisen", + "action-abusefilter-privatedetails": "privat Donnéeën am Mëssbrauchsfilter weisen", "action-abusefilter-modify-restricted": "d'Mëssbrauchsfiltere mat limtéierten Aktiounen z'änneren", "action-abusefilter-revert": "all Ännerungen vun engem bestëmmte Mëssbrauchsfilter zréckzesetzen", "action-abusefilter-view-private": "Mëssbrauchsfilteren ze kucken, déi als privat markéiert sinn", - "abusefilter-log": "Lëscht vun de Mëssbrauchs-Filteren", "abusefilter-log-summary": "Dëst Logbuch weist eng Lëscht vun allen Aktiounen déi duerch Filteren opgefaang goufen.", "abusefilter-log-search": "D'Lëscht vum Mëssbrauch duerchsichen", "abusefilter-log-search-user": "Benotzer:", - "abusefilter-log-search-filter": "Nummer(ID) vum Filter (mat vertikale Strécher(|) trennen):", + "abusefilter-log-search-filter": "Nummer(ID) vum Filter:", "abusefilter-log-search-title": "Titel:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-impact": "Impakt:", @@ -65,14 +64,14 @@ "abusefilter-log-details-var": "Variabel", "abusefilter-log-details-val": "Wäert", "abusefilter-log-details-vars": "Parameter vun der Aktioun", - "abusefilter-log-details-private": "Privat Donnéeën", + "abusefilter-log-details-privatedetails": "Privat Log-Donnéeën", "abusefilter-log-details-ip": "IP-Adress déi bnotzt gouf", "abusefilter-log-details-checkuser": "Benotzer nokucken", "abusefilter-log-noactions": "keen", "abusefilter-log-details-diff": "Ännerungen déi an der Ännerung gemaach goufen", "abusefilter-log-linkoncontribs": "Logbuch vum Mëssbrauch", "abusefilter-log-linkoncontribs-text": "Logbuch vum Mëssbrauch fir {{GENDER:$1|dëse Benotzer}}", - "abusefilter-log-hidden": "(Androung verstoppt)", + "abusefilter-log-linkonundelete": "Logbuch vum Mëssbrauch weisen", "abusefilter-log-hidden-implicit": "(verstoppt, well d'Versioun geläscht gouf)", "abusefilter-log-cannot-see-details": "Dir hutt net déi néideg Rechter fir Detailer hei vun ze gesinn.", "abusefilter-log-details-hidden": "Dir kënnt Detailer hei der vun net gesinn well e virun der Ëffentlechkeet verstoppt sinn.", @@ -83,7 +82,6 @@ "abusefilter-log-hide-reason-other": "Aneren/zousätzleche Grond:", "abusefilter-log-hide-forbidden": "Dir hutt net déi néideg Rechter fir Rubriken aus dem Mëssbrauchsfilter ze verstoppen.", "log-action-filter-abusefilter": "Typ vun der Ännerung vum Filter:", - "abusefilter-management": "Gestioun vum Mëssbrauchsfilter", "abusefilter-list": "All Filteren", "abusefilter-list-id": "Nummer(ID) vum Filter", "abusefilter-list-status": "Statut", @@ -104,6 +102,7 @@ "abusefilter-throttled": "gebremst", "abusefilter-hitcount": "{{PLURAL:$1|1 Treffer|$1 Treffer}}", "abusefilter-new": "En neie Filter uleeën", + "abusefilter-import-button": "Fiter importéieren", "abusefilter-return": "Zréck op d'Gestioun vun de Filteren", "abusefilter-status-global": "Global", "abusefilter-list-options": "Optiounen", @@ -112,9 +111,9 @@ "abusefilter-list-options-deleted-hide": "Geläscht Filtere verstoppen", "abusefilter-list-options-deleted-show": "Geläscht Filteren matabezéien", "abusefilter-list-options-scope": "Filtere weisen:", - "abusefilter-list-options-scope-local": "Nëmme lokal Regelen", - "abusefilter-list-options-scope-global": "Nëmme global Regelen", - "abusefilter-list-options-scope-all": "Lokal a global Regelen", + "abusefilter-list-options-scope-local": "Nëmme lokal Reegelen", + "abusefilter-list-options-scope-global": "Nëmme global Reegelen", + "abusefilter-list-options-scope-all": "Lokal a global Reegelen", "abusefilter-list-options-further-options": "Aner Optiounen:", "abusefilter-list-options-hidedisabled": "Ausgeschalte Filtere verstoppen", "abusefilter-list-options-hideprivate": "Privat filtere verstoppen", @@ -128,15 +127,14 @@ "abusefilter-reautoconfirm-none": "Dësem Benotzer {{GENDER:$1|säin|hiren}}\"autoconfirmed\"-Status war net opgehuewen.", "abusefilter-reautoconfirm-notallowed": "Dir hutt net déi néideg Rechter fir de Status \"autoconfirmed\" zréckzesetzen.", "abusefilter-reautoconfirm-done": "Dem Benotzerkont säi Status 2autoconfirmed\" gouf zréckgesat", - "abusefilter-status": "{{PLURAL:$1|Déi lescht Aktioun|Vun de leschten $1 Aktiounen}} {{PLURAL:$2|huet eng|hunn der $2}} ($3 %) de Grenzwäert vu(n) $4 erreecht.\n{{PLURAL:$5|Eng Aktioun|$5 Aktiounen}} ($6 %) {{PLURAL:$5|gouf|goufe}} vun engem aktivéierte Filter erkannt.", + "abusefilter-status": "{{PLURAL:$1|Déi lescht Aktioun|Vun de leschten $1 Aktiounen}} {{PLURAL:$2|huet eng|hunn der $2}} ($3 %) de Grenzwäert vu(n) $4 erreecht.\n{{PLURAL:$5|Eng Aktioun|$5 Aktiounen}} ($6 %) {{PLURAL:$5|gouf|goufe}} mindestens vun engem aktivéierte Filter erkannt.", "abusefilter-edit": "Mëssbrauchsfilter änneren", "abusefilter-edit-subtitle": "Ännere vum Filter $1", "abusefilter-edit-subtitle-new": "Filter uleeën", - "abusefilter-edit-token-not-match": "D'Ännerung gouf net gespäichert! Späichert et w.e.g. nach eng Kéier.", + "abusefilter-edit-token-not-match": "D'Ännerung gouf net gespäichert! Späichert et wgl. nach eng Kéier.", "abusefilter-edit-oldwarning": "<strong>Dir sidd am Gaang eng al Versioun vum Filter z'änneren.\nD'Statistike sinn déi vun der leschter Versioun vum Filter.\nWann Dir Är Ännerunge späichert dann iwwerschreiwt Dir all Ännerungen zënter der Versioun déi Dir elo ännert. </strong> •\n[[Special:AbuseFilter/history/$2|Zréck op d'Versiounsgeschicht vun dësem Filter]].", "abusefilter-edit-status-label": "Statistiken:", - "abusefilter-edit-status": "Dëse Filter huet bei {{PLURAL:$1|der leschter Aktioun|de leschte(n) $1 Aktiounen}}, $2 mol ($3%) ugeschloen.", - "abusefilter-edit-status-profile": "Dëse Filter huet bei {{PLURAL:$1|der leschter Aktioun|de leschte(n) $1 Aktiounen}}, $2 mol ($3%) ugeschloen.\nAm Duerchschnëtt brauch en dofir $4ms a benotzt dobäi $5 {{PLURAL:$5|Konditioun|Konditioune}} vun der Konditiouns-Limit.", + "abusefilter-edit-status": "Dëse Filter huet bei {{PLURAL:$1|der leschter Aktioun|de leschte(n) $1 Aktiounen}}, $2 mol ($3%) ugeschloen.\nAm Duerchschnëtt leeft en $4 Milli-Sekonnen an e benotzt {{PLURAL:$5|eng Konditioun|$5 Konditioune}} vun der Konditiouns-Limite.", "abusefilter-edit-new": "Neie Filter", "abusefilter-edit-save": "Filter späicheren", "abusefilter-edit-id": "Nummer (ID) vum Filter:", @@ -161,19 +159,22 @@ "abusefilter-edit-action-blockautopromote": "Dem Benotzer seng \"autoconfirmed\"-Rechter ofhuelen", "abusefilter-edit-action-degroup": "De Benotzer aus alle priviligéierte Gruppen eraushuelen", "abusefilter-edit-action-block": "De Benotzer an/oder d'IP-Adress fir Ännerunge spären", - "abusefilter-edit-action-throttle": "Aktiounen nëmmen ausléise wann de Benotzer eng bestëmmte Limit depasséiert", + "abusefilter-edit-action-throttle": "Aktiounen nëmmen ausléise wann de Benotzer eng bestëmmte Limitt depasséiert", "abusefilter-edit-action-rangeblock": "/16-Beräich spären, aus dem dëse Benotzer kënnt.", "abusefilter-edit-action-tag": "D'Ännerung fir e spéidert Nokucke markéieren", "abusefilter-edit-throttle-count": "Zuel vun den erlaabten Aktiounen:", "abusefilter-edit-throttle-period": "Zäitraum (a Sekonnen):", - "abusefilter-edit-throttle-ip": "IP-Adress", - "abusefilter-edit-throttle-user": "Benotzerkont", - "abusefilter-edit-throttle-editcount": "Zuel vun den Ännerungen", - "abusefilter-edit-throttle-site": "De ganzen Internetsite", - "abusefilter-edit-throttle-page": "Säit", + "abusefilter-edit-throttle-groups-help": "Kuckt $1.", + "abusefilter-edit-throttle-groups-help-text": "d'Dokumentatioun op mediawiki.org", + "abusefilter-throttle-ip": "IP-Adress", + "abusefilter-throttle-user": "Benotzerkont", + "abusefilter-throttle-editcount": "Zuel vun den Ännerungen", + "abusefilter-throttle-site": "ganzen Internetsite", + "abusefilter-throttle-page": "Säit", + "abusefilter-throttle-none": "(keen)", "abusefilter-edit-warn-message": "Systemmessage den als Warnung benotzt gëtt:", "abusefilter-edit-warn-other": "Anere Systemmessage", - "abusefilter-edit-warn-other-label": "Säitennumm vun engem anere Systemmessage:\n:''(ouni MediaWiki-Prefix)''", + "abusefilter-edit-warn-other-label": "Säitennumm vun engem anere Message:\n:''(ouni \"MediaWiki:\" Prefix)''", "abusefilter-edit-warn-actions": "Aktiounen:", "abusefilter-edit-warn-preview": "De gewielte Message kucken ouni ofzespäicheren", "abusefilter-edit-warn-edit": "De gewielte Systemmessage uleeën/änneren", @@ -189,13 +190,13 @@ "abusefilter-edit-done-subtitle": "Filter geännert", "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Är Ännerungen]] vum [[Special:AbuseFilter/$1|Filter $3]] goufe gespäichert.", "abusefilter-edit-badsyntax": "Et ass e Syntaxfeeler an dem Filter deen Dir uginn hutt.\nD'Resultat vum Parser war: <pre>$1</pre>", - "abusefilter-edit-restricted": "Dir kënnt dëse Filter net ännere well eng oder méi restriktiv Aktiounen drasti fir déi ee méi Rechter brauch.\nFrot w.e.g. e Benotzer mat de Rechter fir restriktiv Aktioune fir d'Ännerung fir Iech ze maachen.", + "abusefilter-edit-restricted": "Dir kënnt dëse Filter net ännere well eng oder méi restriktiv Aktiounen drasti fir déi ee méi Rechter brauch.\nFrot wgl. e Benotzer mat de Rechter fir restriktiv Aktioune fir d'Ännerung fir Iech ze maachen.", "abusefilter-edit-viewhistory": "D'Versioune vun dësem Filter gesinn", "abusefilter-edit-history": "Versiounen:", "abusefilter-edit-check": "Syntax iwwerpréifen", "abusefilter-edit-badfilter": "De Filter den Dir uginn hutt gëtt et net", "abusefilter-edit-revert": "Aktiounen déi vun dësem Filter gemaach goufen zrécksetzen", - "abusefilter-edit-tools": "Geschir:", + "abusefilter-edit-tools": "Geschier:", "abusefilter-edit-test-link": "Dëse Filter mat de leschten Ännerungen ausprobéieren", "abusefilter-edit-export": "Dëse Filter an eng aner Wiki exportéieren", "abusefilter-edit-syntaxok": "Keng Syntaxfeeler fonnt.", @@ -203,6 +204,7 @@ "abusefilter-edit-bad-tags": "Een oder méi vun den Tags déi Dir uginn hutt ass net valabel.\nTags solle kuerz sinn, an et solle keng Spezialzeechen dra sinn, a si sollen net vun anerer Software reservéiert sinn. Probéiert een aneren Numm erauszesichen", "abusefilter-edit-notallowed": "Et ass Iech net erlaabt fir Mëssbrauchsfilteren unzeleeën oder z'änneren", "abusefilter-edit-notallowed-global": "Dir däerft keng global Mëssbrauchsfilteren uleeën oder änneren", + "abusefilter-edit-invalid-warn-message": "De Warnmessage kann net eidel gelooss ginn.", "abusefilter-edit-builder-select": "Wielt eng Optioun eraus fir se do anzesetzen wou de Cursor steet", "abusefilter-edit-builder-group-op-arithmetic": "Arithmetesch Operateuren", "abusefilter-edit-builder-op-arithmetic-addition": "Additioun (+)", @@ -283,22 +285,24 @@ "abusefilter-edit-builder-vars-all-links": "All extern Linken am neien Text", "abusefilter-edit-builder-vars-added-links": "All extern Linken déi bei der Ännerung dobäigesat goufen", "abusefilter-edit-builder-vars-removed-links": "All extern Linken déi bei der Ännerung ewechgeholl goufen", - "abusefilter-edit-builder-vars-old-text": "Alen Text op der Säit, virun der Ännerung", - "abusefilter-edit-builder-vars-new-text": "Neien Text op der Säit, no der Ännerung", + "abusefilter-edit-builder-vars-old-wikitext": "Ale Wiki-Text op der Säit, virun der Ännerung", + "abusefilter-edit-builder-vars-new-wikitext": "Neien Text op der Säit, no der Ännerung", "abusefilter-edit-builder-vars-new-pst": "Wikitext vun der neier Säit, virum Späicheren ëmgewandelt", - "abusefilter-edit-builder-vars-new-text-stripped": "Neien Text vun der Säit ouni iergendwellech Formatéierung", + "abusefilter-edit-builder-vars-new-text": "Neien Text vun der Säit ouni iergendwellech Formatéierung", "abusefilter-edit-builder-vars-new-html": "Geparseden HTML Quelltext vun der neier Versioun", "abusefilter-edit-builder-vars-restrictions-edit": "Niveau vun der Spär vun der Säit", "abusefilter-edit-builder-vars-restrictions-move": "Niveau vun der Réckelspär vun der Säit", "abusefilter-edit-builder-vars-restrictions-create": "D'Spär vun dëser Säit uleeën", - "abusefilter-edit-builder-vars-old-text-stripped": "Alen Text vun der Säit, ouni iergendwellech Formatéierung", + "abusefilter-edit-builder-vars-old-text": "Alen Text vun der Säit, ouni iergendwellech Formatéierung (gëtt net méi benotzt)", "abusefilter-edit-builder-vars-old-links": "Linken op der Säit, virun der Ännerung", "abusefilter-edit-builder-vars-old-html": "Wikitext vun der aler Säit, an HTML-Format", - "abusefilter-edit-builder-vars-minor-edit": "Ob d'Ännerung als kleng markéiert gëtt oder net", + "abusefilter-edit-builder-vars-minor-edit": "Ob d'Ännerung als kleng markéiert gëtt oder net (gëtt net méi benotzt)", "abusefilter-edit-builder-vars-file-sha1": "SHA1-Hash vum Inhalt vum Fichier", "abusefilter-edit-builder-vars-file-size": "Gréisst vum Fichier a Bytes", "abusefilter-edit-builder-vars-file-width": "Breet vum Fichier a Pixel", "abusefilter-edit-builder-vars-file-height": "Héicht vum Fichier a Pixel", + "abusefilter-edit-builder-vars-wiki-name": "Numm vun der Datebank vun der Wiki", + "abusefilter-edit-builder-vars-wiki-language": "Sproochcode vun der Wiki", "abusefilter-filter-log": "Rezent Ännerunge vu Filteren", "abusefilter-history": "Historique vun den Ännerunge vum Mëssbrauchsfilter #$1", "abusefilter-history-foruser": "Ännerunge vum $1", @@ -309,7 +313,7 @@ "abusefilter-history-user": "Benotzer", "abusefilter-history-public": "Ëffentlech Beschreiwung vum Filter", "abusefilter-history-flags": "Fändelen", - "abusefilter-history-filter": "Regel vum Filter", + "abusefilter-history-filter": "Reegel vum Filter", "abusefilter-history-comments": "Bemierkungen", "abusefilter-history-actions": "Aktiounen", "abusefilter-history-backedit": "Zréck op d'Ännerungssäit vun de Filteren", @@ -341,14 +345,14 @@ "abusefilter-action-rangeblock": "Spär vum Beräich", "abusefilter-action-disallow": "Net erlaben", "abusefilter-revert-title": "All Ännerungen duerch de Filter $1 zrécksetzen", - "abusefilter-revert-intro": "Dëse Formulaire erlaabt et fir all Ännerunge vum Mëssbrauchsfilterm duerch de Filter $1 zréckzesetzen.\nBenotzt dës Funktioun w.e.g. nëmme wann Dir hir Konsequenzen ofschätze kënnt.", + "abusefilter-revert-intro": "Dëse Formulaire erlaabt et fir all Ännerunge vum Mëssbrauchsfilterm duerch de Filter $1 zréckzesetzen.\nBenotzt dës Funktioun wgl. nëmme wann Dir hir Konsequenzen ofschätze kënnt.", "abusefilter-revert-preview-item": "$1: $2 huet $3 op $4 {{GENDER:$7|gemaach}}.\nAktiounen déi zréckgesat ginn: $5 ($6)", "abusefilter-revert-search-legend": "Mëssbrauchsfilteren erauswielen déi zréckgesat solle ginn", "abusefilter-revert-periodstart": "Ufank vun der Period:", "abusefilter-revert-periodend": "Enn vun der Period:", "abusefilter-revert-search": "Aktiounen auswielen", "abusefilter-revert-filter": "Nummer (ID) vum Filter:", - "abusefilter-revert-preview-intro": "Hei ënnerdënner stinn déi Aktioune vum Mëssbrauchsfilter déi duerch dës Aktioun zréckgesat wäerte ginn.\nKuckt se w.e.g. genee no a klickt \"{{int:abusefilter-revert-confirm}}\" fir Är Wiel ze confirméieren.", + "abusefilter-revert-preview-intro": "Hei ënnerdënner stinn déi Aktioune vum Mëssbrauchsfilter déi duerch dës Aktioun zréckgesat wäerte ginn.\nKuckt se wgl. genee no a klickt \"{{int:abusefilter-revert-confirm}}\" fir Är Wiel ze confirméieren.", "abusefilter-revert-confirm-legend": "D'Zrécksetze confirméieren", "abusefilter-revert-confirm": "Confirméieren", "abusefilter-revert-success": "Dir hutt all Aktioune vum Mëssbrauchsfilter, op Grond vum [[Special:AbuseFilter/$1|Filter $2]] zréckgesat.", @@ -391,11 +395,11 @@ "abusefilter-examine-noresults": "Et gouf näischt fonnt mat de Sich-Parameter déi Dir uginn hutt", "abusefilter-topnav": "'''Navigatioun vum Mëssbrauchs-Filter'''", "abusefilter-topnav-home": "Haaptsäit", - "abusefilter-topnav-test": "Regelen testen", + "abusefilter-topnav-recentchanges": "Rezent Ännerunge vu Filteren", + "abusefilter-topnav-test": "Batch testen", "abusefilter-topnav-examine": "Déi lescht Ännerungen nokucken", "abusefilter-topnav-log": "Logbuch vum Mëssbrauch", - "abusefilter-topnav-tools": "Debugg-Geschir", - "abusefilter-topnav-import": "Fiter importéieren", + "abusefilter-topnav-tools": "Debugg-Geschier", "abusefilter-log-name": "Logbuch vum Mëssbrauchsfilter", "abusefilter-log-header": "Dëst Logbuch weist e Resumé vun Ännerungen déi un de Filtere gemaach goufen.\nFir weider Detailer, kuckt [[Special:AbuseFilter/history|d'Lëscht]] vun de rezenten Filterännerungen.", "abusefilter-logentry-modify": "$1 huet $4 ($5) {{GENDER:$2|geännert}} $4 ($5)", @@ -411,9 +415,10 @@ "abusefilter-diff-next": "Méi nei Ännerung", "abusefilter-import-intro": "Dir kënnt dësen Interface benotze fir Filtere vun anere Wikien z'importéieren.\nKlickt op der originaler Wiki op \"{{int:abusefilter-edit-export}}\" ënner \"{{int:abusefilter-edit-tools}}\" op dem Interface vun den Ännerungen.\nKopéiert vun der Textkëscht déi opgeet an dës Textkëscht a klickt op \"{{int:abusefilter-import-submit}}\",", "abusefilter-import-submit": "Donnéeën importéieren", + "abusefilter-import-invalid-data": "D'Donnéeën déi Dir probéiert huet z'importéieren ass net valabel", "abusefilter-group-default": "Standard", "abusefilter-http-error": "Et ass en HTTP-Feeler geschitt: $1.", - "abusefilter-view-private-submit": "Privat Detailer weisen", - "abusefilter-view-private": "Privat Detailer weisen", + "abusefilter-view-privatedetails-submit": "Privat Detailer weisen", + "abusefilter-view-privatedetails-legend": "Privat Detailer weisen", "abusefilter-log-ip-not-available": "Net disponibel" } diff --git a/AbuseFilter/i18n/lfn.json b/AbuseFilter/i18n/lfn.json index 8c2e17e2..2aa6684b 100644 --- a/AbuseFilter/i18n/lfn.json +++ b/AbuseFilter/i18n/lfn.json @@ -1,11 +1,10 @@ { "@metadata": { "authors": [ - "Malafaya", - "Mafcadio" + "Mafcadio", + "Malafaya" ] }, - "abuselog": "Arcivo de malusa", "abusefilter-log-search-user": "Usor:", "abusefilter-log-search-title": "Titulo:", "abusefilter-log-search-submit": "Xerca", diff --git a/AbuseFilter/i18n/li.json b/AbuseFilter/i18n/li.json index 0ae51b42..dae6e82e 100644 --- a/AbuseFilter/i18n/li.json +++ b/AbuseFilter/i18n/li.json @@ -1,13 +1,14 @@ { "@metadata": { "authors": [ + "Fitoschido", + "Matma Rex", "Ooswesthoesbes", - "Pahles", - "Matma Rex" + "Pahles" ] }, "abusefilter-desc": "Veurtj automatisch heuristische analyse oet op bewerkinge", - "abusefilter": "Misbroekfilterinsjtellinge", + "abusefilter": "Misbroekfilterbehieër", "abuselog": "Misbroeklogbook", "abusefilter-intro": "Dit is 't beheersjerm van de misbroekfilter.\nDe misbroekfilter is e systeem det automatische heuristiek toepas op alle hanjelinge.\nVia dit sjerm waere alle ingestelde filters waergegaeve en kinne die aangepas waere.", "abusefilter-warning": "'''Waarsjuwing''': Dees hanjeling is automatisch geïdentificeerd as sjadelik.\nOnconstructieve bewerkinge waere snel trökgedreid, en herhaald onconstructief bewerke eindig in n blokkade van diene gebroeker of IP.\nAs se dinks det dees bewerking waal constructief is, klik dan opnuuj op \"Pagina opslaon\" om de bewerking te bevestige.\n'n Korte besjrieving van de regel op basis waarvan de bewerking is taegegehouwe vólg noe: $1", @@ -23,7 +24,7 @@ "right-abusefilter-view": "Bekiek misbroekfilters", "right-abusefilter-log": "Bekiek 't misbroeklogbook", "right-abusefilter-log-detail": "Bekiek details van misbroeklogbookregels", - "right-abusefilter-private": "Bekiek bepèrk zichbare gegaeves in 't misbroeklogbook", + "right-abusefilter-privatedetails": "Bekiek bepèrk zichbare gegaeves in 't misbroeklogbook", "right-abusefilter-modify-restricted": "Wiezig misbroekfilters mit bepèrkte hanjelinge", "right-abusefilter-revert": "Drei alle wieziginge door 'ne misbroekfilter truuk", "right-abusefilter-view-private": "Bekiek es beperk zichbaar gemarkeerde filters", @@ -33,11 +34,10 @@ "action-abusefilter-view": "bekiek misbroekfilters", "action-abusefilter-log": "bekiek misbroeklogbook", "action-abusefilter-log-detail": "bekiek gedetailleerde misbroeklogbookvermeldinge", - "action-abusefilter-private": "bekiek privégegaeves in 't misbroeklogbook", + "action-abusefilter-privatedetails": "bekiek privégegaeves in 't misbroeklogbook", "action-abusefilter-modify-restricted": "wiezig misbroekfilters mit bepèrkte hanjelinge", "action-abusefilter-revert": "drei alle wieziginge door 'ne bepaolde misbroekfilter truuk", "action-abusefilter-view-private": "es beperk zichbaar gemarkeerde filters bekiekbaar", - "abusefilter-log": "Misbroeklogbook", "abusefilter-log-summary": "Dit logbook guf 'ne lies van hanjelinge die opgevange zeen door misbroekfilters.", "abusefilter-log-search": "Doorzeuk 't misbroeklogbook", "abusefilter-log-search-user": "Gebroeker:", @@ -66,17 +66,16 @@ "abusefilter-log-details-var": "Variabel", "abusefilter-log-details-val": "Waerj", "abusefilter-log-details-vars": "Maotregelparremaeter", - "abusefilter-log-details-private": "Private logdetails", + "abusefilter-log-details-privatedetails": "Private logdetails", "abusefilter-log-details-ip": "IP-adres", "abusefilter-log-details-checkuser": "Konterleer gebroeker", "abusefilter-log-noactions": "gein", "abusefilter-log-details-diff": "Bewèrkingsangeringer", "abusefilter-log-linkoncontribs": "filterlogbook", "abusefilter-log-linkoncontribs-text": "Filterlogbook veur deze {{GENDER:$1|gebroeker}}", - "abusefilter-log-hidden": "(meljing verbórge)", "abusefilter-log-hidden-implicit": "(verstaoke went de versie is eweggesjaf)", "abusefilter-log-cannot-see-details": "Doe höbs neet de rechte veur de details van dezen ingank te betrachte.", - "abusefilter-log-cannot-see-private-details": "Doe höbs gein rechte veur de private details van dezen ingank te betrachte.", + "abusefilter-log-cannot-see-privatedetails": "Doe höbs gein rechte veur de private details van dezen ingank te betrachte.", "abusefilter-log-nonexistent": "'nen Ingank mit 't opgegaove nómmer besteit neet.", "abusefilter-log-details-hidden": "Doe kins de details van dees meljing neet bekieke ómdet dees verbórge is.", "abusefilter-log-hide-legend": "Verberg logbookregel", @@ -84,7 +83,6 @@ "abusefilter-log-hide-hidden": "Verberg dees meljing", "abusefilter-log-hide-reason": "Reeje:", "abusefilter-log-hide-forbidden": "Doe höbs neet de juuste rechte óm meljinge in 't filterlogbook te verberge.", - "abusefilter-management": "Misbroekfilterbehieër", "abusefilter-list": "Al filter", "abusefilter-list-id": "Filter ID", "abusefilter-list-status": "Staat", @@ -103,6 +101,7 @@ "abusefilter-disabled": "Oetgezatj", "abusefilter-hitcount": "$1 {{PLURAL:$1|slaag|slaag}}", "abusefilter-new": "Maak 'ne nuuje filter aan", + "abusefilter-import-button": "Importeer filter", "abusefilter-return": "Trök nao filterbehier", "abusefilter-status-global": "Globaal", "abusefilter-list-options": "Opties", @@ -126,7 +125,6 @@ "abusefilter-edit-oldwarning": "<strong>Doe bis 'n aaj versie van deze filter aan 't bewirke.\nDe weergegeve sjtattestieke gelje veur de lèste versie van dit filter.\nEs de dien wieziginge opsjleis, euversjriefs te alle wieziginge die nao deze versie zeen gemaak.</strong> •\n[[Special:AbuseFilter/history/$2|Trög nao de gesjiedenis van dit filter]]", "abusefilter-edit-status-label": "Euverzich:", "abusefilter-edit-status": "{{PLURAL:$1|De lèste hanjeling voldeech|Van de lèste $1 hanjelinge voldege d'r $2}} aon dit filter ($3%).", - "abusefilter-edit-status-profile": "{{PLURAL:$1|De lèste hanjeling voldeech|Van de lèste $1 hanjelinge voldege d'r $2}} aon dit filter ($3%).\nDe gemiddelde louptied van de filtercontrole is $4ms, en deze gebroek $5 {{PLURAL:$5|conditie|condities}} van de conditielimiet.", "abusefilter-edit-new": "Nuuj filter", "abusefilter-edit-save": "Slaon filter op", "abusefilter-edit-id": "Filternummer:", @@ -255,13 +253,13 @@ "abusefilter-edit-builder-vars-all-links": "Alle extern verwiezinge in de nuuj teks", "abusefilter-edit-builder-vars-added-links": "Alle extern verwiezinge die in dees bewirking zeen toegevoog", "abusefilter-edit-builder-vars-removed-links": "Alle bie dees bewirking toegevoogde extern verwiezinge zeen gewösj", - "abusefilter-edit-builder-vars-old-text": "Wikiteks van de aaj pagina veur de bewirking", - "abusefilter-edit-builder-vars-new-text": "Wikiteks van de nuuj pagina nao de bewirking", - "abusefilter-edit-builder-vars-new-text-stripped": "Nuuj paginateks, óntdaon van ópmaakcode", + "abusefilter-edit-builder-vars-old-wikitext": "Wikiteks van de aaj pagina veur de bewirking", + "abusefilter-edit-builder-vars-new-wikitext": "Wikiteks van de nuuj pagina nao de bewirking", + "abusefilter-edit-builder-vars-new-text": "Nuuj paginateks, óntdaon van ópmaakcode", "abusefilter-edit-builder-vars-new-html": "Verwirkde HTML-bróncode van de nuuj versie", "abusefilter-edit-builder-vars-restrictions-edit": "Beveiligingsniveau veur bewirke van de pagina", "abusefilter-edit-builder-vars-restrictions-move": "Beveiligingsniveau veur verplaatse van de pagina", - "abusefilter-edit-builder-vars-old-text-stripped": "Teks aaj pagina, óntdaon van allen ópmaak", + "abusefilter-edit-builder-vars-old-text": "Teks aaj pagina, óntdaon van allen ópmaak", "abusefilter-edit-builder-vars-old-links": "Verwiezinge in de pagina veur de bewirking", "abusefilter-edit-builder-vars-old-html": "Wikiteks aaj pagina in HTML", "abusefilter-edit-builder-vars-minor-edit": "Of de bewirking waal of neet es klein gemarkeerd is.", @@ -298,7 +296,7 @@ "abusefilter-exception-dividebyzero": "Ongeljige poging toet deile van $2 door nul bie karakter $1.", "abusefilter-exception-unrecognisedvar": "Onherkènbare variabele $2 bie karakter $1", "abusefilter-exception-notenoughargs": "d'r Zeen neet zat parameters ingegaeve veur de functie $2 die is aangeropen in karakter $1.\nd'r {{PLURAL:$3|Woort eine paramaeter|Woorte $3 paramaeters}} verwach en d'r {{PLURAL:$4|is t'r eine|zeen d'r $4}} aangetróffe.", - "abusefilter-exception-regexfailure": "d'r Is 'n fout aangetróffen in de regulier expressie \"$3\" bie karakter $1: \"$2\"", + "abusefilter-exception-regexfailure": "d'r Is 'n fout aangetróffen in de regulier expressie \"$2\" bie karakter $1.", "abusefilter-exception-overridebuiltin": "De ingeboewde variable \"$2\" is vervange bie karakter $1.\nDit is neet toegestange.", "abusefilter-exception-outofbounds": "d'r Is getrach e lieselement ($2 bie liesgruuedje $3) op te haole det neet besteit bie karakter $1.", "abusefilter-exception-notarray": "d'r Is getrach e verzamelingselement op te vraogen oet get det gein verzameling is bie karakter $1.", @@ -358,7 +356,6 @@ "abusefilter-topnav-examine": "Óngerzeuk bewirkinge", "abusefilter-topnav-log": "Filterlogbook", "abusefilter-topnav-tools": "Hólpmiddele veur debugge", - "abusefilter-topnav-import": "Importeer filter", "abusefilter-log-name": "Filterlogbook", "abusefilter-log-header": "Dit logbook geuf 'n euverzich van filterverangeringe.\nZuuch de [[Special:AbuseFilter/history|lies mit recente filterverangeringe]] veur volledige details.", "abusefilter-log-noresults": "Gein resultate", diff --git a/AbuseFilter/i18n/lij.json b/AbuseFilter/i18n/lij.json index 68505d33..627aff97 100644 --- a/AbuseFilter/i18n/lij.json +++ b/AbuseFilter/i18n/lij.json @@ -1,20 +1,25 @@ { "@metadata": { "authors": [ - "Giromin Cangiaxo" + "Giromin Cangiaxo", + "S4b1nuz E.656", + "Samuele2002" ] }, "abusefilter-desc": "O l'apprica un'euiristega aotomattica a-e modiffiche.", - "abusefilter": "Configuaçion do filtro anti abuxi", + "abusefilter": "Manezzo do filtro anti abuxi", "abuselog": "Registro do filtro anti abuxi", "abusefilter-intro": "Benvegnui inte l'interfaccia de gestion do filtro anti abuxi.\nO filtro anti abuxi o l'è un scistema aotomatizou pe l'appricaçion di œüristeghe aotomattiche a tutte i açioin.\nL'interfaccia a mostra 'na lista di filtri definii e a ne consente a modiffica.", "abusefilter-warning": "'''Attençion''': Quest'açion a l'è stæta aotomaticamente identificâ comme peigoza.\nE modifiche non costruttive saian fito annulæ; l'inseimento paleise o ripetuo di contribui non costruttivi daiâ loeugo a-o blocco de l'utença ò do to adresso IP.\nSe ti pensci che l'açion in question a segge costruttiva, ti devi inviâla torna pe confermâla.\nQuesta a l'è una breve descriçion da reggola anti abuso che t'hæ infranto: $1", "abusefilter-disallowed": "Quest'açion a l'è stæta aotomaticamente identificâ comme dannoza e quindi impedia.\nSe ti creddi che a to açion a l'ea construtiva, informa un aministratô de quello che ti çercavi de fâ.\nQuesta a l'è una breve descriçion da reggola de segueça ch'a l'è stæta violâ: $1", "abusefilter-blocked-display": "Quest'açion a l'è stæta aotomaticamente identificâ comme dannoza e t'è stæto impedio de compîla.\nDe ciu, pe proteze {{SITENAME}}, a to utença e tutti i adressi IP associæ son stæti bloccæ da-o fâ modiffiche.\nSe l'è stæto un errô, pe piaxei contatta un aministratô.\nQuesta a l'è una breve descriçion da reggola de segueça ch'a l'è stæta violâ: $1", - "abusefilter-management": "Manezzo do filtro anti abuxi", + "abusefilter-blocker": "Fìltro anti abûxi", + "abusefilter-log-linkoncontribs": "fìltro anti abûxi", + "abusefilter-log-hide-reason": "Motîvo:", "abusefilter-list-public": "Descriçion pubbrica", "abusefilter-list-options-deleted-hide": "Ascondi i filtri scassæ", "abusefilter-list-options-deleted-show": "Includdi i filtri scassæ", "abusefilter-list-options-hidedisabled": "Ascondi i filtri disattivæ", - "abusefilter-status": "Fra i urtime $1 {{PLURAL:$1|açion|açioin}}, $2 ($3 %) {{PLURAL:$2|o l'ha|han}} razonto o limmite de $4 condiçioin e $5 ($6 %) {{PLURAL:$5|o l'ha|han}} attivou un di filtri attoalmente attivi." + "abusefilter-status": "Fra i urtime $1 {{PLURAL:$1|açion|açioin}}, $2 ($3 %) {{PLURAL:$2|o l'ha|han}} razonto o limmite de $4 condiçioin e $5 ($6 %) {{PLURAL:$5|o l'ha|han}} attivou un di filtri attoalmente attivi.", + "abusefilter-log-name": "Fìltro anti abûxi" } diff --git a/AbuseFilter/i18n/lld.json b/AbuseFilter/i18n/lld.json new file mode 100644 index 00000000..84a9da74 --- /dev/null +++ b/AbuseFilter/i18n/lld.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Starladin" + ] + }, + "abusefilter": "Gestiun dl filter cuntra la maladoranza", + "abuselog": "Register di filtri cuntra la maladoranza" +} diff --git a/AbuseFilter/i18n/lmo.json b/AbuseFilter/i18n/lmo.json index f1750945..77c4b006 100644 --- a/AbuseFilter/i18n/lmo.json +++ b/AbuseFilter/i18n/lmo.json @@ -6,8 +6,6 @@ ] }, "abusefilter-desc": "L'aplica de l'heuristega automatega a li edizion", - "abusefilter": "Configuration del filter d'abus", - "abuselog": "Diari d'abus", "abusefilter-warning": "Chetsa azion a l'è staida automatigament identifiada en tant che dagnousa.\nLi edizion miga construtivi i sarà revertid à bott, e grand o repetud edizion mia constructivi i resultarà end al cost cunt o ordenadour blocad. Se cas che creghée che chesta edizion la sighi construtiva, a podée clicar Sotmet de nœuv per confirmar-la. Una curta descripzion de la regula d'abus che la vosta edizion l'ha rencontrad a l'è: $1", "abusefilter-diff-info": "Infurmazión de bas", "abusefilter-diff-pattern": "Cundizión di filter" diff --git a/AbuseFilter/i18n/lrc.json b/AbuseFilter/i18n/lrc.json index 14970f3a..6767cc64 100644 --- a/AbuseFilter/i18n/lrc.json +++ b/AbuseFilter/i18n/lrc.json @@ -1,8 +1,8 @@ { "@metadata": { "authors": [ - "Mogoeilor", - "Lakzon" + "Lakzon", + "Mogoeilor" ] }, "abusefilter-list-public": "توضیحات عمومی", diff --git a/AbuseFilter/i18n/lt.json b/AbuseFilter/i18n/lt.json index d6b34fcd..bac75d2b 100644 --- a/AbuseFilter/i18n/lt.json +++ b/AbuseFilter/i18n/lt.json @@ -3,21 +3,22 @@ "authors": [ "Audriusa", "Eitvys200", + "Fitoschido", "Homo", + "Hugo.arg", "Ignas693", "Mantak111", + "Manvydasz", "Matasg", + "Matma Rex", "Perkunas", "Tomasdd", "Vogone", - "Vpovilaitis", - "Matma Rex", - "Manvydasz", - "Hugo.arg" + "Vpovilaitis" ] }, "abusefilter-desc": "Pakeitimų tikrinimui naudojamas automatinis euristinis tikrinimas", - "abusefilter": "Piktnaudžiavimų filtravimo priemonė", + "abusefilter": "Piktnaudžiavimo filtrų valdymas", "abuselog": "Piktnaudžiavimų sąrašas", "abusefilter-intro": "Sveiki atvykę į piktnaudžiavimų filtrų valdymo puslapį.\nPiktnaudžiavimo filtras yra automatizuota programinė priemonė, kuri atlieka automatinę euristinę visų veiksmų kontrolę.\nŠiame puslapyje yra pateikiamas sąrašas visų apibrėžtų filtrų, ir jame yra leidžiama juos redaguoti.", "abusefilter-warning": "'''Dėmesio:''' Šis veiksmas buvo automatiškai atpažintas kaip kenksmingas.\nNevertingi pakeitimai bus greitai atmesti, dideli ar pasikartojantys nevertingi pakeitimai gali nulemti Jūsų paskyros ar IP adreso blokavimą.\nJei manote, kad šis pakeitimas yra vertingas, tai patvirtindami, paspauskite išsaugojimo mygtuką.\nČia trumpai aprašytas su Jūsų pakeitimu susijęs piktnaudžiavimo filtras: $1", @@ -33,7 +34,7 @@ "right-abusefilter-view": "Peržiūrėti piktnaudžiavimo filtrus", "right-abusefilter-log": "Peržiūrėti piktnaudžiavimų protokolą", "right-abusefilter-log-detail": "Peržiūrėti detalų piktnaudžiavimų protokolą", - "right-abusefilter-private": "Peržiūrėti privačius duomenis piktnaudžiavimų protokole", + "right-abusefilter-privatedetails": "Peržiūrėti privačius duomenis piktnaudžiavimų protokole", "right-abusefilter-modify-restricted": "Keisti piktnaudžiavimo filtrus su uždraustais veiksmais", "right-abusefilter-revert": "Atmesti visus pakeitimus pagal konkretų piktnaudžiavimų filtrą", "right-abusefilter-view-private": "Žiūrėti piktnaudžiavimo filtrus, pažymėtus kaip privatūs.", @@ -45,15 +46,14 @@ "action-abusefilter-view": "peržiūrėti piktnaudžiavimo filtrų", "action-abusefilter-log": "peržiūrėti piktnaudžiavimų protokolo", "action-abusefilter-log-detail": "peržiūrėti detalaus piktnaudžiavimų protokolo", - "action-abusefilter-private": "peržiūrėti privačius duomenis piktnaudžiavimų protokole", + "action-abusefilter-privatedetails": "peržiūrėti privačius duomenis piktnaudžiavimų protokole", "action-abusefilter-modify-restricted": "keisti piktnaudžiavimo filtrų su uždraustais veiksmais", "action-abusefilter-revert": "anuliuoti visus pakeitimus pagal konkretų piktnaudžiavimų filtrą", "action-abusefilter-view-private": "žiūrėti piktnaudžiavimo filtrus, pažymėtus kaip privatūs", - "abusefilter-log": "Piktnaudžiavimų sąrašas", "abusefilter-log-summary": "Šiame sąraše pateikiami visi veiksmai, aptikti filtrų.", "abusefilter-log-search": "Ieškoti piktnaudžiavimų protokole", "abusefilter-log-search-user": "Naudotojas:", - "abusefilter-log-search-filter": "Filtrų ID (atskirti vertikaliais brūkšniais):", + "abusefilter-log-search-filter": "Filtrų ID:", "abusefilter-log-search-title": "Antraštė:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-impact": "Aprėptis:", @@ -80,22 +80,21 @@ "abusefilter-log-details-var": "Kintamasis", "abusefilter-log-details-val": "Reikšmė", "abusefilter-log-details-vars": "Veiksmo parametrai", - "abusefilter-log-details-private": "Privatūs sąrašo duomenys", + "abusefilter-log-details-privatedetails": "Privatūs sąrašo duomenys", "abusefilter-log-details-ip": "Pradinis IP adresas", "abusefilter-log-noactions": "Nėra", "abusefilter-log-details-diff": "Redagavimo pakeitimai", "abusefilter-log-linkoncontribs": "piktnaudžiavimų sąrašas", "abusefilter-log-linkoncontribs-text": "{{GENDER:$1|Šio naudotojo|Šios naudotojos}} piktnaudžiavimų sąrašas", - "abusefilter-log-hidden": "(paslėptas įrašas)", "abusefilter-log-hidden-implicit": "(paslėpta, nes peržiūra buvo panaikinta)", "abusefilter-log-cannot-see-details": "Jūs neturite teisės peržiūrėti informaciją apie šį įrašą.", + "abusefilter-log-cannot-see-privatedetails": "Neturite teisių peržiūrėti šio įrašo privačių detalių.", "abusefilter-log-details-hidden": "Negalima peržiūrėti informaciją apie šį įrašą, nes jis yra paslėptas nuo viešo peržiūrėjimo.", "abusefilter-log-hide-legend": "Slėpti žurnalo įrašą", "abusefilter-log-hide-id": "Žurnalo įrašo ID:", "abusefilter-log-hide-hidden": "Slėpti šį įrašą nuo višuo rodymo", "abusefilter-log-hide-reason": "Priežastis", "abusefilter-log-hide-forbidden": "Jūs neturite teisių paslėpti piktnaudžiavimo žurnalo įrašus.", - "abusefilter-management": "Piktnaudžiavimo filtrų valdymas", "abusefilter-list": "Visi filtrai", "abusefilter-list-id": "Filtro ID", "abusefilter-list-status": "Būsena", @@ -115,6 +114,7 @@ "abusefilter-disabled": "Išjungtas", "abusefilter-hitcount": "$1 {{PLURAL:$1|atvejis|atvejai|atvejų}}", "abusefilter-new": "Sukurti naują filtrą", + "abusefilter-import-button": "Importuoti filtrą", "abusefilter-return": "Grįžti į filtrų valdymą", "abusefilter-status-global": "Visuotinis", "abusefilter-list-options": "Variantai", @@ -144,7 +144,6 @@ "abusefilter-edit-oldwarning": "<strong>Jūs keičiate seną šio filtro versiją.\nRodoma statistika paskaičiuota paskutinei filtro versijai.\nJei įrašysite pakeitimus, jūs perrašysite visus pakeitimus, darytus po dabar redaguojamos versijos.</strong> •\n[[Special:AbuseFilter/history/$2|Grįžti į šio failo istoriją]].", "abusefilter-edit-status-label": "Statistika:", "abusefilter-edit-status": "{{PLURAL:$1|Paskutinis|Paskutiniai|Paskutinių}} $1 {{PLURAL:$1|veiksmas|veiksmai|veiksmų}}, šį filtrą atitiko $2 ($3%).", - "abusefilter-edit-status-profile": "{{PLURAL:$1|Paskutinis|Paskutiniai|Paskutinių}} $1 {{PLURAL:$1|veiksmas|veiksmai|veiksmų}}, Šį filtrą atitiko $2 ($3%). Vidutinis jų vykdymo laikas yra $4ms, sunaudota $5 {{PLURAL:$5|sąlyga|sąlygos|sąlygų}} iš limito.", "abusefilter-edit-new": "Naujas filtras", "abusefilter-edit-save": "Išsaugoti filtrą", "abusefilter-edit-id": "Filtro ID:", @@ -172,14 +171,14 @@ "abusefilter-edit-throttle-count": "Leidžiamų veiksmų skaičius:", "abusefilter-edit-throttle-period": "Laiko tarpas (sekundėmis):", "abusefilter-edit-throttle-groups": "Statistikos rinkimo grupė:\n:''(viena eilutėje, jungti kableliais)''", - "abusefilter-edit-throttle-ip": "IP adresas", - "abusefilter-edit-throttle-user": "Naudotojo paskyra", - "abusefilter-edit-throttle-page": "Puslapis", + "abusefilter-throttle-ip": "IP adresas", + "abusefilter-throttle-user": "naudotojo paskyra", + "abusefilter-throttle-page": "puslapis", "abusefilter-edit-warn-message": "Sisteminis pranešimas, kuris naudojamas perspėjimui:", "abusefilter-edit-warn-other": "Kitas pranešimas", - "abusefilter-edit-warn-other-label": "Kito pranešimo puslapio vardas:\n:''(be MediaWiki priešdėlio)''", + "abusefilter-edit-warn-other-label": "Kito pranešimo puslapio žinutė:\n:''(be ''Mediaviki:'' priešdėlio)''", "abusefilter-edit-warn-actions": "Veiksmai:", - "abusefilter-edit-warn-preview": "Peržiūrėti pasirinktą pranešimą", + "abusefilter-edit-warn-preview": "Rodyti/slėpti pasirinkto pranešimo peržiūrą", "abusefilter-edit-warn-edit": "Sukurti/Redaguoti pasirinktą pranešimą", "abusefilter-edit-tag-tag": "Naudojamos žymės (po vieną eilutėje):", "abusefilter-block-anon": "Užblokuoti anoniminiai naudotojai", @@ -287,15 +286,15 @@ "abusefilter-edit-builder-vars-all-links": "Visos išorinės nuorodos naujame tekste", "abusefilter-edit-builder-vars-added-links": "Visos išorinės nuorodos, kurios buvo įstatytos redaguojant", "abusefilter-edit-builder-vars-removed-links": "Visos išorinės nuorodos, panaikintos redaguojant", - "abusefilter-edit-builder-vars-old-text": "Senasis puslapio wiki tekstas, prieš redagavimą", - "abusefilter-edit-builder-vars-new-text": "Naujas puslapio wiki tekstas, po redagavimo", - "abusefilter-edit-builder-vars-new-text-stripped": "Naujas puslapio tekstas, išmetus visas žymas", + "abusefilter-edit-builder-vars-old-wikitext": "Senasis viki teksto puslapis, prieš redagavimą", + "abusefilter-edit-builder-vars-new-wikitext": "Naujas viki teksto puslapis, po redagavimo", + "abusefilter-edit-builder-vars-new-text": "Naujas puslapio tekstas, išmetus visas žymas", "abusefilter-edit-builder-vars-new-html": "Naujos redakcijos HTML tekstas, išskleidus šablonus", "abusefilter-edit-builder-vars-restrictions-edit": "Keistas puslapio apsaugos lygis", "abusefilter-edit-builder-vars-restrictions-move": "Puslapio pervadinimo apsaugos lygis", "abusefilter-edit-builder-vars-restrictions-create": "Sukurti puslapio apsaugą", "abusefilter-edit-builder-vars-restrictions-upload": "Failo įkėlimo apsauga", - "abusefilter-edit-builder-vars-old-text-stripped": "Senas puslapio tekstas, išmetus visas žymes", + "abusefilter-edit-builder-vars-old-text": "Senas puslapio tekstas, išmetus visas žymes", "abusefilter-edit-builder-vars-old-links": "Nuorodos puslapyje, prieš redagavimą", "abusefilter-edit-builder-vars-old-html": "Seno puslapio wiki teksto HTML, išplėtus šablonus", "abusefilter-edit-builder-vars-minor-edit": "Buvo ar ne pakeitimas pažymėtas smulkiu", @@ -398,7 +397,6 @@ "abusefilter-topnav-examine": "Tikrinti paskutinius pakeitimus", "abusefilter-topnav-log": "Piktnaudžiavimų sąrašas", "abusefilter-topnav-tools": "Testavimo priemonė", - "abusefilter-topnav-import": "Importuoti filtrą", "abusefilter-log-name": "Piktnaudžiavimų filtro žurnalas", "abusefilter-log-header": "Šis sąrašas rodo bendrą filtrų pakeitimo statistiką.\nVisas detales žiūrėkite filtrų naujausių pakeitimų [[Special:AbuseFilter/history|sąraše]].", "abusefilter-log-noresults": "Nėra rezultatų", @@ -414,5 +412,6 @@ "abusefilter-import-intro": "Galite naudoti šią sąsają importuoti filtrus iš kitų wiki.\nŠaltinio wiki, spustelėkite \"{{int:abusefilter-redaguoti-eksporto}}\" pagal \"{{int:abusefilter-įrankiai-paantraštė}}\" redagavimo sąsaja.\nKopijuoti iš teksto lauką, kad pasirodo, ir įklijuokite jį į šį teksto lauką, tada spustelėkite \"{{int:abusefilter-importo-pateikti}}\".", "abusefilter-import-submit": "Importuoti duomenis", "abusefilter-group-default": "Numatytasis", - "abusefilter-http-error": "Įvyko HTTP klaida: $1." + "abusefilter-http-error": "Įvyko HTTP klaida: $1.", + "abusefilter-view-privatedetails-legend": "Peržiūrėti privačią informaciją" } diff --git a/AbuseFilter/i18n/lv.json b/AbuseFilter/i18n/lv.json index 4d9503a6..9ce5f53b 100644 --- a/AbuseFilter/i18n/lv.json +++ b/AbuseFilter/i18n/lv.json @@ -1,23 +1,23 @@ { "@metadata": { "authors": [ + "Edgars2007", "GreenZeb", + "Mailman", "Marozols", - "Papuass", - "Nemo bis", - "Edgars2007", "Matma Rex", + "Nemo bis", + "Papuass", "Silraks", - "Zuiks", - "Mailman" + "Zuiks" ] }, "abusefilter-desc": "Pielieto automātiskas heiristikas labojumiem", - "abusefilter": "Ļaunprātīgās izmantošanas filtru konfigurācija", - "abuselog": "Ļaunprātīgo izmantošanu reģistrs", + "abusefilter": "Ļaunprātīgās izmantošanas filtru vadība", + "abuselog": "Ļaunprātīgās izmantošanas filtru reģistrs", "abusefilter-intro": "Laipni lūdzam ļaunprātīgās izmantošanas filtru pārvaldības saskarnē.\nĻaunprātīgās izmantošanas filtri ir automatizēta programmatūra, kas pielieto automātiskas heiristikas visām lietotāju darbībām.\nŠajā saskarnē redzami patlaban definētie filtri, un tiek dota iespēja tos izmainīt.", "abusefilter-warning": "'''Uzmanību''': Šī darbība automātiski tika atpazīta kā ļaunprātīga.\nNekonstruktīvi labojumi tiks nekavējoties atcelti,\nun nekaunīgu vai atkārtotu ļaunprātīgu labojumu dēļ tavs konts vai IP adrese var tikt bloķēta.\nJa tu uzskati, ka tavs labojums ir konstruktīvs, tad saglabā lapu vēlreiz, lai to apstiprinātu.\nĪss kopsavilkums noteikumam, kas saistīts ar tevis veikto darbību: $1", - "abusefilter-disallowed": "Šī darbība automātiski tika atpazīta kā ļaunprātīga un tāpēc tika aizliegta.\nJa tu uzskati, ka tavs labojums ir konstruktīvs, lūdzu informē administratoru par to, ko tu centies izdarīt.\nĪss kopsavilkums noteikumam, kas saistīts ar tevis veikto darbību: $1", + "abusefilter-disallowed": "Šī darbība automātiski tika atpazīta kā ļaunprātīga un tāpēc tika aizliegta.\nJa uzskati, ka Tavs labojums ir konstruktīvs, lūdzu informē administratoru par to, ko centies izdarīt.\nĪss kopsavilkums noteikumam, kas saistīts ar tevis veikto darbību: $1", "abusefilter-blocked-display": "Šī darbība automātiski tika atpazīta kā ļaunprātīga, un tev ir aizliegts to veikt.\nTurklāt, lai aizsargātu {{SITENAME}}, ir liegti labojumi no tava konta un visām saistītajām IP adresēm.\nJa tu uzskati, ka tas ir noticis kļūdas dēļ, lūdzu sazinies ar administratoru.\nĪss kopsavilkums noteikumam, kas saistīts ar tevis veikto darbību: $1", "abusefilter-degrouped": "Šī darbība automātiski tika atpazīta kā ļaunprātīga.\nLīdz ar to tā tika aizliegta un, tā kā ir aizdomas, ka tavs konts ir apdraudēts, visas tiesības tika atceltas.\nJa tu uzskati, ka tas ir noticis kļūdas dēļ, lūdzu sazinies ar birokrātu un paskaidro šo darbību, lai atgūtu savas tiesības.\nĪss kopsavilkums noteikumam, kas saistīts ar tevis veikto darbību: $1", "abusefilter-autopromote-blocked": "Šī darbība automātiski tika atpazīta kā ļaunprātīga, un tev ir aizliegts to veikt.\nTurklāt, kā drošības līdzeklis, dažas privilēģijas, kas parasti tiek piešķirtas ilgāk pastāvošiem kontiem, uz laiku ir atceltas no jūsu konta.\nĪss kopsavilkums noteikumam, kas saistīts ar tevis veikto darbību: $1", @@ -29,7 +29,7 @@ "right-abusefilter-view": "Apskatīt ļaunprātīgās izmantošanas filtrus", "right-abusefilter-log": "Apskatīt ļaunprātīgās izmantošanas reģistru", "right-abusefilter-log-detail": "Apskatīt detalizētus ļaunprātīgās izmantošanas reģistra ierakstus", - "right-abusefilter-private": "Apskatīt privātu informāciju ļaunprātīgās izmantošanas reģistrā", + "right-abusefilter-privatedetails": "Apskatīt privātu informāciju ļaunprātīgās izmantošanas reģistrā", "right-abusefilter-modify-restricted": "Modificēt ļaunprātīgās izmantošanas filtrus ar ierobežotām darbības iespējām", "right-abusefilter-revert": "Atcelt visas dotā ļaunprātīgās izmantošanas filtra veiktās izmaiņas", "right-abusefilter-view-private": "Apskatīt ļaunprātīgās izmantošanas filtrus, kas atzīmēti kā privāti", @@ -39,16 +39,21 @@ "action-abusefilter-view": "apskatīt ļaunprātīgās izmantošanas filtrus", "action-abusefilter-log": "apskatīt ļaunprātīgās izmantošanas reģistru", "action-abusefilter-log-detail": "apskatīt detalizētus ļaunprātīgās izmantošanas reģistra ierakstus", - "action-abusefilter-private": "apskatīt privātu informāciju ļaunprātīgās izmantošanas reģistrā", + "action-abusefilter-privatedetails": "apskatīt privātu informāciju ļaunprātīgās izmantošanas reģistrā", "action-abusefilter-modify-restricted": "modificēt ļaunprātīgās izmantošanas filtrus ar ierobežotām darbības iespējām", "action-abusefilter-revert": "atcelt visas dotā ļaunprātīgās izmantošanas filtra veiktās izmaiņas", "action-abusefilter-view-private": "apskatīt ļaunprātīgās izmantošanas filtrus, kas atzīmēti kā privāti,", - "abusefilter-log": "Ļaunprātīgās izmantošanas filtru reģistrs", "abusefilter-log-summary": "Šis reģistrs satur sarakstu ar visām filtru konstatētajām darbībām.", "abusefilter-log-search": "Meklēt ļaunprātīgo izmantošanu reģistrā", "abusefilter-log-search-user": "Dalībnieks:", + "abusefilter-log-search-group": "Filtru grupa:", "abusefilter-log-search-filter": "Filtru ID (jāatdala ar vertikālu svītru):", "abusefilter-log-search-title": "Nosaukums:", + "abusefilter-log-search-impact-all": "Visas darbības", + "abusefilter-log-search-entries-label": "Redzamība:", + "abusefilter-log-search-entries-all": "Visi ieraksti", + "abusefilter-log-search-action-other": "Citi", + "abusefilter-log-search-action-taken-label": "Veiktā darbība:", "abusefilter-log-search-submit": "Meklēt", "abusefilter-log-entry": "$1: $2 iedarbināja ļaunprātīgās izmantošanas filtru, veicot darbību \"$3\" lapā $4.\nFiltra veiktās darbības: $5;\nFiltra apraksts: $6", "abusefilter-log-detailedentry-meta": "$1: $2 iedarbināja $3, veicot darbību \"$4\" lapā $5.\nFiltra veiktās darbības: $6;\nFiltra apraksts: $7 ($8)", @@ -61,13 +66,12 @@ "abusefilter-log-details-var": "Mainīgais", "abusefilter-log-details-val": "Vērtība", "abusefilter-log-details-vars": "Darbības parametri", - "abusefilter-log-details-private": "Privāto datu reģistrs", + "abusefilter-log-details-privatedetails": "Privāto datu reģistrs", "abusefilter-log-details-ip": "Izcelsmes IP adrese", "abusefilter-log-noactions": "nav", "abusefilter-log-details-diff": "Veiktās izmaiņas", "abusefilter-log-linkoncontribs": "ļaunprātīgo izmantošanu reģistrs", - "abusefilter-log-linkoncontribs-text": "Ļaunprātīgo izmaiņu reģistrs šim lietotājam", - "abusefilter-log-hidden": "(slēpts ieraksts)", + "abusefilter-log-linkoncontribs-text": "Ļaunprātīgo izmaiņu reģistrs šim dalībniekam", "abusefilter-log-details-hidden": "Sīkāka informācija par šo ierakstu nav publiski pieejama.", "abusefilter-log-hide-legend": "Slēpt žurnāla ierakstu", "abusefilter-log-hide-id": "Reģistra ieraksta ID:", @@ -77,7 +81,7 @@ "abusefilter-log-hide-forbidden": "Jums nav tiesību paslēpt ļaunprātīgās izmantošanas reģistra ierakstus.", "log-action-filter-abusefilter-create": "Jauna filtra izveide", "log-action-filter-abusefilter-modify": "Filtra izmaiņa", - "abusefilter-management": "Ļaunprātīgās izmantošanas filtru vadība", + "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|piekļuva}} $3 privātajiem datiem", "abusefilter-list": "Visi filtri", "abusefilter-list-id": "Filtra ID", "abusefilter-list-status": "Statuss", @@ -97,6 +101,7 @@ "abusefilter-disabled": "Atslēgts", "abusefilter-hitcount": "$1 {{PLURAL:$1|trāpījumi|trāpījums|trāpījumi}}", "abusefilter-new": "Izveidot jaunu filtru", + "abusefilter-import-button": "Importēt filtru", "abusefilter-return": "Atgriezties pie filtru pārvaldnieka", "abusefilter-status-global": "Globāls", "abusefilter-list-options": "Parametri", @@ -108,6 +113,7 @@ "abusefilter-list-options-scope-local": "Tikai vietējie noteikumi", "abusefilter-list-options-scope-global": "Tikai globālie noteikumi", "abusefilter-list-options-hidedisabled": "Nerādīt atslēgtos filtrus", + "abusefilter-list-options-searchoptions": "Meklēšanas režīms:", "abusefilter-list-options-search-rlike": "Regulārā izteiksme", "abusefilter-list-options-submit": "Atjaunināt", "abusefilter-tools-text": "Šeit ir daži rīki, kas var būt noderīgi, lai izveidotu un atkļūdotu ļaunprātīgās izmantošanas filtrus.", @@ -126,7 +132,6 @@ "abusefilter-edit-oldwarning": "<strong>Tu rediģē vecu šī filtra versiju.\nRedzamā statistika atbilst jaunākajai filtra versijai.\nJa tu saglabāsi savus labojumus, tiks pārrakstītas visas izmaiņas versijās, kas ir jaunākas par to, kuru tu rediģē.</strong> •\n[[Special:AbuseFilter/history/$2|Atgriezties pie filtra izmaiņu hronoloģijas]].", "abusefilter-edit-status-label": "Statistika:", "abusefilter-edit-status": "No {{PLURAL:$1|pēdējām|pēdējās|pēdējām}} $1 {{PLURAL:$1|darbībām|darbības|darbībām}} šis filtrs attiecās uz $2 ($3%).", - "abusefilter-edit-status-profile": "No {{PLURAL:$1|pēdējām|pēdējās|pēdējām}} $1 {{PLURAL:$1|darbībām|darbības|darbībām}} šis filtrs attiecās uz $2 ($3%).\nVidēji tā darbības laiks ir $4 ms, un tas izlieto $5 {{PLURAL:$5|nosacījumus|nosacījumu|nosacījumus}} no nosacījumu limitu.", "abusefilter-edit-new": "Jauns filtrs", "abusefilter-edit-save": "Saglabāt filtru", "abusefilter-edit-id": "Filtra ID:", @@ -155,8 +160,12 @@ "abusefilter-edit-action-rangeblock": "Bloķēt /16 diapazonu, kurš atbilst lietotāja izcelsmei", "abusefilter-edit-action-tag": "Atzīmēt labojumu tālākai pārbaudei", "abusefilter-edit-throttle-count": "Atļauto darbību skaits:", - "abusefilter-edit-throttle-period": "Laika periods:", + "abusefilter-edit-throttle-period": "Laika periods (sekundēs):", "abusefilter-edit-throttle-groups": "Grupēt pēc:\n:''(pa vienam katrā rindiņā, apvienot ar komatiem)''", + "abusefilter-throttle-ip": "IP adrese", + "abusefilter-throttle-user": "lietotāja konts", + "abusefilter-throttle-editcount": "labojumu skaits", + "abusefilter-throttle-page": "lapa", "abusefilter-edit-warn-message": "Sistēmas paziņojums, ko lietot kā brīdinājumu:", "abusefilter-edit-warn-other": "Cits paziņojums", "abusefilter-edit-warn-other-label": "Lapas nosaukumi citiem paziņojumiem:\n*''(bez MediaWiki prefiksa)''", @@ -194,8 +203,8 @@ "abusefilter-edit-builder-op-arithmetic-modulo": "Modulis (%)", "abusefilter-edit-builder-op-arithmetic-pow": "Kāpināšana (**)", "abusefilter-edit-builder-group-op-comparison": "Salīdzināšanas operatori", - "abusefilter-edit-builder-op-comparison-equal": "Vienāds (==)", - "abusefilter-edit-builder-op-comparison-notequal": "Nav vienāds (!=)", + "abusefilter-edit-builder-op-comparison-equal": "Vērtība vienāda ar (==)", + "abusefilter-edit-builder-op-comparison-notequal": "Vērtība nav vienāda ar (!=)", "abusefilter-edit-builder-op-comparison-lt": "Mazāks (<)", "abusefilter-edit-builder-op-comparison-gt": "Lielāks (>)", "abusefilter-edit-builder-op-comparison-lte": "Mazāks vai vienāds (<=)", @@ -212,7 +221,7 @@ "abusefilter-edit-builder-misc-contains": "Kreisā virkne satur labo virkni (contains)", "abusefilter-edit-builder-misc-stringlit": "Simbolu virkne (\"\")", "abusefilter-edit-builder-misc-tern": "Ternārs operators (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Nosacījums (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Nosacījums (if X then Y else Z end)", "abusefilter-edit-builder-group-funcs": "Funkcijas", "abusefilter-edit-builder-funcs-length": "Virknes garums (length)", "abusefilter-edit-builder-funcs-lcase": "Ar mazajiem burtiem (lcase)", @@ -262,13 +271,13 @@ "abusefilter-edit-builder-vars-all-links": "Visas ārējās saites jaunajā tekstā", "abusefilter-edit-builder-vars-added-links": "Visas pievienotās ārējās saites", "abusefilter-edit-builder-vars-removed-links": "Visas likvidētās ārējās saites", - "abusefilter-edit-builder-vars-old-text": "Lapas vikiteksts pirms rediģēšanas", - "abusefilter-edit-builder-vars-new-text": "Jaunais lapas vikiteksts pēc rediģēšanas", - "abusefilter-edit-builder-vars-new-text-stripped": "Jaunais lapas teksts, bez marķējuma", + "abusefilter-edit-builder-vars-old-wikitext": "Lapas vikiteksts pirms rediģēšanas", + "abusefilter-edit-builder-vars-new-wikitext": "Jaunais lapas vikiteksts pēc rediģēšanas", + "abusefilter-edit-builder-vars-new-text": "Jaunais lapas teksts, bez marķējuma", "abusefilter-edit-builder-vars-new-html": "Parsēts jaunās versijas HTML kods", "abusefilter-edit-builder-vars-restrictions-edit": "Lapas rediģēšanas aizsardzības līmenis", "abusefilter-edit-builder-vars-restrictions-move": "Lapas pārvietošanas aizsardzības līmenis", - "abusefilter-edit-builder-vars-old-text-stripped": "Vecais lapas teksts, bez marķējuma", + "abusefilter-edit-builder-vars-old-text": "Vecais lapas teksts, bez marķējuma", "abusefilter-edit-builder-vars-old-links": "Saites lapā pirms labošanas", "abusefilter-edit-builder-vars-old-html": "Vecais lapas vikiteksts parsēts HTML formātā", "abusefilter-edit-builder-vars-minor-edit": "Vai labojums atzīmēts kā maznozīmīgs", @@ -356,7 +365,6 @@ "abusefilter-topnav-home": "Sākums", "abusefilter-topnav-examine": "Izmeklēt iepriekšējos labojumus", "abusefilter-topnav-tools": "Atkļūdošanas rīki", - "abusefilter-topnav-import": "Importēt filtru", "abusefilter-log-noresults": "Rezultātu nav", "abusefilter-diff-title": "Atšķirības starp versijām", "abusefilter-diff-item": "Vienums", diff --git a/AbuseFilter/i18n/lzh.json b/AbuseFilter/i18n/lzh.json index c55de25f..a1f905d7 100644 --- a/AbuseFilter/i18n/lzh.json +++ b/AbuseFilter/i18n/lzh.json @@ -1,8 +1,8 @@ { "@metadata": { "authors": [ - "LNDDYL", - "Jason924tw" + "Jason924tw", + "LNDDYL" ] }, "abusefilter-log-search": "尋濫誌", diff --git a/AbuseFilter/i18n/mai.json b/AbuseFilter/i18n/mai.json index 7a5893b3..5a29a3f0 100644 --- a/AbuseFilter/i18n/mai.json +++ b/AbuseFilter/i18n/mai.json @@ -1,23 +1,24 @@ { "@metadata": { "authors": [ + "Haribanshi", + "Tulsi Bhagat", "Vinitutpal", - "बिप्लब आनन्द", - "Tulsi Bhagat" + "बिप्लब आनन्द" ] }, "abusefilter-desc": "संपादनके लेल स्वत: हेरिस्टिक लागू होईत् अछि", - "abusefilter": "दुर्व्यवहार फिल्टर विन्यास", - "abuselog": "दुरुपयोग लौग", + "abusefilter": "दुर्व्यवहार फ़िल्टर प्रबन्ध", + "abuselog": "दुर्व्यवहार फिल्टर लौग", "abusefilter-blocker": "फिल्टरक दुरुपयोग", "abusefilter-blockreason": "स्वचालित रूपसे दुर्व्यवहार फिल्टर द्वारा अवरुद्ध।\nमिलान करल नियमके विवरण: $1", "abusefilter-degroupreason": "अधिकार स्वतः दुर्व्यवहार फिल्टर द्वारा छीन लेल।\nनियम विवरण: $1", "abusefilter-accountreserved": "ई प्रयोक्ता नाम दुरुपयोग फिल्टर के उपयोग के लेल आरक्षित अछि।", - "right-abusefilter-modify": "ख़राब फ़िल्टर के ठीक करू", + "right-abusefilter-modify": "खराब फिल्टर ठीक करी", "right-abusefilter-view": "दुरुपयोग छन्नी देखी", "right-abusefilter-log": "दुर्व्यवहार लौग देखी", "right-abusefilter-log-detail": "दुर्व्यवहार लॉग के प्रविष्टियाँ विस्तारमें देखुं", - "right-abusefilter-private": "दुर्व्यवहार लॉग में निजी डेटा देखुं", + "right-abusefilter-privatedetails": "दुर्व्यवहार लॉग में निजी डेटा देखुं", "right-abusefilter-modify-restricted": "दुर्व्यवहार फ़िल्टर के प्रतिबन्धित कार्य सहित सम्पादित करु", "right-abusefilter-revert": "एक देलगेल दुर्व्यवहार फिल्टर द्वारा सभ परिवर्तन के वापस लेल", "right-abusefilter-hidden-log": "दुर्व्यवहार लॉग के प्रविष्टियाँ विस्तारमें देखुं", @@ -26,15 +27,21 @@ "action-abusefilter-view": "दुर्व्यवहार फ़िल्टर के देखु", "action-abusefilter-log": "दुर्व्यवहार लौग देखी", "action-abusefilter-log-detail": "विस्तृत दुर्व्यवहार लॉग प्रविष्टियों के देखु", - "action-abusefilter-private": "दुर्व्यवहार लॉग में निजी डेटा देखु", + "action-abusefilter-privatedetails": "दुर्व्यवहार लॉग में निजी डेटा देखु", "action-abusefilter-modify-restricted": "दुर्व्यवहार फ़िल्टर के प्रतिबन्धित कार्य सहित सम्पादित करु", "action-abusefilter-revert": "एक देलगेल दुर्व्यवहार फिल्टर द्वारा सभ परिवर्तन के वापस लेल", - "abusefilter-log": "दुर्व्यवहार फिल्टर लौग", "abusefilter-log-summary": "ई लॉग फ़िल्टर द्वारा पकरल गेल सभ कार्य के सूची दिखावैत् अछि।", "abusefilter-log-search": "दुर्व्यवहार लौग खोजी", "abusefilter-log-search-user": "प्रयोक्ता", "abusefilter-log-search-title": "शीर्षक", "abusefilter-log-search-wiki": "विकी:", + "abusefilter-log-search-impact": "प्रभावः", + "abusefilter-log-search-impact-all": "सभ कार्य", + "abusefilter-log-search-entries-label": "दृश्यता:", + "abusefilter-log-search-entries-all": "सभ प्रविष्टिसभ:", + "abusefilter-log-search-action-other": "अैार", + "abusefilter-log-search-action-any": "कोई", + "abusefilter-log-search-action-taken-any": "कोई", "abusefilter-log-search-submit": "ताकी", "abusefilter-log-detailedentry-global": "वैश्विक फिल्टर $1", "abusefilter-log-detailedentry-local": "फिल्टर $1", @@ -45,18 +52,20 @@ "abusefilter-log-details-var": "अस्थायी", "abusefilter-log-details-val": "महत्व", "abusefilter-log-details-vars": "काम मानकसभ", - "abusefilter-log-details-private": "निजी डेटा", + "abusefilter-log-details-privatedetails": "निजी लॉग विवरण", "abusefilter-log-details-ip": "मूल आइ॰पी ठेगाना", + "abusefilter-log-details-checkuser": "प्रयोक्ता जाँच", "abusefilter-log-noactions": "कोनो नै", "abusefilter-log-details-diff": "सम्पादन में बदलाव केल गेल", "abusefilter-log-linkoncontribs": "दुर्व्यवहार लौग", - "abusefilter-log-linkoncontribs-text": "ई सदस्य के लेल दुर्व्यवहार लॉग", + "abusefilter-log-linkoncontribs-text": "{{GENDER:$1|इस सदस्य}} क दुरुपयोग लॉग", + "abusefilter-log-linkonhistory": "दुर्व्यवहार लौग देखी", "abusefilter-log-hide-legend": "लॉग प्रवेश नुकाऊँ", "abusefilter-log-hide-id": "लॉग प्रवेश आइ॰डी:", "abusefilter-log-hide-reason": "कारण:", - "abusefilter-management": "दुर्व्यवहार फ़िल्टर प्रबन्ध", - "abusefilter-list": "सभ फ़िल्टर", + "abusefilter-list": "सभ फिल्टर", "abusefilter-list-id": "फ़िल्टर आइ॰डी", + "abusefilter-list-pattern": "प्रतिमान", "abusefilter-list-status": "स्थिति", "abusefilter-list-public": "सार्वजनिक विवरण", "abusefilter-list-consequences": "परिणाम", @@ -66,7 +75,7 @@ "abusefilter-list-details": "जानकारी", "abusefilter-list-limit": "प्रति पृष्ठ सङ्ख्या:", "abusefilter-list-lastmodified": "पिछला संशोधन", - "abusefilter-list-group": "फ़िल्टर समूह", + "abusefilter-list-group": "फिल्टर समूह", "abusefilter-hidden": "निजी", "abusefilter-unhidden": "सार्वजनिक", "abusefilter-enabled": "सक्षम", @@ -74,14 +83,15 @@ "abusefilter-disabled": "अशक्त कएल", "abusefilter-hitcount": "$1 {{PLURAL:$1|हिट|हिटसभ}}", "abusefilter-new": "नयाँ फ़िल्टर बनाबु", + "abusefilter-import-button": "आयात फ़िल्टर", "abusefilter-return": "प्रबंधन फ़िल्टर मे घुरू", "abusefilter-status-global": "वैश्विक", "abusefilter-list-options": "विकल्प", - "abusefilter-list-options-deleted": "मिटायल फ़िल्टर", + "abusefilter-list-options-deleted": "मेटाएल फिल्टर", "abusefilter-list-options-deleted-only": "मिटायल फ़िल्टर के देखाऊ", "abusefilter-list-options-deleted-hide": "मिटायल फ़िल्टर के नुकाऊ", "abusefilter-list-options-deleted-show": "हटायल गेल फ़िल्टर्स मे शामिल करू", - "abusefilter-list-options-scope": "फ़िल्टर देखाबु:", + "abusefilter-list-options-scope": "फिल्टर देखाबी:", "abusefilter-list-options-scope-local": "स्थानीय नियम सभ मात्र", "abusefilter-list-options-scope-global": "ग्लोबल नियम सभ मात्र", "abusefilter-list-options-scope-all": "स्थानीय आर वैश्विक नियम सभ", @@ -94,29 +104,39 @@ "abusefilter-tools-reautoconfirm-submit": "पुनः स्वतः स्थापित", "abusefilter-edit": "दुर्व्यवहार फ़िल्टर सम्पादन", "abusefilter-edit-subtitle": "फ़िल्टर $1 सम्पादन", - "abusefilter-edit-subtitle-new": "फ़िल्टर बनाबैत्", + "abusefilter-edit-subtitle-new": "फिल्टर बनाबी", "abusefilter-edit-status-label": "अंक-विवरण:", - "abusefilter-edit-new": "नयाँ फ़िल्टर", - "abusefilter-edit-save": "फ़िल्टर संरक्षण करू", + "abusefilter-edit-new": "नव फिल्टर", + "abusefilter-edit-save": "फिल्टर संरक्षण करी", "abusefilter-edit-id": "फ़िल्टर आइ॰डी:", + "abusefilter-edit-switch-editor": "संपादक बदल", "abusefilter-edit-description": "विवरण:\n:\"(सार्वजनिक)\"", - "abusefilter-edit-group": "फ़िल्टर समूह:", + "abusefilter-edit-field-description": "विवरण", + "abusefilter-edit-group": "फिल्टर समूह:", "abusefilter-edit-flags": "झंडा:", "abusefilter-edit-enabled": "ई फ़िल्टरके सक्षम करु", "abusefilter-edit-deleted": "मिटाबै के निशान दियो", "abusefilter-edit-hidden": "सार्वजनिक दृश्य से ई फ़िल्टर कs विवरण छुपाबु", - "abusefilter-edit-global": "वैश्विक फ़िल्टर", + "abusefilter-edit-global": "विश्वव्यापी फिल्टर", "abusefilter-edit-rules": "स्थिति:", + "abusefilter-edit-field-conditions": "शर्त", "abusefilter-edit-notes": "नोट्स:", "abusefilter-edit-lastmod": "फ़िल्टर कs अंतिम संशोधन:", "abusefilter-edit-lastmod-text": "$2 द्वारा $1 के", "abusefilter-edit-hitcount": "फिल्टर हिट सभ:", "abusefilter-edit-throttle-count": "कामसभ कs संख्याके अनुमति:", "abusefilter-edit-throttle-period": "समय कs अवधि:", + "abusefilter-throttle-ip": "आइ.पि.पता", + "abusefilter-throttle-user": "नव खाता", + "abusefilter-throttle-creationdate": "लेखा निर्माण अशक्त कएल", + "abusefilter-throttle-editcount": "संपादन संख्या", + "abusefilter-throttle-page": "पृष्ठ", "abusefilter-edit-warn-other": "अन्य सन्देश", "abusefilter-edit-warn-actions": "क्रिया सभ", "abusefilter-edit-warn-preview": "चुन्ल गेल सन्देश के पूर्वावलोकन करु", "abusefilter-edit-warn-edit": "चुन्ल गेल सन्देश बनाबु अथवा संपादित करु", + "abusefilter-edit-disallow-other": "अन्य सन्देश", + "abusefilter-edit-disallow-actions": "क्रियासभ", "abusefilter-edit-main": "फ़िल्टर मानकसभ", "abusefilter-edit-done-subtitle": "फ़िल्टर संपादित भेल", "abusefilter-edit-viewhistory": "ई फिल्टरके इतिहास देखाऊँ", @@ -184,9 +204,10 @@ "abusefilter-history-actions": "क्रिया सभ", "abusefilter-history-backedit": "फ़िल्टर सम्पादन मे फिर्ता", "abusefilter-history-deleted": "मेटाएल गेल", - "abusefilter-history-filterid": "फ़िल्टर", + "abusefilter-history-filterid": "फिल्टर", "abusefilter-history-select-legend": "परिष्कृत खोज", "abusefilter-history-select-user": "प्रयोक्ता:", + "abusefilter-history-select-filter": "फ़िल्टर आइ॰डी:", "abusefilter-history-select-submit": "परिष्कृत", "abusefilter-history-diff": "परिवर्तन सभ", "abusefilter-action-tag": "टैग", @@ -198,7 +219,7 @@ "abusefilter-revert-periodstart": "अवधि सुरु:", "abusefilter-revert-periodend": "अवधि अंत:", "abusefilter-revert-search": "क्रिया चयन करु", - "abusefilter-revert-filter": "फ़िल्टर:", + "abusefilter-revert-filter": "फिल्टर आइडी:", "abusefilter-revert-confirm": "निश्चित", "abusefilter-revert-reasonfield": "कारण:", "abusefilter-test-legend": "फ़िल्टर परीक्षण करैत्", @@ -209,6 +230,9 @@ "abusefilter-test-period-start": "बादमे केल गेल परिवर्तन:", "abusefilter-test-period-end": "पहिने कएल गेल परिवर्तन:", "abusefilter-test-page": "पृष्ठमे बनेल परिवर्तन:", + "abusefilter-test-search-type-all": "सभ कार्य", + "abusefilter-test-search-type-edit": "सम्पादन", + "abusefilter-test-search-type-upload": "उपारोपण", "abusefilter-changeslist-examine": "परीक्षण", "abusefilter-examine": "व्यक्तिगत परिवर्तन जाँची", "abusefilter-examine-legend": "परिवर्तन सभ चुनु", @@ -218,10 +242,10 @@ "abusefilter-examine-submit": "ताकू", "abusefilter-examine-test-button": "टेस्ट फ़िल्टर", "abusefilter-topnav-home": "घर", + "abusefilter-topnav-test": "बैच-जाँच", "abusefilter-topnav-examine": "पूर्व परिवर्तन जाँच करी", "abusefilter-topnav-log": "दुर्व्यवहार लौग", "abusefilter-topnav-tools": "डिबगिंग उपकरण सभ", - "abusefilter-topnav-import": "आयात फ़िल्टर", "abusefilter-log-name": "दुर्व्यवहार फिल्टर लौग", "abusefilter-log-noresults": "कोनो परिणाम नैँ", "abusefilter-diff-item": "आइटम", @@ -231,5 +255,6 @@ "abusefilter-diff-prev": "पुरना बदलाब", "abusefilter-diff-next": "नयाँ बदलाब", "abusefilter-import-submit": "डेटा आयात करु", - "abusefilter-group-default": "डिफ़ॉल्ट" + "abusefilter-group-default": "डिफ़ॉल्ट", + "abusefilter-log-details-id": "प्रवेश आइडी" } diff --git a/AbuseFilter/i18n/map-bms.json b/AbuseFilter/i18n/map-bms.json index eade9407..a82fa6dd 100644 --- a/AbuseFilter/i18n/map-bms.json +++ b/AbuseFilter/i18n/map-bms.json @@ -1,13 +1,13 @@ { "@metadata": { "authors": [ - "StefanusRA", - "Mbrt" + "Mbrt", + "StefanusRA" ] }, "abusefilter-desc": "Terapna pamriksan heuristik otomatis nang suntingan", - "abusefilter": "Pangaturan saringan planggaran", - "abuselog": "Log planggaran", + "abusefilter": "Manajemen saringan planggaran", + "abuselog": "Log saringan planggaran", "abusefilter-blocker": "Saringan planggaran", "abusefilter-degroupreason": "Hak akses dibedhul otomatis nang saringan planggaran.\nKatrangan aturan: $1", "abusefilter-accountreserved": "Jeneng akun kiye wis dipesen nggo dienggo nang saringan planggaran.", @@ -15,7 +15,7 @@ "right-abusefilter-view": "Deleng saringan planggaran", "right-abusefilter-log": "Deleng log planggaran", "right-abusefilter-log-detail": "Deleng entri log planggaran sacara rinci", - "right-abusefilter-private": "Deleng data pribadi nang log planggaran", + "right-abusefilter-privatedetails": "Deleng data pribadi nang log planggaran", "right-abusefilter-modify-restricted": "Ngowaih saringan planggaran karo tindakan sing dibatesi", "right-abusefilter-revert": "Balekna kabeh owahan sekang saringan owahan ding demaksud", "right-abusefilter-view-private": "Deleng saringan planggaran sing detandani pribadi", @@ -26,11 +26,10 @@ "action-abusefilter-view": "deleng saringan planggaran", "action-abusefilter-log": "deleng log planggaran", "action-abusefilter-log-detail": "deleng entri log planggaran sacara rinci", - "action-abusefilter-private": "deleng data pribadi nang log planggaran", + "action-abusefilter-privatedetails": "deleng data pribadi nang log planggaran", "action-abusefilter-modify-restricted": "ngowaih saringan planggaran karo tindakan sing dibatesi", "action-abusefilter-revert": "balekna kabeh owahan sekang saringan owahan ding demaksud", "action-abusefilter-view-private": "deleng saringan planggaran sing detandani pribadi", - "abusefilter-log": "Log saringan planggaran", "abusefilter-log-summary": "Log kiye nidokna daptar kabeh tindakan sing kecekel yang saringan planggaran.", "abusefilter-log-search": "Ngoleti log planggaran", "abusefilter-log-search-user": "Panganggo:", @@ -49,13 +48,12 @@ "abusefilter-log-details-var": "Variabel", "abusefilter-log-details-val": "Biji", "abusefilter-log-details-vars": "Parameter tindakan", - "abusefilter-log-details-private": "Data pribadi", + "abusefilter-log-details-privatedetails": "Data pribadi", "abusefilter-log-details-ip": "Alamat IP asale", "abusefilter-log-noactions": "ora ana", "abusefilter-log-details-diff": "Owahan sing degawe nang suntingan", "abusefilter-log-linkoncontribs": "log planggaran", "abusefilter-log-linkoncontribs-text": "Log planggaran kanggo panganggo kiye", - "abusefilter-log-hidden": "(entri diumpetna)", "abusefilter-log-hidden-implicit": "(diumpetna jalaran revisi wis dibusek)", "abusefilter-log-cannot-see-details": "Rika ora duwe ijin nggo ndeleng rincian entri kiye.", "abusefilter-log-details-hidden": "Rika ora teyeng ndeleng rinciane entri kiye jalaran anu wis diumpetna sekang publik.", @@ -65,7 +63,6 @@ "abusefilter-log-hide-reason": "Alesan:", "abusefilter-log-hide-forbidden": "Rika ora duwe ijin nggo ngumpetna entri log planggaran.", "logentry-abusefilter-hit": "$1 ngurubna $4, nglakokna tindakan \"$5\" nang $3. Tindakan sing dijikot: $6 ($7)", - "abusefilter-management": "Manajemen saringan planggaran", "abusefilter-list": "Kabeh saringan", "abusefilter-list-id": "ID saringan", "abusefilter-list-status": "Status", @@ -85,6 +82,7 @@ "abusefilter-disabled": "Dinonaktifna", "abusefilter-hitcount": "$1 {{PLURAL:$1|wong$1|wong}}", "abusefilter-new": "Gawé saringan anyar", + "abusefilter-import-button": "Impor saringan", "abusefilter-return": "Mbalik ming manajemen saringan", "abusefilter-status-global": "Global", "abusefilter-list-options": "Pilihan", @@ -173,7 +171,6 @@ "abusefilter-topnav-examine": "Priksa suntingan sing gemiyen", "abusefilter-topnav-log": "Log Planggaran", "abusefilter-topnav-tools": "Pekakas debugging", - "abusefilter-topnav-import": "Impor saringan", "abusefilter-log-name": "Log Saringan Planggaran", "abusefilter-log-header": "Log kiye nidokna ringkesan owahan sing degawe ming saringan.\nKanggo rincian sakumplite, deleng [[Special:AbuseFilter/history|daptar]] owah-owahan saringan sing anyar.", "abusefilter-log-noresults": "Ora aba asuke", diff --git a/AbuseFilter/i18n/mg.json b/AbuseFilter/i18n/mg.json index 917c31c9..37d533f8 100644 --- a/AbuseFilter/i18n/mg.json +++ b/AbuseFilter/i18n/mg.json @@ -4,14 +4,14 @@ "Jagwar" ] }, - "abuselog": "Tatitry ny Abuse Filter", + "abuselog": "Laogin'ny sivana manakam-panararaotana", "abusefilter-blocker": "Sivana manakam-panararaotana", "right-abusefilter-modify": "Hanova ny Abuse filter", "right-abusefilter-view": "Hijery ny Abuse Filter", "right-abusefilter-log": "Hijery ny tatitry ny abuse filter", "right-abusefilter-log-detail": "Hijery ny antsipirihan'ny iditry ny Abuse filter", - "right-abusefilter-private": "Hijery ny fampahalalàna tsy sarababem-bahoaka ao amin'ny Abuse filter", - "right-abusefilter-private-log": "Mijery ny antsipirihany tsiambaratelon'ny laogim-pamakian'i AbuseFilter", + "right-abusefilter-privatedetails": "Hijery ny fampahalalàna tsy sarababem-bahoaka ao amin'ny Abuse filter", + "right-abusefilter-privatedetails-log": "Mijery ny antsipirihany tsiambaratelon'ny laogim-pamakian'i AbuseFilter", "right-abusefilter-revert": "Hamafa ny fanovana nataon'ny abuse filter nofidianao", "right-abusefilter-view-private": "Hijery ny abuse filter voamarika ho tsy sarababem-bahoaka", "right-abusefilter-hide-log": "Manitrika ny iditra ao amin'ny tatitry ny fanararaotana", @@ -21,10 +21,9 @@ "action-abusefilter-view": "hijery ny abuse filter", "action-abusefilter-log": "hijery ny tatitry ny abuse filter", "action-abusefilter-log-detail": "mijery ny antsipirihan'ny iditra ao amin'ny tatitry ny fanararaotana", - "action-abusefilter-private": "Hijery ny fampahalalàna tsy sarababem-bahoaka ao amin'ny tatitry ny fanararaotana", - "action-abusefilter-private-log": "Hijery ny antsipirihany tsiambaratelon'ny laogim-pamakian'i AbuseFilter", + "action-abusefilter-privatedetails": "Hijery ny fampahalalàna tsy sarababem-bahoaka ao amin'ny tatitry ny fanararaotana", + "action-abusefilter-privatedetails-log": "Hijery ny antsipirihany tsiambaratelon'ny laogim-pamakian'i AbuseFilter", "action-abusefilter-revert": "mamafa ny fanovana araka ny filitra mpanakana fanararaotana nofidiana", - "abusefilter-log": "Laogin'ny sivana manakam-panararaotana", "abusefilter-log-search-user": "Mpikambana :", "abusefilter-log-search-title": "Lohateny:", "abusefilter-log-search-wiki": "Wiki :", @@ -36,13 +35,12 @@ "abusefilter-log-diff": "fampitahana", "abusefilter-log-details-var": "Miova", "abusefilter-log-details-val": "Sanda", - "abusefilter-log-details-private": "Fampahalalàna tsy sarababem-bahoaka", + "abusefilter-log-details-privatedetails": "Fampahalalàna tsy sarababem-bahoaka", "abusefilter-log-details-ip": "Adiresy IP nihaviana", "abusefilter-log-details-checkuser": "Hanamarina ny mpikambana", "abusefilter-log-noactions": "tsy misy", "abusefilter-log-details-diff": "Fiovana natao tao amin'ilay fanovana", "abusefilter-log-linkoncontribs": "laogiim-panararaotana", - "abusefilter-log-hidden": "(iditra nasitrika)", "abusefilter-log-hide-legend": "Hanafina ny iditra anaty laogy", "abusefilter-log-hide-id": "Mpamantatra ny iditry ny laogy:", "abusefilter-log-hide-hidden": "Hanafina ity iditra ity amin'ny mason'ny vahoaka", diff --git a/AbuseFilter/i18n/min.json b/AbuseFilter/i18n/min.json index 0c00175d..8c4bec32 100644 --- a/AbuseFilter/i18n/min.json +++ b/AbuseFilter/i18n/min.json @@ -4,20 +4,18 @@ "Iwan Novirion" ] }, - "abusefilter": "Pangaturan panyariang panyalahgunoan", - "abuselog": "Log panyalahgunoan", + "abuselog": "Log panyariang panyalahgunoan", "right-abusefilter-modify": "Maubah panyariang panyalahgunoan", "right-abusefilter-view": "Manampilan panyariang panyalahgunoan", "right-abusefilter-log": "Manampilan log panyalahgunoan", "right-abusefilter-log-detail": "Manampilan log panyalahgunoan sacaro rinci", - "right-abusefilter-private": "Manampilan data paribadi pado log panyalahgunoan", + "right-abusefilter-privatedetails": "Manampilan data paribadi pado log panyalahgunoan", "right-abusefilter-modify-restricted": "Maubah panyariang panyalahgunoan jo tindakan tabateh", "right-abusefilter-revert": "Mangambalian sado parubahan nan dibuek dek panyariang panyalahgunoan", "right-abusefilter-view-private": "Caliak panyariang pangalahgunoan nan ditandoi privat", "right-abusefilter-log-private": "Caliak log panyariang panyalahgunoan nan ditandoi privat", "right-abusefilter-hide-log": "Suruakan entri dalam log panyariang pangalahgunoan", "right-abusefilter-hidden-log": "Caliak log panyalahgunoan nan tasuruak", - "abusefilter-log": "Log panyariang panyalahgunoan", "abusefilter-log-summary": "Log iko manunjuakan daftar tindakan nan ditangkok dek panyariang panyalahgunoan.", "abusefilter-log-search": "Pancarian log panyalahgunoan", "abusefilter-log-search-user": "Pangguno:", @@ -36,13 +34,12 @@ "abusefilter-log-details-var": "Variabel", "abusefilter-log-details-val": "Nilai", "abusefilter-log-details-vars": "Parameter tindakan", - "abusefilter-log-details-private": "Data paribadi", + "abusefilter-log-details-privatedetails": "Data paribadi", "abusefilter-log-details-ip": "Alamaik IP asal", "abusefilter-log-noactions": "indak ado", "abusefilter-log-details-diff": "Parubahan dalam suntiangan", "abusefilter-log-linkoncontribs": "log panyalahgunoan", "abusefilter-log-linkoncontribs-text": "Log panyalahgunoan untuak pangguno ko", - "abusefilter-log-hidden": "(entri disuruakan)", "abusefilter-log-hidden-implicit": "(disuruakan dek revisi alah dihapuih)", "abusefilter-log-cannot-see-details": "Sanak indak diizinkan untuak mancaliak rincian entri iko.", "abusefilter-list-limit": "Jumlah per laman:", @@ -55,6 +52,7 @@ "abusefilter-disabled": "Nonaktipan", "abusefilter-hitcount": "$1 {{PLURAL:$1|kali}}", "abusefilter-new": "Buek sariang baru", + "abusefilter-import-button": "Impor panyariang", "abusefilter-return": "Baliak ka pangaturan panyariang", "abusefilter-status-global": "Global", "abusefilter-list-options": "Piliahan", @@ -74,7 +72,7 @@ "abusefilter-edit-main": "Parameter sariang", "abusefilter-edit-done-subtitle": "Sariang lah disuntiang", "abusefilter-edit-done": "Sanak barasil manyimpan parubahan panyariang $1.", - "abusefilter-edit-history": "Riwayaik:", + "abusefilter-edit-history": "Versi:", "abusefilter-filter-log": "Parubahan panyariang tabaru", "abusefilter-history": "Riwayaik parubahan Sariang Panyalahgunoan #$1", "abusefilter-history-foruser": "Diubah dek $1", @@ -105,9 +103,8 @@ "abusefilter-topnav-examine": "Pariso suntiangan lalu", "abusefilter-topnav-log": "Log panyalahgunoan", "abusefilter-topnav-tools": "Alaik debugging", - "abusefilter-topnav-import": "Impor panyariang", "abusefilter-log-name": "Log panyariang panyalahgunoan", - "abusefilter-log-header": "Log iko barisi ringkasan parubahan nan dilakukan pado panyariang.\nUntuak katarangan langkok, caliak [[Special:AbuseFilter/history|daftar]] parubahan panyariang tabaru.", + "abusefilter-log-header": "Log iko barisi ikhtisar parubahan nan dilakukan pado panyariang.\nUntuak katarangan langkok, caliak [[Special:AbuseFilter/history|daftar]] parubahan panyariang tabaru.", "abusefilter-log-noresults": "Indak ado hasil", "abusefilter-diff-title": "Pabedoan antaro versi", "abusefilter-diff-item": "Item", diff --git a/AbuseFilter/i18n/mk.json b/AbuseFilter/i18n/mk.json index 919022f9..c0e8f488 100644 --- a/AbuseFilter/i18n/mk.json +++ b/AbuseFilter/i18n/mk.json @@ -5,12 +5,13 @@ "Brest", "Matma Rex", "Srdjan m", + "Srđan", "Vlad5250" ] }, "abusefilter-desc": "Извршува автоматски хевристички филтрирања во уредувањата", - "abusefilter": "Прилагодувања на филтерот на злоупотреби", - "abuselog": "Дневник на злоупотреби", + "abusefilter": "Раководење со филтерот за злоупотреби", + "abuselog": "Дневник на филтерот за злоупотреби", "abusefilter-intro": "Добре дојдовте на посредникот за раководење со Филтерот за злоупотреби.\nФилтерот за злоупотреби е автоматизиран програмски механизам за примена на автоматска хевристика врз сите дејства.\nОвој посредник дава список на утврдени филтри, и истиот овозможува нивно менување.", "abusefilter-mustviewprivateoredit": "Од безбедносни причини, овој посредник можат да го користат само корисници со право на гледање лични филтри за злоупотреба или измена на филтри.", "abusefilter-warning": "'''Предупредување:''' Ова дејство е автоматски утврдено како штетно.\nНеконструктивните дејства ќе бидат набргу отстранети,\nа глупавите или упорни некоструктивни уредувања ќе доведат до блокирање на вашата сметка или IP-адреса.\nАко сметате дека оваа постапка е конструктивна, можете повторно да ја поднесете за да ја потврдите.\nЕве краток опис на правилото за злоупотреби според кое беше утврдено дека сте направиле престап: $1", @@ -21,13 +22,14 @@ "abusefilter-blocker": "Филтер за злоупотреби", "abusefilter-blockreason": "Автоматски блокиран од филтерот за злоупотреби.\nОпис на совпаднатото правило: $1", "abusefilter-degroupreason": "Филтерот на злоупотреби автоматски ги одзема правата.\nОпис на правилото: $1", + "abusefilter-blockautopromotereason": "Автоунапредувањето е автоматски одложено од филтерот на злоупотреби.\nОпис на правилото: $1", "abusefilter-accountreserved": "Оваа корисничка сметка е резервирана за употреба од филтерот за злоупотреби", - "right-abusefilter-modify": "Менување на филтри за злоупотреба", + "right-abusefilter-modify": "Создавање или менување на филтри за злоупотреба", "right-abusefilter-view": "Преглед на филтрите за злоупотреба", "right-abusefilter-log": "Преглед на дневникот на злоупотреби", "right-abusefilter-log-detail": "Прегледување на подробности во записите од дневникот на злоупотреби", - "right-abusefilter-private": "Прегледување на лични податоци во дневникот на злоупотреби", - "right-abusefilter-private-log": "Преглед на пристап до лични дневнички податоци од Филтерот за злоупотреби", + "right-abusefilter-privatedetails": "Прегледување на лични податоци во дневникот на злоупотреби", + "right-abusefilter-privatedetails-log": "Преглед на пристап до лични дневнички податоци од Филтерот за злоупотреби", "right-abusefilter-modify-restricted": "Менување на филтри за злоупотреби со ограничени можности за дејствување", "right-abusefilter-revert": "Отповикување на сите промени на даден филтер за злоупотреби", "right-abusefilter-view-private": "Прегледување на филтри за злоупотреби означени како лични", @@ -39,17 +41,23 @@ "action-abusefilter-view": "прегледување на филтри за злоупотреби", "action-abusefilter-log": "прегледување на дневникот за злоупотреби", "action-abusefilter-log-detail": "прегледување на подробности од записите во дневникот на злоупотреби", - "action-abusefilter-private": "прегледување на лични податоци во дневникот на злоупотреби", - "action-abusefilter-private-log": "преглед на пристап до лични дневнички податоци од Филтерот за злоупотреби", + "action-abusefilter-privatedetails": "прегледување на лични податоци во дневникот на злоупотреби", + "action-abusefilter-privatedetails-log": "преглед на пристап до лични дневнички податоци од Филтерот за злоупотреби", "action-abusefilter-modify-restricted": "менување на филтри за злоупотреби со ограничени можности за дејствување", "action-abusefilter-revert": "отповикување на сите промени извршени од даден филтер за злоупотреби", "action-abusefilter-view-private": "прегледување на филтри за злоупотреби означени како лични", "action-abusefilter-log-private": "преглед на дневници на филтрите на злоупотреба означени како приватни", - "abusefilter-log": "Дневник на филтерот за злоупотреби", + "action-abusefilter-hide-log": "криење записи во дневникот на злоупотреби", + "action-abusefilter-hidden-log": "прегледување на скриени записи во дневникот на злоупотреби", + "action-abusefilter-modify-global": "создавање или менување на глобални филтри за злоупотреби", "abusefilter-log-summary": "Овој дневник прикажува список на сите дејства уловени од филтрите.", "abusefilter-log-search": "Пребарај по дневникот на злоупотреби", "abusefilter-log-search-user": "Корисник:", - "abusefilter-log-search-filter": "Филтерски назнаки (одделете со исправени црти):", + "abusefilter-log-search-group": "Филтерска група:", + "abusefilter-log-search-group-any": "Било кое", + "abusefilter-log-search-filter": "Назнаки на филтрите:", + "abusefilter-log-search-filter-help": "Одделувајте со прави црти; и претставката „$1“ за глобални филтри", + "abusefilter-log-search-filter-help-central": "Одделете со прави црти", "abusefilter-log-search-title": "Наслов:", "abusefilter-log-search-wiki": "Вики:", "abusefilter-log-search-impact": "Последица:", @@ -78,22 +86,24 @@ "abusefilter-log-details-var": "Променлива", "abusefilter-log-details-val": "Вредност", "abusefilter-log-details-vars": "Параметри на дејството", - "abusefilter-log-details-private": "Лични дневнички податоци", + "abusefilter-log-details-privatedetails": "Лични дневнички податоци", "abusefilter-log-details-ip": "Исходна IP-адреса", "abusefilter-log-details-checkuser": "Провери корисник", "abusefilter-log-noactions": "нема", + "abusefilter-log-noactions-filter": "Нема", "abusefilter-log-details-diff": "Направени промени при уредувањето", "abusefilter-log-linkoncontribs": "дневник на злоупотреби", "abusefilter-log-linkoncontribs-text": "Дневник на злоупотреби за {{GENDER:$1|овој корисник|оваа корисничка}}", "abusefilter-log-linkonhistory": "погл. дневник на злоупотреби", "abusefilter-log-linkonhistory-text": "Преглед на дневникот на злоупотреби за страницава", - "abusefilter-log-hidden": "(скриен запис)", + "abusefilter-log-linkonundelete": "погл. дневник на злоупотреби", + "abusefilter-log-linkonundelete-text": "Преглед на дневникот на злоупотреби за страницава", "abusefilter-log-hidden-implicit": "(скриено бидејќи преработката е избришана)", "abusefilter-log-cannot-see-details": "Немате дозвола да гледате подробности за записот.", - "abusefilter-log-cannot-see-private-details": "Немате дозвола да гледате лични дневнички податоци во ставкава.", + "abusefilter-log-cannot-see-privatedetails": "Немате дозвола да гледате лични дневнички податоци во ставкава.", "abusefilter-log-nonexistent": "Не постои ставка со укажаната назнака.", - "abusefilter-log-details-hidden": "Не можете да ги прегледувате подробностите на овој запис бидејќи тој е сокриен за јавноста.", - "abusefilter-log-details-hidden-implicit": "Не можете да ги прегледувате подробностите на овој запис бидејќи неговата преработка е сокриена за јавноста.", + "abusefilter-log-details-hidden": "Не можете да ги прегледувате подробностите на овој запис бидејќи тој е скриен за јавноста.", + "abusefilter-log-details-hidden-implicit": "Не можете да ги прегледувате подробностите на овој запис бидејќи неговата преработка е скриена за јавноста.", "abusefilter-log-private-not-included": "Една или повеќе од филтерските назнаки што ги укажавте се лични. Бидејќи не ви е дозволено да ги разгледувате подробностите за личните филтри, овие филтри не се употребени при пребарувањето.", "abusefilter-log-hide-legend": "Скриј ставка", "abusefilter-log-hide-id": "ID на записот:", @@ -108,9 +118,12 @@ "log-action-filter-abusefilter-create": "Создавање на нов филтер", "log-action-filter-abusefilter-modify": "Измена во филтер", "log-action-filter-suppress-abuselog": "Потиснување на дневникот на злоупотреби", + "log-action-filter-rights-blockautopromote": "Блокирање на автоунапредување", + "log-action-filter-rights-restoreautopromote": "Повраток на автоунапредување", "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|пристапи}} до личните податоци за $3", + "logentry-rights-blockautopromote": "$1 {{GENDER:$2|го блокираше}} автоунапредувањето на {{GENDER:$4|$3}} во времетраење од $5", + "logentry-rights-restoreautopromote": "$1 {{GENDER:$2|ја поврати}} можноста за автоунапредување на {{GENDER:$4|$3}}", "abusefilterprivatedetails-log-name": "Дневник на пристап до лични податоци од Филтерот за злоупотреби", - "abusefilter-management": "Раководење со филтерот за злоупотреби", "abusefilter-list": "Сите филтри", "abusefilter-list-id": "Назнака на филтерот", "abusefilter-list-pattern": "Мостра", @@ -132,19 +145,20 @@ "abusefilter-throttled": "наметнато", "abusefilter-hitcount": "$1 {{PLURAL:$1|погодок|погодоци}}", "abusefilter-new": "Создај нов филтер", + "abusefilter-import-button": "Увези филтер", "abusefilter-return": "Назад кон раководењето со филтри", "abusefilter-status-global": "Глобален", "abusefilter-list-options": "Нагодувања", "abusefilter-list-options-deleted": "Избришани филтри:", - "abusefilter-list-options-deleted-only": "Прикажи само избришани филтери", - "abusefilter-list-options-deleted-hide": "Скриј избришани филтери", - "abusefilter-list-options-deleted-show": "Вклучи избришани филтери", + "abusefilter-list-options-deleted-only": "Прикажи само избришани филтри", + "abusefilter-list-options-deleted-hide": "Скриј избришани филтри", + "abusefilter-list-options-deleted-show": "Вклучи избришани филтри", "abusefilter-list-options-scope": "Прикажи филтри:", "abusefilter-list-options-scope-local": "Само месни правила", "abusefilter-list-options-scope-global": "Само глобални правила", "abusefilter-list-options-scope-all": "Месни и глобални правила", "abusefilter-list-options-further-options": "Други поставки:", - "abusefilter-list-options-hidedisabled": "Скриј исклучени филтери", + "abusefilter-list-options-hidedisabled": "Скриј исклучени филтри", "abusefilter-list-options-hideprivate": "Скриј приватни филтри", "abusefilter-list-options-searchfield": "Пребарајте во склад со правилата:", "abusefilter-list-options-searchpattern": "Вметни мостра", @@ -152,27 +166,30 @@ "abusefilter-list-options-search-like": "Просто пребарување", "abusefilter-list-options-search-rlike": "Регуларен израз", "abusefilter-list-options-search-irlike": "Големинскоразликувачки регуларен израз", + "abusefilter-list-invalid-searchmode": "Укажаниот начин на бребарување е неважечки.", "abusefilter-list-regexerror": "Се појави грешка при пребарувањето: Грешка во синтаксата на регуларниот израз.", "abusefilter-list-options-submit": "Поднови", "abusefilter-tools-text": "Еве некои алатки кои можат да помогнат со форматирање и отстранување грешки во филтрите за злоупотреби.", "abusefilter-tools-expr": "Проверка на изрази", "abusefilter-tools-submitexpr": "Провери", + "abusefilter-tools-syntax-error": "Филтерот има неважечка синтакса.", "abusefilter-tools-reautoconfirm": "Врати автопотврден статус", "abusefilter-tools-reautoconfirm-user": "Корисник:", "abusefilter-tools-reautoconfirm-submit": "Преавтопотврда", + "abusefilter-tools-restoreautopromote": "Повратено автоунапредувањето преку алатките на Филтерот на злоупотреби.", "abusefilter-reautoconfirm-none": "На {{GENDER:$1|тој корисник не му бил |таа корисничка не ѝ бил}} замрзнуван статусот на автопотврденост.", "abusefilter-reautoconfirm-notallowed": "Не ви е дозволено да го вратите автопотврдениот статус.", "abusefilter-reautoconfirm-done": "Автопотврдениот статус на сметката е вратен", - "abusefilter-status": "Од {{PLURAL:$1|последното $1 дејствие|последните $1 дејствија}}, $2 ($3%) го {{PLURAL:$2|достигна|достигнаа}} условното ограничување $4, и $5 ($6%) {{PLURAL:$5|се совпаѓа|се совпаѓаат}} со еден од тековно вклучените филтри.", + "abusefilter-status": "Од {{PLURAL:$1|последното $1 дејство|последните $1 дејства}}, $2 ($3%) го {{PLURAL:$2|достигна|достигнаа}} условното ограничување $4, и $5 ($6%) {{PLURAL:$5|се совпаѓа|се совпаѓаат}} со барем еден од тековно вклучените филтри.", "abusefilter-edit": "Уредување на филтер за злоупотреби", "abusefilter-edit-subtitle": "Уредување на филтерот $1", "abusefilter-edit-subtitle-new": "Создавање на филтер", "abusefilter-edit-token-not-match": "Уредувањето не е зачувано! Зачувајте го повторно.", "abusefilter-edit-oldwarning": "<strong>Уредувате стара верзија на овој филтер.\nНаведените статистики се однесуваат на најновата верзија на филтерот.\nАко ги зачувате направените промени, ќе ги поклопите сите промени направени од преработката која ја уредувате наваму.</strong> •\n[[Special:AbuseFilter/history/$2|Назад кон историјата на овој филтер]].", + "abusefilter-edit-oldwarning-view": "<strong>Гледате стара верзија на овој филтер.\nНаведената статистика се однесува на неговата најнова верзија.</strong> •\n[[Special:AbuseFilter/history/$2|Назад на историјата на овој филтер]].", "abusefilter-edit-status-label": "Статистики:", - "abusefilter-edit-status": "Од {{PLURAL:$1|последното дејство|последните $1 дејства}}, овој филтер соодветствува на $2 ($3%).", - "abusefilter-edit-status-profile": "Од $1 {{PLURAL:$1|последното дејство|последните дејства}}, овој филтер соодветствува на $2 ($3%).\nПросечното време на работа изнесува $4мс, и искористува $5 {{PLURAL:$5|услов|услови}} од ограничувањето на услови.", - "abusefilter-edit-throttled-warning": "'''Предупредување:''' Овој филтер е автоматски означен како штетен. ОД безбедносни причини, следниве дејства нема да се исполнат ($1). Прегледајте и [[mw:Extension:AbuseFilter/Conditions|оптимизирајте ги]] условите за да го тргнете ова ограничување", + "abusefilter-edit-status": "Од {{PLURAL:$1|последното дејство|последните $1 дејства}}, овој филтер најде $2 ($3%).\nПросечното време на работа изнесува $4 мс, и искористува $5 {{PLURAL:$5|услов|услови}} од ограничувањето на услови.", + "abusefilter-edit-throttled-warning": "'''Предупредување:''' Овој филтер е автоматски означен како штетен. Од безбедносни причини, следниве дејства нема да се исполнат ($1). Прегледајте и [[mw:Extension:AbuseFilter/Conditions|оптимизирајте ги]] условите за да го тргнете ова ограничување", "abusefilter-edit-new": "Нов филтер", "abusefilter-edit-save": "Зачувај филтер", "abusefilter-edit-id": "Назнака на филтерот:", @@ -204,19 +221,24 @@ "abusefilter-edit-throttle-count": "Број на дозволени дејства:", "abusefilter-edit-throttle-period": "Временски период (во секунди):", "abusefilter-edit-throttle-groups": "Истисок по групи:", - "abusefilter-edit-throttle-ip": "IP-адреси", - "abusefilter-edit-throttle-user": "Корисничка сметка", - "abusefilter-edit-throttle-range": "/16-опсег", - "abusefilter-edit-throttle-creationdate": "Време на послужувачот при создавањето на сметката", - "abusefilter-edit-throttle-editcount": "Број на уредувања", - "abusefilter-edit-throttle-site": "Целото мреж. место", - "abusefilter-edit-throttle-page": "Страница", + "abusefilter-edit-throttle-groups-help": "Погледајте ја $1.", + "abusefilter-edit-throttle-groups-help-text": "документацијата на mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Одделете со запирки за да споите со AND, а со нови редови за да споите со OR", + "abusefilter-edit-throttle-placeholder": "Одделете со запирки за да споите со AND, а вметнете едно по едно за да споите со OR", + "abusefilter-throttle-ip": "IP-адреса", + "abusefilter-throttle-user": "корисничка сметка", + "abusefilter-throttle-range": "/16-опсег", + "abusefilter-throttle-creationdate": "датум на создавање на сметката", + "abusefilter-throttle-editcount": "број на уредувања", + "abusefilter-throttle-site": "целото мреж. место", + "abusefilter-throttle-page": "страница", + "abusefilter-throttle-none": "(нема)", "abusefilter-throttle-details": "Дозволи $1 {{PLURAL:$1|дејство|дејства}} секои $2 {{PLURAL:$2|секунда|секунди}}, групно наметнување од: $3", "abusefilter-edit-warn-message": "Системска порака за предупредувањето:", "abusefilter-edit-warn-other": "Друга порака", "abusefilter-edit-warn-other-label": "Име на страница на друга порака:\n:''(без претставката „MediaWiki“)''", "abusefilter-edit-warn-actions": "Дејства:", - "abusefilter-edit-warn-preview": "Прикажи/сокриј преглед на избраната порака", + "abusefilter-edit-warn-preview": "Прикажи/скриј преглед на избраната порака", "abusefilter-edit-warn-edit": "Создај/Уреди избрана порака", "abusefilter-edit-disallow-message": "Системска порака за забраната:", "abusefilter-edit-disallow-other": "Друга порака", @@ -228,9 +250,9 @@ "abusefilter-edit-tag-placeholder": "Додај ознаки (една по една, одделени со запирки)", "abusefilter-edit-tag-hidden-placeholder": "Додај ознаки (одделени со запирки)", "abusefilter-edit-block-anon-durations": "Траење на блокот за анонимни корисници:", - "abusefilter-edit-block-user-durations": "Траење на блокот за регистрирани корисници:", + "abusefilter-edit-block-user-durations": "Траење на блокот за зачленети корисници:", "abusefilter-block-anon": "Блокирај анонимни корисници", - "abusefilter-block-user": "блокирај регистрирани корисници", + "abusefilter-block-user": "блокирај зачленети корисници", "abusefilter-block-talk": "разговорната страница е блокирана", "abusefilter-edit-denied": "Не можете да ги гледате подробностите на овој филтер бидејќи е скриен за јавноста.", "abusefilter-edit-main": "Параметри на филтерот", @@ -250,10 +272,18 @@ "abusefilter-edit-export": "Извези го филтеров во друго вики", "abusefilter-edit-syntaxok": "Не пронајдов синтаксни грешки.", "abusefilter-edit-syntaxerr": "Пронајдена е синтаксна грешка: $1", + "abusefilter-edit-warn-leave": "Ако ја напуштите страницава ќе ги изгубите направените промени на филтерот.", "abusefilter-edit-bad-tags": "Еден или повеќе назначени ознаки се неважечки.\nОзнаките треба да бидат кратки, не смеат да содржат псоебни знаци, и не не смеат да се резервирани од друг програм. Изберете друг назив на ознаката", "abusefilter-edit-notallowed": "Не ви е дозволено да создавате или уредувате филтри за злоупотреби", "abusefilter-edit-notallowed-global": "Не ви е дозволено да создавате или уредувате глобални филтри за злоупотреби", - "abusefilter-edit-notallowed-global-custom-msg": "Глобалните филтри не поддржуваат кориснички-зададени предупредувања", + "abusefilter-edit-notallowed-global-custom-msg": "Глобалните филтри не поддржуваат прилагодени или забранителни предупредувања", + "abusefilter-edit-invalid-warn-message": "Предупредителната порака не може да стои празна.", + "abusefilter-edit-invalid-disallow-message": "Забранителната порака не може да стои празна.", + "abusefilter-edit-invalid-throttlecount": "Бројот на истакнувања мора да биде позитивен цел број.", + "abusefilter-edit-invalid-throttleperiod": "Периодот на истакнување мора да биде позитивен цел број.", + "abusefilter-edit-empty-throttlegroups": "Мора да се избере барем една група за истакнување.", + "abusefilter-edit-duplicated-throttlegroups": "Групите за истакнување не можат да имаат дупликати.", + "abusefilter-edit-invalid-throttlegroups": "Укажаните групи за истакнување се неважечки.", "abusefilter-edit-builder-select": "Одберете можност за додавање кај курсорот", "abusefilter-edit-builder-group-op-arithmetic": "Аритметички оператори", "abusefilter-edit-builder-op-arithmetic-addition": "Собирање (+)", @@ -284,7 +314,8 @@ "abusefilter-edit-builder-misc-contains": "Левата низа ја содржи десната низа (contains)", "abusefilter-edit-builder-misc-stringlit": "Дословна низа (\"\")", "abusefilter-edit-builder-misc-tern": "Тринарен оператор (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Услов (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Услов (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "Краток услов (if X then Y end)", "abusefilter-edit-builder-group-funcs": "Функции", "abusefilter-edit-builder-funcs-length": "Должина на низата (length)", "abusefilter-edit-builder-funcs-lcase": "Со мали букви (lcase)", @@ -309,7 +340,7 @@ "abusefilter-edit-builder-funcs-str_replace": "Замени ја поднизата со низа (str_replace)", "abusefilter-edit-builder-funcs-rescape": "Извод на низа како дословна во рег. изрази (rescape)", "abusefilter-edit-builder-funcs-set_var": "Постави променлива (set_var)", - "abusefilter-edit-builder-funcs-sanitize": "Нормализирај HTML-единици во уникодни знаци (санитаризација)", + "abusefilter-edit-builder-funcs-sanitize": "Нормализирај HTML-единици во уникодни знаци (sanitize)", "abusefilter-edit-builder-group-vars": "Променливи", "abusefilter-edit-builder-vars-accountname": "Име на сметката (при нејзиното создавање)", "abusefilter-edit-builder-vars-timestamp": "Unix-датум и време на промената", @@ -339,7 +370,7 @@ "abusefilter-edit-builder-vars-movedto-title": "Наслов на целната страница за преместување", "abusefilter-edit-builder-vars-movedto-prefixedtitle": "Полн наслов на целната страница за преместување", "abusefilter-edit-builder-vars-movedto-age": "Старост на целната страница на преместувањето (во секунди)", - "abusefilter-edit-builder-vars-user-editcount": "Уреди број на уредувања од корисникот", + "abusefilter-edit-builder-vars-user-editcount": "Број на уредувања на корисникот", "abusefilter-edit-builder-vars-user-age": "Старост на корисничката сметка", "abusefilter-edit-builder-vars-user-name": "Име на корисничката сметка", "abusefilter-edit-builder-vars-user-groups": "Групи (вклучувајќи нејавни) во кои членува корисникот", @@ -355,12 +386,12 @@ "abusefilter-edit-builder-vars-all-links": "Сите надворешни врски во новиот текст", "abusefilter-edit-builder-vars-added-links": "Сите надворешни врски додадени во уредувањето", "abusefilter-edit-builder-vars-removed-links": "Сите надворешни врски отстранети во уредувањето", - "abusefilter-edit-builder-vars-old-text": "Викитекст на старата страница, пред уредувањето (вон употреба)", - "abusefilter-edit-builder-vars-new-text": "Нов викитекст по уредувањето", + "abusefilter-edit-builder-vars-old-wikitext": "Викитекст на старата страница, пред уредувањето", + "abusefilter-edit-builder-vars-new-wikitext": "Нов викитекст по уредувањето", "abusefilter-edit-builder-vars-new-pst": "Викитекст за нова страница, претворен пред зачувување", "abusefilter-edit-builder-vars-diff-pst": "Обединети разлики во уредувањето, претворени пред зачувување", "abusefilter-edit-builder-vars-addedlines-pst": "Додадени редови во уредувањето, претворени пред зачувување", - "abusefilter-edit-builder-vars-new-text-stripped": "Нов текст на страницата, исчистен од секакви ознаки", + "abusefilter-edit-builder-vars-new-text": "Нов текст на страницата, исчистен од секакви ознаки", "abusefilter-edit-builder-vars-new-html": "Расчленет HTML-извор на новата преработка", "abusefilter-edit-builder-vars-restrictions-edit": "Ниво на заштита на страницата од уредувања", "abusefilter-edit-builder-vars-restrictions-move": "Ниво на заштита од преместување на страницата", @@ -374,10 +405,10 @@ "abusefilter-edit-builder-vars-movedto-restrictions-move": "Заштита од преместување на целната страница", "abusefilter-edit-builder-vars-movedto-restrictions-create": "Заштита од создавање на целната страница", "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Заштита од подигање на целната страница", - "abusefilter-edit-builder-vars-old-text-stripped": "Текст на старата страница, со отстранети ознаки", + "abusefilter-edit-builder-vars-old-text": "Текст на старата страница, со отстранети ознаки (вон употреба)", "abusefilter-edit-builder-vars-old-links": "Врски на оваа страница, пред уредувањето", "abusefilter-edit-builder-vars-old-html": "Викитекст на старата страница, расчленет во HTML (вон употреба)", - "abusefilter-edit-builder-vars-minor-edit": "Дали уредувањето е обележано како ситно", + "abusefilter-edit-builder-vars-minor-edit": "Дали уредувањето е обележано како ситно (вон употреба)", "abusefilter-edit-builder-vars-file-sha1": "SHA1-тараба на содржината на податотеката", "abusefilter-edit-builder-vars-file-size": "Големина на податотеката во бајти", "abusefilter-edit-builder-vars-file-mime": "MIME-тип на податотеката", @@ -385,7 +416,9 @@ "abusefilter-edit-builder-vars-file-width": "Ширина на податотеката во пиксели", "abusefilter-edit-builder-vars-file-height": "Висина на податотеката во пиксели", "abusefilter-edit-builder-vars-file-bits-per-channel": "Битови по боен канал на податотеката", - "abusefilter-filter-log": "Скорешни промени во филтери", + "abusefilter-edit-builder-vars-wiki-name": "Име на базата на викито", + "abusefilter-edit-builder-vars-wiki-language": "Јазичен код на викито", + "abusefilter-filter-log": "Скорешни промени во филтри", "abusefilter-history": "Историја на промените во Филтерот за злоупотреби #$1", "abusefilter-history-foruser": "Промени од $1", "abusefilter-history-hidden": "Скриен", @@ -418,13 +451,16 @@ "abusefilter-exception-dividebyzero": "Недозволен обид за делење на $2 со нула кај знакот $1.", "abusefilter-exception-unrecognisedvar": "Нераспознаена променлива $2 кај знакот $1", "abusefilter-exception-notenoughargs": "Нема доволно аргументи за функцијата $2 повикана кај знакот $1.\nСе {{PLURAL:$3|очекуваше $3 аргумент|очекуваа $3 аргументи}}, а {{PLURAL:$4|добиен е|добиени се}} $4", + "abusefilter-exception-toomanyargs": "Нема доволно аргументи за функцијата $2 повикана кај знакот $1.\nСе {{PLURAL:$3|очекуваше највеќе $3 аргумент|очекуваа највеќе $3 аргументи}}, а {{PLURAL:$4|добиен е|добиени се}} $4", "abusefilter-exception-regexfailure": "Грешка во регуларниот израз „$2“ кај знакот $1.", - "abusefilter-exception-overridebuiltin": "Недозволено поклопување на вградена променлива „$2“ кај знакот $1.", + "abusefilter-exception-overridebuiltin": "Недозволено менување на вградената назнака „$2“ кај знакот $1.", "abusefilter-exception-outofbounds": "Барање за непостоечка ставка во стројот $2 (големина на стројот = $3) кај знакот $1.", + "abusefilter-exception-negativeindex": "Негативните показатели не се дозволени во низите. Добив показател „$2“ во знакот $1.", "abusefilter-exception-notarray": "Барање на елемент од стројот за објект кој не е строј кај знакот $1.", "abusefilter-exception-unclosedcomment": "Незатворена прибелешка кај знакот $1.", "abusefilter-exception-invalidiprange": "Укажан неважечки IP-опсег „$2“ кај знакот $1.", "abusefilter-exception-disabledvar": "Променливата $2 кај знакот $1 повеќе не се користи.", + "abusefilter-exception-variablevariable": "set и set_var очекуваат првиот аргумент да биде буквална низа, кај знакот $1.", "abusefilter-action-tag": "Ознака", "abusefilter-action-throttle": "Стесни", "abusefilter-action-warn": "Предупреди", @@ -456,7 +492,7 @@ "abusefilter-test-user": "Промени од корисникот:", "abusefilter-test-nobots": "Скриј ботовски уредувања", "abusefilter-test-period-start": "Промени направени потоа:", - "abusefilter-test-period-end": "Промени напаравени пред тоа:", + "abusefilter-test-period-end": "Промени направени пред тоа:", "abusefilter-test-page": "Направени промени во страницата:", "abusefilter-test-shownegative": "Прикажи промени кои не се совпаѓаат со филтерот", "abusefilter-test-syntaxerr": "Внесениот филтер содржи синтаксна грешка.\nЌе добиете целосно образложение ако стиснете на копчето „{{int:abusefilter-edit-check}}“.", @@ -484,18 +520,19 @@ "abusefilter-examine-syntaxerror": "Филтерот има неважечка синтакса", "abusefilter-examine-notfound": "Побараната промена не е пронајдена.", "abusefilter-examine-incompatible": "Промената која ја побаравте не е поддржана од Филтерот за злоупотреби", - "abusefilter-examine-noresults": "Нема пронајдено ставки за наведените параметри.", + "abusefilter-examine-noresults": "Не пронајдов ставки за наведените параметри.", "abusefilter-topnav": "'''Содржини на Филтерот за злоупотреби'''", "abusefilter-topnav-home": "Почеток", + "abusefilter-topnav-recentchanges": "Скорешни промени во филтри", "abusefilter-topnav-test": "Групно испробување", "abusefilter-topnav-examine": "Разгледување на минати уредувња", "abusefilter-topnav-log": "Дневник на злоупотреби", "abusefilter-topnav-tools": "Алатки за отстранување грешки", - "abusefilter-topnav-import": "Увези филтер", "abusefilter-log-name": "Дневник на филтерот за злоупотреба", "abusefilter-log-header": "Во овој дневник е прикажан преглед на промените направени во филтрите.\nЗа сите подробности, погледајте го [[Special:AbuseFilter/history|списокот]] на скорешни промени во филтрите.", "abusefilter-logentry-create": "$1 {{GENDER:$2|го создаде}} $4 ($5)", "abusefilter-logentry-modify": "$1 {{GENDER:$2|го измени}} $4 ($5)", + "abusefilter-log-invalid-filter": "Некои од наведените филтерски назнаки се неважечки.", "abusefilter-log-noresults": "Нема исход", "abusefilter-diff-title": "Разлики помеѓу верзиите", "abusefilter-diff-item": "Елемент", @@ -508,11 +545,12 @@ "abusefilter-diff-next": "Понова промена", "abusefilter-import-intro": "Овој посредник служи за увезување на филтри од други викија.\nНа изворното вико, стиснете на „{{int:abusefilter-edit-export}}“ под „{{int:abusefilter-edit-tools}}“ во посредникот за уредување.\nКопирајте ја содржината од полето коешто ќе ви се појави, и залепете ја во ова поле, па стиснете на „{{int:abusefilter-import-submit}}“.", "abusefilter-import-submit": "Увези податоци", + "abusefilter-import-invalid-data": "Податоците што сакате да ги увезете се неважечки", "abusefilter-group-default": "По основно", "abusefilter-http-error": "Се појави грешка во HTTP: $1.", - "abusefilter-view-private-submit": "Погл. лични податоци", - "abusefilter-view-private": "Погл. лични податоци", - "abusefilter-view-private-reason": "Причина за пристап до лични податоци:", + "abusefilter-view-privatedetails-submit": "Погл. лични податоци", + "abusefilter-view-privatedetails-legend": "Погл. лични податоци", + "abusefilter-view-privatedetails-reason": "Причина за пристап до личните податоци:", "abusefilter-log-details-id": "Назнака на дневникот", "abusefilter-invalid-request": "Неважечко барање! Мора да пристапите до личните дневнички податоци преку образецот на [[Special:AbuseLog/$1]] и да наведете причина.", "abusefilter-invalid-request-noid": "Неважечко барање! Мора да пристапите до личните дневнички податоци преку образецот на соодветната страница и да наведете причина.", diff --git a/AbuseFilter/i18n/ml.json b/AbuseFilter/i18n/ml.json index df9b0d27..72c3fd4e 100644 --- a/AbuseFilter/i18n/ml.json +++ b/AbuseFilter/i18n/ml.json @@ -1,16 +1,18 @@ { "@metadata": { "authors": [ + "Adithyak1997", "Anoopan", - "Praveenp", - "Matma Rex" + "Matma Rex", + "Praveenp" ] }, "abusefilter-desc": "തിരുത്തലുകളിൽ സ്വയം പ്രതിരോധപ്രവർത്തനങ്ങൾ നടപ്പിലാക്കുന്നു", - "abusefilter": "ദുരുപയോഗ അരിപ്പയുടെ ക്രമീകരണങ്ങൾ", - "abuselog": "ദുരുപയോഗരേഖ", + "abusefilter": "ദുരുപയോഗ അരിപ്പ കൈകാര്യം", + "abuselog": "ദുരുപയോഗ അരിപ്പയുടെ പ്രവർത്തനരേഖ", "abusefilter-intro": "ദുരുപയോഗ അരിപ്പയുടെ കൈകാര്യത്തിനുള്ള സമ്പർക്കമുഖത്തിലേയ്ക്ക് സ്വാഗതം.\nഎല്ലാവിധത്തിലുള്ള പ്രവർത്തനങ്ങളിലേയും ദോഷകരമായ നടപടികളെ സ്വയംപ്രതിരോധിക്കുന്ന സോഫ്റ്റ്വേർ സൗകര്യമാണ് ദുരുപയോഗ അരിപ്പ.\nഈ സമ്പർക്കമുഖത്തിൽ നിർവചിക്കപ്പെട്ടിരിക്കുന്ന അരിപ്പകളുടെ പട്ടികൾ കാണാനും മാറ്റം വരുത്താനും കഴിയുന്നതാണ്.", - "abusefilter-warning": "'''മുന്നറിയിപ്പ്''': ഈ പ്രവൃത്തി ദോഷകരമെന്ന് സ്വയം തിരിച്ചറിഞ്ഞിട്ടുള്ളതാണ്.\nസൃഷ്ടിപരമല്ലാത്ത തിരുത്തലുകൾ അതിവേഗം മുൻപ്രാപനം ചെയ്യുന്നതായിരിക്കും, ദുരുദ്ദേശത്തോടെയുള്ള അല്ലെങ്കിൽ ആവർത്തിച്ചുണ്ടാകുന്ന സൃഷ്ടിപരമല്ലാത്ത തിരുത്തലുകൾ താങ്കളുടെ അംഗത്വത്തെയോ ഐ.പി. വിലാസത്തേയോ തടയുന്നതിൽ എത്തിയേക്കാം.\nതാങ്കൾ താങ്കളുടെ തിരുത്തൽ സൃഷ്ടിപരമെന്നു വിശ്വസിക്കുന്നുണ്ടെങ്കിൽ സ്ഥിരീകരിക്കാനായി ദയവായി വീണ്ടും സമർപ്പിക്കുക.\nതാങ്കളുടെ പ്രവൃത്തിയിൽ ബാധകമാകുന്ന ദുരുപയോഗ നിയമത്തിന്റെ ലഘുവിവരണം: $1", + "abusefilter-mustviewprivateoredit": "സുരക്ഷാ കാരണങ്ങളാൽ, സ്വകാര്യ ദുരുപയോഗ അരിപ്പ കാണാനും മാറ്റംവരുത്താനും അവകാശമുള്ള ഉപയോക്താക്കൾക്ക് മാത്രമേ ഈ സമ്പർക്കമുഖം ഉപയോഗിക്കാൻ കഴിയൂ.", + "abusefilter-warning": "'''മുന്നറിയിപ്പ്''': ഈ പ്രവൃത്തി ദോഷകരമെന്ന് സ്വയം തിരിച്ചറിഞ്ഞിട്ടുള്ളതാണ്.\nസൃഷ്ടിപരമല്ലാത്ത തിരുത്തലുകൾ അതിവേഗം മുൻപ്രാപനം ചെയ്യുന്നതായിരിക്കും, ദുരുദ്ദേശത്തോടെയുള്ള അല്ലെങ്കിൽ ആവർത്തിച്ചുണ്ടാകുന്ന സൃഷ്ടിപരമല്ലാത്ത പ്രവൃത്തികൾ താങ്കളുടെ അംഗത്വത്തെയോ ഐ.പി. വിലാസത്തേയോ തടയുന്നതിൽ എത്തിയേക്കാം.\nതാങ്കൾ താങ്കളുടെ തിരുത്തൽ സൃഷ്ടിപരമെന്നു വിശ്വസിക്കുന്നുണ്ടെങ്കിൽ സ്ഥിരീകരിക്കാനായി ദയവായി വീണ്ടും സമർപ്പിക്കുക.\nതാങ്കളുടെ പ്രവൃത്തിയിൽ ബാധകമാകുന്ന ദുരുപയോഗ നിയമത്തിന്റെ ലഘുവിവരണം: $1", "abusefilter-disallowed": "ഈ പ്രവൃത്തി ദോഷകരമെന്ന് സ്വയം തിരിച്ചറിഞ്ഞിട്ടുള്ളതാണ്, അതിനാലത് അനുവദിക്കാനാകില്ല. താങ്കളുടെ തിരുത്ത് സൃഷ്ടിപരമാണെന്ന് താങ്കൾ വിശ്വസിക്കുന്നുവെങ്കിൽ, ദയവായി കാര്യനിർവാഹകരിലൊരാളെ ബന്ധപ്പെടുക, താങ്കൾ എന്താണ് ചെയ്യാൻ ശ്രമിച്ചതെന്നറിയിക്കുക.\nതാങ്കളുടെ പ്രവൃത്തിയുമായി സാദൃശ്യമുള്ള ദുരുപയോഗ നിയമത്തിന്റെ ലഘുവിവരണം: $1", "abusefilter-blocked-display": "ഈ പ്രവൃത്തി ദോഷകരമെന്നു സ്വയം തിരിച്ചറിഞ്ഞിട്ടുള്ളതാണ്, ഇതു ചെയ്യുന്നതിൽ നിന്നും താങ്കളെ തടയുന്നതാണ്.\nകൂടുതലായി, {{SITENAME}} സംരക്ഷിക്കുന്നതിനായി താങ്കളുടെ അംഗത്വവും ബന്ധപ്പെട്ട ഐ.പി. വിലാസങ്ങളും തിരുത്തുന്നതിൽ നിന്നും തടയുന്നതാണ്.\nഇത് പിഴവുമൂലമുണ്ടായതെങ്കിൽ ദയവായി ഒരു കാര്യനിർവാഹകനെ ബന്ധപ്പെടുക.\nതാങ്കളുടെ പ്രവൃത്തിയുമായി ഒത്തുപോകുന്ന ദുരുപയോഗനിയമത്തിന്റെ ലഘുവിവരണം കാണുക: $1", "abusefilter-degrouped": "ഈ പ്രവൃത്തി ദോഷകരമെന്ന് സ്വയം തിരിച്ചറിഞ്ഞിട്ടുള്ളതാണ്.\nതത്ഫലമായത് അനുവദിക്കാനാകില്ല, ഇക്കാരണം കൊണ്ട് താങ്കളുടെ അംഗത്വം സംശയത്തിന്റെ നിഴലിലാവുകയും, എല്ലാ അവകാശങ്ങളും നീക്കുകയും ചെയ്യുന്നതാണ്.\nഇതെന്തെങ്കിലും പിഴവുമൂലമുണ്ടായതാണെന്നു താങ്കൾ കരുതുന്നുവെങ്കിൽ ഈ പ്രവൃത്തിയ്ക്കുള്ള വിശദീകരണവുമായി ദയവായി ഒരു ബ്യൂറോക്രാറ്റിനെ സമീപിക്കുക, താങ്കളുടെ അവകാശങ്ങൾ പുനഃസ്ഥാപിക്കപ്പെട്ടേയ്ക്കാം.\nതാങ്കളുടെ പ്രവൃത്തിയുമായി സാദൃശ്യമുള്ള ദുരുപയോഗ നിയമത്തിന്റെ ലഘുവിവരണം: $1", @@ -23,7 +25,7 @@ "right-abusefilter-view": "ദുരുപയോഗ അരിപ്പകൾ കാണുക", "right-abusefilter-log": "ദുരുപയോഗരേഖ കാണുക", "right-abusefilter-log-detail": "ദുരുപയോഗരേഖയിലെ വിവരങ്ങൾ വിശദമായി കാണുക", - "right-abusefilter-private": "ദുരുപയോഗരേഖയിലെ സ്വകാര്യവിവരങ്ങൾ കാണുക", + "right-abusefilter-privatedetails": "ദുരുപയോഗരേഖയിലെ സ്വകാര്യവിവരങ്ങൾ കാണുക", "right-abusefilter-modify-restricted": "പരിമിതപ്പെടുത്തിയിരിക്കുന്ന പ്രവൃത്തികൾക്കായി ദുരുപയോഗ അരിപ്പ പുതുക്കുക", "right-abusefilter-revert": "തന്നിരിക്കുന്ന ദുരുപയോഗ അരിപ്പ ചെയ്ത എല്ലാ മാറ്റങ്ങളും തിരസ്കരിക്കുക", "right-abusefilter-view-private": "സ്വകാര്യമെന്ന് അടയാളപ്പെടുത്തിയ ദുരുപയോഗ അരിപ്പകൾ കാണുക", @@ -35,21 +37,34 @@ "action-abusefilter-view": "ദുരുപയോഗ അരിപ്പകൾ കാണുക", "action-abusefilter-log": "ദുരുപയോഗരേഖ കാണുക", "action-abusefilter-log-detail": "ദുരുപയോഗരേഖയിലെ ഉൾപ്പെടുത്തലുകളുടെ വിശദവിവരങ്ങൾ കാണുക", - "action-abusefilter-private": "ദുരുപയോഗരേഖയിലെ സ്വകാര്യവിവരങ്ങൾ കാണുക", + "action-abusefilter-privatedetails": "ദുരുപയോഗരേഖയിലെ സ്വകാര്യവിവരങ്ങൾ കാണുക", "action-abusefilter-modify-restricted": "പരിമിതപ്പെടുത്തിയിരിക്കുന്ന പ്രവൃത്തികൾക്കായി ദുരുപയോഗ അരിപ്പ പുതുക്കുക", "action-abusefilter-revert": "തന്നിരിക്കുന്ന ദുരുപയോഗ അരിപ്പ ചെയ്ത എല്ലാ മാറ്റങ്ങളും തിരസ്കരിക്കുക", "action-abusefilter-view-private": "സ്വകാര്യമെന്ന അടയാളപ്പെടുത്തിയ ദുരുപയോഗ അരിപ്പകൾ കാണുക", - "abusefilter-log": "ദുരുപയോഗ അരിപ്പയുടെ പ്രവർത്തനരേഖ", "abusefilter-log-summary": "അരിപ്പകൾ കണ്ടെത്തിയ എല്ലാ പ്രവൃത്തിയുടേയും പട്ടിക ഈ രേഖയിൽ കാണാം.", "abusefilter-log-search": "ദുരുപയോഗരേഖയിൽ തിരയുക", "abusefilter-log-search-user": "ഉപയോക്താവ്:", + "abusefilter-log-search-group-any": "ഏതെങ്കിലും", "abusefilter-log-search-filter": "അരിപ്പയുടെ ഐ.ഡി.കൾ (പൈപ്പുകൾ ഉപയോഗിച്ച് വേർതിരിക്കുക):", "abusefilter-log-search-title": "തലക്കെട്ട്:", "abusefilter-log-search-wiki": "വിക്കി:", + "abusefilter-log-search-impact": "പ്രഭാവം:", + "abusefilter-log-search-impact-all": "എല്ലാ പ്രവൃത്തികളും", + "abusefilter-log-search-impact-saved": "സേവ് ചെയ്യപ്പെട്ട മാറ്റങ്ങൾ മാത്രം", + "abusefilter-log-search-impact-not-saved": "സേവ് ചെയ്യപ്പെട്ട മാറ്റങ്ങൾ ഇല്ലാതെ", + "abusefilter-log-search-entries-label": "ദൃശ്യത:", + "abusefilter-log-search-entries-all": "എല്ലാ ഉൾപ്പെടുത്തലുകളും", + "abusefilter-log-search-entries-hidden": "ഗുപ്ത ഉൾപ്പെടുത്തലുകൾ മാത്രം", + "abusefilter-log-search-entries-visible": "ദൃശ്യമായ ഉൾപ്പെടുത്തലുകൾ മാത്രം", + "abusefilter-log-search-action-label": "പ്രേരക പ്രവൃത്തി:", + "abusefilter-log-search-action-other": "മറ്റുള്ളവ", + "abusefilter-log-search-action-any": "ഏതെങ്കിലും", + "abusefilter-log-search-action-taken-label": "എടുത്ത പ്രവൃത്തി\"", + "abusefilter-log-search-action-taken-any": "ഏതെങ്കിലും", "abusefilter-log-search-submit": "തിരയുക", - "abusefilter-log-entry": "$1: $4 എന്ന താളിൽ $2 ചെയ്ത \"$3\" എന്ന പ്രവൃത്തി ഒരു ദുരുപയോഗ അരിപ്പയെ ഉണർത്തിയിരിക്കുന്നു.\nഎടുത്ത നടപടികൾ: $5;\nഅരിപ്പയുടെ വിവരണം: $6", - "abusefilter-log-entry-withdiff": "$4 എന്ന താളിൽ $1-നു $2 ചെയ്ത ''$3'' എന്ന പ്രവൃത്തി ഒരു ദുരുപയോഗ അരിപ്പയെ ഉണർത്തിയിരിക്കുന്നു.\nഎടുത്ത നടപടികൾ: $5;\nഅരിപ്പയുടെ വിവരണം: $6 ($7)", - "abusefilter-log-detailedentry-meta": "$1: $5 എന്ന താളിൽ $2 ചെയ്ത \"$4\" എന്ന പ്രവൃത്തി $3-നെ ഉണർത്തിയിരിക്കുന്നു.\nഎടുത്ത നടപടി: $6;\nഅരിപ്പയുടെ വിവരണം: $7 ($8)", + "abusefilter-log-entry": "$1: $4 എന്ന താളിൽ $2 {{GENDER:$8|ചെയ്ത}} \"$3\" എന്ന പ്രവൃത്തി ഒരു ദുരുപയോഗ അരിപ്പയെ {{GENDER:$8|ഉണർത്തിയിരിക്കുന്നു}}.\nഎടുത്ത നടപടികൾ: $5;\nഅരിപ്പയുടെ വിവരണം: $6", + "abusefilter-log-entry-withdiff": "$4 എന്ന താളിൽ $1-നു $2 {{GENDER:$8|ചെയ്ത}} ''$3'' എന്ന പ്രവൃത്തി ഒരു ദുരുപയോഗ അരിപ്പയെ {{GENDER:$8|ഉണർത്തിയിരിക്കുന്നു}}.\nഎടുത്ത നടപടികൾ: $5;\nഅരിപ്പയുടെ വിവരണം: $6 ($7)", + "abusefilter-log-detailedentry-meta": "$1: $5 എന്ന താളിൽ $2 {{GENDER:$9|ചെയ്ത}} \"$4\" എന്ന പ്രവൃത്തി $3 അരിപ്പയെ {{GENDER:$9|ഉണർത്തിയിരിക്കുന്നു}}.\nഎടുത്ത നടപടി: $6;\nഅരിപ്പയുടെ വിവരണം: $7 ($8)", "abusefilter-log-detailedentry-global": "ആഗോള അരിപ്പ $1", "abusefilter-log-detailedentry-local": "അരിപ്പ $1", "abusefilter-log-detailslink": "വിവരണങ്ങൾ", @@ -59,26 +74,29 @@ "abusefilter-log-details-var": "ചരം", "abusefilter-log-details-val": "മൂല്യം", "abusefilter-log-details-vars": "പ്രവർത്തന ചരങ്ങൾ", - "abusefilter-log-details-private": "സ്വകാര്യ വിവരം", "abusefilter-log-details-ip": "ഉത്ഭവിക്കുന്ന ഐ.പി. വിലാസം", + "abusefilter-log-details-checkuser": "ചെക്ക് യൂസർ", "abusefilter-log-noactions": "ഒന്നുമില്ല", "abusefilter-log-details-diff": "തിരുത്തലിൽ വരുത്തിയ മാറ്റങ്ങൾ", "abusefilter-log-linkoncontribs": "ദുരുപയോഗരേഖ", - "abusefilter-log-linkoncontribs-text": "ഈ ഉപയോക്താവിന്റെ ദുരുപയോഗരേഖ", - "abusefilter-log-hidden": "(വിവരം മറയ്ക്കപ്പെട്ടിരിക്കുന്നു)", + "abusefilter-log-linkoncontribs-text": "{{GENDER:$1|ഈ ഉപയോക്താവിന്റെ}} ദുരുപയോഗരേഖ", + "abusefilter-log-linkonhistory": "ദുരുപയോഗരേഖ കാണുക", + "abusefilter-log-linkonhistory-text": "ഈ താളിന്റെ ദുരുപയോഗരേഖ കാണുക", "abusefilter-log-hidden-implicit": "(നാൾപ്പതിപ്പ് മായ്ക്കപ്പെട്ടിരിക്കുന്നതിനാൽ മറച്ചിരിക്കുന്നു)", "abusefilter-log-cannot-see-details": "ഈ ഉൾപ്പെടുത്തലിന്റെ വിശദാംശങ്ങൾ കാണാനുള്ള അനുമതി താങ്കൾക്കില്ല.", + "abusefilter-log-cannot-see-privatedetails": "ഈ ഉൾപ്പെടുത്തലിന്റെ സ്വകാര്യ വിശദാംശങ്ങൾ കാണാനുള്ള അനുമതി താങ്കൾക്കില്ല.", "abusefilter-log-details-hidden": "ഈ വിവരം പൊതുജനദൃഷ്ടിയിൽ നിന്നും മറയ്ക്കപ്പെട്ടിരിക്കുന്നതിനാൽ, കൂടുതൽ വിവരങ്ങൾ കാണാനാകില്ല.", "abusefilter-log-private-not-included": "താങ്കൾ നൽകിയവയിൽ ഒന്നോ അതിലധികമോ അരിപ്പകളുടെ ഐ.ഡി.കൾ സ്വകാര്യമാണ്. സ്വകാര്യ അരിപ്പകളുടെ വിശദാംശങ്ങൾ കാണാൻ താങ്കൾക്ക് അനുവാദമില്ലാത്തതിനാൽ, ഈ അരിപ്പകൾ തിരയപ്പെടുന്നതല്ല.", "abusefilter-log-hide-legend": "രേഖയിലെ ഉൾപ്പെടുത്തൽ മറയ്ക്കുക", "abusefilter-log-hide-id": "രേഖയിൽ ഉൾപ്പെടുത്തിയതിന്റെ ഐ.ഡി.:", "abusefilter-log-hide-hidden": "പൊതുജനദൃഷ്ടിയിൽ നിന്ന് ഈ വിവരം മറയ്ക്കുക", "abusefilter-log-hide-reason": "കാരണം:", + "abusefilter-log-hide-reason-other": "മറ്റ്/കൂടുതൽ കാരണം:", "abusefilter-log-hide-forbidden": "ദുരുപയോഗരേഖയിലെ വിവരങ്ങൾ മറയ്ക്കാനുള്ള അനുവാദം താങ്കൾക്കില്ല.", - "logentry-abusefilter-hit": "$1 നടത്തിയ പ്രവൃത്തി $4-നെ ഉണർത്തി, $3-യിൽ \"$5\" എന്ന നടപടി എടുക്കുന്നു. എടുത്ത നടപടി: $6 ($7)", - "abusefilter-management": "ദുരുപയോഗ അരിപ്പ കൈകാര്യം", + "logentry-abusefilter-hit": "$3 താളിൽ $1 {{GENDER:$2|നടത്തിയ}} \"$5\" പ്രവൃത്തി $4 അരിപ്പയെ {{GENDER:$2|ഉണർത്തി}}.\nഎടുത്ത നടപടി: $6 ($7)", "abusefilter-list": "എല്ലാ അരിപ്പകളും", "abusefilter-list-id": "അരിപ്പയുടെ ഐ.ഡി.", + "abusefilter-list-pattern": "ശ്രേണി", "abusefilter-list-status": "സ്ഥിതി", "abusefilter-list-public": "പൊതു വിവരണം", "abusefilter-list-consequences": "പരിണതഫലങ്ങൾ", @@ -94,8 +112,10 @@ "abusefilter-enabled": "സജ്ജമാക്കിയിരിക്കുന്നു", "abusefilter-deleted": "മായ്ച്ചിരിക്കുന്നു", "abusefilter-disabled": "നിർജ്ജീവമാക്കപ്പെട്ടിരിക്കുന്നു", + "abusefilter-throttled": "ത്വരണി", "abusefilter-hitcount": "{{PLURAL:$1|ഒരു കുടുങ്ങൽ|$1 കുടുങ്ങൽ}}", "abusefilter-new": "പുതിയൊരു അരിപ്പ സൃഷ്ടിക്കുക", + "abusefilter-import-button": "അരിപ്പ ഇറക്കുമതി ചെയ്യുക", "abusefilter-return": "അരിപ്പയുടെ കൈകാര്യം താളിലേയ്ക്ക് മടങ്ങുക", "abusefilter-status-global": "ആഗോളം", "abusefilter-list-options": "ഐച്ഛികങ്ങൾ", @@ -125,11 +145,11 @@ "abusefilter-edit-oldwarning": "<strong>താങ്കൾ ഈ അരിപ്പയുടെ പഴയൊരു പതിപ്പാണ് തിരുത്തുന്നത്.\nഉദ്ധരിച്ചിരിക്കുന്ന സ്ഥിതിവിവരമാകട്ടെ അരിപ്പയുടെ ഏറ്റവും പുതിയതും.\nതാങ്കളുടെ മാറ്റങ്ങൾ സേവ് ചെയ്യുകയാണെങ്കിൽ, താങ്കൾ തിരുത്തിയ നാൾപ്പതിപ്പ് മുതലുള്ള എല്ലാ മാറ്റങ്ങളും നഷ്ടപ്പെടുന്നതാണ്.</strong> •\n[[Special:AbuseFilter/history/$2|ഈ അരിപ്പയുടെ നാൾവഴിയിലേയ്ക്ക് മടങ്ങുക]].", "abusefilter-edit-status-label": "സ്ഥിതിവിവരക്കണക്കുകൾ:", "abusefilter-edit-status": "ഒടുവിലത്തെ {{PLURAL:$1|പ്രവൃത്തിയിൽ|$1 പ്രവൃത്തികളിൽ}}, അരിപ്പ $2 എണ്ണവുമായി ഒത്തുപോയി ($3%).", - "abusefilter-edit-status-profile": "ഒടുവിലത്തെ {{PLURAL:$1|പ്രവൃത്തിയിൽ|$1 പ്രവൃത്തികളിൽ}}, അരിപ്പ $2 എണ്ണവുമായി ഒത്തുപോയി ($3%).\nശരാശരി, പ്രവർത്തന സമയം $4 മില്ലിസെക്കന്റ് ആണ്, ഉപാധികളിൽ {{PLURAL:$5|ഒരുപാധി|$5 ഉപാധികൾ}} ഉപയോഗിച്ചിരിക്കുന്നു.", "abusefilter-edit-new": "പുതിയ അരിപ്പ", "abusefilter-edit-save": "അരിപ്പ സേവ് ചെയ്യുക", "abusefilter-edit-id": "അരിപ്പയുടെ ഐ.ഡി.:", "abusefilter-edit-description": "വിവരണം:\n:''(പൊതുജന ലഭ്യം)''", + "abusefilter-edit-field-description": "വിവരണം", "abusefilter-edit-group": "അരിച്ചെടുക്കൽ ഗണം:", "abusefilter-edit-flags": "പതാകകൾ:", "abusefilter-edit-enabled": "ഈ അരിപ്പ സജ്ജമാക്കുക", @@ -137,6 +157,7 @@ "abusefilter-edit-hidden": "പൊതുജനദൃഷ്ടിയിൽ നിന്നും അരിപ്പയുടെ വിവരങ്ങൾ മറയ്ക്കുക", "abusefilter-edit-global": "ആഗോള അരിപ്പ", "abusefilter-edit-rules": "ഉപാധികൾ:", + "abusefilter-edit-field-conditions": "ഉപാധികൾ", "abusefilter-edit-notes": "കുറിപ്പുകൾ:", "abusefilter-edit-lastmod": "അരിപ്പ അവസാനം പുതുക്കിയത്:", "abusefilter-edit-lastmod-text": "$1 ചെയ്തത് $2", @@ -148,23 +169,39 @@ "abusefilter-edit-action-degroup": "എല്ലാ പ്രത്യേക പദവികളുള്ള സംഘങ്ങളിൽ നിന്നും ഉപയോക്താവിനെ നീക്കുക", "abusefilter-edit-action-block": "ഉപയോക്താവിനെ ഒപ്പം/അല്ലെങ്കിൽ ഐ.പി. വിലാസത്തെ തിരുത്തുന്നതിൽ നിന്നും തടയുക", "abusefilter-edit-action-throttle": "ഉപയോക്താവ് പരിധി കടന്നാൽ മാത്രം പ്രവൃത്തികൾ തുടങ്ങുക", - "abusefilter-edit-action-rangeblock": "ഉപയോക്താവ് കടന്നുവരുന്ന /16 പരിധി തടയുക", + "abusefilter-edit-action-rangeblock": "ഉപയോക്താവ് കടന്നുവരുന്ന ബന്ധപ്പെട്ട ഐ.പി. പരിധി തടയുക", "abusefilter-edit-action-tag": "കൂടുതൽ സംശോധനത്തിനായി തിരുത്ത് റ്റാഗ് ചെയ്യുക", "abusefilter-edit-throttle-count": "അനുവദിക്കപ്പെട്ടിരിക്കുന്ന പ്രവർത്തനങ്ങളുടെ എണ്ണം:", - "abusefilter-edit-throttle-period": "കാലയളവ്:", - "abusefilter-edit-throttle-groups": "സംഘ ത്വരകം:\n:(അർദ്ധവിരാമമുപയോഗിച്ച് യോജിപ്പിച്ച, ഒരു വരിയിൽ ഒരെണ്ണം വീതം)", + "abusefilter-edit-throttle-period": "കാലയളവ് (സെക്കന്റിൽ):", + "abusefilter-edit-throttle-groups": "സംഘത്തിന്റെ ത്വരകം:", + "abusefilter-edit-throttle-groups-help": "$1 കാണുക.", + "abusefilter-throttle-ip": "ഐ.പി. വിലാസം", + "abusefilter-throttle-user": "ഉപയോക്തൃഅംഗത്വം", + "abusefilter-throttle-range": "/16 പരിധി", + "abusefilter-throttle-creationdate": "അംഗത്വം സൃഷ്ടിച്ച തീയതി", + "abusefilter-throttle-editcount": "തിരുത്തുകളുടെ എണ്ണം", + "abusefilter-throttle-site": "സൈറ്റ് മുഴുവനും", + "abusefilter-throttle-page": "താൾ", "abusefilter-edit-warn-message": "മുന്നറിയിപ്പിനായി ഉപയോഗിക്കുന്ന വ്യവസ്ഥാ സന്ദേശം:", "abusefilter-edit-warn-other": "മറ്റു സന്ദേശം", - "abusefilter-edit-warn-other-label": "മറ്റ് സന്ദേശങ്ങളുടെ താളിന്റെ പേര്:\n:''(പൂർവ്വപദമായ മീഡിയവിക്കി ഇല്ലാതെ)''", + "abusefilter-edit-warn-other-label": "മറ്റ് സന്ദേശങ്ങളുടെ താളിന്റെ പേര്:\n:''(പൂർവ്വപദമായ \"മീഡിയവിക്കി:\" ഇല്ലാതെ)''", "abusefilter-edit-warn-actions": "പ്രവർത്തനങ്ങൾ:", - "abusefilter-edit-warn-preview": "തിരഞ്ഞെടുത്ത സന്ദേശത്തിന്റെ പ്രിവ്യൂ കാണുക", + "abusefilter-edit-warn-preview": "തിരഞ്ഞെടുത്ത സന്ദേശത്തിന്റെ പ്രിവ്യൂ കാണുക/മറയ്ക്കുക", "abusefilter-edit-warn-edit": "തിരഞ്ഞെടുത്ത സന്ദേശം സൃഷ്ടിക്കുക/തിരുത്തുക", - "abusefilter-edit-tag-tag": "ബാധകമാക്കേണ്ട [[Special:Tags|റ്റാഗുകൾ]] (ഒരു വരിയിൽ ഒന്നു വീതം):", + "abusefilter-edit-disallow-other": "മറ്റു സന്ദേശം", + "abusefilter-edit-disallow-other-label": "അടുത്ത സന്ദേശത്തിന്റെ താളിന്റെ പേര്:\n:''(പൂർവ്വപദമായ \"മീഡിയവിക്കി:\" ഇല്ലാതെ)''", + "abusefilter-edit-disallow-actions": "പ്രവൃത്തികൾ:", + "abusefilter-edit-disallow-preview": "തിരഞ്ഞെടുത്ത സന്ദേശത്തിന്റെ പ്രിവ്യൂ കാണുക/മറയ്ക്കുക", + "abusefilter-edit-disallow-edit": "തിരഞ്ഞെടുത്ത സന്ദേശം സൃഷ്ടിക്കുക/തിരുത്തുക", + "abusefilter-edit-tag-tag": "ബാധകമാക്കേണ്ട [[Special:Tags|റ്റാഗുകൾ]]:", + "abusefilter-block-user": "അംഗത്വമെടുത്തിട്ടുള്ളവരെ തടയുക", + "abusefilter-block-talk": "സംവാദത്താൾ തടഞ്ഞിരിക്കുന്നു", "abusefilter-edit-denied": "താങ്കൾക്ക് ഈ അരിപ്പയുടെ വിവരങ്ങൾ കാണാൻ കഴിയണമെന്നില്ല, അത് പൊതുദൃഷ്ടിയിൽ നിന്നും മറയ്ക്കപ്പെട്ടതാണ്.", "abusefilter-edit-main": "അരിപ്പയ്ക്കായുള്ള ചരങ്ങൾ", "abusefilter-edit-done-subtitle": "അരിപ്പ തിരുത്തി", "abusefilter-edit-done": "[[Special:AbuseFilter/$1|അരിപ്പ $3]]-ൽ [[Special:AbuseFilter/history/$1/diff/prev/$2|താങ്കൾ വരുത്തിയ മാറ്റങ്ങൾ]] വിജയകരമായി സേവ് ചെയ്തിരിക്കുന്നു.", "abusefilter-edit-badsyntax": "താങ്കൾ നൽകിയ അരിപ്പയിൽ എഴുതിനൽകിയതിൽ പിഴവുണ്ട്.\nപാഴ്സറിന്റെ ഔട്ട്പുട്ട് ഇപ്രകാരമായിരുന്നു: <pre>$1</pre>", + "abusefilter-edit-deleting-enabled": "ഒരു സജീവ അരിപ്പ മായ്ച്ചതായി അടയാളപ്പെടുത്താൻ താങ്കൾക്ക് സാധിക്കില്ല.", "abusefilter-edit-restricted": "താങ്കൾക്ക് ഈ അരിപ്പയിൽ മാറ്റം വരുത്താൻ കഴിയില്ല, കാരണം ഇതിൽ ഒന്നോ അതിലധികമോ പരിമിതപ്പെടുത്തിയ പ്രവൃത്തികളുണ്ട്.\nദയവായി അനുമതിയുള്ള ഉപയോക്താവിനെ സമീപിച്ച് പരിമിതപ്പെടുത്തിയ മാറ്റങ്ങൾ താങ്കൾക്കായി ചെയ്യാൻ ദയവായി ആവശ്യപ്പെടുക.", "abusefilter-edit-viewhistory": "ഈ അരിപ്പയുടെ നാൾവഴി കാണുക", "abusefilter-edit-history": "നാൾവഴി:", @@ -176,10 +213,12 @@ "abusefilter-edit-export": "ഈ അരിപ്പ മറ്റൊരു വിക്കിയിലേയ്ക്ക് കയറ്റുമതി ചെയ്യുക", "abusefilter-edit-syntaxok": "എഴുത്തുരീതിയിൽ പിഴവുകളൊന്നും കണ്ടെത്തിയില്ല.", "abusefilter-edit-syntaxerr": "എഴുത്തുരീതിയിൽ പിഴവ് കണ്ടെത്തി: $1", - "abusefilter-edit-bad-tags": "താങ്കൾ നൽകിയ റ്റാഗുകളിൽ ഒന്നോ അതിലധികമോ അസാധുവാണ്.\nറ്റാഗുകൾ ചെറുതും പ്രത്യേക അക്ഷരങ്ങൾ ഉൾക്കൊള്ളാത്തവയും ആയിരിക്കണം.", + "abusefilter-edit-bad-tags": "താങ്കൾ നൽകിയ റ്റാഗുകളിൽ ഒന്നോ അതിലധികമോ അസാധുവാണ്.\nറ്റാഗുകൾ ചെറുതും പ്രത്യേക അക്ഷരങ്ങൾ ഉൾക്കൊള്ളാത്തവയും ആയിരിക്കണം, ഒപ്പം അവ മറ്റ് സോഫ്റ്റ്വേറുകൾ സംവരണം ചെയ്തതും ആവരുത്. റ്റാഗിന് പുതിയൊരു പേര് തിരഞ്ഞെടുത്ത് ശ്രമിക്കുക.", "abusefilter-edit-notallowed": "ദുരുപയോഗ അരിപ്പകൾ തിരുത്താനോ സൃഷ്ടിക്കാനോ താങ്കൾക്ക് അനുമതിയില്ല", "abusefilter-edit-notallowed-global": "ആഗോള ദുരുപയോഗ അരിപ്പകൾ നിർമ്മിക്കാൻ അല്ലെങ്കിൽ തിരുത്താൻ താങ്കൾക്ക് അനുവാദമില്ല.", "abusefilter-edit-notallowed-global-custom-msg": "ആഗോള അരിപ്പകൾക്ക് ഐച്ഛിക മുന്നറിയിപ്പ് സന്ദേശങ്ങൾ സാദ്ധ്യമല്ല", + "abusefilter-edit-invalid-warn-message": "മുന്നറിയിപ്പ് സന്ദേശം ശൂന്യമായി ഇടാനാവില്ല.", + "abusefilter-edit-duplicated-throttlegroups": "ത്രോട്ടിൽ സംഘങ്ങൾക്ക് അപരന്മാർ ഉണ്ടാകുവാൻ പാടില്ല.", "abusefilter-edit-builder-select": "കഴ്സറിലേയ്ക്ക് ചേർക്കാനായി ഒരു ഐച്ഛികം തിരഞ്ഞെടുക്കുക", "abusefilter-edit-builder-group-op-arithmetic": "ഗണന ചിഹ്നങ്ങൾ", "abusefilter-edit-builder-op-arithmetic-addition": "സങ്കലനം (+)", @@ -189,8 +228,8 @@ "abusefilter-edit-builder-op-arithmetic-modulo": "ശിഷ്ടം (%)", "abusefilter-edit-builder-op-arithmetic-pow": "വർഗ്ഗപ്പെരുക്കം (**)", "abusefilter-edit-builder-group-op-comparison": "തുലന ചിഹ്നങ്ങൾ", - "abusefilter-edit-builder-op-comparison-equal": "സമമാണ് (==)", - "abusefilter-edit-builder-op-comparison-notequal": "സമമല്ല (!=)", + "abusefilter-edit-builder-op-comparison-equal": "വില സമമാണ് (==)", + "abusefilter-edit-builder-op-comparison-notequal": "വില സമമല്ല (!=)", "abusefilter-edit-builder-op-comparison-lt": "ചെറുതാണ് (<)", "abusefilter-edit-builder-op-comparison-gt": "വലുതാണ് (>)", "abusefilter-edit-builder-op-comparison-lte": "ചെറുതോ സമമോ ആണ് (<=)", @@ -221,7 +260,7 @@ "abusefilter-edit-builder-funcs-rmwhitespace": "ശൂന്യ ഇട നീക്കം ചെയ്യുക (rmwhitespace)", "abusefilter-edit-builder-funcs-rmspecials": "പ്രത്യേക അക്ഷരങ്ങൾ നീക്കംചെയ്യുക (rmspecials)", "abusefilter-edit-builder-funcs-ip_in_range": "ഐ.പി. പരിധിയിലാണോ? (ip_in_range)", - "abusefilter-edit-builder-funcs-contains-any": "വിവിധ ഉപപദങ്ങൾക്ക് വേണ്ടി തിരയാനുള്ള പദം (contains_any)", + "abusefilter-edit-builder-funcs-contains-any": "OR സമ്പ്രദായത്തിൽ വിവിധ ഉപപദങ്ങൾക്ക് വേണ്ടി തിരയാനുള്ള പദം (contains_any)", "abusefilter-edit-builder-funcs-substr": "ഉപപദം (substr)", "abusefilter-edit-builder-funcs-strpos": "പദത്തിൽ ഉപപദത്തിന്റെ സ്ഥാനം (strpos)", "abusefilter-edit-builder-funcs-str_replace": "ഉപപദത്തിനു പകരം പദം ചേർക്കുക (str_replace)", @@ -258,27 +297,30 @@ "abusefilter-edit-builder-vars-user-emailconfirm": "ഇമെയിൽ വിലാസം സ്ഥിരീകരിച്ച സമയം", "abusefilter-edit-builder-vars-recent-contributors": "താളിൽ സേവനങ്ങൾ ചെയ്ത അവസാനത്തെ പത്ത് ഉപയോക്താക്കൾ", "abusefilter-edit-builder-vars-first-contributor": "താളിൽ സംഭാവന ചെയ്ത ആദ്യ ഉപയോക്താവ്", + "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "താൾ മാറ്റുന്നതിനുള്ള സേവനങ്ങൾ ചെയ്ത അവസാനത്തെ പത്ത് ഉപയോക്താക്കൾ", "abusefilter-edit-builder-vars-all-links": "പുതിയ എഴുത്തിലുള്ള പുറത്തേയ്ക്കുള്ള കണ്ണികൾ എല്ലാം", "abusefilter-edit-builder-vars-added-links": "തിരുത്തലിൽ കൂട്ടിച്ചേർക്കപ്പെട്ട പുറത്തേയ്ക്കുള്ള കണ്ണികൾ എല്ലാം", "abusefilter-edit-builder-vars-removed-links": "തിരുത്തലിൽ നീക്കം ചെയ്യപ്പെട്ട പുറത്തേയ്ക്കുള്ള കണ്ണികൾ എല്ലാം", - "abusefilter-edit-builder-vars-old-text": "തിരുത്തലിനു മുമ്പുള്ള, പഴയ താളിലെ വിക്കി എഴുത്ത്", - "abusefilter-edit-builder-vars-new-text": "തിരുത്തലിനു ശേഷമുള്ള, പുതിയ താളിലെ വിക്കി എഴുത്ത്", + "abusefilter-edit-builder-vars-old-wikitext": "തിരുത്തലിനു മുമ്പുള്ള, പഴയ താളിലെ വിക്കി എഴുത്ത് (ഉപയോഗത്തിലില്ല)", + "abusefilter-edit-builder-vars-new-wikitext": "തിരുത്തലിനു ശേഷമുള്ള, പുതിയ താളിലെ വിക്കി എഴുത്ത്", "abusefilter-edit-builder-vars-new-pst": "പുതിയ വിക്കിഎഴുത്ത് താൾ, സേവ് ചെയ്യുന്നതിനു മുമ്പ് തന്നെ മാറ്റിയിരിക്കുന്നു", "abusefilter-edit-builder-vars-diff-pst": "സേവ് നടപ്പിലാകുന്നതിനുമുമ്പേ എടുത്ത, തിരുത്തലിലെ മാറ്റങ്ങളുടെ ആകെ വ്യത്യാസം", "abusefilter-edit-builder-vars-addedlines-pst": "സേവ് നടപ്പിലാകുന്നതിനു മുമ്പേ എടുത്ത, തിരുത്തലിൽ കൂട്ടിച്ചേർക്കപ്പെട്ട വരികൾ", - "abusefilter-edit-builder-vars-new-text-stripped": "പുതിയ താളിലെ, എന്തെങ്കിലും മാർക്കപ്പുകൾ ഉണ്ടെങ്കിൽ അവ നീക്കിയ ശേഷമുള്ള, എഴുത്ത്", + "abusefilter-edit-builder-vars-new-text": "പുതിയ താളിലെ, എന്തെങ്കിലും മാർക്കപ്പുകൾ ഉണ്ടെങ്കിൽ അവ നീക്കിയ ശേഷമുള്ള, എഴുത്ത്", "abusefilter-edit-builder-vars-new-html": "പുതിയ നാൾപ്പതിപ്പിന്റെ എച്ച്.റ്റി.എം.എൽ. ആയി പാഴ്സ് ചെയ്യപ്പെട്ട സ്രോതസ്സ്", "abusefilter-edit-builder-vars-restrictions-edit": "താളിന്റെ സംരക്ഷണ മാനം തിരുത്തുക", "abusefilter-edit-builder-vars-restrictions-move": "താളിന്റെ സംരക്ഷണ മാനത്തിൽ മാറ്റം വരുത്തുക", "abusefilter-edit-builder-vars-restrictions-create": "താളിനുള്ള സംരക്ഷണം സൃഷ്ടിക്കുക", "abusefilter-edit-builder-vars-restrictions-upload": "താളിനുള്ള സംരക്ഷണം അപ്ലോഡ് ചെയ്യുക", - "abusefilter-edit-builder-vars-old-text-stripped": "പഴയ താളിലെ, എന്തെങ്കിലും മാർക്കപ്പുകൾ ഉണ്ടെങ്കിൽ അവ നീക്കിയ ശേഷമുള്ള, എഴുത്ത്", + "abusefilter-edit-builder-vars-old-text": "പഴയ താളിലെ, എന്തെങ്കിലും മാർക്കപ്പുകൾ ഉണ്ടെങ്കിൽ അവ നീക്കിയ ശേഷമുള്ള, എഴുത്ത്", "abusefilter-edit-builder-vars-old-links": "തിരുത്തുന്നതിനു മുമ്പ് താളിലുണ്ടായിരുന്ന കണ്ണികൾ", - "abusefilter-edit-builder-vars-old-html": "എച്ച്.റ്റി.എം.എൽ. ആക്കി പാഴ്സ് ചെയ്യപ്പെട്ട പഴയ താളിലെ വിക്കി എഴുത്തുകൾ", + "abusefilter-edit-builder-vars-old-html": "എച്ച്.റ്റി.എം.എൽ. ആക്കി പാഴ്സ് ചെയ്യപ്പെട്ട പഴയ താളിലെ വിക്കി എഴുത്തുകൾ (ഉപയോഗത്തിലില്ല)", "abusefilter-edit-builder-vars-minor-edit": "തിരുത്തൽ ചെറുതിരുത്തൽ ആയി അടയാളപ്പെടുത്തണോ?", "abusefilter-edit-builder-vars-file-sha1": "പ്രമാണത്തിന്റെ ഉള്ളടക്കത്തിന്റെ SHA1 ഹാഷ്", "abusefilter-edit-builder-vars-file-size": "പ്രമാണത്തിന്റെ വലിപ്പം ബൈറ്റ്സിൽ", - "abusefilter-filter-log": "അരിപ്പ ഉപയോഗിച്ച് ചെയ്ത സമീപകാല മാറ്റങ്ങൾ", + "abusefilter-edit-builder-vars-file-width": "പ്രമാണത്തിന്റെ വീതി പിക്സലിൽ", + "abusefilter-edit-builder-vars-file-height": "പ്രമാണത്തിന്റെ നീളം പിക്സലിൽ", + "abusefilter-filter-log": "അരിപ്പയിലെ സമീപകാല മാറ്റങ്ങൾ", "abusefilter-history": "\"#$1\" ദുരുപയോഗ അരിപ്പയുടെ മാറ്റങ്ങളുടെ ചരിത്രം", "abusefilter-history-foruser": "$1 വരുത്തിയ മാറ്റങ്ങൾ", "abusefilter-history-hidden": "മറയ്ക്കപ്പെട്ടവ", @@ -296,6 +338,7 @@ "abusefilter-history-filterid": "അരിപ്പ", "abusefilter-history-select-legend": "പരിഷ്കരിച്ച തിരച്ചിൽ", "abusefilter-history-select-user": "ഉപയോക്താവ്:", + "abusefilter-history-select-filter": "അരിപ്പയുടെ ഐ.ഡി.:", "abusefilter-history-select-submit": "ശുദ്ധീകരിച്ചെടുക്കുക", "abusefilter-history-diff": "മാറ്റങ്ങൾ", "abusefilter-history-error-hidden": "താങ്കളാവശ്യപ്പെട്ട അരിപ്പ മറയ്ക്കപ്പെട്ടിരിക്കുന്നതിനാൽ, അതിന്റെ നാൾ വഴി താങ്കൾക്ക് ദൃശ്യമല്ല.", @@ -306,13 +349,13 @@ "abusefilter-exception-unclosedstring": "അക്ഷരം $1-ൽ അടയ്ക്കാത്ത പദം ഉണ്ട്.", "abusefilter-exception-invalidoperator": "$1 അക്ഷരത്തിങ്കൽ അസാധുവായ ഓപ്പറേറ്റർ \"$2\".", "abusefilter-exception-unrecognisedtoken": "$1 അക്ഷരത്തിൽ തിരിച്ചറിയപ്പെടാത്ത ചീട്ട് \"$2\".", - "abusefilter-exception-noparams": "\"$2\" എന്ന ഫങ്ഷനിൽ $1 അക്ഷരത്തിങ്കൽ നൽകേണ്ട ചരങ്ങൾ നൽകിയിട്ടില്ല.", + "abusefilter-exception-noparams": "\"$2\" എന്ന ഫങ്ഷനിൽ $1 അക്ഷരത്തിങ്കൽ നൽകേണ്ട ചരങ്ങൾ നൽകിയിട്ടില്ല.{{PLURAL:$3|ഒരു ചരം|$3 ചരങ്ങൾ}} പ്രതീക്ഷിച്ചിരുന്നു.", "abusefilter-exception-dividebyzero": "അക്ഷരം $1-ൽ പൂജ്യം കൊണ്ട് $2-വിനെ ഹരിക്കാനുള്ള ആസാധുവായ ശ്രമം.", "abusefilter-exception-unrecognisedvar": "$1 അക്ഷരത്തിങ്കൽ തിരിച്ചറിയാൻ കഴിയാത്ത ചരം $2", "abusefilter-exception-notenoughargs": "$2 എന്ന ഫങ്ഷനിലെ $1 അക്ഷരത്തിൽ വേണ്ടത്ര ആർഗ്യുമെന്റുകൾ നല്കിയിട്ടില്ല.\n{{PLURAL:$3|ഒരു ആർഗ്യുമെന്റാണ്|$3 ആർഗ്യുമെന്റുകളാണ്}} പ്രതീക്ഷിച്ചതെങ്കിലും $4 എണ്ണമാണ് കിട്ടിയത്.", - "abusefilter-exception-regexfailure": "\"$3\"റെഗുലർ എക്സ്പ്രെഷനിൽ $1 അക്ഷരത്തിങ്കൽ പിഴവുണ്ട്: \"$2\"", + "abusefilter-exception-regexfailure": "$2 റെഗുലർ എക്സ്പ്രെഷനിൽ $1 അക്ഷരത്തിങ്കൽ പിഴവുണ്ട്.", "abusefilter-exception-overridebuiltin": "സ്വതേയുള്ള ചരമായ \"$2\" അക്ഷരം $1-ൽ അനധികൃതമായി അതിലംഘിച്ചിരിക്കുന്നു.", - "abusefilter-exception-outofbounds": "നിലവിലില്ലാത്ത പട്ടികയിലെ ഇനം $2 (പട്ടികയുടെ വലിപ്പം =$3) അക്ഷരം $1-ൽ ആവശ്യപ്പെട്ടിരിക്കുന്നു.", + "abusefilter-exception-outofbounds": "നിലവിലില്ലാത്ത പട്ടികയിലെ ഇനം $2 (പട്ടികയുടെ വലിപ്പം = $3) അക്ഷരം $1-ൽ ആവശ്യപ്പെടുന്നു.", "abusefilter-action-tag": "റ്റാഗ്", "abusefilter-action-throttle": "ത്വരണി", "abusefilter-action-warn": "മുന്നറിയിപ്പ് നൽകുക", @@ -323,13 +366,14 @@ "abusefilter-action-disallow": "അനുവദിക്കാതിരിക്കൽ", "abusefilter-revert-title": "$1 അരിപ്പ ചെയ്ത എല്ലാ മാറ്റങ്ങളും തിരസ്കരിക്കുക", "abusefilter-revert-intro": "അരിപ്പ $1 മൂലം ദുരുപയോഗ അരിപ്പ ചെയ്ത എല്ലാ തിരുത്തലുകളും ഈ ഫോം ഉപയോഗിച്ച് താങ്കൾക്ക് മുൻപ്രാപനം ചെയ്യാൻ കഴിയുന്നതാണ്.\nഈ ഉപകരണം ഉപയോഗിക്കുമ്പോൾ ദയവായി ശ്രദ്ധ പുലർത്തുക.", - "abusefilter-revert-preview-item": "$1: $4-ൽ $2 ഒരു $3 ചെയ്തിരിക്കുന്നു.\nമുൻപ്രാപനം ചെയ്യേണ്ടുന്ന പ്രവൃത്തികൾ: $5 ($6)", + "abusefilter-revert-preview-item": "$1: $4 താളിൽ $2 ഒരു $3 {{GENDER:$7|ചെയ്തു}}.\nതിരിച്ചാക്കേണ്ട പ്രവൃത്തികൾ: $5 ($6)", "abusefilter-revert-search-legend": "ദുരുപയോഗ അരിപ്പയുടെ പ്രവൃത്തികളിൽ തിരസ്കരിക്കപ്പെടേണ്ടവ തിരഞ്ഞെടുക്കുക", "abusefilter-revert-periodstart": "സമയാരംഭം:", "abusefilter-revert-periodend": "സമയാവസാനം:", "abusefilter-revert-search": "പ്രവൃത്തികൾ തിരഞ്ഞെടുക്കുക", - "abusefilter-revert-filter": "അരിപ്പ:", + "abusefilter-revert-filter": "അരിപ്പയുടെ ഐ.ഡി.:", "abusefilter-revert-preview-intro": "ഈ പ്രവൃത്തി ചെയ്താൽ മുൻപ്രാപനം ചെയ്യപ്പെടുന്ന പ്രവൃത്തികൾ താഴെ കൊടുത്തിരിക്കുന്നു.\nദയവായി അവ ശ്രദ്ധയോടെ പരിശോധിക്കുക, താങ്കൾ തിരഞ്ഞെടുത്തവ സ്ഥിരീകരിക്കാനായി \"{{int:abusefilter-revert-confirm}}\" ഞെക്കുക.", + "abusefilter-revert-confirm-legend": "തിരിച്ചാക്കൽ സ്ഥിരീകരിക്കുക", "abusefilter-revert-confirm": "സ്ഥിരീകരിക്കുക", "abusefilter-revert-success": "[[Special:AbuseFilter/$1|അരിപ്പ $2]] ഉപയോഗിച്ച് ദുരുപയോഗ അരിപ്പ ചെയ്ത എല്ലാ പ്രവൃത്തികളും മുന്നവസ്ഥയിലേയ്ക്ക് മാറ്റിയിരിക്കുന്നു.", "abusefilter-revert-reason": "അരിപ്പ $1 ഉപയോഗിച്ച് ദുരുപയോഗ അരിപ്പ ചെയ്ത എല്ലാ പ്രവൃത്തികളും സ്വയം മുൻപ്രാപനം ചെയ്യുന്നു.\nതന്നിരിക്കുന്ന കാരണം:$2", @@ -341,12 +385,20 @@ "abusefilter-test-submit": "പരീക്ഷിയ്ക്കുക", "abusefilter-test-load": "ശേഖരിക്കുക", "abusefilter-test-user": "ഉപയോക്താവ് വരുത്തിയ മാറ്റങ്ങൾ:", + "abusefilter-test-nobots": "യാന്ത്രിക തിരുത്തുകൾ മറയ്ക്കുക", "abusefilter-test-period-start": "പിന്നീട് വരുത്തിയ മാറ്റങ്ങൾ:", "abusefilter-test-period-end": "മുമ്പ് വരുത്തിയ മാറ്റങ്ങൾ:", "abusefilter-test-page": "താളിൽ വരുത്തിയ മാറ്റങ്ങൾ:", "abusefilter-test-shownegative": "അരിപ്പയുമായി യോജിക്കാത്ത മാറ്റങ്ങൾ പ്രദർശിപ്പിക്കുക", "abusefilter-test-syntaxerr": "താങ്കൾ നൽകിയ അരിപ്പയുടെ എഴുത്തുരീതിയിൽ പിശകുണ്ട്.\n\"{{int:abusefilter-edit-check}}\" എന്ന ബട്ടൺ ഞെക്കിയാൽ താങ്കൾക്ക് പൂർണ്ണമായ വിശദീകരണം ലഭിക്കുന്നതാണ്.", "abusefilter-test-badtitle": "താങ്കൾ നൽകിയ താളിന്റെ തലക്കെട്ട് അസാധുവാണ്. തലക്കെട്ടിൽ ഉപയോഗിക്കാൻ പാടില്ലാത്ത ഒന്നോ അതിലധികമോ അക്ഷരങ്ങൾ അതിലുണ്ട്.", + "abusefilter-test-action": "പ്രവൃത്തിയുടെ തരം:", + "abusefilter-test-search-type-all": "എല്ലാ പ്രവൃത്തികളും", + "abusefilter-test-search-type-edit": "തിരുത്തുകൾ", + "abusefilter-test-search-type-move": "തലക്കെട്ട് മാറ്റലുകൾ", + "abusefilter-test-search-type-delete": "മായ്ക്കലുകൾ", + "abusefilter-test-search-type-upload": "അപ്ലോഡുകൾ", + "abusefilter-test-search-type-createaccount": "അംഗത്വ സൃഷ്ടികൾ", "abusefilter-changeslist-examine": "പരിശോധിക്കുക", "abusefilter-examine": "ഒറ്റയൊറ്റ മാറ്റങ്ങൾ പരിശോധിക്കുക", "abusefilter-examine-intro": "ഓരോ ഒറ്റയൊറ്റ മാറ്റത്തിനും ദുരുപയോഗ അരിപ്പ സൃഷ്ടിക്കുന്ന ചരങ്ങൾ പരിശോധിക്കാൻ ഈ താൾ താങ്കളെ അനുവദിക്കുന്നു, ഒപ്പം അത് അരിപ്പകളിൽ പരീക്ഷിക്കാവുന്നതുമാണ്.", @@ -366,13 +418,15 @@ "abusefilter-examine-noresults": "താങ്കൾ നൽകിയവയ്ക്കുള്ള തിരച്ചിലുകൾ യാതൊരു ഫലവും നൽകിയില്ല.", "abusefilter-topnav": "'''ദുരുപയോഗ അരിപ്പയ്ക്കുള്ള വഴികാട്ടി'''", "abusefilter-topnav-home": "പ്രധാനം", + "abusefilter-topnav-recentchanges": "അരിപ്പയിലെ സമീപകാല മാറ്റങ്ങൾ", "abusefilter-topnav-test": "ഗണം പരീക്ഷിക്കൽ", "abusefilter-topnav-examine": "പഴയ തിരുത്തുകൾ പരിശോധിക്കുക", "abusefilter-topnav-log": "ദുരുപയോഗ രേഖ", "abusefilter-topnav-tools": "പ്രശ്നപരിഹാര ഉപകരണങ്ങൾ", - "abusefilter-topnav-import": "അരിപ്പ ഇറക്കുമതി ചെയ്യുക", "abusefilter-log-name": "ദുരുപയോഗ അരിപ്പയുടെ ഉപയോഗ രേഖ", "abusefilter-log-header": "അരിപ്പകളിൽ വരുത്തിയ മാറ്റങ്ങളുടെ ചുരുക്കം ഈ രേഖയിൽ കാണാവുന്നതാണ്.\nപൂർണ്ണ വിവരങ്ങൾക്ക്, അരിപ്പകളിലെ സമീപകാലമാറ്റങ്ങളുടെ [[Special:AbuseFilter/history|പട്ടിക]] കാണുക.", + "abusefilter-logentry-create": "$4 ($5), $1 {{GENDER:$2|സൃഷ്ടിച്ചു}}", + "abusefilter-logentry-modify": "$4 ($5), $1 {{GENDER:$2|പുതുക്കി}}", "abusefilter-log-noresults": "ഫലങ്ങൾ ഒന്നുമില്ല", "abusefilter-diff-title": "പതിപ്പുകൾ തമ്മിലുള്ള വ്യത്യാസങ്ങൾ", "abusefilter-diff-item": "ഇനം", @@ -386,5 +440,11 @@ "abusefilter-import-intro": "മറ്റുവിക്കികളിൽ നിന്ന് അരിപ്പകൾ ഇറക്കുമതി ചെയ്യാൻ ഈ ദൃശ്യമണ്ഡലം ഉപയോഗിക്കാവുന്നതാണ്.\nസ്രോതസ്സ് വിക്കിയിലെ തിരുത്തുവാനുള്ള ദൃശ്യമണ്ഡലത്തിൽ \"{{int:abusefilter-edit-tools}}\" എന്നതിനു താഴെയുള്ള \"{{int:abusefilter-edit-export}}\" ഞെക്കുക.\nഅപ്പോൾ കിട്ടുന്ന ടെക്സ്റ്റ്ബോക്സ് പകർത്തി ഈ ടെക്സ്റ്റ്ബോക്സിൽ നൽകി, \"{{int:abusefilter-import-submit}}\" ഞെക്കുക.", "abusefilter-import-submit": "വിവരങ്ങൾ ഇറക്കുമതി ചെയ്യുക", "abusefilter-group-default": "സ്വതേ", - "abusefilter-http-error": "ഒരു എച്ച്.റ്റി.റ്റി.പി. പിഴവ് സംഭവിച്ചിരിക്കുന്നു: $1" + "abusefilter-http-error": "ഒരു എച്ച്.റ്റി.റ്റി.പി. പിഴവ് സംഭവിച്ചിരിക്കുന്നു: $1", + "abusefilter-view-privatedetails-submit": "സ്വകാര്യ വിശദാംശങ്ങൾ കാണുക", + "abusefilter-view-privatedetails-legend": "സ്വകാര്യ വിശദാംശങ്ങൾ കാണുക", + "abusefilter-view-privatedetails-reason": "സ്വകാര്യ വിശദാംശങ്ങൾ എടുത്തുനോക്കുന്നതിനുള്ള കാരണം:", + "abusefilter-log-details-id": "രേഖയുടെ ഐ.ഡി.", + "abusefilter-log-ip-not-available": "ലഭ്യമല്ല", + "tag-abusefilter-condition-limit": "നിബന്ധനകളുടെ പരിധി എത്തിയിരിക്കുന്നു" } diff --git a/AbuseFilter/i18n/mn.json b/AbuseFilter/i18n/mn.json index 390219a8..47047c35 100644 --- a/AbuseFilter/i18n/mn.json +++ b/AbuseFilter/i18n/mn.json @@ -6,8 +6,6 @@ "Wisdom" ] }, - "abusefilter": "Доромжлол шүүх тохиргоо", - "abuselog": "Доромж хийгдсэн лог", "abusefilter-intro": "Та доромжлолоос сэргийлэх шүүлтүүрийн системд холбогдсон байна.\nУг шүүлтүүр нь автоматаар тохиолдол бүрт өөрчлөлт хийх байдлаар ажиллана.\nЭнд хийгдсэн шүүлтүүрүүдийг жагсаан харуулж тэдгээрийг өөрчилж болно.", "abusefilter-blocker": "Доромжлол шүүгч", "right-abusefilter-modify": "Доромжлол шүүгчид өөрчлөлт хийх", diff --git a/AbuseFilter/i18n/mr.json b/AbuseFilter/i18n/mr.json index 8368a21c..485b7537 100644 --- a/AbuseFilter/i18n/mr.json +++ b/AbuseFilter/i18n/mr.json @@ -4,25 +4,26 @@ "BPositive", "Htt", "Mahitgar", - "Shantanoo", - "V.narsikar", - "Ydyashad", - "संतोष दहिवळ", "Matma Rex", "Pushkar Ekbote", + "Shantanoo", "Sureshkhole", - "Susheelkasab" + "Susheelkasab", + "V.narsikar", + "Ydyashad", + "ज्ञानदा गद्रे-फडके", + "संतोष दहिवळ" ] }, "abusefilter-desc": "संपादन गाळणी सर्व संपादनांचा सांगितल्याप्रमाणे स्वयंशोध घेते.", "abusefilter": "संपादन गाळणी व्यवस्थापन", - "abuselog": "गैरवापर नोंदी", + "abuselog": "गाळणीने टिपलेल्या नोंदी", "abusefilter-intro": "संपादन गाळणी व्यवस्थापन प्रणालीत आपले स्वागत आहे.\n\nसंपादन गाळणी म्हणजे सर्व संपादनांचा सांगितल्याप्रमाणे स्वयंशोध घेणारी स्वयंचलित सॉफ्टवेअर प्रणाली असते. हा इंटरफेस तयार केलेल्या गाळण्यांची यादी दाखवतो आणि त्यात सुधारणा करण्यास अनुमती देतो.", "abusefilter-warning": "'''सूचना''': आपण करू इच्छित असलेली कृती/लेखन/संपादन अभिप्रेत संकेतास अनुसरून नसावी / अयोग्य असावी अथवा साशंकीत म्हणून स्वयमेव संपादन गाळणीकडून नोंदवली जात आहे.\nआपले संपादन जतन (सेव्ह) करण्यापूर्वी आपण करू इच्छित असलेली कृती/लेखन/संपादन रचनात्मक आहे याची खात्री करून घ्यावी.अरचनात्मक संपादने तात्काळ उलटवली जाण्याची किंवा त्यापेक्षा अधिक प्रतिबंधनांची शक्यता असते.\nआपणास हे संपादन सुयोग्य असल्याची खात्री असेल तर आपण ते नक्की करण्यासाठी ”पुन्हा सोपवा’ वर टिचकी मारू शकता.आपल्या क्रियेशी संलग्न, या गाळणीस लागू असलेल्या नियमाचे थोडक्यात वर्णन आहे:$1", "abusefilter-disallowed": "आपण नुकतीच केलेली क्रिया/लेखन/संपादन अभिप्रेत संकेतास अनुसरून नसावी / 'अयोग्य' असावी अथवा 'साशंकीत’ म्हणून स्वयमेव ज्ञात झाली आहे, आणि नामंजूर करण्यात आलेली आहे.आपली क्रिया रचनात्मक असल्याचे जर आपणास वाटत असेल तर,कृपया ,आपण नेमके काय करू इच्छित होता/प्रयत्न करत होता याची माहिती, संपादन गाळणीच्या अनपेक्षीत क्रिया विषयक चर्चा पानावर प्रचालकांना द्या. आपल्या क्रियेशी संलग्न, या गाळणीस लागू असलेल्या नियमाचे थोडक्यात वर्णन आहे:$1", "abusefilter-blocked-display": "आपण नुकतीच केलेली क्रिया ही ’अभिप्रेत संकेतास अनुसरून नसलेली' / 'अयोग्य' असल्याची नोंद संपादन गाळणीने स्वयमेव केली आहे, व म्हणून ती क्रिया करण्यास आपणास रोधित करण्यात आलेले आहे.{{SITENAME}} सुरक्षित ठेवण्यासाठी,आपले सदस्यखाते व अंकपत्ता संपादनांसाठी अवरुद्ध करण्यात आलेला आहे.जर हे चुकीने घडले असल्यास संपादन गाळणी चर्चा पानावर प्रचालकाशी कृपया संपर्क साधा.आपल्या क्रियेशी संलग्न, या गाळणीस लागू असलेल्या नियमाचे थोडक्यात वर्णन आहे:$1", - "abusefilter-degrouped": "ही क्रिया हानीकारक म्हणुन स्वयंचलीतरित्या निवडल्या गेली आहे.म्हणुन तीस परवानगी नाकारण्यात येते, व,आपले खात्याबद्दल रदबदली केल्या गेल्याच्या शंकेमुळे आपले सर्व अधिकार रद्द करण्यात आलेले आलेले आहेत. आपणास जर खात्री आहे कि हे चुकीमुळे झालेले आहे तर या क्रियेच्या स्पष्टीकरणासह प्रशासकाशी कृपया संपर्क साधा ,त्यामुळे आपले अधिकार आपणास पुनर्प्राप्त होतील.आपल्या क्रियेशी जुळणा-या दुरुपयोग नियमाचे थोडक्यात वर्णन आहे :$1", - "abusefilter-autopromote-blocked": "\nही क्रिया हानीकारक म्हणुन स्वयंचलीतरित्या निवडल्या गेली आहे.म्हणुन तीस परवानगी नाकारण्यात येते.याव्यतिरिक्त,सुरक्षिततेचे उपाय म्हणुन,खाते सुरू ठेवण्यासाठी देण्यात आलेल्या काही नित्याच्या सोयी आपल्या खात्यातुन रद्द करण्यात आलेल्या आहेत.\nआपल्या क्रियेबाबत जुळणा-या दुरुपयोग नियमाचे थोडक्यात वर्णन आहे :$1", + "abusefilter-degrouped": "ही क्रिया हानीकारक म्हणून स्वयंचलीतरित्या निवडली गेली आहे.म्हणून तिला परवानगी नाकारण्यात येते.व आपल्या खात्याबद्दल रदबदली केली गेल्याच्या शंकेमुळे आपले सर्व अधिकार रद्द करण्यात आलेले आलेले आहेत. आपणास जर हे चुकीमुळे झाल्याची खात्री असेल तर या क्रियेच्या स्पष्टीकरणासह प्रचालकाशी कृपया संपर्क साधा, त्यामुळे आपले अधिकार आपणास पुनर्प्राप्त होतील.आपल्या क्रियेशी जुळणा-या दुरुपयोग नियमाचे थोडक्यात वर्णन आहे :$1", + "abusefilter-autopromote-blocked": "\nही क्रिया हानीकारक म्हणून स्वयंचलीतरित्या निवडली गेली आहे.म्हणून तिला परवानगी नाकारण्यात येते.याव्यतिरिक्त,सुरक्षिततेचे उपाय म्हणून,खाते सुरू ठेवण्यासाठी देण्यात आलेल्या काही नित्याच्या सोयी आपल्या खात्यातून रद्द करण्यात आलेल्या आहेत.\nआपल्या क्रियेबाबत जुळणा-या दुरुपयोग नियमाचे थोडक्यात वर्णन आहे :$1", "abusefilter-blocker": "संपादन गाळणी", "abusefilter-blockreason": "संपादन गाळणीने आपोआप अवरुद्ध केले.\nसंलग्न नियमाचे वर्णन:$1", "abusefilter-degroupreason": "संपादन गाळणीने आपोआप अधिकार काढले.\nनियमाचे वर्णन:$1", @@ -31,7 +32,7 @@ "right-abusefilter-view": "संपादन गाळण्या बघा", "right-abusefilter-log": "संपादन गाळणीच्या नोंदी बघा", "right-abusefilter-log-detail": "संपादन गाळणी क्रमलेखाच्या विस्तृत नोंदी बघा", - "right-abusefilter-private": "दुरुपयोग नोंदवहीतील जमा केलेली वैयक्तिक माहिती बघा.", + "right-abusefilter-privatedetails": "दुरुपयोग नोंदवहीतील जमा केलेली वैयक्तिक माहिती बघा.", "right-abusefilter-modify-restricted": "सीमित क्रियेसह दुरुपयोग गाळणीस बदलवा", "right-abusefilter-revert": "दिलेल्या दुरुपयोग गाळणीने केलेले सर्व बदल पूर्वपदास न्या.", "right-abusefilter-view-private": "खाजगी म्हणून खूण केलेल्या संपादन गाळण्या बघा.", @@ -43,11 +44,10 @@ "action-abusefilter-view": "संपादन गाळणी पहा", "action-abusefilter-log": "संपादन गाळणीने टिपलेल्या नोंदी पहा", "action-abusefilter-log-detail": "संपादन गाळणीने टिपलेल्या सविस्तर नोंदी पहा", - "action-abusefilter-private": "संपादन गाळणी नोंदी मधील खाजगी विदा पहा", + "action-abusefilter-privatedetails": "संपादन गाळणी नोंदी मधील खाजगी विदा पहा", "action-abusefilter-modify-restricted": "सीमित क्रियेसह संपादन गाळणीस बदलवा.", "action-abusefilter-revert": "येथे दिलेल्या संपादन गाळणीने केलेले सर्व बदल पूर्वपदास न्या.", "action-abusefilter-view-private": "खासगी म्हणुन नोंदविलेल्या संपादन गाळण्या बघा.", - "abusefilter-log": "गाळणीने टिपलेल्या नोंदी", "abusefilter-log-summary": "ही नोंदवही गाळण्यांद्वारे पकडलेल्या सर्व क्रियांची यादी दाखविते.", "abusefilter-log-search": "गाळणी नोंदी शोधा", "abusefilter-log-search-user": "सदस्य:", @@ -73,13 +73,12 @@ "abusefilter-log-details-var": "चल (व्हॅरिएबल)", "abusefilter-log-details-val": "किंमत (व्हॅल्यू)", "abusefilter-log-details-vars": "कार्य प्राचल", - "abusefilter-log-details-private": "खाजगी मजकूर", + "abusefilter-log-details-privatedetails": "खाजगी मजकूर", "abusefilter-log-details-ip": "ज्या मुळ अंकपत्त्याहून", "abusefilter-log-noactions": "काहीही नाही", "abusefilter-log-details-diff": "संपादनात केलेले बदल", "abusefilter-log-linkoncontribs": "संपादन गाळणी नोंदी", "abusefilter-log-linkoncontribs-text": "गाळणीने टिपलेल्या या सदस्याच्या नोंदी", - "abusefilter-log-hidden": "(प्रविष्टी लपविलेली आहे)", "abusefilter-log-hidden-implicit": "(लपविलेली, कारण संस्करण वगळण्यात आले आहे)", "abusefilter-log-cannot-see-details": "या नोंदीचा तपशिल बघण्यास आपणास परवानगी नाही.", "abusefilter-log-details-hidden": "या नोंदीचा तपशिल आपण बघु शकत नाही कारण तिची सार्वजनिक दृष्यता लपविलेली आहे.", @@ -90,7 +89,6 @@ "abusefilter-log-hide-reason": "कारण:", "abusefilter-log-hide-forbidden": "आपणास दुरुपयोग गाळणीच्या नोंदवहीतील नोंदी लपविण्याची परवानगी नाही.", "logentry-abusefilter-hit": "$3 वर \"$5\" ही क्रिया करून $1 ने $4 ला चेतविले.पुढील कार्यवाही केली: $6 ($7)", - "abusefilter-management": "संपादन गाळणी व्यवस्थापन", "abusefilter-list": "सर्व गाळण्या", "abusefilter-list-id": "गाळणी क्रमांक", "abusefilter-list-status": "स्थिती", @@ -110,6 +108,7 @@ "abusefilter-disabled": "अकार्यान्वित", "abusefilter-hitcount": "$1 {{PLURAL:$1|झेल}}", "abusefilter-new": "नवीन संपादन गाळणी बनवा", + "abusefilter-import-button": "संपादन गाळणी आयात करा", "abusefilter-return": "संपादन गाळकाकडे वापस", "abusefilter-status-global": "वैश्विक", "abusefilter-list-options": "पर्याय", @@ -139,7 +138,6 @@ "abusefilter-edit-oldwarning": "<strong> आपण या गाळणीची जुनी आवृत्ती संपादित करीत आहात.\nयेथे नमूद केलेली सांख्यिकी, ही या गाळणीच्या विद्यमान आवृत्तीची आहे.जर आपण आपले बदल जतन केलेत, तर, आपण संपादन करीत असलेल्या आवृत्तीपासून आजतागायतच्या बदलांवर आपण पुनर्लेखन(ओव्हरराईट) कराल</strong> •[[Special:AbuseFilter/history/$2|या गाळणीचा इतिहास तपासुन निर्णय घ्या]].", "abusefilter-edit-status-label": "सांख्यिकी:", "abusefilter-edit-status": "मागील $1 या {{PLURAL:$1|क्रियेपैकी|क्रियांपैकी}},या गाळणीशी, $2 ($3%)अनुरुपन (मॅच) झाल्या आहेत.", - "abusefilter-edit-status-profile": "मागील $1 या {{PLURAL:$1|क्रियेपैकी|क्रियांपैकी}},या गाळणीशी, $2 ($3%)अनुरुपन (मॅच) झाल्या आहेत. सरासरीने,त्याचा कार्यावधी $4 मिली सेकंद आहे व अटमर्यादेपैकी त्याने $5 {{PLURAL:$5|अटीची|अटींची}} खानापूर्ती केली आहे.", "abusefilter-edit-new": "नवीन संपादन गाळणी", "abusefilter-edit-save": "संपादन गाळणी जतन करा", "abusefilter-edit-id": "गाळणी क्रमांक", @@ -156,13 +154,13 @@ "abusefilter-edit-lastmod-text": "$1 द्वारा $2", "abusefilter-edit-hitcount": "गाळणीने पेललेले झेल", "abusefilter-edit-consequences": "अनुरुपन (मॅच) झाल्यावर करावयाची कार्यवाही", - "abusefilter-edit-action-warn": "सदस्यास पुर्व/सजगता सूचना देउन या क्रिया उद्युक्त करा", + "abusefilter-edit-action-warn": "सदस्यास पूर्व/सजगता सूचना देऊन या क्रिया उद्युक्त करा", "abusefilter-edit-action-disallow": "प्रश्नांकित कृती करण्यापासून, उपयोगकर्त्यास थांबवा", "abusefilter-edit-action-blockautopromote": "सदस्याची स्वयंशाबीत(ऑटोकन्फर्म) स्थिती रद्द करा.", "abusefilter-edit-action-degroup": "सदस्यास सर्व सवलत-गटांमधून हटवा", "abusefilter-edit-action-block": "सदस्य व/किंवा त्याचा अंकपत्ता संपादनास प्रतिबंधित करा.", - "abusefilter-edit-action-blocktalk": "स्वत:चे बोलपृष्ठ अद्यन्वित करण्यापासून वापरकर्त्याला / आयपी अड्रेसला परावृत्त करा.", - "abusefilter-edit-action-throttle": "केवळ विशीष्ट 'दर मर्यादा'(रेट लिमीट) ओलांडल्यासच, कृती करा", + "abusefilter-edit-action-blocktalk": "स्वत:चे चर्चा पान अद्यतनीत करण्यापासून वापरकर्त्याला / आयपी अॅड्रेसला परावृत्त करा.", + "abusefilter-edit-action-throttle": "केवळ विशिष्ट दर मर्यादा'(रेट लिमीट) ओलांडल्यासच, कृती करा", "abusefilter-edit-action-rangeblock": "सदस्याचा जेथून उद्गम आहे, ती /16 रेंज प्रतिबंधित करा", "abusefilter-edit-action-tag": "संपादनास, पुढील समीक्षणाकरता खूण करा", "abusefilter-edit-throttle-count": "परवानगी द्यायच्या क्रियांची संख्या:", @@ -183,7 +181,7 @@ "abusefilter-edit-viewhistory": "या गाळणीचा इतिहास पहा", "abusefilter-edit-history": "इतिहास:", "abusefilter-edit-check": "वाक्यविन्यास (सिंटॅक्स) तपासा", - "abusefilter-edit-badfilter": "आपण नमूद केलेली गाळणी अस्तीत्वात नाही", + "abusefilter-edit-badfilter": "आपण नमूद केलेली गाळणी अस्तित्वात नाही", "abusefilter-edit-revert": "गाळणीने केलेली कार्यवाही परत फिरवा(उलटवा)", "abusefilter-edit-tools": "साधने:", "abusefilter-edit-test-link": "ही गाळणी अलिकडील बदलांसोबत तपासा", @@ -235,7 +233,7 @@ "abusefilter-edit-builder-vars-action": "कृती", "abusefilter-edit-builder-vars-addedlines": "संपादनात जोडलेल्या ओळींचे क्षेत्र", "abusefilter-edit-builder-vars-delta": "संपादनातील आकार बदल", - "abusefilter-edit-builder-vars-diff": "संपादन बदलाने झालेला एकुण फरक", + "abusefilter-edit-builder-vars-diff": "संपादन बदलाने झालेला एकूण फरक", "abusefilter-edit-builder-vars-newsize": "नवीन पानाचा आकार", "abusefilter-edit-builder-vars-oldsize": "पानाचा जुना आकार", "abusefilter-edit-builder-vars-removedlines": "संपादनात वगळलेल्या ओळींचे क्षेत्र", @@ -263,13 +261,13 @@ "abusefilter-edit-builder-vars-all-links": "नवीन मजकुरातील सर्व बाह्यदुवे", "abusefilter-edit-builder-vars-added-links": "संपादनात जोडलेले सर्व बाह्यदुवे", "abusefilter-edit-builder-vars-removed-links": "संपादनातून वगळलेले सर्व बाह्यदुवे", - "abusefilter-edit-builder-vars-old-text": "पानातील, संपादनपूर्व स्थितीतील,मागील विकिमजकुर", - "abusefilter-edit-builder-vars-new-text": "संपादनानंतरचा,नवा पृष्ठ मजकुर", + "abusefilter-edit-builder-vars-old-wikitext": "पानातील, संपादनपूर्व स्थितीतील,मागील विकिमजकुर", + "abusefilter-edit-builder-vars-new-wikitext": "संपादनानंतरचा,नवा पृष्ठ मजकुर", "abusefilter-edit-builder-vars-restrictions-edit": "पानाचा संपादन सुरक्षास्तर", "abusefilter-edit-builder-vars-restrictions-move": "या पानाची सुरक्षा पातळी हलवा", "abusefilter-edit-builder-vars-restrictions-create": "या पानास सुरक्षित करा", "abusefilter-edit-builder-vars-restrictions-upload": "संचिकेच्या सुरक्षेचे अपभारण करा", - "abusefilter-edit-builder-vars-old-links": "संपादना पुर्वीचे ,पानातील दुवे", + "abusefilter-edit-builder-vars-old-links": "संपादनापूर्वीचे, पानातील दुवे", "abusefilter-edit-builder-vars-minor-edit": "संपादनातील बदल छोटा म्हणून दर्शविला जातो आहे अथवा नाही", "abusefilter-edit-builder-vars-file-sha1": "संचिका मजकुराचा SHA1 hash", "abusefilter-edit-builder-vars-file-size": "संचिकेचा आकार बाईटमध्ये", @@ -307,10 +305,10 @@ "abusefilter-exception-overridebuiltin": "$1 वर्णावर अनुबंधित चलांची अवैध चढाई \"$2\".", "abusefilter-action-tag": "खूणपताका", "abusefilter-action-throttle": "प्ररोध (थ्रॉटल)", - "abusefilter-action-warn": "सूचीत करा", + "abusefilter-action-warn": "सूचित करा", "abusefilter-action-block": "प्रतिबंधित करा", "abusefilter-action-degroup": "गटांमधून वगळा", - "abusefilter-action-disallow": "नामंजुर", + "abusefilter-action-disallow": "नामंजूर", "abusefilter-revert-title": "गाळणी $1 ने केलेले सर्व बदल उलटवा", "abusefilter-revert-intro": "हे आवेदन दुरुपयोग गाळणीच्या, गाळणी $1 ने केलेले सर्व बदल उलटविण्यास मदत करते.\nहे साधन वापरतांना कृपया खबरदारी बाळगा.", "abusefilter-revert-preview-item": "$1: $2 ने $4 वर $3 केले .\nउलवटण्यासाठीची क्रिया: $5 ($6)", @@ -359,7 +357,6 @@ "abusefilter-topnav-examine": "मागील संपादने तपासा", "abusefilter-topnav-log": "संपादन गाळणीने टिपलेल्या नोंदी", "abusefilter-topnav-tools": "गणकदोष निवारक साधने", - "abusefilter-topnav-import": "संपादन गाळणी आयात करा", "abusefilter-log-name": "गाळणीने टिपलेल्या नोंदी", "abusefilter-log-header": "हा क्रमालेख संपादन गाळण्यात केलेल्या बदलांचे संक्षिप्त विवरण दाखवतो.\nपूर्ण विवरणा करिता ,संपादन गाळण्यांमधील अलिकडील बदलांची [[Special:AbuseFilter/history| हि यादी]] पाहा.", "abusefilter-log-noresults": "निकाल नाहीत", @@ -371,7 +368,7 @@ "abusefilter-diff-invalid": "विनंती केलेल्या आवृत्त्या शेंदण्यात असफल", "abusefilter-diff-backhistory": "गाळणी इतिहासाकडे परत", "abusefilter-diff-prev": "जुने बदल", - "abusefilter-diff-next": "नविनतम बदल", + "abusefilter-diff-next": "नवीनतम बदल", "abusefilter-import-submit": "विदा(डाटा) आयात", "abusefilter-group-default": "अविचल (डिफॉल्ट)" } diff --git a/AbuseFilter/i18n/ms.json b/AbuseFilter/i18n/ms.json index 9b69cb27..c489949f 100644 --- a/AbuseFilter/i18n/ms.json +++ b/AbuseFilter/i18n/ms.json @@ -6,15 +6,16 @@ "Aviator", "Diagramma Della Verita", "Izzudin", + "Jeluang Terluang", "Kurniasan", - "Zamwan", "Matma Rex", - "Jeluang Terluang" + "Tofeiku", + "Zamwan" ] }, "abusefilter-desc": "Mengenakan heuristik automatik pada suntingan.", - "abusefilter": "Tatarajah penapis salah guna", - "abuselog": "Log penyalahgunaan", + "abusefilter": "Pengurusan penapis salah guna", + "abuselog": "Log penapis salah guna", "abusefilter-intro": "Selamat datang ke antara muka pengurusan Penapis Salah Guna.\nAbuse Filter ialah mekanisme perisian automatik untuk mengenakan swakaji automatik kepada semua tindakan.\nAntara muka ini menunjukkan senarai penapis yang ditakrif, dan membenarkan mereka diubahsuai.", "abusefilter-warning": "'''Amaran''': Tindakan ini telah dikenalpasti secara automatik sebagai berbahaya.\nSuntingan yang tidak membina akan dibalikkan dengan segera, dan suntingan tidak membina yang berat atau berulang-ulang akan menyebabkan akaun atau alamat IP anda disekat.\nJika anda percaya bahawa tindakan ini membina, sila tekan Simpan sekali lagi untuk mengesahkankannya.\nPenerangan ringkas tentang peraturan penyalahgunaan yang sepadan dengan tindakan anda ialah: $1", "abusefilter-disallowed": "Tindakan ini telah dikenalpasti secara automatik sebagai berbahaya, dan oleh itu tidak dibenarkan.\nJika anda percaya bahawa tindakan anda itu membina, sila hubungi penyelia dan beritahu mereka mengenai perkara yang anda cuba lakukan.\nSatu penerangan ringkas tentang peraturan penyalahgunaan yang sepadan dengan tindakan anda ialah: $1", @@ -29,7 +30,7 @@ "right-abusefilter-view": "Melihat penapis salah guna", "right-abusefilter-log": "Melihat log penyalahgunaan", "right-abusefilter-log-detail": "Melihat entri lanjut log penyalahgunaan", - "right-abusefilter-private": "Melihat data rahsia dalam log penyalahgunaan", + "right-abusefilter-privatedetails": "Melihat data rahsia dalam log penyalahgunaan", "right-abusefilter-modify-restricted": "Mengubah suai penapis salah guna dengan tindakan-tindakan terhad", "right-abusefilter-revert": "Membalikkan semua perubahan oleh penapis salah guna tertentu", "right-abusefilter-view-private": "Melihat penapis salah guna yang ditanda rahsia", @@ -41,17 +42,18 @@ "action-abusefilter-view": "melihat penapis salah guna", "action-abusefilter-log": "melihat log penyalahgunaan", "action-abusefilter-log-detail": "melihat entri lanjut log penyalahgunaan", - "action-abusefilter-private": "melihat data rahsia dalam log penyalahgunaan", + "action-abusefilter-privatedetails": "melihat data rahsia dalam log penyalahgunaan", "action-abusefilter-modify-restricted": "mengubah suai penapis salah guna dengan tindakan-tindakan terhad", "action-abusefilter-revert": "membalikkan semua perubahan oleh penapis salah guna tertentu", "action-abusefilter-view-private": "melihat penapis salah guna yang ditanda rahsia", - "abusefilter-log": "Log penapis salah guna", "abusefilter-log-summary": "Log ini menunjukkan senarai bagi semua tindakan yang ditangkap oleh penapis.", "abusefilter-log-search": "Cari dalam log penyalahgunaan", "abusefilter-log-search-user": "Pengguna:", + "abusefilter-log-search-group": "Tapis kumpulan:", "abusefilter-log-search-filter": "ID penapis (asingkan dengan tanda paip \"|\"):", "abusefilter-log-search-title": "Tajuk:", "abusefilter-log-search-wiki": "Wiki:", + "abusefilter-log-search-entries-all": "Semua masukan", "abusefilter-log-search-submit": "Cari", "abusefilter-log-entry": "$1: $2 mencetuskan penapis salah guna, melakukan tindakan \"$3\" pada $4.\nTindakan diambil: $5;\nHuraian penapis: $6", "abusefilter-log-entry-withdiff": "$1: $2 telah mencetuskan penapis salah guna dengan melakukan tindakan \"$3\" di $4.\nTindakan diambil: $5;\nKeterangan penapis: $6 ($7)", @@ -65,13 +67,12 @@ "abusefilter-log-details-var": "Pemboleh ubah", "abusefilter-log-details-val": "Nilai", "abusefilter-log-details-vars": "Parameter tindakan", - "abusefilter-log-details-private": "Data peribadi", "abusefilter-log-details-ip": "Alamat IP pelaku", + "abusefilter-log-details-checkuser": "Periksa pengguna", "abusefilter-log-noactions": "tiada", "abusefilter-log-details-diff": "Perubahan akibat suntingan", "abusefilter-log-linkoncontribs": "log penyalahgunaan", "abusefilter-log-linkoncontribs-text": "Log penyalahgunaan bagi pengguna ini", - "abusefilter-log-hidden": "(entri disorok)", "abusefilter-log-hidden-implicit": "(disorokkan kerana semakan telah dihapuskan)", "abusefilter-log-cannot-see-details": "Anda tiada kebenaran untuk melihat butiran entri ini.", "abusefilter-log-details-hidden": "Anda tidak dapat melihat butiran bagi entri ini kerana ia disembunyikan daripada pandangan awam.", @@ -80,11 +81,13 @@ "abusefilter-log-hide-id": "ID entri log:", "abusefilter-log-hide-hidden": "Sorokkan entri ini daripada tatapan umum", "abusefilter-log-hide-reason": "Sebab:", + "abusefilter-log-hide-reason-other": "Sebab lain/tambahan:", "abusefilter-log-hide-forbidden": "Anda tiada kebenaran untuk menyorokkan entri log penyalahgunaan.", "logentry-abusefilter-hit": "$1 mencetuskan $4, melakukan tindakan \"$5\" pada $3. Tindakan yang diambil: $6 ($7)", - "abusefilter-management": "Pengurusan penapis salah guna", + "log-action-filter-abusefilter": "Jenis perubahan penapis:", "abusefilter-list": "Semua penapis", "abusefilter-list-id": "ID penapis", + "abusefilter-list-pattern": "Corak", "abusefilter-list-status": "Status", "abusefilter-list-public": "Keterangan umum", "abusefilter-list-consequences": "Akibat", @@ -102,6 +105,7 @@ "abusefilter-disabled": "Dimatikan", "abusefilter-hitcount": "$1 hit", "abusefilter-new": "Cipta penapis baru", + "abusefilter-import-button": "Import penapis", "abusefilter-return": "Pulang ke pengurusan penapis", "abusefilter-status-global": "Sedunia", "abusefilter-list-options": "Pilihan", @@ -131,7 +135,6 @@ "abusefilter-edit-oldwarning": "<strong>Anda sedang menyunting versi lama bagi penapis ini.\nStatistik yang dipetik adalah bagi versi terkini bagi penapis ini.\nJika anda menyimpan perubahan anda, anda akan membatalkan segala perubahan sejak semakan yang anda sunting itu.</strong> •\n[[Special:AbuseFilter/history/$2|Kembali ke sejarah penapis ini]].", "abusefilter-edit-status-label": "Statistik:", "abusefilter-edit-status": "Penapis ini telah memadani $2 ($3%) daripada $1 tindakan terkini.", - "abusefilter-edit-status-profile": "Penapis ini telah memadani $2 ($3%) daripada $1 tindakan terkini.\nSecara puratanya, masa berjalannya ialah $4ms, dan ia mengambil $5 syarat daripada had syarat.", "abusefilter-edit-new": "Penapis baru", "abusefilter-edit-save": "Simpan penapis", "abusefilter-edit-id": "ID penapis:", @@ -159,12 +162,21 @@ "abusefilter-edit-throttle-count": "Bilangan tindakan untuk dibenarkan:", "abusefilter-edit-throttle-period": "Tempoh masa", "abusefilter-edit-throttle-groups": "Pendikit kumpulan ikut:\n:''(satu sebaris, gabungkan dengan tanda koma)''", + "abusefilter-edit-throttle-groups-help": "Lihat $1.", + "abusefilter-edit-throttle-groups-help-text": "pendokumenan di mediawiki.org", + "abusefilter-throttle-ip": "Alamat IP", + "abusefilter-throttle-user": "akaun pengguna", + "abusefilter-throttle-site": "seluruh tapak", + "abusefilter-throttle-page": "laman", + "abusefilter-throttle-none": "(tiada)", "abusefilter-edit-warn-message": "Pesanan sistem yang digunakan untuk amaran:", "abusefilter-edit-warn-other": "Pesanan lain", "abusefilter-edit-warn-other-label": "Nama laman pesanan lain:\n:''(tanpa awalan MediaWiki)''", "abusefilter-edit-warn-actions": "Tindakan:", "abusefilter-edit-warn-preview": "Pralihat pesanan yang dipilih", "abusefilter-edit-warn-edit": "Cipta/Sunting pesanan yang dipilih", + "abusefilter-edit-disallow-other": "Pesanan lain", + "abusefilter-edit-disallow-actions": "Tindakan:", "abusefilter-edit-tag-tag": "Tag untuk digunakan (satu sebaris):", "abusefilter-edit-denied": "Anda tidak boleh melihat butiran bagi penapis ini kerana ia disembunyikan daripada pandangan awam.", "abusefilter-edit-main": "Parameter penapis", @@ -268,16 +280,16 @@ "abusefilter-edit-builder-vars-all-links": "Semua pautan luar dalam teks baru", "abusefilter-edit-builder-vars-added-links": "Semua pautan luar yang dibubuh dalam suntingan", "abusefilter-edit-builder-vars-removed-links": "Semua pautan luar yang dipadamkan dalam suntingan", - "abusefilter-edit-builder-vars-old-text": "Teks wiki laman lama, sebelum disunting", - "abusefilter-edit-builder-vars-new-text": "Teks wiki laman baru, selepas disunting", + "abusefilter-edit-builder-vars-old-wikitext": "Teks wiki laman lama, sebelum disunting", + "abusefilter-edit-builder-vars-new-wikitext": "Teks wiki laman baru, selepas disunting", "abusefilter-edit-builder-vars-new-pst": "Wikiteks halaman baru, prasimpan diubah", - "abusefilter-edit-builder-vars-new-text-stripped": "Teks laman baru tanpa sebarang penanda", + "abusefilter-edit-builder-vars-new-text": "Teks laman baru tanpa sebarang penanda", "abusefilter-edit-builder-vars-new-html": "Sumber HTML terhurai bagi semakan baru", "abusefilter-edit-builder-vars-restrictions-edit": "Tahap perlindungan penyuntingan laman", "abusefilter-edit-builder-vars-restrictions-move": "Tahap perlindungan peralihan laman", "abusefilter-edit-builder-vars-restrictions-create": "Wujudkan perlindungan laman ini", "abusefilter-edit-builder-vars-restrictions-upload": "Muat naik perlindungan fail ini", - "abusefilter-edit-builder-vars-old-text-stripped": "Teks laman lama tanpa sebarang penanda", + "abusefilter-edit-builder-vars-old-text": "Teks laman lama tanpa sebarang penanda", "abusefilter-edit-builder-vars-old-links": "Pautan dalam laman sebelum disunting", "abusefilter-edit-builder-vars-old-html": "Teks wiki laman lama yang dihurai dalam HTML", "abusefilter-edit-builder-vars-minor-edit": "Sama ada suntingan itu ditandai sebagai kecil", @@ -301,6 +313,7 @@ "abusefilter-history-filterid": "Penapis", "abusefilter-history-select-legend": "Carian spesifik", "abusefilter-history-select-user": "Pengguna:", + "abusefilter-history-select-filter": "ID penapis:", "abusefilter-history-select-submit": "Perincikan", "abusefilter-history-diff": "Perubahan", "abusefilter-history-error-hidden": "Penapis yang anda mohon itu disorokkan, jadi anda tidak boleh melihat sejarahnya.", @@ -334,7 +347,7 @@ "abusefilter-revert-periodstart": "Tempoh bermula:", "abusefilter-revert-periodend": "Tempoh tamat:", "abusefilter-revert-search": "Pilih tindakan", - "abusefilter-revert-filter": "Penapis:", + "abusefilter-revert-filter": "ID penapis:", "abusefilter-revert-preview-intro": "Berikut ialah tindakan yang diambil oleh penapis salah guna yang akan diterbalikkan oleh tindakan ini.\nSila buat semakan dengan teliti, kemudian klik \"{{int:abusefilter-revert-confirm}}\" untuk mengesahkan pemilihan anda.", "abusefilter-revert-confirm": "Sahkan", "abusefilter-revert-success": "Anda telah membatalkan semua tindakan yang diambil oleh penapis salah guna atas sebab [[Special:AbuseFilter/$1|penapis $2]].", @@ -353,6 +366,8 @@ "abusefilter-test-shownegative": "Tunjukkan perubahan yang tidak sepadan dengan penapis", "abusefilter-test-syntaxerr": "Penapis yang anda isikan itu ada ralat sintaks.\nAnda boleh menerima penjelasan penuh dengan mengklik butang \"{{int:abusefilter-edit-check}}\".", "abusefilter-test-badtitle": "Tajuk halaman yang anda isikan itu tidak sah. Ia mungkin mengandungi aksara yang tidak boleh digunakan dalam tajuk.", + "abusefilter-test-search-type-edit": "Suntingan", + "abusefilter-test-search-type-upload": "Muat naik", "abusefilter-changeslist-examine": "periksa", "abusefilter-examine": "Periksa perubahan satu demi satu", "abusefilter-examine-intro": "Laman ini membolehkan anda memeriksa pembolehubah yang dijana oleh Penapis Salah Guna untuk satu perubahan tertentu, dan mengujinya dengan penapis.", @@ -376,7 +391,6 @@ "abusefilter-topnav-examine": "Periksa semakan dahulu", "abusefilter-topnav-log": "Log Penyalahgunaan", "abusefilter-topnav-tools": "Alatan penyahpepijatan", - "abusefilter-topnav-import": "Import penapis", "abusefilter-log-name": "Log Penapis Salah Guna", "abusefilter-log-header": "Log ini menunjukkan ringkasan perubahan yang dibuat pada penapis.\nUntuk butiran lanjut, lihat [[Special:AbuseFilter/history|senarai]] perubahan penapis terkini.", "abusefilter-log-noresults": "Tiada hasil", @@ -392,5 +406,7 @@ "abusefilter-import-intro": "Anda boleh menggunakan antara muka ini untuk mengimport penapis dari wiki lain.\nDalam wiki sumber, klik \"{{int:abusefilter-edit-export}}\" di bawah \"{{int:abusefilter-edit-tools}}\" di antara muka penyuntingan.\nSalin dari ruangan teks yang muncul, kemudian tampalkannya ke dalam ruangan teks ini, kemudian klik \"{{int:abusefilter-import-submit}}\".", "abusefilter-import-submit": "Import data", "abusefilter-group-default": "Asali", - "abusefilter-http-error": "Berlakunya ralat HTTP: $1." + "abusefilter-http-error": "Berlakunya ralat HTTP: $1.", + "abusefilter-view-privatedetails-submit": "Lihat butiran peribadi", + "abusefilter-view-privatedetails-legend": "Lihat butiran peribadi" } diff --git a/AbuseFilter/i18n/mt.json b/AbuseFilter/i18n/mt.json index c531cd00..53d63725 100644 --- a/AbuseFilter/i18n/mt.json +++ b/AbuseFilter/i18n/mt.json @@ -2,15 +2,17 @@ "@metadata": { "authors": [ "Chrisportelli", + "Fitoschido", "Giangian15", - "Roderick Mallia", "Leli Forte", - "Matma Rex" + "Matma Rex", + "Roderick Mallia", + "ToniSant" ] }, "abusefilter-desc": "Tapplika ewristika awtomatika lill-modifiki", - "abusefilter": "Konfigurazzjoni tal-filtru tal-abbuż", - "abuselog": "Reġistru tal-abbuż", + "abusefilter": "Ġestjoni tal-filtru tal-abbuż", + "abuselog": "Reġistru tal-filtru tal-abbuż", "abusefilter-intro": "Merħba fl-interfaċċa tal-filtru tal-abbuż.\nIl-filtru tal-abbuż huwa mekkaniżmu ta' softwer awtomatiku li japplika ewristiċi awtomatiċi lil kull azzjoni.\nDin l-interfaċċa turi lista ta' filtri partikolari, u tħalli li jiġu modifikati.", "abusefilter-warning": "'''Attenzjoni''': Din l-azzjoni ġiet awtomatikament identifikata bħala ta' ħsara.\nIl-modifiki mhux kostruttivi jiġu mħassra mill-ewwel, u l-kontribuzzjonijiet ħżiena jew mhux kostruttivi ripetuti jwasslu biex il-kont jew l-indirizz IP tiegħek jiġi imblukkat.\nJekk temmen li l-modifika tiegħek hija kostruttiva, tista' terġa' tissottomettiha sabiex tikkonfermaha.\nDin deskrizzjoni qasira tar-regola tal-abbuż li tapplika fil-każ tal-azzjoni tiegħek: $1", "abusefilter-disallowed": "Din l-azzjoni ġiet awtomatikament identifikata bħala ta' ħsara, u għalhekk ma tħallietx tiġi esegwita.\nJekk temmen li l-modifika tiegħek hija kostruttiva, informa wieħed mill- amministraturi dwar xi ppruvajt tagħmel.\nDin deskrizzjoni qasira tar-regola tal-abbuż li tapplika fil-każ tal-azzjoni tiegħek: $1", @@ -25,7 +27,7 @@ "right-abusefilter-view": "Jara l-filtri tal-abbuż", "right-abusefilter-log": "Jara r-reġistru tal-abbuż", "right-abusefilter-log-detail": "Jara d-daħliet dettalji tar-reġistru tal-abbuż", - "right-abusefilter-private": "Jara d-dati privati fir-reġistru tal-abbuż", + "right-abusefilter-privatedetails": "Jara d-dati privati fir-reġistru tal-abbuż", "right-abusefilter-modify-restricted": "Jimmodifika l-filtri tal-abbuż b'azzjonijiet ristretti", "right-abusefilter-revert": "Iħassar il-modifiki kollha minn filtru tal-abbuż partikulari", "right-abusefilter-view-private": "Jara l-filtri tal-abbuż immarkati bħala privati", @@ -37,11 +39,10 @@ "action-abusefilter-view": "tara l-filtri tal-abbuż", "action-abusefilter-log": "tara r-reġistru tal-abbuż", "action-abusefilter-log-detail": "tara d-daħliet dettalji tar-reġistru tal-abbuż", - "action-abusefilter-private": "tara d-dati privati fir-reġistru tal-abbuż", + "action-abusefilter-privatedetails": "tara d-dati privati fir-reġistru tal-abbuż", "action-abusefilter-modify-restricted": "timmodifika l-filtri tal-abbuż b'azzjonijiet ristretti", "action-abusefilter-revert": "tħassar kull modifika minn filtru tal-abbuż partikulari", "action-abusefilter-view-private": "tara l-filtri tal-abbuż immarkati bħala privati", - "abusefilter-log": "Reġistru tal-filtru tal-abbuż", "abusefilter-log-summary": "Dan ir-reġistru juri lista ta' kull azzjoni maqbuda mill-filtri.", "abusefilter-log-search": "Fittex ir-reġistru tal-abbużi", "abusefilter-log-search-user": "Utent:", @@ -61,13 +62,12 @@ "abusefilter-log-details-var": "Varjabbli", "abusefilter-log-details-val": "Valur", "abusefilter-log-details-vars": "Parametri tal-azzjoni", - "abusefilter-log-details-private": "Informazzjoni riservata", + "abusefilter-log-details-privatedetails": "Informazzjoni riservata", "abusefilter-log-details-ip": "Indirizz IP minn fejn oriġina", "abusefilter-log-noactions": "l-ebda", "abusefilter-log-details-diff": "Modifiki li saru", "abusefilter-log-linkoncontribs": "reġistru tal-abbuż", "abusefilter-log-linkoncontribs-text": "Reġistru tal-abbuż għal dan l-utent", - "abusefilter-log-hidden": "(daħla moħbija)", "abusefilter-log-hidden-implicit": "(moħbi minħabba li r-reviżjoni ġiet imħassra)", "abusefilter-log-cannot-see-details": "M'għandekx il-permessi sabiex tara d-dettalji ta' din id-daħla fir-reġistru.", "abusefilter-log-details-hidden": "Ma tistax tara d-dettalji ta' din id-daħla minħabba li ġiet moħbija mill-pubbliku.", @@ -76,9 +76,9 @@ "abusefilter-log-hide-id": "ID tad-daħla tar-reġistru:", "abusefilter-log-hide-hidden": "Aħbi din id-daħla mid-dehra pubblika", "abusefilter-log-hide-reason": "Raġuni:", + "abusefilter-log-hide-reason-other": "Raġuni oħra/addizzjonali:", "abusefilter-log-hide-forbidden": "M'għandekx il-permess li taħbi daħliet tar-reġistru tal-abbużi", "logentry-abusefilter-hit": "$1 attiva $4, esegwixxa l-azzjoni \"$5\" fuq $3. Azzjonijiet meħuda: $6 ($7)", - "abusefilter-management": "Ġestjoni tal-filtru tal-abbuż", "abusefilter-list": "Il-filtri kollha", "abusefilter-list-id": "ID tal-filtru", "abusefilter-list-status": "Stat", @@ -98,6 +98,7 @@ "abusefilter-disabled": "Diżattivata", "abusefilter-hitcount": "{{PLURAL:$1|korrispondenza waħda|$1 korrispondenzi}}", "abusefilter-new": "Oħloq filtru ġdid", + "abusefilter-import-button": "Importa filtru", "abusefilter-return": "Irritorna għall-ġestjoni tal-filtri", "abusefilter-status-global": "Globali", "abusefilter-list-options": "Għażliet", @@ -109,6 +110,7 @@ "abusefilter-list-options-scope-local": "Wiki lokali", "abusefilter-list-options-scope-global": "Regoli globali", "abusefilter-list-options-hidedisabled": "Aħbi filtri diżattivati", + "abusefilter-list-options-hideprivate": "Aħbi l-filtri privati", "abusefilter-list-options-submit": "Aġġorna", "abusefilter-tools-text": "Hawnhekk hawn xi għodda li jistgħu jkunu utli fil-bini u l-verifika tal-filtri kontra l-abbużi.", "abusefilter-tools-expr": "Tester tal-espressjonijiet", @@ -126,7 +128,6 @@ "abusefilter-edit-oldwarning": "<strong>Qiegħed timmodifika verżjoni antika ta' dan il-filtru.\nL-istatistika kwotata huma għall-aktar verżjoni riċenti ta' dan il-filtru.\nJekk issalva l-modifiki tiegħek, dawn se jieħdu post dawk li huma preżenti issa.</strong> •\n[[Special:AbuseFilter/history/$2|Irritorna lejn il-kronoloġija tal-filtru]].", "abusefilter-edit-status-label": "Statistika:", "abusefilter-edit-status": "Mill-aħħar {{PLURAL:$1|azzjoni|$1 azzjonijiet}}, dan il-filtru sab {{PLURAL:$2|korrispondenza waħda|$2 korrispondenzi}} ($3%).", - "abusefilter-edit-status-profile": "Mill-aħħar {{PLURAL:$1|azzjoni|$1 azzjonijiet}}, dan il-filtru sab {{PLURAL:$2|korrispondenza waħda|$2 korrispondenzi}} ($3%).\nIl-ħin medju ta' eżekuzzjoni hu ta' $4ms, u jikkonsma {{PLURAL:$5|kundizzjoni waħda|$5 kundizzjonijiet}} tal-limitu ta' kundizzjonijiet.", "abusefilter-edit-new": "Filtru ġdid", "abusefilter-edit-save": "Salva l-filtru", "abusefilter-edit-id": "ID tal-filtru:", @@ -251,16 +252,16 @@ "abusefilter-edit-builder-vars-all-links": "Il-ħoloq esterni kollha fit-test il-ġdid", "abusefilter-edit-builder-vars-added-links": "Il-ħoloq esterni kollha miżjuda mill-modifika", "abusefilter-edit-builder-vars-removed-links": "Il-ħoloq esterni kollha mneħħija mill-modifika", - "abusefilter-edit-builder-vars-old-text": "Sors tal-paġna l-qadima, qabel il-modifika", - "abusefilter-edit-builder-vars-new-text": "Sors tal-paġna l-ġdida, wara l-modifika", + "abusefilter-edit-builder-vars-old-wikitext": "Sors tal-paġna l-qadima, qabel il-modifika", + "abusefilter-edit-builder-vars-new-wikitext": "Sors tal-paġna l-ġdida, wara l-modifika", "abusefilter-edit-builder-vars-new-pst": "Wikitest ġdid tal-paġna wara l-bidliet qabel is-sejvjar", - "abusefilter-edit-builder-vars-new-text-stripped": "Test ġdid tal-paġna, mingħajr ''markup''", + "abusefilter-edit-builder-vars-new-text": "Test ġdid tal-paġna, mingħajr ''markup''", "abusefilter-edit-builder-vars-new-html": "Sors HTML analizzat tar-reviżjoni l-ġdida", "abusefilter-edit-builder-vars-restrictions-edit": "Livell ta' protezzjoni tal-paġna għall-modifiki", "abusefilter-edit-builder-vars-restrictions-move": "Livell ta' prtezzjoni tal-paġna għat-tmexxija", "abusefilter-edit-builder-vars-restrictions-create": "Oħloq protezzjoni għal din il-paġna", "abusefilter-edit-builder-vars-restrictions-upload": "Tella' l-protezzjoni tal-fajl", - "abusefilter-edit-builder-vars-old-text-stripped": "Test qadim tal-paġna, mingħajr ''markup''", + "abusefilter-edit-builder-vars-old-text": "Test qadim tal-paġna, mingħajr ''markup''", "abusefilter-edit-builder-vars-old-links": "Ħoloq fil-paġna, qabel il-modifika", "abusefilter-edit-builder-vars-old-html": "Sors il-qadim tal-paġna, interpretat f'HTML", "abusefilter-edit-builder-vars-minor-edit": "Indika jekk il-modifika hix waħda minuri jew le", @@ -296,7 +297,7 @@ "abusefilter-exception-dividebyzero": "Tentattiv li $2 jiġi diviż b'żero fil-karattru $1.", "abusefilter-exception-unrecognisedvar": "Varjabbli $2 mhux magħruf fil-karattru $1.", "abusefilter-exception-notenoughargs": "M'hemmx argumenti biżżejjed għall-funzjoni $2 fil-karattru $1.\n{{PLURAL:$3|Mistenni argument wieħed|Mistennija $3 argumenti}}, minflok hemm $4.", - "abusefilter-exception-regexfailure": "Żball fl-espressjoni regolari \"$3\" fil-karattru $1: \"$2\"", + "abusefilter-exception-regexfailure": "Żball fl-espressjoni regolari \"$2\" fil-karattru $1.", "abusefilter-action-tag": "Tikketta", "abusefilter-action-throttle": "Illimta", "abusefilter-action-warn": "Avża", @@ -350,7 +351,6 @@ "abusefilter-topnav-examine": "Eżamina modifiki preċedenti", "abusefilter-topnav-log": "Reġistru tal-abbuż", "abusefilter-topnav-tools": "Għodda tal-analizzar", - "abusefilter-topnav-import": "Importa filtru", "abusefilter-log-name": "Reġistru tal-filtru tal-abbuż", "abusefilter-log-header": "Dan ir-reġistru juri sommarju ta' modifiki li saru mill-filtru.\nGħal aktar dettalji, ara l-[[Special:AbuseFilter/history|lista]] ta' modifiki riċenti tal-filtru.", "abusefilter-log-noresults": "L-ebda riżultat", diff --git a/AbuseFilter/i18n/mwl.json b/AbuseFilter/i18n/mwl.json index 3fd139f5..2448989a 100644 --- a/AbuseFilter/i18n/mwl.json +++ b/AbuseFilter/i18n/mwl.json @@ -1,12 +1,10 @@ { "@metadata": { "authors": [ - "MokaAkashiyaPT", - "Athena in Wonderland" + "Athena in Wonderland", + "MokaAkashiyaPT" ] }, - "abusefilter": "Cunfiguraçon de l filtro de abusos", - "abuselog": "Registro de abusos", "abusefilter-disabled": "Zatibado", "abusefilter-diff-info": "Anformaçones básicas" } diff --git a/AbuseFilter/i18n/my.json b/AbuseFilter/i18n/my.json index c3e7f601..265d80d7 100644 --- a/AbuseFilter/i18n/my.json +++ b/AbuseFilter/i18n/my.json @@ -1,13 +1,13 @@ { "@metadata": { "authors": [ + "Dr Lotus Black", "Erikoo", - "Ninjastrikers", - "Dr Lotus Black" + "Ninjastrikers" ] }, - "abusefilter": "အလွဲသုံးစားမှု စိစစ်စနစ် ပြင်ဆင်ခြင်း", - "abuselog": "အလွဲသုံးစားပြုမှု မှတ်တမ်း", + "abusefilter": "အလွဲသုံးစားမှု စိစစ်စနစ် စီမံခန့်ခွဲရေး", + "abuselog": "အလွဲသုံးစားမှု စိစစ်စနစ် မှတ်တမ်း", "abusefilter-intro": "အလွဲသုံးစားမှု စိစစ်စနစ် စီမံခန့်ခွဲရေး interface မှ ကြိုဆိုပါသည်။ အလွဲသုံးစားမှု စိစစ်စနစ်သည် ဆောင်ရွက်ချက်အားလုံးကို အလိုအလျောက် တုန့်ပြန်သည့် အလိုအလျောက် ဆော့ဝဲလ်ဖြစ်ပါသည်။ ဤ interface တွင် သတ်မှတ်ထားသော စိစစ်စနစ်များကို ပြသထားပြီး ပြုပြင်ရန်လည်း ခွင့်ပြုထားပါသည်။", "abusefilter-blocker": "အလွဲသုံးစားမှု စိစစ်စနစ်", "abusefilter-blockreason": "အလွဲသုံးစားမှု စိစစ်စနစ်ဖြင့် အလိုအလျောက် ပိတ်ပင်တားဆီးလိုက်သည်။ ကိုက်ညီသောဥပဒေ၏ ဖော်ပြချက်မှာ $1", @@ -17,11 +17,12 @@ "action-abusefilter-modify": "အလွဲသုံးစားမှု စိစစ်စနစ်များကို ပြုပြင်ရန်", "action-abusefilter-view": "အလွဲသုံးစားမှု စိစစ်စနစ်များကို ကြည့်ရန်", "action-abusefilter-log": "အလွဲသုံးစားမှုမှတ်တမ်းကို ကြည့်ရန်", - "abusefilter-log": "အလွဲသုံးစားမှု စိစစ်စနစ် မှတ်တမ်း", "abusefilter-log-summary": "ဤမှတ်တမ်းသည် စိစစ်မှုများက ဖမ်းမိသော လုပ်ဆောင်ချက်အားလုံး၏စာရင်းကို ပြသပေးသည်။", "abusefilter-log-search": "အလွဲသုံးစားမှု မှတ်တမ်းကိုကြည့်ရန်", "abusefilter-log-search-user": "အသုံးပြုသူ:", - "abusefilter-log-search-filter": "စိစစ် အိုင်ဒီများ (ဒေါင်လိုက်မျဉ်း '|' ခြား၍):", + "abusefilter-log-search-group": "စိစစ်မှု အုပ်စု:", + "abusefilter-log-search-group-any": "မည်သည့်အရာမဆို", + "abusefilter-log-search-filter": "စိစစ် အိုင်ဒီများ:", "abusefilter-log-search-title": "ခေါင်းစဉ်:", "abusefilter-log-search-wiki": "ဝီကီ", "abusefilter-log-search-impact": "သက်ရောက်မှု:", @@ -45,13 +46,14 @@ "abusefilter-log-linkoncontribs-text": "{{GENDER:$1|ဤအသုံးပြုသူ}} အတွက် အလွဲသုံးစားမှု မှတ်တမ်း", "abusefilter-log-linkonhistory": "အလွဲသုံးစားမှု မှတ်တမ်းကို ကြည့်ရန်", "abusefilter-log-linkonhistory-text": "ဤစာမျက်နှာအတွက် အလွဲသုံးစားမှုမှတ်တမ်းကို ကြည့်ရန်", + "abusefilter-log-linkonundelete": "အလွဲသုံးစားမှု မှတ်တမ်းကို ကြည့်ရန်", + "abusefilter-log-linkonundelete-text": "ဤစာမျက်နှာအတွက် အလွဲသုံးစားမှုမှတ်တမ်းကို ကြည့်ရန်", "abusefilter-log-hide-reason": "အကြောင်းပြချက်:", "abusefilter-log-hide-reason-other": "အခြားသော/နောက်ထပ် အကြောင်းပြချက် -", "abusefilter-log-entry-suppress": "$1 က $3 ကို {{GENDER:$2|ဝှက်ခဲ့သည်}}", "log-action-filter-abusefilter": "စိစစ်မှု အပြောင်းအလဲ အမျိုးအစား:", "log-action-filter-abusefilter-create": "စိစစ်မှုအသစ် ဖန်တီးခြင်း", "log-action-filter-abusefilter-modify": "စိစစ်မှု ပြုပြင်ပြောင်းလဲခြင်း", - "abusefilter-management": "အလွဲသုံးစားမှု စိစစ်စနစ် စီမံခန့်ခွဲရေး", "abusefilter-list": "စိစစ်မှုများ အားလုံး", "abusefilter-list-id": "စိစစ်မှု အိုင်ဒီ", "abusefilter-list-status": "အခြေအနေ", @@ -60,7 +62,7 @@ "abusefilter-list-visibility": "မြင်နိုင်မှု", "abusefilter-list-hitcount": "ထိမှန်မှု ကြိမ်ရေ", "abusefilter-list-edit": "ပြင်ဆင်ရန်", - "abusefilter-list-details": "အသေးစိတ်", + "abusefilter-list-details": "အသေးစိတ်များ", "abusefilter-list-limit": "စာမျက်နှာအလိုက် အရေအတွက်", "abusefilter-list-lastmodified": "နောက်ဆုံး ပြုပြင်မှု", "abusefilter-list-group": "စိစစ်မှု အုပ်စု", @@ -70,6 +72,7 @@ "abusefilter-deleted": "ဖျက်ပြီး", "abusefilter-disabled": "ပိတ်ထားပြီး", "abusefilter-new": "စိစစ်မှုအသစ်တစ်ခု ဖန်တီးရန်", + "abusefilter-import-button": "စိစစ်မှုစနစ် တင်သွင်းရန်", "abusefilter-return": "စိစစ်မှု စီမံခန့်ခွဲရေးသို့ ပြန်သွားရန်", "abusefilter-status-global": "ဂလိုဘယ်", "abusefilter-list-options": "ရွေးပိုင်ခွင့်", @@ -99,22 +102,31 @@ "abusefilter-edit-description": "ဖော်ပြချက်:\n:''(လူတိုင်း ကြည့်ရှုနိုင်)''", "abusefilter-edit-field-description": "ဖော်ပြချက်", "abusefilter-edit-group": "စိစစ်မှု အုပ်စု:", + "abusefilter-edit-enabled": "ဤစီစစ်မှုကို လုပ်ခွင့်ပြုမည်", + "abusefilter-edit-deleted": "ဖျက်ပြီးကြောင်း မှတ်သားရန်", "abusefilter-edit-global": "ဂလိုဘယ် စိစစ်မှု", "abusefilter-edit-rules": "အခြေနေများ:", "abusefilter-edit-field-conditions": "အခြေနေများ", "abusefilter-edit-notes": "မှတ်စုများ:", "abusefilter-edit-throttle-period": "အချန်အပိုင်းအခြား (စက္ကန့်ဖြင့်):", - "abusefilter-edit-throttle-ip": "အိုင်ပီလိပ်စာ", - "abusefilter-edit-throttle-user": "အသုံးပြုသူ အကောင့်", - "abusefilter-edit-throttle-editcount": "တည်းဖြတ်မှု အရေအတွက်", - "abusefilter-edit-throttle-site": "ဆိုဒ်တစ်ခုလုံး", - "abusefilter-edit-throttle-page": "စာမျက်နှာ", + "abusefilter-edit-throttle-groups-help": "$1 ကိုကြည့်ပါ။", + "abusefilter-throttle-ip": "အိုင်ပီလိပ်စာ", + "abusefilter-throttle-user": "အသုံးပြုသူ အကောင့်", + "abusefilter-throttle-editcount": "တည်းဖြတ်မှု အရေအတွက်", + "abusefilter-throttle-site": "ဆိုဒ်တစ်ခုလုံး", + "abusefilter-throttle-page": "စာမျက်နှာ", + "abusefilter-throttle-none": "(ဗလာ)", "abusefilter-edit-warn-other": "အခြားမက်ဆေ့", "abusefilter-edit-warn-actions": "ဆောင်ရွက်ချက်များ", + "abusefilter-edit-disallow-other": "အခြားမက်ဆေ့", "abusefilter-edit-main": "စိစစ်မှုစနစ် ပါရာမီတာများ", "abusefilter-edit-viewhistory": "ဤစိစစ်မှု၏ ရာဇဝင်အား ကြည့်ရှုရန်", "abusefilter-edit-history": "ရာဇဝင်:", "abusefilter-edit-tools": "ကိရိယာများ:", + "abusefilter-edit-notallowed": "အလွဲသုံးစားမှုစီစစ်စနစ်အား ဖန်တီးရန် သို့မဟုတ် ပြင်ဆင်ဆင်ရန် ခွင့်ပြုချက် မရှိပါ", + "abusefilter-edit-notallowed-global": "ဂလိုဘယ်အလွဲသုံးစားမှုစီစစ်စနစ်အား ဖန်တီးရန် သို့မဟုတ် ပြင်ဆင်ဆင်ရန် ခွင့်ပြုချက် မရှိပါ", + "abusefilter-edit-invalid-warn-message": "သတိပေးချက်မက်ဆေ့ကို ကွက်လပ်မချန်ထားရပါ။", + "abusefilter-edit-invalid-disallow-message": "ခွင့်မပြုမက်ဆေ့ကို ကွက်လပ်မချန်ထားရပါ။", "abusefilter-edit-builder-vars-action": "ဆောင်ရွက်ချက်", "abusefilter-edit-builder-vars-page-id": "စာမျက်နှာ အိုင်ဒီ", "abusefilter-edit-builder-vars-page-prefixedtitle": "စာမျက်နှာခေါင်းစဉ် အပြည့်အစုံ", @@ -137,6 +149,7 @@ "abusefilter-history-filter": "စိစစ်မှု စည်းမျဉ်း", "abusefilter-history-comments": "မှတ်ချက်များ", "abusefilter-history-actions": "ဆောင်ရွက်ချက်များ", + "abusefilter-history-backedit": "စီစစ်မှုအယ်ဒီတာသို့ ပြန်သွားရန်", "abusefilter-history-deleted": "ဖျက်ပြီးပြီ", "abusefilter-history-filterid": "စိစစ်မှု", "abusefilter-history-select-legend": "ရှာဖွေမှုကို သန့်စင်ရန်", @@ -157,6 +170,7 @@ "abusefilter-revert-filter": "စိစစ်မှု အိုင်ဒီ:", "abusefilter-revert-confirm": "အတည်ပြု", "abusefilter-revert-reasonfield": "အကြောင်းပြချက်:", + "abusefilter-test-legend": "စီစစ်မှု စမ်းသပ်ခြင်း", "abusefilter-test-user": "အသုံးပြုသူအလိုက် ပြောင်းလဲမှုများ:", "abusefilter-test-nobots": "ဘော့ တည်းဖြတ်မှုများကို ဝှက်ရန်", "abusefilter-test-period-start": "ပြောင်းလဲမှုများ လုပ်ဆောင်ပြီးနောက်:", @@ -178,15 +192,17 @@ "abusefilter-examine-test-button": "စိစစ်မှုစနစ်ကို စမ်းသပ်ရန်", "abusefilter-topnav": "'''အလွဲသုံးစား စိစစ်မှု အညွှန်း'''", "abusefilter-topnav-home": "ပင်မ", + "abusefilter-topnav-recentchanges": "လတ်တလော စိစစ်မှုစနစ် အပြောင်းအလဲများ", "abusefilter-topnav-examine": "ယခင်တည်းဖြတ်မှုများကို စစ်ဆေးရန်", "abusefilter-topnav-log": "အလွဲသုံးစားပြုမှု မှတ်တမ်း", "abusefilter-topnav-tools": "အပြစ်ရှာ ကိရိယာများ", - "abusefilter-topnav-import": "စိစစ်မှုစနစ် တင်သွင်းရန်", "abusefilter-log-name": "အလွဲသုံးစားမှု စိစစ်စနစ် မှတ်တမ်း", "abusefilter-log-header": "ဤမှတ်တမ်းသည် စိစစ်မှုစနစ်ရှိ ပြုလုပ်ထားသော ပြောင်းလဲမှုများ၏ အကျဉ်းချုပ်ကို ဖော်ပြပေးသည်။ အသေးစိတ် ပြည့်စုံစွာကြည့်လိုပါက လတ်တလော စိစစ်မှု အပြောင်းအလဲများ [[Special:AbuseFilter/history|စာရင်း]]ကို ကြည့်ပါ။", "abusefilter-log-noresults": "မည်သည့်ရလဒ်မှ မရှိပါ", "abusefilter-diff-title": "ဗားရှင်းများကြား ကွဲပြားမှုများ", + "abusefilter-diff-version": "$1 မှ $2 {{GENDER:$3|ပြုလုပ်သော}} ဗားရှင်းဖြစ်သည်", "abusefilter-diff-info": "အခြေခံသတင်းအချက်အလက်", + "abusefilter-diff-pattern": "စီစစ်မှုအခြေနေများ", "abusefilter-diff-backhistory": "စိစစ်မှုရာဇဝင်သို့ ပြန်သွားရန်", "abusefilter-diff-prev": "ပိုဟောင်းသော ပြောင်းလဲမှု", "abusefilter-diff-next": "ပိုသစ်သော ပြောင်းလဲမှု", diff --git a/AbuseFilter/i18n/myv.json b/AbuseFilter/i18n/myv.json index e82f76a4..e653d500 100644 --- a/AbuseFilter/i18n/myv.json +++ b/AbuseFilter/i18n/myv.json @@ -1,13 +1,13 @@ { "@metadata": { "authors": [ - "Botuzhaleny-sodamo" + "Botuzhaleny-sodamo", + "Rueter" ] }, - "abusefilter": "А тевде сувтемень аравтомась", - "abuselog": "А тевде тешкстамот", + "abuselog": "А тевде сувтемень тешкстамот", "abusefilter-blocker": "А тевде сувтеме", - "right-abusefilter-modify": "Лиякстомтомс а тевде сувтеметнень", + "right-abusefilter-modify": "Шкамс эли лиякстомтомс а тевде сувтеметнень", "right-abusefilter-view": "Ванномс а тевде сувтеметнень", "right-abusefilter-log": "Ванномс а тевде сувтемень тешкстамотнень", "right-abusefilter-hide-log": "Кекшемс мезе сёрмадозь а тевде тешкстамотнесэ", @@ -15,7 +15,6 @@ "action-abusefilter-modify": "лиякстомтомс а тевде сувтеметнень", "action-abusefilter-view": "ванномс а тевде сувтеметнень", "action-abusefilter-log": "ванномс а тевде сувтемень тешкстамотнень", - "abusefilter-log": "А тевде сувтемень тешкстамот", "abusefilter-log-search": "Вешнемс а тевде сувтемень тешкстамотнестэ", "abusefilter-log-search-user": "Теицясь:", "abusefilter-log-search-filter": "Сувтемень ID-тне (явомс турбинесэ):", @@ -25,8 +24,7 @@ "abusefilter-log-detailslink": "мезде моли кортамось", "abusefilter-log-hidelink": "петнемс неявомачинть", "abusefilter-log-linkoncontribs": "а тевде тешкстамот", - "abusefilter-log-linkoncontribs-text": "Те совицядонть а тевень тешкстамот", - "abusefilter-log-hidden": "(сёрмадовксось кекшезь)", + "abusefilter-log-linkoncontribs-text": "{{GENDER:$1|Те совицядонть}} а тевень тешкстамот", "abusefilter-log-hidden-implicit": "(кекшезь, нардазь ревизиясь)", "abusefilter-log-hide-reason": "Тувталось:", "abusefilter-list": "Весе сувтеметь", @@ -53,12 +51,17 @@ "abusefilter-edit-enabled": "Тевс нолдавозо сувтемесь", "abusefilter-edit-deleted": "Тешкстамс нардазекс", "abusefilter-edit-notes": "Тешкстамот:", + "abusefilter-throttle-page": "лопа", + "abusefilter-throttle-none": "(арась мезе невтемс)", + "abusefilter-edit-warn-other": "Лия сёрмине", "abusefilter-edit-warn-actions": "Тевтеематне:", "abusefilter-edit-warn-edit": "Шкамс/Витнемс-петнемс кочказь сёрминенть", + "abusefilter-edit-disallow-other": "Лия сёрмине", "abusefilter-edit-main": "Сувтемень параметратне", "abusefilter-edit-done-subtitle": "Сувтемесь витнезь-петнезь", "abusefilter-edit-viewhistory": "Ванномс те сувтементь юронзо-путовксонзо", "abusefilter-edit-history": "Путовкстнэ-юртнэ:", + "abusefilter-edit-check": "Ванномс синтакс", "abusefilter-edit-tools": "Кедьёнкстнэ:", "abusefilter-edit-builder-group-op-arithmetic": "Арифметикань операторт", "abusefilter-edit-builder-op-arithmetic-addition": "Путомась (+)", @@ -83,7 +86,9 @@ "abusefilter-edit-builder-vars-oldsize": "Лопанть икелень покшолмазо", "abusefilter-edit-builder-vars-page-id": "Лопа ID", "abusefilter-edit-builder-vars-page-ns": "Лопань лем потмо", - "abusefilter-edit-builder-vars-page-title": "Лопа конякс (лем потмовтомо)", + "abusefilter-edit-builder-vars-page-title": "Лопаконякс (лемпотмовтомо)", + "abusefilter-edit-builder-vars-page-prefixedtitle": "Лопанть лемезэ целанек", + "abusefilter-edit-builder-vars-page-age": "Лопанть шказо (секундасо)", "abusefilter-edit-builder-vars-user-age": "Совамо тарканть шказо", "abusefilter-edit-builder-vars-user-name": "Совамо тарканть лемезэ", "abusefilter-edit-builder-vars-file-size": "Файланть покшолмазо байтасо", @@ -110,12 +115,12 @@ "abusefilter-action-block": "Озавтомс саймас", "abusefilter-revert-periodstart": "Шкаютконть ушодомазо:", "abusefilter-revert-periodend": "Шкаютконть прядомазо:", - "abusefilter-revert-filter": "Сувтемесь:", + "abusefilter-revert-filter": "ID-нь сувтемесь:", "abusefilter-revert-confirm": "Кемекстамс", "abusefilter-revert-reasonfield": "Тувталось:", "abusefilter-test-load-filter": "Таргамс сувтементь, конань ID-зэ:", "abusefilter-test-submit": "Ванномс", - "abusefilter-test-load": "Ёвкстамс", + "abusefilter-test-load": "Тонгомс", "abusefilter-test-user": "Лиякстомтомат, конатнень теицяст:", "abusefilter-test-period-start": "Лиякстомтомат, конатне теезь те шкадо мейле:", "abusefilter-test-period-end": "Лиякстомтомат, конатне теезь те шкадо икеле:", diff --git a/AbuseFilter/i18n/nah.json b/AbuseFilter/i18n/nah.json index c952882c..2c690fc3 100644 --- a/AbuseFilter/i18n/nah.json +++ b/AbuseFilter/i18n/nah.json @@ -1,18 +1,22 @@ { "@metadata": { "authors": [ + "Akapochtli", "Fluence", - "Teòtlalili", - "Akapochtli" + "Teòtlalili" ] }, - "abusefilter-log-search-user": "Tlatequitiltilīlli:", + "abusefilter-log-search-user": "Tequitiuhqui:", "abusefilter-log-search-title": "Tocaitl:", "abusefilter-log-search-submit": "Tlatemoliztli", "abusefilter-log-noactions": "ahtlein", "abusefilter-log-hide-reason": "Tleca:", "abusefilter-list-edit": "Tlapatlaliztli", + "abusefilter-tools-reautoconfirm-user": "Tequitiuhqui", "abusefilter-edit-throttle-period": "Cahuitl:", + "abusefilter-history-user": "Tequitiuhqui", + "abusefilter-history-select-user": "Tequitiuhqui", + "abusefilter-examine-user": "Tequitiuhqui", "abusefilter-examine-title": "Tlahcuilolamatocaitl:", "abusefilter-examine-submit": "Tlatemoliztli", "abusefilter-topnav-home": "Pehualoyan" diff --git a/AbuseFilter/i18n/nap.json b/AbuseFilter/i18n/nap.json index c0a80bfe..2cf43e86 100644 --- a/AbuseFilter/i18n/nap.json +++ b/AbuseFilter/i18n/nap.json @@ -1,14 +1,13 @@ { "@metadata": { "authors": [ - "Chelin", "C.R.", + "Chelin", "Ruthven" ] }, "abusefilter-desc": "Appreca n'euristica automateca a 'e cagnamiente", - "abusefilter": "Configurazion d' 'o filtro anti abbuse", - "abuselog": "Riggistro 'e ll'abbuse", + "abuselog": "Riggistro d' 'o filtro anti abbuse", "abusefilter-intro": "Bemmenuto dint'a l'interfazze 'e gistione 'e filtre anti-abbuse.\n'O filtro abbuse è nu meccanismo software pe' n'apprecà euristeche automateche a tutte l'aziune.\nChist'interfazze fà vedè n'elenco 'e filtre definite, e cunzente a chiste d'essere cagnate.", "abusefilter-warning": "'''Attenziò''': St'azione è stata automaticamente identificata comme pericolosa.\n'E cagnamiente nun costruttive so' state annullate ampress ampress, e 'e cagnamiente egregge o ripetitive se segnarranno ncopp' 'o cunto o l'indirizzo IP vuosto ca sarrà bloccato.\n\nSi penzate ca st'azione fosse costruttiva, 'a putisseve signà n'ata vota p' 'o cunfermà. Cu na descriziona ampresso 'e l'azione d'abbuso ca soddisfacesse l'aziona vuosta comme: $1", "abusefilter-disallowed": "St'azione è stata automaticamente identificata comme pericolosa e, allora nun s'è premmessa.\nSi cridete ca l'aziona vuosta è custruttiva, pe' piacere nfurmate n'ammenistratore 'e chillo ca vulive fà.\nNa descrizione veloce d' 'a regola d'abbuse ncopp'a l'aziona vuosta fosse comm'a chesta: $1", @@ -21,7 +20,7 @@ "right-abusefilter-view": "Vide 'e filtre d'abbuse", "right-abusefilter-log": "Vide 'o riggistro d'abbuse", "right-abusefilter-log-detail": "Vide cchiù ndettaglio 'e riggistre d'abbuse", - "right-abusefilter-private": "Vide 'e date private int' 'o riggistro d'abbuse", + "right-abusefilter-privatedetails": "Vide 'e date private int' 'o riggistro d'abbuse", "right-abusefilter-modify-restricted": "Càgna 'e filtre d'abbuse cu l'aziune lemmetate", "right-abusefilter-revert": "Sfàje tutt' 'e cagnamiente 'e nu filtro d'abbuse dato", "right-abusefilter-view-private": "Vide filtre abbuse nzignate ccà comme private", @@ -33,11 +32,10 @@ "action-abusefilter-view": "vide 'e filtre 'abbuse", "action-abusefilter-log": "vide 'o riggistro 'abbuse", "action-abusefilter-log-detail": "vide cchiù 'ndettaglio 'e riggistre 'abbuse", - "action-abusefilter-private": "vide 'e date private int' 'o riggistro d'abbuse", + "action-abusefilter-privatedetails": "vide 'e date private int' 'o riggistro d'abbuse", "action-abusefilter-modify-restricted": "càgna 'e filtre d'abbuse cu l'aziune lemmetate", "action-abusefilter-revert": "sfàje tutt' 'e cagnamiente 'e nu filtro d'abbuse dato", "action-abusefilter-view-private": "vide filtre abbuse nzignate ccà comme private", - "abusefilter-log": "Riggistro d' 'o filtro anti abbuse", "abusefilter-log-summary": "Stu riggistro mmustasse n'elenco 'e tutte l'aziune c'avessero appicciato uno o cchiù filtre.", "abusefilter-log-search": "Trova dint'a 'o riggistro 'abbuse", "abusefilter-log-search-user": "Utente:", @@ -54,17 +52,17 @@ "abusefilter-log-details-var": "Variabbele", "abusefilter-log-details-val": "Valore", "abusefilter-log-details-vars": "Parametre 'e l'azione", - "abusefilter-log-details-private": "Date private", + "abusefilter-log-details-privatedetails": "Date private", "abusefilter-log-details-ip": "Inderizzo IP d'origgene", "abusefilter-log-noactions": "nisciuno", "abusefilter-log-details-diff": "Cagnamiente fatte int' 'o modo 'e modifica", "abusefilter-log-linkoncontribs": "riggistro 'e ll'abbuse", "abusefilter-log-linkoncontribs-text": "Riggistro 'e abbuse pe' st'utente", - "abusefilter-log-hidden": "(voce annascunnuta)", "abusefilter-log-hidden-implicit": "(annascunnuta pecché 'a verziona fuje scancellata)", "abusefilter-log-hide-reason": "Mutivo:", "abusefilter-list-edit": "Càgna", "abusefilter-unhidden": "Pubbreco", "abusefilter-enabled": "Attivato", - "abusefilter-deleted": "Canciellato" + "abusefilter-deleted": "Canciellato", + "abusefilter-edit-builder-vars-user-groups": "Gruppe 'e ll'utente" } diff --git a/AbuseFilter/i18n/nb.json b/AbuseFilter/i18n/nb.json index 92a547aa..93f2c129 100644 --- a/AbuseFilter/i18n/nb.json +++ b/AbuseFilter/i18n/nb.json @@ -1,30 +1,36 @@ { "@metadata": { "authors": [ + "Chameleon222", + "Citadell", + "Cocu", "Danmichaelo", "EvenT", "Event", + "Fitoschido", "Guaca", "Harald Khan", + "Imre Eilertsen", + "Jeblad", + "Jon Harald Søby", + "Kingu", "Laaknor", + "Matma Rex", + "Matěj Suchánek", "McDutchie", "Nghtwlkr", "Njardarlogar", + "Orf3us", + "PeterFisk", "Stigmj", - "Cocu", - "Jeblad", - "Chameleon222", - "Matma Rex", - "Jon Harald Søby", - "Imre Eilertsen", - "Matěj Suchánek", - "Citadell" + "VukAnd12" ] }, "abusefilter-desc": "Legger til automatisk heuristikk til redigeringer.", - "abusefilter": "Konfigurasjon av redigeringsfilter", - "abuselog": "Misbrukslogg", + "abusefilter": "Behandling av redigeringsfilter", + "abuselog": "Redigeringsfilterlogg", "abusefilter-intro": "Velkommen til grensesnittet for håndtering av redigeringsfilteret.\nRedigeringsfilteret er en automatisert mekanisme i programvaren som utfører automatisk sjekking av alle handlinger.\nDette grensesnittet viser en liste over definerte filtre og tillater endring av dem.", + "abusefilter-mustviewprivateoredit": "Av sikkerhetsårsaker kan bare brukere med retten til å vise private misbruksfiltre eller endre filtre bruke dette grensesnittet.", "abusefilter-warning": "'''Advarsel''': Handlingen har automatisk blitt identifisert som skadelig.\nIkke-konstruktive handlinger blir raskt tilbakestilt,\nog langvarig forstyrrende redigering vil føre til at din konto eller IP-adresse blir blokkert.\nOm du mener dette er en konstruktiv redigering, klikk «Lagre» igjen for å bekrefte den.\nEn kortfattet beskrivelse av redigeringsregelen som din handling utløste er: $1", "abusefilter-disallowed": "Denne handlingen har automatisk blitt identifisert som skadelig, og er derfor avvist. Om du mener redigeringen var konstruktiv, kontakt en administrator og informer ham eller henne om hva du prøvde å få til.\nEn kortfattet beskrivelse av redigeringsregelen som din handling utløste er: $1", "abusefilter-blocked-display": "Denne handlingen har automatisk blitt identifisert som skadelig, og du har blitt hindret fra å gjennomføre den. I tillegg, for å beskytte {{SITENAME}}, har din konto og alle IP-adresser assosiert med denne blitt blokkert fra å redigere. Om dette var en feil, kontakt en administrator.\nEn kortfattet beskrivelse av redigeringsregelen som din handling utløste er: $1", @@ -33,16 +39,18 @@ "abusefilter-blocker": "Redigeringsfilter", "abusefilter-blockreason": "Automatisk blokkert av redigeringsfilter. Regelbeskrivelse: $1", "abusefilter-degroupreason": "Rettigheter fjernet automatisk av redigeringsfilter. Regelbeskrivelse: $1", + "abusefilter-blockautopromotereason": "Automatisk forfremmelse ble automatisk utsatt av et misbruksfilter.\nRegelbeskrivelse: $1", "abusefilter-accountreserved": "Denne kontoen er reservert for bruk av redigeringsfilteret.", - "right-abusefilter-modify": "Endre redigeringsfiltere", + "right-abusefilter-modify": "Opprette eller endre redigeringsfiltre", "right-abusefilter-view": "Vise redigeringsfiltere", "right-abusefilter-log": "Vise misbruksloggen", "right-abusefilter-log-detail": "Vise detaljerte punkter i misbruksloggen", - "right-abusefilter-private": "Vise privat informasjon i misbruksloggen", + "right-abusefilter-privatedetails": "Vise privat informasjon i misbruksloggen", + "right-abusefilter-privatedetails-log": "Vise tilgangsloggen for private detaljer i misbruksfilteret", "right-abusefilter-modify-restricted": "Endre filtre med begrensede handlinger", "right-abusefilter-revert": "Tilbakestill alle endringer gjort av et gitt redigeringsfilter", "right-abusefilter-view-private": "Vis redigeringsfiltre merket privat", - "right-abusefilter-log-private": "Vis loggposter for redigeringsfiltere som har blitt markert som private", + "right-abusefilter-log-private": "Vise loggoppføringer for redigeringsfiltere som har blitt markert som private", "right-abusefilter-hide-log": "Skjule oppføringer i misbruksloggen", "right-abusefilter-hidden-log": "Vise skjulte misbruksloggoppføringer", "right-abusefilter-modify-global": "Opprett eller endre globale redigeringsfiltre", @@ -50,24 +58,38 @@ "action-abusefilter-view": "se på redigeringsfilterene", "action-abusefilter-log": "se på misbruksloggen", "action-abusefilter-log-detail": "se på detaljene i misbruksloggen", - "action-abusefilter-private": "se på private data i misbruksloggen", + "action-abusefilter-privatedetails": "se på private data i misbruksloggen", + "action-abusefilter-privatedetails-log": "vise tilgangsloggen for private detaljer i misbruksfilteret", "action-abusefilter-modify-restricted": "endre redigeringsfiltere med begrensede handlinger", "action-abusefilter-revert": "tilbakestille alle endringer for et gitt redigeringsfilter", "action-abusefilter-view-private": "vis redigeringsfiltre merket som private", "action-abusefilter-log-private": "vise logger for misbruksfiltre merket som private", - "abusefilter-log": "Redigeringsfilterlogg", + "action-abusefilter-hide-log": "skjule oppføringer i misbruksloggen", + "action-abusefilter-hidden-log": "vise skjulte oppføringer i misbruksloggen", + "action-abusefilter-modify-global": "opprette eller endre globale misbruksfiltre", "abusefilter-log-summary": "Denne loggen viser en liste over alle handlingene som filterene har fanget opp", "abusefilter-log-search": "Søk i misbruksloggen", "abusefilter-log-search-user": "Bruker:", - "abusefilter-log-search-filter": "Filter-ID (skill med vertikalstrek):", + "abusefilter-log-search-group": "Filtergruppe:", + "abusefilter-log-search-group-any": "Hvilket som helst", + "abusefilter-log-search-filter": "Filter-ID-er:", + "abusefilter-log-search-filter-help": "Adskill med vertikalstreker, bruk prefikset «$1» for globale filtre", + "abusefilter-log-search-filter-help-central": "Atskill med vertikalstreker", "abusefilter-log-search-title": "Tittel:", "abusefilter-log-search-wiki": "Wiki:", + "abusefilter-log-search-impact": "Innvirkning:", "abusefilter-log-search-impact-all": "Alle handlinger", + "abusefilter-log-search-impact-saved": "Kun lagrede endringer", + "abusefilter-log-search-impact-not-saved": "Uten lagrede endringer", "abusefilter-log-search-entries-label": "Synlighet:", "abusefilter-log-search-entries-all": "Alle elementer", "abusefilter-log-search-entries-hidden": "Kun skjulte elementer", "abusefilter-log-search-entries-visible": "Kun synlige elementer", + "abusefilter-log-search-action-label": "Utløsende handling:", + "abusefilter-log-search-action-other": "Annet", + "abusefilter-log-search-action-any": "Hvilket som helst", "abusefilter-log-search-action-taken-label": "Handling tatt:", + "abusefilter-log-search-action-taken-any": "Hva som helst", "abusefilter-log-search-submit": "Søk", "abusefilter-log-entry": "$1: $2 utløste et redigeringsfilter ved å {{GENDER:$8|gjøre}} en $3 på $4.\nReaksjon: $5;\nfilterbeskrivelse: $6", "abusefilter-log-entry-withdiff": "$1: $2 utløste et misbruksfilter, ved å {{GENDER:$8|utføre}} handlingen «$3» på $4.\nUtførte handlinger: $5;\nFilterbeskrivelse: $6 ($7)", @@ -81,22 +103,30 @@ "abusefilter-log-details-var": "Variabel", "abusefilter-log-details-val": "Verdi", "abusefilter-log-details-vars": "Handlingsparametere", - "abusefilter-log-details-private": "Privat informasjon", + "abusefilter-log-details-privatedetails": "Private loggdetaljer", "abusefilter-log-details-ip": "Opphavs-IP", + "abusefilter-log-details-checkuser": "IP-kontroll", "abusefilter-log-noactions": "ingen", + "abusefilter-log-noactions-filter": "Ingen", "abusefilter-log-details-diff": "Endringer utført i redigeringen", "abusefilter-log-linkoncontribs": "misbrukslogg", "abusefilter-log-linkoncontribs-text": "Misbrukslogg for denne {{GENDER:$1|brukeren}}", - "abusefilter-log-hidden": "(oppføring skjult)", + "abusefilter-log-linkonhistory": "se endringsfilterlogg", + "abusefilter-log-linkonhistory-text": "Vis misbruksloggen for denne siden", + "abusefilter-log-linkonundelete": "vis misbruksloggen", + "abusefilter-log-linkonundelete-text": "Vis misbruksloggen for denne siden", "abusefilter-log-hidden-implicit": "(skjult fordi revisjonen har blitt slettet)", "abusefilter-log-cannot-see-details": "Du har ikke tillatelse til å se detaljene i dette oppslaget.", + "abusefilter-log-cannot-see-privatedetails": "Du har ikke tillatelse til å se private detaljer i denne oppføringen.", "abusefilter-log-nonexistent": "En oppføring med den angitte ID-en finnes ikke.", "abusefilter-log-details-hidden": "Du kan ikke se detaljene for denne oppføringen fordi den er skjult fra offentlig visning.", + "abusefilter-log-details-hidden-implicit": "Du kan ikke vise detaljene for denne oppføringen fordi den tilknyttede revisjonen er skjult fra offentlig visning.", "abusefilter-log-private-not-included": "En eller flere ID-er for filtre er private. Fordi du mangler rettigheter til å se detaljer i private filtre, så er søket ikke utført for slike.", "abusefilter-log-hide-legend": "Skjul loggoppføring", "abusefilter-log-hide-id": "Loggoppførings-ID:", "abusefilter-log-hide-hidden": "Skjul denne oppføringen fra offentlig visning", "abusefilter-log-hide-reason": "Årsak:", + "abusefilter-log-hide-reason-other": "Annen/utdypened årsak:", "abusefilter-log-hide-forbidden": "Du har ikke rettigheter til å skjule\nmisbruksloggoppføringer.", "abusefilter-log-entry-suppress": "$1 {{GENDER:$2|skjulte}} $3", "abusefilter-log-entry-unsuppress": "$1 {{GENDER:$2|fjernet}} skjuling av $3", @@ -104,7 +134,13 @@ "log-action-filter-abusefilter": "Type filterendring:", "log-action-filter-abusefilter-create": "Opprettelse av nytt filter", "log-action-filter-abusefilter-modify": "Endring av filter", - "abusefilter-management": "Behandling av redigeringsfilter", + "log-action-filter-suppress-abuselog": "Sensur av misbrukslogg", + "log-action-filter-rights-blockautopromote": "Blokker autoforfremming", + "log-action-filter-rights-restoreautopromote": "Gjenopprett autoforfremming", + "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|fikk tilgang}} til private detaljer for $3", + "logentry-rights-blockautopromote": "$1 {{GENDER:$2|blokkerte}} autoforfremmingen av {{GENDER:$4|$3}} i $5", + "logentry-rights-restoreautopromote": "$1 {{GENDER:$2|gjenopprettet}} autoforfremmingsmulighetene til {{GENDER:$4|$3}}", + "abusefilterprivatedetails-log-name": "Tilgangslogg for private detaljer i misbruksfilteret", "abusefilter-list": "Alle filtere", "abusefilter-list-id": "Filter-ID", "abusefilter-list-pattern": "Mønster", @@ -125,7 +161,8 @@ "abusefilter-disabled": "Slått av", "abusefilter-throttled": "begrenset", "abusefilter-hitcount": "$1 {{PLURAL:$1|treff}}", - "abusefilter-new": "Lag et nytt filter", + "abusefilter-new": "Opprett et nytt filter", + "abusefilter-import-button": "Importer filter", "abusefilter-return": "Returner til filteradministrasjon", "abusefilter-status-global": "Global", "abusefilter-list-options": "Alternativer", @@ -137,31 +174,43 @@ "abusefilter-list-options-scope-local": "Kun lokale regler", "abusefilter-list-options-scope-global": "Kun globale regler", "abusefilter-list-options-scope-all": "Lokale og globale regler", + "abusefilter-list-options-further-options": "Videre alternativer:", "abusefilter-list-options-hidedisabled": "Skjul deaktiverte filtre", "abusefilter-list-options-hideprivate": "Skjul private filtere", + "abusefilter-list-options-searchfield": "Søk innen regler:", + "abusefilter-list-options-searchpattern": "Sett inn et mønster", "abusefilter-list-options-searchoptions": "Søkemodus:", + "abusefilter-list-options-search-like": "Enkel spørring", + "abusefilter-list-options-search-rlike": "Regulært uttrykk", + "abusefilter-list-options-search-irlike": "Regulært uttrykk som ikke skiller mellom store og små bokstaver", + "abusefilter-list-invalid-searchmode": "Den gitte søkemodusen er ugyldig.", + "abusefilter-list-regexerror": "En feil oppsto under søk: Syntaksfeil i regulært uttrykk.", "abusefilter-list-options-submit": "Oppdater", "abusefilter-tools-text": "Her er noen verktøy som kan være nyttige for å lage samt feilsøke redigeringsfiltere.", "abusefilter-tools-expr": "Uttrykkstester", "abusefilter-tools-submitexpr": "Evaluer", + "abusefilter-tools-syntax-error": "Filteret har ugyldig syntaks.", "abusefilter-tools-reautoconfirm": "Gi tilbake autobekreftet status", "abusefilter-tools-reautoconfirm-user": "Bruker:", "abusefilter-tools-reautoconfirm-submit": "Gi automatisk bekreftet-status på nytt", - "abusefilter-reautoconfirm-none": "Brukeren har ikke fått opphevet {{GENDER:$1|hans|hennes|sin}} status som automatisk bekreftet.", + "abusefilter-tools-restoreautopromote": "Autoforfremming gjenopprettet via misbruksfilterverktøy.", + "abusefilter-reautoconfirm-none": "Brukeren har ikke fått opphevet statusen {{GENDER:$1|sin}} som automatisk bekreftet.", "abusefilter-reautoconfirm-notallowed": "Du har ikke lov til å gi tilbake autobekreftet-status.", "abusefilter-reautoconfirm-done": "Kontoens automatisk godkjent-status har blitt gitt tilbake", - "abusefilter-status": "Av {{PLURAL:$1|den siste handlingen|de siste $1 handlingene}} har $2 ($3 %) nådd grenseverdien $4. $5 ($6 %) passet med ett av de aktive filterne.", + "abusefilter-status": "Av {{PLURAL:$1|den siste handlingen|de siste $1 handlingene}} har $2 ($3 %) nådd grenseverdien $4, og $5 ($6 %) passet med minst ett av de aktive filterne.", "abusefilter-edit": "Redigerer misbrukssfilter", "abusefilter-edit-subtitle": "Redigerer filteret $1", "abusefilter-edit-subtitle-new": "Oppretter filter", + "abusefilter-edit-token-not-match": "Redigeringen ble ikke lagret! Lagre på nytt.", "abusefilter-edit-oldwarning": "<strong>Du redigerer på en gammel versjon av dette filteret. Statistikken oppgitt er for siste versjon av filteret. Hvis du lagrer dine endringer, vil du overskrive alle endringer siden den revisjonen du redigerer</strong> • [[Special:AbuseFilter/history/$2|Gå tilbake til filterets historikk]]", + "abusefilter-edit-oldwarning-view": "<strong>Du viser en gammel versjon av dette filteret.\nStatistikken som siteres gjelder den nyligste versjonen av filteret.</strong> •\n[[Special:AbuseFilter/history/$2|Tilbake til filterets historikk]].", "abusefilter-edit-status-label": "Statistikk:", - "abusefilter-edit-status": "Av {{PLURAL:$1|den siste handlingen|de siste $1 handlingene}} har dette filteret matchet $2 ($3 %).", - "abusefilter-edit-status-profile": "Av {{PLURAL:$1|den siste handlingen|de siste $1 handlingene}} har dette filteret passet med $2 ($3%).\nKjøretiden er i gjennomsnitt på $4ms, og det bruker {{PLURAL:$5|ett vilkår|$5 vilkår}} av vilkårsgrensen.", + "abusefilter-edit-status": "Av {{PLURAL:$1|den siste handlingen|de siste $1 handlingene}} har dette filteret matchet $2 ($3 %).\nI gjennomsnitt er kjøretiden $4 ms, og det bruker $5 {{PLURAL:$5|vilkår}} av vilkårsgrensen.", "abusefilter-edit-throttled-warning": "'''Advarsel:''' Dette filteret ble automatisk flagget som skadefullt. Av sikkerhetsårsaker vil følgende handlinger ikke bli utført ($1). Gå gjennom og [[mw:Extension:AbuseFilter/Conditions|optimer]] betingelsene for å fjerne denne begrensningen", "abusefilter-edit-new": "Nytt filter", "abusefilter-edit-save": "Lagre filter", "abusefilter-edit-id": "Filter-ID:", + "abusefilter-edit-switch-editor": "Bytt tekstprogram", "abusefilter-edit-description": "Beskrivelse\n:''(vises offentlig)''", "abusefilter-edit-field-description": "beskrivelse", "abusefilter-edit-group": "Filtergruppe:", @@ -172,7 +221,7 @@ "abusefilter-edit-global": "Globalt filter", "abusefilter-edit-rules": "Regelverk:", "abusefilter-edit-field-conditions": "betingelser", - "abusefilter-edit-notes": "Notater:", + "abusefilter-edit-notes": "Merknader:", "abusefilter-edit-lastmod": "Filter sist endret:", "abusefilter-edit-lastmod-text": "$1 av $2", "abusefilter-edit-hitcount": "Filtertreff:", @@ -182,26 +231,41 @@ "abusefilter-edit-action-blockautopromote": "Fjern brukerens «autoconfirmed»-status", "abusefilter-edit-action-degroup": "Fjern brukeren fra alle priviligerte grupper", "abusefilter-edit-action-block": "Blokker brukeren og/eller IP-adressen fra redigering", + "abusefilter-edit-action-blocktalk": "Blokker brukeren og/eller IP-adressen fra å redigere sin egen diskusjonsside", "abusefilter-edit-action-throttle": "Gjennomfør handlingen kun dersom brukeren gjør det flere ganger", "abusefilter-edit-action-rangeblock": "Blokker IP-intervallet brukeren kommer fra", "abusefilter-edit-action-tag": "Merk endringen for videre gjennomgang.", "abusefilter-edit-throttle-count": "Antall tillatte handlinger:", - "abusefilter-edit-throttle-period": "Tidsperiode:", - "abusefilter-edit-throttle-groups": "Grupper fart etter:\n:''(en på hver linje, kombiner med kommaer)''", - "abusefilter-edit-throttle-ip": "IP-adresse", - "abusefilter-edit-throttle-user": "Brukerkonto", - "abusefilter-edit-throttle-editcount": "Antall redigeringer", - "abusefilter-edit-throttle-site": "Hele nettstedet", - "abusefilter-edit-throttle-page": "Side", + "abusefilter-edit-throttle-period": "Tidsperiode (i sekunder):", + "abusefilter-edit-throttle-groups": "Grupper fart etter:", + "abusefilter-edit-throttle-groups-help": "Se $1.", + "abusefilter-edit-throttle-groups-help-text": "dokumentasjonen på mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Splitt med kommaer for å sammenstille med AND, og med linjeskift for å sammenstille med OR", + "abusefilter-edit-throttle-placeholder": "Splitt med kommaer for å sammenstille med AND, og sett inn én etter én for å sammenstille med OR", + "abusefilter-throttle-ip": "IP-adresse", + "abusefilter-throttle-user": "brukerkonto", + "abusefilter-throttle-range": "/16-intervall", + "abusefilter-throttle-creationdate": "kontoopprettelsesdato", + "abusefilter-throttle-editcount": "antall redigeringer", + "abusefilter-throttle-site": "hele nettstedet", + "abusefilter-throttle-page": "side", + "abusefilter-throttle-none": "(ingen)", "abusefilter-throttle-details": "Tillat $1 {{PLURAL:$1|handling|handlinger}} hvert {{PLURAL:$2|sekund|$2. sekund}}, grupper bremsing etter: $3", "abusefilter-edit-warn-message": "Systemmelding å bruke for advarsel:", "abusefilter-edit-warn-other": "Annen melding", - "abusefilter-edit-warn-other-label": "Side med annen melding:\n:''(uten MediaWiki-prefiks)''", + "abusefilter-edit-warn-other-label": "Side med annen melding:\n:''(uten «MediaWiki:»-prefiks)''", "abusefilter-edit-warn-actions": "Handlinger:", - "abusefilter-edit-warn-preview": "Forhåndsvis valgt melding", + "abusefilter-edit-warn-preview": "Vis/skjul forhåndsvisning av valgt melding", "abusefilter-edit-warn-edit": "Opprett/rediger valgt melding", + "abusefilter-edit-disallow-message": "Systembeskjed som skal brukes for å forby:", + "abusefilter-edit-disallow-other": "Annen beskjed", + "abusefilter-edit-disallow-other-label": "Sidenavnet til annen beskjed:\n:''(uten «MediaWiki:»-prefikset)''", + "abusefilter-edit-disallow-actions": "Handlinger:", + "abusefilter-edit-disallow-preview": "Vis/skjul forhåndsvisning av valgt melding", + "abusefilter-edit-disallow-edit": "Opprett/rediger valgt melding", "abusefilter-edit-tag-tag": "[[Special:Tags|Merkelapper]] å legge på:", "abusefilter-edit-tag-placeholder": "Legg til merkelapper (én per linje eller kommaatskilt)", + "abusefilter-edit-tag-hidden-placeholder": "Legg til tagger (kommaseparert)", "abusefilter-edit-block-anon-durations": "Blokkeringsvarighet for anonyme brukere:", "abusefilter-edit-block-user-durations": "Blokkeringsvarighet for registrerte brukere:", "abusefilter-block-anon": "Blokker anonyme brukere", @@ -225,10 +289,18 @@ "abusefilter-edit-export": "Eksporter dette filteret til en annen wiki", "abusefilter-edit-syntaxok": "Ingen syntaksfeil oppdaget.", "abusefilter-edit-syntaxerr": "Syntaksfeil oppdaget: $1", - "abusefilter-edit-bad-tags": "Én eller fler av merkelappene du spesifiserte er ikke gyldige.\nMekelappene burde være korte og burde ikke inneholde spesialtegn, og bør ikke være reservert av annen programvare. Prøv å velge et annet navn.", + "abusefilter-edit-warn-leave": "Hvis du forlater siden vil du miste alle endringer du har gjort i dette filteret.", + "abusefilter-edit-bad-tags": "Én eller fler av merkelappene du spesifiserte er ikke gyldige.\nMekelappene bør være korte og kan ikke inneholde spesialtegn, og kan ikke være reservert av annen programvare. Prøv å velge et annet navn.", "abusefilter-edit-notallowed": "Du har ikke tillatelse til å opprette eller endre redigeringsfilter", "abusefilter-edit-notallowed-global": "Du har ikke tillatelse til å opprette eller endre globale redigeringsfiltre", - "abusefilter-edit-notallowed-global-custom-msg": "Brukerdefinerte advarsler kan ikke brukes for globale filtre", + "abusefilter-edit-notallowed-global-custom-msg": "Brukerdefinerte advarsler eller forbudsbeskjeder kan ikke brukes for globale filtre", + "abusefilter-edit-invalid-warn-message": "Advarslelsmeldingen kan ikke stå tom.", + "abusefilter-edit-invalid-disallow-message": "Forbudsmeldingen kan ikke stå tom.", + "abusefilter-edit-invalid-throttlecount": "Fartsbegrensningen må være et positivt heltall.", + "abusefilter-edit-invalid-throttleperiod": "Fartsperioden må være et positivt heltall.", + "abusefilter-edit-empty-throttlegroups": "Minst én fartsgruppe må være valgt.", + "abusefilter-edit-duplicated-throttlegroups": "Fartsgrupper kan ikke ha dubletter.", + "abusefilter-edit-invalid-throttlegroups": "De gitte fartsgruppene er ugyldige.", "abusefilter-edit-builder-select": "Velg et alternativ for å legge det til på markøren", "abusefilter-edit-builder-group-op-arithmetic": "Aritmetiske operatorer", "abusefilter-edit-builder-op-arithmetic-addition": "Addisjon (+)", @@ -240,7 +312,8 @@ "abusefilter-edit-builder-group-op-comparison": "Sammenligningsoperatorer", "abusefilter-edit-builder-op-comparison-equal": "Verdien er lik (==)", "abusefilter-edit-builder-op-comparison-equal-strict": "Verdien og typen er lik (===)", - "abusefilter-edit-builder-op-comparison-notequal": "Er ikke lik (!=)", + "abusefilter-edit-builder-op-comparison-notequal": "Verdien er ikke lik (!=)", + "abusefilter-edit-builder-op-comparison-notequal-strict": "Verdien og typen er ikke lik (!==)", "abusefilter-edit-builder-op-comparison-lt": "Mindre enn (<)", "abusefilter-edit-builder-op-comparison-gt": "Større enn (>)", "abusefilter-edit-builder-op-comparison-lte": "Mindre enn eller lik med (<=)", @@ -258,12 +331,14 @@ "abusefilter-edit-builder-misc-stringlit": "Konstant streng (\"\")", "abusefilter-edit-builder-misc-tern": "Trefoldig operator (X ? Y : Z)", "abusefilter-edit-builder-misc-cond": "Betinget (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond-short": "Kort betingelse (if X then Y end)", "abusefilter-edit-builder-group-funcs": "Funksjoner", "abusefilter-edit-builder-funcs-length": "Strenglengde (length)", "abusefilter-edit-builder-funcs-lcase": "Gjør om til små bokstaver (lcase)", "abusefilter-edit-builder-funcs-ucase": "Gjør om til store bokstaver (ucase)", "abusefilter-edit-builder-funcs-ccnorm": "Normaliser forvirrende bokstaver (ccnorm)", - "abusefilter-edit-builder-funcs-ccnorm-contains-any": "Normaliser og søk etter flere understrenger i en steng (ccnorm_contains_any)", + "abusefilter-edit-builder-funcs-ccnorm-contains-any": "Normaliser og søk etter flere understrenger i en streng i OR-modus (ccnorm_contains_any)", + "abusefilter-edit-builder-funcs-ccnorm-contains-all": "Normaliser og søk etter flere understrenger i en streng i AND-modus (ccnorm_contains_all)", "abusefilter-edit-builder-funcs-rmdoubles": "Fjern doble bokstaver (rmdoubles)", "abusefilter-edit-builder-funcs-specialratio": "Spesialbokstaver / totalt antall bokstaver (specialratio)", "abusefilter-edit-builder-funcs-norm": "Normaliser (norm)", @@ -273,15 +348,19 @@ "abusefilter-edit-builder-funcs-rmwhitespace": "Fjern mellomrom (rmwhitespace)", "abusefilter-edit-builder-funcs-rmspecials": "Fjern spesialtegn (rmspecials)", "abusefilter-edit-builder-funcs-ip_in_range": "Er IP-en i innenfor område? (ip_in_range)", - "abusefilter-edit-builder-funcs-contains-any": "Søkestrengen for flere delstrenger (contains_any)", + "abusefilter-edit-builder-funcs-contains-any": "Søk etter flere understrenger i en streng i OR-modus. (contains_any)", + "abusefilter-edit-builder-funcs-contains-all": "Søk etter flere understrenger i en streng i AND-modus. (contains_all)", + "abusefilter-edit-builder-funcs-equals-to-any": "Sjekk om et gitt argument er likt (===) noen av de etterfølgende argumentene (equals_to_any)", "abusefilter-edit-builder-funcs-substr": "Delstreng (substr)", "abusefilter-edit-builder-funcs-strpos": "Delstrengens posisjon i strengen (strpos)", "abusefilter-edit-builder-funcs-str_replace": "Erstatt delstreng med streng (str_replace)", "abusefilter-edit-builder-funcs-rescape": "Escape-streng som litteral i regulæruttrykk (regex/rescape)", "abusefilter-edit-builder-funcs-set_var": "Sett variabel (set_var)", + "abusefilter-edit-builder-funcs-sanitize": "Normaliser HTML-entiteter til Unicode-tegn (sanitize)", "abusefilter-edit-builder-group-vars": "Variabler", "abusefilter-edit-builder-vars-accountname": "Kontonavn (on account creation)", "abusefilter-edit-builder-vars-timestamp": "Unix-tidsstempel ved endring", + "abusefilter-edit-builder-vars-timestamp-expanded": "Tidsstempel for loggen", "abusefilter-edit-builder-vars-action": "Handling", "abusefilter-edit-builder-vars-addedlines": "Linjer lagt til i redigering", "abusefilter-edit-builder-vars-delta": "Størrelsesendring i redigering", @@ -291,19 +370,22 @@ "abusefilter-edit-builder-vars-old-content-model": "Gammel innholdsmodell", "abusefilter-edit-builder-vars-new-content-model": "Ny innholdsmodell", "abusefilter-edit-builder-vars-removedlines": "Linjer fjernet i redigering", - "abusefilter-edit-builder-vars-summary": "Redigeringssammendrag", - "abusefilter-edit-builder-vars-page-id": "Artikkel-ID", - "abusefilter-edit-builder-vars-page-ns": "Artikkelnavnerom", - "abusefilter-edit-builder-vars-page-title": "Artikkeltittel (uten navnerom)", - "abusefilter-edit-builder-vars-page-prefixedtitle": "Full artikkeltittel", - "abusefilter-edit-builder-vars-movedfrom-id": "Artikkel-ID til kildeside ved flytting", + "abusefilter-edit-builder-vars-summary": "Redigeringsforklaring", + "abusefilter-edit-builder-vars-page-id": "Side-ID", + "abusefilter-edit-builder-vars-page-ns": "Sidenavnerom", + "abusefilter-edit-builder-vars-page-title": "Sidetittel (uten navnerom)", + "abusefilter-edit-builder-vars-page-prefixedtitle": "Full sidetittel", + "abusefilter-edit-builder-vars-page-age": "Sidealder (i sekunder)", + "abusefilter-edit-builder-vars-movedfrom-id": "Side-ID til kildeside ved flytting", "abusefilter-edit-builder-vars-movedfrom-ns": "Navnerom til målside ved flytting", "abusefilter-edit-builder-vars-movedfrom-title": "Tittel til kildeside ved flytting", "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "Full tittel til kildeside ved flytting", - "abusefilter-edit-builder-vars-movedto-id": "Artikkel-ID til målside ved flytting", + "abusefilter-edit-builder-vars-movedfrom-age": "Sidealder for flyttekilde (i sekunder)", + "abusefilter-edit-builder-vars-movedto-id": "Side-ID til målside ved flytting", "abusefilter-edit-builder-vars-movedto-ns": "Navnerom til målside ved flytting", "abusefilter-edit-builder-vars-movedto-title": "Tittel til målside ved flytting", "abusefilter-edit-builder-vars-movedto-prefixedtitle": "Full tittel til målside ved flytting", + "abusefilter-edit-builder-vars-movedto-age": "Sidealder for flyttemål (i sekunder)", "abusefilter-edit-builder-vars-user-editcount": "Brukers redigeringsteller", "abusefilter-edit-builder-vars-user-age": "Alder på brukerkontoen", "abusefilter-edit-builder-vars-user-name": "Navn på brukerkonto", @@ -313,24 +395,36 @@ "abusefilter-edit-builder-vars-user-emailconfirm": "Tid e-postadresse ble bekreftet", "abusefilter-edit-builder-vars-recent-contributors": "De siste ti bidragsyterene til siden", "abusefilter-edit-builder-vars-first-contributor": "Første bidragsyter til siden", + "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "De siste ti brukerne som har bidratt til flyttekilden", + "abusefilter-edit-builder-vars-movedfrom-first-contributor": "Den første brukeren som bidro til flyttekildesiden", + "abusefilter-edit-builder-vars-movedto-recent-contributors": "De siste ti brukerne som har bidratt til flyttemålsiden", + "abusefilter-edit-builder-vars-movedto-first-contributor": "Den første brukeren som bidro til flyttemålsiden", "abusefilter-edit-builder-vars-all-links": "Alle eksterne lenker i den nye teksten", "abusefilter-edit-builder-vars-added-links": "Alle eksterne lenker lagt til i endringen", "abusefilter-edit-builder-vars-removed-links": "Alle eksterne lenker fjernet i endringen", - "abusefilter-edit-builder-vars-old-text": "Den gamle wikiteksten til siden før endringen", - "abusefilter-edit-builder-vars-new-text": "Den nye wikiteksten til siden etter endringen", + "abusefilter-edit-builder-vars-old-wikitext": "Den gamle wikiteksten til siden, før endringen", + "abusefilter-edit-builder-vars-new-wikitext": "Den nye wikiteksten til siden, etter endringen", "abusefilter-edit-builder-vars-new-pst": "Ny side med wikitekst, transformert fra «pre-save»", "abusefilter-edit-builder-vars-diff-pst": "Enhetlig diff av endringer gjort under redigering, transformert fra «pre-save»", "abusefilter-edit-builder-vars-addedlines-pst": "Linjer lagt til under redigering, transformert fra «pre-save»", - "abusefilter-edit-builder-vars-new-text-stripped": "Ny sidetekst, uten markeringer", + "abusefilter-edit-builder-vars-new-text": "Ny sidetekst, uten markeringer", "abusefilter-edit-builder-vars-new-html": "Tolket HTML-kode for den nye versjonen", "abusefilter-edit-builder-vars-restrictions-edit": "Beskyttelsesnivå for redigering av siden", "abusefilter-edit-builder-vars-restrictions-move": "Beskyttelsesnivå for flytting av siden", "abusefilter-edit-builder-vars-restrictions-create": "Beskytt siden mot opprettelse", "abusefilter-edit-builder-vars-restrictions-upload": "Opplastingsbeskyttelse for filen", - "abusefilter-edit-builder-vars-old-text-stripped": "Gammel sidetekst, renset for all koding", + "abusefilter-edit-builder-vars-movedfrom-restrictions-edit": "Redigeringsbeskyttelsesnivået til flyttekildesiden", + "abusefilter-edit-builder-vars-movedfrom-restrictions-move": "Flyttebeskyttelsesnivået til flyttekildesiden", + "abusefilter-edit-builder-vars-movedfrom-restrictions-create": "Opprettelsesbeskyttelsesnivået til flyttekildesiden", + "abusefilter-edit-builder-vars-movedfrom-restrictions-upload": "Opplastingsbeskyttelsesnivået til flyttekildefila", + "abusefilter-edit-builder-vars-movedto-restrictions-edit": "Redigeringsbeskyttelsesnivået til flyttemålsiden", + "abusefilter-edit-builder-vars-movedto-restrictions-move": "Flyttebeskyttelsesnivået til flyttemålsiden", + "abusefilter-edit-builder-vars-movedto-restrictions-create": "Opprettelsesbeskyttelsesnivået til flyttemålsiden", + "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Opplastingsbeskyttelsesnivået til flyttemålfila", + "abusefilter-edit-builder-vars-old-text": "Gammel sidetekst, renset for all koding", "abusefilter-edit-builder-vars-old-links": "Lenker på denne siden, før redigeringen", - "abusefilter-edit-builder-vars-old-html": "Gammel wikitekst på siden, tolket til HTML", - "abusefilter-edit-builder-vars-minor-edit": "Hvorvidt denne endringen er markert som mindre endring", + "abusefilter-edit-builder-vars-old-html": "Gammel wikitekst på siden, tolket til HTML (ikke lenger ikke bruk)", + "abusefilter-edit-builder-vars-minor-edit": "Hvorvidt denne endringen er markert som mindre endring (ikke lenger i bruk)", "abusefilter-edit-builder-vars-file-sha1": "SHA1-hash av filinnhold", "abusefilter-edit-builder-vars-file-size": "Filstørrelsen i byte", "abusefilter-edit-builder-vars-file-mime": "Filas MIME-type", @@ -338,6 +432,8 @@ "abusefilter-edit-builder-vars-file-width": "Filas bredde i piksler", "abusefilter-edit-builder-vars-file-height": "Filas høyde i piksler", "abusefilter-edit-builder-vars-file-bits-per-channel": "Filas bit per fargekanal", + "abusefilter-edit-builder-vars-wiki-name": "Databasenavnet til wikien", + "abusefilter-edit-builder-vars-wiki-language": "Wikiens språkkode", "abusefilter-filter-log": "Siste filterendringer", "abusefilter-history": "Endringshistorikk for misbruksfilteret #$1", "abusefilter-history-foruser": "Endringer av $1", @@ -354,9 +450,10 @@ "abusefilter-history-backedit": "Tilbake til filterredigering", "abusefilter-history-deleted": "Slettet", "abusefilter-history-filterid": "Filter", - "abusefilter-history-select-legend": "Utvid søk", + "abusefilter-history-select-legend": "Fininnstill søk", "abusefilter-history-select-user": "Bruker:", - "abusefilter-history-select-submit": "Utdyp", + "abusefilter-history-select-filter": "Filter-ID:", + "abusefilter-history-select-submit": "Fininnstill", "abusefilter-history-diff": "Endringer", "abusefilter-history-error-hidden": "Filteret du ba om, er skjult, og du kan ikke se historikken til det.", "abusefilter-exception-unexpectedatend": "Uventet «$2» ved tegn nummer $1.", @@ -370,18 +467,24 @@ "abusefilter-exception-dividebyzero": "Ulovlig forsøk på å dele $2 med null ved tegn nummer $1.", "abusefilter-exception-unrecognisedvar": "Ukjent variabel $2 ved tegn nummer $1.", "abusefilter-exception-notenoughargs": "Funksjonskallet $2 ved tegn $1 hadde ikke nok argumenter.\nForventet {{PLURAL:$3|ett argument|$3 argumenter}}, fikk $4", - "abusefilter-exception-regexfailure": "Feil i det regulære uttrykket «$3» ved tegn $1: «$2»", - "abusefilter-exception-overridebuiltin": "Ulovlig overstyring av innebygd variabel «$2» ved tegn $1.", + "abusefilter-exception-toomanyargs": "For mange argumenter til funksjonen $2 kalt ved tegn $1.\nForventet maksimalt $3 {{PLURAL:$3|argument|argumenter}}, fikk $4.", + "abusefilter-exception-regexfailure": "Feil i det regulære uttrykket «$2» ved tegn $1.", + "abusefilter-exception-overridebuiltin": "Ulovlig overstyring av innebygd identifikator «$2» ved tegn $1.", "abusefilter-exception-outofbounds": "Ber om ikke-eksisterende listeelement $2 (listestørrelse = $3) ved tegn $1.", + "abusefilter-exception-negativeindex": "Negative søk tillates ikke i tabeller. Fikk indeksen «$2» ved tegn $1.", "abusefilter-exception-notarray": "Ber om tabellelement fra en ikke-tabell ved tegn $1.", - "abusefilter-action-tag": "Merkelapp", + "abusefilter-exception-unclosedcomment": "Ikke-lukket kommentar ved tegn $1.", + "abusefilter-exception-invalidiprange": "Ugyldig IP-intervall «$2» gitt ved tegn $1.", + "abusefilter-exception-disabledvar": "Variabelen $2 ved tegn $1 er ikke lenger i bruk.", + "abusefilter-exception-variablevariable": "set og set_var forventer at forventer at det første argumentet er en streng, funnet ved tegn $1.", + "abusefilter-action-tag": "Tagg", "abusefilter-action-throttle": "Begrensning av endringshastighet", "abusefilter-action-warn": "Advar", "abusefilter-action-blockautopromote": "Blokkere automatisk bekreftelse", "abusefilter-action-block": "Blokker", "abusefilter-action-degroup": "Fjerne fra grupper", "abusefilter-action-rangeblock": "Blokkering av område", - "abusefilter-action-disallow": "Nekt", + "abusefilter-action-disallow": "Ikke tillat", "abusefilter-revert-title": "Tilbakestill alle endringer av filteret $1", "abusefilter-revert-intro": "Dette skjemaet lar deg tilbakestille alle endringer utført av redigeringsfilteret $1. Vær forsiktig når du bruker dette verktøyet.", "abusefilter-revert-preview-item": "$1: $2 {{GENDER:$7|gjorde}} en $3 på $4.\nHandlinger som skal tilbakestilles: $5 ($6)", @@ -433,36 +536,44 @@ "abusefilter-examine-syntaxerror": "Filteret har en ugyldig syntaks", "abusefilter-examine-notfound": "Endringen du ba om ble ikke funnet.", "abusefilter-examine-incompatible": "Endringen du ba om er ikke støttet av redigeringsfilteret", - "abusefilter-examine-noresults": "Fant ingen resultat for søkeparametrene du anga.", + "abusefilter-examine-noresults": "Fant ingen resultater for søkeparametrene du anga.", "abusefilter-topnav": "'''Navigasjon for redigeringsfilter'''", "abusefilter-topnav-home": "Hjem", + "abusefilter-topnav-recentchanges": "Nylige filterendringer", "abusefilter-topnav-test": "Gruppetesting", "abusefilter-topnav-examine": "Gransk tidligere endringer", "abusefilter-topnav-log": "Misbrukslogg", "abusefilter-topnav-tools": "Feilsøkingsverktøy", - "abusefilter-topnav-import": "Importer filter", "abusefilter-log-name": "Redigeringsfilterlogg", "abusefilter-log-header": "Denne loggen viser et sammendrag av endringer gjort i filtrene.\nFor fullstendige detaljer, se [[Special:AbuseFilter/history|listen]] over de siste filterendringene.", "abusefilter-logentry-create": "$1 {{GENDER:$2|opprettet}} $4 ($5)", "abusefilter-logentry-modify": "$1 {{GENDER:$2|endret}} $4 ($5)", + "abusefilter-log-invalid-filter": "Noen av de gitte filter-ID-ene er ugyldige.", "abusefilter-log-noresults": "Ingen resultater", "abusefilter-diff-title": "Forskjeller mellom versjoner", "abusefilter-diff-item": "Element", "abusefilter-diff-version": "Versjon fra $1 {{GENDER:$3|av}} $2", "abusefilter-diff-info": "Grunnleggende informasjon", - "abusefilter-diff-pattern": "Filterregler", + "abusefilter-diff-pattern": "Filterbetingelser", "abusefilter-diff-invalid": "Klarte ikke å hente de ønskede versjonene", "abusefilter-diff-backhistory": "Tilbake til filterhistorikk", "abusefilter-diff-prev": "Eldre endring", "abusefilter-diff-next": "Nyere endring", "abusefilter-import-intro": "Du kan bruke dette grensesnittet for å importere filtre fra andre wikier.\nI kildewikien klikker du på «{{int:abusefilter-edit-export}}» under «{{int:abusefilter-edit-tools}}» i redigeringsgrensesnittet.\nKopier fra tekstruten som kommer frem og lim inn i denne tekstruten. Klikk så på «{{int:abusefilter-import-submit}}».", "abusefilter-import-submit": "Importer data", + "abusefilter-import-invalid-data": "Dataene du prøvde å importere er ugyldige", "abusefilter-group-default": "Standard", "abusefilter-http-error": "En HTTP-feil oppstod: $1", - "abusefilter-view-private-submit": "Vis private detaljer", - "abusefilter-view-private": "Vis private detaljer", + "abusefilter-view-privatedetails-submit": "Vis private detaljer", + "abusefilter-view-privatedetails-legend": "Vis private detaljer", + "abusefilter-view-privatedetails-reason": "Årsak for tilgang til private detaljer:", "abusefilter-log-details-id": "Logg-ID", "abusefilter-invalid-request": "Ugyldig forespørsel! For å få tilgang til private loggdetaljer må du gå via skjemaet på [[Special:AbuseLog/$1]] og angi en årsak.", + "abusefilter-invalid-request-noid": "Ugyldig forespørsel! For å få tilgang til private loggdetaljer må du gå via skjemaet på detaljsiden til misbruksloggen og oppgi en årsak.", + "log-description-abusefilterprivatedetails": "Denne loggen viser en liste over tider en bruker har fått tilgang til private detaljer i en misbrukslogg.", + "abusefilter-noreason": "Advarsel: For å se private detaljer i denne loggen må du angi en årsak.", "abusefilter-log-ip-not-available": "Ikke tilgjengelig", - "abusefilter-tag-reserved": "Taggen <code>abusefilter-condition-limit</code> er reservert for intern bruk av misbruksfilteret." + "abusefilter-tag-reserved": "Taggen <code>abusefilter-condition-limit</code> er reservert for intern bruk av misbruksfilteret.", + "tag-abusefilter-condition-limit": "vilkårsgrense nådd", + "tag-abusefilter-condition-limit-description": "Redigeringer eller andre handlinger som ikke kunne sjekkes av alle aktive [[Special:AbuseFilter|misbruksfiltre]] ([[mw:Extension:AbuseFilter/Conditions|hjelp]])." } diff --git a/AbuseFilter/i18n/nds-nl.json b/AbuseFilter/i18n/nds-nl.json index c6dd8815..96d20e35 100644 --- a/AbuseFilter/i18n/nds-nl.json +++ b/AbuseFilter/i18n/nds-nl.json @@ -5,8 +5,8 @@ ] }, "abusefilter-desc": "Voert automaties heuristiese analyse uut op bewarkingen", - "abusefilter": "Filterinstellingen", - "abuselog": "Filterlogboek", + "abusefilter": "Beheyr van misbruukfilter", + "abuselog": "Misbruukfilterlogbook", "abusefilter-intro": "Welkom bie t beheerscharm veur bewarkingsfilters.\nt Filtersysteem past automatiese heuristiek toe op alle haandelingen.\nDit scharm löt alle in-estelden filters zien, en gif de meugelikheid ze an te passen.", "abusefilter-warning": "'''Waorschuwing''': disse haandeling wörden automaties as schaolik ezien.\nOnkonstruktieve haandelingen wörden gauw weerummedreid, en herhaoldelik onkonstruktief bewarken eindigt in n blokkering van joew gebruker of IP-adres.\nA'j denken dat disse haandeling wel konstruktief is, bevestig joew haandeling dan nogmaols.\nn Korte beschrieving van de regel op baosis waorvan joew haandeling tegenehölden is: $1", "abusefilter-disallowed": "Disse haandeling wörden automaties as schaolik ezien, en is daorumme niet toe-estaon.\nA'j denken dat joew haandeling wel konstruktief was, meld dan an de beheerder wa'j probeerden te doon.\nn Korte beschrieving van de regel op baosis waorvan joew haandeling tegenehölden is: $1", @@ -19,27 +19,26 @@ "abusefilter-accountreserved": "Disse gebrukersnaam is ereserveerd veur de misbruukfilter", "right-abusefilter-modify": "Misbruukfilters wiezigen", "right-abusefilter-view": "Misbruukfilters bekieken", - "right-abusefilter-log": "t Misbruukfilterlogboek bekieken", + "right-abusefilter-log": "Et misbruukfilterlogbook bekyken", "right-abusefilter-log-detail": "Details van misbruuklogboekregels bekieken", - "right-abusefilter-private": "Priveegegevens in t misbruuklogboek bekieken", + "right-abusefilter-privatedetails": "Priveegegevens in t misbruuklogboek bekieken", "right-abusefilter-modify-restricted": "Misbruukfilters mit beteunden haandelingen wiezigen", "right-abusefilter-revert": "Alle wiezigingen deur n misbruukfilter weerummedreien", "right-abusefilter-view-private": "Misbruukfilters bekieken die as privee emarkeerd bin", "right-abusefilter-log-private": "Logboekregels bekieken veur misbruukfilter die emarkeerd bin as privee", - "right-abusefilter-hide-log": "Meldinging in t misbruukfilterlogboek verbargen", + "right-abusefilter-hide-log": "Meldingen in et misbruukfilterlogbook verbargen", "right-abusefilter-hidden-log": "Verbörgen misbruuklogboekregels bekieken", "right-abusefilter-modify-global": "Globale misbruukfilters anmaken of anpassen", "action-abusefilter-modify": "misbruukfilters wiezigen", "action-abusefilter-view": "misbruukfilters bekieken", - "action-abusefilter-log": "t misbruukfilterlogboek bekieken", + "action-abusefilter-log": "et misbruukfilterlogbook bekyken", "action-abusefilter-log-detail": "details van misbruuklogboekregels bekieken", - "action-abusefilter-private": "priveegegevens in t misbruuklogboek bekieken", + "action-abusefilter-privatedetails": "priveegegevens in t misbruuklogboek bekieken", "action-abusefilter-modify-restricted": "misbruukfilters mit beteunden haandelingen wiezigen", "action-abusefilter-revert": "alle wiezigingen deur n misbruukfilter weerummedreien", "action-abusefilter-view-private": "misbruukfilters bekieken die as privee emarkeerd bin", - "abusefilter-log": "Misbruukfilterlogboek", "abusefilter-log-summary": "Dit logboek löt n lieste zien van haandelingen die de filters op-evöngen hebben.", - "abusefilter-log-search": "t Misbruukfilterlogboek deurzeuken", + "abusefilter-log-search": "Et misbruukfilterlogbook döärsöken", "abusefilter-log-search-user": "Gebruker:", "abusefilter-log-search-filter": "Filternummer:", "abusefilter-log-search-title": "Titel:", @@ -56,12 +55,11 @@ "abusefilter-log-details-var": "Variabel", "abusefilter-log-details-val": "Weerde", "abusefilter-log-details-vars": "Maotregelparameters", - "abusefilter-log-details-private": "Beparkt zichtbaore gegevens", + "abusefilter-log-details-privatedetails": "Beparkt zichtbaore gegevens", "abusefilter-log-details-ip": "IP-adres", "abusefilter-log-noactions": "gien", "abusefilter-log-details-diff": "Wiezigingen in de bewarking", - "abusefilter-log-linkoncontribs": "filterlogboek", - "abusefilter-log-hidden": "(melding verbörgen)", + "abusefilter-log-linkoncontribs": "misbruuklogbook", "abusefilter-log-hide-legend": "Logboekregel verbargen", "abusefilter-log-hide-id": "Logboekmeldingsnummer:", "abusefilter-log-hide-reason": "Reden:", @@ -93,7 +91,7 @@ "abusefilter-tools-submitexpr": "Evalueren", "abusefilter-tools-reautoconfirm-user": "Gebruker:", "abusefilter-tools-reautoconfirm-submit": "Opniej automaties bevestigen", - "abusefilter-edit-status-label": "Staotistieken:", + "abusefilter-edit-status-label": "Statistiken:", "abusefilter-edit-new": "Nieje filter", "abusefilter-edit-save": "Filter opslaon", "abusefilter-edit-id": "Filternummer:", @@ -107,12 +105,12 @@ "abusefilter-edit-hitcount": "Filtertreffers:", "abusefilter-edit-throttle-period": "Tiedspanne:", "abusefilter-edit-warn-other": "Aander bericht", - "abusefilter-edit-warn-actions": "Haandelingen:", + "abusefilter-edit-warn-actions": "Handelingen:", "abusefilter-edit-main": "Filterparameters", "abusefilter-edit-done-subtitle": "Filter ewiezigd", "abusefilter-edit-history": "Geschiedenisse:", "abusefilter-edit-builder-group-op-arithmetic": "Aritmiese operatoren", - "abusefilter-edit-builder-op-arithmetic-addition": "Optellen (+)", + "abusefilter-edit-builder-op-arithmetic-addition": "Uptellen (+)", "abusefilter-edit-builder-op-arithmetic-subtraction": "Aoftrekken (-)", "abusefilter-edit-builder-op-arithmetic-multiplication": "Vermenigvuldigen (*)", "abusefilter-edit-builder-op-arithmetic-divide": "Delen (/)", @@ -141,7 +139,7 @@ "abusefilter-edit-builder-funcs-substr": "Tekstdeel (substr)", "abusefilter-edit-builder-funcs-set_var": "Variabele instellen (set_var)", "abusefilter-edit-builder-group-vars": "Variabels", - "abusefilter-edit-builder-vars-action": "Aksie", + "abusefilter-edit-builder-vars-action": "Handeling", "abusefilter-edit-builder-vars-delta": "Groottewieziging", "abusefilter-edit-builder-vars-newsize": "Nieje ziedgrootte", "abusefilter-edit-builder-vars-oldsize": "Ouwe ziedgrootte", @@ -158,7 +156,7 @@ "abusefilter-history-flags": "Markeringen", "abusefilter-history-filter": "Filterregel", "abusefilter-history-comments": "Opmarkingen", - "abusefilter-history-actions": "Maotregels", + "abusefilter-history-actions": "Måtregels", "abusefilter-history-deleted": "Vortedaon", "abusefilter-history-filterid": "Filter", "abusefilter-history-select-legend": "Zeukopdrachte verfienen", @@ -177,5 +175,7 @@ "abusefilter-revert-periodstart": "Begin periode:", "abusefilter-revert-periodend": "Einde periode:", "abusefilter-revert-search": "Maotregels selekteren", - "abusefilter-revert-filter": "Filter:" + "abusefilter-revert-filter": "Filter:", + "abusefilter-examine-user": "Gebruker:", + "abusefilter-topnav-log": "Misbruuklogbook" } diff --git a/AbuseFilter/i18n/nds.json b/AbuseFilter/i18n/nds.json index 0c4003a9..d616649a 100644 --- a/AbuseFilter/i18n/nds.json +++ b/AbuseFilter/i18n/nds.json @@ -1,14 +1,16 @@ { "@metadata": { "authors": [ + "Fitoschido", "Joachim Mos", - "Slomox", - "Matma Rex" + "Matma Rex", + "Servien", + "Slomox" ] }, "abusefilter-desc": "Föhrt automaatsch heuristische Analysen op Ännern ut", "abusefilter": "Missbruukfilter instellen", - "abuselog": "Missbruuk-Logbook", + "abuselog": "Missbruukfilter-Logbook", "abusefilter-intro": "Willkamen bi dat Verwalten vun’n Missbruukfilter.\nDe Missbruukfilter it en automaatsch Warktüüch, dat automaatsche Heuristiken op all Ännern anwennt.\nDisse Bildschirm wiest en List mit all defineerte Filters un verlöövt dat, jem to ännern.", "abusefilter-warning": "'''Wohrschau''': Diene Akschoon is dör en automaatschen Filter as mööglicherwies negativ kennt worrn.\nSo’n Bidrääg warrt normalerwies gau wedder utsorteert. Wenn dat fakener vörkummt oder to dull is, denn warrt dien Brukerkonto oder dien IP-Adress sperrt.\nWenn du meenst, dat dien Ännern nich negativ is, denn kannst du noch wedder versöken em to spiekern.\nDor liggt dat an, dat de Filter meckert: $1", "abusefilter-disallowed": "Diene Akschoon is dör en automaatschen Filter as negativ kennt worrn un is nich verlöövt.\nWenn du meenst, dat dien Ännern nich negativ is, denn kannst du en Administrater schrieven un em seggen, wat du doon wullst, dat he di helpt.\nDor liggt dat an, dat de Filter meckert: $1", @@ -23,21 +25,20 @@ "right-abusefilter-view": "Missbruukfilters ankieken", "right-abusefilter-log": "Missbruukfilter-Logbook ankieken", "right-abusefilter-log-detail": "Missbruukfilter-Logbook mit mehr Details ankieken", - "right-abusefilter-private": "Private Daten in dat Missbruukfilter-Logbook ankieken", + "right-abusefilter-privatedetails": "Private Daten in dat Missbruukfilter-Logbook ankieken", "right-abusefilter-modify-restricted": "Missbruukfilter mit verbadene Akschonen ännern", "right-abusefilter-revert": "All Ännern na en Missbruukfilter trüchdreihn", "action-abusefilter-modify": "Missbruukfilters ännern", "action-abusefilter-view": "Missbruukfilters ankieken", "action-abusefilter-log": "Missbruukfilter-Logbook ankieken", "action-abusefilter-log-detail": "dat Missbruukfilter-Logbook mit mehr Details ankieken", - "action-abusefilter-private": "private Daten in’t Missbruukfilter-Logbook antokieken", + "action-abusefilter-privatedetails": "private Daten in’t Missbruukfilter-Logbook antokieken", "action-abusefilter-modify-restricted": "Missbruukfilters mit verbadene Akschonen to ännern", "action-abusefilter-revert": "all Ännern na en bestimmten Missbruukfilter trüchtodreihn", - "abusefilter-log": "Missbruukfilter-Logbook", "abusefilter-log-summary": "Dit Logbook wiest en List mit all Akschonen, bi de en Filter anslagen hett.", "abusefilter-log-search": "In dat Missbruukfilter-Logbook söken", "abusefilter-log-search-user": "Bruker:", - "abusefilter-log-search-filter": "Filter-ID:", + "abusefilter-log-search-filter": "Filter-ID's:", "abusefilter-log-search-title": "Titel:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-submit": "Söken", @@ -50,13 +51,12 @@ "abusefilter-log-details-var": "Variable", "abusefilter-log-details-val": "Weert", "abusefilter-log-details-vars": "Akschoonsparameters", - "abusefilter-log-details-private": "Private Daten", + "abusefilter-log-details-privatedetails": "Private Daten", "abusefilter-log-details-ip": "IP-Adress", "abusefilter-log-noactions": "keen", "abusefilter-log-details-diff": "Wat sik mit’t Ännern ännert hett", "abusefilter-log-linkoncontribs": "Missbruuk-Logbook", "abusefilter-log-linkoncontribs-text": "Missbruuk-Logbook för dissen Bruker", - "abusefilter-management": "Missbruukfilter instellen", "abusefilter-list": "All Filters", "abusefilter-list-id": "Filter-ID", "abusefilter-list-status": "Status", @@ -75,6 +75,7 @@ "abusefilter-disabled": "Utstellt", "abusefilter-hitcount": "$1 {{PLURAL:$1|Fund|Funnen}}", "abusefilter-new": "Stell en ne’en Filter op", + "abusefilter-import-button": "Filter importeren", "abusefilter-return": "Trüch na Filter instellen", "abusefilter-status-global": "Globaal", "abusefilter-list-options": "Optionen", @@ -98,7 +99,6 @@ "abusefilter-edit-oldwarning": "<strong>Du ännerst jüst en ole Version vun’n Filter.\nDe Statistik gellt blot för de jüngste Version vun’n Filter.\nWenn du spiekerst, warrt all Ännern överschreven, de sieddem an’n Filter maakt worrn sünd.</strong> •\n[[Special:AbuseFilter/history/$2|Trüch na de Versionsgeschicht vun’n Filter]].", "abusefilter-edit-status-label": "Statistiken:", "abusefilter-edit-status": "Vun de {{PLURAL:$1|leste een Akschoon|lesten $1 Akschonen}} hett de Filter op $2 ($3 %) passt.\nIn’n Dörsnidd is de Looptied $4 ms.", - "abusefilter-edit-status-profile": "Vun de {{PLURAL:$1|leste een Akschoon|lesten $1 Akschonen}} hett de Filter op $2 ($3 %) passt.\nIn’n Dörsnidd is de Looptied $4 ms.", "abusefilter-edit-new": "Nee Filter", "abusefilter-edit-save": "Filter spiekern", "abusefilter-edit-id": "Filter-ID:", @@ -222,13 +222,13 @@ "abusefilter-edit-builder-vars-all-links": "All Lenken na buten in’n ne’en Text", "abusefilter-edit-builder-vars-added-links": "All toföögt Lenken na buten", "abusefilter-edit-builder-vars-removed-links": "All rutnahmen Lenken na buten", - "abusefilter-edit-builder-vars-old-text": "Olen Wikitext vun de Sied, vör’t Ännern", - "abusefilter-edit-builder-vars-new-text": "Ne’en Wikitext vun de Sied, na’t Ännern", - "abusefilter-edit-builder-vars-new-text-stripped": "Ne’en Wikitext vun de Sied, all Wikisyntax rutnahmen", + "abusefilter-edit-builder-vars-old-wikitext": "Olen Wikitext vun de Sied, vör’t Ännern", + "abusefilter-edit-builder-vars-new-wikitext": "Ne’en Wikitext vun de Sied, na’t Ännern", + "abusefilter-edit-builder-vars-new-text": "Ne’en Wikitext vun de Sied, all Wikisyntax rutnahmen", "abusefilter-edit-builder-vars-new-html": "HTML-Borntext vun de ne’e Version", "abusefilter-edit-builder-vars-restrictions-edit": "Schuul-Graad för Ännern an de Sied", "abusefilter-edit-builder-vars-restrictions-move": "Schuul-Graad för’t Schuven vun de Sied", - "abusefilter-edit-builder-vars-old-text-stripped": "Olen Wikitext vun de Sied, all Wikisyntax rutnahmen", + "abusefilter-edit-builder-vars-old-text": "Olen Wikitext vun de Sied, all Wikisyntax rutnahmen", "abusefilter-edit-builder-vars-old-links": "Lenken in de Sied, vör dat Ännern", "abusefilter-edit-builder-vars-old-html": "HTML-Borntext vun de ole Version", "abusefilter-edit-builder-vars-minor-edit": "Is de Ännern as lütt kenntekent", @@ -264,7 +264,7 @@ "abusefilter-exception-dividebyzero": "Bi Teken $1 warrt versöcht $2 dör Null to delen.", "abusefilter-exception-unrecognisedvar": "Variabel $2 bi Teken $1 nich kennt", "abusefilter-exception-notenoughargs": "De Funkschoon $2 sünd bi Teken $1 to wenig Parameters övergeven worrn.\n{{PLURAL:$3|$3 Parameter|$3 Parameters}} weren verwacht, dor {{PLURAL:$4|weer $4|weren $4}}.", - "abusefilter-exception-regexfailure": "Fehler in’n regulären Utdruck „$3“ bi Teken $1: „$2“", + "abusefilter-exception-regexfailure": "Fehler in’n regulären Utdruck „$2“ bi Teken $1.", "abusefilter-exception-overridebuiltin": "Verbaden Överschrieven vun inboot Variabel „$2“ bi Teken $1.", "abusefilter-exception-outofbounds": "Anfeddern vun en nich vörhannen Listenindrag $2 (Listengrött: $3) bi Teken $1.", "abusefilter-exception-notarray": "Anfeddern vun en Arrayelement ut en Nich-Array bi Teken „$1“.", @@ -324,7 +324,6 @@ "abusefilter-topnav-examine": "Öller Ännern ünnersöken", "abusefilter-topnav-log": "Missbruuk-Logbook", "abusefilter-topnav-tools": "Fehlersöök-Warktüüch", - "abusefilter-topnav-import": "Filter importeren", "abusefilter-log-name": "Missbruukfilter-Logbook", "abusefilter-log-header": "Dit Logbook wiest en Översicht över Ännern an Filters.\nFör mehr Details, kiek di [[Special:AbuseFilter/history|de List]] mit de lesten Ännern an Filters an.", "abusefilter-diff-title": "Ünnerscheed twischen Versionen", diff --git a/AbuseFilter/i18n/ne.json b/AbuseFilter/i18n/ne.json index 869e006a..8997194a 100644 --- a/AbuseFilter/i18n/ne.json +++ b/AbuseFilter/i18n/ne.json @@ -4,11 +4,14 @@ "Bhawani Gautam", "Bhawani Gautam Rhk", "Krish Dulal", + "Matma Rex", + "Nirajan pant", "RajeshPandey", - "सरोज कुमार ढकाल", + "पर्वत सुबेदी", "बिप्लब आनन्द", "राम प्रसाद जोशी", - "Matma Rex" + "सरोज कुमार ढकाल", + "हिमाल सुबेदी" ] }, "abusefilter-desc": "स्वचालित अनुमानित सम्पादनहरुकोनिम्ति लागु हुन्छ", @@ -18,25 +21,31 @@ "abusefilter-warning": "'''चेतावनी:''' यो कार्य हानिकारक भनेर स्वतः चिनियो।\nध्वंसात्मक सम्पादन शीघ्र उल्टाइनेछ,\nर जबरजस्ती अथवा ध्वंसात्मक सम्पादन दोहोराएको परिणाम स्वरुप तपाईंको खाता अथवा IP ठेगानामा प्रतिबन्ध लगाइनेछ।\nयदि तपाईं आफ्नो सम्पादन रचनात्मक भएकोमा विश्वस्त हुनुहुन्छ भनें पुनः '''संग्रह गर्नुहोस्'''मा क्लिक गरेर सुनिश्चित गर्नुहोस्।\nदुर्व्यहार नीति जसमा तपाईंको कार्यसित मेल खाइरहेछ, यसको एउटा संक्षिप्त विवरण यस प्रकार छ: $1", "abusefilter-disallowed": "यो कार्य हानिकारक भनेर स्वतः चिनियो, अनि यसकारण अनुमति छैन।\nयदि तपाईं आफ्नो सम्पादन रचनात्मक भएकोमा विश्वस्त हुनुहुन्छ भनें कृपया तपाईंले के गर्ने प्रयास गर्नु हुँदै थियो यो कुरा कुनै एक जना प्रबन्धकलाई जनाउनुहोस् ।\nदुर्व्यहार नीति जसमा तपाईंको कार्यसित मेल खाइरहेछ, यसको एउटा संक्षिप्त विवरण यस प्रकार छ: $1", "abusefilter-blocked-display": "यो कार्य घातक भनेर स्वतः चिनियो,\nर तपाईंलाई यसको क्रियान्वयनमा रोक लगाइएकोछ।\nअनि {{SITENAME}}को सुरक्षाको निम्ति तपाईंको प्रयोगकर्ता खाता अनि सबै सम्बन्धित आई पी ठेगानाहरूमाथि पनि सम्पादन गर्न रोक\nलगाइएकोछ।\nयदि यो गल्तीले भएको भए कृपया प्रबन्धकसित सम्पर्क गर्नुहोला।\nयस गलत कार्य नीतिसित तपाईंको कार्यले मेल खाँदैछ, एउटा संक्षिप्त विवरण यस प्रकार छ :$1", - "abusefilter-blocker": "दुर्व्यवहार फिल्टर", + "abusefilter-blocker": "दुर्व्यवहार छनाेट", "right-abusefilter-modify": "दुर्व्यवहार फिल्टर परिमार्जन गर्ने", "right-abusefilter-view": "दुर्व्यवहार फिल्टरहरु हेर्ने", "right-abusefilter-log": "दुर्व्यवहार लग हेर्ने", "right-abusefilter-log-detail": "विस्तृत दुरुपयोग लग प्रविष्टीहरू हेर्नुहोस्", - "right-abusefilter-private": "दुरुपयोग लगमा व्यक्तिगत डेटा हर्ने", + "right-abusefilter-privatedetails": "दुरुपयोग लगमा व्यक्तिगत डेटा हर्ने", "action-abusefilter-modify": "दुर्व्यवहार फिल्टर परिवर्तन गर्ने", "action-abusefilter-view": "दुर्व्यवहार फिल्टरहरु हेर्ने", "action-abusefilter-log": "दुरुपयोग लगहरू हेर्नुहोस् \\", "action-abusefilter-log-detail": "विस्तृत दुरुपयोग लग प्रविष्टीहरु हेर्नुहोस् \\", - "abusefilter-log": "दुर्व्यवहार लग", "abusefilter-log-search": "दुर्व्यवहार लग खोज्ने", "abusefilter-log-search-user": "प्रयोगकर्ता:", - "abusefilter-log-search-filter": "फिल्टर परिचय:", + "abusefilter-log-search-group-any": "कुनै", + "abusefilter-log-search-filter": "छनाेट परिचय:", "abusefilter-log-search-title": "शीर्षक:", "abusefilter-log-search-wiki": "विकी:", + "abusefilter-log-search-impact-all": "सबै कार्यहरू", + "abusefilter-log-search-entries-label": "दृश्यता:", + "abusefilter-log-search-entries-all": "सबै प्रविष्टहरू", + "abusefilter-log-search-action-other": "अन्य", + "abusefilter-log-search-action-any": "कुनै", + "abusefilter-log-search-action-taken-any": "कुनै", "abusefilter-log-search-submit": "खोज्नुहोस्", "abusefilter-log-detailedentry-global": " विश्वव्यापी फिल्टर \"$1\" \\", - "abusefilter-log-detailedentry-local": "$1 फिल्टर गर्ने", + "abusefilter-log-detailedentry-local": "$1 छनाेट गर्नुहाेस्", "abusefilter-log-detailslink": "विवरण", "abusefilter-log-diff": "भिन्नता", "abusefilter-log-hidelink": "दर्शिता मिलाउने", @@ -44,13 +53,15 @@ "abusefilter-log-details-var": "चल राशी", "abusefilter-log-details-val": "मान", "abusefilter-log-details-vars": "कार्य प्यारामेटर", - "abusefilter-log-details-private": "निजी आँकड़ा", + "abusefilter-log-details-privatedetails": "निजी आँकड़ा", "abusefilter-log-details-ip": "सुरुवात गरिएको IP ठेगाना", + "abusefilter-log-details-checkuser": "प्रयोगकर्ता जाँच", "abusefilter-log-noactions": "कुनै पनि हैन", "abusefilter-log-details-diff": "सम्पादनमा गरिएका परिवर्तनहरू", "abusefilter-log-linkoncontribs": "दुर्व्यवहार लग", - "abusefilter-log-linkoncontribs-text": "यो प्रयोगकर्ताको दुरुपयोग लग", - "abusefilter-log-hidden": "(प्रविष्टि लुकाइएको)", + "abusefilter-log-linkoncontribs-text": "{{GENDER:$1याे प्रयाेगकर्ता|}}काे दुरुपयोग लग", + "abusefilter-log-linkonhistory": "दुरुपयोग लग हेर्नुहोस्", + "abusefilter-log-linkonundelete": "दुरुपयोग लग हेर्नुहोस्", "abusefilter-log-hidden-implicit": "(लुकाइएको छ किनभने संसोधन मेटिएको छ)", "abusefilter-log-cannot-see-details": "तपाईंलाई यस इन्ट्रीको विवरण हेर्ने अनुमति छैन।", "abusefilter-log-hide-legend": "लग प्रविष्टि लुकाउने", @@ -58,9 +69,9 @@ "abusefilter-log-hide-hidden": "सार्वजनिक रुपले हेर्न यस इन्ट्रीलाई लुकाउने", "abusefilter-log-hide-reason": "कारण:", "abusefilter-log-hide-forbidden": "तपाईंलाई दुरुपयोग लग इन्ट्रीहरू लुकाउने अनुमति छैन।", - "abusefilter-management": "दुर्व्यवहार फिल्टर विन्यास", "abusefilter-list": "सबै फिल्टरहरु", "abusefilter-list-id": "फिल्टर परिचय:", + "abusefilter-list-pattern": "ढाँचा", "abusefilter-list-status": "स्थिति", "abusefilter-list-public": "सार्वजनिक विवरण", "abusefilter-list-consequences": "परिणाम", @@ -78,17 +89,21 @@ "abusefilter-disabled": "निरस्त", "abusefilter-hitcount": "$1 {{PLURAL:$1|हिट|हिटहरु}}", "abusefilter-new": "नयाँ फिल्टर बनाउने", + "abusefilter-import-button": "फिल्टर आयात गर्ने", "abusefilter-status-global": "विश्वव्यापी", "abusefilter-list-options": "विकल्पहरू", "abusefilter-list-options-deleted": "मेटाइएका फिल्टहरु:", "abusefilter-list-options-deleted-only": "मेटाइएका फिल्टहरु मात्र देखाउनुहोस्", "abusefilter-list-options-deleted-hide": "मेटाइएका फिल्टहरु लुकाउनुहोस्", "abusefilter-list-options-deleted-show": "मेटाइएका फिल्टहरु संलग्न गर्नुहोस्", - "abusefilter-list-options-scope": "फिल्टरहरू देखाउने:", + "abusefilter-list-options-scope": "छनाेटहरू देखाउने:", "abusefilter-list-options-scope-local": "स्थानीय नियम मात्र", "abusefilter-list-options-scope-global": "विश्वव्यापी नियम मात्र", "abusefilter-list-options-scope-all": "स्थानीय तथा विश्वव्यापी नियमहरू", "abusefilter-list-options-hidedisabled": "निस्क्रिय फिल्टरहरु लुकाउने", + "abusefilter-list-options-searchfield": "नियम भित्र खोज्नुहोस्:", + "abusefilter-list-options-searchpattern": "ढाँचा हाल्नुहाेस्", + "abusefilter-list-options-searchoptions": "खोज्नु रिति:", "abusefilter-list-options-submit": "अद्यतन", "abusefilter-tools-expr": "अभिव्यक्ति जाँचकी", "abusefilter-tools-submitexpr": "जाँच गर्ने", @@ -101,29 +116,37 @@ "abusefilter-edit-subtitle-new": "फिल्टर निर्माण हुँदै", "abusefilter-edit-status-label": "तथ्याङ्कहरू:", "abusefilter-edit-status": "विगत $1 {{PLURAL:$1|को कार्य|का कार्यहरु}}सित, $2 ($3%) मेल खान्छ।", - "abusefilter-edit-status-profile": "विगत $1 {{PLURAL:$1|को कार्य|का कार्यहरु}}सित, $2 ($3%) मेल खान्छ।\nऔसतमा, यसको संचालन $4ms समय छ र यसले शर्त सीमाको $5 {{PLURAL:$5|शर्त|शर्तहरु}} खपत गर्छ।", "abusefilter-edit-new": "नयाँ फिल्टर", - "abusefilter-edit-save": "फिलटर संग्रह गर्ने", + "abusefilter-edit-save": "संशोधन सङ्ग्रह गर्ने", "abusefilter-edit-id": "फिल्टर परिचय:", + "abusefilter-edit-switch-editor": "सम्पादक फेर्नुहाेस्", "abusefilter-edit-description": "विवरण:\n:''(सार्वजनिक रुपमा देखिने)''", + "abusefilter-edit-field-description": "विवरण", "abusefilter-edit-group": "फिल्टर समूह:", "abusefilter-edit-flags": "पताकाहरु:", "abusefilter-edit-enabled": "यस फिल्टरलाई सक्रिय गर्ने", "abusefilter-edit-deleted": "मेटिएको भनी चिन्ह लगाउने", "abusefilter-edit-global": "विश्वव्यापी फिल्टर", "abusefilter-edit-rules": "शर्तहरु:", + "abusefilter-edit-field-conditions": "शर्तहरू", "abusefilter-edit-notes": "टिप्पणी:", "abusefilter-edit-lastmod": "पछिल्लो संशोधित फिल्टर", "abusefilter-edit-lastmod-text": "$2ले $1लाई", "abusefilter-edit-hitcount": "फिल्टर गणना:", "abusefilter-edit-action-degroup": "सबै विशेषाधिकार प्राप्त समूहबाट प्रयोगकर्तालाई निकाल्ने", - "abusefilter-edit-throttle-period": "समयावधि:", + "abusefilter-edit-throttle-period": "समयावधि (सेकेन्डमा):", + "abusefilter-edit-throttle-groups-help": "$1 हेर्नुहाेस्", + "abusefilter-throttle-user": "प्रयाेगकर्ता खाता", + "abusefilter-throttle-editcount": "सम्पादन गणना", + "abusefilter-throttle-page": "पृष्ठ", + "abusefilter-throttle-none": "(कुनै पनि होइन)", "abusefilter-edit-warn-other": "अन्य सन्देशहरू", "abusefilter-edit-warn-actions": "कार्य:", "abusefilter-edit-warn-preview": "छानिएको सन्देशको पूर्वावलोकन", "abusefilter-edit-warn-edit": "चुनिएको सन्देश बनाउने/सम्पादन गर्ने", + "abusefilter-edit-disallow-actions": "कार्यहरू:", "abusefilter-edit-main": "फिल्टर पेरामिटरहरू", - "abusefilter-edit-done-subtitle": "फिल्टर सम्पादित", + "abusefilter-edit-done-subtitle": "सम्पादित छनोट", "abusefilter-edit-history": "इतिहास:", "abusefilter-edit-check": "वाक्यविन्यास जाँच्ने", "abusefilter-edit-badfilter": "तपाईंले खुलाउनु भएको फिल्टर उपलब्ध छैन ।", @@ -161,14 +184,14 @@ "abusefilter-edit-builder-vars-removedlines": "सम्पादनमा हटाइएका पंक्तिहरु", "abusefilter-edit-builder-vars-summary": "सारांश/कारण सम्पादन", "abusefilter-edit-builder-vars-page-id": "पृष्ठको ID", - "abusefilter-edit-builder-vars-page-ns": "पृष्ठको नेमस्पेस", + "abusefilter-edit-builder-vars-page-ns": "पृष्ठको नामपद", "abusefilter-edit-builder-vars-page-prefixedtitle": "पूर्ण पृष्ठको शीर्षक", "abusefilter-edit-builder-vars-movedfrom-id": "सारिएको श्रोत पृष्ठको पृष्ठ आइडी", - "abusefilter-edit-builder-vars-movedfrom-ns": "सारिएको श्रोत पृष्ठको नामस्थान", + "abusefilter-edit-builder-vars-movedfrom-ns": "सारिएको श्रोत पृष्ठको नामपद", "abusefilter-edit-builder-vars-movedfrom-title": "सारिएको श्रोत पृष्ठको शिर्षक", "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "सारिएको श्रोत पृष्ठको पूर्ण शीर्षक", "abusefilter-edit-builder-vars-movedto-id": "सारिएको श्रोत पृष्ठको पृष्ठ गन्तव्य", - "abusefilter-edit-builder-vars-movedto-ns": "सार्दाको गन्तव्य पृष्ठको नेमस्पेस", + "abusefilter-edit-builder-vars-movedto-ns": "सार्दाको गन्तव्य पृष्ठको नामपद", "abusefilter-edit-builder-vars-movedto-title": "सार्दाको गन्तव्य पृष्ठको शीर्षक", "abusefilter-edit-builder-vars-movedto-prefixedtitle": "सारिएको श्रोत पृष्ठको पूर्ण पृष्ठ गन्तव्य", "abusefilter-edit-builder-vars-user-editcount": "प्रयोगकर्ताको सम्पादन गणना", @@ -182,12 +205,13 @@ "abusefilter-edit-builder-vars-all-links": "नयाँ पाठमा सबै बाह्य लिङ्कहरू", "abusefilter-edit-builder-vars-added-links": "सम्पादनमा सबै बाहिरी लिंक जोड़ियो", "abusefilter-edit-builder-vars-removed-links": "सम्पादनमा सबै बाहिरी लिंक हटाइयो", - "abusefilter-edit-builder-vars-old-text": "सम्पादन पहिले पुरानो पृष्ठ विकिपाठ", - "abusefilter-edit-builder-vars-new-text": "सम्पादन पहिले नयाँ पृष्ठ विकिपाठ", + "abusefilter-edit-builder-vars-old-wikitext": "सम्पादन पहिले पुरानो पृष्ठ विकिपाठ", + "abusefilter-edit-builder-vars-new-wikitext": "सम्पादन पहिले नयाँ पृष्ठ विकिपाठ", "abusefilter-edit-builder-vars-new-pst": "रक्षण हुनु पहिले नयाँ पृष्ठ विकिपाठ", "abusefilter-edit-builder-vars-restrictions-edit": "पृष्ठको सुरक्षा स्तर सम्पादन गर्ने", "abusefilter-edit-builder-vars-restrictions-move": "पृष्ठको सुरक्षा स्तर सम्पादन हटाउने", "abusefilter-edit-builder-vars-file-size": "फाइलको आकार बाइटसमा", + "abusefilter-edit-builder-vars-wiki-language": "विकिकाे भाषिक अङ्क", "abusefilter-filter-log": "भर्खरका फिल्टर परिवर्तनहरू", "abusefilter-history": "दुर्व्यवहार फिल्टर #$1को निम्ति इतिहास परिवर्तन गर्ने", "abusefilter-history-foruser": "$1द्वारा परिवर्तन", @@ -203,7 +227,7 @@ "abusefilter-history-actions": "कार्यहरु", "abusefilter-history-backedit": "फिल्टर सम्पादनतिर फर्किने", "abusefilter-history-deleted": "मेटिएको", - "abusefilter-history-filterid": "फिल्टर", + "abusefilter-history-filterid": "छनाेट", "abusefilter-history-select-legend": "परिष्कृत खोज", "abusefilter-history-select-user": "प्रयोगकर्ता:", "abusefilter-history-select-submit": "परिष्कृत गर्ने", @@ -212,7 +236,7 @@ "abusefilter-exception-unexpectedatend": "$1चरित्रमा \"$2\" अप्रत्यासित भएको", "abusefilter-exception-expectednotfound": "$1 चरित्रमा एउटा $2 प्रत्यासित भएको, पाइएन ( $3 $4 स्थानमा पाइयो).", "abusefilter-exception-unrecognisedkeyword": "$1 चरित्रको नचिनिने $2 शव्दकुञ्जी।", - "abusefilter-action-tag": "ट्याग", + "abusefilter-action-tag": "चिनो", "abusefilter-action-throttle": "थ्रोटल", "abusefilter-action-warn": "चेतावनी", "abusefilter-action-block": "रोक्ने", @@ -237,6 +261,7 @@ "abusefilter-test-period-end": "पहिले गरिएका परिवर्तनहरू:", "abusefilter-test-page": "यस पृष्ठमा गरिएका परिवर्तनहरू:", "abusefilter-test-shownegative": "ती परिवर्तनहरू हेर्ने जो फिल्टरसित मेल खाँदैनन्", + "abusefilter-test-search-type-edit": "सम्पादनहरू", "abusefilter-changeslist-examine": "जाँच्ने", "abusefilter-examine": "प्रत्येक परिवर्तनलाई जाँच्ने", "abusefilter-examine-legend": "परिवर्तहरु छान्ने", @@ -249,11 +274,11 @@ "abusefilter-examine-noresults": "तपाईंले खोजको निम्ति दिएका मापदण्ड अनुसार परिणाम प्राप्त भएन।", "abusefilter-topnav": "'''दुर्व्यवहार फिल्टर नेभिगेसन'''", "abusefilter-topnav-home": "गृह", + "abusefilter-topnav-recentchanges": "जर्सी", "abusefilter-topnav-test": "ब्याच जाँच्ने", "abusefilter-topnav-examine": "पुराना सम्पादनहरू जाँच्ने", "abusefilter-topnav-log": "दुर्व्यवहार लग", "abusefilter-topnav-tools": "डिबगिंग औजार", - "abusefilter-topnav-import": "फिल्टर आयात गर्ने", "abusefilter-log-name": "दुर्व्यवहार फिल्टर लग", "abusefilter-log-noresults": "नतिजाहरू छैन", "abusefilter-diff-title": "संस्करणहरूबीच भिन्नता", diff --git a/AbuseFilter/i18n/nl.json b/AbuseFilter/i18n/nl.json index ee8984b4..6885c45d 100644 --- a/AbuseFilter/i18n/nl.json +++ b/AbuseFilter/i18n/nl.json @@ -3,34 +3,40 @@ "authors": [ "Annabel", "Arent", + "Bdijkstra", + "Daimona Eaytoy", + "Elroy", + "Festina90", "GerardM", + "JaapDeKleine", + "Jeleniccz", "JurgenNL", + "Kippenvlees1", + "Mainframe98", + "Mar(c)", + "Matma Rex", "McDutchie", "Mwpnl", "Niknetniko", + "QZanden", "Romaine", "SPQRobin", "Siebrand", + "Sjoerddebruin", "Southparkfan", + "Sumurai8", "Tjcool007", + "Trijnstel", "Tvdm", "Wiki13", - "Sjoerddebruin", - "Trijnstel", - "JaapDeKleine", - "Matma Rex", - "Jeleniccz", - "Mainframe98", - "QZanden", - "Festina90", - "Mar(c)", - "Kippenvlees1" + "Xbaked potatox" ] }, "abusefilter-desc": "Voert automatisch heuristische analyse uit op bewerkingen", - "abusefilter": "Filterinstellingen", + "abusefilter": "Beheer van filters", "abuselog": "Filterlogboek", "abusefilter-intro": "Dit is het beheerscherm voor bewerkingsfilters.\nHet filtersysteem past automatische heuristiek toe op alle handelingen.\nVia dit scherm worden alle ingestelde filters weergegeven en kunnen ze aangepast worden.", + "abusefilter-mustviewprivateoredit": "Om veiligheidsredenen hebben alleen gebruikers met het recht om beperkt zichtbare filters te bekijken of filters te wijzigen de mogelijkheid deze interface te gebruiken.", "abusefilter-warning": "'''Waarschuwing:''' Deze handeling is automatisch als schadelijk geïdentificeerd.\nOnconstructieve handelingen worden snel teruggedraaid, en herhaald onconstructief bewerken eindigt in een blokkade van uw account of IP-adres.\nAls u denkt dat deze handeling wel constructief is, bevestig uw handeling dan opnieuw.\nEen korte beschrijving van de regel op basis waarvan uw handeling is tegengehouden: $1", "abusefilter-disallowed": "Deze handeling is automatisch geïdentificeerd als schadelijk, en daarom niet toegelaten.\nAls u denkt dat uw handeling wel constructief was, rapporteer dan aan de beheerder wat u probeerde te doen.\nEen korte beschrijving van de regel op basis waarvan uw handeling is tegengehouden volgt nu: $1", "abusefilter-blocked-display": "Deze handeling is automatisch geïdentificeerd als schadelijk. Daarom is deze niet uitgevoerd.\nOm {{SITENAME}} te beschermen zijn uw gebruikersaccount en alle bijbehorende IP-adressen geblokkeerd.\nAls deze maatregel onterecht is genomen, neem dan contact op met een beheerder.\nEen korte beschrijving van de regel op basis waarvan uw bewerking is tegengehouden: $1", @@ -39,12 +45,14 @@ "abusefilter-blocker": "Filter", "abusefilter-blockreason": "Automatisch geblokkeerd door het filter.\nBeschrijving van de regel die dit heeft veroorzaakt: $1", "abusefilter-degroupreason": "Rechten zijn automatisch verwijderd door het filter. Regelbeschrijving: $1", + "abusefilter-blockautopromotereason": "Automatisch promoveren is uitgesteld door het filter.\nRegelbeschrijving: $1", "abusefilter-accountreserved": "Deze gebruiker is gereserveerd voor het filter.", - "right-abusefilter-modify": "Filters wijzigen", + "right-abusefilter-modify": "Filters aanmaken of aanpassen", "right-abusefilter-view": "Filters bekijken", "right-abusefilter-log": "Het filterlogboek bekijken", "right-abusefilter-log-detail": "Details van filterlogboekregels bekijken", - "right-abusefilter-private": "Beperkt zichtbare gegevens in het filterlogboek bekijken", + "right-abusefilter-privatedetails": "Beperkt zichtbare gegevens in het filterlogboek bekijken", + "right-abusefilter-privatedetails-log": "Het toegangslogboek van beperkt zichtbare logboekgegevens van het misbruikfilter bekijken", "right-abusefilter-modify-restricted": "Filters met beperkte handelingen wijzigen", "right-abusefilter-revert": "Alle wijzigingen door een filter terugdraaien", "right-abusefilter-view-private": "Als beperkt zichtbaar gemarkeerde filters bekijken", @@ -56,16 +64,22 @@ "action-abusefilter-view": "filters te bekijken", "action-abusefilter-log": "het filterlogboek te bekijken", "action-abusefilter-log-detail": "gedetailleerde filterlogboekvermeldingen te bekijken", - "action-abusefilter-private": "privégegevens in het filterlogboek te bekijken", + "action-abusefilter-privatedetails": "privégegevens in het filterlogboek te bekijken", + "action-abusefilter-privatedetails-log": "het toegangslogboek van beperkt zichtbare logboekgegevens van het misbruikfilter te mogen bekijken", "action-abusefilter-modify-restricted": "filters met beperkte handelingen te wijzigen", "action-abusefilter-revert": "alle wijzigingen door een bepaald filter terug te draaien", "action-abusefilter-view-private": "als beperkt zichtbaar gemarkeerde filters te bekijken", "action-abusefilter-log-private": "Logboeken weergeven van misbruikfilters die zijn gemarkeerd als privé.", - "abusefilter-log": "Filterlogboek", + "action-abusefilter-hide-log": "meldingen in het filterlogboek te verbergen", + "action-abusefilter-hidden-log": "verborgen meldingen in het filterlogboek te bekijken", + "action-abusefilter-modify-global": "globale misbruikfilters aan te maken of aan te passen", "abusefilter-log-summary": "Dit logboek geeft een lijst weer van handelingen die opgevangen zijn door filters.", "abusefilter-log-search": "Het filterlogboek doorzoeken", "abusefilter-log-search-user": "Gebruiker:", - "abusefilter-log-search-filter": "Filternummers (gescheiden met het teken \"|\"):", + "abusefilter-log-search-group": "Filtergroep:", + "abusefilter-log-search-group-any": "Alle", + "abusefilter-log-search-filter": "Filternummers:", + "abusefilter-log-search-filter-help": "Gescheiden met sluistekens (|), gebruik het voorvoegsel \"$1\" voor globale filters", "abusefilter-log-search-title": "Paginanaam:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-impact": "Impact:", @@ -76,6 +90,8 @@ "abusefilter-log-search-entries-all": "Alle regels", "abusefilter-log-search-entries-hidden": "Alleen verborgen regels", "abusefilter-log-search-entries-visible": "Alleen zichtbare regels", + "abusefilter-log-search-action-label": "Uitgevoerde handeling:", + "abusefilter-log-search-action-other": "Overige", "abusefilter-log-search-action-any": "Alle", "abusefilter-log-search-action-taken-label": "Genomen maatregel:", "abusefilter-log-search-action-taken-any": "Alle", @@ -92,21 +108,24 @@ "abusefilter-log-details-var": "Variabele", "abusefilter-log-details-val": "Waarde", "abusefilter-log-details-vars": "Maatregelparameters", - "abusefilter-log-details-private": "Beperkt zichtbare logboekgegevens", + "abusefilter-log-details-privatedetails": "Beperkt zichtbare logboekgegevens", "abusefilter-log-details-ip": "IP-adres", "abusefilter-log-details-checkuser": "Gebruiker controleren", "abusefilter-log-noactions": "geen", + "abusefilter-log-noactions-filter": "Geen", "abusefilter-log-details-diff": "Wijzigingen in de bewerking", "abusefilter-log-linkoncontribs": "filterlogboek", "abusefilter-log-linkoncontribs-text": "Filterlogboek voor {{GENDER:$1|deze gebruiker}}", "abusefilter-log-linkonhistory": "filterlogboek bekijken", "abusefilter-log-linkonhistory-text": "Filterlogboek voor deze pagina bekijken", - "abusefilter-log-hidden": "(melding verborgen)", + "abusefilter-log-linkonundelete": "misbruiklogboek bekijken", + "abusefilter-log-linkonundelete-text": "Filterlogboek voor deze pagina bekijken", "abusefilter-log-hidden-implicit": "(verborgen omdat de versie verwijderd is)", "abusefilter-log-cannot-see-details": "U hebt niet de juiste rechten om dit item te bekijken.", - "abusefilter-log-cannot-see-private-details": "U hebt niet de juiste rechten om de beperkt zichbare gegevens van dit item te bekijken.", + "abusefilter-log-cannot-see-privatedetails": "U hebt niet de juiste rechten om de beperkt zichbare gegevens van dit item te bekijken.", "abusefilter-log-nonexistent": "Een regel met de opgegeven ID bestaat niet.", "abusefilter-log-details-hidden": "U kunt de details van deze melding niet bekijken omdat deze verborgen is.", + "abusefilter-log-details-hidden-implicit": "U kunt de details van deze melding niet bekijken omdat de gekoppelde versie verborgen is.", "abusefilter-log-private-not-included": "Een of meer van de opgegeven filter-ID's zijn persoonlijk. Omdat u de details van privéfilters niet mag zien, is er niet in deze filters gezocht.", "abusefilter-log-hide-legend": "Logboekregel verbergen", "abusefilter-log-hide-id": "Logboekmeldingsnummer:", @@ -118,8 +137,14 @@ "abusefilter-log-entry-unsuppress": "$1 heeft $3 {{GENDER:$2|zichtbaar}} gemaakt", "logentry-abusefilter-hit": "$1 heeft $4 {{GENDER:$2|geactiveerd}} door de handeling \"$5\" op $3\". Uitgevoerde acties: $6 ($7)", "log-action-filter-abusefilter": "Type filterwijziging:", + "log-action-filter-abusefilter-create": "Aanmaak nieuw filter", "log-action-filter-abusefilter-modify": "Filteraanpassing", - "abusefilter-management": "Beheer van filters", + "log-action-filter-rights-blockautopromote": "Uitstellen van automatisch promoveren", + "log-action-filter-rights-restoreautopromote": "Herstellen van automatisch promoveren", + "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|bekeek}} de beperkte zichtbare logboekgegevens van $3", + "logentry-rights-blockautopromote": "$1 {{GENDER:$2|heeft}} het automatisch promoveren van {{GENDER:$4|$3}} met $5 uitgesteld", + "logentry-rights-restoreautopromote": "$1 {{GENDER:$2|heeft}} de mogelijkheid van {{GENDER:$4|$3}} om automatisch te promoveren hersteld", + "abusefilterprivatedetails-log-name": "Toegangslogboek van beperkt zichtbare logboekgegevens van het misbruikfilter", "abusefilter-list": "Alle filters", "abusefilter-list-id": "Filternummer", "abusefilter-list-pattern": "Patroon", @@ -138,8 +163,10 @@ "abusefilter-enabled": "Ingeschakeld", "abusefilter-deleted": "Verwijderd", "abusefilter-disabled": "Uitgeschakeld", + "abusefilter-throttled": "gelimiteerd", "abusefilter-hitcount": "$1 {{PLURAL:$1|hit|hits}}", "abusefilter-new": "Nieuw filter aanmaken", + "abusefilter-import-button": "Filter importeren", "abusefilter-return": "Terug naar filterbeheer", "abusefilter-status-global": "Globaal", "abusefilter-list-options": "Opties", @@ -151,27 +178,38 @@ "abusefilter-list-options-scope-local": "Alleen lokale regels", "abusefilter-list-options-scope-global": "Alleen globale regels", "abusefilter-list-options-scope-all": "Lokale en globale regels", + "abusefilter-list-options-further-options": "Andere opties:", "abusefilter-list-options-hidedisabled": "Uitgeschakelde filters verbergen", + "abusefilter-list-options-hideprivate": "Verberg beperkt zichtbare filters", + "abusefilter-list-options-searchfield": "Zoeken binnen de regels:", + "abusefilter-list-options-searchpattern": "Patroon invoegen", + "abusefilter-list-options-searchoptions": "Zoekmodus:", + "abusefilter-list-options-search-like": "Normale zoekopdracht", "abusefilter-list-options-search-rlike": "Reguliere expressie", "abusefilter-list-options-search-irlike": "Hoofdletter-ongevoelige reguliere expressie", + "abusefilter-list-invalid-searchmode": "De opgegeven zoekmodus is ongeldig.", + "abusefilter-list-regexerror": "Er trad een fout op tijdens het zoeken: Syntaxfout in de reguliere expressie.", "abusefilter-list-options-submit": "Bijwerken", "abusefilter-tools-text": "Dit zijn een aantal hulpmiddelen die van pas kunnen komen bij het formuleren en debuggen van filters.", "abusefilter-tools-expr": "Expressietester", "abusefilter-tools-submitexpr": "Evalueren", + "abusefilter-tools-syntax-error": "Het filter heeft een ongeldige syntax.", "abusefilter-tools-reautoconfirm": "Automatisch bevestigde status opnieuw instellen", "abusefilter-tools-reautoconfirm-user": "Gebruiker:", "abusefilter-tools-reautoconfirm-submit": "Opnieuw automatisch bevestigen", + "abusefilter-tools-restoreautopromote": "Automatisch promoveren hersteld met de misbruikfilter hulpmiddelen.", "abusefilter-reautoconfirm-none": "Voor die gebruiker is de automatisch bevestigde status niet ingetrokken.", "abusefilter-reautoconfirm-notallowed": "U hebt geen rechten om de automatisch bevestigde status opnieuw in te stellen.", "abusefilter-reautoconfirm-done": "De bevestigde gebruikersstatus van de gebruiker is hersteld", - "abusefilter-status": "Van de laatste $1 {{PLURAL:$1|handeling|handelingen}}, {{PLURAL:$2|heeft er 1|hebben er $2}} ($3%) de drempelwaarde van $4 bereikt, en {{PLURAL:$5|past|passen}} $5 ($6%) bij één van de huidige ingeschakelde filters.", + "abusefilter-status": "Van de laatste $1 {{PLURAL:$1|handeling|handelingen}}, {{PLURAL:$2|heeft er 1|hebben er $2}} ($3%) de drempelwaarde van $4 bereikt, en {{PLURAL:$5|past|passen}} $5 ($6%) bij ten minste één van de huidige ingeschakelde filters.", "abusefilter-edit": "Filter bewerken", "abusefilter-edit-subtitle": "Bezig met het bewerken van filter $1", "abusefilter-edit-subtitle-new": "Bezig met het aanmaken van een filter", + "abusefilter-edit-token-not-match": "De bewerking is niet opgeslagen! Probeer opnieuw op te slaan.", "abusefilter-edit-oldwarning": "<strong>U bent een oude versie van dit filter aan het bewerken.\nDe weergegeven statistieken gelden voor de meest recente versie van het filter.\nAls u uw wijzigingen opslaat, overschrijft u alle wijzigingen die na deze versie zijn gemaakt.</strong> •\n[[Special:AbuseFilter/history/$2|Terug naar de geschiedenis van dit filter]]", + "abusefilter-edit-oldwarning-view": "<strong>U bekijkt een oudere versie van dit filter.\nDe statistieken die hier genoemd worden zijn voor de meest recente versie van dit filter.</strong> •\n[[Special:AbuseFilter/history/$2|Terug naar de geschiedenis van dit filter]].", "abusefilter-edit-status-label": "Statistieken:", - "abusefilter-edit-status": "{{PLURAL:$1|De laatste handeling voldeed|Van de laatste $1 handelingen voldeden er $2}} aan dit filter ($3%).", - "abusefilter-edit-status-profile": "{{PLURAL:$1|De laatste handeling voldeed|Van de laatste $1 handelingen voldeden er $2}} aan dit filter ($3%).\nDe gemiddelde looptijd van de filtercontrole is $4ms, en deze gebruikt $5 {{PLURAL:$5|conditie|condities}} van de conditielimiet.", + "abusefilter-edit-status": "{{PLURAL:$1|De laatste handeling voldeed|Van de laatste $1 handelingen voldeden er $2}} aan dit filter ($3%).\nDe gemiddelde looptijd van de filtercontrole is $4 ms, en deze gebruikt $5 {{PLURAL:$5|conditie|condities}} van de conditielimiet.", "abusefilter-edit-throttled-warning": "'''Waarschuwing:''' Dit filter is automatisch gemarkeerd als schadelijk. Als veiligheidsmaatregel zijn de volgende handelingen niet uitgevoerd ($1). Controleer en [[mw:Extension:AbuseFilter/Conditions|optimaliseer]] de condities om deze limitatie te verwijderen.", "abusefilter-edit-new": "Nieuw filter", "abusefilter-edit-save": "Filter opslaan", @@ -186,6 +224,7 @@ "abusefilter-edit-hidden": "Details van dit filter niet openbaar maken", "abusefilter-edit-global": "Globaal filter", "abusefilter-edit-rules": "Regels:", + "abusefilter-edit-field-conditions": "voorwaarden", "abusefilter-edit-notes": "Opmerkingen:", "abusefilter-edit-lastmod": "Filter laatst aangepast:", "abusefilter-edit-lastmod-text": "door $2 op $3 om $4", @@ -203,20 +242,34 @@ "abusefilter-edit-throttle-count": "Aantal toe te laten handelingen:", "abusefilter-edit-throttle-period": "Tijdsduur (in seconden):", "abusefilter-edit-throttle-groups": "Beperkingen groeperen op:", - "abusefilter-edit-throttle-ip": "IP-adres", - "abusefilter-edit-throttle-editcount": "Aantal bewerkingen", - "abusefilter-edit-throttle-page": "Pagina", + "abusefilter-edit-throttle-groups-help": "Bekijk $1.", + "abusefilter-edit-throttle-groups-help-text": "de documentatie op mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Combineer met komma's om met EN samen te voegen, en met nieuwe regels om met OF samen te voegen", + "abusefilter-edit-throttle-placeholder": "Combineer met komma's om met EN samen te voegen, en voer een voor een in om met OF samen te voegen", + "abusefilter-throttle-ip": "IP-adres", + "abusefilter-throttle-user": "gebruikersaccount", + "abusefilter-throttle-range": "/16 bereik", + "abusefilter-throttle-creationdate": "aanmaakdatum account", + "abusefilter-throttle-editcount": "aantal bewerkingen", + "abusefilter-throttle-site": "gehele website", + "abusefilter-throttle-page": "pagina", + "abusefilter-throttle-none": "(geen)", + "abusefilter-throttle-details": "Sta $1 {{PLURAL:$1|handeling|handelingen}} elke {{PLURAL:$2|seconde|$2 seconden}} toe, van toepassing op de groepen: $3", "abusefilter-edit-warn-message": "Te gebruiken systeembericht voor waarschuwing:", "abusefilter-edit-warn-other": "Ander bericht", - "abusefilter-edit-warn-other-label": "Paginanaam of ander bericht:\n:''(zonder voorvoegsel MediaWiki)''", + "abusefilter-edit-warn-other-label": "Paginanaam of ander bericht:\n:''(zonder het ''MediaWiki:'' voorvoegsel)''", "abusefilter-edit-warn-actions": "Handelingen:", - "abusefilter-edit-warn-preview": "Voorvertoning geselecteerd bericht", + "abusefilter-edit-warn-preview": "Toon/Verberg voorvertoning van het geselecteerde bericht", "abusefilter-edit-warn-edit": "Geselecteerd bericht aanmaken/bewerken", + "abusefilter-edit-disallow-message": "Te gebruiken systeembericht voor weigeren:", "abusefilter-edit-disallow-other": "Ander bericht", + "abusefilter-edit-disallow-other-label": "Paginanaam of ander bericht:\n:''(zonder het ''MediaWiki:'' voorvoegsel)''", "abusefilter-edit-disallow-actions": "Handelingen:", "abusefilter-edit-disallow-preview": "Toon/Verberg voorvertoning van het geselecteerde bericht", "abusefilter-edit-disallow-edit": "Geselecteerd bericht aanmaken/bewerken", - "abusefilter-edit-tag-tag": "[[Special:Tags|Labels]] toe te passen (één per regel):", + "abusefilter-edit-tag-tag": "[[Special:Tags|Labels]] toe te passen:", + "abusefilter-edit-tag-placeholder": "Labels toevoegen (één per regel of door komma's gescheiden)", + "abusefilter-edit-tag-hidden-placeholder": "Labels toevoegen (gescheiden door een komma)", "abusefilter-edit-block-anon-durations": "Blokkadeduur voor anonieme gebruikers:", "abusefilter-edit-block-user-durations": "Blokkadeduur voor geregistreerde gebruikers:", "abusefilter-block-anon": "Anonieme gebruikers blokkeren", @@ -240,10 +293,13 @@ "abusefilter-edit-export": "Dit filter exporteren naar een andere wiki", "abusefilter-edit-syntaxok": "Er zijn geen syntaxisfouten gevonden.", "abusefilter-edit-syntaxerr": "Er is een syntaxisfout gevonden: $1", + "abusefilter-edit-warn-leave": "Wijzigingen die aan het filter gemaakt zijn worden niet opgeslagen als u de pagina verlaat.", "abusefilter-edit-bad-tags": "Een of meerdere van de labels die u hebt opgegeven zijn niet geldig.\nLabels moeten kort zijn, mogen geen speciale tekens bevatten, en mogen niet gereserveerd zijn door andere software. Kies een andere labelnaam.", "abusefilter-edit-notallowed": "U hebt geen rechten om filters aan te maken of te wijzigen", "abusefilter-edit-notallowed-global": "U kunt globale misbruikfilters niet aanmaken of bewerken", - "abusefilter-edit-notallowed-global-custom-msg": "Aangepaste waarschuwingsberichten worden niet ondersteund voor globale filters", + "abusefilter-edit-notallowed-global-custom-msg": "Aangepaste waarschuwings- of weigeringsberichten worden niet ondersteund voor globale filters", + "abusefilter-edit-invalid-warn-message": "Het waarschuwingsbericht mag niet leeg zijn.", + "abusefilter-edit-invalid-disallow-message": "Het weigeringsbericht mag niet leeg zijn.", "abusefilter-edit-builder-select": "Selecteer een optie om deze aan de cursor toe te voegen", "abusefilter-edit-builder-group-op-arithmetic": "Aritmische operatoren", "abusefilter-edit-builder-op-arithmetic-addition": "Optellen (+)", @@ -273,7 +329,8 @@ "abusefilter-edit-builder-misc-contains": "De linker tekst bevat de rechter tekst (contains)", "abusefilter-edit-builder-misc-stringlit": "Letterlijke tekst (\"\")", "abusefilter-edit-builder-misc-tern": "Ternaire operator (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Voorwaardelijk (als X dan Y anders Z)", + "abusefilter-edit-builder-misc-cond": "Voorwaardelijk (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond-short": "Korte voorwaardelijkheidsdefinitie (if X then Y end)", "abusefilter-edit-builder-group-funcs": "Functies", "abusefilter-edit-builder-funcs-length": "Tekstlengte (length)", "abusefilter-edit-builder-funcs-lcase": "Naar kleine letters (lcase)", @@ -289,15 +346,19 @@ "abusefilter-edit-builder-funcs-rmwhitespace": "Witruimte verwijderen (rmwhitespace)", "abusefilter-edit-builder-funcs-rmspecials": "Speciale tekens verwijderen (rmspecials)", "abusefilter-edit-builder-funcs-ip_in_range": "Bevindt het IP-adres zich in de opgegeven range? (ip_in_range)", - "abusefilter-edit-builder-funcs-contains-any": "Tekst doorzoeken op meerdere tekstdelen (contains_any)", + "abusefilter-edit-builder-funcs-contains-any": "Zoekreeks voor meerdere substrings in de OF-modus. (Contains_any)", + "abusefilter-edit-builder-funcs-contains-all": "Zoekreeks voor meerdere substrings in EN-modus (contains_all)", + "abusefilter-edit-builder-funcs-equals-to-any": "Controleer of het gegeven argument gelijk is (===) aan een van de volgende argumenten (equals_to_any)", "abusefilter-edit-builder-funcs-substr": "Tekstdeel (substr)", "abusefilter-edit-builder-funcs-strpos": "Plaats van het tekstdeel (strpos)", "abusefilter-edit-builder-funcs-str_replace": "Tekstdeel vervangen door tekst (str_replace)", "abusefilter-edit-builder-funcs-rescape": "Tekst escapen als letterlijk in reguliere expressies (rescape)", "abusefilter-edit-builder-funcs-set_var": "Variabele instellen (set_var)", + "abusefilter-edit-builder-funcs-sanitize": "Normaliseer HTML-entiteiten naar unicodekarakters (sanitize)", "abusefilter-edit-builder-group-vars": "Variabelen", "abusefilter-edit-builder-vars-accountname": "Accountnaam (tijdens aanmaken)", "abusefilter-edit-builder-vars-timestamp": "UNIX-tijdstempel van wijziging", + "abusefilter-edit-builder-vars-timestamp-expanded": "Tijdmarkering van de logboekregel", "abusefilter-edit-builder-vars-action": "Handeling", "abusefilter-edit-builder-vars-addedlines": "Regels toegevoegd in bewerking", "abusefilter-edit-builder-vars-delta": "Groottewijziging", @@ -312,14 +373,17 @@ "abusefilter-edit-builder-vars-page-ns": "Paginanaamruimte", "abusefilter-edit-builder-vars-page-title": "Paginanaam (zonder naamruimte)", "abusefilter-edit-builder-vars-page-prefixedtitle": "Volledige paginanaam", + "abusefilter-edit-builder-vars-page-age": "Paginaleeftijd (in seconden)", "abusefilter-edit-builder-vars-movedfrom-id": "Pagina-ID van de te hernoemen pagina", "abusefilter-edit-builder-vars-movedfrom-ns": "Naamruimte van de te verplaatsen pagina", "abusefilter-edit-builder-vars-movedfrom-title": "Naam van de te verplaatsen pagina", "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "Volledige naam van de te verplaatsen pagina", + "abusefilter-edit-builder-vars-movedfrom-age": "Leeftijd van te verplaatsen pagina (in seconden)", "abusefilter-edit-builder-vars-movedto-id": "Pagina-ID van de bestemming van de te hernoemen pagina", "abusefilter-edit-builder-vars-movedto-ns": "Naamruimte van de bestemming van de te verplaatsen pagina", "abusefilter-edit-builder-vars-movedto-title": "Naam van de bestemming van de te verplaatsen pagina", "abusefilter-edit-builder-vars-movedto-prefixedtitle": "Volledige naam van de bestemming van de te verplaatsen pagina", + "abusefilter-edit-builder-vars-movedto-age": "Leeftijd van doelpagina (in seconden)", "abusefilter-edit-builder-vars-user-editcount": "Aantal bewerkingen gebruiker", "abusefilter-edit-builder-vars-user-age": "Bestaansduur gebruiker", "abusefilter-edit-builder-vars-user-name": "Gebruikersaccountnaam", @@ -329,24 +393,36 @@ "abusefilter-edit-builder-vars-user-emailconfirm": "Tijdstip e-mailbevestiging", "abusefilter-edit-builder-vars-recent-contributors": "Laatste tien bewerkers van de pagina", "abusefilter-edit-builder-vars-first-contributor": "Eerste gebruiker die heeft bijgedragen aan de pagina", + "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "Laatste tien gebruikers die de te verplaatsen pagina bewerkt hebben", + "abusefilter-edit-builder-vars-movedfrom-first-contributor": "Eerste gebruiker die heeft bijgedragen aan de te verplaatsen pagina", + "abusefilter-edit-builder-vars-movedto-recent-contributors": "Laatste tien gebruikers die de doelpagina bewerkt hebben", + "abusefilter-edit-builder-vars-movedto-first-contributor": "Eerste gebruiker die heeft bijgedragen aan de doelpagina", "abusefilter-edit-builder-vars-all-links": "Alle externe koppelingen in de nieuwe tekst", "abusefilter-edit-builder-vars-added-links": "Alle externe koppelingen die in deze bewerking zijn toegevoegd", "abusefilter-edit-builder-vars-removed-links": "Alle bij deze bewerking toegevoegde externe koppelingen zijn verwijderd", - "abusefilter-edit-builder-vars-old-text": "Wikitekst van de oude pagina vóór de bewerking (niet meer in gebruik)", - "abusefilter-edit-builder-vars-new-text": "Wikitekst van de nieuwe pagina ná de bewerking", + "abusefilter-edit-builder-vars-old-wikitext": "Wikitekst van de oude pagina vóór de bewerking", + "abusefilter-edit-builder-vars-new-wikitext": "Wikitekst van de nieuwe pagina ná de bewerking", "abusefilter-edit-builder-vars-new-pst": "Wikitext nieuwe pagina, voor opslaan getransformeerd", "abusefilter-edit-builder-vars-diff-pst": "Samengevoegde verschillende van de bewerking, transformaties voor opslaan", "abusefilter-edit-builder-vars-addedlines-pst": "Regels toegevoegd in bewerking, transformaties voor opslaan", - "abusefilter-edit-builder-vars-new-text-stripped": "Nieuwe paginatekst, ontdaan van opmaakcode", + "abusefilter-edit-builder-vars-new-text": "Nieuwe paginatekst, ontdaan van opmaakcode", "abusefilter-edit-builder-vars-new-html": "Verwerkte HTML-broncode van de nieuwe versie", "abusefilter-edit-builder-vars-restrictions-edit": "Beveiligingsniveau voor bewerken van de pagina", "abusefilter-edit-builder-vars-restrictions-move": "Beveiligingsniveau voor hernoemen van de pagina", "abusefilter-edit-builder-vars-restrictions-create": "Aanmaakbeveiliging voor de pagina", "abusefilter-edit-builder-vars-restrictions-upload": "Uploadbeveiliging van het bestand", - "abusefilter-edit-builder-vars-old-text-stripped": "Tekst oude pagina, ontdaan van alle opmaak", + "abusefilter-edit-builder-vars-movedfrom-restrictions-edit": "Beveiligingsniveau voor bewerken van de te verplaatsen pagina", + "abusefilter-edit-builder-vars-movedfrom-restrictions-move": "Beveiligingsniveau voor hernoemen van de te verplaatsen pagina", + "abusefilter-edit-builder-vars-movedfrom-restrictions-create": "Beveiligingsniveau voor aanmaken van de te verplaatsen pagina", + "abusefilter-edit-builder-vars-movedfrom-restrictions-upload": "Beveiligingsniveau voor uploaden van het te verplaatsen bestand", + "abusefilter-edit-builder-vars-movedto-restrictions-edit": "Beveiligingsniveau voor bewerken van doelpagina", + "abusefilter-edit-builder-vars-movedto-restrictions-move": "Beveiligingsniveau voor hernoemen van doelpagina", + "abusefilter-edit-builder-vars-movedto-restrictions-create": "Beveiligingsniveau voor aanmaken van doelpagina", + "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Beveiligingsniveau voor hernoemen van doelbestand", + "abusefilter-edit-builder-vars-old-text": "Tekst oude pagina, ontdaan van alle opmaak (niet langer in gebruik)", "abusefilter-edit-builder-vars-old-links": "Koppelingen in de pagina voor de bewerking", "abusefilter-edit-builder-vars-old-html": "Wikitext oude pagina in HTML (niet meer in gebruik)", - "abusefilter-edit-builder-vars-minor-edit": "Of de bewerking wel of niet als klein gemarkeerd is", + "abusefilter-edit-builder-vars-minor-edit": "Of de bewerking wel of niet als klein gemarkeerd is (niet langer in gebruik)", "abusefilter-edit-builder-vars-file-sha1": "SHA1-hashcode van de bestandsinhoud", "abusefilter-edit-builder-vars-file-size": "Grootte van het bestand in bytes", "abusefilter-edit-builder-vars-file-mime": "Het MIME-type van het bestand", @@ -354,6 +430,8 @@ "abusefilter-edit-builder-vars-file-width": "Breedte van het bestand in pixels", "abusefilter-edit-builder-vars-file-height": "De hoogte van het bestand in pixels", "abusefilter-edit-builder-vars-file-bits-per-channel": "Bits per kleurkanaal van het bestand", + "abusefilter-edit-builder-vars-wiki-name": "Databasenaam van de wiki", + "abusefilter-edit-builder-vars-wiki-language": "Taalcode van de wiki", "abusefilter-filter-log": "Recente filterwijzigingen", "abusefilter-history": "Geschiedenis voor het filter #$1", "abusefilter-history-foruser": "Wijzigingen door $1", @@ -383,16 +461,22 @@ "abusefilter-exception-unclosedstring": "Niet-gesloten tekst die begint bij teken $1.", "abusefilter-exception-invalidoperator": "Ongeldige operator \"$2\" bij teken $1.", "abusefilter-exception-unrecognisedtoken": "Token \"$2\" niet herkend bij teken $1.", - "abusefilter-exception-noparams": "Er zijn geen parameters opgegeven voor functie \"$2\" bij teken $1.", + "abusefilter-exception-noparams": "Er zijn geen parameters opgegeven voor functie \"$2\" bij teken $1.\nVerwachte $3 {{PLURAL:$3|argument|argumenten}}.", "abusefilter-exception-dividebyzero": "Ongeldige poging tot delen van $2 door nul bij teken $1.", "abusefilter-exception-unrecognisedvar": "Onherkenbare variabele $2 bij teken $1", "abusefilter-exception-notenoughargs": "Er zijn niet voldoende parameters opgegeven voor de functie $2 die is aangeroepen bij teken $1.\nEr {{PLURAL:$3|werd één parameter|werden $3 parameters}} verwacht, en er {{PLURAL:$4|is er één|zijn er $4}} aangetroffen.", - "abusefilter-exception-regexfailure": "Er is een fout aangetroffen in de reguliere expressie \"$3\" bij teken $1: \"$2\"", - "abusefilter-exception-overridebuiltin": "De ingebouwde variabele \"$2\" is vervangen bij teken $1.\nDit is niet toegestaan.", + "abusefilter-exception-toomanyargs": "Er zijn teveel parameters opgegeven voor de functie $2 die is aangeroepen bij teken $1.\nEr {{PLURAL:$3|werd maximaal één parameter|werden maximaal $3 parameters}} verwacht, en er {{PLURAL:$4|is er één|zijn er $4}} aangetroffen.", + "abusefilter-exception-regexfailure": "Er is een fout aangetroffen in de reguliere expressie \"$2\" bij teken $1.", + "abusefilter-exception-overridebuiltin": "De ingebouwde identifier \"$2\" wordt vervangen bij teken $1.\nDit is niet toegestaan.", "abusefilter-exception-outofbounds": "Er is getracht een lijstelement ($2 bij lijstgrootte $3) op te halen dat niet niet bestaat bij teken $1.", + "abusefilter-exception-negativeindex": "Een negatieve positie is niet toegestaan in een lijst. Positie \"$2\" werd gevonden als karakter $1.", "abusefilter-exception-notarray": "Er is getracht een verzamelingselement op te vragen uit iets dat geen verzameling is bij teken $1.", - "abusefilter-action-tag": "Label", - "abusefilter-action-throttle": "Limieten", + "abusefilter-exception-unclosedcomment": "Een opmerking werd niet afgesloten op karakterpositie $1.", + "abusefilter-exception-invalidiprange": "Ongeldig IP-bereik \"$2\" bij teken $1.", + "abusefilter-exception-disabledvar": "Variabele $2 bij teken $1 is niet meer in gebruik.", + "abusefilter-exception-variablevariable": "set en set_var verwachten dat het eerste argument een tekenreeks (string) is, op karakterpositie $1.", + "abusefilter-action-tag": "Labelen", + "abusefilter-action-throttle": "Limiteren", "abusefilter-action-warn": "Waarschuwen", "abusefilter-action-blockautopromote": "Automatisch promoveren blokkeren", "abusefilter-action-block": "Blokkeren", @@ -408,6 +492,7 @@ "abusefilter-revert-search": "Maatregelen selecteren", "abusefilter-revert-filter": "Filternummer:", "abusefilter-revert-preview-intro": "Hieronder staan de maatregelen die het filter heeft genomen die door deze handeling worden teruggedraaid.\nControleer de terug te draaien maatregelen zorgvuldig, en klik \"{{int:abusefilter-revert-confirm}}\" om uw selectie te bevestigen.", + "abusefilter-revert-confirm-legend": "Bevestig het terugdraaien", "abusefilter-revert-confirm": "Bevestigen", "abusefilter-revert-success": "U hebt alle maatregelen die door het filter via [[Special:AbuseFilter/$1|filter $2]] zijn genomen teruggedraaid.", "abusefilter-revert-reason": "Automatisch terugdraaien van alle maatregelen door de midbruikfilter via filter $1. Reden: $2", @@ -432,6 +517,7 @@ "abusefilter-test-search-type-move": "Hernoemingen", "abusefilter-test-search-type-delete": "Verwijderingen", "abusefilter-test-search-type-upload": "Uploads", + "abusefilter-test-search-type-createaccount": "Account creaties", "abusefilter-changeslist-examine": "onderzoeken", "abusefilter-examine": "Individuele wijzigingen onderzoeken", "abusefilter-examine-intro": "Via deze pagina kunt u de door het filter aangemaakte variabelen voor een individuele wijziging onderzoeken, en deze testen tegen filters.", @@ -451,15 +537,16 @@ "abusefilter-examine-noresults": "Er zijn geen resultaten gevonden voor de zoekopdrachtparameters die u hebt opgegeven.", "abusefilter-topnav": "'''Filternavigatie'''", "abusefilter-topnav-home": "Hoofdmenu", + "abusefilter-topnav-recentchanges": "Recente filterwijzigingen", "abusefilter-topnav-test": "Batchtesten", "abusefilter-topnav-examine": "Bewerkingen onderzoeken", "abusefilter-topnav-log": "Filterlogboek", "abusefilter-topnav-tools": "Hulpmiddelen voor debuggen", - "abusefilter-topnav-import": "Filter importeren", "abusefilter-log-name": "Filterlogboek", "abusefilter-log-header": "Dit logboek geeft een overzicht van wijzigingen aan filters.\nZie de [[Special:AbuseFilter/history|lijst met recente filterwijzigingen]] voor volledige details.", "abusefilter-logentry-create": "$1 heeft $4 {{GENDER:$2|aangemaakt}} ($5)", "abusefilter-logentry-modify": "$1 {{GENDER:$2|heeft}} $4 aangepast ($5)", + "abusefilter-log-invalid-filter": "Een aantal van de opgegeven filter IDs zijn ongeldig.", "abusefilter-log-noresults": "Geen resultaten", "abusefilter-diff-title": "Verschillen tussen versies", "abusefilter-diff-item": "Item", @@ -472,9 +559,16 @@ "abusefilter-diff-next": "Nieuwere wijziging", "abusefilter-import-intro": "U kunt deze interface gebruiken om filters van andere wiki's te importeren.\nKlik \"{{int:abusefilter-edit-export}}\" bij \"{{int:abusefilter-edit-tools}}\".\nKopieer de tekst die verschijnt naar dit bewerkingsvenster en klik dan op \"{{int:abusefilter-import-submit}}\".", "abusefilter-import-submit": "Filtergegevens importeren", + "abusefilter-import-invalid-data": "De data die u probeerde te importeren is niet geldig", "abusefilter-group-default": "Standaard", "abusefilter-http-error": "Er is een HTTP-fout opgetreden: $1.", - "abusefilter-view-private-reason": "Reden voor het opvragen van privélogboekgegevens:", + "abusefilter-view-privatedetails-submit": "Beperkt zichtbare gegevens bekijken", + "abusefilter-view-privatedetails-legend": "Privégegevens bekijken", + "abusefilter-view-privatedetails-reason": "Reden voor het opvragen van beperkt zichtbare logboekgegevens:", "abusefilter-log-details-id": "Logboekregel-ID", - "abusefilter-log-ip-not-available": "Niet beschikbaar" + "abusefilter-invalid-request": "Ongeldig verzoek! U kunt verborgen details inzien via het formulier op [[Special:AbuseLog/$1]] met opgaaf van reden.", + "abusefilter-noreason": "Waarschuwing: als u de privégegevens van dit logboek wilt bekijken, moet u een reden opgeven.", + "abusefilter-log-ip-not-available": "Niet beschikbaar", + "abusefilter-tag-reserved": "Het label <code>abusefilter-condition-limit</code> is gereserveerd voor intern gebruik door AbuseFilter.", + "tag-abusefilter-condition-limit": "conditielimiet bereikt" } diff --git a/AbuseFilter/i18n/nn.json b/AbuseFilter/i18n/nn.json index 2f6d8856..f183cf37 100644 --- a/AbuseFilter/i18n/nn.json +++ b/AbuseFilter/i18n/nn.json @@ -3,15 +3,15 @@ "authors": [ "Gunnernett", "Harald Khan", - "Nghtwlkr", - "Njardarlogar", "Matma Rex", - "Matěj Suchánek" + "Matěj Suchánek", + "Nghtwlkr", + "Njardarlogar" ] }, "abusefilter-desc": "Legg automatisk til heuristikk til endringar.", - "abusefilter": "Konfigurasjon av endringsfilter", - "abuselog": "Endringsfilterlogg", + "abusefilter": "Handsaming av endringsfilter", + "abuselog": "Logg for endringsfilter", "abusefilter-intro": "Velkomen til grensesnittet for handsaming av endringsfilteret.\nEndringsfilteret er ein sjølvgåande mekanisme i programvara som automatisk undersøkjer alle handlingar.\nDette grensesnittet viser ei liste over definerte filter, og gjer det mogeleg å endra dei.", "abusefilter-warning": "'''Åtvaring:''' Handlinga har automatisk vorte identifisert som skadeleg.\nIkkje-konstruktive handlingar vert raskt gjorde om, og langvarig forstyrrande endring vil føra til at kontoen din eller IP-adressa di vert blokkert. Meiner du dette er ei konstruktiv handling, kan du lagra henne om att for å stadfesta dette.\nEi kortfatta skildring av filterregelen som handlinga di utløyste er: $1", "abusefilter-disallowed": "Denne handlinga har automatisk vorte identifisert som skadeleg, og vart difor ikkje tillaten.\nOm du meiner handlinga di var konstruktiv, informer ein administrator om kva du freista å få til.\nEi kortfatta skildring av misbruksregelen som handlinga di utløyste er: $1", @@ -26,7 +26,7 @@ "right-abusefilter-view": "Sjå endringsfilter", "right-abusefilter-log": "Sjå misbruksloggen", "right-abusefilter-log-detail": "Sjå detaljert loggføring om misbruk", - "right-abusefilter-private": "Sjå privat informasjon i misbruksloggen", + "right-abusefilter-privatedetails": "Sjå privat informasjon i misbruksloggen", "right-abusefilter-modify-restricted": "Endra endringsfilter med avgrensa handlingar", "right-abusefilter-revert": "Gjera om alle endringar gjorde av eit visst endringsfilter", "right-abusefilter-view-private": "Sjå misbruksfiler merkte som private", @@ -38,21 +38,25 @@ "action-abusefilter-view": "sjå endringsfilter", "action-abusefilter-log": "sjå misbruksloggen", "action-abusefilter-log-detail": "sjå detaljert loggføring om misbruk", - "action-abusefilter-private": "sjå private data i misbruksloggen", + "action-abusefilter-privatedetails": "sjå private data i misbruksloggen", "action-abusefilter-modify-restricted": "endra endringsfilter med avgrensa handlingar", "action-abusefilter-revert": "gjera om alle endringane gjorde av eit endringsfilter", "action-abusefilter-view-private": "sjå endringsfilter merkte som private.", - "abusefilter-log": "Logg for endringsfilter", - "abusefilter-log-summary": "Loggen syner ei liste over alle handlingane fanga opp av filtra.", + "abusefilter-log-summary": "Loggen syner ei liste over alle handlingane fanga opp av filtera.", "abusefilter-log-search": "Søk i misbruksloggen", "abusefilter-log-search-user": "Brukar:", - "abusefilter-log-search-filter": "Filter-ID-ar (skil med vertikalliner):", + "abusefilter-log-search-group-any": "Kva som helst", + "abusefilter-log-search-filter": "Filter-ID-ar:", + "abusefilter-log-search-filter-help": "Skil ID-ane med teiknet «|», nytt prefikset «$1» for globale filter", "abusefilter-log-search-title": "Tittel:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-impact": "Verknad:", "abusefilter-log-search-impact-all": "Alle handlingar", "abusefilter-log-search-impact-saved": "Berre lagra endringar", "abusefilter-log-search-impact-not-saved": "Utan lagra endringar", + "abusefilter-log-search-action-label": "Utløysande handling:", + "abusefilter-log-search-action-other": "Anna", + "abusefilter-log-search-action-any": "Kva som helst", "abusefilter-log-search-action-taken-label": "Handling utført:", "abusefilter-log-search-action-taken-any": "Kva som helst", "abusefilter-log-search-submit": "Søk", @@ -67,14 +71,13 @@ "abusefilter-log-details-var": "Variabel", "abusefilter-log-details-val": "Verdi", "abusefilter-log-details-vars": "Handlingsparametrar", - "abusefilter-log-details-private": "Private loggdetaljar", + "abusefilter-log-details-privatedetails": "Private loggdetaljar", "abusefilter-log-details-ip": "Opphavs-IP", "abusefilter-log-noactions": "ingen", "abusefilter-log-details-diff": "Endringar gjorde i endringa", "abusefilter-log-linkoncontribs": "endringsfilterlogg", "abusefilter-log-linkoncontribs-text": "Endringsfilterlogg for brukaren", "abusefilter-log-linkonhistory": "sjå endringsfilterlogg", - "abusefilter-log-hidden": "(gøymd oppføring)", "abusefilter-log-hidden-implicit": "(gøymd av di versjonen har vorte sletta)", "abusefilter-log-cannot-see-details": "Du har ikkje løyve til å sjå detaljane i oppføringa.", "abusefilter-log-details-hidden": "Du kan ikkje sjå detaljane for oppføringa sidan ho er gøymd frå ålmenn vising.", @@ -84,7 +87,6 @@ "abusefilter-log-hide-reason": "Årsak:", "abusefilter-log-hide-forbidden": "Du har ikkje løyve til å gøyma oppføringar i misbruksloggen.", "logentry-abusefilter-hit": "$1 utløyste $4, utførde handlinga «$5» på $3. Handlingar utførde: $6 ($7)", - "abusefilter-management": "Handsaming av endringsfilter", "abusefilter-list": "Alle filter", "abusefilter-list-id": "Filter-ID", "abusefilter-list-pattern": "Mønster", @@ -106,6 +108,7 @@ "abusefilter-throttled": "avgrensa", "abusefilter-hitcount": "{{PLURAL:$1|eitt treff|$1 treff}}", "abusefilter-new": "Lag eit nytt filter", + "abusefilter-import-button": "Importer filter", "abusefilter-return": "Attende til filterhandsaming", "abusefilter-status-global": "Globalt", "abusefilter-list-options": "Val", @@ -142,7 +145,6 @@ "abusefilter-edit-oldwarning": "<strong>Du endrar ein gammal versjon av dette filteret. Den oppgjevne statistikken gjeld for den seinaste versjonen av filteret. Om du lagrar endringane dine, kjem du til å skriva over alle endringane som blei gjort etter versjonen du no endrar. </strong> • [[Special:AbuseFilter/history/$2|Tilbake til filterhistorikken]]", "abusefilter-edit-status-label": "Statistikk:", "abusefilter-edit-status": "Av {{PLURAL:$1|den siste handlinga|dei siste $1 handlingane}} har dette filteret passa med $2 ($3 %).", - "abusefilter-edit-status-profile": "Av {{PLURAL:$1|den siste handlinga|dei siste $1 handlingane}} har dette filteret passa med $2 ($3 %). I snitt er køyretida på $4ms og filteret nyttar {{PLURAL:$5|$5 vilkår}} av vilkårsgrensa.", "abusefilter-edit-new": "Nytt filter", "abusefilter-edit-save": "Lagra filter", "abusefilter-edit-id": "Filter-ID:", @@ -173,11 +175,16 @@ "abusefilter-edit-throttle-groups": "Grupper snøggleik etter:\n:''(eitt for kvar line, kombiner med komma)''", "abusefilter-edit-warn-message": "Systemmelding som skal verta nytta for åtvaringar:", "abusefilter-edit-warn-other": "Anna melding", - "abusefilter-edit-warn-other-label": "Sidenamn på anna melding:\n:''(utan MediaWiki-forstaving)''", + "abusefilter-edit-warn-other-label": "Sidenamn til anna melding:\n:''(utan «MediaWiki:»-forstavinga)''", "abusefilter-edit-warn-actions": "Handlingar:", - "abusefilter-edit-warn-preview": "Førehandsvis vald melding", + "abusefilter-edit-warn-preview": "Vis/gøym førehandsvising av vald melding", "abusefilter-edit-warn-edit": "Opprett/endra vald melding", + "abusefilter-edit-disallow-message": "Systemmelding som skal verta nytta ved nekting:", + "abusefilter-edit-disallow-other-label": "Sidenamn til anna melding:\n:''(utan «MediaWiki:»-forstavinga)''", + "abusefilter-edit-disallow-preview": "Vis/gøym førehandsvising av vald melding", + "abusefilter-edit-disallow-edit": "Opprett/endra vald melding", "abusefilter-edit-tag-tag": "[[Special:Tags|Merke]] som skal setjast på (eitt per line):", + "abusefilter-edit-tag-placeholder": "Legg til merke (eitt per line eller åtskilde med komma)", "abusefilter-edit-denied": "Du kan ikkje sjå detaljane for filteret sidan det er løynt frå offentleg vising.", "abusefilter-edit-main": "Filterparametrar", "abusefilter-edit-done-subtitle": "Filter endra", @@ -283,16 +290,16 @@ "abusefilter-edit-builder-vars-all-links": "Alle eksterne lenkjer i den nye teksten", "abusefilter-edit-builder-vars-added-links": "Alle eksterne lenkjer lagt til i endringa", "abusefilter-edit-builder-vars-removed-links": "Alle eksterne lenkjer fjerna i endringa", - "abusefilter-edit-builder-vars-old-text": "Den gamle wikiteksten til sida, før endringa", - "abusefilter-edit-builder-vars-new-text": "Den nye wikiteksten til sida, etter endringa", + "abusefilter-edit-builder-vars-old-wikitext": "Den gamle wikiteksten til sida, før endringa", + "abusefilter-edit-builder-vars-new-wikitext": "Den nye wikiteksten til sida, etter endringa", "abusefilter-edit-builder-vars-new-pst": "Wikitekst for ny side, førlagringsomforma", - "abusefilter-edit-builder-vars-new-text-stripped": "Ny sidetekst med eventuelle markeringar fjerna", + "abusefilter-edit-builder-vars-new-text": "Ny sidetekst med eventuelle markeringar fjerna", "abusefilter-edit-builder-vars-new-html": "Tolka HTML-kjelde for den nye versjonen", "abusefilter-edit-builder-vars-restrictions-edit": "Vernenivå på sida", "abusefilter-edit-builder-vars-restrictions-move": "Flyttervernnivå på sida", "abusefilter-edit-builder-vars-restrictions-create": "Opprettingsvernet til sida", "abusefilter-edit-builder-vars-restrictions-upload": "Opplastingsvernet til fila", - "abusefilter-edit-builder-vars-old-text-stripped": "Gamal sidetekst, med all koding teken vekk", + "abusefilter-edit-builder-vars-old-text": "Gamal sidetekst, med all koding teken vekk", "abusefilter-edit-builder-vars-old-links": "Lenkjer på sida, før endringa", "abusefilter-edit-builder-vars-old-html": "Gamal wikitekst på sida, tolka til HTML", "abusefilter-edit-builder-vars-minor-edit": "Om endringa er markert som småplukk eller ikkje", @@ -366,9 +373,10 @@ "abusefilter-test-submit": "Test", "abusefilter-test-load": "Last inn", "abusefilter-test-user": "Endringar av brukar:", + "abusefilter-test-nobots": "Gøym endringar gjorde av robotar", "abusefilter-test-period-start": "Endringar gjorde etter:", "abusefilter-test-period-end": "Endringar gjorde før:", - "abusefilter-test-page": "Endringa gjorde på sida:", + "abusefilter-test-page": "Endringar gjorde på side:", "abusefilter-test-shownegative": "Vis endringar som ikkje passar med filteret", "abusefilter-test-syntaxerr": "Du skreiv inn eit filter som inneheld ein syntaksfeil.\nDu kan sjå ei utførleg skildring ved å klikka på «{{int:abusefilter-edit-check}}»-knappen.", "abusefilter-changeslist-examine": "undersøk", @@ -394,7 +402,6 @@ "abusefilter-topnav-examine": "Gransk tidlegare endringar", "abusefilter-topnav-log": "Endringsfilterlogg", "abusefilter-topnav-tools": "Feilsøkingsverktøy", - "abusefilter-topnav-import": "Importer filter", "abusefilter-log-name": "Logg for endringsfilter", "abusefilter-log-header": "Denne loggen viser eit samandrag av endringar gjorde i filtera.\nFor utførlege detaljar, sjå [[Special:AbuseFilter/history|lista]] over dei siste filterendringane.", "abusefilter-logentry-create": "$1 {{GENDER:$2|oppretta}} $4 ($5)", diff --git a/AbuseFilter/i18n/nqo.json b/AbuseFilter/i18n/nqo.json index d85760c8..0dcbe0b3 100644 --- a/AbuseFilter/i18n/nqo.json +++ b/AbuseFilter/i18n/nqo.json @@ -1,8 +1,40 @@ { "@metadata": { "authors": [ - "Babamamadidiane" + "Babamamadidiane", + "Lancine.kounfantoh.fofana" ] }, - "abusefilter-log-nonexistent": "ߡߍ߲ ߟߊߘߏ߲߬ߣߍ߲߫ ߡߊ߬ߟߐ߲߬ߞߏ ߘߐ߫ ߏ߬ ߕߴߦߋ߲߬" + "abusefilter-log-search-user": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ", + "abusefilter-log-search-group": "ߛߍ߲ߛߍ߲ߟߊ߲ ߞߙߎ:", + "abusefilter-log-search-group-any": "ߝߏߛߌ߬", + "abusefilter-log-search-filter": "ߛߍ߲ߛߍ߲ߟߊ߲ IDs:", + "abusefilter-log-search-title": "ߞߎ߲߬ߕߐ߮:", + "abusefilter-log-search-wiki": "ߥߞߌ:", + "abusefilter-log-search-impact-all": "ߞߍߟߌ ߟߎ߬ ߓߍ߯", + "abusefilter-log-search-impact-saved": "ߡߊ߬ߝߊ߬ߟߋ߲߬ߠߌ߲߬ ߟߊߞߎ߲߬ߘߎ߬ߣߍ߲ ߠߎ߫ ߘߐߙߐ߲߫", + "abusefilter-log-search-impact-not-saved": "ߡߝߊ߬ߟߋ߲߬ߠߌ߲߬ ߟߊߞߎ߲߬ߘߎ߬ߣߍ߲ ߠߎ߫ ߛߋ߲߬ ߕߴߊ߬ ߘߐ߫", + "abusefilter-log-search-entries-label": "ߦߋߟߌ:", + "abusefilter-log-search-entries-all": "ߟߊ߬ߘߏ߲߬ߠߌ߲ ߠߎ߬ ߓߍ߯", + "abusefilter-log-search-entries-hidden": "ߟߊ߬ߘߏ߲߬ߠߌ߲߬ ߢߡߊߘߏ߱ߣߍ߲ ߠߎ߬ ߘߐߙߐ߲߫", + "abusefilter-log-search-entries-visible": "ߟߊ߬ߘߏ߲߬ߠߌ߲߬ ߦߋߕߊ ߟߎ߬ ߘߐߙߐ߲߫", + "abusefilter-log-search-action-other": "ߘߏ߫ ߜߘߍ߫", + "abusefilter-log-search-action-any": "ߝߏߛߌ߬", + "abusefilter-log-search-action-taken-label": "ߞߍߟߌ ߕߊ߬ߟߌ:", + "abusefilter-log-search-action-taken-any": "ߝߏߛߌ߬", + "abusefilter-log-search-submit": "ߢߌߣߌ߲ߠߌ߲", + "abusefilter-log-detailedentry-local": "ߛߍ߲ߛߍ߲ߟߊ߲ $1", + "abusefilter-log-detailslink": "ߝߊߙߊ߲ߝߊ߯ߛߟߌ", + "abusefilter-log-hidelink": "ߦߋߟߌ ߝߙߊ߬", + "abusefilter-log-details-val": "ߡߐ߬ߟߐ߲", + "abusefilter-log-details-vars": "ߞߍߟߌ ߟߊ߬ߓߍ߲߬ߢߐ߲߰ߡߦߊ߬ߘߊ ߟߎ߬", + "abusefilter-log-details-checkuser": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߝߛߍ߬ߝߛߍ߬", + "abusefilter-log-details-diff": "ߡߊ߬ߝߊ߬ߟߋ߲߬ߠߌ߲ ߡߍ߲ ߠߎ߬ ߛߌ߲ߘߌߣߍ߲߫ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߘߐ߫", + "abusefilter-log-nonexistent": "ߡߍ߲ ߟߊߘߏ߲߬ߣߍ߲߫ ߡߊ߬ߟߐ߲߬ߞߏ ߘߐ߫ ߏ߬ ߕߴߦߋ߲߬", + "abusefilter-list": "ߛߍ߲ߛߍ߲ߟߊ߲ ߠߎ߬ ߓߍ߯", + "abusefilter-list-id": "ߛߍ߲ߛߍ߲ߟߊ߲ ID", + "abusefilter-tools-reautoconfirm-user": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ:", + "abusefilter-edit-subtitle": "ߛߍ߲ߛߍ߲ߟߊ߲ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ $1", + "abusefilter-edit-subtitle-new": "ߛߍ߲ߛߍ߲ߟߊ߲ ߛߌ߲ߘߟߌ", + "abusefilter-edit-token-not-match": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߡߊ߫ ߟߊߞߎ߲߬ߘߎ߫ ߘߋ߬߹ ߊ߬ ߟߊߞߎ߲߬ߘߎ߬ ߌߞߐ߫ ߖߊ߰ߣߌ߲߫." } diff --git a/AbuseFilter/i18n/oc.json b/AbuseFilter/i18n/oc.json index fdcee06a..4ce3c460 100644 --- a/AbuseFilter/i18n/oc.json +++ b/AbuseFilter/i18n/oc.json @@ -2,15 +2,16 @@ "@metadata": { "authors": [ "Cedric31", - "Matma Rex", - "Unuaiga", + "Fitoschido", "Guilhelma", - "Matěj Suchánek" + "Matma Rex", + "Matěj Suchánek", + "Unuaiga" ] }, "abusefilter-desc": "Aplica d'euristicas automaticas a las modificacions", - "abusefilter": "Configuracion del filtre dels abuses", - "abuselog": "Jornal dels abuses", + "abusefilter": "Gestion del filtre dels abuses", + "abuselog": "Jornal del filtre dels abuses", "abusefilter-intro": "Benvengut(uda) dins l'interfàcia de gestion dels filtres antiabuses.\nLo filtre antiabuses es un mecanisme logicial automatizat que permet d'aplicar d'euristicas predefinidas a totas las accions.\nAquesta interfàcia presenta una lista dels filtres definits, e balha la possibilitat de los modificar.", "abusefilter-warning": "<big>'''Avertiment'''</big> : Aquesta accion es estada identificada automaticament coma nosibla.\nLas edicions que son pas constructivas seràn rapidament anulladas,\ne la repeticion de las asinadas del meteis genre provocarà lo blocatge de vòstre compte o de vòstra adreça IP.\nSe sètz convençu{{GENDER:||t|(da)}} que vòstra modificacion es constructiva, la podètz la sometre un còp de mai per la validar.\nVaquí la descripcion brèva de la règla de l’abús qu'a detectat vòstra accion : $1", "abusefilter-disallowed": "Aquesta modificacion es estada automaticament idenficada coma nusibla e, per via de consequéncia, pas permesa.\nSe sètz convençu{{GENDER:||t|(da)}} que vòstra modificacion èra constructiva, contactatz un administrator, e informatz-lo de quina accion eratz a far : $1", @@ -25,7 +26,7 @@ "right-abusefilter-view": "Veire los filtres dels abuses", "right-abusefilter-log": "Veire lo jornal dels abuses", "right-abusefilter-log-detail": "Veire las entradas del jornal detalhat dels abuses", - "right-abusefilter-private": "Veire las donadas privadas dins lo jornal dels abuses", + "right-abusefilter-privatedetails": "Veire las donadas privadas dins lo jornal dels abuses", "right-abusefilter-modify-restricted": "Modificar los filtres d'abús qu'an d'accions restrentas", "right-abusefilter-revert": "Revocar totas las modificacions efectuadas per un filtre d'abús", "right-abusefilter-view-private": "Vejatz los filtres d'abuses marcats coma privats", @@ -37,11 +38,10 @@ "action-abusefilter-view": "veire los filtres antiabuses", "action-abusefilter-log": "veire lo jornal dels filtres antiabuses", "action-abusefilter-log-detail": "veire las entradas detalhadas del jornal dels filtres antiabuses", - "action-abusefilter-private": "veire las donadas privadas dins lo jornal dels filtres antiabuses", + "action-abusefilter-privatedetails": "veire las donadas privadas dins lo jornal dels filtres antiabuses", "action-abusefilter-modify-restricted": "modificar los filtres antiabuses amb d'accions restrentas", "action-abusefilter-revert": "revocar totas las modificacions segon un filtre antiabuses donat", "action-abusefilter-view-private": "vejatz los filtres d'abuses marcats coma privats", - "abusefilter-log": "Jornal del filtre dels abuses", "abusefilter-log-summary": "Aqueste jornal aficha una lista de las accions detectadas pels filtres.", "abusefilter-log-search": "Recercar lo jornal dels abuses", "abusefilter-log-search-user": "Utilizaire :", @@ -60,20 +60,18 @@ "abusefilter-log-details-var": "Variabla", "abusefilter-log-details-val": "Valor", "abusefilter-log-details-vars": "Paramètres de l’accion", - "abusefilter-log-details-private": "Donada privada", + "abusefilter-log-details-privatedetails": "Donada privada", "abusefilter-log-details-ip": "Provenéncia de l’adreça IP", "abusefilter-log-noactions": "pas cap", "abusefilter-log-details-diff": "Cambiaments faits dins la modificacion", "abusefilter-log-linkoncontribs": "Jornal dels abuses", "abusefilter-log-linkoncontribs-text": "Jornal dels abuses d'{{GENDER:$1|aqueste utilizaire|aquesta utilizaira}}", - "abusefilter-log-hidden": "(entrada amagada)", "abusefilter-log-hidden-implicit": "(amagada perque la version es estada suprimida)", "abusefilter-log-hide-legend": "Amagar l'entrada dins los jornals", "abusefilter-log-hide-id": "Identificant de l'entrada de jornal :", "abusefilter-log-hide-hidden": "Amagar aquesta entrada a la vista del public", "abusefilter-log-hide-reason": "Motiu :", "abusefilter-log-hide-reason-other": "Autra rason / rason suplementària :", - "abusefilter-management": "Gestion del filtre dels abuses", "abusefilter-list": "Totes los filtres", "abusefilter-list-id": "Filtre ID", "abusefilter-list-pattern": "Motiu", @@ -94,6 +92,7 @@ "abusefilter-disabled": "Desactivat", "abusefilter-hitcount": "$1 {{PLURAL:$1|visita|visitas}}", "abusefilter-new": "Crear un filtre novèl", + "abusefilter-import-button": "Importar un filtre", "abusefilter-return": "Tornar a la gestion dels filtres", "abusefilter-status-global": "Global", "abusefilter-list-options": "Opcions", @@ -129,7 +128,6 @@ "abusefilter-edit-oldwarning": "<strong>Sètz a modificar una version anciana del filtre. Las estatisticas afichadas son per la version correnta d'aqueste. Se salvatz vòstras modificacions, van suprimir las modificacions efectuadas ulteriorament.</strong> • [[Special:AbuseFilter/history/$2|Tornar a l'istoric d'aqueste filtre]]", "abusefilter-edit-status-label": "Estatisticas :", "abusefilter-edit-status": "{{PLURAL:$1|Dins la darrièra accion|Demest las $1 darrièras accions}}, aqueste filtre a atench $2 ($3 %).", - "abusefilter-edit-status-profile": "{{PLURAL:$1|Dins la darrièra accion|Demest las $1 darrièras accions}}, aqueste filtre a atench $2 ($3 %).\nEn mejana, la durada d'execucion d'aqueste filtre es de $4 ms e utiliza $5 condicion{{PLURAL:$5||s}} del limit de las condicions.", "abusefilter-edit-new": "Filtre novèl", "abusefilter-edit-save": "Salvar lo filtre", "abusefilter-edit-id": "Filtre ID :", @@ -268,15 +266,15 @@ "abusefilter-edit-builder-vars-all-links": "Totes los ligams extèrnes dins lo tèxte novèl", "abusefilter-edit-builder-vars-added-links": "Totes los ligams extèrnes aponduts dins la modificacion", "abusefilter-edit-builder-vars-removed-links": "Totes los ligams extèrnes levats dins la modificacion", - "abusefilter-edit-builder-vars-old-text": "Ancian tèxte de la pagina, abans la modificacion", - "abusefilter-edit-builder-vars-new-text": "Tèxte novèl de la pagina, aprèp la modificacion", - "abusefilter-edit-builder-vars-new-text-stripped": "Tèxte novèl de la pagina, sens cap de balisa", + "abusefilter-edit-builder-vars-old-wikitext": "Ancian tèxte de la pagina, abans la modificacion", + "abusefilter-edit-builder-vars-new-wikitext": "Tèxte novèl de la pagina, aprèp la modificacion", + "abusefilter-edit-builder-vars-new-text": "Tèxte novèl de la pagina, sens cap de balisa", "abusefilter-edit-builder-vars-new-html": "Tèxte de la version novèla transformat en HTML", "abusefilter-edit-builder-vars-restrictions-edit": "Nivèl de proteccion d'edicion de la pagina", "abusefilter-edit-builder-vars-restrictions-move": "Nivèl de proteccion de cambiament de nom de la pagina", "abusefilter-edit-builder-vars-restrictions-create": "Crear una proteccion per la pagina", "abusefilter-edit-builder-vars-restrictions-upload": "Proteccion de telecargament del fichièr", - "abusefilter-edit-builder-vars-old-text-stripped": "Tèxte de la pagina anciana, desprovesit de tota mesa en forma", + "abusefilter-edit-builder-vars-old-text": "Tèxte de la pagina anciana, desprovesit de tota mesa en forma", "abusefilter-edit-builder-vars-old-links": "Ligams dins la pagina, abans la modificacion", "abusefilter-edit-builder-vars-old-html": "Wikitèxt de la pagina anciana, parsada en HTML", "abusefilter-edit-builder-vars-minor-edit": "Se la modificacion es marcada coma menora o pas", @@ -313,7 +311,7 @@ "abusefilter-exception-dividebyzero": "Ensag ilegal de devesir $2 per zèro al caractèr $1.", "abusefilter-exception-unrecognisedvar": "Variabla pas reconeguda $2 al caractèr $1", "abusefilter-exception-notenoughargs": "Pas pro de paramètres per la foncion $2 apelada al caractèr $1.\n$3 {{PLURAL:$3|argument demandat|arguments demandats}}, $4 {{PLURAL:$4|obtengut|obtenguts}}", - "abusefilter-exception-regexfailure": "Error dins l’expression regulara « $3 » al caractèr $1 : « $2 »", + "abusefilter-exception-regexfailure": "Error dins l’expression regulara « $2 » al caractèr $1.", "abusefilter-exception-overridebuiltin": "Espotiment interdich de la variabla disponibla per defaut « $2 » al caractèr $1.", "abusefilter-exception-outofbounds": "Demanda de l'element inexistent $2 (talha de la lista = $3) al caractèr $1.", "abusefilter-exception-notarray": "Demanda d'un element dins quicòm mai qu'un tablèu al caractèr $1.", @@ -374,7 +372,6 @@ "abusefilter-topnav-examine": "Examinar las modificacions precedentas", "abusefilter-topnav-log": "Jornal antiabuses", "abusefilter-topnav-tools": "Aisinas de debogatge", - "abusefilter-topnav-import": "Importar un filtre", "abusefilter-log-name": "Jornal del filtre antiabuses", "abusefilter-log-header": "Aqueste jornal aficha un somari de las modificacions faitas als filtres.\nPer mai de detalhs, vejatz [[Special:AbuseFilter/history|la lista]] dels darrièrs cambiaments del filtre.", "abusefilter-log-noresults": "Pas cap de resultat", diff --git a/AbuseFilter/i18n/or.json b/AbuseFilter/i18n/or.json index 3df6224b..fef1fb0e 100644 --- a/AbuseFilter/i18n/or.json +++ b/AbuseFilter/i18n/or.json @@ -4,16 +4,16 @@ "Ansumang", "Jnanaranjan Sahu", "Jose77", + "MKar", "Odisha1", "Psubhashish", "Shisir 1945", - "ଆଶୁତୋଷ କର", - "MKar" + "ଆଶୁତୋଷ କର" ] }, "abusefilter-desc": "ଆପେଆପେ ଅଧିକତର ସମ୍ଭାବନା ସମ୍ପାଦନାରେ ଯୋଡ଼ିଥାଏ", - "abusefilter": "ଅପବ୍ୟବହାର ଛଣା ସଜାଣି", - "abuselog": "ଅପବ୍ୟବହାର ଇତିହାସ", + "abusefilter": "ଗାଳି ଗୁଲଜ ରୋକିବା ବ୍ୟବସ୍ଥା", + "abuselog": "ଅପବ୍ୟବହାର ଛଣା", "abusefilter-intro": "ଅପବ୍ୟବହାର ଛଣା ପରିଚାଳନା ଇଣ୍ଟରଫେସକୁ ପାଛୋଟା ।\nଅପବ୍ୟବହାର ଛଣା ଏକ ଆପେଆପେ ହେଉଥିବା ସଫ୍ଟୱାର ପ୍ରକ୍ରିୟା ଯାହା ଆପେଆପେ ଏକ ସାଧାରଣ ଜ୍ଞାନକୁ ନେଇ କାମ ସବୁ କରିଥାଏ ।\nଏହି ଇଣ୍ଟରଫେସ ବଛା କେତେକ ଛଣା ଦେଖାଉଛି, ଏହା ସେସବୁକୁ ବଦଳାଇବା ପାଇଁ ଅନୁମତି ଦେଇଥାଏ ।", "abusefilter-warning": "'''ଚେତାବନୀ''': ଏହି କାମଟି ବିପଦଜନକ ବୋଲି ଚିହ୍ନିତ ହୋଇଛି ।\nଅଣ-ଗଠନମୂଳକ ସମ୍ପାଦନାସବୁ ସଙ୍ଗେ ସଙ୍ଗେ ପଛକୁ ଫେରାଇଦିଅଯିବ,\nଏବଂ ଭୁଲ, ଅଯଥା ତଥ୍ୟ ଥିବା ଓ ବାରମ୍ବାର ଅଣ-ଗଠନମୂଳକ ସମ୍ପାଦନା କରାଯାଉଥିଲେ ଆପଣଙ୍କ IP ଠିକଣାଟି ଅଟକାଇଦିଆଯିବ ।\nଯଦି ଆପଣ ଏହି ସମ୍ପାଦନାଟି ଗଠନମୂଳକ ବୋଲି ଭାବୁଛନ୍ତି ତେବେ \"ପଠାନ୍ତୁ\" ଉପରେ କ୍ଲିକ କରି ଥୟ କରନ୍ତୁ ।\nଏହି ଅପବ୍ୟବହାରର ନୀତିବଳି ଥିବା ଏକ ସଂକ୍ଷିପ୍ତ ବିବରଣୀ ଯାହା ଆପଣଙ୍କ କାମ ସଙ୍ଗେ ମିଳୁଛି: $1", "abusefilter-blocker": "ଅପବ୍ୟବହାର ଛଣା", @@ -24,7 +24,7 @@ "right-abusefilter-view": "ଅପବ୍ୟବହାର ଛଣା ଦେଖାଇବେ", "right-abusefilter-log": "ଅପବ୍ୟବହାର ଇତିହାସ ଦେଖିବା", "right-abusefilter-log-detail": "ଇତିହାସ ନିବେଶର ସବିଶେଷ ଦେଖିବେ", - "right-abusefilter-private": "ବ୍ୟକ୍ତିଗତ ତଥ୍ୟ ଏକ ଅପବ୍ୟବହାର ଇତିହାସ ପୃଷ୍ଠାରେ ଦେଖିବେ", + "right-abusefilter-privatedetails": "ବ୍ୟକ୍ତିଗତ ତଥ୍ୟ ଏକ ଅପବ୍ୟବହାର ଇତିହାସ ପୃଷ୍ଠାରେ ଦେଖିବେ", "right-abusefilter-modify-restricted": "ଅପବ୍ୟବହାର ଛଣାକୁ କିଳାଯାଇଥିବା କାମ ସହ ବଦଳାନ୍ତୁ", "right-abusefilter-revert": "ଦିଆଯାଇଥିବା ଅପବ୍ୟବହାର ଛଣାରେ ହୋଇଥିବା ବଦଳସବୁକୁ ପଛକୁ ଫେରାଇଦିଅନ୍ତୁ", "right-abusefilter-view-private": "ବ୍ୟକ୍ତିଗତ ଭବରେ ଚିହ୍ନିତ ଅପବ୍ୟବହାର ଛଣାସବୁ ଦେଖନ୍ତୁ", @@ -34,11 +34,10 @@ "action-abusefilter-view": "ଅପବ୍ୟବହାର ଛଣା ଦେଖାଇବେ", "action-abusefilter-log": "ଅପବ୍ୟବହାର ଲଗ ଦେଖିବା", "action-abusefilter-log-detail": "ଅପବ୍ୟବହାର ଇତିହାସର ସବିଶେଷ ଦେଖିବେ", - "action-abusefilter-private": "ବ୍ୟକ୍ତିଗତ ତଥ୍ୟ ଏକ ଅପବ୍ୟବହାର ଇତିହାସ ପୃଷ୍ଠାରେ ଦେଖିବେ", + "action-abusefilter-privatedetails": "ବ୍ୟକ୍ତିଗତ ତଥ୍ୟ ଏକ ଅପବ୍ୟବହାର ଇତିହାସ ପୃଷ୍ଠାରେ ଦେଖିବେ", "action-abusefilter-modify-restricted": "ଅପବ୍ୟବହାର ଛଣାକୁ କିଳାଯାଇଥିବା କାମ ସହ ବଦଳାଇବେ", "action-abusefilter-revert": "ଏକ ନିର୍ଦିଷ୍ଟ ଅପବ୍ୟବହାର ଛଣାର ବଦଳସବୁ ଲେଉଟାଇ ଦିଆଗଲା", "action-abusefilter-view-private": "ବ୍ୟକ୍ତିଗତ ଭବରେ ଚିହ୍ନିତ ଅପବ୍ୟବହାର ଛଣାସବୁ ଦେଖନ୍ତୁ", - "abusefilter-log": "ଅପବ୍ୟବହାର ଛଣା", "abusefilter-log-summary": "ଏହି ଇତିହାସ ଅପବ୍ୟବହାର ଛଣା ଦେଇ ହୋଇଥିବା ସବୁ କାମର ଇତିହାସ ଦେଖାଇଥାଏ ।", "abusefilter-log-search": "ଅପବ୍ୟବହାର ଇତିହାସ ଖୋଜିବେ", "abusefilter-log-search-user": "ବ୍ୟବହାରକାରୀ", @@ -57,20 +56,18 @@ "abusefilter-log-details-var": "ବଦଳୁଥିବା", "abusefilter-log-details-val": "ମୂଲ୍ୟ", "abusefilter-log-details-vars": "କାମର ସଙ୍ଗଠକ", - "abusefilter-log-details-private": "ଗୋପନ ଡାଟା", + "abusefilter-log-details-privatedetails": "ଗୋପନ ଡାଟା", "abusefilter-log-details-ip": "ଆଇ.ପି. ଠିକଣା ତିଆରି କରୁଛି", "abusefilter-log-noactions": "କିଛି ନାହିଁ", "abusefilter-log-details-diff": "ସମ୍ପାଦନାରେ କରିଥିବା ବଦଳ", "abusefilter-log-linkoncontribs": "ଅପବ୍ୟବହାର ଲଗ", "abusefilter-log-linkoncontribs-text": "ଏହି ବ୍ୟବହାରକାରୀଙ୍କ ପାଇଁ ଖରାପ ଲଗ", - "abusefilter-log-hidden": "(ଲୁଚାଯାଇଥିବା ପ୍ରବେଶ)", "abusefilter-log-details-hidden": "ଆପଣ ଏହି ଏଣ୍ଟ୍ରି ଉପରେ ବିଶେଷ କିଛି ଜାଣିପାରିବେ ନାହିଁ କାରଣ ଏହା ସାଧାରଣ ନଜର ଆଢୁଆଳରେ ରଖାଯାଇଛି ।", "abusefilter-log-hide-legend": "ଲଗ ଏଣ୍ଟ୍ରି ଲୁଚାଇବା", "abusefilter-log-hide-id": "ଲଗ ଏଣ୍ଟ୍ରି ଆଇ.ଡ଼ି:", "abusefilter-log-hide-hidden": "ସମସ୍ତଙ୍କ ଦେଖିବାରୁ ଏହାକୁ ଅଟକାଇବା", "abusefilter-log-hide-reason": "କାରଣ", "abusefilter-log-hide-forbidden": "ଲଗ ପ୍ରବେଶସବୁକୁ ଲୁଚାଇବା ପାଇଁ ଏପଣଙ୍କୁ ଅନୁମତି ଦିଆଯାଇନାହିଁ ।", - "abusefilter-management": "ଗାଳି ଗୁଲଜ ରୋକିବା ବ୍ୟବସ୍ଥା", "abusefilter-list": "ସବୁ ଛଣା", "abusefilter-list-id": "IDଟିକୁ ଛାଣିବା", "abusefilter-list-status": "ସ୍ଥିତି", @@ -90,6 +87,7 @@ "abusefilter-disabled": "ଅଚଳ କରିଦିଆଯାଇଛି", "abusefilter-hitcount": "$1 ଟି {{PLURAL:$1|ହିଟ|ହିଟ}}", "abusefilter-new": "ଗୋଟିଏ ନୁଅ ଛଣା ତିଅରି କରିବେ", + "abusefilter-import-button": "ଛଣା ଆମଦାନି କରିବେ", "abusefilter-return": "ଛଣା ପରିଚାଳନାକୁ ଫେରିଯିବେ", "abusefilter-status-global": "ଜଗତ", "abusefilter-list-options": "ପସନ୍ଦ", @@ -132,7 +130,7 @@ "abusefilter-edit-action-degroup": "ଏହି ବ୍ୟବହାରକାରୀଙ୍କୁ ଅଧିକ ସ୍ସୁବିଧାସୁଯୋଗ ଥିବା ଦଳରୁ ବାହାର କରିଦେବେ", "abusefilter-edit-action-block": "ବ୍ୟବହାରକାରୀଙ୍କୁ ବାସନ୍ଦ କରିବେ ଓ/ବା IP ଠିକଣାକୁ ଅଟକାଇବେ", "abusefilter-edit-action-throttle": "କେବଳ ବ୍ୟବହାରକାରୀ ଏକ ମୂଲ୍ୟ ବାହରକୁ ଚାଲିଗଲେ କାମଟି କରିବେ", - "abusefilter-edit-action-rangeblock": "ବ୍ୟବହାରକାରୀ ଆରମ୍ଭ କରିଥିବା /16 କୁ ଅଟକାଇଦେବେ", + "abusefilter-edit-action-rangeblock": "ବ୍ୟବହାରକାରୀଙ୍କଠାରୁ ଆରମ୍ଭ ସମ୍ବନ୍ଧିତ IP ବର୍ଗକୁ ଅଟକାବେ", "abusefilter-edit-action-tag": "ଆଗକୁ ହେବାକୁ ଥିବା ସମୀକ୍ଷା ପାଇଁ ଏହି ସମ୍ପାଦନାକୁ ଚିହ୍ନିତ କରାଗଲା", "abusefilter-edit-throttle-count": "ଅନୁମୋଦିତ କାମ ସଂଖ୍ୟା:", "abusefilter-edit-throttle-period": "କାର୍ଯ୍ୟକାଳ:", @@ -157,7 +155,7 @@ "abusefilter-edit-tools": "ଉପକରଣ:", "abusefilter-edit-test-link": "ନଗଦ ବଦଳ ସବୁରେ ଏହି ଛଣାଟିକୁ ପରଖନ୍ତୁ", "abusefilter-edit-export": "ଏହି ଚଣାଟିକୁ ଏହି ଉଇକିରୁ ଆଉ ଏକ ଉଇକିକୁ ଘୁଞ୍ଚାଇଦିଅନ୍ତୁ", - "abusefilter-edit-syntaxok": "କିଛି ବି ସିଣ୍ଟାକ୍ସ ମିଳିଲା ନାହିଁ ।", + "abusefilter-edit-syntaxok": "କୌଣସି ସିଣ୍ଟାକ୍ସ ମିଳିଲା ନାହିଁ ।", "abusefilter-edit-syntaxerr": "ସିଣ୍ଟାକ୍ସରେ ଭୁଲ ଥିବା ଦେଖିବାକୁ ମିଳିଲା: $1", "abusefilter-edit-notallowed": "ଆପଣଙ୍କୁ ଅପବ୍ୟବହାର ଛଣା ତିଆରି/ସମ୍ପାଦନା କରିବାରୁ ବାରଣ କରାଯାଇଛି ।", "abusefilter-edit-builder-select": "ତୀର ଚିହ୍ନ ଥିବା ଜାଗାରେ ଏହା ପାଇଁ ଏକ ବିକଳ୍ପ ବାଛନ୍ତୁ", @@ -191,7 +189,7 @@ "abusefilter-edit-builder-group-funcs": "କାମ", "abusefilter-edit-builder-funcs-length": "ଷ୍ଟ୍ରିଙ୍ଗ ଲମ୍ବ (length)", "abusefilter-edit-builder-funcs-lcase": "ଛୋଟ ଅକ୍ଷର ପାଇଁ (lcase)", - "abusefilter-edit-builder-funcs-ccnorm": "ଦ୍ଵନ୍ଦ ଉପୁଜାଉଥିବା ଅକ୍ଷର କୁ ସାଧାରଣ କରିବେ (ccnorm)", + "abusefilter-edit-builder-funcs-ccnorm": "ଦ୍ଵନ୍ଦ ଉପୁଜାଉଥିବା ଅକ୍ଷରକୁ ସାଧାରଣ କରିବେ (ccnorm)", "abusefilter-edit-builder-funcs-rmdoubles": "ଦ୍ଵିତ-ଅକ୍ଷର କାଢ଼ିଦେବେ (rmdoubles)", "abusefilter-edit-builder-funcs-specialratio": "ବିଶେଷ ଅକ୍ଷରସମୂହ / ସବୁ ଅକ୍ଷର (specialratio)", "abusefilter-edit-builder-funcs-norm": "ସାଧାରଣ କରିବେ (norm)", @@ -219,7 +217,7 @@ "abusefilter-edit-builder-vars-page-id": "ପୃଷ୍ଠା ଆଇଡ଼ି", "abusefilter-edit-builder-vars-page-ns": "ପୃଷ୍ଠା ନେମସ୍ପେସ", "abusefilter-edit-builder-vars-page-title": "ପୃଷ୍ଠା ଶୀର୍ଷକ (ବିନା ନେମସ୍ପେସ)", - "abusefilter-edit-builder-vars-page-prefixedtitle": "ପୁରା ପୃଷ୍ଠା ନାମ", + "abusefilter-edit-builder-vars-page-prefixedtitle": "ପୂରା ପୃଷ୍ଠା ନାମ", "abusefilter-edit-builder-vars-movedfrom-id": "ଘୁଞ୍ଚାହେବା ମୂଳାଧାର ପୃଷ୍ଠା ID", "abusefilter-edit-builder-vars-movedfrom-ns": "ଘୁଞ୍ଚାହେବା ମୂଳାଧାର ପୃଷ୍ଠାର ନେମସ୍ପେସ", "abusefilter-edit-builder-vars-movedfrom-title": "ଘୁଞ୍ଚାଯିବା ମୂଳାଧାର ପୃଷ୍ଠାର ନାମ", @@ -237,14 +235,14 @@ "abusefilter-edit-builder-vars-all-links": "ସବୁଯାକ ବାହାର ଲିଙ୍କ ନୂଆ ଲେଖା ଭାବରେ ଦେଖାଯିବ", "abusefilter-edit-builder-vars-added-links": "ସବୁଯାକ ବାହାର ଲିଙ୍କ ସମ୍ପାଦନାରେ ଯୋଡ଼ାଯିବ", "abusefilter-edit-builder-vars-removed-links": "ସବୁଯାକ ବାହାର ଲିଙ୍କ ଏହି ସମ୍ପାଦନାରୁ ବାହାର କରିଦିଆଗଲା", - "abusefilter-edit-builder-vars-old-text": "ସମ୍ପାଦନା ଆଗରୁ ଥିବା ପୁରୁଣା ପୃଷ୍ଠା ଉଇକିଲେଖା", - "abusefilter-edit-builder-vars-new-text": "ସମ୍ପାଦନା ପରେ ଥିବା ନୂଆ ପୃଷ୍ଠା ଉଇକିଲେଖା", - "abusefilter-edit-builder-vars-new-text-stripped": "ନୂଆ ପୃଷ୍ଠା ଲେଖା, କୌଣସି ମାର୍କଅପରୁ ବାହାର କରାଗଲା", + "abusefilter-edit-builder-vars-old-wikitext": "ସମ୍ପାଦନା ଆଗରୁ ଥିବା ପୁରୁଣା ପୃଷ୍ଠା ଉଇକିଲେଖା", + "abusefilter-edit-builder-vars-new-wikitext": "ସମ୍ପାଦନା ପରେ ଥିବା ନୂଆ ପୃଷ୍ଠା ଉଇକିଲେଖା", + "abusefilter-edit-builder-vars-new-text": "ନୂଆ ପୃଷ୍ଠା ଲେଖା, କୌଣସି ମାର୍କଅପରୁ ବାହାର କରାଗଲା", "abusefilter-edit-builder-vars-new-html": "ପାର୍ସ କରାଯାଇଥିବା HTML ମୂଳାଧାରର ନୂଆ ସଂସ୍କରଣ", "abusefilter-edit-builder-vars-restrictions-edit": "ପୃଷ୍ଠାଟିର ପ୍ରତିରକ୍ଷା ପରିମାଣ ବଦଳାନ୍ତୁ", "abusefilter-edit-builder-vars-restrictions-move": "ପୃଷ୍ଠାଟିର ସୁରକ୍ଷା ପରିମାଣ ଘୁଞ୍ଚାନ୍ତୁ", "abusefilter-edit-builder-vars-restrictions-upload": "ଏହି ଫାଇଲ ପାଇଁ ସୁରକ୍ଷା ଅପଲୋଡ କରିବେ", - "abusefilter-edit-builder-vars-old-text-stripped": "ନୂଆ ପୃଷ୍ଠା ଲେଖା, କୌଣସି ମାର୍କଅପରୁ ବାହାର କରାଗଲା", + "abusefilter-edit-builder-vars-old-text": "ନୂଆ ପୃଷ୍ଠା ଲେଖା, କୌଣସି ମାର୍କଅପରୁ ବାହାର କରାଗଲା", "abusefilter-edit-builder-vars-old-links": "ଏହି ସମ୍ପାଦନା ଆଗରୁ ଏହି ପୃଷ୍ଠାରେ ଥିବା ଲିଙ୍କସମୂହ", "abusefilter-edit-builder-vars-old-html": "ପୁରୁଣା ପୃଷ୍ଠା ଉଇକିଟେକ୍ସଟ, HTMLକୁ ପାର୍ସ କରାଯାଇଛି", "abusefilter-edit-builder-vars-minor-edit": "ଏହି ସମ୍ପାଦନାଟି ଏକ ସାମାନ୍ୟ ବଦଳ ଭାବେ ଗଣା କି ନୁହେଁ", @@ -323,7 +321,6 @@ "abusefilter-topnav-examine": "ପୁରୁଣା ବଦଳଗୁଡିକୁ ପରୀକ୍ଷା କରିବେ", "abusefilter-topnav-log": "ଅପବ୍ୟବହାର ଲଗ", "abusefilter-topnav-tools": "ଡିବଗ କରିବା ଉପକରଣ", - "abusefilter-topnav-import": "ଛଣା ଆମଦାନି କରିବେ", "abusefilter-log-name": "ଅପବ୍ୟବହାର ଛଣା ଇତିହାସ", "abusefilter-log-noresults": "ପରିଣାମହୀନ", "abusefilter-diff-title": "ସଙ୍କଳନ ଭିତରେ ଥିବା ତଫାତ", diff --git a/AbuseFilter/i18n/pa.json b/AbuseFilter/i18n/pa.json index 2ac9e35c..9ca0d080 100644 --- a/AbuseFilter/i18n/pa.json +++ b/AbuseFilter/i18n/pa.json @@ -13,7 +13,6 @@ "abusefilter-log-diff": "ਫ਼ਰਕ", "abusefilter-log-details-val": "ਮੁੱਲ", "abusefilter-log-details-vars": "ਕਾਰਵਾਈ ਦੇ ਮਾਪਦੰਡ", - "abusefilter-log-details-private": "ਨਿੱਜੀ ਸਮੱਗਰੀ", "abusefilter-log-noactions": "ਕੋਈ ਨਹੀਂ", "abusefilter-log-details-diff": "ਸੋਧ ਵਿਚ ਕੀਤੀਆਂ ਗਈਆਂ ਤਬਦੀਲੀਆਂ", "abusefilter-log-linkoncontribs": "ਦੁਰਵਰਤੋਂ ਦਾ ਚਿੱਠਾ", diff --git a/AbuseFilter/i18n/pam.json b/AbuseFilter/i18n/pam.json index 7146bffb..9884ef3f 100644 --- a/AbuseFilter/i18n/pam.json +++ b/AbuseFilter/i18n/pam.json @@ -1,8 +1,8 @@ { "@metadata": { "authors": [ - "Val2397", - "Leeheonjin" + "Leeheonjin", + "Val2397" ] }, "abusefilter-log-search-user": "Talagamit", @@ -19,6 +19,5 @@ "abusefilter-log-details-ip": "Penibatan ning IP karinan", "abusefilter-log-noactions": "ala", "abusefilter-log-linkoncontribs": "tala ning pamagasamantala", - "abusefilter-log-linkoncontribs-text": "Pamagsamantalang tala nining talagamit", - "abusefilter-log-hidden": "(makasalikot a pepalub)" + "abusefilter-log-linkoncontribs-text": "Pamagsamantalang tala nining talagamit" } diff --git a/AbuseFilter/i18n/pfl.json b/AbuseFilter/i18n/pfl.json index d093dad0..52c8170e 100644 --- a/AbuseFilter/i18n/pfl.json +++ b/AbuseFilter/i18n/pfl.json @@ -1,15 +1,15 @@ { "@metadata": { "authors": [ + "Als-Holder", "Manuae", - "Xqt", "Matma Rex", - "Als-Holder" + "Xqt" ] }, "abusefilter-desc": "Bnudzd selbschddendisch Medoode uff Ännarunge", - "abusefilter": "Siewb-Oischdellunge gesche Missbraisch", - "abuselog": "Logbuch fa Missbraisch", + "abusefilter": "Vawaldung vunde Missbraisch-Siewb", + "abuselog": "Logbuch fa Missbraisch-Siewb", "abusefilter-intro": "Willkumme uffde Owaflesch fa die Hondhawung vunde Missbraisch-Siewb.\nMissbraisch-Siewb sind selbschdschdendischi Voarischdunge, wu vun alle Medoode uff alle Ännarunge õwende dun.\nDie Owaflesch zaischd ä Lischd vun alle Siewb, wu ma a ännare konn.", "abusefilter-warning": "'''Bassma uff''': Was du so mache wilschd, wead als uuerwinschd gseje.\nWonns nix isch, weads a glai widda zrigg'gsezd odda gleschd.\nWonn des was dudo meamols magschd nix isch, weaschd gschberd.\nWonn dengge duschd, die Ännarung isch guud, doan konschd a ruhisch waida mache.\nÄ korzi Schildarung vunde Reschl, wudes ausgleesd kabd hod isch: $1", "abusefilter-disallowed": "Was du do mache wilschd, werd als schedlisch gseje un isch deswesche vabode worre.\nWonn menschd, dasses donoi kead, donn gebem Adminischdrador Bschaid.\nÄ korzi Schildarung vunde Reschl, wudes ausgleesd kabd hod isch: $1", @@ -24,7 +24,7 @@ "right-abusefilter-view": "Missbraisch-Siewb õgugge", "right-abusefilter-log": "Logbuch vum Missbraisch-Siewb õgugge", "right-abusefilter-log-detail": "Nejares im Logbuch vum Missbraisch-Siewb õgugge", - "right-abusefilter-private": "Briwades im Logbuch vum Missbraisch-Siewb õgugge", + "right-abusefilter-privatedetails": "Briwades im Logbuch vum Missbraisch-Siewb õgugge", "right-abusefilter-modify-restricted": "Õn Missbraisch-Siewb mid oigschrengdi Maßnõhme schaffe", "right-abusefilter-revert": "Alli Ännarunge vunem bschdimmde Missbraisch-Siewb rigg'gängisch mache", "right-abusefilter-view-private": "Briwade Missbraisch-Siewb õgugge", @@ -36,11 +36,10 @@ "action-abusefilter-view": "Missbraisch-Siewb õgugge", "action-abusefilter-log": "Logbuch vum Missbraisch-Siewb õgugge", "action-abusefilter-log-detail": "Nejares im Logbuch vum Missbraisch-Siewb õgugge", - "action-abusefilter-private": "Briwades im Logbuch vum Missbraisch-Siewb õgugge", + "action-abusefilter-privatedetails": "Briwades im Logbuch vum Missbraisch-Siewb õgugge", "action-abusefilter-modify-restricted": "Õn Missbraisch-Siewb midd oigschrengdi Maßnõhme schaffe", "action-abusefilter-revert": "Alle Ännarunge vunem bschdimmde Missbraisch-Siewb rigg'gengisch mache", "action-abusefilter-view-private": "Briwade Missbraisch-Siewb õgugge", - "abusefilter-log": "Logbuch fa Missbraisch-Siewb", "abusefilter-log-summary": "S'Logbuch zaischd ä Lischd vunde Ablaif, wus Siewb uffgschnabbd hod.", "abusefilter-log-search": "Im Logbuch vum Missbraisch-Siewb gugge", "abusefilter-log-search-user": "Middawaida:", @@ -59,13 +58,12 @@ "abusefilter-log-details-var": "Vaänalischi", "abusefilter-log-details-val": "Werd", "abusefilter-log-details-vars": "Greeß fa Maßnõhme", - "abusefilter-log-details-private": "Briwadi Daade", + "abusefilter-log-details-privatedetails": "Briwadi Daade", "abusefilter-log-details-ip": "Uaschbrungs-IP-Adress", "abusefilter-log-noactions": "känn", "abusefilter-log-details-diff": "Ännarunge vum Schaffe", "abusefilter-log-linkoncontribs": "Logbuch fa Missbraisch", "abusefilter-log-linkoncontribs-text": "Logbuch vum Missbraisch-Siewb fa den Middawaida", - "abusefilter-log-hidden": "(Oidrach vaschdeggld)", "abusefilter-log-hidden-implicit": "(vaschdeggld, s'isch gleschd worre)", "abusefilter-log-cannot-see-details": "Du hoschd kä Räschd nejares vunde Oigawb õzgugge.", "abusefilter-log-details-hidden": "Du konschda Nejares iwade Oidrach nedd õgugge, s'isch vaschdeggld.", @@ -75,7 +73,6 @@ "abusefilter-log-hide-reason": "Grund:", "abusefilter-log-hide-forbidden": "Du hoschd kä Räschd fas vaschdeggle vun Oidräsch vum Logbuch vum Missbraisch-Siewb.", "logentry-abusefilter-hit": "$1 hodd baide Maßnohm „$5“ uff $3 s'Siewb $4 ausglesd. Bassierd isch: $6 ($7)", - "abusefilter-management": "Vawaldung vunde Missbraisch-Siewb", "abusefilter-list": "Alli Siewb", "abusefilter-list-id": "Siewb-ID", "abusefilter-list-status": "Zuschdond", @@ -95,6 +92,7 @@ "abusefilter-disabled": "Abgschdeld", "abusefilter-hitcount": "$1 {{PLURAL:$1|Dreffa|Dreffa}}", "abusefilter-new": "N'naijs Siewb mache", + "abusefilter-import-button": "Filda roihole", "abusefilter-return": "Zrigg zude Vawaldung vunde Missbraisch-Siewb", "abusefilter-status-global": "Global", "abusefilter-list-options": "Meschlischkaide:", @@ -123,7 +121,6 @@ "abusefilter-edit-oldwarning": "<strong>Du duschd do õnnare alde Version vum Siewb schaffe.\nDie Schdadischdig gild bloß fa die naischd Version vum Siewb.\nWonn des do schbaischere duschd, iwaschraibschd alle Ännarunge, wu saidher gmachd worre sinn.</strong> •\n[[Special:AbuseFilter/history/$2|Zrigg zude Gschischd vum Siewb]].", "abusefilter-edit-status-label": "Schdadischdig:", "abusefilter-edit-status": "Vunde ledschde {{PLURAL:$1|Agzion isch|$1 Agzione sinn}} $2 ($3 %) vundem Siewb gfunne worre.", - "abusefilter-edit-status-profile": "Vunde ledschde {{PLURAL:$1|Agzion isch|$1 Agzione sinn}} $2 ($3 %) vundem Siewb gfunne worre.\nIm Schnidd hodda dodvu $4 ms un $5 {{PLURAL:$5|Bedingung|Bedingunge}} vunde Hegschdzahl gbrauchd.", "abusefilter-edit-new": "Naije Siewb", "abusefilter-edit-save": "Siewb schbaischere", "abusefilter-edit-id": "Siewb-ID", @@ -257,15 +254,15 @@ "abusefilter-edit-builder-vars-all-links": "Alli externe Ling'gs im naije Tegschd", "abusefilter-edit-builder-vars-added-links": "Alli inde B'awaidung uffgnummene externe Ling'gs", "abusefilter-edit-builder-vars-removed-links": "Alli inde B'awaidung gleschdi externe Ling'gs", - "abusefilter-edit-builder-vars-old-text": "Alda Wikitegschd vunde Said, vorm b'awaide", - "abusefilter-edit-builder-vars-new-text": "Naije Wikitegschd vunde Said, nochm b'awaide", - "abusefilter-edit-builder-vars-new-text-stripped": "Naije Saidetegschd, ohni Tegschdauszaischnung", + "abusefilter-edit-builder-vars-old-wikitext": "Alda Wikitegschd vunde Said, vorm b'awaide", + "abusefilter-edit-builder-vars-new-wikitext": "Naije Wikitegschd vunde Said, nochm b'awaide", + "abusefilter-edit-builder-vars-new-text": "Naije Saidetegschd, ohni Tegschdauszaischnung", "abusefilter-edit-builder-vars-new-html": "HTML-Qwelltegschd vunde naije Version", "abusefilter-edit-builder-vars-restrictions-edit": "Äna die Schduuf vum Schudz vunde Said", "abusefilter-edit-builder-vars-restrictions-move": "Äna die Schduuf vum Schudz vunde Said", "abusefilter-edit-builder-vars-restrictions-create": "Schidz die Said voam Easchdelle", "abusefilter-edit-builder-vars-restrictions-upload": "Schidz die Dadai voam Nufflade", - "abusefilter-edit-builder-vars-old-text-stripped": "Alde Saidetegschd, ohni Tegschdauszaischnung", + "abusefilter-edit-builder-vars-old-text": "Alde Saidetegschd, ohni Tegschdauszaischnung", "abusefilter-edit-builder-vars-old-links": "Ling'g vunde Said, vorm B'awaide", "abusefilter-edit-builder-vars-old-html": "HTML-Qwelltegschd vunde alde Version", "abusefilter-edit-builder-vars-minor-edit": "B'aweidung isch als Klänischkaid kennzaischned worre", @@ -362,7 +359,6 @@ "abusefilter-topnav-examine": "Vagongene Änarunge unasuche", "abusefilter-topnav-log": "Logbuch fa Missbraisch", "abusefilter-topnav-tools": "Wergzaisch fas Fehlasuche", - "abusefilter-topnav-import": "Filda roihole", "abusefilter-log-name": "Logbuch fa Missbraisch-Filda", "abusefilter-log-header": "S'Logbuch zaischd ä Zsommefassung vunde Änarunge onde Filda.\nFa Näjares gugschd baide [[Special:AbuseFilter/history|Lischd]] vunde ledschde Änarunge onde Filda.", "abusefilter-log-noresults": "Kä Ergewnis", diff --git a/AbuseFilter/i18n/pl.json b/AbuseFilter/i18n/pl.json index 041ad694..891ca2f8 100644 --- a/AbuseFilter/i18n/pl.json +++ b/AbuseFilter/i18n/pl.json @@ -2,11 +2,17 @@ "@metadata": { "authors": [ "Airwolf", + "Ankam", "Beau", "BeginaFelicysym", "Chrumps", + "CiaPan", "Clamira", + "DeRudySoulStorm", "Derbeth", + "FunPL", + "Halibutt", + "InternerowyGołąb", "Jwitos", "Lazowik", "Leinad", @@ -14,25 +20,25 @@ "Matma Rex", "Odder", "Olgak85", + "Openbk", + "Pan Cube", "Peter Bowman", + "Pietrasagh", + "PiotrekD", + "Rail", + "Railfail536", "Sovq", "Sp5uhe", + "The Polish", "Ty221", - "Woytecr", - "Pan Cube", "Vengir", - "Halibutt", - "Openbk", - "The Polish", - "InternerowyGołąb", - "Ankam", - "Railfail536", - "DeRudySoulStorm" + "WaldiSt", + "Woytecr" ] }, "abusefilter-desc": "Zastosowanie automatycznej heurystyki do edycji", - "abusefilter": "Konfiguracja filtru nadużyć", - "abuselog": "Rejestr nadużyć", + "abusefilter": "Zarządzanie filtrem nadużyć", + "abuselog": "Rejestr filtru nadużyć", "abusefilter-intro": "Zarządzanie filtrem nadużyć.\nFiltr nadużyć jest to oprogramowanie automatycznego stosowania heurystyki do wszystkich akcji.\nInterfejs pozwala przeglądać listę zdefiniowanych filtrów oraz pozwala na ich modyfikowanie.", "abusefilter-mustviewprivateoredit": "Ze względów bezpieczeństwa z tego interfejsu mogą korzystać wyłącznie użytkownicy posiadający uprawnienia do zmieniania, lub przeglądania prywatnych filtrów nadużyć.", "abusefilter-warning": "'''Uwaga:''' Twoje działanie zostało automatycznie zidentyfikowane jako szkodliwe.\nNiewłaściwe działania zostaną szybko wycofane,\na rażące lub powtarzające się niekonstruktywne edytowanie może spowodować zablokowanie Twojego konta lub adresu IP.\nJeśli uważasz, że to, co robisz, ma uzasadnienie, kliknij przycisk „{{int:savearticle}}”, aby zatwierdzić zmiany.\nKrótki opis reguły nadużycia, do której Twoje działanie zostało dopasowane: $1", @@ -41,15 +47,16 @@ "abusefilter-degrouped": "Ta akcja została automatycznie zidentyfikowana jako szkodliwa.\nW związku z odrzuceniem akcji, Twojemu kontu zostały odebrane wszystkie uprawnienia, ponieważ istnieje podejrzenie, że ktoś dokonał na nie włamania.\nJeśli uważasz, że nastąpiło to przez pomyłkę, skontaktuj się z biurokratą w celu wyjaśnienia zaistniałej sytuacji, wtedy Twoje uprawnienia będą mogły zostać przywrócone.\nKrótki opis reguły nadużycia, do której Twoja akcja została dopasowana: $1", "abusefilter-autopromote-blocked": "Ta akcja została automatycznie zidentyfikowana jako szkodliwa i została odrzucona.\nPonadto został zastosowany środek bezpieczeństwa w postaci czasowego odebrania automatycznie nadanych uprawnień Twojemu kontu.\nKrótki opis reguły nadużycia, do której Twoja akcja została dopasowana: $1", "abusefilter-blocker": "Filtr nadużyć", - "abusefilter-blockreason": "Automatycznie zablokawny przez filtr nadużyć. Opis dopasowanej reguły: $1", + "abusefilter-blockreason": "Automatycznie zablokowany przez filtr nadużyć. Opis dopasowanej reguły: $1", "abusefilter-degroupreason": "Uprawnienia automatycznie odebrane przez filtr nadużyć. Opis reguły: $1", + "abusefilter-blockautopromotereason": "Automatyczny awans automatycznie odroczony przez filtr nadużyć.\nOpis reguły: $1", "abusefilter-accountreserved": "Ta nazwa konta jest zarezerwowana do użycia przez filtr nadużyć.", - "right-abusefilter-modify": "Modyfikowanie filtrów nadużyć", + "right-abusefilter-modify": "Tworzenie lub modyfikowanie filtrów nadużyć", "right-abusefilter-view": "Podgląd filtrów nadużyć", "right-abusefilter-log": "Podgląd rejestru nadużyć", "right-abusefilter-log-detail": "Podgląd szczegółów wpisów w rejestrze nadużyć", - "right-abusefilter-private": "Podgląd prywatnych danych w rejestrze nadużyć", - "right-abusefilter-private-log": "Podgląd rejestru dostępu do prywatnych szczegółów filtru nadużyć", + "right-abusefilter-privatedetails": "Podgląd prywatnych danych w rejestrze nadużyć", + "right-abusefilter-privatedetails-log": "Podgląd rejestru dostępu do prywatnych szczegółów filtru nadużyć", "right-abusefilter-modify-restricted": "Modyfikowanie filtrów nadużyć z zastrzeżonymi operacjami", "right-abusefilter-revert": "Anulowanie wszystkich zmian wykonanych przez podany filtr nadużyć", "right-abusefilter-view-private": "Przeglądanie filtrów nadużyć oznaczonych jako prywatne", @@ -61,17 +68,23 @@ "action-abusefilter-view": "przeglądania filtrów nadużyć", "action-abusefilter-log": "przeglądania rejestru nadużyć", "action-abusefilter-log-detail": "przeglądania szczegółów wpisów w rejestrze nadużyć", - "action-abusefilter-private": "oglądania prywatnych informacji w rejestrze nadużyć", - "action-abusefilter-private-log": "podglądu rejestru dostępu do prywatnych szczegółów filtru nadużyć", + "action-abusefilter-privatedetails": "oglądania prywatnych informacji w rejestrze nadużyć", + "action-abusefilter-privatedetails-log": "podglądu rejestru dostępu do prywatnych szczegółów filtru nadużyć", "action-abusefilter-modify-restricted": "zmieniania filtrów nadużyć z ograniczonymi akcjami", "action-abusefilter-revert": "wycofania wszystkich zmian wskazanych przez filtr nadużyć", "action-abusefilter-view-private": "wyświetlenia prywatnych filtrów nadużyć", "action-abusefilter-log-private": "wyświetlania rejestrów filtrów nadużyć oznaczonych jako prywatne", - "abusefilter-log": "Rejestr filtru nadużyć", + "action-abusefilter-hide-log": "ukrywania wpisów w rejestrze nadużyć", + "action-abusefilter-hidden-log": "podglądu ukrytych wpisów w rejestrze nadużyć", + "action-abusefilter-modify-global": "tworzenia lub modyfikowania globalnych filtrów nadużyć", "abusefilter-log-summary": "Rejestr zawierający spis wszystkich działań wychwyconych przez filtry.", "abusefilter-log-search": "Szukaj w rejestrze nadużyć", "abusefilter-log-search-user": "Użytkownik:", - "abusefilter-log-search-filter": "Identyfikatory filtru (oddzielone znakiem pionowej kreski):", + "abusefilter-log-search-group": "Grupa filtrów:", + "abusefilter-log-search-group-any": "Dowolna", + "abusefilter-log-search-filter": "Identyfikatory filtru:", + "abusefilter-log-search-filter-help": "Oddzielaj znakami pionowej kreski, dodaj prefiks „$1” dla globalnych filtrów", + "abusefilter-log-search-filter-help-central": "Oddzielaj znakiem pionowej kreski", "abusefilter-log-search-title": "Tytuł:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-impact": "Wpływ:", @@ -82,6 +95,9 @@ "abusefilter-log-search-entries-all": "Wszystkie wpisy", "abusefilter-log-search-entries-hidden": "Tylko ukryte wpisy", "abusefilter-log-search-entries-visible": "Tylko nieukryte wpisy", + "abusefilter-log-search-action-label": "Akcja wywołująca", + "abusefilter-log-search-action-other": "Inna", + "abusefilter-log-search-action-any": "Dowolna", "abusefilter-log-search-action-taken-label": "Podjęta akcja:", "abusefilter-log-search-action-taken-any": "Dowolna", "abusefilter-log-search-submit": "Szukaj", @@ -97,19 +113,21 @@ "abusefilter-log-details-var": "Zmienna", "abusefilter-log-details-val": "Wartość", "abusefilter-log-details-vars": "Parametry akcji", - "abusefilter-log-details-private": "Szczegóły prywatnego rejestru", + "abusefilter-log-details-privatedetails": "Szczegóły prywatnego rejestru", "abusefilter-log-details-ip": "Użyte adresy IP", "abusefilter-log-details-checkuser": "Sprawdź użytkownika", "abusefilter-log-noactions": "brak", + "abusefilter-log-noactions-filter": "Brak", "abusefilter-log-details-diff": "Wprowadzone w edycji zmiany", "abusefilter-log-linkoncontribs": "rejestr nadużyć", "abusefilter-log-linkoncontribs-text": "Wpisy w rejestrze nadużyć dla {{GENDER:$1|tego użytkownika|tej użytkowniczki}}", "abusefilter-log-linkonhistory": "rejestr nadużyć", "abusefilter-log-linkonhistory-text": "Zobacz rejestr nadużyć dla tej strony", - "abusefilter-log-hidden": "(wpis ukryty)", + "abusefilter-log-linkonundelete": "zobacz rejestr nadużyć", + "abusefilter-log-linkonundelete-text": "Zobacz rejestr nadużyć dla tej strony", "abusefilter-log-hidden-implicit": "(ukryto, ponieważ usunięto wersję)", "abusefilter-log-cannot-see-details": "Nie masz uprawnień do przeglądania szczegółów tego wpisu.", - "abusefilter-log-cannot-see-private-details": "Nie masz uprawnień do przeglądania prywatnych szczegółów tego wpisu.", + "abusefilter-log-cannot-see-privatedetails": "Nie posiadasz uprawnień do podglądu prywatnych szczegółów tego wpisu w rejestrze.", "abusefilter-log-nonexistent": "Wpis o podanym identyfikatorze nie istnieje.", "abusefilter-log-details-hidden": "Nie możesz zobaczyć szczegółów tego wpisu, ponieważ jest ukryty przed widokiem publicznym.", "abusefilter-log-details-hidden-implicit": "Nie możesz zobaczyć szczegółów tego wpisu, ponieważ powiązana edycja strony jest ukryta z widoku publicznego.", @@ -126,9 +144,11 @@ "log-action-filter-abusefilter": "Rodzaj zmiany filtra:", "log-action-filter-abusefilter-create": "Utworzenie nowego filtra", "log-action-filter-abusefilter-modify": "Modyfikacja filtra", + "log-action-filter-suppress-abuselog": "Ukrywanie rejestru nadużyć", "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|uzyskał|uzyskała}} dostęp do prywatnych szczegółów $3", + "logentry-rights-blockautopromote": "$1 {{GENDER:$2|zablokował|zablokowała|zablokował(a)}} automatyczny awans {{GENDER:$4|$3}} na $5", + "logentry-rights-restoreautopromote": "$1 {{GENDER:$2|odtworzył|odtworzyła|odtworzył(a)}} zdolność do automatycznego awansu {{GENDER:$4|$3}}", "abusefilterprivatedetails-log-name": "Rejestr dostępu do prywatnych szczegółów filtru nadużyć", - "abusefilter-management": "Zarządzanie filtrem nadużyć", "abusefilter-list": "Wszystkie filtry", "abusefilter-list-id": "ID filtru", "abusefilter-list-pattern": "Wzór", @@ -147,8 +167,10 @@ "abusefilter-enabled": "Włączony", "abusefilter-deleted": "Usunięty", "abusefilter-disabled": "Wyłączony", + "abusefilter-throttled": "z ograniczeniami", "abusefilter-hitcount": "$1 {{PLURAL:$1|wywołanie|wywołania|wywołań}}", "abusefilter-new": "Utwórz nowy filtr", + "abusefilter-import-button": "Import filtru", "abusefilter-return": "Powrót do zarządzania filtrem", "abusefilter-status-global": "Globalnie", "abusefilter-list-options": "Opcje", @@ -169,14 +191,17 @@ "abusefilter-list-options-search-like": "Proste zapytanie", "abusefilter-list-options-search-rlike": "Wyrażenie regularne", "abusefilter-list-options-search-irlike": "Wyrażenie regularne niewrażliwe na wielkość liter", + "abusefilter-list-invalid-searchmode": "Wybrany tryb wyszukiwania jest nieprawidłowy.", "abusefilter-list-regexerror": "Wystąpił błąd podczas wyszukiwania: Błąd składni wyrażenia regularnego.", "abusefilter-list-options-submit": "Aktualizuj", "abusefilter-tools-text": "Oto kilka narzędzi, które mogą być przydatne w opracowywaniu i śledzeniu pracy filtrów nadużyć.", "abusefilter-tools-expr": "Tester wyrażeń", "abusefilter-tools-submitexpr": "Testuj", + "abusefilter-tools-syntax-error": "Filtr ma nieprawidłową składnię.", "abusefilter-tools-reautoconfirm": "Przywróć status automatycznego zatwierdzenia", "abusefilter-tools-reautoconfirm-user": "Użytkownik", "abusefilter-tools-reautoconfirm-submit": "Ponowne automatyczne zatwierdzenie", + "abusefilter-tools-restoreautopromote": "Automatyczny awans przywrócony przez narzędzia Filtru nadużyć.", "abusefilter-reautoconfirm-none": "{{GENDER:$1|Ten użytkownik|Ta użytkowniczka}} nie ma zawieszonego statusu automatycznie {{GENDER:$1|zatwierdzonego|zatwierdzonej}}.", "abusefilter-reautoconfirm-notallowed": "Nie masz uprawnień, aby przywrócić statusu automatycznie zatwierdzonego.", "abusefilter-reautoconfirm-done": "Został przywrócony status automatycznego zatwierdzania zmian wykonywanych przez użytkowników", @@ -186,9 +211,9 @@ "abusefilter-edit-subtitle-new": "Tworzenie filtru", "abusefilter-edit-token-not-match": "Edycja nie została zapisana! Zapisz ją ponownie.", "abusefilter-edit-oldwarning": "<strong>Edytujesz starą wersję tego filtru. Statystyki są notowane dla najnowszej wersji filtru. Jeśli zapiszesz zmiany, zostaną nadpisane wszystkie późniejsze wersje od tej, którą edytujesz.</strong> • [[Special:AbuseFilter/history/$2|Powrót do historii filtru]]", + "abusefilter-edit-oldwarning-view": "<strong>Oglądasz starsza wersję tego filtra.\nPodane statystyki dotyczą jego aktualnej wersji</strong> •\n[[Special:AbuseFilter/history/$2|Wróć do historii filtra]]", "abusefilter-edit-status-label": "Statystyki:", - "abusefilter-edit-status": "{{PLURAL:$1|Dla ostatniej $1 akcji|W ostatnich $1 akcjach}} ten filtr pasował do $2 ($3%).", - "abusefilter-edit-status-profile": "{{PLURAL:$1|Dla ostatniej $1 akcji|W ostatnich $1 akcjach}} ten filtr pasował do $2 ($3%).\nŚredni czas wykonania wyniósł $4 ms. Wykorzystano $5 {{PLURAL:$5|warunek|warunki|warunków}} z limitu.", + "abusefilter-edit-status": "{{PLURAL:$1|Dla ostatniej $1 akcji|W ostatnich $1 akcjach}} ten filtr pasował do $2 ($3%).\nŚredni czas wykonania wyniósł $4 ms. Wykorzystano $5 {{PLURAL:$5|warunek|warunki|warunków}} z limitu.", "abusefilter-edit-throttled-warning": "'''Uwaga:''' Ten filtr został automatyczne oznaczony jako groźny. Ze względu bezpieczeństwa, te akcje nie zostaną wykonane ($1). Przejrzyj i [[mw:Extension:AbuseFilter/Conditions|zoptymalizuj]] swoje warunki, aby usunąć to ograniczenie", "abusefilter-edit-new": "Nowy filtr", "abusefilter-edit-save": "Zapisz filtr", @@ -221,19 +246,30 @@ "abusefilter-edit-throttle-count": "Liczba dozwolonych akcji", "abusefilter-edit-throttle-period": "Okres (w sekundach):", "abusefilter-edit-throttle-groups": "Grupuj przekroczenia dla:", - "abusefilter-edit-throttle-ip": "Adresu IP", - "abusefilter-edit-throttle-user": "Konta użytkownika", - "abusefilter-edit-throttle-range": "Zakresu /16", - "abusefilter-edit-throttle-creationdate": "Czasu utworzenia konta", - "abusefilter-edit-throttle-editcount": "Liczby edycji", - "abusefilter-edit-throttle-site": "Całej witryny", - "abusefilter-edit-throttle-page": "Strony", + "abusefilter-edit-throttle-groups-help": "Zobacz $1.", + "abusefilter-edit-throttle-groups-help-text": "dokumentacja na mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Rozdziel przecinkami aby połączyć operatorem AND („i”) oraz znakami końca wiersza aby połączyć operatorem OR („lub”)", + "abusefilter-edit-throttle-placeholder": "Rozdziel przecinkami aby połączyć operatorem AND („i”) lub wpisz w osobnych wierszach aby połączyć operatorem OR („lub”)", + "abusefilter-throttle-ip": "adresu IP", + "abusefilter-throttle-user": "konta użytkownika", + "abusefilter-throttle-range": "zakresu /16", + "abusefilter-throttle-creationdate": "daty utworzenia konta", + "abusefilter-throttle-editcount": "liczby edycji", + "abusefilter-throttle-site": "całej witryny", + "abusefilter-throttle-page": "strony", + "abusefilter-throttle-none": "(brak)", "abusefilter-edit-warn-message": "Komunikat systemowy wyświetlany jako ostrzeżenie:", "abusefilter-edit-warn-other": "Inny komunikat", - "abusefilter-edit-warn-other-label": "Nazwa strony innego komunikatu:\n:''(bez przedrostka \"MediaWiki\")''", + "abusefilter-edit-warn-other-label": "Nazwa strony innego komunikatu:\n:''(bez przedrostka „MediaWiki:”)''", "abusefilter-edit-warn-actions": "Operacje:", "abusefilter-edit-warn-preview": "Pokaż/Ukryj podgląd wybranego komunikatu", "abusefilter-edit-warn-edit": "Utwórz lub edytuj wybrany komunikat", + "abusefilter-edit-disallow-message": "Komunikat systemowy wyświetlany gdy zablokowano wykonanie akcji:", + "abusefilter-edit-disallow-other": "Inny komunikat", + "abusefilter-edit-disallow-other-label": "Nazwa strony innego komunikatu:\n:''(bez przedrostka „MediaWiki:”)''", + "abusefilter-edit-disallow-actions": "Działania:", + "abusefilter-edit-disallow-preview": "Pokaż/Ukryj podgląd wybranego komunikatu", + "abusefilter-edit-disallow-edit": "Utwórz lub edytuj wybrany komunikat", "abusefilter-edit-tag-tag": "[[Special:Tags|Znaczniki]] do zastosowania:", "abusefilter-edit-tag-placeholder": "Dodaj znaczniki (jeden po drugim lub oddzielone przecinkami)", "abusefilter-edit-tag-hidden-placeholder": "Dodaj znaczniki (oddzielone przecinkami)", @@ -254,16 +290,24 @@ "abusefilter-edit-history": "Historia", "abusefilter-edit-check": "Sprawdź składnię", "abusefilter-edit-badfilter": "Podany filtr nie istnieje", - "abusefilter-edit-revert": "Anuluj działania podjęte przez ten filtr", + "abusefilter-edit-revert": "Cofnij działania podjęte przez ten filtr", "abusefilter-edit-tools": "Narzędzia", "abusefilter-edit-test-link": "Sprawdź ten filtr na ostatnich zmianach", "abusefilter-edit-export": "Eksportuj filtr do innej wiki", "abusefilter-edit-syntaxok": "Nie wykryto błędów składni.", "abusefilter-edit-syntaxerr": "Wykryto błąd składni – $1", + "abusefilter-edit-warn-leave": "Opuszczenie strony spowoduje utratę wszystkich zmian wprowadzonych w tym filtrze.", "abusefilter-edit-bad-tags": "Co najmniej jedno ze znaczników jest niepoprawne.\nNazwy znaczników powinny być krótkie i nie mogą zawierać znaków specjalnych, oraz nie mogą być wykorzystywane przez inne oprogramowanie. Spróbuj wybrać inną nazwę dla znacznika.", "abusefilter-edit-notallowed": "Nie posiadasz uprawnienia do tworzenia lub edytowania filtrów nadużyć", "abusefilter-edit-notallowed-global": "Nie posiadasz uprawnienia do tworzenia lub edytowania globalnych filtrów nadużyć", - "abusefilter-edit-notallowed-global-custom-msg": "Niestandardowe komunikaty ostrzegawcze nie są obsługiwane przez filtry globalne", + "abusefilter-edit-notallowed-global-custom-msg": "Niestandardowe komunikaty ostrzegające bądź odrzucające akcje nie są obsługiwane przez filtry globalne", + "abusefilter-edit-invalid-warn-message": "Komunikat ostrzegawczy nie może pozostać pusty.", + "abusefilter-edit-invalid-disallow-message": "Komunikat odrzucający akcję nie może pozostać pusty.", + "abusefilter-edit-invalid-throttlecount": "Ilość działań zdławienia musi być dodatnią liczbą całkowitą.", + "abusefilter-edit-invalid-throttleperiod": "Okres zdławienia musi być musi być dodatnią liczbą całkowitą.", + "abusefilter-edit-empty-throttlegroups": "Przynajmniej jedna grupa zdławienia musi być wybrana.", + "abusefilter-edit-duplicated-throttlegroups": "Grupy zdławienia nie mogą mieć duplikatów.", + "abusefilter-edit-invalid-throttlegroups": "Podane grupy zdławienia nie są poprawne.", "abusefilter-edit-builder-select": "Wybierz opcję, aby wkleić ją na pozycji kursora", "abusefilter-edit-builder-group-op-arithmetic": "Operatory arytmetyczne", "abusefilter-edit-builder-op-arithmetic-addition": "Dodawanie (+)", @@ -294,21 +338,26 @@ "abusefilter-edit-builder-misc-contains": "Lewy ciąg znaków zawiera prawy (contains)", "abusefilter-edit-builder-misc-stringlit": "Łańcuch znaków (\"\")", "abusefilter-edit-builder-misc-tern": "Operator warunkowy (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Warunkowo (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Warunkowo (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "Krótkie wyrażenie (if X then Y end)", "abusefilter-edit-builder-group-funcs": "Funkcje", "abusefilter-edit-builder-funcs-length": "Długość ciągu znaków (length)", "abusefilter-edit-builder-funcs-lcase": "Na małe litery (lcase)", "abusefilter-edit-builder-funcs-ucase": "Na duże litery (ucase)", "abusefilter-edit-builder-funcs-ccnorm": "Normalizacja kłopotliwych znaków (ccnorm)", + "abusefilter-edit-builder-funcs-ccnorm-contains-any": "Normalizowanie i wyszukiwanie ciągu dla wielu podciągów w trybie OR (ccnorm_contains_any)", + "abusefilter-edit-builder-funcs-ccnorm-contains-all": "Normalizuj i wyszukaj ciąg dla wielu podciągów w trybie AND (ccnorm_contains_all)", "abusefilter-edit-builder-funcs-rmdoubles": "Usuwanie powtarzających się znaków (rmdoubles)", "abusefilter-edit-builder-funcs-specialratio": "Znaki specjalne / suma znaków (specialratio)", "abusefilter-edit-builder-funcs-norm": "Normalizacja (norm)", "abusefilter-edit-builder-funcs-count": "Ile razy ciąg znaków X wystąpił w ciągu znaków Y (count)", "abusefilter-edit-builder-funcs-rcount": "Liczba wystąpień wyrażenia regularnego X w łańcuchu Y (rcount)", + "abusefilter-edit-builder-funcs-get_matches": "Tablica dopasowań regex w tekście dla każdej grupy przechwytywania (get_matches)", "abusefilter-edit-builder-funcs-rmwhitespace": "Usuń białe znaki (rmwhitespace)", "abusefilter-edit-builder-funcs-rmspecials": "Usuń znaki specjalne (rmspecials)", "abusefilter-edit-builder-funcs-ip_in_range": "Czy IP jest w zakresie? (ip_in_range)", "abusefilter-edit-builder-funcs-contains-any": "Przeszukaj ciąg znaków w poszukiwaniu wielu podciągów jako LUB. (contains_any)", + "abusefilter-edit-builder-funcs-contains-all": "Przeszukaj ciąg znaków w poszukiwaniu wielu podciągów jako ORAZ. (contains_all)", "abusefilter-edit-builder-funcs-substr": "Fragment ciągu znaków (substr)", "abusefilter-edit-builder-funcs-strpos": "Pozycja podciągu znaków w ciągu (strpos)", "abusefilter-edit-builder-funcs-str_replace": "Zastąp fragment ciągu znaków innym ciągiem (str_replace)", @@ -317,6 +366,7 @@ "abusefilter-edit-builder-group-vars": "Zmienne", "abusefilter-edit-builder-vars-accountname": "Nazwa konta (on account creation)", "abusefilter-edit-builder-vars-timestamp": "Unixowy znacznik czasu „timestamp” dla zmiany", + "abusefilter-edit-builder-vars-timestamp-expanded": "Przedział czasowy rejestru", "abusefilter-edit-builder-vars-action": "Akcja", "abusefilter-edit-builder-vars-addedlines": "Linie dodane podczas edycji", "abusefilter-edit-builder-vars-delta": "Rozmiar zmiany podczas edycji", @@ -331,6 +381,7 @@ "abusefilter-edit-builder-vars-page-ns": "Przestrzeń nazw strony", "abusefilter-edit-builder-vars-page-title": "Tytuł strony (bez przestrzeni nazw)", "abusefilter-edit-builder-vars-page-prefixedtitle": "Pełny tytuł strony", + "abusefilter-edit-builder-vars-page-age": "Wiek strony (w sekundach)", "abusefilter-edit-builder-vars-movedfrom-id": "Identyfikator źródła przenoszonej strony", "abusefilter-edit-builder-vars-movedfrom-ns": "Przestrzeń nazw źródła przenoszonej strony", "abusefilter-edit-builder-vars-movedfrom-title": "Tytuł źródła przenoszonej strony", @@ -339,6 +390,7 @@ "abusefilter-edit-builder-vars-movedto-ns": "Przestrzeń nazw przeznaczenia przenoszonej strony", "abusefilter-edit-builder-vars-movedto-title": "Tytuł przeznaczenia przenoszonej strony", "abusefilter-edit-builder-vars-movedto-prefixedtitle": "Pełny tytuł przeznaczenia przenoszonej strony", + "abusefilter-edit-builder-vars-movedto-age": "Wiek przenoszonej strony (w sekundach)", "abusefilter-edit-builder-vars-user-editcount": "Liczba edycji użytkownika", "abusefilter-edit-builder-vars-user-age": "Wiek konta użytkownika", "abusefilter-edit-builder-vars-user-name": "Nazwa konta użytkownika", @@ -347,14 +399,16 @@ "abusefilter-edit-builder-vars-user-blocked": "Czy użytkownik jest zablokowany", "abusefilter-edit-builder-vars-user-emailconfirm": "Czas zatwierdzenia adresu e‐mail", "abusefilter-edit-builder-vars-recent-contributors": "Ostatnie dziesięć osób edytujących stronę", - "abusefilter-edit-builder-vars-first-contributor": "Pierwszy edytor strony", - "abusefilter-edit-builder-vars-all-links": "Wszystkie linki zewnętrzne w nowych tekstach", + "abusefilter-edit-builder-vars-first-contributor": "Pierwszy edytujący daną stronę", + "abusefilter-edit-builder-vars-movedto-recent-contributors": "Ostatnich dziesięciu użytkowników edytujących przenoszoną stronę", + "abusefilter-edit-builder-vars-movedto-first-contributor": "Pierwszy użytkownik edytujący przenoszoną stronę", + "abusefilter-edit-builder-vars-all-links": "Wszystkie linki zewnętrzne w nowej treści", "abusefilter-edit-builder-vars-added-links": "Wszystkie linki zewnętrzne dodane w edycji", "abusefilter-edit-builder-vars-removed-links": "Wszystkie linki zewnętrzne usunięte w edycji", - "abusefilter-edit-builder-vars-old-text": "Stary wikikod strony w formacie wiki, przed modyfikacją (wyszło z użycia)", - "abusefilter-edit-builder-vars-new-text": "Nowa treść strony w formacie wiki, po modyfikacji", - "abusefilter-edit-builder-vars-new-pst": "Nowa strona Wikitekstu, wstępnie zapisane przekształcone", - "abusefilter-edit-builder-vars-new-text-stripped": "Nowa treść strony pozbawiona wszystkich znaczników", + "abusefilter-edit-builder-vars-old-wikitext": "Stary wikikod strony, przed modyfikacją", + "abusefilter-edit-builder-vars-new-wikitext": "Nowa treść strony, po modyfikacji", + "abusefilter-edit-builder-vars-new-pst": "Nowy wikikod strony, wstępnie przekształcony przed zapisaniem", + "abusefilter-edit-builder-vars-new-text": "Nowa treść strony pozbawiona wszystkich znaczników", "abusefilter-edit-builder-vars-new-html": "Sformatowane źródło HTML nowej wersji", "abusefilter-edit-builder-vars-restrictions-edit": "Stopień zabezpieczenia strony przed edycją", "abusefilter-edit-builder-vars-restrictions-move": "Stopień zabezpieczenia strony przed przeniesieniem", @@ -362,10 +416,14 @@ "abusefilter-edit-builder-vars-restrictions-upload": "Stopień zabezpieczenia pliku przed przesłaniem", "abusefilter-edit-builder-vars-movedfrom-restrictions-edit": "Poziom zabezpieczenia przed edycją strony do przeniesienia", "abusefilter-edit-builder-vars-movedfrom-restrictions-move": "Poziom zabezpieczenia przenoszenia strony źródłowej", - "abusefilter-edit-builder-vars-old-text-stripped": "Stara treść strony pozbawiona wszystkich znaczników", + "abusefilter-edit-builder-vars-movedto-restrictions-edit": "Poziom zabezpieczenia przed edycją przenoszonej strony", + "abusefilter-edit-builder-vars-movedto-restrictions-move": "Poziom zabezpieczenia przenoszenia przenoszonej strony", + "abusefilter-edit-builder-vars-movedto-restrictions-create": "Poziom zabezpieczenia przed tworzeniem przenoszonej strony", + "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Zabezpieczenie przenoszonego pliku przed przesyłaniem", + "abusefilter-edit-builder-vars-old-text": "Stara treść strony pozbawiona wszystkich znaczników (wyłączone z użycia)", "abusefilter-edit-builder-vars-old-links": "Łącza na stronie przed edycją", "abusefilter-edit-builder-vars-old-html": "Stary wikikod strony w formacie wiki przetworzona na HTML (wyszło z użycia)", - "abusefilter-edit-builder-vars-minor-edit": "Czy edycja oznaczona jest jako drobna", + "abusefilter-edit-builder-vars-minor-edit": "Czy edycja oznaczona jest jako drobna (ta funkcja została wyłączona z użycia)", "abusefilter-edit-builder-vars-file-sha1": "Skrót SHA1 zawartości pliku", "abusefilter-edit-builder-vars-file-size": "Rozmiar pliku w bajtach", "abusefilter-edit-builder-vars-file-mime": "Typ MIME pliku", @@ -373,6 +431,8 @@ "abusefilter-edit-builder-vars-file-width": "Szerokość pliku w pikselach", "abusefilter-edit-builder-vars-file-height": "Wysokość pliku w pikselach", "abusefilter-edit-builder-vars-file-bits-per-channel": "Liczba bitów na kanał kolorów pliku", + "abusefilter-edit-builder-vars-wiki-name": "Nazwa bazy danych wiki", + "abusefilter-edit-builder-vars-wiki-language": "Kod języka wiki", "abusefilter-filter-log": "Ostatnie zmiany ustawień filtru", "abusefilter-history": "Historia zmian dla filtru nr $1", "abusefilter-history-foruser": "Zmiany wykonane przez $1", @@ -406,10 +466,14 @@ "abusefilter-exception-dividebyzero": "Próba dzielenia $2 przez zero, znak nr $1.", "abusefilter-exception-unrecognisedvar": "Nierozpoznana zmienna $2, znak nr $1.", "abusefilter-exception-notenoughargs": "Zbyt mało argumentów dla funkcji $2, wywołanie – znak $1.\nOczekiwano $3 {{PLURAL:$3|argumentu|argumentów}}, użyto $4", + "abusefilter-exception-toomanyargs": "Zbyt dużo argumentów dla funkcji $2, wywołanie – znak $1.\nOczekiwano najwyżej $3 {{PLURAL:$3|argumentu|argumentów}}, użyto $4", "abusefilter-exception-regexfailure": "Błąd w wyrażeniu regularnym „$2” na znaku $1.", "abusefilter-exception-overridebuiltin": "Nielegalne nadpisanie wbudowanej zmiennej „$2” – znak $1.", "abusefilter-exception-outofbounds": "Żądanie nieistniejącego elementu tablicy $2 (rozmiar tablicy = $3) – znak $1.", + "abusefilter-exception-negativeindex": "Ujemne indeksy są niedozwolone w tablicach. Otrzymano indeks „$2” w $1.", "abusefilter-exception-notarray": "Żądanie elementu tablicy od zmiennej nietablicowej – znak $1.", + "abusefilter-exception-unclosedcomment": "Niedomknięty komentarz – znak $1.", + "abusefilter-exception-invalidiprange": "Wprowadzono nieprawidłowy zakres IP „$2” – znak $1.", "abusefilter-exception-disabledvar": "Zmienna $2 przy znaku $1 nie jest już używana.", "abusefilter-action-tag": "Znacznik", "abusefilter-action-throttle": "Ogranicz", @@ -419,7 +483,7 @@ "abusefilter-action-degroup": "Usuń z grup", "abusefilter-action-rangeblock": "Blokuj zakres", "abusefilter-action-disallow": "Odrzuć", - "abusefilter-revert-title": "Anuluj wszystkie zmiany zrobione przez filtr $1", + "abusefilter-revert-title": "Cofnij wszystkie zmiany zrobione przez filtr $1", "abusefilter-revert-intro": "Formularz pozwala anulować wszystkie zmiany zrobione przez filtr nadużyć $1.\nNależy ostrożnie korzystać z tego narzędzia.", "abusefilter-revert-preview-item": "$1: $2 {{GENDER:$7|wykonał|wykonała|wykonał(a)}} $3 na $4.\nDziałania, które zostaną anulowane: $5 ($6)", "abusefilter-revert-search-legend": "Wybierz działania filtru nadużyć, które mają zostać anulowane", @@ -473,15 +537,16 @@ "abusefilter-examine-noresults": "Nie znaleziono wyników dla zadanych przez Ciebie parametrów wyszukiwania.", "abusefilter-topnav": "'''Nawigacja po filtrze nadużyć'''", "abusefilter-topnav-home": "Główna", + "abusefilter-topnav-recentchanges": "Ostatnie zmiany filtrów", "abusefilter-topnav-test": "Testowanie wsadowe", "abusefilter-topnav-examine": "Skontroluj dawniejsze edycje", "abusefilter-topnav-log": "Rejestr nadużyć", "abusefilter-topnav-tools": "Narzędzia śledzenia", - "abusefilter-topnav-import": "Import filtru", "abusefilter-log-name": "Rejestr filtru nadużyć", "abusefilter-log-header": "Rejestr zawiera zestawienie zmian wprowadzanych w filtrach.\nPełne informacje odnajdziesz w [[Special:AbuseFilter/history|rejestrze]] ostatnich zmian w filtrach.", "abusefilter-logentry-create": "$1 {{GENDER:$2|utworzył|utworzyła}} $4 ($5)", "abusefilter-logentry-modify": "$1 {{GENDER:$2|zmienił|zmieniła}} $4 ($5)", + "abusefilter-log-invalid-filter": "Niektóre z wymienionych ID filtra są nieprawidłowe.", "abusefilter-log-noresults": "Brak wyników", "abusefilter-diff-title": "Różnice pomiędzy wersjami", "abusefilter-diff-item": "Element", @@ -494,13 +559,19 @@ "abusefilter-diff-next": "Następna zmiana", "abusefilter-import-intro": "Ten interfejs służy do importowania filtrów z innych wiki.\nW trybie edycji filtru kliknij w źródłowej wiki „{{int:abusefilter-edit-export}}” przy nagłówku „{{int:abusefilter-edit-tools}}”.\nSkopiuj zawartość pola tekstowego, które się pojawi, i wklej ją do poniższego pola tekstowego, a następnie kliknij przycisk „{{int:abusefilter-import-submit}}”.", "abusefilter-import-submit": "Importuj dane", + "abusefilter-import-invalid-data": "Dane które probowano zaimportować nie są prawidłowe.", "abusefilter-group-default": "Domyślne", "abusefilter-http-error": "Wystąpił błąd HTTP: $1.", - "abusefilter-view-private-submit": "Zobacz prywatne szczegóły", - "abusefilter-view-private": "Zobacz prywatne szczegóły", - "abusefilter-view-private-reason": "Powód dostępu do prywatnych szczegółów:", + "abusefilter-view-privatedetails-submit": "Zobacz prywatne szczegóły", + "abusefilter-view-privatedetails-legend": "Zobacz prywatne szczegóły", + "abusefilter-view-privatedetails-reason": "Powód dostępu do prywatnych szczegółów:", "abusefilter-log-details-id": "ID wpisu", + "abusefilter-invalid-request": "Niewłaściwe żądanie! Musisz wejść w szczegóły prywatnego rejestru za pośrednictwem formularza na [[Special:AbuseLog/$1]] i wprowadzić powód.", + "abusefilter-invalid-request-noid": "Niewłaściwe żądanie! Musisz wejść w szczegóły prywatnego rejestru za pośrednictwem formularza na stronie szczegółów filtra nadużyć i wprowadzić powód.", + "log-description-abusefilterprivatedetails": "Ten rejestr przedstawia listę dostępów do prywatnych szczegółów filtru nadużyć.", "abusefilter-noreason": "Uwaga: aby podejrzeć poufne szczegóły tego rejestru, musisz podać powód.", "abusefilter-log-ip-not-available": "Niedostępne", - "abusefilter-tag-reserved": "Tag <code>abusefilter-condition-limit</code> jest zarezerwowany dla wewnętrznego użytku przez Filtr nadużyć." + "abusefilter-tag-reserved": "Tag <code>abusefilter-condition-limit</code> jest zarezerwowany dla wewnętrznego użytku przez Filtr nadużyć.", + "tag-abusefilter-condition-limit": "osiągnięto limit warunku", + "tag-abusefilter-condition-limit-description": "Edycje lub inne operacje które nie mogły zostać sprzawdzone przez wszystkie aktywne [[Special:AbuseFilter|filtry nadużyć]] ([[mw:Extension:AbuseFilter/Conditions|pomoc]])." } diff --git a/AbuseFilter/i18n/pms.json b/AbuseFilter/i18n/pms.json index aa254123..15d9a175 100644 --- a/AbuseFilter/i18n/pms.json +++ b/AbuseFilter/i18n/pms.json @@ -3,13 +3,15 @@ "authors": [ "Borichèt", "Dragonòt", - "McDutchie", - "Matma Rex" + "Fitoschido", + "Matma Rex", + "MaxSem", + "McDutchie" ] }, "abusefilter-desc": "A àplica dj'eurìstiche automàtiche a le modìfiche", - "abusefilter": "Configurassion dël fìlter contra j'abus", - "abuselog": "Registr ëd j'abus", + "abusefilter": "Gestion dël filtr ëd sicurëssa", + "abuselog": "Registr dij filtr ëd sicurëssa", "abusefilter-intro": "Bin ëvnù ant l'antërfassa ëd gestion dij fìlter contra j'abus.\nËl fìlter contra j'abus a l'é un mecanism ëd programa automatisà ch'a àplica dj'eurìstiche automàtiche a tute j'assion.\nCosta antërfassa a smon na lista ëd fìlter definì e a përmet ëd modificheje.", "abusefilter-warning": "'''Atension''': Costa assion a l'è stàita indentificà an automàtich coma danosa.\nLe modificassion nen costrutive a saran tòst anulà,\ne le modìfiche nen costrutive esagerà o arpetùe a mneran al blocagi ëd sò cont o soa adrëssa IP.\nS'a chërd che soa assion a l'é costrutiva, a peul torna mandela për confermela.\nNa curta descrission ëd la régola dj'abus anté ch'a l'é cascà soa modìfica a l'é: $1", "abusefilter-disallowed": "Costa assion a l'é stàita identificà an automàtich coma danosa, e donca ampedìa.\nS'a chërd che soa assion a l'era costrutiva, ch'a buta al corent n'aministrator ëd lòn ch'a sërcava ëd fé.\nNa curta descrission ëd la régola dj'abus anté ch'a l'é cascà soa assion a l'é: $1", @@ -24,7 +26,7 @@ "right-abusefilter-view": "Varda ij filtr ëd sicurëssa", "right-abusefilter-log": "varda ël registr ëd sicurëssa", "right-abusefilter-log-detail": "varda le vos detajà ëd sicurëssa", - "right-abusefilter-private": "varda ij dat privà ant ël registr ëd sicurëssa", + "right-abusefilter-privatedetails": "varda ij dat privà ant ël registr ëd sicurëssa", "right-abusefilter-modify-restricted": "Modifiché ij filtr contra j'abus con assion limità", "right-abusefilter-revert": "Buta andré tùit ij cambi da un dàit filtr ëd sicurëssa", "right-abusefilter-view-private": "varda ij filtr ëd sicurëssa marcà com privà", @@ -36,11 +38,10 @@ "action-abusefilter-view": "varda ij filtr ëd sicurëssa", "action-abusefilter-log": "varda ël registr ëd sicurëssa", "action-abusefilter-log-detail": "varda le vos detajà dël registr ëd sicurëssa", - "action-abusefilter-private": "varda ij dat privà ant ël registr ëd sicurëssa", + "action-abusefilter-privatedetails": "varda ij dat privà ant ël registr ëd sicurëssa", "action-abusefilter-modify-restricted": "modifiché ij filtr contra j'abus con assion limità", "action-abusefilter-revert": "buta andré tùit ij cambi da un dàit filtr ëd sicurëssa", "action-abusefilter-view-private": "varda ij filtr ëd sicurëssa marcà com privà", - "abusefilter-log": "Registr dij filtr ëd sicurëssa", "abusefilter-log-summary": "Ës registr a smon na lista ëd tute j'assion andividuà daj filtr.", "abusefilter-log-search": "Sërché ant ël registr ëd j'abus", "abusefilter-log-search-user": "Utent:", @@ -59,13 +60,12 @@ "abusefilter-log-details-var": "Variàbil", "abusefilter-log-details-val": "Valor", "abusefilter-log-details-vars": "Paràmetr dl'assion", - "abusefilter-log-details-private": "Dat privà", + "abusefilter-log-details-privatedetails": "Dat privà", "abusefilter-log-details-ip": "Adrëssa IP original", "abusefilter-log-noactions": "gnun", "abusefilter-log-details-diff": "Cangiament fàit ant la modìfica", "abusefilter-log-linkoncontribs": "registr ëd j'abus", "abusefilter-log-linkoncontribs-text": "Registr ëd sicurëssa për st'utent", - "abusefilter-log-hidden": "(vos stërmà)", "abusefilter-log-hidden-implicit": "(stërmà përchè la revision a l'é stàita scancelà)", "abusefilter-log-cannot-see-details": "It l'has pa ël përmess ëd vardé ij detaj dë sta vos.", "abusefilter-log-details-hidden": "It peule pa vardé ij detaj për sta vos përchè a l'é stërmà da la vista pùblica.", @@ -75,7 +75,6 @@ "abusefilter-log-hide-reason": "Rason:", "abusefilter-log-hide-forbidden": "It l'has pa ël përmess dë stërmé le vos dël registr ëd sicurëssa.", "logentry-abusefilter-hit": "$1 a l'ha assionà $4, an fasend l'assion \"$5\" dzora $3. Assion fàite: $6 ($7)", - "abusefilter-management": "Gestion dël filtr ëd sicurëssa", "abusefilter-list": "Tùit ij filtr", "abusefilter-list-id": "Identificativ dël filtr", "abusefilter-list-status": "Stat", @@ -95,6 +94,7 @@ "abusefilter-disabled": "Disabilità", "abusefilter-hitcount": "$1 {{PLURAL:$1|andividuassion|andividuassion}}", "abusefilter-new": "Creé un filtr neuv", + "abusefilter-import-button": "Amporté un filtr", "abusefilter-return": "Torné andré a la gestion dij filtr", "abusefilter-status-global": "Global", "abusefilter-list-options": "Opsion", @@ -123,7 +123,6 @@ "abusefilter-edit-oldwarning": "<strong>A l'é an camin ch'a modìfica na version veja d'ës fìlter.\nLe statìstiche mostrà a rësguardo la version pì recenta dël fìlter.\nS'a salva soe modìfiche, a-j scrivrà ëdzora a tute ij cangiament fàit a parte dla revision ch'a l'é an camin ch'a modìfica.</strong> •\n[[Special:AbuseFilter/history/$2|Torné a la stòria d'ës fìlter]].", "abusefilter-edit-status-label": "Statìstiche:", "abusefilter-edit-status": "{{PLURAL:$1|Dl'ùltima|Dj'ùltime $1}} assion, ës fìlter a n'ha andividuane $2 ($3%).", - "abusefilter-edit-status-profile": "{{PLURAL:$1|Dl'ùltima|Dj'ùltime $1}} assion, ës fìlter a n'ha andividuane $2 ($3%).\nAn media, sò temp ëd travaj a l'é ëd $4 ms e a consuma $5 {{PLURAL:$5|condission|condission}} dël lìmit ëd condission.", "abusefilter-edit-new": "Filtr neuv", "abusefilter-edit-save": "Salvé ël filtr", "abusefilter-edit-id": "Identificativ dël fìlter", @@ -153,7 +152,7 @@ "abusefilter-edit-throttle-groups": "Argropé la moderassion për:\n:''(un për linia, separà con dle vìrgole)''", "abusefilter-edit-warn-message": "Mëssagi ëd sistema da dovré për l'avis:", "abusefilter-edit-warn-other": "Àutr mëssagi", - "abusefilter-edit-warn-other-label": "Nòm ëd pàgina ëd n'àutr mëssagi:\n:''(sensa prefiss mediaWiki)''", + "abusefilter-edit-warn-other-label": "Nòm ëd pàgina ëd n'àutr mëssagi:\n:''(sensa 'l prefiss «MédiaWiki»)''", "abusefilter-edit-warn-actions": "Assion:", "abusefilter-edit-warn-preview": "Previsualisé ël mëssagi selessionà", "abusefilter-edit-warn-edit": "Creé o modifiché ël mëssagi selessionà", @@ -206,7 +205,7 @@ "abusefilter-edit-builder-misc-tern": "Operador ternari ( X ? Y : Z)", "abusefilter-edit-builder-misc-cond": "Condissional (if X then Y else Z)", "abusefilter-edit-builder-group-funcs": "Funsion", - "abusefilter-edit-builder-funcs-length": "Longheur dla stringa (lenght)", + "abusefilter-edit-builder-funcs-length": "Longheur dla stringa (length)", "abusefilter-edit-builder-funcs-lcase": "Convert a minùscol (lcase)", "abusefilter-edit-builder-funcs-ccnorm": "Normalisé ij caràter confondìbij (ccnorm)", "abusefilter-edit-builder-funcs-rmdoubles": "Gavé ij caràter dobi (rmdoubles)", @@ -256,15 +255,15 @@ "abusefilter-edit-builder-vars-all-links": "Tute j'anliure esterne ant ël test neuv", "abusefilter-edit-builder-vars-added-links": "Tute j'anliure esterne giontà ant la modìfica", "abusefilter-edit-builder-vars-removed-links": "Tute j'anliure esterne gavà ant la modìfica", - "abusefilter-edit-builder-vars-old-text": "Vej wikitest ëd la pàgina, prima dla modìfica", - "abusefilter-edit-builder-vars-new-text": "Wikitest neuv ëd la pàgina, dòp ëd la modìfica", - "abusefilter-edit-builder-vars-new-text-stripped": "Test neuv ëd la pàgina, gavà tùit ij marcador", + "abusefilter-edit-builder-vars-old-wikitext": "Vej wikitest ëd la pàgina, prima dla modìfica", + "abusefilter-edit-builder-vars-new-wikitext": "Wikitest neuv ëd la pàgina, dòp ëd la modìfica", + "abusefilter-edit-builder-vars-new-text": "Test neuv ëd la pàgina, gavà tùit ij marcador", "abusefilter-edit-builder-vars-new-html": "Sorgiss HTML parsificà dla neuva revision", "abusefilter-edit-builder-vars-restrictions-edit": "Livel ëd protession dle modìfiche dla pàgina", "abusefilter-edit-builder-vars-restrictions-move": "Livel ëd protession për ij tramud ëd la pàgina", "abusefilter-edit-builder-vars-restrictions-create": "Protession ëd creassion ëd la pàgina", "abusefilter-edit-builder-vars-restrictions-upload": "Carìa la protession ëd l'archivi", - "abusefilter-edit-builder-vars-old-text-stripped": "Test vej ëd la pàgina, gavà tùit ij marcador", + "abusefilter-edit-builder-vars-old-text": "Test vej ëd la pàgina, gavà tùit ij marcador", "abusefilter-edit-builder-vars-old-links": "Anliure ant la pàgina, prima dla modìfica", "abusefilter-edit-builder-vars-old-html": "Vej wikitest ëd la pàgina, parsificà an HTML", "abusefilter-edit-builder-vars-minor-edit": "Se o nò la modìfica a l'é marcà com minor", @@ -301,7 +300,7 @@ "abusefilter-exception-dividebyzero": "Tentativ ilegal ëd divide $2 për zero al caràter $1.", "abusefilter-exception-unrecognisedvar": "Variàbil pa arconossùa $2 al caràter $1.", "abusefilter-exception-notenoughargs": "Pa basta d'argoment a la funsion $2 ciamà al caràter $1.\nSpetà $3 {{PLURAL:$3|argument|argument}}, otnune $4", - "abusefilter-exception-regexfailure": "Eror ant l'espression regolar \"$3\" al caràter $1: \"$2\"", + "abusefilter-exception-regexfailure": "Eror ant l'espression regolar \"$2\" al caràter $1.", "abusefilter-exception-overridebuiltin": "Coatà ëd fasson ilegal la variàbil dë stàndard \"$2\" al caràter $1.", "abusefilter-exception-outofbounds": "Arcesta ëd l'element inesistent $2 ëd la lista (dimension ëd la lista = $3) al caràter $1.", "abusefilter-exception-notarray": "Arcesta ëd n'element fòra ëd na tàula al caràter $1.", @@ -361,7 +360,6 @@ "abusefilter-topnav-examine": "Esaminé le modìfiche veje", "abusefilter-topnav-log": "Registr ëd j'abus", "abusefilter-topnav-tools": "Utiss ëd coression dij bigat", - "abusefilter-topnav-import": "Amporté un filtr", "abusefilter-log-name": "Registr dij Filtr ëd Sicurëssa", "abusefilter-log-header": "Sto registr a smon un resumé dij cambi fàit ai filtr.\nPër ij detaj complet, ch'a bèica [[Special:AbuseFilter/history|la lista]] dle modìfiche recent dël filtr.", "abusefilter-log-noresults": "Gnun arzultà", diff --git a/AbuseFilter/i18n/ps.json b/AbuseFilter/i18n/ps.json index b16614a1..f3447706 100644 --- a/AbuseFilter/i18n/ps.json +++ b/AbuseFilter/i18n/ps.json @@ -4,7 +4,7 @@ "Ahmed-Najib-Biabani-Ibrahimkhel" ] }, - "abuselog": "د ورانکارۍ يادښت", + "abuselog": "د ورانکارۍ چاڼگر يادښت", "abusefilter-warning": "'''گواښنه''': همدا کړنه په اتوماتيک ډول زيانمنه وپېژندل شوه.\nنارغوونکې سمونې به ډېر ژر پر شا خپلې پخوانۍ بڼې ته واړول شي،\nورانکاري او په بيا بيا نارغوونکې سمونې ترسره کول به ستاسې په گڼون او يا هم IP پتې باندې د بنديزونو سبب شي.\nکه چېرته تاسې په دې ډاډه ياست چې همدا يو رغوونکی سمون دی، نو تاسې کولای شی چې پر «سپارل» وټوکۍ چې ستاسې د کړنې پخلی وشي.\nد ناوړو کړنو د کړنلارې يوه لنډه څرگندونه چې ستاسې د کړنې همډوله وه، په دې توگه ده: $1", "abusefilter-disallowed": "دا کړنه په خپلکاره توگه نارغنده او زيانمنه وپېژندل شوه، او په همدې سبب يې مخنيوی وشو. \nکه چېرته بيا هم دا کړنه تاسو ته رغنده ښکاري نو، لطفاً يو پازوال پرې خبر کړی چې تاسې څه ترسره کول غواړۍ. \nستاسې همدا کړنه چې په نارغنده معيارونو کې شمېرل شوې داسې څرگندېږي: $1", "abusefilter-blocker": "د ورانکارۍ چاڼگر", @@ -15,7 +15,6 @@ "right-abusefilter-hide-log": "د ورانکارۍ يادښت مېنځپانگې پټول", "action-abusefilter-view": "د ورانکارۍ چاڼگرونه کتل", "action-abusefilter-log": "د ورانکارۍ يادښت کتل", - "abusefilter-log": "د ورانکارۍ چاڼگر يادښت", "abusefilter-log-search-user": "کارن:", "abusefilter-log-search-filter": "د چاڼگر پېژند:", "abusefilter-log-search-title": "سرليک:", diff --git a/AbuseFilter/i18n/pt-br.json b/AbuseFilter/i18n/pt-br.json index 86450cf0..d99200f0 100644 --- a/AbuseFilter/i18n/pt-br.json +++ b/AbuseFilter/i18n/pt-br.json @@ -1,38 +1,39 @@ { "@metadata": { "authors": [ + "!Silent", "Amgauna", "Anaclaudiaml", + "Araceletorres", "Cainamarques", + "Dianakc", + "Eduardo Addad de Oliveira", + "Felipe L. Ewald", + "Fitoschido", "Fúlvio", "Giro720", "Hamilton Abreu", + "He7d3r", "Helder.wiki", + "HenriqueCrang", "Luckas", "Luckas Blade", + "Matma Rex", "MetalBrasil", "OTAVIO1981", "Opraco", "Pedroca cerebral", + "Pedrofariasm", "Rafael Vargas", - "TheGabrielZaum", - "555", - "Dianakc", - "He7d3r", "Teles", - "Araceletorres", - "HenriqueCrang", - "Matma Rex", "TheEduGobi", - "!Silent", - "Felipe L. Ewald", - "Eduardo Addad de Oliveira", - "Pedrofariasm" + "TheGabrielZaum", + 555 ] }, "abusefilter-desc": "Aplica heurísticas automáticas às edições", - "abusefilter": "Configuração do filtro de edições", - "abuselog": "Registro de abusos", + "abusefilter": "Gerenciamento do filtro de abuso", + "abuselog": "Registro do filtro de abusos", "abusefilter-intro": "Bem-vindo à interface de gestão do Filtro de Abusos.\nO Filtro de Abuso é um mecanismo de ''software'' automatizado de aplicação de heurísticas automáticas a todas as ações.\nEsta interface mostra uma lista de filtros definidos e permite que sejam modificados.", "abusefilter-mustviewprivateoredit": "Por razões de segurança, só os usuários com o direito de ver filtros de abuso privados ou de modificar filtros podem usar esta interface.", "abusefilter-warning": "'''Aviso:''' esta operação foi identificada automaticamente como prejudicial.\nEdições não construtivas serão revertidas rapidamente,\ne a repetição destas edições resultará no bloqueio da sua conta ou do seu endereço IP.\nSe você acredita que esta edição é construtiva, pode submeter novamente para confirmá-la.\nUma breve descrição da regra de abuso com a qual a sua ação coincidiu é: $1", @@ -43,13 +44,14 @@ "abusefilter-blocker": "Filtro de abusos", "abusefilter-blockreason": "Automaticamente bloqueado pelo filtro de abusos.\nDescrição da regra correspondida: $1", "abusefilter-degroupreason": "Direitos automaticamente retirados pelo filtro de abusos.\nDescrição da regra: $1", + "abusefilter-blockautopromotereason": "Autopromoção automaticamente atrasado pelo filtro de abuso.\nDescrição da regra: $1", "abusefilter-accountreserved": "Este nome de conta está reservado para uso pelo filtro de abusos.", - "right-abusefilter-modify": "Modificar filtros de abusos", + "right-abusefilter-modify": "Criar ou modificar filtros de abuso", "right-abusefilter-view": "Ver filtros de abusos", "right-abusefilter-log": "Ver o registro de abusos", "right-abusefilter-log-detail": "Ver entradas detalhadas do registro de abusos", - "right-abusefilter-private": "Ver dados privados no registro de abusos", - "right-abusefilter-private-log": "Veja o registro de acesso de detalhes privados no Filtro de abuso", + "right-abusefilter-privatedetails": "Ver dados privados no registro de abusos", + "right-abusefilter-privatedetails-log": "Veja o registro de acesso de detalhes privados no Filtro de abuso", "right-abusefilter-modify-restricted": "Modificar filtros de abusos com ações restritas", "right-abusefilter-revert": "Reverter todas as modificações feitas por um dado filtro de abusos", "right-abusefilter-view-private": "Ver filtros de abuso marcados como privados", @@ -61,17 +63,23 @@ "action-abusefilter-view": "ver filtros de abuso", "action-abusefilter-log": "ver o registro de abusos", "action-abusefilter-log-detail": "ver entradas detalhadas do registro de abusos", - "action-abusefilter-private": "ver dados privados no registro de abusos", - "action-abusefilter-private-log": "ver o registo de consultas dos detalhes privados do filtro de abusos", + "action-abusefilter-privatedetails": "ver dados privados no registro de abusos", + "action-abusefilter-privatedetails-log": "ver o registo de consultas dos detalhes privados do filtro de abusos", "action-abusefilter-modify-restricted": "modificar filtros de abuso com ações restritas", "action-abusefilter-revert": "reverter todas as alterações feitas por um dado filtro de abuso", "action-abusefilter-view-private": "ver filtros de abuso marcados como privados", "action-abusefilter-log-private": "ver registro de entrada dos fitros de edições marcados como privados", - "abusefilter-log": "Registro do filtro de abusos", + "action-abusefilter-hide-log": "ocultar entradas no registro de abuso", + "action-abusefilter-hidden-log": "ver entradas de registro de abuso ocultos", + "action-abusefilter-modify-global": "criar ou modificar filtros globais de abuso", "abusefilter-log-summary": "Este registro mostra uma lista de todas as ações capturadas pelos filtros.", "abusefilter-log-search": "Pesquisar o registro de abusos", "abusefilter-log-search-user": "Usuário:", - "abusefilter-log-search-filter": "ID dos filtros (separar com barras verticais):", + "abusefilter-log-search-group": "Grupo de filtros:", + "abusefilter-log-search-group-any": "Qualquer", + "abusefilter-log-search-filter": "ID dos filtros:", + "abusefilter-log-search-filter-help": "Separar com barras verticais e prefixar filtros globais com \"$1\".", + "abusefilter-log-search-filter-help-central": "Separe com tubos", "abusefilter-log-search-title": "Título:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-impact": "Impacto:", @@ -100,19 +108,21 @@ "abusefilter-log-details-var": "Variável", "abusefilter-log-details-val": "Valor", "abusefilter-log-details-vars": "Parâmetros de ação", - "abusefilter-log-details-private": "Detalhes do registro privado", + "abusefilter-log-details-privatedetails": "Detalhes do registro privado", "abusefilter-log-details-ip": "Endereço de IP de origem", "abusefilter-log-details-checkuser": "Verificar usuário", "abusefilter-log-noactions": "nenhum", + "abusefilter-log-noactions-filter": "Nenhum", "abusefilter-log-details-diff": "Alterações feitas na edição", "abusefilter-log-linkoncontribs": "registro de abusos", "abusefilter-log-linkoncontribs-text": "Registro de abuso para {{GENDER:$1|este usuário}}", "abusefilter-log-linkonhistory": "ver o registro de abusos", "abusefilter-log-linkonhistory-text": "Ver o registro de abusos para esta página", - "abusefilter-log-hidden": "(entrada ocultada)", + "abusefilter-log-linkonundelete": "ver o registro de abusos", + "abusefilter-log-linkonundelete-text": "Ver o registro de abusos para esta página", "abusefilter-log-hidden-implicit": "(oculto porque a revisão foi eliminada)", "abusefilter-log-cannot-see-details": "Você não tem permissão para ver os detalhes desta entrada.", - "abusefilter-log-cannot-see-private-details": "Você não tem permissão para ver detalhes particulares desta entrada.", + "abusefilter-log-cannot-see-privatedetails": "Você não tem permissão para ver detalhes particulares desta entrada.", "abusefilter-log-nonexistent": "Não existe entrada com o ID fornecido.", "abusefilter-log-details-hidden": "Você não pode ver os detalhes desta entrada porque estes estão ocultados ao público.", "abusefilter-log-details-hidden-implicit": "Não pode ver os detalhes desta entrada porque a revisão associada está ocultada do público.", @@ -130,9 +140,12 @@ "log-action-filter-abusefilter-create": "Criação de novos filtros", "log-action-filter-abusefilter-modify": "Modificação de filtros", "log-action-filter-suppress-abuselog": "Supressão de registro de abuso", + "log-action-filter-rights-blockautopromote": "Bloquear promoção automática", + "log-action-filter-rights-restoreautopromote": "Restaurar promoção automática", "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|acessou}} detalhes privados de $3", + "logentry-rights-blockautopromote": "$1 {{GENDER:$2|bloqueou}} a promoção automática {{GENDER:$4|$3}} élo período de $5", + "logentry-rights-restoreautopromote": "$1 {{GENDER:$2|restaurou}} a capacidade de promoção automática de {{GENDER:$4|$3}}", "abusefilterprivatedetails-log-name": "registro de acesso do do Filtro de abuso para detalhes privados", - "abusefilter-management": "Gerenciamento do filtro de abuso", "abusefilter-list": "Todos os filtros", "abusefilter-list-id": "Identificação de filtro", "abusefilter-list-pattern": "Padrão", @@ -154,6 +167,7 @@ "abusefilter-throttled": "limitado", "abusefilter-hitcount": "$1 {{PLURAL:$1|resultado|resultados}}", "abusefilter-new": "Criar um novo filtro", + "abusefilter-import-button": "Importar filtro", "abusefilter-return": "Voltar ao gerenciamento de filtros", "abusefilter-status-global": "Global", "abusefilter-list-options": "Opções", @@ -174,26 +188,29 @@ "abusefilter-list-options-search-like": "Consulta simples", "abusefilter-list-options-search-rlike": "Expressão regular", "abusefilter-list-options-search-irlike": "Expressão regular insensível a maiúsculas", + "abusefilter-list-invalid-searchmode": "O modo de pesquisa especificado não é válido.", "abusefilter-list-regexerror": "Ocorreu um erro durante a pesquisa: Erro de sintaxe de expressão regular.", "abusefilter-list-options-submit": "Atualizar", "abusefilter-tools-text": "Aqui estão algumas ferramentas que poderão ser úteis na formulação e depuração dos filtros de abuso.", "abusefilter-tools-expr": "Testador de expressões", "abusefilter-tools-submitexpr": "Calcular", + "abusefilter-tools-syntax-error": "O filtro tem sintaxe inválida.", "abusefilter-tools-reautoconfirm": "Restaurar estatuto autoconfirmado", "abusefilter-tools-reautoconfirm-user": "Usuário:", "abusefilter-tools-reautoconfirm-submit": "Re-autoconfirmar", + "abusefilter-tools-restoreautopromote": "Autopromoção restaurada através das ferramentas do filtro de abusos.", "abusefilter-reautoconfirm-none": "Não foi suspenso o estado autoconfirmado {{GENDER:$1|desse usuário|dessa usuária|desse(a) usuário(a)}}.", "abusefilter-reautoconfirm-notallowed": "Você não está autorizado a restaurar o estado autoconfirmado.", "abusefilter-reautoconfirm-done": "O estado autoconfirmado da conta foi restaurado", - "abusefilter-status": "{{PLURAL:$1|Da última 1 ação|Das últimas $1 ações}}, $2 ($3%) {{PLURAL:$2|atingiu|atingiram}} o limite de $4 condições, e $5 ($6%) {{PLURAL:$5|correspondeu|corresponderam}} a um dos filtros neste momento ativos.", + "abusefilter-status": "{{PLURAL:$1|Da última 1 ação|Das últimas $1 ações}}, $2 ($3%) {{PLURAL:$2|atingiu|atingiram}} o limite de $4 condições, e $5 ($6%) {{PLURAL:$5|coincidiu|coincidiram}} com pelo menos um dos filtros neste momento ativos.", "abusefilter-edit": "Editando um filtro de abusos", "abusefilter-edit-subtitle": "Editando filtro $1", "abusefilter-edit-subtitle-new": "Criando filtro", "abusefilter-edit-token-not-match": "A edição não foi publicada! Por favor, grave novamente.", "abusefilter-edit-oldwarning": "<strong>Você está editando uma versão antiga deste filtro.\nAs estatísticas transcritas são relativas à versão mais recente do filtro.\nSe gravar as suas modificações, irá sobrepor todas as modificações desde a revisão que você está aeditando.</strong> •\n[[Special:AbuseFilter/history/$2|Voltar ao histórico deste filtro]].", + "abusefilter-edit-oldwarning-view": "<strong>Você está visualizando uma versão antiga deste filtro.\nAs estatísticas citadas são para a versão mais recente do filtro.</strong> •\n[[Special:AbuseFilter/history/$2|Retornar ao histórico deste filtro]].", "abusefilter-edit-status-label": "Estatísticas:", - "abusefilter-edit-status": "{{PLURAL:$1|Da última $1 ação|Das últimas $1 ações}}, este filtro correspondeu com $2 ($3%).", - "abusefilter-edit-status-profile": "{{PLURAL:$1|Da última 1 ação|Das últimas $1 ações}}, este filtro correspondeu com $2 ($3%).\nEm média, o seu tempo de execução é de $4 ms, e consome $5 {{PLURAL:$5|condição|condições}} do seu limite de condições.", + "abusefilter-edit-status": "{{PLURAL:$1|Da última 1 ação|Das últimas $1 ações}}, este filtro correspondeu com $2 ($3%).\nEm média, o seu tempo de execução é de $4 ms, e consome $5 {{PLURAL:$5|condição|condições}} do seu limite de condições.", "abusefilter-edit-throttled-warning": "'''Aviso:''' Este filtro foi automaticamente identificado como prejudicial. Como medida de prevenção, as seguintes operações não serão executadas ($1). Para remover esta restrição reveja e [[mw:Extension:AbuseFilter/Conditions|otimize]] as suas condições, por favor", "abusefilter-edit-new": "Novo filtro", "abusefilter-edit-save": "Salvar filtro", @@ -226,13 +243,18 @@ "abusefilter-edit-throttle-count": "Número de ações a permitir:", "abusefilter-edit-throttle-period": "Período de tempo (em segundos):", "abusefilter-edit-throttle-groups": "Agrupar limitador por:", - "abusefilter-edit-throttle-ip": "Endereço de IP", - "abusefilter-edit-throttle-user": "Conta de usuário", - "abusefilter-edit-throttle-range": "Gama /16", - "abusefilter-edit-throttle-creationdate": "Hora do servidor de criação da conta", - "abusefilter-edit-throttle-editcount": "Contador de edições", - "abusefilter-edit-throttle-site": "Todo o ''site''", - "abusefilter-edit-throttle-page": "Página", + "abusefilter-edit-throttle-groups-help": "Consultar $1.", + "abusefilter-edit-throttle-groups-help-text": "a documentação no mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Dividir com vírgulas para se juntar ao AND, e com quebras de linha para se juntar ao OR", + "abusefilter-edit-throttle-placeholder": "Dividir com vírgulas para se juntar com AND e inserir um por um para ingressar com OU", + "abusefilter-throttle-ip": "Endereço de IP", + "abusefilter-throttle-user": "conta de usuário", + "abusefilter-throttle-range": "gama /16", + "abusefilter-throttle-creationdate": "data de criação da conta", + "abusefilter-throttle-editcount": "contador de edições", + "abusefilter-throttle-site": "Todo o site", + "abusefilter-throttle-page": "página", + "abusefilter-throttle-none": "(nenhum)", "abusefilter-throttle-details": "Permitir $1 {{PLURAL:$1|operação|operações}} a cada $2 {{PLURAL:$2|segundo|segundos}}, agrupar o limitador por: $3", "abusefilter-edit-warn-message": "Mensagem de sistema para usar como aviso:", "abusefilter-edit-warn-other": "Outra mensagem", @@ -272,10 +294,18 @@ "abusefilter-edit-export": "Exportar este filtro para outra wiki", "abusefilter-edit-syntaxok": "Nenhum erro de sintaxe foi detectado.", "abusefilter-edit-syntaxerr": "Erro de sintaxe detectado: $1", + "abusefilter-edit-warn-leave": "Deixar a página fará com que você perca qualquer alteração feita nesse filtro.", "abusefilter-edit-bad-tags": "Uma ou mais das etiquetas que especificou não são válidas.\nAs etiquetas devem ser curtas, não podem conter caracteres especiais e não podem estar reservadas por outro programa. Tente escolher um novo nome de etiqueta.", "abusefilter-edit-notallowed": "Você não tem permissão para criar ou editar filtros de abuso", "abusefilter-edit-notallowed-global": "Você não está autorizada a criar ou editar filtros de abuso globais", - "abusefilter-edit-notallowed-global-custom-msg": "Mensagens de advertência personalizados não são suportadas por filtros globais", + "abusefilter-edit-notallowed-global-custom-msg": "Mensagens personalizadas de aviso ou não permitidas não são suportadas para filtros globais", + "abusefilter-edit-invalid-warn-message": "A mensagem de aviso não pode ser deixada em branco.", + "abusefilter-edit-invalid-disallow-message": "A mensagem não permitida não pode ser deixada em branco.", + "abusefilter-edit-invalid-throttlecount": "A contagem de ações do acelerador deve ser um inteiro positivo.", + "abusefilter-edit-invalid-throttleperiod": "O período de aceleração deve ser um inteiro positivo.", + "abusefilter-edit-empty-throttlegroups": "Pelo menos um grupo de aceleração deve ser selecionado.", + "abusefilter-edit-duplicated-throttlegroups": "Grupos de aceleração não podem ter duplicatas.", + "abusefilter-edit-invalid-throttlegroups": "Os grupos de aceleração especificados não são válidos.", "abusefilter-edit-builder-select": "Selecione uma opção para inserir no cursor", "abusefilter-edit-builder-group-op-arithmetic": "Operadores aritméticos", "abusefilter-edit-builder-op-arithmetic-addition": "Adição (+)", @@ -306,7 +336,8 @@ "abusefilter-edit-builder-misc-contains": "Texto da esquerda contém o da direita (contains)", "abusefilter-edit-builder-misc-stringlit": "Texto literal (\"\")", "abusefilter-edit-builder-misc-tern": "Operador ternário (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Condicional (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Condicional (se X e Y mais Z terminarem)", + "abusefilter-edit-builder-misc-cond-short": "Condicional curto (se X então Y terminar)", "abusefilter-edit-builder-group-funcs": "Funções", "abusefilter-edit-builder-funcs-length": "Comprimento do texto (length)", "abusefilter-edit-builder-funcs-lcase": "Para minúscula (lcase)", @@ -377,12 +408,12 @@ "abusefilter-edit-builder-vars-all-links": "Todos os links externos no novo texto", "abusefilter-edit-builder-vars-added-links": "Todos os links externos adicionados na edição", "abusefilter-edit-builder-vars-removed-links": "Todos os links externos removidos na edição", - "abusefilter-edit-builder-vars-old-text": "Texto wiki anterior da página, antes da edição (já não é usado)", - "abusefilter-edit-builder-vars-new-text": "Nova página com texto wiki, após a edição", + "abusefilter-edit-builder-vars-old-wikitext": "Página antiga wikitexto, antes da edição", + "abusefilter-edit-builder-vars-new-wikitext": "Nova página com texto wiki, após a edição", "abusefilter-edit-builder-vars-new-pst": "Nova página de wiki texto, transformada antes de salvar", "abusefilter-edit-builder-vars-diff-pst": "Diferenças unificadas das alterações nesta edição, transformadas antes da gravação", "abusefilter-edit-builder-vars-addedlines-pst": "Linhas adicionadas na edição, transformadas antes da gravação", - "abusefilter-edit-builder-vars-new-text-stripped": "Nova página de texto, sem qualquer formatação", + "abusefilter-edit-builder-vars-new-text": "Nova página de texto, sem qualquer formatação", "abusefilter-edit-builder-vars-new-html": "Fonte HTML analisada da nova revisão", "abusefilter-edit-builder-vars-restrictions-edit": "Nível de proteção de edição da página", "abusefilter-edit-builder-vars-restrictions-move": "Nível de proteção de movimentação da página", @@ -396,10 +427,10 @@ "abusefilter-edit-builder-vars-movedto-restrictions-move": "Nível de proteção de movimentações da página de destino da movimentação", "abusefilter-edit-builder-vars-movedto-restrictions-create": "Proteção de criação da página de destino da movimentação", "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Proteção de carregamento do arquivo de destino da movimentação", - "abusefilter-edit-builder-vars-old-text-stripped": "Texto anterior da página, sem a formatação", + "abusefilter-edit-builder-vars-old-text": "Texto de página antiga, despojado de qualquer marcação (não mais em uso)", "abusefilter-edit-builder-vars-old-links": "Links na página, antes da edição", "abusefilter-edit-builder-vars-old-html": "Texto wiki anterior da página, convertido para HTML (já não é usado)", - "abusefilter-edit-builder-vars-minor-edit": "Se a edição está marcada ou não como menor", + "abusefilter-edit-builder-vars-minor-edit": "Se a edição está marcada ou não como menor (não mais em uso)", "abusefilter-edit-builder-vars-file-sha1": "Hash SHA1 do conteúdo do arquivo", "abusefilter-edit-builder-vars-file-size": "Tamanho do arquivo em bytes", "abusefilter-edit-builder-vars-file-mime": "Tipo do arquivo MIME", @@ -407,6 +438,8 @@ "abusefilter-edit-builder-vars-file-width": "Largura do arquivo em pixels", "abusefilter-edit-builder-vars-file-height": "Altura do arquivo em pixels", "abusefilter-edit-builder-vars-file-bits-per-channel": "Bits por canal de cor do arquivo", + "abusefilter-edit-builder-vars-wiki-name": "Nome do banco de dados da wiki", + "abusefilter-edit-builder-vars-wiki-language": "Código do idioma da wiki", "abusefilter-filter-log": "Modificações recentes de filtros", "abusefilter-history": "Histórico de modificações do Filtro de Abusos #$1", "abusefilter-history-foruser": "Modificações por $1", @@ -440,13 +473,16 @@ "abusefilter-exception-dividebyzero": "Tentativa ilegal de dividir $2 por zero, na posição $1.", "abusefilter-exception-unrecognisedvar": "Variável não reconhecida $2, na posição $1.", "abusefilter-exception-notenoughargs": "Argumentos insuficientes para a função $2, na posição $1.\nEsperava-se $3 {{PLURAL:$3|argumento|argumentos}}, obteve-se $4", - "abusefilter-exception-regexfailure": "Erro na expressão regular “$2”, na posição $1: “$1”", - "abusefilter-exception-overridebuiltin": "Sobreposição ilegal da variável integrada “$2”, na posição $1.", + "abusefilter-exception-toomanyargs": "Muitos argumentos para a função $2 chamados no caractere $1.\nEsperado no máximo $3 {{PLURAL:$3|argumento|argumentos}}, obteve $4", + "abusefilter-exception-regexfailure": "Erro na expressão regular “$2”, na posição $1.", + "abusefilter-exception-overridebuiltin": "Sobreposição ilegal da identificador integrado “$2”, na posição $1.", "abusefilter-exception-outofbounds": "Foi solicitada a entrada $2 que não existe na matriz (tamanho da matriz = $3) na posição $1.", + "abusefilter-exception-negativeindex": "Índices negativos não são permitidos em matrizes. Obteve o índice \"$2\" no caractere $1.", "abusefilter-exception-notarray": "Solicitando uma entrada de matriz a uma não matriz, na posição $1.", "abusefilter-exception-unclosedcomment": "Comentário por fechar, no caráter $1.", "abusefilter-exception-invalidiprange": "Foi fornecida uma gama IP inválida \"$2\" no carácter $1.", "abusefilter-exception-disabledvar": "A variável $2 na posição $1 deixou de ser usada.", + "abusefilter-exception-variablevariable": "set e set_var esperam que o primeiro argumento seja uma string literal, encontrada no caractere $1.", "abusefilter-action-tag": "Etiquetar", "abusefilter-action-throttle": "Limitador", "abusefilter-action-warn": "Avisar", @@ -509,15 +545,16 @@ "abusefilter-examine-noresults": "Não foram encontrados resultados para os parâmetros de pesquisa fornecidos.", "abusefilter-topnav": "'''Navegação no Filtro de Abusos'''", "abusefilter-topnav-home": "Início", + "abusefilter-topnav-recentchanges": "Modificações recentes de filtros", "abusefilter-topnav-test": "Teste em bloco", "abusefilter-topnav-examine": "Examinar edições passadas", "abusefilter-topnav-log": "Registro de abusos", "abusefilter-topnav-tools": "Ferramentas de depuração", - "abusefilter-topnav-import": "Importar filtro", "abusefilter-log-name": "Registro do filtro de abusos", "abusefilter-log-header": "Este registro mostra um resumo das alterações efetuadas aos filtros.\nPara detalhes completos, ver [[Special:AbuseFilter/history|a lista]] de alterações recentes a filtros.", "abusefilter-logentry-create": "$1 {{GENDER:$2|criou}} $4 ($5)", "abusefilter-logentry-modify": "$1 {{GENDER:$2|modificou}} $4 ($5)", + "abusefilter-log-invalid-filter": "Alguns dos IDs de filtro especificados são inválidos.", "abusefilter-log-noresults": "Nenhum resultado", "abusefilter-diff-title": "Diferenças entre versões", "abusefilter-diff-item": "Item", @@ -530,11 +567,12 @@ "abusefilter-diff-next": "Alteração recente", "abusefilter-import-intro": "Você pode usar esta interface para importar filtros de outros wikis.\nNo wiki de origem, clique em “{{int:abusefilter-edit-export}}”, sob “{{int:abusefilter-edit-tools}}” na interface de edição.\nCopie o conteúdo da caixa de texto exibida, colando-o nesta caixa de texto; em seguida, clique em “{{int:abusefilter-import-submit}}”.", "abusefilter-import-submit": "Importar dados", + "abusefilter-import-invalid-data": "Os dados que você tentou importar não são válidos", "abusefilter-group-default": "Padrão", "abusefilter-http-error": "Ocorreu um erro HTTP: $1.", - "abusefilter-view-private-submit": "Ver detalhes privados", - "abusefilter-view-private": "Ver detalhes privados", - "abusefilter-view-private-reason": "Razão para acessar detalhes privados:", + "abusefilter-view-privatedetails-submit": "Ver detalhes privados", + "abusefilter-view-privatedetails-legend": "Ver detalhes privados", + "abusefilter-view-privatedetails-reason": "Razão para acessar detalhes privados:", "abusefilter-log-details-id": "ID de log", "abusefilter-invalid-request": "Pedido inválido! Você deve acessar os detalhes do registro privado através do formulário em [[Special:AbuseLog/$1]] e fornecer um motivo.", "abusefilter-invalid-request-noid": "Pedido inválido! Você deve acessar os detalhes do registro privado através do formulário na página de detalhes do registro de abuso e fornecer um motivo.", diff --git a/AbuseFilter/i18n/pt.json b/AbuseFilter/i18n/pt.json index 52b894b4..3caf5875 100644 --- a/AbuseFilter/i18n/pt.json +++ b/AbuseFilter/i18n/pt.json @@ -2,36 +2,38 @@ "@metadata": { "authors": [ "Alchimista", + "Athena in Wonderland", "Bonifácio", + "Daimona Eaytoy", "Fúlvio", "Giro720", "GoEThe", "Hamilton Abreu", + "He7d3r", "Helder.wiki", "Imperadeiro98", "Lijealso", "Luckas", "MF-Warburg", "Malafaya", + "Mansil", + "Mansil alfalb", + "Matma Rex", "McDutchie", "OTAVIO1981", + "Opraco", "Pedroca cerebral", "SandroHc", "Sarilho1", - "Waldir", - "555", "Vitorvicentevalente", - "He7d3r", - "Opraco", - "Matma Rex", - "Mansil", - "Athena in Wonderland", - "Daimona Eaytoy" + "Waldir", + "Waldyrious", + 555 ] }, "abusefilter-desc": "Aplica heurísticas automáticas às edições.", - "abusefilter": "Configuração do filtro de abusos", - "abuselog": "Registo de abusos", + "abusefilter": "Administração do filtro de abusos", + "abuselog": "Registo do filtro de abusos", "abusefilter-intro": "Bem-vindo à interface de gestão do Filtro de Abusos.\nO Filtro de Abusos é um mecanismo de software automatizado de aplicação de heurísticas automáticas a todas as operações.\nEsta interface mostra uma lista dos filtros definidos e permite que estes sejam modificados.", "abusefilter-mustviewprivateoredit": "Por razões de segurança, só os utilizadores com o direito de ver filtros de abuso privados ou de modificar filtros podem usar esta interface.", "abusefilter-warning": "'''Aviso:''' esta operação foi identificada de forma automática como prejudicial.\nAs operações não construtivas serão revertidas rapidamente,\ne a repetição destas edições resultará no bloqueio da sua conta ou do seu endereço IP.\nSe crê que esta operação é construtiva, pode enviar novamente para confirmá-la.\nSegue-se uma breve descrição da regra de prevenção de abusos que detetou a sua operação: $1", @@ -42,13 +44,14 @@ "abusefilter-blocker": "Filtro de abusos", "abusefilter-blockreason": "Automaticamente bloqueado pelo filtro de abusos.\nDescrição da regra que detetou a sua ação: $1", "abusefilter-degroupreason": "Direitos automaticamente retirados pelo filtro de abusos. Descrição da regra: $1", + "abusefilter-blockautopromotereason": "Promoção automática atrasada automaticamente pelo filtro de abusos. Descrição da regra: $1", "abusefilter-accountreserved": "Este nome de conta está reservado para uso pelo filtro de abusos.", - "right-abusefilter-modify": "Modificar filtros de abuso", + "right-abusefilter-modify": "Criar ou modificar filtros de abusos", "right-abusefilter-view": "Ver filtros de abuso", "right-abusefilter-log": "Ver o registo de abusos", "right-abusefilter-log-detail": "Ver entradas detalhadas do registo de abusos", - "right-abusefilter-private": "Ver dados privados no registo de abusos", - "right-abusefilter-private-log": "Ver o registo de consultas dos detalhes privados do filtro de abusos", + "right-abusefilter-privatedetails": "Ver dados privados no registo de abusos", + "right-abusefilter-privatedetails-log": "Ver o registo de consultas dos detalhes privados do filtro de abusos", "right-abusefilter-modify-restricted": "Modificar filtros de abuso com ações restritas", "right-abusefilter-revert": "Reverter todas as alterações feitas por um dado filtro de abuso", "right-abusefilter-view-private": "Ver filtros de abuso marcados como privados", @@ -60,17 +63,22 @@ "action-abusefilter-view": "ver filtros de abuso", "action-abusefilter-log": "ver o registo de abusos", "action-abusefilter-log-detail": "ver entradas detalhadas do registo de abusos", - "action-abusefilter-private": "ver dados privados do registo de abusos", - "action-abusefilter-private-log": "ver o registo de consultas dos detalhes privados do filtro de abusos", + "action-abusefilter-privatedetails": "ver dados privados do registo de abusos", + "action-abusefilter-privatedetails-log": "ver o registo de consultas dos detalhes privados do filtro de abusos", "action-abusefilter-modify-restricted": "modificar filtros de abuso com ações restritas", "action-abusefilter-revert": "reverter todas as alterações feitas por um dado filtro de abuso", "action-abusefilter-view-private": "ver filtros de abuso marcados como privados", "action-abusefilter-log-private": "ver registos dos filtros de abuso marcados como privados", - "abusefilter-log": "Registo do filtro de abusos", + "action-abusefilter-hide-log": "ocultar entradas do filtro de abusos", + "action-abusefilter-hidden-log": "ver entradas ocultadas do registo de abusos", + "action-abusefilter-modify-global": "criar ou modificar os filtros globais de abusos", "abusefilter-log-summary": "Este registo mostra uma lista de todas as ações captadas pelos filtros.", "abusefilter-log-search": "Pesquisar o registo de abusos", "abusefilter-log-search-user": "Utilizador:", - "abusefilter-log-search-filter": "ID dos filtros (separar com barras verticais):", + "abusefilter-log-search-group": "Grupo de filtros:", + "abusefilter-log-search-group-any": "Qualquer", + "abusefilter-log-search-filter": "Identificadores dos filtros:", + "abusefilter-log-search-filter-help": "Separar com barras verticais e prefixar filtros globais com \"$1\".", "abusefilter-log-search-title": "Título:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-impact": "Impacto:", @@ -99,7 +107,7 @@ "abusefilter-log-details-var": "Variável", "abusefilter-log-details-val": "Valor", "abusefilter-log-details-vars": "Parâmetros de ação", - "abusefilter-log-details-private": "Detalhes do registo privado", + "abusefilter-log-details-privatedetails": "Detalhes do registo privado", "abusefilter-log-details-ip": "Endereço IP de origem", "abusefilter-log-details-checkuser": "Verificação de utilizadores", "abusefilter-log-noactions": "nenhuma", @@ -108,10 +116,11 @@ "abusefilter-log-linkoncontribs-text": "Registo de abusos para {{GENDER:$1|este utilizador|esta utilizadora}}", "abusefilter-log-linkonhistory": "ver o registo de abusos", "abusefilter-log-linkonhistory-text": "Ver o registo de abusos para esta página", - "abusefilter-log-hidden": "(entrada ocultada)", + "abusefilter-log-linkonundelete": "ver o registo de abusos", + "abusefilter-log-linkonundelete-text": "Ver o registo de abusos para esta página", "abusefilter-log-hidden-implicit": "(oculto porque a revisão foi eliminada)", "abusefilter-log-cannot-see-details": "Não tem permissão para ver os detalhes desta entrada.", - "abusefilter-log-cannot-see-private-details": "Não tem permissão para ver os detalhes privados desta entrada.", + "abusefilter-log-cannot-see-privatedetails": "Não tem permissão para ver os detalhes privados desta entrada.", "abusefilter-log-nonexistent": "Não existe nenhuma entrada com o identificador fornecido.", "abusefilter-log-details-hidden": "Não pode ver os detalhes desta entrada porque estes estão ocultados ao público.", "abusefilter-log-details-hidden-implicit": "Não pode ver os detalhes desta entrada porque a revisão associada está ocultada do público.", @@ -129,9 +138,12 @@ "log-action-filter-abusefilter-create": "Criação de novos filtros", "log-action-filter-abusefilter-modify": "Modificação de filtros", "log-action-filter-suppress-abuselog": "Supressão do registo de abusos", + "log-action-filter-rights-blockautopromote": "Bloqueio de promoção automática", + "log-action-filter-rights-restoreautopromote": "Restauro de promoção automática", "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|acedeu}} aos detalhes privados de $3", + "logentry-rights-blockautopromote": "$1 {{GENDER:$2|bloqueou}} a promoção automática de {{GENDER:$4|$3}} por um período de $5", + "logentry-rights-restoreautopromote": "$1 {{GENDER:$2|restaurou}} a capacidade de promoção automática de {{GENDER:$4|$3}}", "abusefilterprivatedetails-log-name": "Registo de consulta dos detalhes privados do filtro de abusos", - "abusefilter-management": "Administração do filtro de abusos", "abusefilter-list": "Todos os filtros", "abusefilter-list-id": "ID do filtro", "abusefilter-list-pattern": "Padrão", @@ -153,6 +165,7 @@ "abusefilter-throttled": "limitado", "abusefilter-hitcount": "$1 {{PLURAL:$1|resultado|resultados}}", "abusefilter-new": "Criar um filtro novo", + "abusefilter-import-button": "Importar filtro", "abusefilter-return": "Voltar à administração de filtros", "abusefilter-status-global": "Global", "abusefilter-list-options": "Opções", @@ -173,26 +186,29 @@ "abusefilter-list-options-search-like": "Consulta simples", "abusefilter-list-options-search-rlike": "Expressão regular", "abusefilter-list-options-search-irlike": "Expressão regular insensível ao uso de letras maiúsculas", + "abusefilter-list-invalid-searchmode": "O modo de pesquisa especificado é inválido.", "abusefilter-list-regexerror": "Ocorreu um erro durante a pesquisa: Erro de sintaxe na expressão regular.", "abusefilter-list-options-submit": "Atualizar", "abusefilter-tools-text": "Aqui estão algumas ferramentas que poderão ser úteis na formulação e depuração dos filtros de abuso.", "abusefilter-tools-expr": "Testador de expressões", "abusefilter-tools-submitexpr": "Calcular", + "abusefilter-tools-syntax-error": "O filtro contém sintaxe inválida.", "abusefilter-tools-reautoconfirm": "Restaurar estatuto autoconfirmado", "abusefilter-tools-reautoconfirm-user": "Utilizador:", "abusefilter-tools-reautoconfirm-submit": "Re-autoconfirmar", + "abusefilter-tools-restoreautopromote": "Promoção automática restaurada através das ferramentas do filtro de abusos.", "abusefilter-reautoconfirm-none": "Não foi suspendido o estado autoconfirmado {{GENDER:$1|desse utilizador|dessa utilizadora|desse utilizador}}.", "abusefilter-reautoconfirm-notallowed": "Não está autorizado a repor o estado autoconfirmado.", "abusefilter-reautoconfirm-done": "O estado autoconfirmado da conta foi restaurado", - "abusefilter-status": "{{PLURAL:$1|Da última 1 ação|Das últimas $1 ações}}, $2 ($3%) {{PLURAL:$2|atingiu|atingiram}} o limite de $4 condições, e $5 ($6%) {{PLURAL:$5|coincidiu|coincidiram}} com um dos filtros neste momento ativos.", + "abusefilter-status": "{{PLURAL:$1|Da última 1 ação|Das últimas $1 ações}}, $2 ($3%) {{PLURAL:$2|atingiu|atingiram}} o limite de $4 condições, e $5 ($6%) {{PLURAL:$5|coincidiu|coincidiram}} com pelo menos um dos filtros neste momento ativos.", "abusefilter-edit": "A editar filtro de abusos", "abusefilter-edit-subtitle": "A editar o filtro $1", "abusefilter-edit-subtitle-new": "A criar filtro", "abusefilter-edit-token-not-match": "A edição não foi publicada! Por favor, grave novamente.", "abusefilter-edit-oldwarning": "<strong>Está a editar uma versão antiga deste filtro.\nAs estatísticas transcritas são relativas à versão mais recente do filtro.\nSe gravar as suas modificações, irá sobrepor todas as modificações desde a revisão que está a editar.</strong> •\n[[Special:AbuseFilter/history/$2|Voltar ao histórico deste filtro]].", + "abusefilter-edit-oldwarning-view": "<strong>Está a ver uma versão antiga deste filtro.\nAs estatísticas apresentadas concernem a versão mais recente do filtro.</strong> •\n[[Special:AbuseFilter/history/$2|Voltar ao historial deste filtro]].", "abusefilter-edit-status-label": "Estatísticas:", - "abusefilter-edit-status": "{{PLURAL:$1|Da última 1 ação|Das últimas $1 ações}}, $2 ($3%) acionaram este filtro.", - "abusefilter-edit-status-profile": "{{PLURAL:$1|Da última 1 ação|Das últimas $1 ações}}, este filtro detetou $2 ($3%).\nEm média, o seu tempo de execução é de $4ms, e consome $5 {{PLURAL:$5|condição|condições}} do seu limite de condições.", + "abusefilter-edit-status": "{{PLURAL:$1|Da última 1 ação|Das últimas $1 ações}}, $2 ($3%) acionaram este filtro.\nEm média, o seu tempo de execução é de $4ms, e consome $5 {{PLURAL:$5|condição|condições}} do seu limite de condições.", "abusefilter-edit-throttled-warning": "'''Aviso:''' Este filtro foi automaticamente identificado como prejudicial. Como medida de prevenção, as seguintes operações não serão executadas ($1). Para remover esta restrição reveja e [[mw:Extension:AbuseFilter/Conditions|otimize]] as suas condições, por favor", "abusefilter-edit-new": "Novo filtro", "abusefilter-edit-save": "Gravar filtro", @@ -213,7 +229,7 @@ "abusefilter-edit-lastmod-text": "$1 por $2", "abusefilter-edit-hitcount": "Deteções do filtro:", "abusefilter-edit-consequences": "Ações a realizar quando acionado", - "abusefilter-edit-action-warn": "Desencadear estas ações após emitir um aviso ao utilizador", + "abusefilter-edit-action-warn": "Desencadear estas ações depois de emitir um aviso ao utilizador", "abusefilter-edit-action-disallow": "Impedir o utilizador de realizar a ação em questão", "abusefilter-edit-action-blockautopromote": "Revogar o estatuto autoconfirmado do utilizador", "abusefilter-edit-action-degroup": "Remover o utilizador de todos os grupos privilegiados", @@ -225,13 +241,18 @@ "abusefilter-edit-throttle-count": "Número de ações que serão permitidas:", "abusefilter-edit-throttle-period": "Período de tempo (em segundos):", "abusefilter-edit-throttle-groups": "Agrupar limitador por:", - "abusefilter-edit-throttle-ip": "Endereço IP", - "abusefilter-edit-throttle-user": "Conta de utilizador", - "abusefilter-edit-throttle-range": "Gama /16", - "abusefilter-edit-throttle-creationdate": "Hora do servidor da criação da conta", - "abusefilter-edit-throttle-editcount": "Contagem de edições", - "abusefilter-edit-throttle-site": "Todo o ''site''", - "abusefilter-edit-throttle-page": "Página", + "abusefilter-edit-throttle-groups-help": "Consultar $1.", + "abusefilter-edit-throttle-groups-help-text": "a documentação em mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Separar com vírgulas para combinar com E e com quebras de linha para combinar com OU", + "abusefilter-edit-throttle-placeholder": "Separar com vírgulas para combinar com E e inserir uma a uma para combinar com OU", + "abusefilter-throttle-ip": "endereço IP", + "abusefilter-throttle-user": "conta de utilizador", + "abusefilter-throttle-range": "gama /16", + "abusefilter-throttle-creationdate": "data de criação da conta", + "abusefilter-throttle-editcount": "contagem de edições", + "abusefilter-throttle-site": "todo o ''site''", + "abusefilter-throttle-page": "página", + "abusefilter-throttle-none": "(nenhum)", "abusefilter-throttle-details": "Permitir $1 {{PLURAL:$1|operação|operações}} a cada $2 {{PLURAL:$2|segundo|segundos}}, agrupar o limitador por: $3", "abusefilter-edit-warn-message": "Mensagem de sistema para usar como aviso:", "abusefilter-edit-warn-other": "Outra mensagem", @@ -256,7 +277,7 @@ "abusefilter-edit-denied": "Não pode ver detalhes deste filtro, porque ele está ocultado de vista pública.", "abusefilter-edit-main": "Parâmetros do filtro", "abusefilter-edit-done-subtitle": "Filtro editado", - "abusefilter-edit-done": "Gravou com sucesso as [[Special:AbuseFilter/history/$1/diff/prev/$2|alterações]] ao [[Special:AbuseFilter/$1|filtro $3]].", + "abusefilter-edit-done": "As [[Special:AbuseFilter/history/$1/diff/prev/$2|suas alterações]] do [[Special:AbuseFilter/$1|filtro $3]] foram gravadas.", "abusefilter-edit-badsyntax": "Há um erro de sintaxe no filtro que especificou.\nO resultado de saída do analisador foi: <pre>$1</pre>", "abusefilter-edit-missingfields": "Os seguintes campos são obrigatórios e têm de ser preenchidos: $1", "abusefilter-edit-deleting-enabled": "Não pode marcar um filtro ativo como eliminado.", @@ -271,10 +292,18 @@ "abusefilter-edit-export": "Exportar este filtro para outra wiki", "abusefilter-edit-syntaxok": "Não foi detetado nenhum erro de sintaxe.", "abusefilter-edit-syntaxerr": "Erro de sintaxe detetado: $1", + "abusefilter-edit-warn-leave": "Se deixar a página perderá todas as alterações feitas a este filtro.", "abusefilter-edit-bad-tags": "Uma ou mais das etiquetas que especificou não são válidas.\nAs etiquetas devem ser curtas, não podem conter caracteres especiais e não podem estar reservadas por outro programa. Tente escolher um novo nome de etiqueta.", "abusefilter-edit-notallowed": "Não tem permissão para criar ou editar filtros de abuso", "abusefilter-edit-notallowed-global": "Não tem permissão para criar ou editar filtros de abuso globais", - "abusefilter-edit-notallowed-global-custom-msg": "Não são suportadas mensagens de advertência personalizadas para filtros globais", + "abusefilter-edit-notallowed-global-custom-msg": "Mensagens personalizadas de advertência ou de falta de permissões não são suportadas nos filtros globais", + "abusefilter-edit-invalid-warn-message": "A mensagem de advertência não pode ser deixada vazia.", + "abusefilter-edit-invalid-disallow-message": "A mensagem de falta de permissões não pode ficar vazia.", + "abusefilter-edit-invalid-throttlecount": "O número de ações para a limitação deve ser um inteiro positivo.", + "abusefilter-edit-invalid-throttleperiod": "O período para a limitação deve ser um inteiro positivo.", + "abusefilter-edit-empty-throttlegroups": "Tem de ser selecionado pelo menos um grupo de limitação.", + "abusefilter-edit-duplicated-throttlegroups": "Os grupos de limitação não podem ter duplicados.", + "abusefilter-edit-invalid-throttlegroups": "Os grupos de limitação especificados não são válidos.", "abusefilter-edit-builder-select": "Selecione uma opção para inserir no cursor", "abusefilter-edit-builder-group-op-arithmetic": "Operadores aritméticos", "abusefilter-edit-builder-op-arithmetic-addition": "Adição (+)", @@ -304,7 +333,8 @@ "abusefilter-edit-builder-misc-contains": "Texto da esquerda contém o da direita (contains)", "abusefilter-edit-builder-misc-stringlit": "Texto literal (\"\")", "abusefilter-edit-builder-misc-tern": "Operador ternário (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Condicional (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Condicional (se X então Y se não Z fim)", + "abusefilter-edit-builder-misc-cond-short": "Condicional curto (se X então Y fim)", "abusefilter-edit-builder-group-funcs": "Funções", "abusefilter-edit-builder-funcs-length": "Comprimento do texto (length)", "abusefilter-edit-builder-funcs-lcase": "Para minúscula (lcase)", @@ -375,12 +405,12 @@ "abusefilter-edit-builder-vars-all-links": "Todas as hiperligações externas no novo texto", "abusefilter-edit-builder-vars-added-links": "Todas as hiperligações externas adicionadas na edição", "abusefilter-edit-builder-vars-removed-links": "Todas as hiperligações externas removidas na edição", - "abusefilter-edit-builder-vars-old-text": "Texto wiki anterior da página, antes da edição (já não é usado)", - "abusefilter-edit-builder-vars-new-text": "Texto wiki novo da página, após a edição", + "abusefilter-edit-builder-vars-old-wikitext": "Texto wiki anterior da página, antes da edição", + "abusefilter-edit-builder-vars-new-wikitext": "Texto wiki novo da página, após a edição", "abusefilter-edit-builder-vars-new-pst": "Texto wiki novo, transformado antes da gravação", "abusefilter-edit-builder-vars-diff-pst": "Diferenças unificadas das alterações nesta edição, transformadas antes da gravação", "abusefilter-edit-builder-vars-addedlines-pst": "Linhas adicionadas na edição, transformadas antes da gravação", - "abusefilter-edit-builder-vars-new-text-stripped": "Nova página de texto, sem qualquer elemento de formatação", + "abusefilter-edit-builder-vars-new-text": "Nova página de texto, sem qualquer elemento de formatação", "abusefilter-edit-builder-vars-new-html": "Fonte HTML analisada, da nova revisão", "abusefilter-edit-builder-vars-restrictions-edit": "Nível de proteção de edição da página", "abusefilter-edit-builder-vars-restrictions-move": "Nível de proteção de movimentação da página", @@ -394,10 +424,10 @@ "abusefilter-edit-builder-vars-movedto-restrictions-move": "Nível de proteção de movimentações da página de destino da movimentação", "abusefilter-edit-builder-vars-movedto-restrictions-create": "Proteção de criação da página de destino da movimentação", "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Proteção de carregamento do ficheiro de destino da movimentação", - "abusefilter-edit-builder-vars-old-text-stripped": "Texto anterior da página, sem a formatação", + "abusefilter-edit-builder-vars-old-text": "Texto anterior da página, sem formatação (já não é utilizado)", "abusefilter-edit-builder-vars-old-links": "Hiperligações na página, antes da edição", "abusefilter-edit-builder-vars-old-html": "Texto wiki anterior da página, convertido para HTML (já não é usado)", - "abusefilter-edit-builder-vars-minor-edit": "Se a edição está marcada ou não como menor", + "abusefilter-edit-builder-vars-minor-edit": "Se a edição está marcada ou não como menor (já não é utilizado)", "abusefilter-edit-builder-vars-file-sha1": "Resumo criptográfico (<i>hash</i>) SHA1 do conteúdo do ficheiro", "abusefilter-edit-builder-vars-file-size": "Tamanho do ficheiro em bytes", "abusefilter-edit-builder-vars-file-mime": "Tipo MIME do ficheiro", @@ -405,6 +435,8 @@ "abusefilter-edit-builder-vars-file-width": "Largura do ficheiro em píxeis", "abusefilter-edit-builder-vars-file-height": "Altura do ficheiro em píxeis", "abusefilter-edit-builder-vars-file-bits-per-channel": "Bits por canal de cor do ficheiro", + "abusefilter-edit-builder-vars-wiki-name": "Nome da base de dados da wiki", + "abusefilter-edit-builder-vars-wiki-language": "Código de língua da wiki", "abusefilter-filter-log": "Modificações recentes de filtros", "abusefilter-history": "Histórico de modificações do Filtro de Abusos #$1", "abusefilter-history-foruser": "Modificações por $1", @@ -438,13 +470,16 @@ "abusefilter-exception-dividebyzero": "Tentativa ilegal de dividir $2 por zero, na posição $1.", "abusefilter-exception-unrecognisedvar": "Variável não reconhecida $2, na posição $1", "abusefilter-exception-notenoughargs": "Argumentos insuficientes para a função $2, na posição $1.\nEsperava-se $3 {{PLURAL:$3|argumento|argumentos}}, obteve-se $4", - "abusefilter-exception-regexfailure": "Erro na expressão regular \"$3\", na posição $1: \"$2\"", - "abusefilter-exception-overridebuiltin": "Sobreposição ilegal da variável integrada \"$2\", na posição $1.", + "abusefilter-exception-toomanyargs": "Foram fornecidos demasiados argumentos à função $2 chamada no carácter $1.\nEra esperado um máximo de $3 {{PLURAL:$3|argumento|argumentos}}; foram fornecidos $4", + "abusefilter-exception-regexfailure": "Erro na expressão regular \"$2\", na posição $1.", + "abusefilter-exception-overridebuiltin": "Sobreposição ilegal do identificador integrado \"$2\", na posição $1.", "abusefilter-exception-outofbounds": "Foi solicitada a entrada $2 que não existe na matriz (tamanho da matriz = $3) na posição $1.", + "abusefilter-exception-negativeindex": "Não são permitidos índices negativos em matrizes. Foi detetado o índice \"$2\" na posição $1.", "abusefilter-exception-notarray": "Foi solicitada uma entrada de matriz a uma não matriz, na posição $1.", "abusefilter-exception-unclosedcomment": "Comentário por fechar, no carácter $1.", "abusefilter-exception-invalidiprange": "Foi fornecida uma gama IP inválida \"$2\" no carácter $1.", "abusefilter-exception-disabledvar": "A variável $2 na posição $1 deixou de ser usada.", + "abusefilter-exception-variablevariable": "set e set_var esperam que o primeiro argumento seja um literal na forma de texto, encontrado no carácter $1.", "abusefilter-action-tag": "Etiquetar", "abusefilter-action-throttle": "Limitador", "abusefilter-action-warn": "Avisar", @@ -507,15 +542,16 @@ "abusefilter-examine-noresults": "Não foram encontrados resultados para os parâmetros de pesquisa fornecidos.", "abusefilter-topnav": "'''Navegação no Filtro de Abusos'''", "abusefilter-topnav-home": "Início", + "abusefilter-topnav-recentchanges": "Modificações recentes de filtros", "abusefilter-topnav-test": "Teste em bloco", "abusefilter-topnav-examine": "Examinar edições passadas", "abusefilter-topnav-log": "Registo de Abusos", "abusefilter-topnav-tools": "Ferramentas de depuração", - "abusefilter-topnav-import": "Importar filtro", "abusefilter-log-name": "Registo de filtragens de abusos", "abusefilter-log-header": "Este registo mostra um resumo das alterações efetuadas a filtros.\nPara todos os detalhes, ver [[Special:AbuseFilter/history|a lista]] de alterações recentes a filtros.", "abusefilter-logentry-create": "$1 {{GENDER:$2|criou}} $4 ($5)", "abusefilter-logentry-modify": "$1 {{GENDER:$2|modificou}} $4 ($5)", + "abusefilter-log-invalid-filter": "Alguns dos identificadores de filtro especificados são inválidos.", "abusefilter-log-noresults": "Não foram encontrados resultados.", "abusefilter-diff-title": "Diferenças entre versões", "abusefilter-diff-item": "Entrada", @@ -528,11 +564,12 @@ "abusefilter-diff-next": "Alteração recente", "abusefilter-import-intro": "Pode usar esta interface para importar filtros de outras wikis.\nNa wiki de origem, clique \"{{int:abusefilter-edit-export}}\", sob \"{{int:abusefilter-edit-tools}}\" na interface de edição.\nCopie da caixa de texto que aparece, coloque nesta caixa de texto e depois clique \"{{int:abusefilter-import-submit}}\".", "abusefilter-import-submit": "Importar dados", + "abusefilter-import-invalid-data": "Os dados que tentou importar não são válidos", "abusefilter-group-default": "Padrão", "abusefilter-http-error": "Ocorreu um erro HTTP: $1.", - "abusefilter-view-private-submit": "Ver detalhes privados", - "abusefilter-view-private": "Ver detalhes privados", - "abusefilter-view-private-reason": "Motivo do acesso aos detalhes privados:", + "abusefilter-view-privatedetails-submit": "Ver detalhes privados", + "abusefilter-view-privatedetails-legend": "Ver detalhes privados", + "abusefilter-view-privatedetails-reason": "Motivo para aceder aos detalhes privados:", "abusefilter-log-details-id": "Identificador do registo", "abusefilter-invalid-request": "Pedido inválido! Deve aceder aos detalhes privados do registo através do formulário em [[Special:AbuseLog/$1]] e fornecer um motivo.", "abusefilter-invalid-request-noid": "Pedido inválido! Deve aceder aos detalhes privados do registo através do formulário na página dos detalhes do registo de abusos e fornecer um motivo.", diff --git a/AbuseFilter/i18n/qqq.json b/AbuseFilter/i18n/qqq.json index 69ac7e4c..bea69484 100644 --- a/AbuseFilter/i18n/qqq.json +++ b/AbuseFilter/i18n/qqq.json @@ -1,9 +1,14 @@ { "@metadata": { "authors": [ + "Amire80", + "Ankam", "Aotake", + "BadDog", + "Bdijkstra", "Bennylin", "ChrisiPK", + "Daimona Eaytoy", "Darth Kule", "EugeneZelenko", "Fryed-peach", @@ -14,12 +19,18 @@ "Krenair", "Krinkle", "Kwj2772", + "Legoktm", "Lejonel", + "Liuxinyu970226", "Lloffiwr", "McDutchie", "Meno25", "Mormegil", + "MuratTheTurkish", "Nemo bis", + "Patriot Kur", + "Phjtieudoc", + "Pikne", "Praveenp", "Purodha", "Pxos", @@ -29,18 +40,12 @@ "The Evil IP address", "Translationista", "Umherirrender", - "Yekrats", - "Liuxinyu970226", - "Legoktm", - "Pikne", - "Amire80", - "Ankam", - "Daimona Eaytoy" + "Yekrats" ] }, "abusefilter-desc": "{{desc|name=Abuse Filter|url=https://www.mediawiki.org/wiki/Extension:AbuseFilter}}", - "abusefilter": "{{doc-special|AbuseFilter}}", - "abuselog": "{{doc-special|AbuseLog}}\n{{Identical|Abuse log}}", + "abusefilter": "Title of [[Special:AbuseFilter]]", + "abuselog": "Caption of [[Special:AbuseLog]]", "abusefilter-intro": "Introduction text for the list of filter rules.", "abusefilter-mustviewprivateoredit": "\"No access\" message shown when a user does not have access rights.", "abusefilter-warning": "A warning message shown when a user tries to save an edit which matches some abuse filter rule. Parameters:\n* $1 is a short description of the abuse filter rule which triggered this action\n* $2 is the filter id", @@ -51,13 +56,14 @@ "abusefilter-blocker": "Username of reserved user for abuse filter actions.", "abusefilter-blockreason": "Message given to user because of a triggered filter. Parameters:\n* $1 is a filter description\n* $2 is the filter id", "abusefilter-degroupreason": "Used as log entry when removal of the user from all privileged groups performed by Abuse filter. Parameters:\n* $1 is the filter description (reason)\n* $2 is the filter id", + "abusefilter-blockautopromotereason": "Used as log entry when delaying the autopromotion of a user. Parameters:\n* $1 is the filter description (reason)\n* $2 is the filter id", "abusefilter-accountreserved": "Message given when trying to register a reserved account name for AbuseFilter actions.", "right-abusefilter-modify": "{{doc-right|abusefilter-modify}}", "right-abusefilter-view": "{{doc-right|abusefilter-view}}", "right-abusefilter-log": "{{doc-right|abusefilter-log}}", "right-abusefilter-log-detail": "{{doc-right|abusefilter-log-detail}}", - "right-abusefilter-private": "{{doc-right|abusefilter-private}}", - "right-abusefilter-private-log": "{{doc-right|abusefilter-private-log}}", + "right-abusefilter-privatedetails": "{{doc-right|abusefilter-privatedetails}}", + "right-abusefilter-privatedetails-log": "{{doc-right|abusefilter-privatedetails-log}}", "right-abusefilter-modify-restricted": "{{doc-right|abusefilter-modify-restricted}}", "right-abusefilter-revert": "{{doc-right|abusefilter-revert}}", "right-abusefilter-view-private": "{{doc-right|abusefilter-view-private}}", @@ -69,17 +75,23 @@ "action-abusefilter-view": "{{doc-action|abusefilter-view}}", "action-abusefilter-log": "{{doc-action|abusefilter-log}}", "action-abusefilter-log-detail": "{{doc-action|abusefilter-log-detail}}", - "action-abusefilter-private": "{{doc-action|abusefilter-private}}", - "action-abusefilter-private-log": "{{doc-action|abusefilter-private-log}}", + "action-abusefilter-privatedetails": "{{doc-action|abusefilter-privatedetails}}", + "action-abusefilter-privatedetails-log": "{{doc-action|abusefilter-privatedetails-log}}", "action-abusefilter-modify-restricted": "{{doc-action|abusefilter-modify-restricted}}", "action-abusefilter-revert": "{{doc-action|abusefilter-revert}}", "action-abusefilter-view-private": "{{doc-action|abusefilter-view-private}}", "action-abusefilter-log-private": "{{doc-action|abusefilter-log-private}}", - "abusefilter-log": "Caption of [[Special:AbuseLog]]", + "action-abusefilter-hide-log": "{{doc-action|abusefilter-hide-log}}", + "action-abusefilter-hidden-log": "{{doc-action|abusefilter-hidden-log}}", + "action-abusefilter-modify-global": "{{doc-action|abusefilter-modify-global}}", "abusefilter-log-summary": "This message is displayed at the top of the log overview page for extension AbuseFilter.", "abusefilter-log-search": "Caption of a fieldset for filter definition on [[Special:AbuseLog]]", "abusefilter-log-search-user": "Field label in abuse filter log page.\n{{Identical|User}}", + "abusefilter-log-search-group": "Field label in abuse filter log page.", + "abusefilter-log-search-group-any": "Option allowing to find entries from any group in abuse log.\n{{Identical|Any}}", "abusefilter-log-search-filter": "Field label in abuse filter log page.", + "abusefilter-log-search-filter-help": "Help text, see {{msg-mw|abusefilter-log-search-filter}}. Parameters:\n* $1 - The prefix used by global filters.\n\nSee also {{msg-mw|abusefilter-log-search-filter-help-central}}", + "abusefilter-log-search-filter-help-central": "Help text, see {{msg-mw|abusefilter-log-search-filter}}.\n\nSee also {{msg-mw|abusefilter-log-search-filter-help}}", "abusefilter-log-search-title": "Field label in abuse filter log page.\n{{Identical|Title}}", "abusefilter-log-search-wiki": "Label for text field that allows the user to limit search results to a specific wiki, by name.\n{{Identical|Wiki}}", "abusefilter-log-search-impact": "Label for options allowing to filter abuse log by whether the action was actually saved.\n{{Identical|Impact}}", @@ -108,19 +120,21 @@ "abusefilter-log-details-var": "Caption of a column on a detail view of [[Special:AbuseLog]]\n{{Identical|Variable}}", "abusefilter-log-details-val": "Caption of a column on a detail view of [[Special:AbuseLog]]\n{{Identical|Value}}", "abusefilter-log-details-vars": "Caption on a detail view of [[Special:AbuseLog]]", - "abusefilter-log-details-private": "Header for private log details.", + "abusefilter-log-details-privatedetails": "Header for private log details.", "abusefilter-log-details-ip": "Row label in private log details.", "abusefilter-log-details-checkuser": "Text to use as link to [[Special:Checkuser]] for the given IP.\n{{Identical|Check user}}", "abusefilter-log-noactions": "Text displayed in Special:AbuseLog when a rule was triggered, but no action was taken.\n{{Identical|None}}", + "abusefilter-log-noactions-filter": "Text displayed in the dropdown menu on Special:AbuseLog when a user tries fo filter the logs for those where a rule was triggered, but no action was taken.\n{{Identical|None}}", "abusefilter-log-details-diff": "Header for differences between two edits in log details.", "abusefilter-log-linkoncontribs": "Link text added on [[Special:Contributions]] and other relevant special pages.\n{{Identical|Abuse log}}", "abusefilter-log-linkoncontribs-text": "Title for link added on [[Special:Contributions]] and other relevant special pages. Parameters:\n* $1 is the target user name used for GENDER.", "abusefilter-log-linkonhistory": "Link text added to the subtitle of the revision history page.", - "abusefilter-log-linkonhistory-text": "Title for link added to the subtitle of the revision history page.", - "abusefilter-log-hidden": "Text for a hidden log entry.", + "abusefilter-log-linkonhistory-text": "Tooltip for the link added to the subtitle of the revision history page.", + "abusefilter-log-linkonundelete": "Link text added to the subtitle of the undelete page.", + "abusefilter-log-linkonundelete-text": "Title for link added to the subtitle of the undelete page.", "abusefilter-log-hidden-implicit": "Explanatory text to be shown beside an abuse filter log entry if it cannot be viewed due to its corresponding revision being hidden", "abusefilter-log-cannot-see-details": "Message shown instead of log row details for users without permissions to see them.", - "abusefilter-log-cannot-see-private-details": "Message shown instead of log row private details for users without permissions to see them.", + "abusefilter-log-cannot-see-privatedetails": "Message shown instead of log row private details for users without permissions to see them.", "abusefilter-log-nonexistent": "Message shown instead of log row details when the provided log ID does not exist.", "abusefilter-log-details-hidden": "Message shown instead of log row details when those are hidden.", "abusefilter-log-details-hidden-implicit": "Message shown instead of log row details when their associated revision is hidden.", @@ -138,9 +152,12 @@ "log-action-filter-abusefilter-create": "{{doc-log-action-filter-action|abusefilter|create}}", "log-action-filter-abusefilter-modify": "{{doc-log-action-filter-action|abusefilter|modify}}", "log-action-filter-suppress-abuselog": "{{doc-log-action-filter-action|suppress|abuselog}}", + "log-action-filter-rights-blockautopromote": "{{doc-log-action-filter-action|rights|blockautopromote}}", + "log-action-filter-rights-restoreautopromote": "{{doc-log-action-filter-action|rights|restoreautopromote}}", "logentry-abusefilterprivatedetails-access": "This message is for a log entry. Parameters:\n* $1 User who accessed the private logs\n* $2 User who accessed the private logs (used for gender)\n* $3 The log entry of which private details were accessed", + "logentry-rights-blockautopromote": "Message used in rights log entries when AbuseFilter delayed the autopromotion of a user. Parameters:\n* $1 The filter user\n* $2 Same as $1 but for gender support\n* $3 User whose autopromotion was delayed\n* $4 Same user as $3, but used for gender\n*$5 The period for which autopromotion has been blocked", + "logentry-rights-restoreautopromote": "Message used in rights log entries when autopromotion capability of a user. Parameters:\n* $1 The user who restored the rights\n* $2 Same as $1 but for gender support\n* $3 User whose autopromotion status was restored\n* $4 Same user as $3, but used for gender", "abusefilterprivatedetails-log-name": "Log name", - "abusefilter-management": "Title of [[Special:AbuseFilter]]", "abusefilter-list": "Used as HTML <code><nowiki><h2></nowiki></code> heading.\n\nFollowed by the fieldset label {{msg-mw|Abusefilter-list-options}}.", "abusefilter-list-id": "Column header in abuse filter overview for the filter identifier.\n{{Identical|Filter ID}}", "abusefilter-list-pattern": "Column header in abuse filter overview for the filter pattern.\n{{Identical|Pattern}}", @@ -161,7 +178,8 @@ "abusefilter-disabled": "Abuse filter status.\n{{Identical|Disabled}}", "abusefilter-throttled": "Abuse filter status where some actions have been automatically disabled. See {{msg-mw|abusefilter-edit-throttled-warning}}", "abusefilter-hitcount": "Indicates number of times an abuse filter was triggered. Parameters:\n* $1 is the number of hits.", - "abusefilter-new": "Link text for creating a new abuse filter.", + "abusefilter-new": "Button text for creating a new abuse filter.", + "abusefilter-import-button": "Used as link text in the navigation toolbar.\n\nThe link points to [[Special:AbuseLog]].", "abusefilter-return": "Link displayed when filtering abuse filters without results.", "abusefilter-status-global": "Abuse filter status. Means that it is active on all wikis in a farm.\n{{Identical|Global}}", "abusefilter-list-options": "Fieldset legend for abuse filter filter options.\n{{Identical|Options}}", @@ -175,21 +193,24 @@ "abusefilter-list-options-scope-all": "Radio button indicating that local and global rules should be shown", "abusefilter-list-options-further-options": "Field label in filter form.", "abusefilter-list-options-hidedisabled": "Checkbox label in filter form.", - "abusefilter-list-options-hideprivate": "Checkbox label in filter form.", + "abusefilter-list-options-hideprivate": "Checkbox label in filter form.\n\n(Filters marked as private can only be viewed by users with either the abusefilter-modify or abusefilter-view-private permission.)", "abusefilter-list-options-searchfield": "Field label in filter form.", "abusefilter-list-options-searchpattern": "Text input for search pattern", "abusefilter-list-options-searchoptions": "Field label in filter form.", "abusefilter-list-options-search-like": "Radio button label in filter form.", "abusefilter-list-options-search-rlike": "Radio button label in filter form. See [[w:en:regular expression]]", "abusefilter-list-options-search-irlike": "Radio button label in filter form. See [[w:en:regular expression]]", + "abusefilter-list-invalid-searchmode": "Error message text.", "abusefilter-list-regexerror": "Error message text.", "abusefilter-list-options-submit": "Submit button text in filter form to update a filtered list.\n{{Identical|Update}}", "abusefilter-tools-text": "Introduction test for abuse filter tools.", "abusefilter-tools-expr": "Fieldset legend for form to test a filter expression.", "abusefilter-tools-submitexpr": "Submit button label to test a filter expression.", + "abusefilter-tools-syntax-error": "Message error shown to the user when they try to evaluate an expression with a syntax error.", "abusefilter-tools-reautoconfirm": "Fieldset legend for a form to add a user to the autoconfirmed group again.", "abusefilter-tools-reautoconfirm-user": "Field label. See {{msg-mw|group-autoconfirmed}} for concept translation.\n{{Identical|User}}", "abusefilter-tools-reautoconfirm-submit": "Submit button text to add a user to the autoconfirmed user group. See {{msg-mw|group-autoconfirmed}} for concept translation.", + "abusefilter-tools-restoreautopromote": "Message displayed in the logs when a user restores the autopromotion status of another user using the form on Special:AbuseFilter/tools.", "abusefilter-reautoconfirm-none": "{{doc-singularthey}}\nError text in case a user has not had their autoconfirmed status revoked. See {{msg-mw|group-autoconfirmed}} for concept translation.\n\nParameters:\n* $1 - the target user name used for GENDER", "abusefilter-reautoconfirm-notallowed": "Error text when trying to perform an action the user cannot perform. See {{msg-mw|group-autoconfirmed}} for concept translation.", "abusefilter-reautoconfirm-done": "See {{msg-mw|group-autoconfirmed}} for concept translation.\n* $1 is the target user name (optional, used for GENDER).", @@ -198,10 +219,10 @@ "abusefilter-edit-subtitle": "Page subtitle when editing an abuse filter. Parameters:\n* $1 - filter ID\n* $2 - (Unused) history ID\nSee also:\n* {{msg-mw|Abusefilter-edit-subtitle-new}} - if the filter ID is \"new\".", "abusefilter-edit-subtitle-new": "Page subtitle when creating an abuse filter. Parameters:\n* $1 - (Unused) filter ID\n* $2 - (Unused) history ID\nSee also:\n* {{msg-mw|Abusefilter-edit-subtitle}} - if editing the existing filter", "abusefilter-edit-token-not-match": "Warning displayed when saving the filter didn't succeed.", - "abusefilter-edit-oldwarning": "Warning displayed when editing an older version of a filter. Parameters:\n* $1 - (Unused) history ID\n* $2 - filter ID", + "abusefilter-edit-oldwarning": "Warning displayed when editing an older version of a filter. Parameters:\n* $1 - (Unused) history ID\n* $2 - filter ID\nSee also {{msg-mw|AbuseFilter-edit-oldwarning-view}}", + "abusefilter-edit-oldwarning-view": "Warning displayed when viewing an older version of a filter. Parameters:\n* $1 - (Unused) history ID\n* $2 - filter ID\nSee also {{msg-mw|AbuseFilter-edit-oldwarning}}", "abusefilter-edit-status-label": "Field label for abuse filter statistics.\n{{Identical|Statistics}}", - "abusefilter-edit-status": "Parameters:\n* $1 - number of actions\n* $2 - matched count\n* $3 - matched percentage", - "abusefilter-edit-status-profile": "Parameters:\n* $1 - number of actions\n* $2 - matched count\n* $3 - matched percentage\n* $4 - time (in milliseconds)\n* $5 - number of conditions", + "abusefilter-edit-status": "Parameters:\n* $1 - number of actions\n* $2 - matched count\n* $3 - matched percentage\n* $4 - time (in milliseconds)\n* $5 - number of conditions", "abusefilter-edit-throttled-warning": "Used as warning message when the filter is throttled and actions will not execute. Parameters:\n* $1 - is a string containing the actions that will not execute", "abusefilter-edit-new": "Field value in case an edited filter is new.", "abusefilter-edit-save": "Submit button text to save a filter.", @@ -234,19 +255,22 @@ "abusefilter-edit-throttle-count": "Field label for entering the number of allowed hits before triggering the filter consequences.", "abusefilter-edit-throttle-period": "Field label for entering a time period in seconds.\n{{Identical|Second}}", "abusefilter-edit-throttle-groups": "Field label for properties to group throttle counts by (for example IP address and username). Throttling is the concept of limiting occurrences of a certain action in a given time frame.", + "abusefilter-edit-throttle-groups-help": "Message for a help tooltip next to the throttle groups field. Parameters:\n* $1 - A help link, pointing to mediawiki.org.\n\nSee also:\n* {{msg-mw|abusefilter-edit-throttle-groups-help-text}}", + "abusefilter-edit-throttle-groups-help-text": "Text for a help link next to the throttle groups field.\n\nSee also:\n* {{msg-mw|abusefilter-edit-throttle-groups-help}}", "abusefilter-edit-throttle-hidden-placeholder": "Label for a textarea where users may insert throttling criteria.", "abusefilter-edit-throttle-placeholder": "Label for an input field where users may insert throttling criteria.", - "abusefilter-throttle-ip": "Throttle option.", + "abusefilter-throttle-ip": "Throttle option. The first letter is meant to be lowercase.", "abusefilter-throttle-user": "Throttle option.", - "abusefilter-throttle-range": "Throttle option.", + "abusefilter-throttle-range": "Throttle option. The first letter is meant to be lowercase.", "abusefilter-throttle-creationdate": "Throttle option.", "abusefilter-throttle-editcount": "Throttle option.", "abusefilter-throttle-site": "Throttle option.", "abusefilter-throttle-page": "Throttle option.", + "abusefilter-throttle-none": "Bogus throttle option, means that no options are enabled.", "abusefilter-throttle-details": "Description for Special:AbuseFilter/history with a detailed description for throttle action. Parameters:\n* $1 is the number of allowed actions, $2 is the time in seconds to use before resetting the action count, $3 is a list of throttled groups", "abusefilter-edit-warn-message": "Field label for dropdown list with system messages.", "abusefilter-edit-warn-other": "Option in dropdown menu to specify no item from the list should be used.\n\nSee also:\n* {{msg-mw|abusefilter-edit-disallow-other}}", - "abusefilter-edit-warn-other-label": "Field label for entering a system message key to use as warning text.\n\nSee also:\n* {{msg-mw|abusefilter-edit-disallow-other-label}}", + "abusefilter-edit-warn-other-label": "Tên trang của thông điệp khác:\n:''(không bao gồm tiền tố \"MediaWiki:\")''", "abusefilter-edit-warn-actions": "Field label for two action buttons in abuse filter editor. The button texts are {{msg-mw|abusefilter-edit-warn-preview}} and {{msg-mw|abusefilter-edit-warn-edit}}.\n{{Identical|Action}}", "abusefilter-edit-warn-preview": "Button text for actions relating to a warning message for an abuse filter.\n\nSee also:\n* {{msg-mw|Abusefilter-edit-warn-actions}}\n* {{msg-mw|Abusefilter-edit-warn-edit}}", "abusefilter-edit-warn-edit": "Button text for actions relating to a warning message for an abuse filter.\n\nSee also:\n* {{msg-mw|Abusefilter-edit-warn-actions}}\n* {{msg-mw|Abusefilter-edit-warn-preview}}\n* {{msg-mw|Abusefilter-edit-disallow-edit}}", @@ -282,10 +306,13 @@ "abusefilter-edit-export": "Link text for link to create filter. Accompanying label is {{msg-mw|abusefilter-edit-tools}}.\n\nUsed in:\n* {{msg-mw|Abusefilter-import-intro}}", "abusefilter-edit-syntaxok": "Status message for filter test.", "abusefilter-edit-syntaxerr": "Status message for filter test. Parameters:\n* $1 is the reported error.", + "abusefilter-edit-warn-leave": "Warning message shown when the user tries to leave the page with unsaved changes to a filter.", "abusefilter-edit-bad-tags": "Status message for filter test.", "abusefilter-edit-notallowed": "Error message when trying to modify a filter while not allowed.", "abusefilter-edit-notallowed-global": "Error message when trying to modify a global filter while not allowed.", - "abusefilter-edit-notallowed-global-custom-msg": "Error message when trying to add a custom warning message to a global filter, which is not allowed.", + "abusefilter-edit-notallowed-global-custom-msg": "Error message when trying to add a custom warning or disallow message to a global filter, which is not allowed.", + "abusefilter-edit-invalid-warn-message": "Error message when trying to provide an empty message for \"warn\" action.", + "abusefilter-edit-invalid-disallow-message": "Error message when trying to provide an empty message for \"disallow\" action.", "abusefilter-edit-invalid-throttlecount": "Error message when trying to provide an invalid action count for \"throttle\" action.", "abusefilter-edit-invalid-throttleperiod": "Error message when trying to provide an invalid time period for \"throttle\" action.", "abusefilter-edit-empty-throttlegroups": "Error message when trying to save a filter with \"throttle\" action enabled but no throttle groups selected.", @@ -321,7 +348,8 @@ "abusefilter-edit-builder-misc-contains": "{{doc-important|Do not translate \"contains\".}} Abuse filter syntax option in a dropdown from the group {{msg-mw|Abusefilter-edit-builder-group-misc}}.", "abusefilter-edit-builder-misc-stringlit": "{{doc-important|Do not \"translate\" quotation marks in brackets to any other styles (<code><nowiki>“”, ‘’, 「」, 『』, «», „“...</nowiki></code>).}}\nAbuse filter syntax option in a dropdown from the group {{msg-mw|Abusefilter-edit-builder-group-misc}}.", "abusefilter-edit-builder-misc-tern": "{{doc-important|Do not change \"X ? Y : Z\".}} Abuse filter syntax option in a dropdown from the group {{msg-mw|Abusefilter-edit-builder-group-misc}}.", - "abusefilter-edit-builder-misc-cond": "{{doc-important|Do not change \"if X then Y else Z\".}} Abuse filter syntax option in a dropdown from the group {{msg-mw|Abusefilter-edit-builder-group-misc}}.", + "abusefilter-edit-builder-misc-cond": "{{doc-important|Do not change \"if X then Y else Z end\".}} Abuse filter syntax option in a dropdown from the group {{msg-mw|Abusefilter-edit-builder-group-misc}}.", + "abusefilter-edit-builder-misc-cond-short": "{{doc-important|Do not change \"if X then Y end\".}} Abuse filter syntax option in a dropdown from the group {{msg-mw|Abusefilter-edit-builder-group-misc}}.", "abusefilter-edit-builder-group-funcs": "Group entry in dropdown menu.\n{{Identical|Function}}", "abusefilter-edit-builder-funcs-length": "{{doc-important|Do not translate \"'''length'''\".}} Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-funcs}}.", "abusefilter-edit-builder-funcs-lcase": "{{doc-important|Do not translate \"'''lcase'''\".}} Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-funcs}}.", @@ -392,12 +420,12 @@ "abusefilter-edit-builder-vars-all-links": "Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.", "abusefilter-edit-builder-vars-added-links": "Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.", "abusefilter-edit-builder-vars-removed-links": "Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.", - "abusefilter-edit-builder-vars-old-text": "Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.", - "abusefilter-edit-builder-vars-new-text": "Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.", + "abusefilter-edit-builder-vars-old-wikitext": "Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.", + "abusefilter-edit-builder-vars-new-wikitext": "Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.", "abusefilter-edit-builder-vars-new-pst": "Paraphrased: The output wikitext after pre-save transform is applied to new_wikitext. Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.", "abusefilter-edit-builder-vars-diff-pst": "Paraphrased: Edit diff of new_pst against old_wikitext. Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.", "abusefilter-edit-builder-vars-addedlines-pst": "Paraphrased: Added lines in edit_diff_pst. Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.", - "abusefilter-edit-builder-vars-new-text-stripped": "Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.", + "abusefilter-edit-builder-vars-new-text": "Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.", "abusefilter-edit-builder-vars-new-html": "Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.", "abusefilter-edit-builder-vars-restrictions-edit": "This variable contains the level of protection required to edit the page. (\"Edit\" here is not a verb, but an adjective, like \"Edit-related protection level\"). Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.\n\nSee also {{msg-mw|Abusefilter-edit-builder-vars-restrictions-create}}, {{msg-mw|Abusefilter-edit-builder-vars-restrictions-move}}, {{msg-mw|Abusefilter-edit-builder-vars-restrictions-upload}}.", "abusefilter-edit-builder-vars-restrictions-move": "This variable contains the level of protection required to move the page. (\"Move\" here is not a verb, but an adjective, like \"Move-related protection level\"). Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.\n\nSee also {{msg-mw|Abusefilter-edit-builder-vars-restrictions-edit}}, {{msg-mw|Abusefilter-edit-builder-vars-restrictions-create}}, {{msg-mw|Abusefilter-edit-builder-vars-restrictions-upload}}.", @@ -411,7 +439,7 @@ "abusefilter-edit-builder-vars-movedto-restrictions-move": "This variable contains the level of protection required to move the page that is to be moved. (\"Move\" here is not a verb, but an adjective, like \"Move-related protection level\"). Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.\n\nSee also {{msg-mw|Abusefilter-edit-builder-vars-movedto-restrictions-edit}}, {{msg-mw|Abusefilter-edit-builder-vars-movedto-restrictions-create}}, {{msg-mw|Abusefilter-edit-builder-vars-movedto-restrictions-upload}}.", "abusefilter-edit-builder-vars-movedto-restrictions-create": "This variable contains the level of protection required to create the page that is to be moved. (\"Create\" here is not a verb, but an adjective, like \"Create-related protection level\"). Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.\n\nSee also {{msg-mw|Abusefilter-edit-builder-vars-movedto-restrictions-edit}}, {{msg-mw|Abusefilter-edit-builder-vars-movedto-restrictions-move}}, {{msg-mw|Abusefilter-edit-builder-vars-movedto-restrictions-upload}}.", "abusefilter-edit-builder-vars-movedto-restrictions-upload": "This variable contains the level of protection required to upload the file that is to be moved. (\"Upload\" here is not a verb, but an adjective, like \"Upload-related protection level\"). Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.\n\nSee also {{msg-mw|Abusefilter-edit-builder-vars-movedto-restrictions-edit}}, {{msg-mw|Abusefilter-edit-builder-vars-movedto-restrictions-move}}, {{msg-mw|Abusefilter-edit-builder-vars-movedto-restrictions-create}}.", - "abusefilter-edit-builder-vars-old-text-stripped": "Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.", + "abusefilter-edit-builder-vars-old-text": "Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.", "abusefilter-edit-builder-vars-old-links": "Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.", "abusefilter-edit-builder-vars-old-html": "Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.", "abusefilter-edit-builder-vars-minor-edit": "Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.", @@ -422,6 +450,8 @@ "abusefilter-edit-builder-vars-file-width": "This variable contains the width of the file in pixels", "abusefilter-edit-builder-vars-file-height": "This variable contains the height of the file in pixels", "abusefilter-edit-builder-vars-file-bits-per-channel": "This variable contains the number of bits per color channel of the file", + "abusefilter-edit-builder-vars-wiki-name": "Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.", + "abusefilter-edit-builder-vars-wiki-language": "Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-vars}}.", "abusefilter-filter-log": "Used as page title.", "abusefilter-history": "Used as page title.\n\n\"Change history\" is the \"history of changes\"\n\nParameters:\n* $1 - filter ID\n\nIf the filter ID is not specified, {{msg-mw|Abusefilter-filter-log}} will be used.", "abusefilter-history-foruser": "Parameters:\n* $1 - a link to the changing user's page\n* $2 - (Optional) the plain text username", @@ -455,17 +485,20 @@ "abusefilter-exception-dividebyzero": "Error message from the abuse filter parser.\nParameters:\n* $1 - Position in the string\n* $2 - AFPData (integer or float?)", "abusefilter-exception-unrecognisedvar": "Error message from the abuse filter parser. Parameters:\n* $1 - Position in the string\n* $2 - Unrecognized variable", "abusefilter-exception-notenoughargs": "Error message from the abuse filter parser. Parameters:\n* $1 - position in the string (numeral)\n* $2 - a function name\n* $3 - the number of expected arguments\n* $4 - the number of passed arguments (also supports PLURAL)", + "abusefilter-exception-toomanyargs": "Error message from the abuse filter parser. Parameters:\n* $1 - position in the string (numeral)\n* $2 - a function name\n* $3 - the number of expected arguments\n* $4 - the number of passed arguments (also supports PLURAL)", "abusefilter-exception-regexfailure": "Error message from the abuse filter parser. Parameters:\n* $1 - Position in the string\n* $2 - Regular expression", - "abusefilter-exception-overridebuiltin": "Error message from the abuse filter parser. Parameters:\n* $1 - Position in the string\n* $2 - Built-in variable", + "abusefilter-exception-overridebuiltin": "Error message from the abuse filter parser. Parameters:\n* $1 - Position in the string\n* $2 - Built-in identifier", "abusefilter-exception-outofbounds": "Error message from the abuse filter parser. Parameters:\n* $1 - Position in the string\n* $2 - Index\n* $3 - Number of items in array", + "abusefilter-exception-negativeindex": "Error message from the abuse filter parser. Parameters:\n* $1 - Position in the string\n* $2 - Index", "abusefilter-exception-notarray": "Error message from the abuse filter parser. Parameters:\n* $1 - Position in the string", "abusefilter-exception-unclosedcomment": "Error message from the abuse filter parser. Parameters:\n* $1 - Position in the string", "abusefilter-exception-invalidiprange": "Error message from the abuse filter parser. Parameters:\n* $1 - Position in the string\n* $2 - String provided as an argument to a function", "abusefilter-exception-disabledvar": "Error message from the abuse filter parser. Parameters:\n* $1 - Position in the string\n* $2 - Name of the disabled variable", + "abusefilter-exception-variablevariable": "{{doc-important|Do not translate \"'''set'''\" and \"'''set_var'''\".}} Error message from the abuse filter parser. Parameters:\n* $1 - Position in the string", "abusefilter-action-tag": "{{doc-abusefilter-action}}\n\nThe edit or change can be 'tagged' with a particular tag, which will be shown on Recent Changes, contributions, logs, new pages, history, and everywhere else. \n\nThis is a verb in the imperative form.\n\n{{Identical|Tag}}", "abusefilter-action-throttle": "{{doc-abusefilter-action}}", "abusefilter-action-warn": "{{doc-abusefilter-action}}", - "abusefilter-action-blockautopromote": "{{doc-abusefilter-action}}\n\n'''Revoking auto-promoted groups'''\n\nTo '''block autopromote''' means that actions matching the filter will cause the user in question to be barred from receiving any extra groups from $wgAutoPromote for a period ranging from 3 to 7 days (random). \nAdditional information available: https://www.mediawiki.org/wiki/Extension:AbuseFilter/Actions", + "abusefilter-action-blockautopromote": "{{doc-abusefilter-action}}\n\n'''Revoking auto-promoted groups'''\n\nTo '''block autopromote''' means that actions matching the filter will cause the user in question to be barred from receiving any extra groups from $wgAutoPromote for 5 days. \nAdditional information available: https://www.mediawiki.org/wiki/Extension:AbuseFilter/Actions", "abusefilter-action-block": "{{doc-abusefilter-action}}\n\nUsers matching the filter will be blocked indefinitely, with a descriptive block summary indicating the rule that was triggered.\n\nThis is a verb.\n{{Identical|Block}}", "abusefilter-action-degroup": "{{doc-abusefilter-action}}\n\n'''Removing from privileged groups'''\n\nUsers matching the filter will be '''removed from all privileged groups''' (sysop, bureaucrat, etc). A descriptive summary will be used, detailing the rule that was triggered. \nAdditional information: https://www.mediawiki.org/wiki/Extension:AbuseFilter/Actions", "abusefilter-action-rangeblock": "{{doc-abusefilter-action}}\n\n'''Range-block'''\n\nSomewhat of a 'nuclear option', the entire /16 range from which the rule was triggered will be blocked for 24 hours.\n\nThis is a verb in the imperative form.", @@ -512,7 +545,7 @@ "abusefilter-examine-diff": "Used somewhere on [[Special:AbuseFilter/examine]]", "abusefilter-examine-user": "{{Identical|User}}", "abusefilter-examine-title": "{{Identical|Page title}}", - "abusefilter-examine-submit": "{{Identical|Search}}", + "abusefilter-examine-submit": "Used as submit button on [[Special:AbuseFilter/examine]]", "abusefilter-examine-vars": "Used as header on [[Special:AbuseFilter/examine]]", "abusefilter-examine-test": "Used as header on [[Special:AbuseFilter/examine]]", "abusefilter-examine-test-button": "Used as button text on [[Special:AbuseFilter/examine]]", @@ -524,15 +557,16 @@ "abusefilter-examine-noresults": "Used as warning on [[Special:AbuseFilter/examine]]", "abusefilter-topnav": "Used as header for navigation links which have the following link texts:\n* {{msg-mw|Abusefilter-topnav-home}}\n* {{msg-mw|Abusefilter-topnav-test}}\n* {{msg-mw|Abusefilter-topnav-examine}}\n* {{msg-mw|Abusefilter-topnav-log}}\n* {{msg-mw|Abusefilter-topnav-tools}}\n* {{msg-mw|Abusefilter-topnav-import}}", "abusefilter-topnav-home": "Used as link text. The link points to [[Special:AbuseFilter]].\n{{Identical|Home}}", + "abusefilter-topnav-recentchanges": "Used as link text in the navigation toolbar. The link points to [[Special:AbuseFilter/history]].\nSee {{msg-mw|abusefilter-filter-log}}.", "abusefilter-topnav-test": "Used as link text in the navigation toolbar.", "abusefilter-topnav-examine": "Used as link text in the navigation toolbar.\n\nThe link points to [[Special:AbuseFilter/examine]].", "abusefilter-topnav-log": "Used as link text in the navigation toolbar.\n\nThe link points to [[Special:AbuseFilter/history]].\n{{Identical|Abuse log}}", "abusefilter-topnav-tools": "Used as link text in the navigation toolbar.", - "abusefilter-topnav-import": "Used as link text in the navigation toolbar.\n\nThe link points to [[Special:AbuseLog]].", "abusefilter-log-name": "{{doc-logpage}}", "abusefilter-log-header": "Used as description on [[Special:Log/abusefilter]]", "abusefilter-logentry-create": "Parameters:\n* $1 - a link to a user page with a user name as link text, followed by a series of related links\n* $2 - raw username, for GENDER support\n* $3 - (unused)\n* $4 - text {{msg-mw|abusefilter-log-detailedentry-local}} linked to the filter created\n* $5 - text {{msg-mw|abusefilter-log-detailslink}} linked to the filter change details\n{{Identical|Created}}", "abusefilter-logentry-modify": "Parameters:\n* $1 - a link to a user page with a user name as link text, followed by a series of related links\n* $2 - raw username, for GENDER support\n* $3 - (unused)\n* $4 - text {{msg-mw|abusefilter-log-detailedentry-local}} linked to the modified filter\n* $5 - text {{msg-mw|abusefilter-log-detailslink}} linked to the filter change details", + "abusefilter-log-invalid-filter": "Warning message shown above search results in the AbuseLog.", "abusefilter-log-noresults": "{{Identical|No result}}", "abusefilter-diff-title": "Similar to {{msg-mw|Difference}}", "abusefilter-diff-item": "{{Identical|Item}}", @@ -545,11 +579,12 @@ "abusefilter-diff-next": "Link to the diff view for the next change to this filter.\n\nSee also:\n* {{msg-mw|Abusefilter-diff-prev}}\n* {{msg-mw|Previousdiff}} and {{msg-mw|Nextdiff}}", "abusefilter-import-intro": "{{doc-important|Do not translate <code><nowiki>{{int:abusefilter-edit-export}}</nowiki></code>, <code><nowiki>{{int:abusefilter-tools-subtitle}}</nowiki></code>, and <code><nowiki>{{int:abusefilter-import-submit}}</nowiki></code> unless you absolute must substitute any of them.}}\n\nRefers to:\n* {{msg-mw|Abusefilter-edit-export}}\n* {{msg-mw|Abusefilter-edit-tools}}\n* {{msg-mw|Abusefilter-import-submit}}", "abusefilter-import-submit": "Used as label for the Submit button.\n\nPreceded by the textarea.\n\nUsed in:\n* {{msg-mw|Abusefilter-import-intro}}.", + "abusefilter-import-invalid-data": "Error message shown when provided data is invalid.", "abusefilter-group-default": "The name for the default filter group. Most filters will be in this group.\n{{Identical|Default}}", "abusefilter-http-error": "Error message for HTTP requests. Parameters:\n* $1 - HTTP response code.", - "abusefilter-view-private-submit": "Submit button label for viewing private details of an abuse log", - "abusefilter-view-private": "Legend for abuse filter log entry private details form.", - "abusefilter-view-private-reason": "Label for the textbox where the user enters the reason they are accessing private log details.", + "abusefilter-view-privatedetails-submit": "Submit button label for viewing private details of an abuse log", + "abusefilter-view-privatedetails-legend": "Legend for abuse filter log entry private details form.", + "abusefilter-view-privatedetails-reason": "Label for the textbox where the user enters the reason they are accessing private log details.", "abusefilter-log-details-id": "Row label in private log details.", "abusefilter-invalid-request": "Warning shown when accessing the private details page without submitting the form properly. Parameters:\n* $1 is the ID of the log requested.", "abusefilter-invalid-request-noid": "Warning shown when accessing the private details page without a log ID parameter.", diff --git a/AbuseFilter/i18n/qu.json b/AbuseFilter/i18n/qu.json index f46c50e4..36d9b880 100644 --- a/AbuseFilter/i18n/qu.json +++ b/AbuseFilter/i18n/qu.json @@ -4,11 +4,9 @@ "AlimanRuna" ] }, - "abusefilter": "Millay ruray ch'illchina churana", "abuselog": "Millay ruray hallch'a", "abusefilter-blocker": "Millay ruray ch'illchina", "action-abusefilter-log": "Millay ruray hallch'ata qhaway", - "abusefilter-log": "Millay ruray hallch'a", "abusefilter-log-linkoncontribs": "millay ruray hallch'a", "abusefilter-log-linkoncontribs-text": "Kay ruraqpaq millay ruray hallch'a", "abusefilter-edit-warn-actions": "Ruraykuna:", diff --git a/AbuseFilter/i18n/rif.json b/AbuseFilter/i18n/rif.json index 0a513952..fe772d05 100644 --- a/AbuseFilter/i18n/rif.json +++ b/AbuseFilter/i18n/rif.json @@ -1,8 +1,8 @@ { "@metadata": { "authors": [ - "Jose77", - "Amara-Amaziɣ" + "Amara-Amaziɣ", + "Jose77" ] }, "abusefilter-log-search-submit": "ⵔⵣⵓ", diff --git a/AbuseFilter/i18n/rm.json b/AbuseFilter/i18n/rm.json index 4096bdb0..458e6887 100644 --- a/AbuseFilter/i18n/rm.json +++ b/AbuseFilter/i18n/rm.json @@ -5,7 +5,6 @@ ] }, "abuselog": "Protocol dal filter d'abus", - "abusefilter-log": "Protocol dal filter d'abus", "abusefilter-log-linkoncontribs": "protocol dal filter d'abus", "abusefilter-topnav-log": "Protocol dal filter d'abus", "abusefilter-log-name": "Protocol dal filter d'abus" diff --git a/AbuseFilter/i18n/ro.json b/AbuseFilter/i18n/ro.json index 467cae64..7c49107d 100644 --- a/AbuseFilter/i18n/ro.json +++ b/AbuseFilter/i18n/ro.json @@ -1,25 +1,31 @@ { "@metadata": { "authors": [ + "Andrei Stroe", + "Carcassonne93", "Cin", "Ervinutz", "Firilacroco", + "Fitoschido", + "GabiBil", "KlaudiuMihaila", + "Matma Rex", "Mihai", "Minisarm", "Misterr", + "NGC 54", "Rsocol", "Silviubogan", "Stelistcristi", "Strainu", - "Matma Rex" + "WebSourceContentRO" ] }, "abusefilter-desc": "Aplică euristici automate modificărilor.", - "abusefilter": "Configurare filtru de abuz", - "abuselog": "Jurnal abuzuri", + "abusefilter": "Administrare filtru abuz", + "abuselog": "Jurnal filtru abuz", "abusefilter-intro": "Bun venit la interfața de gestionare a filtrului de abuzuri.\nFiltrul de abuzuri este un mecanism software automat care aplică euristici automate tuturor acțiunilor.\nAceastă interfață afișează o listă de filtre definite și permite modificarea acestora.", - "abusefilter-warning": "'''Atenție:''' Această acțiune a fost identificată în mod automat ca fiind periculoasă.\nModificările neconstructive vor fi rapid înlăturate,\niar cele evident neconstructive și repetate vor avea ca efect blocarea contului sau adresei IP de la care vă conectați.\nDacă într-adevăr credeți că această acțiune este constructivă, o puteți retrimite pentru a o confirma.\nO descriere sumară a regulii abuzului care se potrivește acțiunii dumneavoastră este: $1", + "abusefilter-warning": "'''Atenție:''' Această acțiune a fost identificată în mod automat ca fiind periculoasă.\nModificările neconstructive vor fi rapid înlăturate, iar acțiunile evident neconstructive și repetate vor avea ca efect blocarea contului sau adresei IP de la care vă conectați.\nDacă într-adevăr credeți că această acțiune este constructivă, o puteți retrimite pentru a o confirma.\nO descriere sumară a regulii abuzului care se potrivește acțiunii dumneavoastră este: $1", "abusefilter-disallowed": "Această acțiune a fost identificată în mod automat ca fiind periculoasă, din acest motiv fiind refuzată.\nDacă într-adevăr credeți că acțiunea dumneavoastră a fost constructivă, vă rugăm să contactați un administrator și să-l informați despre ceea ce doriți să întreprindeți.\nO descriere sumară a regulii abuzului care se potrivește acțiunii dumneavoastră este: $1", "abusefilter-blocked-display": "Această acțiune a fost identificată în mod automat ca fiind periculoasă;\ndrept urmare ați fost împiedicat să o executați.\nÎn plus, pentru a proteja {{SITENAME}}, contul dumneavoastră și toate adresele IP asociate acestuia au fost blocate de la modificare.\nDacă blocarea este eronată, vă rugăm să contactați un administrator.\nO descriere sumară a regulii abuzului care se potrivește acțiunii dumneavoastră este: $1", "abusefilter-degrouped": "Această acțiune a fost identificată în mod automat ca fiind periculoasă.\nÎn consecință, acțiunea a fost refuzată și, din moment ce contul dumneavoastră pare a fi compromis, toate drepturile au fost revocate.\nDacă sunteți de părere că această sancțiune este eronată, vă rugăm să contactați un birocrat căruia să-i explicați cele întâmplate, drepturile dumneavoastră putând fi astfel restaurate.\nO descriere sumară a regulii abuzului care se potrivește acțiunii dumneavoastră este: $1", @@ -28,11 +34,12 @@ "abusefilter-blockreason": "Blocare automată efectuată de filtrul de abuz.\nDescrierea regulii aplicate: $1", "abusefilter-degroupreason": "Drepturi automat suspendate de către filtrul de abuz.\nDescrierea regulii: $1", "abusefilter-accountreserved": "Acest nume de cont este rezervat pentru a fi folosit de către filtrul abuz.", - "right-abusefilter-modify": "Modifică filtrele de abuz", + "right-abusefilter-modify": "Crează sau modifică filtrele de abuz", "right-abusefilter-view": "Vizualizează filtrele de abuz", "right-abusefilter-log": "Vizualizează jurnalul de abuzuri", "right-abusefilter-log-detail": "Vizualizează intrări detaliate în jurnalul de abuzuri", - "right-abusefilter-private": "Vizualizează datele private din jurnalul de abuzuri", + "right-abusefilter-privatedetails": "Vizualizează datele private din jurnalul de abuzuri", + "right-abusefilter-privatedetails-log": "Vizualizează jurnalul de acces la date private al filtrului de abuz", "right-abusefilter-modify-restricted": "Modifică filtrele de abuz cu acțiuni restricționate", "right-abusefilter-revert": "Revine asupra tuturor modificărilor corespunzătoare unui filtru de abuz dat", "right-abusefilter-view-private": "Vizualizează filtrele de abuz marcate ca private", @@ -44,25 +51,30 @@ "action-abusefilter-view": "vezi filtrele de abuzare", "action-abusefilter-log": "vezi jurnalul de abuzare", "action-abusefilter-log-detail": "vedeți înregistrările jurnalului cu abuzuri detaliate", - "action-abusefilter-private": "vedeți date private în jurnalul de abuzuri", + "action-abusefilter-privatedetails": "vedeți date private în jurnalul de abuzuri", "action-abusefilter-modify-restricted": "modificați filtrele de abuzare cu acțiuni restricționate", "action-abusefilter-revert": "anulați toate modificările de la filtru de abuzare", "action-abusefilter-view-private": "vezi filtrele de abuzare marcate ca private", - "abusefilter-log": "Jurnal filtru abuz", "abusefilter-log-summary": "Acest jurnal afișează o listă a tuturor acțiunilor capturate de către filtre.", "abusefilter-log-search": "Căutare jurnal abuz", "abusefilter-log-search-user": "Utilizator:", "abusefilter-log-search-filter": "ID-uri filtre (separate prin bare verticale):", "abusefilter-log-search-title": "Titlu:", "abusefilter-log-search-wiki": "Wiki:", + "abusefilter-log-search-impact": "Impact:", + "abusefilter-log-search-impact-all": "Toate acțiunile", "abusefilter-log-search-entries-label": "Vizibilitate:", "abusefilter-log-search-entries-all": "Toate intrările", "abusefilter-log-search-entries-hidden": "Doar intrările ascunse", "abusefilter-log-search-entries-visible": "Doar intrările vizibile", + "abusefilter-log-search-action-other": "Altceva", + "abusefilter-log-search-action-any": "Orice", + "abusefilter-log-search-action-taken-label": "Acțiunea luată:", + "abusefilter-log-search-action-taken-any": "Orice", "abusefilter-log-search-submit": "Caută", - "abusefilter-log-entry": "$1: $2 a declanșat un filtru de abuz, executând acțiunea „$3” asupra paginii $4.\nMăsura luată: $5;\nDescrierea filtrului: $6", - "abusefilter-log-entry-withdiff": "$1: $2 a declanșat un filtru de abuz, executând acțiunea „$3” asupra paginii $4.\nMăsura luată: $5;\nDescrierea filtrului: $6 ($7)", - "abusefilter-log-detailedentry-meta": "$1: $2 a declanșat $3, executând acțiunea „$4” asupra paginii $5.\nMăsura luată: $6;\nDescrierea filtrului: $7 ($8)", + "abusefilter-log-entry": "$1: $2 a declanșat un filtru de abuz, {{GENDER:$8|executând}} acțiunea „$3” asupra paginii $4.\nMăsura luată: $5;\nDescrierea filtrului: $6", + "abusefilter-log-entry-withdiff": "$1: $2 a {{GENDER:$8|declanșat}} un filtru de abuz, {{GENDER:$8|executând}} acțiunea „$3” asupra paginii $4.\nMăsura luată: $5;\nDescrierea filtrului: $6 ($7)", + "abusefilter-log-detailedentry-meta": "$1: $2 {{GENDER:$9|a declanșat}} $3, {{GENDER:$9|executând}} acțiunea „$4” asupra paginii $5.\nMăsura luată: $6;\nDescrierea filtrului: $7 ($8)", "abusefilter-log-detailedentry-global": "filtru global $1", "abusefilter-log-detailedentry-local": "filtrul $1", "abusefilter-log-detailslink": "detalii", @@ -72,23 +84,27 @@ "abusefilter-log-details-var": "Variabilă", "abusefilter-log-details-val": "Valoare", "abusefilter-log-details-vars": "Parametrii acțiunii", - "abusefilter-log-details-private": "Date private", + "abusefilter-log-details-privatedetails": "Date private", "abusefilter-log-details-ip": "Adresa IP de origine", + "abusefilter-log-details-checkuser": "Verifică utilizator", "abusefilter-log-noactions": "nimic", "abusefilter-log-details-diff": "Modificări făcute în modificare", "abusefilter-log-linkoncontribs": "jurnal de abuzare", - "abusefilter-log-linkoncontribs-text": "Jurnalul de abuzare pentru acest utilizator", - "abusefilter-log-hidden": "(intrare ascunsă)", + "abusefilter-log-linkoncontribs-text": "Jurnalul de abuzare pentru {{GENDER:$1|acest utilizator|această utilizatoare|acest utilizator}}", + "abusefilter-log-linkonhistory": "vezi jurnalul de abuzare", + "abusefilter-log-linkonundelete": "vezi jurnalul de abuzare", + "abusefilter-log-linkonundelete-text": "Afișează jurnalul de abuzare pentru această pagină", "abusefilter-log-hidden-implicit": "(ascuns, deoarece versiunea a fost ștearsă)", "abusefilter-log-cannot-see-details": "Nu aveți permisiunea de a vizualiza detalii despre această intrare.", "abusefilter-log-details-hidden": "Nu puteți vizualiza detaliile acestei intrări, deoarece acestea nu sunt oferite publicului.", + "abusefilter-log-details-hidden-implicit": "Nu puteți vizualiza detaliile acestei intrări, deoarece acestea nu sunt oferite publicului.", + "abusefilter-log-private-not-included": "Unul sau mai multe dintre ID-urile de filtrare pe care le-ați specificat sunt private. Deoarece nu aveți permisiunea de a vedea detalii despre filtrele private, aceste filtre nu au fost căutate.", "abusefilter-log-hide-legend": "Ascunde intrarea în jurnal", "abusefilter-log-hide-id": "ID-ul intrării în jurnal:", "abusefilter-log-hide-hidden": "Ascunde această intrare afișării publice", "abusefilter-log-hide-reason": "Motiv:", "abusefilter-log-hide-forbidden": "Nu aveți permisiunea să ascundeți intrările din jurnalul de abuzuri.", - "logentry-abusefilter-hit": "$1 a declanșat $4 prin efectuarea acțiunii „$5” la $3. Acțiuni întreprinse: $6 ($7)", - "abusefilter-management": "Administrare filtru abuz", + "logentry-abusefilter-hit": "$1 {{GENDER:$2|a declanșat}} $4 prin {{GENDER:$2|efectuarea}} acțiunii „$5” la $3. Acțiuni întreprinse: $6 ($7)", "abusefilter-list": "Toate filtrele", "abusefilter-list-id": "ID filtru", "abusefilter-list-status": "Statut", @@ -106,8 +122,10 @@ "abusefilter-enabled": "Activat", "abusefilter-deleted": "Șters", "abusefilter-disabled": "Dezactivat", + "abusefilter-throttled": "înăbușit", "abusefilter-hitcount": "$1 {{PLURAL:$1|potrivire|potriviri|de potriviri}}", "abusefilter-new": "Creează un filtru nou", + "abusefilter-import-button": "Importă filtru", "abusefilter-return": "Înapoi la gestionarea filtrului", "abusefilter-status-global": "Global", "abusefilter-list-options": "Opțiuni", @@ -120,6 +138,7 @@ "abusefilter-list-options-scope-global": "Doar reguli globale", "abusefilter-list-options-scope-all": "Reguli locale și globale", "abusefilter-list-options-hidedisabled": "Ascunde filtrele dezactivate", + "abusefilter-list-options-searchoptions": "Mod de căutare:", "abusefilter-list-options-submit": "Actualizează", "abusefilter-tools-text": "Aici sunt câteva unelte care pot fi utile în formularea și depanarea filtrelor abuz.", "abusefilter-tools-expr": "Expresii test", @@ -136,12 +155,14 @@ "abusefilter-edit-subtitle-new": "Se creează filtrul", "abusefilter-edit-oldwarning": "<strong>Modificați o versiune învechită a acestui filtru.\nStatisticile citate sunt pentru cea mai recentă versiune a filtrului.\nDacă salvați modificările dumneavoastră, veți suprascrie toate modificările efectuate după versiunea pe care o editați.</strong> •\n[[Special:AbuseFilter/history/$2|Înapoi la istoricul acestui filtru]].", "abusefilter-edit-status-label": "Statistici:", - "abusefilter-edit-status": "Din {{PLURAL:$1|ultima acțiune|ultimele $1 acțiuni| ultimele $1 de acțiuni}}, acest filtru a găsit $2 ($3%).", - "abusefilter-edit-status-profile": "Din {{PLURAL:$1|ultima acțiune|ultimele $1 acțiuni| ultimele $1 de acțiuni}}, acest filtru a găsit $2 ($3%).\nÎn medie, timpul său de rulare este de $4 ms și consumă $5 {{PLURAL:$5|condiție|condiții|de condiții}} ale limitei de condiții.", + "abusefilter-edit-status": "Din {{PLURAL:$1|ultima acțiune|ultimele $1 acțiuni| ultimele $1 de acțiuni}}, acest filtru a găsit $2 ($3%).\nÎn medie, timpul său de rulare este de $4 ms, și consumă $5 {{PLURAL:$5|condiție|condiții}} din limita de condiții", + "abusefilter-edit-throttled-warning": "'''Atenție:''' Acest filtru a fost marcat automat ca dăunător. Ca măsură de siguranță, următoarele acțiuni nu se vor executa ($1). Vă rugăm să revedeți și să [[mw:Extension:AbuseFilter/Conditions|optimizați]] condițiile pentru a înlătura această restricție", "abusefilter-edit-new": "Filtru nou", "abusefilter-edit-save": "Salvează filtru", "abusefilter-edit-id": "ID filtru:", + "abusefilter-edit-switch-editor": "Comută editor", "abusefilter-edit-description": "Descriere:\n:''(publică)''", + "abusefilter-edit-field-description": "descriere", "abusefilter-edit-group": "Grup de filtru:", "abusefilter-edit-flags": "Steaguri:", "abusefilter-edit-enabled": "Activează acest filtru", @@ -149,6 +170,7 @@ "abusefilter-edit-hidden": "Ascunde publicului detaliile acestui filtru", "abusefilter-edit-global": "Filtru global", "abusefilter-edit-rules": "Condiții:", + "abusefilter-edit-field-conditions": "condiții", "abusefilter-edit-notes": "Note:", "abusefilter-edit-lastmod": "Ultima modificare filtru:", "abusefilter-edit-lastmod-text": "$1 de $2", @@ -159,19 +181,41 @@ "abusefilter-edit-action-blockautopromote": "Revocă statutul autoconfirmat al utilizatorului", "abusefilter-edit-action-degroup": "Elimină utilizatorul din toate grupurile cu privilegii", "abusefilter-edit-action-block": "Blochează utilizatorul și/sau adresa IP la modificare", + "abusefilter-edit-action-blocktalk": "Blochează utilizatorul și/sau adresa IP de la editarea propriei pagini de discuție", "abusefilter-edit-action-throttle": "Declanșează acțiunile doar dacă utilizatorul a depășit limita impusă", - "abusefilter-edit-action-rangeblock": "Blochează intervalul de IP-uri /16 din care provine utilizatorul.", + "abusefilter-edit-action-rangeblock": "Blochează intervalul de IP-uri din care provine utilizatorul.", "abusefilter-edit-action-tag": "Marchează modificarea pentru revizuire ulterioară", "abusefilter-edit-throttle-count": "Număr de acțiuni permise:", - "abusefilter-edit-throttle-period": "Perioadă de timp:", - "abusefilter-edit-throttle-groups": "Grupează ?throttle? după:\n:''(una pe linie, despărțite prin virgule)''", + "abusefilter-edit-throttle-period": "Perioadă de timp (în secunde):", + "abusefilter-edit-throttle-groups": "Grupează limitările de viteză după:\n:''(una pe linie, despărțite prin virgule)''", + "abusefilter-edit-throttle-groups-help": "Vezi $1.", + "abusefilter-edit-throttle-groups-help-text": "documentația de la mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Separați cu virgule pentru a uni prin ȘI, ori prin sfârșituri de linie pentru a uni prin SAU", + "abusefilter-edit-throttle-placeholder": "Separați cu virgule pentru a uni prin ȘI, ori introduceți unul câte unul pentru a uni prin SAU", + "abusefilter-throttle-ip": "adresă IP", + "abusefilter-throttle-user": "cont de utilizator", + "abusefilter-throttle-range": "gamă /16", + "abusefilter-throttle-creationdate": "data creării contului", + "abusefilter-throttle-editcount": "numărul de editări", + "abusefilter-throttle-site": "întreg site-ul", + "abusefilter-throttle-page": "pagină", + "abusefilter-throttle-none": "(niciuna)", + "abusefilter-throttle-details": "Permite $1 {{PLURAL:$1|acțiune|acțiuni}} la fiecare {{PLURAL:$2|secundă|$2 secunde}}, limitează viteza în grup la: $3", "abusefilter-edit-warn-message": "Mesaj de sistem de utilizat pentru avertizare:", "abusefilter-edit-warn-other": "Alt mesaj", - "abusefilter-edit-warn-other-label": "Numele paginii unui alt mesaj:\n:''(fără prefix MediaWiki)''", + "abusefilter-edit-warn-other-label": "Numele paginii unui alt mesaj:\n:''(fără prefix „MediaWiki:”)''", "abusefilter-edit-warn-actions": "Acțiuni:", - "abusefilter-edit-warn-preview": "Previzualizați mesajul ales", + "abusefilter-edit-warn-preview": "Ascunde/afișează previzualizarea mesajului ales", "abusefilter-edit-warn-edit": "Creați/Editați mesajul selectat", - "abusefilter-edit-tag-tag": "[[Special:Tags|Marcaje]] de aplicat (unul pe linie):", + "abusefilter-edit-disallow-message": "Mesaj de sistem care trebuie utilizat pentru a nu permite:", + "abusefilter-edit-disallow-other": "Alt mesaj", + "abusefilter-edit-disallow-other-label": "Numele paginii unui alt mesaj: :(fără prefixul \"MediaWiki:\")", + "abusefilter-edit-disallow-actions": "Acțiuni:", + "abusefilter-edit-disallow-preview": "Afișați / Ascundeți previzualizarea mesajului selectat", + "abusefilter-edit-disallow-edit": "Creează/Editează mesajul selectat", + "abusefilter-edit-tag-tag": "[[Special:Tags|Marcaje]] de aplicat:", + "abusefilter-edit-tag-placeholder": "Adaugă taguri (unul câte unul sau separate prin virgulă)", + "abusefilter-edit-tag-hidden-placeholder": "Adaugă taguri (separate prin virgulă)", "abusefilter-edit-denied": "Este posibil să nu puteți vedea detaliile acestui filtru, deoarece a fost ascuns publicului.", "abusefilter-edit-main": "Parametrii filtrului", "abusefilter-edit-done-subtitle": "Filtru modificat", @@ -188,7 +232,7 @@ "abusefilter-edit-export": "Exportă acest filtru către un alt wiki", "abusefilter-edit-syntaxok": "Nici o eroare de sintaxă detectată.", "abusefilter-edit-syntaxerr": "Eroare de sintaxă detectată: $1", - "abusefilter-edit-bad-tags": "Una sau mai multe dintre etichetele pe care le-ați specificat nu este/sunt corectă/e.\nEtichetele trebuie să fie scurte și nu trebuie să conțină caractere speciale.", + "abusefilter-edit-bad-tags": "Una sau mai multe dintre etichetele pe care le-ați specificat nu este/sunt corectă/e.\nEtichetele trebuie să fie scurte, nu trebuie să conțină caractere speciale, și trebuie să nu fie rezervate de alte software-uri. Încercați să alegeți alt nume.", "abusefilter-edit-notallowed": "Nu aveți permisiunea de a crea sau modifica filtre de abuz", "abusefilter-edit-notallowed-global": "Nu vă sunt permise crearea sau modificarea filtrelor globale de abuz", "abusefilter-edit-notallowed-global-custom-msg": "Mesajele de avertizare personalizate nu pot fi folosite în filtrele globale", @@ -201,8 +245,8 @@ "abusefilter-edit-builder-op-arithmetic-modulo": "Modulo (%)", "abusefilter-edit-builder-op-arithmetic-pow": "Putere (**)", "abusefilter-edit-builder-group-op-comparison": "Operatori comparativi", - "abusefilter-edit-builder-op-comparison-equal": "Egal cu (==)", - "abusefilter-edit-builder-op-comparison-notequal": "Diferit de (!=)", + "abusefilter-edit-builder-op-comparison-equal": "Valoare egală cu (==)", + "abusefilter-edit-builder-op-comparison-notequal": "Valoare diferită de (!=)", "abusefilter-edit-builder-op-comparison-lt": "Mai mic decât (<)", "abusefilter-edit-builder-op-comparison-gt": "Mai mare decât (>)", "abusefilter-edit-builder-op-comparison-lte": "Mai mic sau egal cu (<=)", @@ -233,7 +277,7 @@ "abusefilter-edit-builder-funcs-rmwhitespace": "Elimină spațiile libere (rmwhitespace)", "abusefilter-edit-builder-funcs-rmspecials": "Elimină caracterele speciale (rmspecials)", "abusefilter-edit-builder-funcs-ip_in_range": "Este adresa IP în interval? (ip_in_range)", - "abusefilter-edit-builder-funcs-contains-any": "Verifică șirul pentru mai multe subșiruri (contains_any)", + "abusefilter-edit-builder-funcs-contains-any": "Verifică șirul pentru mai multe subșiruri în mod SAU. (contains_any)", "abusefilter-edit-builder-funcs-substr": "Subșir (substr)", "abusefilter-edit-builder-funcs-strpos": "Poziția subșirului în șir (strpos)", "abusefilter-edit-builder-funcs-str_replace": "Înlocuiește subșirul cu șirul (str_replace)", @@ -273,18 +317,18 @@ "abusefilter-edit-builder-vars-all-links": "Toate legăturile externe din textul nou", "abusefilter-edit-builder-vars-added-links": "Toate legăturile externe adăugate la modificare", "abusefilter-edit-builder-vars-removed-links": "Toate legăturile externe șterse la modificare", - "abusefilter-edit-builder-vars-old-text": "Textul wiki vechi, dinainte de modificare", - "abusefilter-edit-builder-vars-new-text": "Textul wiki nou, după modificare", - "abusefilter-edit-builder-vars-new-text-stripped": "Textul wiki nou, fără nici un marcaj", + "abusefilter-edit-builder-vars-old-wikitext": "Textul wiki vechi, dinainte de modificare", + "abusefilter-edit-builder-vars-new-wikitext": "Textul wiki nou, după modificare", + "abusefilter-edit-builder-vars-new-text": "Textul wiki nou, fără nici un marcaj", "abusefilter-edit-builder-vars-new-html": "Sursa HTML parsată a noii revizii", "abusefilter-edit-builder-vars-restrictions-edit": "Nivelul de protecție la modificare al paginii", "abusefilter-edit-builder-vars-restrictions-move": "Nivelul de protecție la redenumire al paginii", "abusefilter-edit-builder-vars-restrictions-create": "Protecția la creare a paginii", "abusefilter-edit-builder-vars-restrictions-upload": "Protecția la încărcare a fișierului", - "abusefilter-edit-builder-vars-old-text-stripped": "Textul vechi, fără nici un marcaj", + "abusefilter-edit-builder-vars-old-text": "Textul vechi, fără nici un marcaj (nu mai e folosit)", "abusefilter-edit-builder-vars-old-links": "Legăturile din pagină, înainte de modificare", - "abusefilter-edit-builder-vars-old-html": "Textul wiki vechi, parsat în HTML", - "abusefilter-edit-builder-vars-minor-edit": "Indiferent dacă modificarea este sau nu marcată ca minoră", + "abusefilter-edit-builder-vars-old-html": "Textul wiki vechi, parsat în HTML (nu mai este folosit)", + "abusefilter-edit-builder-vars-minor-edit": "Indiferent dacă modificarea este sau nu marcată ca minoră (nu mai este folosit)", "abusefilter-edit-builder-vars-file-sha1": "Hash-ul SHA1 al conținutului fișierului", "abusefilter-edit-builder-vars-file-size": "Dimensiunea fișierului în octeți", "abusefilter-edit-builder-vars-file-mime": "Tipul MIME al fișierului", @@ -318,11 +362,11 @@ "abusefilter-exception-unclosedstring": "Şirul de la poziția $1 este neînchis.", "abusefilter-exception-invalidoperator": "Operatorul „$2” invalid la caracterul $1.", "abusefilter-exception-unrecognisedtoken": "Jeton nerecunoscut „$2” la caracterul $1.", - "abusefilter-exception-noparams": "Nici un parametru trimis funcției \"$2\" la caracterul $1.", + "abusefilter-exception-noparams": "Nici un parametru trimis funcției \"$2\" la caracterul $1.\nSe așteaptă $3 {{PLURAL:$3|argument|argumente}}", "abusefilter-exception-dividebyzero": "Încercare ilegală de diviziune prin zero a lui $2 la caracterul $1.", "abusefilter-exception-unrecognisedvar": "Variabila $2 nerecunoscută la caracterul $1", "abusefilter-exception-notenoughargs": "Parametri insuficienți pentru funcția $2 invocată la caracterul $1.\nSe {{PLURAL:$3|aștepta un argument|așteptau $3 argumente}}, {{PLURAL:$4|s-a primit|s-au primit}} $4.", - "abusefilter-exception-regexfailure": "Eroare în expresia regulată „$3” la caracterul $1: „$2”", + "abusefilter-exception-regexfailure": "Eroare în expresia regulată „$2” la caracterul $1.", "abusefilter-exception-overridebuiltin": "Folosire interzisă a variabilei disponibilă implicit „$2” la caracterul $1.", "abusefilter-exception-outofbounds": "Se solicită elementul $2 inexistent în listă (mărimea listei = $3) la caracterul $1", "abusefilter-exception-notarray": "Se solicită un element al vectorului pentru ceva ce nu este vector la caracterul $1.", @@ -336,13 +380,14 @@ "abusefilter-action-disallow": "Nu permite", "abusefilter-revert-title": "Reveniți toate modificările făcute de filtrul $1", "abusefilter-revert-intro": "Acest formular vă permite să reveniți asupra tuturor modificărilor efectuate de filtrul de abuzuri datorită regulii $1.\nVă rugăm să folosiți această unealtă cu grijă.", - "abusefilter-revert-preview-item": "$1: $2 a făcut o $3 în $4.\nAcțiunile ce vor fi anulate: $5 ($6)", + "abusefilter-revert-preview-item": "$1: $2 {{GENDER:$7|a făcut}} o $3 în $4.\nAcțiunile ce vor fi anulate: $5 ($6)", "abusefilter-revert-search-legend": "Alegeți acțiunile filtrului de abuzare pentru a fi inversate", "abusefilter-revert-periodstart": "Perioadă de începere:", "abusefilter-revert-periodend": "Perioadă de încheiere:", "abusefilter-revert-search": "Marchează acțiunile", "abusefilter-revert-filter": "Filtru:", "abusefilter-revert-preview-intro": "Mai jos sunt acțiunile întreprinse de filtrul de abuzuri care vor fi anulate prin această acțiune.\nVă rugăm să le verificați cu atenție și să apăsați „{{int:abusefilter-revert-confirm}}” pentru a confirma selecția.", + "abusefilter-revert-confirm-legend": "Confirmă revenirea", "abusefilter-revert-confirm": "Confirmă", "abusefilter-revert-success": "Ați anulat toate acțiunile filtrului de abuzuri datorate [[Special:AbuseFilter/$1|regulii $2]].", "abusefilter-revert-reason": "Revenire automată a tuturor acțiunilor întreprinse de către abuzarea filtrului din cauza filtrului $1.\nMotivul dat: $2", @@ -354,12 +399,20 @@ "abusefilter-test-submit": "Testează", "abusefilter-test-load": "Încarcă", "abusefilter-test-user": "Schimbări după utilizator:", + "abusefilter-test-nobots": "Ascunde modificările făcute de roboți", "abusefilter-test-period-start": "Schimbări efectuate după:", "abusefilter-test-period-end": "Schimbări efectuate înainte:", "abusefilter-test-page": "Schimbări aduse paginii:", "abusefilter-test-shownegative": "Arată schimbările care nu se potrivesc filtrului", "abusefilter-test-syntaxerr": "Filtrul pe care l-ați introdus conține o eroare de sintaxă.\nPuteți primi o explicație completă apăsând butonul „{{int:abusefilter-edit-check}}”.", "abusefilter-test-badtitle": "Titlul paginii introdus nu este valid. Este posibil să conțină unul sau mai multe caractere care nu pot fi folosite în titluri.", + "abusefilter-test-action": "Tipul acțiunii:", + "abusefilter-test-search-type-all": "Toate acțiunile", + "abusefilter-test-search-type-edit": "Modificări", + "abusefilter-test-search-type-move": "Mutări", + "abusefilter-test-search-type-delete": "Ștergeri", + "abusefilter-test-search-type-upload": "încărcări", + "abusefilter-test-search-type-createaccount": "Creări de conturi", "abusefilter-changeslist-examine": "examinează", "abusefilter-examine": "Examinare schimbări individuale", "abusefilter-examine-intro": "Această pagină vă permite să examinați variabilele generate de filtrul de abuzuri pentru o modificare și să o treceți prin filtre.", @@ -379,13 +432,14 @@ "abusefilter-examine-noresults": "Niciun rezultat n-a fost găsit pentru parametrii căutarii furnizați de dvs.", "abusefilter-topnav": "'''Navigare filtru abuz'''", "abusefilter-topnav-home": "Acasă", + "abusefilter-topnav-recentchanges": "Schimbări recente ale filtrului", "abusefilter-topnav-test": "Testare în serie", "abusefilter-topnav-examine": "Examinare modificări din trecut", "abusefilter-topnav-log": "Jurnal abuzuri", "abusefilter-topnav-tools": "Unelte de depanare", - "abusefilter-topnav-import": "Importă filtru", "abusefilter-log-name": "Jurnal filtru abuz", "abusefilter-log-header": "Acest jurnal afișează un rezumat de schimbări realizate de filtre.\nPentru informații complete, vedeți [[Special:AbuseFilter/history|lista]] cu schimbările ale filtrului recente.", + "abusefilter-logentry-create": "$1 {{GENDER:$2|a creat}} $4 ($5)", "abusefilter-logentry-modify": "$1 {{GENDER:$2|a modificat}} $4 ($5)", "abusefilter-log-noresults": "Niciun rezultat", "abusefilter-diff-title": "Diferențe între versiuni", @@ -400,5 +454,8 @@ "abusefilter-import-intro": "Puteți folosi această interfață pentru a importa filtre din alte wikiuri.\nÎn wikiul sursă, apăsați „{{int:abusefilter-edit-export}}” din „{{int:abusefilter-edit-tools}}”, în cadrul interfeței de editare.\nCopiați conținutul din caseta care apare și lipiți-l în această casetă de text, după care apăsați „{{int:abusefilter-import-submit}}”.", "abusefilter-import-submit": "Importă datele", "abusefilter-group-default": "Implicit", - "abusefilter-http-error": "A apărut o eroare HTTP: $1." + "abusefilter-http-error": "A apărut o eroare HTTP: $1.", + "abusefilter-view-privatedetails-submit": "Vezi detalii private", + "abusefilter-view-privatedetails-legend": "Vezi detalii private", + "abusefilter-log-ip-not-available": "Indisponibil" } diff --git a/AbuseFilter/i18n/roa-tara.json b/AbuseFilter/i18n/roa-tara.json index fc886f0a..5883c0f3 100644 --- a/AbuseFilter/i18n/roa-tara.json +++ b/AbuseFilter/i18n/roa-tara.json @@ -1,15 +1,16 @@ { "@metadata": { "authors": [ + "Daimona Eaytoy", "Joetaras", + "Matma Rex", "McDutchie", - "Reder", - "Matma Rex" + "Reder" ] }, "abusefilter-desc": "Applichesce le euristeche automateche pe le cangiaminde", - "abusefilter": "Configurazione d'u filtre de le abbuse", - "abuselog": "Archivie de l'abusaminde", + "abusefilter": "Gestione d'u filtre de le abbuse", + "abuselog": "Archivije de le filtre de le abbuse", "abusefilter-intro": "Bovègne jndr'â gestione filtre abbuse de le 'nderfazze.\n'U filtre abbuse jè 'nu meccanisme software pè applechesce l'euristeche automateche a totte le aziune.\nQuèste 'nderfazze fàce vedè 'nu elenghe de filtre definite, e conzente a lòre de essere cangiate.", "abusefilter-mustviewprivateoredit": "Pè mutive de sicurezze, sule le utinde cu 'u diritte de 'ndrucà le filtre abbuse private ponne ausà sta 'nderfacce.", "abusefilter-warning": "'''Attenzione''': St'azione ha state automaticamende idendificate cumme pericolose.\nLe cangiaminde non costruttive onne state annullate veloce veloce, e le cangiaminde egregge o repetitive onna resultà sus a 'u cunde tune o l'indirizze IP ca adda avenè bloccate.\nCe tu cride ca st'azione éte costruttive, tu puè confermarle arrete.\n'Na descriziona veloce d'a regole de l'abbuse ca soddisfe l'aziona toje éte: $1", @@ -20,13 +21,14 @@ "abusefilter-blocker": "Filtre de le abbuse", "abusefilter-blockreason": "Bloccate automatecamènde da 'u filtre de abbuse.\nDescriziune d'a reghele iacchiute: $1", "abusefilter-degroupreason": "Diritte automatecamènde luàte da 'u filtre de le abbuse.\nDescriziune d'a reghele: $1", + "abusefilter-blockautopromotereason": "Autopromozzione automatecamènde retardate da 'u filtre de le abbuse.\nDescriziune d'a regole: $1", "abusefilter-accountreserved": "Quiste nome account jè reservate pè l'ause de le filtre de le abbuse.", - "right-abusefilter-modify": "Cange le filtre de le abbuse", + "right-abusefilter-modify": "Ccrèje o cange le filtre de le abbuse", "right-abusefilter-view": "Vide le filtre de le abbuse", "right-abusefilter-log": "Vide l'archivije de le abbuse", "right-abusefilter-log-detail": "Vide l'abbuse dettagliate de le vôsce de reggistre", - "right-abusefilter-private": "Vide le date private jndr'ô reggistre de le abbuse", - "right-abusefilter-private-log": "'Ndruche le dettaglie private d'u reggistre de le abbuse d'u filtre ande abbuse", + "right-abusefilter-privatedetails": "Vide le date private jndr'ô reggistre de le abbuse", + "right-abusefilter-privatedetails-log": "'Ndruche le dettaglie private d'u reggistre de le abbuse d'u filtre ande abbuse", "right-abusefilter-modify-restricted": "Cangià le filtre de le abbuse cu aziune limitate", "right-abusefilter-revert": "Annullà totte le cangiaminde da 'nu date filtre de le abbuse", "right-abusefilter-view-private": "Vide le filtre de le abbuse ca sonde signate cumme private", @@ -38,17 +40,23 @@ "action-abusefilter-view": "vide le filtre de le abbuse", "action-abusefilter-log": "vide l'archivije de le abbuse", "action-abusefilter-log-detail": "Vide l'abbuse dettagliate de le vôsce de l'archivije", - "action-abusefilter-private": "Vide le date private jndr'à ll'archivije de le abbuse", - "action-abusefilter-private-log": "'ndruche le dettaglie private d'u reggistre de le abbuse d'u filtre ande abbuse", + "action-abusefilter-privatedetails": "Vide le date private jndr'à ll'archivije de le abbuse", + "action-abusefilter-privatedetails-log": "'ndruche le dettaglie private d'u reggistre de le abbuse d'u filtre ande abbuse", "action-abusefilter-modify-restricted": "Cangià le filtre de le abbuse, cu aziune limitate", "action-abusefilter-revert": "Annullà totte le cangiaminde da 'nu date filtre de le abbuse", "action-abusefilter-view-private": "Vide le filtre de le abbuse ca sonde signate cumme private", "action-abusefilter-log-private": "vide l'archivije de le filtre de l'abbuse signate cumme private", - "abusefilter-log": "Archivije de le filtre de le abbuse", + "action-abusefilter-hide-log": "scunne le vôsce jndr'à l'archivije de le abbuse", + "action-abusefilter-hidden-log": "'ndruche le abbuse scunnute jndr'à le vôsce de l'archivije", + "action-abusefilter-modify-global": "ccreje o cange le filtre de abbuse globbale", "abusefilter-log-summary": "Quiste archvije fàce vedè 'nu elenghe de totte le aziune pigghiate da le filtre.", "abusefilter-log-search": "Cirche l'archivije de le abbuse", "abusefilter-log-search-user": "Utende:", - "abusefilter-log-search-filter": "ID d'u filtre (separate da le |):", + "abusefilter-log-search-group": "Filtre de gruppe:", + "abusefilter-log-search-group-any": "Tutte", + "abusefilter-log-search-filter": "ID d'u filtre:", + "abusefilter-log-search-filter-help": "Separe cu le barre verticale (|), ausanne 'u prefisse cu \"$1\" pe le filtre globbale", + "abusefilter-log-search-filter-help-central": "Separe cu 'u | (pipe)", "abusefilter-log-search-title": "Titele:", "abusefilter-log-search-wiki": "Uicchi:", "abusefilter-log-search-impact": "Imbatte:", @@ -77,19 +85,21 @@ "abusefilter-log-details-var": "Variabbele", "abusefilter-log-details-val": "Valore", "abusefilter-log-details-vars": "Parametre de l'azione", - "abusefilter-log-details-private": "Dettaglie de l'archivije private", + "abusefilter-log-details-privatedetails": "Dettaglie de l'archivije private", "abusefilter-log-details-ip": "Inderizze IP origgenarie", "abusefilter-log-details-checkuser": "Utende verificatore", "abusefilter-log-noactions": "ninde", + "abusefilter-log-noactions-filter": "Ninde", "abusefilter-log-details-diff": "Cangiaminde fatte cu 'u cangiamende", "abusefilter-log-linkoncontribs": "archivije de l'abbuse", "abusefilter-log-linkoncontribs-text": "Archivije de l'abbuse pe {{GENDER:$1|stu utende}}", "abusefilter-log-linkonhistory": "'ndruche l'archivije de le abbuse", "abusefilter-log-linkonhistory-text": "'Ndruche l'archivie de l'abbuse pe sta pàgene", - "abusefilter-log-hidden": "(vôsce scunnute)", + "abusefilter-log-linkonundelete": "'ndruche l'archivije de le abbuse", + "abusefilter-log-linkonundelete-text": "'Ndruche l'archivie de l'abbuse pe sta pàgene", "abusefilter-log-hidden-implicit": "(scunnute purcé le revisiune onne state scangellate)", "abusefilter-log-cannot-see-details": "Tu non ge tìne 'u permesse pe 'ndrucà le dettaglie de sta vôsce.", - "abusefilter-log-cannot-see-private-details": "Tu non ge tìne 'u permesse pe 'ndrucà le dettaglie private de sta vôsce.", + "abusefilter-log-cannot-see-privatedetails": "Tu non ge tìne 'u permesse pe 'ndrucà le dettaglie private de sta vôsce.", "abusefilter-log-nonexistent": "'Na vôsce cu l'ID date non g'esiste.", "abusefilter-log-details-hidden": "Tu non ge pòte vedè le dettaglie de quèste vôsce, piccè sonde scunnute da 'a viste d'u pubbleche.", "abusefilter-log-details-hidden-implicit": "Non ge puè 'ndrucà le dettaglie pe sta vôsce, purcé 'a revisione associate jè scunnute da 'u 'ndrucamende pubbleche.", @@ -107,7 +117,12 @@ "log-action-filter-abusefilter-create": "Ccrejazione de 'nu filtre nuève", "log-action-filter-abusefilter-modify": "Cangiamende d'u filtre", "log-action-filter-suppress-abuselog": "Scangellazzione de l'archivije de le abbuse", - "abusefilter-management": "Gestione d'u filtre de le abbuse", + "log-action-filter-rights-blockautopromote": "Blocche de autopromozzione", + "log-action-filter-rights-restoreautopromote": "Repstine de autopromozzione", + "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|ave trasute}} a le dettaglie private de $3", + "logentry-rights-blockautopromote": "$1 {{GENDER:$2|ave bloccate}} l'autopromozzione de {{GENDER:$4|$3}} pe 'nu periode de $5", + "logentry-rights-restoreautopromote": "$1 {{GENDER:$2|ave repristinate}} 'a possibbeletà de autopromozzione de {{GENDER:$4|$3}}", + "abusefilterprivatedetails-log-name": "Archivije de le accesse a le dettaglie private de AbuseFilter", "abusefilter-list": "Tutte le filtre", "abusefilter-list-id": "ID d'u filtre", "abusefilter-list-pattern": "Pattern", @@ -129,6 +144,7 @@ "abusefilter-throttled": "aziune disattivate automaticamende", "abusefilter-hitcount": "$1 {{PLURAL:$1|successe|successe}}", "abusefilter-new": "Ccreje 'nu filtre nuève", + "abusefilter-import-button": "'Mbortazione d'u filtre", "abusefilter-return": "Tuèrne a 'a gestione de le filtre", "abusefilter-status-global": "Globbale", "abusefilter-list-options": "Opziune", @@ -149,24 +165,29 @@ "abusefilter-list-options-search-like": "'Nderrogazione semblice", "abusefilter-list-options-search-rlike": "Espressione regolare", "abusefilter-list-options-search-irlike": "Espressione regolare senze penzà a maiuscole e minuscole", + "abusefilter-list-invalid-searchmode": "'U mode de recerche specificate non g'è valide.", + "abusefilter-list-regexerror": "Ave assute 'n'errore duranne 'a recerche: errore de sindasse jndr'à l'espressione regolare.", "abusefilter-list-options-submit": "Aggiorne", "abusefilter-tools-text": "Aqquà se iacchiene quacche strumènde ca pòtene essere utile jndr'à formulazziune e jndr'ô debugging de le filtre de le abbuse.", "abusefilter-tools-expr": "Test de le espressiune", "abusefilter-tools-submitexpr": "Valute", + "abusefilter-tools-syntax-error": "'U filtre tène 'na sindasse invalide.", "abusefilter-tools-reautoconfirm": "Repristenà 'u state autoconfirmate", "abusefilter-tools-reautoconfirm-user": "Utende:", "abusefilter-tools-reautoconfirm-submit": "Re-autoconfirme", + "abusefilter-tools-restoreautopromote": "Autopromozzione repristinate cu le struminde de filtre condre le abbuse.", "abusefilter-reautoconfirm-none": "Quèste utinde non g'à avute 'a sospesione d'u {{GENDER:$1|jidde|jèdde|soje}} state autoconfirmate.", "abusefilter-reautoconfirm-notallowed": "Tu non ge sìnde autorezzate a repristenà 'u state autocunfirmate.", "abusefilter-reautoconfirm-done": "Ô state de l'account autocunfirmate jè state repristenate", - "abusefilter-status": "De le urteme $1 {{PLURAL:$1|aziune|aziune}}, $2 ($3%) {{PLURAL:$2|hagghie|honne}} raggiunde 'u limite de condiziune de $4, e $5 ($6%) {{PLURAL:$5|hagghie|honne}} iacchiute une de le filtre ce jè ôsce a die abbilitate.", + "abusefilter-status": "De le urteme $1 {{PLURAL:$1|azione|aziune}}, $2 ($3%) {{PLURAL:$2|ave|onne}} raggiunde 'u limite de condiziune de $4, e $5 ($6%) {{PLURAL:$5|ave|onne}} accucchiate ninde ninde une de le filtre ce jè ôsce a die abbilitate.", "abusefilter-edit": "Stoche a cange le filtre de l'abbuse", "abusefilter-edit-subtitle": "Cangiaminde d'u filtre $1", "abusefilter-edit-subtitle-new": "Stoche a creje 'nu filtre", + "abusefilter-edit-token-not-match": "'U cangiamende non g'a state reggistrate! Pruève arrete.", "abusefilter-edit-oldwarning": "<strong>Tu stè a cangianne 'na versiune vècchie de quiste filtre.\nLe statisteche citate sonde pè 'a versiune cchiù recende de quiste filtre.\nCe tu salve le cangiaminde toje, tu pòte sovrascrivere totte le cangiaminde combiute d'a revisione ca tu stè a cangià.</strong> •\n[[Special:AbuseFilter/history/$2|Torne sus 'a storie de quiste filtre]].", + "abusefilter-edit-oldwarning-view": "<strong>Ste 'ndruche 'na versiona vecchie de stu filtre.\nLe statisteche elengate sò d'a versione cchiù nove d'u filtre.</strong> •\n[[Special:AbuseFilter/history/$2|Tuèrne a 'u cunde de stu filtre]].", "abusefilter-edit-status-label": "Statisteche:", - "abusefilter-edit-status": "De le urteme $1 {{PLURAL:$1|azione|aziune}}, quiste filtre ave soddisfatte $2 ($3%).", - "abusefilter-edit-status-profile": "De le urteme $1 {{PLURAL:$1|aziune|aziune}}, quiste filtre hagghie iacchiute $2 ($3%).\nJndr'à medie, 'u soje timbe jè de $4ms, e conzume $5 {{PLURAL:$5|condiziune|condiziune}} d'u limite de condiziune.", + "abusefilter-edit-status": "De le urteme $1 {{PLURAL:$1|azione|aziune}}, stu filtre ave accocchiate $2 ($3%).\nJndr'à medie, 'u tiembe sue jè de $4ms, e cunzume $5 {{PLURAL:$5|condizione|condiziune}} d'u limite de condiziune.", "abusefilter-edit-throttled-warning": "'''Attenziò:''' Stu filtre ha state signate automaticamende cumme pericolose. Cumme mesure de securezze, le aziune seguende non ge avénene eseguite ($1). Pe piacere condrolle e [[mw:Extension:AbuseFilter/Conditions|ottimizze]] le condiziune tune pe luà sta restrizzione", "abusefilter-edit-new": "Filtre nueve", "abusefilter-edit-save": "Reggistre 'u filtre", @@ -192,18 +213,26 @@ "abusefilter-edit-action-blockautopromote": "Revoche ô state de utinde autocunfirmate", "abusefilter-edit-action-degroup": "Luà l'utinde da totte le gruppe privilegiate", "abusefilter-edit-action-block": "Blocche le utinde e/o le inderizze IP da l'editaziune", + "abusefilter-edit-action-blocktalk": "Blocche l'utende e/o l'indirizze IP de cangià 'a pàgene de le 'ngazzaminde soje", "abusefilter-edit-action-throttle": "Attivà le aziune sule se l'utinde tène 'nu limite de percenduale", "abusefilter-edit-action-rangeblock": "Blocche 'u rispettive 'ndervalle de IP de origgine de l'utende", "abusefilter-edit-action-tag": "Tag de cangiaminde pè n'otre revisiune", "abusefilter-edit-throttle-count": "Numere de aziune permesse:", "abusefilter-edit-throttle-period": "Periode de tiembe (in seconde):", "abusefilter-edit-throttle-groups": "Criterie de raggruppamende pe:", - "abusefilter-edit-throttle-ip": "Indirizze IP", - "abusefilter-edit-throttle-user": "Cunde de l'utende", - "abusefilter-edit-throttle-range": "Range /16", - "abusefilter-edit-throttle-editcount": "Condegge de le cangiaminde", - "abusefilter-edit-throttle-site": "Tutte 'u site", - "abusefilter-edit-throttle-page": "Pàgene", + "abusefilter-edit-throttle-groups-help": "'Ndruche $1.", + "abusefilter-edit-throttle-groups-help-text": "'a documendazione sus a mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Separe cu 'na virgole pe raggruppà in AND, e cu retuèrne a cape pe raggruppà in OR", + "abusefilter-edit-throttle-placeholder": "Separe cu 'na virgole pe raggruppà in AND, e mitte une a une pe raggruppà in OR", + "abusefilter-throttle-ip": "Indirizze IP", + "abusefilter-throttle-user": "cunde de l'utende", + "abusefilter-throttle-range": "Range /16", + "abusefilter-throttle-creationdate": "date d0a ccreazione de le cunde utinde", + "abusefilter-throttle-editcount": "condegge de le cangiaminde", + "abusefilter-throttle-site": "tutte 'u site", + "abusefilter-throttle-page": "pàgene", + "abusefilter-throttle-none": "(nisciune)", + "abusefilter-throttle-details": "Permette $1 {{PLURAL:$1|azione|aziune}} ogne {{PLURAL:$2|seconde|$2 seconde}}, criterie de raggruppamende: $3", "abusefilter-edit-warn-message": "Messagge de sisteme da ausà pè l'avvise:", "abusefilter-edit-warn-other": "Otre messagge", "abusefilter-edit-warn-other-label": "Nome d'a paggene de n'otre mesagge:\n:''(senze prefisse ''MediaWiki:'')''", @@ -217,13 +246,20 @@ "abusefilter-edit-disallow-preview": "'Ndruche/Scunne l'andeprime d'u messagge scacchiate", "abusefilter-edit-disallow-edit": "Ccreje/Cange 'u messagge scacchiate", "abusefilter-edit-tag-tag": "[[Special:Tags|Tag]] da applecà:", + "abusefilter-edit-tag-placeholder": "Aggiunge le tag (une a une o separate da 'a virgole)", "abusefilter-edit-tag-hidden-placeholder": "Aggiunge le tag (separate da le virgole)", + "abusefilter-edit-block-anon-durations": "Durate d'u blocche pe utinde anonime:", + "abusefilter-edit-block-user-durations": "Durate d'u blocche pe utinde reggistrate:", + "abusefilter-block-anon": "Bluècche le utinde anonime", "abusefilter-block-user": "blocche le utinde reggistrate", + "abusefilter-block-talk": "pàgene de le 'ngazzaminde bloccate", "abusefilter-edit-denied": "Non ge puè uardà le dettaglie de stu filtre, purcé jè scunnute da 'a viste d'u pubbleche.", "abusefilter-edit-main": "Parametre d'u filtre", "abusefilter-edit-done-subtitle": "Filtre cangiate", "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Le cangiaminde tune]] a 'u [[Special:AbuseFilter/$1|filtre $3]] onne state reggistrate.", "abusefilter-edit-badsyntax": "Se iacchie 'nu errore de sindasse jndr'à lle filtre specifecate.\nL'uscite d'u parser jè state: <pre>$1</pre>", + "abusefilter-edit-missingfields": "Le cambe ca avènene mò so richieste e onna essere anghiute: $1", + "abusefilter-edit-deleting-enabled": "Non ge puè signà cumme scangellate 'nu filtre attive.", "abusefilter-edit-restricted": "Non g'ète possibbele cangià 'u filtre, piccè jidde tène une o cchiù aziune restrette.\nSe preghe de chiedere a 'nu utinde cu 'u permesse pè aggiungere aziune limitate pè fà 'u cangiaminde ad 'u puèste toje.", "abusefilter-edit-viewhistory": "Vide 'a storie de quiste filtre", "abusefilter-edit-history": "Cunde:", @@ -235,10 +271,18 @@ "abusefilter-edit-export": "Esporte quiste filtre sus a n'otre wiki", "abusefilter-edit-syntaxok": "Nisciune errore de sindasse ha state acchiate.", "abusefilter-edit-syntaxerr": "Errore de sindasse rilevate: $1", + "abusefilter-edit-warn-leave": "Lassanne 'a pàgene vè pirde tutte le cangiaminde tune ca è fatte a stu filtre.", "abusefilter-edit-bad-tags": "Une o cchiù de le tag specifecate non g'è valide.\nLe tag honne da esse curte, e non g'onne a condenè carattere speciale e non g'onna essere reservate da otre softuer. Pruéve a scacchià 'nu nome nuève.", "abusefilter-edit-notallowed": "Tu non ge sìnde autorizzate a crijà o a cangià le filtre de le abbuse", "abusefilter-edit-notallowed-global": "Tu non ge sìnde autorizzate a crijà o a cangià le filtre de le abbuse globbale", - "abusefilter-edit-notallowed-global-custom-msg": "Messàgge personalizzate de avvertimende non ge sò supportate pe le filtre globbale", + "abusefilter-edit-notallowed-global-custom-msg": "Messàgge personalizzate de avvertimende o de diviete non ge sò supportate pe le filtre globbale", + "abusefilter-edit-invalid-warn-message": "'U messàgge de avvise non ge pò essere vacande.", + "abusefilter-edit-invalid-disallow-message": "'U messàgge ausate pe 'mbedì l'azione non ge pò essere vacande.", + "abusefilter-edit-invalid-throttlecount": "'U numere de aziune da fa fà adda essere 'nu numere indere positive.", + "abusefilter-edit-invalid-throttleperiod": "'U periode de tiembe pu rallendamende adda essere 'nu numere indere positive.", + "abusefilter-edit-empty-throttlegroups": "Adda essere specificate almene 'nu criterie de raggruppamende pu rallendamende.", + "abusefilter-edit-duplicated-throttlegroups": "Le criterie de raggruppamende pu rallendamende non ge ponne tenè duplicate.", + "abusefilter-edit-invalid-throttlegroups": "Le criterie de raggruppamende pu rallendamende specificate non ge sò valide.", "abusefilter-edit-builder-select": "Selezione 'na opzione pè scaffà quidde ad 'a posiziune d'u cursore", "abusefilter-edit-builder-group-op-arithmetic": "Operature aritmetece", "abusefilter-edit-builder-op-arithmetic-addition": "Addizione (+)", @@ -269,7 +313,8 @@ "abusefilter-edit-builder-misc-contains": "'A righe de mmanghe contène 'a righe de destre (contène)", "abusefilter-edit-builder-misc-stringlit": "Strnghe letterale (\"\")", "abusefilter-edit-builder-misc-tern": "Operatore ternarie (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Condizionale (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Condizionale (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "Condizionale curte (if X then Y end)", "abusefilter-edit-builder-group-funcs": "Funziune", "abusefilter-edit-builder-funcs-length": "Lunghezze d'a stringhe (length)", "abusefilter-edit-builder-funcs-lcase": "'U cchù vasce (lcase)", @@ -288,14 +333,17 @@ "abusefilter-edit-builder-funcs-ip_in_range": "L'IP stè jndr'à l'indervalle? (ip_in_range)", "abusefilter-edit-builder-funcs-contains-any": "Stringhe de recerche pè cchiù sottestringhe o cu 'u mode OR (contains_any)", "abusefilter-edit-builder-funcs-contains-all": "Stringhe de recerche pè cchiù sottestringhe o cu 'u mode AND (contains_all)", + "abusefilter-edit-builder-funcs-equals-to-any": "Condrolle ce 'nu parametre date jè uguale (===) ninde ninde a une de le parametre ca avènene mò (equals_to_any)", "abusefilter-edit-builder-funcs-substr": "Sottostringhe (substr)", "abusefilter-edit-builder-funcs-strpos": "Posiziune de sottostringhe in stringhe (strpos)", "abusefilter-edit-builder-funcs-str_replace": "Cangià 'na sottostringhe cu 'na stringhe (str_replace)", "abusefilter-edit-builder-funcs-rescape": "'A stringhe de assute cumme 'nu letterale jndr'à regex (rescape)", "abusefilter-edit-builder-funcs-set_var": "'Mboste 'a variabbele (set_var)", + "abusefilter-edit-builder-funcs-sanitize": "Normalizze le endità HTML in carattere unicode (sanitize)", "abusefilter-edit-builder-group-vars": "Variabbele", "abusefilter-edit-builder-vars-accountname": "Nome d'u cunde utende (o nome d'u cunde utende de ccrejazione)", "abusefilter-edit-builder-vars-timestamp": "Orarie Unix d'u cangiamende", + "abusefilter-edit-builder-vars-timestamp-expanded": "Orarie de stambe de l'archivije", "abusefilter-edit-builder-vars-action": "Azione", "abusefilter-edit-builder-vars-addedlines": "Linee aggiunde cu 'nu cangiaminde", "abusefilter-edit-builder-vars-delta": "Dimenzione cangiate jndr'à 'u cangiamende", @@ -310,14 +358,17 @@ "abusefilter-edit-builder-vars-page-ns": "Namespace d'a pàgene", "abusefilter-edit-builder-vars-page-title": "Nome d'a pagene (senze namespace)", "abusefilter-edit-builder-vars-page-prefixedtitle": "Titele comblete d'a pàgene", + "abusefilter-edit-builder-vars-page-age": "Età d'a pàgene (in seconde)", "abusefilter-edit-builder-vars-movedfrom-id": "Pagene ID pè mòvere 'a pagene de origgene", "abusefilter-edit-builder-vars-movedfrom-ns": "Namespace pè mòvere 'a pagene de origgene", "abusefilter-edit-builder-vars-movedfrom-title": "Titole pè mòvere 'a pagene de origgene", "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "Titole comblete pè mòvere 'a pagene de origgene", + "abusefilter-edit-builder-vars-movedfrom-age": "Età d'a pàgene de origgene d'u spustamende (in seconde)", "abusefilter-edit-builder-vars-movedto-id": "Pagene ID pè mòvere 'a pagene de destinaziune", "abusefilter-edit-builder-vars-movedto-ns": " Namespace pè mòvere 'a pagene de destinaziune", "abusefilter-edit-builder-vars-movedto-title": "Titole pè mòvere 'a pagene de destinaziune", "abusefilter-edit-builder-vars-movedto-prefixedtitle": "Titole comblete pè mòvere 'a pagene de destinaziune", + "abusefilter-edit-builder-vars-movedto-age": "Età d'a pàgene de destinazione d'u spustamende (in seconde)", "abusefilter-edit-builder-vars-user-editcount": "Cunde de le cangiaminde pe l'utende", "abusefilter-edit-builder-vars-user-age": "Età d'u cunde utende", "abusefilter-edit-builder-vars-user-name": "Nome d'u cunde utende", @@ -327,24 +378,36 @@ "abusefilter-edit-builder-vars-user-emailconfirm": "Mò le 'nderizze e-mail jè state confermate", "abusefilter-edit-builder-vars-recent-contributors": "Le urteme dice utinde ce honne condrebbuite ad 'a pagene", "abusefilter-edit-builder-vars-first-contributor": "Prime utende ca ave condrebbuite 'a pàgene", + "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "Le urteme dece utinde ca onne condrebbuite a 'a pàgene de origgene d'u spustamende", + "abusefilter-edit-builder-vars-movedfrom-first-contributor": "Prime utende ca ave condrebbuite 'a pàgene de origgene d'u spustamende", + "abusefilter-edit-builder-vars-movedto-recent-contributors": "Le urteme dece utinde ca onne condrebbuite a 'a pàgene de destinazione d'u spustamende", + "abusefilter-edit-builder-vars-movedto-first-contributor": "Prime utende ca ave condrebbuite a 'a pàgene de destinazione d'u spustamende", "abusefilter-edit-builder-vars-all-links": "Totte le link esterne jndr'ô teste nuève", "abusefilter-edit-builder-vars-added-links": "Totte le link esterne aggiunde jndr'à lle cangiaminde", "abusefilter-edit-builder-vars-removed-links": "Totte le link esterne luàte jndr'à lle cangiaminde", - "abusefilter-edit-builder-vars-old-text": "Vècchia pàgene uicchiteste, apprime d'u cangiamende (no cchiù ausate)", - "abusefilter-edit-builder-vars-new-text": "Nuève pagene wikitext, dope le cangiaminde", + "abusefilter-edit-builder-vars-old-wikitext": "Vècchia pàgene uicchiteste, apprime d'u cangiamende", + "abusefilter-edit-builder-vars-new-wikitext": "Nova pàgene uicchiteste, apprisse 'u cangiamende", "abusefilter-edit-builder-vars-new-pst": "Pàgena nove de uicchiteste, trasformate in pre-reggistrazione", "abusefilter-edit-builder-vars-diff-pst": "Unifiche le differenze de le cangiaminde fatte da 'nu cangiamende, trasformate apprime d'a reggistrazione", "abusefilter-edit-builder-vars-addedlines-pst": "Linèe aggiunde jndr'à 'nu cangiamende, trasformate apprime d'a reggistrazione", - "abusefilter-edit-builder-vars-new-text-stripped": "Teste d'a pagene nuève, cu ogne markup luàte", + "abusefilter-edit-builder-vars-new-text": "Teste d'a pagene nuève, cu ogne markup luàte", "abusefilter-edit-builder-vars-new-html": "Analise d'a sorgende HTML d'a revisiune nuève", "abusefilter-edit-builder-vars-restrictions-edit": "Cange 'u levelle de protezione d'a pagene", "abusefilter-edit-builder-vars-restrictions-move": "Spuèste 'u levelle de protezione d'a pagene", "abusefilter-edit-builder-vars-restrictions-create": "Ccreje 'a protezione d'a pàgene", "abusefilter-edit-builder-vars-restrictions-upload": "Careche 'a protezzione d'u file", - "abusefilter-edit-builder-vars-old-text-stripped": "Teste d'a pagene vècchie, cu ogne markup luàte", + "abusefilter-edit-builder-vars-movedfrom-restrictions-edit": "Cange 'u levèlle de protezione d'a pagene de origgene d'u spustamende", + "abusefilter-edit-builder-vars-movedfrom-restrictions-move": "Spuèste 'u levelle de protezione d'a pagene de origgene d'u spustamende", + "abusefilter-edit-builder-vars-movedfrom-restrictions-create": "Ccrèje 'u levèlle de protezione d'a pàgene de origgene d'u spustamende", + "abusefilter-edit-builder-vars-movedfrom-restrictions-upload": "Careche 'u levèlle de protezione d'u file de origgene d'u spustamende", + "abusefilter-edit-builder-vars-movedto-restrictions-edit": "Cange 'u levèlle de protezione d'a pagene de destinazione d'u spustamende", + "abusefilter-edit-builder-vars-movedto-restrictions-move": "Spuèste 'u levelle de protezione d'a pagene de destinazione d'u spustamende", + "abusefilter-edit-builder-vars-movedto-restrictions-create": "Ccrèje 'u levèlle de protezione d'a pàgene de destinazione d'u spustamende", + "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Careche 'u levèlle de protezione d'u file de destinazione d'u spustamende", + "abusefilter-edit-builder-vars-old-text": "Teste d'a pagene vècchie, cu ogne markup luàte (no cchiù ausate)", "abusefilter-edit-builder-vars-old-links": "Cullegaminde jndr'à pagene, prime de le cangiaminde", "abusefilter-edit-builder-vars-old-html": "Vècchia pàgene de uicchiteste, analizzate cu l'HTML (no cchiù ausate)", - "abusefilter-edit-builder-vars-minor-edit": "Ce o none ce 'u cangiaminde jè condrassignate cumme minore", + "abusefilter-edit-builder-vars-minor-edit": "Dice ce 'u cangiaminde jè condrassegnate cumme stuèdeche (non cchiù ausate)", "abusefilter-edit-builder-vars-file-sha1": "SHA1 miskulanze d'u condenute de le file", "abusefilter-edit-builder-vars-file-size": "Dimenzione d'u file in byte", "abusefilter-edit-builder-vars-file-mime": "Tipe MIME d'u file", @@ -352,6 +415,8 @@ "abusefilter-edit-builder-vars-file-width": "Larghezze d'u file cu le pixel", "abusefilter-edit-builder-vars-file-height": "Altezze d'u file cu le pixel", "abusefilter-edit-builder-vars-file-bits-per-channel": "Bit pe canale de colore d'u file", + "abusefilter-edit-builder-vars-wiki-name": "Nome d'u database d'a uicchi", + "abusefilter-edit-builder-vars-wiki-language": "Codece d'a lènghe d'a uicchi", "abusefilter-filter-log": "Cangiaminde recende d'u filtre", "abusefilter-history": "Cronologgie de le cangiaminde pè le filtre de le abbuse #$1", "abusefilter-history-foruser": "Cangiate da $1", @@ -384,11 +449,17 @@ "abusefilter-exception-noparams": "Nisciune parametre date da 'a funziune \"$2\" pu carattere $1.\nPreviste {{PLURAL:$3|'n argomende|$3 arguminde}}.", "abusefilter-exception-dividebyzero": "Tendative illegale de scucchià $2 pè zere ad 'u carattere $1.", "abusefilter-exception-unrecognisedvar": "Variabbele non recanosciute $2 ad 'u carattere $1", - "abusefilter-exception-notenoughargs": "Non ge stonne sufficiènde argumènde pè 'a funzune $2 chiamate ad 'u carattere $1.\nPreviste $3 {{PLURAL:$3|argumènde|argumènde}}, got $4", + "abusefilter-exception-notenoughargs": "Non ge stonne sufficiènde argumènde pè 'a funzune $2 chiamate ad 'u carattere $1.\nPreviste $3 {{PLURAL:$3|argumènde|arguminde}}, invece so $4", + "abusefilter-exception-toomanyargs": "Troppe arguminde pa funzione $2 chiamate a 'u carattere $1.\nS'aspettane assaije assaije $3 {{PLURAL:$3|argumende|arguminde}}, invece sò $4", "abusefilter-exception-regexfailure": "Errore jndr'à l'espressione regolare \"$2\" ad 'u carattere $1.", - "abusefilter-exception-overridebuiltin": "Annullamènde illegale de variabbele 'ngorporate \"$2\" ad 'u carattere $1.", + "abusefilter-exception-overridebuiltin": "Annullamènde illegale de idendificatore 'ngorporate \"$2\" ad 'u carattere $1.", "abusefilter-exception-outofbounds": "Rechieste de 'na vôsce jndr'à ll'elenghe inesistende $2 (lunghezze de l'elenghe = $3) pu carattere $1.", + "abusefilter-exception-negativeindex": "Le indice negative jndr'à le matrice non ge sò permesse. Acchiate indice \"$2\" a 'u carattere $1.", "abusefilter-exception-notarray": "Rechieste de l'elemènde serie de non serie ad 'u carattere $1.", + "abusefilter-exception-unclosedcomment": "Commende apirte in corrispondenze d'u carattere $1.", + "abusefilter-exception-invalidiprange": "Indervalle IP \"$2\" non valide a 'u carattere $1", + "abusefilter-exception-disabledvar": "Variabbile $2 a 'u carattere $1 non ge se po ausà cchiù.", + "abusefilter-exception-variablevariable": "set e set_var s'aspettane ca 'u prime argomende adda essere 'na stringhe letterale, acchiate a 'u carattere $1.", "abusefilter-action-tag": "Tag", "abusefilter-action-throttle": "Annullate", "abusefilter-action-warn": "Avvertì", @@ -406,6 +477,7 @@ "abusefilter-revert-search": "Scacchie l'aziune", "abusefilter-revert-filter": "ID d'u filtre:", "abusefilter-revert-preview-intro": "Aqquà abbasce stonne elengate le aziune combiute da 'u filtre de le abbuse ca onna essere repristenate da sta azione.\nPe piacere verifiche attentamènde, e cazze \"{{int:abusefilter-revert-confirm}}\" pe confermà 'a selezione.", + "abusefilter-revert-confirm-legend": "Conferme 'u repristine", "abusefilter-revert-confirm": "Conferme", "abusefilter-revert-success": " Tu hé repristenate totte le aziune combiute da 'u filtre de le abbuse a cause d'u [[Special:AbuseFilter/$1|filtre $2]].", "abusefilter-revert-reason": "Repristene automateche de totte le aziune combiute da 'u filtre de le abbuse a cause d'u filtre $1.\nRaggione date: $2", @@ -417,12 +489,15 @@ "abusefilter-test-submit": "Test", "abusefilter-test-load": "Careche", "abusefilter-test-user": "Cangiaminde de l'utende:", + "abusefilter-test-nobots": "Scunne le cangiaminde de le bot", "abusefilter-test-period-start": "Cangiaminde fatte apprisse:", "abusefilter-test-period-end": "Cangiaminde fatte apprime:", "abusefilter-test-page": "Cangiaminde fatte a 'a pàgene:", "abusefilter-test-shownegative": "Fàce vedè sule le cangiaminde ca non ge sonde correspondende ad 'u filtre", "abusefilter-test-syntaxerr": "'U filtre ca tu é mise tène 'n'errore de sindasse.\nTu pòte avè 'na spiegazione comblete ce cazze 'u pulsande \"{{int:abusefilter-edit-check}}\".", "abusefilter-test-badtitle": "'U titole d'a pàgene inserite ere invalide. Jidde pò tené une o cchiù carattere ca non ge ponne essere ausate jndr'à le titole.", + "abusefilter-test-action": "Tipe de azione:", + "abusefilter-test-search-type-all": "Tutte le aziune", "abusefilter-test-search-type-edit": "Cangiaminde", "abusefilter-test-search-type-move": "Spustaminde", "abusefilter-test-search-type-delete": "Scangellaziune", @@ -447,15 +522,16 @@ "abusefilter-examine-noresults": "Non ge sonde state iacchiute nisciune resultate pè le parametre de recerche ca tu é date.", "abusefilter-topnav": "'''Navigazione d'u filtre de le abbuse'''", "abusefilter-topnav-home": "Pàgena Prengepàle", + "abusefilter-topnav-recentchanges": "Cangiaminde recende d'u filtre", "abusefilter-topnav-test": "Teste Batch", "abusefilter-topnav-examine": "Esamine le cangiaminde passate", "abusefilter-topnav-log": "Archivije de l'abbuse", "abusefilter-topnav-tools": "Struminde pu debug", - "abusefilter-topnav-import": "'Mbortazione d'u filtre", "abusefilter-log-name": "Archivije de le filtre de le abbuse", "abusefilter-log-header": "Quiste reggistre fàce vedè 'nu elenghe de cangiaminde combiute da le filtre.\nPè avè cchiù dettaglie, vide [[Special:AbuseFilter/history|'a liste]] de le cangiaminde recende d'u filtre.", "abusefilter-logentry-create": "$1 {{GENDER:$2|ccrejate}} $4 ($5)", "abusefilter-logentry-modify": "$1 {{GENDER:$2|cangiate}} $4 ($5)", + "abusefilter-log-invalid-filter": "Quacche valore de le ID de le filtre specificate jè invalide.", "abusefilter-log-noresults": "Nisciune resultate", "abusefilter-diff-title": "Differenze 'mbrà versiune", "abusefilter-diff-item": "Elemende", @@ -468,7 +544,19 @@ "abusefilter-diff-next": "Cangiamende cchiù nuève", "abusefilter-import-intro": "Jè possibbele ausà quèste 'nderfazze pè le filtre de 'mbortazziune da otre wiki.\nSus ad 'a wiki de origgene, cazzà \"{{int:abusefilter-edit-export}}\" sutte \"{{int:abusefilter-edit-tools}}\" sus a le 'nderfazze de le cangiaminde.\nCopià da 'a caselle de teste ce vide, e 'ngolle jidde sus a quiste cambe de teste, cchiù nnande cazze \"{{int:abusefilter-import-submit}}\".", "abusefilter-import-submit": "'Mborte date", + "abusefilter-import-invalid-data": "Le date ca èpruvate a 'mbortà non ge sò valide", "abusefilter-group-default": "De base", "abusefilter-http-error": "Ha assute 'n'errore HTTP: $1.", - "abusefilter-view-private-submit": "'Ndruche le dettaglie private" + "abusefilter-view-privatedetails-submit": "'Ndruche le dettaglie private", + "abusefilter-view-privatedetails-legend": "'Ndruche le dettaglie private", + "abusefilter-view-privatedetails-reason": "Mutive pe 'ndrucà le dettaglie private:", + "abusefilter-log-details-id": "ID de l'archivije", + "abusefilter-invalid-request": "Richieste invalide! Jè necessarie sce sus a le dettaglie private de l'archivije ausanne 'u module sus a [[Special:AbuseLog/$1]] e dà 'nu mutive.", + "abusefilter-invalid-request-noid": "Richieste invalide! Jè necessarie sce sus a le dettaglie private de l'archivije ausanne 'u module sus 'a pàgene de le dettaglie de l'archivije de le abbuse e dà 'nu mutive.", + "log-description-abusefilterprivatedetails": "Stu archivije face 'ndrucà 'n'elenghe de accesse a le dettaglie private de l'archivije de l'abbuse.", + "abusefilter-noreason": "Iapre l'uecchije: pe 'ndrucà le dettaglie private de stu archivije, a dà 'nu mutive.", + "abusefilter-log-ip-not-available": "Non disponibbile", + "abusefilter-tag-reserved": "'U tag <code>abusefilter-condition-limit</code> jè riservate pe l'ause inderne da AbuseFilter.", + "tag-abusefilter-condition-limit": "limite de condiziune raggiunde", + "tag-abusefilter-condition-limit-description": "Cangiaminde o otre avveneminde ca non ge onne state condrollate da tutte le [[Special:AbuseFilter|filtre anti abbuse]] attive ([[mw:Extension:AbuseFilter/Conditions|aijute]])." } diff --git a/AbuseFilter/i18n/ru.json b/AbuseFilter/i18n/ru.json index 61d3f4b1..e88a2644 100644 --- a/AbuseFilter/i18n/ru.json +++ b/AbuseFilter/i18n/ru.json @@ -1,53 +1,65 @@ { "@metadata": { "authors": [ + "Abiyoyo", "Ahonc", "Aleksandrit", "AlexSm", + "Artsiom91", + "Athena Atterdag", + "Carn ru", + "Cat1987", "DCamer", + "Daimona Eaytoy", + "DmitTrix", + "Dmsm", "Eleferen", + "Facenapalm", "Ferrer", "HalanTul", + "Happy13241", "Ignatus", + "Iniquity", + "Jack who built the house", "KPu3uC B Poccuu", "Kaganer", "Kalan", + "Kareyac", + "Katunchik", + "Kreal39", "Lockal", + "Mailman", + "Matma Rex", + "MaxBioHazard", "MaxSem", - "NBS", - "Okras", - "VasilievVV", - "Александр Сигачёв", - "Сrower", "Meshkov.a", - "Striking Blue", - "Matma Rex", - "Mailman", - "Cat1987", - "Туллук", - "Facenapalm", - "Redredsonia", - "Putnik", - "Smigles", "Mouse21", - "Patrick Star", - "Happy13241", - "Jack who built the house", - "Ole Yves", - "Katunchik", - "Artsiom91", "Movses", - "Abiyoyo", + "NBS", + "Okras", + "Ole Yves", + "Pacha Tchernof", + "Patrick Star", "Ping08", + "Putnik", + "Redredsonia", + "Shaleych", + "Smigles", + "Sobloku", "Stjn", + "Striking Blue", + "VasilievVV", "Vlad5250", - "MaxBioHazard", - "Shaleych" + "Wikisaurus", + "Александр Сигачёв", + "ЛингвоЧел", + "Сrower", + "Туллук" ] }, "abusefilter-desc": "Позволяет применять автоматические эвристические фильтры к правкам", - "abusefilter": "Настройка фильтра злоупотреблений", - "abuselog": "Журнал злоупотреблений", + "abusefilter": "Управление фильтром злоупотреблений", + "abuselog": "Журнал фильтра злоупотреблений", "abusefilter-intro": "Добро пожаловать на страницу управления фильтром злоупотреблений.\nФильтр злоупотреблений представляет собой автоматизированный механизм применения эвристик к действиям участников.\nНиже приведён список всех установленных фильтров.", "abusefilter-mustviewprivateoredit": "По соображениям безопасности, только участники с правом просмотра и изменения частных фильтров злоупотреблений могут использовать этот интерфейс.", "abusefilter-warning": "'''Внимание'''. Данное действие было автоматически определено как нежелательное.\nНеконструктивные действия будут быстро отменены,\nгрубые или неоднократные неконструктивные правки приведут к блокировке вашей учётной записи или IP-адреса.\nЕсли вы уверены, что это конструктивное действие, вы можете нажать кнопку отправки или сохранения ещё раз.\nКраткое описание сработавшего фильтра: $1", @@ -58,35 +70,41 @@ "abusefilter-blocker": "Фильтр злоупотреблений", "abusefilter-blockreason": "Автоматически заблокирован фильтром злоупотреблений. Описание фильтра: $1", "abusefilter-degroupreason": "Фильтр злоупотреблений автоматически снял права. Описание фильтра: $1", + "abusefilter-blockautopromotereason": "Фильтр злоупотреблений автоматически отложил автопродвижение.\nОписание правила: $1", "abusefilter-accountreserved": "Эта учётная запись зарезервирована для использования фильтром злоупотреблений.", - "right-abusefilter-modify": "изменение фильтров злоупотреблений", - "right-abusefilter-view": "просмотр фильтров злоупотреблений", - "right-abusefilter-log": "просмотр журнала злоупотреблений", - "right-abusefilter-log-detail": "просмотр подробностей в журнале фильтра злоупотреблений", - "right-abusefilter-private": "просмотр частных сведений в журнале злоупотреблений", - "right-abusefilter-private-log": "просмотр журнала доступа к личной информации фильтров злоупотребления", - "right-abusefilter-modify-restricted": "изменение ограничивающих фильтров злоупотреблений", - "right-abusefilter-revert": "откат изменений, произведённых фильтром злоупотреблений", - "right-abusefilter-view-private": "просмотр скрытых фильтров злоупотреблений", - "right-abusefilter-log-private": "просмотр частных записей в журнале фильтра злоупотреблений", - "right-abusefilter-hide-log": "сокрытие записей в журнале злоупотреблений", - "right-abusefilter-hidden-log": "просмотр скрытых записей в журнале фильтра злоупотреблений", - "right-abusefilter-modify-global": "создание или изменение глобальных фильтров злоупотреблений", + "right-abusefilter-modify": "Создание или изменение фильтров злоупотреблений", + "right-abusefilter-view": "Просмотр фильтров злоупотреблений", + "right-abusefilter-log": "Просмотр журнала злоупотреблений", + "right-abusefilter-log-detail": "Просмотр подробностей в журнале фильтра злоупотреблений", + "right-abusefilter-privatedetails": "Просмотр частных сведений в журнале злоупотреблений", + "right-abusefilter-privatedetails-log": "Просмотр журнала доступа к личной информации фильтров злоупотребления", + "right-abusefilter-modify-restricted": "Изменение фильтров злоупотреблений с ограничивающими действиями", + "right-abusefilter-revert": "Откат изменений, произведённых фильтром злоупотреблений", + "right-abusefilter-view-private": "Просмотр частных фильтров злоупотреблений", + "right-abusefilter-log-private": "Просмотр записей для частных фильтров в журнале фильтра злоупотреблений", + "right-abusefilter-hide-log": "Сокрытие записей в журнале злоупотреблений", + "right-abusefilter-hidden-log": "Просмотр скрытых записей в журнале фильтра злоупотреблений", + "right-abusefilter-modify-global": "Создание или изменение глобальных фильтров злоупотреблений", "action-abusefilter-modify": "изменение фильтров злоупотреблений", "action-abusefilter-view": "просмотр фильтров злоупотреблений", "action-abusefilter-log": "просмотр журнала злоупотреблений", - "action-abusefilter-log-detail": "просматривать подробности журнала фильтра злоупотреблений", - "action-abusefilter-private": "просмотр личных данных в журнале злоупотреблений", - "action-abusefilter-private-log": "просмотреть журнал доступа к личной информации фильтр злоупотребления", - "action-abusefilter-modify-restricted": "изменять фильтры злоупотреблений с запрещающими действиями", + "action-abusefilter-log-detail": "просмотр подробностей в журнале фильтра злоупотреблений", + "action-abusefilter-privatedetails": "просмотр личных данных в журнале злоупотреблений", + "action-abusefilter-privatedetails-log": "просмотреть журнал доступа к личной информации фильтр злоупотребления", + "action-abusefilter-modify-restricted": "изменение фильтров злоупотреблений с ограничивающими действиями", "action-abusefilter-revert": "отмена всех действий, выполненных фильтром злоупотреблений", "action-abusefilter-view-private": "просмотр фильтров злоупотреблений, отмеченных как скрытые", "action-abusefilter-log-private": "просмотр частных журналов фильтра злоупотреблений", - "abusefilter-log": "Журнал фильтра злоупотреблений", + "action-abusefilter-hide-log": "сокрытие записей в журнале злоупотреблений", + "action-abusefilter-hidden-log": "просмотр скрытых записей в журнале фильтра злоупотреблений", + "action-abusefilter-modify-global": "создание или изменение глобальных фильтров злоупотреблений", "abusefilter-log-summary": "В этом журнале представлен список всех действий, обнаруженных фильтрами.", "abusefilter-log-search": "Поиск в журнале злоупотреблений", "abusefilter-log-search-user": "Участник:", - "abusefilter-log-search-filter": "ID фильтров (разделённые символом вертикальной линии):", + "abusefilter-log-search-group": "Группа фильтра:", + "abusefilter-log-search-group-any": "Любой", + "abusefilter-log-search-filter": "ID фильтров:", + "abusefilter-log-search-filter-help": "Разделите вертикальной чертой, префикс «$1» используется для глобальных фильтров", "abusefilter-log-search-title": "Заголовок:", "abusefilter-log-search-wiki": "Википроект:", "abusefilter-log-search-impact": "Влияние:", @@ -115,7 +133,7 @@ "abusefilter-log-details-var": "Переменная", "abusefilter-log-details-val": "Значение", "abusefilter-log-details-vars": "Параметры действия", - "abusefilter-log-details-private": "Скрытые данные журнала", + "abusefilter-log-details-privatedetails": "Личные данные в журнале", "abusefilter-log-details-ip": "Исходящий IP-адрес", "abusefilter-log-details-checkuser": "Проверить участника", "abusefilter-log-noactions": "нет", @@ -124,14 +142,15 @@ "abusefilter-log-linkoncontribs-text": "Записи журнала злоупотреблений для {{GENDER:$1|этого участника|этой участницы}}", "abusefilter-log-linkonhistory": "просмотр журнала фильтров", "abusefilter-log-linkonhistory-text": "Показать журналы злоупотреблений для этой страницы", - "abusefilter-log-hidden": "(запись скрыта)", + "abusefilter-log-linkonundelete": "просмотр журнала злоупотреблений", + "abusefilter-log-linkonundelete-text": "Показать журналы злоупотреблений для этой страницы", "abusefilter-log-hidden-implicit": "(скрыто, так как правка была удалена)", "abusefilter-log-cannot-see-details": "У вас нет разрешения на просмотр подробностей этой записи.", - "abusefilter-log-cannot-see-private-details": "У вас нет разрешения просматривать личные данные этой записи.", + "abusefilter-log-cannot-see-privatedetails": "У вас нет разрешения просматривать личные данные этой записи.", "abusefilter-log-nonexistent": "Записи с указанным ID не существует.", "abusefilter-log-details-hidden": "Вы не можете просмотреть подробности этой записи, поскольку она была скрыта.", "abusefilter-log-details-hidden-implicit": "Вы не можете просмотреть подробности этой записи, поскольку соответствующая ей версия была скрыта.", - "abusefilter-log-private-not-included": "Один или несколько заданных вами идентификатора принадлежать скрытым фильтрам. Поскольку вы не можете просматривать скрытые фильтры, они не будут отображены в поиске.", + "abusefilter-log-private-not-included": "Один или несколько заданных вами идентификатора принадлежат скрытым фильтрам. Поскольку вы не можете просматривать скрытые фильтры, они не будут отображены в поиске.", "abusefilter-log-hide-legend": "Скрыть запись журнала", "abusefilter-log-hide-id": "ID записи журнала:", "abusefilter-log-hide-hidden": "Скрыть эту запись от публичного просмотра", @@ -145,9 +164,12 @@ "log-action-filter-abusefilter-create": "Создание нового фильтра", "log-action-filter-abusefilter-modify": "Изменение фильтра", "log-action-filter-suppress-abuselog": "Подавление журнала злоупотреблений", + "log-action-filter-rights-blockautopromote": "Блокировка автопродвижения", + "log-action-filter-rights-restoreautopromote": "Восстановление автопродвижения", "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|доступ к}} личные данные для $3", + "logentry-rights-blockautopromote": "$1 {{GENDER:$2|заблокировал|заблокировала}} автопродвижение {{GENDER:$4|$3}} на срок $5", + "logentry-rights-restoreautopromote": "$1 {{GENDER:$2|восстановил|восстановила}} возможность автопродвижения {{GENDER:$4|$3}}", "abusefilterprivatedetails-log-name": "Журнал доступа к конфиденциальным данным фильтр злоупотребления", - "abusefilter-management": "Управление фильтром злоупотреблений", "abusefilter-list": "Все фильтры", "abusefilter-list-id": "ID фильтра", "abusefilter-list-pattern": "Паттерн", @@ -166,8 +188,10 @@ "abusefilter-enabled": "Включён", "abusefilter-deleted": "Удалён", "abusefilter-disabled": "Выключен", + "abusefilter-throttled": "ограничен", "abusefilter-hitcount": "$1 {{PLURAL:$1|срабатывание|срабатывания|срабатываний}}", "abusefilter-new": "Создать новый фильтр", + "abusefilter-import-button": "Импорт фильтра", "abusefilter-return": "Вернуться к управлению фильтрами", "abusefilter-status-global": "Глобальный", "abusefilter-list-options": "Параметры", @@ -188,26 +212,29 @@ "abusefilter-list-options-search-like": "Простой запрос", "abusefilter-list-options-search-rlike": "Регулярное выражение", "abusefilter-list-options-search-irlike": "Нечувствительное к регистру регулярное выражение", + "abusefilter-list-invalid-searchmode": "Режим «Спецпоиск» не дейвствителен", "abusefilter-list-regexerror": "Во время поиска произошла ошибка: Синтаксическая ошибка регулярного выражения.", "abusefilter-list-options-submit": "Обновить", "abusefilter-tools-text": "Здесь находятся некоторые инструменты, которые могут помочь в формулировании и отладке фильтров злоупотреблений.", "abusefilter-tools-expr": "Проверка выражения", "abusefilter-tools-submitexpr": "Опробовать", + "abusefilter-tools-syntax-error": "Синтаксическая ошибка в фильтре.", "abusefilter-tools-reautoconfirm": "Восстановить статус «autoconfirmed»", "abusefilter-tools-reautoconfirm-user": "Участник:", "abusefilter-tools-reautoconfirm-submit": "Переавтоподтверждение", + "abusefilter-tools-restoreautopromote": "Автопродвижение восстановлено с помощью инструментов фильтра злоупотреблений.", "abusefilter-reautoconfirm-none": "У {{GENDER:$1|этого участника|этой участницы}} не отключён статус автоподтверждения.", "abusefilter-reautoconfirm-notallowed": "Вам не разрешено восстанавливать статус автоподтверждения.", "abusefilter-reautoconfirm-done": "Восстановлен статус автоподтверждения учётной записи", - "abusefilter-status": "Из $1 {{PLURAL:$1|последнего действия|последних действий}}, $2 ($3%) {{PLURAL:$2|попало|попали}} под ограничивающее условие $4, а $5 ($6%) {{PLURAL:$5|соответствует|соответствуют}} одному из включённых в настоящее время фильтров.", + "abusefilter-status": "Из $1 {{PLURAL:$1|последнего действия|последних действий}}, $2 ($3%) {{PLURAL:$2|попало|попали}} под ограничивающее условие $4, а $5 ($6%) {{PLURAL:$5|соответствует|соответствуют}} по крайней мере одному из включённых в настоящее время фильтров.", "abusefilter-edit": "Править фильтр злоупотреблений", "abusefilter-edit-subtitle": "Изменение фильтра $1", "abusefilter-edit-subtitle-new": "Создание фильтра", "abusefilter-edit-token-not-match": "Ваша правка не сохранена! Попробуйте ещё раз.", "abusefilter-edit-oldwarning": "<strong>Вы правите старую версию фильтра. Статистика приводится для последней версии фильтра. Если вы сохраните вашу правку, то вы перезапишите сделанные ранее изменения.</strong> • [[Special:AbuseFilter/history/$2|Вернуться к странице истории фильтра]]", + "abusefilter-edit-oldwarning-view": "<strong>Вы просматриваете старую версию фильтра правок.\nПриведенная статистика относится к самой последней версии фильтра.</strong> •\n[[Special:AbuseFilter/history/$2|Вернуться к истории этого фильтра]].", "abusefilter-edit-status-label": "Статистика:", - "abusefilter-edit-status": "Из {{PLURAL:$1|последнего $1 действия|последних $1 действий}}, этот фильтр соответствует $2 ($3%).", - "abusefilter-edit-status-profile": "Из {{PLURAL:$1|последнего $1 действия|последних $1 действий}}, этот фильтр соответствует $2 ($3%).\nСреднее время его работы — $4 мс, он использует $5 {{PLURAL:$5|условие|условий|условия}} из лимита условий.", + "abusefilter-edit-status": "{{PLURAL:$1|Для $1 последнего действия|Из $1 последних действий}}, этот фильтр соответствует $2 ($3%).\nСреднее время его работы — $4 мс, он использует $5 {{PLURAL:$5|условие|условий|условия}} из лимита условий.", "abusefilter-edit-throttled-warning": "'''Внимание:''' Этот фильтр автоматически помечен как вредный. В качестве меры безопасности следующие действия не будут выполнены ($1). Пожалуйста, проверьте и [[mw:Extension:AbuseFilter/Conditions|оптимизируйте]] ваши условия, чтобы удалить это ограничение", "abusefilter-edit-new": "Новый фильтр", "abusefilter-edit-save": "Сохранить фильтр", @@ -240,19 +267,26 @@ "abusefilter-edit-throttle-count": "Количество разрешённых действий:", "abusefilter-edit-throttle-period": "Отрезок времени (в секундах):", "abusefilter-edit-throttle-groups": "Сужение по группам:\n''(по одному на строке, разделение запятыми)''", - "abusefilter-edit-throttle-ip": "IP-адрес", - "abusefilter-edit-throttle-user": "Учётная запись", - "abusefilter-edit-throttle-range": "Диапазон /16", - "abusefilter-edit-throttle-creationdate": "Серверное время регистрации", - "abusefilter-edit-throttle-editcount": "Счётчик правок", - "abusefilter-edit-throttle-site": "Весь сайт", - "abusefilter-edit-throttle-page": "Страница", + "abusefilter-edit-throttle-groups-help": "См. $1.", + "abusefilter-edit-throttle-groups-help-text": "документацию на mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Разделите запятыми, чтобы соединить логическим оператором И, и переводами строк, чтобы соединить логическим оператором ИЛИ", + "abusefilter-edit-throttle-placeholder": "Разделите запятыми, чтобы соединить логическим оператором AND, и переводами строк, чтобы соединить логическим оператором OR", + "abusefilter-throttle-ip": "IP-адрес", + "abusefilter-throttle-user": "учётная запись", + "abusefilter-throttle-range": "Диапазон /16", + "abusefilter-throttle-creationdate": "дата создания учётной записи", + "abusefilter-throttle-editcount": "счётчик правок", + "abusefilter-throttle-site": "весь сайт", + "abusefilter-throttle-page": "страница", + "abusefilter-throttle-none": "(нет)", + "abusefilter-throttle-details": "Разрешить $1 {{PLURAL:$1|действие|действия|действий}} каждые $2 {{PLURAL:$2|секунду|секунды|секунд}}, ограничение для групп: $3", "abusefilter-edit-warn-message": "Системное сообщение для предупреждений:", "abusefilter-edit-warn-other": "Другое сообщение", "abusefilter-edit-warn-other-label": "Название страницы другого сообщения:\n:''(без префикса MediaWiki:)''", "abusefilter-edit-warn-actions": "Действия:", "abusefilter-edit-warn-preview": "Показать/скрыть предпросмотр выбранного сообщения", "abusefilter-edit-warn-edit": "Создать/Изменить выбранное сообщение", + "abusefilter-edit-disallow-message": "Системное сообщение для запрета:", "abusefilter-edit-disallow-other": "Другое сообщение", "abusefilter-edit-disallow-other-label": "Название страницы другого сообщения:\n:''(без префикса MediaWiki:)''", "abusefilter-edit-disallow-actions": "Действия:", @@ -284,10 +318,14 @@ "abusefilter-edit-export": "Экспортировать этот фильтр в другую вики", "abusefilter-edit-syntaxok": "Не обнаружено ошибок синтаксиса.", "abusefilter-edit-syntaxerr": "Обнаружена ошибка синтаксиса: $1", + "abusefilter-edit-warn-leave": "Если вы покинете эту страницу, будут потеряны все изменения, сделанные в фильтре.", "abusefilter-edit-bad-tags": "Одна или более из указанным вами меток неверна.\nМетки должны быть короткими, не должны содержать спецсимволов или быть зарезервированными другим программным обеспечением. Попробуйте выбрать новое название метки", "abusefilter-edit-notallowed": "У вас нет разрешения создавать или редактировать фильтры злоупотреблений", "abusefilter-edit-notallowed-global": "У вас нет прав на создание или изменение глобальных фильтров злоупотреблений", - "abusefilter-edit-notallowed-global-custom-msg": "Пользовательские предупреждающие сообщения не поддерживаются для глобальных фильтров", + "abusefilter-edit-notallowed-global-custom-msg": "Глобальные фильтры не поддерживают пользовательские или запрещающие сообщения", + "abusefilter-edit-invalid-warn-message": "Поле для предупреждающего сообщения не может быть пустым.", + "abusefilter-edit-invalid-disallow-message": "Поле для сообщения об отклонении не может быть пустым.", + "abusefilter-edit-invalid-throttlecount": "Значение «тормозящего» счетчика должено быть положительным целым числом.", "abusefilter-edit-builder-select": "Выберите пункт для добавления", "abusefilter-edit-builder-group-op-arithmetic": "Арифметические операторы", "abusefilter-edit-builder-op-arithmetic-addition": "Сложение (+)", @@ -318,7 +356,7 @@ "abusefilter-edit-builder-misc-contains": "Левая строка содержит правую строку (contains)", "abusefilter-edit-builder-misc-stringlit": "Строковое выражение (\"\")", "abusefilter-edit-builder-misc-tern": "Тернарный оператор (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Условие (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Условие (if X then Y else Z end)", "abusefilter-edit-builder-group-funcs": "Функции", "abusefilter-edit-builder-funcs-length": "Длина строки (length)", "abusefilter-edit-builder-funcs-lcase": "В нижний регистр (lcase)", @@ -383,18 +421,18 @@ "abusefilter-edit-builder-vars-recent-contributors": "Последние десять редакторов страницы", "abusefilter-edit-builder-vars-first-contributor": "Первый сделавший свой вклад в страницу", "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "Последние десять пользователей, редактировавших страницу, которая перемещается", - "abusefilter-edit-builder-vars-movedfrom-first-contributor": "Первый пользователь внесет вклад в перемещение исходной страницы", + "abusefilter-edit-builder-vars-movedfrom-first-contributor": "Первый участник в исходной переименованной странице", "abusefilter-edit-builder-vars-movedto-recent-contributors": "Последние десять участников, редактировавших целевую страницу", - "abusefilter-edit-builder-vars-movedto-first-contributor": "Первый пользователь внесет вклад в перемещение страницы назначения", + "abusefilter-edit-builder-vars-movedto-first-contributor": "Первый участник в целевой странице", "abusefilter-edit-builder-vars-all-links": "Все внешние ссылки в новом тексте", "abusefilter-edit-builder-vars-added-links": "Все внешние ссылки, добавленные в правке", "abusefilter-edit-builder-vars-removed-links": "Все внешние ссылки, удалённые в правке", - "abusefilter-edit-builder-vars-old-text": "Старый вики-текст, до правки страницы (больше не используется)", - "abusefilter-edit-builder-vars-new-text": "Новый вики-текст, после правки страницы", + "abusefilter-edit-builder-vars-old-wikitext": "Вики-текст старой страницы до правки", + "abusefilter-edit-builder-vars-new-wikitext": "Вики-текст новой страницы после правки", "abusefilter-edit-builder-vars-new-pst": "Вики-текст новой страницы, преобразованный перед сохранением", "abusefilter-edit-builder-vars-diff-pst": "Унифицированный diff изменений в процессе редактирования, преобразованных перед сохранением", "abusefilter-edit-builder-vars-addedlines-pst": "Строчки, добавленные при редактировании, преобразованные перед сохранением", - "abusefilter-edit-builder-vars-new-text-stripped": "Новый текст страницы, очищенный от разметки", + "abusefilter-edit-builder-vars-new-text": "Новый текст страницы, очищенный от разметки", "abusefilter-edit-builder-vars-new-html": "Разобранный HTML-код новой версии", "abusefilter-edit-builder-vars-restrictions-edit": "Уровень защиты страницы от правок", "abusefilter-edit-builder-vars-restrictions-move": "Уровень защиты страницы от переименований", @@ -407,11 +445,11 @@ "abusefilter-edit-builder-vars-movedto-restrictions-edit": "Изменить уровень защиты от переименования целевой страницы", "abusefilter-edit-builder-vars-movedto-restrictions-move": "Изменить уровень защиты от переименования целевой страницы", "abusefilter-edit-builder-vars-movedto-restrictions-create": "Защита от создания целевой страницы при перемещении", - "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Загрузить защиту файла назначения перемещения", - "abusefilter-edit-builder-vars-old-text-stripped": "Текст старой страницы, лишённый разметки", + "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Защита от загрузки целевой страницы", + "abusefilter-edit-builder-vars-old-text": "Текст старой страницы, лишённый разметки (больше не используется)", "abusefilter-edit-builder-vars-old-links": "Ссылки на странице до правки", - "abusefilter-edit-builder-vars-old-html": "Вики-текст старой страницы, преобразованный в HTML (боьше не используется)", - "abusefilter-edit-builder-vars-minor-edit": "Была ли правка отмечена как «малое изменение»", + "abusefilter-edit-builder-vars-old-html": "Вики-текст старой страницы, преобразованный в HTML (больше не используется)", + "abusefilter-edit-builder-vars-minor-edit": "Была ли правка отмечена как «малое изменение» (больше не используется)", "abusefilter-edit-builder-vars-file-sha1": "SHA1-хэш содержания файла", "abusefilter-edit-builder-vars-file-size": "Размер файла в байтах", "abusefilter-edit-builder-vars-file-mime": "MIME-тип файла", @@ -419,6 +457,8 @@ "abusefilter-edit-builder-vars-file-width": "Ширина файла в пикселях", "abusefilter-edit-builder-vars-file-height": "Высота файла в пикселях", "abusefilter-edit-builder-vars-file-bits-per-channel": "Глубина цвета в файле", + "abusefilter-edit-builder-vars-wiki-name": "Название базы данных вики", + "abusefilter-edit-builder-vars-wiki-language": "Языковой код вики", "abusefilter-filter-log": "Последние изменения фильтров", "abusefilter-history": "История изменений фильтра злоупотреблений #$1", "abusefilter-history-foruser": "Изменения сделанные $1", @@ -452,13 +492,16 @@ "abusefilter-exception-dividebyzero": "Попытка деления $2 на ноль в позиции $1.", "abusefilter-exception-unrecognisedvar": "Неопознанная переменная $2 в позиции $1", "abusefilter-exception-notenoughargs": "Не хватает аргументов в функции $2, вызываемой в позиции $1.\nОжидается $3 {{PLURAL:$3|аргумент|аргументов|аргумента}}, {{PLURAL:$4|получен|получено}} $4", - "abusefilter-exception-regexfailure": "Ошибка в регулярном выражении «$3» в позиции $1: «$2»", - "abusefilter-exception-overridebuiltin": "Недопустимое переопределение встроенной переменной «$2» в позиции $1.", + "abusefilter-exception-toomanyargs": "Слишком много аргументов в функции $2, вызываемой в позиции $1.\nОжидается не более $3 {{PLURAL:$3|аргумент|аргументов|аргумента}}, {{PLURAL:$4|получен|получено}} $4", + "abusefilter-exception-regexfailure": "Ошибка в регулярном выражении «$2» в позиции $1.", + "abusefilter-exception-overridebuiltin": "Недопустимое переопределение встроенного идентификатора «$2» в позиции $1.", "abusefilter-exception-outofbounds": "Запрос несуществующего элемента списка $2 (размер списка = $3) в позиции $1.", + "abusefilter-exception-negativeindex": "Отрицательные индексы не допускаются в массивах. Получен индекс \"$2\" в позиции $1.", "abusefilter-exception-notarray": "Запрос элемента массива для объекта, не являющемся массивом, в позиции $1.", "abusefilter-exception-unclosedcomment": "Незакрытый комментарий в позиции $1", "abusefilter-exception-invalidiprange": "Неверный диапазон IP-адресов «$2» на позиции $1.", "abusefilter-exception-disabledvar": "Переменная $2 на позиции $1 более не используется.", + "abusefilter-exception-variablevariable": "Переменные \"set\" и \"set_var\" не разрешены, найдено на позиции $1.", "abusefilter-action-tag": "Метка", "abusefilter-action-throttle": "Сужение", "abusefilter-action-warn": "Предупреждение", @@ -521,15 +564,16 @@ "abusefilter-examine-noresults": "Ничего не найдено по запросу с заданными параметрами.", "abusefilter-topnav": "'''Навигация по Фильтру злоупотреблений'''", "abusefilter-topnav-home": "В начало", + "abusefilter-topnav-recentchanges": "Последние изменения фильтров", "abusefilter-topnav-test": "Пакетное тестирование", "abusefilter-topnav-examine": "Изучение последних правок", "abusefilter-topnav-log": "Журнал злоупотреблений", "abusefilter-topnav-tools": "Средства отладки", - "abusefilter-topnav-import": "Импорт фильтра", "abusefilter-log-name": "Журнал фильтра злоупотреблений", "abusefilter-log-header": "В этот журнал записываются описания изменений, произведённых в фильтрах.\nПодробности можно найти в [[Special:AbuseFilter/history|списке]] последних изменений фильтров.", "abusefilter-logentry-create": "$1 {{GENDER:$2|создано}} $4 ($5)", "abusefilter-logentry-modify": "$1 {{GENDER:$2|изменил|изменила}} $4 ($5)", + "abusefilter-log-invalid-filter": "Некоторые из указанных идентификаторов фильтров являются недопустимыми.", "abusefilter-log-noresults": "Ничего не найдено", "abusefilter-diff-title": "Различия между версиями", "abusefilter-diff-item": "Элемент", @@ -542,13 +586,14 @@ "abusefilter-diff-next": "Следующая правка", "abusefilter-import-intro": "Вы можете использовать этот интерфейс для импорта фильтров из других вики.\nВ исходной вики, нажмите «{{int:abusefilter-edit-export}}» в разделе «{{int:abusefilter-edit-tools}}» интерфейса редактирования.\nСкопируйте содержание текстового поля, вставьте его на эту страницу и нажмите «{{int:abusefilter-import-submit}}».", "abusefilter-import-submit": "Импортировать данные", + "abusefilter-import-invalid-data": "Вы пытаетесь внести недействительные данные", "abusefilter-group-default": "По умолчанию", "abusefilter-http-error": "Произошла ошибка HTTP: $1.", - "abusefilter-view-private-submit": "Просмотр личные данные", - "abusefilter-view-private": "Просмотр личные данные", - "abusefilter-view-private-reason": "Причина доступа к личные данные:", + "abusefilter-view-privatedetails-submit": "Просмотр личных данных", + "abusefilter-view-privatedetails-legend": "Просмотр личные данные", + "abusefilter-view-privatedetails-reason": "Причина доступа к личным данным:", "abusefilter-log-details-id": "ID журнала", - "abusefilter-invalid-request": "Неверный запрос! Вы должны получить доступ к частным данным журнала через форму на [[Special:AbuseLog/$1]] и обеспечить причину.", + "abusefilter-invalid-request": "Неверный запрос! Вы должны получить доступ к личным данным в журнале с помощью формы на [[Special:AbuseLog/$1]] при этом указав причину запроса.", "abusefilter-invalid-request-noid": "Неверный запрос! Вы должны получить доступ к частным данным журнала через форму на странице сведений о журнале злоупотреблений и указать причину.", "log-description-abusefilterprivatedetails": "В этом журнале отображается список случаев, когда пользователь просматривал личные данные журнала злоупотреблений.", "abusefilter-noreason": "Предупреждение. Чтобы просмотреть личные данные этого журнала, вы должны указать причину.", diff --git a/AbuseFilter/i18n/rue.json b/AbuseFilter/i18n/rue.json index fbfea584..7e1661d8 100644 --- a/AbuseFilter/i18n/rue.json +++ b/AbuseFilter/i18n/rue.json @@ -9,8 +9,8 @@ ] }, "abusefilter-desc": "Придавать автоматічны геврістікы до едітовань", - "abusefilter": "Конфіґурація філтрів знеужываня", - "abuselog": "Запис знеужываня", + "abusefilter": "Управлїня філтром едітовань", + "abuselog": "Протокол філтра знеужываня", "abusefilter-intro": "Вітайте у інтерфейсї керованя філтрів зловжываня.\nФілтер зловжываня є автоматічный софтверовый механізм, через котрого ся вшыткы операції тестують за помочі автоматічных еврістік.\nВ тім інтерфейсї можете видїти список дефінованых філтрів і мінити їх.", "abusefilter-warning": "'''Позірь:''' Тота дїя была автоматічно ідентіфікована як шкодлива.\nНеконштруктівны едітованя будуть швыдко ревертованы, в повторяный або заважных припадах може быти ваше конто хоснователя ці IP-адреса заблокованы.\nКідь тримете свою дїю за правилну, можете єй підтвердити кликнутём на Уложыти зміны.\nКуртый опис правила, котре вашу дїю означіло за шкодливу : $1", "abusefilter-disallowed": "Тота дїя была автоматічно означена як шкодлива,\nі зато заборонена.\nКідь вірите, же ваше едітованя є конштруктівне, просиме контактуйте адміністратора і дайте му знати, што сьте хотїли зробити.\nКороткый опис правила, котре вашу дїю означіло за шкодливу: $1", @@ -25,7 +25,7 @@ "right-abusefilter-view": "Перегляд філтрів знеужываня", "right-abusefilter-log": "Перезераня протоколу знеужываня", "right-abusefilter-log-detail": "Перегляд детайлів в протоколї знеужываня", - "right-abusefilter-private": "Перегляд пріватных дат в протоколї знеужываня", + "right-abusefilter-privatedetails": "Перегляд пріватных дат в протоколї знеужываня", "right-abusefilter-modify-restricted": "Зміна філтрів з обмеджуючімя дїями", "right-abusefilter-revert": "Ревертованя вшыткых змін зробленых філтром едітовань", "right-abusefilter-view-private": "Перезераня філтрів знеужытя означеный як пріватны", @@ -37,11 +37,10 @@ "action-abusefilter-view": "перезерати філтры знеужываня", "action-abusefilter-log": "перезерати протоколу знеужываня", "action-abusefilter-log-detail": "перезерати детайлы в протоколї знеужываня", - "action-abusefilter-private": "перезерати пріватны дата в протоколї знеужываня", + "action-abusefilter-privatedetails": "перезерати пріватны дата в протоколї знеужываня", "action-abusefilter-modify-restricted": "мінити філтры знеужываня з обмеджуючімя дїями", "action-abusefilter-revert": "ревертовати вшыткы зміны зроблены філтром едітовань", "action-abusefilter-view-private": "перезерати філтрів знеужытя означеный як пріватны", - "abusefilter-log": "Протокол філтра знеужываня", "abusefilter-log-summary": "Тот протокол обсягує список вшыткых дїй захопленых філтрами", "abusefilter-log-search": "Глядати в записї знеужытя", "abusefilter-log-search-user": "Хоснователь:", @@ -61,13 +60,13 @@ "abusefilter-log-details-var": "Перемінна", "abusefilter-log-details-val": "Значіня", "abusefilter-log-details-vars": "Параметры дїї", - "abusefilter-log-details-private": "Пріватны дата", + "abusefilter-log-details-privatedetails": "Пріватны дата", "abusefilter-log-details-ip": "Жрідлова IP-адреса", "abusefilter-log-noactions": "жадна", "abusefilter-log-details-diff": "Зміны, зроблены при едітованю", "abusefilter-log-linkoncontribs": "протокол знеужываня", "abusefilter-log-linkoncontribs-text": "Протокол знеужытя про того хоснователя", - "abusefilter-log-hidden": "(схованый запис)", + "abusefilter-log-linkonhistory": "перегляд протоколу знеужываня", "abusefilter-log-hidden-implicit": "(сховане, бо верзія была вылучена)", "abusefilter-log-cannot-see-details": "Вы не мате дозволїня на перегляд детайлів того запису.", "abusefilter-log-details-hidden": "У того запису сі не можете посмотрити детайлы, бо были схованы перед публічном приступом.", @@ -77,7 +76,6 @@ "abusefilter-log-hide-reason": "Причіна:", "abusefilter-log-hide-forbidden": "Не маєте права про схованя записів в протоколї знеужытя", "logentry-abusefilter-hit": "$1 {{#gender:$1|выкликав|выкликала}} спрацовованя $4, выконуючі дїю \"$5\" на $3. Учінены крокы: $6 ($7)", - "abusefilter-management": "Управлїня філтром едітовань", "abusefilter-list": "Вшыткы філтры", "abusefilter-list-id": "ІД філтра", "abusefilter-list-status": "Статус", @@ -97,6 +95,7 @@ "abusefilter-disabled": "Выпнутый", "abusefilter-hitcount": "$1 {{PLURAL:$1|засяг|засягы|засягів}}", "abusefilter-new": "Створити новый філтер", + "abusefilter-import-button": "Імпорт філтру", "abusefilter-return": "Вернути ся на адміністрацію філтрів", "abusefilter-status-global": "Ґлобалный", "abusefilter-list-options": "Можности", @@ -124,7 +123,6 @@ "abusefilter-edit-oldwarning": "<strong>Едітуєте старшу верзію того філтру. Уведены штатістікы платять про актуалну верзію. Кідь уложыте свої зміны, перепишете новшы управы.</strong> • [[Special:AbuseFilter/history/$2|Вернути ся на історію того філтру]].", "abusefilter-edit-status-label": "Штатістіка:", "abusefilter-edit-status": "Z {{PLURAL:$1|1 послїдня дїя|послїднїх $1 дїй}} тому філтру {{PLURAL:$2|одповідала|одповідали|одповідало}} $2 ($3 %).", - "abusefilter-edit-status-profile": "Z {{PLURAL:$1|1 послїдня дїя|послїднїх $1 дїй}} тому філтру {{PLURAL:$2|одповідала|одповідали|одповідало}} $2 ($3 %).\nСередня доба біжаня філтру є $4 мс, філтер потребує $5 з доволеного чісла подмінок.", "abusefilter-edit-new": "Новый філтер", "abusefilter-edit-save": "Уложыти філтер", "abusefilter-edit-id": "ІД філтра:", @@ -256,15 +254,15 @@ "abusefilter-edit-builder-vars-all-links": "Вшыткы екстеры одказы в новім текстї", "abusefilter-edit-builder-vars-added-links": "Вшыткы екстерны одказы приданы почас едітованя", "abusefilter-edit-builder-vars-removed-links": "Вшыткы екстерны одказы одстранены почас едітованя", - "abusefilter-edit-builder-vars-old-text": "Старый вікітекст, перед едітованым сторінкы", - "abusefilter-edit-builder-vars-new-text": "Новый вікітекст, по едітованю сторінкы", - "abusefilter-edit-builder-vars-new-text-stripped": "Новый текст сторінкы очіщеный од форматованя", + "abusefilter-edit-builder-vars-old-wikitext": "Старый вікітекст, перед едітованым сторінкы", + "abusefilter-edit-builder-vars-new-wikitext": "Новый вікітекст, по едітованю сторінкы", + "abusefilter-edit-builder-vars-new-text": "Новый текст сторінкы очіщеный од форматованя", "abusefilter-edit-builder-vars-new-html": "Выґенерованый HTML код новой верзії", "abusefilter-edit-builder-vars-restrictions-edit": "Рівень замкнутя сторінкы про едітованя", "abusefilter-edit-builder-vars-restrictions-move": "Рівень замкнутя сторінкы про переменованя", "abusefilter-edit-builder-vars-restrictions-create": "Створити замок той сторінкы", "abusefilter-edit-builder-vars-restrictions-upload": "Уровень замку про наладованя файлу", - "abusefilter-edit-builder-vars-old-text-stripped": "Старый текст сторінкы очіщеный од вшыткых значок", + "abusefilter-edit-builder-vars-old-text": "Старый текст сторінкы очіщеный од вшыткых значок", "abusefilter-edit-builder-vars-old-links": "Одказы на сторінцї перед едітованём", "abusefilter-edit-builder-vars-old-html": "Вікітекст старой сторінкы, перетвореный до HTML", "abusefilter-edit-builder-vars-minor-edit": "Ці было едітованя означене як мале", @@ -361,7 +359,6 @@ "abusefilter-topnav-examine": "Перевірити минулы едітованя", "abusefilter-topnav-log": "Лоґ знеужываня", "abusefilter-topnav-tools": "Інштрументы ладжіня", - "abusefilter-topnav-import": "Імпорт філтру", "abusefilter-log-name": "Лоґ філтра знеужываня", "abusefilter-log-header": "Тот лоґ обсягує перегляд змін філтрів.\nДетайлы найдете у [[Special:AbuseFilter/history|списки послїднїх змін філтрів]].", "abusefilter-log-noresults": "Жадны ресултаты", diff --git a/AbuseFilter/i18n/sa.json b/AbuseFilter/i18n/sa.json index 8e8d5be3..e0ad14ee 100644 --- a/AbuseFilter/i18n/sa.json +++ b/AbuseFilter/i18n/sa.json @@ -3,18 +3,18 @@ "authors": [ "Ansumang", "Hemant wikikosh1", - "Shubha", - "NehalDaveND" + "NehalDaveND", + "Shubha" ] }, - "abuselog": "दुरुपयुक्तम् अङ्कनम्", + "abusefilter": "दुरुपयुक्तशोधकस्य प्रबन्धनम्", "abusefilter-blocker": "दुरुपयुक्तं शोधकम्", "abusefilter-blockreason": "दुरुपयोगनिःस्यन्दकद्वारा स्वतः एव निरोधितम्।\nसङ्गतस्य नियमस्य वर्णनम्:$1", "abusefilter-accountreserved": "दुरुपयुक्तस्य शोधकस्य कृते उपयोगाय इदं सदस्यनाम आरक्षितं वर्तते ।", "right-abusefilter-modify": "दुरुपयुक्तानि शोधकानि संशोध्यन्ताम्", "right-abusefilter-view": "दुरुपयुक्तानि शोधकानि दृश्यन्ताम्", "right-abusefilter-log": "दुरुपयुक्तम् अङ्कनं दृश्यताम्", - "right-abusefilter-private": "दुरुपयुक्ते अङ्कने वैयक्तिकः दत्तांशः दृश्यताम्", + "right-abusefilter-privatedetails": "दुरुपयुक्ते अङ्कने वैयक्तिकः दत्तांशः दृश्यताम्", "right-abusefilter-modify-restricted": "निर्बन्धक्रियानां द्वारा दुरुपयुक्ताः शोधकाः परिवर्त्यन्ताम्", "right-abusefilter-revert": "निर्दिष्टेन दुरुपयुक्तेन शोधकेन सर्वाणि पूर्वतनानि परिवर्तनानि आनीयन्ताम्", "action-abusefilter-modify": "दुरुपयुक्तानि शोधकानि संशोध्यन्ताम्", @@ -34,17 +34,15 @@ "abusefilter-log-details-var": "भङ्गुरम्", "abusefilter-log-details-val": "मूल्यम्", "abusefilter-log-details-vars": "कार्यस्य परिमितिः", - "abusefilter-log-details-private": "वैयक्तिकः दत्तांशः", + "abusefilter-log-details-privatedetails": "वैयक्तिकः दत्तांशः", "abusefilter-log-noactions": "नास्ति", "abusefilter-log-details-diff": "सम्पादने कृतानि परिवर्तनानि", "abusefilter-log-linkoncontribs": "दुरुपयुक्तम् अङ्कनम्", "abusefilter-log-linkoncontribs-text": "अस्य सदस्यस्य दुरुपयुक्तम् अङ्कनम्", - "abusefilter-log-hidden": "(प्रवेशः विलोपितः)", "abusefilter-log-cannot-see-details": "अस्य विवरणं ज्ञातुं भवतः अनुमतिः न विद्यते ।", "abusefilter-log-details-hidden": "अस्य विवरणानि भवान् द्रष्टुं नार्हति यतः इदं सार्वजनिकवीक्षणात् गुहितम् ।", "abusefilter-log-hide-hidden": "सार्वजनिकदर्शनात् अयं प्रवेशः विलोप्यताम्", "abusefilter-log-hide-reason": "कारणम् :", - "abusefilter-management": "दुरुपयुक्तशोधकस्य प्रबन्धनम्", "abusefilter-list": "सर्वे शोधकाः", "abusefilter-list-id": "शोधकस्य अभिज्ञापकम् :", "abusefilter-list-status": "स्थितिः", @@ -64,6 +62,7 @@ "abusefilter-disabled": "निष्क्रियः", "abusefilter-hitcount": "$1 {{PLURAL:$1|सम्पादनम्|सम्पादनानि}}", "abusefilter-new": "नूतनः शोधकः सृज्यताम्", + "abusefilter-import-button": "शोधकायातः", "abusefilter-return": "शोधकप्रबन्धनं प्रति निवर्त्यताम्", "abusefilter-status-global": "वैश्विकम्", "abusefilter-list-options": "विकल्पाः", @@ -172,7 +171,6 @@ "abusefilter-topnav-test": "समूहपरीक्षणम्", "abusefilter-topnav-examine": "पूर्वतनसम्पादनानि परीक्ष्यन्ताम्", "abusefilter-topnav-log": "दुरुपयुक्तम् अङ्कनम्", - "abusefilter-topnav-import": "शोधकायातः", "abusefilter-log-name": "दुरुपयुक्तशोधकस्य वृत्तम्", "abusefilter-log-noresults": "फलितानि न सन्ति", "abusefilter-diff-title": "संस्करणानां भेदाः", diff --git a/AbuseFilter/i18n/sah.json b/AbuseFilter/i18n/sah.json index 69803fd2..6643127a 100644 --- a/AbuseFilter/i18n/sah.json +++ b/AbuseFilter/i18n/sah.json @@ -6,8 +6,8 @@ ] }, "abusefilter-desc": "Көннөрүүлэргэ эвристика сиидэлэрин (фильтрдарын) туһанарга туттуллар", - "abusefilter": "Аһара түһүү фильтрын туоруоруута", - "abuselog": "Аһара түһүү (злоупотребление) сурунаала", + "abusefilter": "Омсо сиидэтин салайыы", + "abuselog": "Омсо сиидэтин сурунаала", "abusefilter-intro": "Омсо сиидэтин сирэйигэр нөрүөн нөргүй.\nОмсо сиидэтэ кыттааччылар уларытыыларын аптамаатынан хамсатар устуука буолар.\nМанна туруоруллубут сиидэлэр бары көстөллөр, уларытыахха сөп.", "abusefilter-warning": "'''Болҕой''': Бу дьайыыҥ аптамаатынан омсолоох курдук бэлиэтэммит.\nТуһата суох көннөрүүлэриҥ түргэнник сотуллуохтара,\nоннук көннөрүүҥ бөдөҥ эбэтэр хаста да оҥоһуллубут буоллаҕына аатыҥ эбэтэр IP-аадырыҥ хааччахтаныа.\nОл эрээри, туһалаах дьайыыны оҥороргун эрэнэр буоллаххына, өссө биирдэ ыытар эбэтэр бигэргэтэр тимэҕи баттаа.\nЭн оҥорбут дьайыыгын кытта ситимнэммит сиэр кылгас ис хоһооно: $1", "abusefilter-disallowed": "Бу дьайыы апатамаатынан омсолоох курдук бэлиэтэммит,\nонон бобуллубут.\nОл гынан баран, туһалаах көннөрүүнү оҥордум диэн эрэнэр буоллаххына, дьаһабылга тахсан тугу гынаары гынаргын кэпсээ.\nЭн оҥорбут дьайыыгын кытта ситимнэммит аһара түһүү кылгас ис хоһооно: $1", @@ -22,7 +22,7 @@ "right-abusefilter-view": "Омсо сиидэлэрин көрүү", "right-abusefilter-log": "Омсолоох дьайыылар сурунаалларын көрүү", "right-abusefilter-log-detail": "Омсолоох дьайыылар сурунаалларын сиһилии көрүү", - "right-abusefilter-private": "Омсолоох дьайыылар сурунаалларыгар кистэнэр тус сибидиэнньэлэри көрүү", + "right-abusefilter-privatedetails": "Омсолоох дьайыылар сурунаалларыгар кистэнэр тус сибидиэнньэлэри көрүү", "right-abusefilter-modify-restricted": "Хааччахтыыр сиидэлэри уларытыы", "right-abusefilter-revert": "Омсо сиидэтэ оҥорбут уларытыытын төннөр", "right-abusefilter-view-private": "Кистэммит омсо сиидэлэрин көрүү", @@ -34,11 +34,10 @@ "action-abusefilter-view": "омсо сиидэтин көрүү", "action-abusefilter-log": "омсо сиидэтин сурунаалын көрүү", "action-abusefilter-log-detail": "омсо сиидэтин сурунаалын ымпыктаан-чымпыктаан көрүү", - "action-abusefilter-private": "омсо сиидэтин сурунаалыгар тус дааннайдары көрүү", + "action-abusefilter-privatedetails": "омсо сиидэтин сурунаалыгар тус дааннайдары көрүү", "action-abusefilter-modify-restricted": "бобор/хааччахтыыр сиидэлэри уларытыы", "action-abusefilter-revert": "бу сиидэ уларытыыларын барытын оннугар төннөрүү", "action-abusefilter-view-private": "кистэммит омсо сиидэлэрин көрүү", - "abusefilter-log": "Омсо сиидэтин сурунаала", "abusefilter-log-summary": "Бу сурунаалга сиидэлэр булбут дьайыылара барыта көрдөрүлүннэ.", "abusefilter-log-search": "Омсо сурунаалыгар көрдөөһүн", "abusefilter-log-search-user": "Кыттааччы:", @@ -57,13 +56,12 @@ "abusefilter-log-details-var": "Уларыйар кэриҥ (переменная)", "abusefilter-log-details-val": "Суолтата", "abusefilter-log-details-vars": "Дьайыы кээмэйдэрэ", - "abusefilter-log-details-private": "Кистэлэҥ билии (данные)", + "abusefilter-log-details-privatedetails": "Кистэлэҥ билии (данные)", "abusefilter-log-details-ip": "Таска тахсар IP", "abusefilter-log-noactions": "суох", "abusefilter-log-details-diff": "Уларытыы уратылара", "abusefilter-log-linkoncontribs": "омсо сурунаала", "abusefilter-log-linkoncontribs-text": "Омсо сурунаалын бу кыттааччыга сыһыаннаах суруктара", - "abusefilter-log-hidden": "(сурук кистэннэ)", "abusefilter-log-hidden-implicit": "(көннөрүү сотуллубут буолан кистэммит)", "abusefilter-log-cannot-see-details": "Бу сурук туһунан сиһилии көрөр кыаҕыҥ суох эбит.", "abusefilter-log-details-hidden": "Бу суругу, кистэммит буолан, сиһилии көрөр кыах суох.", @@ -72,7 +70,6 @@ "abusefilter-log-hide-hidden": "Бу суругу аһаҕастык көрүүттэн кистээ", "abusefilter-log-hide-reason": "Төрүөтэ:", "abusefilter-log-hide-forbidden": "Омсо сурунаалын суруктарын кистиир быраабыҥ суох эбит.", - "abusefilter-management": "Омсо сиидэтин салайыы", "abusefilter-list": "Бары сиидэлэр", "abusefilter-list-id": "Сиидэ нүөмэрэ", "abusefilter-list-status": "Туруга", @@ -92,6 +89,7 @@ "abusefilter-disabled": "Холбоммотох", "abusefilter-hitcount": "$1 {{PLURAL:$1|ахсаан|ахсааннаах}}", "abusefilter-new": "Саҥа сиидэни оҥоруу", + "abusefilter-import-button": "Сиидэни импортааһын", "abusefilter-return": "Сиидэни салайыыга төннүү", "abusefilter-status-global": "Аан (глобальнай)", "abusefilter-list-options": "Туруоруулар", @@ -120,7 +118,6 @@ "abusefilter-edit-oldwarning": "<strong>Сиидэ эргэ барылын уларыттыҥ.\nСтатиистика сиидэ бүтэһик эрэр барылыгар олоҕурар.\nОнорбут уларытыыгын бигэргэттэххинэ, урут оҥоһуллубут уларытыллыа.</strong> •\n[[Special:AbuseFilter/history/$2|Сиидэ устуоруйатын сирэйигэр төннүү]].", "abusefilter-edit-status-label": "Статистиката:", "abusefilter-edit-status": "Бүтэһик $1 {{PLURAL:$1|дьайыыттан|дьайыылартан}}, бу сиидэ $2 ($3%) сөп түбэһэр.", - "abusefilter-edit-status-profile": "Бүтэһик $1 {{PLURAL:$1|дьайыыттан|дьайыылартан}}, бу сиидэ $2 ($3%) сөп түбэһэр.\nКини үлэтэ ортотунан — $4 мс, усулуобуйа лимиититтэн $5 {{PLURAL:$5|усулуобуйаны|усулуобуйатын}} туттар.", "abusefilter-edit-new": "Саҥа сиидэ", "abusefilter-edit-save": "Сиидэни бигэргэт", "abusefilter-edit-id": "Сиидэ нүөмэрэ:", @@ -254,14 +251,14 @@ "abusefilter-edit-builder-vars-all-links": "Саҥа тиэкискэ/сурукка тас сигэлэр барыта", "abusefilter-edit-builder-vars-added-links": "Уларытыы түмүгэр эбиллибит тас сигэлэр", "abusefilter-edit-builder-vars-removed-links": "Уларытыы түмүгэр сотуллубут тас сигэлэр", - "abusefilter-edit-builder-vars-old-text": "Уларытыах иннинээҕи, эргэ биики тиэкис", - "abusefilter-edit-builder-vars-new-text": "Уларыппыт кэннэ, саҥа биики тиэкис", - "abusefilter-edit-builder-vars-new-text-stripped": "Анал бэлиэлэрэ (разметката) суох саҥа тиэкис", + "abusefilter-edit-builder-vars-old-wikitext": "Уларытыах иннинээҕи, эргэ биики тиэкис", + "abusefilter-edit-builder-vars-new-wikitext": "Уларыппыт кэннэ, саҥа биики тиэкис", + "abusefilter-edit-builder-vars-new-text": "Анал бэлиэлэрэ (разметката) суох саҥа тиэкис", "abusefilter-edit-builder-vars-new-html": "Саҥа барыл HTML-куода (parsed, разобранный)", "abusefilter-edit-builder-vars-restrictions-edit": "Сирэй уларытыыттан көмүскэлин таһыма", "abusefilter-edit-builder-vars-restrictions-move": "Сирэй аатын уларытыыттан көмүскэлин таһыма", "abusefilter-edit-builder-vars-restrictions-upload": "Билэ хачайданыыттан көмүскэлэ", - "abusefilter-edit-builder-vars-old-text-stripped": "Эргэ сирэй тиэкиһэ, анал бэлиэлэрэ (разметката) суох", + "abusefilter-edit-builder-vars-old-text": "Эргэ сирэй тиэкиһэ, анал бэлиэлэрэ (разметката) суох", "abusefilter-edit-builder-vars-old-links": "Көннөрүөх иннинэ сирэйгэ баар сигэлэр", "abusefilter-edit-builder-vars-old-html": "Эргэ сирэй биики тиэкиһэ, HTML-га көһөрүллүбүтэ", "abusefilter-edit-builder-vars-minor-edit": "\"Кыра суолталаах\" уларыйыы курдук бэлиэтэммит дуо", @@ -355,7 +352,6 @@ "abusefilter-topnav-examine": "Бүтэһик улартыылары үөрэтии", "abusefilter-topnav-log": "Омсо сурунаала", "abusefilter-topnav-tools": "Өрөмүөн сэбиргэлэ", - "abusefilter-topnav-import": "Сиидэни импортааһын", "abusefilter-log-name": "Омсо сиидэтин сурунаала", "abusefilter-log-header": "Бу сурунаалга туох баар сиидэлэргэ оҥоһуллубут улартыылар суруллаллар.\nСиһилии сиидэлэр кэнники улартыыларын [[Special:AbuseFilter/history|тиһигэр]] көрүөххүн сөп.", "abusefilter-log-noresults": "Туох да көстүбэтэ", diff --git a/AbuseFilter/i18n/sc.json b/AbuseFilter/i18n/sc.json index 7af2d0e4..91b25cac 100644 --- a/AbuseFilter/i18n/sc.json +++ b/AbuseFilter/i18n/sc.json @@ -2,21 +2,20 @@ "@metadata": { "authors": [ "Andria", - "Uharteko", - "Taxandru" + "Taxandru", + "Uharteko" ] }, - "abuselog": "Registru de is abusos", + "abuselog": "Registru de su filtru contra s'abusu", "abusefilter-blocker": "Filtru contra s'abusu", "right-abusefilter-modify": "Acontza is filtros contra s'abusu", "right-abusefilter-view": "Ammustra is filtros contra s'abusu", "right-abusefilter-log": "Ammustra su registru de is abusos", - "right-abusefilter-private": "Ammustra is datos privados in su registru de is abusos", + "right-abusefilter-privatedetails": "Ammustra is datos privados in su registru de is abusos", "action-abusefilter-modify": "acontza is filtros contra s'abusu", "action-abusefilter-view": "ammustra is filtros contra s'abusu", "action-abusefilter-log": "ammustra su registru de is abusos", - "action-abusefilter-private": "ammustra is datos privados in su registru de is abusos", - "abusefilter-log": "Registru de su filtru contra s'abusu", + "action-abusefilter-privatedetails": "ammustra is datos privados in su registru de is abusos", "abusefilter-log-search": "Chirca in su registru de su filtru contra s'abusu", "abusefilter-log-search-user": "Impitadore:", "abusefilter-log-search-filter": "ID filtru (separadas dae \"|\"):", @@ -25,6 +24,6 @@ "abusefilter-log-detailedentry-global": "filtru globale $1", "abusefilter-log-detailedentry-local": "filtru $1", "abusefilter-log-detailslink": "particulares", - "abusefilter-log-details-private": "Datos privados", + "abusefilter-log-details-privatedetails": "Datos privados", "abusefilter-log-noactions": "peruna" } diff --git a/AbuseFilter/i18n/scn.json b/AbuseFilter/i18n/scn.json index 4e2a9a53..b2a75135 100644 --- a/AbuseFilter/i18n/scn.json +++ b/AbuseFilter/i18n/scn.json @@ -2,14 +2,15 @@ "@metadata": { "authors": [ "Aushulz", + "Fitoschido", "Gmelfi", "Pippinu", "Sarvaturi" ] }, "abusefilter-desc": "Fa' cuntrolli autumàtici di tipu eurìsticu supra dî canciamenti", - "abusefilter": "Cunfigurazzioni dû filtru anti-abbusi", - "abuselog": "Riggistru di l'abbusi", + "abusefilter": "Gistioni dû filtru anti-abbusi", + "abuselog": "Riggistru dû filtru anti-abbusi", "abusefilter-intro": "Bimminutu ntâ ntirfaccia di gistioni dû filtru anti-abbusi.\nLu filtru anti-abbusi è nu miccanismu software autumatizzatu chi àpprica cuntrolli di tipu eurìsticu supra a tutti l'azzioni ca si fannu.\nSta ntirfaccia ammustra na lista di li filtri difinuti, e cunzenti di canciàrili.", "abusefilter-warning": "'''Accura:''' St'azzioni fu idintificata di manera autumàtica comu n'azzioni dannìfica.\nLi canciamenti ca nun sunnu custruttivi vèninu annullati vittivitti, e fari canciamenti ca nun sunnu custruttivi di manera palisi e arripituta è mutivu di bloccu dû tò cuntu o dû tò nnirizzu IP.\nSi penzi ca pi daveru st'azzioni è custruttiva, la poi mannari n'àutra vota pi cunfirmàrila.\nNu riassuntu dâ règula anti-abbusi ca fu viulata dâ tò azzioni è: $1", "abusefilter-disallowed": "St'azzioni fu idintificata di manera autumàtica comu n'azzioni dannìfica, e dunca nun fu cunzintuta.\nSi penzi ca mmeci st'azzioni è custruttiva, pi favuri nforma a n'amministraturi di zocchi stai pruvannu a fari.\nNu riassuntu dâ règula anti-abbusi ca fu viulata dâ tò azzioni è: $1", @@ -24,7 +25,7 @@ "right-abusefilter-view": "Taliari li filtri anti-abbusi", "right-abusefilter-log": "Taliari lu riggistru di l'abbusi", "right-abusefilter-log-detail": "Taliari ntô dittagghiu li vuci dû riggistru di l'abbusi", - "right-abusefilter-private": "Taliari li dati risirvati prisenti ntô riggistru di l'abbusi", + "right-abusefilter-privatedetails": "Taliari li dati risirvati prisenti ntô riggistru di l'abbusi", "right-abusefilter-modify-restricted": "Canciari li filtri anti-abbusi ca fannu azzioni risirvati", "right-abusefilter-revert": "Annullari tutti li canciamenti fatti dûn filtru anti-abbusi", "right-abusefilter-view-private": "Taliari li filtri anti-abbusi marcati comu privati", @@ -36,11 +37,10 @@ "action-abusefilter-view": "taliari li filtri anti-abbusi", "action-abusefilter-log": "taliari lu riggistru di l'abbusi", "action-abusefilter-log-detail": "taliari ntô dittagghiu li vuci dû riggistru di l'abbusi", - "action-abusefilter-private": "taliari li dati risirvati prisenti ntô riggistru di l'abbusi", + "action-abusefilter-privatedetails": "taliari li dati risirvati prisenti ntô riggistru di l'abbusi", "action-abusefilter-modify-restricted": "canciari li filtri anti-abbusi ca fannu azzioni risirvati", "action-abusefilter-revert": "annullari tutti li canciamenti fatti dûn filtru anti-abbusi", "action-abusefilter-view-private": "taliari li filtri anti-abbusi marcati comu privati", - "abusefilter-log": "Riggistru dû filtru anti-abbusi", "abusefilter-log-summary": "Stu riggistru ammustra n'elencu di tutti l'azzioni ntircittati dî filtri.", "abusefilter-log-search": "Cerca ntô riggistru di l'abbusi", "abusefilter-log-search-user": "Utenti:", @@ -60,13 +60,12 @@ "abusefilter-log-details-var": "Variàbbili", "abusefilter-log-details-val": "Valuri", "abusefilter-log-details-vars": "Paràmitri di l’azzioni", - "abusefilter-log-details-private": "Dati risirvati", + "abusefilter-log-details-privatedetails": "Dati risirvati", "abusefilter-log-details-ip": "Nnirizzu IP di pruvinenza", "abusefilter-log-noactions": "nudda", "abusefilter-log-details-diff": "Canciamenti fatti", "abusefilter-log-linkoncontribs": "riggistru di l'abbusi", "abusefilter-log-linkoncontribs-text": "Riggistru di l'abbusi addibbitati a st'utenti", - "abusefilter-log-hidden": "(vuci ammucciata)", "abusefilter-log-hidden-implicit": "(ammucciata pirchì la virsioni fu cancillata)", "abusefilter-log-cannot-see-details": "Nun hai lu pirmissu di vìdiri li dittagghî di sta vuci.", "abusefilter-log-details-hidden": "Nun poi vìdiri li dittagghî di sta vuci pirchì veni ammucciata dû pùbblicu.", @@ -77,7 +76,6 @@ "abusefilter-log-hide-reason": "Mutivu:", "abusefilter-log-hide-forbidden": "Nun hai lu pirmissu d'ammucciari li vuci dû riggistru di l'abbusi.", "logentry-abusefilter-hit": "$1 fici scattari $4, ntô fari l'azzioni «$5» nta $3. Misuri pigghiati: $6 ($7)", - "abusefilter-management": "Gistioni dû filtru anti-abbusi", "abusefilter-list": "Tutti li filtri", "abusefilter-list-id": "ID dû filtru", "abusefilter-list-status": "Statu", @@ -97,6 +95,7 @@ "abusefilter-disabled": "Disattivatu", "abusefilter-hitcount": "$1 {{PLURAL:$1|trasuta|trasuti}} n funzioni", "abusefilter-new": "Crea nu filtru novu", + "abusefilter-import-button": "Mporta nu filtru", "abusefilter-return": "Torna â gistioni dî filtri", "abusefilter-status-global": "Glubbali", "abusefilter-list-options": "Opzioni", @@ -262,18 +261,18 @@ "abusefilter-edit-builder-vars-all-links": "Tutti li liami pi fora ntô testu novu", "abusefilter-edit-builder-vars-added-links": "Tutti li liami pi fora agghiunciuti ntô canciamentu", "abusefilter-edit-builder-vars-removed-links": "Tutti li liami pi fora livati ntô canciamentu", - "abusefilter-edit-builder-vars-old-text": "Wikitestu vecchiu dâ pàggina, avanti dû canciamentu", - "abusefilter-edit-builder-vars-new-text": "Wikitestu novu dâ pàggina, appressu dû canciamentu", + "abusefilter-edit-builder-vars-old-wikitext": "Wikitestu vecchiu dâ pàggina, avanti dû canciamentu", + "abusefilter-edit-builder-vars-new-wikitext": "Wikitestu novu dâ pàggina, appressu dû canciamentu", "abusefilter-edit-builder-vars-new-pst": "Wikitestu dâ pàggina nova, appressu dâ trasfurmazzioni prima dô sarvamentu", "abusefilter-edit-builder-vars-diff-pst": "Diff unificata dî canciamenti fatti ntô canciamentu, appressu â trasfurmazzioni prima dô sarvamentu", "abusefilter-edit-builder-vars-addedlines-pst": "Nùmmiru di righi agghiunciuti ntô canciamentu, appressu dâ trasfurmazzioni prima dô sarvamentu", - "abusefilter-edit-builder-vars-new-text-stripped": "Testu novu dâ pàggina, cu tutta la furmattazzioni livata", + "abusefilter-edit-builder-vars-new-text": "Testu novu dâ pàggina, cu tutta la furmattazzioni livata", "abusefilter-edit-builder-vars-new-html": "Surgenti HTML labburatu dâ virsioni nova", "abusefilter-edit-builder-vars-restrictions-edit": "Liveddu di prutizzioni pû canciamentu dâ pàggina", "abusefilter-edit-builder-vars-restrictions-move": "Liveddu di prutizzioni pû spustamentu dâ pàggina", "abusefilter-edit-builder-vars-restrictions-create": "Liveddu di prutizzioni pâ criazzioni dâ pàggina", "abusefilter-edit-builder-vars-restrictions-upload": "Liveddu di prutizzioni pû carricamentu dû file", - "abusefilter-edit-builder-vars-old-text-stripped": "Testu vecchiu dâ pàggina, cu tutta la furmattazzioni livata", + "abusefilter-edit-builder-vars-old-text": "Testu vecchiu dâ pàggina, cu tutta la furmattazzioni livata", "abusefilter-edit-builder-vars-old-links": "Liami ntâ pàggina, avanti dû canciamentu", "abusefilter-edit-builder-vars-old-html": "Wikitestu dâ pàggina vecchia, labburatu n HTML", "abusefilter-edit-builder-vars-minor-edit": "Si stu canciamentu è signatu comu nicu o puru no", @@ -311,7 +310,7 @@ "abusefilter-exception-dividebyzero": "Divisioni nun vàlida di nu $2 pi zeru ô caràttiri $1.", "abusefilter-exception-unrecognisedvar": "Variàbbili scanusciuta «$2» ô caràttiri $1.", "abusefilter-exception-notenoughargs": "Sunnu passati troppu picca argumenti â funzioni «$2» quannu veni chiamata ô caràttiri $1.\n\tCi nni {{PLURAL:$3|voli|vonnu}} $3, nn'havi $4", - "abusefilter-exception-regexfailure": "Erruri ntâ sprissioni rigulari «$3» ô caràttiri $1: «$2»", + "abusefilter-exception-regexfailure": "Erruri ntâ sprissioni rigulari «$2» ô caràttiri $1.", "abusefilter-exception-overridebuiltin": "Suprascrittura nun cunzintuta dâ variàbbili ncurpurata «$2» ô caràttiri $1.", "abusefilter-exception-outofbounds": "Veni addumannatu di na lista l'elimentu $2 ca nun esisti (lunghizza dâ lista = $3), ô caràttiri $1.", "abusefilter-exception-notarray": "Veni addumannatu l’elementu dûn vitturi nta na cosa ca nun è un vitturi, ô caràttiri $1.", @@ -372,7 +371,6 @@ "abusefilter-topnav-examine": "Esàmina li canciamenti passati", "abusefilter-topnav-log": "Riggistru di l'abbusi", "abusefilter-topnav-tools": "Strummenti di debug", - "abusefilter-topnav-import": "Mporta nu filtru", "abusefilter-log-name": "Riggistru dû filtru anti-abbusi", "abusefilter-log-header": "Stu riggistru ammustra nu riassuntu dî canciamenti ca foru fatti ntê filtri.\nPî dittagghî cumpleti, talìa [[Special:AbuseFilter/history|l'elencu]] dî canciamenti ricenti.", "abusefilter-log-noresults": "Nuddu risurtatu", diff --git a/AbuseFilter/i18n/sco.json b/AbuseFilter/i18n/sco.json index 0afbd34b..e66bd707 100644 --- a/AbuseFilter/i18n/sco.json +++ b/AbuseFilter/i18n/sco.json @@ -5,8 +5,6 @@ ] }, "abusefilter-desc": "Applies autæmatic heuristics til edits", - "abusefilter": "Abuiss filter confeeguration", - "abuselog": "Abuiss log", "abusefilter-intro": "Weelcome til the Abuiss Filter management interface.\nThe Abuiss Filter is aen autæmated saffware mechanism o appliein autæmatic heuristics til aw actions.\nThis interface shaws ae leet o defined filters, n permits thaim tae be modified.", "abusefilter-warning": "'''Warnishment:''' This action haes been autæmaticlie ideentified aes harmful.\nOnconstructeeve eedits will be quicklie reverted, n egregioos or repeated onconstructeeve eeeditin will result in yer accoont or IP address bein blockit.\nGif ye true this action tae be constructeeve, ye can haun it in again tae confirm it.\nAe brief descreeption o the abuiss rule that yer action matched is: $1", "abusefilter-log-search-filter": "Filter IDs (separate wi pipes):", diff --git a/AbuseFilter/i18n/sd.json b/AbuseFilter/i18n/sd.json index 484c745d..f6441347 100644 --- a/AbuseFilter/i18n/sd.json +++ b/AbuseFilter/i18n/sd.json @@ -1,40 +1,76 @@ { "@metadata": { "authors": [ - "Mehtab ahmed", "Indus Asia", + "Mehtab ahmed", "Saraiki" ] }, - "abuselog": "غلط-استعمال لاگ", + "abuselog": "غلط-استعمال ڇاڻي لاگ", "abusefilter-blocker": "غلط-استعمال ڇاڻي", "right-abusefilter-modify": "غلط-استعمال ڇاڻين کي بدلايو", "right-abusefilter-view": "غلط-استعمال ڇاڻيون ڏيکاريو", "right-abusefilter-log": "غلط-استعمال لاگ ڏيکاريو", "right-abusefilter-log-detail": "غلط-استعمال لاگ جون ڊگھيون داخلائون ڏيکاريو", - "right-abusefilter-private": "غلط-استعمال لاگ ۾ خانگي مودا ڏيکاريو", + "right-abusefilter-privatedetails": "غلط-استعمال لاگ ۾ خانگي مودا ڏيکاريو", "right-abusefilter-hide-log": "غلط-استعمال لاگ ۾ داخلائون لڪايو", "right-abusefilter-hidden-log": "غلط-استعمال لاگ جون لڪيل داخلائون ڏيکاريو", "action-abusefilter-modify": "غلط-استعمال ڇاڻيون بدلايو", "action-abusefilter-view": "غلط-استعمال ڇاڻيون ڏيکاريو", "action-abusefilter-log": "غلط-استعمال لاگ ڏيکاريو", "action-abusefilter-log-detail": "غلط-استعمال لاگ جون ڊگھيون داخلائون ڏيکاريو", - "action-abusefilter-private": "غلط-استعمال لاگ ۾ خانگي مواد ڏيکاريو", - "abusefilter-log": "غلط-استعمال ڇاڻي لاگ", + "action-abusefilter-privatedetails": "غلط-استعمال لاگ ۾ خانگي مواد ڏيکاريو", "abusefilter-log-search": "غلط-استعمال لاگ ڳوليو", + "abusefilter-log-search-group-any": "ڪوبہ", + "abusefilter-log-search-action-taken-any": "ڪوبہ", + "abusefilter-log-noactions": "ڪوبہ نہ", "abusefilter-log-linkoncontribs": "غلط-استعمال لاگ", "abusefilter-log-linkoncontribs-text": "{{GENDER:$1|ھن واپرائيندڙ}} لاءِ غلط-استعمال لاگ", + "abusefilter-log-linkonhistory": "غلط-استعمال لاگ ڏسو", + "abusefilter-log-linkonhistory-text": "ھن صفحي لاءِ غلط-استعمال لاگ ڏسو", + "abusefilter-log-linkonundelete": "غلط-استعمال لاگ ڏسو", + "abusefilter-log-linkonundelete-text": "ھن صفحي لاءِ غلط-استعمال لاگ ڏسو", "abusefilter-log-hide-forbidden": "توھان کي غلط-استعمال لاگ جي داخلائن کي لڪائڻ جي اجازت ناھي.", - "abusefilter-edit-status-label": "انگ اکر:", + "abusefilter-list": "سڀ ڇاڻيو", + "abusefilter-list-id": "ڇاڻي آئڊي", + "abusefilter-list-status": "حالت", + "abusefilter-list-public": "عوامي تشريح", + "abusefilter-list-consequences": "نتيجا", + "abusefilter-list-visibility": "ظاھريت", + "abusefilter-list-edit": "سنواريو", + "abusefilter-list-details": "تفصيل", + "abusefilter-list-limit": "انگ في صفحو:", + "abusefilter-list-lastmodified": "آخري ڀيرو بدلايل", + "abusefilter-list-group": "گروھ ڇاڻي", + "abusefilter-hidden": "ذاتي", + "abusefilter-unhidden": "عوامي", + "abusefilter-enabled": "فعال", + "abusefilter-deleted": "ڊاھيل", + "abusefilter-disabled": "غيرفعال", + "abusefilter-new": "ڪا نئين ڇاڻي سرجيو", + "abusefilter-return": "ڇاڻي سنڀال ڏانھن ورو", + "abusefilter-status-global": "عالمي", + "abusefilter-list-options": "چارا", + "abusefilter-list-options-deleted": "ڊاھيل ڇاڻيون", + "abusefilter-list-options-deleted-only": "صرف ڊاھيل ڇاڻيو ڏيکاريو", + "abusefilter-list-options-deleted-hide": "ڊاھيل ڇاڻيون لڪايو", + "abusefilter-list-options-deleted-show": "ڊاھيل ڇاڻيو شامل ڪريو", + "abusefilter-list-options-scope": "ڇاڻيو ڏيکاريو:", + "abusefilter-list-options-scope-local": "صرف مقامي اصول", + "abusefilter-edit-status-label": "انگ-اکر:", + "abusefilter-throttle-page": "صفحو", + "abusefilter-throttle-none": "(ڪوبہ نہ)", "abusefilter-edit-disallow-actions": "عمل", "abusefilter-edit-tools": "اوزار:", - "abusefilter-history-diff": "تبديليون", + "abusefilter-edit-builder-vars-removedlines": "سنوار ۾ ھٽايل سٽون", + "abusefilter-history-diff": "بدلاءَ", "abusefilter-revert-confirm": "پڪ ڪريو", + "abusefilter-test-search-type-edit": "سنوارون", "abusefilter-examine-legend": "تبديليون چونڊيو", "abusefilter-examine-title": "صفحي جو عنوان:", - "abusefilter-topnav-examine": "پوين ترميمن کي تپاسيو", + "abusefilter-topnav-examine": "پويون سنوارون تپاسيو", "abusefilter-topnav-log": "غلط-استعمال لاگ", "abusefilter-log-name": "غلط-استعمال ڇاڻي لاگ", - "abusefilter-log-noresults": "ڪي به نتيجا ناھن", + "abusefilter-log-noresults": "نتيجا ناھن", "abusefilter-diff-item": "جزو" } diff --git a/AbuseFilter/i18n/sdc.json b/AbuseFilter/i18n/sdc.json index b703aff8..5b8fc894 100644 --- a/AbuseFilter/i18n/sdc.json +++ b/AbuseFilter/i18n/sdc.json @@ -4,11 +4,105 @@ "Jun Misugi" ] }, + "abusefilter": "Gisthioni di filthri d'abusu", + "abusefilter-blocker": "Filthru d'abusu", + "right-abusefilter-modify": "Mudifiggà filthri d'abusu", + "right-abusefilter-view": "Vidé filthri d'abusu", + "right-abusefilter-modify-global": "Crià o mudifiggà filthri d'abusu grobari", + "action-abusefilter-modify": "mudifiggà filthri d'abusu", + "action-abusefilter-view": "abbaiddà filthri d'abusu", + "action-abusefilter-modify-global": "crià o mudifiggà filthri d'abusu grobari", "abusefilter-log-search-user": "Utenti:", + "abusefilter-log-search-group": "Filthrà gruppu:", + "abusefilter-log-search-group-any": "Tutti", "abusefilter-log-search-title": "Tìturu", "abusefilter-log-search-wiki": "Vichi:", + "abusefilter-log-search-impact": "Effettu:", + "abusefilter-log-search-impact-all": "Tutti l'azioni", + "abusefilter-log-search-impact-saved": "Soru ciambamenti saivvaddi", + "abusefilter-log-search-impact-not-saved": "Chena ciambamenti saivvaddi", + "abusefilter-log-search-entries-label": "Visibiriddai:", + "abusefilter-log-search-action-other": "Althri", + "abusefilter-log-search-action-any": "Tutti", + "abusefilter-log-search-action-taken-any": "Tutti", "abusefilter-log-search-submit": "Zercha", + "abusefilter-log-detailedentry-global": "filthru grobari $1", + "abusefilter-log-detailedentry-local": "filthru $1", + "abusefilter-log-detailslink": "dettàglii", + "abusefilter-log-diff": "diffarènzia", + "abusefilter-log-details-checkuser": "Verifiggà l'utenti", + "abusefilter-log-noactions": "nisciuna", + "abusefilter-log-details-diff": "Ciambamenti da chistha mudìfigga", + "abusefilter-log-hide-reason": "Mutibazioni:", + "abusefilter-log-hide-reason-other": "Althra mutibazioni o mutibazioni aggiuntiba:", + "abusefilter-log-entry-suppress": "$1 {{GENDER:$2|cuadda}} $3", + "log-action-filter-abusefilter": "Tipu di lu ciambu di filthru:", + "log-action-filter-abusefilter-create": "Criazioni d'un nobu filthru", + "log-action-filter-abusefilter-modify": "Modìfica di filthru", + "abusefilter-list": "Tutti li filthri", + "abusefilter-list-pattern": "Taurozza basi", + "abusefilter-list-visibility": "Visibiriddai", "abusefilter-list-edit": "Mudifiggà", + "abusefilter-list-details": "Dettàglii", + "abusefilter-list-group": "Gruppu di filthru", + "abusefilter-unhidden": "Prùbbiggu", + "abusefilter-enabled": "Attibu", "abusefilter-deleted": "Canzilladdu", - "abusefilter-list-options-scope-local": "Vichi lucari" + "abusefilter-new": "Crià un nobu filthru", + "abusefilter-return": "Turrà a la gisthioni di filthri d'abusu", + "abusefilter-status-global": "Grobari", + "abusefilter-list-options": "Ozioni", + "abusefilter-list-options-deleted": "Filthri canzilladdi:", + "abusefilter-list-options-deleted-only": "Visuarizza soru filthri canzilladdi", + "abusefilter-list-options-deleted-hide": "Cuà filthri annulladdi", + "abusefilter-list-options-scope": "Musthrà filthri:", + "abusefilter-list-options-scope-local": "Soru réguri lucari", + "abusefilter-list-options-scope-global": "Soru réguri grobari", + "abusefilter-list-options-scope-all": "Réguri lucari e grobari", + "abusefilter-list-options-further-options": "Althri ozioni:", + "abusefilter-list-options-hidedisabled": "Cuà filthri chi no so attibi", + "abusefilter-list-options-hideprivate": "Cuà filthri pribaddi", + "abusefilter-list-options-searchfield": "Zirchà cunfòimmu li réguri:", + "abusefilter-list-options-searchpattern": "Insirì una taurozza basi", + "abusefilter-list-options-searchoptions": "Modu di zercha:", + "abusefilter-list-options-search-like": "Dumanda sémprizi", + "abusefilter-list-options-submit": "Attuarizà", + "abusefilter-tools-submitexpr": "Verifiggà", + "abusefilter-tools-reautoconfirm-user": "Utenti:", + "abusefilter-edit": "Mudifigghendi filthru d'abusu", + "abusefilter-edit-subtitle": "Mudifigghendi filthru $1", + "abusefilter-edit-subtitle-new": "Criendu filthru", + "abusefilter-edit-token-not-match": "La mudìfigga nò è isthadda saivvadda! Pa piazéri turrà a saivvà.", + "abusefilter-edit-status-label": "Sthatisthigghi:", + "abusefilter-edit-new": "Filthru novu", + "abusefilter-edit-save": "Saivva filthru", + "abusefilter-edit-field-description": "deschrizioni", + "abusefilter-edit-group": "Gruppu di filthru:", + "abusefilter-edit-enabled": "Attibà kisthu filthru", + "abusefilter-edit-global": "Filthru grobari", + "abusefilter-edit-rules": "Cundizioni:", + "abusefilter-edit-field-conditions": "cundizioni", + "abusefilter-edit-notes": "Noti:", + "abusefilter-edit-lastmod": "Ùlthima modìfica di lu filthru:", + "abusefilter-edit-lastmod-text": "$1 pai $2", + "abusefilter-edit-throttle-groups-help": "Vedi $1.", + "abusefilter-throttle-ip": "Indirizzu IP", + "abusefilter-throttle-user": "registhrazioni d'utenti", + "abusefilter-throttle-creationdate": "data di la criazioni registhrazioni", + "abusefilter-throttle-editcount": "cuntéggiu di li mudìfigghi", + "abusefilter-throttle-page": "pàgina", + "abusefilter-throttle-none": "(nisciuna)", + "abusefilter-edit-warn-other": "Althra imbasciadda", + "abusefilter-edit-warn-actions": "Azioni:", + "abusefilter-edit-disallow-other": "Althra imbasciadda", + "abusefilter-edit-disallow-actions": "Azioni:", + "abusefilter-block-anon": "Bruccà utenti anònimi", + "abusefilter-block-user": "bruccà utenti registhraddi", + "abusefilter-block-talk": "pàgina di dischussioni bruccadda", + "abusefilter-edit-done-subtitle": "Filthru mudifiggaddu", + "abusefilter-edit-history": "Cronologia:", + "abusefilter-edit-tools": "Isthrumenti:", + "abusefilter-edit-builder-op-comparison-lt": "Più minori di (<)", + "abusefilter-edit-builder-op-comparison-gt": "Più mannu di (>)", + "abusefilter-edit-builder-vars-action": "Azioni" } diff --git a/AbuseFilter/i18n/se.json b/AbuseFilter/i18n/se.json index 13fba2c2..d722b207 100644 --- a/AbuseFilter/i18n/se.json +++ b/AbuseFilter/i18n/se.json @@ -2,11 +2,13 @@ "@metadata": { "authors": [ "Jeblad", - "Linnea" + "Linnea", + "Yupik" ] }, - "abusefilter-log": "Boasttogeavahanfiltera logga", + "abuselog": "Boasttogeavahanfiltera logga", "abusefilter-deleted": "Sihkkojuvvon", + "abusefilter-edit-throttle-groups-help": "Geahča $1.", "abusefilter-history-deleted": "Sihkkojuvvon", "abusefilter-action-block": "Hehtte", "abusefilter-log-noresults": "Eai bohtosat" diff --git a/AbuseFilter/i18n/sh.json b/AbuseFilter/i18n/sh.json index 76f37a94..a3bd97ae 100644 --- a/AbuseFilter/i18n/sh.json +++ b/AbuseFilter/i18n/sh.json @@ -1,15 +1,19 @@ { "@metadata": { "authors": [ + "BadDog", + "Daimona Eaytoy", "Kolega2357", - "OC Ripper" + "OC Ripper", + "Vlad5250" ] }, - "abusefilter-desc": "Dodaje automatske heuristike izmjenama.", - "abusefilter": "Konfiguracija filtera za zloupotrebu", - "abuselog": "Evidencija zloupotreba", + "abusefilter-desc": "Izvršava automatsko heurističko filtriranje u izmenama", + "abusefilter": "Upravljanje filterom protiv zloupotrebe", + "abuselog": "Evidencija filtera zloupotrebe", "abusefilter-intro": "Dobrodošli u interfejs upravljanja filterom zloupotreba.\nFilter zloupotreba je automatizirani softverski mehanizam za pravljenje automatskih heuristika za sve akcije.\nOvaj interfejs prikazuje spisak napravljenih filtera i omogućuje Vam da ih prilagodite.", - "abusefilter-warning": "'''Upozorenje''': Ova akcija je automatski identificirana kao štetna.\nNekonstruktivna uređivanja biti će brzo uklonjena,\na prekomjerno ili ponovljeno nekonstruktivno uređivanje će uzrokovati da vaš račun ili IP adresa budu blokirani.\nUkoliko vjerujete da je vaše uređivanje konstruktivno, možete ga ponovo poslati da ga potvrdite.\nKratak opis pravila sprječavanja zloupotreaba koji se podudara s vašim uređivanjem je: $1", + "abusefilter-mustviewprivateoredit": "Iz sigurnosnih razloga, ovaj posrednik mogu koristiti samo korisnici s pravom gledanja osobnih filtera za zlouporabu ili izmjenu filtera.", + "abusefilter-warning": "'''Upozorenje''': Ova akcija je automatski identificirana kao štetna.\nNekonstruktivne akcije biti će brzo uklonjene,\na prekomjerno ili ponovljeno nekonstruktivno uređivanje će uzrokovati da vaš račun ili IP adresa budu blokirani.\nUkoliko vjerujete da je vaše uređivanje konstruktivno, možete ga ponovo poslati da ga potvrdite.\nKratak opis pravila sprječavanja zloupotreaba koji se podudara s vašim uređivanjem je: $1", "abusefilter-disallowed": "Ova akcija je automatski identificirana kao štetna, pa je stoga onemogućena.\nAko vjerujete da je uređivanje konstruktivno, molimo kontaktirajte administratora i obavijestite ga o tome što ste pokušali učiniti.\nKratak opis pravila spriječavanja zloupotrebe koji se podudara s vašim uređivanjem je: $1", "abusefilter-blocked-display": "Ova akcija je automatski identificirana kao opasna,\ni kao takva onemogućena da se izvrši.\nDodatno, da bi se zaštitio {{SITENAME}}, Vaš korisnički račun i sve pripadajuće IP adrese su blokirane za uređivanje.\nAko se desila greška, molimo da kontaktirate administratora.\nKratki opis prekršenih pravila koja odgovaraju Vašoj akciji je: $1", "abusefilter-degrouped": "Ova akcija je automatski prepoznata kao štetna.\nU skladu s tim je onemogućena, a sumnja se da je Vaš račun kompromitovan, sva Vaša prava su povučena.\nAko mislite da je ovo greška, molimo da kontaktirate birokratu sa objašnjenjem ove akcije te će tada Vaša prava biti vraćena.\nKratki opis kršenja pravila koja su prekršena Vašom akcijom je: $1", @@ -17,12 +21,14 @@ "abusefilter-blocker": "Filter zloupotreba", "abusefilter-blockreason": "Automatski blokirano od strane filtera za zloupoterbu. Opis povrijeđenog pravila: $1", "abusefilter-degroupreason": "Prava su automatski oduzeta od strane filtera za zloupotrebu. Opis pravila: $1", + "abusefilter-blockautopromotereason": "Samounapređivanje je automatski odloženo od strane filtera za zloupotrebu.\nOpis pravila: $1", "abusefilter-accountreserved": "Ovaj korisnički račun je rezervisan za upotrebu od strane filtera za zloupotrebu.", "right-abusefilter-modify": "Modificiraj filtere za zloupotrebu", "right-abusefilter-view": "Pogledaj filtere za zloupotrebu", "right-abusefilter-log": "Pogledaj evidenciju zloupotrebe", "right-abusefilter-log-detail": "Pogledaj detaljne unose u evidenciji zloupotrebe", - "right-abusefilter-private": "Pogledaj privatne podatke u evidenciji zloupotrebe.", + "right-abusefilter-privatedetails": "Pogledaj privatne podatke u evidenciji zloupotrebe.", + "right-abusefilter-privatedetails-log": "Pogledaj pristup osobnim dnevničkim podacima iz Filtra za zloupotrebu", "right-abusefilter-modify-restricted": "Mijenjanje filtera zloupotrebe sa ograničenim akcijama", "right-abusefilter-revert": "Vrati sve izmjene date od filtera zloupotreba", "right-abusefilter-view-private": "Pregled filtera zloupotrebe koji su označeni kao privatni", @@ -30,25 +36,45 @@ "right-abusefilter-hide-log": "Sakrij unose u evidenciji zloupotreba", "right-abusefilter-hidden-log": "Pogledaj skrivene unose u evidenciji zloupotreba", "right-abusefilter-modify-global": "Stvori ili promijeni globalni filter zloupotreba", - "action-abusefilter-modify": "Modificiraj filtere zloupotrebe", - "action-abusefilter-view": "Pogledaj filtere zloupotreba", - "action-abusefilter-log": "Pogledaj evidenciju zloupotreba", - "action-abusefilter-log-detail": "Vidi detaljne unose evidencije zloupotreba", - "action-abusefilter-private": "pregledanje ličnih podataka u izveštaju zloupotrebe", + "action-abusefilter-modify": "promijeni filtere zloupotrebe", + "action-abusefilter-view": "pregledanje filtere zloupotreba", + "action-abusefilter-log": "pregled evidencije zloupotreba", + "action-abusefilter-log-detail": "pregled detaljnih unosa evidencije zloupotreba", + "action-abusefilter-privatedetails": "pregledanje ličnih podataka u izveštaju zloupotrebe", + "action-abusefilter-privatedetails-log": "pregledanje pristupa osobnim dnevničkim podacima iz Filtra za zloupotrebu", "action-abusefilter-modify-restricted": "menjanje filtera protiv zloupotrebe s ograničenim radnjama", "action-abusefilter-revert": "vraćanje svih izmjena koje je napravio filter protiv zloupotrebe", "action-abusefilter-view-private": "pregledanje privatnih filtera protiv zloupotrebe", - "abusefilter-log": "Evidencija filtera zloupotrebe", - "abusefilter-log-summary": "Ovaj izveštaj prikazuje spisak svih akcija koje su izvršili filteri.", + "action-abusefilter-log-private": "pregled evidencija filtera zloupotreba označenih kao privatne", + "action-abusefilter-hide-log": "sakrij unose u evidenciji zloupotreba", + "action-abusefilter-hidden-log": "pogledaj skrivene unose u evidenciji zloupotreba", + "action-abusefilter-modify-global": "stvori ili promijeni globalni filter zloupotreba", + "abusefilter-log-summary": "Ova evidencija prikazuje spisak svih akcija uhvaćenih filtrima.", "abusefilter-log-search": "Pretraga izveštaja zloupotrebe", "abusefilter-log-search-user": "Korisnik:", - "abusefilter-log-search-filter": "'''MediaWiki:Abusefilter-log-search-filter/sh'''\nID filtera:", + "abusefilter-log-search-group": "Filterska grupa:", + "abusefilter-log-search-group-any": "Bilo koja", + "abusefilter-log-search-filter": "Naznake filtera:", + "abusefilter-log-search-filter-help": "Odijelite pravim crtima; i prefiksom \"$1\" za globalne filtre", "abusefilter-log-search-title": "Naslov:", "abusefilter-log-search-wiki": "Wiki:", + "abusefilter-log-search-impact": "Posljedica:", + "abusefilter-log-search-impact-all": "Sve radnje", + "abusefilter-log-search-impact-saved": "Samo spremljene izmjene", + "abusefilter-log-search-impact-not-saved": "Bez spremljenih izmjena", + "abusefilter-log-search-entries-label": "Vidljivost:", + "abusefilter-log-search-entries-all": "Sve stavke", + "abusefilter-log-search-entries-hidden": "Samo skrivene stavke", + "abusefilter-log-search-entries-visible": "Samo vidljive stavke", + "abusefilter-log-search-action-label": "Pokrenuta radnja:", + "abusefilter-log-search-action-other": "Ostalo", + "abusefilter-log-search-action-any": "Bilo koja", + "abusefilter-log-search-action-taken-label": "Poduzete radnje:", + "abusefilter-log-search-action-taken-any": "Bilo koja", "abusefilter-log-search-submit": "Pretraži", - "abusefilter-log-entry": "$1: $2 je aktivirao filter, izvodeći radnju „$3“ na stranici $4. Preduzete radnje: $5; Opis filtera: $6", - "abusefilter-log-entry-withdiff": "$1: Korisnik $2 je pokrenuo filter za zloupotrebu, napravivši akciju \"$3\" na stranici $4.\nNapravljena akcija: $5;\nOpis filtera: $6 ($7)", - "abusefilter-log-detailedentry-meta": "$1: $2 je aktivirao $3, izvodeći radnju „$4“ na stranici $5.\nPreduzete radnje: $6;\nOpis filtera: $7 ($8)", + "abusefilter-log-entry": "$1: $2 {{GENDER:$8|pokrenuo|pokrenula}} je filter protiv zloupotrebe, {{GENDER:$8|izvodeći}} radnju „$3“ na $4.\nPreduzete radnje: $5;\nOpis iz filtera: $6", + "abusefilter-log-entry-withdiff": "$1: $2 {{GENDER:$8|pokrenuo|pokrenula}} je filter za zloupotrebu, {{GENDER:$8|izvodeći}} radnju \"$3\" na $4.\nPoduzete radnje: $5;\nOpis iz filtera: $6 ($7)", + "abusefilter-log-detailedentry-meta": "$1: $2 {{GENDER:$9|pokrenuo|pokrenula}} je $3, {{GENDER:$9|izvodeći}} radnju „$4“ na $5.\nPreduzete radnje: $6;\nOpis iz filtera: $7 ($8)", "abusefilter-log-detailedentry-global": "globalni filter $1", "abusefilter-log-detailedentry-local": "filter $1", "abusefilter-log-detailslink": "detalji", @@ -58,42 +84,326 @@ "abusefilter-log-details-var": "Promjenjiva", "abusefilter-log-details-val": "Vrijednost", "abusefilter-log-details-vars": "Parametri akcije", - "abusefilter-log-details-private": "Privatni podaci", + "abusefilter-log-details-privatedetails": "Osobni dnevnički podaci", "abusefilter-log-details-ip": "Izvorna IP adresa", + "abusefilter-log-details-checkuser": "Provjeri korisnika", "abusefilter-log-noactions": "Ništa", "abusefilter-log-details-diff": "Izmene napravljene pri uređivanju", - "abusefilter-log-linkoncontribs": "Evidencija zloupotreba", - "abusefilter-log-linkoncontribs-text": "Izveštaj zloupotrebe ovog korisnika", - "abusefilter-log-hidden": "(unos je sakriven)", + "abusefilter-log-linkoncontribs": "evidencija zloupotreba", + "abusefilter-log-linkoncontribs-text": "Evidencija zloupotrebe za {{GENDER:$1|ovog korisnika|ovu korisnicu}}", + "abusefilter-log-linkonhistory": "vidi dnevnik zloupotrebe", + "abusefilter-log-linkonhistory-text": "Pogledajte dnevnik zloupotrebe ove stranice", + "abusefilter-log-linkonundelete": "vidi dnevnik zloupotrebe", + "abusefilter-log-linkonundelete-text": "Pogledajte dnevnik zloupotrebe ove stranice", + "abusefilter-log-hidden-implicit": "(sakriveno jer je izmjena obrisana)", "abusefilter-log-cannot-see-details": "Nemate ovlašćenje da vidite detalje ovog unosa.", - "abusefilter-log-details-hidden": "Ne možete da vidite detalje ovog filtera jer su sakriveni.", + "abusefilter-log-cannot-see-privatedetails": "Nemate ovlašćenje da vidite osobni podaci u stavci.", + "abusefilter-log-nonexistent": "Ne postoji stavka s naznačenom naznakom.", + "abusefilter-log-details-hidden": "Ne možete da vidite detalje ovog unosa jer su sakriveni.", + "abusefilter-log-details-hidden-implicit": "Ne možete vidjeti podrobnosti ovog unosa jer je njegova revizija skrivena.", + "abusefilter-log-private-not-included": "Jedna ili više filterskih naznaka koje ste naveli su osobne. Budući da vam nije dopušteno vidjeti podrobnosti osobnih filtera, ti se filtri ne koriste u pretraživanju.", + "abusefilter-log-hide-legend": "Sakrij stavku", + "abusefilter-log-hide-id": "ID unosa:", + "abusefilter-log-hide-hidden": "Sakrij ovaj unos od javnog pregleda", "abusefilter-log-hide-reason": "Razlog:", - "abusefilter-log-hide-forbidden": "Nemate dozvolu da sakrivate unose u izveštaju filtera zloupotrebe.", - "abusefilter-management": "Upravljanje filterom protiv zloupotrebe", + "abusefilter-log-hide-reason-other": "Ostali/dodatni razlog:", + "abusefilter-log-hide-forbidden": "Nemate dozvolu da sakrivate unose u evidenciji filtera zloupotrebe.", + "abusefilter-log-entry-suppress": "$1 {{GENDER:$2|ga skrio|skrila}} je $3", + "abusefilter-log-entry-unsuppress": "$1 {{GENDER:$2|ga odkrio|odkrila}} je $3", + "logentry-abusefilter-hit": "$1 je {{GENDER:$2|pokrenuo|pokrenula}} filter $4, {{GENDER:$2|izvodeći}} radnju \"$5\" na $3.\nPoduzete radnje: $6 ($7)", + "log-action-filter-abusefilter": "Vrsta promjene u filteru:", + "log-action-filter-abusefilter-create": "Pravljenje novog filtera", + "log-action-filter-abusefilter-modify": "Izmjena u filtru", + "log-action-filter-suppress-abuselog": "Potiskivanje evidencije zloupotrebe", + "log-action-filter-rights-blockautopromote": "Blok autounapređivanja", + "log-action-filter-rights-restoreautopromote": "Povratak autounapređivanja", + "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|pristupio|pristupila}} je osobnim podacima za $3", + "logentry-rights-blockautopromote": "$1 {{GENDER:$2|je blokirao|je blokirala}} autounapređivanje korisnika {{GENDER:$4|$3}} u trajanju od $5", + "logentry-rights-restoreautopromote": "$1 {{GENDER:$2|je povratio|je povratila}} mogućnost autounapređivanja korisnika {{GENDER:$4|$3}}", + "abusefilterprivatedetails-log-name": "Dnevnik pristupa osobnim podacima iz Filtra za zloupotrebu", "abusefilter-list": "Svi filteri", "abusefilter-list-id": "ID filtera", + "abusefilter-list-pattern": "Mostra", "abusefilter-list-status": "Status", + "abusefilter-list-public": "Javni opis", + "abusefilter-list-consequences": "Posljedice", + "abusefilter-list-visibility": "Vidljivost", + "abusefilter-list-hitcount": "Brojač pogodaka", + "abusefilter-list-edit": "Uredi", + "abusefilter-list-details": "Podrobno", + "abusefilter-list-limit": "Broj po stranici:", + "abusefilter-list-lastmodified": "Posljednja promjena", + "abusefilter-list-group": "Filterska grupa", "abusefilter-hidden": "Privatno", "abusefilter-unhidden": "Javno", + "abusefilter-enabled": "Uključen", + "abusefilter-deleted": "Obrisan", "abusefilter-disabled": "Onemogućeno", + "abusefilter-throttled": "namjetnuto", + "abusefilter-hitcount": "$1 {{PLURAL:$1|pogodak|pogotka|pogodaka}}", + "abusefilter-new": "Napravi novi filter", + "abusefilter-import-button": "Uvezi filter", "abusefilter-return": "Nazad na upravljanje filterima", + "abusefilter-status-global": "Globalan", + "abusefilter-list-options": "Podešavanja", + "abusefilter-list-options-deleted": "Obrisani filteri:", + "abusefilter-list-options-deleted-only": "Prikaži samo obrisane filtere", + "abusefilter-list-options-deleted-hide": "Sakrij obrisane filtere", + "abusefilter-list-options-deleted-show": "Uključi obrisane filtere", + "abusefilter-list-options-scope": "Prikaži filtere:", + "abusefilter-list-options-scope-local": "Samo lokalna pravila", + "abusefilter-list-options-scope-global": "Samo globalna pravila", + "abusefilter-list-options-scope-all": "Lokalna i globalna pravila", + "abusefilter-list-options-further-options": "Dalje postavke:", + "abusefilter-list-options-hidedisabled": "Sakrij isključene filtere", + "abusefilter-list-options-hideprivate": "Sakrij privatne filtere", + "abusefilter-list-options-searchfield": "Pretražite u skladu s pravilima:", + "abusefilter-list-options-searchpattern": "Umetni mostru", + "abusefilter-list-options-searchoptions": "Mod pretraživanja:", + "abusefilter-list-options-search-like": "Prosto pretraživanje", + "abusefilter-list-options-search-rlike": "Regularni izraz", + "abusefilter-list-options-search-irlike": "Veličinskorazličivački regularni izraz", + "abusefilter-list-invalid-searchmode": "Ukazani način bretrage je nevažeći.", + "abusefilter-list-regexerror": "Došlo je do greške pri pretraživanju: Greška u sintaksi regularnog izraza.", "abusefilter-list-options-submit": "Ažuriraj", "abusefilter-tools-text": "Ovde se nalaze alatke koje su korisne za ispravljanje grešaka na filteru protiv zloupotrebe.", "abusefilter-tools-expr": "Testiranje filtera", "abusefilter-tools-submitexpr": "Proceni", "abusefilter-tools-reautoconfirm": "Vrati samopotvrđeni status", "abusefilter-tools-reautoconfirm-user": "Korisnik:", - "abusefilter-tools-reautoconfirm-submit": "Potvrdi", - "abusefilter-reautoconfirm-none": "Samopotvrđeni status ovog korisnika nikada nije bio ukinut.", + "abusefilter-tools-reautoconfirm-submit": "Presamopotvrda", + "abusefilter-tools-restoreautopromote": "Povraćeno autounapređivanja preko alata Filtra zloporaba.", + "abusefilter-reautoconfirm-none": "{{GENDER:$1|Ovom suradniku|Ovoj suradnici}} nije bio suspendiran status samopotvrđenosti.", "abusefilter-reautoconfirm-notallowed": "Nije vam dozvoljeno da vratite samopotvrđeni status.", + "abusefilter-reautoconfirm-done": "Status autopotvrđenog korisnika je vraćen", + "abusefilter-status": "Od {{PLURAL:$1|posljednje radnje|posljednje $1 radnje|posljednjih $1 radnji}}, $2 ($3%) {{PLURAL:$2|dostigla je|dostigle su|dostiglo je}} uvjetno ograničenje $4, a $5 ($6%) {{PLURAL:$5|podudara se|podudaraju se|podudara se}} s jednim od trenutno uključenih filtera.", "abusefilter-edit": "Uređivanje filtera zloupotrebe", - "abusefilter-edit-action-disallow": "Spreči korisnika da izvrši dotičnu akciju", - "abusefilter-edit-action-blockautopromote": "Vrati samopotvrđeni status korisnika", + "abusefilter-edit-subtitle": "Uređujete filter $1", + "abusefilter-edit-subtitle-new": "Pravljenje filtera", + "abusefilter-edit-token-not-match": "Uređivanje nije spremljeno! Spremite ga ponovo.", + "abusefilter-edit-oldwarning": "<strong>Uređujete staru verziju ovog filtera.\nNavedene statistike odnose se na najnoviju verziju filtera.\nAko sačuvate napravljene promjene poklopit ćete sve promjene napravljene od verzije koju uređujete.</strong> •\n[[Special:AbuseFilter/history/$2|Vrati se na historiju ovog filtera]]", + "abusefilter-edit-status-label": "Statistike:", + "abusefilter-edit-status": "Od {{PLURAL:$1|posljednje akcije|posljednje $1 akcije|posljednjih $1 akcija}} ovaj filter je pogođen $2 puta ($3%).\nProsječno vrijeme pokretanja iznosi $4ms, a utrošio je $5 {{PLURAL:$5|uvjet|uvjeta}} unutar ograničenja uvjeta.", + "abusefilter-edit-throttled-warning": "'''Upozorenje:''' Ovaj filter automatski je označen kao štetan. Iz sigurnosnih razloga sljedeće radnje neće biti ispunjene ($1). Pregledajte i [[mw:Extension:AbuseFilter/Conditions|optimizirajte]] uvjete kako biste trgnuli ovo ograničenje", + "abusefilter-edit-new": "Novi filter", + "abusefilter-edit-save": "Sačuvaj filter", + "abusefilter-edit-id": "Naznaka filtera:", + "abusefilter-edit-switch-editor": "Smijeni urednik", + "abusefilter-edit-description": "Opis:\n:''(javno vidljiv)''", + "abusefilter-edit-field-description": "opis", + "abusefilter-edit-group": "Filterska grupa:", + "abusefilter-edit-flags": "Zastavice:", + "abusefilter-edit-enabled": "Omogući ovaj filter", + "abusefilter-edit-deleted": "Označi kao obrisan", + "abusefilter-edit-hidden": "Sakrij iz javnosti informacije ovog filtera", + "abusefilter-edit-global": "Globalni filter", + "abusefilter-edit-rules": "Uslovi:", + "abusefilter-edit-field-conditions": "uslovi", + "abusefilter-edit-notes": "Bilješke:", + "abusefilter-edit-lastmod": "Nedavno izmijenjeni filtri:", + "abusefilter-edit-lastmod-text": "$1 od strane $2", + "abusefilter-edit-hitcount": "Pogoci filtera:", + "abusefilter-edit-consequences": "Radnje što se poduzimaju pri slaganju", + "abusefilter-edit-action-warn": "Poduzimaj ove mjere nakon upozorenja korisniku", + "abusefilter-edit-action-disallow": "Spriječi korisnika da izvrši dotičnu radnju", + "abusefilter-edit-action-blockautopromote": "Opozovi samopotvrđeni status korisnika", "abusefilter-edit-action-degroup": "Ukloni korisnika iz svih korisničkih grupa", - "abusefilter-edit-action-block": "Blokiraj izmene korisnika i/ili IP adrese", + "abusefilter-edit-action-block": "Blokiraj korisnika i/ili IP adresu od uređivanja", + "abusefilter-edit-action-blocktalk": "Blokiraj korisnika i/ili IP adresu od uređivanja vlastite stranice za razgovor", "abusefilter-edit-action-throttle": "Pokreni akcije samo ako korisnik pređe ograničenje učestalosti", - "abusefilter-edit-action-rangeblock": "Blokiraj /16 opseg IP adresa korisnika", + "abusefilter-edit-action-rangeblock": "Blokiraj respektivni opseg IP adresa korisnika odakle korisnik radi", "abusefilter-edit-action-tag": "Označi izmenu za dalji pregled", + "abusefilter-edit-throttle-count": "Broj dozvoljenih radnji:", + "abusefilter-edit-throttle-period": "Vremenski period (u sekundama):", + "abusefilter-edit-throttle-groups": "Istisak prema skupinama:", + "abusefilter-edit-throttle-groups-help": "Pogledajte $1.", + "abusefilter-edit-throttle-groups-help-text": "dokumentaciju na mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Razdjelite sa zarezima za spajanje s AND, a s novim redovima za spajanje s OR", + "abusefilter-edit-throttle-placeholder": "Razdjelite sa zarezima za spajanje s AND, a umetnite jednu po jednu za spajanje s OR", + "abusefilter-throttle-ip": "IP adresa", + "abusefilter-throttle-user": "korisnički račun", + "abusefilter-throttle-range": "/16 opseg", + "abusefilter-throttle-creationdate": "datum stvaranja računa", + "abusefilter-throttle-editcount": "brojač izmjena", + "abusefilter-throttle-site": "cijelo mrež. mjesto", + "abusefilter-throttle-page": "stranica", + "abusefilter-throttle-none": "(nema)", + "abusefilter-throttle-details": "Dopusti $1 {{PLURAL:$1|akciju|akcije|akcija}} svakih $2 {{PLURAL:$2|sekund|sekundi}}, grupno nametnivanje od: $3", + "abusefilter-edit-warn-message": "Sistemska poruka koja se koristi za upozorenje:", + "abusefilter-edit-warn-other": "Ostale poruke", + "abusefilter-edit-warn-other-label": "Ime stranice druge poruke:\n:''(bez prefiksa „MediaWiki“)''", + "abusefilter-edit-warn-actions": "Akcije:", + "abusefilter-edit-warn-preview": "Prikaži/sakrij pretpregled izabrane poruke", + "abusefilter-edit-warn-edit": "Napravi/Uredi izabranu poruku", + "abusefilter-edit-disallow-message": "Sistemska poruka koja se koristi za zabranjivanje:", + "abusefilter-edit-disallow-other": "Ostale poruke", + "abusefilter-edit-disallow-other-label": "Ime stranice druge poruke:\n:''(bez prefiksa „MediaWiki“)''", + "abusefilter-edit-disallow-actions": "Akcije:", + "abusefilter-edit-disallow-preview": "Prikaži/sakrij pretpregled izabrane poruke", + "abusefilter-edit-disallow-edit": "Napravi/uredi izabranu poruku", + "abusefilter-edit-tag-tag": "[[Special:Tags|Oznake]] za primjenu:", + "abusefilter-edit-tag-placeholder": "Dodaj oznake (jednu po jednu, odvojene zarezima)", + "abusefilter-edit-tag-hidden-placeholder": "Dodaj oznake (odvojene zarezima)", + "abusefilter-edit-block-anon-durations": "Trajanje bloka za anonimne korisnike:", + "abusefilter-edit-block-user-durations": "Trajanje bloka za registrovane korisnike:", + "abusefilter-block-anon": "Blokiraj anonimne korisnike", + "abusefilter-block-user": "blokiraj registrovane korisnike", + "abusefilter-block-talk": "razgovor je blokiran", + "abusefilter-edit-denied": "Možda nećete vidjeti podrobnosti ovog filtera jer je sakriven za javni pregled.", + "abusefilter-edit-main": "Parametri filtera", + "abusefilter-edit-done-subtitle": "Filter je uređen", + "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Vaše izmjene]] [[Special:AbuseFilter/$1|filtera $3]] su sačuvane.", + "abusefilter-edit-badsyntax": "Navedeni filter ima sintaksnu grešku.\nIzlaz iz raščlanjivača je: <pre>$1</pre>", + "abusefilter-edit-missingfields": "Sljedeća polja moraju biti popunjena: $1", + "abusefilter-edit-deleting-enabled": "Ne možete označiti aktivan filter kao obrisan.", + "abusefilter-edit-restricted": "Ne možete uređivati ovaj filtar jer sadrži jednu ili više ograničenih radnji.\nZatražite ove promjene da biste korisniku dali dopuštenje za dodavanje ograničenih radnji.", + "abusefilter-edit-viewhistory": "Pregled historije filtera", + "abusefilter-edit-history": "Historija:", + "abusefilter-edit-check": "Provjeri sintaksu", + "abusefilter-edit-badfilter": "Navedeni filter ne postoji", + "abusefilter-edit-revert": "Vrati radnje ovog filtra", + "abusefilter-edit-tools": "Alati:", + "abusefilter-edit-test-link": "Testiraj filterav protiv nedavnih izmjena", + "abusefilter-edit-export": "Izvezi filterav na drugi wiki", + "abusefilter-edit-syntaxok": "Nisam pronašao sintaksne greške.", + "abusefilter-edit-syntaxerr": "Otkrivena je sintaksna greška: $1", + "abusefilter-edit-warn-leave": "Ako napustite ovu stranicu, izgubit ćete napravljene promjene na filtru.", + "abusefilter-edit-bad-tags": "Jedan ili više oznaka koje ste naveli nisu ispravne.\nOznaka mora biti kratka, ne smije sadržavati psoebne znakove i ne smiju biti rezervirani u drugoj programskoj podršci. Izaberite novi naziv oznake", + "abusefilter-edit-notallowed": "Nije Vam dozvoljeno da pravite ili uređujete filtere protiv zloupotrebe", + "abusefilter-edit-notallowed-global": "Nije Vam dozvoljeno da pravite ili uređujete globalne filtere protiv zloupotrebe", + "abusefilter-edit-invalid-throttlecount": "Broj isticanja mora biti pozitivan cijeli broj.", + "abusefilter-edit-invalid-throttleperiod": "Period isticanja mora biti pozitivan cijeli broj.", + "abusefilter-edit-empty-throttlegroups": "Mora izabrati se barem jednu grupu za isticanje.", + "abusefilter-edit-duplicated-throttlegroups": "Grupe isticanja ne mogu imati duplikate.", + "abusefilter-edit-invalid-throttlegroups": "Navedene grupe isticanja nisu važeće.", + "abusefilter-edit-builder-select": "Odaberite mogućnost za dodavanje kursoru", + "abusefilter-edit-builder-group-op-arithmetic": "Aritmetički operatori", + "abusefilter-edit-builder-op-arithmetic-addition": "Sabiranje (+)", + "abusefilter-edit-builder-op-arithmetic-subtraction": "Oduzimanje (-)", + "abusefilter-edit-builder-op-arithmetic-multiplication": "Množenje (*)", + "abusefilter-edit-builder-op-arithmetic-divide": "Dijeljenje (/)", + "abusefilter-edit-builder-op-arithmetic-modulo": "Modul (%)", + "abusefilter-edit-builder-op-arithmetic-pow": "Stepenovanje (**)", + "abusefilter-edit-builder-group-op-comparison": "Operatori poređenja", + "abusefilter-edit-builder-op-comparison-equal": "Vrijednost jednaka (==)", + "abusefilter-edit-builder-op-comparison-equal-strict": "Vrijednost i tip jednaki (===)", + "abusefilter-edit-builder-op-comparison-notequal": "Vrijednost nije jednaka (!=)", + "abusefilter-edit-builder-op-comparison-notequal-strict": "Vrijednost i tip nisu jednaki (!==)", + "abusefilter-edit-builder-op-comparison-lt": "Manje od (<)", + "abusefilter-edit-builder-op-comparison-gt": "Veće od (>)", + "abusefilter-edit-builder-op-comparison-lte": "Manje ili jednako sa (<=)", + "abusefilter-edit-builder-op-comparison-gte": "Veće ili jednako sa (>=)", + "abusefilter-edit-builder-group-op-bool": "Bulovi operatori", + "abusefilter-edit-builder-op-bool-not": "Ne (!)", + "abusefilter-edit-builder-op-bool-and": "I (&)", + "abusefilter-edit-builder-op-bool-or": "Ili (|)", + "abusefilter-edit-builder-group-misc": "Razno", + "abusefilter-edit-builder-misc-in": "sadržano u nizu (in)", + "abusefilter-edit-builder-misc-like": "Odgovara uzorku (like)", + "abusefilter-edit-builder-misc-rlike": "Odgovara regularnom izrazu (rlike)", + "abusefilter-edit-builder-misc-irlike": "Odgovara regularnom izrazu, bez razlikovanja velikih i malih slova (irlike)", + "abusefilter-edit-builder-misc-contains": "Lijevi string sadrži desni string (contains)", + "abusefilter-edit-builder-misc-stringlit": "String literal (\"\")", + "abusefilter-edit-builder-misc-tern": "Ternarni operator (X ? Y : Z)", + "abusefilter-edit-builder-misc-cond": "Uslov (if X then Y else Z)", + "abusefilter-edit-builder-group-funcs": "Funkcije", + "abusefilter-edit-builder-funcs-length": "Dužina stringa (length)", + "abusefilter-edit-builder-funcs-lcase": "Mala slova (lcase)", + "abusefilter-edit-builder-funcs-ucase": "Velika slova (ucase)", + "abusefilter-edit-builder-funcs-ccnorm": "Normaliziraj zbunjujuće znakove (ccnorm)", + "abusefilter-edit-builder-funcs-ccnorm-contains-any": "Normaliziraj i pretraži string s više podnizima u OR-načinu (ccnorm_contains_any)", + "abusefilter-edit-builder-funcs-ccnorm-contains-all": "Normaliziraj i pretraži string s više podnizima u načinu I (ccnorm_contains_all)", + "abusefilter-edit-builder-funcs-rmdoubles": "Skloni duple karaktere (rmdoubles)", + "abusefilter-edit-builder-funcs-specialratio": "Specijalni karakteri / svi karakteri (specialratio)", + "abusefilter-edit-builder-funcs-norm": "Normaliziraj (norm)", + "abusefilter-edit-builder-funcs-count": "Broj pojavljivanja niza X u nizu Y (count)", + "abusefilter-edit-builder-funcs-rcount": "Broj pojavljivanja regexa X u nizu Y (count)", + "abusefilter-edit-builder-funcs-get_matches": "Stroj podudaranja u regularnim izrazima unutar tekstota za svaku zahvatnu grupu (get_matches)", + "abusefilter-edit-builder-funcs-rmwhitespace": "Ukloni praznine (rmwhitespace)", + "abusefilter-edit-builder-funcs-rmspecials": "Ukloni posebne znakove (rmspecials)", + "abusefilter-edit-builder-funcs-ip_in_range": "Provjera da li je IP u opsegu (ip_in_range)", + "abusefilter-edit-builder-funcs-contains-any": "Traži više podnizki u načinu ILI (contains_any)", + "abusefilter-edit-builder-funcs-contains-all": "Traži više podnizki u načinu I (contains_all)", + "abusefilter-edit-builder-funcs-equals-to-any": "Provjeri je li argument jednak (===) bilo kojem od sljedećih argumenata (equals_to_any)", + "abusefilter-edit-builder-funcs-substr": "Podstring (substr)", + "abusefilter-edit-builder-funcs-strpos": "Pozicija podstringa u stringu (strpos)", + "abusefilter-edit-builder-funcs-str_replace": "Zamijeni podstring nekim stringom (str_replace)", + "abusefilter-edit-builder-funcs-rescape": "Izvod stringa kao doslovnog u reg. izrazima (rescape)", + "abusefilter-edit-builder-funcs-set_var": "Postavi varijablu (set_var)", + "abusefilter-edit-builder-funcs-sanitize": "Normaliziraj HTML-jedinice u unicode znakove (sanitize)", + "abusefilter-edit-builder-group-vars": "Promjenjive", + "abusefilter-edit-builder-vars-accountname": "Ime računa (u trenutku pravljenja)", + "abusefilter-edit-builder-vars-timestamp": "Unix-datum i vreme promjene", + "abusefilter-edit-builder-vars-timestamp-expanded": "Vrijeme i datum dnevnika", + "abusefilter-edit-builder-vars-action": "Radnja", + "abusefilter-edit-builder-vars-addedlines": "Linije dodane u izmjeni", + "abusefilter-edit-builder-vars-delta": "Veličinska promjena s izmjenom", + "abusefilter-edit-builder-vars-diff": "Zajedničke razlike promjena napravljenih uređivanjem", + "abusefilter-edit-builder-vars-newsize": "Veličina nove stranice", + "abusefilter-edit-builder-vars-oldsize": "Veličina stare stranice", + "abusefilter-edit-builder-vars-old-content-model": "Stari sadržajni model", + "abusefilter-edit-builder-vars-new-content-model": "Novi sadržajni model", + "abusefilter-edit-builder-vars-removedlines": "Linije uklonjene pri izmjeni", + "abusefilter-edit-builder-vars-summary": "Opis/razlog izmjene", + "abusefilter-edit-builder-vars-page-id": "Naznaka stranice", + "abusefilter-edit-builder-vars-page-ns": "Imenski prostor stranice", + "abusefilter-edit-builder-vars-page-title": "Naslov stranice (bez imenskog prostora)", + "abusefilter-edit-builder-vars-page-prefixedtitle": "Puni naslov stranice", + "abusefilter-edit-builder-vars-page-age": "Starost stranice (u sekundama)", + "abusefilter-edit-builder-vars-movedfrom-id": "Naznaka stranice za premještanje", + "abusefilter-edit-builder-vars-movedfrom-ns": "Imenski prostor preimenovane stranice", + "abusefilter-edit-builder-vars-movedfrom-title": "Ime preimenovane stranice", + "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "Puni naslov premjestene stranice", + "abusefilter-edit-builder-vars-movedfrom-age": "Starost izvorne stranice premještanja (u sekundama)", + "abusefilter-edit-builder-vars-movedto-id": "Naznaka odredišne stranice za premještanje", + "abusefilter-edit-builder-vars-movedto-ns": "Imenski prostor odredišne stranice za premještanje", + "abusefilter-edit-builder-vars-movedto-title": "Naslov odredišne stranice za premještanje", + "abusefilter-edit-builder-vars-movedto-prefixedtitle": "Puni naslov odredišne stranice za premještanje", + "abusefilter-edit-builder-vars-movedto-age": "Starost odredišne stranice premještanja (u sekundama)", + "abusefilter-edit-builder-vars-user-editcount": "Brojač izmjena korisnika", + "abusefilter-edit-builder-vars-user-age": "Starost korisničkog računa", + "abusefilter-edit-builder-vars-user-name": "Ime korisničkog računa", + "abusefilter-edit-builder-vars-user-groups": "Grupe (uključujući implicitne) u kojima je korisnik", + "abusefilter-edit-builder-vars-user-rights": "Prava što ih korisnik ima", + "abusefilter-edit-builder-vars-user-blocked": "Da li je korisnik blokiran", + "abusefilter-edit-builder-vars-user-emailconfirm": "Vrijeme u kojem je e-mail adresa bila potvrđena", + "abusefilter-edit-builder-vars-recent-contributors": "Posljednjih deset urednika stranice", + "abusefilter-edit-builder-vars-first-contributor": "Prvi urednik stranice", + "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "Posljednjih deset urednika izvorne premjestene stranice", + "abusefilter-edit-builder-vars-movedfrom-first-contributor": "Prvi doprinositelj u izvornoj premjestenoj stranici", + "abusefilter-edit-builder-vars-movedto-recent-contributors": "Posljednjih deset doprinositelja u odredišnoj stranici", + "abusefilter-edit-builder-vars-movedto-first-contributor": "Prvi doprinositelj u odredišnoj stranici", + "abusefilter-edit-builder-vars-all-links": "Sve vanjske veze u novom tekstu", + "abusefilter-edit-builder-vars-added-links": "Sve vanjske veze dodane uređivanjem", + "abusefilter-edit-builder-vars-removed-links": "Sve vanjske veze uklonjene uređivanjem", + "abusefilter-edit-builder-vars-old-wikitext": "Wikitekst stare stranice, prije izmjene", + "abusefilter-edit-builder-vars-new-wikitext": "Novi wikitekst nakon uređivanja", + "abusefilter-edit-builder-vars-new-pst": "Wikitekst za novu stranicu, prilagođen za sačuvanje", + "abusefilter-edit-builder-vars-diff-pst": "Zajedničke razlike uređivanjem, prilagođene za sačuvanje", + "abusefilter-edit-builder-vars-addedlines-pst": "Dodani redovi u uređivanju, pretvoreni prije spremanja", + "abusefilter-edit-builder-vars-new-text": "Novi tekst stranice, isčišćen od ikakvih oznaki", + "abusefilter-edit-builder-vars-new-html": "Raščlanjeni HTML-izvor nove izmjene", + "abusefilter-edit-builder-vars-restrictions-edit": "Nivo zaštite stranice (uređivanje)", + "abusefilter-edit-builder-vars-restrictions-move": "Nivo zaštite stranice (premještanje)", + "abusefilter-edit-builder-vars-restrictions-create": "Zaštita za pravljenje stranice", + "abusefilter-edit-builder-vars-restrictions-upload": "Zaštita za postavljanje datoteke", + "abusefilter-edit-builder-vars-movedfrom-restrictions-edit": "Stupanj zaštite premjestene stranice", + "abusefilter-edit-builder-vars-movedfrom-restrictions-move": "Stupanj zaštite izvorne stranice", + "abusefilter-edit-builder-vars-movedfrom-restrictions-create": "Zaštita pravljenja izvorne premjestene stranice", + "abusefilter-edit-builder-vars-movedfrom-restrictions-upload": "Zaštita postavljanja izvorne premjestene stranice", + "abusefilter-edit-builder-vars-movedto-restrictions-edit": "Zaštita uređivanja odredišne stranice", + "abusefilter-edit-builder-vars-movedto-restrictions-move": "Zaštita premještanja odredišne stranice", + "abusefilter-edit-builder-vars-movedto-restrictions-create": "Zaštita pravljenja odredišne stranice", + "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Zaštita postavljanja odredišne stranice", + "abusefilter-edit-builder-vars-old-text": "Tekst stare stranice, s uklonjenim oznakama (izvan upotrebe)", + "abusefilter-edit-builder-vars-old-links": "Linkovi na ovoj stranici, prije uređivanja", + "abusefilter-edit-builder-vars-old-html": "Wikitekst stare stranice, raščlanjen u HTML (izvan upotrebe)", + "abusefilter-edit-builder-vars-minor-edit": "Je li izmjena označena kao manja (izvan upotrebe)", + "abusefilter-edit-builder-vars-file-sha1": "SHA1-taraba sadržaja datoteke", + "abusefilter-edit-builder-vars-file-size": "Veličina datoteke u bajtovima", + "abusefilter-edit-builder-vars-file-mime": "MIME-tip datoteke", + "abusefilter-edit-builder-vars-file-mediatype": "Medijski tip datoteke", + "abusefilter-filter-log": "Nedavne promjene u filtrima", "abusefilter-history": "Historija izmjena filtera #$1", "abusefilter-history-foruser": "Izmene od $1", "abusefilter-history-hidden": "Sakriveno", @@ -111,11 +421,25 @@ "abusefilter-history-filterid": "Filter", "abusefilter-history-select-legend": "Preciziraj pretragu", "abusefilter-history-select-user": "Korisnik:", + "abusefilter-history-select-filter": "Naznaka filtera:", "abusefilter-history-select-submit": "Pročisti", "abusefilter-history-diff": "Izmjene", "abusefilter-history-error-hidden": "Traženi filter je sakriven, i zato ne možete da vidite njegovu istoriju.", + "abusefilter-exception-unexpectedatend": "Neočekivano \"$2\" na znaku $1.", + "abusefilter-exception-expectednotfound": "Očekivano $2 na znaku $1, nije pronađeno (umjesto toga pronađeno $3 $4).", + "abusefilter-exception-unrecognisedkeyword": "Neprepoznata ključna riječ $2 na znaku $1.", + "abusefilter-exception-unexpectedtoken": "Neočekivani token \"$3\" (tipa $2) na znaku $1.", + "abusefilter-exception-unclosedstring": "Nezatvoren niz počevši od znaka $1.", + "abusefilter-exception-invalidoperator": "Nevaljan operator \"$2\" kod znaka $1.", + "abusefilter-exception-dividebyzero": "Nedozvoljen pokušaj dijeljenja $2 sa nulom kod znaka $1.", + "abusefilter-exception-unrecognisedvar": "Neraspoznata varijabla $2 kod znaka $1", + "abusefilter-exception-notenoughargs": "Nema dovoljno argumenata za funkciju $2 pozvanu kod znaka $1.\n{{PLURAL:$3|Očekivan je $3 argument|Očekivana su $3 argumenta|Očekivano je $3 argumenata}}, a {{PLURAL:$4|dobiven je|dobivena su|dobiveno je}} $4", + "abusefilter-exception-toomanyargs": "Nema dovoljno argumenata za funkciju $2 pozvanu kod znaka $1.\n{{PLURAL:$3|Očekivan je najviše $3 argument|Očekivana su najviše $3 argumenta|Očekivano je najviše $3 argumenata}}, a {{PLURAL:$4|dobiven je|dobivena su|dobiveno je}} $4", + "abusefilter-exception-overridebuiltin": "Nedozvoljeno poklapanje ugrađene varijable \"$2\" kod znaka $1.", + "abusefilter-exception-variablevariable": "Nisu dopuštene promjenljive pri znaku $1.", "abusefilter-action-tag": "Tag", "abusefilter-action-throttle": "Uspori", + "abusefilter-action-warn": "Upozori", "abusefilter-action-blockautopromote": "Blokiraj samounapređivanje", "abusefilter-action-block": "Blokiraj", "abusefilter-action-degroup": "Ukloni iz grupa", @@ -123,28 +447,39 @@ "abusefilter-action-disallow": "Zabrani", "abusefilter-revert-title": "Vrati sve akcije koje je napravio filter $1", "abusefilter-revert-intro": "Ovo Vam omogućava da vratite sve izmene koje je načinio filter $1.\nBudite pažljivi pri korišćenju ove alatke.", - "abusefilter-revert-preview-item": "$1: $2 {{GENDER:$2|je napravio|je napravila|je napravio}} $3 na $4.\nAkcije za vraćanje: $5 ($6)", + "abusefilter-revert-preview-item": "$1: $2 {{GENDER:$7|je napravio|je napravila}} $3 na $4.\nAkcije za vraćanje: $5 ($6)", "abusefilter-revert-search-legend": "Izaberi akcije filtera zloupotrebe koje trebaju biti vraćene", "abusefilter-revert-periodstart": "Početak perioda:", "abusefilter-revert-periodend": "Kraj perioda:", "abusefilter-revert-search": "Izaberi akcije", - "abusefilter-revert-filter": "Filter:", - "abusefilter-revert-preview-intro": "Ispod su prikazane akcije koje će biti vraćene. Pažljivo ih proverite i kliknite na opciju „potvrdi“ da biste potvrdili svoj izbor.", + "abusefilter-revert-filter": "Naznaka filtera:", + "abusefilter-revert-preview-intro": "Ispod su prikazani postupci filtera zlouporaba koje će sada biti vraćene.\nProvjerite ih pažljivo, a zatim kliknite \"{{int:abusefilter-revert-confirm}}\" da biste potvrdili izabrano.", + "abusefilter-revert-confirm-legend": "Potvrdi povratak", "abusefilter-revert-confirm": "Potvrdi", - "abusefilter-revert-success": "Vratili ste sve ackije.", + "abusefilter-revert-success": "Vratili ste sve akcije koje je poduzeo filter zloupotreba zbog [[Special:AbuseFilter/$1|filtera $2]].", "abusefilter-revert-reason": "Automatsko vraćanje svih akcija koje je načinio filter $1.\nRazlog: $2", "abusefilter-revert-reasonfield": "Razlog vraćanja:", - "abusefilter-test-intro": "Ova stranica Vam omogućava da proverite filter iz donje kutijice na poslednjih $1 izmjena. Da biste učitali postojeći filter, unesite njegov ID u kutijicu ispod polja za uređivanje i klinkite na dugme „Učitaj“.", + "abusefilter-test": "Isprobavanje filtera protiv prethodnih izmjena", + "abusefilter-test-intro": "Ova stranica Vam omogućava da proverite filter iz donje kutijice na {{PLURAL:$1|poslednjoj promjeni|poslednjih $1 promjena}}.\nDa biste učitali postojeći filter, unesite njegov ID-broj ispod polja za uređivanje, i klinkite na dugme „{{int:abusefilter-test-load}}“.", "abusefilter-test-legend": "Testiranje filtera", "abusefilter-test-load-filter": "Učitaj filter s naznakom:", "abusefilter-test-submit": "Testiraj", "abusefilter-test-load": "Učitaj", "abusefilter-test-user": "Izmjene od korisnika:", + "abusefilter-test-nobots": "Sakrij botovska uređivanja", "abusefilter-test-period-start": "Izmjene napravljene posle:", "abusefilter-test-period-end": "Izmjene napravljene pre:", "abusefilter-test-page": "Izmjene napravljene na stranici:", "abusefilter-test-shownegative": "Prikaži izmjene koje ne odgovaraju filteru", "abusefilter-test-syntaxerr": "Filter koji ste uneli sadrži sintaksne greške. Da biste dobili detaljno objašnjenje kliknite na dugme „Proveri sintaksu“.", + "abusefilter-test-badtitle": "Unesen je naslov stranice nevažeći. Može sadržavati jedan ili više znakova što nisu dopušteni u naslovima.", + "abusefilter-test-action": "Vrsta radnje:", + "abusefilter-test-search-type-all": "Sve radnje", + "abusefilter-test-search-type-edit": "Izmjene", + "abusefilter-test-search-type-move": "Premještanja", + "abusefilter-test-search-type-delete": "Brisanja", + "abusefilter-test-search-type-upload": "Postavljanja", + "abusefilter-test-search-type-createaccount": "Stvaranja računa", "abusefilter-changeslist-examine": "pregledaj", "abusefilter-examine": "Ispitaj pojedinačne izmjene", "abusefilter-examine-intro": "Ova stranica Vam omogućava da ispitate promenljive filtera na pojedinačne izmjene i da ih testirate.", @@ -153,15 +488,25 @@ "abusefilter-examine-user": "Korisnik:", "abusefilter-examine-title": "Naslov stranice:", "abusefilter-examine-submit": "Traži", - "abusefilter-topnav": "'''Navigacija po filteru protiv zloupotrebe'''", + "abusefilter-examine-vars": "Varijable generirane za ovu promjenu", + "abusefilter-examine-test": "Isprobaj promjenu putem filtera", + "abusefilter-examine-test-button": "Isprobaj filter", + "abusefilter-examine-syntaxerror": "Filter ima nevaljanu sintaksu", + "abusefilter-examine-notfound": "Izmjena koju ste tražili nije pronađena.", + "abusefilter-examine-incompatible": "Promjena koju ste tražili nije podržana od Filtera zloupotreba", + "abusefilter-examine-noresults": "Nema pronađenih stavki za navedene parametre.", + "abusefilter-topnav": "'''Sadržaje filtera protiv zloupotrebe'''", "abusefilter-topnav-home": "Početna", + "abusefilter-topnav-recentchanges": "Nedavne promjene u filtrima", "abusefilter-topnav-test": "Grupno isprobavanje", "abusefilter-topnav-examine": "Ispitaj prošle izmjene", "abusefilter-topnav-log": "Evidencija zloupotreba", "abusefilter-topnav-tools": "Alati za debagovanje", - "abusefilter-topnav-import": "Uvezi filter", "abusefilter-log-name": "Evidencija filtera zloupotrebe", "abusefilter-log-header": "Ovde je prikazan sažetak izmena koje su napravili filteri.\nZa više informacija pogledajte [[Special:AbuseFilter/history|pregled]] skorašnjih izmjena.", + "abusefilter-logentry-create": "$1 {{GENDER:$2|stvorio je|stvorila je}} $4 ($5)", + "abusefilter-logentry-modify": "$1 {{GENDER:$2|izmijenio je|izmijenila je}} $4 ($5)", + "abusefilter-log-invalid-filter": "Neke od navedenih filterskih naznaki su nevažeći.", "abusefilter-log-noresults": "Nema rezultata", "abusefilter-diff-title": "Razlike između revizija", "abusefilter-diff-item": "Stavka", @@ -174,5 +519,17 @@ "abusefilter-diff-next": "Nove izmjene", "abusefilter-import-intro": "Možete koristiti ovo sučelje da uvezete filtere sa drugih vikija. Na izvornom vikiju kliknite na „Export this filter to another wiki“ ispod opcije „Tools:“. Kopirajte sadržaj polja za uređivanje koje se pojavi, nalepite ga u ovo polje, a potom kliknite na „Import data“.", "abusefilter-import-submit": "Uvezi podatke", - "abusefilter-group-default": "Standardno" + "abusefilter-group-default": "Standardno", + "abusefilter-http-error": "Desila se greška u HTTP-u: $1.", + "abusefilter-view-privatedetails-submit": "Pogl. osobne podatke", + "abusefilter-view-privatedetails-legend": "Pogl. osobne podatke", + "abusefilter-view-privatedetails-reason": "Razlog pristupu osobnim podacima:", + "abusefilter-log-details-id": "Naznaka dnevnika", + "abusefilter-invalid-request": "Nevažeći zahtjev! Morate pristupiti osobnim podacima iz dnevnika putem obrasca na [[Special:AbuseLog/$1]] i navesti razlog.", + "abusefilter-invalid-request-noid": "Nevažeći zahtjev! Morate pristupiti osobnim podacima iz dnevnika putem obrasca na odgovarajućoj stranici i navesti razlog.", + "log-description-abusefilterprivatedetails": "Ovaj dnevnik prikazuje događaje kada određeni korisnik pristupi osobnim podacima u dnevniku filtera zlouporaba.", + "abusefilter-noreason": "Upozorenje: Da biste pregledali osobne podatke iz ovog dnevnika, morate navesti razlog.", + "abusefilter-log-ip-not-available": "Nedostupna", + "abusefilter-tag-reserved": "Oznaka <code>abusefilter-condition-limit</code> je rezervirana za internu upotrebu u Filtru za zlouporabu.", + "tag-abusefilter-condition-limit": "dostignuta granica uvjeta" } diff --git a/AbuseFilter/i18n/shi.json b/AbuseFilter/i18n/shi.json index 7438e128..878c6aa1 100644 --- a/AbuseFilter/i18n/shi.json +++ b/AbuseFilter/i18n/shi.json @@ -1,8 +1,8 @@ { "@metadata": { "authors": [ - "Dalinanir", - "Amara-Amaziɣ" + "Amara-Amaziɣ", + "Dalinanir" ] }, "abusefilter-log-search-title": "Aswl:", diff --git a/AbuseFilter/i18n/shn.json b/AbuseFilter/i18n/shn.json new file mode 100644 index 00000000..cd83eb61 --- /dev/null +++ b/AbuseFilter/i18n/shn.json @@ -0,0 +1,14 @@ +{ + "@metadata": { + "authors": [ + "Saimawnkham" + ] + }, + "right-abusefilter-log": "တူၺ်းသဵၼ်ႈသၢႆလူလၢႆ", + "right-abusefilter-view-private": "တူၺ်းတူဝ်ထွင်လူလၢႆ ဢၼ်မၢႆဝႆႉ ၼင်ႇသုၼ်ႇတူဝ်လဵဝ်", + "action-abusefilter-log": "တူၺ်းသဵၼ်ႈသၢႆလူလၢႆ", + "action-abusefilter-view-private": "တူၺ်းတူဝ်ထွင်လူလၢႆ ဢၼ်မၢႆဝႆႉ ၼင်ႇသုၼ်ႇတူဝ်လဵဝ်", + "abusefilter-enabled": "ပိုတ်ႇၸႂ်ႉဝႆႉ", + "abusefilter-edit-enabled": "ပိုတ်ႇၸႂ်ႉ တူဝ်ထွင်ဢၼ်ၼႆႉ", + "abusefilter-history-enabled": "ပိုတ်ႇၸႂ်ႉဝႆႉ" +} diff --git a/AbuseFilter/i18n/si.json b/AbuseFilter/i18n/si.json index ec5babde..39b60bc4 100644 --- a/AbuseFilter/i18n/si.json +++ b/AbuseFilter/i18n/si.json @@ -1,19 +1,19 @@ { "@metadata": { "authors": [ + "Macofe", "Singhalawap", + "Susith Chandira Gts", "පසිඳු කාවින්ද", "බිඟුවා", "ශ්වෙත", "සුරනිමල", - "Susith Chandira Gts", - "Macofe", 1100100 ] }, "abusefilter-desc": "සංස්කරණ සඳහා ස්වයංක්රීය විවරණෝපයෝගී යෙදේ", - "abusefilter": "අනිසි පෙරහන් සැකසුම", - "abuselog": "අනිසි සටහන්", + "abusefilter": "අපයෙදුම් පෙරහන් කළමනාකරණය", + "abuselog": "අපයෙදුම් පෙරහන් ලඝු සටහන", "abusefilter-intro": "අපයෙදුම් පෙරහන් කළමනාකරණ අතුරු මුහුණතට ඔබව සාදරයෙන් පිළිගනිමු.\nThe Abuse Filter is an automated software mechanism of applying automatic heuristics to all actions.\nThis interface shows a list of defined filters, and allows them to be modified.", "abusefilter-warning": "'''අවවාදයයි''':මෙම ක්රියාව හානිදායක බව ස්වයංක්රීයව හඳුනාගෙන ඇත.\nUnconstructive edits will be quickly reverted,\nand egregious or repeated unconstructive editing will result in your account or IP address being blocked.\nIf you believe this edit to be constructive, you may click Submit again to confirm it.\nA brief description of the abuse rule which your action matched is: $1", "abusefilter-blocker": "අපයෙදුම් පෙරහන", @@ -24,7 +24,7 @@ "right-abusefilter-view": "අපයෙදුම් පෙරහන් නරඹන්න", "right-abusefilter-log": "අපයෙදුම් ලඝු සටහන නරඹන්න", "right-abusefilter-log-detail": "විස්තර කරන ලද අපයෙදුම් ලඝු සටහන් ඇතුළත් කිරීම් නරඹන්න", - "right-abusefilter-private": "අපයෙදුම් ලඝු සටහනේ ඇති පෞද්ගලික දත්ත නරඹන්න", + "right-abusefilter-privatedetails": "අපයෙදුම් ලඝු සටහනේ ඇති පෞද්ගලික දත්ත නරඹන්න", "right-abusefilter-modify-restricted": "සීමාසහිත ක්රියාකාරකම් මඟින් අපයෙදුම් පෙරහන් වෙනස් කරන්න", "right-abusefilter-revert": "අපයෙදුම් පෙරහන මඟින් දෙන ලද සියලුම වෙනස්කම් ප්රතිවර්තනය කරන්න", "right-abusefilter-view-private": "පෞද්ගලික ලෙස සලකුණු කෙරූ අපයෙදුම් පෙරහන් නරඹන්න", @@ -36,11 +36,10 @@ "action-abusefilter-view": "අපයෙදුම් පෙරහන් නරඹන්න", "action-abusefilter-log": "අපයෙදුම් ලඝු සටහන නරඹන්න", "action-abusefilter-log-detail": "විස්තර කරන ලද අපයෙදුම් ලඝු සටහන් ඇතුළත් කිරීම් නරඹන්න", - "action-abusefilter-private": "අපයෙදුම් ලඝු සටහනෙහි පෞද්ගලික දත්ත නරඹන්න", + "action-abusefilter-privatedetails": "අපයෙදුම් ලඝු සටහනෙහි පෞද්ගලික දත්ත නරඹන්න", "action-abusefilter-modify-restricted": "සීමාසහිත ක්රියාකාරකම් සහිත අපයෙදුම් පෙරහන් වෙනස් කරන්න", "action-abusefilter-revert": "අපයෙදුම් පෙරහන මඟින් දෙන ලද සියලුම වෙනස්කම් ප්රතිවර්තනය කරන්න", "action-abusefilter-view-private": "පෞද්ගලික ලෙස සලකුණු කරන ලද අපයෙදුම් පෙරහන් නරඹන්න", - "abusefilter-log": "අපයෙදුම් පෙරහන් ලඝු සටහන", "abusefilter-log-summary": "පෙරහන් විසින් අල්ලන ලද සියලුම ක්රියාකාරකම් ලැයිස්තුවක් මෙම ලඝු සටහනෙන් පෙන්වයි.", "abusefilter-log-search": "අපයෙදුම් ලඝු සටහන ගවේෂණය කරන්න", "abusefilter-log-search-user": "පරිශීලකයා:", @@ -57,13 +56,11 @@ "abusefilter-log-details-var": "විචල්යය", "abusefilter-log-details-val": "වටිනාකම", "abusefilter-log-details-vars": "ක්රියා පරාමිතිය", - "abusefilter-log-details-private": "පුද්ගලික දත්ත", "abusefilter-log-details-ip": "අයිපී ලිපිනය උත්පාදනය කරමින්", "abusefilter-log-noactions": "කිසිවක් නොවේ", "abusefilter-log-details-diff": "සංස්කරණයේදී සිදුකල වෙනස්කම්", "abusefilter-log-linkoncontribs": "අපයෙදුම් ලඝු-සටහන", "abusefilter-log-linkoncontribs-text": "මෙම පරිශීලකයා සඳහා අපයෙදුම් ලඝු සටහන", - "abusefilter-log-hidden": "(ඇතුලත් කිරීම සඟවා ඇත)", "abusefilter-log-hidden-implicit": "(සංශෝධනය මකා දැමීම හේතුවෙන් සඟවා ඇත)", "abusefilter-log-cannot-see-details": "මෙම ඇතුලත් කිරීමෙහි විස්තර නැරඹීමට ඔබ හට අවසර නොමැත.", "abusefilter-log-details-hidden": "ඔබට මෙම ඇතුලත් කිරීමට අදාළ විස්තර නැරඹිය නොහැක මන්ද එය පොදු දර්ශනයෙන් සඟවා ඇත.", @@ -72,7 +69,6 @@ "abusefilter-log-hide-hidden": "පොදු දර්ශනයෙන් මෙම ඇතුලත් කිරීම සඟවන්න", "abusefilter-log-hide-reason": "හේතුව:", "abusefilter-log-hide-forbidden": "අපයෙදුම් ලඝු ඇතුලත් කිරීම් සැඟවීමට ඔබ හට අවසර නොමැත.", - "abusefilter-management": "අපයෙදුම් පෙරහන් කළමනාකරණය", "abusefilter-list": "සියලු පෙරහන්", "abusefilter-list-id": "පෙරනයේ නම", "abusefilter-list-status": "තත්වය", @@ -92,6 +88,7 @@ "abusefilter-disabled": "අක්රිය කෙරිණි", "abusefilter-hitcount": "{{PLURAL:$1|වැදීම්|වැදීම්}} $1 ක්", "abusefilter-new": "නව පෙරහනක් තනන්න", + "abusefilter-import-button": "පෙරහන ආයාත කරන්න", "abusefilter-return": "පෙරහන් කළමනාකරණය වෙත නැවත යන්න", "abusefilter-status-global": "ගෝලීය", "abusefilter-list-options": "විකල්ප", @@ -244,15 +241,15 @@ "abusefilter-edit-builder-vars-all-links": "සියලුම බාහිර සබැඳි නව පාඨයක", "abusefilter-edit-builder-vars-added-links": "සංස්කරණයේදී එකතුවූ සියලුම බාහිර සබැඳියන්", "abusefilter-edit-builder-vars-removed-links": "සංස්කරණයේදී ඉවත්වූ සියලුම බාහිර සබැඳියන්", - "abusefilter-edit-builder-vars-old-text": "පැරණි පිටුවේ විකිපාඨය, සංස්කරණයට පෙර", - "abusefilter-edit-builder-vars-new-text": "නව පිටුවේ විකිපාඨය, සංස්කරණයට පසු", - "abusefilter-edit-builder-vars-new-text-stripped": "නව පිටුවේ පාඨය, ඕනෑම අධිකයකින් පැහැර ගත්තක්", + "abusefilter-edit-builder-vars-old-wikitext": "පැරණි පිටුවේ විකිපාඨය, සංස්කරණයට පෙර", + "abusefilter-edit-builder-vars-new-wikitext": "නව පිටුවේ විකිපාඨය, සංස්කරණයට පසු", + "abusefilter-edit-builder-vars-new-text": "නව පිටුවේ පාඨය, ඕනෑම අධිකයකින් පැහැර ගත්තක්", "abusefilter-edit-builder-vars-new-html": "නව අනුවාදයේ ව්යාකරණ විග්රහ කරන ලද HTML මූලාශ්රය", "abusefilter-edit-builder-vars-restrictions-edit": "පිටුවේ ආරක්ෂණ මට්ටම වෙනස් කරන්න", "abusefilter-edit-builder-vars-restrictions-move": "පිටුවේ ආරක්ෂණ මට්ටම ගෙනයන්න", "abusefilter-edit-builder-vars-restrictions-create": "පිටුවේ ආරක්ෂාව තනන්න", "abusefilter-edit-builder-vars-restrictions-upload": "ගොනුවේ උඩුගත කිරීම් ආරක්ෂණය", - "abusefilter-edit-builder-vars-old-text-stripped": "පැරණි පිටුවේ පාඨය, stripped of any markup", + "abusefilter-edit-builder-vars-old-text": "පැරණි පිටුවේ පාඨය, stripped of any markup", "abusefilter-edit-builder-vars-old-links": "මෙම පිටුවේ ඇති සබැඳි, සංස්කරණයට පෙර", "abusefilter-edit-builder-vars-old-html": "පැරණි පිටුවේ විකිපෙළ, HTML වෙත parsed කරන ලදී", "abusefilter-edit-builder-vars-minor-edit": "වුවත් නොවුවත් සංස්කරණය සුළු ලෙස සලකුණු කර ඇත", @@ -335,7 +332,6 @@ "abusefilter-topnav-examine": "පසුවුණු සංස්කරණයන් විභාග කරන්න", "abusefilter-topnav-log": "අපයෙදුම් ලඝු සටහන", "abusefilter-topnav-tools": "නිදොස් කිරීම් මෙවලම්", - "abusefilter-topnav-import": "පෙරහන ආයාත කරන්න", "abusefilter-log-name": "අපයෙදුම් පෙරහන් ලඝු සටහන", "abusefilter-log-header": "පෙරහන් වෙත සිදු කරන ලද වෙනස්කම් වල සාරාංශයක් මෙම ලඝු සටහනෙන් පෙන්වයි.\nසම්පූර්ණ විස්තර සඳහා, මෑත පෙරහන් වෙනස්කම්වල [[Special:AbuseFilter/history|ලැයිස්තුව]] බලන්න.", "abusefilter-log-noresults": "ප්රතිඵල නොමැත", diff --git a/AbuseFilter/i18n/sk.json b/AbuseFilter/i18n/sk.json index a3ee9de9..dffe2bda 100644 --- a/AbuseFilter/i18n/sk.json +++ b/AbuseFilter/i18n/sk.json @@ -2,21 +2,24 @@ "@metadata": { "authors": [ "Helix84", - "Mormegil", - "Teslaton", - "Sudo77(new)", "Kusavica", + "Luky001", "Matma Rex", + "Mormegil", + "Patriccck", + "Robert Važan", + "Sudo77(new)", + "Teslaton", "TomášPolonec", - "Patriccck" + "Vlad5250" ] }, "abusefilter-desc": "Vykonáva automatickú heuristiku úprav.", - "abusefilter": "Nastavenie filtra zneužití", - "abuselog": "Záznam zneužití", + "abusefilter": "Správa filtra zneužití", + "abuselog": "Záznam filtra zneužití", "abusefilter-intro": "Vitajte v rozhraní na správu Filtrov zneužití.\nFilter zneužití je automatizovaný softvérový mechanizmus, ktorý na všetky operácie používa automatickú heuristiku.\nToto rozhranie zobrazuje zoznam definovaných filtrov a umožňuje ich zmenu.", "abusefilter-mustviewprivateoredit": "Z bezpečnostných dôvodov môžu toto rozhranie používať len používatelia s oprávnením spravovať filtre zneužitia alebo prezerať neverejné filtre.", - "abusefilter-warning": "'''Upozornenie:''' Táto činnosť bola automaticky identifikovaná ako škodlivá.\nNekonštruktívne úpravy budú rýchlo vrátené a zjavné alebo opakované nekonštruktívne zásahy budú mať za následok zablokovanie vášho účtu alebo IP adresy. Ak veríte, že je táto úprava konštruktívna, môžete znova kliknúť na Uložiť, čím ju potvrdíte.\nStručný popis pravidla zneužitia, ktoré zachytilo vašu úpravu, je: $1", + "abusefilter-warning": "'''Upozornenie:''' Táto činnosť bola automaticky identifikovaná ako škodlivá.\nNekonštruktívne činnosti budú rýchlo vrátené a zjavné alebo opakované nekonštruktívne zásahy budú mať za následok zablokovanie vášho účtu alebo IP adresy. Ak veríte, že je táto úprava konštruktívna, môžete znova kliknúť na Uložiť, čím ju potvrdíte.\nStručný popis pravidla zneužitia, ktoré zachytilo vašu úpravu, je: $1", "abusefilter-disallowed": "Táto činnosť bola automaticky identifikovaná ako škodlivá a preto bola odmietnutá.\nAk veríte, že je táto úprava konštruktívna, kontaktujte prosím správcu a oznámte im, čo ste sa {{GENDER:|pokúšal|pokúšala|pokúšali}} urobiť.\nStručný popis pravidla zneužitia, ktoré zachytilo vašu úpravu, je: $1", "abusefilter-blocked-display": "Táto činnosť bola automaticky identifikovaná ako škodlivá a preto bola odmietnutá.\nNaviac, na ochranu {{GRAMMAR:genitív|{{SITENAME}}}} boli zablokované úpravy z vášho používateľského účtu a všetkých príslušných IP adries.\nAk veríte, že to je omyl, kontaktujte prosím správcu.\nStručný popis pravidla zneužitia, ktoré zachytilo vašu úpravu, je: $1", "abusefilter-degrouped": "Táto činnosť bola automaticky identifikovaná ako škodlivá.\nNásledne bola odmietnutá a pretože existuje podozrenie, že váš účet bol zneužitý, všetky práva mu boli odobrané.\nAk veríte, že to je omyl, kontaktujte prosím byrokrata, vysvetlite mu, čo ste sa pokúšali urobiť a môže obnoviť vaše práva.\nStručný popis pravidla zneužitia, ktoré zachytilo vašu úpravu, je: $1", @@ -24,12 +27,14 @@ "abusefilter-blocker": "Filter zneužití", "abusefilter-blockreason": "Automaticky zachytené filtrom zneužití. Popis účinného pravidla: $1", "abusefilter-degroupreason": "Práva automaticky odobral filter zneužívania. Popis pravidla: $1", + "abusefilter-blockautopromotereason": "Automatické potvrdenie automaticky pozastaveno filtrom zneužití.\nPopis pravidla: $1", "abusefilter-accountreserved": "Tento názov účtu je vyhradený pre použitie filtrom zneužití.", - "right-abusefilter-modify": "Zmeniť filtre zneužití", + "right-abusefilter-modify": "Vytvoriť alebo upraviť filtre zneužití", "right-abusefilter-view": "Zobraziť filtre zneužití", "right-abusefilter-log": "Zobraziť záznam zneužití", "right-abusefilter-log-detail": "Zobraziť podrobnosti položiek záznamu zneužití", - "right-abusefilter-private": "Zobraziť osobné údaje v zázname zneužití", + "right-abusefilter-privatedetails": "Zobraziť osobné údaje v zázname zneužití", + "right-abusefilter-privatedetails-log": "Prezeranie záznamu prístupu k súkromným detailom filtra zneužití", "right-abusefilter-modify-restricted": "Zmeniť filtre zneužitia s obmedzenými operáciami", "right-abusefilter-revert": "Vrátiť všetky zmeny vykonané zadaným filtrom zneužitia", "right-abusefilter-view-private": "Zobraziť filtre zneužitia označené ako neverejné", @@ -41,16 +46,22 @@ "action-abusefilter-view": "zobraziť filtre zneužití", "action-abusefilter-log": "zobraziť filter zneužití", "action-abusefilter-log-detail": "zobraziť podrobné záznamy filtra zneužití", - "action-abusefilter-private": "zobraziť privátne údaje v zázname filtra zneužití", + "action-abusefilter-privatedetails": "zobraziť privátne údaje v zázname filtra zneužití", + "action-abusefilter-privatedetails-log": "prezrieť si záznam prístupu k súkromným detailom filtra zneužití", "action-abusefilter-modify-restricted": "zmeniť filtre zneužití s obmedzenými operáciami", "action-abusefilter-revert": "vrátiť všetky zmeny vykonané daným filtrom zneužití", "action-abusefilter-view-private": "zobraziť filtre zneužitia označené ako neverejné", "action-abusefilter-log-private": "zobraziť záznamy filtrov zneužitia označených ako neverejné", - "abusefilter-log": "Záznam filtra zneužití", + "action-abusefilter-hide-log": "skryť položky v zázname zneužití", + "action-abusefilter-hidden-log": "zobraziť skryté položky v zázname zneužití", + "action-abusefilter-modify-global": "vytvoriť alebo upraviť globálne filtre zneužití", "abusefilter-log-summary": "Tento záznam zobrazuje zoznam všetkých operácií, ktoré filtre zachytili.", "abusefilter-log-search": "Hľadať v zázname filtra zneužití", "abusefilter-log-search-user": "Používateľ:", - "abusefilter-log-search-filter": "ID filtra:", + "abusefilter-log-search-group": "Skupina filtrov:", + "abusefilter-log-search-group-any": "Ľubovoľný", + "abusefilter-log-search-filter": "ID filtrov:", + "abusefilter-log-search-filter-help": "Oddeľujte zvislými čiarami („|“), globálne filtre začnite s prefixom „$1“", "abusefilter-log-search-title": "Názov:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-impact": "Účinok:", @@ -59,12 +70,17 @@ "abusefilter-log-search-impact-not-saved": "Bez uložených úprav", "abusefilter-log-search-entries-label": "Viditeľnosť:", "abusefilter-log-search-entries-all": "Všetky vstupy", + "abusefilter-log-search-entries-hidden": "Len skryté záznamy", + "abusefilter-log-search-entries-visible": "Len viditeľné záznamy", + "abusefilter-log-search-action-label": "Spúšťajúca akcia:", + "abusefilter-log-search-action-other": "Iné", + "abusefilter-log-search-action-any": "Všetky", "abusefilter-log-search-action-taken-label": "Vykonaná akcia:", "abusefilter-log-search-action-taken-any": "Všetky", "abusefilter-log-search-submit": "Hľadať", - "abusefilter-log-entry": "$1: $2 spustil filter zneužití, pri vykonávaní operácie „$3“ na $4.\nVykonané opatrenia: $5;\nPopis filtra: $6", + "abusefilter-log-entry": "$1: $2 {{GENDER:$8|spustil|spustila}} filter zneužití pri vykonávaní operácie „$3“ na $4.\nVykonané opatrenia: $5;\nPopis filtra: $6", "abusefilter-log-entry-withdiff": "$1: $2 {{GENDER:$8|spustil|spustila|spustil(a)}} filter pri činnosti „$3“ na $4.\nVykonané opatrenia: $5;\nPopis filtra: $6 ($7)", - "abusefilter-log-detailedentry-meta": "$1: $2 {{GENDER:$9|spustil|spustila|spustil(a)}} filter $3, vykonaná operácia „$4“ na $5.\nVykonané opatrenia: $6;\nPopis filtra: $7 ($8)", + "abusefilter-log-detailedentry-meta": "$1: $2 {{GENDER:$9|spustil|spustila|spustil(a)}} filter $3 pri vykonanávaní operácie „$4“ na $5.\nVykonané opatrenia: $6;\nPopis filtra: $7 ($8)", "abusefilter-log-detailedentry-global": "globálny filter $1", "abusefilter-log-detailedentry-local": "filter $1", "abusefilter-log-detailslink": "podrobnosti", @@ -74,26 +90,46 @@ "abusefilter-log-details-var": "Premenná", "abusefilter-log-details-val": "Hodnota", "abusefilter-log-details-vars": "Parametre operácie", - "abusefilter-log-details-private": "Osobné údaje", + "abusefilter-log-details-privatedetails": "Podrobnosti osobného záznamu", "abusefilter-log-details-ip": "Zdrojová IP adresa", + "abusefilter-log-details-checkuser": "Skontrolovať používateľa", "abusefilter-log-noactions": "žiadne", "abusefilter-log-details-diff": "Zmeny vykonané v úprave", "abusefilter-log-linkoncontribs": "záznam zneužití", - "abusefilter-log-linkoncontribs-text": "Záznam zneužití tohto používateľa", - "abusefilter-log-hidden": "(položka skrytá)", + "abusefilter-log-linkoncontribs-text": "Záznam zneužití pre {{GENDER:$1|tohto používateľa|túto používateľku}}", + "abusefilter-log-linkonhistory": "zobraziť záznamy zneužití", + "abusefilter-log-linkonhistory-text": "Zobraziť záznamy filtrov zneužití pre túto stránku", + "abusefilter-log-linkonundelete": "zobraziť záznamy zneužití", + "abusefilter-log-linkonundelete-text": "Zobraziť záznamy filtrov zneužití pre túto stránku", "abusefilter-log-hidden-implicit": "(položka skrytá, pretože bola odstránená revízia)", "abusefilter-log-cannot-see-details": "Nemáte oprávnenie na prehliadanie podrobností tejto položky.", + "abusefilter-log-cannot-see-privatedetails": "Nemáte právo prezrieť si súkromné detaily tohto záznamu.", + "abusefilter-log-nonexistent": "Záznam s daným identifikátorom neexistuje.", "abusefilter-log-details-hidden": "Nemôžete si pozrieť podrobnosti tejto položky, pretože je verejnosti skrytá.", + "abusefilter-log-details-hidden-implicit": "Nemôžete si prezerať detaily tohto záznamu, pretože úprava s ním súvisiaca je pred verejnosťou skrytá.", "abusefilter-log-private-not-included": "Jeden alebo viac filtrov s uvedeným ID je neverejných. Keďže nemáte oprávnenie prezerať si podrobnosti neverejných filtrov, neboli tieto filtre prehľadávané.", "abusefilter-log-hide-legend": "Skryť položku v zázname", "abusefilter-log-hide-id": "ID položky záznamu:", "abusefilter-log-hide-hidden": "Skryť túto položku pred verejnosťou", "abusefilter-log-hide-reason": "Dôvod:", + "abusefilter-log-hide-reason-other": "Iný/ďalší dôvod:", "abusefilter-log-hide-forbidden": "Nemáte oprávnenie skrývať položky záznamu zneužití.", - "logentry-abusefilter-hit": "$1 {{GENDER:$2|spustil|spustila|spustil(a)}} $4, ktorý vykonal činnosť „$5“ na $3. Vykonané kroky: $6 ($7)", - "abusefilter-management": "Správa filtra zneužití", + "abusefilter-log-entry-suppress": "$1 {{GENDER:$2|skryl|skryla}} $3", + "abusefilter-log-entry-unsuppress": "$1 {{GENDER:$2|odkryl|odkryla}} $3", + "logentry-abusefilter-hit": "$1 {{GENDER:$2|spustil|spustila|spustil(a)}} $4, {{GENDER:$2|ktorý vykonal}} činnosť „$5“ na $3. Vykonané kroky: $6 ($7)", + "log-action-filter-abusefilter": "Typ zmeny filtra:", + "log-action-filter-abusefilter-create": "Vytvorenie nového filtra", + "log-action-filter-abusefilter-modify": "Modifikácia filtra", + "log-action-filter-suppress-abuselog": "Utajenie záznamu filtra zneužití", + "log-action-filter-rights-blockautopromote": "Zablokovánie automatického potvrdenia", + "log-action-filter-rights-restoreautopromote": "Obnova automatického potvrdenia", + "logentry-abusefilterprivatedetails-access": "$1 si {{GENDER:$2|prezrel|prezrela}} súkromné detaily k $3", + "logentry-rights-blockautopromote": "$1 {{GENDER:$2|zablokoval|zablokovala}} automatické schválenie {{GENDER:$4|používateľa|používateľky}} $3 na obdobie $5", + "logentry-rights-restoreautopromote": "$1 {{GENDER:$2|obnovil|obnovila}} možnosť automatického schválenia {{GENDER:$4|používateľa|používateľky}} $3", + "abusefilterprivatedetails-log-name": "Záznam prístupu k súkromným detailom filtra zneužití", "abusefilter-list": "Všetky filtre", "abusefilter-list-id": "ID filtra", + "abusefilter-list-pattern": "Vzor", "abusefilter-list-status": "Stav", "abusefilter-list-public": "Verejný popis", "abusefilter-list-consequences": "Následky", @@ -109,8 +145,10 @@ "abusefilter-enabled": "Zapnuté", "abusefilter-deleted": "Zmazané", "abusefilter-disabled": "Vypnuté", + "abusefilter-throttled": "obmedzený", "abusefilter-hitcount": "$1 {{PLURAL:$1|zásah|zásahov}}", "abusefilter-new": "Vytvoriť nový filter", + "abusefilter-import-button": "Importovať filter", "abusefilter-return": "Vrátiť sa späť na správu filtrov", "abusefilter-status-global": "Globálny", "abusefilter-list-options": "Možnosti", @@ -119,40 +157,48 @@ "abusefilter-list-options-deleted-hide": "Skryť zmazané filtre", "abusefilter-list-options-deleted-show": "Vrátane zmazaných filtrov", "abusefilter-list-options-scope": "Zobraziť filtre:", - "abusefilter-list-options-scope-local": "Lokálna wiki", - "abusefilter-list-options-scope-global": "Globálne pravidlá", + "abusefilter-list-options-scope-local": "Len lokálne pravidlá", + "abusefilter-list-options-scope-global": "Len globálne pravidlá", "abusefilter-list-options-scope-all": "Lokálne aj globálne pravidlá", "abusefilter-list-options-further-options": "Ďalšie možnosti:", "abusefilter-list-options-hidedisabled": "Skryť vypnuté filtre", "abusefilter-list-options-hideprivate": "Skryť neverejné filtre", "abusefilter-list-options-searchfield": "Hľadať v podmienkach:", + "abusefilter-list-options-searchpattern": "Vložte výraz", "abusefilter-list-options-searchoptions": "Spôsob hľadania:", "abusefilter-list-options-search-like": "Obyčajný výraz", "abusefilter-list-options-search-rlike": "Regulárny výraz", "abusefilter-list-options-search-irlike": "Regulárny výraz nerozlišujúci veľkosť písmen", + "abusefilter-list-invalid-searchmode": "Zadaný režim vyhľadávania je neplatný.", + "abusefilter-list-regexerror": "Počas vyhľadávania sa stala chyba: Syntaktická chyba regulárneho výrazu.", "abusefilter-list-options-submit": "Aktualizovať", "abusefilter-tools-text": "Tu sa nachádzajú niektoré nástroje, ktoré možno využiť pri tvorbe a ladení filtrov zneužitia.", "abusefilter-tools-expr": "Tester výrazov", "abusefilter-tools-submitexpr": "Vyhodnotiť", + "abusefilter-tools-syntax-error": "Filter má neplatnú syntax.", "abusefilter-tools-reautoconfirm": "Obnoviť stav zaregistrovaný", "abusefilter-tools-reautoconfirm-user": "Používateľ:", "abusefilter-tools-reautoconfirm-submit": "Potvrdiť zaregistrovanie", + "abusefilter-tools-restoreautopromote": "Automatické potvrdzovanie obnovené skrz nástroje filtra zneužití.", "abusefilter-reautoconfirm-none": "Používateľ nemal vypnutý {{GENDER:$1|svoj}} stav „registrovaný”.", "abusefilter-reautoconfirm-notallowed": "Nemáte oprávnenie obnoviť stav „registrovaný”.", "abusefilter-reautoconfirm-done": "Stav účtu „potvrdený“ bol obnovený", - "abusefilter-status": "{{PLURAL:$1|Posledná $1 operácia|Z posledných $1 operácií}} $2 ($3 %) {{PLURAL:$4|dosiahla|dosiahli|dosiahlo}} hraničnú podmienku $4. $5 ($6 %) {{PLURAL:$5|zodpovedala|zodpovedali|zodpovedalo}} momentálne zapnutým filtrom.", + "abusefilter-status": "{{PLURAL:$1|Z posledných $1 operácií}} $2 ($3 %) {{PLURAL:$4|dosiahla|dosiahli|dosiahlo}} hraničnú podmienku $4. $5 ($6 %) {{PLURAL:$5|zodpovedala|zodpovedali|zodpovedalo}} aspoň jednému z momentálne zapnutých filtrov.", "abusefilter-edit": "Úprava filtra zneužití", "abusefilter-edit-subtitle": "Úprava filtra $1", "abusefilter-edit-subtitle-new": "Vytvorenie filtra", + "abusefilter-edit-token-not-match": "Úprava nebola uložená! Uložte ju znova, prosím.", "abusefilter-edit-oldwarning": "<strong>Upravujete starú verziu tohto filtra. Uvedené štatistiky sa týkajú najnovšej verzie filtra. Ak svoje zmeny uložíte, prepíšete všetky zmeny od revízie, ktorú upravujete.</strong> • [[Special:AbuseFilter/history/$2|Vrátiť sa na históriu tohto filtra]]", + "abusefilter-edit-oldwarning-view": "<strong>Prezeráte si starú verziu tohto filtra.\nUvedené štatistiky sú pre aktuálnu verziu filtra.</strong> •\n[[Special:AbuseFilter/history/$2|Vrátiť sa na históriu tohto filtra]].", "abusefilter-edit-status-label": "Štatistika:", - "abusefilter-edit-status": "{{PLURAL:$1|Z poslednej $1 operácie|Z posledných $1 operácií}} tomuto filtru {{PLURAL:$2|zodpovedala|zodpovedali|zodpovedalo}} $2 ($3 %).", - "abusefilter-edit-status-profile": "{{PLURAL:$1|Z poslednej $1 operácie|Z posledných $1 operácií}} tomuto filtru {{PLURAL:$2|zodpovedala|zodpovedali|zodpovedalo}} $2 ($3 %).\nPriemerný čas behu je $4 ms a spotrebuje $5 {{PLURAL:$5|podmienku|podmienky|podmienok}} z celkového povoleného počtu podmienok.", + "abusefilter-edit-status": "{{PLURAL:$1|Z posledných $1 operácií}} tomuto filtru {{PLURAL:$2|zodpovedala|zodpovedali|zodpovedalo}} $2 ($3 %).\nPriemerná doba jeho činnosti je $4 ms a potrebuje $5 {{PLURAL:$5|podmienku|podmienky|podmienok}} z povoleného limitu.", + "abusefilter-edit-throttled-warning": "'''Varovanie:''' Tento filter bol automaticky označený ako škodlivý. Z bezpečnostných dôvodov nebudú nasledovné akcie vykonané: $1. Pre odstránenie tohto obmedzenia, prosím, skontrolujte a [[mw:Extension:AbuseFilter/Conditions|optimalizujte]] podmienky.", "abusefilter-edit-new": "Nový filter", "abusefilter-edit-save": "Uložiť filter", "abusefilter-edit-id": "ID filtra:", "abusefilter-edit-switch-editor": "Prepnúť editor", "abusefilter-edit-description": "Popis:\n:''(verejne viditeľný)''", + "abusefilter-edit-field-description": "popis", "abusefilter-edit-group": "Skupinový filter:", "abusefilter-edit-flags": "Príznaky:", "abusefilter-edit-enabled": "Zapnúť tento filter", @@ -160,6 +206,7 @@ "abusefilter-edit-hidden": "Skryť verejné zobrazovanie podrobností filtra", "abusefilter-edit-global": "Globálny filter", "abusefilter-edit-rules": "Pravidlá:", + "abusefilter-edit-field-conditions": "podmienky", "abusefilter-edit-notes": "Poznámky:", "abusefilter-edit-lastmod": "Posledná zmena filtra:", "abusefilter-edit-lastmod-text": "$1, $2", @@ -170,25 +217,53 @@ "abusefilter-edit-action-blockautopromote": "Odobrať používateľovi stav „zaregistrovaný”", "abusefilter-edit-action-degroup": "Odstrániť používateľa zo všetkých privilegovaných skupín", "abusefilter-edit-action-block": "Zablokovať úpravy používateľa a/alebo IP adresy", + "abusefilter-edit-action-blocktalk": "Zablokovať používateľovi a/alebo IP adrese možnosť úpravy vlastnej diskusnej stránky", "abusefilter-edit-action-throttle": "Spustiť operáciu len ak používateľ dosiahne limit rýchlosti úprav", - "abusefilter-edit-action-rangeblock": "Zablokovať /16 rozsah, z ktorého pochádza adresa používateľa.", + "abusefilter-edit-action-rangeblock": "Zablokovať rozsah IP, z ktorého pochádza adresa používateľa", "abusefilter-edit-action-tag": "Označiť úpravu na ďalšiu kontrolu.", "abusefilter-edit-throttle-count": "Počet povolených operácií:", - "abusefilter-edit-throttle-period": "Časový interval:", - "abusefilter-edit-throttle-groups": "Obmedzenie rýchlosti úprav skupiny:\n:''(jedna na riadok, viaceré oddelené čiarkami)''", + "abusefilter-edit-throttle-period": "Časový interval (v sekundách):", + "abusefilter-edit-throttle-groups": "Obmedzenie rýchlosti úprav skupiny:", + "abusefilter-edit-throttle-groups-help": "Viď $1.", + "abusefilter-edit-throttle-groups-help-text": "dokumentáciu na mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Oddeľujte čiarkami na spojenie skrz AND a zalomte riadok na spojenie skrz OR", + "abusefilter-edit-throttle-placeholder": "Oddeľujte čiarkami na spojenie skrz AND a vkladajte jedno po druhom na spojenie skrz OR", + "abusefilter-throttle-ip": "IP adresa", + "abusefilter-throttle-user": "používateľský účet", + "abusefilter-throttle-range": "rozsah /16", + "abusefilter-throttle-creationdate": "datum založenia účtu", + "abusefilter-throttle-editcount": "počet úprav", + "abusefilter-throttle-site": "celá stránka", + "abusefilter-throttle-page": "stránka", + "abusefilter-throttle-none": "(žiadne)", "abusefilter-throttle-details": "Povoliť $1 {{PLURAL:$1|akciu|akcie|akcií}} {{PLURAL:$2|každú sekundu|každé $2 sekundy|každých $2 sekúnd}}, limity počítané pre: $3", "abusefilter-edit-warn-message": "Systémová správa použitá pri upozornení:", "abusefilter-edit-warn-other": "Iná správa", - "abusefilter-edit-warn-other-label": "Názov stránky inej správy:\n:''(bez predpony MediaWiki)''", + "abusefilter-edit-warn-other-label": "Názov stránky inej správy:\n:''(bez predpony „MediaWiki:“)''", "abusefilter-edit-warn-actions": "Operácie:", - "abusefilter-edit-warn-preview": "Zobraziť náhľad vybranej správy", + "abusefilter-edit-warn-preview": "Zobraziť/Skryť náhľad vybranej správy", "abusefilter-edit-warn-edit": "Vytvoriť/upraviť vybranú správu", - "abusefilter-edit-tag-tag": "Označiť nasledovnými značkami (jednu na riadok):", + "abusefilter-edit-disallow-message": "Systémová správa použitá pri hatení:", + "abusefilter-edit-disallow-other": "Iná správa", + "abusefilter-edit-disallow-other-label": "Názov stránky inej správy:\n:''(bez predpony „MediaWiki:“)''", + "abusefilter-edit-disallow-actions": "Operácie:", + "abusefilter-edit-disallow-preview": "Zobraziť/Skryť náhľad vybranej správy", + "abusefilter-edit-disallow-edit": "Vytvoriť/upraviť vybranú správu", + "abusefilter-edit-tag-tag": "[[Special:Tags|Značky]], ktoré sa majú pridať:", + "abusefilter-edit-tag-placeholder": "Pridať prvky (osve alebo oddelené čiarkami)", + "abusefilter-edit-tag-hidden-placeholder": "Pridať prvky (oddelené čiarkami)", + "abusefilter-edit-block-anon-durations": "Obdobie trvania zablokovania pre anonymných používateľov:", + "abusefilter-edit-block-user-durations": "Obdobie trvania zablokovania pre registrovaných používateľov:", + "abusefilter-block-anon": "Blokovať anonymných používateľov", + "abusefilter-block-user": "blokovať registrovaných používateľov", + "abusefilter-block-talk": "diskusná stránka zablokovaná", "abusefilter-edit-denied": "Nemôžete zobraziť podrobnosti toho filtra, pretože jeho verejné zobrazovanie je vypnuté", "abusefilter-edit-main": "Parametre filtra", "abusefilter-edit-done-subtitle": "Filter bol upravený", - "abusefilter-edit-done": "Úspešne ste uložili zmeny filtra $1.", + "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Vaše úpravy]] [[Special:AbuseFilter/$1|filtra $3]] boli uložené.", "abusefilter-edit-badsyntax": "Filter, ktorý ste zadali, obsahuje syntaktickú chybu. Výstup syntaktického analyzátora: <pre>$1</pre>", + "abusefilter-edit-missingfields": "Tieto polia sú povinné: $1", + "abusefilter-edit-deleting-enabled": "Aktívny filter nemožno označiť ako zmazaný.", "abusefilter-edit-restricted": "Nemôžete upravovať tento filter, pretože obsahuje jednu alebo viac obmedzených operácií. Prosím, požiadajte používateľa s potrebným oprávnením, aby za vás vykonal túto zmenu.", "abusefilter-edit-viewhistory": "Zobraziť históriu tohto filtra", "abusefilter-edit-history": "História:", @@ -200,9 +275,13 @@ "abusefilter-edit-export": "Exportovať tento filter do inej wiki", "abusefilter-edit-syntaxok": "Neboli zistené žiadne syntaktické chyby.", "abusefilter-edit-syntaxerr": "Zistená syntaktická chyba: $1", - "abusefilter-edit-bad-tags": "Jedna alebo viac zo značiek, ktoré ste uviedli nie je platných.\nZnačky by mali byť krátke a nemali by obsahovať špeciálne znaky.", + "abusefilter-edit-warn-leave": "Opustenie stránky privodí stratu akejkoľvek zmeny tohto filtra.", + "abusefilter-edit-bad-tags": "Jedna alebo viac zo značiek, ktoré ste uviedli nie je platných.\nZnačky by mali byť krátke, nemali by obsahovať špeciálne znaky a nesmú byť rezervované iným softvérom. Skúste zvoliť iný názov značky.", "abusefilter-edit-notallowed": "Nemáte oprávnenie vytvárať alebo meniť filtre zneužití", "abusefilter-edit-notallowed-global": "Nemáte oprávnenie vytvárať alebo meniť globálne filtre zneužití", + "abusefilter-edit-notallowed-global-custom-msg": "Vlastné varovné alebo hatiace správy nie sú pre globálne filtre podporované", + "abusefilter-edit-invalid-warn-message": "Varovnú správu nemožno nechať prázdnu.", + "abusefilter-edit-invalid-disallow-message": "Hatiacu správu nemožno nechať prázdnu.", "abusefilter-edit-builder-select": "Vyberte voľbu, ktorá sa pridá na miesto, kde je kurzor", "abusefilter-edit-builder-group-op-arithmetic": "Aritmetické operátory", "abusefilter-edit-builder-op-arithmetic-addition": "Sčítanie (+)", @@ -212,9 +291,9 @@ "abusefilter-edit-builder-op-arithmetic-modulo": "Modulo (%)", "abusefilter-edit-builder-op-arithmetic-pow": "Umocnenie (**)", "abusefilter-edit-builder-group-op-comparison": "Operátory porovnávania", - "abusefilter-edit-builder-op-comparison-equal": "Rovná sa (==)", + "abusefilter-edit-builder-op-comparison-equal": "Hodnota sa rovná (==)", "abusefilter-edit-builder-op-comparison-equal-strict": "Hodnota a typ sa rovnajú (===)", - "abusefilter-edit-builder-op-comparison-notequal": "Nerovná sa (!=)", + "abusefilter-edit-builder-op-comparison-notequal": "Hodnota sa nerovná (!=)", "abusefilter-edit-builder-op-comparison-notequal-strict": "Hodnota alebo typ sa nerovnajú (!==)", "abusefilter-edit-builder-op-comparison-lt": "Menší ako (<)", "abusefilter-edit-builder-op-comparison-gt": "Väčší ako (>)", @@ -232,7 +311,8 @@ "abusefilter-edit-builder-misc-contains": "Reťazec vľavo obsahuje reťazec vpravo (obsahuje)", "abusefilter-edit-builder-misc-stringlit": "Reťazcový literál (\"\")", "abusefilter-edit-builder-misc-tern": "Ternárny operátor (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Podmienka (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Podmienka (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "Krátka podmienka (if X then Y end)", "abusefilter-edit-builder-group-funcs": "Funkcie", "abusefilter-edit-builder-funcs-length": "Dĺžka reťazca (length)", "abusefilter-edit-builder-funcs-lcase": "Zmeniť na malé písmená (lcase)", @@ -261,6 +341,7 @@ "abusefilter-edit-builder-group-vars": "Premenné", "abusefilter-edit-builder-vars-accountname": "Názov účtu (on account creation)", "abusefilter-edit-builder-vars-timestamp": "Čas úpravy v unixovom formáte", + "abusefilter-edit-builder-vars-timestamp-expanded": "Čas záznamu", "abusefilter-edit-builder-vars-action": "Operácia", "abusefilter-edit-builder-vars-addedlines": "Riadky pridané pri úprave", "abusefilter-edit-builder-vars-delta": "Zmena veľkosti pri úprave", @@ -268,20 +349,24 @@ "abusefilter-edit-builder-vars-newsize": "Nová veľkosť stránky", "abusefilter-edit-builder-vars-oldsize": "Stará veľkosť stránky", "abusefilter-edit-builder-vars-old-content-model": "Pôvodný model obsahu", + "abusefilter-edit-builder-vars-new-content-model": "Nový model obsahu", "abusefilter-edit-builder-vars-removedlines": "Riadky odstránené pri úprave", "abusefilter-edit-builder-vars-summary": "Zhrnutie úprav/zdôvodnenie", "abusefilter-edit-builder-vars-page-id": "ID stránky", "abusefilter-edit-builder-vars-page-ns": "Menný priestor stránky", "abusefilter-edit-builder-vars-page-title": "Názov stránky (bez menného priestoru)", "abusefilter-edit-builder-vars-page-prefixedtitle": "Úplný názov stránky", + "abusefilter-edit-builder-vars-page-age": "Vek stránky (v sekundách)", "abusefilter-edit-builder-vars-movedfrom-id": "ID presúvanej stránky", "abusefilter-edit-builder-vars-movedfrom-ns": "Menný priestor presúvanej stránky", "abusefilter-edit-builder-vars-movedfrom-title": "Názov presúvanej stránky", "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "Úplný názov presúvanej stránky", + "abusefilter-edit-builder-vars-movedfrom-age": "Vek stránky na presun (v sekundách)", "abusefilter-edit-builder-vars-movedto-id": "ID stránky, na ktorú sa presúva", "abusefilter-edit-builder-vars-movedto-ns": "Menný priestor, do ktorého sa presúva", "abusefilter-edit-builder-vars-movedto-title": "Názov, na ktorý sa stránka presúva", "abusefilter-edit-builder-vars-movedto-prefixedtitle": "Úplný názov, na ktorý sa stránka presúva", + "abusefilter-edit-builder-vars-movedto-age": "Vek cieľovej stránky (v sekundách)", "abusefilter-edit-builder-vars-user-editcount": "Počet úprav používateľa", "abusefilter-edit-builder-vars-user-age": "Vek používateľského účtu", "abusefilter-edit-builder-vars-user-name": "Názov používateľského účtu", @@ -298,12 +383,12 @@ "abusefilter-edit-builder-vars-all-links": "Všetky externé odkazy v novom texte", "abusefilter-edit-builder-vars-added-links": "Všetky externé odkazy pridané v úprave", "abusefilter-edit-builder-vars-removed-links": "Všetky externé odkazy odstránené v úprave", - "abusefilter-edit-builder-vars-old-text": "Pôvodný wikitext stránky pred úpravou (už sa nepoužíva)", - "abusefilter-edit-builder-vars-new-text": "Nový wikitext stránky po úprave", + "abusefilter-edit-builder-vars-old-wikitext": "Pôvodný wikitext stránky pred úpravou", + "abusefilter-edit-builder-vars-new-wikitext": "Nový wikitext stránky po úprave", "abusefilter-edit-builder-vars-new-pst": "Nový wikitext stránky, po transformácii pred uložením", "abusefilter-edit-builder-vars-diff-pst": "Zjednotený diff zmien vykonaných pri úprave, po transformácii pred uložením", "abusefilter-edit-builder-vars-addedlines-pst": "Riadky pridané pri úprave, po transformácii pred uložením", - "abusefilter-edit-builder-vars-new-text-stripped": "Nový text stránky zbavený formátovania", + "abusefilter-edit-builder-vars-new-text": "Nový text stránky zbavený formátovania", "abusefilter-edit-builder-vars-new-html": "Vygenerovaný HTML markup novej revízie", "abusefilter-edit-builder-vars-restrictions-edit": "Úroveň zámku stránky pre úpravy", "abusefilter-edit-builder-vars-restrictions-move": "Úroveň zámku stránky pre presuny", @@ -317,10 +402,10 @@ "abusefilter-edit-builder-vars-movedto-restrictions-move": "Úroveň zámku stránky, na ktorú sa presúva, pre presuny", "abusefilter-edit-builder-vars-movedto-restrictions-create": "Úroveň zámku stránky, na ktorú sa presúva, pre založenie", "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Úroveň zámku stránky, na ktorú sa presúva, pre upload", - "abusefilter-edit-builder-vars-old-text-stripped": "Pôvodný text stránky, zbavený všetkých značiek", + "abusefilter-edit-builder-vars-old-text": "Pôvodný text stránky, zbavený všetkých značiek", "abusefilter-edit-builder-vars-old-links": "Odkazy na stránke pred úpravou", "abusefilter-edit-builder-vars-old-html": "Pôvodný wikitext stránky, prevedený na HTML (už sa nepoužíva)", - "abusefilter-edit-builder-vars-minor-edit": "Či je alebo nie je táto úprava označená ako drobná", + "abusefilter-edit-builder-vars-minor-edit": "Či je alebo nie je táto úprava označená ako drobná (už sa nepoužíva)", "abusefilter-edit-builder-vars-file-sha1": "SHA1 haš obsahu súboru", "abusefilter-edit-builder-vars-file-size": "Veľkosť súboru v bajtoch", "abusefilter-edit-builder-vars-file-mime": "MIME typ súboru", @@ -328,6 +413,8 @@ "abusefilter-edit-builder-vars-file-width": "Šírka súboru v pixeloch", "abusefilter-edit-builder-vars-file-height": "Výška súboru v pixeloch", "abusefilter-edit-builder-vars-file-bits-per-channel": "Farebná hĺbka súboru v bitoch na farebný kanál", + "abusefilter-edit-builder-vars-wiki-name": "Názov databázy wiki", + "abusefilter-edit-builder-vars-wiki-language": "Jazykový kód wiki", "abusefilter-filter-log": "Posledné úpravy filtra", "abusefilter-history": "História zmien filtra zneužití $1", "abusefilter-history-foruser": "Zmeny používateľa $1", @@ -346,6 +433,7 @@ "abusefilter-history-filterid": "Filter", "abusefilter-history-select-legend": "Upraviť vyhľadávací reťazec", "abusefilter-history-select-user": "Používateľ:", + "abusefilter-history-select-filter": "ID filtra:", "abusefilter-history-select-submit": "Upraviť", "abusefilter-history-diff": "Zmeny", "abusefilter-history-error-hidden": "Filter, ktorý ste si vyžiadali, je skrytý a nemôžete zobraziť jeho históriu.", @@ -356,14 +444,19 @@ "abusefilter-exception-unclosedstring": "Neukončený reťazec začínajúci na pozícii $1.", "abusefilter-exception-invalidoperator": "Neplatný operátor $2 na pozícii $1.", "abusefilter-exception-unrecognisedtoken": "Nerozpoznaný token „$2“ na pozícii $1.", - "abusefilter-exception-noparams": "Funkcii „$2“ na pozícii $1 neboli zadané žiadne parametre.", + "abusefilter-exception-noparams": "Funkcii „$2“ na pozícii $1 neboli zadané žiadne parametre.\n{{PLURAL:$3|Očakávaný jeden parameter|Očakávané $3 parametre|Očakávaných $3 parametrov}}.", "abusefilter-exception-dividebyzero": "Neplatný pokus deliť $2 nulou na pozícii $1.", "abusefilter-exception-unrecognisedvar": "Nerozpoznaná premenná $2 na pozícii $1", "abusefilter-exception-notenoughargs": "Nebol zadaný dostatočný pčet argumentov funkcii $2 zavolanej na znaku $1.\n{{PLURAL:$3|Očakával sa $3 argument|Očakávali sa $3 argumenty|Očakávalo sa $3 argumentov}}, {{PLURAL:$4|zadaný $4|zadané $4|zadaných $4}}.", - "abusefilter-exception-regexfailure": "Chyba v regulárnom výraze „$3“ na znaku $1: „$2“", - "abusefilter-exception-overridebuiltin": "Neplatné prekrytie vstavanej premennej „$2“ na pozícii $1.", - "abusefilter-exception-outofbounds": "Požadovaná bola neexistujúca položka zoznamu $2 (veľkosť zoznamu = $3) na pozícii $1.", + "abusefilter-exception-toomanyargs": "Priveľa parametrov funkcie $2 volanej na pozícii $1.\n{{PLURAL:$3|Očakávaný nanajvýš 1 parameter|Očakávané nanajvýš $3 parametre|Očakávaných nanajvýš $3 parametrov}}, {{PLURAL:$4|prijatý bol|prijaté boli|prijatých bolo}} $4.", + "abusefilter-exception-regexfailure": "Chyba v regulárnom výraze „$2“ na pozícii $1.", + "abusefilter-exception-overridebuiltin": "Neplatné prekrytie vstavaného identifikátora „$2“ na pozícii $1.", + "abusefilter-exception-outofbounds": "Bol požadovaný neexistujúci prvok poľa $2 (veľkosť poľa = $3) na pozícii $1.", + "abusefilter-exception-negativeindex": "Záporné indexy v poliach nie sú povolené. Bol použitý index „$2“ na pozícii $1.", "abusefilter-exception-notarray": "Požaduje sa položka poľa premennej, ktorá nie je pole na pozícii $1.", + "abusefilter-exception-unclosedcomment": "Neuzavretý komentár na pozícii $1.", + "abusefilter-exception-invalidiprange": "Neplatný rozsah IP adries „$2“ na pozícii $1.", + "abusefilter-exception-disabledvar": "Premenná $2 na pozícii $1 sa už nepoužíva.", "abusefilter-action-tag": "Značka", "abusefilter-action-throttle": "Obmedzenie", "abusefilter-action-warn": "Upozornenie", @@ -374,19 +467,20 @@ "abusefilter-action-disallow": "Zákaz", "abusefilter-revert-title": "Vrátiť všetky zmeny filtra $1", "abusefilter-revert-intro": "Tento formulár vám umožňuje vrátiť všetky zmeny vykonané filtrom zneužitia $1.\nProsím, buďte opatrní pri používaní tohto nástroja.", - "abusefilter-revert-preview-item": "$1: $2 vykonal $3 na $4. Operácie, ktoré sa majú vrátiť: $5 ($6)", + "abusefilter-revert-preview-item": "$1: $2 {{GENDER:$7|vykonal|vykonala}} $3 na $4.\nOperácie, ktoré sa majú vrátiť: $5 ($6)", "abusefilter-revert-search-legend": "Vybrať operácie filtra zneužitia, ktoré sa majú vrátiť", "abusefilter-revert-periodstart": "Začiatok obdobia:", "abusefilter-revert-periodend": "Koniec obdobia:", "abusefilter-revert-search": "Vyberte operácie", "abusefilter-revert-filter": "ID filtra:", - "abusefilter-revert-preview-intro": "Dolu je zoznam operácií vykonaných filtrom zneužitia, ktoré táto operácia vráti.\nProsím, pozorne ich skontrolujte a potvrďte svoj výber kliknutím na na „Potvrdiť“.", + "abusefilter-revert-preview-intro": "Dolu je zoznam operácií vykonaných filtrom zneužitia, ktoré táto operácia vráti.\nProsím, pozorne ich skontrolujte a potvrďte svoj výber kliknutím na na „{{int:abusefilter-revert-confirm}}“.", + "abusefilter-revert-confirm-legend": "Potvrdiť vrátenie", "abusefilter-revert-confirm": "Potvrdiť", "abusefilter-revert-success": "Vrátili ste všetky zmeny vykonané filtrom zneužitia [[Special:AbuseFilter/$1|$2]].", "abusefilter-revert-reason": "Automatické vrátenie všetkých operácií vykonaných filtrom zneužitia $1.\nUvedený dôvod: $2", "abusefilter-revert-reasonfield": "Dôvod:", "abusefilter-test": "Otestovať filter na existujúcich úpravách", - "abusefilter-test-intro": "Táto stránka vám umožňuje otestovať filter zadaný do poľa nižšie na {{PLURAL:$1|posledej úprave|posledých $1 úpravách}}.\nExistujúci filter načítate napísaním jeho ID do poľa pod poľom úprav a kliknuím na tlačidlo „Načítať“.", + "abusefilter-test-intro": "Táto stránka vám umožňuje otestovať filter zadaný do poľa nižšie na {{PLURAL:$1|poslednej úprave|posledých $1 úpravách}}.\nExistujúci filter načítate napísaním jeho ID do poľa pod editačným oknom a kliknuím na tlačidlo „{{int:abusefilter-test-load}}“.", "abusefilter-test-legend": "Test filtra", "abusefilter-test-load-filter": "Načítať filter s ID:", "abusefilter-test-submit": "Otestovať", @@ -397,7 +491,7 @@ "abusefilter-test-period-end": "Zmeny vykonané pred:", "abusefilter-test-page": "Dotknutá stránka:", "abusefilter-test-shownegative": "Zobraziť aj úpravy, ktoré filtru nezodpovedajú", - "abusefilter-test-syntaxerr": "Filter, ktorý ste zadali obsahoval syntaktickú chybu.\nKompletné vysvetlenie dostanete po kliknutí na tlačidlo „Skontrolovať syntax“.", + "abusefilter-test-syntaxerr": "Filter, ktorý ste zadali obsahoval syntaktickú chybu.\nÚplné vysvetlenie dostanete po kliknutí na tlačidlo „{{int:abusefilter-edit-check}}“.", "abusefilter-test-badtitle": "Zadaný názov stránky je neplatný. Možno obsahuje jeden či viac znakov, ktoré nie je možné používať v názvoch stránok.", "abusefilter-test-action": "Typ akcie:", "abusefilter-test-search-type-all": "Všetky akcie", @@ -425,17 +519,20 @@ "abusefilter-examine-noresults": "Nenašli sa žiadne výsledky vyhovujúce zadaným parametrom vyhľadávania.", "abusefilter-topnav": "'''Navigácia Filtrom zneužití'''", "abusefilter-topnav-home": "Domov", + "abusefilter-topnav-recentchanges": "Posledné zmeny filtrov", "abusefilter-topnav-test": "Dávkové testovanie", "abusefilter-topnav-examine": "Preskúmať minulé úpravy", "abusefilter-topnav-log": "Záznam zneužití", "abusefilter-topnav-tools": "Ladiace nástroje", - "abusefilter-topnav-import": "Importovať filter", "abusefilter-log-name": "Záznam filtra zneužití", "abusefilter-log-header": "Tento záznam zobrazuje súhrn zmien filtrov.\nPodrobnosti nájdete v [[Special:AbuseFilter/history|zozname]] posledných zmien filtrov.", + "abusefilter-logentry-create": "$1 {{GENDER:$2|vytvoril|vytvorila|vytvoril(a)}} $4 ($5)", + "abusefilter-logentry-modify": "$1 {{GENDER:$2|upravil|upravila|upravil(a)}} $4 ($5)", + "abusefilter-log-invalid-filter": "Niektoré z uvedených filtrov identifikátorov sú neplatné.", "abusefilter-log-noresults": "Žiadne výsledky", "abusefilter-diff-title": "Rozdiely medzi verziami", "abusefilter-diff-item": "Položka", - "abusefilter-diff-version": "Verzia od $1 používateľa $2", + "abusefilter-diff-version": "Verzia z $1 od {{GENDER:$3|používateľa|používateľky}} $2", "abusefilter-diff-info": "Základné informácie", "abusefilter-diff-pattern": "Podmienky filtra", "abusefilter-diff-invalid": "Nepodarilo sa získať požadované verzie", @@ -444,6 +541,12 @@ "abusefilter-diff-next": "Novšia zmena", "abusefilter-import-intro": "Toto rozhranie môžete použiť na importovanie filtrov z iných wiki.\nNa zdrojovej wiki kliknite na „{{int:Abusefilter-edit-export}}“ v ponuke „{{int:abusefilter-edit-tools}}“ v rozhraní na úpravy.\nSkopírujte ho z textového poľa, kde sa objaví a vložte ho do tohto textového poľa. Potom kliknite na „{{int:abusefilter-import-submit}}“.", "abusefilter-import-submit": "Importovať údaje", + "abusefilter-import-invalid-data": "Údaje, ktoré ste sa snažili importovať, sú neplatné", "abusefilter-group-default": "Predvolené", - "abusefilter-http-error": "Došlo k chybe HTTP: $1." + "abusefilter-http-error": "Došlo k chybe HTTP: $1.", + "abusefilter-view-privatedetails-submit": "Zobraziť súkromné detaily", + "abusefilter-view-privatedetails-legend": "Zobraziť súkromné detaily", + "abusefilter-view-privatedetails-reason": "Dôvod prístupu k súkromným detailom:", + "abusefilter-log-details-id": "ID záznamu", + "abusefilter-log-ip-not-available": "Nedostupné" } diff --git a/AbuseFilter/i18n/skr-arab.json b/AbuseFilter/i18n/skr-arab.json index e7c16d92..8b02a5bb 100644 --- a/AbuseFilter/i18n/skr-arab.json +++ b/AbuseFilter/i18n/skr-arab.json @@ -5,6 +5,7 @@ ] }, "abusefilter-log-search-user": "ورتݨ آلا:", + "abusefilter-log-search-group-any": "کوئی", "abusefilter-log-search-title": "عنوان:", "abusefilter-log-search-wiki": "وکی:", "abusefilter-log-search-impact": "اثر:", @@ -27,7 +28,7 @@ "abusefilter-edit-switch-editor": "ایڈیٹر وٹاؤ", "abusefilter-edit-field-description": "تفصیل", "abusefilter-edit-field-conditions": "شرطاں", - "abusefilter-edit-throttle-page": "ورقہ", + "abusefilter-throttle-page": "ورقہ", "abusefilter-edit-disallow-other": "ٻیا سنیہا", "abusefilter-edit-disallow-actions": "کم:", "abusefilter-edit-tools": "آوزار:", @@ -44,8 +45,8 @@ "abusefilter-revert-confirm": "تصدیق", "abusefilter-test-search-type-all": "سارے کم", "abusefilter-examine-user": "ورتݨ آلا:", - "abusefilter-view-private-submit": "ذاتی تفصیلاں ݙیکھو", - "abusefilter-view-private": "ذاتی تفصیلاں ݙیکھو", + "abusefilter-view-privatedetails-submit": "ذاتی تفصیلاں ݙیکھو", + "abusefilter-view-privatedetails-legend": "ذاتی تفصیلاں ݙیکھو", "abusefilter-log-details-id": "لاگ آئی ڈی", "abusefilter-log-ip-not-available": "دستیاب کائنی" } diff --git a/AbuseFilter/i18n/sl.json b/AbuseFilter/i18n/sl.json index f4f5fa1d..b082d380 100644 --- a/AbuseFilter/i18n/sl.json +++ b/AbuseFilter/i18n/sl.json @@ -4,14 +4,17 @@ "Dbc334", "Eleassar", "Emperyan", + "Janezdrilc", "Matma Rex", - "Janezdrilc" + "RStular", + "Upwinxp" ] }, "abusefilter-desc": "Pri urejanjih uporabi samodejno hevristiko", - "abusefilter": "Konfiguracija filtrov zlorab", - "abuselog": "Dnevnik zlorab", + "abusefilter": "Upravljanje filtrov zlorab", + "abuselog": "Dnevnik filtrov zlorab", "abusefilter-intro": "Dobrodošli v vmesniku upravljanja s filtri zlorab.\nFilter zlorab je samodejni mehanizem programja, ki uporabi samodejno hevristiko za vsa dejanja.\nVmesnik prikazuje seznam določenih filtrov in omogoča, da jih spremenite.", + "abusefilter-mustviewprivateoredit": "Iz varnostnih razlogov lahko ta vmesnik uporabljajo samo uporabniki s pravico do ogleda zasebnih filtrov in spreminjanja filtrov zlorab.", "abusefilter-warning": "'''Opozorilo:''' To dejanje je bilo samodejno zaznano kot škodljivo.\nNekoristna dejanja bodo hitro povrnjena,\nnezaslišana ali ponavljajoča nekoristna urejanja pa bodo sledila v blokado vašega računa ali IP-naslova.\nČe verjamete, da je to dejanje koristno, ga lahko ponovno potrdite.\nKratek opis pravila zlorab, ki mu je ustrezalo vaše dejanje: $1", "abusefilter-disallowed": "To dejanje je bilo samodejno zaznano kot škodljivo in je zato prepovedano.\nČe verjamete, da je bilo vaše dejanje koristno, prosimo, obvestite administratorja o tem, kar ste skušali storiti.\nKratek opis pravila zlorab, ki mu je ustrezalo vaše dejanje: $1", "abusefilter-blocked-display": "To dejanje je bilo samodejno prepoznano kot škodljivo\nin vam je zato bila njegova izvedba preprečena.\nPoleg tega je bilo zavoljo zaščite {{GRAMMAR:rodilnik|{{SITENAME}}}} vašemu uporabniškemu računu in vsem pripadajočim IP-naslovom preprečeno urejanje.\nČe se je to zgodilo po pomoti, se obrnite na administratorja.\nKratek opis pravila zlorab, kateremu je ustrezalo vaše dejanje: $1", @@ -20,12 +23,14 @@ "abusefilter-blocker": "Filter zlorab", "abusefilter-blockreason": "Samodejno blokirano s strani filtra zlorab.\nOpis ujemajočega pravila: $1", "abusefilter-degroupreason": "Pravice so samodejno odstranjene s strani filtra zlorab.\nOpis pravila: $1", + "abusefilter-blockautopromotereason": "Samodejno napredovanje zakasnjeno zaradi filtra proti zlorabam.\nRazlog: $1", "abusefilter-accountreserved": "To ime računa je rezervirano za uporabo s filtrom zlorab.", - "right-abusefilter-modify": "Spreminjanje filtrov zlorab", + "right-abusefilter-modify": "Ustvarjanje ali spreminjanje filtrov zlorab", "right-abusefilter-view": "Ogled filtrov zlorab", "right-abusefilter-log": "Ogled dnevnika zlorab", "right-abusefilter-log-detail": "Ogled podrobnosti dnevniška vnosa zlorabe", - "right-abusefilter-private": "Ogled zasebnih podatkov v dnevniku zlorab", + "right-abusefilter-privatedetails": "Ogled zasebnih podatkov v dnevniku zlorab", + "right-abusefilter-privatedetails-log": "Pregledovanje zasebnih podrobnosti v dnevniškem zapisu filtra proti zlorabam.", "right-abusefilter-modify-restricted": "Spreminjanje filtrov zlorab z omejenimi dejanji", "right-abusefilter-revert": "Povrnitev vse sprememb danega filtra zlorab", "right-abusefilter-view-private": "Ogled filtrov zlorab označenih kot zasebni", @@ -37,16 +42,22 @@ "action-abusefilter-view": "ogled filtra zlorab", "action-abusefilter-log": "ogled dnevnika zlorab", "action-abusefilter-log-detail": "ogled podrobnosti vnosa v dnevniku zlorab", - "action-abusefilter-private": "ogled zasebnih podatkov v dnevniki zlorab", + "action-abusefilter-privatedetails": "ogled zasebnih podatkov v dnevniki zlorab", + "action-abusefilter-privatedetails-log": "do ogledovanja zasebnih podrobnosti v dnevniškem zapisu filtra proti zlorabam.", "action-abusefilter-modify-restricted": "spreminjanje filtra zlorab z omejenimi dejanji", "action-abusefilter-revert": "povrnitev vse sprememb danega filtra zlorab", "action-abusefilter-view-private": "ogled filtrov zlorab označenih kot zasebni", "action-abusefilter-log-private": "prikaži dnevnike filtrov zlorab, ki so označeni kot zasebni", - "abusefilter-log": "Dnevnik filtrov zlorab", + "action-abusefilter-hide-log": "skrij vnose v dnevniku zlorab", + "action-abusefilter-hidden-log": "ogled skritih vnosov v dnevniku zlorab", + "action-abusefilter-modify-global": "ustvarjanje ali spreminjanje globalnih filtrov zlorab", "abusefilter-log-summary": "Ta dnevnik prikazuje seznam vseh dejanj, ki so jih ujeli filtri.", "abusefilter-log-search": "Iskanje po dnevniku zlorab", "abusefilter-log-search-user": "Uporabnik:", - "abusefilter-log-search-filter": "ID filtra (ločeno z navpičnicami):", + "abusefilter-log-search-group": "Filtriraj skupino:", + "abusefilter-log-search-group-any": "katerikoli", + "abusefilter-log-search-filter": "ID-ji filtrov:", + "abusefilter-log-search-filter-help": "Ločite z navpičnimi črtami, dodajte predpono \"$1\" za globalne filtre.", "abusefilter-log-search-title": "Naslov:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-impact": "Vpliv:", @@ -57,9 +68,14 @@ "abusefilter-log-search-entries-all": "Vsi vpisi", "abusefilter-log-search-entries-hidden": "Samo skriti vpisi", "abusefilter-log-search-entries-visible": "Samo vidni vpisi", + "abusefilter-log-search-action-label": "Sprožilno dejanje:", + "abusefilter-log-search-action-other": "Drugo", + "abusefilter-log-search-action-any": "Katerokoli", + "abusefilter-log-search-action-taken-label": "Sprejet ukrep:", "abusefilter-log-search-action-taken-any": "Katerikoli", "abusefilter-log-search-submit": "Iskanje", "abusefilter-log-entry": "$1: $2 je med izvajanjem dejanja »$3« na $4 {{GENDER:$8|sprožil|sprožila|sprožil(-a)}} filter zlorab.\nSprejeti ukrepi: $5;\nOpis filtra: $6", + "abusefilter-log-entry-withdiff": "$1: $2 je med izvajanjem dejanja »$3« na $4 {{GENDER:$8|sprožil|sprožila|sprožil(-a)}} filter zlorab.\nSprejeti ukrepi: $5;\nOpis filtra: $6 ($7)", "abusefilter-log-detailedentry-meta": "$1: $2 je med izvajanjem dejanja »$4« na $5 {{GENDER:$9|sprožil|sprožila|sprožil(-a)}} $3.\nSprejeti ukrepi: $6;\nOpis filtra: $7 ($8)", "abusefilter-log-detailedentry-global": "globalni filter $1", "abusefilter-log-detailedentry-local": "filter $1", @@ -70,7 +86,7 @@ "abusefilter-log-details-var": "Spremenljivka", "abusefilter-log-details-val": "Vrednost", "abusefilter-log-details-vars": "Parametri dejanja", - "abusefilter-log-details-private": "Zasebne podrobnosti o dnevniku", + "abusefilter-log-details-privatedetails": "Zasebne podrobnosti o dnevniku", "abusefilter-log-details-ip": "Izvirni IP-naslov", "abusefilter-log-details-checkuser": "Preveri uporabnika", "abusefilter-log-noactions": "nobeno", @@ -78,21 +94,35 @@ "abusefilter-log-linkoncontribs": "dnevnik zlorab", "abusefilter-log-linkoncontribs-text": "Dnevnik zlorab {{GENDER:$1|tega uporabnika|te uporabnice}}", "abusefilter-log-linkonhistory": "poglej dnevnik filtrov zlorab", - "abusefilter-log-hidden": "(vnos je skrit)", + "abusefilter-log-linkonhistory-text": "Preglejte dnevnik zlorab za to stran", + "abusefilter-log-linkonundelete": "ogled dnevnika zlorab", + "abusefilter-log-linkonundelete-text": "Preglejte dnevnik zlorab za to stran", "abusefilter-log-hidden-implicit": "(skrito, ker je redakcija izbrisana)", "abusefilter-log-cannot-see-details": "Nimate dovoljenja za ogled podrobnosti tega vnosa.", + "abusefilter-log-cannot-see-privatedetails": "Nimate dovoljenj za ogled zasebnih podrobnosti tega filtra.", + "abusefilter-log-nonexistent": "Vnos s to ID številko ne obstaja.", "abusefilter-log-details-hidden": "Ne morete si ogledati podrobnosti tega vnosa, ker je skrit pred javnim vpogledom.", + "abusefilter-log-details-hidden-implicit": "Ne morete si ogledati podrobnosti tega vnosa, ker je skrit pred javnim vpogledom.", + "abusefilter-log-private-not-included": "Eden ali več filtrov je zasebnih. Ker nimate dovoljenja da si ogledate te vnose, niso navedeni v rezultatih iskanja.", "abusefilter-log-hide-legend": "Skrij dnevniški vnos", "abusefilter-log-hide-id": "ID dnevniškega vnosa:", "abusefilter-log-hide-hidden": "Skrij ta vnos pred javnim vpogledom", "abusefilter-log-hide-reason": "Razlog:", "abusefilter-log-hide-reason-other": "Drug/dodaten razlog:", "abusefilter-log-hide-forbidden": "Nimate dovoljenja za skrivanje dnevniških vnosov zlorab.", + "abusefilter-log-entry-suppress": "$1 je {{GENDER:$2|skril|skrila|skril(-a)}} $3", + "abusefilter-log-entry-unsuppress": "$1 je {{GENDER:$2|odkril|odkrila|odkril(-a)}} $3", "logentry-abusefilter-hit": "$1 je {{GENDER:$2|sprožil|sprožila|sprožil(-a)}} $4 z dejanjem »$5« na $3. Ukrepi: $6 ($7)", "log-action-filter-abusefilter": "Vrsta spremembe filtra:", "log-action-filter-abusefilter-create": "Ustvaritev novega filtra", "log-action-filter-abusefilter-modify": "Sprememba filtra", - "abusefilter-management": "Upravljanje filtrov zlorab", + "log-action-filter-suppress-abuselog": "Utišaj dnevnik zlorab.", + "log-action-filter-rights-blockautopromote": "Blokiraj samodejno napredovanje", + "log-action-filter-rights-restoreautopromote": "Povrni samodejno napredovanje", + "logentry-abusefilterprivatedetails-access": "$1 je {{GENDER:$2|dostopal|dostopala}} do zasebnih podrobnosti $3", + "logentry-rights-blockautopromote": "$1 je {{GENDER:$2|blokiral|blokirala}} samodejno napredovanje {{GENDER:$4|uporabnika|uporabnice}} $3 za $5", + "logentry-rights-restoreautopromote": "$1 je {{GENDER:$2|omogočil|omogočila}} samodejno napredovanje {{GENDER:$4|uporabnika|uporabnice}} $3.", + "abusefilterprivatedetails-log-name": "Dnevnik dostopov do zasebnih podrobnosti filtra proti zlorabam", "abusefilter-list": "Vsi filtri", "abusefilter-list-id": "ID filtra", "abusefilter-list-pattern": "Vzorec", @@ -111,15 +141,17 @@ "abusefilter-enabled": "Omogočeno", "abusefilter-deleted": "Izbrisano", "abusefilter-disabled": "Onemogočeno", + "abusefilter-throttled": "upočasnjen", "abusefilter-hitcount": "$1 {{PLURAL:$1|zadetek|zadetka|zadetki|zadetkov}}", "abusefilter-new": "Ustvari nov filter", + "abusefilter-import-button": "Uvozi filter", "abusefilter-return": "Vrnitev na upravljanje filtrov", "abusefilter-status-global": "Globalno", "abusefilter-list-options": "Možnosti", "abusefilter-list-options-deleted": "Izbrisani filtri:", "abusefilter-list-options-deleted-only": "Prikaži samo izbrisane filtre", "abusefilter-list-options-deleted-hide": "Skrij izbrisane filtre", - "abusefilter-list-options-deleted-show": "Vključi izbrisane filter", + "abusefilter-list-options-deleted-show": "Vključi izbrisane filtre", "abusefilter-list-options-scope": "Prikaži filtre:", "abusefilter-list-options-scope-local": "Samo lokalna pravila", "abusefilter-list-options-scope-global": "Samo globalna pravila", @@ -132,6 +164,9 @@ "abusefilter-list-options-searchoptions": "Način iskanja:", "abusefilter-list-options-search-like": "Goli iskalni niz", "abusefilter-list-options-search-rlike": "Regularni izraz", + "abusefilter-list-options-search-irlike": "Regularni izraz (neobčutljiv na velike črke)", + "abusefilter-list-invalid-searchmode": "Ta način iskanja ni veljaven.", + "abusefilter-list-regexerror": "Med iskanjem je prišlo do napake: napaka v sintaksi regularnega izraza.", "abusefilter-list-options-submit": "Posodobi", "abusefilter-tools-text": "Tukaj je nekaj orodij, ki so lahko koristna pri oblikovanju in popravljanju napak filtrov zlorab.", "abusefilter-tools-expr": "Preizkuševalec izrazov", @@ -139,17 +174,20 @@ "abusefilter-tools-reautoconfirm": "Povrni samodejno potrjeno stanje", "abusefilter-tools-reautoconfirm-user": "Uporabnik:", "abusefilter-tools-reautoconfirm-submit": "Ponovno samodejno potrdi", + "abusefilter-tools-restoreautopromote": "Samodejno napredovanje povrnjeno z orodji filtra proti zlorabam.", "abusefilter-reautoconfirm-none": "Ta uporabnik nima prekinjenega {{GENDER:$1|svojega}} stanja samodejne potrditve.", "abusefilter-reautoconfirm-notallowed": "Nimate dovoljenja za povrnitev stanja samodejne potrditve.", "abusefilter-reautoconfirm-done": "Samodejno potrjeno stanje računa je bilo povrnjeno", - "abusefilter-status": "Od {{PLURAL:$1|zadnjega $1 dejanja|zadnjih $1 dejanj}} {{PLURAL:$2|je|sta|so|jih je}} $2 ($3 %) {{PLURAL:$2|dosegel|dosegla|dosegli|doseglo}} omejitev pogojev $4 in $5 ($6 %) {{PLURAL:$2|se je uejam|sta se ujemala|so se ujemali|se jih je ujemalo}} z enim od trenutno omogočenih filtrov.", + "abusefilter-status": "Od {{PLURAL:$1|zadnjega $1 dejanja|zadnjih $1 dejanj}} {{PLURAL:$2|je|sta|so|jih je}} $2 ($3 %) {{PLURAL:$2|dosegel|dosegla|dosegli|doseglo}} omejitev pogojev $4 in $5 ($6 %) {{PLURAL:$2|se je ujemal|sta se ujemala|so se ujemali|se jih je ujemalo}} vsaj z enim od trenutno omogočenih filtrov.", "abusefilter-edit": "Urejanje filtra zlorab", "abusefilter-edit-subtitle": "Urejanje filtra $1", "abusefilter-edit-subtitle-new": "Ustvarjanje filtra", + "abusefilter-edit-token-not-match": "Urejanje ni bilo shranjeno! Shranite ga znova.", "abusefilter-edit-oldwarning": "<strong>Urejate staro različico filtra.\nNavedena statistika drži za najnovejšo različico filtra.\nČe shranite svoje spremembe, boste prepisali vse spremembe od redakcije, ki jo urejate.</strong> •\n[[Special:AbuseFilter/history/$2|Vrnitev na zgodovino filtra]].", + "abusefilter-edit-oldwarning-view": "<strong>Ogledujete si staro različico filtra.\nNavedene so statistike za zadnjo različico filtra.</strong> •\n[[Special:AbuseFilter/history/$2|Vrni se na zgodovino filtra]].", "abusefilter-edit-status-label": "Statistike:", - "abusefilter-edit-status": "Od {{PLURAL:$1|zadnjega $1 dejanja|zadnjih $1 dejanj}} se je ta filter ujemal z/s $2 ($3 %).", - "abusefilter-edit-status-profile": "Od {{PLURAL:$1|zadnjega $1 dejanja|zadnjih $1 dejanj}} se je ta filter ujemal z/s $2 ($3 %).\nV povprečju je njegov čas delovanja $4 ms, porabi pa $5 {{PLURAL:$5|pogoj|pogoja|pogoje|pogojev}} omejitve pogojev.", + "abusefilter-edit-status": "Od {{PLURAL:$1|zadnjega $1 dejanja|zadnjih $1 dejanj}} se je ta filter ujemal z/s $2 ($3 %).\nV povprečju je njegov čas delovanja $4 ms, porabi pa $5 {{PLURAL:$5|pogoj|pogoja|pogoje|pogojev}} omejitve pogojev.", + "abusefilter-edit-throttled-warning": "'''Opozorilo:''' Ta filter je bil samodejno označen kot škodljiv. Zaradi varnostnih razlogov naslednje dejanje ne bo izvedeno ($1). Prosimo, preglejte in [[mw:Extension:AbuseFilter/Conditions|optimiziranje]] vaš vnos da ostranite to omejitev.", "abusefilter-edit-new": "Nov filter", "abusefilter-edit-save": "Shrani filter", "abusefilter-edit-id": "ID filtra:", @@ -171,7 +209,7 @@ "abusefilter-edit-consequences": "Dejanja za izvedbo ob ujemanju", "abusefilter-edit-action-warn": "Sproži ta dejanja po opozoritvi uporabnika", "abusefilter-edit-action-disallow": "Prepreči uporabniku izvesti vprašljivo dejanje", - "abusefilter-edit-action-blockautopromote": "Odvzami uporabnikovo stanje samodejne potrditve", + "abusefilter-edit-action-blockautopromote": "Odvzemi uporabnikovo stanje samodejne potrditve", "abusefilter-edit-action-degroup": "Odstrani uporabnika iz vseh priviligiranih skupin", "abusefilter-edit-action-block": "Uporabniku in/ali IP-naslovu prepreči urejanje", "abusefilter-edit-action-blocktalk": "Blokiraj uporabnika in /ali IP naslov za urejanje njihovih lastnih pogovornih strani", @@ -181,20 +219,34 @@ "abusefilter-edit-throttle-count": "Število dovoljenih dejanj:", "abusefilter-edit-throttle-period": "Časovno obdobje (v sekundah):", "abusefilter-edit-throttle-groups": "Omejevanje skupine:", - "abusefilter-edit-throttle-ip": "IP naslov", - "abusefilter-edit-throttle-user": "Uporabniški račun", - "abusefilter-edit-throttle-creationdate": "Datum stražnika ustvaritve računa", - "abusefilter-edit-throttle-editcount": "Število urejanj", - "abusefilter-edit-throttle-site": "Celotna stran", - "abusefilter-edit-throttle-page": "Stran", + "abusefilter-edit-throttle-groups-help": "Glejte $1.", + "abusefilter-edit-throttle-groups-help-text": "dokumentacijo na mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Ločite z vejicami da združite z IN, ločite z prelomi vrstic da združite z ALI", + "abusefilter-edit-throttle-placeholder": "Ločite z vejicami da združite z IN, naredite ločene vnose da združite z ALI", + "abusefilter-throttle-ip": "IP-naslov", + "abusefilter-throttle-user": "uporabniški račun", + "abusefilter-throttle-range": "obseg /16", + "abusefilter-throttle-creationdate": "datum ustvaritve računa", + "abusefilter-throttle-editcount": "število urejanj", + "abusefilter-throttle-site": "celotna stran", + "abusefilter-throttle-page": "stran", + "abusefilter-throttle-none": "(noben)", + "abusefilter-throttle-details": "Dovoli $1 {{PLURAL:$1|dejanje|dejanja}} {{PLURAL:$2|vsako|vsakih}} $2 {{PLURAL:$2|sekundo|sekund}}, združi omejitve po: $3", "abusefilter-edit-warn-message": "Sistemsko sporočilo, uporabljeno za opozorilo:", "abusefilter-edit-warn-other": "Drugo sporočilo", - "abusefilter-edit-warn-other-label": "Ime strani drugega sporočila:\n:''(brez predpone MediaWiki)''", + "abusefilter-edit-warn-other-label": "Ime strani drugega sporočila:\n:''(brez predpone »MediaWiki:«)''", "abusefilter-edit-warn-actions": "Dejanja:", "abusefilter-edit-warn-preview": "Prikaži/skrij predogled izbranega sporočila", "abusefilter-edit-warn-edit": "Ustvari/Uredi izbrano sporočilo", + "abusefilter-edit-disallow-message": "Sistemsko sporočilo, uporabljeno za zavrnitev:", + "abusefilter-edit-disallow-other": "Drugo sporočilo", + "abusefilter-edit-disallow-other-label": "Ime strani drugega sporočila:\n:''(brez predpone »MediaWiki:«)''", + "abusefilter-edit-disallow-actions": "Dejanja:", + "abusefilter-edit-disallow-preview": "Prikaži/skrij predogled izbranega sporočila", + "abusefilter-edit-disallow-edit": "Ustvari/Uredi izbrano sporočilo", "abusefilter-edit-tag-tag": "[[Special:Tags|Oznake]] za uporabo:", "abusefilter-edit-tag-placeholder": "Dodaj oznake (eno po eno ali ločene z vejico)", + "abusefilter-edit-tag-hidden-placeholder": "Dodaj oznake (ločene z vejico)", "abusefilter-edit-block-anon-durations": "Trajanje blokiranja za anonimne uporabnike:", "abusefilter-edit-block-user-durations": "Trajanje blokiranja za registrirane uporabnike:", "abusefilter-block-anon": "Blokiraj anonimne uporabnike", @@ -205,6 +257,8 @@ "abusefilter-edit-done-subtitle": "Filter je urejen", "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Svoje spremembe]] [[Special:AbuseFilter/$1|filtra $3]] ste uspešno shranili.", "abusefilter-edit-badsyntax": "V navedenem filtru je skladenjska napaka.\nRezultat razčlenjevalnika je bil: <pre>$1</pre>", + "abusefilter-edit-missingfields": "Naslednja polja morajo biti izpolnjena: $1", + "abusefilter-edit-deleting-enabled": "Aktivnega filtra ne morete označiti kot izbrisanega.", "abusefilter-edit-restricted": "Ne morete urediti tega filtra, ker vsebuje eno ali več omejenih dejanj.\nProsite uporabnika, ki lahko dodaja omejena dejanja, da stori spremembo namesto vas.", "abusefilter-edit-viewhistory": "Ogled zgodovine tega filtra", "abusefilter-edit-history": "Zgodovina:", @@ -216,10 +270,18 @@ "abusefilter-edit-export": "Izvozi ta filter na drug wiki", "abusefilter-edit-syntaxok": "Zaznana ni nobena skladenjska napaka.", "abusefilter-edit-syntaxerr": "Zaznana je skladenjska napaka: $1", + "abusefilter-edit-warn-leave": "Če zapustite to stran, boste izgubili vse spremembe, ki ste jih naredili na tem filtru.", "abusefilter-edit-bad-tags": "Ena ali več navedenih oznak ni veljavnih.\nOznake morajo biti kratke, ne smejo vsebovati posebnih znakov in ne sme jih rezervirati drugo programje. Poskusite izbrati novo ime oznake.", "abusefilter-edit-notallowed": "Ustvarjanje ali urejanje filtrov zlorab vam ni dovoljeno.", "abusefilter-edit-notallowed-global": "Nimate dovoljenj za ustvarjanje ali spreminjanje globalnih filtrov zlorab", - "abusefilter-edit-notallowed-global-custom-msg": "Opozorilna sporočila po meri niso podprta za globalne filtre", + "abusefilter-edit-notallowed-global-custom-msg": "Opozorilna ali preprečitvena sporočila po meri niso podprta za globalne filtre", + "abusefilter-edit-invalid-warn-message": "Opozorilno sporočilo ne sme ostati prazno.", + "abusefilter-edit-invalid-disallow-message": "Sporočilo o prepovedi ne sme ostati prazno.", + "abusefilter-edit-invalid-throttlecount": "Število dejanj mora biti pozitivno število.", + "abusefilter-edit-invalid-throttleperiod": "Čas mora biti pozitivno število.", + "abusefilter-edit-empty-throttlegroups": "Vsaj ena skupina mora biti izbrana.", + "abusefilter-edit-duplicated-throttlegroups": "Skupine ne smejo biti podvojene.", + "abusefilter-edit-invalid-throttlegroups": "Izbrane skupine niso veljavne.", "abusefilter-edit-builder-select": "Izberite možnost, da jo dodate na mesto kazalca", "abusefilter-edit-builder-group-op-arithmetic": "Aritmetični operatorji", "abusefilter-edit-builder-op-arithmetic-addition": "Seštevanje (+)", @@ -230,7 +292,9 @@ "abusefilter-edit-builder-op-arithmetic-pow": "Potenciranje (**)", "abusefilter-edit-builder-group-op-comparison": "Operatorji primerjanja", "abusefilter-edit-builder-op-comparison-equal": "Vrednost je enaka (==)", + "abusefilter-edit-builder-op-comparison-equal-strict": "Vrednost in vrsta se ujemata (===)", "abusefilter-edit-builder-op-comparison-notequal": "Vrednost ni enaka (!=)", + "abusefilter-edit-builder-op-comparison-notequal-strict": "Vrednost in vrsta se ne ujemata (!==)", "abusefilter-edit-builder-op-comparison-lt": "Manjše od (<)", "abusefilter-edit-builder-op-comparison-gt": "Večje od (>)", "abusefilter-edit-builder-op-comparison-lte": "Manjše ali enako kot (<=)", @@ -247,29 +311,37 @@ "abusefilter-edit-builder-misc-contains": "Levi niz vsebuje desni niz (contains)", "abusefilter-edit-builder-misc-stringlit": "Dobesedni niz (\"\")", "abusefilter-edit-builder-misc-tern": "Operator trojka (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Pogojnik (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Pogojnik (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "Kratka pogojna izjava (če X potem Y konec)", "abusefilter-edit-builder-group-funcs": "Funkcije", "abusefilter-edit-builder-funcs-length": "Dolžina niza (length)", "abusefilter-edit-builder-funcs-lcase": "V male črke (lcase)", "abusefilter-edit-builder-funcs-ucase": "V velike črke (ucase)", "abusefilter-edit-builder-funcs-ccnorm": "Normaliziraj zamenljive znake (ccnorm)", + "abusefilter-edit-builder-funcs-ccnorm-contains-any": "V normaliziranem nizu poišči več podnizov v načinu ALI. (ccnorm_contains_any)", + "abusefilter-edit-builder-funcs-ccnorm-contains-all": "V normaliziranem nizu poišči več podnizov v načinu IN. (ccnorm_contains_all)", "abusefilter-edit-builder-funcs-rmdoubles": "Odstrani dvojne znake (rmdoubles)", "abusefilter-edit-builder-funcs-specialratio": "Posebni znaki / število znakov (specialratio)", "abusefilter-edit-builder-funcs-norm": "Normaliziraj (norm)", "abusefilter-edit-builder-funcs-count": "Število pojavov niza X v nizu Y (count)", "abusefilter-edit-builder-funcs-rcount": "Število pojavov regularnega izraza X v nizu Y (rcount)", + "abusefilter-edit-builder-funcs-get_matches": "Seznam ujemanj regularnega izraza za vsako zajemalno skupino (get_matches)", "abusefilter-edit-builder-funcs-rmwhitespace": "Odstrani presledke (rmwhitespace)", "abusefilter-edit-builder-funcs-rmspecials": "Odstrani posebne znake (rmspecials)", "abusefilter-edit-builder-funcs-ip_in_range": "Je IP v območju? (ip_in_range)", "abusefilter-edit-builder-funcs-contains-any": "V nizu poišči več podnizov v načinu ALI. (contains_any)", + "abusefilter-edit-builder-funcs-contains-all": "V nizu poišči več podnizov v načinu ALI. (contains_any)", + "abusefilter-edit-builder-funcs-equals-to-any": "Preveri če je podana vrednost enaka (===) katerikoli izmed sledečih vrednosti (equals_to_any)", "abusefilter-edit-builder-funcs-substr": "Podniz (substr)", "abusefilter-edit-builder-funcs-strpos": "Položaj podniza v nizu (strpos)", "abusefilter-edit-builder-funcs-str_replace": "Zamenjaj podniz z nizom (str_replace)", "abusefilter-edit-builder-funcs-rescape": "Ubeži niz kot dobeseden regularni izraz (rescape)", "abusefilter-edit-builder-funcs-set_var": "Določi spremenljivko (set_var)", + "abusefilter-edit-builder-funcs-sanitize": "Normaliziraj HTML enote v unicode znake (prečisti)", "abusefilter-edit-builder-group-vars": "Spremenljivke", "abusefilter-edit-builder-vars-accountname": "Ime računa (ob ustvarjanju računa)", "abusefilter-edit-builder-vars-timestamp": "Unixov časovni žig spremembe", + "abusefilter-edit-builder-vars-timestamp-expanded": "Čas in datum dnevniškega zapisa", "abusefilter-edit-builder-vars-action": "Dejanje", "abusefilter-edit-builder-vars-addedlines": "Vrstice dodane v urejanju", "abusefilter-edit-builder-vars-delta": "Sprememba velikosti v urejanju", @@ -284,6 +356,7 @@ "abusefilter-edit-builder-vars-page-ns": "Imenski prostor strani", "abusefilter-edit-builder-vars-page-title": "Naslov strani (brez imenskega prostora)", "abusefilter-edit-builder-vars-page-prefixedtitle": "Polni naslov strani", + "abusefilter-edit-builder-vars-page-age": "Starost strani (v sekundah)", "abusefilter-edit-builder-vars-movedfrom-id": "ID izvorne strani prestavljanja", "abusefilter-edit-builder-vars-movedfrom-ns": "Imenski prostor izvorne strani prestavljanja", "abusefilter-edit-builder-vars-movedfrom-title": "Naslov izvorne strani prestavljanja", @@ -303,22 +376,24 @@ "abusefilter-edit-builder-vars-all-links": "Vse zunanje povezave v novem besedilu", "abusefilter-edit-builder-vars-added-links": "Vse zunanje povezave dodane med urejanjem", "abusefilter-edit-builder-vars-removed-links": "Vse zunanje povezave odstranjene med urejanjem", - "abusefilter-edit-builder-vars-old-text": "Staro wikibesedilo strani, pred urejanjem (se ne uporablja več)", - "abusefilter-edit-builder-vars-new-text": "Novo wikibesedilo strani, po urejanju", + "abusefilter-edit-builder-vars-old-wikitext": "Wikibesedilo stare strani, pred urejanjem", + "abusefilter-edit-builder-vars-new-wikitext": "Wikibesedilo nove strani, po urejanju", "abusefilter-edit-builder-vars-new-pst": "Wikibesedilo nove strani, preoblikovano pred shranjevanjem", - "abusefilter-edit-builder-vars-new-text-stripped": "Novo besedilo strani, z odstranjenimi oznakami", + "abusefilter-edit-builder-vars-new-text": "Novo besedilo strani, z odstranjenimi oznakami", "abusefilter-edit-builder-vars-new-html": "Razčlenjen izvor HTML nove redakcije", "abusefilter-edit-builder-vars-restrictions-edit": "Uredi stopnjo zaščite strani", "abusefilter-edit-builder-vars-restrictions-move": "Prestavi stopnjo zaščite strani", "abusefilter-edit-builder-vars-restrictions-create": "Zaščita strani pred ustvarjanjem", "abusefilter-edit-builder-vars-restrictions-upload": "Zaščita datoteke pred nalaganjem", - "abusefilter-edit-builder-vars-old-text-stripped": "Staro besedilo strani, z odstranjenimi oznakami", + "abusefilter-edit-builder-vars-old-text": "Staro besedilo strani, z odstranjenimi oznakami (se ne uporablja več)", "abusefilter-edit-builder-vars-old-links": "Povezave na strani, pred urejanjem", "abusefilter-edit-builder-vars-old-html": "Staro wikibesedilo strani, razčlenjeno v HTML (se ne uporablja več)", - "abusefilter-edit-builder-vars-minor-edit": "Ali je bilo urejanje označeno kot manjše", + "abusefilter-edit-builder-vars-minor-edit": "Ali je bilo urejanje označeno kot manjše (se ne uporablja več)", "abusefilter-edit-builder-vars-file-sha1": "Odtis SHA1 vsebine datoteke", "abusefilter-edit-builder-vars-file-size": "Velikost datoteke v znakih", - "abusefilter-edit-builder-vars-file-height": "Višina datoteke v pikslih", + "abusefilter-edit-builder-vars-file-mime": "Vrsta MIME datoteke", + "abusefilter-edit-builder-vars-file-width": "Širina datoteke v slikovnih pikah", + "abusefilter-edit-builder-vars-file-height": "Višina datoteke v slikovnih pikah", "abusefilter-filter-log": "Zadnje spremembe filtrov", "abusefilter-history": "Zgodovina sprememb filtra zlorab #$1", "abusefilter-history-foruser": "Spremembe $1", @@ -337,6 +412,7 @@ "abusefilter-history-filterid": "Filter", "abusefilter-history-select-legend": "Izboljšaj iskanje", "abusefilter-history-select-user": "Uporabnik:", + "abusefilter-history-select-filter": "ID filtra:", "abusefilter-history-select-submit": "Prikaži", "abusefilter-history-diff": "Spremembe", "abusefilter-history-error-hidden": "Zahtevani filter je skrit in njegove zgodovine si ne morete ogledati.", @@ -351,8 +427,8 @@ "abusefilter-exception-dividebyzero": "Nedovoljen poskus deljenja $2 z ničlo pri znaku $1.", "abusefilter-exception-unrecognisedvar": "Neprepoznana spremenljivka $2 pri znaku $1.", "abusefilter-exception-notenoughargs": "Funkcija $2, klicana pri znaku $1, nima dovolj parametrov.\n{{PLURAL:$3|Pričakovan je $3 parameter|Pričakovana sta $3 parametra|Pričakovani so $3 parametri|Pričakovanih je $3 parametrov}}, dobil sem jih $4", - "abusefilter-exception-regexfailure": "Napaka v regularnem izrazu »$3« pri znaku $1: »$2«", - "abusefilter-exception-overridebuiltin": "Nedovoljeno prepisovanje vgrajene spremenljivke »$2« pri znaku $1.", + "abusefilter-exception-regexfailure": "Napaka v regularnem izrazu »$2« pri znaku $1.", + "abusefilter-exception-overridebuiltin": "Nedovoljeno prepisovanje vgrajenega identifikatorja »$2« pri znaku $1.", "abusefilter-exception-outofbounds": "Zahtevanje neobstoječega vnosa polja $2 (velikost polja = $3) pri znaku $1.", "abusefilter-exception-notarray": "Zahtevanje elementa polja v nepolju pri znaku $1.", "abusefilter-action-tag": "Označi", @@ -372,6 +448,7 @@ "abusefilter-revert-search": "Izberite dejanja", "abusefilter-revert-filter": "ID filtra:", "abusefilter-revert-preview-intro": "Spodaj se nahajajo dejanja filtra zlorab, ki bodo vrnjena s tem dejanjem.\nProsimo, skrbno jih preverite in kliknite »{{int:abusefilter-revert-confirm}}«, da potrdite izbiro.", + "abusefilter-revert-confirm-legend": "Potrdi vrnitev", "abusefilter-revert-confirm": "Potrdi", "abusefilter-revert-success": "Vrnili ste vsa dejanja filtra zlorab zaradi [[Special:AbuseFilter/$1|filtra $2]].", "abusefilter-revert-reason": "Samodejna vrnitev vseh dejanj filtra zlorab zaradi filtra $1.\nPodan razlog: $2", @@ -416,13 +493,16 @@ "abusefilter-examine-noresults": "Za navedene iskalne parametre ni bilo najdenih rezultatov.", "abusefilter-topnav": "'''Navigacija filtra zlorab'''", "abusefilter-topnav-home": "Domov", + "abusefilter-topnav-recentchanges": "Zadnje spremembe filtrov", "abusefilter-topnav-test": "Paketno preizkušanje", "abusefilter-topnav-examine": "Preuči pretekla urejanja", "abusefilter-topnav-log": "Dnevnik zlorab", "abusefilter-topnav-tools": "Orodja za iskanje napak", - "abusefilter-topnav-import": "Uvozi filter", "abusefilter-log-name": "Dnevnik filtrov zlorab", "abusefilter-log-header": "Ta dnevnik prikazuje povzetek sprememb filtrov.\nZa vse podrobnosti si oglejte [[Special:AbuseFilter/history|seznam]] zadnjih sprememb filtrov.", + "abusefilter-logentry-create": "$1 je {{GENDER:$2|ustvaril|ustvarila|ustvaril(-a)}} $4 ($5)", + "abusefilter-logentry-modify": "$1 je {{GENDER:$2|spremenil|spremenila|spremenil(-a)}} $4 ($5)", + "abusefilter-log-invalid-filter": "Nekateri od navedenih ID-jev filtrov so neveljavni.", "abusefilter-log-noresults": "Ni zadetkov", "abusefilter-diff-title": "Razlike med različicami", "abusefilter-diff-item": "Postavka", @@ -436,8 +516,10 @@ "abusefilter-import-intro": "Ta vmesnik lahko uporabite za uvoz filtrov iz drugih wikijev.\nNa izvornem wikiju kliknite »{{int:abusefilter-edit-export}}« pod »{{int:abusefilter-edit-tools}}« v urejevalnem vmesniku.\nNato skopirajte besedilo v prikazanem polju, prilepite ga v to polje in kliknite »{{int:abusefilter-import-submit}}«.", "abusefilter-import-submit": "Uvozi podatke", "abusefilter-group-default": "Privzeto", - "abusefilter-view-private-submit": "Prikaži zasebne podatke", - "abusefilter-view-private": "Prikaži zasebne podatke", - "abusefilter-view-private-reason": "Razlog za dostop do zasebnih podatkov:", - "abusefilter-log-details-id": "ID dnevnika" + "abusefilter-http-error": "Prišlo je do napake HTTP: $1.", + "abusefilter-view-privatedetails-submit": "Prikaži zasebne podrobnosti", + "abusefilter-view-privatedetails-legend": "Prikaži zasebne podatke", + "abusefilter-view-privatedetails-reason": "Razlog za dostop do zasebnih podrobnosti:", + "abusefilter-log-details-id": "ID dnevnika", + "abusefilter-log-ip-not-available": "Ni na voljo" } diff --git a/AbuseFilter/i18n/smn.json b/AbuseFilter/i18n/smn.json new file mode 100644 index 00000000..8d913981 --- /dev/null +++ b/AbuseFilter/i18n/smn.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Yupik" + ] + }, + "abusefilter-list-lastmodified": "Majemustáá nubástittum", + "abusefilter-edit-throttle-groups-help": "Keejâ $1." +} diff --git a/AbuseFilter/i18n/sms.json b/AbuseFilter/i18n/sms.json new file mode 100644 index 00000000..a6dd06e8 --- /dev/null +++ b/AbuseFilter/i18n/sms.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Yupik" + ] + }, + "abusefilter-edit-throttle-groups-help": "Ǩiičč $1." +} diff --git a/AbuseFilter/i18n/sq.json b/AbuseFilter/i18n/sq.json index 9c059336..ecafdfac 100644 --- a/AbuseFilter/i18n/sq.json +++ b/AbuseFilter/i18n/sq.json @@ -1,25 +1,26 @@ { "@metadata": { "authors": [ + "Arianit", + "Bjakupi", "Euriditi", - "Marinari", - "Vinie007", + "Klein Muçi", "Kosovastar", + "Marinari", "Matma Rex", - "Arianit", - "Bjakupi" + "Vinie007" ] }, "abusefilter-desc": "Zbaton automatikisht deduktimin e redaktimeve", - "abusefilter": "Shpërdoron filter konfigurimin", - "abuselog": "Shpërdoron gjurmën e kyçjes", + "abusefilter": "Shpërdoro filtër menaxhmentin", + "abuselog": "Gjurmët e kyçjes të filtrit të shpërdorimit", "abusefilter-intro": "Mirë se vini në ballinën kryesore të Filter shpërdoruesit.\nFilter shpërdoruesi është një mekanizëm i automatizuar sofverik Për të aplikuar deduktimin automatik të të gjitha veprimeve.\nKjo ballinë tregon një listë të filtrave të përcaktuara, dhe i lejon ata të modifikohen.", "abusefilter-warning": "' ' ' Kujdes ' ' ' : Ky veprim është identifikuar automatikisht si i dëmshëm.\nRedaktimet jo-konstruktive do të rikthehen shpejt dhe redaktimet skandaloze apo jo-konstruktive të përsëritura do të rezultojë në llogarinë tuaj ose IP adresën si të bllokuara.\nNëse besoni ky redaktim të jetë konstruktiv, mund të shtypni Paraqit edhe njëherë për ta konfirmuar.\nNjë përshkrim i shkurtër i rregullave të shpërdorimit që veprimet tuaja janë përputhur janë: $1", "abusefilter-disallowed": "Ky veprim është identifikuar automatikisht si i dëmshëm, dhe për këtë arsye i ndaluar.\nNëse besoni se redaktimi i juaj të jetë konstruktiv, ju lutem informoni administratorin se çfarë ishit duke tentuar të bënit.\nNjë përshkrim i shkurtër i rregullave të shpërdorimit që veprimet tuaja janë përputhur janë: $1", "abusefilter-blocked-display": "Ky veprim është identifikuar automatikisht si i dëmshëm,\ndhe ju keni qenë të penguar në ekzekutimin e tij.\nNë mënyrë për të mbrojtur {{SITENAME}} , emri i përdoruesit tuaj dhe të gjitha IP adresat e lidhura janë bllokuar nga redaktimi.\nNëse kjo ka ndodhur në gabim, ju lutem kontaktoni administratorin.\n Një përshkrim i shkurtër i rregullave të shpërdorimit që veprimet tuaja janë përputhur janë: $1", "abusefilter-degrouped": "Ky veprim është identifikuar automatikisht si i dëmshëm.\nSi pasojë, ai ka qenë i ndaluar, dhe me që llogaria juaj është dyshuar për të qenë e kompromentuar, të gjitha të drejtat janë revokuar.\nNëse besoni se kjo ka qenë një gabim, ju lutem kontaktoni një burokrat me shpjegimim e këtij veprimi, dhe të drejtat tuaja mund të rikthehen.\nNjë përshkrim i shkurtër i rregullave të shpërdorimit që veprimet tuaja janë përputhur janë: $1", "abusefilter-autopromote-blocked": "Ky veprim është identifikuar automatikisht si i dëmshëm dhe është ndaluar.\nPërveç kësaj, si masë sigurie, disa privilegje të dhëna në mënyrë rutinore janë revokuar përkohësisht në llogarinë tuaj.\nNjë përshkrim i shkurtër i rregullave të shpërdorimit që veprimet tuaja janë përputhur janë: $1", - "abusefilter-blocker": "Abuse filtër", + "abusefilter-blocker": "Filtër redaktimesh", "abusefilter-blockreason": "të e bllokuara automatikisht nga abuzimi me filtër rregull:.! XAU prej Përshkrim përkojnë $1", "abusefilter-degroupreason": "Të drejtat e hequra automatikisht nga filtër shpërdoruesi.\nPërshkrimi i rregullit: $1", "abusefilter-accountreserved": "Ky emër llogari është i rezervuar për përdorim nga ana e abuzimit filtri.", @@ -27,7 +28,7 @@ "right-abusefilter-view": "abuzim filtra Modifiko", "right-abusefilter-log": "Shiko log abuzimin", "right-abusefilter-log-detail": "Shiko log detajuar abuzimet", - "right-abusefilter-private": "Shiko të dhënave private në log abuzimin", + "right-abusefilter-privatedetails": "Shiko të dhënave private në log abuzimin", "right-abusefilter-modify-restricted": "abuzim filtra Modifiko me veprimet e kufizuar", "right-abusefilter-revert": "Rikthehet të gjitha ndryshimet nga një abuzim të dhënë filtër", "right-abusefilter-view-private": "abuzim filtra Shiko shënuar si private", @@ -37,11 +38,10 @@ "action-abusefilter-view": "abuzim filtra Modifiko", "action-abusefilter-log": "pamje log abuzimin", "action-abusefilter-log-detail": "Shiko në hollësi gjurmët e kyçjes së shpërdoruesit", - "action-abusefilter-private": "Shiko të dhënave private në gjurmët e kyçjes së shpërdoruesit", + "action-abusefilter-privatedetails": "Shiko të dhënave private në gjurmët e kyçjes së shpërdoruesit", "action-abusefilter-modify-restricted": "Modifiko filtër shpërdoruesin me veprimet e kufizuara", "action-abusefilter-revert": "Rikthehet të gjitha ndryshimet nga filtri i shpërdorimit të dhënë", "action-abusefilter-view-private": "Shiko filtra shpërdorimit të shënuara si private", - "abusefilter-log": "Gjurmët e kyçjes të filtrit të shpërdorimit", "abusefilter-log-summary": "Kjo gjurmë tregon listën e të gjitha veprimeve të kapur nga filtrat.", "abusefilter-log-search": "Kërko gjurmët e shpërdorimit", "abusefilter-log-search-user": "Përdoruesi:", @@ -58,20 +58,18 @@ "abusefilter-log-details-var": "Variabël", "abusefilter-log-details-val": "Vlera", "abusefilter-log-details-vars": "Parametrat e veprimit", - "abusefilter-log-details-private": "Të dhënave private", + "abusefilter-log-details-privatedetails": "Të dhënave private", "abusefilter-log-details-ip": "IP adresa origjinale", "abusefilter-log-noactions": "asnjë", "abusefilter-log-details-diff": "Ndryshimet e bëra në redaktim", "abusefilter-log-linkoncontribs": "Shpërdoro gjurmët e kyçjes", "abusefilter-log-linkoncontribs-text": "Shpërdoro gjurmët e kyçjes për këtë përdorues", - "abusefilter-log-hidden": "(të dhënat e fshehura)", "abusefilter-log-details-hidden": "Nuk mund të shihni detajet për këtë shenim sepse është e fshehur për vështrim publik", "abusefilter-log-hide-legend": "Fshih shënimet për gjurmët e kyqjes", "abusefilter-log-hide-id": "ID shënimet e kyçjes", "abusefilter-log-hide-hidden": "Fsheh këtë term nga opinioni publik", "abusefilter-log-hide-reason": "Arsyeja:", "abusefilter-log-hide-forbidden": "Ju nuk keni leje për të fshehur shpërdorimin e shënimeve të kyçjes.", - "abusefilter-management": "Shpërdoro filtër menaxhmentin", "abusefilter-list": "Të gjithë filtrat", "abusefilter-list-id": "Filtër ID-ja", "abusefilter-list-status": "Statusi", @@ -91,6 +89,7 @@ "abusefilter-throttled": "Te gjitha te paperkthyera, te dala afati te perkthyera...", "abusefilter-hitcount": "$1 {{PLURAL:$1|klikim|klikime}}", "abusefilter-new": "Krijo filter të ri", + "abusefilter-import-button": "Importo filtër", "abusefilter-return": "Kthehu tek filtër menaxhmenti", "abusefilter-status-global": "Global", "abusefilter-list-options": "Opcionet", @@ -115,7 +114,6 @@ "abusefilter-edit-oldwarning": "<strong>Ju jeni duke redaktuar versionin e vjetër të këtij filtri.\nStatistikat e cituara janë për versionin më të fundit të filtrit.\nNëse ju ruani ndryshimet tuaja, ju do të mbishkruani të gjitha ndryshimet që nga inspektimi që jeni duke redaktuar. </strong> •\n[[Special:AbuseFilter/history/$2|Kthehu ne historinë e këtij filtri ]].", "abusefilter-edit-status-label": "Statistikat:", "abusefilter-edit-status": "fundit $1 {{PLURAL:$1|veprimi i|veprimet e}}, ky filtër i ka krahasuar $2 ($3%).", - "abusefilter-edit-status-profile": "fundit $1 {{PLURAL:$1|veprimi i|veprimet e}}, ky filtër i ka krahasuar $2 ($3%).\nMesatarisht, koha e rrjedhës është $4ms, dhe konsumon $5 {{PLURAL:$5|kusht|kushtet}} e kufirit të kushtit", "abusefilter-edit-new": "Filtër i ri", "abusefilter-edit-save": "Ruaj filtrin", "abusefilter-edit-id": "Filter ID-ja:", @@ -244,13 +242,13 @@ "abusefilter-edit-builder-vars-all-links": "Të gjitha vegzat e jashtme (links) në tekst të ri", "abusefilter-edit-builder-vars-added-links": "Të gjitha vegzat e jashtme (links) të shtuara në redaktim", "abusefilter-edit-builder-vars-removed-links": "Të gjitha vegzat e jashtme (links) të larguara në redaktim", - "abusefilter-edit-builder-vars-old-text": "Faqet e vjetra wikitext, përpara redaktimit", - "abusefilter-edit-builder-vars-new-text": "Faqe e re wikitext, pas redaktimit", - "abusefilter-edit-builder-vars-new-text-stripped": "Tekst faqe e re, e zhveshur nga çdo shenjim", + "abusefilter-edit-builder-vars-old-wikitext": "Faqet e vjetra wikitext, përpara redaktimit", + "abusefilter-edit-builder-vars-new-wikitext": "Faqe e re wikitext, pas redaktimit", + "abusefilter-edit-builder-vars-new-text": "Tekst faqe e re, e zhveshur nga çdo shenjim", "abusefilter-edit-builder-vars-new-html": "HTML burimi i analizuar gramatikisht nga revizioni i ri", "abusefilter-edit-builder-vars-restrictions-edit": "Redakto nivelin mbrojtës të faqes", "abusefilter-edit-builder-vars-restrictions-move": "Largo nivelin mbrojtjes të faqes", - "abusefilter-edit-builder-vars-old-text-stripped": "Tekst faqe e vjetër, e zhveshur nga çdo shenjim", + "abusefilter-edit-builder-vars-old-text": "Tekst faqe e vjetër, e zhveshur nga çdo shenjim", "abusefilter-edit-builder-vars-old-links": "Vegzat në faqe, përpara redaktimit", "abusefilter-edit-builder-vars-old-html": "Faqe e vjetër wikitext, e analizuar gramatikisht në HTML", "abusefilter-edit-builder-vars-minor-edit": "Nëse janë apo jo, redaktimi është shënuar si i vogël", @@ -305,7 +303,6 @@ "abusefilter-examine-title": "Titulli i faqes:", "abusefilter-examine-submit": "Kërko", "abusefilter-topnav-home": "Faqja kryesore", - "abusefilter-topnav-import": "Importo filtër", "abusefilter-log-noresults": "S'ka rezultate", "abusefilter-diff-item": "Artikulli", "abusefilter-diff-info": "Informata bazë", diff --git a/AbuseFilter/i18n/sr-ec.json b/AbuseFilter/i18n/sr-ec.json index fb2d70f3..7b0c1217 100644 --- a/AbuseFilter/i18n/sr-ec.json +++ b/AbuseFilter/i18n/sr-ec.json @@ -1,168 +1,186 @@ { "@metadata": { "authors": [ + "Acamicamacaraca", + "BadDog", + "Dungodung", "FriedrickMILBarbarossa", + "Kizule", + "Matma Rex", "Milicevic01", + "Obsuser", "Rancher", "Sasa Stefanovic", + "Zoranzoki21", "Жељко Тодоровић", "Михајло Анђелковић", - "Сербијана", - "Matma Rex", - "Dungodung", - "Obsuser", - "Acamicamacaraca", - "Zoranzoki21", - "BadDog" + "Сербијана" ] }, "abusefilter-desc": "Примењује аутоматске хеуристике изменама", - "abusefilter": "Конфигурација филтера злоупотребе", - "abuselog": "Дневник злоупотребе", - "abusefilter-intro": "Добро дошли у интерфејс за управљање филтером злоупотребе.\nТо је аутоматизовани софтверски механизам који примењује хеуристику за све радње.\nОвај интерфејс приказује списак дефинисаних филтера и дозвољава вам да их измените.", - "abusefilter-warning": "'''Упозорење''': Ова радња је аутоматски идентификована као штетна.\nНеконструктивне радње ће брзо бити враћене,\nа прекомерно или поновљено неконструктивно уређивање ће довести до блокирања вашег налога или IP адресе.\nУколико верујете да је ова радња конструктивна, можете је поново послати да је потврдите.\nКратак опис правила о злоупотреби који се подудара са вашом радњом: $1", - "abusefilter-disallowed": "Аутоматски филтер је препознао ову измену као потенцијално штетну и стога је није дозволио.\nУколико сматрате да измена ипак јесте конструктивна, обавестите неког од администратора о томе шта покушавате да учините.\nКратак опис повређеног правила: $1", - "abusefilter-blocked-display": "Аутоматски филтер је препознао ову измену као потенцијално штетну и није вам допуштено да је извршите.\nОсим тога, да би се заштититио/ла {{SITENAME}}, ваш налог и одговарајуће IP адресе су блокиране.\nУколико се ово догодило грешком, контактирајте неког од администратора.\nКратак опис повређеног правила: $1", - "abusefilter-degrouped": "Аутоматски филтер је препознао ову измену као потенцијално штетну.\nСтога измена није дозвољена, а уклоњена су вам и сва овлашћења која сте имали. Уколико сматрате да је до тога дошло грешком, контактирајте неког од бирократа, објасните шта сте урадили и овлашћења ће вам можда бити враћена.\nКратак опис повређеног правила: $1", - "abusefilter-autopromote-blocked": "Аутоматски филтер је препознао ову измену као потенцијално штетну и стога је није дозволио.\nОсим тога, из предострожности су вам привремено уклоњена одређена овлашћења.\nКратак опис повређеног правила: $1", - "abusefilter-blocker": "Филтер злоупотребе", - "abusefilter-blockreason": "Блокирани сте од стране филтера против злоупотребе.\nОпис повређеног правила: $1", - "abusefilter-degroupreason": "Филтер злоупотребе је аутоматски одузео права.\nОпис правила: $1", - "abusefilter-accountreserved": "Ово корисничко име је резервисано од стране филтера против злоупотребе.", - "right-abusefilter-modify": "мењање филтерâ против злоупотребе", - "right-abusefilter-view": "прегледање филтерâ против злоупотребе", - "right-abusefilter-log": "прегледање дневника злоупотребе", - "right-abusefilter-log-detail": "прегледање детаљних уноса у евиденцији злоупотребе", - "right-abusefilter-private": "прегледање приватних података у евиденцији злоупотребе", - "right-abusefilter-modify-restricted": "мењање филтерâ против злоупотребе са ограниченим радњама", - "right-abusefilter-revert": "враћање свих промена које је направио филтер злоупотребе", - "right-abusefilter-view-private": "прегледање филтера против злоупотребе означених као приватни", - "right-abusefilter-log-private": "прегледање уноса у евиденцији злоупотребе означених као приватни", - "right-abusefilter-hide-log": "сакривање уноса у евиденцији злоупотребе", - "right-abusefilter-hidden-log": "прегледање скривених уноса у евиденцији злоупотребе", - "right-abusefilter-modify-global": "прављење или мењање глобалних филтера против злоупотребе", - "action-abusefilter-modify": "измењујете филтере против злоупотребе", - "action-abusefilter-view": "прегледате филтере против злоупотребе", - "action-abusefilter-log": "прегледате дневник злоупотребе", - "action-abusefilter-log-detail": "прегледате детаљне уносе у евиденцији злоупотребе", - "action-abusefilter-private": "прегледате приватне податаке у евиденцији злоупотребе", - "action-abusefilter-modify-restricted": "мењате филтере прозив злоупотребе са ограниченим радњама", - "action-abusefilter-revert": "вратите све промене датог филтера против злоупотребе", - "action-abusefilter-view-private": "прегледате филтере против злоупотребе означене као приватни", - "action-abusefilter-log-private": "прегледање дневника филтера против злоупотребе означених као приватни", - "abusefilter-log": "Дневник филтера против злоупотребе", - "abusefilter-log-summary": "Овај дневник приказује списак свих радњи које су задржали филтери.", - "abusefilter-log-search": "Претрага дневника злоупотребе", + "abusefilter": "Управљање филтерима злоупотреба", + "abuselog": "Дневник филтерâ злоупотреба", + "abusefilter-intro": "Добро дошли на страницу за управљање филтерима злоупотреба!<br />Ови филтери служе да успоре, упозоре или забране извршење нежељених радњи. Испод можете да их видите и мењате.", + "abusefilter-mustviewprivateoredit": "Из безбедносних разлога само корисници са правом прегледа приватних филтера злоупотреба или мењања филтера могу да користе ово окружење.", + "abusefilter-warning": "'''Упозорење''': Ова радња је аутоматски препозната као штетна.\nНеконструктивне радње ће брзо бити враћене,\nа прекомерно или поновљено неконструктивно уређивање може довести до блокирања вашег налога или IP адресе.\nАко сматрате да ова радња јесте конструктивна, поново поднесите образац како бисте је потврдили.\nКратак опис прекршеног правила: $1", + "abusefilter-disallowed": "Ова радња је аутоматски препозната као штетна, па није дозвољена.\nАко сматрате да измена јесте конструктивна, обавестите неког од администратора о томе шта покушавате да учините.\nКратак опис прекршеног правила: $1", + "abusefilter-blocked-display": "Аутоматски филтер је препознао ову измену као потенцијално штетну и није вам допуштено да је извршите.\nОсим тога, да би се заштитио пројекат {{SITENAME}}, ваш налог и одговарајуће IP адресе су блокиране.\nАко се ово догодило грешком, обратите се неком администратору.\nКратак опис повређеног правила: $1", + "abusefilter-degrouped": "Ова радња је аутоматски препозната као штетна, па није дозвољена.\nБудући да се сумња да је ваш налог угрожен, сва права су опозвана.\nАко сматрате да је ово грешка, обратите се бирократи с објашњењем радње и права ће вам вероватно бити враћена.\nКратак опис прекршеног правила: $1", + "abusefilter-autopromote-blocked": "Ова радња је аутоматски препозната као штетна, па није дозвољена.\nОсим тога, из предострожности су вам привремено опозване одређене привилегије.\nКратак опис прекршеног правила: $1", + "abusefilter-blocker": "Филтер злоупотреба", + "abusefilter-blockreason": "Филтер злоупотреба Вас је аутоматски блокирао.\nОпис прекршеног правила: $1", + "abusefilter-degroupreason": "Филтер злоупотреба је аутоматски одузео права.\nОпис правила: $1", + "abusefilter-blockautopromotereason": "Филтер злоупотреба је аутоматски одложио самоунапређивање.\nОпис правила: $1", + "abusefilter-accountreserved": "Ово корисничко име је резервисано за филтер злоупотреба.", + "right-abusefilter-modify": "прављење или мењање филтерâ злоупотреба", + "right-abusefilter-view": "прегледање филтерâ злоупотреба", + "right-abusefilter-log": "прегледање дневника злоупотреба", + "right-abusefilter-log-detail": "прегледање детаљних података у дневнику злоупотреба", + "right-abusefilter-privatedetails": "прегледање приватних података у дневнику злоупотреба", + "right-abusefilter-modify-restricted": "мењање филтерâ злоупотреба с ограниченим радњама", + "right-abusefilter-revert": "враћање свих измена датог филтера злоупотреба", + "right-abusefilter-view-private": "прегледање филтерâ злоупотреба означених приватнима", + "right-abusefilter-log-private": "прегледање ставки у дневнику злоупотреба означених приватнима", + "right-abusefilter-hide-log": "сакривање ставки у дневнику злоупотреба", + "right-abusefilter-hidden-log": "прегледање скривених ставки у дневнику злоупотреба", + "right-abusefilter-modify-global": "прављење или мењање глобалних филтера злоупотреба", + "action-abusefilter-modify": "мењате филтере злоупотреба", + "action-abusefilter-view": "прегледате филтере злоупотреба", + "action-abusefilter-log": "прегледате дневник злоупотреба", + "action-abusefilter-log-detail": "прегледате детаљне податке у дневнику злоупотреба", + "action-abusefilter-privatedetails": "прегледате приватне податаке у дневнику злоупотреба", + "action-abusefilter-modify-restricted": "мењате филтере злоупотреба с ограниченим радњама", + "action-abusefilter-revert": "вратите све измене датог филтера злоупотреба", + "action-abusefilter-view-private": "прегледате филтере злоупотреба означене приватнима", + "action-abusefilter-log-private": "прегледање дневника филтера злоупотребa означених приватнима", + "action-abusefilter-hide-log": "кријете ставке у дневнику злоупотреба", + "action-abusefilter-hidden-log": "гледате сакривене ставке у дневнику злоупотреба", + "action-abusefilter-modify-global": "прављење или мењање глобалних филтера злоупотреба", + "abusefilter-log-summary": "Овај дневник приказује списак свих радњи које су ухватили филтери.", + "abusefilter-log-search": "Претрага дневника злоупотреба", "abusefilter-log-search-user": "Корисник:", - "abusefilter-log-search-filter": "ID-ови филтера (одвојени усправним цртама):", + "abusefilter-log-search-group": "Група филтера:", + "abusefilter-log-search-group-any": "Било који", + "abusefilter-log-search-filter": "ID-јеви филтера:", "abusefilter-log-search-title": "Наслов:", - "abusefilter-log-search-wiki": "Вики:", + "abusefilter-log-search-wiki": "Пројекат:", "abusefilter-log-search-impact": "Утицај:", "abusefilter-log-search-impact-all": "Све радње", - "abusefilter-log-search-impact-saved": "Само сачуване промене", + "abusefilter-log-search-impact-saved": "Само сачуване измене", "abusefilter-log-search-impact-not-saved": "Без сачуваних измена", "abusefilter-log-search-entries-label": "Видљивост:", - "abusefilter-log-search-entries-all": "Сви уноси", - "abusefilter-log-search-entries-hidden": "Само сакривени уноси", - "abusefilter-log-search-entries-visible": "Само видљиви уноси", + "abusefilter-log-search-entries-all": "Све ставке", + "abusefilter-log-search-entries-hidden": "Само сакривене ставке", + "abusefilter-log-search-entries-visible": "Само видљиве ставке", "abusefilter-log-search-action-label": "Покренута радња:", "abusefilter-log-search-action-other": "други", "abusefilter-log-search-action-any": "Било који", "abusefilter-log-search-action-taken-label": "Предузета радња:", "abusefilter-log-search-action-taken-any": "Било која", "abusefilter-log-search-submit": "Претражи", - "abusefilter-log-entry": "$1: $2 је {{GENDER:$8|активирао}} филтер, {{GENDER:$8|изводећи}} радњу „$3“ на страници $4.\nПредузете радње: $5;\nОпис филтера: $6", - "abusefilter-log-entry-withdiff": "$1: $2 је {{GENDER:$8|активирао}} филтер злоупотребе, {{GENDER:$8|изводећи}} радњу „$3“ на страници $4.\nПредузете радње: $5;\nОпис филтера: $6 ($7)", - "abusefilter-log-detailedentry-meta": "$1: $2 је {{GENDER:$9|активирао}} $3, {{GENDER:$9|изводећи}} радњу „$4“ на страници $5.\nПредузете радње: $6;\nОпис филтера: $7 ($8)", + "abusefilter-log-entry": "$1: $2 је {{GENDER:$8|активирао}} филтер {{GENDER:$8|изводећи}} радњу „$3” на страници $4.\nПредузете радње: $5;\nОпис филтера: $6", + "abusefilter-log-entry-withdiff": "$1: $2 је {{GENDER:$8|активирао}} филтер злоупотреба {{GENDER:$8|изводећи}} радњу „$3” на страници $4.\nПредузете радње: $5;\nОпис филтера: $6 ($7)", + "abusefilter-log-detailedentry-meta": "$1: $2 је {{GENDER:$9|активирао}} $3 {{GENDER:$9|изводећи}} радњу „$4” на страници $5.\nПредузете радње: $6;\nОпис филтера: $7 ($8)", "abusefilter-log-detailedentry-global": "глобални филтер $1", "abusefilter-log-detailedentry-local": "филтер $1", "abusefilter-log-detailslink": "детаљи", "abusefilter-log-diff": "разл", "abusefilter-log-hidelink": "подеси видљивост", - "abusefilter-log-details-legend": "Детаљи уноса у евиденцији $1", + "abusefilter-log-details-legend": "Детаљи ставке у дневнику $1", "abusefilter-log-details-var": "Променљива", "abusefilter-log-details-val": "Вредност", "abusefilter-log-details-vars": "Параметри радње", - "abusefilter-log-details-private": "Приватни детаљи дневника", + "abusefilter-log-details-privatedetails": "Приватни детаљи дневника", "abusefilter-log-details-ip": "Изворна IP адреса", "abusefilter-log-details-checkuser": "Провери корисника", "abusefilter-log-noactions": "ништа", "abusefilter-log-details-diff": "Промене направљене при уређивању", - "abusefilter-log-linkoncontribs": "дневник злоупотребе", - "abusefilter-log-linkoncontribs-text": "Дневник злоупотребе {{GENDER:$1|овог корисника|ове кориснице}}", - "abusefilter-log-linkonhistory": "прикажи дневник злоупотребе", - "abusefilter-log-linkonhistory-text": "Погледајте дневник злоупотребе ове странице", - "abusefilter-log-hidden": "(унос је сакривен)", + "abusefilter-log-linkoncontribs": "дневник злоупотреба", + "abusefilter-log-linkoncontribs-text": "Дневник злоупотреба {{GENDER:$1|овог корисника|ове кориснице}}", + "abusefilter-log-linkonhistory": "дневник злоупотребa", + "abusefilter-log-linkonhistory-text": "Погледајте дневник злоупотребa ове странице", + "abusefilter-log-linkonundelete": "прикажи дневник злоупотребa", + "abusefilter-log-linkonundelete-text": "Прикажи дневник злоупотребa ове странице", "abusefilter-log-hidden-implicit": "(скривено јер је измена избрисана)", - "abusefilter-log-cannot-see-details": "Немате дозволу да видите детаље овог уноса.", - "abusefilter-log-cannot-see-private-details": "Немате дозволу да видите приватне детаље овог уноса.", - "abusefilter-log-nonexistent": "Унос са наведеним ID-ом не постоји.", + "abusefilter-log-cannot-see-details": "Немате дозволу да видите детаље ове ставке.", + "abusefilter-log-cannot-see-privatedetails": "Немате дозволу да видите приватне детаље ове ставке.", + "abusefilter-log-nonexistent": "Ставка с наведеним ID-јем не постоји.", "abusefilter-log-details-hidden": "Не можете да видите детаље овог филтера јер су сакривени за јавни преглед.", - "abusefilter-log-hide-legend": "Сакриј унос у евиденцији", - "abusefilter-log-hide-id": "ID уноса у евиденцији:", - "abusefilter-log-hide-hidden": "Сакриј овај унос од јавног прегледа", + "abusefilter-log-details-hidden-implicit": "Не можете да видите детаље овог филтера јер су повезане измене сакривене за јавни преглед.", + "abusefilter-log-hide-legend": "Сакриј ставку у дневнику", + "abusefilter-log-hide-id": "ID ставке у дневнику:", + "abusefilter-log-hide-hidden": "Сакриј ову ставку од јавног прегледа", "abusefilter-log-hide-reason": "Разлог:", "abusefilter-log-hide-reason-other": "Други/додатни разлог:", - "abusefilter-log-hide-forbidden": "Немате дозволу да сакривате уносе у извештају злоупотребе.", - "abusefilter-log-entry-suppress": "$1 је {{GENDER:$2|сакрио|сакрила}} унос у евиденцији $3", - "logentry-abusefilter-hit": "$1 је {{GENDER:$2|активирао|активирала}} $4, изводећи радњу „$5“ на страници $3. Предузете радње: $6 ($7)", - "log-action-filter-abusefilter": "Тип промене филтера:", + "abusefilter-log-hide-forbidden": "Немате дозволу да сакривате ставке у дневнику злоупотреба.", + "abusefilter-log-entry-suppress": "$1 је {{GENDER:$2|сакрио|сакрила}} ставку у дневнику $3", + "logentry-abusefilter-hit": "$1 је {{GENDER:$2|активирао|активирала}} $4 изводећи радњу „$5” на страници $3. Предузете радње: $6 ($7)", + "log-action-filter-abusefilter": "Врста промене филтера:", "log-action-filter-abusefilter-create": "нови филтер", "log-action-filter-abusefilter-modify": "уређивање филтера", - "log-action-filter-suppress-abuselog": "Сакривање дневника злоупотребе", - "abusefilter-management": "Управљање филтером против злоупотребе", + "log-action-filter-suppress-abuselog": "Сакривање дневника злоупотреба", + "log-action-filter-rights-blockautopromote": "Блокирање самоунапређивања", "abusefilter-list": "Сви филтери", "abusefilter-list-id": "ID филтера", + "abusefilter-list-pattern": "Узорак", "abusefilter-list-status": "Статус", "abusefilter-list-public": "Јавни опис", - "abusefilter-list-consequences": "Последице", + "abusefilter-list-consequences": "Мере", "abusefilter-list-visibility": "Видљивост", - "abusefilter-list-hitcount": "Бројач погодака", + "abusefilter-list-hitcount": "Број погодака", "abusefilter-list-edit": "Уреди", "abusefilter-list-details": "Детаљи", - "abusefilter-list-limit": "Ставки по страници:", + "abusefilter-list-limit": "Филтера по страници:", "abusefilter-list-lastmodified": "Последња измена", "abusefilter-list-group": "Група филтера", "abusefilter-hidden": "Приватно", "abusefilter-unhidden": "Јавно", - "abusefilter-enabled": "Омогућено", - "abusefilter-deleted": "Обрисано", - "abusefilter-disabled": "Онемогућено", + "abusefilter-enabled": "укључен", + "abusefilter-deleted": "Избрисано", + "abusefilter-disabled": "искључен", + "abusefilter-throttled": "успорено", "abusefilter-hitcount": "$1 {{PLURAL:$1|погодак|поготка|погодака}}", "abusefilter-new": "Направи нови филтер", + "abusefilter-import-button": "увези филтер", "abusefilter-return": "Назад на управљање филтерима", "abusefilter-status-global": "Глобално", "abusefilter-list-options": "Опције", - "abusefilter-list-options-deleted": "Обрисани филтери:", - "abusefilter-list-options-deleted-only": "Прикажи само обрисане филтере", - "abusefilter-list-options-deleted-hide": "Сакриј обрисане филтере", - "abusefilter-list-options-deleted-show": "Укључи и обрисане филтере", + "abusefilter-list-options-deleted": "Избрисани филтери:", + "abusefilter-list-options-deleted-only": "Прикажи само избрисане филтере", + "abusefilter-list-options-deleted-hide": "Сакриј избрисане филтере", + "abusefilter-list-options-deleted-show": "Прикажи избрисане филтере", "abusefilter-list-options-scope": "Прикажи филтере:", "abusefilter-list-options-scope-local": "Само локална правила", "abusefilter-list-options-scope-global": "Само глобална правила", "abusefilter-list-options-scope-all": "Локална и глобална правила", - "abusefilter-list-options-hidedisabled": "Сакриј онемогућене филтере", - "abusefilter-list-options-searchoptions": "Претражи режим:", - "abusefilter-list-options-search-rlike": "Регуларни израз", + "abusefilter-list-options-further-options": "Додатне опције:", + "abusefilter-list-options-hidedisabled": "Сакриј искључене филтере", + "abusefilter-list-options-hideprivate": "Сакриј приватне филтере", + "abusefilter-list-options-searchfield": "Претражи:", + "abusefilter-list-options-searchpattern": "Унесите узорак", + "abusefilter-list-options-searchoptions": "Режим претраге:", + "abusefilter-list-options-search-like": "обична претрага", + "abusefilter-list-options-search-rlike": "регуларни израз", + "abusefilter-list-options-search-irlike": "регуларни израз (без разликовања малих и великих слова)", "abusefilter-list-options-submit": "Ажурирај", - "abusefilter-tools-text": "Овде се налазе алатке које су корисне за исправљање грешака на филтеру против злоупотребе.", + "abusefilter-tools-text": "Овде се налазе алатке које су корисне за састављање и преправку филтерâ злоупотреба.", "abusefilter-tools-expr": "Тестирање филтера", "abusefilter-tools-submitexpr": "Процени", - "abusefilter-tools-reautoconfirm": "Врати самопотврђени статус", + "abusefilter-tools-syntax-error": "Филтер има неважећу синтаксу.", + "abusefilter-tools-reautoconfirm": "Врати аутоматски потврђен статус", "abusefilter-tools-reautoconfirm-user": "Корисник:", "abusefilter-tools-reautoconfirm-submit": "Потврди", "abusefilter-reautoconfirm-none": "Самопотврђени статус {{GENDER:$1|овог корисника|ове кориснице|овог корисника}} никада није био укинут.", "abusefilter-reautoconfirm-notallowed": "Није вам дозвољено да вратите самопотврђени статус.", "abusefilter-reautoconfirm-done": "Самопотврђени статус је враћен", - "abusefilter-status": "Од {{PLURAL:$1|последње радње|последње $1 радње|последњих $1 радњи}}, $2 ($3%) {{PLURAL:$2|је достигла|су достигле|је достигло}} ограничење од $4, а $5 ($6%) {{PLURAL:$5|се подудара|се подударају}} с једним од тренутно омогућених филтера.", - "abusefilter-edit": "Уређивање филтера злоупотребе", + "abusefilter-status": "Од {{PLURAL:$1|последње радње|последње $1 радње|последњих $1 радњи}}, $2 ($3%) {{PLURAL:$2|је достигла|су достигле|је достигло}} ограничење од $4, а $5 ($6%) {{PLURAL:$5|се подудара|се подударају}} са најмање једним од тренутно омогућених филтера.", + "abusefilter-edit": "Уређивање филтера злоупотреба", "abusefilter-edit-subtitle": "Уређујете филтер $1", "abusefilter-edit-subtitle-new": "Прављење филтера", "abusefilter-edit-token-not-match": "Измена није сачувана. Сачувајте је поново.", "abusefilter-edit-oldwarning": "<strong>Уређујете стару верзију овог филтера.\nИсказане статистике су за најновију верзију филтера.\nАко сачувате измене, обрисаћете све измене настале од измене коју управо уређујете.</strong> •\n[[Special:AbuseFilter/history/$2|Назад на историју овог филтера]].", "abusefilter-edit-status-label": "Статистике:", - "abusefilter-edit-status": "Од {{PLURAL:$1|последње радње|последње $1 радње|последњих $1 радњи}}, овај филтер се поклопио $2 ($3%).", - "abusefilter-edit-status-profile": "Од {{PLURAL:$1|последње радње|последње $1 радње|последњих $1 радњи}}, овај филтер се поклопио $2 ($3%).\nУ просеку, његово време покретања је $4 мс, а троши $5 {{PLURAL:$5|услов|услова}}.", + "abusefilter-edit-status": "Од {{PLURAL:$1|последње радње|последње $1 радње|последњих $1 радњи}}, овај филтер се поклопио $2 ($3%).\n\nУ просеку, његово време рада је $4 ms, и троши $5 {{PLURAL:$5|услов|услова}} ограничења услова.", "abusefilter-edit-new": "Нови филтер", "abusefilter-edit-save": "Сачувај филтер", "abusefilter-edit-id": "ID филтера:", @@ -171,32 +189,38 @@ "abusefilter-edit-field-description": "опис", "abusefilter-edit-group": "Група филтера:", "abusefilter-edit-flags": "Заставице:", - "abusefilter-edit-enabled": "Омогући овај филтер", - "abusefilter-edit-deleted": "Означи као обрисан", + "abusefilter-edit-enabled": "Омогући филтер", + "abusefilter-edit-deleted": "Означи избрисаним", "abusefilter-edit-hidden": "Сакриј детаље овог филтера из јавног приказа", "abusefilter-edit-global": "Глобални филтер", "abusefilter-edit-rules": "Услови:", "abusefilter-edit-field-conditions": "услови", "abusefilter-edit-notes": "Напомене:", "abusefilter-edit-lastmod": "Последња измена филтера:", - "abusefilter-edit-lastmod-text": "$3, $4 од {{GENDER:$5|корисника|кориснице|корисника}} $2", + "abusefilter-edit-lastmod-text": "{{GENDER:$5|аутор}}: $2; датум: $3 у $4", "abusefilter-edit-hitcount": "Погоци филтера:", "abusefilter-edit-consequences": "Предузети радње при поклапању", - "abusefilter-edit-action-warn": "Покрени ове радње након што упозорите корисника", - "abusefilter-edit-action-disallow": "Спречи корисника да изврши дотичну радњу", - "abusefilter-edit-action-blockautopromote": "Врати самопотврђени статус корисника", + "abusefilter-edit-action-warn": "Упозори корисника", + "abusefilter-edit-action-disallow": "Забрани кориснику да изврши дату радњу", + "abusefilter-edit-action-blockautopromote": "Одузми кориснику аутоматски потврђен статус", "abusefilter-edit-action-degroup": "Уклони корисника са свих овлашћених група", - "abusefilter-edit-action-block": "Блокирај корисника/цу и/или IP адресу од уређивања", - "abusefilter-edit-action-throttle": "Покрени радње само ако корисник пређе ограничење учесталости", + "abusefilter-edit-action-block": "Блокирај уређивање кориснику и/или IP адреси", + "abusefilter-edit-action-throttle": "Успори корисника ако пређе ограничење учесталости", "abusefilter-edit-action-rangeblock": "Блокирај /16 опсег IP адреса корисника", "abusefilter-edit-action-tag": "Означи измену за будући преглед", "abusefilter-edit-throttle-count": "Број дозвољених радњи:", - "abusefilter-edit-throttle-period": "Временски период (у секундама):", + "abusefilter-edit-throttle-period": "Период (у секундама):", "abusefilter-edit-throttle-groups": "Групно успоравање према:", - "abusefilter-edit-throttle-ip": "IP адреса", - "abusefilter-edit-throttle-user": "Кориснички налог", - "abusefilter-edit-throttle-editcount": "Број измена", - "abusefilter-edit-throttle-page": "Страница", + "abusefilter-edit-throttle-groups-help": "Погледајте $1.", + "abusefilter-edit-throttle-groups-help-text": "документацију на сајту mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Разделите са зарезима да бисте се придружили са AND, или са преломима реда да бисте се придружили са OR", + "abusefilter-throttle-ip": "IP адреса", + "abusefilter-throttle-user": "кориснички налог", + "abusefilter-throttle-creationdate": "датум отварања налога", + "abusefilter-throttle-editcount": "број измена", + "abusefilter-throttle-site": "цео сајт", + "abusefilter-throttle-page": "страница", + "abusefilter-throttle-none": "(ништа)", "abusefilter-edit-warn-message": "Системска порука која ће се користити за упозорење:", "abusefilter-edit-warn-other": "Остале поруке", "abusefilter-edit-warn-other-label": "Име странице друге поруке:\n:''(без префикса „Медијавики”)''", @@ -211,15 +235,18 @@ "abusefilter-edit-disallow-edit": "Направи/уреди изабрану поруку", "abusefilter-edit-tag-tag": "[[Special:Tags|Ознаке]] за примену:", "abusefilter-edit-tag-hidden-placeholder": "Додајте ознаке (одвојене зарезом)", + "abusefilter-edit-block-anon-durations": "Дужина блокирања за анонимне кориснике:", + "abusefilter-edit-block-user-durations": "Трајање блокирања регистрованих корисника:", "abusefilter-block-anon": "Блокирај анонимне кориснике", "abusefilter-block-user": "блокирај регистроване кориснике", + "abusefilter-block-talk": "блокирана страница за разговор", "abusefilter-edit-denied": "Не можете видети детаље овог филтера јер је сакривен из јавног приказа.", "abusefilter-edit-main": "Параметри филтера", "abusefilter-edit-done-subtitle": "Филтер је уређен", - "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Ваше измене]] [[Special:AbuseFilter/$1|филтера $3]] су сачуване.", + "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Ваше промене]] [[Special:AbuseFilter/$1|филтера $3]] су сачуване.", "abusefilter-edit-badsyntax": "Наведени филтер има синтаксну грешку.\nИзлаз из рашчлањивача био је: <pre>$1</pre>", "abusefilter-edit-restricted": "Не можете уређивати овај филтер јер садржи једну или више ограничених радњи.\nЗамолите корисника с одређеним овлашћењем да направи измене уместо вас.", - "abusefilter-edit-viewhistory": "Погледај историју филтера", + "abusefilter-edit-viewhistory": "Прикажи историју филтера", "abusefilter-edit-history": "Историја:", "abusefilter-edit-check": "Провери синтаксу", "abusefilter-edit-badfilter": "Наведени филтер не постоји", @@ -230,9 +257,14 @@ "abusefilter-edit-syntaxok": "Нема синтаксних грешака.", "abusefilter-edit-syntaxerr": "Откривена је синтактичка грешка: $1", "abusefilter-edit-bad-tags": "Једна или више ознака које сте навели нису валидне.\nОзнака мора бити кратка и не сме садржати специјалне карактере, и они не смеју бити коришћени од стране другог софтвера. Покушајте са бирањем нове ознаке.", - "abusefilter-edit-notallowed": "Није вам дозвољено да правите или уређујете филтере против злоупотребе", - "abusefilter-edit-notallowed-global": "Није вам дозвољено да правите или уређујете глобалне филтере против злоупотребе", - "abusefilter-edit-builder-select": "Изаберите могућност за додавање на показивач", + "abusefilter-edit-notallowed": "Није вам дозвољено да правите или уређујете филтере злоупотреба", + "abusefilter-edit-notallowed-global": "Није вам дозвољено да правите или уређујете глобалне филтере злоупотреба", + "abusefilter-edit-invalid-throttlecount": "Број радњи регулатора мора да буде позитиван цео број.", + "abusefilter-edit-invalid-throttleperiod": "Период регулатора мора да буде позитиван цео број.", + "abusefilter-edit-empty-throttlegroups": "Мора се изабрати најмање једна група регулатора.", + "abusefilter-edit-duplicated-throttlegroups": "Групе регулатора не могу имати дупликате.", + "abusefilter-edit-invalid-throttlegroups": "Наведена група регулатора није важећа.", + "abusefilter-edit-builder-select": "Изаберите опцију да бисте је додали у оквир уређивања", "abusefilter-edit-builder-group-op-arithmetic": "Аритметички оператори", "abusefilter-edit-builder-op-arithmetic-addition": "Сабирање (+)", "abusefilter-edit-builder-op-arithmetic-subtraction": "Одузимање (-)", @@ -260,7 +292,8 @@ "abusefilter-edit-builder-misc-contains": "Лева ниска садржи десну ниску (contains)", "abusefilter-edit-builder-misc-stringlit": "Буквалан израз у ниски (\"\")", "abusefilter-edit-builder-misc-tern": "Тринарни оператор (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Услов (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Услов (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "Кратки услов (if X then Y end)", "abusefilter-edit-builder-group-funcs": "Функције", "abusefilter-edit-builder-funcs-length": "Дужина ниске (length)", "abusefilter-edit-builder-funcs-lcase": "Малим словима (lcase)", @@ -315,22 +348,36 @@ "abusefilter-edit-builder-vars-user-rights": "Права која корисник има", "abusefilter-edit-builder-vars-user-emailconfirm": "Време када је имејл адреса потврђена", "abusefilter-edit-builder-vars-recent-contributors": "Последњих десет уредника странице", + "abusefilter-edit-builder-vars-first-contributor": "Први уредник странице", + "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "Последњих десет уредника изворне странице премештања", + "abusefilter-edit-builder-vars-movedfrom-first-contributor": "Први уредник изворне странице премештања", + "abusefilter-edit-builder-vars-movedto-recent-contributors": "Последњих десет уредника одредишне странице премештања", + "abusefilter-edit-builder-vars-movedto-first-contributor": "Први уредник одредишне странице премештања", "abusefilter-edit-builder-vars-all-links": "Све спољашње везе у новом тексту", "abusefilter-edit-builder-vars-added-links": "Све спољашње везе додате у измени", "abusefilter-edit-builder-vars-removed-links": "Све спољашње везе уклоњене у измени", - "abusefilter-edit-builder-vars-old-text": "Стари викитекст пре измене (није више у употреби)", - "abusefilter-edit-builder-vars-new-text": "Нови викитекст после измене", + "abusefilter-edit-builder-vars-old-wikitext": "Стари викитекст странице пре измене", + "abusefilter-edit-builder-vars-new-wikitext": "Нови викитекст странице после измене", "abusefilter-edit-builder-vars-addedlines-pst": "Линије додане у уређивању, трансформиране у несачуване", - "abusefilter-edit-builder-vars-new-text-stripped": "Текст нове странице, без икаквих обележавања", + "abusefilter-edit-builder-vars-new-text": "Текст нове странице, без икаквих обележавања", "abusefilter-edit-builder-vars-new-html": "Рашчлањени HTML извор нове измене", - "abusefilter-edit-builder-vars-restrictions-edit": "Ниво заштите странице (уређивање)", - "abusefilter-edit-builder-vars-restrictions-move": "Ниво заштите странице (премештање)", - "abusefilter-edit-builder-vars-old-text-stripped": "Текст старе странице, без икаквих обележавања", + "abusefilter-edit-builder-vars-restrictions-edit": "Степен заштите странице (уређивање)", + "abusefilter-edit-builder-vars-restrictions-move": "Степен заштите странице (премештање)", + "abusefilter-edit-builder-vars-restrictions-create": "Заштита од прављења странице", + "abusefilter-edit-builder-vars-restrictions-upload": "Заштита за отпремање датотеке", + "abusefilter-edit-builder-vars-old-text": "Текст старе странице, са одстрањеним назнакама (није више у употреби)", "abusefilter-edit-builder-vars-old-links": "Везе на страници, пре уређивања", "abusefilter-edit-builder-vars-old-html": "Викитекст старе странице, рашчлањен у HTML (није више у употреби)", - "abusefilter-edit-builder-vars-minor-edit": "Да ли је измена била означена као мања", + "abusefilter-edit-builder-vars-minor-edit": "Да ли је измена била означена као мања (није више у употреби)", "abusefilter-edit-builder-vars-file-sha1": "Дисперзија SHA1 садржаја датотеке", - "abusefilter-filter-log": "Скорашње измене филтера", + "abusefilter-edit-builder-vars-file-size": "Величина датотеке у бајтовима", + "abusefilter-edit-builder-vars-file-mime": "MIME тип датотеке", + "abusefilter-edit-builder-vars-file-mediatype": "Медијски тип датотеке", + "abusefilter-edit-builder-vars-file-width": "Ширина датотеке у пикселима", + "abusefilter-edit-builder-vars-file-height": "Висина датотеке у пикселима", + "abusefilter-edit-builder-vars-wiki-name": "Име базе података викија", + "abusefilter-edit-builder-vars-wiki-language": "Језички код викија", + "abusefilter-filter-log": "Скорашње измене филтерâ", "abusefilter-history": "Историја измена филтера #$1", "abusefilter-history-foruser": "Измене од $1", "abusefilter-history-hidden": "Сакривено", @@ -344,7 +391,7 @@ "abusefilter-history-comments": "Коментари", "abusefilter-history-actions": "Радње", "abusefilter-history-backedit": "Назад на уређивање филтера", - "abusefilter-history-deleted": "Обрисано", + "abusefilter-history-deleted": "Избрисано", "abusefilter-history-filterid": "Филтер", "abusefilter-history-select-legend": "Прецизирај претрагу", "abusefilter-history-select-user": "Корисник:", @@ -352,33 +399,33 @@ "abusefilter-history-select-submit": "Прочисти", "abusefilter-history-diff": "Измене", "abusefilter-history-error-hidden": "Филтер који сте тражили је сакривен. Не можете да видите његову историју.", - "abusefilter-exception-unexpectedatend": "Неочекивано „$2“ код знака $1.", + "abusefilter-exception-unexpectedatend": "Неочекивано „$2” код знака $1.", "abusefilter-exception-expectednotfound": "Очекивало се $2 код знака $1, није нађено (уместо тога је пронађено $3 $4).", "abusefilter-exception-unrecognisedkeyword": "Непрепозната кључна реч $2 код знака $1.", - "abusefilter-exception-unexpectedtoken": "Неочекивани токен „$3“ (типа $2) код знака $1.", + "abusefilter-exception-unexpectedtoken": "Неочекивани токен „$3” (типа $2) код знака $1.", "abusefilter-exception-unclosedstring": "Незатворена ниска почиње са знаком $1.", - "abusefilter-exception-invalidoperator": "Неисправан оператор „$2“ код знака $1.", - "abusefilter-exception-unrecognisedtoken": "Непрепознат токен „$2“ код знака $1.", + "abusefilter-exception-invalidoperator": "Неважећи оператор „$2” код знака $1.", + "abusefilter-exception-unrecognisedtoken": "Непрепознат токен „$2” код знака $1.", "abusefilter-exception-noparams": "Нема наведених параметара за функцију „$2” код знака $1.\n{{PLURAL:$3|Очекиван $3 аргумент|Очекивано $3 аргумената}}.", "abusefilter-exception-dividebyzero": "Недозвољен покушај дељења $2 с нулом код знака $1.", "abusefilter-exception-unrecognisedvar": "Непрепозната променљива $2 код знака $1", "abusefilter-exception-notenoughargs": "Недовољно аргумената за функцију $2 позвану на карактеру $1.\n{{PLURAL:$3|Очекивало се аргумената:}} $3, а добијено: $4", - "abusefilter-exception-regexfailure": "Грешка у регуларном изрзу „$3“ код знака $1: „$2“", - "abusefilter-exception-overridebuiltin": "Недозвољено мењање променљиве „$2“ на карактеру $1.", + "abusefilter-exception-regexfailure": "Грешка у регуларном изрзу „$2” код знака $1.", + "abusefilter-exception-overridebuiltin": "Недозвољено мењање променљиве „$2” на карактеру $1.", "abusefilter-exception-outofbounds": "Захтевање непостојеће ставке у низу $2 (величина низа = $3) код знака $1.", "abusefilter-exception-notarray": "Захтевање ставке низа за објекат који није низ код знака $1.", - "abusefilter-action-tag": "означено", + "abusefilter-action-tag": "означи", "abusefilter-action-throttle": "успори", "abusefilter-action-warn": "упозори", "abusefilter-action-blockautopromote": "блокирај самоунапређивање", "abusefilter-action-block": "блокирај", "abusefilter-action-degroup": "уклони из група", - "abusefilter-action-rangeblock": "блокирање распона", + "abusefilter-action-rangeblock": "блокирај распон", "abusefilter-action-disallow": "забрани", - "abusefilter-revert-title": "Врати све измене направљене од филтера $1", + "abusefilter-revert-title": "Врати све измене филтера $1", "abusefilter-revert-intro": "Ово вам омогућава да вратите све измене које је начинио филтер $1.\nБудите пажљиви при коришћењу ове алатке.", "abusefilter-revert-preview-item": "$1: $2 је {{GENDER:$7|направио}} $3 на $4.\nРадње за враћање: $5 ($6)", - "abusefilter-revert-search-legend": "Изабери радње филтера злоупотребе које требају бити враћене", + "abusefilter-revert-search-legend": "Изаберите радње филтера злоупотреба за враћање", "abusefilter-revert-periodstart": "Почетак периода:", "abusefilter-revert-periodend": "Крај периода:", "abusefilter-revert-search": "Изабери радње", @@ -395,23 +442,24 @@ "abusefilter-test-load-filter": "Учитај филтер с назнаком:", "abusefilter-test-submit": "Тестирај", "abusefilter-test-load": "Учитај", - "abusefilter-test-user": "Измене од корисника:", + "abusefilter-test-user": "Корисничко име:", "abusefilter-test-nobots": "Сакриј измене ботова", - "abusefilter-test-period-start": "Измене направљене после:", - "abusefilter-test-period-end": "Измене направљене пре:", + "abusefilter-test-period-start": "Од датума:", + "abusefilter-test-period-end": "До датума:", "abusefilter-test-page": "Измене направљене на страници:", "abusefilter-test-shownegative": "Прикажи измене које не одговарају филтеру", - "abusefilter-test-syntaxerr": "Филтер који сте унели садржи синтаксне грешке.\nДа бисте добили детаљно објашњење кликните на дугме „{{int:abusefilter-edit-check}}“.", - "abusefilter-test-action": "Тип радње:", + "abusefilter-test-syntaxerr": "Филтер који сте унели садржи синтаксне грешке.\nДа бисте добили детаљно објашњење кликните на дугме „{{int:abusefilter-edit-check}}”.", + "abusefilter-test-action": "Врста радње:", "abusefilter-test-search-type-all": "Све радње", "abusefilter-test-search-type-edit": "Измене", + "abusefilter-test-search-type-move": "Премештања", "abusefilter-test-search-type-delete": "Брисања", "abusefilter-test-search-type-upload": "Отпремања", "abusefilter-test-search-type-createaccount": "Отварања налога", "abusefilter-changeslist-examine": "прегледај", - "abusefilter-examine": "Испитај појединачне измене", - "abusefilter-examine-intro": "Ова страница омогућава испитивање променљивих које је генерисао филтер злоупотреба за одређену измену и испробавање на филтерима.", - "abusefilter-examine-legend": "Изаберите промене", + "abusefilter-examine": "Испитивање појединачних измена", + "abusefilter-examine-intro": "Ова страница вам омогућава да испитате променљиве филтера злоупотреба на појединачне измене и да их испробате на филтерима.", + "abusefilter-examine-legend": "Избор измена", "abusefilter-examine-diff": "Адреса разлике:", "abusefilter-examine-user": "Корисник:", "abusefilter-examine-title": "Наслов странице:", @@ -423,35 +471,38 @@ "abusefilter-examine-nomatch": "Ова измена се не поклапа с филтером.", "abusefilter-examine-syntaxerror": "Филтер има неисправну синтаксу", "abusefilter-examine-notfound": "Тражена измена није пронађена.", - "abusefilter-examine-incompatible": "Измена коју сте тражили није подржана од филтера против злоупотребе", + "abusefilter-examine-incompatible": "Тражену измену не подржава филтер злоупотреба", "abusefilter-examine-noresults": "Нису нађени пезултати за параметре претраге које сте задали.", - "abusefilter-topnav": "'''Навигација по филтеру против злоупотребе'''", + "abusefilter-topnav": "'''Навигација'''", "abusefilter-topnav-home": "почетна", + "abusefilter-topnav-recentchanges": "скорашње измене филтерâ", "abusefilter-topnav-test": "групно испробавање", "abusefilter-topnav-examine": "испитај прошле измене", - "abusefilter-topnav-log": "историја злоупотребе", - "abusefilter-topnav-tools": "Алатке за дебаговање", - "abusefilter-topnav-import": "увези филтер", - "abusefilter-log-name": "Дневник филтера злоупотребе", + "abusefilter-topnav-log": "дневник злоупотреба", + "abusefilter-topnav-tools": "отклони грешке", + "abusefilter-log-name": "Дневник филтера злоупотреба", "abusefilter-log-header": "Овде је приказан сажетак измена начињених над филтерима.\nЗа више информација погледајте [[Special:AbuseFilter/history|преглед]] скорашњих измена.", "abusefilter-logentry-create": "$1 је {{GENDER:$2|направио|направила}} $4 ($5)", "abusefilter-logentry-modify": "$1 је {{GENDER:$2|уредио|уредила}} $4 ($5)", "abusefilter-log-noresults": "Нема резултата", - "abusefilter-diff-title": "Разлике између издања", + "abusefilter-diff-title": "Разлике између измена", "abusefilter-diff-item": "Ставка", - "abusefilter-diff-version": "Издање од $1 {{GENDER:$3|од}} $2", + "abusefilter-diff-version": "{{GENDER:$3|Аутор}}: $2; датум: $1", "abusefilter-diff-info": "Основни подаци", "abusefilter-diff-pattern": "Услови филтера", - "abusefilter-diff-invalid": "Не могу да прибавим захтеваног издања", - "abusefilter-diff-backhistory": "Повратак на историју филтера", + "abusefilter-diff-invalid": "Није могуће прибавити тражене измене", + "abusefilter-diff-backhistory": "Назад на историју филтера", "abusefilter-diff-prev": "Старије измене", "abusefilter-diff-next": "Новије измене", "abusefilter-import-intro": "Ово корисничко окружење служи за увоз филтера са других викија.\nНа изворном викију, кликните на „{{int:abusefilter-edit-export}}“ под „{{int:abusefilter-edit-tools}}“ у уређивачком оквиру.\nКопирајте садржај из поља које се појави и налепите га у ово поље, па кликните на „{{int:abusefilter-import-submit}}“.", "abusefilter-import-submit": "Увези податке", + "abusefilter-import-invalid-data": "Подаци које сте покушали да увезете нису важећи", "abusefilter-group-default": "Подразумевано", "abusefilter-http-error": "Дошло је до HTTP грешке: $1.", - "abusefilter-view-private-submit": "Погледај приватне детаље", - "abusefilter-view-private-reason": "Разлог за приступање приватним детаљима:", + "abusefilter-view-privatedetails-submit": "Прикажи приватне детаље", + "abusefilter-view-privatedetails-legend": "Приказ приватних детаља", + "abusefilter-view-privatedetails-reason": "Разлог за приступање приватним детаљима:", + "abusefilter-log-details-id": "ID дневника", "abusefilter-log-ip-not-available": "Недоступно", "tag-abusefilter-condition-limit": "достигнуто условно ограничење" } diff --git a/AbuseFilter/i18n/sr-el.json b/AbuseFilter/i18n/sr-el.json index dd64d2a1..ccce0709 100644 --- a/AbuseFilter/i18n/sr-el.json +++ b/AbuseFilter/i18n/sr-el.json @@ -2,276 +2,379 @@ "@metadata": { "authors": [ "FriedrickMILBarbarossa", + "Kizule", + "Matma Rex", "Michaello", "Milicevic01", + "Obsuser", "Rancher", + "Vlad5250", + "Zoranzoki21", "Михајло Анђелковић", - "Matma Rex", - "Сербијана", - "Obsuser", - "Zoranzoki21" + "Сербијана" ] }, - "abusefilter-desc": "Izvršava automatsko heurističko filtriranje izmena", - "abusefilter": "Postavke filtera protiv zloupotrebe", - "abuselog": "Izveštaj zloupotrebe", - "abusefilter-intro": "Dobro došli u okruženje za upravljanje Filterom protiv zloupotrebe.\nTo je softverski mehanizam koji primenjuje automatsku heuristiku za sve radnje.\nOvo okruženje prikazuje spisak određenih filtera i omogućava vam da ih promenite.", - "abusefilter-warning": "'''Upozorenje''': Automatski filter je prepoznao ovu izmenu kao potencijalno štetnu.\nNekonstruktivne akcije će biti vraćene i mogu da dovedu do zabrane uređivanja.\nUkoliko smatrate da izmena ipak jeste konstruktivna, kliknite još jedanput na dugme „Sačuvaj stranicu“.\nKratak opis pravila zloupotrebe koje ste aktivirali: $1", - "abusefilter-disallowed": "Automatski filter je prepoznao ovu izmenu kao potencijalno štetnu i stoga je nije dozvolio.\nUkoliko smatrate da izmena ipak jeste konstruktivna, obavestite nekog od administratora o tome šta pokušavate da učinite.\nKratak opis povređenog pravila: $1", - "abusefilter-blocked-display": "Automatski filter je prepoznao ovu izmenu kao potencijalno štetnu i nije vam dopušteno da je izvršite.\nOsim toga, da bi se zaštititio/la {{SITENAME}}, vaš nalog i odgovarajuće IP adrese su blokirane.\nUkoliko se ovo dogodilo greškom, kontaktirajte nekog od administratora.\nKratak opis povređenog pravila: $1", - "abusefilter-degrouped": "Automatski filter je prepoznao ovu izmenu kao potencijalno štetnu.\nStoga izmena nije dozvoljena, a uklonjena su vam i sva ovlašćenja koja ste imali. Ukoliko smatrate da je do toga došlo greškom, kontaktirajte nekog od birokrata, objasnite šta ste uradili i ovlašćenja će vam možda biti vraćena.\nKratak opis povređenog pravila: $1", - "abusefilter-autopromote-blocked": "Automatski filter je prepoznao ovu izmenu kao potencijalno štetnu i stoga je nije dozvolio.\nOsim toga, iz predostrožnosti su vam privremeno uklonjena određena ovlašćenja.\nKratak opis povređenog pravila: $1", - "abusefilter-blocker": "Filter protiv zloupotrebe", - "abusefilter-blockreason": "Blokirani ste od strane filtera protiv zloupotrebe.\nOpis povređenog pravila: $1", - "abusefilter-degroupreason": "Filter je automatski uklonio ovlašćenja.\nOpis pravila: $1", - "abusefilter-accountreserved": "Ovo korisničko ime je rezervisano od strane filtera protiv zloupotrebe.", - "right-abusefilter-modify": "uređivanje filtera protiv zloupotrebe", - "right-abusefilter-view": "pregledanje filtera protiv zloupotrebe", - "right-abusefilter-log": "pregledanje izveštaja zloupotrebe", - "right-abusefilter-log-detail": "pregledanje detaljnih podataka u izveštaju zloupotrebe", - "right-abusefilter-private": "pregledanje privatnih podataka u izveštaju zloupotrebe", - "right-abusefilter-modify-restricted": "menjanje filtera zloupotrebe s ograničenim radnjama", - "right-abusefilter-revert": "vraćanje svih izmena koje je napravio filter protiv zloupotrebe", - "right-abusefilter-view-private": "pregledanje privatnih filtera protiv zloupotrebe", - "right-abusefilter-hide-log": "sakrivanje unosa u izveštaju zloupotrebe", - "right-abusefilter-hidden-log": "pregledanje sakrivenih unosa u izveštaju zloupotrebe", - "action-abusefilter-modify": "uređivanje filtera protiv zloupotrebe", - "action-abusefilter-view": "pregledanje filtera protiv zloupotrebe", - "action-abusefilter-log": "pregledanje izveštaja zloupotrebe", - "action-abusefilter-log-detail": "pregledanje detaljnih unosa u izveštaju zloupotrebe", - "action-abusefilter-private": "pregledanje ličnih podataka u izveštaju zloupotrebe", - "action-abusefilter-modify-restricted": "menjanje filtera protiv zloupotrebe s ograničenim radnjama", - "action-abusefilter-revert": "vraćanje svih izmena koje je napravio filter protiv zloupotrebe", - "action-abusefilter-view-private": "pregledanje privatnih filtera protiv zloupotrebe", - "abusefilter-log": "Dnevnik filtera protiv zloupotrebe", - "abusefilter-log-summary": "Ovaj izveštaj prikazuje spisak svih radnji koje su izvršili filteri.", - "abusefilter-log-search": "Pretraga izveštaja zloupotrebe", + "abusefilter-desc": "Primenjuje automatske heuristike izmenama", + "abusefilter": "Upravljanje filterima zloupotreba", + "abuselog": "Dnevnik filterâ zloupotreba", + "abusefilter-intro": "Dobro došli na stranicu za upravljanje filterima zloupotreba!<br />Ovi filteri služe da uspore, upozore ili zabrane izvršenje neželjenih radnji. Ispod možete da ih vidite i menjate.", + "abusefilter-mustviewprivateoredit": "Iz bezbednosnih razloga samo korisnici sa pravom pregleda privatnih filtera zloupotreba ili menjanja filtera mogu da koriste ovo okruženje.", + "abusefilter-warning": "'''Upozorenje''': Ova radnja je automatski prepoznata kao štetna.\nNekonstruktivne radnje će brzo biti vraćene,\na prekomerno ili ponovljeno nekonstruktivno uređivanje može dovesti do blokiranja vašeg naloga ili IP adrese.\nAko smatrate da ova radnja jeste konstruktivna, ponovo podnesite obrazac kako biste je potvrdili.\nKratak opis prekršenog pravila: $1", + "abusefilter-disallowed": "Ova radnja je automatski prepoznata kao štetna, pa nije dozvoljena.\nAko smatrate da izmena jeste konstruktivna, obavestite nekog od administratora o tome šta pokušavate da učinite.\nKratak opis prekršenog pravila: $1", + "abusefilter-blocked-display": "Automatski filter je prepoznao ovu izmenu kao potencijalno štetnu i nije vam dopušteno da je izvršite.\nOsim toga, da bi se zaštitio projekat {{SITENAME}}, vaš nalog i odgovarajuće IP adrese su blokirane.\nAko se ovo dogodilo greškom, obratite se nekom administratoru.\nKratak opis povređenog pravila: $1", + "abusefilter-degrouped": "Ova radnja je automatski prepoznata kao štetna, pa nije dozvoljena.\nBudući da se sumnja da je vaš nalog ugrožen, sva prava su opozvana.\nAko smatrate da je ovo greška, obratite se birokrati s objašnjenjem radnje i prava će vam verovatno biti vraćena.\nKratak opis prekršenog pravila: $1", + "abusefilter-autopromote-blocked": "Ova radnja je automatski prepoznata kao štetna, pa nije dozvoljena.\nOsim toga, iz predostrožnosti su vam privremeno opozvane određene privilegije.\nKratak opis prekršenog pravila: $1", + "abusefilter-blocker": "Filter zloupotreba", + "abusefilter-blockreason": "Filter zloupotreba Vas je automatski blokirao.\nOpis prekršenog pravila: $1", + "abusefilter-degroupreason": "Filter zloupotreba je automatski oduzeo prava.\nOpis pravila: $1", + "abusefilter-blockautopromotereason": "Filter zloupotreba je automatski odložio samounapređivanje.\nOpis pravila: $1", + "abusefilter-accountreserved": "Ovo korisničko ime je rezervisano za filter zloupotreba.", + "right-abusefilter-modify": "pravljenje ili menjanje filterâ zloupotreba", + "right-abusefilter-view": "pregledanje filterâ zloupotreba", + "right-abusefilter-log": "pregledanje dnevnika zloupotreba", + "right-abusefilter-log-detail": "pregledanje detaljnih podataka u dnevniku zloupotreba", + "right-abusefilter-privatedetails": "pregledanje privatnih podataka u dnevniku zloupotreba", + "right-abusefilter-modify-restricted": "menjanje filterâ zloupotreba s ograničenim radnjama", + "right-abusefilter-revert": "vraćanje svih izmena datog filtera zloupotreba", + "right-abusefilter-view-private": "pregledanje filterâ zloupotreba označenih privatnima", + "right-abusefilter-log-private": "pregledanje stavki u dnevniku zloupotreba označenih privatnima", + "right-abusefilter-hide-log": "sakrivanje stavki u dnevniku zloupotreba", + "right-abusefilter-hidden-log": "pregledanje skrivenih stavki u dnevniku zloupotreba", + "right-abusefilter-modify-global": "pravljenje ili menjanje globalnih filtera zloupotreba", + "action-abusefilter-modify": "menjate filtere zloupotreba", + "action-abusefilter-view": "pregledate filtere zloupotreba", + "action-abusefilter-log": "pregledate dnevnik zloupotreba", + "action-abusefilter-log-detail": "pregledate detaljne podatke u dnevniku zloupotreba", + "action-abusefilter-privatedetails": "pregledate privatne podatake u dnevniku zloupotreba", + "action-abusefilter-modify-restricted": "menjate filtere zloupotreba s ograničenim radnjama", + "action-abusefilter-revert": "vratite sve izmene datog filtera zloupotreba", + "action-abusefilter-view-private": "pregledate filtere zloupotreba označene privatnima", + "action-abusefilter-log-private": "pregledanje dnevnika filtera zloupotreba označenih privatnima", + "action-abusefilter-hide-log": "krijete stavke u dnevniku zloupotreba", + "action-abusefilter-hidden-log": "gledate sakrivene stavke u dnevniku zloupotreba", + "action-abusefilter-modify-global": "pravljenje ili menjanje globalnih filtera zloupotreba", + "abusefilter-log-summary": "Ovaj dnevnik prikazuje spisak svih radnji koje su uhvatili filteri.", + "abusefilter-log-search": "Pretraga dnevnika zloupotreba", "abusefilter-log-search-user": "Korisnik:", - "abusefilter-log-search-filter": "ID filtera:", + "abusefilter-log-search-group": "Grupa filtera:", + "abusefilter-log-search-group-any": "Bilo koji", + "abusefilter-log-search-filter": "ID-jevi filtera:", "abusefilter-log-search-title": "Naslov:", - "abusefilter-log-search-wiki": "Viki:", + "abusefilter-log-search-wiki": "Projekat:", + "abusefilter-log-search-impact": "Uticaj:", + "abusefilter-log-search-impact-all": "Sve radnje", + "abusefilter-log-search-impact-saved": "Samo sačuvane izmene", + "abusefilter-log-search-impact-not-saved": "Bez sačuvanih izmena", + "abusefilter-log-search-entries-label": "Vidljivost:", + "abusefilter-log-search-entries-all": "Sve stavke", + "abusefilter-log-search-entries-hidden": "Samo sakrivene stavke", + "abusefilter-log-search-entries-visible": "Samo vidljive stavke", + "abusefilter-log-search-action-label": "Pokrenuta radnja:", + "abusefilter-log-search-action-other": "drugi", + "abusefilter-log-search-action-any": "Bilo koji", + "abusefilter-log-search-action-taken-label": "Preduzeta radnja:", + "abusefilter-log-search-action-taken-any": "Bilo koja", "abusefilter-log-search-submit": "Pretraži", - "abusefilter-log-entry": "$1: $2 je aktivirao filter, izvodeći radnju „$3“ na stranici $4.\nPreduzete radnje: $5;\nOpis filtera: $6", - "abusefilter-log-entry-withdiff": "$1: $2 je aktivirao filter zloupotrebe, izvodeći radnju „$3“ na stranici $4.\nPreduzete radnje: $5;\nOpis filtera: $6 ($7)", - "abusefilter-log-detailedentry-meta": "$1: $2 je aktivirao $3, izvodeći radnju „$4“ na stranici $5.\nPreduzete radnje: $6;\nOpis filtera: $7 ($8)", + "abusefilter-log-entry": "$1: $2 je {{GENDER:$8|aktivirao}} filter {{GENDER:$8|izvodeći}} radnju „$3” na stranici $4.\nPreduzete radnje: $5;\nOpis filtera: $6", + "abusefilter-log-entry-withdiff": "$1: $2 je {{GENDER:$8|aktivirao}} filter zloupotreba {{GENDER:$8|izvodeći}} radnju „$3” na stranici $4.\nPreduzete radnje: $5;\nOpis filtera: $6 ($7)", + "abusefilter-log-detailedentry-meta": "$1: $2 je {{GENDER:$9|aktivirao}} $3 {{GENDER:$9|izvodeći}} radnju „$4” na stranici $5.\nPreduzete radnje: $6;\nOpis filtera: $7 ($8)", "abusefilter-log-detailedentry-global": "globalni filter $1", "abusefilter-log-detailedentry-local": "filter $1", "abusefilter-log-detailslink": "detalji", "abusefilter-log-diff": "razl", "abusefilter-log-hidelink": "podesi vidljivost", - "abusefilter-log-details-legend": "Detalji unosa $1", + "abusefilter-log-details-legend": "Detalji stavke u dnevniku $1", "abusefilter-log-details-var": "Promenljiva", "abusefilter-log-details-val": "Vrednost", "abusefilter-log-details-vars": "Parametri radnje", - "abusefilter-log-details-private": "Privatni podaci", + "abusefilter-log-details-privatedetails": "Privatni detalji dnevnika", "abusefilter-log-details-ip": "Izvorna IP adresa", + "abusefilter-log-details-checkuser": "Proveri korisnika", "abusefilter-log-noactions": "ništa", - "abusefilter-log-details-diff": "Izmene napravljene pri uređivanju", - "abusefilter-log-linkoncontribs": "dnevnik zloupotrebe", - "abusefilter-log-linkoncontribs-text": "Izveštaj zloupotrebe ovog korisnika", - "abusefilter-log-hidden": "(unos je sakriven)", - "abusefilter-log-hidden-implicit": "(skriveno zato što je izmena obrisana)", - "abusefilter-log-cannot-see-details": "Nemate ovlašćenje da vidite detalje ovog unosa.", - "abusefilter-log-details-hidden": "Ne možete da vidite detalje ovog filtera jer su sakriveni.", - "abusefilter-log-hide-legend": "Sakrij unos u izveštaju", - "abusefilter-log-hide-id": "ID unosa:", - "abusefilter-log-hide-hidden": "Sakrij ovaj unos iz javnog prikaza", + "abusefilter-log-details-diff": "Promene napravljene pri uređivanju", + "abusefilter-log-linkoncontribs": "dnevnik zloupotreba", + "abusefilter-log-linkoncontribs-text": "Dnevnik zloupotreba {{GENDER:$1|ovog korisnika|ove korisnice}}", + "abusefilter-log-linkonhistory": "dnevnik zloupotreba", + "abusefilter-log-linkonhistory-text": "Pogledajte dnevnik zloupotreba ove stranice", + "abusefilter-log-linkonundelete": "prikaži dnevnik zloupotreba", + "abusefilter-log-linkonundelete-text": "Prikaži dnevnik zloupotreba ove stranice", + "abusefilter-log-hidden-implicit": "(skriveno jer je izmena izbrisana)", + "abusefilter-log-cannot-see-details": "Nemate dozvolu da vidite detalje ove stavke.", + "abusefilter-log-cannot-see-privatedetails": "Nemate dozvolu da vidite privatne detalje ove stavke.", + "abusefilter-log-nonexistent": "Stavka s navedenim ID-jem ne postoji.", + "abusefilter-log-details-hidden": "Ne možete da vidite detalje ovog filtera jer su sakriveni za javni pregled.", + "abusefilter-log-details-hidden-implicit": "Ne možete da vidite detalje ovog filtera jer su povezane izmene sakrivene za javni pregled.", + "abusefilter-log-hide-legend": "Sakrij stavku u dnevniku", + "abusefilter-log-hide-id": "ID stavke u dnevniku:", + "abusefilter-log-hide-hidden": "Sakrij ovu stavku od javnog pregleda", "abusefilter-log-hide-reason": "Razlog:", - "abusefilter-log-hide-forbidden": "Nemate dozvolu da sakrivate unose u izveštaju zloupotrebe.", - "logentry-abusefilter-hit": "$1 je {{GENDER:$2|aktivirao|aktivirala}} $4, izvodeći radnju „$5“ na stranici $3. Preduzete radnje: $6 ($7)", - "abusefilter-management": "Upravljanje filterom protiv zloupotrebe", + "abusefilter-log-hide-reason-other": "Drugi/dodatni razlog:", + "abusefilter-log-hide-forbidden": "Nemate dozvolu da sakrivate stavke u dnevniku zloupotreba.", + "abusefilter-log-entry-suppress": "$1 je {{GENDER:$2|sakrio|sakrila}} stavku u dnevniku $3", + "logentry-abusefilter-hit": "$1 je {{GENDER:$2|aktivirao|aktivirala}} $4 izvodeći radnju „$5” na stranici $3. Preduzete radnje: $6 ($7)", + "log-action-filter-abusefilter": "Tip promene filtera:", + "log-action-filter-abusefilter-create": "novi filter", + "log-action-filter-abusefilter-modify": "uređivanje filtera", + "log-action-filter-suppress-abuselog": "Sakrivanje dnevnika zloupotreba", + "log-action-filter-rights-blockautopromote": "Blokiranje samounapređivanja", "abusefilter-list": "Svi filteri", "abusefilter-list-id": "ID filtera", + "abusefilter-list-pattern": "Uzorak", "abusefilter-list-status": "Status", "abusefilter-list-public": "Javni opis", - "abusefilter-list-consequences": "Posledice", + "abusefilter-list-consequences": "Mere", "abusefilter-list-visibility": "Vidljivost", - "abusefilter-list-hitcount": "Brojač pogodaka", + "abusefilter-list-hitcount": "Broj pogodaka", "abusefilter-list-edit": "Uredi", "abusefilter-list-details": "Detalji", - "abusefilter-list-limit": "Stavki po stranici:", + "abusefilter-list-limit": "Filtera po stranici:", "abusefilter-list-lastmodified": "Poslednja izmena", "abusefilter-list-group": "Grupa filtera", "abusefilter-hidden": "Privatno", "abusefilter-unhidden": "Javno", - "abusefilter-enabled": "Omogućeno", - "abusefilter-deleted": "Obrisano", - "abusefilter-disabled": "Onemogućeno", + "abusefilter-enabled": "uključen", + "abusefilter-deleted": "Izbrisano", + "abusefilter-disabled": "isključen", + "abusefilter-throttled": "usporeno", "abusefilter-hitcount": "$1 {{PLURAL:$1|pogodak|pogotka|pogodaka}}", - "abusefilter-new": "Napravi novi filter", + "abusefilter-new": "Napravite novi filter", + "abusefilter-import-button": "uvoz filtera", "abusefilter-return": "Nazad na upravljanje filterima", "abusefilter-status-global": "Globalno", "abusefilter-list-options": "Opcije", - "abusefilter-list-options-deleted": "Obrisani filteri:", - "abusefilter-list-options-deleted-only": "Prikaži samo obrisane filtere", - "abusefilter-list-options-deleted-hide": "Sakrij obrisane filtere", - "abusefilter-list-options-deleted-show": "Uključi i obrisane filtere", + "abusefilter-list-options-deleted": "Izbrisani filteri:", + "abusefilter-list-options-deleted-only": "Prikaži samo izbrisane filtere", + "abusefilter-list-options-deleted-hide": "Sakrij izbrisane filtere", + "abusefilter-list-options-deleted-show": "Uključi i izbrisane filtere", "abusefilter-list-options-scope": "Prikaži filtere:", "abusefilter-list-options-scope-local": "Samo lokalna pravila", "abusefilter-list-options-scope-global": "Samo globalna pravila", "abusefilter-list-options-scope-all": "Lokalna i globalna pravila", - "abusefilter-list-options-hidedisabled": "Sakrij onemogućene filtere", + "abusefilter-list-options-further-options": "Dalje opcije:", + "abusefilter-list-options-hidedisabled": "Sakrij isključene filtere", + "abusefilter-list-options-hideprivate": "Sakrij privatne filtere", + "abusefilter-list-options-searchfield": "Pretraživanje unutar pravila:", + "abusefilter-list-options-searchpattern": "Unesite uzorak", + "abusefilter-list-options-searchoptions": "Režim pretrage:", + "abusefilter-list-options-search-like": "obična pretraga", + "abusefilter-list-options-search-rlike": "regularni izraz", + "abusefilter-list-options-search-irlike": "regularni izraz (bez razlikovanja malih i velikih slova)", "abusefilter-list-options-submit": "Ažuriraj", - "abusefilter-tools-text": "Ovde se nalaze alatke koje su korisne za ispravljanje grešaka na filteru protiv zloupotrebe.", + "abusefilter-tools-text": "Ovde se nalaze alatke koje su korisne za sastavljanje i prepravku filterâ zloupotreba.", "abusefilter-tools-expr": "Testiranje filtera", "abusefilter-tools-submitexpr": "Proceni", - "abusefilter-tools-reautoconfirm": "Vrati samopotvrđeni status", + "abusefilter-tools-syntax-error": "Filter ima nevažeću sintaksu.", + "abusefilter-tools-reautoconfirm": "Vrati automatski potvrđen status", "abusefilter-tools-reautoconfirm-user": "Korisnik:", "abusefilter-tools-reautoconfirm-submit": "Potvrdi", "abusefilter-reautoconfirm-none": "Samopotvrđeni status {{GENDER:$1|ovog korisnika|ove korisnice|ovog korisnika}} nikada nije bio ukinut.", "abusefilter-reautoconfirm-notallowed": "Nije vam dozvoljeno da vratite samopotvrđeni status.", "abusefilter-reautoconfirm-done": "Samopotvrđeni status je vraćen", - "abusefilter-status": "Od {{PLURAL:$1|poslednje radnje|poslednje $1 radnje|poslednjih $1 radnji}}, $2 ($3%) {{PLURAL:$2|je dostigla|su dostigle|je dostiglo}} ograničenje od $4, a $5 ($6%) {{PLURAL:$5|se podudara|se podudaraju}} s jednim od trenutno omogućenih filtera.", - "abusefilter-edit": "Uređivanje filtera zloupotrebe", + "abusefilter-status": "Od {{PLURAL:$1|poslednje radnje|poslednje $1 radnje|poslednjih $1 radnji}}, $2 ($3%) {{PLURAL:$2|je dostigla|su dostigle|je dostiglo}} ograničenje od $4, a $5 ($6%) {{PLURAL:$5|se podudara|se podudaraju}} sa najmanje jednim od trenutno omogućenih filtera.", + "abusefilter-edit": "Uređivanje filtera zloupotreba", "abusefilter-edit-subtitle": "Uređujete filter $1", "abusefilter-edit-subtitle-new": "Pravljenje filtera", - "abusefilter-edit-oldwarning": "<strong>Uređujete staro izdanje ovog filtera.\nIskazane statistike su za najnovije izdanje.\nAko sačuvate, obrisaćete sve izmene nastale od izmene koju upravo uređujete.</strong> •\n[[Special:AbuseFilter/history/$2|Nazad na istoriju ovog filtera]].", + "abusefilter-edit-token-not-match": "Izmena nije sačuvana. Sačuvajte je ponovo.", + "abusefilter-edit-oldwarning": "<strong>Uređujete staru verziju ovog filtera.\nIskazane statistike su za najnoviju verziju filtera.\nAko sačuvate izmene, obrisaćete sve izmene nastale od izmene koju upravo uređujete.</strong> •\n[[Special:AbuseFilter/history/$2|Nazad na istoriju ovog filtera]].", "abusefilter-edit-status-label": "Statistike:", - "abusefilter-edit-status": "Od {{PLURAL:$1|1=poslednje radnje|poslednje $1 radnje|poslednjih $1 radnji}}, ovaj filter se poklopio $2 ($3%).", - "abusefilter-edit-status-profile": "Od {{PLURAL:$1|poslednje radnje|poslednje $1 radnje|poslednjih $1 radnji}}, ovaj filter se poklopio $2 ($3%).\nU proseku, njegovo vreme pokretanja je $4 ms, a troši $5 {{PLURAL:$5|uslov|uslova}}.", + "abusefilter-edit-status": "Od {{PLURAL:$1|poslednje radnje|poslednje $1 radnje|poslednjih $1 radnji}}, ovaj filter se poklopio $2 ($3%).\n\nU proseku, njegovo vreme rada je $4 ms, i troši $5 {{PLURAL:$5|uslov|uslova}} ograničenja uslova.", "abusefilter-edit-new": "Novi filter", "abusefilter-edit-save": "Sačuvaj filter", "abusefilter-edit-id": "ID filtera:", + "abusefilter-edit-switch-editor": "Promeni uređivač", "abusefilter-edit-description": "Opis:\n:''(javno vidljivo)''", + "abusefilter-edit-field-description": "opis", "abusefilter-edit-group": "Grupa filtera:", "abusefilter-edit-flags": "Zastavice:", - "abusefilter-edit-enabled": "Omogući ovaj filter", - "abusefilter-edit-deleted": "Označi kao obrisan", + "abusefilter-edit-enabled": "Omogući filter", + "abusefilter-edit-deleted": "Označi izbrisanim", "abusefilter-edit-hidden": "Sakrij detalje ovog filtera iz javnog prikaza", "abusefilter-edit-global": "Globalni filter", "abusefilter-edit-rules": "Uslovi:", + "abusefilter-edit-field-conditions": "uslovi", "abusefilter-edit-notes": "Napomene:", "abusefilter-edit-lastmod": "Poslednja izmena filtera:", - "abusefilter-edit-lastmod-text": "$3, $4 od {{GENDER:$5|korisnika|korisnice|korisnika}} $2", + "abusefilter-edit-lastmod-text": "{{GENDER:$5|autor}}: $2; datum: $3 u $4", "abusefilter-edit-hitcount": "Pogoci filtera:", - "abusefilter-edit-consequences": "Preduzete radnje pri poklapanju", - "abusefilter-edit-action-warn": "Pokreni ove radnje nakon što upozorite korisnika", - "abusefilter-edit-action-disallow": "Spreči korisnika da izvrši dotičnu radnju", - "abusefilter-edit-action-blockautopromote": "Vrati samopotvrđeni status korisnika", + "abusefilter-edit-consequences": "Preduzeti radnje pri poklapanju", + "abusefilter-edit-action-warn": "Upozori korisnika", + "abusefilter-edit-action-disallow": "Zabrani korisniku da izvrši datu radnju", + "abusefilter-edit-action-blockautopromote": "Oduzmi korisniku automatski potvrđen status", "abusefilter-edit-action-degroup": "Ukloni korisnika sa svih ovlašćenih grupa", - "abusefilter-edit-action-block": "Blokiraj korisnika / IP adresu od uređivanja", - "abusefilter-edit-action-throttle": "Pokreni radnje samo ako korisnik pređe ograničenje učestalosti", + "abusefilter-edit-action-block": "Blokiraj korisnika/cu i/ili IP adresu od uređivanja", + "abusefilter-edit-action-throttle": "Uspori korisnika ako pređe ograničenje učestalosti", "abusefilter-edit-action-rangeblock": "Blokiraj /16 opseg IP adresa korisnika", "abusefilter-edit-action-tag": "Označi izmenu za budući pregled", "abusefilter-edit-throttle-count": "Broj dozvoljenih radnji:", - "abusefilter-edit-throttle-period": "Vremenski period:", - "abusefilter-edit-throttle-groups": "Grupno usporavanje prema:\n:''(jedan po redu, zajedno sa zapetama)''", + "abusefilter-edit-throttle-period": "Period (u sekundama):", + "abusefilter-edit-throttle-groups": "Grupno usporavanje prema:", + "abusefilter-edit-throttle-groups-help": "Pogledajte $1.", + "abusefilter-edit-throttle-groups-help-text": "dokumentaciju na sajtu mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Razdelite sa zarezima da biste se pridružili sa AND, ili sa prelomima reda da biste se pridružili sa OR", + "abusefilter-throttle-ip": "IP adresa", + "abusefilter-throttle-user": "korisnički nalog", + "abusefilter-throttle-creationdate": "datum otvaranja naloga", + "abusefilter-throttle-editcount": "broj izmena", + "abusefilter-throttle-site": "ceo sajt", + "abusefilter-throttle-page": "stranica", + "abusefilter-throttle-none": "(ništa)", "abusefilter-edit-warn-message": "Sistemska poruka koja će se koristiti za upozorenje:", "abusefilter-edit-warn-other": "Ostale poruke", - "abusefilter-edit-warn-other-label": "Naziv stranice druge poruke:\n:''(bez prefiksa „Medijaviki“)''", - "abusefilter-edit-warn-actions": "Akcije:", - "abusefilter-edit-warn-preview": "Pregledaj izabranu poruku", + "abusefilter-edit-warn-other-label": "Ime stranice druge poruke:\n:''(bez prefiksa „Medijaviki”)''", + "abusefilter-edit-warn-actions": "Radnje:", + "abusefilter-edit-warn-preview": "Prikaži/sakrij pregled izabrane poruke", "abusefilter-edit-warn-edit": "Napravi/uredi izabranu poruku", - "abusefilter-edit-tag-tag": "Oznake (jedna po redu):", + "abusefilter-edit-disallow-message": "Sistemska poruka koja će se koristiti za upozorenje:", + "abusefilter-edit-disallow-other": "Druge poruke", + "abusefilter-edit-disallow-other-label": "Ime stranice druge poruke:\n:''(bez prefiksa „Medijaviki”)''", + "abusefilter-edit-disallow-actions": "Radnje:", + "abusefilter-edit-disallow-preview": "Prikaži/sakrij pregled izabrane poruke", + "abusefilter-edit-disallow-edit": "Napravi/uredi izabranu poruku", + "abusefilter-edit-tag-tag": "[[Special:Tags|Oznake]] za primenu:", + "abusefilter-edit-tag-hidden-placeholder": "Dodajte oznake (odvojene zarezom)", + "abusefilter-edit-block-anon-durations": "Dužina blokiranja za anonimne korisnike:", + "abusefilter-edit-block-user-durations": "Trajanje blokiranja registrovanih korisnika:", + "abusefilter-block-anon": "Blokiraj anonimne korisnike", + "abusefilter-block-user": "blokiraj registrovane korisnike", + "abusefilter-block-talk": "blokirana stranica za razgovor", "abusefilter-edit-denied": "Ne možete videti detalje ovog filtera jer je sakriven iz javnog prikaza.", "abusefilter-edit-main": "Parametri filtera", - "abusefilter-edit-done-subtitle": "Filter izmenjen", - "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Vaše izmene]] [[Special:AbuseFilter/$1|filtera $3]] su sačuvane.", + "abusefilter-edit-done-subtitle": "Filter je uređen", + "abusefilter-edit-done": "[[Special:AbuseFilter/history/$1/diff/prev/$2|Vaše promene]] [[Special:AbuseFilter/$1|filtera $3]] su sačuvane.", "abusefilter-edit-badsyntax": "Navedeni filter ima sintaksnu grešku.\nIzlaz iz raščlanjivača bio je: <pre>$1</pre>", "abusefilter-edit-restricted": "Ne možete uređivati ovaj filter jer sadrži jednu ili više ograničenih radnji.\nZamolite korisnika s određenim ovlašćenjem da napravi izmene umesto vas.", - "abusefilter-edit-viewhistory": "Pogledaj istoriju filtera", + "abusefilter-edit-viewhistory": "Prikaži istoriju filtera", "abusefilter-edit-history": "Istorija:", - "abusefilter-edit-check": "Proveri sitaksu", + "abusefilter-edit-check": "Proveri sintaksu", "abusefilter-edit-badfilter": "Navedeni filter ne postoji", "abusefilter-edit-revert": "Vraćanja koja je izvršio ovaj filter", - "abusefilter-edit-tools": "Alati:", + "abusefilter-edit-tools": "Alatke:", "abusefilter-edit-test-link": "Testiraj ovaj filter na skorašnjim izmenama", "abusefilter-edit-export": "Izvezi ovaj filter na drugi viki", "abusefilter-edit-syntaxok": "Nema sintaksnih grešaka.", - "abusefilter-edit-syntaxerr": "Otkrivena je sintaksna greška: $1", - "abusefilter-edit-bad-tags": "Jedna ili više oznaka koje ste naveli nisu validne.\nOznaka mora biti kratka i ne bi trebala imati specijalne karaktere.", - "abusefilter-edit-notallowed": "Nije vam dozvoljeno da pravite ili uređujete filtere protiv zloupotrebe", - "abusefilter-edit-notallowed-global": "Nije vam dozvoljeno da pravite ili uređujete globalne filtere protiv zloupotrebe", - "abusefilter-edit-builder-select": "Izaberite opciju koju ćete dodati kursoru", - "abusefilter-edit-builder-group-op-arithmetic": "Aritmetičke operacije", + "abusefilter-edit-syntaxerr": "Otkrivena je sintaktička greška: $1", + "abusefilter-edit-bad-tags": "Jedna ili više oznaka koje ste naveli nisu validne.\nOznaka mora biti kratka i ne sme sadržati specijalne karaktere, i oni ne smeju biti korišćeni od strane drugog softvera. Pokušajte sa biranjem nove oznake.", + "abusefilter-edit-notallowed": "Nije vam dozvoljeno da pravite ili uređujete filtere zloupotreba", + "abusefilter-edit-notallowed-global": "Nije vam dozvoljeno da pravite ili uređujete globalne filtere zloupotreba", + "abusefilter-edit-invalid-throttlecount": "Broj radnji regulatora mora da bude pozitivan ceo broj.", + "abusefilter-edit-invalid-throttleperiod": "Period regulatora mora da bude pozitivan ceo broj.", + "abusefilter-edit-empty-throttlegroups": "Mora se izabrati najmanje jedna grupa regulatora.", + "abusefilter-edit-duplicated-throttlegroups": "Grupe regulatora ne mogu imati duplikate.", + "abusefilter-edit-invalid-throttlegroups": "Navedena grupa regulatora nije važeća.", + "abusefilter-edit-builder-select": "Izaberite opciju da biste je dodali u okvir uređivanja", + "abusefilter-edit-builder-group-op-arithmetic": "Aritmetički operatori", "abusefilter-edit-builder-op-arithmetic-addition": "Sabiranje (+)", "abusefilter-edit-builder-op-arithmetic-subtraction": "Oduzimanje (-)", "abusefilter-edit-builder-op-arithmetic-multiplication": "Množenje (*)", "abusefilter-edit-builder-op-arithmetic-divide": "Deljenje (/)", "abusefilter-edit-builder-op-arithmetic-modulo": "Modul (%)", "abusefilter-edit-builder-op-arithmetic-pow": "Stepenovanje (**)", - "abusefilter-edit-builder-group-op-comparison": "Operatori poređenja", - "abusefilter-edit-builder-op-comparison-equal": "Jednako (==)", - "abusefilter-edit-builder-op-comparison-notequal": "Nejednako (!=)", - "abusefilter-edit-builder-op-comparison-lt": "Manje (<)", - "abusefilter-edit-builder-op-comparison-gt": "Veće (>)", - "abusefilter-edit-builder-op-comparison-lte": "Manje ili jednako (<=)", - "abusefilter-edit-builder-op-comparison-gte": "Veće ili jednako (>=)", - "abusefilter-edit-builder-group-op-bool": "Bulove operacije", + "abusefilter-edit-builder-group-op-comparison": "Operatori za poređenje", + "abusefilter-edit-builder-op-comparison-equal": "Vrednost jednaka sa (==)", + "abusefilter-edit-builder-op-comparison-notequal": "Vrednost nije jednaka sa (!=)", + "abusefilter-edit-builder-op-comparison-lt": "Manje od (<)", + "abusefilter-edit-builder-op-comparison-gt": "Veće od (>)", + "abusefilter-edit-builder-op-comparison-lte": "Manje ili jednako sa (<=)", + "abusefilter-edit-builder-op-comparison-gte": "Veće ili jednako sa (>=)", + "abusefilter-edit-builder-group-op-bool": "Bulovi operatori", "abusefilter-edit-builder-op-bool-not": "Ne (!)", "abusefilter-edit-builder-op-bool-and": "I (&)", "abusefilter-edit-builder-op-bool-or": "Ili (|)", "abusefilter-edit-builder-op-bool-xor": "EKSILI (^)", "abusefilter-edit-builder-group-misc": "Razno", "abusefilter-edit-builder-misc-in": "sadržano u niski (in)", - "abusefilter-edit-builder-misc-like": "Odgovara obrazcu (like)", + "abusefilter-edit-builder-misc-like": "Odgovara obrascu (like)", "abusefilter-edit-builder-misc-rlike": "Odgovara regularnom izrazu (rlike)", "abusefilter-edit-builder-misc-irlike": "Odgovara regularnom izrazu, bez razlikovanja malih i velikih slova (irlike)", - "abusefilter-edit-builder-misc-contains": "Levi string sadrži desni string (contains)", - "abusefilter-edit-builder-misc-stringlit": "String literal (\"\")", - "abusefilter-edit-builder-misc-tern": "Ternarni operator (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Uslov (if X then Y else Z)", + "abusefilter-edit-builder-misc-contains": "Leva niska sadrži desnu nisku (contains)", + "abusefilter-edit-builder-misc-stringlit": "Bukvalan izraz u niski (\"\")", + "abusefilter-edit-builder-misc-tern": "Trinarni operator (X ? Y : Z)", + "abusefilter-edit-builder-misc-cond": "Uslov (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "Kratki uslov (if X then Y end)", "abusefilter-edit-builder-group-funcs": "Funkcije", - "abusefilter-edit-builder-funcs-length": "Dužina stringa (length)", - "abusefilter-edit-builder-funcs-lcase": "Prebacivanje u mala slova (lcase)", - "abusefilter-edit-builder-funcs-ccnorm": "Normaolzuj zbunjujuće karaktere (ccnorm)", - "abusefilter-edit-builder-funcs-rmdoubles": "Obriši duple karaktere (rmdoubles)", - "abusefilter-edit-builder-funcs-specialratio": "Specijalni karakteri / ukupnom broju karaktera (specialratio)", + "abusefilter-edit-builder-funcs-length": "Dužina niske (length)", + "abusefilter-edit-builder-funcs-lcase": "Malim slovima (lcase)", + "abusefilter-edit-builder-funcs-ucase": "Velikim slovima (ucase)", + "abusefilter-edit-builder-funcs-ccnorm": "Normalizuj znake podložne zabuni (ccnorm)", + "abusefilter-edit-builder-funcs-rmdoubles": "Ukloni ponovljene znakove (rmdoubles)", + "abusefilter-edit-builder-funcs-specialratio": "Posebni znakovi / ukupno znakova (specialratio)", "abusefilter-edit-builder-funcs-norm": "Normalizuj (norm)", - "abusefilter-edit-builder-funcs-count": "Koliko puta se string X javlja u stringu Y (count)", - "abusefilter-edit-builder-funcs-rcount": "Koliko puta se regularni izraz X javlja u stringu Y (rcount)", - "abusefilter-edit-builder-funcs-rmwhitespace": "Izbriši praznine (rmwhitespace)", - "abusefilter-edit-builder-funcs-rmspecials": "Izbriši specijalne karaktere (rmspecials)", + "abusefilter-edit-builder-funcs-count": "Broj javljanja niske X u nisci Y (count)", + "abusefilter-edit-builder-funcs-rcount": "Broj javljanja regularnog izraza X u nisci Y (rcount)", + "abusefilter-edit-builder-funcs-rmwhitespace": "Ukloni razmake (rmwhitespace)", + "abusefilter-edit-builder-funcs-rmspecials": "Ukloni posebne znakove (rmspecials)", "abusefilter-edit-builder-funcs-ip_in_range": "Da li je IP u opsegu? (ip_in_range)", - "abusefilter-edit-builder-funcs-contains-any": "Pretraži string na više podstringova (contains_any)", - "abusefilter-edit-builder-funcs-substr": "Podstring (substr)", - "abusefilter-edit-builder-funcs-strpos": "Mesto podstringa u stringu (strpos)", - "abusefilter-edit-builder-funcs-str_replace": "Zameni podstring nekim stringom (str_replace)", + "abusefilter-edit-builder-funcs-contains-any": "Pretraži nisku za više podniski u OR režimu. (contains_any)", + "abusefilter-edit-builder-funcs-substr": "Podniska (substr)", + "abusefilter-edit-builder-funcs-strpos": "Položaj podniske u nisci (strpos)", + "abusefilter-edit-builder-funcs-str_replace": "Zameni podnisku s niskom (str_replace)", "abusefilter-edit-builder-funcs-rescape": "Izbegni bukvalne niske u regeksu (rescape)", "abusefilter-edit-builder-funcs-set_var": "Postavi promenljivu (set_var)", "abusefilter-edit-builder-group-vars": "Promenljive", - "abusefilter-edit-builder-vars-accountname": "Naziv naloga (u trenutku otvaranja)", + "abusefilter-edit-builder-vars-accountname": "Ime naloga (u trenutku otvaranja)", + "abusefilter-edit-builder-vars-timestamp": "Juniksov vremenski potpis izmene", + "abusefilter-edit-builder-vars-timestamp-expanded": "Vremenska oznaka dnevnika", "abusefilter-edit-builder-vars-action": "Radnja", - "abusefilter-edit-builder-vars-addedlines": "Linija dodatih pri izmeni", - "abusefilter-edit-builder-vars-delta": "Promena veličine pri izmeni", - "abusefilter-edit-builder-vars-newsize": "Veličina nove strane", - "abusefilter-edit-builder-vars-oldsize": "Veličina stare strane", - "abusefilter-edit-builder-vars-removedlines": "Linije uklonjene tokom izmene", + "abusefilter-edit-builder-vars-addedlines": "Dodati redovi u izmeni", + "abusefilter-edit-builder-vars-delta": "Promena veličine u izmeni", + "abusefilter-edit-builder-vars-newsize": "Nova veličina stranice", + "abusefilter-edit-builder-vars-oldsize": "Stara veličina stranice", + "abusefilter-edit-builder-vars-old-content-model": "Stari model sadržaja", + "abusefilter-edit-builder-vars-new-content-model": "Novi model sadržaja", + "abusefilter-edit-builder-vars-removedlines": "Uklonjeni redovi u izmeni", "abusefilter-edit-builder-vars-summary": "Opis/razlog izmene", "abusefilter-edit-builder-vars-page-id": "ID stranice", "abusefilter-edit-builder-vars-page-ns": "Imenski prostor stranice", "abusefilter-edit-builder-vars-page-title": "Naslov stranice (bez imenskog prostora)", "abusefilter-edit-builder-vars-page-prefixedtitle": "Pun naslov stranice", + "abusefilter-edit-builder-vars-page-age": "Starost stranice (u sekundama)", "abusefilter-edit-builder-vars-movedfrom-id": "ID izvorne stranice premeštanja", "abusefilter-edit-builder-vars-movedfrom-ns": "Imenski prostor premeštene stranice", "abusefilter-edit-builder-vars-movedfrom-title": "Naslov stranice koju premeštate", "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "Pun naslov stranice koju premeštate", + "abusefilter-edit-builder-vars-movedfrom-age": "Premesti starost izvorne stranice (u sekundama)", "abusefilter-edit-builder-vars-movedto-id": "ID odredišne stranice premeštanja", "abusefilter-edit-builder-vars-movedto-ns": "Imenski prostor odredišne stranice", "abusefilter-edit-builder-vars-movedto-title": "Naslov odredišne stranice", "abusefilter-edit-builder-vars-movedto-prefixedtitle": "Pun naslov odredišne stranice", - "abusefilter-edit-builder-vars-user-editcount": "Korisički brojač izmena", + "abusefilter-edit-builder-vars-movedto-age": "Premesti starost odredišne stranice (u sekundama)", + "abusefilter-edit-builder-vars-user-editcount": "Brojač korisničkih izmena", "abusefilter-edit-builder-vars-user-age": "Starost korisničkog naloga", - "abusefilter-edit-builder-vars-user-name": "Naziv korisničkog naloga", + "abusefilter-edit-builder-vars-user-name": "Ime korisničkog naloga", "abusefilter-edit-builder-vars-user-groups": "Grupe (uključujući posredne) u kojima je korisnik", "abusefilter-edit-builder-vars-user-rights": "Prava koja korisnik ima", "abusefilter-edit-builder-vars-user-emailconfirm": "Vreme kada je imejl adresa potvrđena", - "abusefilter-edit-builder-vars-recent-contributors": "Poslednjih deset korisnika, koji su doprineli strani", + "abusefilter-edit-builder-vars-recent-contributors": "Poslednjih deset urednika stranice", + "abusefilter-edit-builder-vars-first-contributor": "Prvi urednik stranice", + "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "Poslednjih deset urednika izvorne stranice premeštanja", + "abusefilter-edit-builder-vars-movedfrom-first-contributor": "Prvi urednik izvorne stranice premeštanja", + "abusefilter-edit-builder-vars-movedto-recent-contributors": "Poslednjih deset urednika odredišne stranice premeštanja", + "abusefilter-edit-builder-vars-movedto-first-contributor": "Prvi urednik odredišne stranice premeštanja", "abusefilter-edit-builder-vars-all-links": "Sve spoljašnje veze u novom tekstu", "abusefilter-edit-builder-vars-added-links": "Sve spoljašnje veze dodate u izmeni", "abusefilter-edit-builder-vars-removed-links": "Sve spoljašnje veze uklonjene u izmeni", - "abusefilter-edit-builder-vars-old-text": "Stari vikitekst pre izmene (nije više u upotrebi)", - "abusefilter-edit-builder-vars-new-text": "Novi vikitekst posle izmene", - "abusefilter-edit-builder-vars-new-text-stripped": "Tekst nove stranice, bez ikakvih obeležavanja", + "abusefilter-edit-builder-vars-old-wikitext": "Stari vikitekst stranice pre izmene", + "abusefilter-edit-builder-vars-new-wikitext": "Novi vikitekst stranice posle izmene", + "abusefilter-edit-builder-vars-addedlines-pst": "Linije dodane u uređivanju, transformirane u nesačuvane", + "abusefilter-edit-builder-vars-new-text": "Tekst nove stranice, bez ikakvih obeležavanja", "abusefilter-edit-builder-vars-new-html": "Raščlanjeni HTML izvor nove izmene", "abusefilter-edit-builder-vars-restrictions-edit": "Stepen zaštite stranice (uređivanje)", "abusefilter-edit-builder-vars-restrictions-move": "Stepen zaštite stranice (premeštanje)", - "abusefilter-edit-builder-vars-old-text-stripped": "Tekst stare stranice, bez ikakvih obeležavanja", + "abusefilter-edit-builder-vars-restrictions-create": "Zaštita od pravljenja stranice", + "abusefilter-edit-builder-vars-restrictions-upload": "Zaštita za otpremanje datoteke", + "abusefilter-edit-builder-vars-old-text": "Tekst stare stranice, sa odstranjenim naznakama (nije više u upotrebi)", "abusefilter-edit-builder-vars-old-links": "Veze na stranici, pre uređivanja", "abusefilter-edit-builder-vars-old-html": "Vikitekst stare stranice, raščlanjen u HTML (nije više u upotrebi)", - "abusefilter-edit-builder-vars-minor-edit": "Da li je izmena bila označena kao mala", + "abusefilter-edit-builder-vars-minor-edit": "Da li je izmena bila označena kao manja (nije više u upotrebi)", "abusefilter-edit-builder-vars-file-sha1": "Disperzija SHA1 sadržaja datoteke", - "abusefilter-filter-log": "Skorašnje izmene filtera", + "abusefilter-edit-builder-vars-file-size": "Veličina datoteke u bajtovima", + "abusefilter-edit-builder-vars-file-mime": "MIME tip datoteke", + "abusefilter-edit-builder-vars-file-mediatype": "Medijski tip datoteke", + "abusefilter-edit-builder-vars-file-width": "Širina datoteke u pikselima", + "abusefilter-edit-builder-vars-file-height": "Visina datoteke u pikselima", + "abusefilter-edit-builder-vars-wiki-name": "Ime baze podataka vikija", + "abusefilter-edit-builder-vars-wiki-language": "Jezički kod vikija", + "abusefilter-filter-log": "Skorašnje izmene filterâ", "abusefilter-history": "Istorija izmena filtera #$1", "abusefilter-history-foruser": "Izmene od $1", "abusefilter-history-hidden": "Sakriveno", @@ -280,104 +383,123 @@ "abusefilter-history-timestamp": "Vreme", "abusefilter-history-user": "Korisnik", "abusefilter-history-public": "Javni opis filtera", - "abusefilter-history-flags": "Zastavice", + "abusefilter-history-flags": "Oznake", "abusefilter-history-filter": "Pravilo filtera", "abusefilter-history-comments": "Komentari", "abusefilter-history-actions": "Radnje", - "abusefilter-history-backedit": "Povratak na editor filtera", - "abusefilter-history-deleted": "Obrisano", + "abusefilter-history-backedit": "Nazad na uređivanje filtera", + "abusefilter-history-deleted": "Izbrisano", "abusefilter-history-filterid": "Filter", - "abusefilter-history-select-legend": "Profini pretragu", + "abusefilter-history-select-legend": "Preciziraj pretragu", "abusefilter-history-select-user": "Korisnik:", - "abusefilter-history-select-submit": "Profini", + "abusefilter-history-select-filter": "ID filtera:", + "abusefilter-history-select-submit": "Pročisti", "abusefilter-history-diff": "Izmene", - "abusefilter-history-error-hidden": "Filter koga ste tražili je sakriven, i Vi ne možete videti njegovu istoriju.", - "abusefilter-exception-unexpectedatend": "Neočekivano \"$2\" na karakteru $1.", - "abusefilter-exception-expectednotfound": "Očekuje se $2 na karakteru $1, nije pronađen (umesto toga nađeno $3 $4).", - "abusefilter-exception-unrecognisedkeyword": "Nepoznata ključna reč $2 na karakteru $1.", - "abusefilter-exception-unexpectedtoken": "Neočekivani žeton „$3“ (od vrste $2) kod znaka $1.", - "abusefilter-exception-unclosedstring": "Nezatvoren string počinje na karakteru $1.", - "abusefilter-exception-invalidoperator": "Neispravan operator \"$2\" na karakteru $1.", - "abusefilter-exception-unrecognisedtoken": "Neprepoznati žeton „$2“ kod znaka $1.", - "abusefilter-exception-noparams": "Nema navedenih parametara za funkciju „$2“ kod znaka $1.", - "abusefilter-exception-dividebyzero": "Nedozvoljen pokušaj deljenja $2 nulom, na karakteru $1.", - "abusefilter-exception-unrecognisedvar": "Nepoznata promenljiva $2 na karakteru $1", + "abusefilter-history-error-hidden": "Filter koji ste tražili je sakriven. Ne možete da vidite njegovu istoriju.", + "abusefilter-exception-unexpectedatend": "Neočekivano „$2” kod znaka $1.", + "abusefilter-exception-expectednotfound": "Očekivalo se $2 kod znaka $1, nije nađeno (umesto toga je pronađeno $3 $4).", + "abusefilter-exception-unrecognisedkeyword": "Neprepoznata ključna reč $2 kod znaka $1.", + "abusefilter-exception-unexpectedtoken": "Neočekivani token „$3” (tipa $2) kod znaka $1.", + "abusefilter-exception-unclosedstring": "Nezatvorena niska počinje sa znakom $1.", + "abusefilter-exception-invalidoperator": "Nevažeći operator „$2” kod znaka $1.", + "abusefilter-exception-unrecognisedtoken": "Neprepoznat token „$2” kod znaka $1.", + "abusefilter-exception-noparams": "Nema navedenih parametara za funkciju „$2” kod znaka $1.\n{{PLURAL:$3|Očekivan $3 argument|Očekivano $3 argumenata}}.", + "abusefilter-exception-dividebyzero": "Nedozvoljen pokušaj deljenja $2 s nulom kod znaka $1.", + "abusefilter-exception-unrecognisedvar": "Neprepoznata promenljiva $2 kod znaka $1", "abusefilter-exception-notenoughargs": "Nedovoljno argumenata za funkciju $2 pozvanu na karakteru $1.\n{{PLURAL:$3|Očekivalo se argumenata:}} $3, a dobijeno: $4", - "abusefilter-exception-regexfailure": "Greška u regularnom izrzu \"$3\" na karakteru $1: \"$2\"", - "abusefilter-exception-overridebuiltin": "Nedozvoljeno menjanje promenljive „$2“ na karakteru $1.", - "abusefilter-exception-outofbounds": "Zahtevanje nepostojećeg elementa spiska $2 (veličina spiska = $3) na karakteru $1.", - "abusefilter-exception-notarray": "Zahtevanje člana niza od nečega što nije niz, na karakteru $1.", - "abusefilter-action-tag": "označeno", + "abusefilter-exception-regexfailure": "Greška u regularnom izrzu „$2” kod znaka $1.", + "abusefilter-exception-overridebuiltin": "Nedozvoljeno menjanje promenljive „$2” na karakteru $1.", + "abusefilter-exception-outofbounds": "Zahtevanje nepostojeće stavke u nizu $2 (veličina niza = $3) kod znaka $1.", + "abusefilter-exception-notarray": "Zahtevanje stavke niza za objekat koji nije niz kod znaka $1.", + "abusefilter-action-tag": "označi", "abusefilter-action-throttle": "uspori", "abusefilter-action-warn": "upozori", "abusefilter-action-blockautopromote": "blokiraj samounapređivanje", "abusefilter-action-block": "blokiraj", "abusefilter-action-degroup": "ukloni iz grupa", - "abusefilter-action-rangeblock": "blokiranje raspona", + "abusefilter-action-rangeblock": "blokiraj raspon", "abusefilter-action-disallow": "zabrani", - "abusefilter-revert-title": "Vrati sve izmene po filteru $1", + "abusefilter-revert-title": "Vrati sve izmene filtera $1", "abusefilter-revert-intro": "Ovo vam omogućava da vratite sve izmene koje je načinio filter $1.\nBudite pažljivi pri korišćenju ove alatke.", - "abusefilter-revert-preview-item": "$1: $2 je napravio $3 na $4.\nRadnje za vraćanje: $5 ($6)", - "abusefilter-revert-search-legend": "Izaberi radnje filtera zloupotrebe koje trebaju biti vraćene", + "abusefilter-revert-preview-item": "$1: $2 je {{GENDER:$7|napravio}} $3 na $4.\nRadnje za vraćanje: $5 ($6)", + "abusefilter-revert-search-legend": "Izaberite radnje filtera zloupotreba za vraćanje", "abusefilter-revert-periodstart": "Početak perioda:", "abusefilter-revert-periodend": "Kraj perioda:", - "abusefilter-revert-search": "Izaberi akcije", - "abusefilter-revert-filter": "Filter:", + "abusefilter-revert-search": "Izaberi radnje", + "abusefilter-revert-filter": "ID filtera:", "abusefilter-revert-preview-intro": "Ispod su prikazane radnje koje će biti vraćene.\nPažljivo ih proverite i kliknite na opciju „potvrdi“ da biste potvrdili svoj izbor.", + "abusefilter-revert-confirm-legend": "Potvrdi vraćanje", "abusefilter-revert-confirm": "Potvrdi", "abusefilter-revert-success": "Vratili ste sve radnje koje je preuzeo filter za uređivanje zbog [[Special:AbuseFilter/$1|filtera $2]].", "abusefilter-revert-reason": "Automatsko vraćanje svih radnji koje je načinio filter $1.\nRazlog: $2", "abusefilter-revert-reasonfield": "Razlog:", - "abusefilter-test": "Testiraj filter na prethodne izmene", + "abusefilter-test": "Testiraj filter prema prethodnim izmenama", "abusefilter-test-intro": "Ova stranica vam omogućava da proverite filter iz donje kutijice na {{PLURAL:$1|poslednju $1 izmenu|poslednje $1 izmene|poslednjih $1 izmena}}.\nDa biste učitali postojeći filter, unesite njegov ID u kutijicu ispod polja za uređivanje i klinkite na dugme „Učitaj“.", "abusefilter-test-legend": "Testiranje filtera", - "abusefilter-test-load-filter": "Učitaj ID filtera:", - "abusefilter-test-submit": "Test", + "abusefilter-test-load-filter": "Učitaj filter s naznakom:", + "abusefilter-test-submit": "Testiraj", "abusefilter-test-load": "Učitaj", - "abusefilter-test-user": "Izmene koje je napravio korisnik:", - "abusefilter-test-period-start": "Izmene posle:", - "abusefilter-test-period-end": "Izmene pre:", - "abusefilter-test-page": "Izmene nad stranom:", - "abusefilter-test-shownegative": "Pokaži izmene koje ne odgovaraju filteru", - "abusefilter-test-syntaxerr": "Filter koji ste uneli sadrži sintaksne greške.\nDa biste dobili detaljno objašnjenje kliknite na dugme „{{int:abusefilter-edit-check}}“.", + "abusefilter-test-user": "Korisničko ime:", + "abusefilter-test-nobots": "Sakrij izmene botova", + "abusefilter-test-period-start": "Od datuma:", + "abusefilter-test-period-end": "Do datuma:", + "abusefilter-test-page": "Izmene napravljene na stranici:", + "abusefilter-test-shownegative": "Prikaži izmene koje ne odgovaraju filteru", + "abusefilter-test-syntaxerr": "Filter koji ste uneli sadrži sintaksne greške.\nDa biste dobili detaljno objašnjenje kliknite na dugme „{{int:abusefilter-edit-check}}”.", + "abusefilter-test-action": "Tip radnje:", + "abusefilter-test-search-type-all": "Sve radnje", + "abusefilter-test-search-type-edit": "Izmene", + "abusefilter-test-search-type-move": "Premeštanja", + "abusefilter-test-search-type-delete": "Brisanja", + "abusefilter-test-search-type-upload": "Otpremanja", + "abusefilter-test-search-type-createaccount": "Otvaranja naloga", "abusefilter-changeslist-examine": "pregledaj", - "abusefilter-examine": "Ispitaj pojedinačne izmene", - "abusefilter-examine-intro": "Ova stranica omogućava ispitivanje promenljivih koje je generisao filter zloupotreba za određenu izmenu i isprobavanje na filterima.", - "abusefilter-examine-legend": "Izaberi izmene", - "abusefilter-examine-diff": "URL difa:", + "abusefilter-examine": "Ispitivanje pojedinačnih izmena", + "abusefilter-examine-intro": "Ova stranica vam omogućava da ispitate promenljive filtera zloupotreba na pojedinačne izmene i da ih isprobate na filterima.", + "abusefilter-examine-legend": "Izbor izmena", + "abusefilter-examine-diff": "Adresa razlike:", "abusefilter-examine-user": "Korisnik:", - "abusefilter-examine-title": "Naslov strane:", - "abusefilter-examine-submit": "Pretraga", + "abusefilter-examine-title": "Naslov stranice:", + "abusefilter-examine-submit": "Pretraži", "abusefilter-examine-vars": "Generisane promenljive za ovu izmenu", - "abusefilter-examine-test": "Testiraj ovu izmenu na filter", + "abusefilter-examine-test": "Testiraj ovu izmenu s filterom", "abusefilter-examine-test-button": "Testiraj filter", - "abusefilter-examine-match": "Filter je odgovarao ovoj izmeni.", - "abusefilter-examine-nomatch": "Filter nije odgovarao ovoj izmeni.", + "abusefilter-examine-match": "Ova izmena se poklapa s filterom.", + "abusefilter-examine-nomatch": "Ova izmena se ne poklapa s filterom.", "abusefilter-examine-syntaxerror": "Filter ima neispravnu sintaksu", - "abusefilter-examine-notfound": "Izmena koju ste zatražili nije nađena.", - "abusefilter-examine-incompatible": "Izmena koju ste tražili nije podržana od filtera protiv zloupotrebe", + "abusefilter-examine-notfound": "Tražena izmena nije pronađena.", + "abusefilter-examine-incompatible": "Traženu izmenu ne podržava filter zloupotreba", "abusefilter-examine-noresults": "Nisu nađeni pezultati za parametre pretrage koje ste zadali.", - "abusefilter-topnav": "'''Navigacija po filteru protiv zloupotrebe'''", + "abusefilter-topnav": "'''Navigacija'''", "abusefilter-topnav-home": "početna", + "abusefilter-topnav-recentchanges": "skorašnje izmene filterâ", "abusefilter-topnav-test": "grupno isprobavanje", - "abusefilter-topnav-examine": "ispitaj prošle izmene", - "abusefilter-topnav-log": "istorija zloupotrebe", - "abusefilter-topnav-tools": "alati za debagovanje", - "abusefilter-topnav-import": "uvezi filter", - "abusefilter-log-name": "Dnevnik filtera protiv zloupotrebe", + "abusefilter-topnav-examine": "ispitivanje prošlih izmena", + "abusefilter-topnav-log": "dnevnik zloupotreba", + "abusefilter-topnav-tools": "otklanjanje grešaka", + "abusefilter-log-name": "Dnevnik filtera zloupotreba", "abusefilter-log-header": "Ovde je prikazan sažetak izmena načinjenih nad filterima.\nZa više informacija pogledajte [[Special:AbuseFilter/history|pregled]] skorašnjih izmena.", + "abusefilter-logentry-create": "$1 je {{GENDER:$2|napravio|napravila}} $4 ($5)", + "abusefilter-logentry-modify": "$1 je {{GENDER:$2|uredio|uredila}} $4 ($5)", "abusefilter-log-noresults": "Nema rezultata", - "abusefilter-diff-title": "Razlike između verzija", + "abusefilter-diff-title": "Razlike između izmena", "abusefilter-diff-item": "Stavka", - "abusefilter-diff-version": "Verzija od $1 {{GENDER:$3|od}} $2", - "abusefilter-diff-info": "Osnovne infomacije", + "abusefilter-diff-version": "{{GENDER:$3|Autor}}: $2; datum: $1", + "abusefilter-diff-info": "Osnovni podaci", "abusefilter-diff-pattern": "Uslovi filtera", - "abusefilter-diff-invalid": "Ne mogu da pribavim zahtevane verzije", - "abusefilter-diff-backhistory": "Povratak na istoriju filtera", + "abusefilter-diff-invalid": "Nije moguće pribaviti tražene izmene", + "abusefilter-diff-backhistory": "Nazad na istoriju filtera", "abusefilter-diff-prev": "Starije izmene", "abusefilter-diff-next": "Novije izmene", "abusefilter-import-intro": "Ovo korisničko okruženje služi za uvoz filtera sa drugih vikija.\nNa izvornom vikiju, kliknite na „{{int:abusefilter-edit-export}}“ pod „{{int:abusefilter-edit-tools}}“ u uređivačkom okviru.\nKopirajte sadržaj iz polja koje se pojavi i nalepite ga u ovo polje, pa kliknite na „{{int:abusefilter-import-submit}}“.", "abusefilter-import-submit": "Uvezi podatke", + "abusefilter-import-invalid-data": "Podaci koje ste pokušali da uvezete nisu važeći", "abusefilter-group-default": "Podrazumevano", - "abusefilter-http-error": "Došlo je do HTTP greške: $1." + "abusefilter-http-error": "Došlo je do HTTP greške: $1.", + "abusefilter-view-privatedetails-submit": "Prikaži privatne detalje", + "abusefilter-view-privatedetails-legend": "Prikaz privatnih detalja", + "abusefilter-view-privatedetails-reason": "Razlog za pristupanje privatnim detaljima:", + "abusefilter-log-details-id": "ID dnevnika", + "abusefilter-log-ip-not-available": "Nedostupno", + "tag-abusefilter-condition-limit": "dostignuto uslovno ograničenje" } diff --git a/AbuseFilter/i18n/stq.json b/AbuseFilter/i18n/stq.json index 8bda67d6..bc8f1a54 100644 --- a/AbuseFilter/i18n/stq.json +++ b/AbuseFilter/i18n/stq.json @@ -1,13 +1,13 @@ { "@metadata": { "authors": [ - "Pyt", - "Matma Rex" + "Matma Rex", + "Pyt" ] }, "abusefilter-desc": "Woant automatiske Heuristike ap Annerengen an.", - "abusefilter": "Misbruukssieuwe-Ienstaalengen", - "abuselog": "Misbruuks-Logbouk", + "abusefilter": "Misbruukssieuwe-Ferwaltenge", + "abuselog": "Misbruukssieuwe-Logbouk", "abusefilter-warning": "'''Woarskauenge''': Disse Aktion wuud automatisk as skoadelk ärkoand.\nUunkonstruktive Biedraage wäide maast gjucht gau wächhoald. In wierhoalde un besunners läipe Falle wäd dien Account blw. dien IP-Adresse speerd.\nWan du toankst, dät dien Annerenge konstruktiv waas, koast du ju oawers mäd n näien Klik ap „{{int:savearticle}}“ bestäätigje.\nKuute Beskrieuwenge fon ju nit beoachtede Räägel: $1", "abusefilter-disallowed": "Disse Aktion wuud automatisk as skoadelk ärkoand un deeruum nit truchfierd.\nWan du toankst, dät dien Biedraach konstruktiv waas, weende die dan an n Administrator un skilderje him, wät du fersoacht hääst bietoudreegen.\n\nKuute Beskrieuwenge fon ju nit beoachtede Räägel: $1", "abusefilter-blocked-display": "Disse Aktion wuud automatisk as skoadelk ärkoand un nit uutfierd.\nFääre wuud dien Benutseraccount un aal touheerige IP-Adressen speerd.\nWan du toankst, dät et sik hierbie uum n Failer honnelt, weende die dan an n Administrator.\n\nKuute Beskrieuwenge fon ju nit beoachtede Räägel: $1", @@ -21,7 +21,7 @@ "right-abusefilter-view": "Misbruukssieuwen bekiekje", "right-abusefilter-log": "Misbruuks-Logbouk ienkiekje", "right-abusefilter-log-detail": "Detaillierd Misbruuks-Logbouk ienkiekje", - "right-abusefilter-private": "Privoate Doaten in dät Misbruuks-Logbouk ienkiekje", + "right-abusefilter-privatedetails": "Privoate Doaten in dät Misbruuks-Logbouk ienkiekje", "right-abusefilter-modify-restricted": "Misbruuk-Sieuwe mäd ferbeedene Aktione beoarbaidje", "right-abusefilter-view-private": "Misbruuksieuwen ounkiekje, do der as privoat markierd wuuden", "right-abusefilter-hide-log": "Iendroage uut dät Misbruuksieuwe-Logbouk uutbländje", @@ -30,11 +30,10 @@ "action-abusefilter-view": "Misbruukssieuwen bekiekje", "action-abusefilter-log": "dät Misbruuksieuwe-Logbouk ienkiekje", "action-abusefilter-log-detail": "Detaillierd Misbruuksieuwe-Logbouk ienkiekje", - "action-abusefilter-private": "Privoate Doaten in dät Misbruuksieuwe-Logbouk ienkiekje", + "action-abusefilter-privatedetails": "Privoate Doaten in dät Misbruuksieuwe-Logbouk ienkiekje", "action-abusefilter-modify-restricted": "Misbruuksieuwe mäd ferbeedene Aktione beoarbaidje", "action-abusefilter-revert": "aal Annerengen truch ne bestimde Misbruuksieuwe touräächtraale", "action-abusefilter-view-private": "Misbruuksieuwen ounkiekje, do der as privoat markierd wuuden", - "abusefilter-log": "Misbruukssieuwe-Logbouk", "abusefilter-log-search": "Misbruuks-Logbouk truchsäike", "abusefilter-log-search-user": "Benutser:", "abusefilter-log-search-filter": "Sieuwe-ID:", @@ -48,12 +47,11 @@ "abusefilter-log-details-var": "Variable", "abusefilter-log-details-val": "Wäid", "abusefilter-log-details-vars": "Aktionsparametere", - "abusefilter-log-details-private": "Privoate Doaten", + "abusefilter-log-details-privatedetails": "Privoate Doaten", "abusefilter-log-details-ip": "IP-Adresse fon dän Feruurseeker", "abusefilter-log-noactions": "neen", "abusefilter-log-hide-reason": "Gruund:", "abusefilter-log-hide-forbidden": "Du hääst nit ju Begjuchtigenge, die Iendraage fon dät Misbruuksieuwe-Logbouk tou fersteeten.", - "abusefilter-management": "Misbruukssieuwe-Ferwaltenge", "abusefilter-list": "Aal Sieuwen", "abusefilter-list-id": "Sieuwe-ID", "abusefilter-list-status": "Stoatus", @@ -92,7 +90,6 @@ "abusefilter-edit-oldwarning": "<strong>Du beoarbaidest nit ju aktuelle, man ne allere Version fon disse Sieuwe. Ju Statistik jält bloot foar ju lääste Version fon ju Sieuwe. Wan du spiekerst, wäd ju oolde as aktuelle Version näi spiekerd. </strong> • [[Special:AbuseFilter/history/$2|Tourääch tou ju Versionsgeskichte fon ju Sieuwe]]", "abusefilter-edit-status-label": "Statistike:", "abusefilter-edit-status": "Fon {{PLURAL:$1|ju|do}} lääste {{PLURAL:$1|Aktion|$1 Aktione}} {{PLURAL:$2|wuud|wuuden}} $2 ($3 %) fon disse Sieuwe wierkoand.", - "abusefilter-edit-status-profile": "Fon {{PLURAL:$1|ju|do}} lääste {{PLURAL:$1|Aktion|$1 Aktione}} {{PLURAL:$2|wuud|wuuden}} $2 ($3 %) fon disse Sieuwe wierkoand.\nIn n Truchsnit bedruuch hiere Beoarbaidengstied $4 ms un do benöödigeden $5 {{PLURAL:$5|Bedingenge|Bedingengen}} fon ju ferlööwede Hoochsttaal.", "abusefilter-edit-new": "Näie Sieuwe", "abusefilter-edit-save": "Sieuwe spiekerje", "abusefilter-edit-id": "Sieuwe-ID:", diff --git a/AbuseFilter/i18n/su.json b/AbuseFilter/i18n/su.json index eb55fcc9..bc0a196b 100644 --- a/AbuseFilter/i18n/su.json +++ b/AbuseFilter/i18n/su.json @@ -7,10 +7,9 @@ }, "abusefilter-log-search-user": "Pamaké:", "abusefilter-log-search-title": "Judul:", - "abusefilter-log-details-private": "Data pribadi", + "abusefilter-log-details-privatedetails": "Data pribadi", "abusefilter-log-details-ip": "Alamat IP asal", "abusefilter-log-noactions": "kosong", - "abusefilter-log-hidden": "(éntri disumputkeun)", "abusefilter-log-hide-legend": "Sumputkeun éntri log", "abusefilter-log-hide-id": "ID éntri log:", "abusefilter-log-hide-reason": "Alesan:", diff --git a/AbuseFilter/i18n/sv.json b/AbuseFilter/i18n/sv.json index 09a13fbc..3caf1767 100644 --- a/AbuseFilter/i18n/sv.json +++ b/AbuseFilter/i18n/sv.json @@ -3,42 +3,47 @@ "authors": [ "Ainali", "Bengt B", + "Bengtsson96", "Boivie", "Cybjit", "Fluff", "Gabbe.g", "GameOn", + "JohanahoJ", + "Jopparn", + "Josve05a", "Lejonel", "Leo Johannes", "Lokal Profil", "M.M.S.", "MagnusA", + "Marfuas", + "Matma Rex", + "Matěj Suchánek", "McDutchie", + "Mjälten", "Najami", "Nghtwlkr", + "Nirmos (Wikimedia)", "Njaelkies Lea", "Petter Strandmark", "Poxnar", + "Psl85", "Rotsee", + "Sabelöga", "Sertion", "Skalman", "Thurs", "Tobulos1", - "WikiPhoenix", - "Jopparn", - "Marfuas", - "Josve05a", - "Matma Rex", - "Matěj Suchánek", - "Bengtsson96" + "WikiPhoenix" ] }, "abusefilter-desc": "Tillämpar automatiska filter på redigeringar", - "abusefilter": "Konfiguration av missbruksfilter", - "abuselog": "Missbrukslogg", + "abusefilter": "Hantering av missbruksfilter", + "abuselog": "Logg för missbruksfilter", "abusefilter-intro": "Välkommen till gränssnittet för hantering av missbruksfiltret.\nMissbruksfiltret är en automatisk mjukvarumekanism som utför automatisk kontroll av alla handlingar.\nDetta gränssnitt visar en lista över definierade filter och gör det möjligt att ändra i dessa.", "abusefilter-mustviewprivateoredit": "Av säkerhetsskäl kan bara användare med rättigheten att visa privata missbruksfilter eller modifiera missbruksfiltret använda detta gränssnitt.", - "abusefilter-warning": "'''Varning:''' Denna handling har automatiskt identifierats som skadlig.\nDestruktiva handlingar kommer snabbt att återställas,\noch återkommande förstörande redigeringar kommer leda till att ditt konto eller IP-adress blir blockerad.\nOm du anser att denna handling är konstruktiv, klicka på \"Spara\" igen för att bekräfta det.\nEn kortfattad beskrivning av missbruksregler som din handling utlöste är: $1", + "abusefilter-warning": "'''Varning:''' Denna handling har automatiskt identifierats som skadlig.\nDestruktiva handlingar kommer snabbt att återställas,\noch återkommande förstörande redigeringar kommer leda till att ditt konto eller IP-adress blir blockerad.\nOm du anser att denna handling är konstruktiv, klicka på \"Spara ändringar\" igen för att bekräfta det.\nEn kortfattad beskrivning av missbruksregler som din handling utlöste är: \"$1\"", "abusefilter-disallowed": "Denna handling har automatiskt identifierats som skadlig och tillåts därför inte.\nOm du anser att din handling var konstruktiv, kontakta en administratör och informera denna om vad du försökte göra.\nEn kortfattad beskrivning av missbruksregeln som din handling utlöste är: $1", "abusefilter-blocked-display": "Denna handling har automatiskt identifierats som skadlig och du har blivit hindrad från att genomföra den.\nDessutom har ditt användarkonto och alla associerade IP-adresser blivit blockerade från att redigera {{SITENAME}}.\nOm detta var ett fel, var god kontakta en administratör.\nEn kortfattad beskrivning av missbruksregeln som din handling utlöste är: $1", "abusefilter-degrouped": "Denna handling har automatiskt identifierats som skadlig.\nDärför tilläts den inte, och på grund av misstanke om missbruk har ditt konto mist alla rättigheter.\nOm du menar att detta har skett på grund av ett fel, var god kontakta en byråkrat med en förklaring av vad du gjorde, så kan dina rättigheter återställas.\nEn kortfattad beskrivning av missbruksregeln som din handling utlöste är: $1", @@ -46,42 +51,49 @@ "abusefilter-blocker": "Missbruksfilter", "abusefilter-blockreason": "Automatiskt blockerad av missbruksfiltret.\nBeskrivning av utlöst regel: $1", "abusefilter-degroupreason": "Behörigheter borttagna automatiskt av missbruksfilter. Regelbeskrivning: $1", + "abusefilter-blockautopromotereason": "Autobefordring fördröjdes automatiskt av missbruksfilter. Regelbeskrivning: $1", "abusefilter-accountreserved": "Detta konto är reserverat för användning av missbruksfiltret.", - "right-abusefilter-modify": "Ändra missbruksfilter", - "right-abusefilter-view": "Visa missbruksfilter", + "right-abusefilter-modify": "Skapa eller ändra missbruksfilter", + "right-abusefilter-view": "Se missbruksfilter", "right-abusefilter-log": "Visa missbruksloggen", "right-abusefilter-log-detail": "Visa detaljerade element i missbruksloggen", - "right-abusefilter-private": "Visa privat information i missbruksloggen", - "right-abusefilter-private-log": "Visa missbruksfiltrets privata detaljer i åtkomstloggen", + "right-abusefilter-privatedetails": "Visa privat information i missbruksloggen", + "right-abusefilter-privatedetails-log": "Visa missbruksfiltrets privata detaljer i åtkomstloggen", "right-abusefilter-modify-restricted": "Justera missbruksfilter med begränsade handlingar", "right-abusefilter-revert": "Återställ alla ändringar gjorda av ett visst missbruksfilter", "right-abusefilter-view-private": "Visa missbruksfilter som är markerade som privata", "right-abusefilter-log-private": "Visa loggposter från missbruksfiltret som har markerats som privata", - "right-abusefilter-hide-log": "Dölja poster i missbruksloggen", - "right-abusefilter-hidden-log": "Visa dolda missbruksloggsposter", + "right-abusefilter-hide-log": "Dölj poster i missbruksloggen", + "right-abusefilter-hidden-log": "Visa dolda missbruksloggsposter", "right-abusefilter-modify-global": "Skapa eller ändra globala missbruksfilter", "action-abusefilter-modify": "modifiera missbruksfilter", - "action-abusefilter-view": "se missbruksfilter", + "action-abusefilter-view": "se redigeringsfilter", "action-abusefilter-log": "se missbruksloggen", "action-abusefilter-log-detail": "se detaljerna i missbruksloggen", - "action-abusefilter-private": "se privat data i missbruksloggen", - "action-abusefilter-private-log": "visa missbruksfiltrets privata detaljer i åtkomstloggen", + "action-abusefilter-privatedetails": "se privat data i missbruksloggen", + "action-abusefilter-privatedetails-log": "visa missbruksfiltrets privata detaljer i åtkomstloggen", "action-abusefilter-modify-restricted": "ändra missbruksfilter med begränsade handlingar", "action-abusefilter-revert": "återställ alla ändringar av ett angivet missbruksfilter", "action-abusefilter-view-private": "visa missbruksfilter markerade som privata", "action-abusefilter-log-private": "visa loggar över missbruksfilter som är märkta som privata", - "abusefilter-log": "Logg för missbruksfilter", + "action-abusefilter-hide-log": "dölja poster i missbruksloggen", + "action-abusefilter-hidden-log": "visa dolda poster i missbruksloggen", + "action-abusefilter-modify-global": "skapa eller ändra globala missbruksfilter", "abusefilter-log-summary": "Denna logg visar en lista över alla handlingar som fångats upp av filtren.", "abusefilter-log-search": "Sök i missbruksloggen", "abusefilter-log-search-user": "Användare:", - "abusefilter-log-search-filter": "Filter-ID (separeras med vertikalstreck):", + "abusefilter-log-search-group": "Filtergrupp:", + "abusefilter-log-search-group-any": "Alla", + "abusefilter-log-search-filter": "Filter-ID:n", + "abusefilter-log-search-filter-help": "Separera med vertikala linjer, inled med \"$1\" för globala filter", + "abusefilter-log-search-filter-help-central": "Skilj med vertikalstreck", "abusefilter-log-search-title": "Titel:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-impact": "Påverkan:", "abusefilter-log-search-impact-all": "Alla handlingar", "abusefilter-log-search-impact-saved": "Endast sparade ändringar", "abusefilter-log-search-impact-not-saved": "Utan sparade ändringar", - "abusefilter-log-search-entries-label": "Synlighet", + "abusefilter-log-search-entries-label": "Synlighet:", "abusefilter-log-search-entries-all": "Alla poster", "abusefilter-log-search-entries-hidden": "Endast dolda poster", "abusefilter-log-search-entries-visible": "Endast synliga poster", @@ -103,19 +115,21 @@ "abusefilter-log-details-var": "Variabel", "abusefilter-log-details-val": "Värde", "abusefilter-log-details-vars": "Handlingsparametrar", - "abusefilter-log-details-private": "Privata loggdetaljer", + "abusefilter-log-details-privatedetails": "Privata loggdetaljer", "abusefilter-log-details-ip": "Upphovs-IP", "abusefilter-log-details-checkuser": "Kontrollera användare", "abusefilter-log-noactions": "ingen", + "abusefilter-log-noactions-filter": "Ingen", "abusefilter-log-details-diff": "Ändringar utförda i redigeringen", "abusefilter-log-linkoncontribs": "missbrukslogg", "abusefilter-log-linkoncontribs-text": "Missbrukslogg för {{GENDER:$1|den här användaren}}", "abusefilter-log-linkonhistory": "visa missbrukslogg", "abusefilter-log-linkonhistory-text": "Visa missbruksloggen för denna sida", - "abusefilter-log-hidden": "(post dold)", + "abusefilter-log-linkonundelete": "visa missbrukslogg", + "abusefilter-log-linkonundelete-text": "Visa missbruksloggen för denna sida", "abusefilter-log-hidden-implicit": "(dold eftersom versionen har tagits bort)", "abusefilter-log-cannot-see-details": "Du har inte behörighet att se detaljer om den här posten.", - "abusefilter-log-cannot-see-private-details": "Du har inte behörighet för att se privata detaljer över denna post.", + "abusefilter-log-cannot-see-privatedetails": "Du har inte behörighet för att se privata detaljer över denna post.", "abusefilter-log-nonexistent": "En post med angivet ID finns inte.", "abusefilter-log-details-hidden": "Du kan inte se detaljerna för denna post eftersom den är dold från allmän visning", "abusefilter-log-details-hidden-implicit": "Du kan inte se detaljerna för detta element eftersom dess associerade sidversion är dold från allmän vy.", @@ -133,9 +147,12 @@ "log-action-filter-abusefilter-create": "Nya skapade filter", "log-action-filter-abusefilter-modify": "Ändring av filter", "log-action-filter-suppress-abuselog": "Censur av missbrukslogg", + "log-action-filter-rights-blockautopromote": "Blockera autobefordring", + "log-action-filter-rights-restoreautopromote": "Återställ autobefordring", "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|fick åtkomst}} till privata detaljer för $3", + "logentry-rights-blockautopromote": "$1 {{GENDER:$2|blockerade}} autobefordringen för {{GENDER:$4|$3}} under en tidsperiod på $5", + "logentry-rights-restoreautopromote": "$1 {{GENDER:$2|återställde}} möjligheten att autobefordras för {{GENDER:$4|$3}}", "abusefilterprivatedetails-log-name": "Missbruksfilter för privata detaljer i åtkomstloggen", - "abusefilter-management": "Hantering av missbruksfilter", "abusefilter-list": "Alla filter", "abusefilter-list-id": "Filter-ID", "abusefilter-list-pattern": "Mönster", @@ -157,6 +174,7 @@ "abusefilter-throttled": "begränsad", "abusefilter-hitcount": "$1 {{PLURAL:$1|träff|träffar}}", "abusefilter-new": "Skapa ett nytt filter", + "abusefilter-import-button": "Importera filter", "abusefilter-return": "Återvänd till filteradministration", "abusefilter-status-global": "Globalt", "abusefilter-list-options": "Alternativ", @@ -169,7 +187,7 @@ "abusefilter-list-options-scope-global": "Endast globala regler", "abusefilter-list-options-scope-all": "Lokala och globala regler", "abusefilter-list-options-further-options": "Ytterligare alternativ:", - "abusefilter-list-options-hidedisabled": "Göm avaktiverade filter", + "abusefilter-list-options-hidedisabled": "Dölj inaktiverade filter", "abusefilter-list-options-hideprivate": "Dölj privata filter", "abusefilter-list-options-searchfield": "Sök inom regler:", "abusefilter-list-options-searchpattern": "Ange ett mönster", @@ -177,26 +195,29 @@ "abusefilter-list-options-search-like": "Vanlig fråga", "abusefilter-list-options-search-rlike": "Reguljärt uttryck", "abusefilter-list-options-search-irlike": "Icke-skiftlägeskänsligt reguljärt uttryck", + "abusefilter-list-invalid-searchmode": "Det angivna sökläget är inte giltigt.", "abusefilter-list-regexerror": "Ett fel uppstod under sökning: Syntaxfel i reguljärt uttryck.", "abusefilter-list-options-submit": "Uppdatera", "abusefilter-tools-text": "Här är några verktyg som kan vara användbara för att skapa och felsöka missbruksfilter.", "abusefilter-tools-expr": "Uttryckstestare", "abusefilter-tools-submitexpr": "Utvärdera", + "abusefilter-tools-syntax-error": "Filtret har ogiltig syntax.", "abusefilter-tools-reautoconfirm": "Återställ status som automatiskt bekräftad", "abusefilter-tools-reautoconfirm-user": "Användare:", "abusefilter-tools-reautoconfirm-submit": "Åter-automatbekräfta", + "abusefilter-tools-restoreautopromote": "Autobefordring återställdes via missbruksfilterverktyg.", "abusefilter-reautoconfirm-none": "Användaren har inte blivit fråntagen {{GENDER:$1|sin|sin|sin}} status som automatiskt bekräftad.", "abusefilter-reautoconfirm-notallowed": "Du är inte tillåten att återställa status som automatiskt bekräftad.", "abusefilter-reautoconfirm-done": "Kontots status som automatiskt bekräftad har återställts", - "abusefilter-status": "Av {{PLURAL:$1|den senaste handlingen|de $1 senaste handlingarna}} har $2 ($3%) nått gränsvärdet $4. $5 ($6%) har matchat ett av de filter som för närvarande är aktiverade.", + "abusefilter-status": "Av {{PLURAL:$1|den senaste handlingen|de $1 senaste handlingarna}} har $2 ($3 %) nått gränsvärdet $4. $5 ($6 %) har matchat minst ett av de filter som för närvarande är aktiverade.", "abusefilter-edit": "Redigerar missbruksfilter", "abusefilter-edit-subtitle": "Redigerar filtret $1", "abusefilter-edit-subtitle-new": "Skapa filter", "abusefilter-edit-token-not-match": "Redigeringen sparades inte! Var god spara igen.", "abusefilter-edit-oldwarning": "<strong>Du redigerar en gammal version av detta filter. Den angivna statistiken gäller den senaste versionen av filtret. Om du sparar dina ändringar kommer du att skriva över alla ändringar som gjorts efter den version du redigerar. </strong> • [[Special:AbuseFilter/history/$2|Återvänd till detta filters historik]]", + "abusefilter-edit-oldwarning-view": "Du visar en gammal version av detta filtret.\nStatistiken som citeras gäller den nyaste versionen av filtret. •\n[[Special:AbuseFilter/history/$2|Tillbaka till filterets historik]].", "abusefilter-edit-status-label": "Statistik:", - "abusefilter-edit-status": "Av {{PLURAL:$1|den senaste handlingen|de senaste $1 handlingarna}} har detta filter matchat $2 ($3 %).", - "abusefilter-edit-status-profile": "Av {{PLURAL:$1|den senaste handlingen|de senaste $1 handlingarna}} har detta filter matchat $2 ($3 %). Körtiden är i genomsnitt $4 ms och filtret använder $5 {{PLURAL:$5|villkor|villkor}} av villkorsgränsen.", + "abusefilter-edit-status": "Av {{PLURAL:$1|den senaste handlingen|de senaste $1 handlingarna}} har detta filter matchat $2 ($3 %).\nI genomsnitt ligger körtiden på $4 ms och konsumerar $5 {{PLURAL:$5|villkor}} av villkorsgränsen.", "abusefilter-edit-throttled-warning": "'''Varning:''' Detta filter flaggades automatiskt som skadligt. Följande åtgärder kommer inte utföras av säkerhetsskäl ($1). Granska och [[mw:Extension:AbuseFilter/Conditions|optimera villkoren]] för att ta bort denna begränsning", "abusefilter-edit-new": "Nytt filter", "abusefilter-edit-save": "Spara filter", @@ -229,20 +250,31 @@ "abusefilter-edit-throttle-count": "Antal tillåtna handlingar:", "abusefilter-edit-throttle-period": "Tidsperiod (i sekunder):", "abusefilter-edit-throttle-groups": "Gruppera begränsningarna på:", - "abusefilter-edit-throttle-ip": "IP-adress", - "abusefilter-edit-throttle-user": "Användarkonto", - "abusefilter-edit-throttle-range": "/16-intervall", - "abusefilter-edit-throttle-creationdate": "Servertid för skapat konto", - "abusefilter-edit-throttle-editcount": "Antal redigeringar", - "abusefilter-edit-throttle-site": "Hela webbplatsen", - "abusefilter-edit-throttle-page": "Sida", + "abusefilter-edit-throttle-groups-help": "Se $1.", + "abusefilter-edit-throttle-groups-help-text": "dokumentationen på mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Dela upp med kommatecken för att sammanfoga med AND och med radbrytningar för att sammanfoga med OR", + "abusefilter-edit-throttle-placeholder": "Dela upp med kommatecken för att sammanfoga med AND och infoga en efter en för att sammanfoga med OR", + "abusefilter-throttle-ip": "IP-adress", + "abusefilter-throttle-user": "användarkonto", + "abusefilter-throttle-range": "/16-intervall", + "abusefilter-throttle-creationdate": "datum för kontoregistrering", + "abusefilter-throttle-editcount": "antal redigeringar", + "abusefilter-throttle-site": "hela webbplatsen", + "abusefilter-throttle-page": "sida", + "abusefilter-throttle-none": "(ingen)", "abusefilter-throttle-details": "Tillåt $1 {{PLURAL:$1|åtgärd|åtgärder}} efter $2 {{PLURAL:$2|sekund|sekunder}}, gruppbegränsat efter: $3", "abusefilter-edit-warn-message": "Systemmeddelande att använda för varning:", "abusefilter-edit-warn-other": "Annat meddelande", - "abusefilter-edit-warn-other-label": "Sidnamn för annat meddelande:\n:''(utan MediaWiki-prefix)''", + "abusefilter-edit-warn-other-label": "Sidnamn för annat meddelande:\n:''(utan prefixet \"MediaWiki:\")''", "abusefilter-edit-warn-actions": "Åtgärder:", "abusefilter-edit-warn-preview": "Visa/dölj förhandsgranskning av valt meddelande", "abusefilter-edit-warn-edit": "Skapa/redigera valt meddelande", + "abusefilter-edit-disallow-message": "Systemmeddelande att använda för förbjud:", + "abusefilter-edit-disallow-other": "Annat meddelande", + "abusefilter-edit-disallow-other-label": "Sidnamn för annat meddelande:\n:''(utan prefixet \"MediaWiki:\")''", + "abusefilter-edit-disallow-actions": "Åtgärder:", + "abusefilter-edit-disallow-preview": "Visa/dölj förhandsgranskning av valt meddelande", + "abusefilter-edit-disallow-edit": "Skapa/redigera valt meddelande", "abusefilter-edit-tag-tag": "[[Special:Tags|Märken]] att tillämpa:", "abusefilter-edit-tag-placeholder": "Lägg till märken (en per rad eller separerade med komma)", "abusefilter-edit-tag-hidden-placeholder": "Lägg till taggar (kommaseparerade)", @@ -269,10 +301,18 @@ "abusefilter-edit-export": "Exportera det här filtret till en annan wiki", "abusefilter-edit-syntaxok": "Inga syntaxfel upptäcktes.", "abusefilter-edit-syntaxerr": "Syntaxfel uppstod: $1", + "abusefilter-edit-warn-leave": "Om du lämnar sidan kommer du förlora alla ändringar du har gjort i detta filter.", "abusefilter-edit-bad-tags": "En eller flera av de märken du angav är inte giltigt.\nMärken skall vara korta och de kan inte innehålla några specialtecken och de kan inte reserveras av andra programvaror. Försök att välja ett nytt märkesnamn", "abusefilter-edit-notallowed": "Du har inte tillåtelse att skapa eller ändra missbruksfilter", "abusefilter-edit-notallowed-global": "Du har inte tillåtelse att skapa eller ändra globala missbruksfilter", - "abusefilter-edit-notallowed-global-custom-msg": "Anpassade varningsmeddelanden stöds inte för globala filter", + "abusefilter-edit-notallowed-global-custom-msg": "Anpassade varnings- och förbudsmeddelanden stöds inte för globala filter", + "abusefilter-edit-invalid-warn-message": "Varningsmeddelandet kan inte vara tomt.", + "abusefilter-edit-invalid-disallow-message": "Förbudsmeddelandet kan inte vara tomt.", + "abusefilter-edit-invalid-throttlecount": "Antalet begränsningsåtgärder måste vara ett positivt heltal.", + "abusefilter-edit-invalid-throttleperiod": "Begränsningsperioden måste vara ett positiv heltal.", + "abusefilter-edit-empty-throttlegroups": "Minst en begränsningsgrupp måste markeras.", + "abusefilter-edit-duplicated-throttlegroups": "Begränsningsgrupper kan inte ha dubbletter.", + "abusefilter-edit-invalid-throttlegroups": "De angivna begränsningsgrupperna är inte giltiga.", "abusefilter-edit-builder-select": "Ange ett alternativ för att lägga till det vid markören", "abusefilter-edit-builder-group-op-arithmetic": "Aritmetiska operatorer", "abusefilter-edit-builder-op-arithmetic-addition": "Addition (+)", @@ -302,7 +342,8 @@ "abusefilter-edit-builder-misc-contains": "Texten till vänster innehåller texten till höger (contains)", "abusefilter-edit-builder-misc-stringlit": "Literal sträng (\"\")", "abusefilter-edit-builder-misc-tern": "Ternära operatorn (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Villkor (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "Villkor (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "Kort villkor (if X then Y end)", "abusefilter-edit-builder-group-funcs": "Funktioner", "abusefilter-edit-builder-funcs-length": "Stränglängd (length)", "abusefilter-edit-builder-funcs-lcase": "Gör om till små bokstäver (lcase)", @@ -373,12 +414,12 @@ "abusefilter-edit-builder-vars-all-links": "Alla externa länkar i den nya texten", "abusefilter-edit-builder-vars-added-links": "Alla externa länkar tillagda i redigeringen", "abusefilter-edit-builder-vars-removed-links": "Alla externa länkar borttagna i redigeringen", - "abusefilter-edit-builder-vars-old-text": "Gamla sidans wikitext, innan redigeringen (används inte längre)", - "abusefilter-edit-builder-vars-new-text": "Sidans nya wikitext, efter redigeringen", + "abusefilter-edit-builder-vars-old-wikitext": "Sidans gamla wikitext, innan redigeringen", + "abusefilter-edit-builder-vars-new-wikitext": "Sidans nya wikitext, efter redigeringen", "abusefilter-edit-builder-vars-new-pst": "Ny sida wikitext förändrades innan den sparades", "abusefilter-edit-builder-vars-diff-pst": "Sammanslagen diff av ändringarna gjorda under redigering, innan de sparades", "abusefilter-edit-builder-vars-addedlines-pst": "Rader tillagda under redigering, innan den sparades", - "abusefilter-edit-builder-vars-new-text-stripped": "Ny sidtext, strippad från eventuell markup", + "abusefilter-edit-builder-vars-new-text": "Ny sidtext, med all kodning borttagen", "abusefilter-edit-builder-vars-new-html": "Parsad HTML-källkod för den nya versionen", "abusefilter-edit-builder-vars-restrictions-edit": "Skyddsnivå för redigering av sidan", "abusefilter-edit-builder-vars-restrictions-move": "Skyddsnivå för flytt av sidan", @@ -392,10 +433,10 @@ "abusefilter-edit-builder-vars-movedto-restrictions-move": "Flytta skyddsnivå för flyttning av destinationssida", "abusefilter-edit-builder-vars-movedto-restrictions-create": "Skapa skyddsnivå för flyttning av destinationssida", "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Ladda upp skyddsnivå för flyttning av destinationsfil", - "abusefilter-edit-builder-vars-old-text-stripped": "Gammal sidtext, med all kodning borttagen", + "abusefilter-edit-builder-vars-old-text": "Gammal sidtext, med all kodning borttagen (används inte längre)", "abusefilter-edit-builder-vars-old-links": "Länkar i denna sida, före redigeringen", "abusefilter-edit-builder-vars-old-html": "Gammal sidwikitext, parsad till HTML (används inte längre)", - "abusefilter-edit-builder-vars-minor-edit": "Huruvida redigeringen är markerad som mindre", + "abusefilter-edit-builder-vars-minor-edit": "Huruvida redigeringen är markerad som mindre (används inte längre)", "abusefilter-edit-builder-vars-file-sha1": "SHA1-hash av filinnehållet", "abusefilter-edit-builder-vars-file-size": "Storlek på filen i bytes", "abusefilter-edit-builder-vars-file-mime": "MIME-typ av filen", @@ -403,6 +444,8 @@ "abusefilter-edit-builder-vars-file-width": "Bredd på filen i pixlar", "abusefilter-edit-builder-vars-file-height": "Höjd på filen i pixlar", "abusefilter-edit-builder-vars-file-bits-per-channel": "Bitar per färgkanal för filen", + "abusefilter-edit-builder-vars-wiki-name": "Wikins databasnamn", + "abusefilter-edit-builder-vars-wiki-language": "Wikins språkkod", "abusefilter-filter-log": "Senaste filterändringar", "abusefilter-history": "Ändringshistorik för missbruksfilter #$1", "abusefilter-history-foruser": "Ändringar av $1", @@ -436,13 +479,16 @@ "abusefilter-exception-dividebyzero": "Ogiltigt försök att dividera $2 med noll vid tecken $1.", "abusefilter-exception-unrecognisedvar": "Okänd variabel $2 vid tecken $1", "abusefilter-exception-notenoughargs": "Funktionen $2 anropades med för få argument vid teckenposition $1. $3 {{PLURAL:$3|argument|argument}} väntades, fick bara $4.", - "abusefilter-exception-regexfailure": "Fel i det reguljära uttrycket \"$3\" vid teckenposition $1: \"$2\"", - "abusefilter-exception-overridebuiltin": "Ogiltig överskrivning av inbyggd variabel \"$2\" vid teckenposition $1.", + "abusefilter-exception-toomanyargs": "För många argument i funktionen $2 som anropades vid teckennummer $1.\nMinst $3 {{PLURAL:$3|argument}} förväntades, men $4 hittades", + "abusefilter-exception-regexfailure": "Fel i det reguljära uttrycket \"$2\" vid teckenposition $1.", + "abusefilter-exception-overridebuiltin": "Ogiltig överskrivning av inbyggd identifieraren \"$2\" vid teckenposition $1.", "abusefilter-exception-outofbounds": "Begärde icke-befintligt listelement $2 (arraystorlek = $3) vid teckenposition $1.", + "abusefilter-exception-negativeindex": "Negativa sök tillåts inte i tabeller. Fick index «$2» vid $1.", "abusefilter-exception-notarray": "Begär tabellelement från en icketabell vid teckenposition $1.", "abusefilter-exception-unclosedcomment": "Öppen kommentar vid tecken $1.", "abusefilter-exception-invalidiprange": "\"$2\" är ett ogiltigt IP-intervall vid tecknet $1.", "abusefilter-exception-disabledvar": "Variabeln $2 vid tecknet $1 används inte längre.", + "abusefilter-exception-variablevariable": "set och set_var förväntar att det första argumentet är en sträng, vid tecken nummer $1.", "abusefilter-action-tag": "Tagg", "abusefilter-action-throttle": "Begränsning", "abusefilter-action-warn": "Varna", @@ -505,15 +551,16 @@ "abusefilter-examine-noresults": "Inga resultat hittades för de sökparametrar du gav.", "abusefilter-topnav": "'''Navigation'''", "abusefilter-topnav-home": "Huvudsida", + "abusefilter-topnav-recentchanges": "Senaste filterändringar", "abusefilter-topnav-test": "Grupptestning", "abusefilter-topnav-examine": "Granska tidigare ändringar", "abusefilter-topnav-log": "Missbrukslogg", "abusefilter-topnav-tools": "Felsökningsverktyg", - "abusefilter-topnav-import": "Importera filter", "abusefilter-log-name": "Missbruksfilterändringar", "abusefilter-log-header": "Denna logg visar en sammanfattning av ändringar som har gjorts i filtren.\nFör fullständiga detaljer, se [[Special:AbuseFilter/history|listan]] över de senaste filterändringarna.", "abusefilter-logentry-create": "$1 {{GENDER:$2|skapade}} $4 ($5)", "abusefilter-logentry-modify": "$1 {{GENDER:$2|ändrade}} $4 ($5)", + "abusefilter-log-invalid-filter": "Några specificerade filter-ID:n är ogiltiga.", "abusefilter-log-noresults": "Inga resultat", "abusefilter-diff-title": "Skillnader mellan versioner", "abusefilter-diff-item": "Element", @@ -526,11 +573,12 @@ "abusefilter-diff-next": "Nyare förändring", "abusefilter-import-intro": "Du kan använda detta gränssnitt till att importera filter från andra wikier.\nI källwikin klickar du på \"{{int:abusefilter-edit-export}}\" under \"{{int:abusefilter-edit-tools}}\" i redigeringsgränsnittet.\nKopiera från textrutan som kommer fram och klistra in det till denna ruta. Klicka sedan på \"{{int:abusefilter-import-submit}}\".", "abusefilter-import-submit": "Importera data", + "abusefilter-import-invalid-data": "Datan du försökte importera är inte giltig", "abusefilter-group-default": "Standard", "abusefilter-http-error": "Ett HTTP-fel uppstod: $1.", - "abusefilter-view-private-submit": "Visa privata detaljer", - "abusefilter-view-private": "Visa privata detaljer", - "abusefilter-view-private-reason": "Anledning för att komma åt privata detaljer:", + "abusefilter-view-privatedetails-submit": "Visa privata detaljer", + "abusefilter-view-privatedetails-legend": "Visa privata detaljer", + "abusefilter-view-privatedetails-reason": "Anledning för att komma åt privata detaljer:", "abusefilter-log-details-id": "Logg-ID", "abusefilter-invalid-request": "Ogiltig begäran! Du måste få åtkomst till privata loggdetaljer via formuläret på [[Special:AbuseLog/$1]] och ange en anledning.", "abusefilter-invalid-request-noid": "Ogiltig begäran! Du måste få åtkomst till privata loggdetaljer via formuläret på missbruksloggens detaljsida och ange en anledning.", diff --git a/AbuseFilter/i18n/sw.json b/AbuseFilter/i18n/sw.json index 58ec3946..c1a11334 100644 --- a/AbuseFilter/i18n/sw.json +++ b/AbuseFilter/i18n/sw.json @@ -1,14 +1,14 @@ { "@metadata": { "authors": [ + "Fitoschido", "Ikiwaner", "Kwisha", "Lloffiwr", - "Stephenwanjau", - "Rance" + "Rance", + "Stephenwanjau" ] }, - "abuselog": "Kumbukumbu ya matumizi mabaya", "right-abusefilter-modify": "Rekebisha cinchungi vya unyanyasaji", "right-abusefilter-view": "Tazama vichungi vya unyanyasaji", "abusefilter-log-search-user": "Mtumiaji:", @@ -18,7 +18,7 @@ "abusefilter-log-detailslink": "Maelezo zaidi", "abusefilter-log-details-var": "Kibadili", "abusefilter-log-details-val": "Thamani", - "abusefilter-log-details-private": "Data binafsi", + "abusefilter-log-details-privatedetails": "Data binafsi", "abusefilter-log-noactions": "usichague", "abusefilter-log-details-hidden-implicit": "Huwezi kutazama maelezo kwa ingizo hili kwa sababu ukaguzi unaohusiana na ingizo haujawekwa wazi kwa kila mtu kutazama", "abusefilter-log-hide-reason": "Sababu:", @@ -39,6 +39,7 @@ "abusefilter-deleted": "Imefutwa", "abusefilter-disabled": "Imelemazwa", "abusefilter-new": "Tengeza chujio mpya", + "abusefilter-import-button": "Leta chujio", "abusefilter-return": "Rejea katika usimamizi wa chujio", "abusefilter-status-global": "Dunia nzima", "abusefilter-list-options": "Chaguzi", @@ -65,11 +66,13 @@ "abusefilter-edit-notes": "Vidokezo:", "abusefilter-edit-lastmod-text": "$1 na $2", "abusefilter-edit-throttle-period": "Kiwango cha muda (katika sekunde)", - "abusefilter-edit-throttle-ip": "Anuani ya Itifaki ya Muunganiko wa mtandao wa Kompyuta", - "abusefilter-edit-throttle-user": "Akaunti ya mtumiaji", - "abusefilter-edit-throttle-editcount": "Idadi ya hariri", - "abusefilter-edit-throttle-site": "Tovuti nzima", - "abusefilter-edit-throttle-page": "Ukurasa", + "abusefilter-edit-throttle-hidden-placeholder": "Tenganisha kwa mkato kuunganisha AND, na kuunganisha OR tenganisha kwa mistari tofauti", + "abusefilter-throttle-ip": "Anuani ya Itifaki ya Muunganiko wa mtandao wa Kompyuta", + "abusefilter-throttle-user": "akaunti ya mtumiaji", + "abusefilter-throttle-creationdate": "Tarehe ya kutengeneza akaunti", + "abusefilter-throttle-editcount": "Idadi ya hariri", + "abusefilter-throttle-site": "Tovuti nzima", + "abusefilter-throttle-page": "Ukurasa", "abusefilter-edit-warn-other": "Ujumbe mwingine", "abusefilter-edit-warn-actions": "Vitendo:", "abusefilter-edit-warn-preview": "Onyesha/Ficha uhakiki wa ujumbe uliochaguliwa", @@ -84,6 +87,10 @@ "abusefilter-edit-syntaxok": "Hakuna hitilafu za sintaksia zimegunduliwa", "abusefilter-edit-syntaxerr": "Hitilafu ya sintaksia imegunduliwa: $1", "abusefilter-edit-notallowed": "Hauruhusiwi kutemgeza au kuhariri chujio za matumizi mabaya", + "abusefilter-edit-invalid-throttleperiod": "Muda wa udhibiti lazima uwe nambari chanya", + "abusefilter-edit-empty-throttlegroups": "Lazima ichaguliwe angalau kundi moja la kudhibiti", + "abusefilter-edit-duplicated-throttlegroups": "Makundi ya udhibiti hayawezi kuwa na ufanano", + "abusefilter-edit-invalid-throttlegroups": "Makundi ya udhibiti yaliyoainishwa hayafai", "abusefilter-edit-builder-op-arithmetic-addition": "Kuongeza (+)", "abusefilter-edit-builder-op-arithmetic-subtraction": "Kutoa (-)", "abusefilter-edit-builder-op-arithmetic-multiplication": "Kuzidisha (*)", @@ -150,7 +157,6 @@ "abusefilter-topnav-examine": "Chunguza hariri zilizopita", "abusefilter-topnav-log": "Kumbukumbu ya matumizi mabaya", "abusefilter-topnav-tools": "Vifaa vya kueua", - "abusefilter-topnav-import": "Leta chujio", "abusefilter-log-name": "Kumbukumbu ya matumizi mabaya ya chujio", "abusefilter-log-noresults": "Hakuna matokeo", "abusefilter-diff-title": "Tofauti kati ya matokeo", diff --git a/AbuseFilter/i18n/syl.json b/AbuseFilter/i18n/syl.json new file mode 100644 index 00000000..00d70347 --- /dev/null +++ b/AbuseFilter/i18n/syl.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "এম আবু সাঈদ" + ] + }, + "right-abusefilter-modify": "ꠛꠣꠘꠣꠃ ꠘꠣꠁꠟꠦ ꠅꠙꠛꠦꠛꠢꠣꠞ ꠚꠤꠟꠐꠣꠞꠞꠦ ꠢꠣꠎꠣꠃ", + "abusefilter-log-noactions-filter": "ꠇꠥꠘꠥꠐꠣꠅ ꠘꠣꠄ" +} diff --git a/AbuseFilter/i18n/szl.json b/AbuseFilter/i18n/szl.json index 0bda61ed..f4c88475 100644 --- a/AbuseFilter/i18n/szl.json +++ b/AbuseFilter/i18n/szl.json @@ -2,16 +2,18 @@ "@metadata": { "authors": [ "Britscher", - "Krol111" + "Krol111", + "Uostofchuodnego" ] }, - "abusefilter-desc": "Automatyczno heurystyko do edycyj", - "abusefilter": "Konfiguracyjo filtra zńyłużyćůw", - "abuselog": "↓Register zńyłużyćůw", - "abusefilter-intro": "Regiyrowańy registrym zńyłużyćów\nRegister zńyłużyćów je program, kery automatyczńy używo heurystyka do wszyjskich akcyj.\nInterface pozwolo przeglůndać lista zedefińůwanych filtrůw a je pomjyńać.", + "abusefilter-desc": "Używanie autōmatycznyj heurystyki do edycyji", + "abuselog": "Regest filtra nadużyć", + "abusefilter-intro": "Witej we interfejsie zarzōndzaniŏ filtrym nadużyć.\nFilter nadużyć to je autōmatyczny mechanizm używaniŏ do wszyjskich ôperacyji zautōmatyzowanyj heurystyki.\nTyn interfejs pokazuje listã zdefiniowanych filtrōw i przizwŏlŏ na jejich modyfikowanie.", "abusefilter-warning": "'''Pozůr''': Ta akcyjo bůła automatyczńy uznono szkodzůnco.\nFelerne pomjyny bydům cofńynte nazod, a fest złe abo uopakujůnce śe edytowańy skůńczy śe zwarćem twojigo kůnta abo IP.\nEli uważosz, aże to co żeś zrobjůł je dobre, spamjyntej pomjany bez „{{int:savearticle}}”.\nKrůtki uopis regli zńyłużyćo, keremu przipasowano twojo akcyjo: $1", - "abusefilter-disallowed": "Ta akcyjo bůła automatyczńy uznona szkodzůnco i uodćepńynto.\nEli uważosz, aże ta edycyjo bůła ajntlichowo, pedź uo tyj sytuacyji administratůrowi.\nKrůtki uopis regla zńyłużyćo, keremu bůła przipasowano twojo akcyjo: $1", - "abusefilter-blocker": "Filter zńyłużyćów", - "right-abusefilter-modify": "Pomjyńańy filtrůw zńyłużyćůw", - "abusefilter-list-options-submit": "Aktualizacyjo" + "abusefilter-disallowed": "Ta akcyjŏ była autōmatycznie zidyntyfikowanŏ za szkodliwõ i beztōż zakŏzanõ.\nJeźli uwŏżŏsz, iże twoja ôperacyjŏ była nŏleżnŏ, skōntaktuj sie ze administratorym i powiydz mu, co prōbujesz zrobić.\nKrōtki ôpis prawidła, co dō niego twoja ôperacyjŏ pasuje: $1", + "abusefilter-blocker": "Filter nadużyć", + "right-abusefilter-modify": "Modyfikacyjŏ filtrōw nadużyć", + "abusefilter-log-linkoncontribs": "regest nadużyć", + "abusefilter-list-options-submit": "Aktualizacyjo", + "abusefilter-log-name": "Regest filtra nadużyć" } diff --git a/AbuseFilter/i18n/ais.json b/AbuseFilter/i18n/szy.json index 37cc4af3..4c92d3d2 100644 --- a/AbuseFilter/i18n/ais.json +++ b/AbuseFilter/i18n/szy.json @@ -1,8 +1,8 @@ { "@metadata": { "authors": [ - "Bunukwiki", "Benel", + "Bunukwiki", "Tokoabibi" ] }, diff --git a/AbuseFilter/i18n/ta.json b/AbuseFilter/i18n/ta.json index 83367bc8..ca628ca6 100644 --- a/AbuseFilter/i18n/ta.json +++ b/AbuseFilter/i18n/ta.json @@ -1,6 +1,7 @@ { "@metadata": { "authors": [ + "Balajijagadesh", "ElangoRamanujam", "Kanags", "Karthi.dr", @@ -10,20 +11,19 @@ "TRYPPN", "கௌசிக் பிரபு", "செல்வா", - "மதனாஹரன்", - "Balajijagadesh" + "மதனாஹரன்" ] }, "abusefilter-desc": "தொகுப்புகள் தானியங்கியாய் முறைவரிசைப்படுத்துதலைச் செயற்படுத்தும்", - "abusefilter": "முறைகேடு வடிக்கட்டி அமைப்பு", - "abuselog": "முறைகேடு பதிவு", + "abusefilter": "முறைகேட்டு வடிகட்டி மேலாண்மை", + "abuselog": "முறைகேடு வடிகட்டிப் பதிகை", "abusefilter-blocker": "முறைகேடு வடிகட்டி", "abusefilter-accountreserved": "இப்பயனர் கணக்குப்பெயர் முறைகேடு வடிகட்டி பயன்படுத்துவதற்காக ஒதுக்கப்பட்டது", "right-abusefilter-modify": "முறைகேடு வடிகட்டியை மாற்றியமை", "right-abusefilter-view": "முறைகேடு வடிகட்டிகளைப் பார்", "right-abusefilter-log": "முறைகேடு பதிகையைப் பார்", "right-abusefilter-log-detail": "விரிவான முறைகேடு பதிவேட்டுப் பதிவுகளைப் பார்", - "right-abusefilter-private": "தனியார் தரவை முறைகேடு பதிவேட்டில் பார்", + "right-abusefilter-privatedetails": "தனியார் தரவை முறைகேடு பதிவேட்டில் பார்", "right-abusefilter-revert": "குறிப்பிட்ட முறைகேடு வடிகட்டி செய்த அனைத்து மாற்றங்களையும் முன்னிலைக்கு மாற்று", "right-abusefilter-view-private": "தனியாரது எனக் குறிக்கப்பெற்ற முறைகேடு வடிகட்டிகளைப் பார்", "right-abusefilter-hide-log": "முறைகேடு பதிவில் உள்ள உள்ளீடுகளை மறை", @@ -32,10 +32,9 @@ "action-abusefilter-view": "முறைகேடு வடிகட்டியைப் பார்", "action-abusefilter-log": "முறைகேடுப் பதிவேட்டைப் பார்", "action-abusefilter-log-detail": "விரிவான முறைகேடு பதிவேட்டுப் பதிவுகளைப் பார்", - "action-abusefilter-private": "தனியார் தரவை முறைகேடுப் பதிவேட்டில் பார்", + "action-abusefilter-privatedetails": "தனியார் தரவை முறைகேடுப் பதிவேட்டில் பார்", "action-abusefilter-modify-restricted": "முறைகேடு வடிகட்டிகளைக் கட்டுக்குளடங்கிய செயல்களால் மாற்று", "action-abusefilter-revert": "குறிப்பிட்ட முறைகேடு வடிகட்டி செய்த அனைத்து மாற்றங்களையும் முன்னிலைப் படுத்து", - "abusefilter-log": "முறைகேடு வடிகட்டிப் பதிகை", "abusefilter-log-search": "முறைகேட்டுப் பதிவேட்டைத் தேடு", "abusefilter-log-search-user": "பயனர்:", "abusefilter-log-search-filter": "வடிகட்டியின் அடையாள எண்:", @@ -52,13 +51,12 @@ "abusefilter-log-details-var": "மாறி", "abusefilter-log-details-val": "மதிப்பு", "abusefilter-log-details-vars": "செயலுக்கான வினைக்கூறுகள்", - "abusefilter-log-details-private": "தனிப்பட்ட தரவு", + "abusefilter-log-details-privatedetails": "தனிப்பட்ட தரவு", "abusefilter-log-details-ip": "மூல இணைய வழங்கியரின் (IP) முகவரி", "abusefilter-log-noactions": "ஒன்றுமில்லை", "abusefilter-log-details-diff": "தொகுப்பில் செய்த மாற்றங்க்கள்", "abusefilter-log-linkoncontribs": "முறைகேடுகள் பதிவேடு", "abusefilter-log-linkoncontribs-text": "இப்பயனரின் முறைகேடுகள் பதிவேடு", - "abusefilter-log-hidden": "(நுழைவு மறைக்கப்பட்டுள்ளது)", "abusefilter-log-cannot-see-details": "இப் பதிவின் விளக்கவிரிவைக் காண உங்களுக்கு அனுமதி இல்லை.", "abusefilter-log-details-hidden": "பொதுவில் காட்டப்படாத பதிவு என்பதால் இதன் விரிவான குறிப்புகளை நீங்கள் பார்க்க இயலாது", "abusefilter-log-hide-legend": "பதிவேடு உள்ளீட்டை மறை", @@ -66,7 +64,6 @@ "abusefilter-log-hide-hidden": "பொதுப் பார்வையில் இருந்து இப்பதிவை மறை", "abusefilter-log-hide-reason": "காரணம்:", "abusefilter-log-hide-forbidden": "முறைகேட்டுப் பதிவேட்டு உள்ளிடுகைகளை மறைக்க உரிமை இல்லை", - "abusefilter-management": "முறைகேட்டு வடிகட்டி மேலாண்மை", "abusefilter-list": "எல்லா வடிகட்டிகளும்", "abusefilter-list-id": "வடிகட்டி எண்", "abusefilter-list-status": "நிலைமை", @@ -86,6 +83,7 @@ "abusefilter-disabled": "செயலிழக்கம் செய்யப்பட்டுள்ளது", "abusefilter-hitcount": "$1 {{PLURAL:$1|பொருந்தும் தொகுப்பு|பொருந்தும் தொகுப்புகள்}}", "abusefilter-new": "புது வடிகட்டியை உருவாக்கு", + "abusefilter-import-button": "வடிகட்டியை இறக்குமதி செய்", "abusefilter-return": "விடிகட்டி மேலாண்மைக்கு திரும்பு", "abusefilter-status-global": "எங்கும்", "abusefilter-list-options": "விருப்பத்தேர்வுகள்", @@ -212,8 +210,8 @@ "abusefilter-edit-builder-vars-all-links": "புதிய உரையில் உள்ள எல்லா வெளியிணைப்புகள்", "abusefilter-edit-builder-vars-added-links": "தொகுப்பில் சேர்க்கப்பட்ட எல்லா வெளியிணைப்புகள்", "abusefilter-edit-builder-vars-removed-links": "தொகுப்பில் நீக்கப்பட்ட எல்லா வெளியிணைப்புகள்", - "abusefilter-edit-builder-vars-old-text": "தொகுப்புக்கு முன்னரான பழைய பக்க விக்கியுரை", - "abusefilter-edit-builder-vars-new-text": "தொகுப்புக்குப் பின்னரான புதிய பக்க விக்கியுரை", + "abusefilter-edit-builder-vars-old-wikitext": "தொகுப்புக்கு முன்னரான பழைய பக்க விக்கியுரை", + "abusefilter-edit-builder-vars-new-wikitext": "தொகுப்புக்குப் பின்னரான புதிய பக்க விக்கியுரை", "abusefilter-edit-builder-vars-restrictions-edit": "பக்கத்தின் காப்புநிலையைத் தொகு", "abusefilter-filter-log": "அண்மைய வடிகட்டி மாற்றங்கள்", "abusefilter-history": "முறைகேட்டு வடிகட்டி $1 உக்கான வரலாறு", @@ -270,7 +268,6 @@ "abusefilter-topnav-examine": "கடந்த திருத்தங்ககளை ஆய்வு செய்", "abusefilter-topnav-log": "முறைகேடு பதிவு", "abusefilter-topnav-tools": "பிழை திருத்தும் கருவிகள்", - "abusefilter-topnav-import": "வடிகட்டியை இறக்குமதி செய்", "abusefilter-log-name": "முறைகேடு வடிகட்டிப் பதிகை", "abusefilter-log-noresults": "முடிவுகள் ஏதுமில்லை", "abusefilter-diff-title": "பதிப்புகளுக்கிடையிலான வேறுபாடு", diff --git a/AbuseFilter/i18n/tcy.json b/AbuseFilter/i18n/tcy.json index 6f43452f..9fb265dd 100644 --- a/AbuseFilter/i18n/tcy.json +++ b/AbuseFilter/i18n/tcy.json @@ -1,6 +1,7 @@ { "@metadata": { "authors": [ + "Ravi Mundkur", "VASANTH S.N." ] }, @@ -14,7 +15,7 @@ "abusefilter-log-hidelink": "ನೋಟ ಹೊಂದಿಸಾಲೆ", "abusefilter-log-details-val": "ಮೌಲ್ಯ", "abusefilter-log-details-vars": "ಕಾರ್ಯದ ಪರಿಮಿತಿಲು", - "abusefilter-log-details-private": "ಖಾಸಗಿ ದತ್ತಾಂಶ", + "abusefilter-log-details-privatedetails": "ಖಾಸಗಿ ದತ್ತಾಂಶ", "abusefilter-log-details-diff": "ಸಂಪಾದನೆಡ್ ಮಲ್ತಿನ ಬದಲಾವಣೆಲು", "abusefilter-log-linkoncontribs": "ದುರುಪಯೋಗದ ಅನುಕ್ರಮಣಿಕೆ", "abusefilter-log-hide-reason": "ಕಾರಣ:", @@ -49,9 +50,23 @@ "abusefilter-edit-global": "ಜಾಗತಿಕ ಅರಿಪೆ", "abusefilter-edit-rules": "ನಿಬಂಧನೆಲು:", "abusefilter-edit-notes": "ಟಿಪ್ಪಣಿಲು:", + "abusefilter-edit-throttle-hidden-placeholder": "AND ಕೂಡಾರೆ ಅಲ್ಪವಿರಾಮ ಕೊರ್ದು, ಬೊಕ OR ಕೂಡಾರೆ ಗೆರೆಬುಡುದು", + "abusefilter-edit-throttle-placeholder": "AND ಕೂಡಾರೆ ಅಲ್ಪವಿರಾಮ ಕೊರ್ದು, ಬೊಕ OR ಕೂಡಾರೆ ಒಂಜಿ ಒಂಜೆ ಸೇರಾದ್", + "abusefilter-throttle-user": "ಬಳಕೆದಾರೆ ಖಾತೆ", + "abusefilter-throttle-creationdate": "ಖಾತೆ ರಚನೆ ದಿನಾಂಕ", + "abusefilter-throttle-editcount": "ಸಂಪಾದಿ ಲೆಕ್ಕ", + "abusefilter-throttle-site": "ಪೂರ್ಣ ತಾಣ", + "abusefilter-throttle-page": "ಪುಟ", "abusefilter-edit-warn-actions": "ಕ್ರಿಯೆಕ್ಕುಲು:", "abusefilter-edit-history": "ಇತಿಹಾಸೊ:", "abusefilter-edit-tools": "ಉಪಕರಣೊಲು:", + "abusefilter-edit-invalid-warn-message": "ಎಚ್ಚರಿಕೆ ಸಂದೇಶ ಖಾಲಿ ಒರಿಪಾರೆ ಆವಂದ್.", + "abusefilter-edit-invalid-disallow-message": "ಅಸ್ಪದದಾಂತಿನ ಸಂದೇಶ ಖಾಲಿ ಒರಿಪಾವರೆ ಆವಂದ್.", + "abusefilter-edit-invalid-throttlecount": "ಹತೋಟಿ ಕ್ರಿಯೆತ ಲೆಕ್ಕ ಧನಾತ್ಮಕ ಪೂರ್ಣಾಂಕ ಆದಿಪ್ಪೊಡು.", + "abusefilter-edit-invalid-throttleperiod": "ಹತೋಟಿದ ಅವಧಿ ಒಂಜಿ ಧನಾತ್ಮಕ ಪೂರ್ಣಾಂಕ ಆದಿಪ್ಪೊಡು.", + "abusefilter-edit-empty-throttlegroups": "ಕನಿಷ್ಟ ಒಂಜಿ ಹತೋಟಿ ಗುಂಪುನು ಆಯೊಡು.", + "abusefilter-edit-duplicated-throttlegroups": "ಹತೋಟಿ ಗುಂಪುಲೆಡ್ ದ್ವಿಪ್ರತಿಲು ಉಪ್ಪರೆ ಬಲ್ಲಿ.", + "abusefilter-edit-invalid-throttlegroups": "ವಿಸೂಚಿತ ಹತೋಟಿ ಗುಂಪುಲು ಮಾನ್ಯ ಅತ್ತ್.", "abusefilter-edit-builder-op-arithmetic-addition": "ಸಂಕಲನ(+)", "abusefilter-edit-builder-op-arithmetic-subtraction": "ವ್ಯವಕಲನ(-)", "abusefilter-edit-builder-op-arithmetic-multiplication": "ಗುಣಾಕಾರ(*)", diff --git a/AbuseFilter/i18n/te.json b/AbuseFilter/i18n/te.json index 53650b7a..a9196478 100644 --- a/AbuseFilter/i18n/te.json +++ b/AbuseFilter/i18n/te.json @@ -3,14 +3,15 @@ "authors": [ "Chaduvari", "Kiranmayee", + "Matma Rex", + "Pavan santhosh.s", "Ravichandra", "Veeven", - "వైజాసత్య", - "Matma Rex" + "వైజాసత్య" ] }, - "abusefilter": "దుర్వినియోగ వడపోతల స్వరూపణం", - "abuselog": "దురుపయోగాల చర్యానివేదిక", + "abusefilter": "దుర్వినియోగ వడపోతల నిర్వహణ", + "abuselog": "దుర్వినియోగ వడపోతల చిట్టా", "abusefilter-intro": "దుశ్చర్య వడపోతల నిర్వహణ ఇంటర్ఫేసుకు స్వాగతం.\nదుశ్చర్యల వడపోత అనేది ఇక్కడ జరిగే అన్ని చర్యలకు ఆటోమాటిగ్గా వర్తించే నియమాలతో కూడిన సాఫ్టువేరు మెకానిజము.\nవికీలో నిర్వచించిన వడపోతలను ఈ ఇంటర్ఫేసులో చూదవచ్చు, వాటిని మార్చనూ వచ్చు.", "abusefilter-mustviewprivateoredit": "భద్రతా కారణాల దృష్ట్యా, దుర్వినియోగ వడపోతలను మార్చే హక్కున్న వాడుకరులు మాత్రమే ఈ ఇంటర్ఫేసును ఉపయోగించవచ్చు.", "abusefilter-warning": "'''హెచ్చరిక''': ఈ చర్య హానికరమని ఆటోమాటిగ్గా గుర్తించబడింది.\nపసలేని మార్పుచేర్పులు వెంటనే రద్దు చెయ్యబడతాయి,\nకొట్టొచ్చినట్టుగా కనబడే తప్పులు చేసినా, పదేపదే పసలేని మార్పుచేర్పులు చేసినా.. మీ ఖాతా లేదా ఐపీ అడ్రసు నిషేధానికి దారితీయవచ్చు.\nఈ మార్పు సరైనదేనని మీరు నమ్మితే, మళ్ళీ సమర్పించండి.\nమీ చర్యను దుశ్చర్యగా భావించేందుకు దారితీసిన నియమం క్లుప్తంగా ఇది: $1", @@ -26,32 +27,48 @@ "right-abusefilter-view": "దుర్వినియోగ వడపోతలని చూడగలగడం", "right-abusefilter-log": "దుర్వినియోగాల చిట్టాని చూడగలగడం", "right-abusefilter-log-detail": "దుర్వినియోగాల చిట్టా యొక్క వివరణాత్మక పద్దులను చూడగలగడం", - "right-abusefilter-private": "దుర్వినియోగాల చిట్టాలోని అంతరంగిక భోగట్టాని చూడగలగడం", + "right-abusefilter-privatedetails": "దుర్వినియోగాల చిట్టాలోని అంతరంగిక భోగట్టాని చూడగలగడం", "right-abusefilter-modify-restricted": "నియంత్రిత చర్యలతో కూడిన దుర్వినియోగ వడపోతలను మార్చగలగడం", "right-abusefilter-revert": "ఒక నిర్దిష్ట దుశ్చర్య వడపోత యొక్క అన్ని మార్పులని తిప్పికొట్టడం", "right-abusefilter-view-private": "అంతరంగికం అని గుర్తించిన దుర్వినియోగ వడపోతలను చూడగలగడం", "right-abusefilter-log-private": "గోప్యము అని గుర్తించిన వడపోతల లాగ్ వివరాలు చూడడం", "right-abusefilter-hide-log": "దుర్వినియోగ చిట్టా లోని పద్దులను దాచగలగడం", "right-abusefilter-hidden-log": "దాచివున్న దుర్వినియోగ చిట్టా పద్దులను చూడగలగడం", + "right-abusefilter-modify-global": "సార్వత్రిక దుశ్చర్య వడపోతలను సృష్టించడం, సవరించడం", "action-abusefilter-modify": "దుర్వినియోగ వడపోతలను మార్చడానికి", "action-abusefilter-view": "దుర్వినియోగ వడపోతలను చూడడానికి", "action-abusefilter-log": "దుర్వినియోగాల చిట్టాని చూడడానికి", "action-abusefilter-log-detail": "వివరణాత్మకమైన దుర్వినియోగాల చిట్టా పద్దులను చూడడానికి", - "action-abusefilter-private": "దుర్వినియోగాల చిట్టాలో అంతరంగిక భోగట్టాని చూడడానికి", + "action-abusefilter-privatedetails": "దుర్వినియోగాల చిట్టాలో అంతరంగిక భోగట్టాని చూడడానికి", "action-abusefilter-modify-restricted": "నియంత్రిత చర్యలతో కూడిన దుర్వినియోగ వడపోతలను మార్చడానికి", "action-abusefilter-revert": "ఒక నిర్దిష్ట దుశ్చర్య వడపోత యొక్క అన్ని మార్పులని తిప్పికొట్టే", "action-abusefilter-view-private": "అంతరంగికం అని గుర్తించిన దుర్వినియోగ వడపోతలను చూడడానికి", - "abusefilter-log": "దుర్వినియోగ వడపోతల చిట్టా", "abusefilter-log-summary": "ఈ చిట్టా దుర్వినియోగ వడపోతలలో చిక్కుకున్న అన్ని చర్యల జాబితాని చూపిస్తుంది.", "abusefilter-log-search": "దుర్వినియోగాల చిట్టా అన్వేషణ", "abusefilter-log-search-user": "వాడుకరి:", - "abusefilter-log-search-filter": "వడపోత ID:", + "abusefilter-log-search-group": "వడపోత గుంపు:", + "abusefilter-log-search-group-any": "ఏదైనా", + "abusefilter-log-search-filter": "వడపోత IDలు:", + "abusefilter-log-search-filter-help": "పైప్లతో వేరు చేయండి, సార్వత్రిక ఫిల్టర్ల కోసం ముందు \"$1\" చేర్చండి", "abusefilter-log-search-title": "శీర్షిక:", "abusefilter-log-search-wiki": "వికీ:", + "abusefilter-log-search-impact": "ప్రభావం:", + "abusefilter-log-search-impact-all": "అన్ని చర్యలూ", + "abusefilter-log-search-impact-saved": "భద్రపరచిన మార్పులు మాత్రమే", + "abusefilter-log-search-impact-not-saved": "భద్రపరచిన మార్పులు లేకుండా", + "abusefilter-log-search-entries-label": "దృశ్యత (విజిబిలిటీ):", + "abusefilter-log-search-entries-all": "అన్ని పద్దులూ", + "abusefilter-log-search-entries-hidden": "దాచిన పద్దులు మాత్రమే", + "abusefilter-log-search-entries-visible": "కనిపించే పద్దులు మాత్రమే", + "abusefilter-log-search-action-label": "ట్రిగ్గరు చర్య", + "abusefilter-log-search-action-other": "ఇతరాలు", + "abusefilter-log-search-action-any": "ఏదైనా", + "abusefilter-log-search-action-taken-label": "తీసుకున్న చర్య:", + "abusefilter-log-search-action-taken-any": "ఏదైనా", "abusefilter-log-search-submit": "వెతుకు", "abusefilter-log-entry": "$1: $4లో \"$3\" చర్యను చెయ్యడం ద్వారా $2 ఒక దుర్వినియోగ వడపోతను {{GENDER:$8|కదిలించారు}}.\nతీసుకున్న చర్య: $5;\nవడపోత వివరణ: $6", - "abusefilter-log-entry-withdiff": "$1: $2 $4 లో \"$3\" పని చేసి, దుశ్చర్య వడపోతను ప్రేరేపించారు.\nతీసుకున్న చర్య: $5;\nవడపోత వివరం: $6 ($7)", - "abusefilter-log-detailedentry-meta": "↓ $1: $2, $3 ను ప్రయోగించారు. దాంతో $5 పై \"$4\" చర్య జరిగింది.\nజరిగిన చర్యలు: $6;\nవడపోతకం వివరణ: $7 ($8)", + "abusefilter-log-entry-withdiff": "$1: $2, $4 లో \"$3\" {{GENDER:$8|పని చేసి}}, దుశ్చర్య వడపోతను {{GENDER:$8|ప్రేరేపించారు}}.\nతీసుకున్న చర్య: $5;\nవడపోత వివరం: $6 ($7)", + "abusefilter-log-detailedentry-meta": "$1: $2, $5 లో \"$4\" {{GENDER:$9|పని చేసి}}, $3 ను {{GENDER:$9|ప్రేరేపించారు}}.\nతీసుకున్న చర్య: $6;\nవడపోత వివరం: $7 ($8)", "abusefilter-log-detailedentry-global": "సార్వత్రిక వడపోత $1", "abusefilter-log-detailedentry-local": "వడపోత $1", "abusefilter-log-detailslink": "వివరాలు", @@ -61,25 +78,42 @@ "abusefilter-log-details-var": "చరరాశి", "abusefilter-log-details-val": "విలువ", "abusefilter-log-details-vars": "చర్య పరామితులు", - "abusefilter-log-details-private": "అంతరంగిక భోగట్టా", + "abusefilter-log-details-privatedetails": "గోప్య లాగ్ వివరాలు", "abusefilter-log-details-ip": "ఉద్భవించిన ఐ.పీ.చిరునామా", + "abusefilter-log-details-checkuser": "చెక్ యూజర్", "abusefilter-log-noactions": "ఏమీలేవు", "abusefilter-log-details-diff": "దిద్దుబాటులో చేసిన మార్పులు", "abusefilter-log-linkoncontribs": "దుర్వినియోగాల చిట్టా", "abusefilter-log-linkoncontribs-text": "{{GENDER:$1|ఈ వాడుకరి}} దుర్వినియోగాల చిట్టా", - "abusefilter-log-hidden": "(పద్దుని దాచారు)", + "abusefilter-log-linkonhistory": "దుర్వినియోగాల లాగ్ చూడండి", + "abusefilter-log-linkonhistory-text": "ఈ పేజీకి సంబంధించిన దుర్వినియోగాల లాగ్ చూడండి", + "abusefilter-log-linkonundelete": "దుర్వినియోగాల చిట్టా చూడండి", + "abusefilter-log-linkonundelete-text": "ఈ పేజీకి సంబంధించిన దుర్వినియోగాల చిట్టా చూడండి", "abusefilter-log-hidden-implicit": "(కూర్పును తొలగించారు కాబట్టి, అది దాచబడింది)", "abusefilter-log-cannot-see-details": "ఈ ఎంట్రీ వివరాలు చూసే అనుమతి మీకు లేదు.", + "abusefilter-log-cannot-see-privatedetails": "ఈ పద్దు యొక్క గోప్య వివరాలను చూసే అనుమతి మీకు లేదు.", + "abusefilter-log-nonexistent": "ఇచ్చిన ఐడీతో పద్దేమీ లేదు.", "abusefilter-log-details-hidden": "ఈ పద్దు యొక్క వివరాలని మీరు చూడలేరు, ఎందుకంటే దీన్ని బహిరంగ వీక్షణం నుండి దాచేసారు.", + "abusefilter-log-details-hidden-implicit": "ఈ పద్దుకు సంబంధించిన కూర్పును బహిరంగంగా కనిపించకుండా దాచడం చేత మీరు దాని వివరాలను చూడలేరు.", + "abusefilter-log-private-not-included": "మీరిచ్చిన వడపోత ఐడీలు ఒకటి గాని అంత కంటే ఎక్కువ గానీ గోప్యమైనవి. గోప్య వడపోతల వివరాలను చూసే అనుమతి మీకు లేదు కాబట్టి, ఆ వడపోతల కోసం వెతకలేదు.", "abusefilter-log-hide-legend": "చిట్టా పద్దుని దాచండి", "abusefilter-log-hide-id": "చిట్టా పద్దు ID:", "abusefilter-log-hide-hidden": "బహిరంగ వీక్షణం నుండి ఈ పద్దుని దాచు", "abusefilter-log-hide-reason": "కారణం:", + "abusefilter-log-hide-reason-other": "ఇతర/అదనపు కారణం:", "abusefilter-log-hide-forbidden": "దుర్వినియోగ చిట్టా పద్దులను దాచే అనుమతి మీకు లేదు.", - "logentry-abusefilter-hit": "$1, పేజీ $3 లో \"$5\" పని చేసి, $4 ను ప్రేరేపించారు. తీసుకున్న చర్య: $6 ($7)", - "abusefilter-management": "దుర్వినియోగ వడపోతల నిర్వహణ", + "abusefilter-log-entry-suppress": "$1, $3 ను {{GENDER:$2|దాచారు}}", + "abusefilter-log-entry-unsuppress": "$1, $3 ను దాపు నుండి {{GENDER:$2|తీసారు}}", + "logentry-abusefilter-hit": "$1, పేజీ $3 లో \"$5\" {{GENDER:$2|పని చేసి}}, $4 ను {{GENDER:$2|ప్రేరేపించారు}}. తీసుకున్న చర్య: $6 ($7)", + "log-action-filter-abusefilter-create": "కొత్త వడపోత సృష్టి", + "log-action-filter-abusefilter-modify": "వడపోత సవరణ", + "logentry-abusefilterprivatedetails-access": "$1, $3 కు చెందిన గోప్య వివరాలను {{GENDER:$2|చూసారు}}", + "logentry-rights-blockautopromote": "{{GENDER:$4|$3}} ఆటోప్రమోషన్ను $1, $5 పాటు {{GENDER:$2|నిరోధించారు}}", + "logentry-rights-restoreautopromote": "{{GENDER:$4|$3}} ఆటోప్రమోషన్ సామర్థ్యాన్ని, $1 {{GENDER:$2|పునస్థాపించారు}}", + "abusefilterprivatedetails-log-name": "దుశ్చర్య వడపోతల గోప్య వివరాలను చూసిన లాగ్", "abusefilter-list": "అన్ని వడపోతలు", "abusefilter-list-id": "వడపోత ID", + "abusefilter-list-pattern": "సరళి", "abusefilter-list-status": "స్థితి", "abusefilter-list-public": "బహిరంగ వివరణ", "abusefilter-list-consequences": "పరిణామాలు", @@ -95,8 +129,10 @@ "abusefilter-enabled": "సచేతనం", "abusefilter-deleted": "తొలగించారు", "abusefilter-disabled": "అచేతనం", + "abusefilter-throttled": "థ్రాటిల్ అయినవి", "abusefilter-hitcount": "$1 {{PLURAL:$1|హిట్టు|హిట్లు}}", "abusefilter-new": "కొత్త జల్లెడని సృష్టించు", + "abusefilter-import-button": "వడపోత దిగుమతి", "abusefilter-return": "తిరిగి వడపోత నిర్వహణకి", "abusefilter-status-global": "సార్వత్రికం", "abusefilter-list-options": "ఎంపికలు", @@ -108,7 +144,14 @@ "abusefilter-list-options-scope-local": "స్థానిక నియమాలు మాత్రమే", "abusefilter-list-options-scope-global": "సార్వత్రిక నియమాలు మాత్రమే", "abusefilter-list-options-scope-all": "స్థానిక, సార్వత్రిక నియమాలు", + "abusefilter-list-options-further-options": "మరిన్ని వికల్పాలు:", "abusefilter-list-options-hidedisabled": "అచేతన వడపోతలను దాచు", + "abusefilter-list-options-hideprivate": "గోప్య వడపోతలను దాచు", + "abusefilter-list-options-searchfield": "నియమాల్లో వెతుకు:", + "abusefilter-list-options-search-like": "సాదా క్వెరీ", + "abusefilter-list-options-search-rlike": "రెగ్యులర్ ఎక్స్ప్రెషన్", + "abusefilter-list-options-search-irlike": "కేస్-సెన్సిటివ్ రెగ్యులర్ ఎక్స్ప్రెషన్", + "abusefilter-list-regexerror": "వెతుకులాటలో ఏదో లోపం దొర్లింది: రెగ్యులర్ ఎక్స్ప్రెషన్ సింటాక్స్ లోపం.", "abusefilter-list-options-submit": "తాజాకరించు", "abusefilter-tools-text": "దుర్వినియోగ వడపోతకాలను తయారుచెయ్యడంలోను, డీబగ్గింగులోనూ ఉపయోగపడగల పరికరాలు కొన్నింటిని చూడండి.", "abusefilter-tools-expr": "పదబంధపు పరీక్షకం", @@ -121,11 +164,12 @@ "abusefilter-edit-oldwarning": "<strong>ఈ వడపోత యొక్క పాతకూర్పును మారుస్తున్నారు.\nఇచ్చిన గణాంకాలు మాత్రం దీని సరికొత్త కూర్పుకు సంబంధించినవి.\nమీరు మీ మార్పులను భద్రపరిస్తే, సదరు కూర్పు తరువాత జరిగిన మార్పులన్నీ తిరగరాయబడతాయి.</strong> •\n[[Special:AbuseFilter/history/$2|ఈ వడపోత చరితానికి తిరిగివెళ్ళు]].", "abusefilter-edit-status-label": "గణాంకాలు:", "abusefilter-edit-status": "గత $1 {{PLURAL:$1|చర్యలో|చర్యలలో}}, ఈ వడపోత $2 సార్లు సరిపోలింది ($3%).", - "abusefilter-edit-status-profile": "గత $1 {{PLURAL:$1|చర్యలో|చర్యలలో}}, ఈ వడపోత $2 సార్లు సరిపోలింది ($3%).\nసగటున అది నడిచిన సమయం $4 ms, అది నిబంధనల పరిమితిలో $5 {{PLURAL:$5|నిబంధనను|నిబంధనలను}} వినియోగిస్తుంది.", + "abusefilter-edit-throttled-warning": "'''హెచ్చరిక:''' ఈ వడపోత హానికరమైనదని ఆటోమాటిగ్గా గుర్తించబడింది. భద్రతా కారణాల రీత్యా, కింది చర్యలు అమలు కావు ($1). ఈ ఆంక్షను తీసివేసేందుకు, మీ షరతులను ఓసారి మళ్ళీ [[mw:Extension:AbuseFilter/Conditions|అనుకూలీకరించండి]] \n(ఆప్టిమైజు చెయ్యండి).", "abusefilter-edit-new": "కొత్త జల్లెడ", "abusefilter-edit-save": "జల్లెడ భద్రపరచు", "abusefilter-edit-id": "వడపోత ID:", "abusefilter-edit-description": "వివరణ:\n:''(బహిరంగంగా కనిపిస్తుంది)''", + "abusefilter-edit-field-description": "వివరం", "abusefilter-edit-group": "వడపోత గుంపు:", "abusefilter-edit-flags": "పతాకలు:", "abusefilter-edit-enabled": "ఈ వడపోతని చేతనం చేయి", @@ -133,6 +177,7 @@ "abusefilter-edit-hidden": "ఈ వడపోత యొక్క వివరాలని బహిరంగపరచకుండా దాచు", "abusefilter-edit-global": "సార్వత్రిక వడపోత", "abusefilter-edit-rules": "నిబంధనలు:", + "abusefilter-edit-field-conditions": "నిబంధనలు:", "abusefilter-edit-notes": "గమనికలు:", "abusefilter-edit-lastmod": "వడపోత చివరి మార్పు:", "abusefilter-edit-lastmod-text": "$1న $2చే", @@ -140,23 +185,53 @@ "abusefilter-edit-consequences": "జోడి కుదిరినప్పుడు తీసుకోవాల్సిన చర్యలు", "abusefilter-edit-action-warn": "వాడుకరికి ఒక హెచ్చరిక చేసాక, ఈ చర్యలను ప్రేరేపించు", "abusefilter-edit-action-disallow": "వాడుకరి చేసే ఈ చర్యను నిరాకరించు", + "abusefilter-edit-action-blockautopromote": "వాడుకరి ఆటోకన్ఫర్మ్డ్ స్థితిని ఉపసంహరించు", "abusefilter-edit-action-degroup": "వాడుకరిని ముఖ్య అనుమతుల గుంపులన్నిటి నుండి తీసివెయ్యి", "abusefilter-edit-action-block": "ఈ వాడుకరిని/ఐపీ చిరునామాను దిద్దుబాట్లు చేయకుండా నిషేధించు", + "abusefilter-edit-action-blocktalk": "వాడుకరి/ఐపీ అడ్రసు తమ స్వంత చర్చా పేజీలో దిద్దుబాట్లు చెయ్యకుండా నిరోధించు", + "abusefilter-edit-action-throttle": "వాడుకరి పనులు ఒక పరిమితి దాటాకే చర్యలను ప్రేరేపించు", + "abusefilter-edit-action-rangeblock": "వాడుకరి ఏ ఐపీ శ్రేణి నుండి వచ్చాడో ఆ శ్రేణిని నిరోధించు", "abusefilter-edit-action-tag": "ఈ మార్పును సమీక్షార్థం గుర్తు పెట్టు", "abusefilter-edit-throttle-count": "అనుమతించాల్సిన చర్యల సంఖ్య:", - "abusefilter-edit-throttle-period": "కాల వ్యవధి:", + "abusefilter-edit-throttle-period": "కాల వ్యవధి (సెకండ్లలో):", + "abusefilter-edit-throttle-hidden-placeholder": "AND తో జతపరచేందుకు మధ్యలో కామా పెట్టండి, OR తో జతపరచేందుకు లైన్బ్రేక్ ఇవ్వండి", + "abusefilter-edit-throttle-placeholder": "AND తో జతపరచేందుకు మధ్యలో కామా పెట్టండి, OR తో జతపరచేందుకు ఒకదాని కింద ఒకటి ఇవ్వండి", + "abusefilter-throttle-ip": "ఐపీ చిరునామా", + "abusefilter-throttle-user": "వాడుకరి ఖాతా", + "abusefilter-throttle-range": "/16 శ్రేణి", + "abusefilter-throttle-creationdate": "ఖాతా సృష్టించిన తేదీ", + "abusefilter-throttle-editcount": "దిద్దుబాట్ల సంఖ్య", + "abusefilter-throttle-site": "సైటంతా", + "abusefilter-throttle-page": "పేజీ", + "abusefilter-throttle-none": "(ఏమీలేదు)", + "abusefilter-throttle-details": "ప్రతి $2 {{PLURAL:$2|సెకండు|సెకండ్ల}}కూ $1 {{PLURAL:$1|చర్యను|చర్యలను}} అనుమతించు, థ్రాటిల్ను ఇలా గుది గుచ్చు: $3", "abusefilter-edit-warn-message": "హెచ్చరికకై ఉపయోగించాల్సిన వ్యవస్థా సందేశం:", "abusefilter-edit-warn-other": "ఇతర సందేశం", - "abusefilter-edit-warn-other-label": "ఇతర సందేశం యొక్క పేజీ పేరు:\n:''(మీడియావికీ ఉపసర్గ లేకుండా)''", + "abusefilter-edit-warn-other-label": "ఇతర సందేశపు పేజీ పేరు:\n:''(\"మీడియావికీ:\" అన్న ఉపసర్గ లేకుండా)''", "abusefilter-edit-warn-actions": "చర్యలు:", - "abusefilter-edit-warn-preview": "ఎంచుకున్న సందేశాన్ని మునుజూడండి", + "abusefilter-edit-warn-preview": "ఎంచుకున్న సందేశపు మునుజూపు చూపించు/దాచు", "abusefilter-edit-warn-edit": "ఎంచుకున్న సందేశాన్ని సృష్టించండి/మార్చండి", - "abusefilter-edit-tag-tag": "వర్తింపజేయాల్సిన [[Special:Tags|ట్యాగులు]] (పంక్తికి ఒకటి చొప్పున):", + "abusefilter-edit-disallow-message": "నిరాకరించేందుకు ఉపయోగించాల్సిన వ్యవస్థా సందేశం:", + "abusefilter-edit-disallow-other": "ఇతర సందేశం", + "abusefilter-edit-disallow-other-label": "ఇతర సందేశపు పేజీ పేరు:\n:''(\"మీడియావికీ:\" అన్న ఉపసర్గ లేకుండా)''", + "abusefilter-edit-disallow-actions": "చర్యలు:", + "abusefilter-edit-disallow-preview": "ఎంచుకున్న సందేశపు మునుజూపు చూపించు/దాచు", + "abusefilter-edit-disallow-edit": "ఎంచుకున్న సందేశాన్ని సృష్టించండి/మార్చండి", + "abusefilter-edit-tag-tag": "వర్తింపజేయాల్సిన [[Special:Tags|ట్యాగులు]]:", + "abusefilter-edit-tag-placeholder": "ట్యాగులను చేర్చండి (ఒకదాని కింద ఒకటిగా లేదా కామాతో విడదీస్తూ)", + "abusefilter-edit-tag-hidden-placeholder": "ట్యాగులను చేర్చండి (కామాతో విడదీస్తూ)", + "abusefilter-edit-block-anon-durations": "అజ్ఞాత వాడుకరులకు నిరోధ గడువు:", + "abusefilter-edit-block-user-durations": "నమోదైన వాడుకరులకు నిరోధ గడువు:", + "abusefilter-block-anon": "అజ్ఞాత వాడుకరులను నిరోధించు", + "abusefilter-block-user": "నమోదైన వాడుకరులను నిరోధించు", + "abusefilter-block-talk": "చర్చా పేజీ నిరోధించబడినవారు", "abusefilter-edit-denied": "ఈ వడపోత వివరాలను మీరు చూడలేరు. ఎందుకంటే దీన్ని బహిరంగ వీక్షణం నుండి దాచేసారు.", "abusefilter-edit-main": "వడపోత పరామితులు", "abusefilter-edit-done-subtitle": "వడపోతని మార్చారు", "abusefilter-edit-done": "[[Special:AbuseFilter/$1|వడపోత $3]] లో [[Special:AbuseFilter/history/$1/diff/prev/$2|మీరు చేసిన మార్పులను]] భద్రపరచాం.", "abusefilter-edit-badsyntax": "మీరిచ్చిన వడపోతలో ఓ సింటాక్స్ దోషం ఉంది.\nపార్సరు నుంచి వచ్చిన ఔట్పుట్ ఇది: <pre>$1</pre>", + "abusefilter-edit-missingfields": "కింది ఫీల్డులను పూరించడం తప్పనిసరి: $1", + "abusefilter-edit-deleting-enabled": "చేతనంగా ఉన్న వడపోతను తొలగించినట్లుగా గుర్తించలేరు.", "abusefilter-edit-restricted": "ఈ వడపోతను మీరు మార్చలేరు. ఎంచేతంటే, అందులో ఒకటో, మరిన్నో నిరోధిత చర్యలున్నాయి.\nనిరోధిత చర్యలకు అనుమతులు కలిగిన వాడుకరిని అడిగి, సదరు మార్పును చేయించుకోండి.", "abusefilter-edit-viewhistory": "ఈ వడపోత చరిత్రను చూడండి", "abusefilter-edit-history": "చరిత్ర:", @@ -168,10 +243,18 @@ "abusefilter-edit-export": "ఈ వడపోతని వేరే వికీలోనికి ఎగుమతించు", "abusefilter-edit-syntaxok": "సింటాక్సు దోషాలేమీ లేవు.", "abusefilter-edit-syntaxerr": "సింటాక్సు దోషం కనబడింది: $1", - "abusefilter-edit-bad-tags": "మీరిచ్చిన ట్యాగుల్లో ఒకటిగాని, మరిన్నిగానీ చెల్లనివి.\nట్యాగులు చిన్నవిగాను, స్పెషలు కారెక్టర్లేమీ లేకుండానూ ఉండాలి.", + "abusefilter-edit-warn-leave": "ఈ పేజీని వదలి వెళ్తే, ఈ వడపోతకు మీరు చేసిన సవరణలు పోతాయి.", + "abusefilter-edit-bad-tags": "మీరిచ్చిన ట్యాగుల్లో ఒకటిగాని, మరిన్నిగానీ చెల్లనివి.\nట్యాగులు చిన్నవిగాను, స్పెషలు కారెక్టర్లేమీ లేకుండానూ ఉండాలి. వాటిని వేరే సాఫ్టువేర్లేవీ రిజర్వు చేసుకుని ఉండరాదు. మరేదైనా ట్యాగు పేరును ఎంచుకోండి.", "abusefilter-edit-notallowed": "దుర్వినియోగ వడపోతలను సృష్టించడానికి లేదా మార్చడానికి మీకు అనుమతి లేదు", "abusefilter-edit-notallowed-global": "సార్వత్రిక దుశ్చర్య వడపోతలను సృష్టించేందుకు, మార్చేందుకూ మీకు అనుమతులు లేవు", - "abusefilter-edit-notallowed-global-custom-msg": "సార్వత్రిక వడపోతలు ఐచ్ఛిక హెచ్చరిక సందేశాలకు అనుకూలించవు", + "abusefilter-edit-notallowed-global-custom-msg": "సార్వత్రిక వడపోతలకు విశేష హెచ్చరిక సందేశాలు గాని నిరాకరణ సందేశాలు గానీ ఇవ్వరాదు", + "abusefilter-edit-invalid-warn-message": "హెచ్చరిక సందేశాన్ని ఖాళీగా వదిలెయ్యరాదు.", + "abusefilter-edit-invalid-disallow-message": "నిరాకరణ సందేశాన్ని ఖాళీగా వదిలెయ్యరాదు.", + "abusefilter-edit-invalid-throttlecount": "థ్రాటిల్ చర్యల లెక్క ధన పూర్ణ సంఖ్య అయి ఉండాలి.", + "abusefilter-edit-invalid-throttleperiod": "థ్రాటిల్ వ్యవధి ధన పూర్ణ సంఖ్య అయి ఉండాలి.", + "abusefilter-edit-empty-throttlegroups": "కనీసం ఒక థ్రాటిల్ శ్రేణిని ఎంచుకోవాలి.", + "abusefilter-edit-duplicated-throttlegroups": "థ్రాటిల్ శ్రేణులకు నకళ్ళు ఉండరాదు.", + "abusefilter-edit-invalid-throttlegroups": "ఇచ్చిన థ్రాటిల్ శ్రేణులు సరైనవి కావు.", "abusefilter-edit-builder-select": "కర్సరు ఉన్న స్థలంలో చేర్చాల్సిన వికల్పాన్ని ఎంచుకోండి", "abusefilter-edit-builder-group-op-arithmetic": "అంకగణిత కారకాలు", "abusefilter-edit-builder-op-arithmetic-addition": "కూడిక (+)", @@ -181,8 +264,10 @@ "abusefilter-edit-builder-op-arithmetic-modulo": "Modulo (%)", "abusefilter-edit-builder-op-arithmetic-pow": "వర్గం (**)", "abusefilter-edit-builder-group-op-comparison": "పోలిక కారకాలు", - "abusefilter-edit-builder-op-comparison-equal": "సరిసమానం (==)", - "abusefilter-edit-builder-op-comparison-notequal": "సరిసమానం కాదు (!=)", + "abusefilter-edit-builder-op-comparison-equal": "విలువ సమానం (==)", + "abusefilter-edit-builder-op-comparison-equal-strict": "విలువ, రకం సమానం (===)", + "abusefilter-edit-builder-op-comparison-notequal": "విలువ సమానం కాదు (!=)", + "abusefilter-edit-builder-op-comparison-notequal-strict": "విలువ, రకం సమానం కాదు (===)", "abusefilter-edit-builder-op-comparison-lt": "కంటే తక్కువ (<)", "abusefilter-edit-builder-op-comparison-gt": "కంటే ఎక్కువ (>)", "abusefilter-edit-builder-op-comparison-lte": "తక్కువ లేదా సరిసమానం (<=)", @@ -204,54 +289,85 @@ "abusefilter-edit-builder-funcs-length": "పదబంధపు పొడవు (length)", "abusefilter-edit-builder-funcs-lcase": "లోవరు కేసుకు (lcase)", "abusefilter-edit-builder-funcs-ucase": "అప్పరు కేసుకు (ucase)", + "abusefilter-edit-builder-funcs-ccnorm": "సందిగ్ధం కలిగించే క్యరెక్టర్లను నార్మలైజు చెయ్యి (ccnorm)", + "abusefilter-edit-builder-funcs-rmdoubles": "జమిలి-క్యారెక్టర్లను తీసివెయ్యి (rmdoubles)", "abusefilter-edit-builder-funcs-specialratio": "ప్రత్యేక అక్షరాలు / మొత్తం అక్షరాలు (specialratio)", + "abusefilter-edit-builder-funcs-norm": "నార్మలైజు చెయ్యి (norm)", "abusefilter-edit-builder-funcs-count": "స్ట్రింగ్ Y లో స్ట్రింగ్ X కనబడే తడవలు (లెక్కింపు)", + "abusefilter-edit-builder-funcs-rcount": "Y అనే స్ట్రింగులో X అనే రెగెక్సు కనిపించే సార్లు (rcount)", "abusefilter-edit-builder-funcs-rmwhitespace": "ఖాళీలను తొలగించు (rmwhitespace)", "abusefilter-edit-builder-funcs-rmspecials": "ప్రత్యేక అక్షరాలను తొలగించు (rmspecials)", "abusefilter-edit-builder-funcs-ip_in_range": "ఐపీ హద్దుల్లోనే ఉందా? (ip_in_range)", + "abusefilter-edit-builder-funcs-contains-any": "OR మోడ్లో ఒకటి కంటే ఎక్కువ సబ్స్ట్రింగులను వెతికేందుకు వెతుకులాట స్ట్రింగు. (contains_any)", + "abusefilter-edit-builder-funcs-contains-all": "AND మోడ్లో ఒకటి కంటే ఎక్కువ సబ్స్ట్రింగులను వెతికేందుకు వెతుకులాట స్ట్రింగు. (contains_all)", + "abusefilter-edit-builder-funcs-equals-to-any": "ఇచ్చిన ఆర్గ్యుమెంటు కింది ఆర్గ్యుమెంట్లలో దేనితోనైనా సమానంగా ఉందేమో (===) చూడు (equals_to_any)", + "abusefilter-edit-builder-funcs-substr": "సబ్స్ట్రింగు (substr)", + "abusefilter-edit-builder-funcs-strpos": "స్ట్రింగులో సబ్స్ట్రింగు ఉన్న స్థానం (strpos)", + "abusefilter-edit-builder-funcs-str_replace": "సబ్స్ట్రింగును తీసి స్ట్రింగును పెట్టు (str_replace)", "abusefilter-edit-builder-funcs-set_var": "చరరాశిని సెట్ చెయ్యి (set_var)", "abusefilter-edit-builder-group-vars": "చరరాశులు", "abusefilter-edit-builder-vars-accountname": "ఖాతా పేరు (ఖాతాని సృష్టించేప్పుడు)", "abusefilter-edit-builder-vars-timestamp": "మార్పు యొక్క యూనిక్స్ కాలముద్ర", + "abusefilter-edit-builder-vars-timestamp-expanded": "లాగ్ యొక్క టైమ్స్టాంప్", "abusefilter-edit-builder-vars-action": "చర్య", "abusefilter-edit-builder-vars-addedlines": "మార్పులో చేర్చిన పంక్తులు", "abusefilter-edit-builder-vars-delta": "మార్పులో మారిన పరిమాణం", "abusefilter-edit-builder-vars-diff": "సవరణ ద్వారా జరిగిన అన్ని మార్పులు", "abusefilter-edit-builder-vars-newsize": "కొత్త పేజీ పరిమాణం", "abusefilter-edit-builder-vars-oldsize": "పాత పేజీ పరిమాణం", + "abusefilter-edit-builder-vars-old-content-model": "పాత కంటెంటు మోడల్", + "abusefilter-edit-builder-vars-new-content-model": "కొత్త కంటెంటు మోడల్", "abusefilter-edit-builder-vars-removedlines": "మార్పులో తొలగించిన పంక్తులు", "abusefilter-edit-builder-vars-summary": "మార్పు సంగ్రహం/కారణం", "abusefilter-edit-builder-vars-page-id": "పుట ID", "abusefilter-edit-builder-vars-page-ns": "పేజీ పేరుబరి", "abusefilter-edit-builder-vars-page-title": "పేజీ శీర్షిక (పేరుబరి లేకుండా)", "abusefilter-edit-builder-vars-page-prefixedtitle": "పేజీ పూర్తి శీర్షిక", + "abusefilter-edit-builder-vars-page-age": "పేజీ వయసు (సెకండ్లలో)", "abusefilter-edit-builder-vars-movedfrom-id": "తరలింపు మూల పుట యొక్క పుట ID", "abusefilter-edit-builder-vars-movedfrom-ns": "తరలింపు మూల పుట యొక్క పేరుబరి", "abusefilter-edit-builder-vars-movedfrom-title": "తరలింపు మూల పుట యొక్క శీర్షిక", "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "తరలింపు మూల పుట యొక్క పూర్తి శీర్షిక", + "abusefilter-edit-builder-vars-movedfrom-age": "తరలింపు మూలం పేజీ వయసు (సెకండ్లలో)", "abusefilter-edit-builder-vars-movedto-id": "తరలింపు గమ్యస్థాన పుట యొక్క పుట ID", "abusefilter-edit-builder-vars-movedto-ns": "తరలింపు గమ్యస్థాన పుట యొక్క పేరుబరి", "abusefilter-edit-builder-vars-movedto-title": "తరలింపు గమ్యస్థాన పేజీ యొక్క శీర్షిక", "abusefilter-edit-builder-vars-movedto-prefixedtitle": "తరలింపు గమ్యస్థాన పేజీ యొక్క పూర్తి శీర్షిక", - "abusefilter-edit-builder-vars-user-editcount": "వాడుకరి యొక్క మార్పుల సంఖ్య", + "abusefilter-edit-builder-vars-movedto-age": "తరలింపు గమ్యం పేజీ వయసు (సెకండ్లలో)", + "abusefilter-edit-builder-vars-user-editcount": "వాడుకరి మార్పుల సంఖ్య", "abusefilter-edit-builder-vars-user-age": "వాడుకరి ఖాతా యొక్క వయసు", - "abusefilter-edit-builder-vars-user-name": "వాడుకరి ఖాతా యొక్క పేరు", + "abusefilter-edit-builder-vars-user-name": "వాడుకరి ఖాతా పేరు", "abusefilter-edit-builder-vars-user-groups": "వాడుకరి ఉన్న (అవ్యక్తమైన వాటితో సహా) గుంపులు", "abusefilter-edit-builder-vars-user-rights": "వాడుకరి హక్కులు", "abusefilter-edit-builder-vars-user-blocked": "వాడుకరి నిరోధించబడి ఉన్నారా", "abusefilter-edit-builder-vars-user-emailconfirm": "ఈమెయిలు చిరునామాని నిర్ధారించిన సమయం", "abusefilter-edit-builder-vars-recent-contributors": "ఈ పుటకి తోడ్పడిన చివరి పదుగురు వాడుకరులు", "abusefilter-edit-builder-vars-first-contributor": "ఈ పేజీలో రాసిన మొట్టమొదటి వాడుకరి", + "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "తరలింపు మూలం పేజీలో దిద్దుబాట్లు చేసిన చివరి పది మంది వాడుకరులు", + "abusefilter-edit-builder-vars-movedfrom-first-contributor": "తరలింపు మూలం పేజీలో దిద్దుబాటు చేసిన మొట్టమొదటి వాడుకరి", + "abusefilter-edit-builder-vars-movedto-recent-contributors": "తరలింపు గమ్యం పేజీలో దిద్దుబాట్లు చేసిన చివరి పది మంది వాడుకరులు", + "abusefilter-edit-builder-vars-movedto-first-contributor": "తరలింపు గమ్యం పేజీలో దిద్దుబాటు చేసిన మొట్టమొదటి వాడుకరి", "abusefilter-edit-builder-vars-all-links": "కొత్త పాఠ్యం లోని అన్ని బయటి లంకెలు", "abusefilter-edit-builder-vars-added-links": "మార్పులో చేర్చిన అన్ని బయటి లంకెలు", "abusefilter-edit-builder-vars-removed-links": "మార్పులో తొలగించిన అన్ని బయటి లంకెలు", - "abusefilter-edit-builder-vars-old-text": "పాత పేజీ యొక్క వికీపాఠ్యం, మార్పుకి ముందు", - "abusefilter-edit-builder-vars-new-text": "కొత్త పేజీ యొక్క వికీపాఠ్యం, మార్పు తర్వాత", - "abusefilter-edit-builder-vars-new-text-stripped": "కొత్త పుట పాఠ్యం, ఏదైనా మార్కప్ ఉంటే తీసివేసి", + "abusefilter-edit-builder-vars-old-wikitext": "పాత పేజీ యొక్క వికీపాఠ్యం, మార్పుకి ముందు (ఇప్పుడు వాడుకలో లేదు)", + "abusefilter-edit-builder-vars-new-wikitext": "కొత్త పేజీ యొక్క వికీపాఠ్యం, మార్పు తర్వాత", + "abusefilter-edit-builder-vars-new-pst": "కొత్త పేజీ యొక్క వికీపాఠ్యం, భద్రపరచే ముందు ట్రాన్స్ఫార్మ్ అయ్యాక", + "abusefilter-edit-builder-vars-addedlines-pst": "దిద్దుబాటులో చేర్చిన లైన్లు, భద్రపరచే ముందు ట్రాన్స్ఫార్మ్ అయ్యాక", + "abusefilter-edit-builder-vars-new-text": "కొత్త పుట పాఠ్యం, ఏదైనా మార్కప్ ఉంటే తీసివేసి", "abusefilter-edit-builder-vars-restrictions-edit": "పేజీ యొక్క మార్పుల సంరక్షణా స్థాయి", "abusefilter-edit-builder-vars-restrictions-move": "పేజీ యొక్క తరలింపు సంరక్షణా స్థాయి", "abusefilter-edit-builder-vars-restrictions-create": "పేజీకి రక్షణా వలయాన్ని సృష్టించండి", - "abusefilter-edit-builder-vars-old-text-stripped": "పాత పుట పాఠ్యం, ఏదైనా మార్కప్ ఉంటే తీసివేసి", + "abusefilter-edit-builder-vars-restrictions-upload": "దస్త్రం ఎక్కింపు-సంరక్షణ", + "abusefilter-edit-builder-vars-movedfrom-restrictions-edit": "తరలింపు మూలం పేజీ దిద్దుబాటు-సంరక్షణ స్థాయి", + "abusefilter-edit-builder-vars-movedfrom-restrictions-move": "తరలింపు మూలం పేజీ తరలింపు-సంరక్షణ స్థాయి", + "abusefilter-edit-builder-vars-movedfrom-restrictions-create": "తరలింపు మూలం పేజీ సృష్టి-సంరక్షణ", + "abusefilter-edit-builder-vars-movedfrom-restrictions-upload": "తరలింపు మూలం దస్త్రం ఎక్కింపు-సంరక్షణ", + "abusefilter-edit-builder-vars-movedto-restrictions-edit": "తరలింపు గమ్యం పేజీ దిద్దుబాటు-సంరక్షణ స్థాయి", + "abusefilter-edit-builder-vars-movedto-restrictions-move": "తరలింపు గమ్యం పేజీ తరలింపు-సంరక్షణ స్థాయి", + "abusefilter-edit-builder-vars-movedto-restrictions-create": "తరలింపు గమ్యం పేజీ సృష్టి-సంరక్షణ", + "abusefilter-edit-builder-vars-movedto-restrictions-upload": "తరలింపు గమ్యం దస్త్రం ఎక్కింపు-సంరక్షణ", + "abusefilter-edit-builder-vars-old-text": "పాత పుట పాఠ్యం, ఏదైనా మార్కప్ ఉంటే తీసివేసి", "abusefilter-edit-builder-vars-old-links": "ఈ పేజీలోని లంకెలు, మార్పుకి ముందు", "abusefilter-edit-builder-vars-minor-edit": "మార్పు చిన్న మార్పుగా గుర్తించబడినదా లేదా", "abusefilter-edit-builder-vars-file-sha1": "దస్త్రం యొక్క SHA1 సంగ్రహం", @@ -260,7 +376,7 @@ "abusefilter-edit-builder-vars-file-height": "దస్త్రం ఎత్తు, పిక్సెళ్ళలో", "abusefilter-filter-log": "ఇటీవలి వడపోతల మార్పులు", "abusefilter-history": "దుర్వినియోగ వడపోత #$1 యొక్క మార్పుల చరిత్ర", - "abusefilter-history-foruser": "$1 యొక్క మార్పులు", + "abusefilter-history-foruser": "$1 మార్పులు", "abusefilter-history-hidden": "దాచినది", "abusefilter-history-enabled": "చేతనమైంది", "abusefilter-history-global": "సార్వత్రిక", @@ -278,7 +394,7 @@ "abusefilter-history-select-user": "వాడుకరి:", "abusefilter-history-select-submit": "మెరుగుపరచు", "abusefilter-history-diff": "మార్పులు", - "abusefilter-history-error-hidden": "మీరు అభ్యర్థించిన వడపోత దాచబడి ఉంది, మరియు మీరు దాని చరిత్రని చూడలేరు.", + "abusefilter-history-error-hidden": "మీరు అభ్యర్థించిన వడపోత దాచబడి ఉంది. మీరు దాని చరిత్రని చూడజాలరు.", "abusefilter-exception-unexpectedatend": "$1 వ అక్షరం దగ్గర \"$2\" ని ఊహించలేదు.", "abusefilter-exception-expectednotfound": "$1 అక్షరం వద్ద $2 ఉండాలి, కానీ లేదు (దానిబదులుగా $3 $4 ఉంది).", "abusefilter-exception-unrecognisedkeyword": "$1వ అక్షరం వద్ద గుర్తుతెలియని కీపదం $2.", @@ -300,7 +416,7 @@ "abusefilter-revert-periodstart": "సమయ ప్రారంభం:", "abusefilter-revert-periodend": "సమయ ముగింపు:", "abusefilter-revert-search": "చర్యలను ఎంచుకోండి", - "abusefilter-revert-filter": "వడపోత:", + "abusefilter-revert-filter": "వడపోత ఐడీ:", "abusefilter-revert-confirm": "నిర్ధారించు", "abusefilter-revert-reasonfield": "కారణం:", "abusefilter-test-legend": "వడపోత పరీక్ష", @@ -310,6 +426,13 @@ "abusefilter-test-period-start": "తర్వాత చేసిన మార్పులు:", "abusefilter-test-period-end": "ముందు జరిగిన మార్పులు:", "abusefilter-test-page": "పేజీకి చేసిన మార్పులు:", + "abusefilter-test-action": "చర్య రకం:", + "abusefilter-test-search-type-all": "అన్ని చర్యలూ", + "abusefilter-test-search-type-edit": "దిద్దుబాట్లు", + "abusefilter-test-search-type-move": "తరలింపులు", + "abusefilter-test-search-type-delete": "తొలగింపులు", + "abusefilter-test-search-type-upload": "ఎక్కింపులు", + "abusefilter-test-search-type-createaccount": "ఖాతా సృష్టింపులు", "abusefilter-changeslist-examine": "పరిశీలించు", "abusefilter-examine": "వ్యక్తిగత మార్పులను పరిశీలించు", "abusefilter-examine-legend": "మార్పులని ఎంచుకోండి", @@ -324,13 +447,15 @@ "abusefilter-examine-noresults": "మీరు ఇచ్చిన అన్వేషణ పరామితులకి ఏ ఫలితాలూ లేవు.", "abusefilter-topnav": "'''దుర్వినియోగ వడపోతల మార్గసూచీ'''", "abusefilter-topnav-home": "ముంగిలి", + "abusefilter-topnav-recentchanges": "ఇటీవలి వడపోతల మార్పులు", "abusefilter-topnav-test": "టోకు పరీక్ష", "abusefilter-topnav-examine": "గత మార్పులను పరిశీలించు", "abusefilter-topnav-log": "దుర్వినియోగాల చిట్టా", "abusefilter-topnav-tools": "డీబగ్గింగు పరకరాలు", - "abusefilter-topnav-import": "వడపోత దిగుమతి", "abusefilter-log-name": "దుర్వినియోగ వడపోతల చిట్టా", "abusefilter-log-header": "వడపోతలకు జరిగిన మార్పుల సంగ్రహాన్ని ఈ చిట్టా చూపిస్తుంది.\nపూర్తి వివరాల కొరకు, ఇటీవలి [[Special:AbuseFilter/history|వడపోత మార్పుల జాబితా]]ని చూడండి.", + "abusefilter-logentry-create": "$1, $4 ($5) ను {{GENDER:$2|సృష్టించారు}}", + "abusefilter-logentry-modify": "$1, $4 ($5) ను {{GENDER:$2|సవరించారు}}", "abusefilter-log-noresults": "ఫలితాలు లేవు", "abusefilter-diff-title": "కూర్పుల మధ్య తేడాలు", "abusefilter-diff-item": "అంశం", @@ -343,5 +468,16 @@ "abusefilter-diff-next": "కొత్త మార్పు", "abusefilter-import-intro": "ఇతర వికీల నుండి వడపోతకాలను దిగుమతి చేసుకునేందుకు ఈ ఇంటరుఫేసును వాడవచ్చు.\nమూలవికీలో, ఎడిటింగ్ ఇంటరుఫేసులోని \"{{int:abusefilter-edit-tools}}\" కింద ఉన్న \"{{int:abusefilter-edit-export}}\" ను నొక్కండి.\nఅప్పుడు కనిపించే టెక్స్టుబాక్సులో ఉన్న పాఠ్యాన్ని కాపీ చేసుకుని, దాన్ని ఈ టెక్స్టుబాక్సులో పేస్టు చెయ్యండి. ఆ తరవాత \"{{int:abusefilter-import-submit}}\" నొక్కండి.", "abusefilter-import-submit": "భోగట్టాని దిగుమతించు", - "abusefilter-group-default": "అప్రమేయం" + "abusefilter-group-default": "అప్రమేయం", + "abusefilter-http-error": "HTTP లోపమేదో దొర్లింది: $1.", + "abusefilter-view-privatedetails-reason": "గోప్య వివరాలను చూడటానికి కారణం:", + "abusefilter-log-details-id": "లాగ్ ఐడీ", + "abusefilter-invalid-request": "సరైన అభ్యర్ధన కాదు! [[Special:AbuseLog/$1]] వద్ద ఉన్న ఫారములో కారణం చెప్పి గోప్య లాగ్ వివరాలను చూడాలి.", + "abusefilter-invalid-request-noid": "సరైన అభ్యర్ధన కాదు! దుశ్చర్యల లాగ్ వద్ద ఉన్న ఫారములో కారణం చెప్పి గోప్య లాగ్ వివరాలను చూడాలి.", + "log-description-abusefilterprivatedetails": "దుశ్చర్యల లాగ్ యొక్క గోప్య వివరాలను ఓ వాడుకరి ఎన్ని సార్లు చూసారో ఈ లాగ్ చూపిస్తుంది.", + "abusefilter-noreason": "హెచ్చరిక: ఈ లాగ్ యొక్క గోప్య వివరాలను చూడాలంటే, కారణం చెప్పాలి.", + "abusefilter-log-ip-not-available": "అందుబాటులో లేదు", + "abusefilter-tag-reserved": "<code>abusefilter-condition-limit</code> ట్యాగును దుశ్చర్యవడపోత అంతర్గత వినియోగం కోసం రిజర్వు చేసాం.", + "tag-abusefilter-condition-limit": "నిబంధనల పరిమితి అందుకుంది", + "tag-abusefilter-condition-limit-description": "చేతనంగా ఉన్న [[Special:AbuseFilter|దుశ్చర్య వడపోతలన్నీ]] కూడా పరిశీలించలేని దిద్దుబాట్లు, ఇతర ఘటనలు ([[mw:Extension:AbuseFilter/Conditions|సహాయం]])." } diff --git a/AbuseFilter/i18n/tg-cyrl.json b/AbuseFilter/i18n/tg-cyrl.json index e5ab2a57..23442b16 100644 --- a/AbuseFilter/i18n/tg-cyrl.json +++ b/AbuseFilter/i18n/tg-cyrl.json @@ -8,11 +8,20 @@ "abusefilter-warning": "'''Таваҷҷӯҳ'''. Амали зерин ба таври автоматӣ чун нохуб ҳисобида шуд. Вироишоти нолозим вогардонӣ мешавад,\nдашном ва/ё вироишоти ғайризабонӣ ба басташавии ҳисоби корбарӣ ва ё IP-адресатон меорад.\nАгар шумо боварӣ доред, ки вироишатон лозима аст, лутфан тугмаи фиристан ё захира карданро бори дигар пахш кунед. \nТавзеҳоти хурди ин қоида: $1", "abusefilter-log-search-user": "Корбар:", "abusefilter-log-search-title": "Унвон:", + "abusefilter-log-search-action-other": "Дигар", "abusefilter-log-search-submit": "Ҷустуҷӯ", + "abusefilter-log-diff": "фарқият", "abusefilter-log-details-val": "Қимат", + "abusefilter-log-details-checkuser": "Бозрасии корбар", + "abusefilter-log-noactions": "ҳеҷ як", + "abusefilter-log-cannot-see-privatedetails": "Шумо иҷозат барои дидани ҷузъиёти хусусии вурудиро надоред.", "abusefilter-list-edit": "Вироиш", + "abusefilter-edit-new": "Филтри нав", + "abusefilter-edit-save": "Захираи филтр", "abusefilter-edit-builder-vars-old-content-model": "Навъи таркибии саҳифа", "abusefilter-edit-builder-vars-page-id": "Рамзи саҳифа", "abusefilter-examine-submit": "Ҷустуҷӯ", - "abusefilter-diff-item": "Элемент" + "abusefilter-diff-item": "Элемент", + "abusefilter-group-default": "Пешфарз", + "abusefilter-view-privatedetails-legend": "Дидани ҷузъиёти хусусӣ" } diff --git a/AbuseFilter/i18n/th.json b/AbuseFilter/i18n/th.json index f236181f..bdf82c3a 100644 --- a/AbuseFilter/i18n/th.json +++ b/AbuseFilter/i18n/th.json @@ -1,108 +1,154 @@ { "@metadata": { "authors": [ + "Aefgh39622", "Akkhaporn", "Ans", + "B20180", + "Geonuch", "Harley Hartwell", "Horus", "Korrawit", + "Matma Rex", "Nullzero", "Octahedron80", "Passawuth", - "Woraponboonkerd", - "Matma Rex" + "Patsagorn Y.", + "Woraponboonkerd" ] }, "abusefilter-desc": "วิเคราะห์พฤติกรรมการแก้ไขอัตโนมัติ", - "abusefilter": "โครงแบบตัวกรองการละเมิดกฎ", - "abuselog": "ปูมการละเมิดกฎ", - "abusefilter-intro": "ยินดีต้อนรับสู่อินเตอร์เฟซการจัดการตัวกรองการละเมิดกฎ\nตัวกรองการละเมิดกฎเป็นซอฟต์แวร์อัตโนมัติในการวิเคราะห์พฤติกรรมการกระทำทั้งหมด\nอินเตอร์เฟซนี้แสดงรายการตัวกรองที่กำหนดไว้และสามารถแก้ไขได้", - "abusefilter-warning": "'''คำเตือน''': การกระทำนี้ถูกระบุว่าไม่เหมาะสมอัตโนมัติ\nการแก้ไขที่ไม่เหมาะสมหรือเป็นภัยต่อระบบจะถูกย้อนกลับโดยเร็ว\nและการแก้ไขที่ไม่สร้างสรรค์อย่างยิ่ง หรือซ้ำหลายครั้งจะส่งผลให้บัญชีหรือเลขที่อยู่ไอพีของคุณถูกบล็อก\nหากคุณเชื่อว่าการกระทำนี้สร้างสรรค์ คุณอาจส่งอีกครั้งเพื่อยืนยัน\nคำอธิบายอย่างย่อเกี่ยวกับการละเมิดกฎที่ตรงกับการกระทำของคุณ: $1", + "abusefilter": "การจัดการตัวกรองการละเมิดกฎ", + "abuselog": "ปูมตัวกรองการละเมิด", + "abusefilter-intro": "ยินดีต้อนรับสู่อินเทอร์เฟซการจัดการตัวกรองการละเมิดกฎ\nตัวกรองการละเมิดกฎเป็นซอฟต์แวร์อัตโนมัติในการวิเคราะห์พฤติกรรมการกระทำทั้งหมด\nอินเทอร์เฟซนี้แสดงรายการตัวกรองที่กำหนดไว้และสามารถแก้ไขได้", + "abusefilter-mustviewprivateoredit": "เฉพาะผู้ใช้ที่มีสิทธิแก้ไขตัวกรองการละเมิดกฎเท่านั้นที่สามารถใช้อินเทอร์เฟซนี้ เพื่อความปลอดภัย", + "abusefilter-warning": "'''คำเตือน''': การกระทำนี้ถูกระบุว่าไม่เหมาะสมอัตโนมัติ\nการกระทำที่ไม่เหมาะสมหรือเป็นภัยต่อระบบจะถูกแปลงกลับอย่างรวดเร็ว\nและการแก้ไขที่ไม่สร้างสรรค์อย่างยิ่ง หรือซ้ำหลายครั้งจะส่งผลให้บัญชีหรือเลขที่อยู่ไอพีของคุณถูกบล็อก\nหากคุณเชื่อว่าการกระทำนี้สร้างสรรค์ คุณสามารถส่งอีกครั้งเพื่อยืนยันได้\nคำอธิบายอย่างย่อเกี่ยวกับการละเมิดกฎที่ตรงกับการกระทำของคุณ: $1", "abusefilter-disallowed": "การกระทำนี้ถูกระบุว่าไม่เหมาะสมอัตโนมัติ จึงไม่ได้รับอนุญาตให้ดำเนินการต่อ\nหากคุณเชื่อว่าการกระทำของคุณสร้างสรรค์ โปรดแจ้งผู้ดูแลระบบถึงสิ่งที่คุณพยายามทำ\nคำอธิบายโดยสรุปเกี่ยวกับการละเมิดกฎที่ตรงกับการกระทำของคุณ คือ $1", - "abusefilter-blocked-display": "การดำเนินการนี้ถูกระบุว่าไม่เหมาะสมอัตโนมัติ\nและคุณถูกกันมิให้ดำเนินการ\nนอกจากนี้ เพื่อปกป้อง {{SITENAME}} บัญชีผู้ใช้ของคุณและทุกเลขที่อยู่ไอพีที่เกี่ยวข้องถูกบล็อกมิให้แก้ไขแล้ว\nหากสิ่งนี้เกิดจากข้อผิดพลาด โปรดติดต่อผู้ดูแลระบบ\nคำอธิบายโดยสรุปเกี่ยวกับการละเมิดกฎที่ตรงกับการกระทำของคุณ คือ $1", + "abusefilter-blocked-display": "การดำเนินการนี้ถูกระบุว่าไม่เหมาะสมอัตโนมัติ\nและคุณถูกป้องกันไม่ให้ดำเนินการต่อ\nนอกจากนี้ เพื่อปกป้อง {{SITENAME}} บัญชีผู้ใช้ของคุณและทุกเลขที่อยู่ไอพีที่เกี่ยวข้องถูกบล็อกไม่ให้แก้ไขแล้ว\nหากสิ่งนี้เกิดจากข้อผิดพลาด โปรดติดต่อผู้ดูแลระบบ\nคำอธิบายโดยสรุปเกี่ยวกับการละเมิดกฎที่ตรงกับการกระทำของคุณ คือ $1", "abusefilter-degrouped": "การกระทำนี้ถูกระบุว่าไม่เหมาะสมอัตโนมัติ\nจึงไม่ได้รับอนุญาต และเนื่องจากต้องสงสัยว่าบัญชีของคุณตกอยู่ในมือผู้อื่น สิทธิทั้งหมดจึงถูกเพิกถอน\nหากคุณเชื่อว่าเป็นข้อผิดพลาด โปรดติดต่อผู้ดูแลสิทธิแต่งตั้งพร้อมคำอธิบายการกระทำนี้ และคุณอาจได้รับสิทธิคืน\nคำอธิบายโดยสรุปเกี่ยวกับการละเมิดกฎที่ตรงกับการกระทำของคุณ คือ $1", "abusefilter-autopromote-blocked": "การกระทำนี้ถูกระบุว่าไม่เหมาะสมอัตโนมัติ และไม่อนุญาตให้ดำเนินการต่อ\nนอกจากนี้ ตามมาตรการรักษาความปลอดภัย สิทธิพิเศษบางอย่างที่ปกติมอบให้บัญชีที่ได้รับการรับรองถูกเพิกถอนจากบัญชีของคุณชั่วคราว\nคำอธิบายโดยสรุปเกี่ยวกับการละเมิดกฎที่ตรงกับการกระทำของคุณ คือ $1", "abusefilter-blocker": "ตัวกรองการละเมิดกฎ", "abusefilter-blockreason": "ถูกตัวกรองการละเมิดกฎบล็อกอัตโนมัติ\nรายละเอียดของกฎที่ตรงกัน: $1", "abusefilter-degroupreason": "สิทธิถูกตัวกรองการละเมิดกฎริบอัตโนมัติ\nคำอธิบายกฎ: $1", + "abusefilter-blockautopromotereason": "การเลื่อนระดับอัตโนมัติถูกหน่วงเวลาโดยอัตโนมัติโดยตัวกรองการละเมิดกฎ\nคำอธิบายกฎ: $1", "abusefilter-accountreserved": "ชื่อบัญชีนี้สงวนไว้สำหรับการใช้งานโดยตัวกรองการละเมิดกฎ", - "right-abusefilter-modify": "แก้ไขตัวกรองการละเมิดกฎ", + "right-abusefilter-modify": "สร้างหรือดัดแปรตัวกรองการละเมิด", "right-abusefilter-view": "ดูตัวกรองการละเมิดกฎ", "right-abusefilter-log": "ดูปูมการละเมิดกฎ", - "right-abusefilter-log-detail": "ดูรายละเอียดหน่วยปูมการละเมิดกฎ", - "right-abusefilter-private": "ดูข้อมูลส่วนตัวในปูมการละเมิดกฎ", - "right-abusefilter-modify-restricted": "ดัดแปรตัวกรองการละเมิดกฎด้วยการกระทำที่จำกัด", - "right-abusefilter-revert": "ย้อนการเปลี่ยนแปลงทั้งหมดโดยตัวกรองการละเมิดกฎที่กำหนด", + "right-abusefilter-log-detail": "ดูหน่วยรายการบันทึกการละเมิดกฎแบบละเอียด", + "right-abusefilter-privatedetails": "ดูข้อมูลส่วนตัวในรายการบันทึกการละเมิดกฎ", + "right-abusefilter-privatedetails-log": "ดูรายการบันทึกการเข้าถึงรายละเอียดส่วนตัวของตัวกรองการละเมิดกฎ", + "right-abusefilter-modify-restricted": "ปรับเปลี่ยนตัวกรองการละเมิดกฎด้วยการกระทำที่จำกัด", + "right-abusefilter-revert": "แปลงกลับการเปลี่ยนแปลงทั้งหมดโดยตัวกรองการละเมิดกฎที่กำหนด", "right-abusefilter-view-private": "ดูตัวกรองการละเมิดกฎที่ทำเครื่องหมายเป็นส่วนตัว", - "right-abusefilter-log-private": "ดูหน่วยปูมตัวกรองการละเมิดกฎที่ทำครื่องหมายเป็นส่วนตัว", - "right-abusefilter-hide-log": "ซ่อนหน่วยในปูมการละเมิดกฎ", - "right-abusefilter-hidden-log": "ดูหน่วยปูมการละเมิดกฎที่ถูกซ่อน", - "right-abusefilter-modify-global": "สร้างหรือดัดแปรตัวกรองการละเมิดกฎทั่วโลก", - "action-abusefilter-modify": "ดัดแปรตัวกรองการละเมิดกฎ", + "right-abusefilter-log-private": "ดูหน่วยรายการบันทึกตัวกรองการละเมิดกฎที่ทำเครื่องหมายเป็นส่วนตัว", + "right-abusefilter-hide-log": "ซ่อนหน่วยในรายการบันทึกการละเมิดกฎ", + "right-abusefilter-hidden-log": "ดูหน่วยรายการบันทึกการละเมิดกฎที่ถูกซ่อน", + "right-abusefilter-modify-global": "สร้างหรือปรับเปลี่ยนตัวกรองการละเมิดกฎทั่วโลก", + "action-abusefilter-modify": "ปรับเปลี่ยนตัวกรองการละเมิดกฎ", "action-abusefilter-view": "ดูตัวกรองการละเมิดกฎ", "action-abusefilter-log": "ดูปูมการละเมิดกฎ", - "action-abusefilter-log-detail": "ดูรายละเอียดหน่วยปูมการละเมิดกฎ", - "action-abusefilter-private": "ดูข้อมูลส่วนตัวในปูมการละเมิดกฎ", - "action-abusefilter-modify-restricted": "ดัดแปรตัวกรองการละเมิดกฎด้วยการกระทำที่จำกัด", - "action-abusefilter-revert": "ย้อนการเปลี่ยนแปลงทั้งหมดโดยตัวกรองการละเมิดกฎที่กำหนด", + "action-abusefilter-log-detail": "ดูหน่วยรายการบันทึกการละเมิดกฎแบบละเอียด", + "action-abusefilter-privatedetails": "ดูข้อมูลส่วนตัวในรายการบันทึกการละเมิดกฎ", + "action-abusefilter-privatedetails-log": "ดูรายการบันทึกการเข้าถึงรายละเอียดส่วนตัวของตัวกรองการละเมิดกฎ", + "action-abusefilter-modify-restricted": "ปรับเปลี่ยนตัวกรองการละเมิดกฎด้วยการกระทำที่จำกัด", + "action-abusefilter-revert": "แปลงกลับการเปลี่ยนแปลงทั้งหมดโดยตัวกรองการละเมิดกฎที่กำหนด", "action-abusefilter-view-private": "ดูตัวกรองการละเมิดกฎที่ทำเครื่องหมายเป็นส่วนตัว", - "abusefilter-log": "ปูมตัวกรองการละเมิดกฎ", + "action-abusefilter-log-private": "ดูรายการบันทึกของตัวกรองการละเมิดกฎที่ทำเครื่องหมายเป็นส่วนตัว", + "action-abusefilter-hide-log": "ซ่อนหน่วยในปูมการละเมิด", + "action-abusefilter-hidden-log": "ดูหน่วยปูมการละเมิดที่ถูกซ่อน", + "action-abusefilter-modify-global": "สร้างหรือดัดแปรตัวกรองการละเมิดทั่วโลก", "abusefilter-log-summary": "ปูมนี้แสดงรายการการกระทำทั้งหมดที่ถูกตัวกรองตรวจจับ", - "abusefilter-log-search": "ค้นหาปูมการละเมิดกฎ", + "abusefilter-log-search": "ค้นหารายการบันทึกการละเมิดกฎ", "abusefilter-log-search-user": "ผู้ใช้:", - "abusefilter-log-search-filter": "หมายเลขประจำตัวกรอง (คั่นด้วยไปป์):", - "abusefilter-log-search-title": "ชื่อเรื่อง :", + "abusefilter-log-search-group": "กลุ่มตัวกรอง:", + "abusefilter-log-search-group-any": "ทั้งหมด", + "abusefilter-log-search-filter": "หมายเลขตัวกรอง:", + "abusefilter-log-search-filter-help": "คั่นด้วยไพป์ คำขึ้นต้น \"$1\" สำหรับตัวกรองทั่วโลก", + "abusefilter-log-search-title": "ชื่อเรื่อง:", "abusefilter-log-search-wiki": "วิกิ:", + "abusefilter-log-search-impact": "ผลกระทบ:", + "abusefilter-log-search-impact-all": "การกระทำทั้งหมด", + "abusefilter-log-search-impact-saved": "เฉพาะการเปลี่ยนแปลงที่บันทึกเท่านั้น", + "abusefilter-log-search-impact-not-saved": "ไม่มีการเปลี่ยนแปลงที่บันทึก", + "abusefilter-log-search-entries-label": "สถานะการแสดง:", + "abusefilter-log-search-entries-all": "หน่วยทั้งหมด", + "abusefilter-log-search-entries-hidden": "เฉพาะหน่วยที่ซ่อนเท่านั้น", + "abusefilter-log-search-entries-visible": "เฉพาะหน่วยที่มองเห็นได้เท่านั้น", + "abusefilter-log-search-action-label": "การกระทำทริกเกอร์:", + "abusefilter-log-search-action-other": "อื่นๆ", + "abusefilter-log-search-action-any": "ใดๆ", + "abusefilter-log-search-action-taken-label": "การกระทำที่ปฏิบัติ:", + "abusefilter-log-search-action-taken-any": "ใดๆ", "abusefilter-log-search-submit": "ค้นหา", - "abusefilter-log-entry": "$1: ผู้ใช้ $2 ถูกตรวจจับตัวกรองการละเมิดกฎ ขณะกระทำการ \"$3\" บน $4\nสิ่งที่ตัวกรองดำเนินการ: $5;\nคำอธิบายตัวกรอง: $6", - "abusefilter-log-entry-withdiff": "$1: $2 เรียกคำสั่งจากตัวกรองการละเมิดกฎ ขณะกระทำการ \"$3\" ในหน้า $4\nสิ่งที่ตัวกรองดำเนินการ: $5\nรายละเอียดตัวกรอง: $6 ($7)", - "abusefilter-log-detailedentry-meta": "$1: ผู้ใช้ $2 เรียกคำสั่งจาก $3 ขณะกระทำการ \"$4\" บน $5\nสิ่งที่ตัวกรองดำเนินการ: $6;\nคำอธิบายตัวกรอง: $7 ($8)", + "abusefilter-log-entry": "$1: ผู้ใช้ $2 ถูก{{GENDER:$8|ตรวจจับ}}ตัวกรองการละเมิดกฎ ขณะ{{GENDER:$8|กระทำ}}การ \"$3\" บน $4\nสิ่งที่ตัวกรองดำเนินการ: $5;\nคำอธิบายตัวกรอง: $6", + "abusefilter-log-entry-withdiff": "$1: $2 {{GENDER:$8|เรียกคำสั่ง}}จากตัวกรองการละเมิดกฎ ขณะ{{GENDER:$8|กระทำการ}} \"$3\" ในหน้า $4\nสิ่งที่ตัวกรองดำเนินการ: $5\nรายละเอียดตัวกรอง: $6 ($7)", + "abusefilter-log-detailedentry-meta": "$1: ผู้ใช้ $2 {{GENDER:$9|เรียกคำสั่ง}}จาก $3 ขณะ{{GENDER:$9|กระทำการ}} \"$4\" บน $5\nสิ่งที่ตัวกรองดำเนินการ: $6;\nคำอธิบายตัวกรอง: $7 ($8)", "abusefilter-log-detailedentry-global": "ตัวกรองทั่วโลก $1", "abusefilter-log-detailedentry-local": "ตัวกรอง $1", "abusefilter-log-detailslink": "รายละเอียด", "abusefilter-log-diff": "แตกต่าง", - "abusefilter-log-hidelink": "ปรับทัศนวิสัย", - "abusefilter-log-details-legend": "รายละเอียดสำหรับหน่วยปูม $1", + "abusefilter-log-hidelink": "ปรับสถานะการแสดง", + "abusefilter-log-details-legend": "รายละเอียดสำหรับหน่วยรายการบันทึก $1", "abusefilter-log-details-var": "ตัวแปร", "abusefilter-log-details-val": "ค่า", - "abusefilter-log-details-vars": "ตัวแปรเสริมการกระทำ", - "abusefilter-log-details-private": "ข้อมูลส่วนตัว", - "abusefilter-log-details-ip": "ที่อยู่ไอพีเดิม:", + "abusefilter-log-details-vars": "พารามิเตอร์การกระทำ", + "abusefilter-log-details-privatedetails": "รายละเอียดปูมลับ", + "abusefilter-log-details-ip": "ที่อยู่ไอพีเดิม", + "abusefilter-log-details-checkuser": "ตรวจสอบผู้ใช้", "abusefilter-log-noactions": "ไม่มี", "abusefilter-log-details-diff": "การเปลี่ยนแปลงในการแก้ไข", - "abusefilter-log-linkoncontribs": "ปูมการละเมิดกฎ", - "abusefilter-log-linkoncontribs-text": "ปูมการละเมิดกฎของผู้ใช้นี้", - "abusefilter-log-hidden": "(รายการถูกซ่อนไว้)", - "abusefilter-log-hidden-implicit": "(ถูกซ่อนเพราะรุ่นถูกลบ)", - "abusefilter-log-cannot-see-details": "คุณไม่ได้รับอนุญาตให้ดูรายละเอียดของหน่วยนี้", - "abusefilter-log-details-hidden": "คุณไม่สามารถดูรายละเอียดของหน่วยนี้ เพราะถูกซ่อนจากการเข้าชมสาธารณะ", - "abusefilter-log-private-not-included": "หมายเลขประจำตัวกรองอย่างน้อยหนึ่งหมายเลขที่คุณระบุเป็นส่นวตัว เนื่องจากคุณไม่ได้รับอนุญาตให้ดูรายละเอียดของตัวกรองส่วนตัว ตัวกรองเหล่านี้จึงไม่ถูกค้นหา", - "abusefilter-log-hide-legend": "ซ่อนหน่วยปูม", - "abusefilter-log-hide-id": "หมายเลขประจำหน่วยปูม:", - "abusefilter-log-hide-hidden": "ซ่อนหน่วยนี้มิให้ปรากฏต่อสาธารณะ", + "abusefilter-log-linkoncontribs": "ปูมการละเมิด", + "abusefilter-log-linkoncontribs-text": "ปูมการละเมิดกฎของ{{GENDER:$1|ผู้ใช้นี้}}", + "abusefilter-log-linkonhistory": "ดูปูมการละเมิดกฎ", + "abusefilter-log-linkonhistory-text": "ดูรายการบันทึกการละเมิดกฎสำหรับหน้านี้", + "abusefilter-log-linkonundelete": "ดูปูมการละเมิดกฎ", + "abusefilter-log-linkonundelete-text": "ดูปูมการละเมิดกฎสำหรับหน้านี้", + "abusefilter-log-hidden-implicit": "(ถูกซ่อนเนื่องจากรุ่นแก้ไขถูกลบแล้ว)", + "abusefilter-log-cannot-see-details": "คุณไม่มีสิทธิดูรายละเอียดของหน่วยนี้", + "abusefilter-log-cannot-see-privatedetails": "คุณไม่มีสิทธิดูรายละเอียดส่วนตัวของหน่วยนี้", + "abusefilter-log-nonexistent": "ไม่มีหน่วยที่มีไอดีที่ระบุอยู่", + "abusefilter-log-details-hidden": "คุณไม่สามารถดูรายละเอียดของหน่วยนี้เนื่องจากถูกซ่อนจากการเข้าชมสาธารณะ", + "abusefilter-log-details-hidden-implicit": "คุณไม่สามารถดูรายละเอียดของหน่วยนี้เนื่องจากรุ่นแก้ไขที่เชื่อมโยงถูกซ่อนจากการเข้าชมสาธารณะ", + "abusefilter-log-private-not-included": "ไอดีตัวกรองอย่างน้อยหนึ่งไอดีที่คุณระบุเป็นส่วนตัว เนื่องจากคุณไม่ได้รับอนุญาตให้ดูรายละเอียดของตัวกรองส่วนตัว ตัวกรองเหล่านี้จึงไม่ถูกค้นหา", + "abusefilter-log-hide-legend": "ซ่อนหน่วยรายการบันทึก", + "abusefilter-log-hide-id": "ไอดีหน่วยรายการบันทึก:", + "abusefilter-log-hide-hidden": "ซ่อนหน่วยนี้จากการเข้าชมสาธารณะ", "abusefilter-log-hide-reason": "สาเหตุ:", - "abusefilter-log-hide-forbidden": "คุณไม่มีสิทธิซ่อนหน่วยปูมการละเมิดกฎ", - "logentry-abusefilter-hit": "$1 เรียกคำสั่งจาก $4 ขณะกระทำการ \"$5\" บน $3\nสิ่งที่ตัวกรองดำเนินการ: $6 ($7)", - "abusefilter-management": "การจัดการตัวกรองการละเมิดกฎ", + "abusefilter-log-hide-reason-other": "สาเหตุอื่นๆ/เพิ่มเติม:", + "abusefilter-log-hide-forbidden": "คุณไม่มีสิทธิซ่อนหน่วยรายการบันทึกการละเมิดกฎ", + "abusefilter-log-entry-suppress": "$1 ได้{{GENDER:$2|ซ่อน}} $3", + "abusefilter-log-entry-unsuppress": "$1 ได้{{GENDER:$2|เลิกซ่อน}} $3", + "logentry-abusefilter-hit": "$1 {{GENDER:$2|เรียกคำสั่ง}}จาก $4 ขณะ{{GENDER:$2|กระทำการ}} \"$5\" บน $3 การกระทำที่ปฏิบัติ: $6 ($7)", + "log-action-filter-abusefilter": "ประเภทของการเปลี่ยนตัวกรอง:", + "log-action-filter-abusefilter-create": "การสร้างตัวกรองใหม่", + "log-action-filter-abusefilter-modify": "การปรับเปลี่ยนตัวกรอง", + "log-action-filter-suppress-abuselog": "การซ่อนรายการบันทึกการละเมิดกฎ", + "log-action-filter-rights-blockautopromote": "การบล็อกการเลื่อนระดับอัตโนมัติ", + "logentry-abusefilterprivatedetails-access": "$1 ได้{{GENDER:$2|เข้าถึง}}รายละเอียดส่วนตัวสำหรับ $3", + "abusefilterprivatedetails-log-name": "ปูมการเข้าถึงรายละเอียดส่วนตัวของตัวกรองการละเมิด", "abusefilter-list": "ตัวกรองทั้งหมด", - "abusefilter-list-id": "หมายเลขประจำตัวกรอง:", + "abusefilter-list-id": "ไอดีตัวกรอง", + "abusefilter-list-pattern": "รูปแบบ", "abusefilter-list-status": "สถานะ", "abusefilter-list-public": "รายละเอียดต่อสาธารณะ", "abusefilter-list-consequences": "ผลลัพธ์", - "abusefilter-list-visibility": "ทัศนวิสัย", + "abusefilter-list-visibility": "สถานะการแสดง", "abusefilter-list-hitcount": "จำนวนการเรียก", "abusefilter-list-edit": "แก้ไข", "abusefilter-list-details": "รายละเอียด", "abusefilter-list-limit": "จำนวนต่อหน้า:", - "abusefilter-list-lastmodified": "ดัดแปรล่าสุด", + "abusefilter-list-lastmodified": "ปรับเปลี่ยนล่าสุด", "abusefilter-list-group": "กลุ่มตัวกรอง", "abusefilter-hidden": "ส่วนตัว", "abusefilter-unhidden": "สาธารณะ", "abusefilter-enabled": "เปิดใช้งาน", "abusefilter-deleted": "ถูกลบ", "abusefilter-disabled": "ปิดใช้งาน", + "abusefilter-throttled": "ถูกจำกัด", "abusefilter-hitcount": "$1 ครั้ง", "abusefilter-new": "สร้างตัวกรองใหม่", + "abusefilter-import-button": "นำเข้าตัวกรอง", "abusefilter-return": "กลับไปยังส่วนการจัดการตัวกรอง", "abusefilter-status-global": "ทั่วโลก", "abusefilter-list-options": "ตัวเลือก", @@ -114,7 +160,17 @@ "abusefilter-list-options-scope-local": "เฉพาะกฎท้องถิ่น", "abusefilter-list-options-scope-global": "เฉพาะกฎทั่วโลก", "abusefilter-list-options-scope-all": "กฎท้องถิ่นและทั่วโลก", + "abusefilter-list-options-further-options": "ตัวเลือกเพิ่มเติม:", "abusefilter-list-options-hidedisabled": "ซ่อนตัวกรองที่ปิดใช้งาน", + "abusefilter-list-options-hideprivate": "ซ่อนตัวกรองส่วนตัว", + "abusefilter-list-options-searchfield": "ค้นหาภายใต้กฎ:", + "abusefilter-list-options-searchpattern": "แทรกรูปแบบ", + "abusefilter-list-options-searchoptions": "โหมดการค้นหา:", + "abusefilter-list-options-search-like": "คิวรีธรรมดา", + "abusefilter-list-options-search-rlike": "นิพจน์ปกติ", + "abusefilter-list-options-search-irlike": "นิพจน์ปกติที่ไม่จำเป็นต้องตรงตามตัวพิมพ์ใหญ่-เล็ก", + "abusefilter-list-invalid-searchmode": "โหมดการค้นหาที่ระบุไม่ถูกต้อง", + "abusefilter-list-regexerror": "เกิดข้อผิดพลาดขณะค้นหา: ข้อผิดพลาดไวยากรณ์นิพจน์ปกติ", "abusefilter-list-options-submit": "อัปเดต", "abusefilter-tools-text": "นี่เป็นเครื่องมือซึ่งอาจเป็นประโยชน์ในการคิดระบบและการแก้จุดบกพร่องของตัวกรองการละเมิดกฎ", "abusefilter-tools-expr": "ตัวทดสอบนิพจน์", @@ -129,62 +185,105 @@ "abusefilter-edit": "แก้ไขตัวกรองการละเมิดกฎ", "abusefilter-edit-subtitle": "แก้ไขตัวกรอง $1", "abusefilter-edit-subtitle-new": "สร้างตัวกรอง", + "abusefilter-edit-token-not-match": "การแก้ไขยังไม่ได้ถูกบันทึก! โปรดบันทึกอีกครั้ง", "abusefilter-edit-oldwarning": "<strong>คุณกำลังแก้ไขรุ่นเก่าของตัวกรองนี้\nสถิติที่คัดมาเป็นของตัวกรองรุ่นล่าสุด\nถ้าคุณบันทึกการเปลี่ยนแปลง คุณจะเขียนทับการเปลี่ยนแปลงทั้งหมดนับแต่รุ่นที่คุณกำลังแก้ไข</strong> •\n[[Special:AbuseFilter/history/$2|กลับไปยังประวัติของตัวกรองนี้]]", "abusefilter-edit-status-label": "สถิติ:", - "abusefilter-edit-status": "จาก $1 การกระทำล่าสุด ตรงกับตัวกรองนี้ $2 ครั้ง ($3%)", - "abusefilter-edit-status-profile": "จาก $1 การกระทำล่าสุด ตรงกับตัวกรองนี้ $2 ครั้ง ($3%) โดยเฉลี่ย เวลาดำเนินงานอยู่ที่ $4 มิลลิวินาที และใช้ $5 เงื่อนไขของขีดจำกัดเงื่อนไข", + "abusefilter-edit-status": "จาก $1 การกระทำล่าสุด ตรงกับตัวกรองนี้ $2 ครั้ง ($3%)\nโดยเฉลี่ย เวลาดำเนินการอยู่ที่ $4 มิลลิวินาที และกินเงื่อนไข $5 เงื่อนไขของขีดจำกัดเงื่อนไข", + "abusefilter-edit-throttled-warning": "'''คำเตือน:''' มีการทำเครื่องหมายตัวกรองนี้ว่าเป็นโทษโดยอัตโนมัติ จะไม่ดำเนินการ\nการกระทำต่อไปนี้ ($1) เพื่อเป็นมาตรการความปลอดภัย กรุณาทบทวนและ[[mw:Extension:AbuseFilter/Conditions|ทำให้เงื่อนไขของคุณเหมาะที่สุด]]ก่อนลบข้อจำกัดนี้", "abusefilter-edit-new": "ตัวกรองใหม่", "abusefilter-edit-save": "บันทึกตัวกรอง", "abusefilter-edit-id": "หมายเลขประจำตัวกรอง:", + "abusefilter-edit-switch-editor": "เปลี่ยนตัวแก้ไข", "abusefilter-edit-description": "คำอธิบาย:\n:''(สาธารณะสามารถดูได้)''", + "abusefilter-edit-field-description": "คำอธิบาย", "abusefilter-edit-group": "กลุ่มตัวกรอง:", "abusefilter-edit-flags": "ตัวบ่งชี้:", "abusefilter-edit-enabled": "เปิดใช้งานตัวกรองนี้", "abusefilter-edit-deleted": "ทำเครื่องหมายว่าลบแล้ว", - "abusefilter-edit-hidden": "ซ่อนรายละเอียดของตัวกรองนี้ต่อสาธารณะ", + "abusefilter-edit-hidden": "ซ่อนรายละเอียดของตัวกรองนี้จากการเข้าชมสาธารณะ", "abusefilter-edit-global": "ตัวกรองทั่วโลก", "abusefilter-edit-rules": "เงื่อนไข:", + "abusefilter-edit-field-conditions": "เงื่อนไข", "abusefilter-edit-notes": "หมายเหตุ:", - "abusefilter-edit-lastmod": "ดัดแปรตัวกรองล่าสุด:", + "abusefilter-edit-lastmod": "ปรับเปลี่ยนตัวกรองล่าสุดเมื่อ:", "abusefilter-edit-lastmod-text": "$1 โดย $2", "abusefilter-edit-hitcount": "จำนวนการเรียกตัวกรอง:", - "abusefilter-edit-consequences": "การกระทำเมื่อตรงกัน", + "abusefilter-edit-consequences": "การกระทำที่จะปฏิบัติเมื่อตรงกัน", "abusefilter-edit-action-warn": "เรียกใช้การกระทำเหล่านี้หลังเตือนผู้ใช้นั้นแล้ว", - "abusefilter-edit-action-disallow": "ป้องกันมิให้ผู้ใช้ดำเนินการกระทำดังกล่าว", + "abusefilter-edit-action-disallow": "ป้องกันไม่ให้ผู้ใช้ดำเนินการกระทำดังกล่าว", "abusefilter-edit-action-blockautopromote": "เพิกถอนสถานะยืนยันอัตโนมัติของผู้ใช้", "abusefilter-edit-action-degroup": "นำผู้ใช้ออกจากกลุ่มสิทธิพิเศษทั้งหมด", - "abusefilter-edit-action-block": "บล็อกผู้ใช้ และ/หรือ เลขที่อยู่ไอพีมิให้แก้ไข", + "abusefilter-edit-action-block": "บล็อกผู้ใช้และ/หรือที่อยู่ไอพีไม่ให้ทำการแก้ไข", + "abusefilter-edit-action-blocktalk": "บล็อกผู้ใช้และ/หรือที่อยู่ไอพีไม่ให้ทำการแก้ไขหน้าพูดคุยของพวกเขา", "abusefilter-edit-action-throttle": "เรียกใช้การกระทำเฉพาะเมื่อผู้ใช้ดำเนินการเกินขีดจำกัด", - "abusefilter-edit-action-rangeblock": "บล็อกช่วง /16 อันเป็นที่มาของผู้ใช้", - "abusefilter-edit-action-tag": "ติดป้ายกำกับการแก้ไขเพื่อทบทวนต่อไป", + "abusefilter-edit-action-rangeblock": "บล็อกช่วงไอพีที่เกี่ยวของซึ่งเป็นที่มาของผู้ใช้", + "abusefilter-edit-action-tag": "ติดป้ายกำกับการแก้ไขเพื่อตรวจทานต่อไป", "abusefilter-edit-throttle-count": "จำนวนการกระทำที่อนุญาต:", - "abusefilter-edit-throttle-period": "ช่วงเวลา:", - "abusefilter-edit-warn-message": "ข้อความระบบที่ใช้เตือน", - "abusefilter-edit-warn-other": "ข้อความอื่น", - "abusefilter-edit-warn-other-label": "ชื่อหน้าของข้อความอื่น:\n:''(โดยไม่มีคำขึ้นต้นมีเดียวิกิ)''", + "abusefilter-edit-throttle-period": "ช่วงเวลา (ในหน่วยวินาที):", + "abusefilter-edit-throttle-groups": "จัดกลุ่มการจำกัดผลลัพธ์ตาม:", + "abusefilter-edit-throttle-groups-help": "ดู $1", + "abusefilter-edit-throttle-groups-help-text": "เอกสารทาง mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "คั่นด้วยจุลภาคเพื่อเชื่อมด้วย AND หรือด้วยการแบ่งบรรทัดเพื่อเชื่อมด้วย OR", + "abusefilter-edit-throttle-placeholder": "คั่นด้วยจุลภาคเพื่อเชื่อมด้วย AND และแทรกเดี่ยว ๆ เพื่อเชื่อมด้วย OR", + "abusefilter-throttle-ip": "ที่อยู่ไอพี", + "abusefilter-throttle-user": "บัญชีผู้ใช้", + "abusefilter-throttle-range": "ช่วง /16", + "abusefilter-throttle-creationdate": "วันที่สร้างบัญชี", + "abusefilter-throttle-editcount": "จำนวนการแก้ไข", + "abusefilter-throttle-site": "ทั้งไซต์", + "abusefilter-throttle-page": "หน้า", + "abusefilter-throttle-none": "(ไม่มี)", + "abusefilter-throttle-details": "อนุญาต $1 การกระทำทุก $2 วินาที โดยจัดกลุ่มการจำกัดผลลัพธ์ตาม: $3", + "abusefilter-edit-warn-message": "ข้อความระบบที่ใช้สำหรับเตือน:", + "abusefilter-edit-warn-other": "ข้อความอื่นๆ", + "abusefilter-edit-warn-other-label": "ชื่อหน้าของข้อความอื่น:\n:''(โดยไม่มีคำขึ้นต้น \"MediaWiki:\")''", "abusefilter-edit-warn-actions": "การกระทำ:", - "abusefilter-edit-warn-preview": "แสดงตัวอย่างข้อความที่เลือก", + "abusefilter-edit-warn-preview": "แสดง/ซ่อนตัวอย่างข้อความที่เลือก", "abusefilter-edit-warn-edit": "สร้าง/แก้ไขข้อความที่เลือก", - "abusefilter-edit-tag-tag": "[[Special:Tags|ป้ายกำกับ]]ที่ใช้ (บรรทัดละหนึ่งป้าย):", - "abusefilter-edit-denied": "คุณไม่สามารถดูรายละเอียดของตัวกรองนี้ได้ เพราะถูกซ่อนมิให้สาธารณะชม", - "abusefilter-edit-main": "ตัวแปรเสริมตัวกรอง", + "abusefilter-edit-disallow-message": "ข้อความระบบที่ใช้สำหรับเลิกอนุญาต:", + "abusefilter-edit-disallow-other": "ข้อความอื่นๆ", + "abusefilter-edit-disallow-other-label": "ชื่อหน้าของข้อความอื่น:\n:''(โดยไม่มีคำขึ้นต้น \"MediaWiki:\")''", + "abusefilter-edit-disallow-actions": "การกระทำ:", + "abusefilter-edit-disallow-preview": "แสดง/ซ่อนตัวอย่างข้อความที่เลือก", + "abusefilter-edit-disallow-edit": "สร้าง/แก้ไขข้อความที่เลือก", + "abusefilter-edit-tag-tag": "[[Special:Tags|ป้ายกำกับ]]ที่ใช้:", + "abusefilter-edit-tag-placeholder": "เพิ่มป้ายกำกับ (ทีละป้ายหรือคั่นด้วยจุลภาค)", + "abusefilter-edit-tag-hidden-placeholder": "เพิ่มป้ายกำกับ (คั่นด้วยจุลภาค)", + "abusefilter-edit-block-anon-durations": "ระยะเวลาในการบล็อกสำหรับผู้ใช้นิรนาม:", + "abusefilter-edit-block-user-durations": "รายะเวลาในการบล็อกสำหรับผู้ใช้ที่ลงทะเบียน:", + "abusefilter-block-anon": "บล็อกผู้ใช้นิรนาม", + "abusefilter-block-user": "บล็อกผู้ใช้ที่ลงทะเบียน", + "abusefilter-block-talk": "หน้าพูดคุยถูกบล็อก", + "abusefilter-edit-denied": "คุณไม่สามารถดูรายละเอียดของตัวกรองนี้ได้เนื่องจากถูกซ่อนจากการเข้าชมสาธารณะ", + "abusefilter-edit-main": "พารามิเตอร์ตัวกรอง", "abusefilter-edit-done-subtitle": "แก้ไขตัวกรองแล้ว", "abusefilter-edit-done": "บันทึก[[Special:AbuseFilter/history/$1/diff/prev/$2|การเปลี่ยนแปลงของคุณ]]ใน[[Special:AbuseFilter/$1|ตัวกรอง $3]] แล้ว", - "abusefilter-edit-badsyntax": "มีข้อผิดพลาดของวายกสัมพันธ์ในตัวกรองที่คุณระบุ ตัวแจงส่วนส่งออกคือ: <pre>$1</pre>", - "abusefilter-edit-restricted": "คุณไม่สามารถแก้ไขตัวกรองนี้ เพราะพบการกระทำที่ถูกจำกัด\nโปรดขอให้ผู้ใช้ที่ได้รับอนุญาตเพิ่มการกระทำที่จำกัดแทนคุณ", + "abusefilter-edit-badsyntax": "มีข้อผิดพลาดไวยากรณ์ในตัวกรองที่คุณระบุ ผลลัพธ์จากตัวแยกวิเคราะห์คือ: <pre>$1</pre>", + "abusefilter-edit-missingfields": "คุณจำเป็นต้องกรอกข้อมูลลงในช่องต่อไปนี้: $1", + "abusefilter-edit-deleting-enabled": "คุณไม่สามารถทำเครื่องหมายตัวกรองที่ใช้งานอยู่ว่าถูกลบได้", + "abusefilter-edit-restricted": "คุณไม่สามารถแก้ไขตัวกรองนี้เนื่องจากพบการกระทำที่ถูกจำกัด\nโปรดขอให้ผู้ใช้ที่ได้รับอนุญาตเพิ่มการกระทำที่จำกัดแทนคุณ", "abusefilter-edit-viewhistory": "ดูประวัติของตัวกรองนี้", "abusefilter-edit-history": "ประวัติ:", - "abusefilter-edit-check": "ตรวจสอบวากยสัมพันธ์", + "abusefilter-edit-check": "ตรวจสอบไวยากรณ์", "abusefilter-edit-badfilter": "ไม่มีตัวกรองที่คุณระบุ", - "abusefilter-edit-revert": "ย้อนการกระทำโดยตัวกรองนี้", + "abusefilter-edit-revert": "แปลงกลับการกระทำที่ปฏิบัติโดยตัวกรองนี้", "abusefilter-edit-tools": "เครื่องมือ:", "abusefilter-edit-test-link": "ทดสอบตัวกรองนี้กับการแก้ไขล่าสุด", "abusefilter-edit-export": "ส่งออกตัวกรองนี้ไปยังวิกิอื่น", - "abusefilter-edit-syntaxok": "ไม่พบวายกสัมพันธ์ผิดพลาด", - "abusefilter-edit-syntaxerr": "พบวายกสัมพันธ์ผิดพลาด: $1", - "abusefilter-edit-bad-tags": "มีป้ายกำกับที่ระบุไม่ถูกต้อง\nชื่อป้ายกำกับควรสั้น และไม่ควรมีอักขระพิเศษ", - "abusefilter-edit-notallowed": "คุณไม่ได้รับอนุญาตให้สร้างหรือแก้ไขตัวกรองการละเมิดกฎ", - "abusefilter-edit-notallowed-global": "คุณไม่ได้รับอนุญาตให้สร้างหรือแก้ไขตัวกรองการละเมิดกฎทั่วโลก", + "abusefilter-edit-syntaxok": "ตรวจไม่พบข้อผิดพลาดไวยากรณ์", + "abusefilter-edit-syntaxerr": "ตรวจพบข้อผิดพลาดไวยากรณ์: $1", + "abusefilter-edit-warn-leave": "การออกจากหน้านี้จะทำให้คุณสูญเสียการเปลี่ยนแปลงใด ๆ ที่คุณทำกับตัวกรองนี้", + "abusefilter-edit-bad-tags": "มีป้ายกำกับที่ระบุไม่ถูกต้อง\nชื่อป้ายกำกับควรสั้น ไม่ควรมีอักขระพิเศษ และต้องไม่ถูกสงวนไว้โดยซอฟต์แวร์อื่น ลองเลือกชื่อป้ายกำกับใหม่", + "abusefilter-edit-notallowed": "คุณไม่มีสิทธิสร้างหรือแก้ไขตัวกรองการละเมิดกฎ", + "abusefilter-edit-notallowed-global": "คุณไม่มีสิทธิสร้างหรือแก้ไขตัวกรองการละเมิดกฎทั่วโลก", + "abusefilter-edit-notallowed-global-custom-msg": "ข้อความเตือนหรือไม่อนุญาตแบบกำหนดเองไม่รองรับโดยตัวกรองส่วนกลาง", + "abusefilter-edit-invalid-warn-message": "ข้อความเตือนต้องไม่ว่างเปล่า", + "abusefilter-edit-invalid-disallow-message": "ข้อความไม่อนุญาตต้องไม่ว่างเปล่า", + "abusefilter-edit-invalid-throttlecount": "จำนวนการกระทำ throttle ต้องมีค่าเป็นจำนวนเต็มบวก", + "abusefilter-edit-invalid-throttleperiod": "ระยะเวลา throttle ต้องมีค่าเป็นจำนวนเต็มบวก", + "abusefilter-edit-empty-throttlegroups": "ต้องเลือกกลุ่ม throttle อย่างน้อยหนึ่งกลุ่ม", + "abusefilter-edit-duplicated-throttlegroups": "กลุ่ม throttle ต้องไม่มีที่ซ้ำกัน", + "abusefilter-edit-invalid-throttlegroups": "กลุ่ม throttle ที่ระบุไม่ถูกต้อง", "abusefilter-edit-builder-select": "เลือกตัวเลือกเพื่อเพิ่มที่เคอร์เซอร์", "abusefilter-edit-builder-group-op-arithmetic": "ตัวดำเนินการเลขคณิต", "abusefilter-edit-builder-op-arithmetic-addition": "การบวก (+)", @@ -194,8 +293,10 @@ "abusefilter-edit-builder-op-arithmetic-modulo": "มอดุโล (%)", "abusefilter-edit-builder-op-arithmetic-pow": "ยกกำลัง (**)", "abusefilter-edit-builder-group-op-comparison": "ตัวดำเนินการเปรียบเทียบ", - "abusefilter-edit-builder-op-comparison-equal": "เท่ากับ (==)", - "abusefilter-edit-builder-op-comparison-notequal": "ไม่เท่ากับ (!=)", + "abusefilter-edit-builder-op-comparison-equal": "ค่าเท่ากับ (==)", + "abusefilter-edit-builder-op-comparison-equal-strict": "ค่าและแบบชนิดเท่ากับ (===)", + "abusefilter-edit-builder-op-comparison-notequal": "ค่าไม่เท่ากับ (!=)", + "abusefilter-edit-builder-op-comparison-notequal-strict": "ค่าและแบบชนิดไม่เท่ากับ (!==)", "abusefilter-edit-builder-op-comparison-lt": "น้อยกว่า (<)", "abusefilter-edit-builder-op-comparison-gt": "มากกว่า (>)", "abusefilter-edit-builder-op-comparison-lte": "น้อยกว่าหรือเท่ากับ (<=)", @@ -207,54 +308,67 @@ "abusefilter-edit-builder-group-misc": "เบ็ดเตล็ด", "abusefilter-edit-builder-misc-in": "อยู่ในสายอักขระ (in)", "abusefilter-edit-builder-misc-like": "ตรงตามรูปแบบ (like)", - "abusefilter-edit-builder-misc-rlike": "ตรงตามนิพจน์ปรกติ (rlike)", - "abusefilter-edit-builder-misc-irlike": "ตรงตามนิพจน์ปรกติ ไวต่ออักษรใหญ่เล็ก (irlike)", - "abusefilter-edit-builder-misc-contains": "สายอักขระฝั่งซ้ายมีสายอักขระฝั่งขวา (contains)", - "abusefilter-edit-builder-misc-stringlit": "สัญพจน์สายอักขระ (\"\")", + "abusefilter-edit-builder-misc-rlike": "ตรงตามนิพจน์ปกติ (rlike)", + "abusefilter-edit-builder-misc-irlike": "ตรงตามนิพจน์ปกติ ตรงตามอักษรพิมพ์ใหญ่-เล็ก (irlike)", + "abusefilter-edit-builder-misc-contains": "สตริงฝั่งซ้ายมีสตริงฝั่งขวา (contains)", + "abusefilter-edit-builder-misc-stringlit": "สัญพจน์สตริง (\"\")", "abusefilter-edit-builder-misc-tern": "ตัวดำเนินการไตรภาค (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "มีเงื่อนไข (if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "มีเงื่อนไข (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "มีเงื่อนไขสั้น (if X then Y end)", "abusefilter-edit-builder-group-funcs": "ฟังก์ชัน", - "abusefilter-edit-builder-funcs-length": "ความยาวสายอักขระ (length)", + "abusefilter-edit-builder-funcs-length": "ความยาวสตริง (length)", "abusefilter-edit-builder-funcs-lcase": "เปลื่ยนเป็นตัวเล็ก (lcase)", "abusefilter-edit-builder-funcs-ucase": "เปลี่ยนเป็นตัวใหญ่ (ucase)", "abusefilter-edit-builder-funcs-ccnorm": "ทำให้อักขระที่สับสนเป็นปกติ (ccnorm)", + "abusefilter-edit-builder-funcs-ccnorm-contains-any": "ทำให้เป็นปกติและค้นหาสตริงสำหรับสตริงย่อยหลายสตริงในโหมด OR (ccnorm_contains_any)", + "abusefilter-edit-builder-funcs-ccnorm-contains-all": "ทำให้เป็นปกติและค้นหาสตริงสำหรับสตริงย่อยหลายสตริงในโหมด AND (ccnorm_contains_all)", "abusefilter-edit-builder-funcs-rmdoubles": "นำอักขระคู่ออก (rmdoubles)", "abusefilter-edit-builder-funcs-specialratio": "อักขระพิเศษ / อักขระรวม (specialratio)", "abusefilter-edit-builder-funcs-norm": "ทำให้เป็นปกติ (norm)", - "abusefilter-edit-builder-funcs-count": "จำนวนครั้งที่สายอักขระ X ปรากฏในสายอักขระ Y (count)", - "abusefilter-edit-builder-funcs-rcount": "จำนวนครั้งที่นิพจน์ปรกติ X ปรากฏในสายอักขระ Y (rcount)", + "abusefilter-edit-builder-funcs-count": "จำนวนครั้งที่สตริง X ปรากฏในสตริง Y (count)", + "abusefilter-edit-builder-funcs-rcount": "จำนวนครั้งที่นิพจน์ปกติ X ปรากฏในสตริง Y (rcount)", + "abusefilter-edit-builder-funcs-get_matches": "แถวลำดับ regex ในข้อความหนึ่งสำหรับกลุ่มที่ยึดมาแต่ละลกุ่ม (get_matches)", "abusefilter-edit-builder-funcs-rmwhitespace": "นำช่องว่างออก (rmwhitespace)", "abusefilter-edit-builder-funcs-rmspecials": "นำอักขระพิเศษออก (rmspecials)", "abusefilter-edit-builder-funcs-ip_in_range": "ไอพีอยู่ในช่วงหรือไม่ (ip_in_range)", - "abusefilter-edit-builder-funcs-contains-any": "ค้นหาสายอักขระดูสายอักขระย่อย (contains_any)", - "abusefilter-edit-builder-funcs-substr": "สายอักขระย่อย (substr)", - "abusefilter-edit-builder-funcs-strpos": "ตำแหน่งสายอักขระย่อยในสายอักขระ (strpos)", - "abusefilter-edit-builder-funcs-str_replace": "แทนที่สายอักขระย่อยด้วยสายอักขระ (str_replace)", - "abusefilter-edit-builder-funcs-rescape": "หลีกสายอักขระเป็นสัญพจน์ในนิพจน์ปรกติ (rescape)", + "abusefilter-edit-builder-funcs-contains-any": "ค้นหาสตริงสำหรับสตริงย่อยหลายสตริงในโหมด OR (contains_any)", + "abusefilter-edit-builder-funcs-contains-all": "ค้นหาสตริงสำหรับสตริงย่อยหลายสตริงในโหมด AND (contains_all)", + "abusefilter-edit-builder-funcs-equals-to-any": "ตรวจสอบว่าอาร์กิวเมนต์ที่ระบุเท่ากับ (===) อาร์กิวเมนต์อันใดอันหนึ่งต่อไปนี้ (equals_to_any)", + "abusefilter-edit-builder-funcs-substr": "สตริงย่อย (substr)", + "abusefilter-edit-builder-funcs-strpos": "ตำแหน่งของสตริงย่อยในสตริง (strpos)", + "abusefilter-edit-builder-funcs-str_replace": "แทนที่สตริงย่อยด้วยสตริง (str_replace)", + "abusefilter-edit-builder-funcs-rescape": "หลีกสตริงเป็นสัญพจน์ในนิพจน์ปกติ (rescape)", "abusefilter-edit-builder-funcs-set_var": "ตั้งตัวแปร (set_var)", + "abusefilter-edit-builder-funcs-sanitize": "ทำให้เอนทิตีเอชทีเอ็มแอลเป็นมาตรฐานสู่อักขระยูนิโค้ด (sanitize)", "abusefilter-edit-builder-group-vars": "ตัวแปร", "abusefilter-edit-builder-vars-accountname": "ชื่อบัญชี (เมื่อสร้างบัญชี)", "abusefilter-edit-builder-vars-timestamp": "ตราเวลายูนิกซ์ของการเปลี่ยนแปลง", + "abusefilter-edit-builder-vars-timestamp-expanded": "ตราเวลาของปูม", "abusefilter-edit-builder-vars-action": "การกระทำ", "abusefilter-edit-builder-vars-addedlines": "บรรทัดที่เพิ่มในการแก้ไข", "abusefilter-edit-builder-vars-delta": "การเปลี่ยนแปลงขนาดในการแก้ไข", "abusefilter-edit-builder-vars-diff": "ผลต่างรวมของการเปลี่ยนแปลงที่ทำโดยการแก้ไข", "abusefilter-edit-builder-vars-newsize": "ขนาดหน้าใหม่", "abusefilter-edit-builder-vars-oldsize": "ขนาดหน้าเก่า", + "abusefilter-edit-builder-vars-old-content-model": "แบบจำลองเนื้อหาเก่า", + "abusefilter-edit-builder-vars-new-content-model": "แบบจำลองเนื้อหาใหม่", "abusefilter-edit-builder-vars-removedlines": "บรรทัดที่นำออกในการแก้ไข", "abusefilter-edit-builder-vars-summary": "คำอธิบายอย่างย่อ/เหตุผล", "abusefilter-edit-builder-vars-page-id": "หมายเลขประจำหน้า", "abusefilter-edit-builder-vars-page-ns": "เนมสเปซหน้า", "abusefilter-edit-builder-vars-page-title": "ชื่อหน้า (ไม่มีเนมสเปซ)", "abusefilter-edit-builder-vars-page-prefixedtitle": "ชื่อเต็มหน้า", + "abusefilter-edit-builder-vars-page-age": "อายุหน้า (หน่วยเป็นวินาที)", "abusefilter-edit-builder-vars-movedfrom-id": "หมายเลขประจำหน้าต้นทางที่เปลี่ยนชื่อ", "abusefilter-edit-builder-vars-movedfrom-ns": "เนมสเปซหน้าต้นทางที่เปลี่ยนชื่อ", "abusefilter-edit-builder-vars-movedfrom-title": "ชื่อหน้าต้นทางที่เปลี่ยนชื่อ", "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "ชื่อเต็มหน้าต้นทางที่เปลี่ยนชื่อ", + "abusefilter-edit-builder-vars-movedfrom-age": "อายุหน้าต้นทางการย้าย (หน่วยเป็นวินาที)", "abusefilter-edit-builder-vars-movedto-id": "หมายเลขประจำหน้าปลายทางที่เปลี่ยนชื่อ", "abusefilter-edit-builder-vars-movedto-ns": "เนมสเปซหน้าปลายทางที่เปลี่ยนชื่อ", "abusefilter-edit-builder-vars-movedto-title": "ชื่อหน้าปลายทางที่เปลี่ยนชื่อ", "abusefilter-edit-builder-vars-movedto-prefixedtitle": "ชื่อเต็มหน้าปลายทางที่เปลี่ยนชื่อ", + "abusefilter-edit-builder-vars-movedto-age": "อายุหน้าปลายทางการย้าย (หน่วยเป็นวินาที)", "abusefilter-edit-builder-vars-user-editcount": "จำนวนการแก้ไขของผู้ใช้", "abusefilter-edit-builder-vars-user-age": "อายุบัญชีผู้ใช้", "abusefilter-edit-builder-vars-user-name": "ชื่อบัญชีผู้ใช้", @@ -264,26 +378,45 @@ "abusefilter-edit-builder-vars-user-emailconfirm": "เวลาที่ยืนยันที่อยู่อีเมล", "abusefilter-edit-builder-vars-recent-contributors": "ผู้ใช้สิบคนสุดท้ายที่เขียนหน้า", "abusefilter-edit-builder-vars-first-contributor": "ผู้ใช้คนแรกที่มีส่วนร่วมในหน้า", + "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "ผู้ใช้สิบคนสุดท้ายที่ร่วมแก้ไขหน้าต้นทางการย้าย", + "abusefilter-edit-builder-vars-movedfrom-first-contributor": "ผู้ใช้สิคนแรกที่ร่วมแก้ไขหน้าต้นทางการย้าย", + "abusefilter-edit-builder-vars-movedto-recent-contributors": "ผู้ใช้สิบคนสุดท้ายที่ร่วมแก้ไขหน้าปลายทางการย้าย", + "abusefilter-edit-builder-vars-movedto-first-contributor": "ผู้ใช้คนแรกสุดท้ายที่ร่วมแก้ไขหน้าปลายทางการย้าย", "abusefilter-edit-builder-vars-all-links": "ลิงก์ภายนอกทั้งหมดในข้อความใหม่", "abusefilter-edit-builder-vars-added-links": "ลิงก์ภายนอกทั้งหมดที่เพิ่มมาในการแก้ไข", "abusefilter-edit-builder-vars-removed-links": "ลิงก์ภายนอกทั้งหมดที่นำออกในการแก้ไข", - "abusefilter-edit-builder-vars-old-text": "ข้อความวิกิเก่าก่อนการแก้ไข", - "abusefilter-edit-builder-vars-new-text": "ข้อความวิกิใหม่หลังการแก้ไข", + "abusefilter-edit-builder-vars-old-wikitext": "ข้อความวิกิหน้าเก่าก่อนการแก้ไข", + "abusefilter-edit-builder-vars-new-wikitext": "ข้อความวิกิใหม่หลังการแก้ไข", "abusefilter-edit-builder-vars-new-pst": "ข้อความวิกิหน้าใหม่ แปลงก่อนบันทึก", "abusefilter-edit-builder-vars-diff-pst": "ผลต่างรวมของการแก้ไขที่ทำโดยการแก้ไข แปลงก่อนบันทึก", "abusefilter-edit-builder-vars-addedlines-pst": "บรรทัดที่เพิ่มในการแก้ไข แปลงก่อนบันทึก", - "abusefilter-edit-builder-vars-new-text-stripped": "ข้อความหน้าใหม่โดยไม่มีอาร์กอัพใด ๆ", + "abusefilter-edit-builder-vars-new-text": "ข้อความหน้าใหม่โดยไม่มีอาร์กอัพใด ๆ", "abusefilter-edit-builder-vars-new-html": "โค้ดเอชทีเอ็มแอลแจงส่วนของรุ่นใหม่", "abusefilter-edit-builder-vars-restrictions-edit": "ระดับการล็อกการแก้ไขหน้า", "abusefilter-edit-builder-vars-restrictions-move": "ระดับการล็อกย้ายหน้า", "abusefilter-edit-builder-vars-restrictions-create": "การล็อกสร้างหน้า", "abusefilter-edit-builder-vars-restrictions-upload": "การล็อกอัปโหลดไฟล์", - "abusefilter-edit-builder-vars-old-text-stripped": "ข้อความหน้าเก่าโดยไม่มีมาร์กอัพ", + "abusefilter-edit-builder-vars-movedfrom-restrictions-edit": "ระดับการป้องกันการแก้ไขของหน้าต้นทางการย้าย", + "abusefilter-edit-builder-vars-movedfrom-restrictions-move": "ระดับการป้องกันการย้ายของหน้าต้นทางการย้าย", + "abusefilter-edit-builder-vars-movedfrom-restrictions-create": "สร้างการป้องกันสำหรับหน้าต้นทางการย้าย", + "abusefilter-edit-builder-vars-movedfrom-restrictions-upload": "การป้องกันอัปโหลดของไฟล์ต้นทางการย้าย", + "abusefilter-edit-builder-vars-movedto-restrictions-edit": "ระดับการป้องกันการแก้ไขของหน้าปลายทางการย้าย", + "abusefilter-edit-builder-vars-movedto-restrictions-move": "ระดับการป้องกันการย้ายของหน้าต้นทางการย้าย", + "abusefilter-edit-builder-vars-movedto-restrictions-create": "สร้างการป้องกันสำหรับหน้าปลายทางการย้าย", + "abusefilter-edit-builder-vars-movedto-restrictions-upload": "การป้องกันการอัปโหลดของหน้าปลายทางการย้าย", + "abusefilter-edit-builder-vars-old-text": "ข้อความหน้าเก่าโดยไม่มีมาร์กอัพ (เลิกใช้แล้ว)", "abusefilter-edit-builder-vars-old-links": "ลิงก์ในหน้าก่อนการแก้ไข", - "abusefilter-edit-builder-vars-old-html": "ข้อความวิกิหน้าเก่าแจงส่วนเป็นเอชทีเอ็มแอล", - "abusefilter-edit-builder-vars-minor-edit": "การแก้ไขนี้ทำเครื่องหมายเป็นการแก้ไขเล็กน้อยหรือไม่", + "abusefilter-edit-builder-vars-old-html": "ข้อความวิกิหน้าเก่าแจงส่วนเป็นเอชทีเอ็มแอล (เลิกใช้แล้ว)", + "abusefilter-edit-builder-vars-minor-edit": "การแก้ไขนี้ทำเครื่องหมายเป็นการแก้ไขเล็กน้อยหรือไม่ (เลิกใช้แล้ว)", "abusefilter-edit-builder-vars-file-sha1": "แฮช SHA1 ของเนื้อหาไฟล์", "abusefilter-edit-builder-vars-file-size": "ขนาดของไฟล์หน่วยเป็นไบต์", + "abusefilter-edit-builder-vars-file-mime": "ประเภท MIME ของไฟล์", + "abusefilter-edit-builder-vars-file-mediatype": "ประเภทสื่อของไฟล์", + "abusefilter-edit-builder-vars-file-width": "ความกว้างของไฟล์ หน่วยเป็นพิกเซล", + "abusefilter-edit-builder-vars-file-height": "ความสูงของไฟล์ หน่วยเป็นพิกเซล", + "abusefilter-edit-builder-vars-file-bits-per-channel": "บิตต่อช่องสีของไฟล์", + "abusefilter-edit-builder-vars-wiki-name": "ชื่อฐานข้อมูลของวิกิ", + "abusefilter-edit-builder-vars-wiki-language": "รหัสภาษาของวิกิ", "abusefilter-filter-log": "การเปลี่ยนแปลงตัวกรองล่าสุด", "abusefilter-history": "ประวัติการเปลี่ยนแปลงตัวกรองการละเมิดกฏ #$1", "abusefilter-history-foruser": "การเปลี่ยนแปลงโดย $1", @@ -302,12 +435,28 @@ "abusefilter-history-filterid": "ตัวกรอง", "abusefilter-history-select-legend": "แบ่งละเอียดการค้นหา", "abusefilter-history-select-user": "ผู้ใช้:", + "abusefilter-history-select-filter": "หมายเลขประจำตัวกรอง:", "abusefilter-history-select-submit": "แบ่งละเอียด", - "abusefilter-history-diff": "จำนวนการเปลี่ยนแปลง", + "abusefilter-history-diff": "การเปลี่ยนแปลง", "abusefilter-history-error-hidden": "ตัวกรองที่คุณขอถูกซ่อน และคุณไม่สามารถดูประวัติได้", "abusefilter-exception-unexpectedatend": "\"$2\" ไม่คาดหมายที่อักขระ $1", "abusefilter-exception-expectednotfound": "คาดหมาย $2 ที่อักขระ $1 แต่ไม่พบ (พบ $3 $4 แทน)", - "abusefilter-action-tag": "ป้ายกำกับ", + "abusefilter-exception-unrecognisedkeyword": "คำสำคัญที่ไม่รู้จัก $2 ณ อักขระ $1", + "abusefilter-exception-unexpectedtoken": "โทเค็นไม่คาดหมาย \"$3\" (ประเภท $2) ณ อักขระ $1", + "abusefilter-exception-unclosedstring": "สายอักขระยังไม่ปิดซึ่งเริ่มที่อักขระ $1", + "abusefilter-exception-invalidoperator": "ตัวดำเนินการไม่สมเหตุสมผล \"$2\" ณ อักขระ $1", + "abusefilter-exception-unrecognisedtoken": "โทเค็นไม่คาดหมาย \"$2\" ณ อักขระ $1", + "abusefilter-exception-noparams": "ไม่ได้ระบุพารามิเตอร์ใดให้กับฟังก์ชัน \"$2\" ที่อักขระ $1\nต้องการ $3 {{PLURAL:$3|อาร์กิวเมนต์}}", + "abusefilter-exception-dividebyzero": "ไม่สามารถพยายามหาร $2 ด้วยศูนย์ที่อักขระ $1 ได้", + "abusefilter-exception-unrecognisedvar": "ไม่รู้จักตัวแปร $2 ที่อักขระ $1", + "abusefilter-exception-notenoughargs": "มีอาร์กิวเมนต์ไม่เพียงพอสำหรับฟังก์ชัน $2 ที่ถูกเรียกที่อักขระ $1\nต้องการ $3 {{PLURAL:$3|อาร์กิวเมนต์}} ได้รับแล้ว $4", + "abusefilter-exception-regexfailure": "มีข้อผิดพลาดในนิพจน์ธรรมดา \"$2\" ที่อักขระ $1", + "abusefilter-exception-outofbounds": "กำลังร้องขอรายการแถวลำดับที่ไม่มีอยู่ $2 (ขนาดแถวลำดับ = $3) ที่อักขระ $1", + "abusefilter-exception-notarray": "กำลังร้องขอรายการแถวลำดับของที่ไม่ใช่แถวลำดับที่อักขระ $1", + "abusefilter-exception-unclosedcomment": "ความเห็นไม่ปิดที่อักขระ $1", + "abusefilter-exception-invalidiprange": "มีการระบุช่วงไอพีที่ไม่ถูกต้อง \"$2\" ที่อักขระ $1", + "abusefilter-exception-disabledvar": "ตัวแปร $2 ที่อักขระ $1 ไม่ได้มีการใช้อีกต่อไปแล้ว", + "abusefilter-action-tag": "ป้ายระบุ", "abusefilter-action-throttle": "ตรงเฉพาะเมื่อเกินขีดจำกัด", "abusefilter-action-warn": "เตือน", "abusefilter-action-blockautopromote": "บล็อกการแต่งตั้งอัตโนมัติ", @@ -317,13 +466,14 @@ "abusefilter-action-disallow": "ห้ามการกระทำ", "abusefilter-revert-title": "ย้อนการเปลี่ยนแปลงทั้งหมดโดยตัวกรอง $1", "abusefilter-revert-intro": "แบบนี้ให้คุณย้อนการเปลี่ยนแปลงทั้งหมดโดยตัวกรองการละเมิดกฎเนื่องจากตัวกรอง $1 \nโปรดใส่ใจขณะใช้เครื่องมือนี้", - "abusefilter-revert-preview-item": "$1: $2 กระทำการ $3 บน $4\nการดำเนินการที่จะถูกย้อน: $5 ($6)", + "abusefilter-revert-preview-item": "$1: $2 {{GENDER:$7|กระทำการ}} $3 บน $4\nการดำเนินการที่จะถูกย้อน: $5 ($6)", "abusefilter-revert-search-legend": "เลือกการกระทำตัวกรองการละเมิดกฎที่จะถูกย้อน", "abusefilter-revert-periodstart": "ช่วงเวลาเริ่มต้น:", "abusefilter-revert-periodend": "ช่วงเวลาสิ้นสุด:", "abusefilter-revert-search": "เลือกการกระทำ", - "abusefilter-revert-filter": "ตัวกรอง:", + "abusefilter-revert-filter": "หมายเลขประจำตัวกรอง:", "abusefilter-revert-preview-intro": "ด้านล่างนี้เป็นการกระทำโดยตัวกรองการละเมิดกฎที่จะถูกย้อนในปฏิบัติการนี้\nโปรดตรวจสอบอย่างระมัดระวัง และคลิก \"{{int:abusefilter-revert-confirm}}\" เพื่อยืนยันการเลือกของคุณ", + "abusefilter-revert-confirm-legend": "ยืนยันการย้อน", "abusefilter-revert-confirm": "ยืนยัน", "abusefilter-revert-success": "คุณย้อนการกระทำทั้งหมดโดยตัวกรองการละเมิดกฎเนื่องจาก[[Special:AbuseFilter/$1|ตัวกรอง $2]] แล้ว", "abusefilter-revert-reason": "ย้อนการกระทำทั้งหมดโดยตัวกรองการละเมิดกฎเนื่องจากตัวกรอง $1 แล้ว\nเหตุผลที่ให้ไว้: $2", @@ -335,12 +485,20 @@ "abusefilter-test-submit": "ทดสอบ", "abusefilter-test-load": "โหลด", "abusefilter-test-user": "การเปลี่ยนแปลงโดยผู้ใช้:", + "abusefilter-test-nobots": "ซ่อนการแก้ไขของบอต", "abusefilter-test-period-start": "การเปลี่ยนแปลงหลัง:", "abusefilter-test-period-end": "การเปลี่ยนแปลงก่อน:", "abusefilter-test-page": "การเปลี่ยนแปลงไปยังหน้า:", "abusefilter-test-shownegative": "แสดงการเปลี่ยนแปลงที่ไม่ตรงกับตัวกรอง", "abusefilter-test-syntaxerr": "ตัวกรองที่คุณกรอกนั้นมีวากยสัมพันธ์ผิดพลาด\nคุณสามารถดูคำอธิบายเต็มได้โดยคลิกปุ่ม \"{{int:abusefilter-edit-check}}\"", "abusefilter-test-badtitle": "ชื่อหน้าที่คุณกรอกไม่สมเหตุสมผล โดยอาจมีอักขระที่ไม่สามารถใช้เป็นชื่อเรื่อง", + "abusefilter-test-action": "ประเภทการกระทำ:", + "abusefilter-test-search-type-all": "การกระทำทั้งหมด", + "abusefilter-test-search-type-edit": "แก้ไข", + "abusefilter-test-search-type-move": "ย้อน", + "abusefilter-test-search-type-delete": "ลบ", + "abusefilter-test-search-type-upload": "อัปโหลด", + "abusefilter-test-search-type-createaccount": "สร้างบัญชี", "abusefilter-changeslist-examine": "ตรวจสอบ", "abusefilter-examine": "ตรวจสอบการเปลี่ยนแปลงจำเพาะ", "abusefilter-examine-intro": "หน้านี้ให้คุณตรวจสอบตัวแปรที่ตัวกรองการละเมิดกฎสร้างสำหรับการเปลี่ยนแปลงจำเพาะ และทดสอบกับตัวกรอง", @@ -360,13 +518,16 @@ "abusefilter-examine-noresults": "ไม่พบผลลัพธ์ตัวแปรเสริมการค้นหาที่คุณระบุ", "abusefilter-topnav": "'''ป้ายนำทางตัวกรองการละเมิดกฎ'''", "abusefilter-topnav-home": "หน้าแรก", + "abusefilter-topnav-recentchanges": "การเปลี่ยนแปลงตัวกรองล่าสุด", "abusefilter-topnav-test": "การทดสอบกลุ่ม", "abusefilter-topnav-examine": "ตรวจสอบการแก้ไขที่ผ่านมา", "abusefilter-topnav-log": "ปูมการละเมิดกฎ", "abusefilter-topnav-tools": "เครื่องมือแก้จุดบกพร่อง", - "abusefilter-topnav-import": "นำเข้าตัวกรอง", "abusefilter-log-name": "ปูมตัวกรองการละเมิดกฏ", - "abusefilter-log-header": "ปูมนี้แสดงสรุปการเปลี่ยนแปลงต่อตัวกรอง \nสำหรับรายละเอียดเต็ม ดู[[Special:AbuseFilter/history|รายการ]]การเปลี่ยนแปลงตัวกรองล่าสุด", + "abusefilter-log-header": "ปูมนี้แสดงความย่อการเปลี่ยนแปลงที่กระทำต่อตัวกรอง\nสำหรับรายละเอียดฉบับเต็ม ให้ดู[[Special:AbuseFilter/history|รายการ]]สำหรับการเปลี่ยนปลงตัวกรองล่าสุด", + "abusefilter-logentry-create": "$1 {{GENDER:$2|สร้าง}} $4 ($5)", + "abusefilter-logentry-modify": "$1 {{GENDER:$2|ดัดแปร}} $4 ($5)", + "abusefilter-log-invalid-filter": "ไอดีตัวกรองที่ระบุบางส่วนไม่ถูกต้อง", "abusefilter-log-noresults": "ไม่มีผลลัพธ์", "abusefilter-diff-title": "ความแตกต่างระหว่างรุ่น", "abusefilter-diff-item": "รายการ", @@ -377,6 +538,20 @@ "abusefilter-diff-backhistory": "กลับไปยังประวัติตัวกรอง", "abusefilter-diff-prev": "การเปลี่ยนแปลงที่เก่ากว่า", "abusefilter-diff-next": "การเปลี่ยนแปลงที่ใหม่กว่า", + "abusefilter-import-intro": "คุณสามารถใช้ส่วนติดต่อนี้เพื่อนำเข้าตัวกรองจากวิกิอื่นได้\nบนวิกิต้นฉบับ คลิก \"{{int:abusefilter-edit-export}}\" ภายใต้ \"{{int:abusefilter-edit-tools}}\" บนส่วนติดต่อการแก้ไข\nคัดลอกเนื้อหาจากกล่องข้อความที่ปรากฏ แล้ววางลงในกล่องข้อความนี้ แล้วคลิก \"{{int:abusefilter-import-submit}}\"", "abusefilter-import-submit": "นำเข้าข้อมูล", - "abusefilter-group-default": "ค่าโดยปริยาย" + "abusefilter-group-default": "ค่าโดยปริยาย", + "abusefilter-http-error": "เกิดข้อผิดพลาด HTTP: $1", + "abusefilter-view-privatedetails-submit": "ดูรายละเอียดลับ", + "abusefilter-view-privatedetails-legend": "ดูรายละเอียดลับ", + "abusefilter-view-privatedetails-reason": "เหตุผลสำหรับการเข้าถึงรายละเอียดลับ:", + "abusefilter-log-details-id": "หมายเลขปูม", + "abusefilter-invalid-request": "คำร้องขอไม่ถูกต้อง! คุณต้องเข้าถึงรายละเอียดปูมส่วนตัวผ่านฟอร์มบน [[Special:AbuseLog/$1]] และระบุเหตุผล", + "abusefilter-invalid-request-noid": "คำร้องขอไม่ถูกต้อง! คุณต้องเข้าถึงรายละเอียดปูมส่วนตัวผ่านฟอร์มบนหน้ารายละเอียดของปูมการละเมิดกฎและระบุเหตุผล", + "log-description-abusefilterprivatedetails": "ปูมนี้แสดงรายการเวลาที่ผู้ใช้เข้าถึงรายละเอียดส่วนตัวของปูมการละเมิดกฎ", + "abusefilter-noreason": "คำเตือน: หากต้องการดูรายละเอียดส่วนตัวของปูมนี้ คุณต้องระบุเหตุผล", + "abusefilter-log-ip-not-available": "ไม่มี", + "abusefilter-tag-reserved": "แท็ก <code>abusefilter-condition-limit</code> ถูกสงวนไว้สำหรับใช้ภายในโดยตัวกรองการละเมิดกฎ", + "tag-abusefilter-condition-limit": "ถึงขีดจำกัดเงื่อนไขแล้ว", + "tag-abusefilter-condition-limit-description": "การแก้ไขหรือเหตุการณ์อื่น ๆ ที่ไม่สามารถตรวจสอบได้โดย[[Special:AbuseFilter|ตัวกรองการละเมิดกฎ]]ที่ใช้งานอยู่ทั้งหมด ([[mw:Extension:AbuseFilter/Conditions|ความช่วยเหลือ]])" } diff --git a/AbuseFilter/i18n/ti.json b/AbuseFilter/i18n/ti.json new file mode 100644 index 00000000..2ae9421e --- /dev/null +++ b/AbuseFilter/i18n/ti.json @@ -0,0 +1,19 @@ +{ + "@metadata": { + "authors": [ + "Joanmp17" + ] + }, + "abusefilter-log-search-submit": "ምድላይ", + "abusefilter-log-hide-reason": "ምኽንያት፥", + "abusefilter-list-status": "ደረጃ", + "abusefilter-list-options": "ኣማራጺታት", + "abusefilter-list-options-submit": "ኣሐዲስ", + "abusefilter-edit-status-label": "ስታቲስቲክስ፥", + "abusefilter-history-diff": "ለውጥታት", + "abusefilter-test-search-type-edit": "ምምዕርራያት", + "abusefilter-topnav-home": "ቤት", + "abusefilter-diff-item": "ውልቀ ነገር", + "abusefilter-group-default": "ንቡር", + "abusefilter-log-ip-not-available": "ኣይርከብን" +} diff --git a/AbuseFilter/i18n/tk.json b/AbuseFilter/i18n/tk.json index 0ef45188..49d26768 100644 --- a/AbuseFilter/i18n/tk.json +++ b/AbuseFilter/i18n/tk.json @@ -6,15 +6,15 @@ ] }, "abusefilter-desc": "Özgerdişlerde awtomatik ewristik filtleri ulanýar", - "abusefilter": "Erbet ulanmak filtri konfigurasiýasy", - "abuselog": "Erbet ulanmak gündeligi", + "abusefilter": "Erbet Ulanmak filtr dolandyryşy", + "abuselog": "Erbet ulanmak filtri gündeligi", "abusefilter-blocker": "Erbet ulanmak filtri", "abusefilter-accountreserved": "Bu hasap ady betniýetli ulanyş filtri tarapyndan ulanylar ýaly ätiýaçlyga goýuldy.", "right-abusefilter-modify": "Erbet ulanmak filtrlerini üýtget", "right-abusefilter-view": "Erbet ulanmak filtrlerini görkez", "right-abusefilter-log": "Erbet ulanmak gündeligini görkez", "right-abusefilter-log-detail": "Jikme-jik gündelik girişlerini görkez", - "right-abusefilter-private": "Erbet ulanmak gündeligindäki hususy maglumatlary görkez", + "right-abusefilter-privatedetails": "Erbet ulanmak gündeligindäki hususy maglumatlary görkez", "right-abusefilter-modify-restricted": "Çäklendirilen hereketli erbet ulanmak filtrlerini üýtget", "right-abusefilter-revert": "Berlen erbet ulanmak filtri tarapyndan ähli üýtgeşmelri yzyna al", "right-abusefilter-view-private": "Hususy diýlip bellenilen erbet ulanmak filtrlerini görkez", @@ -24,11 +24,10 @@ "action-abusefilter-view": "erbet ulanmak filtrlerini görkez", "action-abusefilter-log": "erbet ulanmak gündeligini görkez", "action-abusefilter-log-detail": "jikme-jik erbet ulanmak gündeligi girişlerini görkez", - "action-abusefilter-private": "erbet ulanmak gündeligindäki hususy maglumatlary görkez", + "action-abusefilter-privatedetails": "erbet ulanmak gündeligindäki hususy maglumatlary görkez", "action-abusefilter-modify-restricted": "çäklendirilen hereketli erbet ulanmak filtrlerini üýtgetmäge", "action-abusefilter-revert": "berlen betniýetli ulanyş filtri tarapyndan edilen ähli üýtgeşmeleri yzyna al", "action-abusefilter-view-private": "hususy diýlip bellenilen betniýetli ulanyş filtrlerini görkez", - "abusefilter-log": "Erbet ulanmak filtri gündeligi", "abusefilter-log-summary": "Bu gündelik filtrlerde tutulan ähli hereketleriň sanawyny görkezýär.", "abusefilter-log-search": "Erbet ulanmak gündeligini gözle", "abusefilter-log-search-user": "Ulanyjy:", @@ -45,20 +44,18 @@ "abusefilter-log-details-var": "Üýtgeýän", "abusefilter-log-details-val": "Baha", "abusefilter-log-details-vars": "Hereket parametrleri", - "abusefilter-log-details-private": "Hususy maglumat", + "abusefilter-log-details-privatedetails": "Hususy maglumat", "abusefilter-log-details-ip": "Çeşme IP adresi", "abusefilter-log-noactions": "ýok", "abusefilter-log-details-diff": "Özgerdişde edilen üýtgeşmeler", "abusefilter-log-linkoncontribs": "erbet ulanmak gündeligi", "abusefilter-log-linkoncontribs-text": "Bu ulanyjy üçin Erbet Ulanmak Gündeligi", - "abusefilter-log-hidden": "(gizlin ýazgy)", "abusefilter-log-details-hidden": "Bu ýazgy üçin jikme-jiklikleri görüp bilmeýärsiňiz, çünki ol jemgyýetçilikden gizlenilipdir", "abusefilter-log-hide-legend": "Gündelik ýazgysyny gizle", "abusefilter-log-hide-id": "Gündelik ýazgysynyň ID-si:", "abusefilter-log-hide-hidden": "Bu ýazgyny köpçüligiň görmeginden gizle", "abusefilter-log-hide-reason": "Sebäp:", "abusefilter-log-hide-forbidden": "Betniýetli ulanyş gündeliginiň ýazgylaryny gizlemäge rugsadyňyz ýok.", - "abusefilter-management": "Erbet Ulanmak filtr dolandyryşy", "abusefilter-list": "Ähli filtrler", "abusefilter-list-id": "Filtr ID-si", "abusefilter-list-status": "Status", @@ -77,6 +74,7 @@ "abusefilter-disabled": "Ýapyk", "abusefilter-hitcount": "$1 {{PLURAL:$1|hit|hit}}", "abusefilter-new": "Täze filtr döret", + "abusefilter-import-button": "Filtri importirle", "abusefilter-return": "Filtr dolandyryşyna gaýdyp bar", "abusefilter-status-global": "Global", "abusefilter-list-options": "Opsiýalar", @@ -98,7 +96,6 @@ "abusefilter-edit-subtitle": "$1 filtri redaktirlenýär", "abusefilter-edit-status-label": "Statistikalar:", "abusefilter-edit-status": "Bu filtr soňky $1 {{PLURAL:$1|hereketden|hereketden}} $2 (%$3) sanysyna gabat geldi.", - "abusefilter-edit-status-profile": "Bu filtr soňky $1 {{PLURAL:$1|hereketden|hereketden}} $2 (%$3) sanysyna gabat geldi.\nOrtaça alnanda, işlän wagty $4ms, we onuň şert çägi $5 sany şerti sarp edýär.", "abusefilter-edit-new": "Täze filtr", "abusefilter-edit-save": "Filtri ýazdyr", "abusefilter-edit-id": "Filtr ID-si:", @@ -221,13 +218,13 @@ "abusefilter-edit-builder-vars-all-links": "Täze tekstdäki ähli daşarky çykgytlar", "abusefilter-edit-builder-vars-added-links": "Özgerdişe goşulan ähli daşarky çykgytlar", "abusefilter-edit-builder-vars-removed-links": "Özgerdişden aýyrlan ähli daşarky çykgytlar", - "abusefilter-edit-builder-vars-old-text": "Köne sahypa wikiteksti, özgerdişden öň", - "abusefilter-edit-builder-vars-new-text": "Täze sahypa wikiteksti, özgerdişden soň", - "abusefilter-edit-builder-vars-new-text-stripped": "Täze sahypa teksti, hiçhili belliksiz", + "abusefilter-edit-builder-vars-old-wikitext": "Köne sahypa wikiteksti, özgerdişden öň", + "abusefilter-edit-builder-vars-new-wikitext": "Täze sahypa wikiteksti, özgerdişden soň", + "abusefilter-edit-builder-vars-new-text": "Täze sahypa teksti, hiçhili belliksiz", "abusefilter-edit-builder-vars-new-html": "Täze wersiýanyň tertibe salnan HTML çeşmesi", "abusefilter-edit-builder-vars-restrictions-edit": "Sahypanyň redaktirleme gorag derejesi", "abusefilter-edit-builder-vars-restrictions-move": "Sahypanyň gorag derejesini geçir", - "abusefilter-edit-builder-vars-old-text-stripped": "Köne sahypa teksti, hiçhili belliksiz", + "abusefilter-edit-builder-vars-old-text": "Köne sahypa teksti, hiçhili belliksiz", "abusefilter-edit-builder-vars-old-links": "Sahypadaky çykgytlar, özgerdişden öňki", "abusefilter-edit-builder-vars-old-html": "Köne sahypanyň wikiteksti, HTML-de tertiplenen", "abusefilter-edit-builder-vars-minor-edit": "Özgerdiş \"ujypsyzja\" diýlip bellenilen bolsa-da, bolmasa-da", @@ -309,7 +306,6 @@ "abusefilter-topnav-examine": "Öňki özgerdişleri gözden geçir", "abusefilter-topnav-log": "Erbet ulanmak gündeligi", "abusefilter-topnav-tools": "Otkladka gurallary", - "abusefilter-topnav-import": "Filtri importirle", "abusefilter-log-name": "Erbet ulanmak filtr gündeligi", "abusefilter-log-header": "Bu gündelik filtrlerde edilen üýtgeşmeleriň düşündirişini görkezýär.\nJikme-jik maglumat üçin, soňky filtr üýtgeşmeleriniň [[Special:AbuseFilter/history|sanawyna]] serediň.", "abusefilter-diff-title": "Wersiýalaryň aratapawutlary", diff --git a/AbuseFilter/i18n/tl.json b/AbuseFilter/i18n/tl.json index ee85d816..d50904b6 100644 --- a/AbuseFilter/i18n/tl.json +++ b/AbuseFilter/i18n/tl.json @@ -2,15 +2,16 @@ "@metadata": { "authors": [ "AnakngAraw", + "Emem.calist", + "Fitoschido", "Jojit fb", "Matma Rex", - "Emem.calist", "Sky Harbor" ] }, "abusefilter-desc": "Naghahain ng mga kusang gabay-aral/heuristiko sa mga pamamatnugot", - "abusefilter": "Pagkakaayos ng pansala ng pang-aabuso", - "abuselog": "Tala ng pang-aabuso", + "abusefilter": "Pamamahala ng pansala ng pang-aabuso", + "abuselog": "Tala ng pansala ng pang-aabuso", "abusefilter-intro": "Maligayang pagdating sa ugnayang-hangganan ng pamamahala ng Pansala ng Pang-aabuso.\nAng Pansala ng Pang-aabuso ay isang kusang mekanismo ng sopwer ng paggamit ng automatikong tulong ng pagkatuto sa lahat ng mga kilos.\nNagpapakita ang ugnayang-hangganang ito ng isang talaan ng binigyang kahulugang mga pansala, at nagpapahintulot na mabago ang mga ito.", "abusefilter-warning": "'''Babala''': Ang galaw na ito ay kusang kinilala bilang mapanganib. Mabilisang ibabalik sa dati ang hindi nakapagpapainam na pagbabago, at magbubunga ang kapansin-pansin at paulit-ulit na hindi maiinam na pagbabago ng pagharang sa akawnt o adres ng IP. Kung sa tingin mong mainam ang pagbabagong ito, maaaring mong pindutin uli ang Ipasa upang tiyakin ito. Isang maikling paglalarawan ng alituntunin sa pang-aabuso na tumugma sa iyong galaw ang: $1", "abusefilter-disallowed": "Ang kilos na ito ay kusang nakilala bilang makakapinsala,\nkaya't hindi pinahintulutan.\nKung naniniwala kang mabuti ang iyong ginawang pagbabago, makipag-ugnayan sa isang tagapangasiwa, at ipagbigay-alam sa kanila ang kung ano ang sinusubok mong gawin.\nIsang maiksing paglalarawan ng alituntunin sa pang-aabuso na tumugma sa kilos mo ang: $1", @@ -25,7 +26,7 @@ "right-abusefilter-view": "Tingnan ang mga pansala ng pang-aabuso", "right-abusefilter-log": "Tingnan ang tala ng pang-aabuso", "right-abusefilter-log-detail": "Tingnan ang detalyadong mga ipinasok sa tala ng pang-aabuso", - "right-abusefilter-private": "Tingnan ang pansariling datong nasa loob ng tala ng pang-aabuso", + "right-abusefilter-privatedetails": "Tingnan ang pansariling datong nasa loob ng tala ng pang-aabuso", "right-abusefilter-modify-restricted": "Baguhin ang mga pansala ng pang-aabuso na may hangganan sa mga paggalaw", "right-abusefilter-revert": "Ibalik sa dati ang lahat ng mga pagbabagong ginawa ng isang partikular na pansala ng pang-aabuso", "right-abusefilter-view-private": "Tingnan ang mga pansala ng pang-aabuso bilang pribado", @@ -36,11 +37,10 @@ "action-abusefilter-view": "tingnan ang mga pansala ng pang-aabuso", "action-abusefilter-log": "tingnan ang talaan ng pang-aabuso", "action-abusefilter-log-detail": "tingnan ang detalyadong mga ipinasok sa talaan ng pang-aabuso", - "action-abusefilter-private": "tingnan ang pribadong datong nasa loob ng talaan ng pang-aabuso", + "action-abusefilter-privatedetails": "tingnan ang pribadong datong nasa loob ng talaan ng pang-aabuso", "action-abusefilter-modify-restricted": "baguhin ang mga pansala ng pang-aabuso na may mga kilos na may hangganan", "action-abusefilter-revert": "ibalik sa dati ang lahat ng mga pagbabago ginawa ng isang ibinigay na pansala ng pang-aabuso", "action-abusefilter-view-private": "tingnan ang mga pansala ng pang-aabuso na tinatakan bilang pribado", - "abusefilter-log": "Tala ng pansala ng pang-aabuso", "abusefilter-log-summary": "Nagpapakita ang talaang ito ng isang talaan ng lahat ng mga kilos na nahuli ng mga pansala.", "abusefilter-log-search": "Maghanap sa tala ng pang-aabuso", "abusefilter-log-search-user": "Tagagamit:", @@ -62,13 +62,12 @@ "abusefilter-log-details-var": "Pabagu-bago", "abusefilter-log-details-val": "Halaga", "abusefilter-log-details-vars": "Mga parametro ng kilos", - "abusefilter-log-details-private": "Pansariling dato", + "abusefilter-log-details-privatedetails": "Pansariling dato", "abusefilter-log-details-ip": "Pinagmumulang adres ng IP", "abusefilter-log-noactions": "wala", "abusefilter-log-details-diff": "Mga pagbabagong ginawa sa pamamatnugot", "abusefilter-log-linkoncontribs": "Tala ng pang-aabuso", "abusefilter-log-linkoncontribs-text": "Tala ng Pang-aabuso para sa tagagamit na ito", - "abusefilter-log-hidden": "(nakatago ang ipinasok)", "abusefilter-log-hidden-implicit": "(nakakubli dahil nabura ang rebisyon)", "abusefilter-log-cannot-see-details": "Wala kang pahintulot upang tingnan ang mga detalye ng lahok na ito.", "abusefilter-log-details-hidden": "Hindi mo makikita ang mga detalye para sa ipinasok na ito dahil nakatago ito mula sa pagtanaw ng madla.", @@ -78,7 +77,6 @@ "abusefilter-log-hide-reason": "Dahilan:", "abusefilter-log-hide-forbidden": "Wala kang pahintulot na itago ang mga pagpapasok sa tala ng pang-aabuso.", "logentry-abusefilter-hit": "Nakanti ni $1 ang $4, na nagsagawa ng kilos na \"$5\" doon sa $3. Mga kilos na ginawa: $6 ($7)", - "abusefilter-management": "Pamamahala ng pansala ng pang-aabuso", "abusefilter-list": "Lahat ng mga pansala", "abusefilter-list-id": "ID ng pansala", "abusefilter-list-status": "Kalagayan", @@ -98,6 +96,7 @@ "abusefilter-disabled": "Hindi pinagana", "abusefilter-hitcount": "$1 {{PLURAL:$1|paghagip|mga paghagip}}", "abusefilter-new": "Lumikha ng isang bagong pansala", + "abusefilter-import-button": "Angkatin ang pansala", "abusefilter-return": "Bumalik sa pamamahala ng pansala", "abusefilter-status-global": "Pandaigdigan", "abusefilter-list-options": "Mga pagpipilian", @@ -125,7 +124,6 @@ "abusefilter-edit-oldwarning": "<strong>Binabago mo ang isang lumang bersyon ng pansalang ito. Ang siniping mga estadistika ay para sa pinakakamakailang bersyon ng pansala. Kapag sinagip mo ang iyong mga pagbabago, mapapatungan mo ang lahat ng mga pagbabago magmula sa rebisyong pinapatnugutan mo.</strong> • [[Special:AbuseFilter/history/$2|Bumalik sa kasaysayan ng pansalang ito]]", "abusefilter-edit-status-label": "Mga estadistika:", "abusefilter-edit-status": "Mula sa huling $1 na {{PLURAL:$1|kilos|mga kilos}}, tumugma ang pansalang ito sa $2 ($3%).", - "abusefilter-edit-status-profile": "Mula sa huling $1 na {{PLURAL:$1|kilos|mga kilos}}, tumugma ang pansalang ito sa $2 ($3%).\nSa karaniwan, ang oras ng pagtakbo nito ay $4ms, at gumugugol ng $5 na {{PLURAL:$5|kundisyon|mga kundisyon}} ng hangganan ng kundisyon.", "abusefilter-edit-new": "Bagong pansala", "abusefilter-edit-save": "Itala ang pansala", "abusefilter-edit-id": "ID ng pansala:", @@ -153,10 +151,10 @@ "abusefilter-edit-throttle-count": "Bilang ng papayagang mga kilos:", "abusefilter-edit-throttle-period": "Panahong saklaw:", "abusefilter-edit-throttle-groups": "Siiling nakapangkat sa pamamagitan ng:\n:''(isa bawat guhit, pagsamahing may mga kuwit)''", - "abusefilter-edit-throttle-ip": "Direksiyong IP", - "abusefilter-edit-throttle-user": "Account ng tagagamit", - "abusefilter-edit-throttle-range": "Ranggong /16", - "abusefilter-edit-throttle-page": "Pahina", + "abusefilter-throttle-ip": "direksiyong IP", + "abusefilter-throttle-user": "account ng tagagamit", + "abusefilter-throttle-range": "Ranggong /16", + "abusefilter-throttle-page": "pahina", "abusefilter-throttle-details": "Panatilihing $1 {{PLURAL:$1|action|actions}} kada- $2 {{PLURAL:$2|second|seconds}}, sa mga grupong naitakda na: $3", "abusefilter-edit-warn-message": "Mensahe ng sistemang gagamitin para sa babala:", "abusefilter-edit-warn-other": "Iba pang mensahe", @@ -263,13 +261,13 @@ "abusefilter-edit-builder-vars-all-links": "Lahat ng panlabas na mga kawing na nasa loob ng bagong teksto", "abusefilter-edit-builder-vars-added-links": "Lahat ng panlabas na mga kawing na idinagdag sa loob ng pagbabago", "abusefilter-edit-builder-vars-removed-links": "Lahat ng panlabas na mga kawing na tinanggal sa loob ng pagbabago", - "abusefilter-edit-builder-vars-old-text": "Lumang pahina ng tekstong wiki, bago ginawa ang pagbago", - "abusefilter-edit-builder-vars-new-text": "Bagong pahina ng tekstong wiki, pagkaraan ng pagbabago", - "abusefilter-edit-builder-vars-new-text-stripped": "Teksto ng bagong pahina, na tinanggalan ng anumang pananda", + "abusefilter-edit-builder-vars-old-wikitext": "Lumang pahina ng tekstong wiki, bago ginawa ang pagbago", + "abusefilter-edit-builder-vars-new-wikitext": "Bagong pahina ng tekstong wiki, pagkaraan ng pagbabago", + "abusefilter-edit-builder-vars-new-text": "Teksto ng bagong pahina, na tinanggalan ng anumang pananda", "abusefilter-edit-builder-vars-new-html": "Binanghay na pinagmulang HTML ng bagong rebisyon", "abusefilter-edit-builder-vars-restrictions-edit": "Baguhin ang antas ng pagsasanggalang ng pahina", "abusefilter-edit-builder-vars-restrictions-move": "Ilipat ang antas ng pagsasanggalang ng pahina", - "abusefilter-edit-builder-vars-old-text-stripped": "Teksto ng lumang pahina, na tinanggalan ng anumang pantanda", + "abusefilter-edit-builder-vars-old-text": "Teksto ng lumang pahina, na tinanggalan ng anumang pantanda", "abusefilter-edit-builder-vars-old-links": "Mga kawing sa loob ng pahina, bago mangyari ang pagbago", "abusefilter-edit-builder-vars-old-html": "Teksto ng wiki ng lumang pahina, ibinanghay upang maging HTML", "abusefilter-edit-builder-vars-minor-edit": "Kung tinatakan ba o hindi ang pagbabago bilang mababa ang antas", @@ -366,7 +364,6 @@ "abusefilter-topnav-examine": "Suriin ang nakaraang mga pamamatnugot", "abusefilter-topnav-log": "Talaan ng Pang-aabuso", "abusefilter-topnav-tools": "Mga kagamitang pantanggal ng depekto", - "abusefilter-topnav-import": "Angkatin ang pansala", "abusefilter-log-name": "Talaan ng Pansala ng Pang-aabuso", "abusefilter-log-header": "Nagpapakita ang talaang ito ng isang buod ng mga pagbabagong ginawa sa mga pansala.\nPara sa buong mga detalye, tingnan [[Special:AbuseFilter/history|ang talaan]] ng kamakailang mga pagbabago sa pansala.", "abusefilter-log-noresults": "Walang mga resulta", diff --git a/AbuseFilter/i18n/tly.json b/AbuseFilter/i18n/tly.json index 336ba0f3..5f99798e 100644 --- a/AbuseFilter/i18n/tly.json +++ b/AbuseFilter/i18n/tly.json @@ -1,9 +1,13 @@ { "@metadata": { "authors": [ - "Erdemaslancan" + "Erdemaslancan", + "Patriot Kur" ] }, - "abusefilter-list-options": "Кукон", - "abusefilter-history-comments": "Мындәриҹот" + "abusefilter-list-edit": "Dəqiş karde", + "abusefilter-list-options": "Tənziməkon", + "abusefilter-throttle-page": "səhifə", + "abusefilter-edit-builder-vars-page-id": "Səhifə ID", + "abusefilter-history-comments": "Şərhon" } diff --git a/AbuseFilter/i18n/tn.json b/AbuseFilter/i18n/tn.json new file mode 100644 index 00000000..619950fb --- /dev/null +++ b/AbuseFilter/i18n/tn.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Mosime" + ] + }, + "abusefilter-list-invalid-searchmode": "Patlisiso e e dirisitsweng ga ya letlelelwa" +} diff --git a/AbuseFilter/i18n/tr.json b/AbuseFilter/i18n/tr.json index 672f92cb..aaa438b4 100644 --- a/AbuseFilter/i18n/tr.json +++ b/AbuseFilter/i18n/tr.json @@ -1,29 +1,33 @@ { "@metadata": { "authors": [ + "Ayrıntılı Bilgi", + "BaRaN6161 TURK", + "By erdo can", + "Diyapazon", "Emperyan", "Erdemaslancan", + "Fitoschido", + "Hedda", "Hedda Gabler", "Incelemeelemani", "Joseph", "LuCKY", "Mach", - "Srhat", - "Vito Genovese", - "Ayrıntılı Bilgi", - "Sayginer", - "Mavrikant", - "Ömer Berkay", "Matma Rex", - "Diyapazon", - "Hedda", + "Mavrikant", + "MuratTheTurkish", "Rapsar", + "Sayginer", + "Srhat", "TmY e12", - "By erdo can" + "ToprakM", + "Vito Genovese", + "Ömer Berkay" ] }, "abusefilter-desc": "Değişikliklere otomatik bulucu yöntemler uygular", - "abusefilter": "Kötüye kullanım süzgeci yapılandırması", + "abusefilter": "Kötüye kullanım süzgeci yönetimi", "abuselog": "Kötüye kullanım günlüğü", "abusefilter-intro": "Kötüye Kullanım Süzgeci yönetim arayüzüne hoş geldiniz.\nKötüye Kullanım Süzgeci, tüm işlemlere otomatik bulucu yöntemler uygulayan otomatik bir yazılım mekanizmasıdır.\nBu arayüz, tanımlı süzgeçlerin listesini gösterir ve değiştirilmelerine olanak sağlar.", "abusefilter-mustviewprivateoredit": "Güvenlik nedenleriyle, yalnızca özel kötüye kullanım filtrelerini görüntüleme veya filtreleri değiştirme hakkı olan kullanıcılar bu arayüzü kullanabilir.", @@ -35,49 +39,61 @@ "abusefilter-blocker": "Kötüye kullanım süzgeci", "abusefilter-blockreason": "Kötüye kullanım süzgeci tarafından otomatik olarak engellendi.\nEşleşen kuralın açıklaması: $1", "abusefilter-degroupreason": "Haklar, suistimal filtresi tarafından otomatik olarak kısıtlandı.\nKural açıklaması: $1", + "abusefilter-blockautopromotereason": "Kötüye kullanım filtresi tarafından otomatik olarak otomatik ilerleme.\nKural açıklaması: $1", "abusefilter-accountreserved": "Bu hesap adı, kötüye kullanım süzgeci tarafından kullanım için ayrıldı.", - "right-abusefilter-modify": "Kötüye kullanım süzgeçlerini değiştir", + "right-abusefilter-modify": "Kötüye kullanım filtreleri oluştur veya değiştir", "right-abusefilter-view": "Kötüye kullanım süzgeçlerini gör", "right-abusefilter-log": "Kötüye kullanım günlüğünü gör", "right-abusefilter-log-detail": "Ayrıntılı suistimal girdilerini gör", - "right-abusefilter-private": "Kötüye kullanım günlüğündeki özel verileri gör", - "right-abusefilter-private-log": "AbuseFilter özel ayrıntıları erişim günlüğünü görüntüle", + "right-abusefilter-privatedetails": "Kötüye kullanım günlüğündeki özel verileri gör", + "right-abusefilter-privatedetails-log": "AbuseFilter özel ayrıntıları erişim günlüğünü görüntüle", "right-abusefilter-modify-restricted": "Kısıtlı eylemler içeren suistimal filtrelerini değiştir", "right-abusefilter-revert": "Verilen bir suistimal filtresi tarafından yapılan tüm değişiklikleri geri al", "right-abusefilter-view-private": "Özel olarak işaretlenmiş suistimal filtrelerini gör", "right-abusefilter-log-private": "Özel olarak işaretlenmiş suistimal süzgeci günlük girdilerini gör", "right-abusefilter-hide-log": "Girdileri kötüye kullanım günlüğünde gizle", - "right-abusefilter-hidden-log": "Gizli suistimal günlüğü girdilerine bak", + "right-abusefilter-hidden-log": "Gizli kötüye kullanım günlüğü girişlerini görüntüle", "right-abusefilter-modify-global": "Küresel suistimal süzgeçleri oluştur ya da değiştir", - "action-abusefilter-modify": "kötüye kullanım süzgeçlerini değiştirmek", - "action-abusefilter-view": "kötüye kullanım süzgeçlerini görmek", - "action-abusefilter-log": "kötüye kullanım günlüğünü görmek", - "action-abusefilter-log-detail": "ayrıntılı kötüye kullanım günlüğünü girdilerini görmek", - "action-abusefilter-private": "kötüye kullanım günlüğündeki özel verileri görmek", - "action-abusefilter-private-log": "AbuseFilter özel ayrıntıları erişim günlüğünü gör", - "action-abusefilter-modify-restricted": "kısıtlanmış işlemlere sahip kötüye kullanım süzgeçlerini değiştirmek", - "action-abusefilter-revert": "belirli bir kötüye kullanım süzgecindeki tüm değişiklikleri geri almak", - "action-abusefilter-view-private": "özel olarak işaretlenmiş kötüye kullanım süzgeçlerini görmeye", - "action-abusefilter-log-private": "Özel olarak işaretlenmiş kötüye kullanım süzgeci günlüklerini gör", - "abusefilter-log": "Kötüye kullanım süzgeci günlüğü", + "action-abusefilter-modify": "kötüye kullanım süzgeçlerini değiştir", + "action-abusefilter-view": "kötüye kullanım süzgeçlerini gör", + "action-abusefilter-log": "kötüye kullanım günlüğünü gör", + "action-abusefilter-log-detail": "ayrıntılı kötüye kullanım günlüğünü girdilerini gör", + "action-abusefilter-privatedetails": "kötüye kullanım günlüğündeki özel verileri gör", + "action-abusefilter-privatedetails-log": "AbuseFilter özel ayrıntıları erişim günlüğünü gör", + "action-abusefilter-modify-restricted": "kısıtlanmış işlemlere sahip kötüye kullanım süzgeçlerini değiştir", + "action-abusefilter-revert": "belirli bir kötüye kullanım süzgecindeki tüm değişiklikleri geri al", + "action-abusefilter-view-private": "özel olarak işaretlenmiş kötüye kullanım süzgeçlerini gör", + "action-abusefilter-log-private": "özel olarak işaretlenmiş kötüye kullanım süzgeci günlüklerini gör", + "action-abusefilter-hide-log": "kötüye kullanım günlüğündeki girdileri gizle", + "action-abusefilter-hidden-log": "gizli kötüye kullanım günlüğü girişlerini görüntüle", + "action-abusefilter-modify-global": "küresel kötüye kullanım filtreleri oluşturun veya değiştirin", "abusefilter-log-summary": "Bu günlük, süzgeçlere yakalanan tüm eylemlerin bir listesini gösterir.", "abusefilter-log-search": "Kötüye kullanım günlüğünde ara", "abusefilter-log-search-user": "Kullanıcı:", - "abusefilter-log-search-filter": "Süzgeç kimlikleri (dikey çizgilerle ayrılmıştır):", + "abusefilter-log-search-group": "Filtre grubu:", + "abusefilter-log-search-group-any": "Herhangi", + "abusefilter-log-search-filter": "Filtre kimlikleri:", + "abusefilter-log-search-filter-help": "Borularla ayrı, genel filtreler için \"$1\" öneki", + "abusefilter-log-search-filter-help-central": "Borularla ayırın", "abusefilter-log-search-title": "Başlık:", "abusefilter-log-search-wiki": "Viki:", + "abusefilter-log-search-impact": "Etki:", "abusefilter-log-search-impact-all": "Tüm eylemler", "abusefilter-log-search-impact-saved": "Yalnızca kaydedilen değişiklikler", "abusefilter-log-search-impact-not-saved": "Kaydedilmiş değişiklikler olmadan", + "abusefilter-log-search-entries-label": "Görünürlük:", "abusefilter-log-search-entries-all": "Tüm girdiler", - "abusefilter-log-search-entries-hidden": "Sadece gizli girdiler", - "abusefilter-log-search-entries-visible": "Sadece görünen girdiler", + "abusefilter-log-search-entries-hidden": "Yalnızca gizli girdiler", + "abusefilter-log-search-entries-visible": "Yalnızca görünen girdiler", "abusefilter-log-search-action-label": "Tetikleme eylemi:", "abusefilter-log-search-action-other": "Diğer", - "abusefilter-log-search-action-any": "Hiç", + "abusefilter-log-search-action-any": "Herhangi", + "abusefilter-log-search-action-taken-label": "Alınan eylem:", + "abusefilter-log-search-action-taken-any": "Herhangi", "abusefilter-log-search-submit": "Ara", - "abusefilter-log-entry": "$1: $2 bir suistimal filtresini tetikledi, $4 sayfasında \"$3\" eylemi yapılıyor.\nYapılan eylemler: $5;\nFiltre açıklaması: $6", - "abusefilter-log-detailedentry-meta": "$1: $2, tetiklediği süzgeç: $3, $5 sayfasında \"$4\" eylemini yaptı.\nYapılan eylemler: $6;\nSüzgeç açıklaması: $7 ($8)", + "abusefilter-log-entry": "$1: $2 bir suistimal filtresini {{GENDER:$8|tetikledi}}, $4 sayfasında \"$3\" {{GENDER:$8|eylemi yapılıyor}}.\nYapılan eylemler: $5;\nFiltre açıklaması: $6", + "abusefilter-log-entry-withdiff": "$1: $2 {{GENDER:$8|tetiklenen}} bir kötüye kullanım filtresi, {{GENDER:$8|üzerinde}} \"$3\" üzerinden $4 eylemi gerçekleştirildi.\nYapılan işlemler: $5;\nFiltre açıklaması: $6 ($7)", + "abusefilter-log-detailedentry-meta": "$1: $2 {{GENDER:$9|tetiklenen}} $3, {{GENDER:$9|eylemi}} \"$4\" $5 üzerinde gerçekleştiriliyor.\nYapılan işlemler: $6;\nFiltre açıklaması: $7 ($8)", "abusefilter-log-detailedentry-global": "küresel süzgeç $1", "abusefilter-log-detailedentry-local": "$1 süzgeci", "abusefilter-log-detailslink": "detaylar", @@ -87,28 +103,44 @@ "abusefilter-log-details-var": "Değişken", "abusefilter-log-details-val": "Değer", "abusefilter-log-details-vars": "Eylem parametreleri", - "abusefilter-log-details-private": "Özel günlük detayları", + "abusefilter-log-details-privatedetails": "Özel günlük detayları", "abusefilter-log-details-ip": "Kaynak IP adresi", "abusefilter-log-details-checkuser": "Denetçi", - "abusefilter-log-noactions": "yok", + "abusefilter-log-noactions": "hiçbiri", + "abusefilter-log-noactions-filter": "Hiçbiri", "abusefilter-log-details-diff": "Düzenleme yapılan değişiklikler", "abusefilter-log-linkoncontribs": "kötüye kullanım günlüğü", "abusefilter-log-linkoncontribs-text": "{{GENDER:$1|Bu kullanıcı}} için kötüye kullanım günlüğü", "abusefilter-log-linkonhistory": "istismar günlüğünü görüntüle", "abusefilter-log-linkonhistory-text": "Bu sayfa için kötüye kullanım günlüğünü görüntüle", - "abusefilter-log-hidden": "(gizli girdi)", + "abusefilter-log-linkonundelete": "kötüye kullanım günlüğünü görüntüle", + "abusefilter-log-linkonundelete-text": "Bu sayfa için kötüye kullanım günlüğünü görüntüle", "abusefilter-log-hidden-implicit": "(gizlendi çünkü revizyon silindi)", "abusefilter-log-cannot-see-details": "Bu giriş detaylarını görebilmek için izniniz yok.", - "abusefilter-log-cannot-see-private-details": "Bu maddenin özel ayrıntılarını görme izniniz yok.", + "abusefilter-log-cannot-see-privatedetails": "Bu maddenin özel ayrıntılarını görme izniniz yok.", + "abusefilter-log-nonexistent": "Sağlanan kimliğe sahip bir giriş yok.", "abusefilter-log-details-hidden": "Bu girdinin ayrıntılarını göremezsiniz çünkü herkese açık değil", "abusefilter-log-details-hidden-implicit": "İlgili revizyonun silinmesi nedeniyle ayrıntılarını maalesef görüntüleyemezsiniz.", + "abusefilter-log-private-not-included": "Belirttiğiniz filtre kimliklerinden biri veya daha fazlası özel. Özel filtrelerin ayrıntılarını görüntüleyemediğiniz için, bu filtreler aranmadı.", "abusefilter-log-hide-legend": "Günlük girişini gizle", "abusefilter-log-hide-id": "Günlük girdi numarası:", "abusefilter-log-hide-hidden": "Bu girdiyi herkesin görüntülemesini engelle", "abusefilter-log-hide-reason": "Sebep:", + "abusefilter-log-hide-reason-other": "Diğer/ek gerekçe:", "abusefilter-log-hide-forbidden": "Kötüye kullanım günlüğü girdilerini gizleme yetkiniz yok.", - "logentry-abusefilter-hit": "$1, $3 sayfasında \"$5\" eylemini yaparak, $4 süzgecini tetikledi. Alınan eylemler: $6 ($7)", - "abusefilter-management": "Kötüye kullanım süzgeci yönetimi", + "abusefilter-log-entry-suppress": "$1 $3 {{GENDER:$2|gizli}}", + "abusefilter-log-entry-unsuppress": "$1 $3 {{GENDER:$2|gizli değil}}", + "logentry-abusefilter-hit": "$1 {{GENDER:$2|tetiklenen}} $4, {{GENDER:$2|eylemi}} $3 üzerinde \"$5\" gerçekleştiriliyor. Yapılan işlemler: $6 ($7)", + "log-action-filter-abusefilter": "Filtre değişiminin türü:", + "log-action-filter-abusefilter-create": "Yeni filtre oluşturma", + "log-action-filter-abusefilter-modify": "Filtre değişikliği", + "log-action-filter-suppress-abuselog": "Kötüye kullanım günlük bastırma", + "log-action-filter-rights-blockautopromote": "Otopromot bloğu", + "log-action-filter-rights-restoreautopromote": "Otopromot geri yükleme", + "logentry-abusefilterprivatedetails-access": "$1, $3 için özel detaylar {{GENDER:$2|erişildi}}", + "logentry-rights-blockautopromote": "$1 otomatik tanıtım {{GENDER:$4|$3}} bir süre için $5 {{GENDER:$2|engellendi}}", + "logentry-rights-restoreautopromote": "$1, {{GENDER:$4|$3}} otopromotion yeteneğini {{GENDER:$2|geri yüklendi}}", + "abusefilterprivatedetails-log-name": "AbuseFilter özel detaylar erişim günlüğü", "abusefilter-list": "Tüm süzgeçler", "abusefilter-list-id": "Süzgeç kimliği", "abusefilter-list-pattern": "Desen", @@ -127,18 +159,20 @@ "abusefilter-enabled": "Etkin", "abusefilter-deleted": "Silindi", "abusefilter-disabled": "Devre dışı", - "abusefilter-hitcount": "$1 eşleşme", + "abusefilter-throttled": "kısıtlandı", + "abusefilter-hitcount": "$1 {{PLURAL:$1|eşleşme|eşleşme}}", "abusefilter-new": "Yeni bir süzgeç oluştur", + "abusefilter-import-button": "Süzgeci içe aktar", "abusefilter-return": "Süzgeç yönetimine geri dön", "abusefilter-status-global": "Küresel", "abusefilter-list-options": "Seçenekler", "abusefilter-list-options-deleted": "Silinmiş süzgeçler:", - "abusefilter-list-options-deleted-only": "Sadece silinmiş süzgeçleri göster", + "abusefilter-list-options-deleted-only": "Yalnızca silinmiş filtreleri göster", "abusefilter-list-options-deleted-hide": "Silinmiş süzgeçleri gizle", "abusefilter-list-options-deleted-show": "Silinmiş süzgeçleri içer", "abusefilter-list-options-scope": "Süzgeçleri göster:", - "abusefilter-list-options-scope-local": "Sadece yerel kurallar", - "abusefilter-list-options-scope-global": "Sadece genel kurallar", + "abusefilter-list-options-scope-local": "Yalnızca yerel kurallar", + "abusefilter-list-options-scope-global": "Yalnızca genel kurallar", "abusefilter-list-options-scope-all": "Yerel ve genel kurallar", "abusefilter-list-options-further-options": "Diğer seçenekler:", "abusefilter-list-options-hidedisabled": "Devre dışı süzgeçleri gizle", @@ -149,28 +183,34 @@ "abusefilter-list-options-search-like": "Düz sorgu", "abusefilter-list-options-search-rlike": "Düzenli sorgu", "abusefilter-list-options-search-irlike": "Büyük-küçük harfe duyarlı sorgu", + "abusefilter-list-invalid-searchmode": "Belirtilen arama modu geçerli değil.", + "abusefilter-list-regexerror": "Arama yapılırken bir hata oluştu: Normal ifade sözdizimi hatası.", "abusefilter-list-options-submit": "Güncelle", "abusefilter-tools-text": "Burada suistimal filtrelerini formüle ederken ve hata ayıklarken yararlı olabilecek bazı araçlar bulunmaktadır.", "abusefilter-tools-expr": "İfade testi", "abusefilter-tools-submitexpr": "Değerlendir", + "abusefilter-tools-syntax-error": "Filtre geçersiz sözdizimine sahip.", "abusefilter-tools-reautoconfirm": "Otomatik onaylı durumu geri getir", "abusefilter-tools-reautoconfirm-user": "Kullanıcı:", "abusefilter-tools-reautoconfirm-submit": "Yeniden oto-onayla", + "abusefilter-tools-restoreautopromote": "Otomatik tanıtım, AbuseFilter araçlarıyla geri alındı.", "abusefilter-reautoconfirm-none": "Bu {{GENDER:$1|kullanıcının|kullanıcının|kullanıcıların}} otomatik onaylı durumu askıya alınmadı.", "abusefilter-reautoconfirm-notallowed": "Otomatik onaylı durumu getirmeye yetkiniz yok.", "abusefilter-reautoconfirm-done": "Hesabın otomatik onaylı durumu geri getirildi", - "abusefilter-status": "Son $1 {{PLURAL:$1|eylemde|eylemde}}, $2 (%$3) filtre $4 koşul sınırına erişti, ve $5 (%$6) eylem şuanda etkin bir filtreyle eşleşti.", + "abusefilter-status": "Son $1 {{PLURAL:$1|işlem|işlem}}, $2 (%$3) {{PLURAL:$2|şuanda|şuanda}} $4 ve $5 (%$6) koşul limitine ulaştı, etkin olan filtrelerden en az biriyle eşleşti.", "abusefilter-edit": "Kötüye kullanım süzgeci düzenleniyor", "abusefilter-edit-subtitle": "$1 süzgeci değiştiriliyor", "abusefilter-edit-subtitle-new": "Filtre oluşturma", + "abusefilter-edit-token-not-match": "Değişiklik kaydedilmedi! Lütfen tekrar kaydedin.", "abusefilter-edit-oldwarning": "<strong>Bu filtrenin eski bir sürümünü değiştiriyorsunuz.\nGösterilen istatistikler bu filtrenin en güncel sürümü içindir.\nEğer değişikliklerinizi kaydederseniz, değişiklik yaptığınız revizyondan itibaren tüm değişikliklerin üzerine yazacaksınız.</strong> •\n[[Special:AbuseFilter/history/$2|Bu filtrenin geçmişine geri dön]].", + "abusefilter-edit-oldwarning-view": "<strong>Bu filtrenin eski bir sürümünü görüntülüyorsunuz.\nAlıntılanan istatistikler filtrenin en son sürümleri içindir.</strong> •\n[[Special:AbuseFilter/history/$2|Bu filtrenin geçmişine dön]].", "abusefilter-edit-status-label": "İstatistikler:", - "abusefilter-edit-status": "Son $1 {{PLURAL:$1|eylemde|eylemde}}, $2 eylem ($3%) oranında bu filtreyle eşleşti.", - "abusefilter-edit-status-profile": "Son $1 {{PLURAL:$1|eylemde|eylemde}}, $2 eylem ($3%) oranında bu filtreyle eşleşti.\nOrtalama çalışma süresi $4ms olan bu süzgeç koşul sınırının $5 koşulunu tüketiyor.", + "abusefilter-edit-status": "Bu süzgeç son $1 işlemden $2 tanesi (%$3) ile eşleşmiştir.\nÇalışma süresi ortalama $4 ms'dir ve koşul sınırının $5 koşulunu tüketmektedir.", + "abusefilter-edit-throttled-warning": "'''Uyarı:''' Bu filtre otomatik olarak zararlı olarak işaretlendi. Bir güvenlik önlemi olarak, aşağıdaki eylemler yürütülmeyecektir ($1). Lütfen bu kısıtlamayı kaldırmak için koşullarınızı gözden geçirin ve [[mw:Extension:AbuseFilter/Conditions|optimize]] edinin", "abusefilter-edit-new": "Yeni süzgeç", "abusefilter-edit-save": "Süzgeci kaydet", "abusefilter-edit-id": "Süzgeç kimliği:", - "abusefilter-edit-switch-editor": "Düzenleme aracını değiştir", + "abusefilter-edit-switch-editor": "Düzenleyiciyi değiştir", "abusefilter-edit-description": "Açıklama:\n:''(umumi olarak görünebilir)''", "abusefilter-edit-field-description": "açıklama", "abusefilter-edit-group": "Filtre grubu:", @@ -183,40 +223,61 @@ "abusefilter-edit-field-conditions": "şartlar", "abusefilter-edit-notes": "Notlar:", "abusefilter-edit-lastmod": "Süzgeci son değiştiren:", - "abusefilter-edit-lastmod-text": "$1 tarihinde $2 tarafından", + "abusefilter-edit-lastmod-text": "$1 tarihinde $2", "abusefilter-edit-hitcount": "Süzgeç eşleşmeleri:", "abusefilter-edit-consequences": "Eşleştiğinde yapılacaklar", - "abusefilter-edit-action-warn": "Kullanıcıya bir uyarı verdikten sonra bu eylemleri tetikle", - "abusefilter-edit-action-disallow": "Kullanıcının, sorudaki eylemi yapmasını engelle", - "abusefilter-edit-action-blockautopromote": "Kullanıcının otomatik onaylı durumunu iptal et", + "abusefilter-edit-action-warn": "Kullanıcıya bir uyarıda bulunduktan sonra bu işlemleri etkinleştir", + "abusefilter-edit-action-disallow": "Kullanıcının söz konusu işlemi yapmasını önle", + "abusefilter-edit-action-blockautopromote": "Kullanıcının otomatik onaylanmış statüsünü geri al", "abusefilter-edit-action-degroup": "Kullanıcıyı tüm ayrıcalıklı gruplardan çıkar", - "abusefilter-edit-action-block": "Kullanıcıyı ve/veya IP adresini değişiklik yapmaya engelle", - "abusefilter-edit-action-throttle": "Eylemleri sadece, eğer kullanıcı bir derece sınırına takılırsa tetikle", - "abusefilter-edit-action-rangeblock": "Kullanıcının geldiği /16 aralığını engelle", - "abusefilter-edit-action-tag": "İleride gözden geçirme için değişikliği etiketle.", + "abusefilter-edit-action-block": "Kullanıcıyı ve/veya IP adresini engelle", + "abusefilter-edit-action-blocktalk": "Kullanıcının ve/veya IP adresinin kendi tartışma sayfasını düzenlemesini engelle", + "abusefilter-edit-action-throttle": "İşlemleri ancak kullanıcı bir derece sınırına takılırsa etkinleştir", + "abusefilter-edit-action-rangeblock": "Kullanıcının geldiği IP aralığını engelleyin", + "abusefilter-edit-action-tag": "Gözden geçirilmesi için düzenlemeyi etiketle", "abusefilter-edit-throttle-count": "İzin verilen eylem sayısı:", - "abusefilter-edit-throttle-period": "Zaman periyodu:", - "abusefilter-edit-throttle-groups": "Grup kısma yapan:\n:''(her satıra bir tane, virgülle birleştirin)''", - "abusefilter-edit-throttle-ip": "IP adresi", - "abusefilter-edit-throttle-user": "Kullanıcı hesabı", - "abusefilter-edit-throttle-editcount": "Değişiklik sayısı", - "abusefilter-edit-throttle-site": "Tüm site", - "abusefilter-edit-throttle-page": "Sayfa", + "abusefilter-edit-throttle-period": "Zaman periyodu (saniye):", + "abusefilter-edit-throttle-groups": "Grup kısma yapan:", + "abusefilter-edit-throttle-groups-help": "$1 sayfasına bakın.", + "abusefilter-edit-throttle-groups-help-text": "mediawiki.org adresindeki belgeler", + "abusefilter-edit-throttle-hidden-placeholder": "AND ile katılmak için virgüllerle ve OR ile katılmak için çizgi satırlarıyla bölün", + "abusefilter-edit-throttle-placeholder": "AND ile katılmak için virgülle bölün ve OR ile katılmak için tek tek ekleyin", + "abusefilter-throttle-ip": "IP adresi", + "abusefilter-throttle-user": "kullanıcı hesabı", + "abusefilter-throttle-range": "/16 aralık", + "abusefilter-throttle-creationdate": "hesap oluşturma tarihi", + "abusefilter-throttle-editcount": "değişiklik sayısı", + "abusefilter-throttle-site": "tüm site", + "abusefilter-throttle-page": "sayfa", + "abusefilter-throttle-none": "(hiçbiri)", + "abusefilter-throttle-details": "$1 {{PLURAL:$1|işlemi|işlemi}} her $2 {{PLURAL:$2|saniye|saniye}} izin ver, grup başına: $3", "abusefilter-edit-warn-message": "Uyarı için kullanılan sistem mesajı:", "abusefilter-edit-warn-other": "Diğer mesaj", - "abusefilter-edit-warn-other-label": "Diğer mesajın sayfa adı:\n:''(MediaWiki ön eki olmadan)''", + "abusefilter-edit-warn-other-label": "Diğer mesajın sayfa adı:\n:''(\"MediaWiki:\" öneki olmadan)''", "abusefilter-edit-warn-actions": "Eylemler:", "abusefilter-edit-warn-preview": "Seçilen mesajın önizlemesini göster/gizle", "abusefilter-edit-warn-edit": "Seçili mesajı oluştur/değiştir", - "abusefilter-edit-tag-tag": "Uygulanacak etiketler (her satıra bir tane):", + "abusefilter-edit-disallow-message": "İzin vermemek için kullanılacak sistem mesajı:", + "abusefilter-edit-disallow-other": "Diğer mesaj", + "abusefilter-edit-disallow-other-label": "Diğer mesajın sayfa adı:\n:''(\"MediaWiki:\" öneki olmadan)''", + "abusefilter-edit-disallow-actions": "Eylemler:", + "abusefilter-edit-disallow-preview": "Seçilen mesajın önizlemesini göster/gizle", + "abusefilter-edit-disallow-edit": "Seçili mesajı oluştur/düzenle", + "abusefilter-edit-tag-tag": "[[Special:Tags|Etiketler]] uygulanacak:", + "abusefilter-edit-tag-placeholder": "Etiketleri ekleyin (birer birer veya virgülle ayrılmış)", + "abusefilter-edit-tag-hidden-placeholder": "Etiket ekle (virgülle ayrılmış)", + "abusefilter-edit-block-anon-durations": "Anonim kullanıcılar için engelleme süresi:", + "abusefilter-edit-block-user-durations": "Kayıtlı kullanıcılar için engelleme süresi:", "abusefilter-block-anon": "Anonim kullanıcıları engelle", "abusefilter-block-user": "kayıtlı kullanıcıları engelle", "abusefilter-block-talk": "mesaj sayfası engellendi", "abusefilter-edit-denied": "Bu süzgecin ayrıntılarını göremeyebilirsiniz, çünkü umumi görünümden gizlenmiş.", - "abusefilter-edit-main": "Süzgeç değişkenleri", + "abusefilter-edit-main": "Filtre parametreleri", "abusefilter-edit-done-subtitle": "Süzgeç değiştirildi", "abusefilter-edit-done": "[[Special:AbuseFilter/$1|$3 süzgeci]] için [[Special:AbuseFilter/history/$1/diff/prev/$2|değişiklikleriniz]] kaydedildi.", "abusefilter-edit-badsyntax": "Belirttiğiniz filtrede bir söz dizimi hatası var.\nDerleyicinin çıktısı: <pre>$1</pre>", + "abusefilter-edit-missingfields": "Aşağıdaki alanlar zorunludur ve doldurulması zorunludur: $1", + "abusefilter-edit-deleting-enabled": "Aktif bir filtreyi silinmiş olarak işaretleyemezsiniz.", "abusefilter-edit-restricted": "Bu filtreyi değiştiremezsiniz, çünkü bir veya daha fazla kısıtlı eylem içeriyor.\nLütfen kısıtlı eylemleri eklemeye izni olan bir kullanıcıdan, sizin için değişikliği yapmasını isteyin.", "abusefilter-edit-viewhistory": "Bu süzgecin geçmişini gör", "abusefilter-edit-history": "Geçmiş:", @@ -228,10 +289,18 @@ "abusefilter-edit-export": "Bu süzgeci başka bir vikiye aktar", "abusefilter-edit-syntaxok": "Hiçbir sözdizimi hatası algılanmadı.", "abusefilter-edit-syntaxerr": "Sözdizimi hatası algılandı: $1", - "abusefilter-edit-bad-tags": "Belirttiğiniz etiketlerin bir veya daha fazlası geçersiz.\nEtiketler kısa olmalıdır, ve özel karakter içermemelidir.", + "abusefilter-edit-warn-leave": "Sayfadan çıkmak, bu filtrede yapılan değişiklikleri kaybetmenize neden olur.", + "abusefilter-edit-bad-tags": "Belirttiğiniz etiketlerden biri veya daha fazlası geçerli değil.\nEtiketler kısa olmalı, özel karakterler içermemeli ve başka bir yazılım tarafından rezerve edilmemelidir. Yeni bir etiket adı seçmeyi deneyin.", "abusefilter-edit-notallowed": "Kötüye kullanım süzgeci oluşturma veya düzenleme yetkiniz bulunmuyor", "abusefilter-edit-notallowed-global": "Küresel suistimal süzgeçlerini oluşturmaya ya da değiştirmeye izniniz yok", - "abusefilter-edit-notallowed-global-custom-msg": "Özel uyarı mesajları küresel süzgeçler için desteklenmiyor", + "abusefilter-edit-notallowed-global-custom-msg": "Genel filtreler için özel uyarı veya izin verme mesajları desteklenmez", + "abusefilter-edit-invalid-warn-message": "Uyarı mesajı boş bırakılamaz.", + "abusefilter-edit-invalid-disallow-message": "Uyarı mesajı boş bırakılamaz.", + "abusefilter-edit-invalid-throttlecount": "Gaz kelebeği hareket sayısı pozitif bir tamsayı olmalıdır.", + "abusefilter-edit-invalid-throttleperiod": "Gaz kelebeği periyodu pozitif bir tamsayı olmalıdır.", + "abusefilter-edit-empty-throttlegroups": "En az bir gaz grubu seçilmelidir.", + "abusefilter-edit-duplicated-throttlegroups": "Gaz kelebeği gruplarının kopyaları olamaz.", + "abusefilter-edit-invalid-throttlegroups": "Belirtilen gaz grupları geçerli değil.", "abusefilter-edit-builder-select": "İmleçte eklemek için bir seçenek seçin", "abusefilter-edit-builder-group-op-arithmetic": "Aritmetik operatörler", "abusefilter-edit-builder-op-arithmetic-addition": "Toplama (+)", @@ -241,12 +310,14 @@ "abusefilter-edit-builder-op-arithmetic-modulo": "Modülo (%)", "abusefilter-edit-builder-op-arithmetic-pow": "Üs (**)", "abusefilter-edit-builder-group-op-comparison": "Karşılaştırma operatörleri", - "abusefilter-edit-builder-op-comparison-equal": "Eşittir (==)", + "abusefilter-edit-builder-op-comparison-equal": "Değer eşittir (==)", + "abusefilter-edit-builder-op-comparison-equal-strict": "Değer ve eşittir (===)", "abusefilter-edit-builder-op-comparison-notequal": "Eşit değil (!=)", - "abusefilter-edit-builder-op-comparison-lt": "Küçüktür (<)", - "abusefilter-edit-builder-op-comparison-gt": "Büyüktür (>)", - "abusefilter-edit-builder-op-comparison-lte": "Küçük eşit (<=)", - "abusefilter-edit-builder-op-comparison-gte": "Büyük eşit (>=)", + "abusefilter-edit-builder-op-comparison-notequal-strict": "Değer ve tür eşit değil (!==)", + "abusefilter-edit-builder-op-comparison-lt": "Daha az (<)", + "abusefilter-edit-builder-op-comparison-gt": "Daha büyük (>)", + "abusefilter-edit-builder-op-comparison-lte": "Küçük veya eşit (<=)", + "abusefilter-edit-builder-op-comparison-gte": "Büyük veya eşit (>=)", "abusefilter-edit-builder-group-op-bool": "Mantıksal operatörler", "abusefilter-edit-builder-op-bool-not": "Değil (!)", "abusefilter-edit-builder-op-bool-and": "Ve (&)", @@ -259,48 +330,62 @@ "abusefilter-edit-builder-misc-contains": "Sol dizi sağ diziyi içeriyor (contains)", "abusefilter-edit-builder-misc-stringlit": "Dizi aynen (\"\")", "abusefilter-edit-builder-misc-tern": "Üçlü operatör (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "Koşullu (if X then Y else Z)", - "abusefilter-edit-builder-group-funcs": "Fonksiyonlar", + "abusefilter-edit-builder-misc-cond": "Koşullu (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "Kısa koşullu (if X then Y end)", + "abusefilter-edit-builder-group-funcs": "İşlevler", "abusefilter-edit-builder-funcs-length": "Dizin uzunluğu (length)", "abusefilter-edit-builder-funcs-lcase": "Küçük harfe çevir (lcase)", "abusefilter-edit-builder-funcs-ucase": "Büyük harfe (ucase)", "abusefilter-edit-builder-funcs-ccnorm": "Karıştırılabilir karakterleri normalleştir (ccnorm)", + "abusefilter-edit-builder-funcs-ccnorm-contains-any": "OR modunda birden fazla alt dizgiyi normalleştirmek ve aramak (ccnorm_contains_any)", + "abusefilter-edit-builder-funcs-ccnorm-contains-all": "VE modunda birden fazla alt dizgiyi normalleştirmek ve aramak(ccnorm_contains_all)", "abusefilter-edit-builder-funcs-rmdoubles": "Çift-karakterleri çıkar (rmdoubles)", "abusefilter-edit-builder-funcs-specialratio": "Özel karakterler / toplam karakterler (specialratio)", "abusefilter-edit-builder-funcs-norm": "Normalleştir (norm)", "abusefilter-edit-builder-funcs-count": "X dizisinin Y dizisi içinde görünme sayısı (count)", "abusefilter-edit-builder-funcs-rcount": "X düzenli ifadesinin Y dizisinde görülme sayısı (rcount)", + "abusefilter-edit-builder-funcs-get_matches": "Her bir yakalama grubu için bir metin içindeki düzenli ifade dizisi eşleşir (get_matches)", "abusefilter-edit-builder-funcs-rmwhitespace": "Beyazboşluğu çıkar (rmwhitespace)", "abusefilter-edit-builder-funcs-rmspecials": "Özel karakterleri çıkar (rmspecials)", "abusefilter-edit-builder-funcs-ip_in_range": "IP aralıkta mı? (ip_in_range)", - "abusefilter-edit-builder-funcs-contains-any": "Dizeyi birden çok altdize için ara (contains_any)", + "abusefilter-edit-builder-funcs-contains-any": "OR modunda birden fazla alt dizgede arama dizesi. (contains_any)", + "abusefilter-edit-builder-funcs-contains-all": "AND modunda birden fazla alt dizge için dize arayın. (contains_all)", + "abusefilter-edit-builder-funcs-equals-to-any": "Verilen bir argümanın aşağıdaki argümanlardan birine eşit (===) olup olmadığını kontrol edin (equals_to_any)", "abusefilter-edit-builder-funcs-substr": "Altdizi (substr)", "abusefilter-edit-builder-funcs-strpos": "Altdizinin dizideki yeri (strpos)", "abusefilter-edit-builder-funcs-str_replace": "Altdiziyi dizi ile değiştir (str_replace)", + "abusefilter-edit-builder-funcs-rescape": "Düzenli ifadeler (rescape) değişmez olarak dizisini kaçış", "abusefilter-edit-builder-funcs-set_var": "Değişkeni ayarla (set_var)", + "abusefilter-edit-builder-funcs-sanitize": "HTML varlıklarını unicode karakterlerle normalize et (sanitize)", "abusefilter-edit-builder-group-vars": "Değişkenler", "abusefilter-edit-builder-vars-accountname": "Hesap adı (hesap oluşturulduğunda)", "abusefilter-edit-builder-vars-timestamp": "Değişikliğin Unix zaman damgası", + "abusefilter-edit-builder-vars-timestamp-expanded": "Günlüğün zaman damgası", "abusefilter-edit-builder-vars-action": "Eylem", "abusefilter-edit-builder-vars-addedlines": "Değişiklikte eklenen satırlar", "abusefilter-edit-builder-vars-delta": "Değişiklikteki boyut değişimi", "abusefilter-edit-builder-vars-diff": "Değişiklik tarafından yapılan değişikliklerin birleşik farkı", "abusefilter-edit-builder-vars-newsize": "Yeni sayfa boyutu", "abusefilter-edit-builder-vars-oldsize": "Eski sayfa boyutu", + "abusefilter-edit-builder-vars-old-content-model": "Eski içerik modeli", + "abusefilter-edit-builder-vars-new-content-model": "Yeni içerik modeli", "abusefilter-edit-builder-vars-removedlines": "Değişiklikte çıkarılan satırlar", "abusefilter-edit-builder-vars-summary": "Değişiklik özeti/sebebi", - "abusefilter-edit-builder-vars-page-id": "Sayfa IDsi", + "abusefilter-edit-builder-vars-page-id": "Sayfa kimliği", "abusefilter-edit-builder-vars-page-ns": "Sayfa ad alanı", "abusefilter-edit-builder-vars-page-title": "Sayfa başlığı (ad alanı olmadan)", "abusefilter-edit-builder-vars-page-prefixedtitle": "Tam sayfa başlığı", - "abusefilter-edit-builder-vars-movedfrom-id": "Kaynak taşıma sayfasının sayfa IDsi", + "abusefilter-edit-builder-vars-page-age": "Sayfa yaşı (saniyelerle)", + "abusefilter-edit-builder-vars-movedfrom-id": "Kaynak taşıma sayfasının sayfa kimliği", "abusefilter-edit-builder-vars-movedfrom-ns": "Kaynak taşıma sayfasının ad alanı", "abusefilter-edit-builder-vars-movedfrom-title": "Kaynak taşıma sayfası başlığı", "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "Kaynak taşıma sayfasının tam başlığı", - "abusefilter-edit-builder-vars-movedto-id": "Hedef taşıma sayfasının sayfa IDsi", + "abusefilter-edit-builder-vars-movedfrom-age": "Kaynak sayfa yaşını taşı (saniye olarak)", + "abusefilter-edit-builder-vars-movedto-id": "Hedef taşıma sayfasının sayfa limliği", "abusefilter-edit-builder-vars-movedto-ns": "Hedef taşıma sayfasının ad alanı", "abusefilter-edit-builder-vars-movedto-title": "Hedef taşıma sayfasının başlığı", "abusefilter-edit-builder-vars-movedto-prefixedtitle": "Hedef taşıma sayfasının tam başlığı", + "abusefilter-edit-builder-vars-movedto-age": "Hedef sayfa yaşını taşı (saniye olarak)", "abusefilter-edit-builder-vars-user-editcount": "Kullanıcının değişiklik sayısı", "abusefilter-edit-builder-vars-user-age": "Kullanıcı hesabının yaşı", "abusefilter-edit-builder-vars-user-name": "Kullanıcı hesabının adı", @@ -310,28 +395,50 @@ "abusefilter-edit-builder-vars-user-emailconfirm": "E-posta adresinin doğrulanma zamanı", "abusefilter-edit-builder-vars-recent-contributors": "Sayfaya katkıda bulunan son on kullanıcı", "abusefilter-edit-builder-vars-first-contributor": "Kullanıcının ilk katkısı", + "abusefilter-edit-builder-vars-movedfrom-recent-contributors": "Kaynak sayfayı taşımak için katkıda bulunan son on kullanıcı", + "abusefilter-edit-builder-vars-movedfrom-first-contributor": "Kaynak sayfayı taşımaya katkıda bulunan ilk kullanıcı", + "abusefilter-edit-builder-vars-movedto-recent-contributors": "Hedef sayfayı taşımak için katkıda bulunan son on kullanıcı", + "abusefilter-edit-builder-vars-movedto-first-contributor": "Hedef sayfayı taşımaya katkıda bulunan ilk kullanıcı", "abusefilter-edit-builder-vars-all-links": "Yeni metindeki tüm dış bağlantılar", "abusefilter-edit-builder-vars-added-links": "Değişiklikte eklenen tüm dış bağlantılar", "abusefilter-edit-builder-vars-removed-links": "Değişiklikte çıkarılan tüm dış bağlantılar", - "abusefilter-edit-builder-vars-old-text": "Eski sayfa vikimetni, değişiklikten önce", - "abusefilter-edit-builder-vars-new-text": "Yeni sayfa vikimetni, değişiklikten sonra", - "abusefilter-edit-builder-vars-new-pst": "Yeni sayfa viki metni, ön kayıt dönüştürüldü", - "abusefilter-edit-builder-vars-new-text-stripped": "Yeni sayfa metni, herhangi bir biçimlendirme olmadan", + "abusefilter-edit-builder-vars-old-wikitext": "Eski sayfa vikimetin, düzenlemeden önce", + "abusefilter-edit-builder-vars-new-wikitext": "Yeni sayfa vikimetin, düzenlemeden sonra", + "abusefilter-edit-builder-vars-new-pst": "Yeni sayfa vikimetni, ön kayıt dönüştürüldü", + "abusefilter-edit-builder-vars-diff-pst": "Düzenleme tarafından yapılan değişikliklerin birleştirilmiş fark, dönüştürülmüş ön-kaydet", + "abusefilter-edit-builder-vars-addedlines-pst": "Düzenlemeye eklenen satırlar, önceden kaydedilmiş dönüştürülmüş", + "abusefilter-edit-builder-vars-new-text": "Yeni sayfa metni, herhangi bir biçimlendirme olmadan", "abusefilter-edit-builder-vars-new-html": "Yeni revizyonun derlenmiş HTML kaynağı", "abusefilter-edit-builder-vars-restrictions-edit": "Sayfanın koruma düzeyini değiştir", "abusefilter-edit-builder-vars-restrictions-move": "Sayfanın koruma düzeyini taşı", "abusefilter-edit-builder-vars-restrictions-create": "Sayfayı koruma altına al", - "abusefilter-edit-builder-vars-old-text-stripped": "Eski sayfa metni, herhangi bir biçimlendirme olmadan", - "abusefilter-edit-builder-vars-old-links": "Sayfadaki bağlantılar, değişiklikten önce", - "abusefilter-edit-builder-vars-old-html": "Eski sayfa vikimetni, HTML'ye derlendi", - "abusefilter-edit-builder-vars-minor-edit": "Değişikliğin küçük olarak işaretlenip işaretlenmeyeceği", + "abusefilter-edit-builder-vars-restrictions-upload": "Dosyanın korumasını yükle", + "abusefilter-edit-builder-vars-movedfrom-restrictions-edit": "Kaynak sayfasının koruma düzeyini düzenle", + "abusefilter-edit-builder-vars-movedfrom-restrictions-move": "Kayna sayfasının koruma düzeyini taşı", + "abusefilter-edit-builder-vars-movedfrom-restrictions-create": "Taşıma kaynak sayfasının koruması oluşturun", + "abusefilter-edit-builder-vars-movedfrom-restrictions-upload": "Taşıma kaynak dosyasının korumasını yükleyin", + "abusefilter-edit-builder-vars-movedto-restrictions-edit": "Hedef sayfanın taşınmasını koruma düzeyini düzenle", + "abusefilter-edit-builder-vars-movedto-restrictions-move": "Hedef sayfanın taşınmasını koruma düzeyini taşı", + "abusefilter-edit-builder-vars-movedto-restrictions-create": "Hedef sayfayı taşı koruma oluştur", + "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Taşıma hedefi dosyasının koruma koruması", + "abusefilter-edit-builder-vars-old-text": "Herhangi bir biçimlendirmeden arındırılmış eski sayfa metni (artık kullanımda değil)", + "abusefilter-edit-builder-vars-old-links": "Düzenlemeden önceki sayfadaki bağlantılar", + "abusefilter-edit-builder-vars-old-html": "Eski sayfa vikimetin, HTML'ye ayrıştırıldı (artık kullanımda değil)", + "abusefilter-edit-builder-vars-minor-edit": "Düzenlemenin küçük olarak işaretlenip işaretlenmediği (artık kullanımda değil)", "abusefilter-edit-builder-vars-file-sha1": "Dosya içeriklerinin SHA1 hash'i", "abusefilter-edit-builder-vars-file-size": "Dosyanın bayt cinsinden boyutu", + "abusefilter-edit-builder-vars-file-mime": "Dosyanın MIME türü", + "abusefilter-edit-builder-vars-file-mediatype": "Dosyanın medya türü", + "abusefilter-edit-builder-vars-file-width": "Dosyanın piksel cinsinden genişliği", + "abusefilter-edit-builder-vars-file-height": "Dosyanın piksel cinsinden yüksekliği", + "abusefilter-edit-builder-vars-file-bits-per-channel": "Dosyanın renk kanalı başına bit", + "abusefilter-edit-builder-vars-wiki-name": "Vikinin veritabanı adı", + "abusefilter-edit-builder-vars-wiki-language": "Vikinin dil kodu", "abusefilter-filter-log": "Son süzgeç değişiklikleri", "abusefilter-history": "Suistimal filtresi #$1 için değişiklik geçmişi", "abusefilter-history-foruser": "$1 tarafından değişiklikler", "abusefilter-history-hidden": "Gizli", - "abusefilter-history-enabled": "Etkinleştirildi", + "abusefilter-history-enabled": "Etkin", "abusefilter-history-global": "Küresel", "abusefilter-history-timestamp": "Zaman", "abusefilter-history-user": "Kullanıcı", @@ -342,9 +449,10 @@ "abusefilter-history-actions": "Eylemler", "abusefilter-history-backedit": "Süzgeç editörüne geri dön", "abusefilter-history-deleted": "Silindi", - "abusefilter-history-filterid": "Süzgeç", + "abusefilter-history-filterid": "Filtre", "abusefilter-history-select-legend": "Aramayı geliştir", "abusefilter-history-select-user": "Kullanıcı:", + "abusefilter-history-select-filter": "Süzgeç kimliği:", "abusefilter-history-select-submit": "Geliştir", "abusefilter-history-diff": "Değişiklikler", "abusefilter-history-error-hidden": "İstediğiniz filtre gizli, ve geçmişini görüntüleyemezsiniz.", @@ -355,15 +463,21 @@ "abusefilter-exception-unclosedstring": "$1 karakterinde başlayan kapanmamış dizi", "abusefilter-exception-invalidoperator": "$1 karakterinde geçersiz operatör \"$2\".", "abusefilter-exception-unrecognisedtoken": "$1 karakterinde tanınmayan simge \"$2\".", - "abusefilter-exception-noparams": "\"$2\" fonksiyonuna $1 karakterinde hiç parametre verilmedi.", - "abusefilter-exception-dividebyzero": "$1 karakterinde $2 ile kuraldışı sıfıra bölme girişimi.", - "abusefilter-exception-unrecognisedvar": "$1 karakterinde tanınmayan değişken $2", - "abusefilter-exception-notenoughargs": "$1 karakterinde çağrılan $2 fonksiyonu için yeterli değişken yok.\n$3 {{PLURAL:$3|değişken|değişken}} bekleniyordu, $4 alındı", - "abusefilter-exception-regexfailure": "\"$3\" düzenli ifadesinin $1 karakterinde hata: \"$2\"", - "abusefilter-exception-overridebuiltin": "$1 karakterinde \"$2\" yerleşik değişkeninin kuraldışı geçersiz kılınması.", - "abusefilter-exception-outofbounds": "$1 karakterindeki mevcut olmayan liste öğesi $2 (liste boyutu = $3) isteniyor.", + "abusefilter-exception-noparams": "$1 karakterinde \"$2\" işlevine verilen parametre yok.\n$3 {{PLURAL:$3|tartışma|tartışma}} bekleniyordu.", + "abusefilter-exception-dividebyzero": "$1 karakterinde $2 ile yasa dışı sıfıra bölme girişimi.", + "abusefilter-exception-unrecognisedvar": "$1 karakterinde tanınmayan değişken $2.", + "abusefilter-exception-notenoughargs": "$1 karakterinde çağrılan $2 fonksiyonu için yeterli değişken yok.\n$3 {{PLURAL:$3|tartışma|tartışma}} bekleniyordu, $4 alındı", + "abusefilter-exception-toomanyargs": "$2 işlevini çalıştırmak için çok fazla argüman $1 karakterinde çağrıldı.\nEn fazla $3 {{PLURAL:$3|tartışma|tartışma}} bekleniyordu, $4 aldı", + "abusefilter-exception-regexfailure": "\"$2\" düzenli ifadesinin $1 karakterinde hata.", + "abusefilter-exception-overridebuiltin": "$1 karakterinde yerleşik \"$2\" tanımlayıcısının geçersiz kılınması.", + "abusefilter-exception-outofbounds": "Var olmayan bir dizi öğesi $2 (dizi boyutu = $3), $1 karakterinden isteniyor.", + "abusefilter-exception-negativeindex": "Dizilerde negatif dizinlere izin verilmez. $1 karakterinde \"$2\" endeksini alındı.", "abusefilter-exception-notarray": "$1 karakterinde dizi olmayan dizi öğesi isteniyor.", - "abusefilter-action-tag": "Etiketle", + "abusefilter-exception-unclosedcomment": "$1 karakterindeki açıklanmamış yorum.", + "abusefilter-exception-invalidiprange": "$1 karakterinde geçersiz IP aralığı \"$2\" verildi.", + "abusefilter-exception-disabledvar": "$1 karakterindeki $2 değişkeni artık kullanımda değil.", + "abusefilter-exception-variablevariable": "set ve set_var ilk argümanın $1 karakterinde bulunan bir dizgi değişmezi olmasını bekler.", + "abusefilter-action-tag": "Etiket", "abusefilter-action-throttle": "Kısıtla", "abusefilter-action-warn": "Uyar", "abusefilter-action-blockautopromote": "Otomatik terfiyi engelle", @@ -373,22 +487,23 @@ "abusefilter-action-disallow": "İzin verme", "abusefilter-revert-title": "$1 süzgecinin tüm değişikliklerini geri al", "abusefilter-revert-intro": "Bu form, $1 filtresi yüzünden suistimal filtresi tarafından yapılan tüm değişiklikleri geri almanıza izin verir.\nLütfen bu aracı kullanmada dikkatli çalışın.", - "abusefilter-revert-preview-item": "$1: $2, $4 üzerinde bir $3 yaptı.\nGeri alınacak eylemler: $5 ($6)", + "abusefilter-revert-preview-item": "$1: $2, $4 üzerinde bir $3 {{GENDER:$7|yaptı}}.\nGeri alınacak eylemler: $5 ($6)", "abusefilter-revert-search-legend": "Geri alınacak suistimal filtresi eylemlerini seçin", "abusefilter-revert-periodstart": "Dönem başlangıcı:", "abusefilter-revert-periodend": "Dönem sonu:", "abusefilter-revert-search": "Eylemleri seç", - "abusefilter-revert-filter": "Süzgeç:", - "abusefilter-revert-preview-intro": "Aşağıdakiler, suistimal filtresi tarafından alınan ve bu eylemle geri alınacak eylemlerdir.\nLütfen dikkatlice kontrol edin, ve seçiminizi onaylamak için \"onayla\"ya tıklayın.", + "abusefilter-revert-filter": "Süzgeç kimliği:", + "abusefilter-revert-preview-intro": "Aşağıda, bu işlem tarafından geri döndürülecek kötüye kullanım filtresi tarafından gerçekleştirilen eylemler bulunmaktadır.\nLütfen bunları dikkatlice kontrol edin ve seçiminizi onaylamak için \"{{int:abusefilter-revert-confirm}}\" düğmesini tıklayın.", + "abusefilter-revert-confirm-legend": "Geri almayı onayla", "abusefilter-revert-confirm": "Onayla", "abusefilter-revert-success": "[[Special:AbuseFilter/$1|$2 filtresinden]] dolayı suistimal filtresi tarafından alınan tüm eylemleri geri aldınız.", "abusefilter-revert-reason": "$1 filtresinden dolayı suistimal filtresi tarafından alınan tüm eylemlerin otomatik geri alımı.\nVerilen sebep: $2", - "abusefilter-revert-reasonfield": "Neden:", + "abusefilter-revert-reasonfield": "Sebep:", "abusefilter-test": "Önceki değişiklikler için bir süzgeci dene", - "abusefilter-test-intro": "Bu sayfa, aşağıdaki kutuya girilen bir filtreyi son $1 {{PLURAL:$1|değişikliğe|değişikliğe}} karşı kontrol etmenize izin verir.\nMevcut bir filtreyi yüklemek için, filtre IDsini değişiklik metin kutusunun altındaki kutuya girin, ve \"Yükle\" düğmesine tıklayın.", + "abusefilter-test-intro": "Bu sayfa, aşağıdaki kutuya girilen filtreyi en son $1 {{PLURAL:$1|değişime|değişime}} göre kontrol etmenizi sağlar.\nMevcut bir filtreyi yüklemek için, filtre kimliğini düzenleme metin kutusunun altındaki kutuya yazın ve \"{{int:abusefilter-test-load}}\" düğmesini tıklayın.", "abusefilter-test-legend": "Süzgeç denemesi", - "abusefilter-test-load-filter": "Süzgeç IDsini yükle:", - "abusefilter-test-submit": "Deneme", + "abusefilter-test-load-filter": "Süzgeç kimliği yükle:", + "abusefilter-test-submit": "Test", "abusefilter-test-load": "Yükle", "abusefilter-test-user": "Kullanıcının değişiklikleri:", "abusefilter-test-nobots": "Bot değişikliklerini gizle", @@ -396,12 +511,20 @@ "abusefilter-test-period-end": "Önceden yapılan değişiklikler:", "abusefilter-test-page": "Sayfaya yapılan değişiklikler:", "abusefilter-test-shownegative": "Süzgeçle eşleşmeyen değişiklikleri göster", - "abusefilter-test-syntaxerr": "Girdiğiniz filtre sözdizimi hatası içerdi.\n\"Sözdizimini kontrol et\" düğmesine tıklayarak tam bir açıklama alabilirsiniz.", + "abusefilter-test-syntaxerr": "Girdiğiniz filtre sözdizimi hatası içeriyordu.\n\"{{int:abusefilter-edit-check}}\" düğmesine tıklayarak tam bir açıklama alabilirsiniz.", + "abusefilter-test-badtitle": "Girdiğiniz sayfa başlığı geçersizdi. Başlıklarda kullanılamayan bir veya daha fazla karakter içerebilir.", + "abusefilter-test-action": "Eylem türü:", + "abusefilter-test-search-type-all": "Tüm eylemler", + "abusefilter-test-search-type-edit": "Düzenlemeler", + "abusefilter-test-search-type-move": "Taşımalar", + "abusefilter-test-search-type-delete": "Silmeler", + "abusefilter-test-search-type-upload": "Yüklemeler", + "abusefilter-test-search-type-createaccount": "Hesap oluşturmalar", "abusefilter-changeslist-examine": "incele", "abusefilter-examine": "Bireysel değişiklikleri incele", "abusefilter-examine-intro": "Bu sayfa, Suistimal filtresi tarafından özgün bir değişiklik için oluşturulan değişkenleri incelemenize, ve filtrelere karşı test etmenize izin verir.", "abusefilter-examine-legend": "Değişiklikleri seç", - "abusefilter-examine-diff": "Fark URLsi:", + "abusefilter-examine-diff": "Fark URL'si:", "abusefilter-examine-user": "Kullanıcı:", "abusefilter-examine-title": "Sayfa başlığı:", "abusefilter-examine-submit": "Ara", @@ -415,25 +538,42 @@ "abusefilter-examine-incompatible": "İstediğiniz değişiklik Suistimal filtresi tarafından desteklenmiyor", "abusefilter-examine-noresults": "Belirtmiş olduğunuz arama parametrelerine uygun hiçbir sonuç bulunamadı.", "abusefilter-topnav": "'''Kötüye Kullanım Süzgeci gezintisi'''", - "abusefilter-topnav-home": "Ana", - "abusefilter-topnav-test": "Toplu test", + "abusefilter-topnav-home": "Anasayfa", + "abusefilter-topnav-recentchanges": "Son süzgeç değişiklikleri", + "abusefilter-topnav-test": "Toplu test etme", "abusefilter-topnav-examine": "Geçmiş değişiklikleri incele", "abusefilter-topnav-log": "Kötüye kullanım günlüğü", "abusefilter-topnav-tools": "Hata ayıklama araçları", - "abusefilter-topnav-import": "Süzgeci içe aktar", "abusefilter-log-name": "Kötüye kullanım süzgeci günlüğü", "abusefilter-log-header": "Bu günlük filtrelere yapılan değişikliklerin bir özetini gösterir.\nTam ayrıntılar için, son filtre değişiklikleri [[Special:AbuseFilter/history|listesine]] bakın.", + "abusefilter-logentry-create": "$1 {{GENDER:$2|oluşturdu}} $4 ($5)", + "abusefilter-logentry-modify": "$1 {{GENDER:$2|değiştirdi}} $4 ($5)", + "abusefilter-log-invalid-filter": "Belirtilen filtre kimlikleri bazıları geçersiz.", "abusefilter-log-noresults": "Sonuç yok", "abusefilter-diff-title": "Sürümler arasındaki farklar", "abusefilter-diff-item": "Öğe", - "abusefilter-diff-version": "$1'dan sürüm $2 tarafından", + "abusefilter-diff-version": "$1 üzerinden sürümü {{GENDER:$3|yapan}} $2", "abusefilter-diff-info": "Temel bilgiler", "abusefilter-diff-pattern": "Süzgeç koşulları", "abusefilter-diff-invalid": "İstenen sürümler alınamıyor", "abusefilter-diff-backhistory": "Filtre geçmişine geri dön", "abusefilter-diff-prev": "Daha eski değişiklik", "abusefilter-diff-next": "Daha yeni değişiklik", - "abusefilter-import-intro": "Bu arayüzü diğer vikilerden filtreleri içe aktarmak için kullanabilirsiniz.\nKaynak vikide, değiştirme arayüzünde \"{{int:abusefilter-edit-tools}}\"ın altındaki \"{{int:abusefilter-edit-export}}\"a tıklayın.\nGörünen metin kutusundan kopyalayın, ve bu metin kutusuna yapıştırın, daha sonra \"{{int:abusefilter-import-submit}}\"a tıklayın,", + "abusefilter-import-intro": "Bu arayüzü diğer vikilerden filtreleri içe aktarmak için kullanabilirsiniz.\nKaynak vikide, değiştirme arayüzünde \"{{int:abusefilter-edit-tools}}\" altındaki \"{{int:abusefilter-edit-export}}\" tıklayın.\nGörünen metin kutusundan kopyalayın, ve bu metin kutusuna yapıştırın, daha sonra \"{{int:abusefilter-import-submit}}\" tıklayın.", "abusefilter-import-submit": "Verileri içe aktar", - "abusefilter-group-default": "Varsayılan" + "abusefilter-import-invalid-data": "İçe aktarmaya çalıştığınız veriler geçerli değil", + "abusefilter-group-default": "Varsayılan", + "abusefilter-http-error": "Bir HTTP hatası oluştu: $1.", + "abusefilter-view-privatedetails-submit": "Özel detayları görüntüle", + "abusefilter-view-privatedetails-legend": "Özel ayrıntıları görüntüle", + "abusefilter-view-privatedetails-reason": "Özel ayrıntılara erişme nedeni:", + "abusefilter-log-details-id": "Günlük kimliği", + "abusefilter-invalid-request": "Geçersiz istek! Özel günlük ayrıntılarına [[Special:AbuseLog/$1]] formundaki formdan erişmeniz ve bir neden belirtmeniz gerekir.", + "abusefilter-invalid-request-noid": "Geçersiz istek! Kötüye kullanım günlüğü ayrıntıları sayfasındaki form aracılığıyla özel günlük ayrıntılarına erişmeli ve bir neden belirtmelisiniz.", + "log-description-abusefilterprivatedetails": "Bu günlük, bir kullanıcının kötüye kullanım günlüğünün özel detaylarına eriştiği zamanların bir listesini gösterir.", + "abusefilter-noreason": "Uyarı: Bu kaydın özel ayrıntılarını görmek için bir sebep belirtmelisiniz.", + "abusefilter-log-ip-not-available": "Mevcut değil", + "abusefilter-tag-reserved": "<code>abusefilter-condition-limit</code> etiketi, AbuseFilter tarafından dahili kullanım için ayrılmıştır.", + "tag-abusefilter-condition-limit": "koşul sınırına ulaşıldı", + "tag-abusefilter-condition-limit-description": "Tüm etkin kullanıcılar tarafından kontrol edilemeyen düzenlemeler veya diğer etkinlikler [[Special:AbuseFilter|kötüye kullanım filtreleri]]([[mw:Extension:AbuseFilter/Conditions|yardım]])." } diff --git a/AbuseFilter/i18n/trv.json b/AbuseFilter/i18n/trv.json new file mode 100644 index 00000000..83963bb4 --- /dev/null +++ b/AbuseFilter/i18n/trv.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [] + }, + "abusefilter-log-search-submit": "Miying", + "abusefilter-edit-history": "Endaan:", + "abusefilter-history-comments": "Patas numal pgkla", + "abusefilter-examine-submit": "Miying" +} diff --git a/AbuseFilter/i18n/tt-cyrl.json b/AbuseFilter/i18n/tt-cyrl.json index 1e9dfcae..3f153ef7 100644 --- a/AbuseFilter/i18n/tt-cyrl.json +++ b/AbuseFilter/i18n/tt-cyrl.json @@ -3,15 +3,31 @@ "authors": [ "Ajdar", "Zahidulla", + "Ерней", "Ильнар" ] }, "abusefilter-desc": "Үзгәртүләргә эвристик ысуллар кулланырга мөмкинлек бирә.", "abuselog": "Яман эшләр көндәлеге", - "abusefilter-log": "Яман эшләр көндәлеге", "abusefilter-log-linkoncontribs": "яман эшләр көндәлеге", - "abusefilter-status-global": "Глобаль", + "abusefilter-status-global": "Гомум", "abusefilter-list-options-submit": "Яңарту", + "abusefilter-edit-builder-vars-page-ns": "Битнең исемнәр киңлеге", + "abusefilter-edit-builder-vars-page-title": "Битнең атамасы (исемнәр киңлегесез)", + "abusefilter-edit-builder-vars-page-prefixedtitle": "Битнең тулы атамасы", + "abusefilter-edit-builder-vars-page-age": "Битнең яше (секунд)", + "abusefilter-history-timestamp": "Вакыт", + "abusefilter-history-user": "Кулланучы", + "abusefilter-history-filterid": "Сөзгеч", + "abusefilter-history-select-user": "Кулланучы:", + "abusefilter-history-diff": "Үзгәрешләр", + "abusefilter-action-tag": "Тамга", + "abusefilter-revert-reasonfield": "Сәбәп:", + "abusefilter-test-load": "Төяү", + "abusefilter-test-search-type-edit": "Төзәтмәләр", + "abusefilter-test-search-type-upload": "Төяүләр", + "abusefilter-examine-user": "Кулланучы:", + "abusefilter-examine-submit": "Эзләү", "abusefilter-topnav-log": "Яман эшләр көндәлеге", "abusefilter-log-name": "Яман эшләр көндәлеге" } diff --git a/AbuseFilter/i18n/tyv.json b/AbuseFilter/i18n/tyv.json index 188f7ccd..461aa5cd 100644 --- a/AbuseFilter/i18n/tyv.json +++ b/AbuseFilter/i18n/tyv.json @@ -4,5 +4,6 @@ "Agilight" ] }, + "abusefilter-topnav-log": "Буруу ажыглалдар журналы", "abusefilter-diff-info": "Кол медээлел" } diff --git a/AbuseFilter/i18n/udm.json b/AbuseFilter/i18n/udm.json index 580bbbf6..8066bafd 100644 --- a/AbuseFilter/i18n/udm.json +++ b/AbuseFilter/i18n/udm.json @@ -5,7 +5,6 @@ "Wadorgurt" ] }, - "abusefilter": "Умойтэм ужъёсыз фильтрлы настройка", "abusefilter-warning": "'''Сак луэ:''' Та уж автоматически тодмамын умойтэм кадь.\nНеконструктивной ужъёс ӝог палэнтӥськозы,\nно урод яке трос полъем неконструктивной тупатонъёс ваёзы тӥлесьтыд аккаунттэс яке IP-адрестэс блокировка борды.\nТӥ оскиськоды ке, та тупатон луэ конструктивной шуыса, тӥ быгатӥськоды выльысь сое быдэстыны кнопкаез эшшо одӥг пол зӥбыса.\nПравилолэн вакчи описаниез, кудӥзлы тӥляд ужды кельшиз: $1", "abusefilter-disallowed": "Та уж автоматически тодмамын умойтэм кадь, соин ик дугдытэмын.\nТӥ оскиськоды ке, та тупатон луэ конструктивной шуыса, тауна, ивортэ администраторлы, мае тӥ оскалтӥды лэсьтыны.\nПравилолэн вакчи описаниез, кудӥзлы тӥляд ужды кельшиз: $1", "abusefilter-blocked-display": "Та уж автоматически тодмамын умойтэм кадь,\nно тӥ дугдытэмын сое быдэстыны.\nСо сяна, {{SITENAME}} возьманы вылысь, тӥляд учётной записьты но вань герӟаськем IP-адресъёсты заблокировать каремын.\nТа потӥз янгышен сэрен ке, тауна, администраторен герӟаське.\nФильтрлэн вакчи описаниез, кудӥзлы тӥляд ужды кельшиз: $1", diff --git a/AbuseFilter/i18n/ug-arab.json b/AbuseFilter/i18n/ug-arab.json index 820c5417..fff2878e 100644 --- a/AbuseFilter/i18n/ug-arab.json +++ b/AbuseFilter/i18n/ug-arab.json @@ -2,14 +2,14 @@ "@metadata": { "authors": [ "Arlin", - "Sahran", "Matma Rex", + "Sahran", "Uzdil" ] }, "abusefilter-desc": "تەھرىرلەش قىلمىشىغا ئۆزلۈكىدىن شەرت ھۆكۈم قىل", - "abusefilter": "سۈيىئىستىمال سۈزگۈچ سەپلىمىسى", - "abuselog": "سۈيىئىستىمال خاتىرىسى", + "abusefilter": "سۈيىئىستىمال سۈزگۈچ باشقۇرۇش", + "abuselog": "سۈيىئىستىمال سۈزگۈچ خاتىرىسى", "abusefilter-intro": "سۈيىئىستىمال سۈزگۈچ باشقۇرۇش ئارا يۈزىگە خۇش كەلدىڭىز.\nسۈيىئىستىمال سۈزگۈچى يېقىنقى بارلىق تەھرىر قىلمىشلىغا ئۆزلۈكىدىن ھۆكۈم قىلىدىغان يۇمشاق دېتال سىستېمىسىدۇر.\nبۇ ئارايۈزدە نۆۋەتتىكى ھەممە سۈزگۈچلەر تىزىملىكى بار، باشقۇرغۇچىلارنىڭ بۇ سۈزگۈچلەرنى ئۆزگەرتىشىگە يول قويۇلىدۇ.", "abusefilter-warning": "'''ئاگاھلاندۇرۇش''': قىلمىشىڭىزنىڭ خەتەرلىك ئىكەنلىكى ئاپتوماتىك بايقالدى.\nئەھمىيەتسىز تەھرىرلەش تېز سۈرئەتتە ئەسلىگە قايتۇرۇلىدۇ،\nچەكتىن ئاشقان ياكى تەكرارلانغان ئەھمىيەتسىز تەھرىرلەش ھېساباتىڭىز ياكى IP ئادرېسىڭىزنىڭ چەكلىنىشىنى كەلتۈرۈپ چىقىرىدۇ.\nئەگەر شۇ قېتىملىق تەھرىرلەشنىڭ ئەھمىيىتى بار دەپ قارىسىڭىز، سىز يەنە قايتا چېكىپ تاپشۇرۇشنى جەزملىسىڭىز بولىدۇ.\nبۇ قېتىملىق تەھرىرلەش قىلمىشىڭىزغا ماس كەلگەن سۈزگۈچ قائىدىسىنىڭ چۈشەندۈرۈشى تۆۋەندىكىچە: $1", "abusefilter-disallowed": "قىلمىشىڭىزنىڭ خەتەرلىك ئىكەنلىكى ئاپتوماتىك بايقىلىپ چەكلەندى. \nئەگەر شۇ قېتىملىق تەھرىرلەشنىڭ ئەھمىيىتى بار دەپ قارىسىڭىز، باشقۇرغۇچى بىلەن ئالاقىلىشىپ، سىز قىلماقچى بولغان ئىشنى ئۇلارغا ئېيتىڭ. \nبۇ قېتىملىق تەھرىرلەش قىلمىشىڭىزغا ماس كەلگەن سۈزگۈچ قائىدىسىنىڭ چۈشەندۈرۈشى تۆۋەندىكىچە: $1", @@ -24,7 +24,7 @@ "right-abusefilter-view": "سۈيىئىستىمال سۈزگۈچ كۆرسەت", "right-abusefilter-log": "سۈيىئىستىمال خاتىرىسىنى كۆرسەت", "right-abusefilter-log-detail": "سۈيىئىستىمال خاتىرىسىنىڭ تەپسىلاتىنى كۆرسەت", - "right-abusefilter-private": "سۈيىئىستىمال خاتىرىسىدىكى شەخسىي سانلىق مەلۇماتنى كۆرسەت", + "right-abusefilter-privatedetails": "سۈيىئىستىمال خاتىرىسىدىكى شەخسىي سانلىق مەلۇماتنى كۆرسەت", "right-abusefilter-modify-restricted": "چەكلىك مەشغۇلاتتا سۈيىئىستىمال سۈزگۈچىنى ئۆزگەرت", "right-abusefilter-revert": "سۈيىئىستىمال سۈزگۈچى ئېلىپ بارغان ھەممە مەشغۇلاتنى ئەسلىگە قايتۇر", "right-abusefilter-view-private": "شەخسىيەت بەلگىسى قويۇلغان سۈيىئىستىمال سۈزگۈچىنى كۆرسەت", @@ -35,11 +35,10 @@ "action-abusefilter-view": "سۈيىئىستىمال سۈزگۈچلەرنى كۆرسەت", "action-abusefilter-log": "بۇ سۈيىئىستىمال خاتىرىسىنى كۆرسەت", "action-abusefilter-log-detail": "سۈيىئىستىمال خاتىرىلىرىنىڭ تەپسىلاتىنى كۆرسەت", - "action-abusefilter-private": "سۈيىئىستىمال خاتىرىسىدىكى شەخسىي سانلىق مەلۇماتنى كۆرسەت", + "action-abusefilter-privatedetails": "سۈيىئىستىمال خاتىرىسىدىكى شەخسىي سانلىق مەلۇماتنى كۆرسەت", "action-abusefilter-modify-restricted": "چەكلىك مەشغۇلاتتا سۈيىئىستىمال سۈزگۈچلىرىنى ئۆزگەرت", "action-abusefilter-revert": "سۈيىئىستىمال سۈزگۈچى ئېلىپ بارغان ھەممە ئۆزگەرتىشلەرنى ئەسلىگە قايتۇر", "action-abusefilter-view-private": "شەخسىيەت بەلگىسى قويۇلغان سۈيىئىستىمال سۈزگۈچلەرنى كۆرسەت", - "abusefilter-log": "سۈيىئىستىمال سۈزگۈچ خاتىرىسى", "abusefilter-log-summary": "بۇ خاتىرە سۈيىئىستىمال سۈزگۈچى بايقىغان ھەممە مەشغۇلاتنى كۆرسىتىدۇ.", "abusefilter-log-search": "سۈيىئىستىمال خاتىرىسىنى ئىزدە", "abusefilter-log-search-user": "ئىشلەتكۈچى:", @@ -58,13 +57,12 @@ "abusefilter-log-details-var": "ئۆزگەرگۈچى مىقدار", "abusefilter-log-details-val": "قىممىتى", "abusefilter-log-details-vars": "مەشغۇلات پارامېتىرى", - "abusefilter-log-details-private": "شەخسىي سانلىق مەلۇمات", + "abusefilter-log-details-privatedetails": "شەخسىي سانلىق مەلۇمات", "abusefilter-log-details-ip": "ئەسلى IP ئادرېسى", "abusefilter-log-noactions": "يوق", "abusefilter-log-details-diff": "تەھرىرلەشتىكى ئۆزگىرىش", "abusefilter-log-linkoncontribs": "سۈيىئىستىمال خاتىرىسى", "abusefilter-log-linkoncontribs-text": "بۇ ئىشلەتكۈچىنىڭ سۈيىئىستىمال خاتىرىسى", - "abusefilter-log-hidden": "(تۈر يوشۇرۇن)", "abusefilter-log-hidden-implicit": "(تۈزىتىلگەن نەشرى ئۆچۈرۈلگەنلىكتىن يوشۇرۇلدى)", "abusefilter-log-cannot-see-details": "بۇ تۈرنىڭ تەپسىلاتىنى كۆرۈش ھوقۇقىڭىز يوق.", "abusefilter-log-details-hidden": "سىز بۇ تۈرنىڭ تەپسىلاتىنى كۆرەلمەيسىز چۈنكى بۇ تۈر ئاممىۋى كۆرۈنۈشتىن يوشۇرۇلغان.", @@ -74,7 +72,6 @@ "abusefilter-log-hide-reason": "سەۋەب:", "abusefilter-log-hide-forbidden": "سۈيىئىستىمال خاتىرە تۈرىنى يوشۇرۇش ھوقۇقىڭىز يوق.", "logentry-abusefilter-hit": "$1 بولسا $4 غا تەسىر قىلىپ $3 دا \"$5\" مەشغۇلاتنى ئېلىپ باردى، مەشغۇلاتى: $6 ($7)", - "abusefilter-management": "سۈيىئىستىمال سۈزگۈچ باشقۇرۇش", "abusefilter-list": "ھەممە سۈزگۈچلەر", "abusefilter-list-id": "سۈزگۈچ ID سى", "abusefilter-list-status": "ھالەت", @@ -94,6 +91,7 @@ "abusefilter-disabled": "چەكلەنگەن", "abusefilter-hitcount": "$1 {{PLURAL:$1|قېتىم|قېتىم}} ئۇرۇلغان", "abusefilter-new": "يېڭى بىر سۈزگۈچ قۇر", + "abusefilter-import-button": "سۈزگۈچ ئەكىر", "abusefilter-return": "سۈزگۈچ باشقۇرۇشقا قايت", "abusefilter-status-global": "ئومۇمىيەت", "abusefilter-list-options": "تاللانما", @@ -121,7 +119,6 @@ "abusefilter-edit-oldwarning": "<strong>سىز بۇ سۈزگۈچنىڭ كونا نەشرىنى تەھرىرلەۋاتىسىز. سىتاتىستىكىدا نەقىل ئېلىۋاتقان سۈزگۈچ ئەڭ يېڭىسى. ئەگەر تەھرىرلىشىڭىزنى ساقلىسىڭىز، تەھرىرلىگەن نەشرىدىن كېيىنكى ھەممە ئۆزگەرتىشلەر قاپلىنىپ كېتىدۇ</strong> •\n[[Special:AbuseFilter/history/$2|بۇ سۈزگۈچنىڭ تارىخ خاتىرىسىگە قايت]].", "abusefilter-edit-status-label": "ستاتىستىكا:", "abusefilter-edit-status": "ئاخىرقى {{PLURAL:$1|مەشغۇلات}}تا $2 ($3%) قېتىملىق تەھرىرلەش بۇ سۈزگۈچنى قوزغاتتى. ئۇنىڭ ئوتتۇرىچە ئىجرا قىلىنىش ۋاقتى $4 ms (مىللىسېكۇنت)، {{PLURAL:$5|چەكلىمە}}نى سەرپ قىلدى.", - "abusefilter-edit-status-profile": "ئاخىرقى {{PLURAL:$1|مەشغۇلات}}تا $2 ($3%) قېتىملىق تەھرىرلەش بۇ سۈزگۈچنى قوزغاتتى. ئۇنىڭ ئوتتۇرىچە ئىجرا قىلىنىش ۋاقتى $4 ms (مىللىسېكۇنت)، {{PLURAL:$5|چەكلىمە}}نى سەرپ قىلدى.", "abusefilter-edit-new": "يېڭى سۈزگۈچ", "abusefilter-edit-save": "سۈزگۈچ ساقلا", "abusefilter-edit-id": "سۈزگۈچ IDسى:", @@ -254,15 +251,15 @@ "abusefilter-edit-builder-vars-all-links": "يېڭى تېكىستتىكى بارلىق سىرتقى ئۇلانمىلار", "abusefilter-edit-builder-vars-added-links": "تەھرىرلىگەندە قوشقان بارلىق سىرتقى ئۇلانمىلار", "abusefilter-edit-builder-vars-removed-links": "تەھرىرلىگەندە چىقىرىۋەتكەن بارلىق سىرتقى ئۇلانمىلار", - "abusefilter-edit-builder-vars-old-text": "تەھرىرلەشتىن ئىلگىرىكى كونا بەتنىڭ ۋىكى تېكىستى", - "abusefilter-edit-builder-vars-new-text": "تەھرىرلىگەندىن كېيىنكى يېڭى بەتنىڭ ۋىكى تېكىستى", - "abusefilter-edit-builder-vars-new-text-stripped": "ھەممە بەلگىلەرنى چىقىرىۋەتكەندىن كېيىنكى يېڭى بەتنىڭ تېكىستى", + "abusefilter-edit-builder-vars-old-wikitext": "تەھرىرلەشتىن ئىلگىرىكى كونا بەتنىڭ ۋىكى تېكىستى", + "abusefilter-edit-builder-vars-new-wikitext": "تەھرىرلىگەندىن كېيىنكى يېڭى بەتنىڭ ۋىكى تېكىستى", + "abusefilter-edit-builder-vars-new-text": "ھەممە بەلگىلەرنى چىقىرىۋەتكەندىن كېيىنكى يېڭى بەتنىڭ تېكىستى", "abusefilter-edit-builder-vars-new-html": "تەھرىرلىگەندىن كېيىنكى يېڭى بەت HTML ئەسلى كودى بويىچە تەھلىل قىلىندى", "abusefilter-edit-builder-vars-restrictions-edit": "بەتنىڭ تەھرىرلەشتىن قوغداش دەرىجىسى", "abusefilter-edit-builder-vars-restrictions-move": "بەتنىڭ يۆتكەشتىن قوغداش دەرىجىسى", "abusefilter-edit-builder-vars-restrictions-create": "بۇ بەتنى قوغداش", "abusefilter-edit-builder-vars-restrictions-upload": "يۈكلىگەن ھۆججەتنى قوغداش", - "abusefilter-edit-builder-vars-old-text-stripped": "ھەممە بەلگىلەرنى چىقىرىۋەتكەندىن كېيىنكى كونا بەتنىڭ تېكىستى", + "abusefilter-edit-builder-vars-old-text": "ھەممە بەلگىلەرنى چىقىرىۋەتكەندىن كېيىنكى كونا بەتنىڭ تېكىستى", "abusefilter-edit-builder-vars-old-links": "تەھرىرلەشتىن ئىلگىرىكى بەتتىكى ئۇلانمىلار", "abusefilter-edit-builder-vars-old-html": "HTML سۈپىتىدە تەھلىل قىلىنغان تەھرىرلەشتىن ئىلگىرىكى ۋىكى تېكىست", "abusefilter-edit-builder-vars-minor-edit": "تەھرىرلەشكە كىچىك ئۆزگەرتىش بەلگىسى قويۇلغانمۇ يوق", @@ -359,7 +356,6 @@ "abusefilter-topnav-examine": "ئىلگىرىكى تەھرىرلەرنى تەكشۈر", "abusefilter-topnav-log": "سۈيىئىستىمال خاتىرىسى", "abusefilter-topnav-tools": "سازلاش قورالى", - "abusefilter-topnav-import": "سۈزگۈچ ئەكىر", "abusefilter-log-name": "سۈيىئىستىمال سۈزگۈچ خاتىرىسى", "abusefilter-log-header": "بۇ خاتىرە سۈزگۈچ ئېلىپ بارغان ئۆزگەرتىشنىڭ ئۈزۈندىسىنى كۆرسىتىدۇ. خاتىرە تەپسىلاتىنى [[Special:AbuseFilter/history|بۇ تىزىم]]دىن سۈزگۈچنىڭ يېقىنقى ئۆزگەرتىشىدىن كۆرۈڭ.", "abusefilter-log-noresults": "نەتىجە يوق", diff --git a/AbuseFilter/i18n/ug-latn.json b/AbuseFilter/i18n/ug-latn.json index e967a0b0..d1f6fa67 100644 --- a/AbuseFilter/i18n/ug-latn.json +++ b/AbuseFilter/i18n/ug-latn.json @@ -1,4 +1,6 @@ { - "@metadata": [], + "@metadata": { + "authors": [] + }, "abusefilter-examine-submit": "Izdash" } diff --git a/AbuseFilter/i18n/uk.json b/AbuseFilter/i18n/uk.json index 956518fb..d3bcbcf0 100644 --- a/AbuseFilter/i18n/uk.json +++ b/AbuseFilter/i18n/uk.json @@ -5,28 +5,30 @@ "Ahonc", "Alex Khimich", "Andriykopanytsia", + "Avatar6", "Base", + "Daimona Eaytoy", + "DonDrakon", "JenVan", + "Matma Rex", "Microcell", + "Movses", + "Mykola Swarnyk", "NickK", + "Olion", "Olvin", + "Piramidion", "Prima klasy4na", "SamOdin", + "Vlad5250", "Ата", - "Тест", - "Mykola Swarnyk", - "Olion", - "DonDrakon", - "Piramidion", - "Matma Rex", "Максим Підліснюк", - "Avatar6", - "Vlad5250" + "Тест" ] }, "abusefilter-desc": "Застосовує до редагувань автоматичні евристики.", - "abusefilter": "Налаштування фільтра редагувань", - "abuselog": "Журнал зловживань", + "abusefilter": "Управління фільтрами редагувань", + "abuselog": "Журнал фільтра редагувань", "abusefilter-intro": "Ласкаво просимо на сторінку керування фільтром редагувань.\nФільтр редагувань — це автоматизований механізм застосування автоматичних евристик до дій користувачів.\nТут наведений список усіх установлених фільтрів, надається можливість їх зміни.", "abusefilter-mustviewprivateoredit": "З причин безпеки, цей інтерфейс можуть використовувати тільки користувачі з правом переглядати приватні фільтри редагувань чи редагувати фільтри.", "abusefilter-warning": "'''Увага:''' ця дія була автоматично визначена як шкідлива.\nНеконструктивні дії будуть швидко скасовані,\nгрубі або неодноразові неконструктивні редагування призведуть до блокування вашого облікового запису або IP-адреси.\nЯкщо Ви вважаєте, що це редагування конструктивне, то Ви можете ще раз натиснути «Зберегти сторінку», щоб підтвердити редагування.\nКороткий опис зловживання, на яке схожа Ваша дія: $1", @@ -37,35 +39,41 @@ "abusefilter-blocker": "Фільтр редагувань", "abusefilter-blockreason": "Автоматично заблокований фільтром редагувань. Опис правила: $1", "abusefilter-degroupreason": "Права автоматично відібрані фільтром редагувань. Опис правила: $1", + "abusefilter-blockautopromotereason": "Автопросування було автоматично відкладено фільтром зловживань.\nОпис правила: $1", "abusefilter-accountreserved": "Цей обліковий запис є зарезервованим для використання фільтром редагувань.", - "right-abusefilter-modify": "налаштовування фільтрів зловживань", - "right-abusefilter-view": "перегляд фільтрів редагувань", - "right-abusefilter-log": "перегляд журналу зловживань", - "right-abusefilter-log-detail": "перегляд детальних записів журналу зловживань", - "right-abusefilter-private": "перегляд приватних даних у журналі зловживань", - "right-abusefilter-private-log": "перегляд журналу доступу до приватних деталей фільтрів редагувань", - "right-abusefilter-modify-restricted": "зміна фільтрів з обмежуючими діями", - "right-abusefilter-revert": "відкіт змін, зроблених фільтром редагувань", - "right-abusefilter-view-private": "перегляд приватних фільтрів зловживань", - "right-abusefilter-log-private": "перегляд записів журналу зловживань, позначених як приватні", - "right-abusefilter-hide-log": "приховування записів у журналі зловживань", - "right-abusefilter-hidden-log": "перегляд прихованих записів журналу зловживань", - "right-abusefilter-modify-global": "створення або зміна глобальних фільтрів зловживань", - "action-abusefilter-modify": "змінювати фільтри редагувань", - "action-abusefilter-view": "переглядати фільтри редагувань", - "action-abusefilter-log": "переглядати журнал зловживань", - "action-abusefilter-log-detail": "переглядати деталі журналу зловживань", - "action-abusefilter-private": "переглядати особисті дані в журналі зловживань", - "action-abusefilter-private-log": "перегляд журналу доступу до приватних деталей фільтрів редагувань", - "action-abusefilter-modify-restricted": "змінювати фільтри редагувань із заборонювальними діями", - "action-abusefilter-revert": "скасовувати всі зміни зазначеного фільтра редагувань", + "right-abusefilter-modify": "Створення або зміна фільтрів зловживань", + "right-abusefilter-view": "Перегляд фільтрів редагувань", + "right-abusefilter-log": "Перегляд журналу зловживань", + "right-abusefilter-log-detail": "Перегляд детальних записів журналу зловживань", + "right-abusefilter-privatedetails": "Перегляд приватних даних у журналі зловживань", + "right-abusefilter-privatedetails-log": "Перегляд журналу доступу до приватних деталей фільтрів редагувань", + "right-abusefilter-modify-restricted": "Зміна фільтрів з обмежувальними діями", + "right-abusefilter-revert": "Відкіт усіх змін, зроблених окремим фільтром редагувань", + "right-abusefilter-view-private": "Перегляд приватних фільтрів зловживань", + "right-abusefilter-log-private": "Перегляд записів журналу зловживань, позначених як приватні", + "right-abusefilter-hide-log": "Приховування записів у журналі зловживань", + "right-abusefilter-hidden-log": "Перегляд прихованих записів журналу зловживань", + "right-abusefilter-modify-global": "Створення або зміна глобальних фільтрів зловживань", + "action-abusefilter-modify": "зміну фільтрів редагувань", + "action-abusefilter-view": "перегляд фільтрів редагувань", + "action-abusefilter-log": "перегляд журналу зловживань", + "action-abusefilter-log-detail": "перегляд детальних записів журналу зловживань", + "action-abusefilter-privatedetails": "перегляд приватних даних у журналі зловживань", + "action-abusefilter-privatedetails-log": "перегляд журналу доступу до приватних деталей фільтрів редагувань", + "action-abusefilter-modify-restricted": "зміну фільтрів редагувань із обмежувальними діями", + "action-abusefilter-revert": "відкіт усіх змін, зроблених окремим фільтром редагувань", "action-abusefilter-view-private": "перегляд приватних фільтрів зловживань", "action-abusefilter-log-private": "перегляд записів журналу тих фільтрів зловживань, які позначені як приватні", - "abusefilter-log": "Журнал фільтра редагувань", + "action-abusefilter-hide-log": "приховування записів у журналі зловживань", + "action-abusefilter-hidden-log": "перегляд прихованих записів журналу зловживань", + "action-abusefilter-modify-global": "створення або зміна глобальних фільтрів зловживань", "abusefilter-log-summary": "У цьому журналі показано список усіх дій, перехоплених фільтрами.", "abusefilter-log-search": "Пошук в журналі зловживань", "abusefilter-log-search-user": "Користувач:", - "abusefilter-log-search-filter": "Ідентифікатори фільтру (відокремлені вертикальними рисками):", + "abusefilter-log-search-group": "Група фільтра:", + "abusefilter-log-search-group-any": "Будь-який", + "abusefilter-log-search-filter": "Ідентифікатори фільтра:", + "abusefilter-log-search-filter-help": "Відокремлюються вертикальними рисками, з префіксом «$1» длял глобальних фільтрів", "abusefilter-log-search-title": "Заголовок:", "abusefilter-log-search-wiki": "Вікі:", "abusefilter-log-search-impact": "Вплив:", @@ -82,9 +90,9 @@ "abusefilter-log-search-action-taken-label": "Вжиті заходи:", "abusefilter-log-search-action-taken-any": "Будь-які", "abusefilter-log-search-submit": "Знайти", - "abusefilter-log-entry": "$1: $2 {{GENDER:$8|запустив|запустила}} фільтр редагувань, виконуючи «$3» на сторінці $4.\nУжиті заходи: $5.\nОпис фільтру: $6", - "abusefilter-log-entry-withdiff": "$1: $2 {{GENDER:$8|запустив|запустила}} фільтр редагувань, виконуючи «$3» на сторінці $4.\nУжиті заходи: $5.\nОпис фільтру: $6 ($7)", - "abusefilter-log-detailedentry-meta": "$1: $2 запустив $3, {{GENDER:$9|виконуючи}} «$4» на сторінці «$5».\nВжиті заходи: $6.\nОпис фільтру: $7 ($8)", + "abusefilter-log-entry": "$1: $2 {{GENDER:$8|запустив|запустила}} фільтр редагувань, виконуючи «$3» на сторінці $4.\nУжиті заходи: $5.\nОпис фільтра: $6", + "abusefilter-log-entry-withdiff": "$1: $2 {{GENDER:$8|запустив|запустила}} фільтр редагувань, виконуючи «$3» на сторінці $4.\nУжиті заходи: $5.\nОпис фільтра: $6 ($7)", + "abusefilter-log-detailedentry-meta": "$1: $2 запустив $3, {{GENDER:$9|виконуючи}} «$4» на сторінці «$5».\nВжиті заходи: $6.\nОпис фільтра: $7 ($8)", "abusefilter-log-detailedentry-global": "глобальний фільтр $1", "abusefilter-log-detailedentry-local": "фільтр $1", "abusefilter-log-detailslink": "деталі", @@ -94,7 +102,7 @@ "abusefilter-log-details-var": "Змінна", "abusefilter-log-details-val": "Значення", "abusefilter-log-details-vars": "Параметри дії", - "abusefilter-log-details-private": "Приватні журнальовані дані", + "abusefilter-log-details-privatedetails": "Деталі приватного журналу", "abusefilter-log-details-ip": "Вихідна IP-адреса", "abusefilter-log-details-checkuser": "Перевірити користувача", "abusefilter-log-noactions": "нема", @@ -103,10 +111,11 @@ "abusefilter-log-linkoncontribs-text": "Журнал зловживань {{GENDER:$1|цього користувача|цієї користувачки}}", "abusefilter-log-linkonhistory": "журнал зловживань", "abusefilter-log-linkonhistory-text": "Показати журнали зловживань для цієї сторінки", - "abusefilter-log-hidden": "(запис приховано)", + "abusefilter-log-linkonundelete": "перегляд журналу зловживань", + "abusefilter-log-linkonundelete-text": "Показати журнали зловживань для цієї сторінки", "abusefilter-log-hidden-implicit": "(приховано, бо версію було вилучено)", "abusefilter-log-cannot-see-details": "Ви не маєте дозволу на перегляд відомостей про цей запис.", - "abusefilter-log-cannot-see-private-details": "У Вас немає прав на перегляд приватних даних для цього запису.", + "abusefilter-log-cannot-see-privatedetails": "У Вас немає прав на перегляд приватних даних для цього запису.", "abusefilter-log-nonexistent": "Запис з вказаним ідентифікатором не існує.", "abusefilter-log-details-hidden": "Ви не можете проглянути докладну інформацію про цей фільтр, оскільки вона прихована від звичайних користувачів.", "abusefilter-log-details-hidden-implicit": "Ви не можете проглянути докладну інформацію про цей запис, оскільки його відповідна версія прихована.", @@ -124,11 +133,14 @@ "log-action-filter-abusefilter-create": "Створення нового фільтра", "log-action-filter-abusefilter-modify": "Зміна фільтра", "log-action-filter-suppress-abuselog": "Приховування журналу зловживань", + "log-action-filter-rights-blockautopromote": "Блокування автопросування", + "log-action-filter-rights-restoreautopromote": "Відновлення автопросування", "logentry-abusefilterprivatedetails-access": "$1 {{GENDER:$2|отримав|отримала}} доступ до приватних даних для $3", + "logentry-rights-blockautopromote": "$1 {{GENDER:$2|заблокував|заблокувала|заблокував}} автопросування для {{GENDER:$4|$3}} на $5.", + "logentry-rights-restoreautopromote": "$1 {{GENDER:$2|відновив|відновила|відновив}} автопросування для {{GENDER:$4|користувача|користувачки|}} $3.", "abusefilterprivatedetails-log-name": "Журнал доступу до приватних даних фільтра редагувань", - "abusefilter-management": "Управління фільтрами редагувань", "abusefilter-list": "Усі фільтри", - "abusefilter-list-id": "ІД фільтра", + "abusefilter-list-id": "ID фільтра", "abusefilter-list-pattern": "Взірець", "abusefilter-list-status": "Стан", "abusefilter-list-public": "Публічний опис", @@ -139,7 +151,7 @@ "abusefilter-list-details": "Деталі", "abusefilter-list-limit": "Кількість на сторінці:", "abusefilter-list-lastmodified": "Останні зміни", - "abusefilter-list-group": "Група фільтру", + "abusefilter-list-group": "Група фільтра", "abusefilter-hidden": "Прихований", "abusefilter-unhidden": "Публічний", "abusefilter-enabled": "Увімкнений", @@ -148,6 +160,7 @@ "abusefilter-throttled": "обмежено", "abusefilter-hitcount": "$1 {{PLURAL:$1|спрацьовування|спрацьовування|спрацьовувань}}", "abusefilter-new": "Створити фільтр", + "abusefilter-import-button": "Імпорт фільтра", "abusefilter-return": "Повернутися до керування фільтрами", "abusefilter-status-global": "Глобальний", "abusefilter-list-options": "Налаштування", @@ -168,26 +181,29 @@ "abusefilter-list-options-search-like": "Простий запит", "abusefilter-list-options-search-rlike": "Регулярний вираз", "abusefilter-list-options-search-irlike": "Нечутливий до регістру регулярний вираз", + "abusefilter-list-invalid-searchmode": "Вказано недопустимий режим пошуку.", "abusefilter-list-regexerror": "Сталася помилка при пошуку: синтаксична помилка регулярного виразу.", "abusefilter-list-options-submit": "Оновити", "abusefilter-tools-text": "Тут є деякі засоби, які можуть пригодитися у формулюванні та налагодженні фільтрів редагувань.", "abusefilter-tools-expr": "Випробувач виразів", "abusefilter-tools-submitexpr": "Випробувати", + "abusefilter-tools-syntax-error": "Синтаксична помилка у фільтрі.", "abusefilter-tools-reautoconfirm": "Відновити статус автопідтвердження", "abusefilter-tools-reautoconfirm-user": "Користувач:", "abusefilter-tools-reautoconfirm-submit": "Повторне автопідтвердження", + "abusefilter-tools-restoreautopromote": "Автопросування відновлено інструментами Фільтру зловживань.", "abusefilter-reautoconfirm-none": "У {{GENDER:$1|цього користувача|цієї користувачки}} не відключений статус автопідтвердження.", "abusefilter-reautoconfirm-notallowed": "Вам не дозволено відновлювати статус автопідтвердження.", "abusefilter-reautoconfirm-done": "Відновлений статус автопідтвердження облікового запису", "abusefilter-status": "Серед $1 {{PLURAL:$1|1=дії|дій}}, $2 ($3%) {{PLURAL:$2|1=досягла|досягли}} межі $4. $5 ($6%) {{PLURAL:$5|1=активізувала|активізували}} один з увімкнених фільтрів.", - "abusefilter-edit": "Зміна фільтру редагувань", - "abusefilter-edit-subtitle": "Редагування фільтру $1", - "abusefilter-edit-subtitle-new": "Створення фільтру", + "abusefilter-edit": "Зміна фільтра редагувань", + "abusefilter-edit-subtitle": "Редагування фільтра $1", + "abusefilter-edit-subtitle-new": "Створення фільтра", "abusefilter-edit-token-not-match": "Ваше редагування не збережене! Будь ласка, збережіть знову.", - "abusefilter-edit-oldwarning": "<strong>Ви редагуєте стару версію цього фільтра. Статистика наведена для найновішої версії фільтра. Якщо ви збережете свої зміни, ви перезапишете усі редагування починаючи з версії, яку ви редагуєте.</strong> • [[Special:AbuseFilter/history/$2|Повернутися до історії цього фільтру]]", + "abusefilter-edit-oldwarning": "<strong>Ви редагуєте стару версію цього фільтра. Статистика наведена для найновішої версії фільтра. Якщо ви збережете свої зміни, ви перезапишете усі редагування починаючи з версії, яку ви редагуєте.</strong> • [[Special:AbuseFilter/history/$2|Повернутися до історії цього фільтра]].", + "abusefilter-edit-oldwarning-view": "<strong>Ви переглядаєте стару версію цього фільтру.\nАле статистика наведена для найновішої версії.</strong> •\n[[Special:AbuseFilter/history/$2|Повернутись до історії фільтру]].", "abusefilter-edit-status-label": "Статистика:", - "abusefilter-edit-status": "Серед $1 {{PLURAL:$1|останньої дії|останніх дій}} цей фільтр знайшов {{PLURAL:$2|$2 збіг|$2 збіги|$2 збігів}} ($3%).", - "abusefilter-edit-status-profile": "Серед $1 {{PLURAL:$1|останньої дії|останніх дій|останніх дій}} цей фільтр знайшов {{PLURAL:$2|$2 збіг|$2 збіги|$2 збігів}} ($3%).\nСередня тривалість його роботи — $4 мс, він використовує $5 {{PLURAL:$5|умову|умови|умов}} з ліміту умов.", + "abusefilter-edit-status": "Серед $1 {{PLURAL:$1|останньої дії|останніх дій}} цей фільтр знайшов {{PLURAL:$2|$2 збіг|$2 збіги|$2 збігів}} ($3%).\nСередня тривалість його роботи — $4 мс, він використовує $5 {{PLURAL:$5|умову|умови|умов}} з ліміту умов.", "abusefilter-edit-throttled-warning": "'''Попередження:''' Цей фільтр було автоматично позначено як шкідливий. У рамках заходів безпеки, подані в дужках дії не виконуватимуться ($1). Будь ласка, перевірте й [[mw:Extension:AbuseFilter/Conditions|оптимізуйте]] свої умови, щоб уникнути цього обмеження", "abusefilter-edit-new": "Новий фільтр", "abusefilter-edit-save": "Зберегти фільтр", @@ -195,18 +211,18 @@ "abusefilter-edit-switch-editor": "Перемкнути редактор", "abusefilter-edit-description": "Опис:\n:''(публічний) ''", "abusefilter-edit-field-description": "опис", - "abusefilter-edit-group": "Група фільтру:", + "abusefilter-edit-group": "Група фільтра:", "abusefilter-edit-flags": "Прапорці:", "abusefilter-edit-enabled": "Увімкнути цей фільтр", "abusefilter-edit-deleted": "Позначити як вилучений", - "abusefilter-edit-hidden": "Приховати деталі цього фільтру від загальнодоступного огляду", + "abusefilter-edit-hidden": "Приховати подробиці цього фільтра від загалу", "abusefilter-edit-global": "Глобальний фільтр", "abusefilter-edit-rules": "Умови:", "abusefilter-edit-field-conditions": "умови", "abusefilter-edit-notes": "Примітки:", - "abusefilter-edit-lastmod": "Остання зміна фільтру:", + "abusefilter-edit-lastmod": "Остання зміна фільтра:", "abusefilter-edit-lastmod-text": "$1 користувачем $2", - "abusefilter-edit-hitcount": "Спрацьовувань фільтру:", + "abusefilter-edit-hitcount": "Спрацьовувань фільтра:", "abusefilter-edit-consequences": "Заходи, що будуть вжиті при спрацьовуванні", "abusefilter-edit-action-warn": "Перед уживанням заходів видати попередження", "abusefilter-edit-action-disallow": "Заборонити користувачеві виконати дію", @@ -220,20 +236,31 @@ "abusefilter-edit-throttle-count": "Кількість дозволених дій:", "abusefilter-edit-throttle-period": "Відтинок часу (у секундах):", "abusefilter-edit-throttle-groups": "Звуження за групами:", - "abusefilter-edit-throttle-ip": "IP-адреса", - "abusefilter-edit-throttle-user": "Обліковий запис", - "abusefilter-edit-throttle-range": "Діапазон /16", - "abusefilter-edit-throttle-creationdate": "Серверний час створення облікового запису", - "abusefilter-edit-throttle-editcount": "Лічильник редагувань", - "abusefilter-edit-throttle-site": "Весь сайт", - "abusefilter-edit-throttle-page": "Сторінка", + "abusefilter-edit-throttle-groups-help": "Див. $1.", + "abusefilter-edit-throttle-groups-help-text": "документацію на mediawiki.org", + "abusefilter-edit-throttle-hidden-placeholder": "Відокремлюйте комами, щоб поєднувати через AND, та переносом рядка, щоб поєднувати через OR", + "abusefilter-edit-throttle-placeholder": "Відокремлюйте комами, щоб поєднувати через AND, та вставляйте один за одним, щоб поєднувати через OR", + "abusefilter-throttle-ip": "IP-адреса", + "abusefilter-throttle-user": "обліковий запис", + "abusefilter-throttle-range": "Діапазон /16", + "abusefilter-throttle-creationdate": "дата створення облікового запису", + "abusefilter-throttle-editcount": "лічильник редагувань", + "abusefilter-throttle-site": "весь сайт", + "abusefilter-throttle-page": "сторінка", + "abusefilter-throttle-none": "(нема)", "abusefilter-throttle-details": "Дозволити $1 {{PLURAL:$1|дію|дії|дій}} {{PLURAL:$2|кожну $2 секунду|кожні $2 секунди|кожні $2 секунд}}, звужувати за групами: $3", "abusefilter-edit-warn-message": "Системне повідомлення для попереджень:", "abusefilter-edit-warn-other": "Інше повідомлення", - "abusefilter-edit-warn-other-label": "Назва сторінки іншого повідомлення:\n:''(без префікса MediaWiki)''", + "abusefilter-edit-warn-other-label": "Назва сторінки іншого повідомлення:\n:''(без префікса «MediaWiki:»)''", "abusefilter-edit-warn-actions": "Дії:", "abusefilter-edit-warn-preview": "Показати/приховати попередній перегляд вибраного повідомлення", "abusefilter-edit-warn-edit": "Створити/редагувати вибране повідомлення", + "abusefilter-edit-disallow-message": "Системне повідомлення для заборони:", + "abusefilter-edit-disallow-other": "Інше повідомлення", + "abusefilter-edit-disallow-other-label": "Назва сторінки іншого повідомлення:\n:''(Без префікса «MediaWiki:»)''", + "abusefilter-edit-disallow-actions": "Дії:", + "abusefilter-edit-disallow-preview": "Показати/Приховати попередній перегляд вибраного повідомлення", + "abusefilter-edit-disallow-edit": "Створити/Редагувати вибране повідомлення", "abusefilter-edit-tag-tag": "Присвоювані [[Special:Tags|мітки]]:", "abusefilter-edit-tag-placeholder": "Додати мітки (по одній або через кому)", "abusefilter-edit-tag-hidden-placeholder": "Додати мітки (через кому)", @@ -253,17 +280,25 @@ "abusefilter-edit-viewhistory": "Показати історію цього фільтра", "abusefilter-edit-history": "Історія:", "abusefilter-edit-check": "Перевірити синтаксис", - "abusefilter-edit-badfilter": "Вказаного вами фільтру не існує", + "abusefilter-edit-badfilter": "Вказаний Вами фільтр не існує", "abusefilter-edit-revert": "Відкотити дії, виконані фільтром", "abusefilter-edit-tools": "Засоби:", "abusefilter-edit-test-link": "Перевірити цей фільтр на нових редагуваннях", "abusefilter-edit-export": "Експортувати цей фільтр до іншої вікі", "abusefilter-edit-syntaxok": "Не знайдено синтаксичних помилок", "abusefilter-edit-syntaxerr": "Знайдено синтаксичну помилку: $1", + "abusefilter-edit-warn-leave": "Якщо Ви покинете цю сторінку, всі зміни до цього фільтру буде втрачено.", "abusefilter-edit-bad-tags": "Принаймні одна з вказаних Вами міток неправильна.\nМітка має бути короткою і не має містити спецсимволів, а також мітки не повинні бути закріпленими за іншими програмами. Спробуйте обрати якусь іншу назву для мітки.", "abusefilter-edit-notallowed": "У вас нема права створювати чи змінювати фільтри редагувань", "abusefilter-edit-notallowed-global": "Вам не дозволено створювати чи редагувати глобальні фільтри зловживань", - "abusefilter-edit-notallowed-global-custom-msg": "Користувацькі повідомлення попереджень не підтримуються для глобальних фільтрів", + "abusefilter-edit-notallowed-global-custom-msg": "Користувацькі повідомлення про попередження чи заборону не підтримуються для глобальних фільтрів", + "abusefilter-edit-invalid-warn-message": "Попереджуюче повідомлення не може залишатися порожнім.", + "abusefilter-edit-invalid-disallow-message": "Повідомлення заборони не може залишатися порожнім.", + "abusefilter-edit-invalid-throttlecount": "Число дій регулятора має бути додатним цілим числом.", + "abusefilter-edit-invalid-throttleperiod": "Період регулятора має бути додатним цілим числом.", + "abusefilter-edit-empty-throttlegroups": "Необхідно зазначити щонайменше одну групу регулятора.", + "abusefilter-edit-duplicated-throttlegroups": "Групи регулятора не можуть мати дублікатів.", + "abusefilter-edit-invalid-throttlegroups": "Наведена група регулятора не є дійсною.", "abusefilter-edit-builder-select": "Виберіть пункт, щоб додати на місце курсору", "abusefilter-edit-builder-group-op-arithmetic": "Арифметичні оператори", "abusefilter-edit-builder-op-arithmetic-addition": "Додавання (+)", @@ -275,8 +310,8 @@ "abusefilter-edit-builder-group-op-comparison": "Оператори порівняння", "abusefilter-edit-builder-op-comparison-equal": "Значення, рівне (==)", "abusefilter-edit-builder-op-comparison-equal-strict": "Значення й тип, рівні (===)", - "abusefilter-edit-builder-op-comparison-notequal": "Значення не рівне (!=)", - "abusefilter-edit-builder-op-comparison-notequal-strict": "Значення й тип не рівні (!==)", + "abusefilter-edit-builder-op-comparison-notequal": "Значення, не рівне (!=)", + "abusefilter-edit-builder-op-comparison-notequal-strict": "Значення й тип, не рівні (!==)", "abusefilter-edit-builder-op-comparison-lt": "Менше (<)", "abusefilter-edit-builder-op-comparison-gt": "Більше (>)", "abusefilter-edit-builder-op-comparison-lte": "Менше або рівне (<=)", @@ -289,12 +324,13 @@ "abusefilter-edit-builder-group-misc": "Різні", "abusefilter-edit-builder-misc-in": "Міститься в рядку (in)", "abusefilter-edit-builder-misc-like": "Відповідає шаблону (like)", - "abusefilter-edit-builder-misc-rlike": "Підпадає під регулярний вираз (rlike)", - "abusefilter-edit-builder-misc-irlike": "Відповідність регулярному виразу, без урахування регістра (irlike)", + "abusefilter-edit-builder-misc-rlike": "Відповідає регулярному виразу (rlike)", + "abusefilter-edit-builder-misc-irlike": "Відповідає регулярному виразу, без урахування регістра (irlike)", "abusefilter-edit-builder-misc-contains": "Лівий рядок містить правий (contains)", "abusefilter-edit-builder-misc-stringlit": "Текст (\"\")", - "abusefilter-edit-builder-misc-tern": "Тернарний оператор", - "abusefilter-edit-builder-misc-cond": "Умова (if X then Y else Z)", + "abusefilter-edit-builder-misc-tern": "Тернарний оператор (X ? Y : Z)", + "abusefilter-edit-builder-misc-cond": "Умова (if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "Коротка умова (if X then Y end)", "abusefilter-edit-builder-group-funcs": "Функції", "abusefilter-edit-builder-funcs-length": "Довжина рядка (length)", "abusefilter-edit-builder-funcs-lcase": "У нижній регістр (lcase)", @@ -365,12 +401,12 @@ "abusefilter-edit-builder-vars-all-links": "Усі зовнішні посилання в новому тексті", "abusefilter-edit-builder-vars-added-links": "Усі зовнішні посилання, додані редагуванням", "abusefilter-edit-builder-vars-removed-links": "Усі зовнішні посилання, вилучені редагуванням", - "abusefilter-edit-builder-vars-old-text": "Стара вікірозмітка, до редагування сторінки (більше не використовується)", - "abusefilter-edit-builder-vars-new-text": "Новий вікітекст, після редагування сторінки", + "abusefilter-edit-builder-vars-old-wikitext": "Старий вікітекст, до редагування сторінки", + "abusefilter-edit-builder-vars-new-wikitext": "Новий вікітекст, після редагування сторінки", "abusefilter-edit-builder-vars-new-pst": "Нова сторінка вікітексту з попередньо збереженим перетворенням", "abusefilter-edit-builder-vars-diff-pst": "Уніфікований diff змін у процесі редагування, перетворених перед збереженням", "abusefilter-edit-builder-vars-addedlines-pst": "Рядки, додані при редагуванні, перетворені перед збереженням", - "abusefilter-edit-builder-vars-new-text-stripped": "Новий текст сторінки, очищений від розмітки", + "abusefilter-edit-builder-vars-new-text": "Новий текст сторінки, очищений від розмітки", "abusefilter-edit-builder-vars-new-html": "Проаналізований HTML-код нової версії", "abusefilter-edit-builder-vars-restrictions-edit": "Рівень захисту сторінки від редагувань", "abusefilter-edit-builder-vars-restrictions-move": "Рівень захисту сторінки від перейменувань", @@ -384,10 +420,10 @@ "abusefilter-edit-builder-vars-movedto-restrictions-move": "Рівень захисту від перейменувань цільової сторінки перейменування", "abusefilter-edit-builder-vars-movedto-restrictions-create": "Рівень захисту від створення цільової сторінки перейменування", "abusefilter-edit-builder-vars-movedto-restrictions-upload": "Рівень захисту від завантажень цільової сторінки перейменування", - "abusefilter-edit-builder-vars-old-text-stripped": "Текст старої сторінки, позбавлений розмітки", + "abusefilter-edit-builder-vars-old-text": "Текст старої сторінки, позбавлений розмітки (більше не використовується)", "abusefilter-edit-builder-vars-old-links": "Посилання на сторінці перед редагуванням", "abusefilter-edit-builder-vars-old-html": "Стара вікірозмітка сторінки, перетворена в HTML (більше не використовується)", - "abusefilter-edit-builder-vars-minor-edit": "Чи було редагування позначене як незначне", + "abusefilter-edit-builder-vars-minor-edit": "Чи було редагування позначене як незначне (більше не використовується)", "abusefilter-edit-builder-vars-file-sha1": "SHA1-хеш вмісту файлу", "abusefilter-edit-builder-vars-file-size": "Розмір файлу у байтах", "abusefilter-edit-builder-vars-file-mime": "MIME-тип файлу", @@ -395,6 +431,8 @@ "abusefilter-edit-builder-vars-file-width": "Ширина файлу в пікселях", "abusefilter-edit-builder-vars-file-height": "Висота файлу в пікселях", "abusefilter-edit-builder-vars-file-bits-per-channel": "Бітів на кольоровий канал файлу", + "abusefilter-edit-builder-vars-wiki-name": "Назва бази даних цієї вікі", + "abusefilter-edit-builder-vars-wiki-language": "Код мови цієї вікі", "abusefilter-filter-log": "Нові зміни фільтрів", "abusefilter-history": "Історія змін фільтра редагувань #$1", "abusefilter-history-foruser": "Зміни, зроблені $1", @@ -417,24 +455,27 @@ "abusefilter-history-select-submit": "Уточнити", "abusefilter-history-diff": "Зміни", "abusefilter-history-error-hidden": "Цей фільтр прихований, ви не можете проглянути його історію.", - "abusefilter-exception-unexpectedatend": "Неочікуваний \"$2\" на позиції $1.", + "abusefilter-exception-unexpectedatend": "Неочікуваний «$2» на позиції $1.", "abusefilter-exception-expectednotfound": "Не виявлено $2 на позиції $1 (замість нього знайдено $3 $4).", - "abusefilter-exception-unrecognisedkeyword": "Неопізнане ключове слово $2 на позиції $1.", - "abusefilter-exception-unexpectedtoken": "Неочікуваний токен \"$3\" (типу $2) на позиції $1.", - "abusefilter-exception-unclosedstring": "Незакритий рядковий вираз на позиції $1.", - "abusefilter-exception-invalidoperator": "Помилковий оператор \"$2\" на позиції $1.", - "abusefilter-exception-unrecognisedtoken": "Неопізнаний токен \"$2\" на позиції $1.", + "abusefilter-exception-unrecognisedkeyword": "Невпізнане ключове слово $2 на позиції $1.", + "abusefilter-exception-unexpectedtoken": "Неочікуваний токен «$3» (типу $2) на позиції $1.", + "abusefilter-exception-unclosedstring": "Незакритий рядок, що починається на позиції $1.", + "abusefilter-exception-invalidoperator": "Помилковий оператор «$2» на позиції $1.", + "abusefilter-exception-unrecognisedtoken": "Невпізнаний токен «$2» на позиції $1.", "abusefilter-exception-noparams": "Не вказані параметри для функції «$2» на позиції $1. Очікується $3 {{PLURAL:$3|аргумент|аргументи|аргументів}}.", "abusefilter-exception-dividebyzero": "Ділення $2 на нуль на позиції $1.", "abusefilter-exception-unrecognisedvar": "Неопізнана змінна $2 на позиції $1", "abusefilter-exception-notenoughargs": "Замало аргументів для функції $2, що викликається на позиції $1.\nОчікується $3 {{PLURAL:$3|аргумент|аргументи|аргументів}}, а вказано $4", - "abusefilter-exception-regexfailure": "Помилка в регулярному виразі \"$3\" на позиції $1: \"$2\"", - "abusefilter-exception-overridebuiltin": "Недопустиме перевизначення вбудованої змінної \"$2\" на позиції $1.", - "abusefilter-exception-outofbounds": "Запит на неіснуючий елементу списку $2 (розмір списку = $3) на позиції $1.", - "abusefilter-exception-notarray": "Запит на елемент масиву для об'єкту, що не є масивом, на позиції $1.", - "abusefilter-exception-unclosedcomment": "Незакритий коментар у позиції $1.", - "abusefilter-exception-invalidiprange": "Недійсний IP-діапазон «$2», поданий у позиції $1.", - "abusefilter-exception-disabledvar": "Змінна $2 у позиції $1 більше не використовується.", + "abusefilter-exception-toomanyargs": "Забагато аргументів для функції $2, що викликається на позиції $1.\nОчікується максимум $3 {{PLURAL:$3|аргумент|аргументи|аргументів}}, а вказано $4", + "abusefilter-exception-regexfailure": "Помилка в регулярному виразі «$2» на позиції $1.", + "abusefilter-exception-overridebuiltin": "Недопустиме перевизначення вбудованого ідентифікатора «$2» на позиції $1.", + "abusefilter-exception-outofbounds": "Запит на неіснуючий елемент масиву $2 (розмір масиву = $3) на позиції $1.", + "abusefilter-exception-negativeindex": "Негативні індекси не дозволені у масивах. Відноситься до індексу \"$2\" на позиції $1.", + "abusefilter-exception-notarray": "Запит на елемент масиву для об'єкта, що не є масивом, на позиції $1.", + "abusefilter-exception-unclosedcomment": "Незакритий коментар на позиції $1.", + "abusefilter-exception-invalidiprange": "Недійсний IP-діапазон «$2», поданий на позиції $1.", + "abusefilter-exception-disabledvar": "Змінна $2 на позиції $1 більше не використовується.", + "abusefilter-exception-variablevariable": "set і set_var передбачають, що перший аргумент має бути літерним рядком, знайдіть символ $1.", "abusefilter-action-tag": "Мітка", "abusefilter-action-throttle": "Звузити", "abusefilter-action-warn": "Попередження", @@ -446,20 +487,20 @@ "abusefilter-revert-title": "Відкотити всі зміни, зроблені фільтром $1", "abusefilter-revert-intro": "Ця форма дозволяє вам відкотити всі зміни, зроблені фільтром редагувань $1.\nБудь ласка, будьте обачні у використанні цього інструменту.", "abusefilter-revert-preview-item": "$1: $2 {{GENDER:$7|зробив|зробила}} $3 на $4. Дії для скасування: $5 ($6)", - "abusefilter-revert-search-legend": "Виберіть дії фільтру редагувань, які потрібно скасувати", + "abusefilter-revert-search-legend": "Виберіть дії фільтра редагувань, які потрібно скасувати", "abusefilter-revert-periodstart": "Початок періоду:", "abusefilter-revert-periodend": "Закінчення періоду:", "abusefilter-revert-search": "Вибір дій", "abusefilter-revert-filter": "ID фільтра:", - "abusefilter-revert-preview-intro": "Нижче приведені виконані фільтром редагувань дії, які будуть скасовані.\nБудь ласка, уважно їх перевірте та натисніть \"{{int:abusefilter-revert-confirm}}\" для підтвердження виділеного.", - "abusefilter-revert-confirm-legend": "Підтвердіть відкат", + "abusefilter-revert-preview-intro": "Нижче приведені виконані фільтром редагувань дії, які будуть відкочені.\nБудь ласка, уважно їх перевірте та натисніть «{{int:abusefilter-revert-confirm}}» для підтвердження виділеного.", + "abusefilter-revert-confirm-legend": "Підтвердіть відкіт", "abusefilter-revert-confirm": "Підтвердити", - "abusefilter-revert-success": "Ви відкотили всі дії, виконані фільтром редагувань [[Special:AbuseFilter/$1|$2]].", + "abusefilter-revert-success": "Ви відкотили всі дії, виконані фільтром редагувань під [[Special:AbuseFilter/$1|номером $2]].", "abusefilter-revert-reason": "Автоматичний відкіт всіх дій, виконаних фільтром редагувань $1.\nВказана причина: $2", "abusefilter-revert-reasonfield": "Причина:", "abusefilter-test": "Перевірити фільтр на вже зроблених редагуваннях", - "abusefilter-test-intro": "Ця сторінка дозволяє вам перевірити фільтр, введений у наведене нижче поле, на {{PLURAL:$1|1=останній $1 зміні|останніх $1 змінах}}.\nЩоб завантажити існуючий фільтр, введіть його ідентифікатор (ID) у текстове поле під полем редагування і натисніть кнопку \"{{int:abusefilter-test-load}}\".", - "abusefilter-test-legend": "Перевірка фільтру", + "abusefilter-test-intro": "Ця сторінка дозволяє вам перевірити фільтр, введений у наведене нижче поле, на {{PLURAL:$1|1=останній $1 зміні|останніх $1 змінах}}.\nЩоб завантажити існуючий фільтр, введіть його ідентифікатор (ID) у текстове поле під полем редагування і натисніть кнопку «{{int:abusefilter-test-load}}».", + "abusefilter-test-legend": "Перевірка фільтра", "abusefilter-test-load-filter": "Завантажити фільтр з ID:", "abusefilter-test-submit": "Перевірити", "abusefilter-test-load": "Завантажити", @@ -469,7 +510,7 @@ "abusefilter-test-period-end": "Зміни зроблені до:", "abusefilter-test-page": "Зміни на сторінці:", "abusefilter-test-shownegative": "Показувати зміни, які не попадають під фільтр", - "abusefilter-test-syntaxerr": "Введений вами фільтр містить синтаксичну помилку.\nВи можете отримати докладне пояснення, натиснувши кнопку \"{{int:abusefilter-edit-check}}\"", + "abusefilter-test-syntaxerr": "Введений вами фільтр містить синтаксичну помилку.\nВи можете отримати докладне пояснення, натиснувши кнопку «{{int:abusefilter-edit-check}}»", "abusefilter-test-badtitle": "Вами введено хибний заголовок сторінки. Можливо, він містить один або кілька символів, які не можна вживати у назвах.", "abusefilter-test-action": "Тип дії:", "abusefilter-test-search-type-all": "Усі дії", @@ -495,17 +536,18 @@ "abusefilter-examine-notfound": "Вказану вами зміну не знайдено.", "abusefilter-examine-incompatible": "Фільтр редагувань не підтримує вказану вами зміну", "abusefilter-examine-noresults": "Нічого не знайдено за запитом із заданими параметрами.", - "abusefilter-topnav": "'''Навігація по фільтрах редагувань'''", - "abusefilter-topnav-home": "Список", + "abusefilter-topnav": "'''Навігація фільтрами редагувань'''", + "abusefilter-topnav-home": "Головна", + "abusefilter-topnav-recentchanges": "Нові зміни фільтрів", "abusefilter-topnav-test": "Пакетна перевірка", "abusefilter-topnav-examine": "Перевірка останніх редагувань", "abusefilter-topnav-log": "Журнал зловживань", "abusefilter-topnav-tools": "Засоби зневадження", - "abusefilter-topnav-import": "Імпорт фільтру", - "abusefilter-log-name": "Журнал фільтру редагувань", + "abusefilter-log-name": "Журнал фільтра редагувань", "abusefilter-log-header": "У цей журнал записуються описи змін, зроблених у фільтрах.\nПодробиці можна знайти в [[Special:AbuseFilter/history|списку]] останніх змін фільтрів.", "abusefilter-logentry-create": "$1 {{GENDER:$2|створив|створила}} $4 ($5)", "abusefilter-logentry-modify": "$1 {{GENDER:$2|змінив|змінила}} $4 ($5)", + "abusefilter-log-invalid-filter": "Деякі із зазначених ідентифікаторів фільтрів неприпустимі.", "abusefilter-log-noresults": "Немає результатів", "abusefilter-diff-title": "Різниця між версіями", "abusefilter-diff-item": "Елемент", @@ -513,16 +555,17 @@ "abusefilter-diff-info": "Основні відомості", "abusefilter-diff-pattern": "Умови фільтрації", "abusefilter-diff-invalid": "Не вдається отримати запитані версії", - "abusefilter-diff-backhistory": "Повернутися до історії фільтру", + "abusefilter-diff-backhistory": "Повернутися до історії фільтра", "abusefilter-diff-prev": "Попередня зміна", "abusefilter-diff-next": "Наступна зміна", "abusefilter-import-intro": "Ви можете використовувати цей інтерфейс для імпорту фільтрів з інших вікі.\nУ джерельній вікі, натисніть «{{int:abusefilter-edit-export}}» у розділі «{{int:abusefilter-edit-tools}}» інтерфейсу редагування.\nСкопіюйте зміст текстового поля, вставте його у цю сторінку і натисніть «{{int:abusefilter-import-submit}}».", "abusefilter-import-submit": "Імпортувати дані", + "abusefilter-import-invalid-data": "Дані, які Ви намагались імпортувати, недійсні", "abusefilter-group-default": "Стандартна", "abusefilter-http-error": "Сталася помилка HTTP: $1.", - "abusefilter-view-private-submit": "Переглянути приватні дані", - "abusefilter-view-private": "Переглянути приватні дані", - "abusefilter-view-private-reason": "Причина доступу до приватних даних:", + "abusefilter-view-privatedetails-submit": "Переглянути приватні дані", + "abusefilter-view-privatedetails-legend": "Переглянути приватні дані", + "abusefilter-view-privatedetails-reason": "Причина доступу до приватних даних:", "abusefilter-log-details-id": "ID журналу", "abusefilter-invalid-request": "Недійсний запит! Ви повинні отримувати доступ до приватних даних журналу через форму на [[Special:AbuseLog/$1]] і вказати причину.", "abusefilter-invalid-request-noid": "Недійсний запит! Ви повинні отримувати доступ до приватних даних журналу через форму на сторінці деталей журналу зловживань і вказати причину.", diff --git a/AbuseFilter/i18n/ur.json b/AbuseFilter/i18n/ur.json index a6affab9..3819fda0 100644 --- a/AbuseFilter/i18n/ur.json +++ b/AbuseFilter/i18n/ur.json @@ -1,59 +1,93 @@ { "@metadata": { "authors": [ - "පසිඳු කාවින්ද", - "عثمان خان شاہ", + "Abdulq", + "BukhariSaeed", "Muhammad Shuaib", "Zainab Meher", - "Abdulq", - "BukhariSaeed" + "عثمان خان شاہ", + "පසිඳු කාවින්ද" ] }, - "abusefilter": "مقطار غلط کاری کی ترتیب", - "abuselog": "غلط استعمال کی لاگ ان کریں", + "abusefilter": "غلط استعمال فلٹر کا انتظام", + "abuselog": "نوشتہ مقطر غلط کاری", "abusefilter-disallowed": "یہ عمل روک دیا گیا ہے کیونکہ خود کار طریقے سے نقصان دہ شناخت ہوا ہے۔\nاگر آپ کو یقین ہے کہ آپ کا عمل فائدہ مند تھا، تو براہ مہربانی آپ کسی منتظم کو مطلع کریں کہ آپ کیا کرنے کی کوشش کر رہے تھے۔\nآپ کے عمل کی رک جانے کی مختصر وجہ یہ ہے: $1", - "abusefilter-blocker": "غلط استعمال فلٹر کریں", - "right-abusefilter-modify": "غلط کاری کے مقطاروں میں ترمیم", - "right-abusefilter-view": "غلط کاری کے مقطاروں کا مشاہدہ", + "abusefilter-blocker": "مقطر غلط کاری", + "right-abusefilter-modify": "غلط کاری کے مقطروں میں ترمیم", + "right-abusefilter-view": "غلط کاری کے مقطروں کا مشاہدہ", "right-abusefilter-log": "نوشتہ غلط کاری کا مشاہدہ", "right-abusefilter-log-detail": "نوشتہ غلط کاری کے مفصل اندراجات کا مشاہدہ", - "right-abusefilter-private": "غلط استعمال کی لاگ میں نجی ڈیٹا نقطہ نظر", - "right-abusefilter-modify-restricted": "محدود اعمال کے ساتھ غلط استعمال فلٹر میں ترمیم", - "right-abusefilter-revert": "کی طرف سے ایک دیا کے غلط استعمال کے فلٹر سب تبدیلیاں الٹا واپس", - "right-abusefilter-hide-log": "میں لکھے گئے مراسلے کے غلط استعمال کے لاگ ان میں چھپائیں", - "right-abusefilter-hidden-log": "دیکھیں چھپے ہوئے غلط استعمال لاگ ان میں لکھے گئے مراسلے", - "action-abusefilter-modify": "غلط استعمال کی فلٹر میں ترمیم", - "action-abusefilter-view": "غلط استعمال کی فلٹر دیکھیں", + "right-abusefilter-privatedetails": "نوشتہ غلط کاری میں نجی معلومات دیکھیں", + "right-abusefilter-privatedetails-log": "مقطر غلط کاری کی خصوصی تفصیلات کے نوشتہ کا معائنہ", + "right-abusefilter-modify-restricted": "ممنوع اقدمات کے حامل مقطر غلط کاری میں ترمیم کریں", + "right-abusefilter-revert": "کسی ایک درج شدہ مقطر غلط کاری کی تمام تبدیلیوں کو واپس پھیریں", + "right-abusefilter-hide-log": "نوشتہ غلط کاری کے اندراجات چھپائیں", + "right-abusefilter-hidden-log": "نوشتہ غلط کاری کے پوشیدہ اندراجات دیکھیں", + "action-abusefilter-modify": "مقطر غلط کاری میں ترمیم", + "action-abusefilter-view": "مقطر غلط کاری دیکھنے", "action-abusefilter-log": "غلط استعمال کے لاگ کو دیکھیں", "action-abusefilter-log-detail": "دیکھیں تفصیلی غلط استعمال لاگ ان میں لکھے گئے مراسلے", - "action-abusefilter-private": "غلط استعمال کی لاگ میں نجی اعداد و شمار دیکھیں", + "action-abusefilter-privatedetails": "غلط استعمال کی لاگ میں نجی اعداد و شمار دیکھیں", + "action-abusefilter-privatedetails-log": "مقطر غلط کاری کی خصوصی تفصیلات کے نوشتہ رسائی کے معائنہ", "action-abusefilter-modify-restricted": "محدود اعمال کے ساتھ غلط استعمال فلٹر میں ترمیم", "action-abusefilter-revert": "کی طرف سے ایک دیا کے غلط استعمال کے فلٹر سب تبدیلیاں الٹا واپس", "action-abusefilter-view-private": "قول کے غلط استعمال کے فلٹر کو ذاتی کے طور پر نشان", - "abusefilter-log": "غلط استعمال فلٹر لاگ ان کریں", "abusefilter-log-summary": "اس لاگ ان کے فلٹرز کی طرف سے پکڑے گئے سب اعمال کی فہرست کو ظاہر کرتا ہے.", "abusefilter-log-search": "تلاش کے غلط استعمال لاگ ان کریں", "abusefilter-log-search-user": "صارف:", "abusefilter-log-search-title": "عنوان:", "abusefilter-log-search-wiki": "ویکی:", + "abusefilter-log-search-impact": "اثر:", + "abusefilter-log-search-impact-all": "تمام اقدمات", + "abusefilter-log-search-impact-saved": "محض محفوظ تبدیلیاں", + "abusefilter-log-search-impact-not-saved": "محفوظ تبدیلیوں کو چھوڑ کر", + "abusefilter-log-search-entries-all": "تمام اندراجات", + "abusefilter-log-search-entries-hidden": "محض پوشیدہ اندراجات", "abusefilter-log-search-action-other": "دیگر", "abusefilter-log-search-action-any": "کوئی بھی", + "abusefilter-log-search-action-taken-label": "اقدام:", + "abusefilter-log-search-action-taken-any": "کوئی بھی", "abusefilter-log-search-submit": "تلاش", + "abusefilter-log-detailedentry-local": "مقطر $1", "abusefilter-log-detailslink": "تفصیلات", "abusefilter-log-diff": "فرق", "abusefilter-log-hidelink": "رویت کو ایڈجسٹ", "abusefilter-log-details-var": "متغیر", "abusefilter-log-details-val": "قدر", "abusefilter-log-details-vars": "کارروائی کے پیرامیٹر", - "abusefilter-log-details-private": "نجی نوشتہ کی تفصیلات", + "abusefilter-log-details-privatedetails": "نجی نوشتہ کی تفصیلات", + "abusefilter-log-details-checkuser": "صارف پڑتال", "abusefilter-log-noactions": "کوئی بھی نہیں", "abusefilter-log-details-diff": "تبدیلیوں میں ترمیم کی گئی", - "abusefilter-log-linkoncontribs": "غلط استعمال کی لاگ ان کریں", + "abusefilter-log-linkoncontribs": "نوشتہ غلط کاری", + "abusefilter-log-linkoncontribs-text": "{{GENDER:$1|اس صارف}} کا نوشتہ غلط کاری", "abusefilter-log-linkonhistory": "نوشتہ غلط کاری دیکھیں", + "abusefilter-log-linkonhistory-text": "اس صفحہ کا نوشتہ غلط کاری دیکھیں", + "abusefilter-log-linkonundelete": "نوشتہ غلط کاری دیکھیں", + "abusefilter-log-linkonundelete-text": "اس صفحہ کا نوشتہ غلط کاری دیکھیں", + "abusefilter-log-hidden-implicit": "(نسخہ کے حذف شدہ ہونے کی بنا پر پوشیدہ ہے)", + "abusefilter-log-cannot-see-details": "آپ کو اس اندراج کی تفصیلات دیکھنے کی اجازت نہیں ہے۔", + "abusefilter-log-cannot-see-privatedetails": "آپ کو اس اندراج کی نجی تفصیلات دیکھنے کی اجازت نہیں ہے۔", + "abusefilter-log-nonexistent": "فراہم کردہ شناختی نمبر کا کوئی اندراج موجود نہیں ہے۔", + "abusefilter-log-details-hidden": "آپ اس اندراج کی تفصیلات نہیں دیکھ سکتے، کیونکہ اسے مخفی رکھا گیا ہے۔", + "abusefilter-log-details-hidden-implicit": "آپ اس اندراج کی تفصیلات نہیں دیکھ سکتے، کیونکہ اس سے ملحق نسخہ کو پوشیدہ رکھا گیا ہے۔", + "abusefilter-log-private-not-included": "آپ کے درج کردہ فلٹر نجی ہیں۔\nچونکہ آپ نجی مقطر کی تفصیلات دیکھنے کے مجاز نہیں ہیں، اس لیے ان مقطروں کو تلاش نہیں کیا جا سکتا۔", + "abusefilter-log-hide-legend": "نوشتہ کا اندراج چھپائیں", + "abusefilter-log-hide-id": "اندراجِ نوشتہ کا شناختی نمبر:", + "abusefilter-log-hide-hidden": "اس اندراج کو عوامی نگاہ سے چھپائیں", "abusefilter-log-hide-reason": "وجہ:", + "abusefilter-log-hide-reason-other": "دیگر/اضافی وجہ:", "abusefilter-log-hide-forbidden": "آپ غلط استعمال لاگ ان میں لکھے گئے مراسلے کو چھپانے کے لئے اجازت نہیں ہے.", - "abusefilter-management": "غلط استعمال فلٹر کا انتظام", + "abusefilter-log-entry-suppress": "$1 نے $3 کو {{GENDER:$2|مخفی کیا}}", + "abusefilter-log-entry-unsuppress": "$1 نے $3 کو {{GENDER:$2|عام کیا}}", + "log-action-filter-abusefilter": "تبدیلئ مقطر کی نوعیت:", + "log-action-filter-abusefilter-create": "تخلیق مقطر جدید", + "log-action-filter-abusefilter-modify": "تبدیلی مقطر", + "logentry-abusefilterprivatedetails-access": "$1 نے $3 کی نجی تفصیلات تک {{GENDER:$2|رسائی حاصل کی}}", + "abusefilterprivatedetails-log-name": "نوشتہ رسائی برائے نجی مقطر غلط کاری", "abusefilter-list": "سب فلٹر", + "abusefilter-list-id": "مقطر کا شناختی نمبر", + "abusefilter-list-pattern": "طرز", "abusefilter-list-status": "حیثیت", "abusefilter-list-public": "عوامی تفصیل", "abusefilter-list-consequences": "ہوگا ؟", @@ -69,87 +103,144 @@ "abusefilter-enabled": "فعال", "abusefilter-deleted": "خارج کر دیا گیا", "abusefilter-disabled": "معذور", + "abusefilter-hitcount": "$1 {{PLURAL:$1|ضرب|ضربات}}", "abusefilter-new": "ایک نئے فلٹر تخلیق کریں", + "abusefilter-import-button": "درآمد فلٹر کریں", "abusefilter-status-global": "عالمی", "abusefilter-list-options": "اختیارات", "abusefilter-list-options-deleted": "خارج کردہ فلٹر:", "abusefilter-list-options-deleted-only": "شو صرف حذف فلٹر کر", "abusefilter-list-options-deleted-hide": "فلٹر چھپائیں حذف کر دی ہے", "abusefilter-list-options-deleted-show": "خارج کردہ فلٹر شامل ہیں", - "abusefilter-list-options-scope": "مقطارات دکھائیں:", + "abusefilter-list-options-scope": "مقطرات دکھائیں:", + "abusefilter-list-options-scope-local": "محض مقامی قوانین", + "abusefilter-list-options-scope-global": "محض عالمی قوانین", + "abusefilter-list-options-scope-all": "مقامی و عالمی قوانین", + "abusefilter-list-options-further-options": "مزید اختیارات:", "abusefilter-list-options-hidedisabled": "چھپائیں فلٹر غیر فعال کر دیا", + "abusefilter-list-options-hideprivate": "نجی مقطروں کو چھپائیں", "abusefilter-list-options-searchfield": "اصول کے مظابق تلاش", "abusefilter-list-options-searchpattern": "نمونہ شامل کریں", "abusefilter-list-options-searchoptions": "طریقہ تلاش", "abusefilter-list-options-search-like": "واضح سوال", + "abusefilter-list-options-search-rlike": "ریگولر ایکسپریشن", + "abusefilter-list-options-search-irlike": "غیر حساس (case-insensitive) ریجیکس", + "abusefilter-list-regexerror": "دوران تلاش میں کوئی نقص واقع ہے: ریجیکس کے سنٹیکس میں کوئی غلطی ہے۔", "abusefilter-list-options-submit": "اپ ڈیٹ", "abusefilter-tools-expr": "اظہار ٹیسٹر", "abusefilter-tools-reautoconfirm-user": "صارف:", + "abusefilter-edit": "زیر ترمیم مقطر غلط کاری", + "abusefilter-edit-subtitle": "زیر ترمیم مقطر $1", "abusefilter-edit-subtitle-new": "فلٹر کی تشکیل", + "abusefilter-edit-token-not-match": "یہ ترمیم محفوظ نہیں ہوئی، براہ کرم دوبارہ محفوظ کریں۔", "abusefilter-edit-status-label": "اعداد و شمار:", "abusefilter-edit-new": "نئے فلٹر کریں", "abusefilter-edit-save": "فلٹر کو محفوظ کریں", + "abusefilter-edit-id": "مقطر کا شناختی نمبر:", "abusefilter-edit-switch-editor": "خانہ ترمیم تبدیل کریں", + "abusefilter-edit-description": "وضاحت:\n:\"(عوامی)\"", + "abusefilter-edit-field-description": "وضاحت", "abusefilter-edit-group": "فلٹر گروپ:", - "abusefilter-edit-enabled": "اس فلٹر کو فعال", - "abusefilter-edit-deleted": "حذف کر کے طور پر نشان زد کریں", - "abusefilter-edit-hidden": "عوامی نقطہ نظر سے اس فلٹر کی تفصیلات چھپائیں", - "abusefilter-edit-rules": "شروط:", + "abusefilter-edit-flags": "پرچم:", + "abusefilter-edit-enabled": "اس فلٹر کو فعال کریں", + "abusefilter-edit-deleted": "بطور حذف شدہ نشان زد کریں", + "abusefilter-edit-hidden": "عوامی نگاہ سے اس مقطر کی تفصیلات چھپائیں", + "abusefilter-edit-global": "عالمی مقطر", + "abusefilter-edit-rules": "شرائط:", + "abusefilter-edit-field-conditions": "شرائط", + "abusefilter-edit-notes": "ملاحظات:", + "abusefilter-edit-lastmod": "فلٹر میں آخری ترمیم کی تاریخ:", + "abusefilter-edit-lastmod-text": "$1 از $2", "abusefilter-edit-hitcount": "فلٹر مشاہدات:", "abusefilter-edit-consequences": "مطابقت پائی جانے کی صورت میں ضروری اقدامات", - "abusefilter-edit-action-warn": "دے صارف ایک انتباہ کے بعد ان کے اعمال کو دکھانے کا محرک", + "abusefilter-edit-action-warn": "صارف کو انتباہ دینے کے بعد یہ کام کریں", "abusefilter-edit-action-disallow": "ےہ سوال کارروائی سے صارف کی روک تھام", + "abusefilter-edit-action-blockautopromote": "صارف کی خود توثیق شدہ حیثیت کو ختم کریں", "abusefilter-edit-action-degroup": "تمام مراعات یافتہ طبقے کے موضوعات سے صارف حذف کریں", "abusefilter-edit-action-block": "میں صارف اور/یا ترمیم سے آئی پی ایڈریس بلاک", "abusefilter-edit-action-rangeblock": "متفرق آئ پی رینج کو بندکریں جس سے صارف اختراع کرتا ھے۔", - "abusefilter-edit-action-tag": "ٹیگ مزید کا جائزہ کے لئے ترمیم کریں", - "abusefilter-edit-throttle-count": "اجازت دینے کے لئے اعمال کی تعداد:", + "abusefilter-edit-action-tag": "مکرر مراجعت کی غرض سے ترمیم کو ٹیگ کریں", + "abusefilter-edit-throttle-count": "مجاز اقدامات کی تعداد:", "abusefilter-edit-throttle-period": "وقت کی مدت (سیکنڈ میں):", - "abusefilter-edit-throttle-ip": "آئی پی پتا", - "abusefilter-edit-throttle-user": "صارف کھاتہ", - "abusefilter-edit-warn-message": "انتباہ کے لئے استعمال کرنے کے لئے نظام پیغام:", + "abusefilter-throttle-ip": "آئی پی پتا", + "abusefilter-throttle-user": "صارف کھاتا", + "abusefilter-throttle-editcount": "تعداد ترامیم", + "abusefilter-throttle-site": "پوری سائٹ", + "abusefilter-throttle-page": "صفحہ", + "abusefilter-edit-warn-message": "انتباہ کے لیے زیر استعمال نظامی پیغام:", "abusefilter-edit-warn-other": "دوسرے پیغام", + "abusefilter-edit-warn-other-label": "دوسرے پیغام کا عنوان:\n:\"(\"میڈیاویکی:\" کے سابقہ کے بغیر)\"", "abusefilter-edit-warn-actions": "اعمال:", - "abusefilter-edit-main": "پیرامیٹرز کو فلٹر", + "abusefilter-edit-disallow-message": "عدم اجازت کے لیے زیر استعمال نظامی پیغام:", + "abusefilter-edit-disallow-other": "دوسرا پیغام", + "abusefilter-edit-disallow-other-label": "دوسرے پیغام کا عنوان:\n:\"(\"میڈیاویکی:\" کے سابقہ کے بغیر)\"", + "abusefilter-edit-disallow-actions": "اقدامات:", + "abusefilter-edit-disallow-edit": "منتخب پیغام کو بنائیں/ترمیم کریں", + "abusefilter-edit-tag-tag": "[[Special:Tags|ٹیگ]]:", + "abusefilter-edit-tag-placeholder": "ٹیگ درج کریں (یکے بعد دیگرے یا فاصلوں کی علامت سے جدا کریں)", + "abusefilter-edit-tag-hidden-placeholder": "ٹیگ درج کریں (فاصلوں کی علامت سے جدا کریں)", + "abusefilter-edit-block-anon-durations": "گمنام صارفین کی مدت پابندی:", + "abusefilter-edit-block-user-durations": "مندرج صارفین کی مدت پابندی:", + "abusefilter-block-anon": "گمنام صارفین پر پابندی", + "abusefilter-block-user": "مندرج صارفین پر پابندی", + "abusefilter-block-talk": "تبادلہ خیال کی ترمیم ممنوع", + "abusefilter-edit-denied": "آپ شاید اس مقطر کی تفصیلات نہ دیکھ سکیں، کیونکہ اسے مخفی رکھا گیا ہے۔", + "abusefilter-edit-main": "فلٹر کے پیرامیٹر", "abusefilter-edit-done-subtitle": "فلٹر ترمیم", - "abusefilter-edit-viewhistory": "فلٹر اس تاریخ کو دیکھیں", + "abusefilter-edit-done": "[[Special:AbuseFilter/$1|مقطر $3]] میں \n[[Special:AbuseFilter/history/$1/diff/prev/$2|آپ کی تبدیلیاں]] محفوظ ہو گئیں۔", + "abusefilter-edit-viewhistory": "اس فلٹر کا تاریخچہ دیکھیں", "abusefilter-edit-history": "تاریخ:", "abusefilter-edit-check": "سنٹکس چیک کریں", "abusefilter-edit-badfilter": "آپ مخصوص فلٹر موجود نہیں", "abusefilter-edit-revert": "اعمال اس فلٹر کی طرف لے جایا جاسکتا", - "abusefilter-edit-tools": "فورم کے اوزار:", - "abusefilter-edit-test-link": "حال ہی میں کی گئی تدوین کے خلاف اس فلٹر ٹیسٹ", - "abusefilter-edit-export": "ایک اور وکیپیڈیا کو اس فلٹر میں برآمد", + "abusefilter-edit-tools": "آلات:", + "abusefilter-edit-test-link": "حالیہ تبدیلیوں پر اس فلٹر کو جانچیں", + "abusefilter-edit-export": "اس فلٹر کو دوسری ویکی میں برآمد کریں", "abusefilter-edit-syntaxok": "کوئی سنٹکس غلطیوں کا پتہ چلا.", "abusefilter-edit-notallowed": "آپ تخلیق یا غلط استعمال فلٹر میں ترمیم کرنے کے لئے جائز نہيں کر رہے ہیں", - "abusefilter-edit-builder-select": "یہ کرسر پر شامل کرنے کے لئے ایک آپشن منتخب کریں", + "abusefilter-edit-builder-select": "جہاں کرسر ہے وہاں درج کرنے کے لیے کسی آپشن کا انتخاب کریں", "abusefilter-edit-builder-group-op-arithmetic": "حساب آپریٹرز", + "abusefilter-edit-builder-op-arithmetic-addition": "جمع (+)", + "abusefilter-edit-builder-op-arithmetic-subtraction": "وضع (-)", + "abusefilter-edit-builder-op-arithmetic-multiplication": "ضرب (*)", + "abusefilter-edit-builder-op-arithmetic-divide": "تقسیم (/)", + "abusefilter-edit-builder-op-arithmetic-modulo": "باقی ماندہ (%)", + "abusefilter-edit-builder-op-arithmetic-pow": "قوت (**)", + "abusefilter-edit-builder-op-bool-not": "نہیں (!)", + "abusefilter-edit-builder-op-bool-and": "اور (&)", + "abusefilter-edit-builder-op-bool-or": "یا (|)", "abusefilter-edit-builder-group-misc": "متفرق", "abusefilter-edit-builder-group-funcs": "افعال", "abusefilter-edit-builder-funcs-get_matches": "ریجکس میچ میں ہر جوڑ کے گرو کی صف آرائی متن سے ملتی ہے۔", + "abusefilter-edit-builder-group-vars": "متغیرات", "abusefilter-edit-builder-vars-action": "کارروائی", "abusefilter-edit-builder-vars-newsize": "نیا صفحہ کا سائز", "abusefilter-edit-builder-vars-oldsize": "پرانے صفحہ کا سائز", - "abusefilter-edit-builder-vars-removedlines": "لائنوں ترمیم میں ہٹا دیا جاتا", + "abusefilter-edit-builder-vars-removedlines": "ترمیم میں حذف کی گئی سطریں", "abusefilter-edit-builder-vars-summary": "خلاصہ/وجہ میں ترمیم کریں", - "abusefilter-edit-builder-vars-page-ns": "صفحہ نیم سپیس", + "abusefilter-edit-builder-vars-page-id": "صفحہ کا شناختی نمبر", + "abusefilter-edit-builder-vars-page-ns": "صفحہ کا نام فضا", + "abusefilter-edit-builder-vars-page-title": "صفحہ کا عنوان (بدون نام فضا)", "abusefilter-edit-builder-vars-page-prefixedtitle": "مکمل صفحہ کا عنوان", "abusefilter-edit-builder-vars-movedfrom-title": "اقدام ذریعہ صفحہ کا عنوان", "abusefilter-edit-builder-vars-movedfrom-prefixedtitle": "اقدام ذریعہ صفحہ کا مکمل عنوان", - "abusefilter-edit-builder-vars-movedto-ns": "نیم سپیس میں منتقل منزل صفحے کے", - "abusefilter-edit-builder-vars-movedto-title": "اقدام منزل صفحہ کا عنوان", - "abusefilter-edit-builder-vars-movedto-prefixedtitle": "اقدام منزل صفحہ کا مکمل عنوان", + "abusefilter-edit-builder-vars-movedto-ns": "منتقلی کے لیے ہدف صفحہ کا نام فضا", + "abusefilter-edit-builder-vars-movedto-title": "منتقل کرنے کے لیے ہدف صفحہ کا عنوان", + "abusefilter-edit-builder-vars-movedto-prefixedtitle": "منتقل کرنے کے لیے ہدف صفحہ کا مکمل عنوان", "abusefilter-edit-builder-vars-user-editcount": "صارف کے شمار میں ترمیم کریں", - "abusefilter-edit-builder-vars-user-age": "صارف اکاؤنٹ کی عمر", + "abusefilter-edit-builder-vars-user-age": "صارف کھاتے کی عمر", "abusefilter-edit-builder-vars-user-name": "صارف اکاؤنٹ کا نام", "abusefilter-edit-builder-vars-user-groups": "گروپس (سمیت آدمى) صارف میں ہے", - "abusefilter-edit-builder-vars-user-emailconfirm": "وقت کا ای میل ایڈریس کی تصدیق کی تھی", + "abusefilter-edit-builder-vars-user-emailconfirm": "برقی ڈاک پتے کی تصدیق کا وقت", "abusefilter-edit-builder-vars-recent-contributors": "اس صفحہ کو میں شراکت کے لئے آخری دس صارفین", "abusefilter-edit-builder-vars-all-links": "نئے متن میں تمام بیرونی لنکس", "abusefilter-edit-builder-vars-added-links": "اس ترمیم میں شامل تمام بیرونی لنکس", "abusefilter-edit-builder-vars-removed-links": "تمام بیرونی روابط کی ترمیم میں ہٹا دیا جاتا", - "abusefilter-edit-builder-vars-new-text-stripped": "نیا صفحہ ٹیکسٹ ، کسی بھی تدوین چھین لیا", + "abusefilter-edit-builder-vars-new-text": "نیا صفحہ ٹیکسٹ ، کسی بھی تدوین چھین لیا", "abusefilter-edit-builder-vars-restrictions-edit": "اس صفحے کے حفاظتی مراحل میں ترمیم کریں", + "abusefilter-filter-log": "مقطر کی حالیہ تبدیلیاں", + "abusefilter-history": "مقطر غلط کاری #$1 کی تبدیلیوں کا تاریخچہ", + "abusefilter-history-foruser": "$1 کی تبدیلیاں", "abusefilter-history-hidden": "پوشیدہ", "abusefilter-history-enabled": "فعال", "abusefilter-history-global": "عالمی", @@ -173,6 +264,7 @@ "abusefilter-revert-search": "اعمال کا انتخاب", "abusefilter-revert-filter": "ٓئی ڈی فلٹر کریں:", "abusefilter-revert-confirm": "اس بات کی تصدیق", + "abusefilter-revert-reasonfield": "وجہ:", "abusefilter-test-submit": "ٹیسٹ", "abusefilter-test-load": "بوجھ", "abusefilter-test-user": "صارف کی طرف سے تبدیلیاں:", @@ -180,9 +272,15 @@ "abusefilter-test-period-end": "تبدیلیوں سے پہلے بنا دیا ہے:", "abusefilter-test-page": "تبدیلیاں بنایا صفحہ کرنے کے لئے:", "abusefilter-test-shownegative": "شو کی تبدیلیاں جو کہ سے میل نہیں کھاتے فلٹر", + "abusefilter-test-search-type-edit": "ترامیم", + "abusefilter-test-search-type-move": "منتقلیاں", + "abusefilter-test-search-type-delete": "حذف شدگیاں", + "abusefilter-test-search-type-upload": "اپلوڈ", + "abusefilter-test-search-type-createaccount": "کھاتہ سازی", "abusefilter-changeslist-examine": "کی جانچ پڑتال", "abusefilter-examine": "انفرادی تبدیلیاں کی جانچ پڑتال", "abusefilter-examine-user": "صارف:", + "abusefilter-examine-title": "صفحہ کا عنوان:", "abusefilter-examine-submit": "تلاش", "abusefilter-examine-test": "اس تبدیلی کے خلاف ایک فلٹر ٹیسٹ", "abusefilter-examine-test-button": "ٹیسٹ فلٹر کریں", @@ -195,15 +293,18 @@ "abusefilter-topnav-home": "گھر", "abusefilter-topnav-test": "بیچ ٹیسٹنگ", "abusefilter-topnav-examine": "ماضی کی گئی تدوین کی جانچ پڑتال", - "abusefilter-topnav-log": "غلط استعمال کی لاگ ان کریں", + "abusefilter-topnav-log": "نوشتہ غلط کاری", "abusefilter-topnav-tools": "درستگی نقص ، فورم کے اوزار", - "abusefilter-topnav-import": "درآمد فلٹر کریں", - "abusefilter-log-name": "غلط استعمال فلٹر لاگ ان کریں", + "abusefilter-log-name": "نوشتہ مقطر غلط کاری", + "abusefilter-logentry-create": "$1 نے $4 ($5) کو {{GENDER:$2|بنایا}}", "abusefilter-log-noresults": "کوئی نتائج", "abusefilter-diff-title": "ورژن کے درمیان اختلافات", "abusefilter-diff-item": "آئٹم کو", "abusefilter-diff-info": "بنیادی معلومات", "abusefilter-diff-pattern": "فلٹر حالات", + "abusefilter-import-intro": "آپ اس انٹرفیس کی مدد سے دوسری ویکیوں سے فلٹر درآمد کر سکتے ہیں۔\nجس ویکی سے درآمد کر رہے ہیں وہاں \"{{int:abusefilter-edit-tools}}\" کے تحت موجود \"{{int:abusefilter-edit-export}}\" پر کلک کریں۔\nایک خانہ نمودار ہوگا، جس میں درج مواد کو نقل کرکے یہاں نیچے موجود خانہ میں چسپاں کریں اور اس کے بعد \"{{int:abusefilter-import-submit}}\" کی بٹن پر کلک کریں۔", "abusefilter-group-default": "پہلے سے طے شدہ", + "abusefilter-view-privatedetails-legend": "نجی تفصیلات دیکھیں", + "abusefilter-log-ip-not-available": "دستیاب نہیں ہے", "tag-abusefilter-condition-limit": "تعداد شرائط کے حدود تک جا پہنچا" } diff --git a/AbuseFilter/i18n/uz.json b/AbuseFilter/i18n/uz.json index 54b83e22..ef70c873 100644 --- a/AbuseFilter/i18n/uz.json +++ b/AbuseFilter/i18n/uz.json @@ -7,7 +7,6 @@ "abuselog": "Filtrlash qaydlari", "right-abusefilter-log": "filtrlash qaydlarini koʻrish", "action-abusefilter-log": "filtrlash qaydlarini koʻrish", - "abusefilter-log": "Filtrlash qaydlari", "abusefilter-log-linkoncontribs": "filtrlash qaydlari", "abusefilter-log-linkoncontribs-text": "Ushbu foydalanuvchi haqida filtrlash qaydlaridagi yozuvlar", "abusefilter-log-hide-reason": "Sabab:", diff --git a/AbuseFilter/i18n/vec.json b/AbuseFilter/i18n/vec.json index 2ad9de49..adad0bbc 100644 --- a/AbuseFilter/i18n/vec.json +++ b/AbuseFilter/i18n/vec.json @@ -2,46 +2,50 @@ "@metadata": { "authors": [ "Candalua", + "Conky77", + "Cusolotto", + "Fierodelveneto", + "Fitoschido", "Frigotoni", "GatoSelvadego", + "Matma Rex", "Nemo bis", "Nick1915", - "Matma Rex", - "Cusolotto" + "S4b1nuz E.656" ] }, "abusefilter-desc": "Àplica dele eurìstiche automatiche a le modifiche.", - "abusefilter": "Configurassion del filtro abusi", - "abuselog": "Registro abusi", + "abusefilter": "Gestion del filtro abusi", + "abuselog": "Registro del filtro abusi", "abusefilter-intro": "Benvegnù in te l'interfacia de gestion del Filtro Abusi.\nEl Filtro Abusi el xe un sistema automatixà par l'aplicassion de eurìstiche automatiche a tute le azion.\nSta interfacia la mostra un elenco dei filtri definìi e la parmete de modificarli.", "abusefilter-warning": "'''Ocio''': sta azion la xe stà ritegnùa pericolosa in base a na verifica automatica.\nLe modifiche mia costrutive le vegnarà prontamente anulà; l'inserimento palese o ripetùo de contributi mia costrutivi el darà luogo al bloco de l'utensa o del to indirizo IP.\nSe te ritien che la modifica in question la sia costrutiva, strucar de novo su Invia par confermarla.\nSta qua la xe na breve descrission de la regola de sicureza che xe stà violà: $1", "abusefilter-disallowed": "Sta azion la xe stà ritegnùa pericolosa in base a na verifica automatica.\nSe te ritien che la modifica in question la sia costrutiva, par piaser dighelo a un aministrador.\nSta qua la xe na breve descrission de la regola de sicureza che xe stà violà: $1", "abusefilter-blocked-display": "Sta azion la xe stà ritegnùa pericolosa in base a na verifica automatica,\ne quindi te xe stà inpedìo de farla.\nInoltre, par protegere {{SITENAME}}, l'utensa coivolta e tuti i indirizi IP associà i xe stà blocà e no i pole pi far modifiche.\nSe te ritien che la modifica in question la sia costrutiva, par piaser dighelo a un aministrador.\nSta qua la xe na breve descrission de la regola de sicureza che xe stà violà: $1", "abusefilter-degrouped": "Sta azion la xe stà ritegnùa pericolosa in base a na verifica automatica.\nQuindi te xe stà inpedìo de farla e, sicome ghe xe el ris-cio che la to utensa la sia conpromessa, tuti i diriti i ghe xe stà revocà.\nSe te ritien che sia stà un eror, par piaser dighelo a un burocrate spiegando cossa te seri drio far, e i to diriti i te vegnarà ridati.\nSta qua la xe na breve descrission de la regola de sicureza che xe stà violà: $1", "abusefilter-autopromote-blocked": "Sta azion la xe stà ritegnùa pericolosa in base a na verifica automatica,\ne quindi te xe stà inpedìo de farla.\nInoltre, par sicuressa, alcuni privilegi tipici de le utense conossùe i te xe stà tenporaneamente cavà.\nSta qua la xe na breve descrission de la regola de sicureza che xe stà violà: $1", - "abusefilter-blocker": "Filtro abusi", + "abusefilter-blocker": "Filtro anti abusi", "abusefilter-blockreason": "Blocà automaticamente dal filtro abusi.\nDescrission de la regola corispondente: $1", "abusefilter-degroupreason": "Diriti cavà automaticamente dal filtro abusi.\nDescrission de la regola: $1", "abusefilter-accountreserved": "Sta utensa la xe riservà par el filtro abusi.", "right-abusefilter-modify": "Modìfega i filtri abusi", "right-abusefilter-view": "Varda i filtri abusi", - "right-abusefilter-log": "Varda el registro abusi", - "right-abusefilter-log-detail": "Varda voci detaglià del registro abusi", - "right-abusefilter-private": "Varda i dati privati nel registro dei abusi", - "right-abusefilter-modify-restricted": "Modifica i filtri anti abusi con le azion riservà", - "right-abusefilter-revert": "Anula tuti i canbiamenti fati da un determinato filtro abusi", - "right-abusefilter-view-private": "Varda i filtri abuso segnà come privati", - "right-abusefilter-hide-log": "Scondi voci nel registro dei abusi", - "right-abusefilter-hidden-log": "Vardar elementi sconti del registro dei abusi", - "action-abusefilter-modify": "modificar i filtri abusi", - "action-abusefilter-view": "vardar i filtri abusi", - "action-abusefilter-log": "vardar el registro dei abusi", - "action-abusefilter-log-detail": "vardar le voci de detaglio del registro dei abusi", - "action-abusefilter-private": "vardar le informassion riservà in tel registro dei abusi", - "action-abusefilter-modify-restricted": "modificar i filtri abusi con le azion riservà", - "action-abusefilter-revert": "ripristinar tute le modifiche fate da un determinato filtro abusi", - "action-abusefilter-view-private": "vardar i filtri abuso segnà come privati", - "abusefilter-log": "Registro del filtro abusi", + "right-abusefilter-log": "Varda el rejistro anti-abuxi", + "right-abusefilter-log-detail": "Varda voxe detajade del rejistro del filtro anti-abuxi", + "right-abusefilter-privatedetails": "Varda i dati privai n'tel rejistro dei abuxi", + "right-abusefilter-modify-restricted": "Modìfega i filtri anti-abuxi co łe asion riservae", + "right-abusefilter-revert": "Desfa tuti i canbiamenti fati da on determinato filtro abusi", + "right-abusefilter-view-private": "Varda i filtri anti-abuxi segnai cofà privai", + "right-abusefilter-hide-log": "Scondi voxe in tel rejistro del filtro anti-abuxi", + "right-abusefilter-hidden-log": "Vardar voxe sconte del rejistro del filtro anti-abuxi", + "action-abusefilter-modify": "modifegar i filtri abuxi", + "action-abusefilter-view": "vardar i filtri abuxi", + "action-abusefilter-log": "vardar el rejistro dei abuxi", + "action-abusefilter-log-detail": "vardar łe voxe de detajo del rejistro del filtro anti-abuxi", + "action-abusefilter-privatedetails": "vardar le informasion riservà in tel rejistro dei abuxi", + "action-abusefilter-modify-restricted": "modifegar i filtri anti-abuxi co łe asion riservà", + "action-abusefilter-revert": "riciapar fora tute łe modifeghe faxeste da on determinà filtro anti-abuxi", + "action-abusefilter-view-private": "vardar i filtri abuxo segnà cofà privai", + "action-abusefilter-hide-log": "scondi voxe in tel rejistro dei abuxi", "abusefilter-log-summary": "Sto registro el mostra un elenco de tute le azion caturà dai filtri.", "abusefilter-log-search": "Serca in tel registro dei abusi", "abusefilter-log-search-user": "Utente:", @@ -58,13 +62,14 @@ "abusefilter-log-details-var": "Variabile", "abusefilter-log-details-val": "Valor", "abusefilter-log-details-vars": "Parametri de l'azion", - "abusefilter-log-details-private": "Dati privati", + "abusefilter-log-details-privatedetails": "Dati privati", "abusefilter-log-details-ip": "Indirisso IP de origine", "abusefilter-log-noactions": "nissuna", "abusefilter-log-details-diff": "Modìfeghe fate", "abusefilter-log-linkoncontribs": "registro abusi", "abusefilter-log-linkoncontribs-text": "Registro dei abusi par sto utente", - "abusefilter-log-hidden": "(elemento sconto)", + "abusefilter-log-linkonhistory": "Varda el rejistro anti-abuxi", + "abusefilter-log-linkonundelete": "Varda el rejistro anti-abuxi", "abusefilter-log-details-hidden": "No te podi védar i detagli de sta voce, parché i xe sconti al pùblico.", "abusefilter-log-hide-legend": "Scondi elemento", "abusefilter-log-hide-id": "ID de l'elemento:", @@ -72,7 +77,6 @@ "abusefilter-log-hide-reason": "Motivassion:", "abusefilter-log-hide-reason-other": "Altra motivasion:", "abusefilter-log-hide-forbidden": "No te ghè el parmesso de scondar i elementi del registro dei abusi.", - "abusefilter-management": "Gestion del filtro abusi", "abusefilter-list": "Tuti i filtri", "abusefilter-list-id": "ID del filtro", "abusefilter-list-status": "Stato", @@ -86,19 +90,21 @@ "abusefilter-list-lastmodified": "Ultima modìfega", "abusefilter-hidden": "Privado", "abusefilter-unhidden": "Pùblico", - "abusefilter-enabled": "Intacà", + "abusefilter-enabled": "Ativà", "abusefilter-deleted": "Scancelà", "abusefilter-disabled": "Destacà", "abusefilter-hitcount": "{{PLURAL:$1|una corispondensa|$1 corispondense}}", "abusefilter-new": "Crèa un filtro novo", + "abusefilter-import-button": "Inporta filtro", "abusefilter-return": "Torna a la gestion del filtro", "abusefilter-status-global": "Globałe", - "abusefilter-list-options": "Opzioni", + "abusefilter-list-options": "Opsion", "abusefilter-list-options-deleted": "Filtri scancelè:", "abusefilter-list-options-deleted-only": "Fà védar solo i filtri scancelè", "abusefilter-list-options-deleted-hide": "Scondi i filtri scancelè", "abusefilter-list-options-deleted-show": "Includi i filtri scancelè", "abusefilter-list-options-hidedisabled": "Scondi i filtri destachè", + "abusefilter-list-options-hideprivate": "Scondi i filtri privati", "abusefilter-list-options-submit": "Ajorna", "abusefilter-tools-text": "Qua ghe xe alcuni strumenti utili par la costrussion e la verifica dei filtri abusi.", "abusefilter-tools-expr": "Verifica espressioni", @@ -111,10 +117,9 @@ "abusefilter-reautoconfirm-done": "El stato de autoconfermà de l'utensa el xe stà ripristinà.", "abusefilter-status": "Fra le ultime $1 {{PLURAL:$1|azion|azioni}}, $2 ($3 %) {{PLURAL:$2|gà|gà}} ragiunto el limite de $4 condizion e $5 ($6 %) {{PLURAL:$5|gà|gà}} ativà uno dei filtri atualmente ativi.", "abusefilter-edit-subtitle": "Modìfega del filtro $1", - "abusefilter-edit-oldwarning": "<strong>Te sì drio modificar na version vecia del filtro.\nLe statistiche cità le se riferisse a la version pi nova del filtro.\nSalvando le modifiche vegnarà anulà tuti i canbiamenti fati da sta version in poi.</strong> •\n[[Special:AbuseFilter/history/$2|Ritorna a la cronologia del filtro]].", + "abusefilter-edit-oldwarning": "<strong>Se xé drio modifegare na version vecia de sto filtro.\nŁe statisteghe çitàe łe xé par ła version nova del filtro.\nSalvando łe modifeghe i vegnarà desfai tuti i canbiamenti fati da sta version in dopo.</strong> •\n[[Special:AbuseFilter/history/$2|Torna a l'istorego del filtro]].", "abusefilter-edit-status-label": "Statìsteghe:", "abusefilter-edit-status": "Rispeto {{PLURAL:$1|a l'azion pi recente|a le $1 azioni pi recenti}}, sto filtro el gà catà $2 {{PLURAL:$2|corispondensa|corispondense}} ($3 %).", - "abusefilter-edit-status-profile": "Rispeto {{PLURAL:$1|a l'azion pi recente|a le $1 azioni pi recenti}}, sto filtro el gà catà $2 {{PLURAL:$2|corispondensa|corispondense}} ($3 %).\nEl so tempo medio de esecuzion xe de $4 ms, e impiega $5 {{PLURAL:$5|condizione|condizioni}} del limite de condizioni.", "abusefilter-edit-new": "Filtro novo", "abusefilter-edit-save": "Salva filtro", "abusefilter-edit-id": "ID del filtro:", @@ -124,31 +129,33 @@ "abusefilter-edit-enabled": "Intaca sto filtro", "abusefilter-edit-deleted": "Segna come scancelà", "abusefilter-edit-hidden": "Scondi i detagli de sto filtro da la vista pùblica", - "abusefilter-edit-global": "Àplica sto filtro globalmente", + "abusefilter-edit-global": "Filtro globałe", "abusefilter-edit-rules": "Condission:", "abusefilter-edit-field-conditions": "condisioni", - "abusefilter-edit-notes": "Note:\n:''(private)''", + "abusefilter-edit-notes": "Note:", "abusefilter-edit-lastmod": "Filtro modifegà l'ultima olta:", "abusefilter-edit-lastmod-text": "$1 da $2", "abusefilter-edit-hitcount": "Corespondense par el filtro:", - "abusefilter-edit-consequences": "Azioni in caso de corispondensa", + "abusefilter-edit-consequences": "Asion da far in tel caxo de corispondensa", "abusefilter-edit-action-warn": "Ativa le seguenti azion dopo aver avisà l'utente", "abusefilter-edit-action-disallow": "Fèrma l'utente prima che el cònpia l'azion in question", "abusefilter-edit-action-blockautopromote": "Revoca a l'utente el stato de autoconfermà", "abusefilter-edit-action-degroup": "Cava l'utente da tuti quanti i grupi con privilegi", "abusefilter-edit-action-block": "Inpedìssighe le modifiche a l'utensa e/o a l'indirisso IP", "abusefilter-edit-action-throttle": "Ativa le azion solo se l'utente supera un limite predeterminà", - "abusefilter-edit-action-rangeblock": "Bloca l'intervalo /16 da cui vien l'utente", + "abusefilter-edit-action-rangeblock": "Blocar el rispetivo intervało IP de orìxane de l'utensa", "abusefilter-edit-action-tag": "Segna la modifica par na verifica ulteriore", "abusefilter-edit-throttle-count": "Nùmaro de azioni de permétar:", - "abusefilter-edit-throttle-period": "Perìodo de tenpo:", - "abusefilter-edit-throttle-groups": "Criteri de ragruppamento par el ritardo:\n:''(uno par riga opure unìi da virgole)''", + "abusefilter-edit-throttle-period": "Perìodo de tenpo (in segondi):", + "abusefilter-edit-throttle-groups": "Criteri de ingrupamento par el rałentamento", + "abusefilter-edit-throttle-groups-help": "Varda $1.", "abusefilter-edit-warn-message": "Messajo de sistema da doparar come avertimento:", "abusefilter-edit-warn-other": "Altro messajo", - "abusefilter-edit-warn-other-label": "Nome de la pagina par l'altro messajo:\n:''(sensa el prefisso MediaWiki)''", - "abusefilter-edit-warn-actions": "Azioni:", - "abusefilter-edit-warn-preview": "Anteprima del messajo selessionà", + "abusefilter-edit-warn-other-label": "Nome de ła pàjina par l'altro mesajo:\n:''(sensa el prefiso \"MediaWiki\")''", + "abusefilter-edit-warn-actions": "Asion:", + "abusefilter-edit-warn-preview": "Mostra/Scondi l'anteprima de el mesajo selesionà", "abusefilter-edit-warn-edit": "Crèa/Modìfega el messajo selessionà", + "abusefilter-edit-disallow-preview": "Mostra/scondi l'anteprima del mesajo selesionà", "abusefilter-edit-tag-tag": "Tag da aplicar (uno par riga):", "abusefilter-edit-denied": "No te podi védar i detagli de sto filtro, parché i xe sconti al pùblico.", "abusefilter-edit-main": "Parametri del filtro", @@ -245,13 +252,13 @@ "abusefilter-edit-builder-vars-all-links": "Tuti i colegamenti esterni nel testo novo", "abusefilter-edit-builder-vars-added-links": "Tuti i colegamenti esterni zontà da la modifica", "abusefilter-edit-builder-vars-removed-links": "Tuti i colegamenti esterni cavà da la modifica", - "abusefilter-edit-builder-vars-old-text": "Testo sorxente vecio de la pàxena, prima de la modìfega", - "abusefilter-edit-builder-vars-new-text": "Testo sorxente novo de la pàxena, dopo de la modìfega", - "abusefilter-edit-builder-vars-new-text-stripped": "Testo novo de la pagina, cavando tuto el markup", + "abusefilter-edit-builder-vars-old-wikitext": "Testo sorxente vecio de la pàxena, prima de la modìfega", + "abusefilter-edit-builder-vars-new-wikitext": "Testo sorxente novo de la pàxena, dopo de la modìfega", + "abusefilter-edit-builder-vars-new-text": "Testo novo de la pagina, cavando tuto el markup", "abusefilter-edit-builder-vars-new-html": "Sorxente HTML elaborà de la version nova", "abusefilter-edit-builder-vars-restrictions-edit": "Livèl de protession de la pagina par le modifiche", "abusefilter-edit-builder-vars-restrictions-move": "Livèl de protession de la pagina par i spostamenti", - "abusefilter-edit-builder-vars-old-text-stripped": "Testo vecio de la pagina, cavando tuto el markup", + "abusefilter-edit-builder-vars-old-text": "Testo vecio de la pagina, cavando tuto el markup", "abusefilter-edit-builder-vars-old-links": "Colegamenti in te la pagina, prima de la modifica", "abusefilter-edit-builder-vars-old-html": "Testo sorxente vecio de la pàxena, formatà in HTML", "abusefilter-edit-builder-vars-minor-edit": "Dise se la modifica la xe picenina o no", @@ -260,7 +267,7 @@ "abusefilter-history": "Cronologia de le modifiche al Filtro Abusi n° $1", "abusefilter-history-foruser": "Canbiamenti de $1", "abusefilter-history-hidden": "sconto", - "abusefilter-history-enabled": "Intacà", + "abusefilter-history-enabled": "Ativà", "abusefilter-history-global": "Globale", "abusefilter-history-timestamp": "Data e ora", "abusefilter-history-user": "Utente", @@ -268,7 +275,7 @@ "abusefilter-history-flags": "Flag", "abusefilter-history-filter": "Règola del filtro", "abusefilter-history-comments": "Comenti", - "abusefilter-history-actions": "Azioni", + "abusefilter-history-actions": "Asion", "abusefilter-history-backedit": "Torna indrìo a la modìfega del filtro", "abusefilter-history-deleted": "Scancelà", "abusefilter-history-filterid": "Filtro", @@ -288,11 +295,11 @@ "abusefilter-exception-dividebyzero": "Tentativo de divìdar $2 par xero al caràtere $1.", "abusefilter-exception-unrecognisedvar": "Variàbile $2 mia riconossùa al caràtere $1.", "abusefilter-exception-notenoughargs": "No vien passà argomenti in bisogno a la funsion $2 ciamà al caràtere $1.\nLa se speta $3 {{PLURAL:$3|argomento|argumenti}}, ghe ne riva xo $4.", - "abusefilter-exception-regexfailure": "Eròr al caràtere $1 de l'espression regolare \"$3\": \"$2\"", + "abusefilter-exception-regexfailure": "Eròr al caràtere $1 de l'espression regolare \"$2\".", "abusefilter-exception-overridebuiltin": "Overriding mia valido de la variàbile built-in \"$2\" al caràtere $1.", "abusefilter-exception-outofbounds": "Richiesta de voce inesistente de l'elenco $2 (dimension lista = $3) al caratere $1.", "abusefilter-exception-notarray": "Richiesta de un elemento de array da un non array al caratere $1.", - "abusefilter-action-tag": "Tag", + "abusefilter-action-tag": "Targhete", "abusefilter-action-throttle": "Ralenta", "abusefilter-action-warn": "Avisa", "abusefilter-action-blockautopromote": "Bloca autopromòvi", @@ -304,13 +311,13 @@ "abusefilter-revert-intro": "Sto modulo el consente de anulare tute le modifiche fate dal filtro anti abusi $1.\nDòpara sto strumento con particolare atension.", "abusefilter-revert-preview-item": "$1: $2 el gà fato $3 su $4.\nAzion da anular: $5 ($6)", "abusefilter-revert-search-legend": "Selessiona le azion del filtro abusi da anular", - "abusefilter-revert-periodstart": "Inissio periodo:", + "abusefilter-revert-periodstart": "El periodo el xé tacà:", "abusefilter-revert-periodend": "Fine periodo:", "abusefilter-revert-search": "Selessiona azioni", "abusefilter-revert-filter": "Filtro:", "abusefilter-revert-preview-intro": "Qua ghe xe le azion fate dal filtro anti abusi che vegnarà anulà da st'azion.\nVerifica con cura e struca su \"Conferma\" par confermare la selession.", "abusefilter-revert-confirm": "Conferma", - "abusefilter-revert-success": "Te ghè anulà tute le azion fate dal [[Special:AbuseFilter/$1|filtro anti abusi $2]].", + "abusefilter-revert-success": "Te ghè desfà tute łe asion fate dal [[Special:AbuseFilter/$1|filtro anti abuxi $2]].", "abusefilter-revert-reason": "Anulamento automatico de tute le azion fate dal filtro anti abusi $1.\nMotivo indicà: $2", "abusefilter-revert-reasonfield": "Motivassion de l'anulamento:", "abusefilter-test": "Verifica un filtro confrontandolo co le modifiche precedenti", @@ -320,15 +327,17 @@ "abusefilter-test-submit": "Verifica", "abusefilter-test-load": "Carga", "abusefilter-test-user": "Canbiamenti fati da l'utente:", + "abusefilter-test-nobots": "Scondi ƚe modefeghe de i bot", "abusefilter-test-period-start": "Canbiamenti fati dopo el:", "abusefilter-test-period-end": "Canbiamenti fati prima del:", "abusefilter-test-page": "Canbiamenti fati a la pagina:", "abusefilter-test-shownegative": "Fà védar le modifiche che no corisponde al filtro", "abusefilter-test-syntaxerr": "El filtro inserìo el gà un eror de sintassi.\nStruca su \"Verifica sintassi\" par la spiegassion conpleta.", + "abusefilter-test-search-type-upload": "Cargamenti", "abusefilter-changeslist-examine": "esàmina", "abusefilter-examine": "Esàmina i singoli canbiamenti", "abusefilter-examine-intro": "Sta pagina la consente de esaminare le variabili generà dal filtro anti abusi par na particolare modifica, e de proar el funsionamento dei filtri su de essa.", - "abusefilter-examine-legend": "Selessiona canbiamenti", + "abusefilter-examine-legend": "sełesiona canbiamenti", "abusefilter-examine-diff": "URL de le difarense:", "abusefilter-examine-user": "Utente:", "abusefilter-examine-title": "Titolo de la pàxena:", @@ -343,18 +352,17 @@ "abusefilter-examine-incompatible": "La modifica richiesta no la xe suportada dal filtro abusi.", "abusefilter-examine-noresults": "No xe vegnù fora nissun risultato par i parametri de riserca indicà da ti.", "abusefilter-topnav": "'''Navigassion filtro anti abusi'''", - "abusefilter-topnav-home": "Inissio", + "abusefilter-topnav-home": "Pajina prinçipałe", "abusefilter-topnav-test": "Verifica in batch", "abusefilter-topnav-examine": "Esàmina le modifiche vèce", "abusefilter-topnav-log": "Registro dei abusi", "abusefilter-topnav-tools": "Strumenti de debug", - "abusefilter-topnav-import": "Inporta filtro", "abusefilter-log-name": "Registro del filtro abusi", "abusefilter-log-header": "El registro el mostra un riassunto de le modifiche fate sui filtri.\nPar i detagli completi, varda [[Special:AbuseFilter/history|l'elenco]] de le modifiche pi recenti ai filtri.", - "abusefilter-diff-title": "Difarense tra le version", + "abusefilter-diff-title": "Difarense intra łe version", "abusefilter-diff-item": "Elemento", "abusefilter-diff-version": "Version del $1, fata da $2", - "abusefilter-diff-info": "Informassion de base", + "abusefilter-diff-info": "Informasion de baxe", "abusefilter-diff-pattern": "Condission dei filtri", "abusefilter-diff-invalid": "No se riesse a cargar le version che ti gà domandà", "abusefilter-diff-backhistory": "Torna indrìo a la storia del filtro", diff --git a/AbuseFilter/i18n/vep.json b/AbuseFilter/i18n/vep.json index b5a727bd..99b87a3d 100644 --- a/AbuseFilter/i18n/vep.json +++ b/AbuseFilter/i18n/vep.json @@ -15,6 +15,7 @@ "abusefilter-list-edit": "Redaktiruida", "abusefilter-list-details": "Detalid", "abusefilter-deleted": "Heittud", + "abusefilter-import-button": "Fil'tran import", "abusefilter-list-options": "Opcijad:", "abusefilter-list-options-submit": "Udištada", "abusefilter-tools-reautoconfirm-user": "Kävutai:", @@ -77,7 +78,6 @@ "abusefilter-examine-submit": "Ectä", "abusefilter-examine-test-button": "Kodvda fil'tr", "abusefilter-topnav-home": "Pälehtpolele", - "abusefilter-topnav-import": "Fil'tran import", "abusefilter-diff-title": "Erod versijoiden keskes", "abusefilter-diff-item": "Element", "abusefilter-diff-info": "Päinformacii", diff --git a/AbuseFilter/i18n/vi.json b/AbuseFilter/i18n/vi.json index 3892ed9f..932ae0e6 100644 --- a/AbuseFilter/i18n/vi.json +++ b/AbuseFilter/i18n/vi.json @@ -2,18 +2,23 @@ "@metadata": { "authors": [ "Baonguyen21022003", + "Dinhxuanduyet", + "Ioe2015", + "Matma Rex", "Minh Nguyen", + "Nguyễn Mạnh An", + "Phjtieudoc", + "Trần Nguyễn Minh Huy", "Vinhtantran", "Withoutaname", - "Dinhxuanduyet", - "Trần Nguyễn Minh Huy", - "Matma Rex" + "Đỗ Thảo" ] }, "abusefilter-desc": "Áp dụng heuristic tự động vào các sửa đổi", - "abusefilter": "Thiết lập bộ lọc sai phạm", - "abuselog": "Nhật trình sai phạm", + "abusefilter": "Quản lý bộ lọc sai phạm", + "abuselog": "Nhật trình bộ lọc sai phạm", "abusefilter-intro": "Hoan nghênh bạn đã và trang quản lý Bộ lọc sai phạm.\nBộ lọc sai phạm là chức năng phần mềm để tự động xử lý các tác vụ trang theo điều kiện.\nTrang này có danh sách bộ lọc định trước để cấu hình.", + "abusefilter-mustviewprivateoredit": "Vì lý do bảo mật, chỉ những người dùng có quyền xem các bộ lọc lạm dụng riêng tư hoặc sửa đổi các bộ lọc mới có thể sử dụng giao diện này.", "abusefilter-warning": "'''Cảnh báo''': Tác vụ này đã được tự động xác định là nguy hại.\nNhững tác vụ không có tính xây dựng sẽ nhanh chóng bị hồi lại,\nvà sửa đổi không có tính xây dựng xảy ra thường xuyên và liên tục sẽ dẫn đến việc cấm tài khoản hoặc địa chỉ IP của bạn.\nNếu bạn tin rằng tác vụ này là có tính xây dựng, bạn có thể lưu trang một lần nữa để xác nhận điều đó.\nMiêu tả ngắn về quy định nguy hại mà tác vụ của bạn gặp phải là: $1", "abusefilter-disallowed": "Tác vụ này đã được tự động xác định là nguy hại,\nvà do đó không được phép thực hiện.\nNếu bạn tin rằng tác vụ của bạn là có tính xây dựng, xin hãy liên hệ với một bảo quản viên, và thông báo cho họ về những điều bạn đang cố gắng làm.\nMiêu tả ngắn về quy định nguy hại mà tác vụ của bạn gặp phải là: $1", "abusefilter-blocked-display": "Tác vụ này đã được tự động xác định là nguy hại,\nvà bị ngăn không cho bạn thực hiện nó.\nNgoài ra, để bảo vệ {{PAGENAME}}, tài khoản cá nhân của bạn và tất cả các địa chỉ IP đi cùng với nó đã bị cấm sửa đổi.\nNếu điều này xảy ra do nhầm lẫn, xin hãy liên hệ với một bảo quản viên.\nMiêu tả ngắn về quy định nguy hại mà tác vụ của bạn gặp phải là: $1", @@ -22,12 +27,14 @@ "abusefilter-blocker": "Bộ lọc sai phạm", "abusefilter-blockreason": "Bị bộ lọc sai phạm tự động cấm. Mô tả về quy định liên quan: $1", "abusefilter-degroupreason": "Quyền hạn đã bị bộ lọc sai phạm tự động tước bỏ. Mô tả quy định: $1", + "abusefilter-blockautopromotereason": "Quyền hạn đã bị bộ lọc sai phạm tự động tước bỏ. \nMô tả quy định: $1", "abusefilter-accountreserved": "Tên tài khoản này được bộ lọc sai phạm bảo lưu để sử dụng.", - "right-abusefilter-modify": "Sửa đổi bộ lọc sai phạm", + "right-abusefilter-modify": "Tạo hoặc sửa đổi các bộ lọc sai phạm", "right-abusefilter-view": "Xem bộ lọc sai phạm", "right-abusefilter-log": "Xem nhật trình sai phạm", "right-abusefilter-log-detail": "Xem chi tiết các mục nhật trình sai phạm", - "right-abusefilter-private": "Xem dữ liệu riêng tư trong nhật trình sai phạm", + "right-abusefilter-privatedetails": "Xem dữ liệu riêng tư trong nhật trình sai phạm", + "right-abusefilter-privatedetails-log": "Xem nhật ký truy cập chi tiết riêng tư của AbuseFilter", "right-abusefilter-modify-restricted": "Sửa đổi bộ lọc sai phạm có hành vi bị hạn chế", "right-abusefilter-revert": "Hồi lại tất cả thay đổi theo một bộ lọc vi phạm cho trước", "right-abusefilter-view-private": "Xem những bộ lọc phá hoại được đánh dấu riêng tư", @@ -39,22 +46,35 @@ "action-abusefilter-view": "xem bộ lọc sai phạm", "action-abusefilter-log": "xem nhật trình sai phạm", "action-abusefilter-log-detail": "xem các chi tiết của nhật trình sai phạm", - "action-abusefilter-private": "xem dữ liệu cá nhân trong nhật trình sai phạm", + "action-abusefilter-privatedetails": "xem dữ liệu cá nhân trong nhật trình sai phạm", + "action-abusefilter-privatedetails-log": "xem nhật ký truy cập chi tiết riêng tư của AbuseFilter", "action-abusefilter-modify-restricted": "sửa đổi bộ lọc sai phạm có hành vi bị hạn chế", "action-abusefilter-revert": "lùi sửa thay đổi dùng bộ lọc sai phạm", "action-abusefilter-view-private": "xem bộ lọc phá hoại được đánh dấu riêng tư", "action-abusefilter-log-private": "xem mục nhật trình của các bộ lọc sai phạm riêng", - "abusefilter-log": "Nhật trình bộ lọc sai phạm", + "action-abusefilter-hide-log": "ẩn các mục trong nhật ký lạm dụng", + "action-abusefilter-hidden-log": "xem các mục ẩn trong nhật ký lạm dụng", + "action-abusefilter-modify-global": "tạo hoặc sửa đổi các bộ lọc lạm dụng toàn cầu", "abusefilter-log-summary": "Nhật trình này liệt kê các tác vụ gây ra bộ lọc.", "abusefilter-log-search": "Tìm trong nhật trình sai phạm", "abusefilter-log-search-user": "Người dùng:", + "abusefilter-log-search-group": "Nhóm bộ lọc:", + "abusefilter-log-search-group-any": "Bất kì", "abusefilter-log-search-filter": "Số bộ lọc (phân cách bằng dấu sổ thẳng):", "abusefilter-log-search-title": "Tựa đề:", "abusefilter-log-search-wiki": "Wiki:", + "abusefilter-log-search-impact-all": "Tất cả hành động", + "abusefilter-log-search-impact-saved": "Chỉ lưu thay đổi", + "abusefilter-log-search-impact-not-saved": "Không lưu thay đổi", "abusefilter-log-search-entries-label": "Mức độ truy cập:", "abusefilter-log-search-entries-all": "Tất cả các mục", "abusefilter-log-search-entries-hidden": "Chỉ mục ẩn", "abusefilter-log-search-entries-visible": "Chỉ mục xem được", + "abusefilter-log-search-action-label": "Hành động kích hoạt:", + "abusefilter-log-search-action-other": "Khác", + "abusefilter-log-search-action-any": "Bất kì", + "abusefilter-log-search-action-taken-label": "Hành động:", + "abusefilter-log-search-action-taken-any": "Bất kì", "abusefilter-log-search-submit": "Tìm kiếm", "abusefilter-log-entry": "$1: $2 đã kích hoạt bộ lọc sai phạm, {{GENDER:$8}}thực hiện tác động “$3” vào lúc $4. Tác vụ diễn ra: $5; Miêu tả bộ lọc: $6", "abusefilter-log-entry-withdiff": "$1: $2 đã kích hoạt bộ lọc sai phạm, {{GENDER:$8}}thực hiện tác động “$3” vào lúc $4.\nTác vụ diễn ra: $5;\nMiêu tả bộ lọc: $6 ($7)", @@ -68,27 +88,39 @@ "abusefilter-log-details-var": "Biến", "abusefilter-log-details-val": "Giá trị", "abusefilter-log-details-vars": "Tham số tác vụ", - "abusefilter-log-details-private": "Dữ liệu riêng tư", + "abusefilter-log-details-privatedetails": "Dữ liệu riêng tư", "abusefilter-log-details-ip": "Địa chỉ IP gốc", + "abusefilter-log-details-checkuser": "Kiểm định người dùng", "abusefilter-log-noactions": "không", + "abusefilter-log-noactions-filter": "Không có", "abusefilter-log-details-diff": "Các thay đổi trong phiên sửa đổi", "abusefilter-log-linkoncontribs": "nhật trình sai phạm", "abusefilter-log-linkoncontribs-text": "Nhật trình sai phạm của {{GENDER:$1}}người dùng", - "abusefilter-log-hidden": "(mục ẩn)", + "abusefilter-log-linkonhistory": "xem nhật trình sai phạm", + "abusefilter-log-linkonhistory-text": "Xem nhật ký lạm dụng cho trang này", + "abusefilter-log-linkonundelete": "xem nhật trình sai phạm", + "abusefilter-log-linkonundelete-text": "Xem nhật ký lạm dụng cho trang này", "abusefilter-log-hidden-implicit": "(ẩn vì phiên bản đã bị xóa)", "abusefilter-log-cannot-see-details": "Bạn không có quyền xem chi tiết của mục này.", + "abusefilter-log-cannot-see-privatedetails": "Bạn không có quyền xem chi tiết riêng tư của mục này.", "abusefilter-log-nonexistent": "Không có mục với ID được cung cấp.", "abusefilter-log-details-hidden": "Bạn không có quyền xem chi tiết mục ẩn này.", + "abusefilter-log-details-hidden-implicit": "Bạn không thể xem chi tiết cho mục này vì sửa đổi liên quan của nó bị ẩn khỏi chế độ xem công khai.", "abusefilter-log-private-not-included": "Bạn đã định rõ số bộ lọc riêng tư. Vì bạn không có quyền xem các chi tiết của bộ lọc riêng tư, những kết quả riêng tư nào đó sẽ không được hiển thị.", "abusefilter-log-hide-legend": "Ẩn mục nhật trình", "abusefilter-log-hide-id": "ID của mục nhật trình:", "abusefilter-log-hide-hidden": "Ẩn mục này khỏi công cộng", "abusefilter-log-hide-reason": "Lý do:", + "abusefilter-log-hide-reason-other": "\nLý do khác/bổ sung:", "abusefilter-log-hide-forbidden": "Bạn không có quyền ẩn mục trong nhật trình sai phạm.", + "abusefilter-log-entry-unsuppress": "{{GENDER:$2|}}$1 {{GENDER:$2}}đã tải lên $3", "logentry-abusefilter-hit": "$1 {{GENDER:$2}}gây $4 khi thực hiện tác vụ “$5” tại $3, bộ lọc gây ra các tác vụ: $6 ($7)", - "abusefilter-management": "Quản lý bộ lọc sai phạm", + "log-action-filter-abusefilter-create": "Tạo bộ lọc mới", + "log-action-filter-abusefilter-modify": "Sửa đổi bộ lọc", + "abusefilterprivatedetails-log-name": "Nhật ký truy cập chi tiết riêng tư của AbuseFilter", "abusefilter-list": "Các bộ lọc", "abusefilter-list-id": "ID bộ lọc", + "abusefilter-list-pattern": "Mẫu", "abusefilter-list-status": "Trạng thái", "abusefilter-list-public": "Mô tả công khai", "abusefilter-list-consequences": "Hậu quả", @@ -106,6 +138,7 @@ "abusefilter-disabled": "Tắt kích hoạt", "abusefilter-hitcount": "$1 lần gặp", "abusefilter-new": "Tạo bộ lọc mới", + "abusefilter-import-button": "Nhập bộ lọc", "abusefilter-return": "Trở lại quản lý bộ lọc", "abusefilter-status-global": "Toàn bộ", "abusefilter-list-options": "Tùy chọn", @@ -118,6 +151,10 @@ "abusefilter-list-options-scope-global": "Chỉ các quy định toàn cục", "abusefilter-list-options-scope-all": "Quy tắc địa phương và toàn cục", "abusefilter-list-options-hidedisabled": "Ẩn bộ lọc đã tắt", + "abusefilter-list-options-searchoptions": "Chế độ tìm kiếm:", + "abusefilter-list-options-search-like": "Truy vấn đơn thuần", + "abusefilter-list-options-search-rlike": "Biểu thức chính quy", + "abusefilter-list-regexerror": "Một lỗi đã xảy ra trong khi tìm kiếm: Lỗi cú pháp biểu thức chính quy.", "abusefilter-list-options-submit": "Cập nhật", "abusefilter-tools-text": "Dưới đây là một số công cụ có thể hữu ích trong việc công thức hóa và gỡ rối các bộ lọc sai phạm.", "abusefilter-tools-expr": "Bộ kiểm thử biểu thức", @@ -135,11 +172,12 @@ "abusefilter-edit-oldwarning": "<strong>Bạn đang sửa một phiên bản cũ của bộ lọc này. Thống kê được trích ở trên là cho phiên bản mới nhất của bộ lọc. Nếu bạn lưu sửa đổi, bạn sẽ hi đè lên tất cả các thay đổi được thực hiện sau phiên bản mà bạn đang sửa.</strong> • [[Special:AbuseFilter/history/$2|Trở lại lịch sử bộ lọc]]", "abusefilter-edit-status-label": "Thống kê:", "abusefilter-edit-status": "Trong số $1 tác vụ cuối cùng, bộ lọc này đã so trùng được $2 tác vụ ($3%).", - "abusefilter-edit-status-profile": "Trong vòng $1 {{PLURAL:$1|tác vụ|tác vụ}} cuối, bộ lọc này đã so trùng được $2 tác vụ ($3%).\nThời gian chạy trung bình là $4ms, và sử dụng $5 {{PLURAL:$5||}} điều kiện trong giới hạn các điều kiện.", "abusefilter-edit-new": "Bộ lọc mới", "abusefilter-edit-save": "Lưu bộ lọc", "abusefilter-edit-id": "ID bộ lọc:", + "abusefilter-edit-switch-editor": "Chuyển chế độ sửa đổi", "abusefilter-edit-description": "Mô tả:\n:''(xem được công khai)''", + "abusefilter-edit-field-description": "miêu tả", "abusefilter-edit-group": "Nhóm bộ lọc:", "abusefilter-edit-flags": "Cờ:", "abusefilter-edit-enabled": "Kích hoạt bộ lọc này", @@ -163,12 +201,24 @@ "abusefilter-edit-throttle-count": "Số tác vụ cho phép:", "abusefilter-edit-throttle-period": "Thời gian:", "abusefilter-edit-throttle-groups": "Chặn nhóm theo:\n:''(mỗi nhóm 1 dòng, kết hợp với dấu phẩy)''", + "abusefilter-edit-throttle-groups-help": "Xem $1.", + "abusefilter-throttle-ip": "Địa chỉ IP", + "abusefilter-throttle-user": "tài khoản thành viên", + "abusefilter-throttle-editcount": "số lần sửa đổi", + "abusefilter-throttle-site": "toàn bộ trang", + "abusefilter-throttle-page": "trang", + "abusefilter-throttle-none": "(không có)", "abusefilter-edit-warn-message": "Thông báo hệ thống dùng để cảnh báo:", "abusefilter-edit-warn-other": "Thông điệp khác", - "abusefilter-edit-warn-other-label": "Tên trang của thông điệp khác:\n:''(không có tiền tố MediaWiki)''", + "abusefilter-edit-warn-other-label": "Tên trang của thông điệp khác:\n:''(không bao gồm tiền tố \"MediaWiki:\")''", "abusefilter-edit-warn-actions": "Tác vụ:", "abusefilter-edit-warn-preview": "Xem trước thông điệp được chọn", "abusefilter-edit-warn-edit": "Tạo/Sửa thông điệp được chọn", + "abusefilter-edit-disallow-other": "Tin nhắn khác", + "abusefilter-edit-disallow-other-label": "Tên trang của thông điệp khác:\n:''(không bao gồm tiền tố \"MediaWiki:\")''", + "abusefilter-edit-disallow-actions": "Hành động", + "abusefilter-edit-disallow-preview": "Hiện/Ẩn xem trước của thông điệp được chọn", + "abusefilter-edit-disallow-edit": "Tạo/Sửa đổi thông điệp được chọn", "abusefilter-edit-tag-tag": "[[Special:Tags|Các thẻ]] để áp dụng (mỗi thẻ một dòng):", "abusefilter-edit-denied": "Bạn không có quyền xem thông tin chi tiết của bộ lọc này, bởi vì nó được ẩn khỏi công chúng.", "abusefilter-edit-main": "Tham số bộ lọc", @@ -199,8 +249,8 @@ "abusefilter-edit-builder-op-arithmetic-modulo": "Môđulô (%)", "abusefilter-edit-builder-op-arithmetic-pow": "Lũy thừa (**)", "abusefilter-edit-builder-group-op-comparison": "Toán tử so sánh", - "abusefilter-edit-builder-op-comparison-equal": "Bằng (==)", - "abusefilter-edit-builder-op-comparison-notequal": "Không bằng (!=)", + "abusefilter-edit-builder-op-comparison-equal": "Giá trị bằng (==)", + "abusefilter-edit-builder-op-comparison-notequal": "Giá trị không bằng (!=)", "abusefilter-edit-builder-op-comparison-lt": "Ít hơn (<)", "abusefilter-edit-builder-op-comparison-gt": "Nhiều hơn (>)", "abusefilter-edit-builder-op-comparison-lte": "Ít hơn hay bằng (<=)", @@ -274,18 +324,18 @@ "abusefilter-edit-builder-vars-all-links": "Tất cả các liên kết ngoài trong nội dung mới thêm vào", "abusefilter-edit-builder-vars-added-links": "Tất cả các liên kết ngoài được thêm trong sửa đổi", "abusefilter-edit-builder-vars-removed-links": "Tất cả các liên kết ngoài bị xóa trong sửa đổi", - "abusefilter-edit-builder-vars-old-text": "Mã wiki cũ của trang, trước khi sửa đổi", - "abusefilter-edit-builder-vars-new-text": "Mã wiki mới của trang, sau khi sửa đổi", + "abusefilter-edit-builder-vars-old-wikitext": "Mã wiki cũ của trang, trước khi sửa đổi", + "abusefilter-edit-builder-vars-new-wikitext": "Mã wiki mới của trang, sau khi sửa đổi", "abusefilter-edit-builder-vars-new-pst": "Mã wiki của trang mới ở dạng chuyển đổi trước khi lưu", "abusefilter-edit-builder-vars-diff-pst": "Khác biệt thống nhất trong sửa đổi ở dạng chuyển đổi trước khi lưu", "abusefilter-edit-builder-vars-addedlines-pst": "Số dòng được thêm trong sửa đổi ở dạng chuyển đổi trước khi lưu", - "abusefilter-edit-builder-vars-new-text-stripped": "Nội dung mới của trang, bỏ các mã đánh dấu", + "abusefilter-edit-builder-vars-new-text": "Nội dung mới của trang, bỏ các mã đánh dấu", "abusefilter-edit-builder-vars-new-html": "Phân tích mã HTML của phiên bản mới", "abusefilter-edit-builder-vars-restrictions-edit": "Mức khóa sửa đổi của trang", "abusefilter-edit-builder-vars-restrictions-move": "Mức khóa di chuyển của trang", "abusefilter-edit-builder-vars-restrictions-create": "Mức khóa tạo của trang", "abusefilter-edit-builder-vars-restrictions-upload": "Mức khóa tải lên của tập tin", - "abusefilter-edit-builder-vars-old-text-stripped": "Văn bản cũ của trang, trừ mã đánh dấu", + "abusefilter-edit-builder-vars-old-text": "Văn bản cũ của trang, trừ mã đánh dấu", "abusefilter-edit-builder-vars-old-links": "Các liên kết trong trang trước khi sửa đổi", "abusefilter-edit-builder-vars-old-html": "Mã wiki cũ của trang, được xử lý thành HTML", "abusefilter-edit-builder-vars-minor-edit": "Có gọi sửa đổi nhỏ hay không", @@ -296,7 +346,7 @@ "abusefilter-edit-builder-vars-file-width": "Chiều rộng của tập tin bằng điểm ảnh", "abusefilter-edit-builder-vars-file-height": "Chiều cao của tập tin bằng điểm ảnh", "abusefilter-edit-builder-vars-file-bits-per-channel": "Số bit trên kênh màu của tập tin", - "abusefilter-filter-log": "Các thay đổi bộ lọc gần đây", + "abusefilter-filter-log": "Thay đổi bộ lọc gần đây", "abusefilter-history": "Lịch sử các thay đổi của Bộ Lọc Vi Phạm $1", "abusefilter-history-foruser": "Thay đổi bởi $1", "abusefilter-history-hidden": "ẩn", @@ -314,8 +364,9 @@ "abusefilter-history-filterid": "Bộ lọc", "abusefilter-history-select-legend": "Tinh lọc tìm kiếm", "abusefilter-history-select-user": "Thành viên:", + "abusefilter-history-select-filter": "ID bộ lọc:", "abusefilter-history-select-submit": "Tinh lọc", - "abusefilter-history-diff": "Các thay đổi", + "abusefilter-history-diff": "Thay đổi", "abusefilter-history-error-hidden": "Bạn đã yêu cầu một bộ lọc ẩn, nên không thể xem lịch sử của nó.", "abusefilter-exception-unexpectedatend": "“$2” không mong đợi ở ký tự $1.", "abusefilter-exception-expectednotfound": "Tìm thấy $3 ở ký tự $4 thay vì $2 ở $1.", @@ -328,10 +379,11 @@ "abusefilter-exception-dividebyzero": "Chia $2 cho zero tại ký tự $1.", "abusefilter-exception-unrecognisedvar": "Không hiểu biến $2 tại ký tự $1", "abusefilter-exception-notenoughargs": "Không có đủ tham số khi gọi hàm $2 tại ký tự $1.\nCần $3 tham số, trong khi chỉ tìm thấy $4.", - "abusefilter-exception-regexfailure": "Lỗi trong biểu thức chính quy “$3” tại ký tự $1: “$2”", + "abusefilter-exception-regexfailure": "Lỗi trong biểu thức chính quy “$2” tại ký tự $1.", "abusefilter-exception-overridebuiltin": "Đè lên biến số phần mềm “$2” một cách bất hợp lệ tại ký tự $1.", "abusefilter-exception-outofbounds": "Yêu cầu khoản danh sách thứ $2 không tồn tại (chỉ co $3 khoản) tại ký tự $1.", "abusefilter-exception-notarray": "Yêu cầu khoản mảng từ cấu trúc không phải mảng tại ký tự $1.", + "abusefilter-exception-invalidiprange": "Vùng IP \"$2\" được cung cấp bởi kí tự $1 không hợp lệ.", "abusefilter-action-tag": "Thẻ", "abusefilter-action-throttle": "Thắt cổ chai", "abusefilter-action-warn": "Cảnh báo", @@ -347,8 +399,9 @@ "abusefilter-revert-periodstart": "Thời điểm bắt đầu:", "abusefilter-revert-periodend": "Thời điểm kết thúc:", "abusefilter-revert-search": "Chọn tác vụ", - "abusefilter-revert-filter": "Bộ lọc:", + "abusefilter-revert-filter": "ID bộ lọc:", "abusefilter-revert-preview-intro": "Dưới đây là các tác vụ do bộ lọc vi phạm thực hiện sẽ được hồi lại theo tác vụ này.\nXin hãy kiểm tra lại chúng kỹ lưỡng, và nhấn “{{int:abusefilter-revert-confirm}}” để xác nhận sự lựa chọn của bạn.", + "abusefilter-revert-confirm-legend": "Xác nhận lùi sửa", "abusefilter-revert-confirm": "Xác nhận", "abusefilter-revert-success": "Bạn đã hồi tất cả các tác vụ của bộ lọc vi phạm vì [[Special:AbuseFilter/$1|bộ lọc $2]].", "abusefilter-revert-reason": "Hồi tự động tất cả các tác vụ do bộ lọc vi phạm thực hiện do bộ lọc $1.\nLý do: $2", @@ -360,12 +413,20 @@ "abusefilter-test-submit": "Kiểm thử", "abusefilter-test-load": "Tải", "abusefilter-test-user": "Thay đổi của thành viên:", + "abusefilter-test-nobots": "Ẩn sửa đổi bot", "abusefilter-test-period-start": "Thay đổi thực hiện sau:", "abusefilter-test-period-end": "Thay đổi thực hiện trước:", "abusefilter-test-page": "Các thay đổi tại trang:", "abusefilter-test-shownegative": "Hiển thị thay đổi không trùng với bộ lọc", "abusefilter-test-syntaxerr": "Bộ lọc được nhập vào có lỗi cú pháp. Hãy bấm nút “{{int:abusefilter-edit-check}}” để đọc chi tiết đầy đủ.", "abusefilter-test-badtitle": "Bạn đã nhập một tên trang không hợp lệ. Nó có thể có những ký tự không thể dùng trong tên trang.", + "abusefilter-test-action": "Loại hành động:", + "abusefilter-test-search-type-all": "Tất cả hành động", + "abusefilter-test-search-type-edit": "Sửa đổi", + "abusefilter-test-search-type-move": "Di chuyển", + "abusefilter-test-search-type-delete": "Xoá bài", + "abusefilter-test-search-type-upload": "Tải lên", + "abusefilter-test-search-type-createaccount": "Mở tài khoản", "abusefilter-changeslist-examine": "kiểm tra", "abusefilter-examine": "Kiểm tra từng thay đổi một", "abusefilter-examine-intro": "Trang này cho phép bạn kiểm tra các biến do Bộ lọc Vi phạm tạo ra đối với từng thay đổi cụ thể, và kiểm thử nó với các bộ lọc.", @@ -385,13 +446,14 @@ "abusefilter-examine-noresults": "Không tìm thấy kết quả hợp các tham số tìm kiếm được cho vào.", "abusefilter-topnav": "'''Điều hướng Bộ lọc sai phạm'''", "abusefilter-topnav-home": "Trang đầu", + "abusefilter-topnav-recentchanges": "Thay đổi bộ lọc gần đây", "abusefilter-topnav-test": "Thử hàng loạt", "abusefilter-topnav-examine": "Kiểm tra các sửa đổi về trước", "abusefilter-topnav-log": "Nhật trình sai phạm", "abusefilter-topnav-tools": "Công cụ gỡ rối", - "abusefilter-topnav-import": "Nhập bộ lọc", "abusefilter-log-name": "Nhật trình bộ lọc sai phạm", "abusefilter-log-header": "Nhật trình này tóm lại các thay đổi bộ lọc. Hãy xem các chi tiết đầy đủ trong danh sách các [[Special:AbuseFilter/history|thay đổi bộ lọc gần đây]].", + "abusefilter-logentry-create": "$1 {{GENDER:$2|đã tạo}} $4 ($5)", "abusefilter-logentry-modify": "$1 {{GENDER:$2}}đã thay đổi $4 ($5)", "abusefilter-log-noresults": "Không có kết quả", "abusefilter-diff-title": "Khác biệt giữa các phiên bản", @@ -406,5 +468,6 @@ "abusefilter-import-intro": "Trang này để nhập bộ lọc từ wiki khác.\nTại trang sửa đổi của wiki nguồn, hãy bấm “{{int:abusefilter-edit-export}}” dưới đề mục “{{int:abusefilter-edit-tools}}”.\nSau đó, chép văn bản từ hộp sẽ hiện ra, dán nó vào hộp ở đây, và bấm “{{int:abusefilter-import-submit}}”.", "abusefilter-import-submit": "Nhập dữ liệu", "abusefilter-group-default": "Mặc định", - "abusefilter-http-error": "Đã xuất hiện lỗi HTTP: $1." + "abusefilter-http-error": "Đã xuất hiện lỗi HTTP: $1.", + "abusefilter-log-details-id": "ID nhật trình" } diff --git a/AbuseFilter/i18n/war.json b/AbuseFilter/i18n/war.json index 46fe0a90..908ee863 100644 --- a/AbuseFilter/i18n/war.json +++ b/AbuseFilter/i18n/war.json @@ -1,15 +1,17 @@ { "@metadata": { "authors": [ + "Harvzsf", "JinJian" ] }, + "abuselog": "talaan hin panara hin abusado", "abusefilter-blocker": "Panara hin abusado", "abusefilter-accountreserved": "Ini nga ngaran hin akawnt in nakareserba ha paggamit hiton panara hin abusado.", "right-abusefilter-modify": "Igliwan an mga panara hin abusado", "right-abusefilter-view": "Igpakita an mga panara hin abusado", "right-abusefilter-log": "Kitaa an talaan han abusado", - "right-abusefilter-private": "Kitaa an pribado nga datos han talaan han abusado", + "right-abusefilter-privatedetails": "Kitaa an pribado nga datos han talaan han abusado", "right-abusefilter-view-private": "Kita an mga panara hin abusado ngan markaha komo pribado", "right-abusefilter-log-private": "Kitaa an mga ginsulod ha talaan han mga panara hin abusado ngan markahi komo pribado", "right-abusefilter-hide-log": "Igtago an mga iginsulod ha talaan hin abusado", @@ -19,15 +21,14 @@ "action-abusefilter-view": "kitaa an mga panara hin abusado", "action-abusefilter-log": "kitaa an talaan hin abusado", "action-abusefilter-log-detail": "kitaa an detalyado nga mga iginbutang ha talaan hin abusado", - "action-abusefilter-private": "kitaa an pribado nga datos ha talaan hin abusado", + "action-abusefilter-privatedetails": "kitaa an pribado nga datos ha talaan hin abusado", "action-abusefilter-modify-restricted": "igliwan an mga panara hin abusado hin mga restriktado nga buruhaton", "action-abusefilter-revert": "igbalik an ngatanan nga mga pagbag-o hin uska ginhatag nga panara hin abusado", "action-abusefilter-view-private": "kitaa an mga panara hin abusado nga ginmarkahan komo pribado", - "abusefilter-log": "talaan hin panara hin abusado", "abusefilter-log-summary": "Ini nga talaan in nagpapakita hin lista han ngatanan nga mga ginbuhat nga nadakpan han mga panara.", "abusefilter-log-search": "Pamilnga ha talaan hin abusado", "abusefilter-log-search-user": "Gumaramit:", - "abusefilter-log-search-filter": "Mga ID hit panara (nakabulag pinaagi hin mga patukdaw nga bagis):", + "abusefilter-log-search-filter": "Mga ID hit panara:", "abusefilter-log-search-title": "Titulo:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-submit": "Pamilnga", @@ -35,7 +36,7 @@ "abusefilter-log-detailedentry-local": "panara $1", "abusefilter-log-detailslink": "mga detalye", "abusefilter-log-diff": "kaibhan", - "abusefilter-log-details-private": "Pribado nga datos", + "abusefilter-log-details-privatedetails": "Pribado nga detalye hin talaan", "abusefilter-log-details-ip": "Gintikangan nga IP address", "abusefilter-log-noactions": "Waray", "abusefilter-log-linkoncontribs": "log han pag-abuso", @@ -59,8 +60,8 @@ "abusefilter-list-options-deleted-only": "Igpakita la an mga ginpara nga panara", "abusefilter-list-options-deleted-hide": "Igtago an mga ginpara nga panara", "abusefilter-list-options-deleted-show": "Iglakip an mga ginpara nga panara", - "abusefilter-list-options-scope": "Igpakita an mga panara tikang:", - "abusefilter-list-options-scope-local": "Lokal nga wiki", + "abusefilter-list-options-scope": "Igpakita an mga panara:", + "abusefilter-list-options-scope-local": "Lokal nga mga panurundon là", "abusefilter-list-options-hidedisabled": "Igtago an mga ginparong nga mga panara", "abusefilter-list-options-submit": "Igpayana", "abusefilter-tools-reautoconfirm-user": "Gumaramit:", @@ -72,8 +73,8 @@ "abusefilter-edit-builder-op-arithmetic-multiplication": "Pagpilo-pilo (*)", "abusefilter-edit-builder-op-arithmetic-divide": "Pagtunga-tunga (/)", "abusefilter-edit-builder-op-arithmetic-modulo": "Modulo (%)", - "abusefilter-edit-builder-op-comparison-equal": "Pareho ha (==)", - "abusefilter-edit-builder-op-comparison-notequal": "Diri pareho ha (!=)", + "abusefilter-edit-builder-op-comparison-equal": "Balor pareho ha (==)", + "abusefilter-edit-builder-op-comparison-notequal": "Balor diri pareho ha (!=)", "abusefilter-edit-builder-op-comparison-lt": "ubos ha (<)", "abusefilter-edit-builder-op-comparison-gt": "Labaw ha (>)", "abusefilter-edit-builder-op-comparison-lte": "Ubos ha o pareho ha (<=)", diff --git a/AbuseFilter/i18n/wuu.json b/AbuseFilter/i18n/wuu.json index cb463715..4b69c30b 100644 --- a/AbuseFilter/i18n/wuu.json +++ b/AbuseFilter/i18n/wuu.json @@ -6,10 +6,12 @@ }, "abusefilter-warning": "'''警告:'''侬个行为畀自动识别为有危害性。呒不意义个操作会畀马上恢复,而过分或者重复个无意义编辑会让侬个账号或IP地址畀查封。如果侬确定本次操作有意义,侬可以再次提交确认。搭侬个操作匹配个过滤规则是:$1", "abusefilter-disallowed": "侬个行为畀自动识别为有害操作并畀禁止。如果侬认为该次编辑是有建设性个,请拿侬要做个事体告诉管理员。搭侬本次行为匹配个过滤规则是:$1", + "abusefilter-blockautopromotereason": "自动提升畀滥用过滤器自动延迟。规则说明:$1", "abusefilter-log-entry": "$1:$2来勒$4{{GENDER:$8|执行}}操作“$3”辰光{{GENDER:$8|触发着}}过滤器。采取个动作:$5;过滤器说明:$6", "abusefilter-log-entry-withdiff": "$1:$2来勒$4{{GENDER:$8|执行}}操作“$3”辰光触发着过滤器。采取个动作:$5;过滤器说明:$6($7)", "abusefilter-log-detailedentry-meta": "$1:$2来勒$5{{GENDER:$9|执行}}操作“$4”辰光触发着$3。采取个动作:$6;过滤器说明:$7($8)", "abusefilter-log-hide-reason": "理由:", + "logentry-rights-blockautopromote": "$1{{GENDER:$2|封锁}}{{GENDER:$4|$3}}$5内个自动提升", "abusefilter-hidden": "私密", "abusefilter-unhidden": "公开", "abusefilter-hitcount": "$1趟触发" diff --git a/AbuseFilter/i18n/xmf.json b/AbuseFilter/i18n/xmf.json index 730adca6..5ce59053 100644 --- a/AbuseFilter/i18n/xmf.json +++ b/AbuseFilter/i18n/xmf.json @@ -4,6 +4,7 @@ "David1010" ] }, + "abusefilter": "ბოროტად გამოყენების ფილტრის მართვა", "abusefilter-log-search-user": "მახვარებუეფი:", "abusefilter-log-search-filter": "ფილტრის ID (ვერტიკალური ხაზით გაყოფილი):", "abusefilter-log-search-title": "სათაური:", @@ -16,13 +17,12 @@ "abusefilter-log-hidelink": "ხილვადობის დაყენება", "abusefilter-log-details-var": "ცვალებადი", "abusefilter-log-details-val": "მნიშვნელობა", - "abusefilter-log-details-private": "კერძო მონაცემი", + "abusefilter-log-details-privatedetails": "კერძო მონაცემი", "abusefilter-log-details-ip": "გამავალი IP მისამართი", "abusefilter-log-noactions": "არცერთი", "abusefilter-log-details-diff": "რედაქტირებისას განხორციელებული ცვლილებები", "abusefilter-log-linkoncontribs": "ბოროტად გამოყენების ჟურნალი", "abusefilter-log-linkoncontribs-text": "ბოროტად გამოყენების ფილტრის ჟურნალი ამ მომხმარებლისათვის", - "abusefilter-log-hidden": "(ცვლილება დამალულია)", "abusefilter-log-hidden-implicit": "(დამალულია, რადგან შესწორება წაიშალა)", "abusefilter-log-cannot-see-details": "თქვენ არ გაქვთ ამ ჩანაწერის დეტალური ინფორმაციის ხილვის უფლება.", "abusefilter-log-details-hidden": "თქვენ ვერ იხილავთ დამატებით ინფორმაციას ამ ფილტრის შესახებ, რადგანაც ის დამალულია ჩვეულებრივი მომხმარებლებისთვის.", @@ -31,7 +31,6 @@ "abusefilter-log-hide-hidden": "ამ ცვლილების დამალვა საზოგადოებისათვის", "abusefilter-log-hide-reason": "სამანჯელი:", "abusefilter-log-hide-forbidden": "თქვენ ბოროტად გამოყენების ფილტრის ჟურნალის ჩანაწერების დამალვის უფლება არა გაქვთ.", - "abusefilter-management": "ბოროტად გამოყენების ფილტრის მართვა", "abusefilter-list": "ყველა ფილტრი", "abusefilter-list-id": "ფილტრის ID", "abusefilter-list-status": "სტატუსი", diff --git a/AbuseFilter/i18n/yi.json b/AbuseFilter/i18n/yi.json index d90288a1..bded723d 100644 --- a/AbuseFilter/i18n/yi.json +++ b/AbuseFilter/i18n/yi.json @@ -1,17 +1,17 @@ { "@metadata": { "authors": [ - "Imre", - "פוילישער", - "පසිඳු කාවින්ද", "Har-wradim", + "Imre", + "Jiddisch", "Matma Rex", - "Jiddisch" + "פוילישער", + "පසිඳු කාවින්ද" ] }, "abusefilter-desc": "ווענדט אויטאמאטישע הייריסטיק צו רעדאקטירונגען", - "abusefilter": "שלעכט־באניצן פילטער קאנפיגוראציע", - "abuselog": "שלעכט־באניצן לאג", + "abusefilter": "שעדיקונג־פילטער פארוואלטונג", + "abuselog": "פֿילטער לאגבוך", "abusefilter-warning": "'''ווארענונג''': די פעולה איז געווארן אויטאמאַטיש אידענטיציפירט אלס שעדלעך.\nאומקאנסטרוקטיווע אַקציעס וועלן גיך ווערן צוריקגעשטעלט,\nאון גראבע אדער איבערגעחזרטע אומקאנסטרוקטיווע רעדאַקטירונג וועלן ברענגען צו בלאקירן אײַער קאנטע אדער IP אדרעס.\nווען איר האַלט אַז די רעדאַקטירונג איז יא קאנסטרוקטיוו, מעגט איר קליקן \"אויפהיטן\" נאכאַמאָל צו באַשטעטיגן זי.\nא קורצע באַשרייבונג פונעם כלל וואס איז געבראכן: $1", "abusefilter-disallowed": "די אקציע האט מען אידענטיפֿיצירט אויטאמאטיש ווי שעדלעך, און דעריבער גע'אַסרט.\nווען איר האַלט אַז די רעדאַקטירונג איז יא קאנסטרוקטיוו, מעגט איר קליקן \"אויפהיטן\" נאכאַמאָל צו באַשטעטיגן זי.\nא קורצע באַשרייבונג פונעם כלל וואס איז געבראכן: $1", "abusefilter-blocked-display": "די פעולה ווערט גערעכנט שעדלעך,\nאון מען האט אײַך פארמײַדט פון אויספירן זי.\nדערצו, כדי שיצן {{SITENAME}}, אײַער באניצער קאנטע און אלע אסאציאירטע IP אדרעסן זענען געווארן בלאקירט פון רעדאקטירן.\nIf this has occurred in error, please contact an administrator.\nA brief description of the abuse rule which your action matched is: $1", @@ -21,7 +21,7 @@ "right-abusefilter-view": "באַקוקן שעדיקן פֿילטערס", "right-abusefilter-log": "באקוקן פֿילטער־לאגבוך", "right-abusefilter-log-detail": "באקוקן פרטימדיק דאס קרומבאניץ־לאגבוך", - "right-abusefilter-private": "באקוקן פריוואטע דאטן אין קרומבאניץ־לאגבוך", + "right-abusefilter-privatedetails": "באקוקן פריוואטע דאטן אין קרומבאניץ־לאגבוך", "right-abusefilter-view-private": "באקוקן שעדיקונג־פילטערס מארקירט פריוואט", "right-abusefilter-log-private": "באקוקן לאג איינצן פון שעדיקונג־פילטערס מארקירט פריוואט", "right-abusefilter-hide-log": "באהאלטן איינצן אין שעדיקונג־לאגבוך", @@ -31,9 +31,8 @@ "action-abusefilter-view": "באקוקן שעדיקן פֿילטערס", "action-abusefilter-log": " באקוקן פֿילטער־לאגבוך", "action-abusefilter-log-detail": "באקוקן פרטימדיק אײַנגאבן אין קרומבאניץ־לאגבוך", - "action-abusefilter-private": "באקוקן פריוואטע דאטן אין קרומבאניץ־לאגבוך", + "action-abusefilter-privatedetails": "באקוקן פריוואטע דאטן אין קרומבאניץ־לאגבוך", "action-abusefilter-view-private": "באקוקן שעדיקונג־פילטערס מארקירן פריוואט", - "abusefilter-log": "פֿילטער לאגבוך", "abusefilter-log-summary": "דער לאגבוך ווײַזט א ליסטע פון פעולות געכאפט דורך די פילטערס.", "abusefilter-log-search": "דורכזוכן קרומבאניץ־לאגבוך", "abusefilter-log-search-user": "באַניצער:", @@ -52,20 +51,21 @@ "abusefilter-log-details-var": "וואַריאַבל", "abusefilter-log-details-val": "ווערט", "abusefilter-log-details-vars": "אקציע פאראמעטערס", - "abusefilter-log-details-private": "פריוואטע לאג פרטים", + "abusefilter-log-details-privatedetails": "פריוואטע לאג פרטים", "abusefilter-log-details-ip": "IP־אדרעס פון איניציאטאר", "abusefilter-log-details-checkuser": "בודק זײַן באניצער", "abusefilter-log-noactions": "קיין", "abusefilter-log-details-diff": "ענדערונגען אדורכגעפירט ביי רעדאקטירן", "abusefilter-log-linkoncontribs": "שלעכט־באניצן לאג", "abusefilter-log-linkoncontribs-text": "שלעכט־באניצן לאגבוך פאר {{GENDER:$1|דעם דאזיגן באניצער|דער דאזיגער באניצערין}}", - "abusefilter-log-hidden": "(איינהייט באהאלטן)", + "abusefilter-log-linkonhistory": " באקוקן שלעכט־באניצן לאגבוך", + "abusefilter-log-linkonhistory-text": "ווייזן שלעכט־באַניצן לאגבוך פֿאַר דעם בלאַט", + "abusefilter-log-linkonundelete": " באקוקן שלעכט־באניצן לאגבוך", "abusefilter-log-hidden-implicit": "(באהאלטן ווייל ווערסיע איז געווארן אויסגעמעקט)", "abusefilter-log-cannot-see-details": "איר האט נישט ערלויבניש צו זען פרטים פון דעם ווערט.", "abusefilter-log-hide-legend": "באהאלטן לאגבוך איינגאב", "abusefilter-log-hide-id": "לאגבוך איינגאב ID:", "abusefilter-log-hide-reason": "אורזאַך:", - "abusefilter-management": "שעדיקונג־פילטער פארוואלטונג", "abusefilter-list": "אלע פֿילטערס", "abusefilter-list-id": "פֿילטער נומער", "abusefilter-list-status": "סטאַטוס", @@ -85,6 +85,7 @@ "abusefilter-disabled": "אָפאַקטיוויזירן", "abusefilter-hitcount": "$1 {{PLURAL:$1|טרעף|טרעפֿן}}", "abusefilter-new": "שאפן א נייעם פילטער", + "abusefilter-import-button": "אימפארטירן פֿילטער", "abusefilter-return": "צוריק צו פילטער פארוואלטונג", "abusefilter-status-global": "גלאבאַל", "abusefilter-list-options": "ברירות", @@ -110,7 +111,6 @@ "abusefilter-edit-subtitle-new": "שאפן פילטער", "abusefilter-edit-status-label": "סטאַטיסטיק:", "abusefilter-edit-status": "פון די לעצטע $1 {{PLURAL:$1|פעולה|פעולות}}, האט דער פילטער צוגעפאסט $2 ($3%).", - "abusefilter-edit-status-profile": "פון די לעצטע $1 {{PLURAL:$1|פעולה|פעולות}}, האט דער פילטער צוגעפאסט $2 ($3%).\nדורכשניטלעך איז זיין לויף־צײַט $4 מיליסעקונדעס, און ער ניצט אויס $5 {{PLURAL:$5|באדינג|באדינגען}} פון דער באדינג־באגרענעצונג.", "abusefilter-edit-new": "נײַער פֿילטער", "abusefilter-edit-save": "אױפֿהיטן טעקע", "abusefilter-edit-id": "פֿילטער נומער:", @@ -132,11 +132,11 @@ "abusefilter-edit-throttle-period": "תקופה פון צײַט (אין סעקונדן):", "abusefilter-edit-warn-message": "סיסטעם־מעלדונג פאר ווארענונג:", "abusefilter-edit-warn-other": "אנדער מעלדונג", - "abusefilter-edit-warn-other-label": "בלאטנאמען פון אנדער מעלדונג:\n:''(אן מעדיעוויקי פרעפיקס)''", + "abusefilter-edit-warn-other-label": "בלאטנאמען פון אנדער מעלדונג:\n:''(אן \"מעדיעוויקי:\" פרעפיקס)''", "abusefilter-edit-warn-actions": "אַקציעס:", - "abusefilter-edit-warn-preview": "פאראויסזען געקליבענע מעלדונג", + "abusefilter-edit-warn-preview": "ווייזן/באהאלטן פאראויסקוק פון געקליבענער מעלדונג", "abusefilter-edit-warn-edit": "שאפן/רעדאקטירן געקליבענע מעלדונג", - "abusefilter-edit-tag-tag": "גילטיקע [[Special:Tags|טאגן]] (איינער אין א שורה):", + "abusefilter-edit-tag-tag": "גילטיקע [[Special:Tags|טאגן]]:", "abusefilter-block-anon": "בלאקירן אַנאנימע באַניצער", "abusefilter-edit-denied": "איר קענט נישט באקוקן פרטים פון דעם פילטער, ווייל ער איז באהאלטן פונעם קהל.", "abusefilter-edit-main": "פילטער פאראמעטערס", @@ -208,8 +208,8 @@ "abusefilter-edit-builder-vars-recent-contributors": "לעצטע צען באארבעטער פון דעם בלאט", "abusefilter-edit-builder-vars-first-contributor": "ערשטע באניצער וואס האט בייגישטייערט צום בלאט", "abusefilter-edit-builder-vars-all-links": "אלע דרויסנדיקע לינקען אין נײַעם טעקסט", - "abusefilter-edit-builder-vars-old-text": "אלטער בלאט וויקיטעקסט, פאר דער רעדאקטירונג", - "abusefilter-edit-builder-vars-new-text": "נייער בלאט וויקיטעקסט, פאר דער רעדאקטירונג", + "abusefilter-edit-builder-vars-old-wikitext": "אלטער בלאט וויקיטעקסט, פאר דער רעדאקטירונג (מער נישט אין באניץ)", + "abusefilter-edit-builder-vars-new-wikitext": "נייער בלאט וויקיטעקסט, פאר דער רעדאקטירונג", "abusefilter-edit-builder-vars-restrictions-create": "שאַפֿן באַשיצונג פון דעם בלאַט", "abusefilter-edit-builder-vars-restrictions-upload": "אַרויפֿלאדן באַשיצונג פון דער טעקע", "abusefilter-edit-builder-vars-file-size": "גרייס פון טעקע אין בייטן", @@ -258,8 +258,8 @@ "abusefilter-examine-title": "בלאַטנאָמען:", "abusefilter-examine-submit": "זוכן", "abusefilter-topnav-home": "היימבלאַט", + "abusefilter-topnav-recentchanges": "לעצטע פֿילטער־ענדערונגען", "abusefilter-topnav-log": "שלעכט־באניצן לאג", - "abusefilter-topnav-import": "אימפארטירן פֿילטער", "abusefilter-log-name": "פֿילטער לאגבוך", "abusefilter-log-noresults": "קיין רעזולטאטן", "abusefilter-diff-title": "אונטערשייד צווישן ווערסיעס", diff --git a/AbuseFilter/i18n/yo.json b/AbuseFilter/i18n/yo.json index 0c354e5d..507460b3 100644 --- a/AbuseFilter/i18n/yo.json +++ b/AbuseFilter/i18n/yo.json @@ -2,6 +2,7 @@ "@metadata": { "authors": [ "Demmy", + "Fitoschido", "Wikicology" ] }, @@ -26,7 +27,7 @@ "abusefilter-edit-status-label": "Àwọn statistiki:", "abusefilter-edit-deleted": "Fàlàsí bíi píparẹ́", "abusefilter-edit-lastmod-text": "$1 latọwọ́ $2", - "abusefilter-edit-throttle-page": "Ojú ewé", + "abusefilter-throttle-page": "ojú ewé", "abusefilter-edit-warn-other": "Ìránṣẹ́ míràn", "abusefilter-edit-warn-actions": "Àwọn ìgbéṣe:", "abusefilter-edit-warn-preview": "Àkọ́yẹ̀wò ìránṣẹ́ ṣíṣàyàn", @@ -52,7 +53,7 @@ "abusefilter-edit-builder-op-bool-and": "Àti (&)", "abusefilter-edit-builder-op-bool-or": "Tàbí (|)", "abusefilter-edit-builder-group-funcs": "Àwọn ìgbéṣe", - "abusefilter-edit-builder-vars-accountname": "Orúkọ àpamọ́ (nígbà ìdásílẹ̀ àpamọ́)", + "abusefilter-edit-builder-vars-accountname": "Orúkọ ìforúkọpamọ́ (nígbà ìdá ìforúkọpamọ́)", "abusefilter-edit-builder-vars-action": "Ìgbéṣe", "abusefilter-edit-builder-vars-newsize": "Ìtóbi ojúewé tuntun", "abusefilter-edit-builder-vars-removedlines": "Àwọn ìlà tó jẹ́ yíyọkúrò nínú àtúnṣe", diff --git a/AbuseFilter/i18n/yue.json b/AbuseFilter/i18n/yue.json index f59d3fb3..eb977103 100644 --- a/AbuseFilter/i18n/yue.json +++ b/AbuseFilter/i18n/yue.json @@ -2,21 +2,23 @@ "@metadata": { "authors": [ "Antonytse", + "Deryck Chan", + "Hello903hello", "Horacewai2", + "Matma Rex", + "Moon0319", + "Roy17", "Shinjiman", "Waihorace", - "Wong128hk", - "Matma Rex", - "Deryck Chan", - "Hello903hello" + "Wong128hk" ] }, "abusefilter-desc": "應用自動行為到編輯", - "abusefilter": "濫用過濾器設定", - "abuselog": "濫用紀錄", + "abusefilter": "濫用過濾器管理", + "abuselog": "濫用過濾器紀錄", "abusefilter-intro": "歡迎到濫用過濾器管理界面。\n濫用過濾器係一個自動化軟件程序應用自動行為到任何動作度。\n呢個界面顯示一個定義咗嘅過濾器,容許去改佢哋。", "abusefilter-warning": "'''警告:'''爾個動作已經自動認定咗做有害嘅。\n無建設性嘅動作將會好快噉還原,\n同埋過份或者重覆嘅編輯會令到你個戶口或者電腦封鎖。\n如果你相信爾個動作係有建設性嘅,你可以遞交多一次去確認佢。\n一個簡明濫用條件嘅描述同你嘅動作配合嘅係: $1", - "abusefilter-disallowed": "爾個動作已經自動認定咗做有害嘅,已經唔容許。\n如果你相信爾個動作係有建設性嘅,請同管理員聯絡,通知佢哋你啱啱想做物。\n一個簡明濫用條件嘅描述同你嘅動作配合嘅係: $1", + "abusefilter-disallowed": "呢個動作已經自動認定咗做有害嘅,已經唔容許。\n如果你相信呢個動作係有建設性嘅,請同管理員聯絡,通知佢哋你啱啱想做乜。\n同你嘅動作配合嘅濫用條件嘅描述係:$1", "abusefilter-blocked-display": "呢個動作已經自動認定咗做有害嘅,\n你已經被防止執行佢。\n除此之外,要保謢{{SITENAME}},你嘅戶口同全部有關嘅IP地址已經全部封鎖,唔畀編輯。\n如果出錯,請同管理員聯絡。\n一個簡明濫用條件嘅描述同你嘅動作配合嘅係: $1", "abusefilter-degrouped": "呢個動作已經自動認定咗做有害嘅,\n結果,佢已經唔容許,重有,你個戶口可能已經被盜用,所有嘅權限已經拎走咗。\n如果你相信呢個係有錯嘅話,請聯絡事務員為呢個動作解釋,你嘅權限可能會恢復。\n一個簡明濫用條件嘅描述同你嘅動作配合嘅係: $1", "abusefilter-autopromote-blocked": "呢個動作已經自動認定咗做有害嘅,已經唔容許。\n除此之外,為咗保安理由,一啲開戶口嘅權限已經響你個戶口度拎走咗。\n一個簡明濫用條件嘅描述同你嘅動作配合嘅係: $1", @@ -28,7 +30,7 @@ "right-abusefilter-view": "睇濫用過濾器", "right-abusefilter-log": "去睇濫用紀錄", "right-abusefilter-log-detail": "去睇濫用紀錄細節", - "right-abusefilter-private": "去睇濫用紀錄裏面嘅資料", + "right-abusefilter-privatedetails": "去睇濫用紀錄裏面嘅資料", "right-abusefilter-modify-restricted": "用限制動作改濫用過濾器", "right-abusefilter-revert": "復原一個濫用過濾器嘅全部修改", "right-abusefilter-view-private": "睇一個私密嘅過濾器", @@ -36,11 +38,10 @@ "action-abusefilter-view": "睇濫用過濾器", "action-abusefilter-log": "去睇濫用紀錄", "action-abusefilter-log-detail": "去睇濫用紀錄細節", - "action-abusefilter-private": "去睇濫用紀錄裏面嘅資料", + "action-abusefilter-privatedetails": "去睇濫用紀錄裏面嘅資料", "action-abusefilter-modify-restricted": "用限制動作改濫用過濾器", "action-abusefilter-revert": "復原一個濫用過濾器嘅全部修改", "action-abusefilter-view-private": "睇私密嘅過濾器", - "abusefilter-log": "濫用過濾器紀錄", "abusefilter-log-summary": "呢個紀錄列示咗由過濾器捉到嘅全部動作。", "abusefilter-log-search": "搵濫用紀錄", "abusefilter-log-search-user": "用戶:", @@ -56,7 +57,7 @@ "abusefilter-log-details-var": "變數", "abusefilter-log-details-val": "值", "abusefilter-log-details-vars": "動作參數", - "abusefilter-log-details-private": "私人日誌資料", + "abusefilter-log-details-privatedetails": "私人日誌資料", "abusefilter-log-details-ip": "原生IP地址", "abusefilter-log-noactions": "無", "abusefilter-log-details-diff": "響編輯嘅更動", @@ -64,7 +65,6 @@ "abusefilter-log-linkoncontribs-text": "{{GENDER:$1|爾位用戶}}嘅濫用紀錄", "abusefilter-log-linkonhistory": "去睇濫用過濾器紀錄", "abusefilter-log-linkonhistory-text": "睇呢頁嘅濫用過濾器紀錄", - "abusefilter-management": "濫用過濾器管理", "abusefilter-list": "全部過濾器", "abusefilter-list-id": "過濾器ID", "abusefilter-list-status": "狀態", @@ -83,6 +83,7 @@ "abusefilter-disabled": "閂咗", "abusefilter-hitcount": "$1次", "abusefilter-new": "開一個新過濾器", + "abusefilter-import-button": "倒入過濾器", "abusefilter-return": "返去過濾器管理", "abusefilter-status-global": "全域", "abusefilter-list-options": "選項", @@ -107,7 +108,6 @@ "abusefilter-edit-oldwarning": "<strong>你而家編輯緊呢個過濾器嘅舊版本。\n個統計係計響最近過本嘅過濾器度。\n如果你保存你嘅修改,你會覆蓋自從你編輯修訂嘅全部修改。</strong> •\n[[Special:AbuseFilter/history/$2|返去呢個過濾器嘅歷史]]。", "abusefilter-edit-status-label": "統計:", "abusefilter-edit-status": "響之前$1{{PLURAL:$1|次|次}}動作,呢個過濾器已經配合咗$2次 ($3%)。", - "abusefilter-edit-status-profile": "響之前$1{{PLURAL:$1|次|次}}動作,呢個過濾器已經配合咗$2次 ($3%)。\n平均,佢嘅運行時間係$4毫秒,用左$5{{PLURAL:$5|次|次}}限制。", "abusefilter-edit-new": "新過濾器", "abusefilter-edit-save": "保存過濾器", "abusefilter-edit-id": "過濾器ID:", @@ -134,8 +134,8 @@ "abusefilter-edit-throttle-count": "可以容許嘅動作:", "abusefilter-edit-throttle-period": "時段:", "abusefilter-edit-throttle-groups": "由組截住:", - "abusefilter-edit-throttle-ip": "IP地址", - "abusefilter-edit-throttle-editcount": "編輯次數", + "abusefilter-throttle-ip": "IP地址", + "abusefilter-throttle-editcount": "編輯次數", "abusefilter-edit-warn-message": "用系統訊息去警告:", "abusefilter-edit-warn-other": "其它訊息", "abusefilter-edit-warn-other-label": "其它訊息嘅頁名:\n:''(無MediaWiki字頭)''", @@ -154,7 +154,7 @@ "abusefilter-edit-check": "檢查語法", "abusefilter-edit-badfilter": "你所指定嘅過濾器唔存在", "abusefilter-edit-revert": "還原由呢個過濾器嘅動作", - "abusefilter-edit-tools": "工具:", + "abusefilter-edit-tools": "架撐:", "abusefilter-edit-test-link": "用呢個過濾器試最近嘅編輯", "abusefilter-edit-export": "倒出呢個過濾器到另一個wiki", "abusefilter-edit-syntaxok": "偵測到無語法錯誤。", @@ -239,13 +239,13 @@ "abusefilter-edit-builder-vars-all-links": "新字加外連", "abusefilter-edit-builder-vars-added-links": "編輯加咗嘅全部外連", "abusefilter-edit-builder-vars-removed-links": "編輯拎走咗嘅全部外連", - "abusefilter-edit-builder-vars-old-text": "響編輯之前嘅舊頁wiki字", - "abusefilter-edit-builder-vars-new-text": "響編輯之後嘅新頁wiki字", - "abusefilter-edit-builder-vars-new-text-stripped": "切咗標記嘅新頁字", + "abusefilter-edit-builder-vars-old-wikitext": "響編輯之前嘅舊頁wiki字", + "abusefilter-edit-builder-vars-new-wikitext": "響編輯之後嘅新頁wiki字", + "abusefilter-edit-builder-vars-new-text": "切咗標記嘅新頁字", "abusefilter-edit-builder-vars-new-html": "新修訂處理過嘅HTML源碼", "abusefilter-edit-builder-vars-restrictions-edit": "響嗰版嘅保謢等級", "abusefilter-edit-builder-vars-restrictions-move": "搬嗰版嘅保謢等級", - "abusefilter-edit-builder-vars-old-text-stripped": "切咗標記嘅舊頁字", + "abusefilter-edit-builder-vars-old-text": "切咗標記嘅舊頁字", "abusefilter-edit-builder-vars-old-links": "響編輯之前嘅連結", "abusefilter-edit-builder-vars-old-html": "舊wiki字處理過嘅HTML", "abusefilter-edit-builder-vars-minor-edit": "編輯係小修改", @@ -342,7 +342,6 @@ "abusefilter-topnav-examine": "檢查之前嘅編輯", "abusefilter-topnav-log": "濫用紀錄", "abusefilter-topnav-tools": "除錯工具", - "abusefilter-topnav-import": "倒入過濾器", "abusefilter-log-name": "濫用過濾器紀錄", "abusefilter-log-header": "呢個紀錄顯示過濾器更改過嘅摘要。\n要知更多細節,睇之前過濾器更改嘅[[Special:AbuseFilter/history|表]]。", "abusefilter-diff-title": "唔同版本之間嘅差異", diff --git a/AbuseFilter/i18n/zgh.json b/AbuseFilter/i18n/zgh.json index 8b573350..c821ee98 100644 --- a/AbuseFilter/i18n/zgh.json +++ b/AbuseFilter/i18n/zgh.json @@ -1,8 +1,10 @@ { "@metadata": { "authors": [ + "Hakim1bal", "Mdb897" ] }, - "abusefilter-edit-throttle-creationdate": "ⴰⴽⵓⴷ ⵏ ⵓⵎⴰⴽⴽⴰⵢ ⴷⴰⵔ ⵜⵓⴳⵉ ⵏ ⵓⵎⵉⴹⴰⵏ" + "abusefilter-log-search-title": "ⴰⵣⵡⵍ:", + "abusefilter-log-search-wiki": "ⵡⵉⴽⵉ:" } diff --git a/AbuseFilter/i18n/zh-hans.json b/AbuseFilter/i18n/zh-hans.json index eece8148..7ba5acc3 100644 --- a/AbuseFilter/i18n/zh-hans.json +++ b/AbuseFilter/i18n/zh-hans.json @@ -1,7 +1,11 @@ { "@metadata": { "authors": [ + "94rain", + "A Chinese Wikipedian", + "A2093064", "Anakmalaysia", + "Angrydog001", "Bbqyee", "Bencmq", "Byfserag", @@ -9,50 +13,60 @@ "Chenzw", "Cwek", "Dimension", + "Duolaimi", + "EagerLin", "Fantasticfears", "FireJackey", "Gaoxuewei", + "GoForceX", "Gzdavidwong", "Hydra", "Hzy980512", + "Impersonator 1", + "JerryLiu", "Jimmy xu wrk", "Liangent", "Linforest", "Liuxinyu970226", + "Looong", "Luotiancheng", "Makecat", + "Matma Rex", + "Mywood", + "NeverBehave", + "NigelSoft", "PhiLiP", "Philip <philip.npc@gmail.com>", "Qiyue2001", + "SCP-2000", "Shirayuki", "Shizhao", "Simon Shek", "Skjackey tse", + "Sunny00217", + "Tiger", + "VulpesVulpes825", + "WhitePhosphorus", + "Wmr", "Wmr89502270", "Xiaomingyan", + "XinuGod", + "Xiplus", "Yanmiao liu", "Yfdyh000", + "Ywang", "Zhangjintao", - "Mywood", - "Impersonator 1", - "NigelSoft", - "Duolaimi", + "佛壁灯", + "夢蝶葬花", + "沈澄心", "范", - "Matma Rex", - "EagerLin", - "Wmr", "逆襲的天邪鬼", - "WhitePhosphorus", - "A2093064", - "NeverBehave", - "JerryLiu", - "夢蝶葬花", - "A Chinese Wikipedian" + "飞舞回堂前" ] }, "abusefilter-desc": "对编辑行为自动进行条件判定", - "abusefilter": "滥用过滤器配置", - "abuselog": "滥用日志", + "abusefilter": "滥用过滤器管理", + "abuselog": "防滥用过滤器日志", "abusefilter-intro": "欢迎访问防滥用过滤器管理界面。防滥用过滤器是一个可以针对所有最近编辑动作进行自动化判断的软件系统。本界面包含了现有过滤器的列表,并允许管理人员修改它们。", "abusefilter-mustviewprivateoredit": "出于安全考虑,只有拥有查看私有防滥用过滤器或修改过滤器权限的用户方可使用本界面。", "abusefilter-warning": "'''警告:'''此操作已被自动识别为有害。无意义的操作会被迅速地回退,而过分或重复的无意义编辑会导致您的帐户或IP地址遭到封禁。如果您确信本次操作是有意义的,您可以再次点击提交以确认它。与您此次行为所匹配的过滤规则概述如下:$1", @@ -63,13 +77,14 @@ "abusefilter-blocker": "滥用过滤器", "abusefilter-blockreason": "被滥用过滤器自动封禁。匹配的规则的说明:$1", "abusefilter-degroupreason": "权限被滥用过滤器自动剥夺。规则说明:$1", + "abusefilter-blockautopromotereason": "滥用过滤器已将用户获自动授权的时间推迟。规则描述:$1", "abusefilter-accountreserved": "此帐户已由防滥用过滤器保留使用。", - "right-abusefilter-modify": "修改防滥用过滤器", + "right-abusefilter-modify": "创建或修改滥用过滤器", "right-abusefilter-view": "查看滥用过滤器", "right-abusefilter-log": "查看滥用日志", "right-abusefilter-log-detail": "查看详细滥用日志", - "right-abusefilter-private": "查看滥用日志中的私有数据", - "right-abusefilter-private-log": "查看防滥用过滤器私有详情访问日志", + "right-abusefilter-privatedetails": "查看滥用日志中的私有数据", + "right-abusefilter-privatedetails-log": "查看防滥用过滤器私有详情访问日志", "right-abusefilter-modify-restricted": "修改包含受限动作的防滥用过滤器", "right-abusefilter-revert": "撤销指定防滥用过滤器作出的所有更改", "right-abusefilter-view-private": "查看被标记为私有的防滥用过滤器", @@ -81,17 +96,22 @@ "action-abusefilter-view": "查看滥用过滤器", "action-abusefilter-log": "查看滥用日志", "action-abusefilter-log-detail": "查看详细滥用日志", - "action-abusefilter-private": "查看滥用日志中的私有数据", - "action-abusefilter-private-log": "查看防滥用过滤器私有详情访问日志", + "action-abusefilter-privatedetails": "查看滥用日志中的私有数据", + "action-abusefilter-privatedetails-log": "查看防滥用过滤器私有详情访问日志", "action-abusefilter-modify-restricted": "以有限的操作修改防滥用过滤器", "action-abusefilter-revert": "还原指定防滥用过滤器作出的所有更改", "action-abusefilter-view-private": "查看被标记为私有的防滥用过滤器", "action-abusefilter-log-private": "查看标记为私有的防滥用过滤器日志", - "abusefilter-log": "防滥用过滤器日志", + "action-abusefilter-hide-log": "将条目在滥用日志中隐藏", + "action-abusefilter-hidden-log": "查看隐藏的滥用日志条目", + "action-abusefilter-modify-global": "创建或修改全域滥用过滤器", "abusefilter-log-summary": "本日志列出了过滤器捕捉到的所有操作。", "abusefilter-log-search": "搜索滥用日志", "abusefilter-log-search-user": "用户:", - "abusefilter-log-search-filter": "过滤器ID(以竖线分隔):", + "abusefilter-log-search-group": "过滤器组:", + "abusefilter-log-search-group-any": "任何", + "abusefilter-log-search-filter": "过滤器ID:", + "abusefilter-log-search-filter-help": "以竖线分隔,前缀为“$1”表示全域过滤器", "abusefilter-log-search-title": "标题:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-impact": "影响:", @@ -120,7 +140,7 @@ "abusefilter-log-details-var": "变量", "abusefilter-log-details-val": "值", "abusefilter-log-details-vars": "操作参数", - "abusefilter-log-details-private": "私有日志详情", + "abusefilter-log-details-privatedetails": "私有日志详情", "abusefilter-log-details-ip": "原始IP地址", "abusefilter-log-details-checkuser": "用户查核", "abusefilter-log-noactions": "无", @@ -129,10 +149,11 @@ "abusefilter-log-linkoncontribs-text": "{{GENDER:$1|此用户}}的滥用日志", "abusefilter-log-linkonhistory": "查看滥用日志", "abusefilter-log-linkonhistory-text": "查看该页面的滥用日志", - "abusefilter-log-hidden": "(记录已被隐藏)", + "abusefilter-log-linkonundelete": "查看滥用日志", + "abusefilter-log-linkonundelete-text": "查看该页面的滥用日志", "abusefilter-log-hidden-implicit": "(因为修订已被删除而隐藏)", "abusefilter-log-cannot-see-details": "您没有权限去查看这个记录条目的细节。", - "abusefilter-log-cannot-see-private-details": "您没有权限查看此记录的私有详情。", + "abusefilter-log-cannot-see-privatedetails": "您没有权限查看此记录的私有详情。", "abusefilter-log-nonexistent": "提供ID的实体不存在。", "abusefilter-log-details-hidden": "您无法查看详细信息,因为此条目已被从公共范围隐藏。", "abusefilter-log-details-hidden-implicit": "您无法查看此记录的详细信息,因为其与从公开视图中隐藏的修订版本相关联。", @@ -150,9 +171,12 @@ "log-action-filter-abusefilter-create": "新过滤器创建", "log-action-filter-abusefilter-modify": "过滤器修改", "log-action-filter-suppress-abuselog": "滥用日志监督", + "log-action-filter-rights-blockautopromote": "自动升级模块", + "log-action-filter-rights-restoreautopromote": "自动提升还原", "logentry-abusefilterprivatedetails-access": "$1{{GENDER:$2|访问了}}$3的私有详情", + "logentry-rights-blockautopromote": "$1{{GENDER:$2|禁止}}{{GENDER:$4|$3}}于$5内获得自动授权", + "logentry-rights-restoreautopromote": "$1{{GENDER:$2|存储}}{{GENDER:$4|$3}}的自动提示能力", "abusefilterprivatedetails-log-name": "防滥用过滤器私有详情访问日志", - "abusefilter-management": "滥用过滤器管理", "abusefilter-list": "所有过滤器", "abusefilter-list-id": "过滤器ID", "abusefilter-list-pattern": "模式", @@ -174,6 +198,7 @@ "abusefilter-throttled": "已控制", "abusefilter-hitcount": "$1次触发", "abusefilter-new": "新建过滤器", + "abusefilter-import-button": "导入过滤器", "abusefilter-return": "返回过滤器管理界面", "abusefilter-status-global": "全域", "abusefilter-list-options": "选项", @@ -194,27 +219,30 @@ "abusefilter-list-options-search-like": "纯文本查询", "abusefilter-list-options-search-rlike": "正则表达式", "abusefilter-list-options-search-irlike": "不区分大小写的正则表达式", + "abusefilter-list-invalid-searchmode": "指定的搜索模式无效。", "abusefilter-list-regexerror": "搜索时发生错误:正则表达式语法错误。", "abusefilter-list-options-submit": "更新", "abusefilter-tools-text": "这里提供了一些实用的制作和测试防滥用过滤器的工具。", "abusefilter-tools-expr": "表达式测试器", "abusefilter-tools-submitexpr": "评估", + "abusefilter-tools-syntax-error": "过滤器存在语法错误。", "abusefilter-tools-reautoconfirm": "恢复自动确认状态", "abusefilter-tools-reautoconfirm-user": "用户:", "abusefilter-tools-reautoconfirm-submit": "重新自动确认", + "abusefilter-tools-restoreautopromote": "通过滥用过滤器工具存储自动提示。", "abusefilter-reautoconfirm-none": "该用户的自动确认状态并没有被撤销过", "abusefilter-reautoconfirm-notallowed": "您不被允许恢复自动确认状态。", "abusefilter-reautoconfirm-done": "该账户的自动确认状态已恢复", - "abusefilter-status": "在最近$1次{{PLURAL:$1|操作}}中,$2($3%)个过滤器{{PLURAL:$2|已}}达到$4次条件比较上限,$5($6%)次操作{{PLURAL:$5|已}}匹配当前启用的过滤器之一。", + "abusefilter-status": "在最近$1次{{PLURAL:$1|操作}}中,$2($3%)个过滤器{{PLURAL:$2|已}}达到$4次条件比较上限,至少$5($6%)次操作{{PLURAL:$5|已}}匹配当前启用的过滤器之一。", "abusefilter-edit": "编辑滥用过滤器", "abusefilter-edit-subtitle": "编辑过滤器$1", "abusefilter-edit-subtitle-new": "创建过滤器", "abusefilter-edit-token-not-match": "编辑尚未保存!请再次尝试保存。", - "abusefilter-edit-oldwarning": "<strong>您正在编辑该过滤器的旧版本。统计中引用的是该过滤器的最新版本。如果您保存您的编辑,所编辑版本之后的所有更改均会被覆盖。</strong> •\n[[Special:AbuseFilter/history/$2|返回该过滤器的历史记录]]。", + "abusefilter-edit-oldwarning": "<strong>你正在编辑该过滤器的旧版本。统计中引用的是该过滤器的最新版本。如果你保存你的编辑,所编辑版本之后的所有更改均会被覆盖。</strong> • [[Special:AbuseFilter/history/$2|返回该过滤器的历史记录]]。", + "abusefilter-edit-oldwarning-view": "<strong>您正在查看的是此过滤器的旧版本。\n引用的统计数据是适用于此过滤器的最新版本。</strong> •\n[[Special:AbuseFilter/history/$2|返回到此过滤器的历史记录]]。", "abusefilter-edit-status-label": "统计:", - "abusefilter-edit-status": "在最近的$1次{{PLURAL:$1|操作}}中,有$2($3%)次触发了本过滤器。", - "abusefilter-edit-status-profile": "在最后的$1次编辑中,有$2($3%)次编辑触发了本过滤器。其平均运行时间为$4ms(毫秒),消耗了$5条限制。", - "abusefilter-edit-throttled-warning": "'''警告:'''该过滤器已自动标示为有害。作为安全措施,以下操作将不会执行($1)。请复查并[[mw:Extension:AbuseFilter/Conditions|优化]]您的条件来移除该限制", + "abusefilter-edit-status": "在最近的$1次{{PLURAL:$1|操作}}中,有$2($3%)次触发了本过滤器。\n其平均运行时间为$4毫秒,消耗了$5{{PLURAL:$5|条}}限制。", + "abusefilter-edit-throttled-warning": "'''警告:'''该过滤器已自动标示为有害。作为安全措施,以下操作将不会执行:$1。请复查并[[mw:Extension:AbuseFilter/Conditions|优化]]您的条件来移除该限制", "abusefilter-edit-new": "新建过滤器", "abusefilter-edit-save": "保存过滤器", "abusefilter-edit-id": "过滤器ID:", @@ -246,13 +274,18 @@ "abusefilter-edit-throttle-count": "允许的操作次数:", "abusefilter-edit-throttle-period": "期限(秒):", "abusefilter-edit-throttle-groups": "受限群组:", - "abusefilter-edit-throttle-ip": "IP地址", - "abusefilter-edit-throttle-user": "用户账户", - "abusefilter-edit-throttle-range": "/16段", - "abusefilter-edit-throttle-creationdate": "账户创建的服务器时间", - "abusefilter-edit-throttle-editcount": "编辑计数", - "abusefilter-edit-throttle-site": "整个网站", - "abusefilter-edit-throttle-page": "页面", + "abusefilter-edit-throttle-groups-help": "参见$1。", + "abusefilter-edit-throttle-groups-help-text": "mediawiki.org上的文档", + "abusefilter-edit-throttle-hidden-placeholder": "用逗号分隔来与 AND 相接,并以换行来与 OR 相接。", + "abusefilter-edit-throttle-placeholder": "用逗号分隔来与 AND 相接,并逐一插入来与 OR 相接。", + "abusefilter-throttle-ip": "IP地址", + "abusefilter-throttle-user": "用户账户", + "abusefilter-throttle-range": "/16段", + "abusefilter-throttle-creationdate": "账户创建时间", + "abusefilter-throttle-editcount": "编辑计数", + "abusefilter-throttle-site": "整个网站", + "abusefilter-throttle-page": "页面", + "abusefilter-throttle-none": "(无)", "abusefilter-throttle-details": "允许每$2{{PLURAL:$2|秒}}$1次{{PLURAL:$1|操作}},受限群组:$3", "abusefilter-edit-warn-message": "用作警告的系统消息:", "abusefilter-edit-warn-other": "其他消息", @@ -292,10 +325,18 @@ "abusefilter-edit-export": "导出此过滤器", "abusefilter-edit-syntaxok": "没有检测到语法错误。", "abusefilter-edit-syntaxerr": "检测到语法错误:$1", + "abusefilter-edit-warn-leave": "离开页面会导致您失去对此过滤器所作出的任何更改。", "abusefilter-edit-bad-tags": "一个或更多您指定的标签无效。标签应该较短,但不得包含特殊字符,且不得被其他软件保留。尝试选择新的标签名。", "abusefilter-edit-notallowed": "您未被允许创建或编辑防滥用过滤器", "abusefilter-edit-notallowed-global": "您未被允许创建或编辑全域防滥用过滤器", - "abusefilter-edit-notallowed-global-custom-msg": "对于全域过滤器,不支持自定义警告消息", + "abusefilter-edit-notallowed-global-custom-msg": "对于全域过滤器,自定义警告或者不允许的消息是不支持的", + "abusefilter-edit-invalid-warn-message": "警告消息不可留空。", + "abusefilter-edit-invalid-disallow-message": "禁止消息不可留空。", + "abusefilter-edit-invalid-throttlecount": "受限行动次数必须为正整数。", + "abusefilter-edit-invalid-throttleperiod": "受限周期必须为正整数。", + "abusefilter-edit-empty-throttlegroups": "至少要选择一个受限组。", + "abusefilter-edit-duplicated-throttlegroups": "受限组不可重复。", + "abusefilter-edit-invalid-throttlegroups": "所指定受限组无效。", "abusefilter-edit-builder-select": "选择需添加到光标处的选项", "abusefilter-edit-builder-group-op-arithmetic": "算术运算符", "abusefilter-edit-builder-op-arithmetic-addition": "加(+)", @@ -326,7 +367,8 @@ "abusefilter-edit-builder-misc-contains": "左字符串包含右字符串(contains)", "abusefilter-edit-builder-misc-stringlit": "字符串(\"\")", "abusefilter-edit-builder-misc-tern": "三元运算符(X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "条件表达式(if X then Y else Z)", + "abusefilter-edit-builder-misc-cond": "条件表达式(if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "简短条件表达式(if X then Y end)", "abusefilter-edit-builder-group-funcs": "函数", "abusefilter-edit-builder-funcs-length": "字符串长度(length)", "abusefilter-edit-builder-funcs-lcase": "字母小写化(lcase)", @@ -397,12 +439,12 @@ "abusefilter-edit-builder-vars-all-links": "新内容中的所有外部链接", "abusefilter-edit-builder-vars-added-links": "新内容中新增的所有外部链接", "abusefilter-edit-builder-vars-removed-links": "新内容中移除的所有外部链接", - "abusefilter-edit-builder-vars-old-text": "旧页面的wiki文本,在编辑之前(不再继续使用)", - "abusefilter-edit-builder-vars-new-text": "编辑后的新页面,wiki代码格式", + "abusefilter-edit-builder-vars-old-wikitext": "在编辑之前旧页面的wiki文本", + "abusefilter-edit-builder-vars-new-wikitext": "在编辑之后新页面的wiki文本", "abusefilter-edit-builder-vars-new-pst": "新页面维基语言,预保存转换", "abusefilter-edit-builder-vars-diff-pst": "统一所有由编辑、预保存转换更改的差异", "abusefilter-edit-builder-vars-addedlines-pst": "编辑中加入了行,并在保存前转换", - "abusefilter-edit-builder-vars-new-text-stripped": "编辑后的新页面,去除所有标记", + "abusefilter-edit-builder-vars-new-text": "编辑后的新页面,去除所有标记", "abusefilter-edit-builder-vars-new-html": "编辑后的新页面,已解析为HTML源码", "abusefilter-edit-builder-vars-restrictions-edit": "页面的编辑保护级别", "abusefilter-edit-builder-vars-restrictions-move": "页面的移动保护级别", @@ -416,10 +458,10 @@ "abusefilter-edit-builder-vars-movedto-restrictions-move": "移动目标页面的移动保护级别", "abusefilter-edit-builder-vars-movedto-restrictions-create": "移动目标页面的创建保护", "abusefilter-edit-builder-vars-movedto-restrictions-upload": "移动目标文件的上传保护", - "abusefilter-edit-builder-vars-old-text-stripped": "编辑前的旧页面,去除所有标记", + "abusefilter-edit-builder-vars-old-text": "编辑前的旧页面,去除所有标记(不再使用)", "abusefilter-edit-builder-vars-old-links": "旧内容中的所有外部链接", "abusefilter-edit-builder-vars-old-html": "旧页面的wiki文本,解析为HTML(不再继续使用)", - "abusefilter-edit-builder-vars-minor-edit": "编辑是否被标记为小编辑", + "abusefilter-edit-builder-vars-minor-edit": "编辑是否被标记为小编辑(不再使用)", "abusefilter-edit-builder-vars-file-sha1": "文件内容的SHA1值", "abusefilter-edit-builder-vars-file-size": "文件大小,单位字节", "abusefilter-edit-builder-vars-file-mime": "文件的MIME类型", @@ -427,6 +469,8 @@ "abusefilter-edit-builder-vars-file-width": "文件宽度(像素)", "abusefilter-edit-builder-vars-file-height": "文件高度(像素)", "abusefilter-edit-builder-vars-file-bits-per-channel": "文件的位/颜色通道", + "abusefilter-edit-builder-vars-wiki-name": "Wiki的数据库名称", + "abusefilter-edit-builder-vars-wiki-language": "Wiki的语言代码", "abusefilter-filter-log": "最近过滤器更改", "abusefilter-history": "滥用过滤器#$1的更改历史", "abusefilter-history-foruser": "由$1做出的更改", @@ -460,13 +504,16 @@ "abusefilter-exception-dividebyzero": "字符$1处非法将$2除以零。", "abusefilter-exception-unrecognisedvar": "字符$1处存在无法识别的变量$2。", "abusefilter-exception-notenoughargs": "字符$1处调用的函数$2未得到足够的参数。预期有$3个参数,得到了$4个。", - "abusefilter-exception-regexfailure": "字符$1处的正则表达式“$3”存在错误:“$2”。", + "abusefilter-exception-toomanyargs": "字符$1处调用的函数$2传入过多参数。预期最多应有有$3个参数,却得到了$4个。", + "abusefilter-exception-regexfailure": "字符$1处的正则表达式“$2”存在错误。", "abusefilter-exception-overridebuiltin": "字符$1处非法覆盖内建变量“$2”。", "abusefilter-exception-outofbounds": "字符$1正在请求不存在的数组项$2(数组大小 = $3)。", + "abusefilter-exception-negativeindex": "禁止在数组中使用小于0的项目编号。在“$2”处收到项目编号“$1”。", "abusefilter-exception-notarray": "字符$1正在请求非数组的数组项。", "abusefilter-exception-unclosedcomment": "字符$1处有未闭合注释。", "abusefilter-exception-invalidiprange": "字符$1处提供了无效的IP地址段“$2”。", "abusefilter-exception-disabledvar": "字符$1的变量$2不再继续使用。", + "abusefilter-exception-variablevariable": "在第$1个字符位置发现set和ser_var变量,它们的第一个参数应为字符串字面量。", "abusefilter-action-tag": "标签", "abusefilter-action-throttle": "频率控制", "abusefilter-action-warn": "警告", @@ -528,16 +575,17 @@ "abusefilter-examine-incompatible": "防滥用过滤器不支持您请求的更改。", "abusefilter-examine-noresults": "您输入的搜索参数未找到任何结果。", "abusefilter-topnav": "'''滥用过滤器导航'''", - "abusefilter-topnav-home": "主页", + "abusefilter-topnav-home": "首页", + "abusefilter-topnav-recentchanges": "最近过滤器更改", "abusefilter-topnav-test": "批量测试", "abusefilter-topnav-examine": "检查过去的编辑", "abusefilter-topnav-log": "滥用日志", "abusefilter-topnav-tools": "调试工具", - "abusefilter-topnav-import": "导入过滤器", "abusefilter-log-name": "滥用过滤器日志", "abusefilter-log-header": "本日志展示过滤器更改的摘要。详情请见最近的过滤器更改[[Special:AbuseFilter/history|列表]]。", "abusefilter-logentry-create": "$1{{GENDER:$2|创建}}了$4($5)", "abusefilter-logentry-modify": "$1{{GENDER:$2|修改了}}$4($5)", + "abusefilter-log-invalid-filter": "部分指定过滤器ID无效。", "abusefilter-log-noresults": "没有结果", "abusefilter-diff-title": "版本间的差异", "abusefilter-diff-item": "项目", @@ -550,11 +598,12 @@ "abusefilter-diff-next": "较新的更改", "abusefilter-import-intro": "您可以使用本界面来导入其他wiki的过滤器。在来源处点击过滤器编辑界面处“{{int:abusefilter-edit-tools}}”下的“{{int:abusefilter-edit-export}}”。复制随后出现的文本框中的内容,并粘贴至下方的文本框中,并点击“{{int:abusefilter-import-submit}}”。", "abusefilter-import-submit": "导入数据", + "abusefilter-import-invalid-data": "您尝试导入的数据无效", "abusefilter-group-default": "默认", "abusefilter-http-error": "发生一个HTTP错误:$1。", - "abusefilter-view-private-submit": "查看私有详情", - "abusefilter-view-private": "查看私有详情", - "abusefilter-view-private-reason": "访问私有详情的原因:", + "abusefilter-view-privatedetails-submit": "查看私有详情", + "abusefilter-view-privatedetails-legend": "查看私有详情", + "abusefilter-view-privatedetails-reason": "访问私有详情的原因:", "abusefilter-log-details-id": "日志ID", "abusefilter-invalid-request": "无效请求!您必须通过[[Special:AbuseLog/$1]]上的表单提供原因后才能访问私有日志详情。", "abusefilter-invalid-request-noid": "无效请求!您必须通过在滥用日志详情上的表单提供原因后才能访问私有日志详情。", diff --git a/AbuseFilter/i18n/zh-hant.json b/AbuseFilter/i18n/zh-hant.json index fff51d35..9192fb46 100644 --- a/AbuseFilter/i18n/zh-hant.json +++ b/AbuseFilter/i18n/zh-hant.json @@ -1,85 +1,97 @@ { "@metadata": { "authors": [ + "1233thehongkonger", + "A2093064", "Alexsh", "Anakmalaysia", "Bencmq", "Ch.Andrew", + "Corainn", + "Cwek", "Cwlin0416", "EagerLin", "Gzdavidwong", "Horacewai2", "Jimmy xu wrk", "Justincheng12345", + "Kly", + "LNDDYL", + "Laundry Machine", "Liangent", "Liuxinyu970226", "Mark85296341", + "Matma Rex", "Oapbtommy", "Pbdragonwang", + "S8321414", + "SCP-2000", + "Sanmosa", "Simon Shek", "Skjackey tse", "StephDC", + "Sunny00217", + "VulpesVulpes825", "Waihorace", + "Winston Sung", "Wong128hk", "Wrightbus", + "Xiplus", "Yfdyh000", "Zanhsieh", - "S8321414", - "LNDDYL", "Zhxy 519", - "Cwek", - "Matma Rex", - "1233thehongkonger", - "逆襲的天邪鬼", - "Corainn", - "A2093064", - "Laundry Machine", - "Kly", - "Sanmosa" + "逆襲的天邪鬼" ] }, - "abusefilter-desc": "套用自動啟發式演算法於編輯", - "abusefilter": "防濫用過濾器設定", - "abuselog": "濫用日誌", + "abusefilter-desc": "對編輯行為自動進行條件判定", + "abusefilter": "防濫用過濾器管理", + "abuselog": "防濫用過濾器日誌", "abusefilter-intro": "歡迎使用防濫用過濾器管理介面。防濫用過濾器是針對所有編輯動作進行自動化判斷的軟體機制。本介面包含了現有的過濾器清單並允許修改。", - "abusefilter-mustviewprivateoredit": "基於安全性考量,僅擁有查看非公開防濫用過濾器、或是修改過濾器權限的使用者可使用本介面。", - "abusefilter-warning": "'''警告''':此操作已被系統自動識別為有害動作。\n沒有建設性的操作將會被快速還原,\n嚴重或重複的非建設性的編輯將導致您的帳號或 IP 位址被封鎖。\n如果您認為您的編輯是具有建設性的,您可以再送出一次以確認。\n與您的操作符合的濫用規則描述為:$1", - "abusefilter-disallowed": "此操作已被系統自動識別為有害動作並已禁止。\n如果您認為您的操作是有建設性的,請與管理員聯絡,並告知您剛才嘗試進行的事。\n與您的操作符合的濫用規則描述為:$1", - "abusefilter-blocked-display": "此操作已被系統自動識別為有害動作,\n系統已阻止您執行此操作。\n為了保護 {{SITENAME}},您的帳號及所有其相關的 IP 位址皆會被封鎖,不允許編輯。\n如果這是系統誤判,請聯絡管理員。\n與您的操作符合的濫用規則描述為:$1", - "abusefilter-degrouped": "系統已自動將您的操作識別為有害動作。\n因此已禁止此操作。另外,由於您的帳號疑似遭到盜用,您的所有權限均已取消。\n如果您認為這是系統誤判,請附上此操作的解釋並聯繫行政員,這樣或許能取回權限。\n與您的操作符合的濫用規則描述為:$1", - "abusefilter-autopromote-blocked": "此操作已被系統自動識別為有害動作並已禁止。\n基於安全性考量,部份例行授予已建立帳號的權限將暫時從您的帳號上撤回。\n與您的操作符合的濫用規則描述為:$1", + "abusefilter-mustviewprivateoredit": "基於安全性考量,僅擁有檢視非公開防濫用過濾器或修改過濾器權限的使用者可使用本介面。", + "abusefilter-warning": "'''警告:'''此操作已被自動識別為有害。沒有建設性的操作將會被快速還原,嚴重或重複的非建設性的編輯將導致您的帳號或IP位址被封鎖。如果您認為您的操作是有建設性的,您可以再送出一次以確認。與您的操作符合的防濫用規則描述為:$1", + "abusefilter-disallowed": "此操作已被自動識別為有害並被禁止。如果您認為您的操作是有建設性的,請與管理員聯絡,並告知您剛才嘗試進行的事。與您的操作符合的防濫用規則描述為:$1", + "abusefilter-blocked-display": "此操作已被自動識別為有害,已阻止您執行此操作。為了保護{{SITENAME}},您的帳號及所有相關的IP位址皆已被禁止編輯。如果這是誤判,請聯絡管理員。與您的操作符合的防濫用規則描述為:$1", + "abusefilter-degrouped": "此操作已被自動識別為有害,因此已阻止此操作。另外,由於您的帳號疑似遭到盜用,您的所有權限均已被剝奪。如果您認為這是誤判,請附上此操作的解釋並聯繫行政員,這樣或許能取回權限。與您的操作符合的防濫用規則描述為:$1", + "abusefilter-autopromote-blocked": "此操作已被自動識別為有害並已禁止。基於安全性考量,部份例行授予已建立帳號的權限將暫時從您的帳號上撤回。與您的操作符合的防濫用規則描述為:$1", "abusefilter-blocker": "防濫用過濾器", - "abusefilter-blockreason": "已由防濫用過濾器自動封鎖。\n符合的規則描述為︰$1", - "abusefilter-degroupreason": "已由防濫用篩選器自動移除權限。\n規則描述︰$1", + "abusefilter-blockreason": "被防濫用過濾器自動封鎖。符合的規則描述為︰$1", + "abusefilter-degroupreason": "防濫用篩選器自動移除權限。規則描述︰$1", + "abusefilter-blockautopromotereason": "濫用過濾器已將用戶獲自動授權的時間推遲。規則描述:$1", "abusefilter-accountreserved": "此帳號名稱已保留給防濫用過濾器使用。", - "right-abusefilter-modify": "修改防濫用過濾器", + "right-abusefilter-modify": "建立或修改防濫用過濾器", "right-abusefilter-view": "檢視防濫用過濾器", "right-abusefilter-log": "檢視濫用日誌", "right-abusefilter-log-detail": "檢視濫用日誌詳細資料", - "right-abusefilter-private": "檢視濫用日誌中的非公開資料", - "right-abusefilter-private-log": "檢視防濫用過濾器非公開詳細資料存取日誌", + "right-abusefilter-privatedetails": "檢視濫用日誌中的非公開資料", + "right-abusefilter-privatedetails-log": "檢視防濫用過濾器非公開詳細資料存取日誌", "right-abusefilter-modify-restricted": "修改防濫用過濾器使用已限制的動作", "right-abusefilter-revert": "還原所有指定防濫用過濾器做的變更", "right-abusefilter-view-private": "檢視標記為非公開的防濫用過濾器", "right-abusefilter-log-private": "檢視標記為非公開的濫用過濾器日誌項目", - "right-abusefilter-hide-log": "隱藏此日誌於濫用日誌", + "right-abusefilter-hide-log": "隱藏在濫用日誌的項目", "right-abusefilter-hidden-log": "檢視已隱藏的濫用日誌項目", "right-abusefilter-modify-global": "建立或修改全域濫用過濾器", "action-abusefilter-modify": "修改防濫用過濾器", "action-abusefilter-view": "檢視防濫用過濾器", "action-abusefilter-log": "檢視濫用日誌", "action-abusefilter-log-detail": "檢視濫用日誌詳細資料", - "action-abusefilter-private": "檢視濫用日誌中的非公開資料", - "action-abusefilter-private-log": "檢視防濫用過濾器非公開詳細資料存取日誌", + "action-abusefilter-privatedetails": "檢視濫用日誌中的非公開資料", + "action-abusefilter-privatedetails-log": "檢視防濫用過濾器非公開詳細資料存取日誌", "action-abusefilter-modify-restricted": "修改防濫用過濾器使用已限制的動作", "action-abusefilter-revert": "還原所有指定防濫用過濾器做的變更", "action-abusefilter-view-private": "檢視標記為非公開的防濫用過濾器", "action-abusefilter-log-private": "檢視標記為非公開的濫用過濾器日誌項目", - "abusefilter-log": "防濫用過濾器日誌", + "action-abusefilter-hide-log": "隱藏在濫用日誌的項目", + "action-abusefilter-hidden-log": "檢視已隱藏的濫用日誌項目", + "action-abusefilter-modify-global": "建立或修改全域濫用過濾器", "abusefilter-log-summary": "此日誌顯示曾觸發過濾器的所有操作清單。", "abusefilter-log-search": "搜尋濫用日誌", "abusefilter-log-search-user": "使用者:", - "abusefilter-log-search-filter": "過濾器 ID (以 | 符號分隔) :", + "abusefilter-log-search-group": "過濾器群組:", + "abusefilter-log-search-group-any": "任何", + "abusefilter-log-search-filter": "過濾器 ID:", + "abusefilter-log-search-filter-help": "以豎線字元分隔,全域過濾器以「$1」為前綴。", + "abusefilter-log-search-filter-help-central": "以豎線字元分隔", "abusefilter-log-search-title": "標題:", "abusefilter-log-search-wiki": "Wiki:", "abusefilter-log-search-impact": "影響:", @@ -87,7 +99,7 @@ "abusefilter-log-search-impact-saved": "僅儲存的變更", "abusefilter-log-search-impact-not-saved": "未儲存的變更", "abusefilter-log-search-entries-label": "可見性:", - "abusefilter-log-search-entries-all": "所有紀錄", + "abusefilter-log-search-entries-all": "所有項目", "abusefilter-log-search-entries-hidden": "只顯示隱藏項目", "abusefilter-log-search-entries-visible": "只顯示可見項目", "abusefilter-log-search-action-label": "觸發的操作:", @@ -108,19 +120,21 @@ "abusefilter-log-details-var": "變數", "abusefilter-log-details-val": "值", "abusefilter-log-details-vars": "動作參數", - "abusefilter-log-details-private": "非公開日誌詳細資料", + "abusefilter-log-details-privatedetails": "非公開日誌詳細資料", "abusefilter-log-details-ip": "來源 IP 位址", "abusefilter-log-details-checkuser": "查核使用者", "abusefilter-log-noactions": "無", + "abusefilter-log-noactions-filter": "無", "abusefilter-log-details-diff": "在編輯中所做的變更", "abusefilter-log-linkoncontribs": "濫用日誌", "abusefilter-log-linkoncontribs-text": "{{GENDER:$1|此使用者}}的濫用日誌", "abusefilter-log-linkonhistory": "檢視濫用日誌", "abusefilter-log-linkonhistory-text": "檢視此頁面的濫用日誌", - "abusefilter-log-hidden": "(隱藏項目)", - "abusefilter-log-hidden-implicit": "(隱藏,因修訂已刪除)", + "abusefilter-log-linkonundelete": "檢視濫用日誌", + "abusefilter-log-linkonundelete-text": "檢視此頁面的濫用日誌", + "abusefilter-log-hidden-implicit": "(因修訂已被刪除而隱藏)", "abusefilter-log-cannot-see-details": "您沒有權限查看此項目詳細資料。", - "abusefilter-log-cannot-see-private-details": "您沒有權限查看此項目的非公開詳細資料。", + "abusefilter-log-cannot-see-privatedetails": "您沒有權限查看此項目的非公開詳細資料。", "abusefilter-log-nonexistent": "指定 ID 的實體不存在。", "abusefilter-log-details-hidden": "此為非公開項目,您無法檢視詳細資料。", "abusefilter-log-details-hidden-implicit": "因相關修訂為非公開項目,您無法檢視詳細資料。", @@ -138,17 +152,20 @@ "log-action-filter-abusefilter-create": "新過濾器建立", "log-action-filter-abusefilter-modify": "過濾器修改", "log-action-filter-suppress-abuselog": "濫用日誌監督", + "log-action-filter-rights-blockautopromote": "自動提升封鎖", + "log-action-filter-rights-restoreautopromote": "自動提升復原", "logentry-abusefilterprivatedetails-access": "$1{{GENDER:$2|存取了}}$3的非公開詳細資料", + "logentry-rights-blockautopromote": "$1{{GENDER:$2|封鎖}}了{{GENDER:$4|$3}}為期$5時限的自動提升", + "logentry-rights-restoreautopromote": "$1{{GENDER:$2|還原}}{{GENDER:$4|$3}}的自動提升能力", "abusefilterprivatedetails-log-name": "防濫用過濾器非公開詳細資料存取日誌", - "abusefilter-management": "防濫用過濾器管理", "abusefilter-list": "所有過濾器", "abusefilter-list-id": "過濾器 ID", "abusefilter-list-pattern": "模式", "abusefilter-list-status": "狀態", "abusefilter-list-public": "公開描述", "abusefilter-list-consequences": "處理方式", - "abusefilter-list-visibility": "公開/非公開", - "abusefilter-list-hitcount": "命中次數", + "abusefilter-list-visibility": "可見性", + "abusefilter-list-hitcount": "觸發次數", "abusefilter-list-edit": "編輯", "abusefilter-list-details": "詳細資料", "abusefilter-list-limit": "每頁顯示筆數:", @@ -159,9 +176,10 @@ "abusefilter-enabled": "已開啟", "abusefilter-deleted": "已刪除", "abusefilter-disabled": "已停用", - "abusefilter-throttled": "受限制", - "abusefilter-hitcount": "$1 次命中", + "abusefilter-throttled": "已受限", + "abusefilter-hitcount": "$1 次{{PLURAL:$1|觸發}}", "abusefilter-new": "建立新的過濾器", + "abusefilter-import-button": "匯入過濾器", "abusefilter-return": "返回過濾器管理", "abusefilter-status-global": "全域", "abusefilter-list-options": "選項", @@ -182,27 +200,30 @@ "abusefilter-list-options-search-like": "純文字查詢", "abusefilter-list-options-search-rlike": "正規表達式", "abusefilter-list-options-search-irlike": "不區分大小寫的正規表達式", + "abusefilter-list-invalid-searchmode": "指定的搜尋模式無效。", "abusefilter-list-regexerror": "搜尋時發生錯誤:正規表達式語法錯誤。", "abusefilter-list-options-submit": "更新", "abusefilter-tools-text": "本頁提供可協助您製訂與檢測防濫用過濾器的工具。", "abusefilter-tools-expr": "表示法測試器", "abusefilter-tools-submitexpr": "評估", + "abusefilter-tools-syntax-error": "此過濾器含有無效語法。", "abusefilter-tools-reautoconfirm": "還原自動確認狀態", "abusefilter-tools-reautoconfirm-user": "使用者:", "abusefilter-tools-reautoconfirm-submit": "重新自動確認", + "abusefilter-tools-restoreautopromote": "自動確認權限透過防濫用過濾器工具還原。", "abusefilter-reautoconfirm-none": "該使用者之自動確認狀態並沒有被停止過。", "abusefilter-reautoconfirm-notallowed": "您未被允許還原自動確認狀態。", "abusefilter-reautoconfirm-done": "該帳號的自動確認狀態已被還原", - "abusefilter-status": "在最近 $1 次近期變更中,有 $2 ($3%) 個過濾器達到 $4 次的比較條件限制,且有 $5 ($6%) 次近期變更符合其中一個已開啟的過濾器。", + "abusefilter-status": "在最近 $1 次近期變更中,有 $2($3%)個過濾器達到 $4 次的比較條件限制,且有 $5($6%)次近期變更符合其中至少一個已開啟的過濾器。", "abusefilter-edit": "正在編輯防濫用過濾器", "abusefilter-edit-subtitle": "正在編輯過濾器 $1", "abusefilter-edit-subtitle-new": "正在建立過濾器", "abusefilter-edit-token-not-match": "編輯沒被儲存!請再儲存一次看看。", - "abusefilter-edit-oldwarning": "<strong>您正編輯舊版本的過濾器。\n統計資訊引用的是最近版本的過濾器資訊。\n若您儲存目前的修改,您將會覆蓋所有自您修訂版本之後的所有變更。</strong> •\n[[Special:AbuseFilter/history/$2|返回此過濾器歷史]]。", + "abusefilter-edit-oldwarning": "<strong>你正在編輯該過濾器的舊版本。統計中引用的是該過濾器的最新版本。如果你保存你的編輯,所編輯版本之後的所有更改均會被覆蓋。</strong> • [[Special:AbuseFilter/history/$2|返回該過濾器的歷史記錄]]。", + "abusefilter-edit-oldwarning-view": "<strong>您正檢視此過濾器的舊版本。\n引用的統計內容是適用於最新版本的過濾器。</strong> •\n[[Special:AbuseFilter/history/$2|返回到此過濾器的歷史紀錄]]。", "abusefilter-edit-status-label": "統計資訊:", - "abusefilter-edit-status": "在最近 $1 次{{PLURAL:$1|操作}}中,此過濾器已命中 $2 ($3%) 次。", - "abusefilter-edit-status-profile": "在最近 $1 次操作中,此過濾器已命中 $2 ($3%) 次。\n其平均執行時間為 $4 ms,且使用了條件限制中 $5 個條件。", - "abusefilter-edit-throttled-warning": "'''警告:'''該過濾器已自動標示為有害。作為安全措施,以下操作將不會執行($1)。請複查並[[mw:Extension:AbuseFilter/Conditions|優化]]您的條件來移除該限制", + "abusefilter-edit-status": "在最近 $1 次{{PLURAL:$1|操作}}中,此過濾器已觸發 $2($3%)次。\n其平均執行時間為 $4 ms,且使用了條件限制中 $5 個{{PLURAL:$5|條件}}。", + "abusefilter-edit-throttled-warning": "'''警告:'''該過濾器已自動標示為有害。作為安全措施,以下操作將不會執行:$1。請複查並[[mw:Extension:AbuseFilter/Conditions|優化]]您的條件來移除該限制", "abusefilter-edit-new": "新過濾器", "abusefilter-edit-save": "儲存過濾器", "abusefilter-edit-id": "過濾器 ID:", @@ -220,37 +241,42 @@ "abusefilter-edit-notes": "說明:", "abusefilter-edit-lastmod": "過濾器最近修改:", "abusefilter-edit-lastmod-text": "於 $1 由 $2", - "abusefilter-edit-hitcount": "過濾器命中次數:", + "abusefilter-edit-hitcount": "過濾器觸發次數:", "abusefilter-edit-consequences": "符合條件時採取的動作", "abusefilter-edit-action-warn": "在警告使用者後才觸發這些動作", "abusefilter-edit-action-disallow": "禁止使用者進行可疑動作", "abusefilter-edit-action-blockautopromote": "撤銷使用者的自動確認狀態", "abusefilter-edit-action-degroup": "從所有已授權的群組中移除該使用者", "abusefilter-edit-action-block": "禁止該使用者及/或 IP 位址進行編輯", - "abusefilter-edit-action-blocktalk": "阻止用戶和/或 IP 位址在封禁期間編輯自己的對話頁", + "abusefilter-edit-action-blocktalk": "阻止使用者和/或 IP 位址在封禁期間編輯自己的對話頁", "abusefilter-edit-action-throttle": "僅在使用者超過頻率限制後觸發動作", "abusefilter-edit-action-rangeblock": "封鎖使用者來源位置的對應子網段區間。", "abusefilter-edit-action-tag": "標記該編輯需要進一步審查", "abusefilter-edit-throttle-count": "允許的操作次數:", "abusefilter-edit-throttle-period": "期間(秒):", - "abusefilter-edit-throttle-groups": "群組門檻依︰", - "abusefilter-edit-throttle-ip": "IP 位址", - "abusefilter-edit-throttle-user": "使用者帳號", - "abusefilter-edit-throttle-range": "/16 範圍", - "abusefilter-edit-throttle-creationdate": "建立帳號的伺服器時間", - "abusefilter-edit-throttle-editcount": "編輯次數", - "abusefilter-edit-throttle-site": "整個站台", - "abusefilter-edit-throttle-page": "頁面", - "abusefilter-throttle-details": "允許每 $2 {{PLURAL:$2|秒|秒}} $1 次{{PLURAL:$1|操作|操作}},門檻群組依:$3", + "abusefilter-edit-throttle-groups": "群組受限依︰", + "abusefilter-edit-throttle-groups-help": "查看$1。", + "abusefilter-edit-throttle-groups-help-text": "在mediawiki.org上的文件", + "abusefilter-edit-throttle-hidden-placeholder": "用逗號分隔來與 AND 相接,並以換行來與 OR 相接。", + "abusefilter-edit-throttle-placeholder": "用逗號分隔來與 AND 相接,並逐一插入來與 OR 相接。", + "abusefilter-throttle-ip": "IP 位址", + "abusefilter-throttle-user": "使用者帳號", + "abusefilter-throttle-range": "/16 範圍", + "abusefilter-throttle-creationdate": "帳號建立日期", + "abusefilter-throttle-editcount": "編輯次數", + "abusefilter-throttle-site": "整個站台", + "abusefilter-throttle-page": "頁面", + "abusefilter-throttle-none": "(無)", + "abusefilter-throttle-details": "允許每 $2 {{PLURAL:$2|秒|秒}} $1 次{{PLURAL:$1|操作|操作}},群組受限依:$3", "abusefilter-edit-warn-message": "警告用的系統訊息:", "abusefilter-edit-warn-other": "其他訊息", - "abusefilter-edit-warn-other-label": "其他訊息的頁面名稱:\n:''(不含 \"MediaWiki:\" 字首)''", + "abusefilter-edit-warn-other-label": "其他訊息的頁面名稱:\n:'''(不含「MediaWiki:」字首)'''", "abusefilter-edit-warn-actions": "動作:", "abusefilter-edit-warn-preview": "顯示/隱藏已選預覽的訊息", "abusefilter-edit-warn-edit": "建立/編輯已選擇的訊息", "abusefilter-edit-disallow-message": "使用於不允許的系統訊息:", "abusefilter-edit-disallow-other": "其它訊息", - "abusefilter-edit-disallow-other-label": "其它訊息的頁面名稱:\n:''(不含 \"MediaWiki:\" 字首)''", + "abusefilter-edit-disallow-other-label": "其它訊息的頁面名稱:\n:'''(不含「MediaWiki:」字首)'''", "abusefilter-edit-disallow-actions": "操作:", "abusefilter-edit-disallow-preview": "顯示/隱藏已選預覽的訊息", "abusefilter-edit-disallow-edit": "建立/編輯已選擇的訊息", @@ -280,10 +306,18 @@ "abusefilter-edit-export": "匯出此過濾器至其他 Wiki", "abusefilter-edit-syntaxok": "沒有偵測到語法錯誤。", "abusefilter-edit-syntaxerr": "已偵測到語法錯誤:$1", + "abusefilter-edit-warn-leave": "離開頁面會導致您失去對此過濾器所作出的任何更改。", "abusefilter-edit-bad-tags": "您指定的一個或多個標籤無效。標籤不能過長、不可包含特殊字元,而且不能被其他軟體所占用。嘗試選擇一個新的標籤名。", "abusefilter-edit-notallowed": "您沒有權限建立或編輯防濫用過濾器", "abusefilter-edit-notallowed-global": "您沒有權限建立或編輯全域防濫用過濾器", - "abusefilter-edit-notallowed-global-custom-msg": "全域過濾器不支援使用字訂警告訊息", + "abusefilter-edit-notallowed-global-custom-msg": "全域過濾器不支援使用自定義警告或非允許的訊息", + "abusefilter-edit-invalid-warn-message": "警告訊息不可留空。", + "abusefilter-edit-invalid-disallow-message": "禁止訊息不可留空。", + "abusefilter-edit-invalid-throttlecount": "受限行動次數必須為正整數。", + "abusefilter-edit-invalid-throttleperiod": "受限週期必須為正整數。", + "abusefilter-edit-empty-throttlegroups": "至少要選擇一個受限群組。", + "abusefilter-edit-duplicated-throttlegroups": "受限群組不可重複。", + "abusefilter-edit-invalid-throttlegroups": "所指定受限群組無效。", "abusefilter-edit-builder-select": "請選擇要新增至游標的項目", "abusefilter-edit-builder-group-op-arithmetic": "算術運算子", "abusefilter-edit-builder-op-arithmetic-addition": "加法 (+)", @@ -314,8 +348,9 @@ "abusefilter-edit-builder-misc-contains": "左邊的字串含有右邊的字串 (contains)", "abusefilter-edit-builder-misc-stringlit": "字串 (\"\")", "abusefilter-edit-builder-misc-tern": "三元運算子 (X ? Y : Z)", - "abusefilter-edit-builder-misc-cond": "條件 (if X then Y else Z)", - "abusefilter-edit-builder-group-funcs": "函數", + "abusefilter-edit-builder-misc-cond": "條件(if X then Y else Z end)", + "abusefilter-edit-builder-misc-cond-short": "簡短條件(if X then Y end)", + "abusefilter-edit-builder-group-funcs": "函式", "abusefilter-edit-builder-funcs-length": "字串長度 (length)", "abusefilter-edit-builder-funcs-lcase": "轉為小寫 (lcase)", "abusefilter-edit-builder-funcs-ucase": "轉為大寫 (ucase)", @@ -328,7 +363,7 @@ "abusefilter-edit-builder-funcs-count": "字串 X 在字串 Y 裡出現的次數 (count)", "abusefilter-edit-builder-funcs-rcount": "正規表式法 X 出現在字串 Y 的次數 (rcount)", "abusefilter-edit-builder-funcs-get_matches": "正規表達式匹配文字中的捕捉陣列(get_matches)", - "abusefilter-edit-builder-funcs-rmwhitespace": "移除空白字元 (rmwhitespace)", + "abusefilter-edit-builder-funcs-rmwhitespace": "移除空白字元(rmwhitespace)", "abusefilter-edit-builder-funcs-rmspecials": "移除特殊字元 (rmspecials)", "abusefilter-edit-builder-funcs-ip_in_range": "IP 是否在範圍內? (ip_in_range)", "abusefilter-edit-builder-funcs-contains-any": "在 OR 模式中搜尋字串中是否包含任何子字串。 (contains_any)", @@ -385,12 +420,12 @@ "abusefilter-edit-builder-vars-all-links": "新內容中的所有外部連結", "abusefilter-edit-builder-vars-added-links": "所有編輯後加入的外部連結", "abusefilter-edit-builder-vars-removed-links": "所有編輯後移除的外部連結", - "abusefilter-edit-builder-vars-old-text": "在編輯前舊頁面上的 Wikitext(已不使用)", - "abusefilter-edit-builder-vars-new-text": "在編後新頁面上的 Wikitext", + "abusefilter-edit-builder-vars-old-wikitext": "在編輯前舊頁面上的 wiki 標記式語言", + "abusefilter-edit-builder-vars-new-wikitext": "在編後新頁面上的 wiki 標記式語言", "abusefilter-edit-builder-vars-new-pst": "新頁面 Wikitext,於儲存前轉換", "abusefilter-edit-builder-vars-diff-pst": "編輯所做的變更 Unified,儲存前轉換", "abusefilter-edit-builder-vars-addedlines-pst": "編輯加入的行,儲存前轉換", - "abusefilter-edit-builder-vars-new-text-stripped": "新頁面文字,移除所有標籤", + "abusefilter-edit-builder-vars-new-text": "新頁面文字,移除所有語法", "abusefilter-edit-builder-vars-new-html": "新修訂已解析後的 HTML 原始碼", "abusefilter-edit-builder-vars-restrictions-edit": "編輯該頁面的保護層級", "abusefilter-edit-builder-vars-restrictions-move": "移動該頁面的保護層級", @@ -404,19 +439,21 @@ "abusefilter-edit-builder-vars-movedto-restrictions-move": "移動目標頁面的移動保護層級", "abusefilter-edit-builder-vars-movedto-restrictions-create": "移動目標頁面的建立保護", "abusefilter-edit-builder-vars-movedto-restrictions-upload": "移動目標檔案的上傳保護", - "abusefilter-edit-builder-vars-old-text-stripped": "舊頁面文字,移除所有標籤", + "abusefilter-edit-builder-vars-old-text": "舊頁面文字,移除所有語法(不再使用)", "abusefilter-edit-builder-vars-old-links": "舊內容中的所有外部連結", "abusefilter-edit-builder-vars-old-html": "舊頁面 Wikitext,已解析為 HTML(已不使用)", - "abusefilter-edit-builder-vars-minor-edit": "是否將編輯標示為小修訂", + "abusefilter-edit-builder-vars-minor-edit": "是否將編輯標示為小修訂(不再使用)", "abusefilter-edit-builder-vars-file-sha1": "檔案內容的 SHA1 雜湊值", - "abusefilter-edit-builder-vars-file-size": "文件大小(單位:位元組)", - "abusefilter-edit-builder-vars-file-mime": "文件的MIME類型", - "abusefilter-edit-builder-vars-file-mediatype": "文件的媒體類型", - "abusefilter-edit-builder-vars-file-width": "文件寬度(像素)", - "abusefilter-edit-builder-vars-file-height": "文件高度(像素)", + "abusefilter-edit-builder-vars-file-size": "檔案大小(單位:位元組)", + "abusefilter-edit-builder-vars-file-mime": "檔案的MIME類型", + "abusefilter-edit-builder-vars-file-mediatype": "檔案的媒體類型", + "abusefilter-edit-builder-vars-file-width": "檔案寬度(像素)", + "abusefilter-edit-builder-vars-file-height": "檔案高度(像素)", "abusefilter-edit-builder-vars-file-bits-per-channel": "檔案位元色板", + "abusefilter-edit-builder-vars-wiki-name": "Wiki 的資料庫名稱", + "abusefilter-edit-builder-vars-wiki-language": "Wiki 的語言代碼", "abusefilter-filter-log": "最近過濾器變更", - "abusefilter-history": "防濫用過濾器 #$1 的修訂歷史", + "abusefilter-history": "防濫用過濾器#$1的修訂歷史", "abusefilter-history-foruser": "由 $1 所作的變更", "abusefilter-history-hidden": "已隱藏", "abusefilter-history-enabled": "已開啟", @@ -430,7 +467,7 @@ "abusefilter-history-actions": "動作", "abusefilter-history-backedit": "返回過濾器編輯器", "abusefilter-history-deleted": "已刪除", - "abusefilter-history-filterid": "篩選器", + "abusefilter-history-filterid": "過濾器", "abusefilter-history-select-legend": "精確搜尋", "abusefilter-history-select-user": "使用者:", "abusefilter-history-select-filter": "過濾器ID:", @@ -447,20 +484,23 @@ "abusefilter-exception-noparams": "於第 $1 個字元處未傳入函式「$2」的參數。\n應要有 $3 個{{PLURAL:$3|參數|參數}}。", "abusefilter-exception-dividebyzero": "於第 $1 個字元處嘗試非法將 $2 除以 0。", "abusefilter-exception-unrecognisedvar": "於第 $1 個字元處出現無法識別的變數 $2。", - "abusefilter-exception-notenoughargs": "於第 $1 個字元處函數 $2 未傳入足夠的參數。\n\t預期有 $3 個參數,僅使用了 $4 個", + "abusefilter-exception-notenoughargs": "於第 $1 個字元處呼叫的函式$2未傳入足夠的參數。預期應有 $3 個參數,僅使用了 $4 個", + "abusefilter-exception-toomanyargs": "於第 $1 個字元處呼叫的函式$2傳入太多參數。預期應有 $3 個{{PLURAL:$3|參數}},但使用了 $4 個", "abusefilter-exception-regexfailure": "於第 $1 個字元處的正規表示法「$2」錯誤。", - "abusefilter-exception-overridebuiltin": "於第 $1 個字元處非法覆蓋內建的變數 \"$2\"。", + "abusefilter-exception-overridebuiltin": "於第 $1 個字元處非法覆蓋內建的識別碼「$2」。", "abusefilter-exception-outofbounds": "於第 $1 個字元處使用了不存在的陣列項目 $2(陣列大小 = $3)。", + "abusefilter-exception-negativeindex": "陣列裡不允許負值索引,在位置$1的字元出現為「$2」的索引。", "abusefilter-exception-notarray": "於第 $1 個字元處於非陣列中使用了陣列項目。", "abusefilter-exception-unclosedcomment": "在第 $1 字元有未關閉評論。", "abusefilter-exception-invalidiprange": "在字元 $1 提供了無效 IP 範圍 \"$2\"。", "abusefilter-exception-disabledvar": "在 $1 字元上的變數 $2 已不使用。", + "abusefilter-exception-variablevariable": "set 與 set_var 的第一個參數應為字面常數,在字元 $1 處找到。", "abusefilter-action-tag": "標籤", - "abusefilter-action-throttle": "門檻值", + "abusefilter-action-throttle": "受限", "abusefilter-action-warn": "警告", "abusefilter-action-blockautopromote": "撤銷自動確認", "abusefilter-action-block": "封鎖", - "abusefilter-action-degroup": "從使用者群組中移除", + "abusefilter-action-degroup": "從群組中移除", "abusefilter-action-rangeblock": "範圍封鎖", "abusefilter-action-disallow": "禁止", "abusefilter-revert-title": "還原所有由過濾器 $1 所做的變更", @@ -489,7 +529,7 @@ "abusefilter-test-period-end": "變更時間早於:", "abusefilter-test-page": "對頁面做的變更:", "abusefilter-test-shownegative": "顯示不符合過濾器的變更", - "abusefilter-test-syntaxerr": "您輸入的過濾器語法錯誤。\n請點選 \"{{int:abusefilter-edit-check}}\" 按鈕取得完整說明。", + "abusefilter-test-syntaxerr": "您輸入的過濾器語法錯誤。請點選「{{int:abusefilter-edit-check}}」按鈕取得完整說明。", "abusefilter-test-badtitle": "您輸入的頁面標題無效。它可能包含無法作為標題使用的一個或多個字元。", "abusefilter-test-action": "操作類型:", "abusefilter-test-search-type-all": "所有操作", @@ -502,7 +542,7 @@ "abusefilter-examine": "檢查單次變更", "abusefilter-examine-intro": "此頁面讓您可檢查由防濫用過濾器每次變更所產生的變數並使用過濾器測試。", "abusefilter-examine-legend": "請選擇變更", - "abusefilter-examine-diff": "Diff URL:", + "abusefilter-examine-diff": "差別 URL:", "abusefilter-examine-user": "使用者:", "abusefilter-examine-title": "頁面標題:", "abusefilter-examine-submit": "搜尋", @@ -517,15 +557,16 @@ "abusefilter-examine-noresults": "您提供的搜尋參數找不到任何結果。", "abusefilter-topnav": "'''防濫用過濾器導覽'''", "abusefilter-topnav-home": "首頁", + "abusefilter-topnav-recentchanges": "最近過濾器變更", "abusefilter-topnav-test": "批次測試", "abusefilter-topnav-examine": "檢查過去編輯", "abusefilter-topnav-log": "濫用日誌", "abusefilter-topnav-tools": "除錯工具", - "abusefilter-topnav-import": "匯入過濾器", - "abusefilter-log-name": "修改防濫用過濾器日誌", + "abusefilter-log-name": "防濫用過濾器修改日誌", "abusefilter-log-header": "此日誌顯示了所有對過濾器所作變更摘要。\n詳細資訊請見最近過濾器變更[[Special:AbuseFilter/history|清單]]。", "abusefilter-logentry-create": "$1{{GENDER:$2|建立}}了$4($5)", "abusefilter-logentry-modify": "$1{{GENDER:$2|修改了}}$4($5)", + "abusefilter-log-invalid-filter": "指定的部份過濾器 ID 無效。", "abusefilter-log-noresults": "沒有結果", "abusefilter-diff-title": "修訂版本間差異", "abusefilter-diff-item": "項目", @@ -538,11 +579,12 @@ "abusefilter-diff-next": "較新的變更", "abusefilter-import-intro": "您可以使用此介面匯入來自其他 Wiki 的過濾器。\n在來源的 Wiki,點選於 \"{{int:abusefilter-edit-tools}}\" 下方的 \"{{int:abusefilter-edit-export}}\"。\n複製文字框中顯示的文字,並將該文字貼上至此文字框中,然後點選 \"{{int:abusefilter-import-submit}}\"。", "abusefilter-import-submit": "匯入資料", + "abusefilter-import-invalid-data": "您嘗試匯入的資料無效", "abusefilter-group-default": "預設", "abusefilter-http-error": "發生 HTTP 錯誤:$1。", - "abusefilter-view-private-submit": "檢視非公開詳細資料", - "abusefilter-view-private": "檢視非公開詳細資料", - "abusefilter-view-private-reason": "存取非公開詳細資料的原因:", + "abusefilter-view-privatedetails-submit": "檢視非公開詳細資料", + "abusefilter-view-privatedetails-legend": "檢視非公開詳細資料", + "abusefilter-view-privatedetails-reason": "存取非公開詳細資料的原因:", "abusefilter-log-details-id": "日誌ID", "abusefilter-invalid-request": "無效請求!您必須透過[[Special:AbuseLog/$1]]上的表單提供原因後才能存取非公開日誌詳細資料。", "abusefilter-invalid-request-noid": "無效請求!您必須透過在濫用日誌詳細資料上的表單提供原因後才能訪問非公開日誌詳細資料。", diff --git a/AbuseFilter/i18n/zh-hk.json b/AbuseFilter/i18n/zh-hk.json index 92c0fb6d..3a3ce862 100644 --- a/AbuseFilter/i18n/zh-hk.json +++ b/AbuseFilter/i18n/zh-hk.json @@ -1,12 +1,14 @@ { "@metadata": { "authors": [ - "Liuxinyu970226" + "Liuxinyu970226", + "Sunny00217" ] }, "abusefilter-log-search-user": "用戶:", "abusefilter-tools-reautoconfirm-user": "用戶:", "abusefilter-edit-action-blockautopromote": "撤銷用戶自動確認狀態", + "abusefilter-edit-action-blocktalk": "阻止用戶和/或 IP 位址在封禁期間編輯自己的對話頁", "abusefilter-history-user": "用戶", "abusefilter-history-select-user": "用戶:", "abusefilter-examine-user": "用戶:" diff --git a/AbuseFilter/includes/AFComputedVariable.php b/AbuseFilter/includes/AFComputedVariable.php index 15847598..4a3a5c55 100644 --- a/AbuseFilter/includes/AFComputedVariable.php +++ b/AbuseFilter/includes/AFComputedVariable.php @@ -1,14 +1,32 @@ <?php -use Wikimedia\Rdbms\Database; -use MediaWiki\MediaWikiServices; +use MediaWiki\Extension\AbuseFilter\Hooks\AbuseFilterHookRunner; use MediaWiki\Logger\LoggerFactory; +use MediaWiki\MediaWikiServices; +use Wikimedia\IPUtils; +use Wikimedia\Rdbms\Database; class AFComputedVariable { - public $mMethod, $mParameters; + /** + * @var string The method used to compute the variable + */ + public $mMethod; + /** + * @var array Parameters to be used with the specified method + */ + public $mParameters; + /** + * @var User[] Cache containing User objects already constructed + */ public static $userCache = []; + /** + * @var WikiPage[] Cache containing Page objects already constructed + */ public static $articleCache = []; + /** @var float The amount of time to subtract from profiling */ + public static $profilingExtraTime = 0; + /** * @param string $method * @param array $parameters @@ -23,11 +41,12 @@ class AFComputedVariable { * * * @param string $wikitext - * @param Article $article + * @param WikiPage $article + * @param User $user Context user * * @return object */ - public function parseNonEditWikitext( $wikitext, $article ) { + public function parseNonEditWikitext( $wikitext, WikiPage $article, User $user ) { static $cache = []; $cacheKey = md5( $wikitext ) . ':' . $article->getTitle()->getPrefixedText(); @@ -36,11 +55,10 @@ class AFComputedVariable { return $cache[$cacheKey]; } - global $wgParser; $edit = (object)[]; - $options = new ParserOptions; - $options->setTidy( true ); - $edit->output = $wgParser->parse( $wikitext, $article->getTitle(), $options ); + $options = ParserOptions::newFromUser( $user ); + $parser = MediaWikiServices::getInstance()->getParser(); + $edit->output = $parser->parse( $wikitext, $article->getTitle(), $options ); $cache[$cacheKey] = $edit; return $edit; @@ -72,30 +90,25 @@ class AFComputedVariable { } if ( $user instanceof User ) { - self::$userCache[$username] = $user; - return $user; - } - - if ( IP::isIPAddress( $username ) ) { - $u = new User; - $u->setName( $username ); - self::$userCache[$username] = $u; - return $u; + $ret = $user; + } elseif ( IPUtils::isIPAddress( $username ) ) { + $ret = new User; + $ret->setName( $username ); + } else { + $ret = User::newFromName( $username ); + $ret->load(); } + self::$userCache[$username] = $ret; - $user = User::newFromName( $username ); - $user->load(); - self::$userCache[$username] = $user; - - return $user; + return $ret; } /** * @param int $namespace * @param string $title - * @return Article + * @return WikiPage */ - public static function articleFromTitle( $namespace, $title ) { + public function pageFromTitle( $namespace, $title ) { if ( isset( self::$articleCache["$namespace:$title"] ) ) { return self::$articleCache["$namespace:$title"]; } @@ -105,20 +118,30 @@ class AFComputedVariable { } $logger = LoggerFactory::getInstance( 'AbuseFilter' ); - $logger->debug( "Creating article object for $namespace:$title in cache" ); + $logger->debug( "Creating wikipage object for $namespace:$title in cache" ); - // TODO: use WikiPage instead! - $t = Title::makeTitle( $namespace, $title ); - self::$articleCache["$namespace:$title"] = new Article( $t ); + $t = $this->buildTitle( $namespace, $title ); + self::$articleCache["$namespace:$title"] = WikiPage::factory( $t ); return self::$articleCache["$namespace:$title"]; } /** - * @param Article $article + * Mockable wrapper + * + * @param int $namespace + * @param string $title + * @return Title + */ + protected function buildTitle( $namespace, $title ) : Title { + return Title::makeTitle( $namespace, $title ); + } + + /** + * @param WikiPage $article * @return array */ - public static function getLinksFromDB( $article ) { + public static function getLinksFromDB( WikiPage $article ) { // Stolen from ConfirmEdit, SimpleCaptcha::getLinksFromTracker $id = $article->getId(); if ( !$id ) { @@ -126,35 +149,46 @@ class AFComputedVariable { } $dbr = wfGetDB( DB_REPLICA ); - $res = $dbr->select( + return $dbr->selectFieldValues( 'externallinks', - [ 'el_to' ], + 'el_to', [ 'el_from' => $id ], __METHOD__ ); - $links = []; - foreach ( $res as $row ) { - $links[] = $row->el_to; - } - return $links; } /** * @param AbuseFilterVariableHolder $vars - * @return AFPData|array|int|mixed|null|string + * @return AFPData * @throws MWException * @throws AFPException */ - public function compute( $vars ) { + public function compute( AbuseFilterVariableHolder $vars ) { + // TODO: find a way to inject the User object from hook parameters. + global $wgUser; + + // Used for parsing wikitext from saved revisions and checking for + // whether to show fields. Do not use $wgUser below here, in preparation + // for eventually injecting. See T246733 + $computeForUser = $wgUser; + + $vars->setLogger( LoggerFactory::getInstance( 'AbuseFilter' ) ); $parameters = $this->mParameters; $result = null; - if ( !Hooks::run( 'AbuseFilter-interceptVariable', - [ $this->mMethod, $vars, $parameters, &$result ] ) ) { + $hookRunner = AbuseFilterHookRunner::getRunner(); + + if ( !$hookRunner->onAbuseFilterInterceptVariable( + $this->mMethod, + $vars, + $parameters, + $result + ) ) { return $result instanceof AFPData ? $result : AFPData::newFromPHPVar( $result ); } + $services = MediaWikiServices::getInstance(); switch ( $this->mMethod ) { case 'diff': // Currently unused. Kept for backwards compatibility since it remains @@ -186,13 +220,12 @@ class AFComputedVariable { $diff = $vars->getVar( $parameters['diff-var'] )->toString(); $line_prefix = $parameters['line-prefix']; $diff_lines = explode( "\n", $diff ); - $interest_lines = []; + $result = []; foreach ( $diff_lines as $line ) { if ( substr( $line, 0, 1 ) === $line_prefix ) { - $interest_lines[] = substr( $line, strlen( $line_prefix ) ); + $result[] = substr( $line, strlen( $line_prefix ) ); } } - $result = $interest_lines; break; case 'links-from-wikitext': // This should ONLY be used when sharing a parse operation with the edit. @@ -201,32 +234,42 @@ class AFComputedVariable { if ( isset( $parameters['article'] ) ) { $article = $parameters['article']; } else { - $article = self::articleFromTitle( + $article = $this->pageFromTitle( $parameters['namespace'], $parameters['title'] ); } if ( $article->getContentModel() === CONTENT_MODEL_WIKITEXT ) { + // Shared with the edit, don't count it in profiling + $startTime = microtime( true ); $textVar = $parameters['text-var']; $new_text = $vars->getVar( $textVar )->toString(); $content = ContentHandler::makeContent( $new_text, $article->getTitle() ); - $editInfo = $article->prepareContentForEdit( $content ); - $links = array_keys( $editInfo->output->getExternalLinks() ); + try { + // @fixme TEMPORARY WORKAROUND FOR T187153 + $editInfo = $article->prepareContentForEdit( $content ); + $links = array_keys( $editInfo->output->getExternalLinks() ); + } catch ( Error $e ) { + $logger = LoggerFactory::getInstance( 'AbuseFilter' ); + $logger->warning( 'Caught Error, case 1 - T187153' ); + $links = []; + } $result = $links; + self::$profilingExtraTime += ( microtime( true ) - $startTime ); break; } // Otherwise fall back to database case 'links-from-wikitext-nonedit': case 'links-from-wikitext-or-database': - // TODO: use Content object instead, if available! In any case, use WikiPage, not Article. - $article = self::articleFromTitle( + // TODO: use Content object instead, if available! + $article = $this->pageFromTitle( $parameters['namespace'], $parameters['title'] ); $logger = LoggerFactory::getInstance( 'AbuseFilter' ); - if ( $vars->getVar( 'context' )->toString() == 'filter' ) { + if ( $vars->forFilter ) { $links = $this->getLinksFromDB( $article ); $logger->debug( 'Loading old links from DB' ); } elseif ( $article->getContentModel() === CONTENT_MODEL_WIKITEXT ) { @@ -234,7 +277,11 @@ class AFComputedVariable { $textVar = $parameters['text-var']; $wikitext = $vars->getVar( $textVar )->toString(); - $editInfo = $this->parseNonEditWikitext( $wikitext, $article ); + $editInfo = $this->parseNonEditWikitext( + $wikitext, + $article, + $computeForUser + ); $links = array_keys( $editInfo->output->getExternalLinks() ); } else { // TODO: Get links from Content object. But we don't have the content object. @@ -256,10 +303,10 @@ class AFComputedVariable { $oldLinks = explode( "\n", $oldLinks ); $newLinks = explode( "\n", $newLinks ); - if ( $this->mMethod == 'link-diff-added' ) { + if ( $this->mMethod === 'link-diff-added' ) { $result = array_diff( $newLinks, $oldLinks ); } - if ( $this->mMethod == 'link-diff-removed' ) { + if ( $this->mMethod === 'link-diff-removed' ) { $result = array_diff( $oldLinks, $newLinks ); } break; @@ -268,31 +315,44 @@ class AFComputedVariable { if ( isset( $parameters['article'] ) ) { $article = $parameters['article']; } else { - $article = self::articleFromTitle( + $article = $this->pageFromTitle( $parameters['namespace'], $parameters['title'] ); } if ( $article->getContentModel() === CONTENT_MODEL_WIKITEXT ) { + // Shared with the edit, don't count it in profiling + $startTime = microtime( true ); $textVar = $parameters['wikitext-var']; $new_text = $vars->getVar( $textVar )->toString(); $content = ContentHandler::makeContent( $new_text, $article->getTitle() ); - $editInfo = $article->prepareContentForEdit( $content ); + try { + // @fixme TEMPORARY WORKAROUND FOR T187153 + $editInfo = $article->prepareContentForEdit( $content ); + } catch ( Error $e ) { + $logger = LoggerFactory::getInstance( 'AbuseFilter' ); + $logger->warning( 'Caught Error, case 2 - T187153' ); + $result = ''; + break; + } if ( isset( $parameters['pst'] ) && $parameters['pst'] ) { $result = $editInfo->pstContent->serialize( $editInfo->format ); } else { $newHTML = $editInfo->output->getText(); // Kill the PP limit comments. Ideally we'd just remove these by not setting the // parser option, but then we can't share a parse operation with the edit, which is bad. - $result = preg_replace( '/<!--\s*NewPP limit report[^>]*-->\s*$/si', '', $newHTML ); + // @fixme No awfulness scale can measure how awful this hack is. + $re = '/<!--\s*NewPP limit [^>]*-->\s*(?:<!--\s*Transclusion [^>]+-->\s*)?(?:<\/div>\s*)?$/i'; + $result = preg_replace( $re, '', $newHTML ); } + self::$profilingExtraTime += ( microtime( true ) - $startTime ); break; } // Otherwise fall back to database case 'parse-wikitext-nonedit': - // TODO: use Content object instead, if available! In any case, use WikiPage, not Article. - $article = self::articleFromTitle( $parameters['namespace'], $parameters['title'] ); + // TODO: use Content object instead, if available! + $article = $this->pageFromTitle( $parameters['namespace'], $parameters['title'] ); $textVar = $parameters['wikitext-var']; if ( $article->getContentModel() === CONTENT_MODEL_WIKITEXT ) { @@ -301,7 +361,11 @@ class AFComputedVariable { $result = $vars->getVar( $textVar )->toString(); } else { $text = $vars->getVar( $textVar )->toString(); - $editInfo = $this->parseNonEditWikitext( $text, $article ); + $editInfo = $this->parseNonEditWikitext( + $text, + $article, + $computeForUser + ); $result = $editInfo->output->getText(); } } else { @@ -315,10 +379,14 @@ class AFComputedVariable { case 'strip-html': $htmlVar = $parameters['html-var']; $html = $vars->getVar( $htmlVar )->toString(); - $result = StringUtils::delimiterReplace( '<', '>', '', $html ); + $stripped = StringUtils::delimiterReplace( '<', '>', '', $html ); + // We strip extra spaces to the right because the stripping above + // could leave a lot of whitespace. + // @fixme Find a better way to do this. + $result = TextContent::normalizeLineEndings( $stripped ); break; case 'load-recent-authors': - $title = Title::makeTitle( $parameters['namespace'], $parameters['title'] ); + $title = $this->buildTitle( $parameters['namespace'], $parameters['title'] ); if ( !$title->exists() ) { $result = ''; break; @@ -327,11 +395,12 @@ class AFComputedVariable { $result = self::getLastPageAuthors( $title ); break; case 'load-first-author': - $title = Title::makeTitle( $parameters['namespace'], $parameters['title'] ); + $title = $this->buildTitle( $parameters['namespace'], $parameters['title'] ); - $revision = $title->getFirstRevision(); + $revision = $services->getRevisionLookup()->getFirstRevision( $title ); if ( $revision ) { - $result = $revision->getUserText(); + $user = $revision->getUser(); + $result = $user === null ? '' : $user->getName(); } else { $result = ''; } @@ -339,11 +408,9 @@ class AFComputedVariable { break; case 'get-page-restrictions': $action = $parameters['action']; - $title = Title::makeTitle( $parameters['namespace'], $parameters['title'] ); + $title = $this->buildTitle( $parameters['namespace'], $parameters['title'] ); - $rights = $title->getRestrictions( $action ); - $rights = count( $rights ) ? $rights : []; - $result = $rights; + $result = $title->getRestrictions( $action ); break; case 'simple-user-accessor': $user = $parameters['user']; @@ -361,21 +428,31 @@ class AFComputedVariable { $result = call_user_func( [ $obj, $method ] ); break; + case 'user-block': + // @todo Support partial blocks + $user = $parameters['user']; + $result = (bool)$user->getBlock(); + break; case 'user-age': $user = $parameters['user']; $asOf = $parameters['asof']; $obj = self::getUserObject( $user ); - if ( $obj->getId() == 0 ) { + $registration = $obj->getRegistration(); + + if ( $obj->getId() === 0 ) { $result = 0; - break; + } else { + // HACK: If there's no registration date, assume 2008-01-15, Wikipedia Day + // in the year before the new user log was created. See T243469. + if ( $registration === null ) { + $registration = "20080115000000"; + } + $result = (int)wfTimestamp( TS_UNIX, $asOf ) - (int)wfTimestamp( TS_UNIX, $registration ); } - - $registration = $obj->getRegistration(); - $result = wfTimestamp( TS_UNIX, $asOf ) - wfTimestampOrNull( TS_UNIX, $registration ); break; case 'page-age': - $title = Title::makeTitle( $parameters['namespace'], $parameters['title'] ); + $title = $this->buildTitle( $parameters['namespace'], $parameters['title'] ); $firstRevisionTime = $title->getEarliestRevTime(); if ( !$firstRevisionTime ) { @@ -384,7 +461,7 @@ class AFComputedVariable { } $asOf = $parameters['asof']; - $result = wfTimestamp( TS_UNIX, $asOf ) - wfTimestampOrNull( TS_UNIX, $firstRevisionTime ); + $result = (int)wfTimestamp( TS_UNIX, $asOf ) - (int)wfTimestamp( TS_UNIX, $firstRevisionTime ); break; case 'user-groups': // Deprecated but needed by old log entries @@ -408,19 +485,37 @@ class AFComputedVariable { $result = $v1 - $v2; break; case 'revision-text-by-id': - $rev = Revision::newFromId( $parameters['revid'] ); - $result = AbuseFilter::revisionToString( $rev ); + $revRec = $services + ->getRevisionLookup() + ->getRevisionById( $parameters['revid'] ); + $result = AbuseFilter::revisionToString( $revRec, $computeForUser ); break; case 'revision-text-by-timestamp': $timestamp = $parameters['timestamp']; - $title = Title::makeTitle( $parameters['namespace'], $parameters['title'] ); - $dbr = wfGetDB( DB_REPLICA ); - $rev = Revision::loadFromTimestamp( $dbr, $title, $timestamp ); - $result = AbuseFilter::revisionToString( $rev ); + if ( $timestamp === null ) { + // Temporary BC for T246539#6388362 + $result = '[Revision text not available]'; + break; + } + $title = $this->buildTitle( $parameters['namespace'], $parameters['title'] ); + $revRec = $services + ->getRevisionStore() + ->getRevisionByTimestamp( $title, $timestamp ); + $result = AbuseFilter::revisionToString( $revRec, $computeForUser ); + break; + case 'get-wiki-name': + $result = WikiMap::getCurrentWikiDbDomain()->getId(); + break; + case 'get-wiki-language': + $result = $services->getContentLanguage()->getCode(); break; default: - if ( Hooks::run( 'AbuseFilter-computeVariable', - [ $this->mMethod, $vars, $parameters, &$result ] ) ) { + if ( $hookRunner->onAbuseFilterComputeVariable( + $this->mMethod, + $vars, + $parameters, + $result + ) ) { throw new AFPException( 'Unknown variable compute type ' . $this->mMethod ); } } @@ -448,14 +543,14 @@ class AFComputedVariable { $dbr = wfGetDB( DB_REPLICA ); $setOpts += Database::getCacheSetOptions( $dbr ); // Get the last 100 edit authors with a trivial query (avoid T116557) - $revQuery = Revision::getQueryInfo(); + $revQuery = MediaWikiServices::getInstance()->getRevisionStore()->getQueryInfo(); $revAuthors = $dbr->selectFieldValues( $revQuery['tables'], $revQuery['fields']['rev_user_text'], [ 'rev_page' => $title->getArticleID() ], $fname, // Some pages have < 10 authors but many revisions (e.g. bot pages) - [ 'ORDER BY' => 'rev_timestamp DESC', + [ 'ORDER BY' => 'rev_timestamp DESC, rev_id DESC', 'LIMIT' => 100, // Force index per T116557 'USE INDEX' => [ 'revision' => 'page_timestamp' ], diff --git a/AbuseFilter/includes/AbuseFilter.php b/AbuseFilter/includes/AbuseFilter.php index 2566c25e..f76b4df6 100644 --- a/AbuseFilter/includes/AbuseFilter.php +++ b/AbuseFilter/includes/AbuseFilter.php @@ -1,30 +1,68 @@ <?php -use MediaWiki\Linker\LinkRenderer; +use MediaWiki\Extension\AbuseFilter\AbuseFilterServices; +use MediaWiki\Extension\AbuseFilter\Hooks\AbuseFilterHookRunner; +use MediaWiki\Extension\AbuseFilter\VariableGenerator\VariableGenerator; use MediaWiki\Logger\LoggerFactory; -use MediaWiki\Session\SessionManager; use MediaWiki\MediaWikiServices; +use MediaWiki\Revision\RevisionRecord; +use Wikimedia\Rdbms\DBError; use Wikimedia\Rdbms\IDatabase; /** - * This class contains most of the business logic of AbuseFilter. It consists of mostly - * static functions that handle activities such as parsing edits, applying filters, - * logging actions, etc. + * This class contains most of the business logic of AbuseFilter. It consists of + * static functions for generic use (mostly utility functions). */ class AbuseFilter { + /** + * @var int How long to keep profiling data in cache (in seconds) + */ public static $statsStoragePeriod = 86400; - public static $condLimitEnabled = true; - /** @var array Map of (filter ID => stdClass) */ + /** + * @var array [filter ID => stdClass|null] as retrieved from self::getFilter. ID could be either + * an integer or "<GLOBAL_FILTER_PREFIX><integer>" + */ private static $filterCache = []; - public static $condCount = 0; + /** @var string The prefix to use for global filters */ + public const GLOBAL_FILTER_PREFIX = 'global-'; - /** @var array Map of (action ID => string[]) */ - // FIXME: avoid global state here + /** + * @var array Map of (action ID => string[]) + * @fixme avoid global state here + */ public static $tagsToSet = []; - public static $history_mappings = [ + /** + * @var array IDs of logged filters like [ page title => [ 'local' => [ids], 'global' => [ids] ] ]. + * @fixme avoid global state + */ + public static $logIds = []; + + /** + * @var string[] The FULL list of fields in the abuse_filter table + * @internal + */ + public const ALL_ABUSE_FILTER_FIELDS = [ + 'af_id', + 'af_pattern', + 'af_user', + 'af_user_text', + 'af_timestamp', + 'af_enabled', + 'af_comments', + 'af_public_comments', + 'af_hidden', + 'af_hit_count', + 'af_throttled', + 'af_deleted', + 'af_actions', + 'af_global', + 'af_group' + ]; + + public const HISTORY_MAPPINGS = [ 'af_pattern' => 'afh_pattern', 'af_user' => 'afh_user', 'af_user_text' => 'afh_user_text', @@ -35,343 +73,41 @@ class AbuseFilter { 'af_id' => 'afh_filter', 'af_group' => 'afh_group', ]; - public static $builderValues = [ - 'op-arithmetic' => [ - '+' => 'addition', - '-' => 'subtraction', - '*' => 'multiplication', - '/' => 'divide', - '%' => 'modulo', - '**' => 'pow' - ], - 'op-comparison' => [ - '==' => 'equal', - '===' => 'equal-strict', - '!=' => 'notequal', - '!==' => 'notequal-strict', - '<' => 'lt', - '>' => 'gt', - '<=' => 'lte', - '>=' => 'gte' - ], - 'op-bool' => [ - '!' => 'not', - '&' => 'and', - '|' => 'or', - '^' => 'xor' - ], - 'misc' => [ - 'in' => 'in', - 'contains' => 'contains', - 'like' => 'like', - '""' => 'stringlit', - 'rlike' => 'rlike', - 'irlike' => 'irlike', - 'cond ? iftrue : iffalse' => 'tern', - 'if cond then iftrue elseiffalse end' => 'cond', - ], - 'funcs' => [ - 'length(string)' => 'length', - 'lcase(string)' => 'lcase', - 'ucase(string)' => 'ucase', - 'ccnorm(string)' => 'ccnorm', - 'ccnorm_contains_any(haystack,needle1,needle2,..)' => 'ccnorm-contains-any', - 'ccnorm_contains_all(haystack,needle1,needle2,..)' => 'ccnorm-contains-all', - 'rmdoubles(string)' => 'rmdoubles', - 'specialratio(string)' => 'specialratio', - 'norm(string)' => 'norm', - 'count(needle,haystack)' => 'count', - 'rcount(needle,haystack)' => 'rcount', - 'get_matches(needle,haystack)' => 'get_matches', - 'rmwhitespace(text)' => 'rmwhitespace', - 'rmspecials(text)' => 'rmspecials', - 'ip_in_range(ip, range)' => 'ip_in_range', - 'contains_any(haystack,needle1,needle2,...)' => 'contains-any', - 'contains_all(haystack,needle1,needle2,...)' => 'contains-all', - 'equals_to_any(haystack,needle1,needle2,...)' => 'equals-to-any', - 'substr(subject, offset, length)' => 'substr', - 'strpos(haystack, needle)' => 'strpos', - 'str_replace(subject, search, replace)' => 'str_replace', - 'rescape(string)' => 'rescape', - 'set_var(var,value)' => 'set_var', - 'sanitize(string)' => 'sanitize', - ], - 'vars' => [ - 'timestamp' => 'timestamp', - 'accountname' => 'accountname', - 'action' => 'action', - 'added_lines' => 'addedlines', - 'edit_delta' => 'delta', - 'edit_diff' => 'diff', - 'new_size' => 'newsize', - 'old_size' => 'oldsize', - 'new_content_model' => 'new-content-model', - 'old_content_model' => 'old-content-model', - 'removed_lines' => 'removedlines', - 'summary' => 'summary', - 'page_id' => 'page-id', - 'page_namespace' => 'page-ns', - 'page_title' => 'page-title', - 'page_prefixedtitle' => 'page-prefixedtitle', - 'page_age' => 'page-age', - 'moved_from_id' => 'movedfrom-id', - 'moved_from_namespace' => 'movedfrom-ns', - 'moved_from_title' => 'movedfrom-title', - 'moved_from_prefixedtitle' => 'movedfrom-prefixedtitle', - 'moved_from_age' => 'movedfrom-age', - 'moved_to_id' => 'movedto-id', - 'moved_to_namespace' => 'movedto-ns', - 'moved_to_title' => 'movedto-title', - 'moved_to_prefixedtitle' => 'movedto-prefixedtitle', - 'moved_to_age' => 'movedto-age', - 'user_editcount' => 'user-editcount', - 'user_age' => 'user-age', - 'user_name' => 'user-name', - 'user_groups' => 'user-groups', - 'user_rights' => 'user-rights', - 'user_blocked' => 'user-blocked', - 'user_emailconfirm' => 'user-emailconfirm', - 'old_wikitext' => 'old-text', - 'new_wikitext' => 'new-text', - 'added_links' => 'added-links', - 'removed_links' => 'removed-links', - 'all_links' => 'all-links', - 'new_pst' => 'new-pst', - 'edit_diff_pst' => 'diff-pst', - 'added_lines_pst' => 'addedlines-pst', - 'new_text' => 'new-text-stripped', - 'new_html' => 'new-html', - 'page_restrictions_edit' => 'restrictions-edit', - 'page_restrictions_move' => 'restrictions-move', - 'page_restrictions_create' => 'restrictions-create', - 'page_restrictions_upload' => 'restrictions-upload', - 'page_recent_contributors' => 'recent-contributors', - 'page_first_contributor' => 'first-contributor', - 'moved_from_restrictions_edit' => 'movedfrom-restrictions-edit', - 'moved_from_restrictions_move' => 'movedfrom-restrictions-move', - 'moved_from_restrictions_create' => 'movedfrom-restrictions-create', - 'moved_from_restrictions_upload' => 'movedfrom-restrictions-upload', - 'moved_from_recent_contributors' => 'movedfrom-recent-contributors', - 'moved_from_first_contributor' => 'movedfrom-first-contributor', - 'moved_to_restrictions_edit' => 'movedto-restrictions-edit', - 'moved_to_restrictions_move' => 'movedto-restrictions-move', - 'moved_to_restrictions_create' => 'movedto-restrictions-create', - 'moved_to_restrictions_upload' => 'movedto-restrictions-upload', - 'moved_to_recent_contributors' => 'movedto-recent-contributors', - 'moved_to_first_contributor' => 'movedto-first-contributor', - 'old_links' => 'old-links', - 'minor_edit' => 'minor-edit', - 'file_sha1' => 'file-sha1', - 'file_size' => 'file-size', - 'file_mime' => 'file-mime', - 'file_mediatype' => 'file-mediatype', - 'file_width' => 'file-width', - 'file_height' => 'file-height', - 'file_bits_per_channel' => 'file-bits-per-channel', - ], - ]; - - /** @var array Old vars which aren't in use anymore */ - public static $disabledVars = [ - 'old_text' => 'old-text-stripped', - 'old_html' => 'old-html' - ]; - - public static $deprecatedVars = [ - 'article_text' => 'page_title', - 'article_prefixedtext' => 'page_prefixedtitle', - 'article_namespace' => 'page_namespace', - 'article_articleid' => 'page_id', - 'article_restrictions_edit' => 'page_restrictions_edit', - 'article_restrictions_move' => 'page_restrictions_move', - 'article_restrictions_create' => 'page_restrictions_create', - 'article_restrictions_upload' => 'page_restrictions_upload', - 'article_recent_contributors' => 'page_recent_contributors', - 'article_first_contributor' => 'page_first_contributor', - 'moved_from_text' => 'moved_from_title', - 'moved_from_prefixedtext' => 'moved_from_prefixedtitle', - 'moved_from_articleid' => 'moved_from_id', - 'moved_to_text' => 'moved_to_title', - 'moved_to_prefixedtext' => 'moved_to_prefixedtitle', - 'moved_to_articleid' => 'moved_to_id', - ]; - - public static $editboxName = null; - - /** - * @param IContextSource $context - * @param string $pageType - * @param LinkRenderer $linkRenderer - */ - public static function addNavigationLinks( - IContextSource $context, - $pageType, - LinkRenderer $linkRenderer - ) { - $linkDefs = [ - 'home' => 'Special:AbuseFilter', - 'recentchanges' => 'Special:AbuseFilter/history', - 'examine' => 'Special:AbuseFilter/examine', - 'log' => 'Special:AbuseLog', - ]; - - if ( $context->getUser()->isAllowedAny( 'abusefilter-modify', 'abusefilter-view-private' ) ) { - $linkDefs = array_merge( $linkDefs, [ - 'test' => 'Special:AbuseFilter/test', - 'tools' => 'Special:AbuseFilter/tools' - ] ); - } - - if ( $context->getUser()->isAllowed( 'abusefilter-modify' ) ) { - $linkDefs = array_merge( $linkDefs, [ - 'import' => 'Special:AbuseFilter/import' - ] ); - } - - // Re-use the message - $msgOverrides = [ - 'recentchanges' => 'abusefilter-filter-log', - ]; - - $links = []; - - foreach ( $linkDefs as $name => $page ) { - // Give grep a chance to find the usages: - // abusefilter-topnav-home, abusefilter-topnav-test, abusefilter-topnav-examine - // abusefilter-topnav-log, abusefilter-topnav-tools, abusefilter-topnav-import - $msgName = "abusefilter-topnav-$name"; - - if ( isset( $msgOverrides[$name] ) ) { - $msgName = $msgOverrides[$name]; - } - - $msg = $context->msg( $msgName )->parse(); - $title = Title::newFromText( $page ); - - if ( $name == $pageType ) { - $links[] = Xml::tags( 'strong', null, $msg ); - } else { - $links[] = $linkRenderer->makeLink( $title, new HtmlArmor( $msg ) ); - } - } - - $linkStr = $context->msg( 'parentheses' ) - ->rawParams( $context->getLanguage()->pipeList( $links ) ) - ->text(); - $linkStr = $context->msg( 'abusefilter-topnav' )->parse() . " $linkStr"; - - $linkStr = Xml::tags( 'div', [ 'class' => 'mw-abusefilter-navigation' ], $linkStr ); - - $context->getOutput()->setSubtitle( $linkStr ); - } /** + * @deprecated Since 1.35 Use VariableGenerator::addUserVars() * @param User $user + * @param RecentChange|null $entry * @return AbuseFilterVariableHolder */ - public static function generateUserVars( $user ) { - $vars = new AbuseFilterVariableHolder; - - $vars->setLazyLoadVar( - 'user_editcount', - 'simple-user-accessor', - [ 'user' => $user, 'method' => 'getEditCount' ] - ); - - $vars->setVar( 'user_name', $user->getName() ); - - $vars->setLazyLoadVar( - 'user_emailconfirm', - 'simple-user-accessor', - [ 'user' => $user, 'method' => 'getEmailAuthenticationTimestamp' ] - ); - - $vars->setLazyLoadVar( - 'user_age', - 'user-age', - [ 'user' => $user, 'asof' => wfTimestampNow() ] - ); - - $vars->setLazyLoadVar( - 'user_groups', - 'simple-user-accessor', - [ 'user' => $user, 'method' => 'getEffectiveGroups' ] - ); - - $vars->setLazyLoadVar( - 'user_rights', - 'simple-user-accessor', - [ 'user' => $user, 'method' => 'getRights' ] - ); - - $vars->setLazyLoadVar( - 'user_blocked', - 'simple-user-accessor', - [ 'user' => $user, 'method' => 'isBlocked' ] - ); - - Hooks::run( 'AbuseFilter-generateUserVars', [ $vars, $user ] ); - - return $vars; - } - - /** - * @return array - */ - public static function getBuilderValues() { - static $realValues = null; - - if ( $realValues ) { - return $realValues; - } - - $realValues = self::$builderValues; - - Hooks::run( 'AbuseFilter-builder', [ &$realValues ] ); - - return $realValues; - } - - /** - * @return array - */ - public static function getDeprecatedVariables() { - static $deprecatedVars = null; - - if ( $deprecatedVars ) { - return $deprecatedVars; - } - - $deprecatedVars = self::$deprecatedVars; - - Hooks::run( 'AbuseFilter-deprecatedVariables', [ &$deprecatedVars ] ); - - return $deprecatedVars; + public static function generateUserVars( User $user, RecentChange $entry = null ) { + wfDeprecated( __METHOD__, '1.35' ); + $vars = new AbuseFilterVariableHolder(); + $generator = new VariableGenerator( $vars ); + return $generator->addUserVars( $user, $entry )->getVariableHolder(); } /** - * @param string $filter + * @param int $filterID The ID of the filter + * @param bool|int $global Whether the filter is global * @return bool */ - public static function filterHidden( $filter ) { - $globalIndex = self::decodeGlobalName( $filter ); - if ( $globalIndex ) { - global $wgAbuseFilterCentralDB; + public static function filterHidden( $filterID, $global = false ) { + global $wgAbuseFilterCentralDB; + + if ( $global ) { if ( !$wgAbuseFilterCentralDB ) { return false; } - $dbr = wfGetDB( DB_REPLICA, [], $wgAbuseFilterCentralDB ); - $filter = $globalIndex; + $dbr = self::getCentralDB( DB_REPLICA ); } else { $dbr = wfGetDB( DB_REPLICA ); } - if ( $filter === 'new' ) { - return false; - } + $hidden = $dbr->selectField( 'abuse_filter', 'af_hidden', - [ 'af_id' => $filter ], + [ 'af_id' => $filterID ], __METHOD__ ); @@ -379,441 +115,150 @@ class AbuseFilter { } /** - * @param int $val - * @throws MWException - */ - public static function triggerLimiter( $val = 1 ) { - self::$condCount += $val; - - global $wgAbuseFilterConditionLimit; - - if ( self::$condLimitEnabled && self::$condCount > $wgAbuseFilterConditionLimit ) { - throw new MWException( 'Condition limit reached.' ); - } - } - - /** - * For use in batch scripts and the like - */ - public static function disableConditionLimit() { - self::$condLimitEnabled = false; - } - - /** + * @deprecated Since 1.35 Use VariableGenerator::addTitleVars * @param Title|null $title * @param string $prefix + * @param RecentChange|null $entry * @return AbuseFilterVariableHolder */ - public static function generateTitleVars( $title, $prefix ) { - $vars = new AbuseFilterVariableHolder; - - if ( !$title ) { + public static function generateTitleVars( $title, $prefix, RecentChange $entry = null ) { + wfDeprecated( __METHOD__, '1.35' ); + $vars = new AbuseFilterVariableHolder(); + if ( !( $title instanceof Title ) ) { return $vars; } - - $vars->setVar( $prefix . '_ID', $title->getArticleID() ); - $vars->setVar( $prefix . '_NAMESPACE', $title->getNamespace() ); - $vars->setVar( $prefix . '_TITLE', $title->getText() ); - $vars->setVar( $prefix . '_PREFIXEDTITLE', $title->getPrefixedText() ); - - global $wgRestrictionTypes; - foreach ( $wgRestrictionTypes as $action ) { - $vars->setLazyLoadVar( "{$prefix}_restrictions_$action", 'get-page-restrictions', - [ 'title' => $title->getText(), - 'namespace' => $title->getNamespace(), - 'action' => $action - ] - ); - } - - $vars->setLazyLoadVar( "{$prefix}_recent_contributors", 'load-recent-authors', - [ - 'title' => $title->getText(), - 'namespace' => $title->getNamespace() - ] ); - - $vars->setLazyLoadVar( "{$prefix}_age", 'page-age', - [ - 'title' => $title->getText(), - 'namespace' => $title->getNamespace(), - 'asof' => wfTimestampNow() - ] ); - - $vars->setLazyLoadVar( "{$prefix}_first_contributor", 'load-first-author', - [ - 'title' => $title->getText(), - 'namespace' => $title->getNamespace() - ] ); - - Hooks::run( 'AbuseFilter-generateTitleVars', [ $vars, $title, $prefix ] ); - - return $vars; - } - - /** - * @param string $filter - * @return true|array True when successful, otherwise a two-element array with exception message - * and character position of the syntax error - */ - public static function checkSyntax( $filter ) { - global $wgAbuseFilterParserClass; - - /** @var $parser AbuseFilterParser */ - $parser = new $wgAbuseFilterParserClass; - - return $parser->checkSyntax( $filter ); + $generator = new VariableGenerator( $vars ); + return $generator->addTitleVars( $title, $prefix, $entry )->getVariableHolder(); } /** - * @param string $expr - * @return string + * @deprecated Since 1.35 Use VariableGenerator::addGenericVars + * @return AbuseFilterVariableHolder */ - public static function evaluateExpression( $expr ) { - global $wgAbuseFilterParserClass; - - if ( self::checkSyntax( $expr ) !== true ) { - return 'BADSYNTAX'; - } - - /** @var $parser AbuseFilterParser */ - $parser = new $wgAbuseFilterParserClass; - - return $parser->evaluateExpression( $expr ); - } - - /** - * @param string $conds - * @param AbuseFilterVariableHolder $vars - * @param bool $ignoreError - * @return bool - * @throws Exception - */ - public static function checkConditions( - $conds, $vars, $ignoreError = true - ) { - global $wgAbuseFilterParserClass; - - static $parser, $lastVars; - - if ( is_null( $parser ) || $vars !== $lastVars ) { - /** @var $parser AbuseFilterParser */ - $parser = new $wgAbuseFilterParserClass( $vars ); - $lastVars = $vars; - } - - try { - $result = $parser->parse( $conds, self::$condCount ); - } catch ( Exception $excep ) { - $result = false; - - $logger = LoggerFactory::getInstance( 'AbuseFilter' ); - $logger->debug( 'AbuseFilter parser error: ' . $excep->getMessage() ); - - if ( !$ignoreError ) { - throw $excep; - } - } - - return $result; + public static function generateGenericVars() { + wfDeprecated( __METHOD__, '1.35' ); + $vars = new AbuseFilterVariableHolder(); + $generator = new VariableGenerator( $vars ); + return $generator->addGenericVars()->getVariableHolder(); } /** * Returns an associative array of filters which were tripped * * @param AbuseFilterVariableHolder $vars + * @param Title $title * @param string $group The filter's group (as defined in $wgAbuseFilterValidGroups) - * @param Title|null $title * @param string $mode 'execute' for edits and logs, 'stash' for cached matches - * * @return bool[] Map of (integer filter ID => bool) + * @deprecated Since 1.34 See comment on AbuseFilterRunner::checkAllFilters */ public static function checkAllFilters( - $vars, + AbuseFilterVariableHolder $vars, + Title $title, $group = 'default', - Title $title = null, $mode = 'execute' ) { - global $wgAbuseFilterCentralDB, $wgAbuseFilterIsCentral; - global $wgAbuseFilterConditionLimit; - - // Ensure that we start fresh, see T193374 - self::$condCount = 0; - - // Fetch filters to check from the database. - $filter_matched = []; - - $dbr = wfGetDB( DB_REPLICA ); - $fields = [ - 'af_id', - 'af_pattern', - 'af_public_comments', - 'af_timestamp' - ]; - $res = $dbr->select( - 'abuse_filter', - $fields, - [ - 'af_enabled' => 1, - 'af_deleted' => 0, - 'af_group' => $group, - ], - __METHOD__ - ); - - foreach ( $res as $row ) { - $filter_matched[$row->af_id] = self::checkFilter( $row, $vars, $title, '', $mode ); - } - - if ( $wgAbuseFilterCentralDB && !$wgAbuseFilterIsCentral ) { - // Global filters - $globalRulesKey = self::getGlobalRulesKey( $group ); + $parser = self::getDefaultParser( $vars ); + $user = RequestContext::getMain()->getUser(); - $fname = __METHOD__; - $res = ObjectCache::getMainWANInstance()->getWithSetCallback( - $globalRulesKey, - WANObjectCache::TTL_INDEFINITE, - function () use ( $group, $fname, $fields ) { - global $wgAbuseFilterCentralDB; - - $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory(); - $fdb = $lbFactory->getMainLB( $wgAbuseFilterCentralDB )->getConnectionRef( - DB_REPLICA, [], $wgAbuseFilterCentralDB - ); - - return iterator_to_array( $fdb->select( - 'abuse_filter', - $fields, - [ - 'af_enabled' => 1, - 'af_deleted' => 0, - 'af_global' => 1, - 'af_group' => $group, - ], - $fname - ) ); - }, - [ - 'checkKeys' => [ $globalRulesKey ], - 'lockTSE' => 300 - ] - ); - - foreach ( $res as $row ) { - $filter_matched['global-' . $row->af_id] = - self::checkFilter( $row, $vars, $title, 'global-', $mode ); - } - } - - if ( $title instanceof Title && self::$condCount > $wgAbuseFilterConditionLimit ) { - $actionID = implode( '-', [ - $title->getPrefixedText(), - $vars->getVar( 'user_name' )->toString(), - $vars->getVar( 'action' )->toString() - ] ); - self::bufferTagsToSetByAction( [ $actionID => [ 'abusefilter-condition-limit' ] ] ); - } - - if ( $mode === 'execute' ) { - // Update statistics, and disable filters which are over-blocking. - self::recordStats( $filter_matched, $group ); - } - - return $filter_matched; + $runner = new AbuseFilterRunner( $user, $title, $vars, $group ); + $runner->parser = $parser; + return $runner->checkAllFilters(); } /** - * @param stdClass $row - * @param AbuseFilterVariableHolder $vars - * @param Title|null $title - * @param string $prefix - * @param string $mode 'execute' for edits and logs, 'stash' for cached matches - * @return bool - */ - public static function checkFilter( - $row, - $vars, - Title $title = null, - $prefix = '', - $mode = 'execute' - ) { - global $wgAbuseFilterProfile, $wgAbuseFilterRuntimeProfile, - $wgAbuseFilterSlowFilterRuntimeLimit; - - $filterID = $prefix . $row->af_id; - - // Record data to be used if profiling is enabled and mode is 'execute' - $startConds = self::$condCount; - $startTime = microtime( true ); - - // Store the row somewhere convenient - self::$filterCache[$filterID] = $row; - - $pattern = trim( $row->af_pattern ); - if ( - self::checkConditions( - $pattern, - $vars, - // Ignore errors - true - ) - ) { - // Record match. - $result = true; - } else { - // Record non-match. - $result = false; - } - - $timeTaken = microtime( true ) - $startTime; - $condsUsed = self::$condCount - $startConds; - - if ( $wgAbuseFilterProfile && $mode === 'execute' ) { - self::recordProfilingResult( $row->af_id, $timeTaken, $condsUsed ); - } - - $runtime = $timeTaken * 1000; - if ( $mode === 'execute' && $wgAbuseFilterRuntimeProfile && - $runtime > $wgAbuseFilterSlowFilterRuntimeLimit ) { - self::recordSlowFilter( $filterID, $runtime, $condsUsed, $result, $title ); - } - - return $result; - } - - /** - * Logs slow filter's runtime data for later analysis - * - * @param string $filterId - * @param float $runtime - * @param int $totalConditions - * @param bool $matched - * @param Title|null $title - */ - private static function recordSlowFilter( - $filterId, $runtime, $totalConditions, $matched, Title $title = null - ) { - $title = $title ? $title->getPrefixedText() : ''; - - $logger = LoggerFactory::getInstance( 'AbuseFilterSlow' ); - $logger->info( - 'Edit filter {filter_id} on {wiki} is taking longer than expected', - [ - 'wiki' => wfWikiID(), - 'filter_id' => $filterId, - 'title' => $title, - 'runtime' => $runtime, - 'matched' => $matched, - 'total_conditions' => $totalConditions - ] - ); - } - - /** - * @param int $filter + * @param int|string $filter + * @internal */ public static function resetFilterProfile( $filter ) { - $stash = ObjectCache::getMainStashInstance(); - $countKey = wfMemcKey( 'abusefilter', 'profile', $filter, 'count' ); - $totalKey = wfMemcKey( 'abusefilter', 'profile', $filter, 'total' ); - $condsKey = wfMemcKey( 'abusefilter', 'profile', $filter, 'conds' ); - - $stash->delete( $countKey ); - $stash->delete( $totalKey ); - $stash->delete( $condsKey ); - } + $stash = MediaWikiServices::getInstance()->getMainObjectStash(); + $profileKey = self::filterProfileKey( $filter ); - /** - * @param int $filter - * @param float $time - * @param int $conds - */ - public static function recordProfilingResult( $filter, $time, $conds ) { - // Defer updates to avoid massive (~1 second) edit time increases - DeferredUpdates::addCallableUpdate( function () use ( $filter, $time, $conds ) { - $stash = ObjectCache::getMainStashInstance(); - $countKey = wfMemcKey( 'abusefilter', 'profile', $filter, 'count' ); - $totalKey = wfMemcKey( 'abusefilter', 'profile', $filter, 'total' ); - $condsKey = wfMemcKey( 'abusefilter', 'profile', $filter, 'conds' ); - - $curCount = $stash->get( $countKey ); - $curTotal = $stash->get( $totalKey ); - $curConds = $stash->get( $condsKey ); - - if ( $curCount ) { - $stash->set( $condsKey, $curConds + $conds, 3600 ); - $stash->set( $totalKey, $curTotal + $time, 3600 ); - $stash->incr( $countKey ); - } else { - $stash->set( $countKey, 1, 3600 ); - $stash->set( $totalKey, $time, 3600 ); - $stash->set( $condsKey, $conds, 3600 ); - } - } ); + $stash->delete( $profileKey ); } /** + * Retrieve per-filter statistics. + * * @param string $filter * @return array */ public static function getFilterProfile( $filter ) { - $stash = ObjectCache::getMainStashInstance(); - $countKey = wfMemcKey( 'abusefilter', 'profile', $filter, 'count' ); - $totalKey = wfMemcKey( 'abusefilter', 'profile', $filter, 'total' ); - $condsKey = wfMemcKey( 'abusefilter', 'profile', $filter, 'conds' ); - - $curCount = $stash->get( $countKey ); - $curTotal = $stash->get( $totalKey ); - $curConds = $stash->get( $condsKey ); + $stash = MediaWikiServices::getInstance()->getMainObjectStash(); + $profile = $stash->get( self::filterProfileKey( $filter ) ); - if ( !$curCount ) { - return [ 0, 0 ]; + if ( $profile !== false ) { + $curCount = $profile['count']; + $curTotalTime = $profile['total-time']; + $curTotalConds = $profile['total-cond']; + } else { + return [ 0, 0, 0, 0 ]; } - // 1000 ms in a sec - $timeProfile = ( $curTotal / $curCount ) * 1000; - // Return in ms, rounded to 2dp - $timeProfile = round( $timeProfile, 2 ); + // Return in milliseconds, rounded to 2dp + $avgTime = round( $curTotalTime / $curCount, 2 ); + $avgCond = round( $curTotalConds / $curCount, 1 ); - $condProfile = ( $curConds / $curCount ); - $condProfile = round( $condProfile, 0 ); - - return [ $timeProfile, $condProfile ]; + return [ $curCount, $profile['matches'], $avgTime, $avgCond ]; } /** - * Utility function to decode global-$index to $index. Returns false if not global - * - * @param string $filter + * Utility function to split "<GLOBAL_FILTER_PREFIX>$index" to an array [ $id, $global ], where + * $id is $index casted to int, and $global is a boolean: true if the filter is global, + * false otherwise (i.e. if the $filter === $index). Note that the $index + * is always casted to int. Passing anything which isn't an integer-like value or a string + * in the shape "<GLOBAL_FILTER_PREFIX>integer" will throw. + * This reverses self::buildGlobalName * - * @return string|bool - */ - public static function decodeGlobalName( $filter ) { - if ( strpos( $filter, 'global-' ) === 0 ) { - return substr( $filter, strlen( 'global-' ) ); + * @param string|int $filter + * @return array + * @throws InvalidArgumentException + */ + public static function splitGlobalName( $filter ) { + if ( preg_match( '/^' . self::GLOBAL_FILTER_PREFIX . '\d+$/', $filter ) === 1 ) { + $id = intval( substr( $filter, strlen( self::GLOBAL_FILTER_PREFIX ) ) ); + return [ $id, true ]; + } elseif ( is_numeric( $filter ) ) { + return [ (int)$filter, false ]; + } else { + throw new InvalidArgumentException( "Invalid filter name: $filter" ); } + } - return false; + /** + * Given a filter ID and a boolean indicating whether it's global, build a string like + * "<GLOBAL_FILTER_PREFIX>$ID". Note that, with global = false, $id is casted to string. + * This reverses self::splitGlobalName. + * + * @param int $id The filter ID + * @param bool $global Whether the filter is global + * @return string + * @todo Calling this method should be avoided wherever possible + */ + public static function buildGlobalName( $id, $global = true ) { + $prefix = $global ? self::GLOBAL_FILTER_PREFIX : ''; + return "$prefix$id"; } /** * @param string[] $filters - * @return array[] + * @return (string|array)[][][] + * @phan-return array<string,array<string,array{action:string,parameters:string[]}>> */ public static function getConsequencesForFilters( $filters ) { $globalFilters = []; $localFilters = []; foreach ( $filters as $filter ) { - $globalIndex = self::decodeGlobalName( $filter ); + list( $filterID, $global ) = self::splitGlobalName( $filter ); - if ( $globalIndex ) { - $globalFilters[] = $globalIndex; + if ( $global ) { + $globalFilters[] = $filterID; } else { $localFilters[] = $filter; } } - global $wgAbuseFilterCentralDB; // Load local filter info $dbr = wfGetDB( DB_REPLICA ); // Retrieve the consequences. @@ -824,8 +269,11 @@ class AbuseFilter { } if ( count( $globalFilters ) ) { - $fdb = wfGetDB( DB_REPLICA, [], $wgAbuseFilterCentralDB ); - $consequences = $consequences + self::loadConsequencesFromDB( $fdb, $globalFilters, 'global-' ); + $consequences += self::loadConsequencesFromDB( + self::getCentralDB( DB_REPLICA ), + $globalFilters, + self::GLOBAL_FILTER_PREFIX + ); } return $consequences; @@ -835,9 +283,10 @@ class AbuseFilter { * @param IDatabase $dbr * @param string[] $filters * @param string $prefix - * @return array[] + * @return (string|array)[][][] + * @phan-return array<string,array<string,array{action:string,parameters:string[]}>> */ - public static function loadConsequencesFromDB( $dbr, $filters, $prefix = '' ) { + public static function loadConsequencesFromDB( IDatabase $dbr, $filters, $prefix = '' ) { $actionsByFilter = []; foreach ( $filters as $filter ) { $actionsByFilter[$prefix . $filter] = []; @@ -858,8 +307,16 @@ class AbuseFilter { if ( $row->af_throttled && !empty( $wgAbuseFilterRestrictions[$row->afa_consequence] ) ) { - // Don't do the action - } elseif ( $row->afa_filter != $row->af_id ) { + // Don't do the action, just log + $logger = LoggerFactory::getInstance( 'AbuseFilter' ); + $logger->info( + 'Filter {filter_id} is throttled, skipping action: {action}', + [ + 'filter_id' => $row->af_id, + 'action' => $row->afa_consequence + ] + ); + } elseif ( $row->afa_filter !== $row->af_id ) { // We probably got a NULL, as it's a LEFT JOIN. Don't add it. } else { $actionsByFilter[$prefix . $row->afa_filter][$row->afa_consequence] = [ @@ -873,552 +330,82 @@ class AbuseFilter { } /** - * Executes a set of actions. - * - * @param string[] $filters - * @param Title $title - * @param AbuseFilterVariableHolder $vars - * @param User $user - * @return Status returns the operation's status. $status->isOK() will return true if - * there were no actions taken, false otherwise. $status->getValue() will return - * an array listing the actions taken. $status->getErrors() etc. will provide - * the errors and warnings to be shown to the user to explain the actions. - */ - public static function executeFilterActions( $filters, $title, $vars, User $user ) { - global $wgMainCacheType; - - $actionsByFilter = self::getConsequencesForFilters( $filters ); - $actionsTaken = array_fill_keys( $filters, [] ); - - $messages = []; - // Accumulator to track max block to issue - $maxExpiry = -1; - - global $wgAbuseFilterDisallowGlobalLocalBlocks, $wgAbuseFilterRestrictions, - $wgAbuseFilterBlockDuration, $wgAbuseFilterAnonBlockDuration; - foreach ( $actionsByFilter as $filter => $actions ) { - // Special-case handling for warnings. - $filter_public_comments = self::getFilter( $filter )->af_public_comments; - - $global_filter = self::decodeGlobalName( $filter ) !== false; - - // If the filter has "throttle" enabled and throttling is available via object - // caching, check to see if the user has hit the throttle. - if ( !empty( $actions['throttle'] ) && $wgMainCacheType !== CACHE_NONE ) { - $parameters = $actions['throttle']['parameters']; - $throttleId = array_shift( $parameters ); - list( $rateCount, $ratePeriod ) = explode( ',', array_shift( $parameters ) ); - - $hitThrottle = false; - - // The rest are throttle-types. - foreach ( $parameters as $throttleType ) { - $hitThrottle = $hitThrottle || self::isThrottled( - $throttleId, $throttleType, $title, $rateCount, $ratePeriod, $global_filter ); - } - - unset( $actions['throttle'] ); - if ( !$hitThrottle ) { - $actionsTaken[$filter][] = 'throttle'; - continue; - } - } - - if ( $wgAbuseFilterDisallowGlobalLocalBlocks && $global_filter ) { - $actions = array_diff_key( $actions, array_filter( $wgAbuseFilterRestrictions ) ); - } - - if ( !empty( $actions['warn'] ) ) { - $parameters = $actions['warn']['parameters']; - $action = $vars->getVar( 'action' )->toString(); - // Generate a unique key to determine whether the user has already been warned. - // We'll warn again if one of these changes: session, page, triggered filter or action - $warnKey = 'abusefilter-warned-' . md5( $title->getPrefixedText() ) . - '-' . $filter . '-' . $action; - - // Make sure the session is started prior to using it - $session = SessionManager::getGlobalSession(); - $session->persist(); - - if ( !isset( $session[$warnKey] ) || !$session[$warnKey] ) { - $session[$warnKey] = true; - - // Threaten them a little bit - if ( isset( $parameters[0] ) ) { - $msg = $parameters[0]; - } else { - $msg = 'abusefilter-warning'; - } - $messages[] = [ $msg, $filter_public_comments, $filter ]; - - $actionsTaken[$filter][] = 'warn'; - - // Don't do anything else. - continue; - } else { - // We already warned them - $session[$warnKey] = false; - } - - unset( $actions['warn'] ); - } - - // Prevent double warnings - if ( count( array_intersect_key( $actions, array_filter( $wgAbuseFilterRestrictions ) ) ) > 0 && - !empty( $actions['disallow'] ) - ) { - unset( $actions['disallow'] ); - } - - // Find out the max expiry to issue the longest triggered block. - // Need to check here since methods like user->getBlock() aren't available - if ( !empty( $actions['block'] ) ) { - $parameters = $actions['block']['parameters']; - - if ( count( $parameters ) === 3 ) { - // New type of filters with custom block - if ( $user->isAnon() ) { - $expiry = $parameters[1]; - } else { - $expiry = $parameters[2]; - } - } else { - // Old type with fixed expiry - if ( $user->isAnon() && $wgAbuseFilterAnonBlockDuration !== null ) { - // The user isn't logged in and the anon block duration - // doesn't default to $wgAbuseFilterBlockDuration. - $expiry = $wgAbuseFilterAnonBlockDuration; - } else { - $expiry = $wgAbuseFilterBlockDuration; - } - } - - $currentExpiry = SpecialBlock::parseExpiryInput( $expiry ); - if ( $currentExpiry > SpecialBlock::parseExpiryInput( $maxExpiry ) ) { - // Save the parameters to issue the block with - $maxExpiry = $expiry; - $blockValues = [ - self::getFilter( $filter )->af_public_comments, - $filter, - is_array( $parameters ) && in_array( 'blocktalk', $parameters ) - ]; - } - unset( $actions['block'] ); - } - - // Do the rest of the actions - foreach ( $actions as $action => $info ) { - $newMsg = self::takeConsequenceAction( - $action, - $info['parameters'], - $title, - $vars, - self::getFilter( $filter )->af_public_comments, - $filter, - $user - ); - - if ( $newMsg !== null ) { - $messages[] = $newMsg; - } - $actionsTaken[$filter][] = $action; - } - } - - // Since every filter has been analysed, we now know what the - // longest block duration is, so we can issue the block if - // maxExpiry has been changed. - if ( $maxExpiry !== -1 ) { - self::doAbuseFilterBlock( - [ - 'desc' => $blockValues[0], - 'number' => $blockValues[1] - ], - $user->getName(), - $maxExpiry, - true, - $blockValues[2] - ); - $message = [ - 'abusefilter-blocked-display', - $blockValues[0], - $blockValues[1] - ]; - // Manually add the message. If we're here, there is one. - $messages[] = $message; - $actionsTaken[ $blockValues[1] ][] = 'block'; - } - - return self::buildStatus( $actionsTaken, $messages ); - } - - /** - * Constructs a Status object as returned by executeFilterActions() from the list of - * actions taken and the corresponding list of messages. - * - * @param array[] $actionsTaken associative array mapping each filter to the list if - * actions taken because of that filter. - * @param array[] $messages a list of arrays, where each array contains a message key - * followed by any message parameters. - * - * @return Status - */ - protected static function buildStatus( array $actionsTaken, array $messages ) { - $status = Status::newGood( $actionsTaken ); - - foreach ( $messages as $msg ) { - $status->fatal( ...$msg ); - } - - return $status; - } - - /** * @param AbuseFilterVariableHolder $vars * @param Title $title * @param string $group The filter's group (as defined in $wgAbuseFilterValidGroups) * @param User $user The user performing the action - * @param string $mode Use 'execute' to run filters and log or 'stash' to only cache matches * @return Status + * @deprecated Since 1.34 Build an AbuseFilterRunner instance and call run() on that. */ public static function filterAction( - AbuseFilterVariableHolder $vars, Title $title, $group, User $user, $mode = 'execute' + AbuseFilterVariableHolder $vars, Title $title, $group, User $user ) { - global $wgRequest, $wgAbuseFilterRuntimeProfile, $wgAbuseFilterLogIP; - - $logger = LoggerFactory::getInstance( 'StashEdit' ); - $statsd = MediaWikiServices::getInstance()->getStatsdDataFactory(); - - // Add vars from extensions - Hooks::run( 'AbuseFilter-filterAction', [ &$vars, $title ] ); - $vars->setVar( 'context', 'filter' ); - $vars->setVar( 'timestamp', time() ); - - // Get the stash key based on the relevant "input" variables - $cache = ObjectCache::getLocalClusterInstance(); - $stashKey = self::getStashKey( $cache, $vars, $group ); - $isForEdit = ( $vars->getVar( 'action' )->toString() === 'edit' ); - - if ( $wgAbuseFilterRuntimeProfile ) { - $startTime = microtime( true ); - } - - $filter_matched = false; - if ( $mode === 'execute' && $isForEdit ) { - // Check the filter edit stash results first - $cacheData = $cache->get( $stashKey ); - if ( $cacheData ) { - $filter_matched = $cacheData['matches']; - // Merge in any tags to apply to recent changes entries - self::bufferTagsToSetByAction( $cacheData['tags'] ); - } - } - - if ( is_array( $filter_matched ) ) { - if ( $isForEdit && $mode !== 'stash' ) { - $logger->info( __METHOD__ . ": cache hit for '$title' (key $stashKey)." ); - $statsd->increment( 'abusefilter.check-stash.hit' ); - } - } else { - $filter_matched = self::checkAllFilters( $vars, $group, $title, $mode ); - if ( $isForEdit && $mode !== 'stash' ) { - $logger->info( __METHOD__ . ": cache miss for '$title' (key $stashKey)." ); - $statsd->increment( 'abusefilter.check-stash.miss' ); - } - } - - if ( $mode === 'stash' ) { - // Save the filter stash result and do nothing further - $cacheData = [ 'matches' => $filter_matched, 'tags' => self::$tagsToSet ]; - - // Add runtime metrics in cache for later use - if ( $wgAbuseFilterRuntimeProfile ) { - $cacheData['condCount'] = self::$condCount; - $cacheData['runtime'] = ( microtime( true ) - $startTime ) * 1000; - } - - $cache->set( $stashKey, $cacheData, $cache::TTL_MINUTE ); - $logger->debug( __METHOD__ . ": cache store for '$title' (key $stashKey)." ); - $statsd->increment( 'abusefilter.check-stash.store' ); - - return Status::newGood(); - } - - $matched_filters = array_keys( array_filter( $filter_matched ) ); - - // Save runtime metrics only on edits - if ( $wgAbuseFilterRuntimeProfile && $mode === 'execute' && $isForEdit ) { - if ( $cacheData ) { - $runtime = $cacheData['runtime']; - $condCount = $cacheData['condCount']; - } else { - $runtime = ( microtime( true ) - $startTime ) * 1000; - $condCount = self::$condCount; - } - - self::recordRuntimeProfilingResult( count( $matched_filters ), $condCount, $runtime ); - } - - if ( count( $matched_filters ) == 0 ) { - $status = Status::newGood(); - } else { - $status = self::executeFilterActions( $matched_filters, $title, $vars, $user ); - $actions_taken = $status->getValue(); - $action = $vars->getVar( 'ACTION' )->toString(); - - // If $user isn't safe to load (e.g. a failure during - // AbortAutoAccount), create a dummy anonymous user instead. - $user = $user->isSafeToLoad() ? $user : new User; - - // Create a template - $log_template = [ - 'afl_user' => $user->getId(), - 'afl_user_text' => $user->getName(), - 'afl_timestamp' => wfGetDB( DB_REPLICA )->timestamp(), - 'afl_namespace' => $title->getNamespace(), - 'afl_title' => $title->getDBkey(), - 'afl_action' => $action, - // DB field is not null, so nothing - 'afl_ip' => ( $wgAbuseFilterLogIP ) ? $wgRequest->getIP() : "" - ]; - - // Hack to avoid revealing IPs of people creating accounts - if ( !$user->getId() && ( $action == 'createaccount' || $action == 'autocreateaccount' ) ) { - $log_template['afl_user_text'] = $vars->getVar( 'accountname' )->toString(); - } - - self::addLogEntries( $actions_taken, $log_template, $vars, $group ); - } - - return $status; + $runner = new AbuseFilterRunner( $user, $title, $vars, $group ); + return $runner->run(); } /** - * @param string $id Filter ID (integer or "global-<integer>") - * @return stdClass|null DB row + * @param string $filter Filter ID (integer or "<GLOBAL_FILTER_PREFIX><integer>") + * @return stdClass|null DB row on success, null on failure */ - public static function getFilter( $id ) { + public static function getFilter( $filter ) { global $wgAbuseFilterCentralDB; - if ( !isset( self::$filterCache[$id] ) ) { - $globalIndex = self::decodeGlobalName( $id ); - if ( $globalIndex ) { + if ( !isset( self::$filterCache[$filter] ) ) { + list( $filterID, $global ) = self::splitGlobalName( $filter ); + if ( $global ) { // Global wiki filter if ( !$wgAbuseFilterCentralDB ) { return null; } - - $id = $globalIndex; - $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory(); - $lb = $lbFactory->getMainLB( $wgAbuseFilterCentralDB ); - $dbr = $lb->getConnectionRef( DB_REPLICA, [], $wgAbuseFilterCentralDB ); + $dbr = self::getCentralDB( DB_REPLICA ); } else { // Local wiki filter $dbr = wfGetDB( DB_REPLICA ); } - $fields = [ - 'af_id', - 'af_pattern', - 'af_public_comments', - 'af_timestamp' - ]; - $row = $dbr->selectRow( 'abuse_filter', - $fields, - [ 'af_id' => $id ], + self::ALL_ABUSE_FILTER_FIELDS, + [ 'af_id' => $filterID ], __METHOD__ ); - self::$filterCache[$id] = $row ?: null; + self::$filterCache[$filter] = $row ?: null; } - return self::$filterCache[$id]; + return self::$filterCache[$filter]; } /** - * @param BagOStuff $cache - * @param AbuseFilterVariableHolder $vars - * @param string $group The filter's group (as defined in $wgAbuseFilterValidGroups) - * - * @return string + * Checks whether the given object represents a full abuse_filter DB row + * @param stdClass $row + * @return bool */ - private static function getStashKey( - BagOStuff $cache, AbuseFilterVariableHolder $vars, $group - ) { - $inputVars = $vars->exportNonLazyVars(); - // Exclude noisy fields that have superficial changes - $excludedVars = [ - 'old_html' => true, - 'new_html' => true, - 'user_age' => true, - 'timestamp' => true, - 'page_age' => true, - 'moved_from_age' => true, - 'moved_to_age' => true - ]; + public static function isFullAbuseFilterRow( stdClass $row ) { + $actual = array_keys( get_object_vars( $row ) ); - $inputVars = array_diff_key( $inputVars, $excludedVars ); - ksort( $inputVars ); - $hash = md5( serialize( $inputVars ) ); - - return $cache->makeKey( - 'abusefilter', - 'check-stash', - $group, - $hash, - 'v1' - ); + if ( + count( $actual ) !== count( self::ALL_ABUSE_FILTER_FIELDS ) + || array_diff( self::ALL_ABUSE_FILTER_FIELDS, $actual ) + ) { + return false; + } + return true; } /** - * @param array[] $actions_taken - * @param array $log_template - * @param AbuseFilterVariableHolder $vars - * @param string $group The filter's group (as defined in $wgAbuseFilterValidGroups) + * Saves an abuse_filter row in cache + * @param string $id Filter ID (integer or "<GLOBAL_FILTER_PREFIX><integer>") + * @param stdClass $row A full abuse_filter row to save + * @throws UnexpectedValueException if the row is not full */ - public static function addLogEntries( $actions_taken, $log_template, $vars, $group = 'default' ) { - $dbw = wfGetDB( DB_MASTER ); - - $central_log_template = [ - 'afl_wiki' => wfWikiID(), - ]; - - $log_rows = []; - $central_log_rows = []; - $logged_local_filters = []; - $logged_global_filters = []; - - foreach ( $actions_taken as $filter => $actions ) { - $globalIndex = self::decodeGlobalName( $filter ); - $thisLog = $log_template; - $thisLog['afl_filter'] = $filter; - $thisLog['afl_actions'] = implode( ',', $actions ); - - // Don't log if we were only throttling. - if ( $thisLog['afl_actions'] != 'throttle' ) { - $log_rows[] = $thisLog; - // Global logging - if ( $globalIndex ) { - $title = Title::makeTitle( $thisLog['afl_namespace'], $thisLog['afl_title'] ); - $centralLog = $thisLog + $central_log_template; - $centralLog['afl_filter'] = $globalIndex; - $centralLog['afl_title'] = $title->getPrefixedText(); - $centralLog['afl_namespace'] = 0; - - $central_log_rows[] = $centralLog; - $logged_global_filters[] = $globalIndex; - } else { - $logged_local_filters[] = $filter; - } - } + public static function cacheFilter( $id, $row ) { + // Check that all fields have been passed, otherwise using self::getFilter for this + // row will return partial data. + if ( !self::isFullAbuseFilterRow( $row ) ) { + throw new UnexpectedValueException( 'The specified row must be a full abuse_filter row.' ); } - - if ( !count( $log_rows ) ) { - return; - } - - // Only store the var dump if we're actually going to add log rows. - $var_dump = self::storeVarDump( $vars ); - // To distinguish from stuff stored directly - $var_dump = "stored-text:$var_dump"; - - $stash = ObjectCache::getMainStashInstance(); - - // Increment trigger counter - $stash->incr( self::filterMatchesKey() ); - - $local_log_ids = []; - global $wgAbuseFilterNotifications, $wgAbuseFilterNotificationsPrivate; - foreach ( $log_rows as $data ) { - $data['afl_var_dump'] = $var_dump; - $data['afl_id'] = $dbw->nextSequenceValue( 'abuse_filter_log_afl_id_seq' ); - $dbw->insert( 'abuse_filter_log', $data, __METHOD__ ); - $local_log_ids[] = $data['afl_id'] = $dbw->insertId(); - // Give grep a chance to find the usages: - // logentry-abusefilter-hit - $entry = new ManualLogEntry( 'abusefilter', 'hit' ); - // Construct a user object - $user = User::newFromId( $data['afl_user'] ); - $user->setName( $data['afl_user_text'] ); - $entry->setPerformer( $user ); - $entry->setTarget( Title::makeTitle( $data['afl_namespace'], $data['afl_title'] ) ); - // Additional info - $entry->setParameters( [ - 'action' => $data['afl_action'], - 'filter' => $data['afl_filter'], - 'actions' => $data['afl_actions'], - 'log' => $data['afl_id'], - ] ); - - // Send data to CheckUser if installed and we - // aren't already sending a notification to recentchanges - if ( ExtensionRegistry::getInstance()->isLoaded( 'CheckUser' ) - && strpos( $wgAbuseFilterNotifications, 'rc' ) === false - ) { - $rc = $entry->getRecentChange(); - CheckUserHooks::updateCheckUserData( $rc ); - } - - if ( $wgAbuseFilterNotifications !== false ) { - if ( self::filterHidden( $data['afl_filter'] ) && !$wgAbuseFilterNotificationsPrivate ) { - continue; - } - $entry->publish( 0, $wgAbuseFilterNotifications ); - } - } - - $method = __METHOD__; - - if ( count( $logged_local_filters ) ) { - // Update hit-counter. - $dbw->onTransactionPreCommitOrIdle( - function () use ( $dbw, $logged_local_filters, $method ) { - $dbw->update( 'abuse_filter', - [ 'af_hit_count=af_hit_count+1' ], - [ 'af_id' => $logged_local_filters ], - $method - ); - } - ); - } - - $global_log_ids = []; - - // Global stuff - if ( count( $logged_global_filters ) ) { - $vars->computeDBVars(); - $global_var_dump = self::storeVarDump( $vars, true ); - $global_var_dump = "stored-text:$global_var_dump"; - foreach ( $central_log_rows as $index => $data ) { - $central_log_rows[$index]['afl_var_dump'] = $global_var_dump; - } - - global $wgAbuseFilterCentralDB; - $fdb = wfGetDB( DB_MASTER, [], $wgAbuseFilterCentralDB ); - - foreach ( $central_log_rows as $row ) { - $fdb->insert( 'abuse_filter_log', $row, __METHOD__ ); - $global_log_ids[] = $fdb->insertId(); - } - - $fdb->onTransactionPreCommitOrIdle( - function () use ( $fdb, $logged_global_filters, $method ) { - $fdb->update( 'abuse_filter', - [ 'af_hit_count=af_hit_count+1' ], - [ 'af_id' => $logged_global_filters ], - $method - ); - } - ); - } - - $vars->setVar( 'global_log_ids', $global_log_ids ); - $vars->setVar( 'local_log_ids', $local_log_ids ); - - // Check for emergency disabling. - $total = $stash->get( self::filterUsedKey( $group ) ); - self::checkEmergencyDisable( $group, $logged_local_filters, $total ); + self::$filterCache[$id] = $row; } /** @@ -1428,9 +415,9 @@ class AbuseFilter { * @param AbuseFilterVariableHolder $vars * @param bool $global * - * @return int|null + * @return int The insert ID. */ - public static function storeVarDump( $vars, $global = false ) { + public static function storeVarDump( AbuseFilterVariableHolder $vars, $global = false ) { global $wgCompressRevisions; // Get all variables yet set and compute old and new wikitext if not yet done @@ -1438,14 +425,12 @@ class AbuseFilter { $vars = $vars->dumpAllVars( [ 'old_wikitext', 'new_wikitext' ] ); // Vars is an array with native PHP data types (non-objects) now - $text = serialize( $vars ); - $flags = [ 'nativeDataArray' ]; + $text = FormatJson::encode( $vars ); + $flags = [ 'utf-8' ]; - if ( $wgCompressRevisions ) { - if ( function_exists( 'gzdeflate' ) ) { - $text = gzdeflate( $text ); - $flags[] = 'gzip'; - } + if ( $wgCompressRevisions && function_exists( 'gzdeflate' ) ) { + $text = gzdeflate( $text ); + $flags[] = 'gzip'; } // Store to ExternalStore if applicable @@ -1456,24 +441,18 @@ class AbuseFilter { } else { $text = ExternalStore::insertToDefault( $text ); } - $flags[] = 'external'; - if ( !$text ) { - // Not mission-critical, just return nothing - return null; - } + $flags[] = 'external'; } // Store to text table if ( $global ) { - $dbw = wfGetDB( DB_MASTER, [], $wgAbuseFilterCentralDB ); + $dbw = self::getCentralDB( DB_MASTER ); } else { $dbw = wfGetDB( DB_MASTER ); } - $old_id = $dbw->nextSequenceValue( 'text_old_id_seq' ); $dbw->insert( 'text', [ - 'old_id' => $old_id, 'old_text' => $text, 'old_flags' => implode( ',', $flags ), ], __METHOD__ @@ -1488,25 +467,27 @@ class AbuseFilter { * * @param string $stored_dump * - * @return array|object|AbuseFilterVariableHolder|bool + * @return AbuseFilterVariableHolder */ - public static function loadVarDump( $stored_dump ) { - // Backward compatibility - if ( substr( $stored_dump, 0, strlen( 'stored-text:' ) ) !== 'stored-text:' ) { + public static function loadVarDump( $stored_dump ) : AbuseFilterVariableHolder { + // Backward compatibility for (old) blobs stored in the abuse_filter_log table + if ( !is_numeric( $stored_dump ) && + substr( $stored_dump, 0, strlen( 'stored-text:' ) ) !== 'stored-text:' && + substr( $stored_dump, 0, strlen( 'tt:' ) ) !== 'tt:' + ) { $data = unserialize( $stored_dump ); - if ( is_array( $data ) ) { - $vh = new AbuseFilterVariableHolder; - foreach ( $data as $name => $value ) { - $vh->setVar( $name, $value ); - } - - return $vh; - } else { - return $data; - } + return is_array( $data ) ? AbuseFilterVariableHolder::newFromArray( $data ) : $data; } - $text_id = substr( $stored_dump, strlen( 'stored-text:' ) ); + if ( is_numeric( $stored_dump ) ) { + $text_id = (int)$stored_dump; + } elseif ( strpos( $stored_dump, 'stored-text:' ) !== false ) { + $text_id = (int)str_replace( 'stored-text:', '', $stored_dump ); + } elseif ( strpos( $stored_dump, 'tt:' ) !== false ) { + $text_id = (int)str_replace( 'tt:', '', $stored_dump ); + } else { + throw new LogicException( "Cannot understand format: $stored_dump" ); + } $dbr = wfGetDB( DB_REPLICA ); @@ -1518,10 +499,12 @@ class AbuseFilter { ); if ( !$text_row ) { + $logger = LoggerFactory::getInstance( 'AbuseFilter' ); + $logger->warning( __METHOD__ . ": no text row found for input $stored_dump." ); return new AbuseFilterVariableHolder; } - $flags = explode( ',', $text_row->old_flags ); + $flags = $text_row->old_flags === '' ? [] : explode( ',', $text_row->old_flags ); $text = $text_row->old_text; if ( in_array( 'external', $flags ) ) { @@ -1532,366 +515,60 @@ class AbuseFilter { $text = gzinflate( $text ); } - $obj = unserialize( $text ); + $obj = FormatJson::decode( $text, true ); + if ( $obj === null ) { + // Temporary code until all rows will be JSON-encoded + $obj = unserialize( $text ); + } - if ( in_array( 'nativeDataArray', $flags ) ) { + if ( in_array( 'nativeDataArray', $flags ) || + // Temporary condition: we don't add the flag anymore, but the updateVarDump + // script could be still running and we cannot assume that this branch is the default. + ( is_array( $obj ) && array_key_exists( 'action', $obj ) ) + ) { $vars = $obj; - $obj = new AbuseFilterVariableHolder(); - foreach ( $vars as $key => $value ) { - $obj->setVar( $key, $value ); - } - // If old variable names are used, make sure to keep them - if ( count( array_intersect_key( self::getDeprecatedVariables(), $obj->mVars ) ) !== 0 ) { - $obj->mVarsVersion = 1; - } + $obj = AbuseFilterVariableHolder::newFromArray( $vars ); + $obj->translateDeprecatedVars(); } return $obj; } /** - * @param string $action - * @param array $parameters - * @param Title $title - * @param AbuseFilterVariableHolder $vars - * @param string $rule_desc - * @param int|string $rule_number - * @param User $user + * Get an identifier for the given action to be used in self::$tagsToSet * - * @return array|null a message describing the action that was taken, - * or null if no action was taken. The message is given as an array - * containing the message key followed by any message parameters. + * @param string $action The name of the current action, as used by AbuseFilter (e.g. 'edit' + * or 'createaccount') + * @param Title $title The title where the current action is executed on. This is the user page + * for account creations. + * @param string $username Of the user executing the action (as returned by User::getName()). + * For account creation, this is the name of the new account. + * @return string */ - public static function takeConsequenceAction( $action, $parameters, $title, - $vars, $rule_desc, $rule_number, User $user ) { - global $wgAbuseFilterCustomActionsHandlers, $wgRequest; - - $message = null; - - switch ( $action ) { - case 'disallow': - if ( isset( $parameters[0] ) ) { - $message = [ $parameters[0], $rule_desc, $rule_number ]; - } else { - // Generic message. - $message = [ - 'abusefilter-disallowed', - $rule_desc, - $rule_number - ]; - } - break; - case 'rangeblock': - global $wgAbuseFilterRangeBlockSize, $wgBlockCIDRLimit; - - $ip = $wgRequest->getIP(); - if ( IP::isIPv6( $ip ) ) { - $CIDRsize = max( $wgAbuseFilterRangeBlockSize['IPv6'], $wgBlockCIDRLimit['IPv6'] ); - } else { - $CIDRsize = max( $wgAbuseFilterRangeBlockSize['IPv4'], $wgBlockCIDRLimit['IPv4'] ); - } - $blockCIDR = $ip . '/' . $CIDRsize; - self::doAbuseFilterBlock( - [ - 'desc' => $rule_desc, - 'number' => $rule_number - ], - IP::sanitizeRange( $blockCIDR ), - '1 week', - false - ); - - $message = [ - 'abusefilter-blocked-display', - $rule_desc, - $rule_number - ]; - break; - case 'degroup': - if ( !$user->isAnon() ) { - // Remove all groups from the user. - $groups = $user->getGroups(); - // Make sure that the stored var dump contains user groups, since we may - // need them if reverting this degroup via Special:AbuseFilter/revert - $vars->setVar( 'user_groups', $groups ); - - foreach ( $groups as $group ) { - $user->removeGroup( $group ); - } - - $message = [ - 'abusefilter-degrouped', - $rule_desc, - $rule_number - ]; - - // Don't log it if there aren't any groups being removed! - if ( !count( $groups ) ) { - break; - } - - $logEntry = new ManualLogEntry( 'rights', 'rights' ); - $logEntry->setPerformer( self::getFilterUser() ); - $logEntry->setTarget( $user->getUserPage() ); - $logEntry->setComment( - wfMessage( - 'abusefilter-degroupreason', - $rule_desc, - $rule_number - )->inContentLanguage()->text() - ); - $logEntry->setParameters( [ - '4::oldgroups' => $groups, - '5::newgroups' => [] - ] ); - $logEntry->publish( $logEntry->insert() ); - } - - break; - case 'blockautopromote': - if ( !$user->isAnon() ) { - // Block for 3-7 days. - $blockPeriod = (int)mt_rand( 3 * 86400, 7 * 86400 ); - ObjectCache::getMainStashInstance()->set( - self::autoPromoteBlockKey( $user ), true, $blockPeriod - ); - - $message = [ - 'abusefilter-autopromote-blocked', - $rule_desc, - $rule_number - ]; - } - break; - - case 'block': - // Do nothing, handled at the end of executeFilterActions. Here for completeness. - break; - case 'flag': - // Do nothing. Here for completeness. - break; - - case 'tag': - // Mark with a tag on recentchanges. - $actionID = implode( '-', [ - $title->getPrefixedText(), $user->getName(), - $vars->getVar( 'ACTION' )->toString() - ] ); - - self::bufferTagsToSetByAction( [ $actionID => $parameters ] ); - break; - default: - if ( isset( $wgAbuseFilterCustomActionsHandlers[$action] ) ) { - $custom_function = $wgAbuseFilterCustomActionsHandlers[$action]; - if ( is_callable( $custom_function ) ) { - $msg = call_user_func( - $custom_function, - $action, - $parameters, - $title, - $vars, - $rule_desc, - $rule_number - ); - } - if ( isset( $msg ) ) { - $message = [ $msg ]; - } - } else { - $logger = LoggerFactory::getInstance( 'AbuseFilter' ); - $logger->debug( "Unrecognised action $action" ); - } - } - - return $message; + public static function getTaggingActionId( $action, Title $title, $username ) { + return implode( + '-', + [ + $title->getPrefixedText(), + $username, + $action + ] + ); } /** * @param array[] $tagsByAction Map of (integer => string[]) */ - private static function bufferTagsToSetByAction( array $tagsByAction ) { - global $wgAbuseFilterActions; - if ( isset( $wgAbuseFilterActions['tag'] ) && $wgAbuseFilterActions['tag'] ) { - foreach ( $tagsByAction as $actionID => $tags ) { - if ( !isset( self::$tagsToSet[$actionID] ) ) { - self::$tagsToSet[$actionID] = $tags; - } else { - self::$tagsToSet[$actionID] = array_merge( self::$tagsToSet[$actionID], $tags ); - } - } - } - } - - /** - * Perform a block by the AbuseFilter system user - * @param array $rule should have 'desc' and 'number' - * @param string $target - * @param string $expiry - * @param bool $isAutoBlock - * @param bool $preventEditOwnUserTalk - */ - protected static function doAbuseFilterBlock( - array $rule, - $target, - $expiry, - $isAutoBlock, - $preventEditOwnUserTalk = false - ) { - $filterUser = self::getFilterUser(); - $reason = wfMessage( - 'abusefilter-blockreason', - $rule['desc'], $rule['number'] - )->inContentLanguage()->text(); - - $block = new Block(); - $block->setTarget( $target ); - $block->setBlocker( $filterUser ); - $block->mReason = $reason; - $block->isHardblock( false ); - $block->isAutoblocking( $isAutoBlock ); - $block->prevents( 'createaccount', true ); - $block->prevents( 'editownusertalk', $preventEditOwnUserTalk ); - $block->mExpiry = SpecialBlock::parseExpiryInput( $expiry ); - - $success = $block->insert(); - - if ( $success ) { - // Log it only if the block was successful - $logParams = []; - $logParams['5::duration'] = ( $block->mExpiry === 'infinity' ) - ? 'indefinite' - : $expiry; - $flags = [ 'nocreate' ]; - if ( !$block->isAutoblocking() && !IP::isIPAddress( $target ) ) { - // Conditionally added same as SpecialBlock - $flags[] = 'noautoblock'; - } - if ( $preventEditOwnUserTalk === true ) { - $flags[] = 'nousertalk'; + public static function bufferTagsToSetByAction( array $tagsByAction ) { + foreach ( $tagsByAction as $actionID => $tags ) { + if ( !isset( self::$tagsToSet[ $actionID ] ) ) { + self::$tagsToSet[ $actionID ] = $tags; + } else { + self::$tagsToSet[ $actionID ] = array_unique( + array_merge( self::$tagsToSet[ $actionID ], $tags ) + ); } - $logParams['6::flags'] = implode( ',', $flags ); - - $logEntry = new ManualLogEntry( 'block', 'block' ); - $logEntry->setTarget( Title::makeTitle( NS_USER, $target ) ); - $logEntry->setComment( $reason ); - $logEntry->setPerformer( $filterUser ); - $logEntry->setParameters( $logParams ); - $blockIds = array_merge( [ $success['id'] ], $success['autoIds'] ); - $logEntry->setRelations( [ 'ipb_id' => $blockIds ] ); - $logEntry->publish( $logEntry->insert() ); - } - } - - /** - * @param string $throttleId - * @param string $types - * @param Title $title - * @param string $rateCount - * @param string $ratePeriod - * @param bool $global - * @return bool - */ - public static function isThrottled( $throttleId, $types, $title, $rateCount, - $ratePeriod, $global = false - ) { - $stash = ObjectCache::getMainStashInstance(); - $key = self::throttleKey( $throttleId, $types, $title, $global ); - $count = intval( $stash->get( $key ) ); - - $logger = LoggerFactory::getInstance( 'AbuseFilter' ); - $logger->debug( "Got value $count for throttle key $key" ); - - if ( $count > 0 ) { - $stash->incr( $key ); - $count++; - $logger->debug( "Incremented throttle key $key" ); - } else { - $logger->debug( "Added throttle key $key with value 1" ); - $stash->add( $key, 1, $ratePeriod ); - $count = 1; - } - - if ( $count > $rateCount ) { - $logger->debug( "Throttle $key hit value $count -- maximum is $rateCount." ); - - // THROTTLED - return true; - } - - $logger->debug( "Throttle $key not hit!" ); - - // NOT THROTTLED - return false; - } - - /** - * @param string $type - * @param Title $title - * @return int|string - */ - public static function throttleIdentifier( $type, $title ) { - global $wgUser, $wgRequest; - - switch ( $type ) { - case 'ip': - $identifier = $wgRequest->getIP(); - break; - case 'user': - $identifier = $wgUser->getId(); - break; - case 'range': - $identifier = substr( IP::toHex( $wgRequest->getIP() ), 0, 4 ); - break; - case 'creationdate': - $reg = $wgUser->getRegistration(); - $identifier = $reg - ( $reg % 86400 ); - break; - case 'editcount': - // Hack for detecting different single-purpose accounts. - $identifier = $wgUser->getEditCount(); - break; - case 'site': - $identifier = 1; - break; - case 'page': - $identifier = $title->getPrefixedText(); - break; - default: - $identifier = 0; } - - return $identifier; - } - - /** - * @param string $throttleId - * @param string $type - * @param Title $title - * @param bool $global - * @return string - */ - public static function throttleKey( $throttleId, $type, $title, $global = false ) { - $types = explode( ',', $type ); - - $identifiers = []; - - foreach ( $types as $subtype ) { - $identifiers[] = self::throttleIdentifier( $subtype, $title ); - } - - $identifier = sha1( implode( ':', $identifiers ) ); - - global $wgAbuseFilterIsCentral, $wgAbuseFilterCentralDB; - - if ( $global && !$wgAbuseFilterIsCentral ) { - list( $globalSite, $globalPrefix ) = wfSplitWikiID( $wgAbuseFilterCentralDB ); - - return wfForeignMemcKey( - $globalSite, $globalPrefix, - 'abusefilter', 'throttle', $throttleId, $type, $identifier ); - } - - return wfMemcKey( 'abusefilter', 'throttle', $throttleId, $type, $identifier ); } /** @@ -1901,176 +578,159 @@ class AbuseFilter { public static function getGlobalRulesKey( $group ) { global $wgAbuseFilterIsCentral, $wgAbuseFilterCentralDB; + $cache = MediaWikiServices::getInstance()->getMainWANObjectCache(); if ( !$wgAbuseFilterIsCentral ) { - list( $globalSite, $globalPrefix ) = wfSplitWikiID( $wgAbuseFilterCentralDB ); - - return wfForeignMemcKey( - $globalSite, $globalPrefix, - 'abusefilter', 'rules', $group - ); + return $cache->makeGlobalKey( 'abusefilter', 'rules', $wgAbuseFilterCentralDB, $group ); } - return wfMemcKey( 'abusefilter', 'rules', $group ); + return $cache->makeKey( 'abusefilter', 'rules', $group ); } /** - * @param User $user - * @return string + * Gets the autopromotion block status for the given user + * + * @param User $target + * @return int */ - public static function autoPromoteBlockKey( $user ) { - return wfMemcKey( 'abusefilter', 'block-autopromote', $user->getId() ); + public static function getAutoPromoteBlockStatus( User $target ) { + $store = ObjectCache::getInstance( 'db-replicated' ); + + return (int)$store->get( self::autoPromoteBlockKey( $store, $target ) ); } /** - * Update statistics, and disable filters which are over-blocking. - * @param bool[] $filters - * @param string $group The filter's group (as defined in $wgAbuseFilterValidGroups) - */ - public static function recordStats( $filters, $group = 'default' ) { - global $wgAbuseFilterConditionLimit, $wgAbuseFilterProfileActionsCap; - - $stash = ObjectCache::getMainStashInstance(); - - // Figure out if we've triggered overflows and blocks. - $overflow_triggered = ( self::$condCount > $wgAbuseFilterConditionLimit ); - - $overflow_key = self::filterLimitReachedKey(); - $total_key = self::filterUsedKey( $group ); - - $total = $stash->get( $total_key ); - - $storage_period = self::$statsStoragePeriod; - - if ( !$total || $total > $wgAbuseFilterProfileActionsCap ) { - // This is for if the total doesn't exist, or has gone past 10,000. - // Recreate all the keys at the same time, so they expire together. - $stash->set( $total_key, 0, $storage_period ); - $stash->set( $overflow_key, 0, $storage_period ); - - foreach ( $filters as $filter => $matched ) { - $stash->set( self::filterMatchesKey( $filter ), 0, $storage_period ); - } - $stash->set( self::filterMatchesKey(), 0, $storage_period ); + * Blocks autopromotion for the given user + * + * @param User $target + * @param string $msg The message to show in the log + * @param int $duration Duration for which autopromotion is blocked, in seconds + * @return bool True on success, false on failure + */ + public static function blockAutoPromote( User $target, $msg, int $duration ) { + $store = ObjectCache::getInstance( 'db-replicated' ); + if ( !$store->set( + self::autoPromoteBlockKey( $store, $target ), + 1, + $duration + ) ) { + // Failed to set key + $logger = LoggerFactory::getInstance( 'AbuseFilter' ); + $logger->warning( + "Failed to block autopromotion for $target. Error: " . $store->getLastError() + ); + return false; } - $stash->incr( $total_key ); + $logEntry = new ManualLogEntry( 'rights', 'blockautopromote' ); + $performer = self::getFilterUser(); + $logEntry->setPerformer( $performer ); + $logEntry->setTarget( $target->getUserPage() ); - // Increment overflow counter, if our condition limit overflowed - if ( $overflow_triggered ) { - $stash->incr( $overflow_key ); - } + $logEntry->setParameters( [ + '7::duration' => $duration, + // These parameters are unused in our message, but some parts of the code check for them + '4::oldgroups' => [], + '5::newgroups' => [] + ] ); + $logEntry->setComment( $msg ); + $logEntry->publish( $logEntry->insert() ); + + return true; } /** - * Record runtime profiling data + * Unblocks autopromotion for the given user * - * @param int $totalFilters - * @param int $totalConditions - * @param float $runtime - */ - private static function recordRuntimeProfilingResult( $totalFilters, $totalConditions, $runtime ) { - $keyPrefix = 'abusefilter.runtime-profile.' . wfWikiID() . '.'; + * @param User $target + * @param User $performer + * @param string $msg The message to show in the log + * @return bool True on success, false on failure + */ + public static function unblockAutopromote( User $target, User $performer, $msg ) { + // Immediately expire (delete) the key, failing if it does not exist + $store = ObjectCache::getInstance( 'db-replicated' ); + $expireAt = time() - $store::TTL_HOUR; + if ( !$store->changeTTL( self::autoPromoteBlockKey( $store, $target ), $expireAt ) ) { + // Key did not exist to begin with; nothing to do + return false; + } - $statsd = MediaWikiServices::getInstance()->getStatsdDataFactory(); - $statsd->timing( $keyPrefix . 'runtime', $runtime ); - $statsd->timing( $keyPrefix . 'total_filters', $totalFilters ); - $statsd->timing( $keyPrefix . 'total_conditions', $totalConditions ); + $logEntry = new ManualLogEntry( 'rights', 'restoreautopromote' ); + $logEntry->setTarget( Title::makeTitle( NS_USER, $target->getName() ) ); + $logEntry->setComment( $msg ); + // These parameters are unused in our message, but some parts of the code check for them + $logEntry->setParameters( [ + '4::oldgroups' => [], + '5::newgroups' => [] + ] ); + $logEntry->setPerformer( $performer ); + $logEntry->publish( $logEntry->insert() ); + + return true; } /** - * @param string $group The filter's group (as defined in $wgAbuseFilterValidGroups) - * @param string[] $filters - * @param int $total + * @param BagOStuff $store + * @param User $target + * @return string + * @internal */ - public static function checkEmergencyDisable( $group, $filters, $total ) { - global $wgAbuseFilterEmergencyDisableThreshold, $wgAbuseFilterEmergencyDisableCount, - $wgAbuseFilterEmergencyDisableAge; - - $stash = ObjectCache::getMainStashInstance(); - foreach ( $filters as $filter ) { - // Determine emergency disable values for this action - $emergencyDisableThreshold = - self::getEmergencyValue( $wgAbuseFilterEmergencyDisableThreshold, $group ); - $filterEmergencyDisableCount = - self::getEmergencyValue( $wgAbuseFilterEmergencyDisableCount, $group ); - $emergencyDisableAge = - self::getEmergencyValue( $wgAbuseFilterEmergencyDisableAge, $group ); - - // Increment counter - $matchCount = $stash->get( self::filterMatchesKey( $filter ) ); - - // Handle missing keys... - if ( !$matchCount ) { - $stash->set( self::filterMatchesKey( $filter ), 1, self::$statsStoragePeriod ); - } else { - $stash->incr( self::filterMatchesKey( $filter ) ); - } - $matchCount++; - - // Figure out if the filter is subject to being deleted. - $filter_age = wfTimestamp( TS_UNIX, self::getFilter( $filter )->af_timestamp ); - $throttle_exempt_time = $filter_age + $emergencyDisableAge; - - if ( $total && $throttle_exempt_time > time() - && $matchCount > $filterEmergencyDisableCount - && ( $matchCount / $total ) > $emergencyDisableThreshold - ) { - // More than $wgAbuseFilterEmergencyDisableCount matches, - // constituting more than $emergencyDisableThreshold - // (a fraction) of last few edits. Disable it. - DeferredUpdates::addUpdate( - new AutoCommitUpdate( - wfGetDB( DB_MASTER ), - __METHOD__, - function ( IDatabase $dbw, $fname ) use ( $filter ) { - $dbw->update( 'abuse_filter', - [ 'af_throttled' => 1 ], - [ 'af_id' => $filter ], - $fname - ); - } - ) - ); - } - } + public static function autoPromoteBlockKey( BagOStuff $store, User $target ) { + return $store->makeKey( 'abusefilter', 'block-autopromote', $target->getId() ); } /** - * @param array $emergencyValue + * @param string $type The value to get, either "threshold", "count" or "age" * @param string $group The filter's group (as defined in $wgAbuseFilterValidGroups) * @return mixed */ - public static function getEmergencyValue( array $emergencyValue, $group ) { - return $emergencyValue[$group] ?? $emergencyValue['default']; - } + public static function getEmergencyValue( $type, $group ) { + switch ( $type ) { + case 'threshold': + global $wgAbuseFilterEmergencyDisableThreshold; + $value = $wgAbuseFilterEmergencyDisableThreshold; + break; + case 'count': + global $wgAbuseFilterEmergencyDisableCount; + $value = $wgAbuseFilterEmergencyDisableCount; + break; + case 'age': + global $wgAbuseFilterEmergencyDisableAge; + $value = $wgAbuseFilterEmergencyDisableAge; + break; + default: + throw new InvalidArgumentException( '$type must be either "threshold", "count" or "age"' ); + } - /** - * @return string - */ - public static function filterLimitReachedKey() { - return wfMemcKey( 'abusefilter', 'stats', 'overflow' ); + return $value[$group] ?? $value['default']; } /** - * @param string|null $group The filter's group (as defined in $wgAbuseFilterValidGroups) + * Get the memcache access key used to store per-filter profiling data. + * + * @param string|int $filter * @return string */ - public static function filterUsedKey( $group = null ) { - return wfMemcKey( 'abusefilter', 'stats', 'total', $group ); + public static function filterProfileKey( $filter ) { + $cache = MediaWikiServices::getInstance()->getMainWANObjectCache(); + return $cache->makeKey( 'abusefilter-profile', 'v3', $filter ); } /** - * @param string|null $filter + * Memcache access key used to store overall profiling data for rule groups + * + * @param string $group * @return string */ - public static function filterMatchesKey( $filter = null ) { - return wfMemcKey( 'abusefilter', 'stats', 'matches', $filter ); + public static function filterProfileGroupKey( $group ) { + $cache = MediaWikiServices::getInstance()->getMainWANObjectCache(); + return $cache->makeKey( 'abusefilter-profile', 'group', $group ); } /** * @return User */ - public static function getFilterUser() { + public static function getFilterUser() : User { $username = wfMessage( 'abusefilter-blocker' )->inContentLanguage()->text(); $user = User::newSystemUser( $username, [ 'steal' => true ] ); @@ -2086,6 +746,7 @@ class AbuseFilter { $defaultName = wfMessage( 'abusefilter-blocker' )->inLanguage( 'en' )->text(); $user = User::newSystemUser( $defaultName, [ 'steal' => true ] ); } + '@phan-var User $user'; // Promote user to 'sysop' so it doesn't look // like an unprivileged account is blocking users @@ -2102,21 +763,22 @@ class AbuseFilter { * @param bool $canEdit * @return array */ - public static function getAceConfig( $canEdit ) { - $values = self::getBuilderValues(); - $deprecatedVars = self::getDeprecatedVariables(); + public static function getAceConfig( bool $canEdit ): array { + $keywordsManager = AbuseFilterServices::getKeywordsManager(); + $values = $keywordsManager->getBuilderValues(); + $deprecatedVars = $keywordsManager->getDeprecatedVariables(); $builderVariables = implode( '|', array_keys( $values['vars'] ) ); - $builderFunctions = implode( '|', array_keys( AbuseFilterParser::$mFunctions ) ); - // AbuseFilterTokenizer::$keywords also includes constants (true, false and null), + $builderFunctions = implode( '|', array_keys( AbuseFilterParser::FUNCTIONS ) ); + // AbuseFilterTokenizer::KEYWORDS also includes constants (true, false and null), // but Ace redefines these constants afterwards so this will not be an issue - $builderKeywords = implode( '|', AbuseFilterTokenizer::$keywords ); + $builderKeywords = implode( '|', AbuseFilterTokenizer::KEYWORDS ); // Extract operators from tokenizer like we do in AbuseFilterParserTest $operators = implode( '|', array_map( function ( $op ) { return preg_quote( $op, '/' ); - }, AbuseFilterTokenizer::$operators ) ); + }, AbuseFilterTokenizer::OPERATORS ) ); $deprecatedVariables = implode( '|', array_keys( $deprecatedVars ) ); - $disabledVariables = implode( '|', array_keys( self::$disabledVars ) ); + $disabledVariables = implode( '|', array_keys( $keywordsManager->getDisabledVariables() ) ); return [ 'variables' => $builderVariables, @@ -2130,45 +792,6 @@ class AbuseFilter { } /** - * Build input and button for loading a filter - * - * @return string - */ - public static function buildFilterLoader() { - $loadText = - new OOUI\TextInputWidget( - [ - 'type' => 'number', - 'name' => 'wpInsertFilter', - 'id' => 'mw-abusefilter-load-filter' - ] - ); - $loadButton = - new OOUI\ButtonWidget( - [ - 'label' => wfMessage( 'abusefilter-test-load' )->text(), - 'id' => 'mw-abusefilter-load' - ] - ); - $loadGroup = - new OOUI\ActionFieldLayout( - $loadText, - $loadButton, - [ - 'label' => wfMessage( 'abusefilter-test-load-filter' )->text() - ] - ); - // CSS class for reducing default input field width - $loadDiv = - Xml::tags( - 'div', - [ 'class' => 'mw-abusefilter-load-filter-id' ], - $loadGroup - ); - return $loadDiv; - } - - /** * Check whether a filter is allowed to use a tag * * @param string $tag Tag name @@ -2220,9 +843,7 @@ class AbuseFilter { * @return null|string Null on success, a string with the error message on failure */ public static function checkThrottleParameters( $params ) { - $throttleRate = explode( ',', $params[1] ); - $throttleCount = $throttleRate[0]; - $throttlePeriod = $throttleRate[1]; + list( $throttleCount, $throttlePeriod ) = explode( ',', $params[1], 2 ); $throttleGroups = array_slice( $params, 2 ); $validGroups = [ 'ip', @@ -2284,20 +905,33 @@ class AbuseFilter { } /** - * Checks whether user input for the filter editing form is valid and if so saves the filter + * Checks whether user input for the filter editing form is valid and if so saves the filter. + * Returns a Status object which can be: + * - Good with [ new_filter_id, history_id ] as value if the filter was successfully saved + * - Good with value = false if everything went fine but the filter is unchanged + * - OK with errors if a validation error occurred + * - Fatal in case of a permission-related error * - * @param AbuseFilterViewEdit $page + * @param ContextSource $context * @param int|string $filter - * @param WebRequest $request * @param stdClass $newRow * @param array $actions + * @param IDatabase $dbw DB_MASTER Where the filter should be saved * @return Status */ - public static function saveFilter( $page, $filter, $request, $newRow, $actions ) { + public static function saveFilter( + ContextSource $context, + $filter, + $newRow, + $actions, + IDatabase $dbw + ) { $validationStatus = Status::newGood(); + $request = $context->getRequest(); + $user = $context->getUser(); // Check the syntax - $syntaxerr = self::checkSyntax( $request->getVal( 'wpFilterRules' ) ); + $syntaxerr = self::getDefaultParser()->checkSyntax( $request->getVal( 'wpFilterRules' ) ); if ( $syntaxerr !== true ) { $validationStatus->error( 'abusefilter-edit-badsyntax', $syntaxerr[0] ); return $validationStatus; @@ -2306,27 +940,30 @@ class AbuseFilter { $missing = []; if ( !$request->getVal( 'wpFilterRules' ) || trim( $request->getVal( 'wpFilterRules' ) ) === '' ) { - $missing[] = wfMessage( 'abusefilter-edit-field-conditions' )->escaped(); + $missing[] = $context->msg( 'abusefilter-edit-field-conditions' )->escaped(); } if ( !$request->getVal( 'wpFilterDescription' ) ) { - $missing[] = wfMessage( 'abusefilter-edit-field-description' )->escaped(); + $missing[] = $context->msg( 'abusefilter-edit-field-description' )->escaped(); } if ( count( $missing ) !== 0 ) { - $missing = $page->getLanguage()->commaList( $missing ); + $missing = $context->getLanguage()->commaList( $missing ); $validationStatus->error( 'abusefilter-edit-missingfields', $missing ); return $validationStatus; } // Don't allow setting as deleted an active filter - if ( $request->getCheck( 'wpFilterEnabled' ) == true && - $request->getCheck( 'wpFilterDeleted' ) == true ) { + if ( $request->getCheck( 'wpFilterEnabled' ) && $request->getCheck( 'wpFilterDeleted' ) ) { $validationStatus->error( 'abusefilter-edit-deleting-enabled' ); return $validationStatus; } // If we've activated the 'tag' option, check the arguments for validity. - if ( !empty( $actions['tag'] ) ) { - foreach ( $actions['tag']['parameters'] as $tag ) { + if ( isset( $actions['tag'] ) ) { + if ( count( $actions['tag'] ) === 0 ) { + $validationStatus->error( 'tags-create-no-name' ); + return $validationStatus; + } + foreach ( $actions['tag'] as $tag ) { $status = self::isAllowedTag( $tag ); if ( !$status->isGood() ) { @@ -2338,23 +975,39 @@ class AbuseFilter { } } + // Warning and disallow message cannot be empty + if ( isset( $actions['warn'] ) && $actions['warn'][0] === '' ) { + $validationStatus->error( 'abusefilter-edit-invalid-warn-message' ); + return $validationStatus; + } elseif ( isset( $actions['disallow'] ) && $actions['disallow'][0] === '' ) { + $validationStatus->error( 'abusefilter-edit-invalid-disallow-message' ); + return $validationStatus; + } + // If 'throttle' is selected, check its parameters - if ( !empty( $actions['throttle'] ) ) { - $throttleCheck = self::checkThrottleParameters( $actions['throttle']['parameters'] ); + if ( isset( $actions['throttle'] ) ) { + $throttleCheck = self::checkThrottleParameters( $actions['throttle'] ); if ( $throttleCheck !== null ) { $validationStatus->error( $throttleCheck ); return $validationStatus; } } + $availableActions = array_keys( + array_filter( $context->getConfig()->get( 'AbuseFilterActions' ) ) + ); $differences = self::compareVersions( [ $newRow, $actions ], - [ $newRow->mOriginalRow, $newRow->mOriginalActions ] + [ $newRow->mOriginalRow, $newRow->mOriginalActions ], + $availableActions ); // Don't allow adding a new global rule, or updating a // rule that is currently global, without permissions. - if ( !$page->canEditFilter( $newRow ) || !$page->canEditFilter( $newRow->mOriginalRow ) ) { + if ( + !self::canEditFilter( $user, $newRow ) || + !self::canEditFilter( $user, $newRow->mOriginalRow ) + ) { $validationStatus->fatal( 'abusefilter-edit-notallowed-global' ); return $validationStatus; } @@ -2381,15 +1034,13 @@ class AbuseFilter { } // Check for restricted actions - $restrictions = $page->getConfig()->get( 'AbuseFilterRestrictions' ); + $restrictions = $context->getConfig()->get( 'AbuseFilterRestrictions' ); if ( count( array_intersect_key( array_filter( $restrictions ), - array_merge( - array_filter( $actions ), - array_filter( $origActions ) - ) + array_merge( $actions, $origActions ) ) ) - && !$page->getUser()->isAllowed( 'abusefilter-modify-restricted' ) + && !MediaWikiServices::getInstance()->getPermissionManager() + ->userHasRight( $user, 'abusefilter-modify-restricted' ) ) { $validationStatus->error( 'abusefilter-edit-restricted' ); return $validationStatus; @@ -2397,7 +1048,7 @@ class AbuseFilter { // Everything went fine, so let's save the filter list( $new_id, $history_id ) = - self::doSaveFilter( $newRow, $differences, $filter, $actions, $wasGlobal, $page ); + self::doSaveFilter( $newRow, $differences, $filter, $actions, $wasGlobal, $context, $dbw ); $validationStatus->setResult( true, [ $new_id, $history_id ] ); return $validationStatus; } @@ -2406,11 +1057,12 @@ class AbuseFilter { * Saves new filter's info to DB * * @param stdClass $newRow - * @param int|string $filter * @param array $differences + * @param int|string $filter * @param array $actions * @param bool $wasGlobal - * @param AbuseFilterViewEdit $page + * @param ContextSource $context + * @param IDatabase $dbw DB_MASTER where the filter will be saved * @return int[] first element is new ID, second is history ID */ private static function doSaveFilter( @@ -2419,10 +1071,10 @@ class AbuseFilter { $filter, $actions, $wasGlobal, - $page + ContextSource $context, + IDatabase $dbw ) { - $user = $page->getUser(); - $dbw = wfGetDB( DB_MASTER ); + $user = $context->getUser(); // Convert from object to array $newRow = get_object_vars( $newRow ); @@ -2435,8 +1087,8 @@ class AbuseFilter { $dbw->startAtomic( __METHOD__ ); // Insert MAIN row. - if ( $filter == 'new' ) { - $new_id = $dbw->nextSequenceValue( 'abuse_filter_af_id_seq' ); + if ( $filter === 'new' ) { + $new_id = null; $is_new = true; } else { $new_id = $filter; @@ -2454,21 +1106,21 @@ class AbuseFilter { $newRow['af_deleted'] = (int)$newRow['af_deleted']; $newRow['af_global'] = (int)$newRow['af_global']; - $dbw->replace( 'abuse_filter', [ 'af_id' ], $newRow, __METHOD__ ); + $dbw->replace( 'abuse_filter', 'af_id', $newRow, __METHOD__ ); if ( $is_new ) { $new_id = $dbw->insertId(); } + '@phan-var int $new_id'; - // Actions - $availableActions = $page->getConfig()->get( 'AbuseFilterActions' ); + $availableActions = $context->getConfig()->get( 'AbuseFilterActions' ); $actionsRows = []; foreach ( array_filter( $availableActions ) as $action => $_ ) { // Check if it's set - $enabled = isset( $actions[$action] ) && (bool)$actions[$action]; + $enabled = isset( $actions[$action] ); if ( $enabled ) { - $parameters = $actions[$action]['parameters']; + $parameters = $actions[$action]; if ( $action === 'throttle' && $parameters[0] === 'new' ) { // FIXME: Do we really need to keep the filter ID inside throttle parameters? // We'd save space, keep things simpler and avoid this hack. Note: if removing @@ -2488,20 +1140,14 @@ class AbuseFilter { // Create a history row $afh_row = []; - foreach ( self::$history_mappings as $af_col => $afh_col ) { + foreach ( self::HISTORY_MAPPINGS as $af_col => $afh_col ) { $afh_row[$afh_col] = $newRow[$af_col]; } - // Actions - $displayActions = []; - foreach ( $actions as $action ) { - $displayActions[$action['action']] = $action['parameters']; - } - $afh_row['afh_actions'] = serialize( $displayActions ); + $afh_row['afh_actions'] = serialize( $actions ); $afh_row['afh_changed_fields'] = implode( ',', $differences ); - // Flags $flags = []; if ( $newRow['af_hidden'] ) { $flags[] = 'hidden'; @@ -2519,12 +1165,11 @@ class AbuseFilter { $afh_row['afh_flags'] = implode( ',', $flags ); $afh_row['afh_filter'] = $new_id; - $afh_row['afh_id'] = $dbw->nextSequenceValue( 'abuse_filter_af_id_seq' ); // Do the update $dbw->insert( 'abuse_filter_history', $afh_row, __METHOD__ ); $history_id = $dbw->insertId(); - if ( $filter != 'new' ) { + if ( $filter !== 'new' ) { $dbw->delete( 'abuse_filter_action', [ 'afa_filter' => $filter ], @@ -2538,24 +1183,26 @@ class AbuseFilter { // Invalidate cache if this was a global rule if ( $wasGlobal || $newRow['af_global'] ) { $group = 'default'; - if ( isset( $newRow['af_group'] ) && $newRow['af_group'] != '' ) { + if ( isset( $newRow['af_group'] ) && $newRow['af_group'] !== '' ) { $group = $newRow['af_group']; } $globalRulesKey = self::getGlobalRulesKey( $group ); - ObjectCache::getMainWANInstance()->touchCheckKey( $globalRulesKey ); + MediaWikiServices::getInstance()->getMainWANObjectCache()->touchCheckKey( $globalRulesKey ); } // Logging $subtype = $filter === 'new' ? 'create' : 'modify'; $logEntry = new ManualLogEntry( 'abusefilter', $subtype ); $logEntry->setPerformer( $user ); - $logEntry->setTarget( $page->getTitle( $new_id ) ); + $logEntry->setTarget( + SpecialPage::getTitleFor( SpecialAbuseFilter::PAGE_NAME, (string)$new_id ) + ); $logEntry->setParameters( [ 'historyId' => $history_id, 'newId' => $new_id ] ); - $logid = $logEntry->insert(); + $logid = $logEntry->insert( $dbw ); $logEntry->publish( $logid ); // Purge the tag list cache so the fetchAllTags hook applies tag changes @@ -2573,10 +1220,15 @@ class AbuseFilter { * * @param array $version_1 * @param array $version_2 + * @param string[] $availableActions All actions enabled in the AF config * * @return array */ - public static function compareVersions( $version_1, $version_2 ) { + public static function compareVersions( + array $version_1, + array $version_2, + array $availableActions + ) { $compareFields = [ 'af_public_comments', 'af_pattern', @@ -2598,16 +1250,13 @@ class AbuseFilter { } } - global $wgAbuseFilterActions; - foreach ( array_filter( $wgAbuseFilterActions ) as $action => $_ ) { + foreach ( $availableActions as $action ) { if ( !isset( $actions1[$action] ) && !isset( $actions2[$action] ) ) { // They're both unset } elseif ( isset( $actions1[$action] ) && isset( $actions2[$action] ) ) { // They're both set. Double check needed, e.g. per T180194 - if ( array_diff( $actions1[$action]['parameters'], - $actions2[$action]['parameters'] ) || - array_diff( $actions2[$action]['parameters'], - $actions1[$action]['parameters'] ) ) { + if ( array_diff( $actions1[$action], $actions2[$action] ) || + array_diff( $actions2[$action], $actions1[$action] ) ) { // Different parameters $differences[] = 'actions'; } @@ -2628,7 +1277,7 @@ class AbuseFilter { // Manually translate into an abuse_filter row. $af_row = new stdClass; - foreach ( self::$history_mappings as $af_col => $afh_col ) { + foreach ( self::HISTORY_MAPPINGS as $af_col => $afh_col ) { $af_row->$af_col = $row->$afh_col; } @@ -2646,31 +1295,25 @@ class AbuseFilter { } // Process actions - $actions_raw = unserialize( $row->afh_actions ); - $actions_output = []; - if ( is_array( $actions_raw ) ) { - foreach ( $actions_raw as $action => $parameters ) { - $actions_output[$action] = [ - 'action' => $action, - 'parameters' => $parameters - ]; - } - } + $actionsRaw = unserialize( $row->afh_actions ); + $actionsOutput = is_array( $actionsRaw ) ? $actionsRaw : []; - return [ $af_row, $actions_output ]; + return [ $af_row, $actionsOutput ]; } /** * @param string $action - * @return string + * @param MessageLocalizer|null $localizer + * @return string HTML */ - public static function getActionDisplay( $action ) { + public static function getActionDisplay( $action, MessageLocalizer $localizer = null ) { + $msgCallback = $localizer != null ? [ $localizer, 'msg' ] : 'wfMessage'; // Give grep a chance to find the usages: // abusefilter-action-tag, abusefilter-action-throttle, abusefilter-action-warn, // abusefilter-action-blockautopromote, abusefilter-action-block, abusefilter-action-degroup, // abusefilter-action-rangeblock, abusefilter-action-disallow - $display = wfMessage( "abusefilter-action-$action" )->escaped(); - $display = wfMessage( "abusefilter-action-$action", $display )->isDisabled() + $display = $msgCallback( "abusefilter-action-$action" )->escaped(); + $display = $msgCallback( "abusefilter-action-$action" )->rawParams( $display )->isDisabled() ? htmlspecialchars( $action ) : $display; @@ -2678,216 +1321,32 @@ class AbuseFilter { } /** - * @param stdClass $row - * @return AbuseFilterVariableHolder|null - */ - public static function getVarsFromRCRow( $row ) { - if ( $row->rc_log_type == 'move' ) { - $vars = self::getMoveVarsFromRCRow( $row ); - } elseif ( $row->rc_log_type == 'newusers' ) { - $vars = self::getCreateVarsFromRCRow( $row ); - } elseif ( $row->rc_log_type == 'delete' ) { - $vars = self::getDeleteVarsFromRCRow( $row ); - } elseif ( $row->rc_this_oldid ) { - // It's an edit. - $vars = self::getEditVarsFromRCRow( $row ); - } else { - return null; - } - if ( $vars ) { - $vars->setVar( 'context', 'generated' ); - $vars->setVar( 'timestamp', wfTimestamp( TS_UNIX, $row->rc_timestamp ) ); - } - - return $vars; - } - - /** - * @param stdClass $row - * @return AbuseFilterVariableHolder - */ - public static function getCreateVarsFromRCRow( $row ) { - $vars = new AbuseFilterVariableHolder; - - $vars->setVar( 'ACTION', ( $row->rc_log_action == 'autocreate' ) ? - 'autocreateaccount' : - 'createaccount' ); - - $name = Title::makeTitle( $row->rc_namespace, $row->rc_title )->getText(); - // Add user data if the account was created by a registered user - if ( $row->rc_user && $name != $row->rc_user_text ) { - $user = User::newFromName( $row->rc_user_text ); - $vars->addHolders( self::generateUserVars( $user ) ); - } - - $vars->setVar( 'accountname', $name ); - - return $vars; - } - - /** - * @param stdClass $row - * @return AbuseFilterVariableHolder - */ - public static function getDeleteVarsFromRCRow( $row ) { - $vars = new AbuseFilterVariableHolder; - $title = Title::makeTitle( $row->rc_namespace, $row->rc_title ); - - if ( $row->rc_user ) { - $user = User::newFromName( $row->rc_user_text ); - } else { - $user = new User; - $user->setName( $row->rc_user_text ); - } - - $vars->addHolders( - self::generateUserVars( $user ), - self::generateTitleVars( $title, 'PAGE' ) - ); - - $vars->setVar( 'ACTION', 'delete' ); - $vars->setVar( 'SUMMARY', CommentStore::getStore()->getComment( 'rc_comment', $row )->text ); - - return $vars; - } - - /** - * @param stdClass $row - * @return AbuseFilterVariableHolder - */ - public static function getEditVarsFromRCRow( $row ) { - $vars = new AbuseFilterVariableHolder; - $title = Title::makeTitle( $row->rc_namespace, $row->rc_title ); - - if ( $row->rc_user ) { - $user = User::newFromName( $row->rc_user_text ); - } else { - $user = new User; - $user->setName( $row->rc_user_text ); - } - - $vars->addHolders( - self::generateUserVars( $user ), - self::generateTitleVars( $title, 'PAGE' ) - ); - - $vars->setVar( 'ACTION', 'edit' ); - $vars->setVar( 'SUMMARY', CommentStore::getStore()->getComment( 'rc_comment', $row )->text ); - - $vars->setLazyLoadVar( 'new_wikitext', 'revision-text-by-id', - [ 'revid' => $row->rc_this_oldid ] ); - - if ( $row->rc_last_oldid ) { - $vars->setLazyLoadVar( 'old_wikitext', 'revision-text-by-id', - [ 'revid' => $row->rc_last_oldid ] ); - } else { - $vars->setVar( 'old_wikitext', '' ); - } - - $vars->addHolders( self::getEditVars( $title ) ); - - return $vars; - } - - /** - * @param stdClass $row - * @return AbuseFilterVariableHolder - */ - public static function getMoveVarsFromRCRow( $row ) { - if ( $row->rc_user ) { - $user = User::newFromId( $row->rc_user ); - } else { - $user = new User; - $user->setName( $row->rc_user_text ); - } - - $params = array_values( DatabaseLogEntry::newFromRow( $row )->getParameters() ); - - $oldTitle = Title::makeTitle( $row->rc_namespace, $row->rc_title ); - $newTitle = Title::newFromText( $params[0] ); - - $vars = AbuseFilterVariableHolder::merge( - self::generateUserVars( $user ), - self::generateTitleVars( $oldTitle, 'MOVED_FROM' ), - self::generateTitleVars( $newTitle, 'MOVED_TO' ) - ); - - $vars->setVar( 'SUMMARY', CommentStore::getStore()->getComment( 'rc_comment', $row )->text ); - $vars->setVar( 'ACTION', 'move' ); - - return $vars; - } - - /** - * @param Title|null $title - * @param Page|null $page - * @return AbuseFilterVariableHolder + * @param mixed $var + * @param string $indent + * @return string */ - public static function getEditVars( $title, Page $page = null ) { - $vars = new AbuseFilterVariableHolder; - - // NOTE: $page may end up remaining null, e.g. if $title points to a special page. - if ( !$page && $title instanceof Title && $title->canExist() ) { - $page = WikiPage::factory( $title ); - } - - $vars->setLazyLoadVar( 'edit_diff', 'diff-array', - [ 'oldtext-var' => 'old_wikitext', 'newtext-var' => 'new_wikitext' ] ); - $vars->setLazyLoadVar( 'edit_diff_pst', 'diff-array', - [ 'oldtext-var' => 'old_wikitext', 'newtext-var' => 'new_pst' ] ); - $vars->setLazyLoadVar( 'new_size', 'length', [ 'length-var' => 'new_wikitext' ] ); - $vars->setLazyLoadVar( 'old_size', 'length', [ 'length-var' => 'old_wikitext' ] ); - $vars->setLazyLoadVar( 'edit_delta', 'subtract-int', - [ 'val1-var' => 'new_size', 'val2-var' => 'old_size' ] ); - - // Some more specific/useful details about the changes. - $vars->setLazyLoadVar( 'added_lines', 'diff-split', - [ 'diff-var' => 'edit_diff', 'line-prefix' => '+' ] ); - $vars->setLazyLoadVar( 'removed_lines', 'diff-split', - [ 'diff-var' => 'edit_diff', 'line-prefix' => '-' ] ); - $vars->setLazyLoadVar( 'added_lines_pst', 'diff-split', - [ 'diff-var' => 'edit_diff_pst', 'line-prefix' => '+' ] ); - - // Links - $vars->setLazyLoadVar( 'added_links', 'link-diff-added', - [ 'oldlink-var' => 'old_links', 'newlink-var' => 'all_links' ] ); - $vars->setLazyLoadVar( 'removed_links', 'link-diff-removed', - [ 'oldlink-var' => 'old_links', 'newlink-var' => 'all_links' ] ); - $vars->setLazyLoadVar( 'new_text', 'strip-html', - [ 'html-var' => 'new_html' ] ); - - if ( $title instanceof Title ) { - $vars->setLazyLoadVar( 'all_links', 'links-from-wikitext', - [ - 'namespace' => $title->getNamespace(), - 'title' => $title->getText(), - 'text-var' => 'new_wikitext', - 'article' => $page - ] ); - $vars->setLazyLoadVar( 'old_links', 'links-from-wikitext-or-database', - [ - 'namespace' => $title->getNamespace(), - 'title' => $title->getText(), - 'text-var' => 'old_wikitext' - ] ); - $vars->setLazyLoadVar( 'new_pst', 'parse-wikitext', - [ - 'namespace' => $title->getNamespace(), - 'title' => $title->getText(), - 'wikitext-var' => 'new_wikitext', - 'article' => $page, - 'pst' => true, - ] ); - $vars->setLazyLoadVar( 'new_html', 'parse-wikitext', - [ - 'namespace' => $title->getNamespace(), - 'title' => $title->getText(), - 'wikitext-var' => 'new_wikitext', - 'article' => $page - ] ); + public static function formatVar( $var, string $indent = '' ) { + if ( $var === [] ) { + return '[]'; + } elseif ( is_array( $var ) ) { + $ret = '['; + $indent .= "\t"; + foreach ( $var as $key => $val ) { + $ret .= "\n$indent" . self::formatVar( $key, $indent ) . + ' => ' . self::formatVar( $val, $indent ) . ','; + } + // Strip trailing commas + return substr( $ret, 0, -1 ) . "\n" . substr( $indent, 0, -1 ) . ']'; + } elseif ( is_string( $var ) ) { + // Don't escape the string (specifically backslashes) to avoid displaying wrong stuff + return "'$var'"; + } elseif ( $var === null ) { + return 'null'; + } elseif ( is_float( $var ) ) { + // Don't let float precision produce weirdness + return (string)$var; } - - return $vars; + return var_export( $var, true ); } /** @@ -2903,12 +1362,6 @@ class AbuseFilter { $output = ''; - // I don't want to change the names of the pre-existing messages - // describing the variables, nor do I want to rewrite them, so I'm just - // mapping the variable names to builder messages with a pre-existing array. - $variableMessageMappings = self::getBuilderValues(); - $variableMessageMappings = $variableMessageMappings['vars']; - $output .= Xml::openElement( 'table', [ 'class' => 'mw-abuselog-details' ] ) . Xml::openElement( 'tbody' ) . @@ -2925,30 +1378,27 @@ class AbuseFilter { return $output; } + $keywordsManager = AbuseFilterServices::getKeywordsManager(); // Now, build the body of the table. - $deprecatedVars = self::getDeprecatedVariables(); foreach ( $vars as $key => $value ) { $key = strtolower( $key ); - if ( array_key_exists( $key, $deprecatedVars ) ) { - $key = $deprecatedVars[$key]; - } - if ( !empty( $variableMessageMappings[$key] ) ) { - $mapping = $variableMessageMappings[$key]; - $keyDisplay = $context->msg( "abusefilter-edit-builder-vars-$mapping" )->parse() . - ' ' . Xml::element( 'code', null, $context->msg( 'parentheses' )->rawParams( $key )->text() ); - } elseif ( !empty( self::$disabledVars[$key] ) ) { - $mapping = self::$disabledVars[$key]; - $keyDisplay = $context->msg( "abusefilter-edit-builder-vars-$mapping" )->parse() . - ' ' . Xml::element( 'code', null, $context->msg( 'parentheses' )->rawParams( $key )->text() ); + $varMsgKey = $keywordsManager->getMessageKeyForVar( $key ); + if ( $varMsgKey ) { + $keyDisplay = $context->msg( $varMsgKey )->parse() . + ' ' . Html::element( 'code', [], $context->msg( 'parentheses' )->rawParams( $key )->text() ); } else { - $keyDisplay = Xml::element( 'code', null, $key ); + $keyDisplay = Html::element( 'code', [], $key ); } - if ( is_null( $value ) ) { + if ( $value === null ) { $value = ''; } - $value = Xml::element( 'div', [ 'class' => 'mw-abuselog-var-value' ], $value, false ); + $value = Html::element( + 'div', + [ 'class' => 'mw-abuselog-var-value' ], + self::formatVar( $value ) + ); $trow = Xml::tags( 'td', [ 'class' => 'mw-abuselog-var' ], $keyDisplay ) . @@ -2967,11 +1417,10 @@ class AbuseFilter { /** * @param string $action * @param string[] $parameters + * @param Language $lang * @return string */ - public static function formatAction( $action, $parameters ) { - /** @var $wgLang Language */ - global $wgLang; + public static function formatAction( $action, $parameters, $lang ) { if ( count( $parameters ) === 0 || ( $action === 'block' && count( $parameters ) !== 3 ) ) { $displayAction = self::getActionDisplay( $action ); @@ -2981,57 +1430,49 @@ class AbuseFilter { $messages = [ wfMessage( 'abusefilter-block-anon' )->escaped() . wfMessage( 'colon-separator' )->escaped() . - $wgLang->translateBlockExpiry( $parameters[1] ), + $lang->translateBlockExpiry( $parameters[1] ), wfMessage( 'abusefilter-block-user' )->escaped() . wfMessage( 'colon-separator' )->escaped() . - $wgLang->translateBlockExpiry( $parameters[2] ) + $lang->translateBlockExpiry( $parameters[2] ) ]; if ( $parameters[0] === 'blocktalk' ) { $messages[] = wfMessage( 'abusefilter-block-talk' )->escaped(); } - $displayAction = $wgLang->commaList( $messages ); + $displayAction = $lang->commaList( $messages ); } elseif ( $action === 'throttle' ) { array_shift( $parameters ); list( $actions, $time ) = explode( ',', array_shift( $parameters ) ); - if ( $parameters === [ '' ] ) { - // Having empty groups won't happen for new filters due to validation upon saving, - // but old entries may have it. We'd better not show a broken message. Also, - // the array has an empty string inside because we haven't been passing an empty array - // as the default when retrieving wpFilterThrottleGroups with getArray (when it was - // a CheckboxMultiselect). - $groups = ''; - } else { - // Join comma-separated groups in a commaList with a final "and", and convert to messages. - // Messages used here: abusefilter-throttle-ip, abusefilter-throttle-user, - // abusefilter-throttle-site, abusefilter-throttle-creationdate, abusefilter-throttle-editcount - // abusefilter-throttle-range, abusefilter-throttle-page - foreach ( $parameters as &$val ) { - if ( strpos( $val, ',' ) !== false ) { - $subGroups = explode( ',', $val ); - foreach ( $subGroups as &$group ) { - $msg = wfMessage( "abusefilter-throttle-$group" ); - // We previously accepted literally everything in this field, so old entries - // may have weird stuff. - $group = $msg->exists() ? $msg->text() : $group; - } - unset( $group ); - $val = $wgLang->listToText( $subGroups ); - } else { - $msg = wfMessage( "abusefilter-throttle-$val" ); - $val = $msg->exists() ? $msg->text() : $val; + // Join comma-separated groups in a commaList with a final "and", and convert to messages. + // Messages used here: abusefilter-throttle-ip, abusefilter-throttle-user, + // abusefilter-throttle-site, abusefilter-throttle-creationdate, abusefilter-throttle-editcount + // abusefilter-throttle-range, abusefilter-throttle-page, abusefilter-throttle-none + foreach ( $parameters as &$val ) { + if ( strpos( $val, ',' ) !== false ) { + $subGroups = explode( ',', $val ); + foreach ( $subGroups as &$group ) { + $msg = wfMessage( "abusefilter-throttle-$group" ); + // We previously accepted literally everything in this field, so old entries + // may have weird stuff. + $group = $msg->exists() ? $msg->text() : $group; } + unset( $group ); + $val = $lang->listToText( $subGroups ); + } else { + $msg = wfMessage( "abusefilter-throttle-$val" ); + $val = $msg->exists() ? $msg->text() : $val; } - unset( $val ); - $groups = $wgLang->semicolonList( $parameters ); } + unset( $val ); + $groups = $lang->semicolonList( $parameters ); + $displayAction = self::getActionDisplay( $action ) . wfMessage( 'colon-separator' )->escaped() . wfMessage( 'abusefilter-throttle-details' )->params( $actions, $time, $groups )->escaped(); } else { $displayAction = self::getActionDisplay( $action ) . wfMessage( 'colon-separator' )->escaped() . - $wgLang->semicolonList( array_map( 'htmlspecialchars', $parameters ) ); + $lang->semicolonList( array_map( 'htmlspecialchars', $parameters ) ); } } @@ -3040,22 +1481,21 @@ class AbuseFilter { /** * @param string $value + * @param Language $lang * @return string */ - public static function formatFlags( $value ) { - /** @var $wgLang Language */ - global $wgLang; + public static function formatFlags( $value, $lang ) { $flags = array_filter( explode( ',', $value ) ); $flags_display = []; foreach ( $flags as $flag ) { $flags_display[] = wfMessage( "abusefilter-history-$flag" )->escaped(); } - return $wgLang->commaList( $flags_display ); + return $lang->commaList( $flags_display ); } /** - * @param string $filterID + * @param int $filterID * @return string */ public static function getGlobalFilterDescription( $filterID ) { @@ -3070,7 +1510,7 @@ class AbuseFilter { return $cache[$filterID]; } - $fdb = wfGetDB( DB_REPLICA, [], $wgAbuseFilterCentralDB ); + $fdb = self::getCentralDB( DB_REPLICA ); $cache[$filterID] = $fdb->selectField( 'abuse_filter', @@ -3105,25 +1545,34 @@ class AbuseFilter { * Note also that if the revision for any reason is not an Revision * the function returns with an empty string. * - * @param Revision|null $revision a valid revision - * @param int $audience one of: - * Revision::FOR_PUBLIC to be displayed to all users - * Revision::FOR_THIS_USER to be displayed to the given user - * Revision::RAW get the text regardless of permissions - * @return string|null the content of the revision as some kind of string, + * For now, this returns all the revision's slots, concatenated together. + * In future, this will be replaced by a better solution. See T208769 for + * discussion. + * + * @internal + * @todo Move elsewhere. VariableGenerator is a good candidate + * + * @param RevisionRecord|null $revision a valid revision + * @param User $user the user instance to check for privileged access + * @return string the content of the revision as some kind of string, * or an empty string if it can not be found */ - public static function revisionToString( $revision, $audience = Revision::FOR_THIS_USER ) { - if ( !$revision instanceof Revision ) { + public static function revisionToString( ?RevisionRecord $revision, User $user ) { + if ( !$revision ) { return ''; } - $content = $revision->getContent( $audience ); - if ( $content === null ) { - return ''; + $strings = []; + + foreach ( $revision->getSlotRoles() as $role ) { + $content = $revision->getContent( $role, RevisionRecord::FOR_THIS_USER, $user ); + if ( $content === null ) { + continue; + } + $strings[$role] = self::contentToString( $content ); } - $result = self::contentToString( $content ); + $result = implode( "\n\n", $strings ); return $result; } @@ -3136,6 +1585,9 @@ class AbuseFilter { * The hook 'AbuseFilter::contentToString' can be used to override this * behavior. * + * @internal + * @todo Move elsewhere. VariableGenerator is a good candidate + * * @param Content $content * * @return string a suitable string representation of the content. @@ -3143,9 +1595,13 @@ class AbuseFilter { public static function contentToString( Content $content ) { $text = null; - if ( Hooks::run( 'AbuseFilter-contentToString', [ $content, &$text ] ) ) { + $hookRunner = AbuseFilterHookRunner::getRunner(); + if ( $hookRunner->onAbuseFilterContentToString( + $content, + $text + ) ) { $text = $content instanceof TextContent - ? $content->getNativeData() + ? $content->getText() : $content->getTextForSearchIndex(); } @@ -3158,14 +1614,14 @@ class AbuseFilter { * Get the history ID of the first change to a given filter * * @param int $filterID Filter id - * @return int + * @return string */ public static function getFirstFilterChange( $filterID ) { static $firstChanges = []; if ( !isset( $firstChanges[$filterID] ) ) { $dbr = wfGetDB( DB_REPLICA ); - $row = $dbr->selectRow( + $historyID = $dbr->selectField( 'abuse_filter_history', 'afh_id', [ @@ -3174,9 +1630,120 @@ class AbuseFilter { __METHOD__, [ 'ORDER BY' => 'afh_timestamp ASC' ] ); - $firstChanges[$filterID] = $row->afh_id; + $firstChanges[$filterID] = $historyID; } return $firstChanges[$filterID]; } + + /** + * @param int $index DB_MASTER/DB_REPLICA + * @return IDatabase + * @throws DBerror + * @throws RuntimeException + */ + public static function getCentralDB( $index ) { + global $wgAbuseFilterCentralDB; + + if ( !is_string( $wgAbuseFilterCentralDB ) ) { + throw new RuntimeException( '$wgAbuseFilterCentralDB is not configured' ); + } + + return MediaWikiServices::getInstance() + ->getDBLoadBalancerFactory() + ->getMainLB( $wgAbuseFilterCentralDB ) + ->getConnectionRef( $index, [], $wgAbuseFilterCentralDB ); + } + + /** + * @param User $user + * @return bool + */ + public static function canEdit( User $user ) { + $block = $user->getBlock(); + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); + + return ( + !( $block && $block->isSitewide() ) && + $permissionManager->userHasRight( $user, 'abusefilter-modify' ) + ); + } + + /** + * @param User $user + * @return bool + */ + public static function canEditGlobal( User $user ) { + return MediaWikiServices::getInstance()->getPermissionManager() + ->userHasRight( $user, 'abusefilter-modify-global' ); + } + + /** + * Whether the user can edit the given filter. + * + * @param User $user + * @param object $row Filter row + * @return bool + */ + public static function canEditFilter( User $user, $row ) { + return ( + self::canEdit( $user ) && + !( isset( $row->af_global ) && $row->af_global == 1 && !self::canEditGlobal( $user ) ) + ); + } + + /** + * @param User $user + * @return bool + */ + public static function canViewPrivate( User $user ) { + return MediaWikiServices::getInstance()->getPermissionManager() + ->userHasAnyRight( $user, 'abusefilter-modify', 'abusefilter-view-private' ); + } + + /** + * Get a parser instance using default options. This should mostly be intended as a wrapper + * around $wgAbuseFilterParserClass and for choosing the right type of cache. It also has the + * benefit of typehinting the return value, thus making IDEs and static analysis tools happier. + * + * @param AbuseFilterVariableHolder|null $vars + * @return AbuseFilterParser + * @throws InvalidArgumentException if $wgAbuseFilterParserClass is not valid + */ + public static function getDefaultParser( + AbuseFilterVariableHolder $vars = null + ) : AbuseFilterParser { + global $wgAbuseFilterParserClass; + + $allowedValues = [ AbuseFilterParser::class, AbuseFilterCachingParser::class ]; + if ( !in_array( $wgAbuseFilterParserClass, $allowedValues ) ) { + throw new InvalidArgumentException( + "Invalid value $wgAbuseFilterParserClass for \$wgAbuseFilterParserClass." + ); + } + + $contLang = MediaWikiServices::getInstance()->getContentLanguage(); + $cache = ObjectCache::getLocalServerInstance( 'hash' ); + $logger = LoggerFactory::getInstance( 'AbuseFilter' ); + $keywordsManager = AbuseFilterServices::getKeywordsManager(); + return new $wgAbuseFilterParserClass( $contLang, $cache, $logger, $keywordsManager, $vars ); + } + + /** + * Shortcut for checking whether $user can view the given revision, with mask + * SUPPRESSED_ALL. + * + * @note This assumes that a revision with the given ID exists + * + * @param RevisionRecord $revRec + * @param User $user + * @return bool + */ + public static function userCanViewRev( RevisionRecord $revRec, User $user ) : bool { + return $revRec->audienceCan( + RevisionRecord::SUPPRESSED_ALL, + RevisionRecord::FOR_THIS_USER, + $user + ); + } } diff --git a/AbuseFilter/includes/AbuseFilterChangesList.php b/AbuseFilter/includes/AbuseFilterChangesList.php index 94855f34..ba84d51b 100644 --- a/AbuseFilter/includes/AbuseFilterChangesList.php +++ b/AbuseFilter/includes/AbuseFilterChangesList.php @@ -1,5 +1,7 @@ <?php +use MediaWiki\Revision\RevisionRecord; + class AbuseFilterChangesList extends OldChangesList { /** @@ -25,17 +27,20 @@ class AbuseFilterChangesList extends OldChangesList { public function insertExtra( &$s, &$rc, &$classes ) { if ( (int)$rc->getAttribute( 'rc_deleted' ) !== 0 ) { $s .= ' ' . $this->msg( 'abusefilter-log-hidden-implicit' )->parse(); - if ( !$this->userCan( $rc, Revision::SUPPRESSED_ALL ) ) { + if ( !$this->userCan( $rc, RevisionRecord::SUPPRESSED_ALL ) ) { return; } } $examineParams = []; - if ( $this->testFilter ) { + if ( $this->testFilter && strlen( $this->testFilter ) < 2000 ) { + // Since this is GETed, don't send it if it's too long to prevent broken URLs 2000 is taken from + // https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url- + // in-different-browsers/417184#417184 $examineParams['testfilter'] = $this->testFilter; } - $title = SpecialPage::getTitleFor( 'AbuseFilter', 'examine/' . $rc->mAttribs['rc_id'] ); + $title = SpecialPage::getTitleFor( 'AbuseFilter', 'examine/' . $rc->getAttribute( 'rc_id' ) ); $examineLink = $this->linkRenderer->makeLink( $title, new HtmlArmor( $this->msg( 'abusefilter-changeslist-examine' )->parse() ), @@ -63,12 +68,12 @@ class AbuseFilterChangesList extends OldChangesList { * @param RecentChange &$rc */ public function insertUserRelatedLinks( &$s, &$rc ) { - $links = $this->getLanguage()->getDirMark() . Linker::userLink( $rc->mAttribs['rc_user'], - $rc->mAttribs['rc_user_text'] ) . - Linker::userToolLinks( $rc->mAttribs['rc_user'], $rc->mAttribs['rc_user_text'] ); + $links = $this->getLanguage()->getDirMark() . Linker::userLink( $rc->getAttribute( 'rc_user' ), + $rc->getAttribute( 'rc_user_text' ) ) . + Linker::userToolLinks( $rc->getAttribute( 'rc_user' ), $rc->getAttribute( 'rc_user_text' ) ); - if ( $this->isDeleted( $rc, Revision::DELETED_USER ) ) { - if ( $this->userCan( $rc, Revision::DELETED_USER ) ) { + if ( $this->isDeleted( $rc, RevisionRecord::DELETED_USER ) ) { + if ( $this->userCan( $rc, RevisionRecord::DELETED_USER ) ) { $s .= ' <span class="history-deleted">' . $links . '</span>'; } else { $s .= ' <span class="history-deleted">' . @@ -85,16 +90,16 @@ class AbuseFilterChangesList extends OldChangesList { * @return string */ public function insertComment( $rc ) { - if ( $this->isDeleted( $rc, Revision::DELETED_COMMENT ) ) { - if ( $this->userCan( $rc, Revision::DELETED_COMMENT ) ) { + if ( $this->isDeleted( $rc, RevisionRecord::DELETED_COMMENT ) ) { + if ( $this->userCan( $rc, RevisionRecord::DELETED_COMMENT ) ) { return ' <span class="history-deleted">' . - Linker::commentBlock( $rc->mAttribs['rc_comment'], $rc->getTitle() ) . '</span>'; + Linker::commentBlock( $rc->getAttribute( 'rc_comment' ), $rc->getTitle() ) . '</span>'; } else { return ' <span class="history-deleted">' . $this->msg( 'rev-deleted-comment' )->escaped() . '</span>'; } } else { - return Linker::commentBlock( $rc->mAttribs['rc_comment'], $rc->getTitle() ); + return Linker::commentBlock( $rc->getAttribute( 'rc_comment' ), $rc->getTitle() ); } } @@ -105,7 +110,7 @@ class AbuseFilterChangesList extends OldChangesList { * @return string */ public function insertLogEntry( $rc ) { - $formatter = LogFormatter::newFromRow( $rc->mAttribs ); + $formatter = LogFormatter::newFromRow( $rc->getAttributes() ); $formatter->setContext( $this->getContext() ); $formatter->setAudience( LogFormatter::FOR_THIS_USER ); $formatter->setShowUserToolLinks( true ); diff --git a/AbuseFilter/includes/AbuseFilterHooks.php b/AbuseFilter/includes/AbuseFilterHooks.php index 20c07e4a..0b81bc31 100644 --- a/AbuseFilter/includes/AbuseFilterHooks.php +++ b/AbuseFilter/includes/AbuseFilterHooks.php @@ -1,30 +1,72 @@ <?php +use MediaWiki\Extension\AbuseFilter\VariableGenerator\RunVariableGenerator; use MediaWiki\Linker\LinkRenderer; +use MediaWiki\Logger\LoggerFactory; use MediaWiki\MediaWikiServices; +use MediaWiki\Revision\RevisionRecord; +use MediaWiki\Revision\SlotRecord; +use MediaWiki\User\UserIdentity; +use Wikimedia\IPUtils; use Wikimedia\Rdbms\Database; +use Wikimedia\Rdbms\IMaintainableDatabase; class AbuseFilterHooks { - const FETCH_ALL_TAGS_KEY = 'abusefilter-fetch-all-tags'; + private const FETCH_ALL_TAGS_KEY = 'abusefilter-fetch-all-tags'; - /** @var AbuseFilterVariableHolder|bool */ - public static $successful_action_vars = false; - /** @var WikiPage|Article|bool|null Make sure edit filter & edit save hooks match */ - public static $last_edit_page = false; - // So far, all of the error message out-params for these hooks accept HTML. + /** @var WikiPage|null Make sure edit filter & edit save hooks match */ + private static $lastEditPage = null; /** * Called right after configuration has been loaded. */ public static function onRegistration() { - global $wgAbuseFilterAvailableActions, $wgAbuseFilterRestrictedActions, - $wgAuthManagerAutoConfig, $wgActionFilteredLogs; - - if ( isset( $wgAbuseFilterAvailableActions ) || isset( $wgAbuseFilterRestrictedActions ) ) { - wfWarn( '$wgAbuseFilterAvailableActions and $wgAbuseFilterRestrictedActions have been ' - . 'removed. Please use $wgAbuseFilterActions and $wgAbuseFilterRestrictions ' - . 'instead. The format is the same except the action names are the keys of the ' - . 'array and the values are booleans.' ); + global $wgAuthManagerAutoConfig, $wgActionFilteredLogs, $wgAbuseFilterProfile, + $wgAbuseFilterProfiling, $wgAbuseFilterPrivateLog, $wgAbuseFilterForceSummary, + $wgGroupPermissions; + + // @todo Remove this in a future release (added in 1.33) + if ( isset( $wgAbuseFilterProfile ) || isset( $wgAbuseFilterProfiling ) ) { + wfWarn( '$wgAbuseFilterProfile and $wgAbuseFilterProfiling have been removed and ' . + 'profiling is now enabled by default.' ); + } + + if ( isset( $wgAbuseFilterPrivateLog ) ) { + global $wgAbuseFilterLogPrivateDetailsAccess; + $wgAbuseFilterLogPrivateDetailsAccess = $wgAbuseFilterPrivateLog; + wfWarn( '$wgAbuseFilterPrivateLog has been renamed to $wgAbuseFilterLogPrivateDetailsAccess. ' . + 'Please make the change in your settings; the format is identical.' + ); + } + if ( isset( $wgAbuseFilterForceSummary ) ) { + global $wgAbuseFilterPrivateDetailsForceReason; + $wgAbuseFilterPrivateDetailsForceReason = $wgAbuseFilterForceSummary; + wfWarn( '$wgAbuseFilterForceSummary has been renamed to ' . + '$wgAbuseFilterPrivateDetailsForceReason. Please make the change in your settings; ' . + 'the format is identical.' + ); + } + + $found = false; + foreach ( $wgGroupPermissions as &$perms ) { + if ( array_key_exists( 'abusefilter-private', $perms ) ) { + $perms['abusefilter-privatedetails'] = $perms[ 'abusefilter-private' ]; + unset( $perms[ 'abusefilter-private' ] ); + $found = true; + } + if ( array_key_exists( 'abusefilter-private-log', $perms ) ) { + $perms['abusefilter-privatedetails-log'] = $perms[ 'abusefilter-private-log' ]; + unset( $perms[ 'abusefilter-private-log' ] ); + $found = true; + } + } + unset( $perms ); + + if ( $found ) { + wfWarn( 'The group permissions "abusefilter-private-log" and "abusefilter-private" have ' . + 'been renamed, respectively, to "abusefilter-privatedetails-log" and ' . + '"abusefilter-privatedetails". Please update the names in your settings.' + ); } $wgAuthManagerAutoConfig['preauth'][AbuseFilterPreAuthenticationProvider::class] = [ @@ -38,6 +80,15 @@ class AbuseFilterHooks { // Message: log-action-filter-suppress-abuselog [ 'abuselog' => [ 'hide-afl', 'unhide-afl' ] ] ); + $wgActionFilteredLogs['rights'] = array_merge( + $wgActionFilteredLogs['rights'], + // Messages: log-action-filter-rights-blockautopromote, + // log-action-filter-rights-restoreautopromote + [ + 'blockautopromote' => [ 'blockautopromote' ], + 'restoreautopromote' => [ 'restoreautopromote' ] + ] + ); } /** @@ -49,265 +100,178 @@ class AbuseFilterHooks { * @param string $summary Edit summary for page * @param User $user the user performing the edit * @param bool $minoredit whether this is a minor edit according to the user. + * @param string $slot slot role for the content */ public static function onEditFilterMergedContent( IContextSource $context, Content $content, - Status $status, $summary, User $user, $minoredit + Status $status, $summary, User $user, $minoredit, $slot = SlotRecord::MAIN ) { - $text = AbuseFilter::contentToString( $content ); + $startTime = microtime( true ); - $filterStatus = self::filterEdit( $context, $content, $text, $status, $summary, $minoredit ); + $filterResult = self::filterEdit( $context, $user, $content, $summary, $slot ); - if ( !$filterStatus->isOK() ) { + if ( !$filterResult->isOK() ) { // Produce a useful error message for API edits - $status->apiHookResult = self::getApiResult( $filterStatus ); + $filterResultApi = self::getApiStatus( $filterResult ); + $status->merge( $filterResultApi ); } + MediaWikiServices::getInstance()->getStatsdDataFactory() + ->timing( 'timing.editAbuseFilter', microtime( true ) - $startTime ); } /** * Implementation for EditFilterMergedContent hook. * * @param IContextSource $context the context of the edit + * @param User $user * @param Content $content the new Content generated by the edit - * @param string $text new page content (subject of filtering) - * @param Status $status Error message to return * @param string $summary Edit summary for page - * @param bool $minoredit whether this is a minor edit according to the user. + * @param string $slot slot role for the content * @return Status */ - public static function filterEdit( IContextSource $context, $content, $text, - Status $status, $summary, $minoredit - ) { - $title = $context->getTitle(); - - self::$successful_action_vars = false; - self::$last_edit_page = false; + public static function filterEdit( + IContextSource $context, + User $user, + Content $content, + $summary, $slot = SlotRecord::MAIN + ) : Status { + self::$lastEditPage = null; - $user = $context->getUser(); + // @todo is there any real point in passing this in? + $text = AbuseFilter::contentToString( $content ); - $oldcontent = null; + $title = $context->getTitle(); + if ( $title === null ) { + // T144265: This *should* never happen. + $logger = LoggerFactory::getInstance( 'AbuseFilter' ); + $logger->warning( __METHOD__ . ' received a null title.' ); + return Status::newGood(); + } - if ( ( $title instanceof Title ) && $title->canExist() && $title->exists() ) { + if ( $title->canExist() && $title->exists() ) { // Make sure we load the latest text saved in database (bug 31656) $page = $context->getWikiPage(); - $revision = $page->getRevision(); - if ( !$revision ) { - return Status::newGood(); - } - - $oldcontent = $revision->getContent( Revision::RAW ); - $oldtext = AbuseFilter::contentToString( $oldcontent ); - - // Cache article object so we can share a parse operation - $articleCacheKey = $title->getNamespace() . ':' . $title->getText(); - AFComputedVariable::$articleCache[$articleCacheKey] = $page; - - // Don't trigger for null edits. - if ( $content && $oldcontent ) { - // Compare Content objects if available - if ( $content->equals( $oldcontent ) ) { - return Status::newGood(); - } - } elseif ( strcmp( $oldtext, $text ) == 0 ) { - // Otherwise, compare strings - return Status::newGood(); - } } else { $page = null; } - // Load vars for filters to check - $vars = self::newVariableHolderForEdit( - $user, $title, $page, $summary, $content, $text, $oldcontent - ); - - $filter_result = AbuseFilter::filterAction( $vars, $title, 'default', $user ); - if ( !$filter_result->isOK() ) { - $status->merge( $filter_result ); - - return $filter_result; + $vars = new AbuseFilterVariableHolder(); + $builder = new RunVariableGenerator( $vars, $user, $title ); + $vars = $builder->getEditVars( $content, $text, $summary, $slot, $page ); + if ( $vars === null ) { + // We don't have to filter the edit + return Status::newGood(); + } + $runner = new AbuseFilterRunner( $user, $title, $vars, 'default' ); + $filterResult = $runner->run(); + if ( !$filterResult->isOK() ) { + return $filterResult; } - self::$successful_action_vars = $vars; - self::$last_edit_page = $page; + self::$lastEditPage = $page; return Status::newGood(); } /** - * @param User $user - * @param Title $title - * @param WikiPage|null $page - * @param string $summary - * @param Content $newcontent - * @param string $text - * @param Content|null $oldcontent - * @return AbuseFilterVariableHolder - * @throws MWException - */ - private static function newVariableHolderForEdit( - User $user, Title $title, $page, $summary, Content $newcontent, - $text, $oldcontent = null - ) { - $vars = new AbuseFilterVariableHolder(); - $vars->addHolders( - AbuseFilter::generateUserVars( $user ), - AbuseFilter::generateTitleVars( $title, 'PAGE' ) - ); - $vars->setVar( 'action', 'edit' ); - $vars->setVar( 'summary', $summary ); - if ( $oldcontent instanceof Content ) { - $oldmodel = $oldcontent->getModel(); - $oldtext = AbuseFilter::contentToString( $oldcontent ); - } else { - $oldmodel = ''; - $oldtext = ''; - } - $vars->setVar( 'old_content_model', $oldmodel ); - $vars->setVar( 'new_content_model', $newcontent->getModel() ); - $vars->setVar( 'old_wikitext', $oldtext ); - $vars->setVar( 'new_wikitext', $text ); - // TODO: set old_content and new_content vars, use them - $vars->addHolders( AbuseFilter::getEditVars( $title, $page ) ); - - return $vars; - } - - /** * @param Status $status Error message details - * @return array API result + * @return Status Status containing the same error messages with extra data for the API */ - private static function getApiResult( Status $status ) { - global $wgFullyInitialised; - - $params = $status->getErrorsArray()[0]; - $key = array_shift( $params ); + private static function getApiStatus( Status $status ) { + $allActionsTaken = $status->getValue(); + $statusForApi = Status::newGood(); + + foreach ( $status->getErrors() as $error ) { + list( $filterDescription, $filter ) = $error['params']; + $actionsTaken = $allActionsTaken[ $filter ]; + + $code = ( $actionsTaken === [ 'warn' ] ) ? 'abusefilter-warning' : 'abusefilter-disallowed'; + $data = [ + 'abusefilter' => [ + 'id' => $filter, + 'description' => $filterDescription, + 'actions' => $actionsTaken, + ], + ]; - $warning = wfMessage( $key )->params( $params ); - if ( !$wgFullyInitialised ) { - // This could happen for account autocreation checks - $warning = $warning->inContentLanguage(); + $message = ApiMessage::create( $error, $code, $data ); + $statusForApi->fatal( $message ); } - $filterDescription = $params[0]; - $filter = $params[1]; - - // The value is a nested structure keyed by filter id, which doesn't make sense when we only - // return the result from one filter. Flatten it to a plain array of actions. - $actionsTaken = array_values( array_unique( - array_merge( ...array_values( $status->getValue() ) ) - ) ); - $code = ( $actionsTaken === [ 'warn' ] ) ? 'abusefilter-warning' : 'abusefilter-disallowed'; - - ApiResult::setIndexedTagName( $params, 'param' ); - return [ - 'code' => $code, - 'message' => [ - 'key' => $key, - 'params' => $params, - ], - 'abusefilter' => [ - 'id' => $filter, - 'description' => $filterDescription, - 'actions' => $actionsTaken, - ], - // For backwards-compatibility - 'info' => 'Hit AbuseFilter: ' . $filterDescription, - 'warning' => $warning->parse(), - ]; + return $statusForApi; } /** * @param WikiPage $wikiPage - * @param User $user - * @param string $content Content + * @param UserIdentity $userIdentity * @param string $summary - * @param bool $minoredit - * @param bool $watchthis - * @param string $sectionanchor * @param int $flags - * @param Revision $revision - * @param Status $status - * @param int $baseRevId + * @param RevisionRecord $revisionRecord */ - public static function onPageContentSaveComplete( - WikiPage $wikiPage, $user, $content, $summary, $minoredit, $watchthis, $sectionanchor, - $flags, $revision, $status, $baseRevId + public static function onPageSaveComplete( + WikiPage $wikiPage, + UserIdentity $userIdentity, + string $summary, + int $flags, + RevisionRecord $revisionRecord ) { - if ( !self::$successful_action_vars || !$revision ) { - self::$successful_action_vars = false; - return; - } - - /** @var AbuseFilterVariableHolder|bool $vars */ - $vars = self::$successful_action_vars; - - if ( $vars->getVar( 'page_prefixedtitle' )->toString() !== - $wikiPage->getTitle()->getPrefixedText() + $curTitle = $wikiPage->getTitle()->getPrefixedText(); + if ( !isset( AbuseFilter::$logIds[ $curTitle ] ) || + $wikiPage !== self::$lastEditPage ) { + // This isn't the edit AbuseFilter::$logIds was set for + AbuseFilter::$logIds = []; return; } - if ( !self::identicalPageObjects( $wikiPage, self::$last_edit_page ) ) { - // This isn't the edit $successful_action_vars was set for - return; + // Ignore null edit. + $parentRevId = $revisionRecord->getParentId(); + if ( $parentRevId !== null ) { + $parentRev = MediaWikiServices::getInstance() + ->getRevisionLookup() + ->getRevisionById( $parentRevId ); + if ( $parentRev && $revisionRecord->hasSameContent( $parentRev ) ) { + AbuseFilter::$logIds = []; + return; + } } - self::$last_edit_page = false; - if ( $vars->getVar( 'local_log_ids' ) ) { + self::$lastEditPage = null; + + $logs = AbuseFilter::$logIds[ $curTitle ]; + if ( $logs[ 'local' ] ) { // Now actually do our storage - $log_ids = $vars->getVar( 'local_log_ids' )->toNative(); $dbw = wfGetDB( DB_MASTER ); - if ( $log_ids !== null && count( $log_ids ) ) { - $dbw->update( 'abuse_filter_log', - [ 'afl_rev_id' => $revision->getId() ], - [ 'afl_id' => $log_ids ], - __METHOD__ - ); - } + $dbw->update( 'abuse_filter_log', + [ 'afl_rev_id' => $revisionRecord->getId() ], + [ 'afl_id' => $logs['local'] ], + __METHOD__ + ); } - if ( $vars->getVar( 'global_log_ids' ) ) { - $log_ids = $vars->getVar( 'global_log_ids' )->toNative(); - - if ( $log_ids !== null && count( $log_ids ) ) { - global $wgAbuseFilterCentralDB; - $fdb = wfGetDB( DB_MASTER, [], $wgAbuseFilterCentralDB ); - - $fdb->update( 'abuse_filter_log', - [ 'afl_rev_id' => $revision->getId() ], - [ 'afl_id' => $log_ids, 'afl_wiki' => wfWikiID() ], - __METHOD__ - ); - } + if ( $logs[ 'global' ] ) { + $fdb = AbuseFilter::getCentralDB( DB_MASTER ); + $fdb->update( 'abuse_filter_log', + [ 'afl_rev_id' => $revisionRecord->getId() ], + [ 'afl_id' => $logs['global'], 'afl_wiki' => WikiMap::getCurrentWikiDbDomain()->getId() ], + __METHOD__ + ); } } /** - * Check if two article objects are identical or have an identical WikiPage - * @param Article|WikiPage $page1 - * @param Article|WikiPage $page2 - * @return bool - */ - protected static function identicalPageObjects( $page1, $page2 ) { - $wpage1 = ( $page1 instanceof Article ) ? $page1->getPage() : $page1; - $wpage2 = ( $page2 instanceof Article ) ? $page2->getPage() : $page2; - - return $wpage1 === $wpage2; - } - - /** * @param User $user * @param array &$promote */ - public static function onGetAutoPromoteGroups( $user, &$promote ) { + public static function onGetAutoPromoteGroups( User $user, &$promote ) { if ( $promote ) { - $key = AbuseFilter::autoPromoteBlockKey( $user ); - $blocked = (bool)ObjectCache::getInstance( 'hash' )->getWithSetCallback( + $cache = ObjectCache::getInstance( 'hash' ); + $key = AbuseFilter::autoPromoteBlockKey( $cache, $user ); + $blocked = (bool)$cache->getWithSetCallback( $key, - 30, - function () use ( $key ) { - return (int)ObjectCache::getMainStashInstance()->get( $key ); + $cache::TTL_PROC_LONG, + function () use ( $user ) { + return AbuseFilter::getAutoPromoteBlockStatus( $user ); } ); @@ -322,25 +286,21 @@ class AbuseFilterHooks { * @param Title $newTitle * @param User $user * @param string $reason - * @param Status $status - * @return bool + * @param Status &$status */ - public static function onMovePageCheckPermissions( Title $oldTitle, Title $newTitle, - User $user, $reason, Status $status + public static function onTitleMove( + Title $oldTitle, + Title $newTitle, + User $user, + $reason, + Status &$status ) { - $vars = new AbuseFilterVariableHolder; - $vars->addHolders( - AbuseFilter::generateUserVars( $user ), - AbuseFilter::generateTitleVars( $oldTitle, 'MOVED_FROM' ), - AbuseFilter::generateTitleVars( $newTitle, 'MOVED_TO' ) - ); - $vars->setVar( 'SUMMARY', $reason ); - $vars->setVar( 'ACTION', 'move' ); - - $result = AbuseFilter::filterAction( $vars, $oldTitle, 'default', $user ); + $vars = new AbuseFilterVariableHolder(); + $builder = new RunVariableGenerator( $vars, $user, $oldTitle ); + $vars = $builder->getMoveVars( $newTitle, $reason ); + $runner = new AbuseFilterRunner( $user, $oldTitle, $vars, 'default' ); + $result = $runner->run(); $status->merge( $result ); - - return $result->isOK(); } /** @@ -351,41 +311,46 @@ class AbuseFilterHooks { * @param Status $status * @return bool */ - public static function onArticleDelete( $article, $user, $reason, &$error, $status ) { - $vars = new AbuseFilterVariableHolder; - - $vars->addHolders( - AbuseFilter::generateUserVars( $user ), - AbuseFilter::generateTitleVars( $article->getTitle(), 'PAGE' ) - ); - - $vars->setVar( 'SUMMARY', $reason ); - $vars->setVar( 'ACTION', 'delete' ); - - $filter_result = AbuseFilter::filterAction( $vars, $article->getTitle(), 'default', $user ); + public static function onArticleDelete( WikiPage $article, User $user, $reason, &$error, + Status $status ) { + $vars = new AbuseFilterVariableHolder(); + $builder = new RunVariableGenerator( $vars, $user, $article->getTitle() ); + $vars = $builder->getDeleteVars( $reason ); + $runner = new AbuseFilterRunner( $user, $article->getTitle(), $vars, 'default' ); + $filterResult = $runner->run(); - $status->merge( $filter_result ); - $error = $filter_result->isOK() ? '' : $filter_result->getHTML(); + $status->merge( $filterResult ); + $error = $filterResult->isOK() ? '' : $filterResult->getHTML(); - return $filter_result->isOK(); + return $filterResult->isOK(); } /** * @param RecentChange $recentChange */ - public static function onRecentChangeSave( $recentChange ) { + public static function onRecentChangeSave( RecentChange $recentChange ) { $title = Title::makeTitle( $recentChange->getAttribute( 'rc_namespace' ), $recentChange->getAttribute( 'rc_title' ) ); - $action = $recentChange->mAttribs['rc_log_type'] ? - $recentChange->mAttribs['rc_log_type'] : 'edit'; - $actionID = implode( '-', [ - $title->getPrefixedText(), $recentChange->getAttribute( 'rc_user_text' ), $action - ] ); + + $logType = $recentChange->getAttribute( 'rc_log_type' ) ?: 'edit'; + if ( $logType === 'newusers' ) { + $action = $recentChange->getAttribute( 'rc_log_action' ) === 'autocreate' ? + 'autocreateaccount' : + 'createaccount'; + } else { + $action = $logType; + } + $actionID = AbuseFilter::getTaggingActionId( + $action, + $title, + $recentChange->getAttribute( 'rc_user_text' ) + ); if ( isset( AbuseFilter::$tagsToSet[$actionID] ) ) { $recentChange->addTags( AbuseFilter::$tagsToSet[$actionID] ); + unset( AbuseFilter::$tagsToSet[$actionID] ); } } @@ -408,7 +373,7 @@ class AbuseFilterHooks { } /** - * @param array $tags + * @param array &$tags * @param bool $enabled */ private static function fetchAllTags( array &$tags, $enabled ) { @@ -419,10 +384,8 @@ class AbuseFilterHooks { $tags = $cache->getWithSetCallback( // Key to store the cached value under $cache->makeKey( self::FETCH_ALL_TAGS_KEY, (int)$enabled ), - // Time-to-live (in seconds) $cache::TTL_MINUTE, - // Function that derives the new key value function ( $oldValue, &$ttl, array &$setOpts ) use ( $enabled, $tags, $fname ) { global $wgAbuseFilterCentralDB, $wgAbuseFilterIsCentral; @@ -453,12 +416,11 @@ class AbuseFilterHooks { } if ( $wgAbuseFilterCentralDB && !$wgAbuseFilterIsCentral ) { - $dbr = wfGetDB( DB_REPLICA, [], $wgAbuseFilterCentralDB ); - $where['af_global'] = 1; + $dbr = AbuseFilter::getCentralDB( DB_REPLICA ); $res = $dbr->select( [ 'abuse_filter_action', 'abuse_filter' ], 'afa_parameters', - $where, + [ 'af_global' => 1 ] + $where, $fname, [], [ 'abuse_filter' => [ 'INNER JOIN', 'afa_filter=af_id' ] ] @@ -499,18 +461,17 @@ class AbuseFilterHooks { public static function onLoadExtensionSchemaUpdates( DatabaseUpdater $updater ) { $dir = dirname( __DIR__ ); - if ( $updater->getDB()->getType() == 'mysql' || $updater->getDB()->getType() == 'sqlite' ) { - if ( $updater->getDB()->getType() == 'mysql' ) { + if ( $updater->getDB()->getType() === 'mysql' || $updater->getDB()->getType() === 'sqlite' ) { + if ( $updater->getDB()->getType() === 'mysql' ) { $updater->addExtensionUpdate( [ 'addTable', 'abuse_filter', "$dir/abusefilter.tables.sql", true ] ); - $updater->addExtensionUpdate( [ 'addTable', 'abuse_filter_history', - "$dir/db_patches/patch-abuse_filter_history.sql", true ] ); } else { $updater->addExtensionUpdate( [ 'addTable', 'abuse_filter', "$dir/abusefilter.tables.sqlite.sql", true ] ); - $updater->addExtensionUpdate( [ 'addTable', 'abuse_filter_history', - "$dir/db_patches/patch-abuse_filter_history.sqlite.sql", true ] ); } + $updater->addExtensionTable( 'abuse_filter_history', + "$dir/db_patches/patch-abuse_filter_history.sql" ); + $updater->addExtensionUpdate( [ 'addField', 'abuse_filter_history', 'afh_changed_fields', "$dir/db_patches/patch-afh_changed_fields.sql", true @@ -523,7 +484,7 @@ class AbuseFilterHooks { "$dir/db_patches/patch-global_filters.sql", true ] ); $updater->addExtensionUpdate( [ 'addField', 'abuse_filter_log', 'afl_rev_id', "$dir/db_patches/patch-afl_action_id.sql", true ] ); - if ( $updater->getDB()->getType() == 'mysql' ) { + if ( $updater->getDB()->getType() === 'mysql' ) { $updater->addExtensionUpdate( [ 'addIndex', 'abuse_filter_log', 'filter_timestamp', "$dir/db_patches/patch-fix-indexes.sql", true ] ); } else { @@ -536,42 +497,42 @@ class AbuseFilterHooks { $updater->addExtensionUpdate( [ 'addField', 'abuse_filter', 'af_group', "$dir/db_patches/patch-af_group.sql", true ] ); - if ( $updater->getDB()->getType() == 'mysql' ) { + $updater->addExtensionIndex( + 'abuse_filter_log', 'afl_wiki_timestamp', + "$dir/db_patches/patch-global_logging_wiki-index.sql" + ); + + if ( $updater->getDB()->getType() === 'mysql' ) { $updater->addExtensionUpdate( [ - 'addIndex', 'abuse_filter_log', 'wiki_timestamp', - "$dir/db_patches/patch-global_logging_wiki-index.sql", true + 'modifyField', 'abuse_filter_log', 'afl_namespace', + "$dir/db_patches/patch-afl-namespace_int.sql", true ] ); } else { $updater->addExtensionUpdate( [ - 'addIndex', 'abuse_filter_log', 'afl_wiki_timestamp', - "$dir/db_patches/patch-global_logging_wiki-index.sqlite.sql", true + 'modifyField', 'abuse_filter_log', 'afl_namespace', + "$dir/db_patches/patch-afl-namespace_int.sqlite.sql", true ] ); } + if ( $updater->getDB()->getType() === 'mysql' ) { + $updater->addExtensionUpdate( [ 'dropField', 'abuse_filter_log', + 'afl_log_id', "$dir/db_patches/patch-drop_afl_log_id.sql", true ] ); + } else { + $updater->addExtensionUpdate( [ 'dropField', 'abuse_filter_log', + 'afl_log_id', "$dir/db_patches/patch-drop_afl_log_id.sqlite.sql", true ] ); + } if ( $updater->getDB()->getType() == 'mysql' ) { $updater->addExtensionUpdate( [ - 'modifyField', 'abuse_filter_log', 'afl_namespace', - "$dir/db_patches/patch-afl-namespace_int.sql", true + 'addIndex', 'abuse_filter_log', 'filter_timestamp_full', + "$dir/db_patches/patch-split-afl_filter.sql", true ] ); } else { - /* - $updater->addExtensionUpdate( array( - 'modifyField', - 'abuse_filter_log', - 'afl_namespace', - "$dir/db_patches/patch-afl-namespace_int.sqlite.sql", - true - ) ); - */ - /* @todo Modify a column in sqlite, which do not support such - * things create backup, drop, create with new schema, copy, - * drop backup or simply see - * https://www.mediawiki.org/wiki/Manual:SQLite#About_SQLite : - * Several extensions are known to have database update or - * installation issues with SQLite: AbuseFilter, ... - */ + $updater->addExtensionUpdate( [ + 'addIndex', 'abuse_filter_log', 'filter_timestamp_full', + "$dir/db_patches/patch-split-afl_filter.sqlite.sql", true + ] ); } - } elseif ( $updater->getDB()->getType() == 'postgres' ) { + } elseif ( $updater->getDB()->getType() === 'postgres' ) { $updater->addExtensionUpdate( [ 'addTable', 'abuse_filter', "$dir/abusefilter.tables.pg.sql", true ] ); $updater->addExtensionUpdate( [ @@ -605,8 +566,6 @@ class AbuseFilterHooks { $updater->addExtensionUpdate( [ 'addPgField', 'abuse_filter_log', 'afl_rev_id', 'INTEGER' ] ); $updater->addExtensionUpdate( [ - 'addPgField', 'abuse_filter_log', 'afl_log_id', 'INTEGER' ] ); - $updater->addExtensionUpdate( [ 'changeField', 'abuse_filter_log', 'afl_filter', 'TEXT', '' ] ); $updater->addExtensionUpdate( [ 'changeField', 'abuse_filter_log', 'afl_namespace', "INTEGER", '' ] ); @@ -643,23 +602,34 @@ class AbuseFilterHooks { '(afl_rev_id)' ] ); $updater->addExtensionUpdate( [ - 'addPgExtIndex', 'abuse_filter_log', 'abuse_filter_log_log_id', - '(afl_log_id)' - ] ); - $updater->addExtensionUpdate( [ 'addPgExtIndex', 'abuse_filter_log', 'abuse_filter_log_wiki_timestamp', '(afl_wiki,afl_timestamp)' ] ); + $updater->addExtensionUpdate( [ + 'dropPgField', 'abuse_filter_log', 'afl_log_id' ] ); + $updater->addExtensionUpdate( [ + 'setDefault', 'abuse_filter_log', 'afl_filter', '' + ] ); + $updater->addExtensionUpdate( [ + 'addPgField', 'abuse_filter_log', 'afl_global', 'SMALLINT NOT NULL DEFAULT 0' ] ); + $updater->addExtensionUpdate( [ + 'addPgField', 'abuse_filter_log', 'afl_filter_id', 'INTEGER NOT NULL DEFAULT 0' ] ); + $updater->addExtensionUpdate( [ + 'addPgIndex', 'abuse_filter_log', 'abuse_filter_log_filter_timestamp_full', + '(afl_global, afl_filter_id, afl_timestamp)' ] ); } $updater->addExtensionUpdate( [ [ __CLASS__, 'createAbuseFilterUser' ] ] ); + $updater->addPostDatabaseUpdateMaintenance( 'NormalizeThrottleParameters' ); + $updater->addPostDatabaseUpdateMaintenance( 'FixOldLogEntries' ); + $updater->addPostDatabaseUpdateMaintenance( 'UpdateVarDumps' ); } /** * Updater callback to create the AbuseFilter user after the user tables have been updated. * @param DatabaseUpdater $updater */ - public static function createAbuseFilterUser( $updater ) { + public static function createAbuseFilterUser( DatabaseUpdater $updater ) { $username = wfMessage( 'abusefilter-blocker' )->inContentLanguage()->text(); $user = User::newFromName( $username ); @@ -677,9 +647,12 @@ class AbuseFilterHooks { * @param array &$tools * @param SpecialPage $sp for context */ - public static function onContributionsToolLinks( $id, $nt, array &$tools, SpecialPage $sp ) { + public static function onContributionsToolLinks( $id, Title $nt, array &$tools, SpecialPage $sp ) { $username = $nt->getText(); - if ( $sp->getUser()->isAllowed( 'abusefilter-log' ) && !IP::isValidRange( $username ) ) { + if ( MediaWikiServices::getInstance()->getPermissionManager() + ->userHasRight( $sp->getUser(), 'abusefilter-log' ) + && !IPUtils::isValidRange( $username ) + ) { $linkRenderer = $sp->getLinkRenderer(); $tools['abuselog'] = $linkRenderer->makeLink( SpecialPage::getTitleFor( 'AbuseLog' ), @@ -702,7 +675,9 @@ class AbuseFilterHooks { array &$links ) { $user = $context->getUser(); - if ( $user->isAllowed( 'abusefilter-log' ) ) { + if ( MediaWikiServices::getInstance()->getPermissionManager() + ->userHasRight( $user, 'abusefilter-log' ) + ) { $links[] = $linkRenderer->makeLink( SpecialPage::getTitleFor( 'AbuseLog' ), $context->msg( 'abusefilter-log-linkonhistory' )->text(), @@ -713,18 +688,43 @@ class AbuseFilterHooks { } /** + * @param IContextSource $context + * @param LinkRenderer $linkRenderer + * @param string[] &$links + */ + public static function onUndeletePageToolLinks( + IContextSource $context, + LinkRenderer $linkRenderer, + array &$links + ) { + $pm = MediaWikiServices::getInstance()->getPermissionManager(); + $show = $pm->userHasRight( $context->getUser(), 'abusefilter-log' ); + $action = $context->getRequest()->getVal( 'action', 'view' ); + + // For 'history action', the link would be added by HistoryPageToolLinks hook. + if ( $show && $action !== 'history' ) { + $links[] = $linkRenderer->makeLink( + SpecialPage::getTitleFor( 'AbuseLog' ), + $context->msg( 'abusefilter-log-linkonundelete' )->text(), + [ 'title' => $context->msg( 'abusefilter-log-linkonundelete-text' )->text() ], + [ 'wpSearchTitle' => $context->getTitle()->getPrefixedText() ] + ); + } + } + + /** * Filter an upload. * * @param UploadBase $upload * @param User $user - * @param array $props + * @param array|null $props * @param string $comment * @param string $pageText * @param array|ApiMessage &$error * @return bool */ public static function onUploadVerifyUpload( UploadBase $upload, User $user, - array $props, $comment, $pageText, &$error + $props, $comment, $pageText, &$error ) { return self::filterUpload( 'upload', $upload, $user, $props, $comment, $pageText, $error ); } @@ -752,105 +752,61 @@ class AbuseFilterHooks { * @param string $action 'upload' or 'stashupload' * @param UploadBase $upload * @param User $user User performing the action - * @param array $props File properties, as returned by FSFile::getPropsFromPath() + * @param array|null $props File properties, as returned by MWFileProps::getPropsFromPath(). * @param string|null $summary Upload log comment (also used as edit summary) * @param string|null $text File description page text (only used for new uploads) * @param array|ApiMessage &$error * @return bool */ public static function filterUpload( $action, UploadBase $upload, User $user, - array $props, $summary, $text, &$error + $props, $summary, $text, &$error ) { $title = $upload->getTitle(); - - $vars = new AbuseFilterVariableHolder; - $vars->addHolders( - AbuseFilter::generateUserVars( $user ), - AbuseFilter::generateTitleVars( $title, 'PAGE' ) - ); - $vars->setVar( 'ACTION', $action ); - - // We use the hexadecimal version of the file sha1. - // Use UploadBase::getTempFileSha1Base36 so that we don't have to calculate the sha1 sum again - $sha1 = Wikimedia\base_convert( $upload->getTempFileSha1Base36(), 36, 16, 40 ); - - $vars->setVar( 'file_sha1', $sha1 ); - $vars->setVar( 'file_size', $upload->getFileSize() ); - - $vars->setVar( 'file_mime', $props['mime'] ); - $vars->setVar( - 'file_mediatype', - MediaWiki\MediaWikiServices::getInstance()->getMimeAnalyzer() - ->getMediaType( null, $props['mime'] ) - ); - $vars->setVar( 'file_width', $props['width'] ); - $vars->setVar( 'file_height', $props['height'] ); - $vars->setVar( 'file_bits_per_channel', $props['bits'] ); - - // We only have the upload comment and page text when using the UploadVerifyUpload hook - if ( $summary !== null && $text !== null ) { - // This block is adapted from self::filterEdit() - if ( $title->exists() ) { - $page = WikiPage::factory( $title ); - $revision = $page->getRevision(); - if ( !$revision ) { - return true; - } - - $oldcontent = $revision->getContent( Revision::RAW ); - $oldtext = AbuseFilter::contentToString( $oldcontent ); - - // Cache article object so we can share a parse operation - $articleCacheKey = $title->getNamespace() . ':' . $title->getText(); - AFComputedVariable::$articleCache[$articleCacheKey] = $page; - - // Page text is ignored for uploads when the page already exists - $text = $oldtext; - } else { - $page = null; - $oldtext = ''; - } - - // Load vars for filters to check - $vars->setVar( 'summary', $summary ); - $vars->setVar( 'minor_edit', false ); - $vars->setVar( 'old_wikitext', $oldtext ); - $vars->setVar( 'new_wikitext', $text ); - // TODO: set old_content and new_content vars, use them - $vars->addHolders( AbuseFilter::getEditVars( $title, $page ) ); + if ( $title === null ) { + // T144265: This could happen for 'stashupload' if the specified title is invalid. + // Let UploadBase warn the user about that, and we'll filter later. + $logger = LoggerFactory::getInstance( 'AbuseFilter' ); + $logger->warning( __METHOD__ . " received a null title. Action: $action." ); + return true; } - $filter_result = AbuseFilter::filterAction( $vars, $title, 'default', $user ); + $vars = new AbuseFilterVariableHolder(); + $builder = new RunVariableGenerator( $vars, $user, $title ); + $vars = $builder->getUploadVars( $action, $upload, $summary, $text, $props ); + if ( $vars === null ) { + return true; + } + $runner = new AbuseFilterRunner( $user, $title, $vars, 'default' ); + $filterResult = $runner->run(); - if ( !$filter_result->isOK() ) { - $messageAndParams = $filter_result->getErrorsArray()[0]; - $apiResult = self::getApiResult( $filter_result ); - $error = ApiMessage::create( - $messageAndParams, - $apiResult['code'], - $apiResult - ); + if ( !$filterResult->isOK() ) { + // Produce a useful error message for API edits + $filterResultApi = self::getApiStatus( $filterResult ); + // @todo Return all errors instead of only the first one + $error = $filterResultApi->getErrors()[0]['message']; } - return $filter_result->isOK(); + return $filterResult->isOK(); } /** - * Adds global variables to the Javascript as needed + * For integration with the Renameuser extension. * - * @param array &$vars + * @param RenameuserSQL $renameUserSQL */ - public static function onMakeGlobalVariablesScript( array &$vars ) { - if ( isset( AbuseFilter::$editboxName ) && AbuseFilter::$editboxName !== null ) { - $vars['abuseFilterBoxName'] = AbuseFilter::$editboxName; - } - - if ( AbuseFilterViewExamine::$examineType !== null ) { - $vars['abuseFilterExamine'] = [ - 'type' => AbuseFilterViewExamine::$examineType, - 'id' => AbuseFilterViewExamine::$examineId, - ]; - } + public static function onRenameUserSQL( RenameuserSQL $renameUserSQL ) { + $renameUserSQL->tablesJob['abuse_filter'] = [ + RenameuserSQL::NAME_COL => 'af_user_text', + RenameuserSQL::UID_COL => 'af_user', + RenameuserSQL::TIME_COL => 'af_timestamp', + 'uniqueKey' => 'af_id' + ]; + $renameUserSQL->tablesJob['abuse_filter_history'] = [ + RenameuserSQL::NAME_COL => 'afh_user_text', + RenameuserSQL::UID_COL => 'afh_user', + RenameuserSQL::TIME_COL => 'afh_timestamp', + 'uniqueKey' => 'afh_id' + ]; } /** @@ -871,30 +827,79 @@ class AbuseFilterHooks { * @param Content $content * @param ParserOutput $output * @param string $summary - * @param User|null $user + * @param User $user */ public static function onParserOutputStashForEdit( - WikiPage $page, Content $content, ParserOutput $output, $summary = '', $user = null + WikiPage $page, Content $content, ParserOutput $output, string $summary, User $user ) { - $revision = $page->getRevision(); - if ( !$revision ) { - return; - } - - $text = AbuseFilter::contentToString( $content ); - $oldcontent = $revision->getContent( Revision::RAW ); - $user = $user ?: RequestContext::getMain()->getUser(); + // XXX: This makes the assumption that this method is only ever called for the main slot. + // Which right now holds true, but any more fancy MCR stuff will likely break here... + $slot = SlotRecord::MAIN; // Cache any resulting filter matches. // Do this outside the synchronous stash lock to avoid any chance of slowdown. DeferredUpdates::addCallableUpdate( - function () use ( $user, $page, $summary, $content, $text, $oldcontent ) { - $vars = self::newVariableHolderForEdit( - $user, $page->getTitle(), $page, $summary, $content, $text, $oldcontent - ); - AbuseFilter::filterAction( $vars, $page->getTitle(), 'default', $user, 'stash' ); + function () use ( + $user, + $page, + $summary, + $content, + $slot + ) { + $startTime = microtime( true ); + $vars = new AbuseFilterVariableHolder(); + $generator = new RunVariableGenerator( $vars, $user, $page->getTitle() ); + $vars = $generator->getStashEditVars( $content, $summary, $slot, $page ); + if ( !$vars ) { + return; + } + $runner = new AbuseFilterRunner( $user, $page->getTitle(), $vars, 'default' ); + $runner->runForStash(); + $totalTime = microtime( true ) - $startTime; + MediaWikiServices::getInstance()->getStatsdDataFactory() + ->timing( 'timing.stashAbuseFilter', $totalTime ); }, DeferredUpdates::PRESEND ); } + + /** + * Setup tables to emulate global filters, used in AbuseFilterConsequencesTest. + * + * @param IMaintainableDatabase $db + * @param string $prefix The prefix used in unit tests + * @suppress PhanUndeclaredClassConstant AbuseFilterConsequencesTest is in AutoloadClasses + * @suppress PhanUndeclaredClassStaticProperty AbuseFilterConsequencesTest is in AutoloadClasses + */ + public static function onUnitTestsAfterDatabaseSetup( IMaintainableDatabase $db, $prefix ) { + $externalPrefix = AbuseFilterConsequencesTest::DB_EXTERNAL_PREFIX; + if ( $db->tableExists( $externalPrefix . AbuseFilterConsequencesTest::$externalTables[0], __METHOD__ ) ) { + // Check a random table to avoid unnecessary table creations. See T155147. + return; + } + + foreach ( AbuseFilterConsequencesTest::$externalTables as $table ) { + // Don't create them as temporary, as we'll access the DB via another connection + $db->duplicateTableStructure( + "$prefix$table", + "$prefix$externalPrefix$table", + false, + __METHOD__ + ); + } + } + + /** + * Drop tables used for global filters in AbuseFilterConsequencesTest. + * Note: this has the same problem as T201290. + * + * @suppress PhanUndeclaredClassConstant AbuseFilterConsequencesTest is in AutoloadClasses + * @suppress PhanUndeclaredClassStaticProperty AbuseFilterConsequencesTest is in AutoloadClasses + */ + public static function onUnitTestsBeforeDatabaseTeardown() { + $db = wfGetDB( DB_MASTER ); + foreach ( AbuseFilterConsequencesTest::$externalTables as $table ) { + $db->dropTable( AbuseFilterConsequencesTest::DB_EXTERNAL_PREFIX . $table ); + } + } } diff --git a/AbuseFilter/includes/AbuseFilterModifyLogFormatter.php b/AbuseFilter/includes/AbuseFilterModifyLogFormatter.php index 769c27d3..8defb8b5 100644 --- a/AbuseFilter/includes/AbuseFilterModifyLogFormatter.php +++ b/AbuseFilter/includes/AbuseFilterModifyLogFormatter.php @@ -15,6 +15,7 @@ class AbuseFilterModifyLogFormatter extends LogFormatter { /** * @return array + * @suppress SecurityCheck-DoubleEscaped taint-check false positives */ protected function extractParameters() { $parameters = $this->entry->getParameters(); diff --git a/AbuseFilter/includes/AbuseFilterPreAuthenticationProvider.php b/AbuseFilter/includes/AbuseFilterPreAuthenticationProvider.php index ed72c5a4..343f5478 100644 --- a/AbuseFilter/includes/AbuseFilterPreAuthenticationProvider.php +++ b/AbuseFilter/includes/AbuseFilterPreAuthenticationProvider.php @@ -2,6 +2,8 @@ use MediaWiki\Auth\AbstractPreAuthenticationProvider; use MediaWiki\Auth\AuthenticationRequest; +use MediaWiki\Extension\AbuseFilter\VariableGenerator\RunVariableGenerator; +use MediaWiki\MediaWikiServices; class AbuseFilterPreAuthenticationProvider extends AbstractPreAuthenticationProvider { /** @@ -35,23 +37,22 @@ class AbuseFilterPreAuthenticationProvider extends AbstractPreAuthenticationProv * @return StatusValue */ protected function testUser( $user, $creator, $autocreate ) { - if ( $user->getName() == wfMessage( 'abusefilter-blocker' )->inContentLanguage()->text() ) { + $startTime = microtime( true ); + if ( $user->getName() === wfMessage( 'abusefilter-blocker' )->inContentLanguage()->text() ) { return StatusValue::newFatal( 'abusefilter-accountreserved' ); } - $vars = new AbuseFilterVariableHolder; - - // generateUserVars records $creator->getName() which would be the IP for unregistered users - if ( $creator->isLoggedIn() ) { - $vars->addHolders( AbuseFilter::generateUserVars( $creator ) ); - } - - $vars->setVar( 'ACTION', $autocreate ? 'autocreateaccount' : 'createaccount' ); - $vars->setVar( 'ACCOUNTNAME', $user->getName() ); + $title = SpecialPage::getTitleFor( 'Userlogin' ); + $vars = new AbuseFilterVariableHolder(); + $builder = new RunVariableGenerator( $vars, $creator, $title ); + $vars = $builder->getAccountCreationVars( $user, $autocreate ); // pass creator in explicitly to prevent recording the current user on autocreation - T135360 - $status = AbuseFilter::filterAction( $vars, SpecialPage::getTitleFor( 'Userlogin' ), - 'default', $creator ); + $runner = new AbuseFilterRunner( $creator, $title, $vars, 'default' ); + $status = $runner->run(); + + MediaWikiServices::getInstance()->getStatsdDataFactory() + ->timing( 'timing.createaccountAbuseFilter', microtime( true ) - $startTime ); return $status->getStatusValue(); } diff --git a/AbuseFilter/includes/AbuseFilterRightsLogFormatter.php b/AbuseFilter/includes/AbuseFilterRightsLogFormatter.php new file mode 100644 index 00000000..37255d2f --- /dev/null +++ b/AbuseFilter/includes/AbuseFilterRightsLogFormatter.php @@ -0,0 +1,42 @@ +<?php + +class AbuseFilterRightsLogFormatter extends LogFormatter { + + /** + * This method is identical to the parent, but it's redeclared to give grep a chance + * to find the messages. + * @inheritDoc + */ + protected function getMessageKey() { + $subtype = $this->entry->getSubtype(); + // Messages that can be used here: + // * logentry-rights-blockautopromote + // * logentry-rights-restoreautopromote + return "logentry-rights-$subtype"; + } + + /** + * @inheritDoc + */ + protected function extractParameters() { + $ret = []; + $ret[3] = $this->entry->getTarget()->getText(); + if ( $this->entry->getSubType() === 'blockautopromote' ) { + $parameters = $this->entry->getParameters(); + $duration = $parameters['7::duration']; + $ret[4] = $this->context->getLanguage()->formatDuration( $duration ); + } + return $ret; + } + + /** + * @inheritDoc + */ + protected function getMessageParameters() { + $params = parent::getMessageParameters(); + // remove "User:" prefix + $params[2] = $this->formatParameterValue( 'user-link', $this->entry->getTarget()->getText() ); + return $params; + } + +} diff --git a/AbuseFilter/includes/AbuseFilterRunner.php b/AbuseFilter/includes/AbuseFilterRunner.php new file mode 100644 index 00000000..eca20bae --- /dev/null +++ b/AbuseFilter/includes/AbuseFilterRunner.php @@ -0,0 +1,1434 @@ +<?php + +use MediaWiki\Block\DatabaseBlock; +use MediaWiki\Extension\AbuseFilter\Hooks\AbuseFilterHookRunner; +use MediaWiki\Extension\AbuseFilter\VariableGenerator\VariableGenerator; +use MediaWiki\Logger\LoggerFactory; +use MediaWiki\MediaWikiServices; +use MediaWiki\Session\SessionManager; +use Wikimedia\IPUtils; +use Wikimedia\Rdbms\IDatabase; + +/** + * This class contains the logic for executing abuse filters and their actions. The entry points are + * run() and runForStash(). Note that run() can only be executed once on a given instance. + * @todo In a perfect world, every time this class gets constructed we should have a context + * source at hand. Unfortunately, this currently isn't true, as the hooks used for filtering + * don't pass a full context. If they did, this class would just extend ContextSource and use + * that to retrieve user, title, globals etc. + */ +class AbuseFilterRunner { + /** + * @var User The user who performed the action being filtered + */ + protected $user; + /** + * @var Title The title where the action being filtered was performed + */ + protected $title; + /** + * @var AbuseFilterVariableHolder The variables for the current action + */ + protected $vars; + /** + * @var string The group of filters to check (as defined in $wgAbuseFilterValidGroups) + */ + protected $group; + /** + * @var string The action we're filtering + */ + protected $action; + + /** + * @var array Data from per-filter profiling. Shape: + * [ filterName => [ 'time' => float, 'conds' => int, 'result' => bool ] ] + * @phan-var array<string,array{time:float,conds:int,result:bool}> + * + * Where 'timeTaken' is in seconds, 'result' is a boolean indicating whether the filter matched + * the action, and 'filterID' is "{prefix}-{ID}" ; Prefix should be empty for local + * filters. In stash mode this member is saved in cache, while in execute mode it's used to + * update profiling after checking all filters. + */ + protected $profilingData; + + /** + * @var AbuseFilterParser The parser instance to use to check all filters + * @protected Public for back-compat only, will be made protected. self::init already handles + * building a parser object. + */ + public $parser; + /** + * @var bool Whether a run() was already performed. Used to avoid multiple executions with the + * same members. + */ + private $executed = false; + + /** @var AbuseFilterHookRunner */ + private $hookRunner; + + /** + * @param User $user The user who performed the action being filtered + * @param Title $title The title where the action being filtered was performed + * @param AbuseFilterVariableHolder $vars The variables for the current action + * @param string $group The group of filters to check. It must be defined as so in + * $wgAbuseFilterValidGroups, or this will throw. + * @throws InvalidArgumentException + */ + public function __construct( User $user, Title $title, AbuseFilterVariableHolder $vars, $group ) { + global $wgAbuseFilterValidGroups; + if ( !in_array( $group, $wgAbuseFilterValidGroups ) ) { + throw new InvalidArgumentException( '$group must be defined in $wgAbuseFilterValidGroups' ); + } + if ( !$vars->varIsSet( 'action' ) ) { + throw new InvalidArgumentException( "The 'action' variable is not set." ); + } + $this->user = $user; + $this->title = $title; + $this->vars = $vars; + $this->vars->setLogger( LoggerFactory::getInstance( 'AbuseFilter' ) ); + $this->group = $group; + $this->action = $vars->getVar( 'action' )->toString(); + $this->hookRunner = AbuseFilterHookRunner::getRunner(); + } + + /** + * Inits variables and parser right before running + */ + private function init() { + // Add vars from extensions + $this->hookRunner->onAbuseFilterFilterAction( + $this->vars, + $this->title + ); + $this->hookRunner->onAbuseFilterAlterVariables( + $this->vars, + $this->title, + $this->user + ); + $generator = new VariableGenerator( $this->vars ); + $this->vars = $generator->addGenericVars()->getVariableHolder(); + + $this->vars->forFilter = true; + $this->vars->setVar( 'timestamp', (int)wfTimestamp( TS_UNIX ) ); + $this->parser = $this->getParser(); + $this->parser->setStatsd( MediaWikiServices::getInstance()->getStatsdDataFactory() ); + $this->profilingData = []; + } + + /** + * Shortcut method, so that it can be overridden in mocks. + * @return AbuseFilterParser + */ + protected function getParser() : AbuseFilterParser { + return AbuseFilter::getDefaultParser( $this->vars ); + } + + /** + * The main entry point of this class. This method runs all filters and takes their consequences. + * + * @param bool $allowStash Whether we are allowed to check the cache to see if there's a cached + * result of a previous execution for the same edit. + * @throws BadMethodCallException If run() was already called on this instance + * @return Status Good if no action has been taken, a fatal otherwise. + */ + public function run( $allowStash = true ) : Status { + global $wgAbuseFilterActions; + if ( $this->executed ) { + throw new BadMethodCallException( 'run() was already called on this instance.' ); + } + $this->executed = true; + $this->init(); + + $skipReasons = []; + $shouldFilter = $this->hookRunner->onAbuseFilterShouldFilterAction( + $this->vars, $this->title, $this->user, $skipReasons + ); + if ( !$shouldFilter ) { + $logger = LoggerFactory::getInstance( 'AbuseFilter' ); + $logger->info( + 'Skipping action {action}. Reasons provided: {reasons}', + [ 'action' => $this->action, 'reasons' => implode( ', ', $skipReasons ) ] + ); + return Status::newGood(); + } + + $useStash = $allowStash && $this->action === 'edit'; + + $fromCache = false; + $result = []; + if ( $useStash ) { + $cacheData = $this->seekCache(); + if ( $cacheData !== false ) { + if ( isset( $wgAbuseFilterActions['tag'] ) && $wgAbuseFilterActions['tag'] ) { + // Merge in any tags to apply to recent changes entries + AbuseFilter::bufferTagsToSetByAction( $cacheData['tags'] ); + } + // Use cached vars (T176291) and profiling data (T191430) + $this->vars = AbuseFilterVariableHolder::newFromArray( $cacheData['vars'] ); + $result = [ + 'matches' => $cacheData['matches'], + 'runtime' => $cacheData['runtime'], + 'condCount' => $cacheData['condCount'], + 'profiling' => $cacheData['profiling'] + ]; + $fromCache = true; + } + } + + if ( !$fromCache ) { + $startTime = microtime( true ); + // Ensure there's no extra time leftover + AFComputedVariable::$profilingExtraTime = 0; + + // This also updates $this->profilingData and $this->parser->mCondCount used later + $matches = $this->checkAllFilters(); + $timeTaken = ( microtime( true ) - $startTime - AFComputedVariable::$profilingExtraTime ) * 1000; + $result = [ + 'matches' => $matches, + 'runtime' => $timeTaken, + 'condCount' => $this->parser->getCondCount(), + 'profiling' => $this->profilingData + ]; + } + '@phan-var array{matches:array,runtime:int,condCount:int,profiling:array} $result'; + + $matchedFilters = array_keys( array_filter( $result['matches'] ) ); + $allFilters = array_keys( $result['matches'] ); + + $this->profileExecution( $result, $matchedFilters, $allFilters ); + + if ( count( $matchedFilters ) === 0 ) { + return Status::newGood(); + } + + $status = $this->executeFilterActions( $matchedFilters ); + $actionsTaken = $status->getValue(); + + $this->addLogEntries( $actionsTaken ); + + return $status; + } + + /** + * Similar to run(), but runs in "stash" mode, which means filters are executed, no actions are + * taken, and the result is saved in cache to be later reused. This can only be used for edits, + * and not doing so will throw. + * + * @throws InvalidArgumentException + * @return Status Always a good status, since we're only saving data. + */ + public function runForStash() : Status { + if ( $this->action !== 'edit' ) { + throw new InvalidArgumentException( + __METHOD__ . " can only be called for edits, called for action {$this->action}." + ); + } + + $this->init(); + + $skipReasons = []; + $shouldFilter = $this->hookRunner->onAbuseFilterShouldFilterAction( + $this->vars, $this->title, $this->user, $skipReasons + ); + if ( !$shouldFilter ) { + // Don't log it yet + return Status::newGood(); + } + + $cache = ObjectCache::getLocalClusterInstance(); + $stashKey = $this->getStashKey( $cache ); + + $startTime = microtime( true ); + // Ensure there's no extra time leftover + AFComputedVariable::$profilingExtraTime = 0; + + $matchedFilters = $this->checkAllFilters(); + // Save the filter stash result and do nothing further + $cacheData = [ + 'matches' => $matchedFilters, + 'tags' => AbuseFilter::$tagsToSet, + 'condCount' => $this->parser->getCondCount(), + 'runtime' => ( microtime( true ) - $startTime - AFComputedVariable::$profilingExtraTime ) * 1000, + 'vars' => $this->vars->dumpAllVars(), + 'profiling' => $this->profilingData + ]; + + $cache->set( $stashKey, $cacheData, $cache::TTL_MINUTE ); + $this->logCache( 'store', $stashKey ); + + return Status::newGood(); + } + + /** + * Search the cache to find data for a previous execution done for the current edit. + * + * @return false|array False on failure, the array with data otherwise + */ + protected function seekCache() { + $cache = ObjectCache::getLocalClusterInstance(); + $stashKey = $this->getStashKey( $cache ); + + $ret = $cache->get( $stashKey ); + $status = $ret !== false ? 'hit' : 'miss'; + $this->logCache( $status, $stashKey ); + + return $ret; + } + + /** + * Get the stash key for the current variables + * + * @param BagOStuff $cache + * @return string + */ + protected function getStashKey( BagOStuff $cache ) { + $inputVars = $this->vars->exportNonLazyVars(); + // Exclude noisy fields that have superficial changes + $excludedVars = [ + 'old_html' => true, + 'new_html' => true, + 'user_age' => true, + 'timestamp' => true, + 'page_age' => true, + 'moved_from_age' => true, + 'moved_to_age' => true + ]; + + $inputVars = array_diff_key( $inputVars, $excludedVars ); + ksort( $inputVars ); + $hash = md5( serialize( $inputVars ) ); + + return $cache->makeKey( + 'abusefilter', + 'check-stash', + $this->group, + $hash, + 'v2' + ); + } + + /** + * Log cache operations related to stashed edits, i.e. store, hit and miss + * + * @param string $type Either 'store', 'hit' or 'miss' + * @param string $key The cache key used + * @throws InvalidArgumentException + */ + protected function logCache( $type, $key ) { + if ( !in_array( $type, [ 'store', 'hit', 'miss' ] ) ) { + throw new InvalidArgumentException( '$type must be either "store", "hit" or "miss"' ); + } + $logger = LoggerFactory::getInstance( 'StashEdit' ); + // Bots do not use edit stashing, so avoid distorting the stats + $statsd = $this->user->isBot() + ? new NullStatsdDataFactory() + : MediaWikiServices::getInstance()->getStatsdDataFactory(); + + $logger->debug( __METHOD__ . ": cache $type for '{$this->title}' (key $key)." ); + $statsd->increment( "abusefilter.check-stash.$type" ); + } + + /** + * Returns an associative array of filters which were tripped + * + * @protected Public for back compat only; this will actually be made protected in the future. + * You should either rely on $this->run() or subclass this class. + * @todo This method should simply return an array with IDs of matched filters as values, + * since we always end up filtering it after calling this method. + * @return bool[] Map of (integer filter ID => bool) + */ + public function checkAllFilters() : array { + global $wgAbuseFilterCentralDB, $wgAbuseFilterIsCentral, $wgAbuseFilterConditionLimit; + + // Ensure that we start fresh, see T193374 + $this->parser->resetCondCount(); + + $matchedFilters = []; + + foreach ( $this->getLocalFilters() as $row ) { + $matchedFilters[$row->af_id] = $this->checkFilter( $row ); + } + + if ( $wgAbuseFilterCentralDB && !$wgAbuseFilterIsCentral ) { + foreach ( $this->getGlobalFilters() as $row ) { + $matchedFilters[ AbuseFilter::buildGlobalName( $row->af_id ) ] = + $this->checkFilter( $row, true ); + } + } + + // Tag the action if the condition limit was hit + if ( $this->parser->getCondCount() > $wgAbuseFilterConditionLimit ) { + $actionID = $this->getTaggingID(); + AbuseFilter::bufferTagsToSetByAction( [ $actionID => [ 'abusefilter-condition-limit' ] ] ); + } + + return $matchedFilters; + } + + /** + * @return array abuse_filter DB rows + */ + protected function getLocalFilters() : array { + return iterator_to_array( wfGetDB( DB_REPLICA )->select( + 'abuse_filter', + AbuseFilter::ALL_ABUSE_FILTER_FIELDS, + [ + 'af_enabled' => 1, + 'af_deleted' => 0, + 'af_group' => $this->group, + ], + __METHOD__ + ) ); + } + + /** + * @return array abuse_filter rows from the foreign DB + */ + protected function getGlobalFilters() : array { + $globalRulesKey = AbuseFilter::getGlobalRulesKey( $this->group ); + $fname = __METHOD__; + + return MediaWikiServices::getInstance()->getMainWANObjectCache()->getWithSetCallback( + $globalRulesKey, + WANObjectCache::TTL_WEEK, + function () use ( $fname ) { + $fdb = AbuseFilter::getCentralDB( DB_REPLICA ); + + return iterator_to_array( $fdb->select( + 'abuse_filter', + AbuseFilter::ALL_ABUSE_FILTER_FIELDS, + [ + 'af_enabled' => 1, + 'af_deleted' => 0, + 'af_global' => 1, + 'af_group' => $this->group, + ], + $fname + ) ); + }, + [ + 'checkKeys' => [ $globalRulesKey ], + 'lockTSE' => 300, + 'version' => 1 + ] + ); + } + + /** + * Check the conditions of a single filter, and profile it if $this->executeMode is true + * + * @param stdClass $row + * @param bool $global + * @return bool + */ + protected function checkFilter( $row, $global = false ) { + $filterName = AbuseFilter::buildGlobalName( $row->af_id, $global ); + + $startConds = $this->parser->getCondCount(); + $startTime = microtime( true ); + $origExtraTime = AFComputedVariable::$profilingExtraTime; + + // Store the row somewhere convenient + AbuseFilter::cacheFilter( $filterName, $row ); + + $pattern = trim( $row->af_pattern ); + $this->parser->setFilter( $filterName ); + $result = $this->parser->checkConditions( $pattern, true, $filterName ); + + $actualExtra = AFComputedVariable::$profilingExtraTime - $origExtraTime; + $timeTaken = 1000 * ( microtime( true ) - $startTime - $actualExtra ); + $condsUsed = $this->parser->getCondCount() - $startConds; + + $this->profilingData[$filterName] = [ + 'time' => $timeTaken, + 'conds' => $condsUsed, + 'result' => $result + ]; + + return $result; + } + + /** + * @param array $result Result of the execution, as created in run() + * @param string[] $matchedFilters + * @param string[] $allFilters + */ + protected function profileExecution( array $result, array $matchedFilters, array $allFilters ) { + $this->checkResetProfiling( $allFilters ); + $this->recordRuntimeProfilingResult( + count( $allFilters ), + $result['condCount'], + $result['runtime'] + ); + $this->recordPerFilterProfiling( $result['profiling'] ); + $this->recordStats( $result['condCount'], $result['runtime'], (bool)$matchedFilters ); + } + + /** + * Check if profiling data for all filters is lesser than the limit. If not, delete it and + * also delete per-filter profiling for all filters. Note that we don't need to reset it for + * disabled filters too, as their profiling data will be reset upon re-enabling anyway. + * + * @param array $allFilters + */ + protected function checkResetProfiling( array $allFilters ) { + global $wgAbuseFilterProfileActionsCap; + + $profileKey = AbuseFilter::filterProfileGroupKey( $this->group ); + $stash = MediaWikiServices::getInstance()->getMainObjectStash(); + + $profile = $stash->get( $profileKey ); + $total = $profile['total'] ?? 0; + + if ( $total > $wgAbuseFilterProfileActionsCap ) { + $stash->delete( $profileKey ); + foreach ( $allFilters as $filter ) { + AbuseFilter::resetFilterProfile( $filter ); + } + } + } + + /** + * Record per-filter profiling, for all filters + * + * @param array $data Profiling data, as stored in $this->profilingData + * @phan-param array<string,array{time:float,conds:int,result:bool}> $data + */ + protected function recordPerFilterProfiling( array $data ) { + global $wgAbuseFilterSlowFilterRuntimeLimit; + + foreach ( $data as $filterName => $params ) { + list( $filterID, $global ) = AbuseFilter::splitGlobalName( $filterName ); + if ( !$global ) { + // @todo Maybe add a parameter to recordProfilingResult to record global filters + // data separately (in the foreign wiki) + $this->recordProfilingResult( $filterID, $params['time'], $params['conds'], $params['result'] ); + } + + if ( $params['time'] > $wgAbuseFilterSlowFilterRuntimeLimit ) { + $this->recordSlowFilter( $filterName, $params['time'], $params['conds'], $params['result'] ); + } + } + } + + /** + * Record per-filter profiling data + * + * @param int $filter + * @param float $time Time taken, in milliseconds + * @param int $conds + * @param bool $matched + */ + protected function recordProfilingResult( $filter, $time, $conds, $matched ) { + // Defer updates to avoid massive (~1 second) edit time increases + DeferredUpdates::addCallableUpdate( function () use ( $filter, $time, $conds, $matched ) { + $stash = MediaWikiServices::getInstance()->getMainObjectStash(); + $profileKey = AbuseFilter::filterProfileKey( $filter ); + $profile = $stash->get( $profileKey ); + + if ( $profile !== false ) { + // Number of observed executions of this filter + $profile['count']++; + if ( $matched ) { + // Number of observed matches of this filter + $profile['matches']++; + } + // Total time spent on this filter from all observed executions + $profile['total-time'] += $time; + // Total number of conditions for this filter from all executions + $profile['total-cond'] += $conds; + } else { + $profile = [ + 'count' => 1, + 'matches' => (int)$matched, + 'total-time' => $time, + 'total-cond' => $conds + ]; + } + // Note: It is important that all key information be stored together in a single + // memcache entry to avoid race conditions where competing Apache instances + // partially overwrite the stats. + $stash->set( $profileKey, $profile, 3600 ); + } ); + } + + /** + * Logs slow filter's runtime data for later analysis + * + * @param string $filterId + * @param float $runtime + * @param int $totalConditions + * @param bool $matched + */ + protected function recordSlowFilter( $filterId, $runtime, $totalConditions, $matched ) { + $logger = LoggerFactory::getInstance( 'AbuseFilter' ); + $logger->info( + 'Edit filter {filter_id} on {wiki} is taking longer than expected', + [ + 'wiki' => WikiMap::getCurrentWikiDbDomain()->getId(), + 'filter_id' => $filterId, + 'title' => $this->title->getPrefixedText(), + 'runtime' => $runtime, + 'matched' => $matched, + 'total_conditions' => $totalConditions + ] + ); + } + + /** + * Update global statistics + * + * @param int $condsUsed The amount of used conditions + * @param float $totalTime Time taken, in milliseconds + * @param bool $anyMatch Whether at least one filter matched the action + */ + protected function recordStats( $condsUsed, $totalTime, $anyMatch ) { + $profileKey = AbuseFilter::filterProfileGroupKey( $this->group ); + $stash = MediaWikiServices::getInstance()->getMainObjectStash(); + + // Note: All related data is stored in a single memcache entry and updated via merge() + // to avoid race conditions where partial updates on competing instances corrupt the data. + $stash->merge( + $profileKey, + function ( $cache, $key, $profile ) use ( $condsUsed, $totalTime, $anyMatch ) { + global $wgAbuseFilterConditionLimit; + + if ( $profile === false ) { + $profile = [ + // Total number of actions observed + 'total' => 0, + // Number of actions ending by exceeding condition limit + 'overflow' => 0, + // Total time of execution of all observed actions + 'total-time' => 0, + // Total number of conditions from all observed actions + 'total-cond' => 0, + // Total number of filters matched + 'matches' => 0 + ]; + } + + $profile['total']++; + $profile['total-time'] += $totalTime; + $profile['total-cond'] += $condsUsed; + + // Increment overflow counter, if our condition limit overflowed + if ( $condsUsed > $wgAbuseFilterConditionLimit ) { + $profile['overflow']++; + } + + // Increment counter by 1 if there was at least one match + if ( $anyMatch ) { + $profile['matches']++; + } + + return $profile; + }, + AbuseFilter::$statsStoragePeriod + ); + } + + /** + * Record runtime profiling data for all filters together + * + * @param int $totalFilters + * @param int $totalConditions + * @param float $runtime + */ + protected function recordRuntimeProfilingResult( $totalFilters, $totalConditions, $runtime ) { + $keyPrefix = 'abusefilter.runtime-profile.' . WikiMap::getCurrentWikiDbDomain()->getId() . '.'; + + $statsd = MediaWikiServices::getInstance()->getStatsdDataFactory(); + $statsd->timing( $keyPrefix . 'runtime', $runtime ); + $statsd->timing( $keyPrefix . 'total_filters', $totalFilters ); + $statsd->timing( $keyPrefix . 'total_conditions', $totalConditions ); + } + + /** + * Executes a set of actions. + * + * @param string[] $filters + * @return Status returns the operation's status. $status->isOK() will return true if + * there were no actions taken, false otherwise. $status->getValue() will return + * an array listing the actions taken. $status->getErrors() etc. will provide + * the errors and warnings to be shown to the user to explain the actions. + */ + protected function executeFilterActions( array $filters ) : Status { + global $wgMainCacheType, $wgAbuseFilterDisallowGlobalLocalBlocks, $wgAbuseFilterRestrictions, + $wgAbuseFilterBlockDuration, $wgAbuseFilterAnonBlockDuration; + + $actionsByFilter = AbuseFilter::getConsequencesForFilters( $filters ); + $actionsTaken = array_fill_keys( $filters, [] ); + + $messages = []; + // Accumulator to track max block to issue + $maxExpiry = -1; + + foreach ( $actionsByFilter as $filter => $actions ) { + // Special-case handling for warnings. + $filterPublicComments = AbuseFilter::getFilter( $filter )->af_public_comments; + + $isGlobalFilter = AbuseFilter::splitGlobalName( $filter )[1]; + + // If the filter has "throttle" enabled and throttling is available via object + // caching, check to see if the user has hit the throttle. + if ( !empty( $actions['throttle'] ) && $wgMainCacheType !== CACHE_NONE ) { + $parameters = $actions['throttle']['parameters']; + $throttleId = array_shift( $parameters ); + list( $rateCount, $ratePeriod ) = explode( ',', array_shift( $parameters ) ); + $rateCount = (int)$rateCount; + $ratePeriod = (int)$ratePeriod; + + $hitThrottle = false; + + // The rest are throttle-types. + foreach ( $parameters as $throttleType ) { + $hitThrottle = $hitThrottle || $this->isThrottled( + $throttleId, $throttleType, $rateCount, $ratePeriod, $isGlobalFilter ); + } + + unset( $actions['throttle'] ); + if ( !$hitThrottle ) { + $actionsTaken[$filter][] = 'throttle'; + continue; + } + } + + if ( $wgAbuseFilterDisallowGlobalLocalBlocks && $isGlobalFilter ) { + $actions = array_diff_key( $actions, array_filter( $wgAbuseFilterRestrictions ) ); + } + + if ( !empty( $actions['warn'] ) ) { + $parameters = $actions['warn']['parameters']; + // Generate a unique key to determine whether the user has already been warned. + // We'll warn again if one of these changes: session, page, triggered filter or action + $warnKey = 'abusefilter-warned-' . md5( $this->title->getPrefixedText() ) . + '-' . $filter . '-' . $this->action; + + // Make sure the session is started prior to using it + $session = SessionManager::getGlobalSession(); + $session->persist(); + + if ( !isset( $session[$warnKey] ) || !$session[$warnKey] ) { + $session[$warnKey] = true; + + $msg = $parameters[0] ?? 'abusefilter-warning'; + $messages[] = [ $msg, $filterPublicComments, $filter ]; + + $actionsTaken[$filter][] = 'warn'; + + // Don't do anything else. + continue; + } else { + // We already warned them + $session[$warnKey] = false; + } + + unset( $actions['warn'] ); + } + + // Prevent double warnings + if ( count( array_intersect_key( $actions, array_filter( $wgAbuseFilterRestrictions ) ) ) > 0 && + !empty( $actions['disallow'] ) + ) { + unset( $actions['disallow'] ); + } + + // Find out the max expiry to issue the longest triggered block. + // Need to check here since methods like user->getBlock() aren't available + if ( !empty( $actions['block'] ) ) { + $parameters = $actions['block']['parameters']; + + if ( count( $parameters ) === 3 ) { + // New type of filters with custom block + if ( $this->user->isAnon() ) { + $expiry = $parameters[1]; + } else { + $expiry = $parameters[2]; + } + } else { + // Old type with fixed expiry + if ( $this->user->isAnon() && $wgAbuseFilterAnonBlockDuration !== null ) { + // The user isn't logged in and the anon block duration + // doesn't default to $wgAbuseFilterBlockDuration. + $expiry = $wgAbuseFilterAnonBlockDuration; + } else { + $expiry = $wgAbuseFilterBlockDuration; + } + } + + $currentExpiry = SpecialBlock::parseExpiryInput( $expiry ); + if ( $maxExpiry === -1 || $currentExpiry > SpecialBlock::parseExpiryInput( $maxExpiry ) ) { + // Save the parameters to issue the block with + $maxExpiry = $expiry; + $blockValues = [ + AbuseFilter::getFilter( $filter )->af_public_comments, + $filter, + is_array( $parameters ) && in_array( 'blocktalk', $parameters ) + ]; + } + unset( $actions['block'] ); + } + + // Do the rest of the actions + foreach ( $actions as $action => $info ) { + $newMsg = $this->takeConsequenceAction( + $action, + // @phan-suppress-next-line PhanTypeArraySuspiciousNullable False positive + $info['parameters'], + AbuseFilter::getFilter( $filter )->af_public_comments, + $filter + ); + + if ( $newMsg !== null ) { + $messages[] = $newMsg; + } + $actionsTaken[$filter][] = $action; + } + } + + // Since every filter has been analysed, we now know what the + // longest block duration is, so we can issue the block if + // maxExpiry has been changed. + if ( $maxExpiry !== -1 ) { + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable + $this->doBlock( $blockValues[0], $blockValues[1], $maxExpiry, $blockValues[2] ); + $message = [ + 'abusefilter-blocked-display', + $blockValues[0], + $blockValues[1] + ]; + // Manually add the message. If we're here, there is one. + $messages[] = $message; + // @phan-suppress-next-line PhanTypeMismatchDimAssignment + $actionsTaken[$blockValues[1]][] = 'block'; + } + + return $this->buildStatus( $actionsTaken, $messages ); + } + + /** + * @param string $throttleId + * @param string $types + * @param int $rateCount + * @param int $ratePeriod + * @param bool $global + * @return bool + */ + protected function isThrottled( + $throttleId, + $types, + int $rateCount, + int $ratePeriod, + $global = false + ) { + $stash = MediaWikiServices::getInstance()->getMainObjectStash(); + $key = $this->throttleKey( $throttleId, $types, $global ); + $count = (int)$stash->get( $key ); + + $logger = LoggerFactory::getInstance( 'AbuseFilter' ); + $logger->debug( "Got value $count for throttle key $key" ); + + $count = $stash->incrWithInit( $key, $ratePeriod ); + + if ( $count > $rateCount ) { + $logger->debug( "Throttle $key hit value $count -- maximum is $rateCount." ); + return true; + } + $logger->debug( "Throttle $key not hit!" ); + return false; + } + + /** + * @param string $throttleId + * @param string $type + * @param bool $global + * @return string + */ + protected function throttleKey( $throttleId, $type, $global = false ) { + global $wgAbuseFilterIsCentral, $wgAbuseFilterCentralDB; + + $types = explode( ',', $type ); + + $identifiers = []; + + foreach ( $types as $subtype ) { + $identifiers[] = $this->throttleIdentifier( $subtype ); + } + + $identifier = sha1( implode( ':', $identifiers ) ); + + $cache = MediaWikiServices::getInstance()->getMainWANObjectCache(); + if ( $global && !$wgAbuseFilterIsCentral ) { + return $cache->makeGlobalKey( + 'abusefilter', 'throttle', $wgAbuseFilterCentralDB, $throttleId, $type, $identifier + ); + } + + return $cache->makeKey( 'abusefilter', 'throttle', $throttleId, $type, $identifier ); + } + + /** + * @param string $type + * @return int|string + */ + protected function throttleIdentifier( $type ) { + $request = RequestContext::getMain()->getRequest(); + + switch ( $type ) { + case 'ip': + $identifier = $request->getIP(); + break; + case 'user': + $identifier = $this->user->getId(); + break; + case 'range': + $identifier = substr( IPUtils::toHex( $request->getIP() ), 0, 4 ); + break; + case 'creationdate': + $reg = (int)$this->user->getRegistration(); + $identifier = $reg - ( $reg % 86400 ); + break; + case 'editcount': + // Hack for detecting different single-purpose accounts. + $identifier = (int)$this->user->getEditCount(); + break; + case 'site': + $identifier = 1; + break; + case 'page': + $identifier = $this->title->getPrefixedText(); + break; + default: + // Should never happen + // @codeCoverageIgnoreStart + $identifier = 0; + // @codeCoverageIgnoreEnd + } + + return $identifier; + } + + /** + * @param string $action + * @param array $parameters + * @param string $ruleDescription + * @param int|string $ruleNumber + * + * @return array|null a message describing the action that was taken, + * or null if no action was taken. The message is given as an array + * containing the message key followed by any message parameters. + */ + protected function takeConsequenceAction( $action, $parameters, $ruleDescription, $ruleNumber ) { + global $wgAbuseFilterCustomActionsHandlers, $wgAbuseFilterBlockAutopromoteDuration; + + $message = null; + + switch ( $action ) { + case 'disallow': + $msg = $parameters[0] ?? 'abusefilter-disallowed'; + $message = [ $msg, $ruleDescription, $ruleNumber ]; + break; + case 'rangeblock': + $this->doRangeBlock( $ruleDescription, $ruleNumber, '1 week' ); + + $message = [ + 'abusefilter-blocked-display', + $ruleDescription, + $ruleNumber + ]; + break; + case 'degroup': + if ( !$this->user->isAnon() ) { + // Pull the groups from the VariableHolder, so that they will always be computed. + // This allow us to pull the groups from the VariableHolder to undo the degroup + // via Special:AbuseFilter/revert. + $groups = $this->vars->getVar( 'user_groups', AbuseFilterVariableHolder::GET_LAX ); + if ( $groups->type !== AFPData::DARRAY ) { + // Somehow, the variable wasn't set + $groups = $this->user->getEffectiveGroups(); + $this->vars->setVar( 'user_groups', $groups ); + } else { + $groups = $groups->toNative(); + } + $this->vars->setVar( 'user_groups', $groups ); + + foreach ( $groups as $group ) { + $this->user->removeGroup( $group ); + } + + $message = [ + 'abusefilter-degrouped', + $ruleDescription, + $ruleNumber + ]; + + // Don't log it if there aren't any groups being removed! + if ( !count( $groups ) ) { + break; + } + + $logEntry = new ManualLogEntry( 'rights', 'rights' ); + $logEntry->setPerformer( AbuseFilter::getFilterUser() ); + $logEntry->setTarget( $this->user->getUserPage() ); + $logEntry->setComment( + wfMessage( + 'abusefilter-degroupreason', + $ruleDescription, + $ruleNumber + )->inContentLanguage()->text() + ); + $logEntry->setParameters( [ + '4::oldgroups' => $groups, + '5::newgroups' => [] + ] ); + $logEntry->publish( $logEntry->insert() ); + } + + break; + case 'blockautopromote': + if ( !$this->user->isAnon() ) { + $duration = $wgAbuseFilterBlockAutopromoteDuration * 86400; + $blocked = AbuseFilter::blockAutoPromote( + $this->user, + wfMessage( + 'abusefilter-blockautopromotereason', + $ruleDescription, + $ruleNumber + )->inContentLanguage()->text(), + $duration + ); + + if ( $blocked ) { + $message = [ + 'abusefilter-autopromote-blocked', + $ruleDescription, + $ruleNumber, + $duration + ]; + } else { + $logger = LoggerFactory::getInstance( 'AbuseFilter' ); + $logger->warning( + 'Cannot block autopromotion to {target}', + [ 'target' => $this->user->getName() ] + ); + } + } + break; + + case 'block': + // Do nothing, handled at the end of executeFilterActions. Here for completeness. + break; + + case 'tag': + // Mark with a tag on recentchanges. + $actionID = $this->getTaggingID(); + AbuseFilter::bufferTagsToSetByAction( [ $actionID => $parameters ] ); + break; + default: + if ( isset( $wgAbuseFilterCustomActionsHandlers[$action] ) ) { + $customFunction = $wgAbuseFilterCustomActionsHandlers[$action]; + if ( is_callable( $customFunction ) ) { + $msg = call_user_func( + $customFunction, + $action, + $parameters, + $this->title, + $this->vars, + $ruleDescription, + $ruleNumber + ); + } + if ( isset( $msg ) ) { + $message = [ $msg ]; + } + } else { + $logger = LoggerFactory::getInstance( 'AbuseFilter' ); + $logger->warning( "Unrecognised action $action" ); + } + } + + return $message; + } + + /** + * @param string $ruleDesc + * @param string|int $ruleNumber + * @param string $expiry + */ + private function doRangeBlock( $ruleDesc, $ruleNumber, $expiry ) { + global $wgAbuseFilterRangeBlockSize, $wgBlockCIDRLimit; + + $ip = RequestContext::getMain()->getRequest()->getIP(); + $type = IPUtils::isIPv6( $ip ) ? 'IPv6' : 'IPv4'; + $CIDRsize = max( $wgAbuseFilterRangeBlockSize[$type], $wgBlockCIDRLimit[$type] ); + $blockCIDR = $ip . '/' . $CIDRsize; + + $target = IPUtils::sanitizeRange( $blockCIDR ); + $autoblock = false; + $this->doBlockInternal( $ruleDesc, $ruleNumber, $target, $expiry, $autoblock, false ); + } + + /** + * @param string $ruleDesc + * @param string|int $ruleNumber + * @param string $expiry + * @param bool $preventsTalk + */ + private function doBlock( $ruleDesc, $ruleNumber, $expiry, $preventsTalk ) { + $target = $this->user->getName(); + $autoblock = true; + $this->doBlockInternal( $ruleDesc, $ruleNumber, $target, $expiry, $autoblock, $preventsTalk ); + } + + /** + * Perform a block by the AbuseFilter system user + * @param string $ruleDesc + * @param int|string $ruleNumber + * @param string $target + * @param string $expiry + * @param bool $isAutoBlock + * @param bool $preventEditOwnUserTalk + */ + private function doBlockInternal( + $ruleDesc, + $ruleNumber, + $target, + $expiry, + $isAutoBlock, + $preventEditOwnUserTalk + ) { + $filterUser = AbuseFilter::getFilterUser(); + $reason = wfMessage( + 'abusefilter-blockreason', + $ruleDesc, $ruleNumber + )->inContentLanguage()->text(); + + $block = new DatabaseBlock(); + $block->setTarget( $target ); + $block->setBlocker( $filterUser ); + $block->setReason( $reason ); + $block->isHardblock( false ); + $block->isAutoblocking( $isAutoBlock ); + $block->isCreateAccountBlocked( true ); + $block->isUsertalkEditAllowed( !$preventEditOwnUserTalk ); + $block->setExpiry( SpecialBlock::parseExpiryInput( $expiry ) ); + + $success = $block->insert(); + + if ( $success ) { + // Log it only if the block was successful + $logParams = []; + $logParams['5::duration'] = ( $block->getExpiry() === 'infinity' ) + ? 'indefinite' + : $expiry; + $flags = [ 'nocreate' ]; + if ( !$block->isAutoblocking() && !IPUtils::isIPAddress( $target ) ) { + // Conditionally added same as SpecialBlock + $flags[] = 'noautoblock'; + } + if ( $preventEditOwnUserTalk === true ) { + $flags[] = 'nousertalk'; + } + $logParams['6::flags'] = implode( ',', $flags ); + + $logEntry = new ManualLogEntry( 'block', 'block' ); + $logEntry->setTarget( Title::makeTitle( NS_USER, $target ) ); + $logEntry->setComment( $reason ); + $logEntry->setPerformer( $filterUser ); + $logEntry->setParameters( $logParams ); + $blockIds = array_merge( [ $success['id'] ], $success['autoIds'] ); + $logEntry->setRelations( [ 'ipb_id' => $blockIds ] ); + $logEntry->publish( $logEntry->insert() ); + } + } + + /** + * Constructs a Status object as returned by executeFilterActions() from the list of + * actions taken and the corresponding list of messages. + * + * @param array[] $actionsTaken associative array mapping each filter to the list if + * actions taken because of that filter. + * @param array[] $messages a list of arrays, where each array contains a message key + * followed by any message parameters. + * + * @return Status + */ + protected function buildStatus( array $actionsTaken, array $messages ) : Status { + $status = Status::newGood( $actionsTaken ); + + foreach ( $messages as $msg ) { + $status->fatal( ...$msg ); + } + + return $status; + } + + /** + * Creates a template to use for logging taken actions + * + * @return array + */ + protected function buildLogTemplate() : array { + global $wgAbuseFilterLogIP; + + $request = RequestContext::getMain()->getRequest(); + // If $this->user isn't safe to load (e.g. a failure during + // AbortAutoAccount), create a dummy anonymous user instead. + $user = $this->user->isSafeToLoad() ? $this->user : new User; + // Create a template + $logTemplate = [ + 'afl_user' => $user->getId(), + 'afl_user_text' => $user->getName(), + 'afl_timestamp' => wfGetDB( DB_REPLICA )->timestamp(), + 'afl_namespace' => $this->title->getNamespace(), + 'afl_title' => $this->title->getDBkey(), + 'afl_action' => $this->action, + 'afl_ip' => $wgAbuseFilterLogIP ? $request->getIP() : '' + ]; + // Hack to avoid revealing IPs of people creating accounts + if ( + !$user->getId() && + ( $this->action === 'createaccount' || $this->action === 'autocreateaccount' ) + ) { + $logTemplate['afl_user_text'] = $this->vars->getVar( 'accountname' )->toString(); + } + return $logTemplate; + } + + /** + * Create and publish log entries for taken actions + * + * @param array[] $actionsTaken + * @todo Split this method + */ + protected function addLogEntries( array $actionsTaken ) { + $dbw = wfGetDB( DB_MASTER ); + $logTemplate = $this->buildLogTemplate(); + $centralLogTemplate = [ + 'afl_wiki' => WikiMap::getCurrentWikiDbDomain()->getId(), + ]; + + $logRows = []; + $centralLogRows = []; + $loggedLocalFilters = []; + $loggedGlobalFilters = []; + + foreach ( $actionsTaken as $filter => $actions ) { + list( $filterID, $global ) = AbuseFilter::splitGlobalName( $filter ); + $thisLog = $logTemplate; + $thisLog['afl_filter'] = $filter; + $thisLog['afl_actions'] = implode( ',', $actions ); + + // Don't log if we were only throttling. + if ( $thisLog['afl_actions'] !== 'throttle' ) { + $logRows[] = $thisLog; + // Global logging + if ( $global ) { + $centralLog = $thisLog + $centralLogTemplate; + $centralLog['afl_filter'] = $filterID; + $centralLog['afl_title'] = $this->title->getPrefixedText(); + $centralLog['afl_namespace'] = 0; + + $centralLogRows[] = $centralLog; + $loggedGlobalFilters[] = $filterID; + } else { + $loggedLocalFilters[] = $filter; + } + } + } + + if ( !count( $logRows ) ) { + return; + } + + // Only store the var dump if we're actually going to add log rows. + $varDump = AbuseFilter::storeVarDump( $this->vars ); + $varDump = "tt:$varDump"; + + $localLogIDs = []; + global $wgAbuseFilterNotifications, $wgAbuseFilterNotificationsPrivate; + foreach ( $logRows as $data ) { + $data['afl_var_dump'] = $varDump; + $dbw->insert( 'abuse_filter_log', $data, __METHOD__ ); + $localLogIDs[] = $data['afl_id'] = $dbw->insertId(); + // Give grep a chance to find the usages: + // logentry-abusefilter-hit + $entry = new ManualLogEntry( 'abusefilter', 'hit' ); + // Construct a user object + $user = User::newFromId( $data['afl_user'] ); + $user->setName( $data['afl_user_text'] ); + $entry->setPerformer( $user ); + $entry->setTarget( $this->title ); + // Additional info + $entry->setParameters( [ + 'action' => $data['afl_action'], + 'filter' => $data['afl_filter'], + 'actions' => $data['afl_actions'], + 'log' => $data['afl_id'], + ] ); + + // Send data to CheckUser if installed and we + // aren't already sending a notification to recentchanges + if ( ExtensionRegistry::getInstance()->isLoaded( 'CheckUser' ) + && strpos( $wgAbuseFilterNotifications, 'rc' ) === false + ) { + global $wgCheckUserLogAdditionalRights; + $wgCheckUserLogAdditionalRights[] = 'abusefilter-view'; + $rc = $entry->getRecentChange(); + CheckUserHooks::updateCheckUserData( $rc ); + } + + if ( $wgAbuseFilterNotifications !== false ) { + list( $filterID, $global ) = AbuseFilter::splitGlobalName( $data['afl_filter'] ); + if ( AbuseFilter::filterHidden( $filterID, $global ) && !$wgAbuseFilterNotificationsPrivate ) { + continue; + } + $this->publishEntry( $dbw, $entry, $wgAbuseFilterNotifications ); + } + } + + $method = __METHOD__; + + if ( count( $loggedLocalFilters ) ) { + // Update hit-counter. + $dbw->onTransactionPreCommitOrIdle( + function () use ( $dbw, $loggedLocalFilters, $method ) { + $dbw->update( 'abuse_filter', + [ 'af_hit_count=af_hit_count+1' ], + [ 'af_id' => $loggedLocalFilters ], + $method + ); + }, + $method + ); + } + + $globalLogIDs = []; + + // Global stuff + if ( count( $loggedGlobalFilters ) ) { + $this->vars->computeDBVars(); + $globalVarDump = AbuseFilter::storeVarDump( $this->vars, true ); + $globalVarDump = "tt:$globalVarDump"; + foreach ( $centralLogRows as $index => $data ) { + $centralLogRows[$index]['afl_var_dump'] = $globalVarDump; + } + + $fdb = AbuseFilter::getCentralDB( DB_MASTER ); + + foreach ( $centralLogRows as $row ) { + $fdb->insert( 'abuse_filter_log', $row, __METHOD__ ); + $globalLogIDs[] = $fdb->insertId(); + } + + $fdb->onTransactionPreCommitOrIdle( + function () use ( $fdb, $loggedGlobalFilters, $method ) { + $fdb->update( 'abuse_filter', + [ 'af_hit_count=af_hit_count+1' ], + [ 'af_id' => $loggedGlobalFilters ], + $method + ); + }, + $method + ); + } + + AbuseFilter::$logIds[ $this->title->getPrefixedText() ] = [ + 'local' => $localLogIDs, + 'global' => $globalLogIDs + ]; + + $this->checkEmergencyDisable( $loggedLocalFilters ); + } + + /** + * Like LogEntry::publish, but doesn't require an ID (which we don't have) and skips the + * tagging part + * + * @param IDatabase $dbw To cancel the callback if the log insertion fails + * @param ManualLogEntry $entry + * @param string $to One of 'udp', 'rc' and 'rcandudp' + */ + private function publishEntry( IDatabase $dbw, ManualLogEntry $entry, $to ) { + DeferredUpdates::addCallableUpdate( + function () use ( $entry, $to ) { + $rc = $entry->getRecentChange(); + + if ( $to === 'rc' || $to === 'rcandudp' ) { + $rc->save( $rc::SEND_NONE ); + } + if ( $to === 'udp' || $to === 'rcandudp' ) { + $rc->notifyRCFeeds(); + } + }, + DeferredUpdates::POSTSEND, + $dbw + ); + } + + /** + * Determine whether a filter must be throttled, i.e. its potentially dangerous + * actions must be disabled. + * + * @param string[] $filters The filters to check + */ + protected function checkEmergencyDisable( array $filters ) { + $stash = MediaWikiServices::getInstance()->getMainObjectStash(); + // @ToDo this is an amount between 1 and AbuseFilterProfileActionsCap, which means that the + // reliability of this number may strongly vary. We should instead use a fixed one. + $groupProfile = $stash->get( AbuseFilter::filterProfileGroupKey( $this->group ) ); + $totalActions = $groupProfile['total']; + + foreach ( $filters as $filter ) { + $threshold = AbuseFilter::getEmergencyValue( 'threshold', $this->group ); + $hitCountLimit = AbuseFilter::getEmergencyValue( 'count', $this->group ); + $maxAge = AbuseFilter::getEmergencyValue( 'age', $this->group ); + + $filterProfile = $stash->get( AbuseFilter::filterProfileKey( $filter ) ); + $matchCount = $filterProfile['matches'] ?? 1; + + // Figure out if the filter is subject to being throttled. + $filterAge = (int)wfTimestamp( TS_UNIX, AbuseFilter::getFilter( $filter )->af_timestamp ); + $exemptTime = $filterAge + $maxAge; + + if ( $totalActions && $exemptTime > time() && $matchCount > $hitCountLimit && + ( $matchCount / $totalActions ) > $threshold + ) { + // More than $wgAbuseFilterEmergencyDisableCount matches, constituting more than + // $threshold (a fraction) of last few edits. Disable it. + DeferredUpdates::addUpdate( + new AutoCommitUpdate( + wfGetDB( DB_MASTER ), + __METHOD__, + function ( IDatabase $dbw, $fname ) use ( $filter ) { + $dbw->update( + 'abuse_filter', + [ 'af_throttled' => 1 ], + [ 'af_id' => $filter ], + $fname + ); + } + ) + ); + } + } + } + + /** + * Helper function to get the ID used to identify an action for later tagging it. + * @return string + */ + protected function getTaggingID() { + if ( strpos( $this->action, 'createaccount' ) === false ) { + $username = $this->user->getName(); + $actionTitle = $this->title; + } else { + $username = $this->vars->getVar( 'accountname' )->toString(); + $actionTitle = Title::makeTitleSafe( NS_USER, $username ); + } + '@phan-var Title $actionTitle'; + + return AbuseFilter::getTaggingActionId( $this->action, $actionTitle, $username ); + } +} diff --git a/AbuseFilter/includes/AbuseFilterServices.php b/AbuseFilter/includes/AbuseFilterServices.php new file mode 100644 index 00000000..a028c5aa --- /dev/null +++ b/AbuseFilter/includes/AbuseFilterServices.php @@ -0,0 +1,15 @@ +<?php + +namespace MediaWiki\Extension\AbuseFilter; + +use MediaWiki\MediaWikiServices; + +class AbuseFilterServices { + /** + * Conveniency wrapper for strong typing + * @return KeywordsManager + */ + public static function getKeywordsManager() : KeywordsManager { + return MediaWikiServices::getInstance()->getService( KeywordsManager::SERVICE_NAME ); + } +} diff --git a/AbuseFilter/includes/AbuseFilterVariableHolder.php b/AbuseFilter/includes/AbuseFilterVariableHolder.php index 498c7b4e..e8dfd2fd 100644 --- a/AbuseFilter/includes/AbuseFilterVariableHolder.php +++ b/AbuseFilter/includes/AbuseFilterVariableHolder.php @@ -1,21 +1,80 @@ <?php +use MediaWiki\Extension\AbuseFilter\AbuseFilterServices; +use MediaWiki\Extension\AbuseFilter\KeywordsManager; +use Psr\Log\LoggerInterface; + class AbuseFilterVariableHolder { - /** @var (AFPData|AFComputedVariable)[] */ + /** + * Used in self::getVar() to determine what to do if the requested variable is missing. See + * the docs of that method for an explanation. + */ + public const GET_LAX = 0; + public const GET_STRICT = 1; + public const GET_BC = 2; + + /** @var KeywordsManager */ + private $keywordsManager; + + /** @var LoggerInterface */ + private $logger; + + /** + * @var (AFPData|AFComputedVariable)[] + * @fixme This should be private, but it isn't because of T231542: there are serialized instances + * stored in the DB, and mVars wouldn't be available in HHVM after deserializing them (T213006) + */ public $mVars = []; - /** @var string[] Variables used to store meta-data, we'd better be safe. See T191715 */ - public static $varBlacklist = [ 'context', 'global_log_ids', 'local_log_ids' ]; + /** @var bool Whether this object is being used for an ongoing action being filtered */ + public $forFilter = false; + + /** + * @param KeywordsManager|null $keywordsManager Optional for BC + */ + public function __construct( KeywordsManager $keywordsManager = null ) { + $this->keywordsManager = $keywordsManager ?? AbuseFilterServices::getKeywordsManager(); + // Avoid injecting a Logger, as it's just temporary + $this->logger = new Psr\Log\NullLogger(); + } - /** @var int 2 is the default and means that new variables names (from T173889) should be used. - * 1 means that the old ones should be used, e.g. if this object is constructed from an - * afl_var_dump which still bears old variables. + /** + * @param LoggerInterface $logger + */ + public function setLogger( LoggerInterface $logger ) { + $this->logger = $logger; + } + + /** + * Utility function to translate an array with shape [ varname => value ] into a self instance + * + * @param array $vars + * @param KeywordsManager|null $keywordsManager Optional for BC + * @return AbuseFilterVariableHolder */ - public $mVarsVersion = 2; + public static function newFromArray( + array $vars, + KeywordsManager $keywordsManager = null + ) : AbuseFilterVariableHolder { + $ret = new self( $keywordsManager ); + foreach ( $vars as $var => $value ) { + $ret->setVar( $var, $value ); + } + return $ret; + } - public function __construct() { - // Backwards-compatibility (unused now) - $this->setVar( 'minor_edit', false ); + /** + * Checks whether any deprecated variable is stored with the old name, and replaces it with + * the new name. This should normally only happen when a DB dump is retrieved from the DB. + */ + public function translateDeprecatedVars() : void { + $deprecatedVars = $this->keywordsManager->getDeprecatedVariables(); + foreach ( $this->mVars as $name => $value ) { + if ( array_key_exists( $name, $deprecatedVars ) ) { + $this->mVars[ $deprecatedVars[$name] ] = $value; + unset( $this->mVars[$name] ); + } + } } /** @@ -32,83 +91,107 @@ class AbuseFilterVariableHolder { } /** + * Get all variables stored in this object + * + * @return (AFPData|AFComputedVariable)[] + */ + public function getVars() { + return $this->mVars; + } + + /** + * Get a lazy loader for a variable. This method is here for testing ease + * @param string $method + * @param array $parameters + * @return AFComputedVariable + */ + public function getLazyLoader( $method, $parameters ) { + return new AFComputedVariable( $method, $parameters ); + } + + /** * @param string $variable * @param string $method * @param array $parameters */ public function setLazyLoadVar( $variable, $method, $parameters ) { - $placeholder = new AFComputedVariable( $method, $parameters ); + $placeholder = $this->getLazyLoader( $method, $parameters ); $this->setVar( $variable, $placeholder ); } /** * Get a variable from the current object * - * @param string $variable + * @param string $varName The variable name + * @param int $mode One of the self::GET_* constants, determines how to behave when the variable is unset: + * - GET_STRICT -> In the future, this will throw an exception. For now it returns a DUNDEFINED and logs a warning + * - GET_LAX -> Return a DUNDEFINED AFPData + * - GET_BC -> Return a DNULL AFPData (this should only be used for BC, see T230256) + * @param string|null $tempFilter Filter ID, if available; only used for debugging (temporarily) * @return AFPData */ - public function getVar( $variable ) { - $variable = strtolower( $variable ); - if ( $this->mVarsVersion === 1 && in_array( $variable, AbuseFilter::getDeprecatedVariables() ) ) { - // Variables are stored with old names, but the parser has given us - // a new name. Translate it back. - $variable = array_search( $variable, AbuseFilter::getDeprecatedVariables() ); - } - if ( isset( $this->mVars[$variable] ) ) { - if ( $this->mVars[$variable] instanceof AFComputedVariable ) { - /** @suppress PhanUndeclaredMethod False positive */ - $value = $this->mVars[$variable]->compute( $this ); - $this->setVar( $variable, $value ); + public function getVar( $varName, $mode = self::GET_STRICT, $tempFilter = null ) : AFPData { + $varName = strtolower( $varName ); + if ( $this->varIsSet( $varName ) ) { + /** @var $variable AFComputedVariable|AFPData */ + $variable = $this->mVars[$varName]; + if ( $variable instanceof AFComputedVariable ) { + $value = $variable->compute( $this ); + $this->setVar( $varName, $value ); return $value; - } elseif ( $this->mVars[$variable] instanceof AFPData ) { - return $this->mVars[$variable]; + } elseif ( $variable instanceof AFPData ) { + return $variable; + } else { + throw new UnexpectedValueException( + "Variable $varName has unexpected type " . gettype( $variable ) + ); } } - return new AFPData(); - } - - /** - * @return AbuseFilterVariableHolder - */ - public static function merge() { - $newHolder = new AbuseFilterVariableHolder; - $newHolder->addHolders( ...func_get_args() ); - return $newHolder; + // The variable is not set. + switch ( $mode ) { + case self::GET_STRICT: + $this->logger->warning( + __METHOD__ . ": requested unset variable {varname} in strict mode, filter: {filter}", + [ + 'varname' => $varName, + 'exception' => new RuntimeException(), + 'filter' => $tempFilter ?? 'unavailable' + ] + ); + // @todo change the line below to throw an exception in a future MW version + return new AFPData( AFPData::DUNDEFINED ); + case self::GET_LAX: + return new AFPData( AFPData::DUNDEFINED ); + case self::GET_BC: + // Old behaviour, which can sometimes lead to unexpected results (e.g. + // `edit_delta < -5000` will match any non-edit action). + return new AFPData( AFPData::DNULL ); + default: + throw new LogicException( "Mode '$mode' not recognized." ); + } } /** * Merge any number of holders given as arguments into this holder. * - * @throws MWException + * @param AbuseFilterVariableHolder ...$holders */ - public function addHolders() { - $holders = func_get_args(); - + public function addHolders( AbuseFilterVariableHolder ...$holders ) { foreach ( $holders as $addHolder ) { - if ( !is_object( $addHolder ) ) { - throw new MWException( 'Invalid argument to AbuseFilterVariableHolder::addHolders' ); - } $this->mVars = array_merge( $this->mVars, $addHolder->mVars ); } } - public function __wakeup() { - // Reset the context. - $this->setVar( 'context', 'stored' ); - } - /** - * Export all variables stored in this object as string + * Export all variables stored in this object with their native (PHP) types. * - * @return string[] + * @return array */ public function exportAllVars() { $exported = []; foreach ( array_keys( $this->mVars ) as $varName ) { - if ( !in_array( $varName, self::$varBlacklist ) ) { - $exported[$varName] = $this->getVar( $varName )->toString(); - } + $exported[ $varName ] = $this->getVar( $varName )->toNative(); } return $exported; @@ -122,10 +205,7 @@ class AbuseFilterVariableHolder { public function exportNonLazyVars() { $exported = []; foreach ( $this->mVars as $varName => $data ) { - if ( - !( $data instanceof AFComputedVariable ) - && !in_array( $varName, self::$varBlacklist ) - ) { + if ( !( $data instanceof AFComputedVariable ) ) { $exported[$varName] = $this->getVar( $varName )->toString(); } } @@ -144,51 +224,25 @@ class AbuseFilterVariableHolder { * @return array */ public function dumpAllVars( $compute = [], $includeUserVars = false ) { - $allVarNames = array_keys( $this->mVars ); - $exported = []; $coreVariables = []; if ( !$includeUserVars ) { // Compile a list of all variables set by the extension to be able // to filter user set ones by name - global $wgRestrictionTypes; - - $coreVariables = AbuseFilter::getBuilderValues(); - $coreVariables = array_keys( $coreVariables['vars'] ); - $deprecatedVariables = array_keys( AbuseFilter::getDeprecatedVariables() ); - $coreVariables = array_merge( $coreVariables, $deprecatedVariables ); - - // Title vars can have several prefixes - $prefixes = [ 'MOVED_FROM', 'MOVED_TO', 'PAGE' ]; - $titleVars = [ - '_ID', - '_NAMESPACE', - '_TITLE', - '_PREFIXEDTITLE', - '_recent_contributors', - '_age', - ]; - foreach ( $wgRestrictionTypes as $action ) { - $titleVars[] = "_restrictions_$action"; - } - - foreach ( $titleVars as $var ) { - foreach ( $prefixes as $prefix ) { - $coreVariables[] = $prefix . $var; - } - } + $activeVariables = array_keys( $this->keywordsManager->getVarsMappings() ); + $deprecatedVariables = array_keys( $this->keywordsManager->getDeprecatedVariables() ); + $disabledVariables = array_keys( $this->keywordsManager->getDisabledVariables() ); + $coreVariables = array_merge( $activeVariables, $deprecatedVariables, $disabledVariables ); $coreVariables = array_map( 'strtolower', $coreVariables ); } - foreach ( $allVarNames as $varName ) { + $exported = []; + foreach ( array_keys( $this->mVars ) as $varName ) { + $computeThis = ( is_array( $compute ) && in_array( $varName, $compute ) ) || $compute === true; if ( ( $includeUserVars || in_array( strtolower( $varName ), $coreVariables ) ) && // Only include variables set in the extension in case $includeUserVars is false - !in_array( $varName, self::$varBlacklist ) && - ( $compute === true || - ( is_array( $compute ) && in_array( $varName, $compute ) ) || - $this->mVars[$varName] instanceof AFPData - ) + ( $computeThis || $this->mVars[$varName] instanceof AFPData ) ) { $exported[$varName] = $this->getVar( $varName )->toNative(); } @@ -208,9 +262,6 @@ class AbuseFilterVariableHolder { /** * Compute all vars which need DB access. Useful for vars which are going to be saved * cross-wiki or used for offline analysis. - * - * @suppress PhanUndeclaredProperty for $value->mMethod (phan thinks $value is always AFPData) - * @suppress PhanUndeclaredMethod for $value->compute (phan thinks $value is always AFPData) */ public function computeDBVars() { static $dbTypes = [ @@ -226,13 +277,23 @@ class AbuseFilterVariableHolder { 'revision-text-by-timestamp' ]; - foreach ( $this->mVars as $name => $value ) { - if ( $value instanceof AFComputedVariable && - in_array( $value->mMethod, $dbTypes ) - ) { + /** @var AFComputedVariable[] $missingVars */ + $missingVars = array_filter( $this->mVars, function ( $el ) { + return ( $el instanceof AFComputedVariable ); + } ); + foreach ( $missingVars as $name => $value ) { + if ( in_array( $value->mMethod, $dbTypes ) ) { $value = $value->compute( $this ); $this->setVar( $name, $value ); } } } + + /** + * @fixme Back-compat hack for old objects serialized and stored in the DB. + * Remove this once T213006 is done. + */ + public function __wakeup() { + $this->keywordsManager = AbuseFilterServices::getKeywordsManager(); + } } diff --git a/AbuseFilter/includes/AbuseLogHitFormatter.php b/AbuseFilter/includes/AbuseLogHitFormatter.php index a2fbb284..5bdb7878 100644 --- a/AbuseFilter/includes/AbuseLogHitFormatter.php +++ b/AbuseFilter/includes/AbuseLogHitFormatter.php @@ -1,7 +1,5 @@ <?php -use MediaWiki\MediaWikiServices; - /** * This class formats abuse log notifications. * @@ -14,7 +12,7 @@ class AbuseLogHitFormatter extends LogFormatter { */ protected function getMessageParameters() { $entry = $this->entry->getParameters(); - $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer(); + $linkRenderer = $this->getLinkRenderer(); $params = parent::getMessageParameters(); $filter_title = SpecialPage::getTitleFor( 'AbuseFilter', $entry['filter'] ); @@ -40,19 +38,19 @@ class AbuseLogHitFormatter extends LogFormatter { ) ); } - $actions_taken = $entry['actions']; - if ( !strlen( trim( $actions_taken ) ) ) { + $actions_takenRaw = $entry['actions']; + if ( !strlen( trim( $actions_takenRaw ) ) ) { $actions_taken = $this->msg( 'abusefilter-log-noactions' ); } else { - $actions = explode( ',', $actions_taken ); + $actions = explode( ',', $actions_takenRaw ); $displayActions = []; foreach ( $actions as $action ) { - $displayActions[] = AbuseFilter::getActionDisplay( $action ); + $displayActions[] = AbuseFilter::getActionDisplay( $action, $this->context ); } $actions_taken = $this->context->getLanguage()->commaList( $displayActions ); } - $params[5] = $actions_taken; + $params[5] = Message::rawParam( $actions_taken ); // Bad things happen if the numbers are not in correct order ksort( $params ); diff --git a/AbuseFilter/includes/Hooks/AbuseFilterAlterVariablesHook.php b/AbuseFilter/includes/Hooks/AbuseFilterAlterVariablesHook.php new file mode 100644 index 00000000..b8307c6e --- /dev/null +++ b/AbuseFilter/includes/Hooks/AbuseFilterAlterVariablesHook.php @@ -0,0 +1,27 @@ +<?php + +namespace MediaWiki\Extension\AbuseFilter\Hooks; + +use AbuseFilterVariableHolder; +use Title; +use User; + +interface AbuseFilterAlterVariablesHook { + /** + * Hook runner for the `AbuseFilterAlterVariables` hook + * + * Allows overwriting of abusefilter variables just before they're + * checked against filters. Note that you may specify custom variables in a saner way using other hooks: + * AbuseFilter-generateTitleVars, AbuseFilter-generateUserVars and AbuseFilter-generateGenericVars. + * + * @param AbuseFilterVariableHolder &$vars + * @param Title $title Title object target of the action + * @param User $user User object performer of the action + * @return bool|void True or no return value to continue or false to abort + */ + public function onAbuseFilterAlterVariables( + AbuseFilterVariableHolder &$vars, + Title $title, + User $user + ); +} diff --git a/AbuseFilter/includes/Hooks/AbuseFilterBuilderHook.php b/AbuseFilter/includes/Hooks/AbuseFilterBuilderHook.php new file mode 100644 index 00000000..0354709b --- /dev/null +++ b/AbuseFilter/includes/Hooks/AbuseFilterBuilderHook.php @@ -0,0 +1,15 @@ +<?php + +namespace MediaWiki\Extension\AbuseFilter\Hooks; + +interface AbuseFilterBuilderHook { + /** + * Hook runner for the `AbuseFilter-builder` hook + * + * Allows overwriting of the builder values returned by AbuseFilter::getBuilderValues + * + * @param array &$realValues Builder values + * @return bool|void True or no return value to continue or false to abort + */ + public function onAbuseFilterBuilder( array &$realValues ); +} diff --git a/AbuseFilter/includes/Hooks/AbuseFilterComputeVariableHook.php b/AbuseFilter/includes/Hooks/AbuseFilterComputeVariableHook.php new file mode 100644 index 00000000..ef7a77ec --- /dev/null +++ b/AbuseFilter/includes/Hooks/AbuseFilterComputeVariableHook.php @@ -0,0 +1,26 @@ +<?php + +namespace MediaWiki\Extension\AbuseFilter\Hooks; + +use AbuseFilterVariableHolder; + +interface AbuseFilterComputeVariableHook { + /** + * Hook runner for the `AbuseFilter-computeVariable` hook + * + * Like AbuseFilter-interceptVariable but called if the requested method wasn't found. + * Return true to indicate that the method is known to the hook and was computed successful. + * + * @param string $method Method to generate the variable + * @param AbuseFilterVariableHolder $vars + * @param array $parameters Parameters with data to compute the value + * @param ?string &$result Result of the computation + * @return bool|void True or no return value to continue or false to abort + */ + public function onAbuseFilterComputeVariable( + string $method, + AbuseFilterVariableHolder $vars, + array $parameters, + ?string &$result + ); +} diff --git a/AbuseFilter/includes/Hooks/AbuseFilterContentToStringHook.php b/AbuseFilter/includes/Hooks/AbuseFilterContentToStringHook.php new file mode 100644 index 00000000..74ef1ee6 --- /dev/null +++ b/AbuseFilter/includes/Hooks/AbuseFilterContentToStringHook.php @@ -0,0 +1,23 @@ +<?php + +namespace MediaWiki\Extension\AbuseFilter\Hooks; + +use Content; + +interface AbuseFilterContentToStringHook { + /** + * Hook runner for the `AbuseFilter-contentToString` hook + * + * Called when converting a Content object to a string to which + * filters can be applied. If the hook function returns true, Content::getTextForSearchIndex() + * will be used for non-text content. + * + * @param Content $content + * @param ?string &$text + * @return bool|void True or no return value to continue or false to abort + */ + public function onAbuseFilterContentToString( + Content $content, + ?string &$text + ); +} diff --git a/AbuseFilter/includes/Hooks/AbuseFilterDeprecatedVariablesHook.php b/AbuseFilter/includes/Hooks/AbuseFilterDeprecatedVariablesHook.php new file mode 100644 index 00000000..98340d9e --- /dev/null +++ b/AbuseFilter/includes/Hooks/AbuseFilterDeprecatedVariablesHook.php @@ -0,0 +1,16 @@ +<?php + +namespace MediaWiki\Extension\AbuseFilter\Hooks; + +interface AbuseFilterDeprecatedVariablesHook { + /** + * Hook runner for the `AbuseFilter-deprecatedVariables` hook + * + * Allows adding deprecated variables. If a filter uses an old variable, the parser + * will automatically translate it to the new one. + * + * @param array &$deprecatedVariables deprecated variables, syntax: [ 'old_name' => 'new_name' ] + * @return bool|void True or no return value to continue or false to abort + */ + public function onAbuseFilterDeprecatedVariables( array &$deprecatedVariables ); +} diff --git a/AbuseFilter/includes/Hooks/AbuseFilterFilterActionHook.php b/AbuseFilter/includes/Hooks/AbuseFilterFilterActionHook.php new file mode 100644 index 00000000..655c06d5 --- /dev/null +++ b/AbuseFilter/includes/Hooks/AbuseFilterFilterActionHook.php @@ -0,0 +1,26 @@ +<?php + +namespace MediaWiki\Extension\AbuseFilter\Hooks; + +use AbuseFilterVariableHolder; +use Title; + +interface AbuseFilterFilterActionHook { + /** + * Hook runner for the `AbuseFilter-filterAction` hook + * + * DEPRECATED! Use AbuseFilterAlterVariables instead. + * + * Allows overwriting of abusefilter variables in AbuseFilter::filterAction just before they're + * checked against filters. Note that you may specify custom variables in a saner way using other hooks: + * AbuseFilter-generateTitleVars, AbuseFilter-generateUserVars and AbuseFilter-generateGenericVars. + * + * @param AbuseFilterVariableHolder &$vars + * @param Title $title + * @return bool|void True or no return value to continue or false to abort + */ + public function onAbuseFilterFilterAction( + AbuseFilterVariableHolder &$vars, + Title $title + ); +} diff --git a/AbuseFilter/includes/Hooks/AbuseFilterGenerateGenericVarsHook.php b/AbuseFilter/includes/Hooks/AbuseFilterGenerateGenericVarsHook.php new file mode 100644 index 00000000..b7ba9217 --- /dev/null +++ b/AbuseFilter/includes/Hooks/AbuseFilterGenerateGenericVarsHook.php @@ -0,0 +1,23 @@ +<?php + +namespace MediaWiki\Extension\AbuseFilter\Hooks; + +use AbuseFilterVariableHolder; +use RecentChange; + +interface AbuseFilterGenerateGenericVarsHook { + /** + * Hook runner for the `AbuseFilter-generateGenericVars` hook + * + * Allows altering generic variables, i.e. independent from page and user + * + * @param AbuseFilterVariableHolder $vars + * @param ?RecentChange $rc If the variables should be generated for an RC entry, + * this is the entry. Null if it's for the current action being filtered. + * @return bool|void True or no return value to continue or false to abort + */ + public function onAbuseFilterGenerateGenericVars( + AbuseFilterVariableHolder $vars, + ?RecentChange $rc + ); +} diff --git a/AbuseFilter/includes/Hooks/AbuseFilterGenerateTitleVarsHook.php b/AbuseFilter/includes/Hooks/AbuseFilterGenerateTitleVarsHook.php new file mode 100644 index 00000000..a14ef980 --- /dev/null +++ b/AbuseFilter/includes/Hooks/AbuseFilterGenerateTitleVarsHook.php @@ -0,0 +1,28 @@ +<?php + +namespace MediaWiki\Extension\AbuseFilter\Hooks; + +use AbuseFilterVariableHolder; +use RecentChange; +use Title; + +interface AbuseFilterGenerateTitleVarsHook { + /** + * Hook runner for the `AbuseFilter-generateTitleVars` hook + * + * Allows altering the variables generated for a title + * + * @param AbuseFilterVariableHolder $vars + * @param Title $title + * @param string $prefix Variable name prefix + * @param ?RecentChange $rc If the variables should be generated for an RC entry, + * this is the entry. Null if it's for the current action being filtered. + * @return bool|void True or no return value to continue or false to abort + */ + public function onAbuseFilterGenerateTitleVars( + AbuseFilterVariableHolder $vars, + Title $title, + string $prefix, + ?RecentChange $rc + ); +} diff --git a/AbuseFilter/includes/Hooks/AbuseFilterGenerateUserVarsHook.php b/AbuseFilter/includes/Hooks/AbuseFilterGenerateUserVarsHook.php new file mode 100644 index 00000000..f304a325 --- /dev/null +++ b/AbuseFilter/includes/Hooks/AbuseFilterGenerateUserVarsHook.php @@ -0,0 +1,26 @@ +<?php + +namespace MediaWiki\Extension\AbuseFilter\Hooks; + +use AbuseFilterVariableHolder; +use RecentChange; +use User; + +interface AbuseFilterGenerateUserVarsHook { + /** + * Hook runner for the `AbuseFilter-generateUserVars` hook + * + * Allows altering the variables generated for a specific user + * + * @param AbuseFilterVariableHolder $vars + * @param User $user + * @param ?RecentChange $rc If the variables should be generated for an RC entry, + * this is the entry. Null if it's for the current action being filtered. + * @return bool|void True or no return value to continue or false to abort + */ + public function onAbuseFilterGenerateUserVars( + AbuseFilterVariableHolder $vars, + User $user, + ?RecentChange $rc + ); +} diff --git a/AbuseFilter/includes/Hooks/AbuseFilterHookRunner.php b/AbuseFilter/includes/Hooks/AbuseFilterHookRunner.php new file mode 100644 index 00000000..be6bfaf8 --- /dev/null +++ b/AbuseFilter/includes/Hooks/AbuseFilterHookRunner.php @@ -0,0 +1,290 @@ +<?php + +namespace MediaWiki\Extension\AbuseFilter\Hooks; + +use AbuseFilterVariableHolder; +use Content; +use MediaWiki\HookContainer\HookContainer; +use MediaWiki\MediaWikiServices; +use RecentChange; +use Title; +use User; + +/** + * Handle running AbuseFilter's hooks + * @author DannyS712 + */ +class AbuseFilterHookRunner implements + AbuseFilterAlterVariablesHook, + AbuseFilterBuilderHook, + AbuseFilterComputeVariableHook, + AbuseFilterContentToStringHook, + AbuseFilterDeprecatedVariablesHook, + AbuseFilterFilterActionHook, + AbuseFilterGenerateGenericVarsHook, + AbuseFilterGenerateTitleVarsHook, + AbuseFilterGenerateUserVarsHook, + AbuseFilterInterceptVariableHook, + AbuseFilterShouldFilterActionHook +{ + + /** @var HookContainer */ + private $hookContainer; + + /** + * @param HookContainer $hookContainer + */ + public function __construct( HookContainer $hookContainer ) { + $this->hookContainer = $hookContainer; + } + + /** + * Convenience getter for static contexts + * + * See also core's Hooks::runner + * + * @return AbuseFilterHookRunner + */ + public static function getRunner() : AbuseFilterHookRunner { + return new AbuseFilterHookRunner( + MediaWikiServices::getInstance()->getHookContainer() + ); + } + + /** + * Hook runner for the `AbuseFilter-builder` hook + * + * Allows overwriting of the builder values returned by AbuseFilter::getBuilderValues + * + * @param array &$realValues Builder values + * @return bool|void + */ + public function onAbuseFilterBuilder( array &$realValues ) { + return $this->hookContainer->run( + 'AbuseFilter-builder', + [ &$realValues ] + ); + } + + /** + * Hook runner for the `AbuseFilter-deprecatedVariables` hook + * + * Allows adding deprecated variables. If a filter uses an old variable, the parser + * will automatically translate it to the new one. + * + * @param array &$deprecatedVariables deprecated variables, syntax: [ 'old_name' => 'new_name' ] + * @return bool|void + */ + public function onAbuseFilterDeprecatedVariables( array &$deprecatedVariables ) { + return $this->hookContainer->run( + 'AbuseFilter-deprecatedVariables', + [ &$deprecatedVariables ] + ); + } + + /** + * Hook runner for the `AbuseFilter-computeVariable` hook + * + * Like AbuseFilter-interceptVariable but called if the requested method wasn't found. + * Return true to indicate that the method is known to the hook and was computed successful. + * + * @param string $method Method to generate the variable + * @param AbuseFilterVariableHolder $vars + * @param array $parameters Parameters with data to compute the value + * @param ?string &$result Result of the computation + * @return bool|void + */ + public function onAbuseFilterComputeVariable( + string $method, + AbuseFilterVariableHolder $vars, + array $parameters, + ?string &$result + ) { + return $this->hookContainer->run( + 'AbuseFilter-computeVariable', + [ $method, $vars, $parameters, &$result ] + ); + } + + /** + * Hook runner for the `AbuseFilter-contentToString` hook + * + * Called when converting a Content object to a string to which + * filters can be applied. If the hook function returns true, Content::getTextForSearchIndex() + * will be used for non-text content. + * + * @param Content $content + * @param ?string &$text + * @return bool|void + */ + public function onAbuseFilterContentToString( + Content $content, + ?string &$text + ) { + return $this->hookContainer->run( + 'AbuseFilter-contentToString', + [ $content, &$text ] + ); + } + + /** + * Hook runner for the `AbuseFilter-filterAction` hook + * + * DEPRECATED! Use AbuseFilterAlterVariables instead. + * + * Allows overwriting of abusefilter variables in AbuseFilter::filterAction just before they're + * checked against filters. Note that you may specify custom variables in a saner way using other hooks: + * AbuseFilter-generateTitleVars, AbuseFilter-generateUserVars and AbuseFilter-generateGenericVars. + * + * @param AbuseFilterVariableHolder &$vars + * @param Title $title + * @return bool|void + */ + public function onAbuseFilterFilterAction( + AbuseFilterVariableHolder &$vars, + Title $title + ) { + return $this->hookContainer->run( + 'AbuseFilter-filterAction', + [ &$vars, $title ] + ); + } + + /** + * Hook runner for the `AbuseFilterAlterVariables` hook + * + * Allows overwriting of abusefilter variables just before they're + * checked against filters. Note that you may specify custom variables in a saner way using other hooks: + * AbuseFilter-generateTitleVars, AbuseFilter-generateUserVars and AbuseFilter-generateGenericVars. + * + * @param AbuseFilterVariableHolder &$vars + * @param Title $title Title object target of the action + * @param User $user User object performer of the action + * @return bool|void + */ + public function onAbuseFilterAlterVariables( + AbuseFilterVariableHolder &$vars, + Title $title, + User $user + ) { + return $this->hookContainer->run( + 'AbuseFilterAlterVariables', + [ &$vars, $title, $user ] + ); + } + + /** + * Hook runner for the `AbuseFilter-generateTitleVars` hook + * + * Allows altering the variables generated for a title + * + * @param AbuseFilterVariableHolder $vars + * @param Title $title + * @param string $prefix Variable name prefix + * @param ?RecentChange $rc If the variables should be generated for an RC entry, + * this is the entry. Null if it's for the current action being filtered. + * @return bool|void + */ + public function onAbuseFilterGenerateTitleVars( + AbuseFilterVariableHolder $vars, + Title $title, + string $prefix, + ?RecentChange $rc + ) { + return $this->hookContainer->run( + 'AbuseFilter-generateTitleVars', + [ $vars, $title, $prefix, $rc ] + ); + } + + /** + * Hook runner for the `AbuseFilter-generateUserVars` hook + * + * Allows altering the variables generated for a specific user + * + * @param AbuseFilterVariableHolder $vars + * @param User $user + * @param ?RecentChange $rc If the variables should be generated for an RC entry, + * this is the entry. Null if it's for the current action being filtered. + * @return bool|void + */ + public function onAbuseFilterGenerateUserVars( + AbuseFilterVariableHolder $vars, + User $user, + ?RecentChange $rc + ) { + return $this->hookContainer->run( + 'AbuseFilter-generateUserVars', + [ $vars, $user, $rc ] + ); + } + + /** + * Hook runner for the `AbuseFilter-generateGenericVars` hook + * + * Allows altering generic variables, i.e. independent from page and user + * + * @param AbuseFilterVariableHolder $vars + * @param ?RecentChange $rc If the variables should be generated for an RC entry, + * this is the entry. Null if it's for the current action being filtered. + * @return bool|void + */ + public function onAbuseFilterGenerateGenericVars( + AbuseFilterVariableHolder $vars, + ?RecentChange $rc + ) { + return $this->hookContainer->run( + 'AbuseFilter-generateGenericVars', + [ $vars, $rc ] + ); + } + + /** + * Hook runner for the `AbuseFilter-interceptVariable` hook + * + * Called before a variable is set in AFComputedVariable::compute to be able to set + * it before the core code runs. Return false to make the function return right after. + * + * @param string $method Method to generate the variable + * @param AbuseFilterVariableHolder $vars + * @param array $parameters Parameters with data to compute the value + * @param mixed &$result Result of the computation + * @return bool|void + */ + public function onAbuseFilterInterceptVariable( + string $method, + AbuseFilterVariableHolder $vars, + array $parameters, + &$result + ) { + return $this->hookContainer->run( + 'AbuseFilter-interceptVariable', + [ $method, $vars, $parameters, &$result ] + ); + } + + /** + * Hook runner for the `AbuseFilterShouldFilterAction` hook + * + * Called before filtering an action. If the current action should not be filtered, + * return false and add a useful reason to $skipReasons. + * + * @param AbuseFilterVariableHolder $vars + * @param Title $title Title object target of the action + * @param User $user User object performer of the action + * @param array &$skipReasons Array of reasons why the action should be skipped + * @return bool|void + */ + public function onAbuseFilterShouldFilterAction( + AbuseFilterVariableHolder $vars, + Title $title, + User $user, + array &$skipReasons + ) { + return $this->hookContainer->run( + 'AbuseFilterShouldFilterAction', + [ $vars, $title, $user, &$skipReasons ] + ); + } + +} diff --git a/AbuseFilter/includes/Hooks/AbuseFilterInterceptVariableHook.php b/AbuseFilter/includes/Hooks/AbuseFilterInterceptVariableHook.php new file mode 100644 index 00000000..ba93b3ac --- /dev/null +++ b/AbuseFilter/includes/Hooks/AbuseFilterInterceptVariableHook.php @@ -0,0 +1,26 @@ +<?php + +namespace MediaWiki\Extension\AbuseFilter\Hooks; + +use AbuseFilterVariableHolder; + +interface AbuseFilterInterceptVariableHook { + /** + * Hook runner for the `AbuseFilter-interceptVariable` hook + * + * Called before a variable is set in AFComputedVariable::compute to be able to set + * it before the core code runs. Return false to make the function return right after. + * + * @param string $method Method to generate the variable + * @param AbuseFilterVariableHolder $vars + * @param array $parameters Parameters with data to compute the value + * @param mixed &$result Result of the computation + * @return bool|void True or no return value to continue or false to abort + */ + public function onAbuseFilterInterceptVariable( + string $method, + AbuseFilterVariableHolder $vars, + array $parameters, + &$result + ); +} diff --git a/AbuseFilter/includes/Hooks/AbuseFilterShouldFilterActionHook.php b/AbuseFilter/includes/Hooks/AbuseFilterShouldFilterActionHook.php new file mode 100644 index 00000000..1d67bfff --- /dev/null +++ b/AbuseFilter/includes/Hooks/AbuseFilterShouldFilterActionHook.php @@ -0,0 +1,28 @@ +<?php + +namespace MediaWiki\Extension\AbuseFilter\Hooks; + +use AbuseFilterVariableHolder; +use Title; +use User; + +interface AbuseFilterShouldFilterActionHook { + /** + * Hook runner for the `AbuseFilterShouldFilterAction` hook + * + * Called before filtering an action. If the current action should not be filtered, + * return false and add a useful reason to $skipReasons. + * + * @param AbuseFilterVariableHolder $vars + * @param Title $title Title object target of the action + * @param User $user User object performer of the action + * @param array &$skipReasons Array of reasons why the action should be skipped + * @return bool|void True or no return value to continue or false to abort + */ + public function onAbuseFilterShouldFilterAction( + AbuseFilterVariableHolder $vars, + Title $title, + User $user, + array &$skipReasons + ); +} diff --git a/AbuseFilter/includes/KeywordsManager.php b/AbuseFilter/includes/KeywordsManager.php new file mode 100644 index 00000000..d86c9a3f --- /dev/null +++ b/AbuseFilter/includes/KeywordsManager.php @@ -0,0 +1,283 @@ +<?php + +namespace MediaWiki\Extension\AbuseFilter; + +use MediaWiki\Extension\AbuseFilter\Hooks\AbuseFilterHookRunner; + +/** + * This service can be used to manage the list of keywords recognized by the Parser + */ +class KeywordsManager { + public const SERVICE_NAME = 'AbuseFilterKeywordsManager'; + + private const BUILDER_VALUES = [ + 'op-arithmetic' => [ + '+' => 'addition', + '-' => 'subtraction', + '*' => 'multiplication', + '/' => 'divide', + '%' => 'modulo', + '**' => 'pow' + ], + 'op-comparison' => [ + '==' => 'equal', + '===' => 'equal-strict', + '!=' => 'notequal', + '!==' => 'notequal-strict', + '<' => 'lt', + '>' => 'gt', + '<=' => 'lte', + '>=' => 'gte' + ], + 'op-bool' => [ + '!' => 'not', + '&' => 'and', + '|' => 'or', + '^' => 'xor' + ], + 'misc' => [ + 'in' => 'in', + 'contains' => 'contains', + 'like' => 'like', + '""' => 'stringlit', + 'rlike' => 'rlike', + 'irlike' => 'irlike', + 'cond ? iftrue : iffalse' => 'tern', + 'if cond then iftrue else iffalse end' => 'cond', + 'if cond then iftrue end' => 'cond-short', + ], + 'funcs' => [ + 'length(string)' => 'length', + 'lcase(string)' => 'lcase', + 'ucase(string)' => 'ucase', + 'ccnorm(string)' => 'ccnorm', + 'ccnorm_contains_any(haystack,needle1,needle2,..)' => 'ccnorm-contains-any', + 'ccnorm_contains_all(haystack,needle1,needle2,..)' => 'ccnorm-contains-all', + 'rmdoubles(string)' => 'rmdoubles', + 'specialratio(string)' => 'specialratio', + 'norm(string)' => 'norm', + 'count(needle,haystack)' => 'count', + 'rcount(needle,haystack)' => 'rcount', + 'get_matches(needle,haystack)' => 'get_matches', + 'rmwhitespace(text)' => 'rmwhitespace', + 'rmspecials(text)' => 'rmspecials', + 'ip_in_range(ip, range)' => 'ip_in_range', + 'contains_any(haystack,needle1,needle2,...)' => 'contains-any', + 'contains_all(haystack,needle1,needle2,...)' => 'contains-all', + 'equals_to_any(haystack,needle1,needle2,...)' => 'equals-to-any', + 'substr(subject, offset, length)' => 'substr', + 'strpos(haystack, needle)' => 'strpos', + 'str_replace(subject, search, replace)' => 'str_replace', + 'rescape(string)' => 'rescape', + 'set_var(var,value)' => 'set_var', + 'sanitize(string)' => 'sanitize', + ], + 'vars' => [ + 'timestamp' => 'timestamp', + 'accountname' => 'accountname', + 'action' => 'action', + 'added_lines' => 'addedlines', + 'edit_delta' => 'delta', + 'edit_diff' => 'diff', + 'new_size' => 'newsize', + 'old_size' => 'oldsize', + 'new_content_model' => 'new-content-model', + 'old_content_model' => 'old-content-model', + 'removed_lines' => 'removedlines', + 'summary' => 'summary', + 'page_id' => 'page-id', + 'page_namespace' => 'page-ns', + 'page_title' => 'page-title', + 'page_prefixedtitle' => 'page-prefixedtitle', + 'page_age' => 'page-age', + 'moved_from_id' => 'movedfrom-id', + 'moved_from_namespace' => 'movedfrom-ns', + 'moved_from_title' => 'movedfrom-title', + 'moved_from_prefixedtitle' => 'movedfrom-prefixedtitle', + 'moved_from_age' => 'movedfrom-age', + 'moved_to_id' => 'movedto-id', + 'moved_to_namespace' => 'movedto-ns', + 'moved_to_title' => 'movedto-title', + 'moved_to_prefixedtitle' => 'movedto-prefixedtitle', + 'moved_to_age' => 'movedto-age', + 'user_editcount' => 'user-editcount', + 'user_age' => 'user-age', + 'user_name' => 'user-name', + 'user_groups' => 'user-groups', + 'user_rights' => 'user-rights', + 'user_blocked' => 'user-blocked', + 'user_emailconfirm' => 'user-emailconfirm', + 'old_wikitext' => 'old-wikitext', + 'new_wikitext' => 'new-wikitext', + 'added_links' => 'added-links', + 'removed_links' => 'removed-links', + 'all_links' => 'all-links', + 'new_pst' => 'new-pst', + 'edit_diff_pst' => 'diff-pst', + 'added_lines_pst' => 'addedlines-pst', + 'new_text' => 'new-text', + 'new_html' => 'new-html', + 'page_restrictions_edit' => 'restrictions-edit', + 'page_restrictions_move' => 'restrictions-move', + 'page_restrictions_create' => 'restrictions-create', + 'page_restrictions_upload' => 'restrictions-upload', + 'page_recent_contributors' => 'recent-contributors', + 'page_first_contributor' => 'first-contributor', + 'moved_from_restrictions_edit' => 'movedfrom-restrictions-edit', + 'moved_from_restrictions_move' => 'movedfrom-restrictions-move', + 'moved_from_restrictions_create' => 'movedfrom-restrictions-create', + 'moved_from_restrictions_upload' => 'movedfrom-restrictions-upload', + 'moved_from_recent_contributors' => 'movedfrom-recent-contributors', + 'moved_from_first_contributor' => 'movedfrom-first-contributor', + 'moved_to_restrictions_edit' => 'movedto-restrictions-edit', + 'moved_to_restrictions_move' => 'movedto-restrictions-move', + 'moved_to_restrictions_create' => 'movedto-restrictions-create', + 'moved_to_restrictions_upload' => 'movedto-restrictions-upload', + 'moved_to_recent_contributors' => 'movedto-recent-contributors', + 'moved_to_first_contributor' => 'movedto-first-contributor', + 'old_links' => 'old-links', + 'file_sha1' => 'file-sha1', + 'file_size' => 'file-size', + 'file_mime' => 'file-mime', + 'file_mediatype' => 'file-mediatype', + 'file_width' => 'file-width', + 'file_height' => 'file-height', + 'file_bits_per_channel' => 'file-bits-per-channel', + 'wiki_name' => 'wiki-name', + 'wiki_language' => 'wiki-language', + ], + ]; + + /** @var array Old vars which aren't in use anymore */ + private const DISABLED_VARS = [ + 'old_text' => 'old-text', + 'old_html' => 'old-html', + 'minor_edit' => 'minor-edit' + ]; + + private const DEPRECATED_VARS = [ + 'article_text' => 'page_title', + 'article_prefixedtext' => 'page_prefixedtitle', + 'article_namespace' => 'page_namespace', + 'article_articleid' => 'page_id', + 'article_restrictions_edit' => 'page_restrictions_edit', + 'article_restrictions_move' => 'page_restrictions_move', + 'article_restrictions_create' => 'page_restrictions_create', + 'article_restrictions_upload' => 'page_restrictions_upload', + 'article_recent_contributors' => 'page_recent_contributors', + 'article_first_contributor' => 'page_first_contributor', + 'moved_from_text' => 'moved_from_title', + 'moved_from_prefixedtext' => 'moved_from_prefixedtitle', + 'moved_from_articleid' => 'moved_from_id', + 'moved_to_text' => 'moved_to_title', + 'moved_to_prefixedtext' => 'moved_to_prefixedtitle', + 'moved_to_articleid' => 'moved_to_id', + ]; + + /** @var string[][] Final list of builder values */ + private $builderValues; + + /** @var string[] Final list of deprecated vars */ + private $deprecatedVars; + + /** @var AbuseFilterHookRunner */ + private $hookRunner; + + /** + * @param AbuseFilterHookRunner $hookRunner + */ + public function __construct( AbuseFilterHookRunner $hookRunner ) { + $this->hookRunner = $hookRunner; + } + + /** + * @return array + */ + public function getDisabledVariables(): array { + return self::DISABLED_VARS; + } + + /** + * @return array + */ + public function getDeprecatedVariables(): array { + if ( $this->deprecatedVars === null ) { + $this->deprecatedVars = self::DEPRECATED_VARS; + $this->hookRunner->onAbuseFilterDeprecatedVariables( $this->deprecatedVars ); + } + return $this->deprecatedVars; + } + + /** + * @return array + */ + public function getBuilderValues(): array { + if ( $this->builderValues === null ) { + $this->builderValues = self::BUILDER_VALUES; + $this->hookRunner->onAbuseFilterBuilder( $this->builderValues ); + } + return $this->builderValues; + } + + /** + * @param string $name + * @return bool + */ + public function isVarDisabled( string $name ): bool { + return array_key_exists( $name, self::DISABLED_VARS ); + } + + /** + * @param string $name + * @return bool + */ + public function isVarDeprecated( string $name ): bool { + return array_key_exists( $name, $this->getDeprecatedVariables() ); + } + + /** + * @param string $name + * @return bool + */ + public function isVarInUse( string $name ): bool { + return array_key_exists( $name, $this->getVarsMappings() ); + } + + /** + * Check whether the given name corresponds to a known variable. + * @param string $name + * @return bool + */ + public function varExists( string $name ): bool { + return $this->isVarInUse( $name ) || + $this->isVarDisabled( $name ) || + $this->isVarDeprecated( $name ); + } + + /** + * Get the message for a builtin variable; takes deprecated variables into account. + * Returns null for non-builtin variables. + * + * @param string $var + * @return string|null + */ + public function getMessageKeyForVar( string $var ): ?string { + if ( !$this->varExists( $var ) ) { + return null; + } + if ( $this->isVarDeprecated( $var ) ) { + $var = $this->getDeprecatedVariables()[$var]; + } + + $key = self::DISABLED_VARS[$var] ?? + $this->getVarsMappings()[$var]; + return "abusefilter-edit-builder-vars-$key"; + } + + /** + * @return array + */ + public function getVarsMappings(): array { + return $this->getBuilderValues()['vars']; + } +} diff --git a/AbuseFilter/includes/ServiceWiring.php b/AbuseFilter/includes/ServiceWiring.php new file mode 100644 index 00000000..5901ca80 --- /dev/null +++ b/AbuseFilter/includes/ServiceWiring.php @@ -0,0 +1,13 @@ +<?php + +use MediaWiki\Extension\AbuseFilter\Hooks\AbuseFilterHookRunner; +use MediaWiki\Extension\AbuseFilter\KeywordsManager; +use MediaWiki\MediaWikiServices; + +return [ + KeywordsManager::SERVICE_NAME => function ( MediaWikiServices $services ): KeywordsManager { + return new KeywordsManager( + new AbuseFilterHookRunner( $services->getHookContainer() ) + ); + }, +]; diff --git a/AbuseFilter/includes/VariableGenerator/RCVariableGenerator.php b/AbuseFilter/includes/VariableGenerator/RCVariableGenerator.php new file mode 100644 index 00000000..8c4a1d81 --- /dev/null +++ b/AbuseFilter/includes/VariableGenerator/RCVariableGenerator.php @@ -0,0 +1,235 @@ +<?php + +namespace MediaWiki\Extension\AbuseFilter\VariableGenerator; + +use AbuseFilterVariableHolder; +use MediaWiki\Logger\LoggerFactory; +use MediaWiki\MediaWikiServices; +use MWFileProps; +use MWTimestamp; +use RecentChange; +use Title; +use User; + +/** + * This class contains the logic used to create AbuseFilterVariableHolder objects used to + * examine a RecentChanges row. + */ +class RCVariableGenerator extends VariableGenerator { + /** + * @var RecentChange + */ + protected $rc; + + /** @var User */ + private $contextUser; + + /** + * @param AbuseFilterVariableHolder $vars + * @param RecentChange $rc + * @param User $contextUser + */ + public function __construct( + AbuseFilterVariableHolder $vars, + RecentChange $rc, + User $contextUser + ) { + parent::__construct( $vars ); + + $this->rc = $rc; + $this->contextUser = $contextUser; + } + + /** + * Get an instance for a given rc_id. + * + * @todo FIXME this method doesn't appear to have any uses + * + * @param int $id + * @param AbuseFilterVariableHolder $vars + * @param User $contextUser + * @return self|null + */ + public static function newFromId( + int $id, + AbuseFilterVariableHolder $vars, + User $contextUser + ) : ?self { + $rc = RecentChange::newFromId( $id ); + + if ( !$rc ) { + return null; + } + return new self( $vars, $rc, $contextUser ); + } + + /** + * @return AbuseFilterVariableHolder|null + */ + public function getVars() : ?AbuseFilterVariableHolder { + if ( $this->rc->getAttribute( 'rc_type' ) == RC_LOG ) { + switch ( $this->rc->getAttribute( 'rc_log_type' ) ) { + case 'move': + $this->addMoveVars(); + break; + case 'newusers': + $this->addCreateAccountVars(); + break; + case 'delete': + $this->addDeleteVars(); + break; + case 'upload': + $this->addUploadVars(); + break; + default: + return null; + } + } elseif ( $this->rc->getAttribute( 'rc_last_oldid' ) ) { + // It's an edit. + $this->addEditVarsForRow(); + } else { + // @todo Ensure this cannot happen, and throw if it does + return null; + } + + $this->addGenericVars(); + $this->vars->setVar( + 'timestamp', + MWTimestamp::convert( TS_UNIX, $this->rc->getAttribute( 'rc_timestamp' ) ) + ); + + return $this->vars; + } + + /** + * @return $this + */ + private function addMoveVars() : self { + $user = $this->rc->getPerformer(); + + $oldTitle = $this->rc->getTitle(); + $newTitle = Title::newFromText( $this->rc->getParam( '4::target' ) ); + + $this->addUserVars( $user, $this->rc ) + ->addTitleVars( $oldTitle, 'moved_from', $this->rc ) + ->addTitleVars( $newTitle, 'moved_to', $this->rc ); + + $this->vars->setVar( 'summary', $this->rc->getAttribute( 'rc_comment' ) ); + $this->vars->setVar( 'action', 'move' ); + + return $this; + } + + /** + * @return $this + */ + private function addCreateAccountVars() : self { + $this->vars->setVar( + 'action', + $this->rc->getAttribute( 'rc_log_action' ) === 'autocreate' + ? 'autocreateaccount' + : 'createaccount' + ); + + $name = $this->rc->getTitle()->getText(); + // Add user data if the account was created by a registered user + $user = $this->rc->getPerformer(); + if ( !$user->isAnon() && $name !== $user->getName() ) { + $this->addUserVars( $user, $this->rc ); + } + + $this->vars->setVar( 'accountname', $name ); + + return $this; + } + + /** + * @return $this + */ + private function addDeleteVars() : self { + $title = $this->rc->getTitle(); + $user = $this->rc->getPerformer(); + + $this->addUserVars( $user, $this->rc ) + ->addTitleVars( $title, 'page', $this->rc ); + + $this->vars->setVar( 'action', 'delete' ); + $this->vars->setVar( 'summary', $this->rc->getAttribute( 'rc_comment' ) ); + + return $this; + } + + /** + * @return $this + */ + private function addUploadVars() : self { + $title = $this->rc->getTitle(); + $user = $this->rc->getPerformer(); + + $this->addUserVars( $user, $this->rc ) + ->addTitleVars( $title, 'page', $this->rc ); + + $this->vars->setVar( 'action', 'upload' ); + $this->vars->setVar( 'summary', $this->rc->getAttribute( 'rc_comment' ) ); + + $time = $this->rc->getParam( 'img_timestamp' ); + $file = MediaWikiServices::getInstance()->getRepoGroup()->findFile( + $title, [ 'time' => $time, 'private' => $this->contextUser ] + ); + if ( !$file ) { + // FixMe This shouldn't happen! + $logger = LoggerFactory::getInstance( 'AbuseFilter' ); + $logger->debug( "Cannot find file from RC row with title $title" ); + return $this; + } + + // This is the same as AbuseFilterHooks::filterUpload, but from a different source + $this->vars->setVar( 'file_sha1', \Wikimedia\base_convert( $file->getSha1(), 36, 16, 40 ) ); + $this->vars->setVar( 'file_size', $file->getSize() ); + + $this->vars->setVar( 'file_mime', $file->getMimeType() ); + $this->vars->setVar( + 'file_mediatype', + MediaWikiServices::getInstance()->getMimeAnalyzer() + ->getMediaType( null, $file->getMimeType() ) + ); + $this->vars->setVar( 'file_width', $file->getWidth() ); + $this->vars->setVar( 'file_height', $file->getHeight() ); + + $mwProps = new MWFileProps( MediaWikiServices::getInstance()->getMimeAnalyzer() ); + $bits = $mwProps->getPropsFromPath( $file->getLocalRefPath(), true )['bits']; + $this->vars->setVar( 'file_bits_per_channel', $bits ); + + return $this; + } + + /** + * @return $this + */ + private function addEditVarsForRow() : self { + $title = $this->rc->getTitle(); + $user = $this->rc->getPerformer(); + + $this->addUserVars( $user, $this->rc ) + ->addTitleVars( $title, 'page', $this->rc ); + + // @todo Set old_content_model and new_content_model + $this->vars->setVar( 'action', 'edit' ); + $this->vars->setVar( 'summary', $this->rc->getAttribute( 'rc_comment' ) ); + + $this->vars->setLazyLoadVar( 'new_wikitext', 'revision-text-by-id', + [ 'revid' => $this->rc->getAttribute( 'rc_this_oldid' ) ] ); + + $parentId = $this->rc->getAttribute( 'rc_last_oldid' ); + if ( $parentId ) { + $this->vars->setLazyLoadVar( 'old_wikitext', 'revision-text-by-id', + [ 'revid' => $parentId ] ); + } else { + $this->vars->setVar( 'old_wikitext', '' ); + } + + $this->addEditVars( $title ); + + return $this; + } +} diff --git a/AbuseFilter/includes/VariableGenerator/RunVariableGenerator.php b/AbuseFilter/includes/VariableGenerator/RunVariableGenerator.php new file mode 100644 index 00000000..1f0deab4 --- /dev/null +++ b/AbuseFilter/includes/VariableGenerator/RunVariableGenerator.php @@ -0,0 +1,316 @@ +<?php + +namespace MediaWiki\Extension\AbuseFilter\VariableGenerator; + +use AbuseFilter; +use AbuseFilterVariableHolder; +use AFComputedVariable; +use Content; +use MediaWiki\MediaWikiServices; +use MediaWiki\Revision\MutableRevisionRecord; +use MediaWiki\Revision\RevisionRecord; +use MediaWiki\Revision\SlotRecord; +use MWException; +use MWFileProps; +use Title; +use UploadBase; +use User; +use WikiPage; + +/** + * This class contains the logic used to create AbuseFilterVariableHolder objects before filtering + * an action. + */ +class RunVariableGenerator extends VariableGenerator { + /** + * @var User + */ + protected $user; + + /** + * @var Title + */ + protected $title; + + /** + * @param AbuseFilterVariableHolder $vars + * @param User $user + * @param Title $title + */ + public function __construct( AbuseFilterVariableHolder $vars, User $user, Title $title ) { + parent::__construct( $vars ); + $this->user = $user; + $this->title = $title; + } + + /** + * Get variables for pre-filtering an edit during stash + * + * @param Content $content + * @param string $summary + * @param string $slot + * @param WikiPage $page + * @return AbuseFilterVariableHolder|null + */ + public function getStashEditVars( + Content $content, + string $summary, + $slot, + WikiPage $page + ) : ?AbuseFilterVariableHolder { + $filterText = $this->getEditTextForFiltering( $page, $content, $slot ); + if ( $filterText === null ) { + return null; + } + list( $oldContent, $oldAfText, $text ) = $filterText; + return $this->newVariableHolderForEdit( + $page, $summary, $content, $text, $oldAfText, $oldContent + ); + } + + /** + * Get the text of an edit to be used for filtering + * @todo Full support for multi-slots + * + * @param WikiPage $page + * @param Content $content + * @param string $slot + * @return array|null + */ + protected function getEditTextForFiltering( WikiPage $page, Content $content, $slot ) : ?array { + $oldRevRecord = $page->getRevisionRecord(); + if ( !$oldRevRecord ) { + return null; + } + + $oldContent = $oldRevRecord->getContent( SlotRecord::MAIN, RevisionRecord::RAW ); + $oldAfText = AbuseFilter::revisionToString( $oldRevRecord, $this->user ); + + // XXX: Recreate what the new revision will probably be so we can get the full AF + // text for all slots + $newRevision = MutableRevisionRecord::newFromParentRevision( $oldRevRecord ); + $newRevision->setContent( $slot, $content ); + $text = AbuseFilter::revisionToString( $newRevision, $this->user ); + + // Cache article object so we can share a parse operation + $articleCacheKey = $this->title->getNamespace() . ':' . $this->title->getText(); + AFComputedVariable::$articleCache[$articleCacheKey] = $page; + + // Don't trigger for null edits. Compare Content objects if available, but check the + // stringified contents as well, e.g. for line endings normalization (T240115). + // Don't treat content model change as null edit though. + if ( + ( $oldContent && $content->equals( $oldContent ) ) || + ( $oldContent->getModel() === $content->getModel() && strcmp( $oldAfText, $text ) === 0 ) + ) { + return null; + } + + return [ $oldContent, $oldAfText, $text ]; + } + + /** + * @param WikiPage|null $page + * @param string $summary + * @param Content $newcontent + * @param string $text + * @param string $oldtext + * @param Content|null $oldcontent + * @return AbuseFilterVariableHolder + * @throws MWException + */ + private function newVariableHolderForEdit( + ?WikiPage $page, + string $summary, + Content $newcontent, + string $text, + string $oldtext, + Content $oldcontent = null + ) : AbuseFilterVariableHolder { + $this->addUserVars( $this->user ) + ->addTitleVars( $this->title, 'page' ); + $this->vars->setVar( 'action', 'edit' ); + $this->vars->setVar( 'summary', $summary ); + if ( $oldcontent instanceof Content ) { + $oldmodel = $oldcontent->getModel(); + } else { + $oldmodel = ''; + $oldtext = ''; + } + $this->vars->setVar( 'old_content_model', $oldmodel ); + $this->vars->setVar( 'new_content_model', $newcontent->getModel() ); + $this->vars->setVar( 'old_wikitext', $oldtext ); + $this->vars->setVar( 'new_wikitext', $text ); + $this->addEditVars( $this->title, $page ); + + return $this->vars; + } + + /** + * Get variables for filtering an edit. + * + * @param Content $content + * @param string $text + * @param string $summary + * @param string $slot + * @param WikiPage|null $page + * @return AbuseFilterVariableHolder|null + */ + public function getEditVars( + Content $content, + string $text, + string $summary, + $slot, + WikiPage $page = null + ) : ?AbuseFilterVariableHolder { + $oldContent = null; + + if ( $page !== null ) { + $filterText = $this->getEditTextForFiltering( $page, $content, $slot ); + if ( $filterText === null ) { + return null; + } + list( $oldContent, $oldAfText, $text ) = $filterText; + } else { + $oldAfText = ''; + } + + return $this->newVariableHolderForEdit( + $page, $summary, $content, $text, $oldAfText, $oldContent + ); + } + + /** + * Get variables used to filter a move. + * + * @param Title $newTitle + * @param string $reason + * @return AbuseFilterVariableHolder + */ + public function getMoveVars( + Title $newTitle, + string $reason + ) : AbuseFilterVariableHolder { + $this->addUserVars( $this->user ) + ->addTitleVars( $this->title, 'MOVED_FROM' ) + ->addTitleVars( $newTitle, 'MOVED_TO' ); + $this->vars->setVar( 'summary', $reason ); + $this->vars->setVar( 'action', 'move' ); + return $this->vars; + } + + /** + * Get variables for filtering a deletion. + * + * @param string $reason + * @return AbuseFilterVariableHolder + */ + public function getDeleteVars( + string $reason + ) : AbuseFilterVariableHolder { + $this->addUserVars( $this->user ) + ->addTitleVars( $this->title, 'page' ); + + $this->vars->setVar( 'summary', $reason ); + $this->vars->setVar( 'action', 'delete' ); + return $this->vars; + } + + /** + * Get variables for filtering an upload. + * + * @param string $action + * @param UploadBase $upload + * @param string|null $summary + * @param string|null $text + * @param array|null $props + * @return AbuseFilterVariableHolder|null + */ + public function getUploadVars( + string $action, + UploadBase $upload, + ?string $summary, + ?string $text, + ?array $props + ) : ?AbuseFilterVariableHolder { + $mimeAnalyzer = MediaWikiServices::getInstance()->getMimeAnalyzer(); + if ( !$props ) { + $props = ( new MWFileProps( $mimeAnalyzer ) )->getPropsFromPath( + $upload->getTempPath(), + true + ); + } + + $this->addUserVars( $this->user ) + ->addTitleVars( $this->title, 'page' ); + $this->vars->setVar( 'action', $action ); + + // We use the hexadecimal version of the file sha1. + // Use UploadBase::getTempFileSha1Base36 so that we don't have to calculate the sha1 sum again + $sha1 = \Wikimedia\base_convert( $upload->getTempFileSha1Base36(), 36, 16, 40 ); + + // This is the same as AbuseFilterRowVariableGenerator::addUploadVars, but from a different source + $this->vars->setVar( 'file_sha1', $sha1 ); + $this->vars->setVar( 'file_size', $upload->getFileSize() ); + + $this->vars->setVar( 'file_mime', $props['mime'] ); + $this->vars->setVar( 'file_mediatype', $mimeAnalyzer->getMediaType( null, $props['mime'] ) ); + $this->vars->setVar( 'file_width', $props['width'] ); + $this->vars->setVar( 'file_height', $props['height'] ); + $this->vars->setVar( 'file_bits_per_channel', $props['bits'] ); + + // We only have the upload comment and page text when using the UploadVerifyUpload hook + if ( $summary !== null && $text !== null ) { + // This block is adapted from self::getTextForFiltering() + if ( $this->title->exists() ) { + $page = WikiPage::factory( $this->title ); + $revRec = $page->getRevisionRecord(); + if ( !$revRec ) { + return null; + } + + $oldcontent = $revRec->getContent( SlotRecord::MAIN, RevisionRecord::RAW ); + $oldtext = AbuseFilter::contentToString( $oldcontent ); + + // Cache article object so we can share a parse operation + $articleCacheKey = $this->title->getNamespace() . ':' . $this->title->getText(); + AFComputedVariable::$articleCache[$articleCacheKey] = $page; + + // Page text is ignored for uploads when the page already exists + $text = $oldtext; + } else { + $page = null; + $oldtext = ''; + } + + // Load vars for filters to check + $this->vars->setVar( 'summary', $summary ); + $this->vars->setVar( 'old_wikitext', $oldtext ); + $this->vars->setVar( 'new_wikitext', $text ); + // TODO: set old_content and new_content vars, use them + $this->addEditVars( $this->title, $page ); + } + return $this->vars; + } + + /** + * Get variables for filtering an account creation + * + * @param User $createdUser This is the user being created, not the creator (which is $this->user) + * @param bool $autocreate + * @return AbuseFilterVariableHolder + */ + public function getAccountCreationVars( + User $createdUser, + bool $autocreate + ) : AbuseFilterVariableHolder { + // generateUserVars records $this->user->getName() which would be the IP for unregistered users + if ( $this->user->isLoggedIn() ) { + $this->addUserVars( $this->user ); + } + + $this->vars->setVar( 'action', $autocreate ? 'autocreateaccount' : 'createaccount' ); + $this->vars->setVar( 'accountname', $createdUser->getName() ); + return $this->vars; + } +} diff --git a/AbuseFilter/includes/VariableGenerator/VariableGenerator.php b/AbuseFilter/includes/VariableGenerator/VariableGenerator.php new file mode 100644 index 00000000..468d5c75 --- /dev/null +++ b/AbuseFilter/includes/VariableGenerator/VariableGenerator.php @@ -0,0 +1,230 @@ +<?php + +namespace MediaWiki\Extension\AbuseFilter\VariableGenerator; + +use AbuseFilterVariableHolder; +use MediaWiki\Extension\AbuseFilter\Hooks\AbuseFilterHookRunner; +use RecentChange; +use Title; +use User; +use WikiPage; + +/** + * Class used to generate variables, for instance related to a given user or title. + */ +class VariableGenerator { + /** + * @var AbuseFilterVariableHolder + */ + protected $vars; + + /** @var AbuseFilterHookRunner */ + private $hookRunner; + + /** + * @param AbuseFilterVariableHolder $vars + */ + public function __construct( AbuseFilterVariableHolder $vars ) { + $this->vars = $vars; + + // TODO this class is constructed in other extensions; make this a parameter + $this->hookRunner = AbuseFilterHookRunner::getRunner(); + } + + /** + * @return AbuseFilterVariableHolder + */ + public function getVariableHolder() : AbuseFilterVariableHolder { + return $this->vars; + } + + /** + * Computes all variables unrelated to title and user. In general, these variables may be known + * even without an ongoing action. + * + * @param RecentChange|null $rc If the variables should be generated for an RC entry, + * this is the entry. Null if it's for the current action being filtered. + * @return $this For chaining + */ + public function addGenericVars( RecentChange $rc = null ) : self { + // These are lazy-loaded just to reduce the amount of preset variables, but they + // shouldn't be expensive. + $this->vars->setLazyLoadVar( 'wiki_name', 'get-wiki-name', [] ); + $this->vars->setLazyLoadVar( 'wiki_language', 'get-wiki-language', [] ); + + $this->hookRunner->onAbuseFilterGenerateGenericVars( $this->vars, $rc ); + return $this; + } + + /** + * @param User $user + * @param RecentChange|null $rc If the variables should be generated for an RC entry, + * this is the entry. Null if it's for the current action being filtered. + * @return $this For chaining + */ + public function addUserVars( User $user, RecentChange $rc = null ) : self { + $this->vars->setLazyLoadVar( + 'user_editcount', + 'simple-user-accessor', + [ 'user' => $user, 'method' => 'getEditCount' ] + ); + + $this->vars->setVar( 'user_name', $user->getName() ); + + $this->vars->setLazyLoadVar( + 'user_emailconfirm', + 'simple-user-accessor', + [ 'user' => $user, 'method' => 'getEmailAuthenticationTimestamp' ] + ); + + $this->vars->setLazyLoadVar( + 'user_age', + 'user-age', + [ 'user' => $user, 'asof' => wfTimestampNow() ] + ); + + $this->vars->setLazyLoadVar( + 'user_groups', + 'simple-user-accessor', + [ 'user' => $user, 'method' => 'getEffectiveGroups' ] + ); + + $this->vars->setLazyLoadVar( + 'user_rights', + 'simple-user-accessor', + [ 'user' => $user, 'method' => 'getRights' ] + ); + + $this->vars->setLazyLoadVar( + 'user_blocked', + 'user-block', + [ 'user' => $user ] + ); + + $this->hookRunner->onAbuseFilterGenerateUserVars( $this->vars, $user, $rc ); + + return $this; + } + + /** + * @param Title $title + * @param string $prefix + * @param RecentChange|null $rc If the variables should be generated for an RC entry, + * this is the entry. Null if it's for the current action being filtered. + * @return $this For chaining + */ + public function addTitleVars( + Title $title, + string $prefix, + RecentChange $rc = null + ) : self { + $this->vars->setVar( $prefix . '_id', $title->getArticleID() ); + $this->vars->setVar( $prefix . '_namespace', $title->getNamespace() ); + $this->vars->setVar( $prefix . '_title', $title->getText() ); + $this->vars->setVar( $prefix . '_prefixedtitle', $title->getPrefixedText() ); + + // We only support the default values in $wgRestrictionTypes. Custom restrictions wouldn't + // have i18n messages. If a restriction is not enabled we'll just return the empty array. + $types = [ 'edit', 'move', 'create', 'upload' ]; + foreach ( $types as $action ) { + $this->vars->setLazyLoadVar( "{$prefix}_restrictions_$action", 'get-page-restrictions', + [ 'title' => $title->getText(), + 'namespace' => $title->getNamespace(), + 'action' => $action + ] + ); + } + + $this->vars->setLazyLoadVar( "{$prefix}_recent_contributors", 'load-recent-authors', + [ + 'title' => $title->getText(), + 'namespace' => $title->getNamespace() + ] ); + + $this->vars->setLazyLoadVar( "{$prefix}_age", 'page-age', + [ + 'title' => $title->getText(), + 'namespace' => $title->getNamespace(), + 'asof' => wfTimestampNow() + ] ); + + $this->vars->setLazyLoadVar( "{$prefix}_first_contributor", 'load-first-author', + [ + 'title' => $title->getText(), + 'namespace' => $title->getNamespace() + ] ); + + $this->hookRunner->onAbuseFilterGenerateTitleVars( $this->vars, $title, $prefix, $rc ); + + return $this; + } + + /** + * @param Title $title + * @param WikiPage|null $page + * @return $this For chaining + */ + public function addEditVars( Title $title, WikiPage $page = null ) : self { + // NOTE: $page may end up remaining null, e.g. if $title points to a special page. + if ( !$page && $title->canExist() ) { + // TODO: The caller should do this! + $page = WikiPage::factory( $title ); + } + + $this->vars->setLazyLoadVar( 'edit_diff', 'diff-array', + [ 'oldtext-var' => 'old_wikitext', 'newtext-var' => 'new_wikitext' ] ); + $this->vars->setLazyLoadVar( 'edit_diff_pst', 'diff-array', + [ 'oldtext-var' => 'old_wikitext', 'newtext-var' => 'new_pst' ] ); + $this->vars->setLazyLoadVar( 'new_size', 'length', [ 'length-var' => 'new_wikitext' ] ); + $this->vars->setLazyLoadVar( 'old_size', 'length', [ 'length-var' => 'old_wikitext' ] ); + $this->vars->setLazyLoadVar( 'edit_delta', 'subtract-int', + [ 'val1-var' => 'new_size', 'val2-var' => 'old_size' ] ); + + // Some more specific/useful details about the changes. + $this->vars->setLazyLoadVar( 'added_lines', 'diff-split', + [ 'diff-var' => 'edit_diff', 'line-prefix' => '+' ] ); + $this->vars->setLazyLoadVar( 'removed_lines', 'diff-split', + [ 'diff-var' => 'edit_diff', 'line-prefix' => '-' ] ); + $this->vars->setLazyLoadVar( 'added_lines_pst', 'diff-split', + [ 'diff-var' => 'edit_diff_pst', 'line-prefix' => '+' ] ); + + // Links + $this->vars->setLazyLoadVar( 'added_links', 'link-diff-added', + [ 'oldlink-var' => 'old_links', 'newlink-var' => 'all_links' ] ); + $this->vars->setLazyLoadVar( 'removed_links', 'link-diff-removed', + [ 'oldlink-var' => 'old_links', 'newlink-var' => 'all_links' ] ); + $this->vars->setLazyLoadVar( 'new_text', 'strip-html', + [ 'html-var' => 'new_html' ] ); + + $this->vars->setLazyLoadVar( 'all_links', 'links-from-wikitext', + [ + 'namespace' => $title->getNamespace(), + 'title' => $title->getText(), + 'text-var' => 'new_wikitext', + 'article' => $page + ] ); + $this->vars->setLazyLoadVar( 'old_links', 'links-from-wikitext-or-database', + [ + 'namespace' => $title->getNamespace(), + 'title' => $title->getText(), + 'text-var' => 'old_wikitext' + ] ); + $this->vars->setLazyLoadVar( 'new_pst', 'parse-wikitext', + [ + 'namespace' => $title->getNamespace(), + 'title' => $title->getText(), + 'wikitext-var' => 'new_wikitext', + 'article' => $page, + 'pst' => true, + ] ); + $this->vars->setLazyLoadVar( 'new_html', 'parse-wikitext', + [ + 'namespace' => $title->getNamespace(), + 'title' => $title->getText(), + 'wikitext-var' => 'new_wikitext', + 'article' => $page + ] ); + + return $this; + } +} diff --git a/AbuseFilter/includes/Views/AbuseFilterView.php b/AbuseFilter/includes/Views/AbuseFilterView.php index 9b019335..a8cbcadb 100644 --- a/AbuseFilter/includes/Views/AbuseFilterView.php +++ b/AbuseFilter/includes/Views/AbuseFilterView.php @@ -1,9 +1,29 @@ <?php +use MediaWiki\Extension\AbuseFilter\AbuseFilterServices; use Wikimedia\Rdbms\IDatabase; abstract class AbuseFilterView extends ContextSource { - public $mFilter, $mHistoryID, $mSubmit, $mPage, $mParams; + /** + * @var string The ID of the current filter + */ + public $mFilter; + /** + * @var int|null The history ID of the current filter + */ + public $mHistoryID; + /** + * @var bool Whether the form was submitted + */ + public $mSubmit; + /** + * @var SpecialAbuseFilter The related special page object + */ + public $mPage; + /** + * @var array The parameters of the current request + */ + public $mParams; /** * @var \MediaWiki\Linker\LinkRenderer @@ -14,7 +34,7 @@ abstract class AbuseFilterView extends ContextSource { * @param SpecialAbuseFilter $page * @param array $params */ - public function __construct( $page, $params ) { + public function __construct( SpecialAbuseFilter $page, $params ) { $this->mPage = $page; $this->mParams = $params; $this->setContext( $this->mPage->getContext() ); @@ -22,7 +42,7 @@ abstract class AbuseFilterView extends ContextSource { } /** - * @param string $subpage + * @param string|int $subpage * @return Title */ public function getTitle( $subpage = '' ) { @@ -35,74 +55,45 @@ abstract class AbuseFilterView extends ContextSource { abstract public function show(); /** - * @return bool - */ - public function canEdit() { - return ( - !$this->getUser()->isBlocked() && - $this->getUser()->isAllowed( 'abusefilter-modify' ) - ); - } - - /** - * @return bool - */ - public function canEditGlobal() { - return $this->getUser()->isAllowed( 'abusefilter-modify-global' ); - } - - /** - * Whether the user can edit the given filter. - * - * @param object $row Filter row - * - * @return bool - */ - public function canEditFilter( $row ) { - return ( - $this->canEdit() && - !( isset( $row->af_global ) && $row->af_global == 1 && !$this->canEditGlobal() ) - ); - } - - /** * @param string $rules - * @param string $textName * @param bool $addResultDiv * @param bool $externalForm * @param bool $needsModifyRights * @param-taint $rules none * @return string */ - public function buildEditBox( + protected function buildEditBox( $rules, - $textName = 'wpFilterRules', $addResultDiv = true, $externalForm = false, $needsModifyRights = true ) { $this->getOutput()->enableOOUI(); + $user = $this->getUser(); // Rules are in English - $editorAttrib = [ 'dir' => 'ltr' ]; + $editorAttribs = [ 'dir' => 'ltr' ]; $noTestAttrib = []; $isUserAllowed = $needsModifyRights ? - $this->getUser()->isAllowed( 'abusefilter-modify' ) : - $this->canViewPrivate(); + AbuseFilter::canEdit( $user ) : + AbuseFilter::canViewPrivate( $user ); if ( !$isUserAllowed ) { $noTestAttrib['disabled'] = 'disabled'; $addResultDiv = false; } $rules = rtrim( $rules ) . "\n"; - $canEdit = $needsModifyRights ? $this->canEdit() : $this->canViewPrivate(); $switchEditor = null; + $rulesContainer = ''; if ( ExtensionRegistry::getInstance()->isLoaded( 'CodeEditor' ) ) { - $editorAttrib['name'] = 'wpAceFilterEditor'; - $editorAttrib['id'] = 'wpAceFilterEditor'; - $editorAttrib['class'] = 'mw-abusefilter-editor'; + $aceAttribs = [ + 'name' => 'wpAceFilterEditor', + 'id' => 'wpAceFilterEditor', + 'class' => 'mw-abusefilter-editor' + ]; + $attribs = array_merge( $editorAttribs, $aceAttribs ); $switchEditor = new OOUI\ButtonWidget( @@ -112,35 +103,27 @@ abstract class AbuseFilterView extends ContextSource { ] + $noTestAttrib ); - $rulesContainer = Xml::element( 'div', $editorAttrib, $rules ); - - // Dummy textarea for submitting form and to use in case JS is disabled - $textareaAttribs = []; - if ( !$canEdit ) { - $textareaAttribs['readonly'] = 'readonly'; - } - if ( $externalForm ) { - $textareaAttribs['form'] = 'wpFilterForm'; - } - $rulesContainer .= Xml::textarea( $textName, $rules, 40, 15, $textareaAttribs ); - - $editorConfig = AbuseFilter::getAceConfig( $canEdit ); + $rulesContainer .= Xml::element( 'div', $attribs, $rules ); // Add Ace configuration variable + $editorConfig = AbuseFilter::getAceConfig( $isUserAllowed ); $this->getOutput()->addJsConfigVars( 'aceConfig', $editorConfig ); - } else { - if ( !$canEdit ) { - $editorAttrib['readonly'] = 'readonly'; - } - if ( $externalForm ) { - $editorAttrib['form'] = 'wpFilterForm'; - } - $rulesContainer = Xml::textarea( $textName, $rules, 40, 15, $editorAttrib ); } - if ( $canEdit ) { + // Build a dummy textarea to be used: for submitting form if CodeEditor isn't installed, + // and in case JS is disabled (with or without CodeEditor) + if ( !$isUserAllowed ) { + $editorAttribs['readonly'] = 'readonly'; + } + if ( $externalForm ) { + $editorAttribs['form'] = 'wpFilterForm'; + } + $rulesContainer .= Xml::textarea( 'wpFilterRules', $rules, 40, 15, $editorAttribs ); + + if ( $isUserAllowed ) { + $keywordsManager = AbuseFilterServices::getKeywordsManager(); // Generate builder drop-down - $rawDropDown = AbuseFilter::getBuilderValues(); + $rawDropDown = $keywordsManager->getBuilderValues(); // The array needs to be rearranged to be understood by OOUI. It comes with the format // [ group-msg-key => [ text-to-add => text-msg-key ] ] and we need it as @@ -211,14 +194,52 @@ abstract class AbuseFilterView extends ContextSource { // Add script $this->getOutput()->addModules( 'ext.abuseFilter.edit' ); - AbuseFilter::$editboxName = $textName; return $rulesContainer; } /** + * Build input and button for loading a filter + * + * @return string + */ + public function buildFilterLoader() { + $loadText = + new OOUI\TextInputWidget( + [ + 'type' => 'number', + 'name' => 'wpInsertFilter', + 'id' => 'mw-abusefilter-load-filter' + ] + ); + $loadButton = + new OOUI\ButtonWidget( + [ + 'label' => $this->msg( 'abusefilter-test-load' )->text(), + 'id' => 'mw-abusefilter-load' + ] + ); + $loadGroup = + new OOUI\ActionFieldLayout( + $loadText, + $loadButton, + [ + 'label' => $this->msg( 'abusefilter-test-load-filter' )->text() + ] + ); + // CSS class for reducing default input field width + $loadDiv = + Xml::tags( + 'div', + [ 'class' => 'mw-abusefilter-load-filter-id' ], + $loadGroup + ); + return $loadDiv; + } + + /** * @param IDatabase $db - * @param string|bool $action 'edit', 'move', 'createaccount', 'delete' or false for all + * @param string|false $action 'edit', 'move', 'createaccount', 'delete' or false for all * @return string */ public function buildTestConditions( IDatabase $db, $action = false ) { @@ -250,7 +271,18 @@ abstract class AbuseFilterView extends ContextSource { 'rc_log_type' => 'delete', 'rc_log_action' => 'delete' ], LIST_AND ); - // @ToDo: case 'upload' + case 'upload': + return $db->makeList( [ + 'rc_source' => RecentChange::SRC_LOG, + 'rc_log_type' => 'upload', + 'rc_log_action' => [ 'upload', 'overwrite', 'revert' ] + ], LIST_AND ); + case false: + // Done later + break; + default: + // @phan-suppress-next-line PhanTypeSuspiciousStringExpression False does not reach here + throw new MWException( __METHOD__ . ' called with invalid action: ' . $action ); } return $db->makeList( [ @@ -273,7 +305,10 @@ abstract class AbuseFilterView extends ContextSource { 'rc_log_type' => 'delete', 'rc_log_action' => 'delete' ], LIST_AND ), - // @todo: add upload + $db->makeList( [ + 'rc_log_type' => 'upload', + 'rc_log_action' => [ 'upload', 'overwrite', 'revert' ] + ], LIST_AND ), ], LIST_OR ), ], LIST_AND ), ], LIST_OR ); @@ -290,19 +325,4 @@ abstract class AbuseFilterView extends ContextSource { $text ); } - - /** - * @return bool - */ - public static function canViewPrivate() { - global $wgUser; - static $canView = null; - - if ( is_null( $canView ) ) { - $canView = $wgUser->isAllowedAny( 'abusefilter-modify', 'abusefilter-view-private' ); - } - - return $canView; - } - } diff --git a/AbuseFilter/includes/Views/AbuseFilterViewDiff.php b/AbuseFilter/includes/Views/AbuseFilterViewDiff.php index 8128ad65..11699a50 100644 --- a/AbuseFilter/includes/Views/AbuseFilterViewDiff.php +++ b/AbuseFilter/includes/Views/AbuseFilterViewDiff.php @@ -1,9 +1,23 @@ <?php - +/** + * @phan-file-suppress PhanTypeArraySuspiciousNullable Some confusion with class members + */ class AbuseFilterViewDiff extends AbuseFilterView { + /** + * @var (string|array)[]|null The old version of the filter + */ public $mOldVersion = null; + /** + * @var (string|array)[]|null The new version of the filter + */ public $mNewVersion = null; + /** + * @var int|null The history ID of the next version, if any + */ public $mNextHistoryId = null; + /** + * @var int|null The ID of the filter + */ public $mFilter = null; /** @@ -55,7 +69,7 @@ class AbuseFilterViewDiff extends AbuseFilterView { ] ); } - if ( !is_null( $this->mNextHistoryId ) ) { + if ( $this->mNextHistoryId !== null ) { // Create a "next change" link if this isn't the last change of the given filter $href = $this->getTitle( 'history/' . $this->mFilter . '/diff/prev/' . $this->mNextHistoryId @@ -85,21 +99,29 @@ class AbuseFilterViewDiff extends AbuseFilterView { $newSpec = $this->mParams[4]; $this->mFilter = $this->mParams[1]; - if ( AbuseFilter::filterHidden( $this->mFilter ) - && !$this->getUser()->isAllowedAny( 'abusefilter-modify', 'abusefilter-view-private' ) - ) { - $this->getOutput()->addWikiMsg( 'abusefilter-history-error-hidden' ); + if ( !is_numeric( $this->mFilter ) ) { + $this->getOutput()->addWikiMsg( 'abusefilter-diff-invalid' ); return false; } $this->mOldVersion = $this->loadSpec( $oldSpec, $newSpec ); $this->mNewVersion = $this->loadSpec( $newSpec, $oldSpec ); - if ( is_null( $this->mOldVersion ) || is_null( $this->mNewVersion ) ) { + if ( $this->mOldVersion === null || $this->mNewVersion === null ) { $this->getOutput()->addWikiMsg( 'abusefilter-diff-invalid' ); return false; } + if ( !AbuseFilter::canViewPrivate( $this->getUser() ) && + ( + in_array( 'hidden', explode( ',', $this->mOldVersion['info']['flags'] ) ) || + in_array( 'hidden', explode( ',', $this->mNewVersion['info']['flags'] ) ) + ) + ) { + $this->getOutput()->addWikiMsg( 'abusefilter-history-error-hidden' ); + return false; + } + $this->mNextHistoryId = $this->getNextHistoryId( $this->mNewVersion['meta']['history_id'] ); @@ -134,7 +156,7 @@ class AbuseFilterViewDiff extends AbuseFilterView { /** * @param string $spec * @param string $otherSpec - * @return array|null + * @return (string|array)[]|null */ public function loadSpec( $spec, $otherSpec ) { static $dependentSpecs = [ 'prev', 'next' ]; @@ -166,7 +188,7 @@ class AbuseFilterViewDiff extends AbuseFilterView { [ 'afh_id' => $spec, 'afh_filter' => $this->mFilter ], __METHOD__ ); - } elseif ( $spec == 'cur' ) { + } elseif ( $spec === 'cur' ) { $row = $dbr->selectRow( 'abuse_filter_history', $selectFields, @@ -174,39 +196,23 @@ class AbuseFilterViewDiff extends AbuseFilterView { __METHOD__, [ 'ORDER BY' => 'afh_timestamp desc' ] ); - } elseif ( $spec == 'prev' && !in_array( $otherSpec, $dependentSpecs ) ) { - // cached - $other = $this->loadSpec( $otherSpec, $spec ); - - $row = $dbr->selectRow( - 'abuse_filter_history', - $selectFields, - [ - 'afh_filter' => $this->mFilter, - 'afh_id<' . $dbr->addQuotes( $other['meta']['history_id'] ), - ], - __METHOD__, - [ 'ORDER BY' => 'afh_timestamp desc' ] - ); - if ( $other && !$row ) { - $t = $this->getTitle( - 'history/' . $this->mFilter . '/item/' . $other['meta']['history_id'] ); - $this->getOutput()->redirect( $t->getFullURL() ); - return null; - } - } elseif ( $spec == 'next' && !in_array( $otherSpec, $dependentSpecs ) ) { + } elseif ( ( $spec === 'prev' || $spec === 'next' ) && + !in_array( $otherSpec, $dependentSpecs ) + ) { // cached $other = $this->loadSpec( $otherSpec, $spec ); + $comparison = $spec === 'prev' ? '<' : '>'; + $order = $spec === 'prev' ? 'DESC' : 'ASC'; $row = $dbr->selectRow( 'abuse_filter_history', $selectFields, [ 'afh_filter' => $this->mFilter, - 'afh_id>' . $dbr->addQuotes( $other['meta']['history_id'] ), + "afh_id $comparison" . $dbr->addQuotes( $other['meta']['history_id'] ), ], __METHOD__, - [ 'ORDER BY' => 'afh_timestamp ASC' ] + [ 'ORDER BY' => "afh_timestamp $order" ] ); if ( $other && !$row ) { @@ -228,7 +234,7 @@ class AbuseFilterViewDiff extends AbuseFilterView { /** * @param stdClass $row - * @return array + * @return (string|array)[] */ public function loadFromHistoryRow( $row ) { return [ @@ -319,7 +325,7 @@ class AbuseFilterViewDiff extends AbuseFilterView { ); if ( count( $this->getConfig()->get( 'AbuseFilterValidGroups' ) ) > 1 || - $oldVersion['info']['group'] != $newVersion['info']['group'] + $oldVersion['info']['group'] !== $newVersion['info']['group'] ) { $info .= $this->getDiffRow( 'abusefilter-edit-group', @@ -329,8 +335,8 @@ class AbuseFilterViewDiff extends AbuseFilterView { } $info .= $this->getDiffRow( 'abusefilter-edit-flags', - AbuseFilter::formatFlags( $oldVersion['info']['flags'] ), - AbuseFilter::formatFlags( $newVersion['info']['flags'] ) + AbuseFilter::formatFlags( $oldVersion['info']['flags'], $this->getLanguage() ), + AbuseFilter::formatFlags( $newVersion['info']['flags'], $this->getLanguage() ) ); $info .= $this->getDiffRow( @@ -343,7 +349,6 @@ class AbuseFilterViewDiff extends AbuseFilterView { $body .= $infoHeader . $info; } - // Pattern $patternHeader = $this->getHeaderRow( 'abusefilter-diff-pattern' ); $pattern = ''; $pattern .= $this->getDiffRow( @@ -356,7 +361,6 @@ class AbuseFilterViewDiff extends AbuseFilterView { $body .= $patternHeader . $pattern; } - // Actions $actionsHeader = $this->getHeaderRow( 'abusefilter-edit-consequences' ); $actions = ''; @@ -392,7 +396,7 @@ class AbuseFilterViewDiff extends AbuseFilterView { ksort( $actions ); foreach ( $actions as $action => $parameters ) { - $lines[] = AbuseFilter::formatAction( $action, $parameters ); + $lines[] = AbuseFilter::formatAction( $action, $parameters, $this->getLanguage() ); } if ( !count( $lines ) ) { diff --git a/AbuseFilter/includes/Views/AbuseFilterViewEdit.php b/AbuseFilter/includes/Views/AbuseFilterViewEdit.php index e4c5a93e..d395564d 100644 --- a/AbuseFilter/includes/Views/AbuseFilterViewEdit.php +++ b/AbuseFilter/includes/Views/AbuseFilterViewEdit.php @@ -1,12 +1,13 @@ <?php +use MediaWiki\MediaWikiServices; + class AbuseFilterViewEdit extends AbuseFilterView { - public static $mLoadedRow = null, $mLoadedActions = null; /** * @param SpecialAbuseFilter $page * @param array $params */ - public function __construct( $page, $params ) { + public function __construct( SpecialAbuseFilter $page, array $params ) { parent::__construct( $page, $params ); $this->mFilter = $page->mFilter; $this->mHistoryID = $page->mHistoryID; @@ -19,25 +20,34 @@ class AbuseFilterViewEdit extends AbuseFilterView { $user = $this->getUser(); $out = $this->getOutput(); $request = $this->getRequest(); - $config = $this->getConfig(); $out->setPageTitle( $this->msg( 'abusefilter-edit' ) ); $out->addHelpLink( 'Extension:AbuseFilter/Rules format' ); $filter = $this->mFilter; + if ( !is_numeric( $filter ) && $filter !== 'new' ) { + $out->addHTML( + Xml::tags( + 'p', + null, + Html::errorBox( $this->msg( 'abusefilter-edit-badfilter' )->parse() ) + ) + ); + return; + } $history_id = $this->mHistoryID; if ( $this->mHistoryID ) { $dbr = wfGetDB( DB_REPLICA ); - $row = $dbr->selectRow( + $lastID = (int)$dbr->selectField( 'abuse_filter_history', 'afh_id', [ 'afh_filter' => $filter, ], __METHOD__, - [ 'ORDER BY' => 'afh_timestamp DESC' ] + [ 'ORDER BY' => 'afh_id DESC' ] ); // change $history_id to null if it's current version id - if ( $row->afh_id === $this->mHistoryID ) { + if ( $lastID === $this->mHistoryID ) { $history_id = null; } } @@ -45,7 +55,9 @@ class AbuseFilterViewEdit extends AbuseFilterView { // Add the default warning and disallow messages in a JS variable $this->exposeMessages(); - if ( $filter == 'new' && !$this->canEdit() ) { + $canEdit = AbuseFilter::canEdit( $user ); + + if ( $filter === 'new' && !$canEdit ) { $out->addHTML( Xml::tags( 'p', @@ -59,86 +71,115 @@ class AbuseFilterViewEdit extends AbuseFilterView { $editToken = $request->getVal( 'wpEditToken' ); $tokenMatches = $user->matchEditToken( $editToken, [ 'abusefilter', $filter ], $request ); + $isImport = $request->getRawVal( 'wpImportText' ) !== null; + + if ( $request->wasPosted() && $canEdit && $tokenMatches ) { + $this->saveCurrentFilter( $filter, $history_id ); + return; + } - if ( $tokenMatches && $this->canEdit() ) { - list( $newRow, $actions ) = $this->loadRequest( $filter ); - $status = AbuseFilter::saveFilter( $this, $filter, $request, $newRow, $actions ); + if ( $request->wasPosted() && !$isImport && !$tokenMatches ) { + // Special case for when the token has expired with the page open, warn to retry + $out->addHTML( + Html::warningBox( $this->msg( 'abusefilter-edit-token-not-match' )->escaped() ) + ); + } + + if ( $isImport || ( $request->wasPosted() && !$tokenMatches ) ) { + // Make sure to load from HTTP if the token doesn't match! + $status = $this->loadRequest( $filter ); if ( !$status->isGood() ) { - $err = $status->getErrors(); - $msg = $err[0]['message']; - $params = $err[0]['params']; - if ( $status->isOK() ) { - $out->addHTML( - $this->buildFilterEditor( - $this->msg( $msg, $params )->parseAsBlock(), - $filter, - $history_id - ) - ); - } else { - $out->addWikiMsg( $msg ); - } - } else { - if ( $status->getValue() === false ) { - // No change - $out->redirect( $this->getTitle()->getLocalURL() ); - } else { - list( $new_id, $history_id ) = $status->getValue(); - $out->redirect( - $this->getTitle()->getLocalURL( - [ - 'result' => 'success', - 'changedfilter' => $new_id, - 'changeid' => $history_id, - ] - ) - ); - } - } - } else { - if ( $tokenMatches ) { - // Lost rights meanwhile $out->addHTML( Xml::tags( 'p', null, - Html::errorBox( $this->msg( 'abusefilter-edit-notallowed' )->parse() ) + Html::errorBox( $status->getMessage()->parse() ) ) ); - } elseif ( $request->wasPosted() ) { - // Warn the user to re-attempt save - $out->addHTML( - Html::warningBox( $this->msg( 'abusefilter-edit-token-not-match' )->escaped() ) - ); + return; } + $data = $status->getValue(); + } else { + $data = $this->loadFromDatabase( $filter, $history_id ); + } - if ( $history_id ) { - $out->addWikiMsg( - 'abusefilter-edit-oldwarning', $history_id, $filter ); - } + list( $row, $actions ) = $data ?? [ null, [] ]; - $out->addHTML( $this->buildFilterEditor( null, $filter, $history_id ) ); + // Either the user is just viewing the filter, they cannot edit it, they lost the + // abusefilter-modify right with the page open, the token is invalid, or they're viewing + // the result of importing a filter + $this->buildFilterEditor( null, $row, $actions, $filter, $history_id ); + } - if ( $history_id ) { - $out->addWikiMsg( - 'abusefilter-edit-oldwarning', $history_id, $filter ); + /** + * @param int|string $filter The filter ID or 'new'. + * @param int|null $history_id The history ID of the filter, if applicable. Otherwise null + */ + private function saveCurrentFilter( $filter, $history_id ) : void { + $out = $this->getOutput(); + $reqStatus = $this->loadRequest( $filter ); + if ( !$reqStatus->isGood() ) { + // In the current implementation, this cannot happen. + throw new LogicException( 'Should always be able to retrieve data for saving' ); + } + list( $newRow, $actions ) = $reqStatus->getValue(); + $dbw = wfGetDB( DB_MASTER ); + $status = AbuseFilter::saveFilter( $this, $filter, $newRow, $actions, $dbw ); + + if ( !$status->isGood() ) { + $err = $status->getErrors(); + $msg = $err[0]['message']; + $params = $err[0]['params']; + if ( $status->isOK() ) { + // Fixable error, show the editing interface + $this->buildFilterEditor( + $this->msg( $msg, $params )->parseAsBlock(), + $newRow, + $actions, + $filter, + $history_id + ); + } else { + // Permission-related error + $out->addWikiMsg( $msg ); } + } elseif ( $status->getValue() === false ) { + // No change + $out->redirect( $this->getTitle()->getLocalURL() ); + } else { + // Everything went fine! + list( $new_id, $history_id ) = $status->getValue(); + $out->redirect( + $this->getTitle()->getLocalURL( + [ + 'result' => 'success', + 'changedfilter' => $new_id, + 'changeid' => $history_id, + ] + ) + ); } } /** - * Builds the full form for edit filters. - * Loads data either from the database or from the HTTP request. - * The request takes precedence over the database + * Builds the full form for edit filters, adding it to the OutputPage. $row and $actions can be + * passed in (for instance if there was a failure during save) to avoid searching the DB. + * * @param string|null $error An error message to show above the filter box. - * @param int $filter The filter ID + * @param stdClass|null $row abuse_filter row representing this filter, null if it doesn't exist + * @param array $actions Actions enabled and their parameters + * @param int|string $filter The filter ID or 'new'. * @param int|null $history_id The history ID of the filter, if applicable. Otherwise null - * @return bool|string False if there is a failure building the editor, - * otherwise the HTML text for the editor. */ - public function buildFilterEditor( $error, $filter, $history_id = null ) { + protected function buildFilterEditor( + $error, + ?stdClass $row, + array $actions, + $filter, + $history_id + ) { if ( $filter === null ) { - return false; + return; } // Build the edit form @@ -148,10 +189,11 @@ class AbuseFilterViewEdit extends AbuseFilterView { $lang = $this->getLanguage(); $user = $this->getUser(); - // Load from request OR database. - list( $row, $actions ) = $this->loadRequest( $filter, $history_id ); - - if ( !$row ) { + if ( + $row === null || + // @fixme Temporary stopgap for T237887 + ( $history_id && $row->af_id !== $filter ) + ) { $out->addHTML( Xml::tags( 'p', @@ -165,44 +207,53 @@ class AbuseFilterViewEdit extends AbuseFilterView { 'href' => $href ] ); $out->addHTML( $btn ); - return false; + return; } $out->addSubtitle( $this->msg( $filter === 'new' ? 'abusefilter-edit-subtitle-new' : 'abusefilter-edit-subtitle', - $this->getLanguage()->formatNum( $filter ), $history_id + $filter === 'new' ? $filter : $this->getLanguage()->formatNum( $filter ), + $history_id )->parse() ); // Hide hidden filters. - if ( ( ( isset( $row->af_hidden ) && $row->af_hidden ) || - AbuseFilter::filterHidden( $filter ) ) - && !$this->canViewPrivate() ) { - return $this->msg( 'abusefilter-edit-denied' )->escaped(); + if ( + ( $row->af_hidden || ( $filter !== 'new' && AbuseFilter::filterHidden( $filter ) ) ) && + !AbuseFilter::canViewPrivate( $user ) + ) { + $out->addHTML( $this->msg( 'abusefilter-edit-denied' )->escaped() ); + return; } - $output = ''; - if ( $error ) { - $output .= Html::errorBox( $error ); + if ( $history_id ) { + $oldWarningMessage = AbuseFilter::canEditFilter( $user, $row ) + ? 'abusefilter-edit-oldwarning' + : 'abusefilter-edit-oldwarning-view'; + $out->addWikiMsg( + $oldWarningMessage, + $history_id, + $filter + ); } - // Read-only attribute - $readOnlyAttrib = []; - - if ( !$this->canEditFilter( $row ) ) { - $readOnlyAttrib['disabled'] = 'disabled'; + if ( $error ) { + $out->addHTML( Html::errorBox( $error ) ); } + $readOnly = !AbuseFilter::canEditFilter( $user, $row ); + $fields = []; $fields['abusefilter-edit-id'] = - $this->mFilter == 'new' ? + $this->mFilter === 'new' ? $this->msg( 'abusefilter-edit-new' )->escaped() : $lang->formatNum( $filter ); $fields['abusefilter-edit-description'] = new OOUI\TextInputWidget( [ 'name' => 'wpFilterDescription', - 'value' => $row->af_public_comments ?? '' - ] + $readOnlyAttrib + 'value' => $row->af_public_comments ?? '', + 'readOnly' => $readOnly + ] ); $validGroups = $this->getConfig()->get( 'AbuseFilterValidGroups' ); @@ -212,7 +263,7 @@ class AbuseFilterViewEdit extends AbuseFilterView { 'name' => 'wpFilterGroup', 'id' => 'mw-abusefilter-edit-group-input', 'value' => 'default', - 'disabled' => !empty( $readOnlyAttrib ) + 'disabled' => $readOnly ] ); $options = []; @@ -231,7 +282,7 @@ class AbuseFilterViewEdit extends AbuseFilterView { } // Hit count display - if ( !empty( $row->af_hit_count ) && $user->isAllowed( 'abusefilter-log-detail' ) ) { + if ( !empty( $row->af_hit_count ) && SpecialAbuseLog::canSeeDetails( $user ) ) { $count_display = $this->msg( 'abusefilter-hitcount' ) ->numParams( (int)$row->af_hit_count )->text(); $hitCount = $this->linkRenderer->makeKnownLink( @@ -244,39 +295,31 @@ class AbuseFilterViewEdit extends AbuseFilterView { $fields['abusefilter-edit-hitcount'] = $hitCount; } - if ( $filter !== 'new' ) { + if ( $filter !== 'new' && $row->af_enabled ) { // Statistics - $stash = ObjectCache::getMainStashInstance(); - $matches_count = (int)$stash->get( AbuseFilter::filterMatchesKey( $filter ) ); - $total = (int)$stash->get( AbuseFilter::filterUsedKey( $row->af_group ) ); - - if ( $total > 0 ) { - $matches_percent = sprintf( '%.2f', 100 * $matches_count / $total ); - if ( $this->getConfig()->get( 'AbuseFilterProfile' ) ) { - list( $timeProfile, $condProfile ) = AbuseFilter::getFilterProfile( $filter ); - $fields['abusefilter-edit-status-label'] = $this->msg( 'abusefilter-edit-status-profile' ) - ->numParams( $total, $matches_count, $matches_percent, $timeProfile, $condProfile ) - ->escaped(); - } else { - $fields['abusefilter-edit-status-label'] = $this->msg( 'abusefilter-edit-status' ) - ->numParams( $total, $matches_count, $matches_percent ) - ->parse(); - } + list( $totalCount, $matchesCount, $avgTime, $avgCond ) = + AbuseFilter::getFilterProfile( $filter ); + + if ( $totalCount > 0 ) { + $matchesPercent = round( 100 * $matchesCount / $totalCount, 2 ); + $fields['abusefilter-edit-status-label'] = $this->msg( 'abusefilter-edit-status' ) + ->numParams( $totalCount, $matchesCount, $matchesPercent, $avgTime, $avgCond ) + ->parse(); } } $fields['abusefilter-edit-rules'] = $this->buildEditBox( $row->af_pattern, - 'wpFilterRules', true ); $fields['abusefilter-edit-notes'] = new OOUI\MultilineTextInputWidget( [ 'name' => 'wpFilterNotes', 'value' => isset( $row->af_comments ) ? $row->af_comments . "\n" : "\n", - 'rows' => 15 - ] + $readOnlyAttrib - ); + 'rows' => 15, + 'readOnly' => $readOnly, + 'id' => 'mw-abusefilter-notes-editor' + ] ); // Build checkboxes $checkboxes = [ 'hidden', 'enabled', 'deleted' ]; @@ -301,12 +344,10 @@ class AbuseFilterViewEdit extends AbuseFilterView { array_keys( $throttledActions ) ); - $flags .= $out->parse( - Html::warningBox( - $this->msg( 'abusefilter-edit-throttled-warning' ) - ->plaintextParams( $lang->commaList( $throttledActions ) ) - ->text() - ) + $flags .= Html::warningBox( + $this->msg( 'abusefilter-edit-throttled-warning' ) + ->plaintextParams( $lang->commaList( $throttledActions ) ) + ->parseAsBlock() ); } } @@ -325,25 +366,26 @@ class AbuseFilterViewEdit extends AbuseFilterView { 'name' => $postVar, 'id' => $postVar, 'selected' => $row->$dbField ?? false, - ] + $readOnlyAttrib; + 'disabled' => $readOnly + ]; $labelAttribs = [ 'label' => $this->msg( $message )->text(), 'align' => 'inline', ]; - if ( $checkboxId == 'global' && !$this->canEditGlobal() ) { + if ( $checkboxId === 'global' && !AbuseFilter::canEditGlobal( $user ) ) { $checkboxAttribs['disabled'] = 'disabled'; } // Set readonly on deleted if the filter isn't disabled - if ( $checkboxId == 'deleted' && $row->af_enabled == 1 ) { + if ( $checkboxId === 'deleted' && $row->af_enabled == 1 ) { $checkboxAttribs['disabled'] = 'disabled'; } // Add infusable where needed - if ( $checkboxId == 'deleted' || $checkboxId == 'enabled' ) { + if ( $checkboxId === 'deleted' || $checkboxId === 'enabled' ) { $checkboxAttribs['infusable'] = true; - if ( $checkboxId == 'deleted' ) { + if ( $checkboxId === 'deleted' ) { $labelAttribs['id'] = $postVar . 'Label'; $labelAttribs['infusable'] = true; } @@ -358,10 +400,12 @@ class AbuseFilterViewEdit extends AbuseFilterView { } $fields['abusefilter-edit-flags'] = $flags; - $tools = ''; - if ( $filter != 'new' ) { - if ( $user->isAllowed( 'abusefilter-revert' ) ) { + if ( $filter !== 'new' ) { + $tools = ''; + if ( MediaWikiServices::getInstance()->getPermissionManager() + ->userHasRight( $user, 'abusefilter-revert' ) + ) { $tools .= Xml::tags( 'p', null, $this->linkRenderer->makeLink( @@ -371,7 +415,7 @@ class AbuseFilterViewEdit extends AbuseFilterView { ); } - if ( $this->canEdit() ) { + if ( AbuseFilter::canViewPrivate( $user ) ) { // Test link $tools .= Xml::tags( 'p', null, @@ -407,21 +451,21 @@ class AbuseFilterViewEdit extends AbuseFilterView { $history_display = new HtmlArmor( $this->msg( 'abusefilter-edit-viewhistory' )->parse() ); $fields['abusefilter-edit-history'] = $this->linkRenderer->makeKnownLink( $this->getTitle( 'history/' . $filter ), $history_display ); - } - // Add export - $exportText = FormatJson::encode( [ 'row' => $row, 'actions' => $actions ] ); - $tools .= Xml::tags( 'a', [ 'href' => '#', 'id' => 'mw-abusefilter-export-link' ], - $this->msg( 'abusefilter-edit-export' )->parse() ); - $tools .= - new OOUI\MultilineTextInputWidget( [ - 'id' => 'mw-abusefilter-export', - 'readOnly' => true, - 'value' => $exportText, - 'rows' => 10 - ] ); + // Add export + $exportText = FormatJson::encode( [ 'row' => $row, 'actions' => $actions ] ); + $tools .= Xml::tags( 'a', [ 'href' => '#', 'id' => 'mw-abusefilter-export-link' ], + $this->msg( 'abusefilter-edit-export' )->parse() ); + $tools .= + new OOUI\MultilineTextInputWidget( [ + 'id' => 'mw-abusefilter-export', + 'readOnly' => true, + 'value' => $exportText, + 'rows' => 10 + ] ); - $fields['abusefilter-edit-tools'] = $tools; + $fields['abusefilter-edit-tools'] = $tools; + } $form = Xml::buildForm( $fields ); $form = Xml::fieldset( $this->msg( 'abusefilter-edit-main' )->text(), $form ); @@ -430,7 +474,7 @@ class AbuseFilterViewEdit extends AbuseFilterView { $this->buildConsequenceEditor( $row, $actions ) ); - if ( $this->canEditFilter( $row ) ) { + if ( AbuseFilter::canEditFilter( $user, $row ) ) { $form .= new OOUI\ButtonInputWidget( [ 'type' => 'submit', @@ -448,24 +492,28 @@ class AbuseFilterViewEdit extends AbuseFilterView { $form = Xml::tags( 'form', [ 'action' => $this->getTitle( $filter )->getFullURL(), - 'method' => 'post' + 'method' => 'post', + 'id' => 'mw-abusefilter-editing-form' ], $form ); - $output .= $form; + $out->addHTML( $form ); - return $output; + if ( $history_id ) { + // @phan-suppress-next-line PhanPossiblyUndeclaredVariable + $out->addWikiMsg( $oldWarningMessage, $history_id, $filter ); + } } /** * Builds the "actions" editor for a given filter. * @param stdClass $row A row from the abuse_filter table. - * @param array $actions Array of rows from the abuse_filter_action table + * @param array[] $actions Array of rows from the abuse_filter_action table * corresponding to the abuse filter held in $row. * @return string HTML text for an action editor. */ - public function buildConsequenceEditor( $row, $actions ) { + private function buildConsequenceEditor( $row, array $actions ) { $enabledActions = array_filter( $this->getConfig()->get( 'AbuseFilterActions' ) ); @@ -478,11 +526,9 @@ class AbuseFilterViewEdit extends AbuseFilterView { $output = ''; foreach ( $enabledActions as $action => $_ ) { - Wikimedia\suppressWarnings(); - $params = $actions[$action]['parameters']; - Wikimedia\restoreWarnings(); + $params = $actions[$action] ?? null; $output .= $this->buildConsequenceSelector( - $action, $setActions[$action], $params, $row ); + $action, $setActions[$action], $row, $params ); } return $output; @@ -491,22 +537,19 @@ class AbuseFilterViewEdit extends AbuseFilterView { /** * @param string $action The action to build an editor for * @param bool $set Whether or not the action is activated - * @param array $parameters Action parameters * @param stdClass $row abuse_filter row object + * @param string[]|null $parameters Action parameters. Null iff $set is false. * @return string|\OOUI\FieldLayout */ - public function buildConsequenceSelector( $action, $set, $parameters, $row ) { + private function buildConsequenceSelector( $action, $set, $row, ?array $parameters ) { $config = $this->getConfig(); + $user = $this->getUser(); $actions = $config->get( 'AbuseFilterActions' ); if ( empty( $actions[$action] ) ) { return ''; } - $readOnlyAttrib = []; - - if ( !$this->canEditFilter( $row ) ) { - $readOnlyAttrib['disabled'] = 'disabled'; - } + $readOnly = !AbuseFilter::canEditFilter( $user, $row ); switch ( $action ) { case 'throttle': @@ -520,8 +563,9 @@ class AbuseFilterViewEdit extends AbuseFilterView { 'name' => 'wpFilterActionThrottle', 'id' => 'mw-abusefilter-action-checkbox-throttle', 'selected' => $set, - 'classes' => [ 'mw-abusefilter-action-checkbox' ] - ] + $readOnlyAttrib + 'classes' => [ 'mw-abusefilter-action-checkbox' ], + 'disabled' => $readOnly + ] ), [ 'label' => $this->msg( 'abusefilter-edit-action-throttle' )->text(), @@ -531,12 +575,10 @@ class AbuseFilterViewEdit extends AbuseFilterView { $throttleFields = []; if ( $set ) { - array_shift( $parameters ); - $throttleRate = explode( ',', $parameters[0] ); - $throttleCount = $throttleRate[0]; - $throttlePeriod = $throttleRate[1]; + // @phan-suppress-next-line PhanTypeArraySuspiciousNullable $parameters is array here + list( $throttleCount, $throttlePeriod ) = explode( ',', $parameters[1], 2 ); - $throttleGroups = array_slice( $parameters, 1 ); + $throttleGroups = array_slice( $parameters, 2 ); } else { $throttleCount = 3; $throttlePeriod = 60; @@ -549,8 +591,9 @@ class AbuseFilterViewEdit extends AbuseFilterView { new OOUI\TextInputWidget( [ 'type' => 'number', 'name' => 'wpFilterThrottleCount', - 'value' => $throttleCount - ] + $readOnlyAttrib + 'value' => $throttleCount, + 'readOnly' => $readOnly + ] ), [ 'label' => $this->msg( 'abusefilter-edit-throttle-count' )->text() @@ -561,21 +604,26 @@ class AbuseFilterViewEdit extends AbuseFilterView { new OOUI\TextInputWidget( [ 'type' => 'number', 'name' => 'wpFilterThrottlePeriod', - 'value' => $throttlePeriod - ] + $readOnlyAttrib + 'value' => $throttlePeriod, + 'readOnly' => $readOnly + ] ), [ 'label' => $this->msg( 'abusefilter-edit-throttle-period' )->text() ] ); - $throttleConfig = [ - 'values' => $throttleGroups, - 'label' => $this->msg( 'abusefilter-edit-throttle-groups' )->parse(), - 'disabled' => $readOnlyAttrib - ]; - $this->getOutput()->addJsConfigVars( 'throttleConfig', $throttleConfig ); - + $groupsHelpLink = Html::element( + 'a', + [ + 'href' => 'https://www.mediawiki.org/wiki/Special:MyLanguage/' . + 'Extension:AbuseFilter/Actions#Throttling', + 'target' => '_blank' + ], + $this->msg( 'abusefilter-edit-throttle-groups-help-text' )->text() + ); + $groupsHelp = $this->msg( 'abusefilter-edit-throttle-groups-help' ) + ->rawParams( $groupsHelpLink )->escaped(); $hiddenGroups = new OOUI\FieldLayout( new OOUI\MultilineTextInputWidget( [ @@ -584,20 +632,31 @@ class AbuseFilterViewEdit extends AbuseFilterView { 'rows' => 5, 'placeholder' => $this->msg( 'abusefilter-edit-throttle-hidden-placeholder' )->text(), 'infusable' => true, - 'id' => 'mw-abusefilter-hidden-throttle-field' - ] + $readOnlyAttrib + 'id' => 'mw-abusefilter-hidden-throttle-field', + 'readOnly' => $readOnly + ] ), [ 'label' => new OOUI\HtmlSnippet( $this->msg( 'abusefilter-edit-throttle-groups' )->parse() ), 'align' => 'top', - 'id' => 'mw-abusefilter-hidden-throttle' + 'id' => 'mw-abusefilter-hidden-throttle', + 'help' => new OOUI\HtmlSnippet( $groupsHelp ), + 'helpInline' => true ] ); $throttleFields['abusefilter-edit-throttle-groups'] = $hiddenGroups; + $throttleConfig = [ + 'values' => $throttleGroups, + 'label' => $this->msg( 'abusefilter-edit-throttle-groups' )->parse(), + 'disabled' => $readOnly, + 'help' => $groupsHelp + ]; + $this->getOutput()->addJsConfigVars( 'throttleConfig', $throttleConfig ); + $throttleSettings .= Xml::tags( 'div', @@ -616,8 +675,9 @@ class AbuseFilterViewEdit extends AbuseFilterView { // mw-abusefilter-action-checkbox-warn, mw-abusefilter-action-checkbox-disallow 'id' => "mw-abusefilter-action-checkbox-$action", 'selected' => $set, - 'classes' => [ 'mw-abusefilter-action-checkbox' ] - ] + $readOnlyAttrib + 'classes' => [ 'mw-abusefilter-action-checkbox' ], + 'disabled' => $readOnly + ] ), [ // abusefilter-edit-action-warn, abusefilter-edit-action-disallow @@ -644,8 +704,9 @@ class AbuseFilterViewEdit extends AbuseFilterView { $msg = $action === 'warn' ? 'abusefilter-warning' : 'abusefilter-disallowed'; } + $fields = []; $fields["abusefilter-edit-$action-message"] = - $this->getExistingSelector( $msg, !empty( $readOnlyAttrib ), $action ); + $this->getExistingSelector( $msg, $readOnly, $action ); $otherFieldName = $action === 'warn' ? 'wpFilterWarnMessageOther' : 'wpFilterDisallowMessageOther'; @@ -656,8 +717,9 @@ class AbuseFilterViewEdit extends AbuseFilterView { 'value' => $msg, // mw-abusefilter-warn-message-other, mw-abusefilter-disallow-message-other 'id' => "mw-abusefilter-$action-message-other", - 'infusable' => true - ] + $readOnlyAttrib + 'infusable' => true, + 'readOnly' => $readOnly + ] ), [ 'label' => new OOUI\HtmlSnippet( @@ -679,7 +741,9 @@ class AbuseFilterViewEdit extends AbuseFilterView { ); $buttonGroup = $previewButton; - if ( $this->getUser()->isAllowed( 'editinterface' ) ) { + if ( MediaWikiServices::getInstance()->getPermissionManager() + ->userHasRight( $user, 'editinterface' ) + ) { $editButton = new OOUI\ButtonInputWidget( [ // abusefilter-edit-warn-edit, abusefilter-edit-disallow-edit @@ -720,11 +784,8 @@ class AbuseFilterViewEdit extends AbuseFilterView { return $output; case 'tag': - if ( $set ) { - $tags = $parameters; - } else { - $tags = []; - } + $tags = $set ? $parameters : []; + '@phan-var string[] $parameters'; $output = ''; $checkbox = @@ -733,8 +794,9 @@ class AbuseFilterViewEdit extends AbuseFilterView { 'name' => 'wpFilterActionTag', 'id' => 'mw-abusefilter-action-checkbox-tag', 'selected' => $set, - 'classes' => [ 'mw-abusefilter-action-checkbox' ] - ] + $readOnlyAttrib + 'classes' => [ 'mw-abusefilter-action-checkbox' ], + 'disabled' => $readOnly + ] ), [ 'label' => $this->msg( 'abusefilter-edit-action-tag' )->text(), @@ -746,7 +808,7 @@ class AbuseFilterViewEdit extends AbuseFilterView { $tagConfig = [ 'values' => $tags, 'label' => $this->msg( 'abusefilter-edit-tag-tag' )->parse(), - 'disabled' => $readOnlyAttrib + 'disabled' => $readOnly ]; $this->getOutput()->addJsConfigVars( 'tagConfig', $tagConfig ); @@ -758,8 +820,9 @@ class AbuseFilterViewEdit extends AbuseFilterView { 'rows' => 5, 'placeholder' => $this->msg( 'abusefilter-edit-tag-hidden-placeholder' )->text(), 'infusable' => true, - 'id' => 'mw-abusefilter-hidden-tag-field' - ] + $readOnlyAttrib + 'id' => 'mw-abusefilter-hidden-tag-field', + 'readOnly' => $readOnly + ] ), [ 'label' => new OOUI\HtmlSnippet( @@ -778,12 +841,11 @@ class AbuseFilterViewEdit extends AbuseFilterView { case 'block': if ( $set && count( $parameters ) === 3 ) { // Both blocktalk and custom block durations available - $blockTalk = $parameters[0]; - $defaultAnonDuration = $parameters[1]; - $defaultUserDuration = $parameters[2]; + list( $blockTalk, $defaultAnonDuration, $defaultUserDuration ) = $parameters; } else { if ( $set && count( $parameters ) === 1 ) { // Only blocktalk available + // @phan-suppress-next-line PhanTypeArraySuspiciousNullable $parameters is array here $blockTalk = $parameters[0]; } if ( $config->get( 'AbuseFilterAnonBlockDuration' ) ) { @@ -803,8 +865,9 @@ class AbuseFilterViewEdit extends AbuseFilterView { 'name' => 'wpFilterActionBlock', 'id' => 'mw-abusefilter-action-checkbox-block', 'selected' => $set, - 'classes' => [ 'mw-abusefilter-action-checkbox' ] - ] + $readOnlyAttrib + 'classes' => [ 'mw-abusefilter-action-checkbox' ], + 'disabled' => $readOnly + ] ), [ 'label' => $this->msg( 'abusefilter-edit-action-block' )->text(), @@ -820,7 +883,7 @@ class AbuseFilterViewEdit extends AbuseFilterView { 'name' => 'wpBlockAnonDuration', 'options' => $suggestedBlocks, 'value' => $defaultAnonDuration, - 'disabled' => !$this->canEditFilter( $row ) + 'disabled' => !AbuseFilter::canEditFilter( $user, $row ) ] ); $userDuration = @@ -828,7 +891,7 @@ class AbuseFilterViewEdit extends AbuseFilterView { 'name' => 'wpBlockUserDuration', 'options' => $suggestedBlocks, 'value' => $defaultUserDuration, - 'disabled' => !$this->canEditFilter( $row ) + 'disabled' => !AbuseFilter::canEditFilter( $user, $row ) ] ); $blockOptions = []; @@ -838,9 +901,10 @@ class AbuseFilterViewEdit extends AbuseFilterView { new OOUI\CheckboxInputWidget( [ 'name' => 'wpFilterBlockTalk', 'id' => 'mw-abusefilter-action-checkbox-blocktalk', - 'selected' => isset( $blockTalk ) && $blockTalk == 'blocktalk', - 'classes' => [ 'mw-abusefilter-action-checkbox' ] - ] + $readOnlyAttrib + 'selected' => isset( $blockTalk ) && $blockTalk === 'blocktalk', + 'classes' => [ 'mw-abusefilter-action-checkbox' ], + 'disabled' => $readOnly + ] ), [ 'label' => $this->msg( 'abusefilter-edit-action-blocktalk' )->text(), @@ -889,15 +953,15 @@ class AbuseFilterViewEdit extends AbuseFilterView { 'name' => $form_field, 'id' => "mw-abusefilter-action-checkbox-$action", 'selected' => $status, - 'classes' => [ 'mw-abusefilter-action-checkbox' ] - ] + $readOnlyAttrib + 'classes' => [ 'mw-abusefilter-action-checkbox' ], + 'disabled' => $readOnly + ] ), [ 'label' => $this->msg( $message )->text(), 'align' => 'inline' ] ); - $thisAction = $thisAction; return $thisAction; } } @@ -927,7 +991,7 @@ class AbuseFilterViewEdit extends AbuseFilterView { // mw-abusefilter-warn-message-existing, mw-abusefilter-disallow-message-existing 'id' => "mw-abusefilter-$formId-message-existing", // abusefilter-warning, abusefilter-disallowed - 'value' => $warnMsg == "abusefilter-$action" ? "abusefilter-$action" : 'other', + 'value' => $warnMsg === "abusefilter-$action" ? "abusefilter-$action" : 'other', 'infusable' => true ] ); @@ -940,9 +1004,9 @@ class AbuseFilterViewEdit extends AbuseFilterView { // Find other messages. $dbr = wfGetDB( DB_REPLICA ); $pageTitlePrefix = "Abusefilter-$action"; - $res = $dbr->select( + $titles = $dbr->selectFieldValues( 'page', - [ 'page_title' ], + 'page_title', [ 'page_namespace' => 8, 'page_title LIKE ' . $dbr->addQuotes( $pageTitlePrefix . '%' ) @@ -951,19 +1015,19 @@ class AbuseFilterViewEdit extends AbuseFilterView { ); $lang = $this->getLanguage(); - foreach ( $res as $row ) { - if ( $lang->lcfirst( $row->page_title ) == $lang->lcfirst( $warnMsg ) ) { + foreach ( $titles as $title ) { + if ( $lang->lcfirst( $title ) === $lang->lcfirst( $warnMsg ) ) { $existingSelector->setValue( $lang->lcfirst( $warnMsg ) ); } - if ( $row->page_title != "Abusefilter-$action" ) { - $options += [ $lang->lcfirst( $row->page_title ) => $lang->lcfirst( $row->page_title ) ]; + if ( $title !== "Abusefilter-$action" ) { + $options[ $lang->lcfirst( $title ) ] = $lang->lcfirst( $title ); } } } // abusefilter-edit-warn-other, abusefilter-edit-disallow-other - $options += [ $this->msg( "abusefilter-edit-$formId-other" )->text() => 'other' ]; + $options[ $this->msg( "abusefilter-edit-$formId-other" )->text() ] = 'other'; $options = Xml::listDropDownOptionsOoui( $options ); $existingSelector->setOptions( $options ); @@ -987,7 +1051,7 @@ class AbuseFilterViewEdit extends AbuseFilterView { * @param array $durations * @return array */ - protected static function normalizeBlocks( $durations ) { + protected static function normalizeBlocks( array $durations ) { global $wgAbuseFilterBlockDuration, $wgAbuseFilterAnonBlockDuration; // We need to have same values since it may happen that ipblocklist // and one (or both) of the global variables use different wording @@ -1029,19 +1093,23 @@ class AbuseFilterViewEdit extends AbuseFilterView { /** * Loads filter data from the database by ID. - * @param int $id The filter's ID number - * @return array|null Either an associative array representing the filter, + * @param int|string $id The filter's ID number, or 'new' + * @return array|null Either a [ DB row, actions ] array representing the filter, * or NULL if the filter does not exist. */ public function loadFilterData( $id ) { - if ( $id == 'new' ) { - $obj = new stdClass; - $obj->af_pattern = ''; - $obj->af_enabled = 1; - $obj->af_hidden = 0; - $obj->af_global = 0; - $obj->af_throttled = 0; - return [ $obj, [] ]; + if ( $id === 'new' ) { + return [ + (object)[ + 'af_pattern' => '', + 'af_enabled' => 1, + 'af_hidden' => 0, + 'af_global' => 0, + 'af_throttled' => 0, + 'af_hit_count' => 0 + ], + [] + ]; } // Load from master to avoid unintended reversions where there's replication lag. @@ -1079,7 +1147,6 @@ class AbuseFilterViewEdit extends AbuseFilterView { } // Load the actions - $actions = []; $res = $dbr->select( 'abuse_filter_action', [ 'afa_consequence', 'afa_parameters' ], @@ -1087,57 +1154,78 @@ class AbuseFilterViewEdit extends AbuseFilterView { __METHOD__ ); + $actions = []; foreach ( $res as $actionRow ) { - $thisAction = []; - $thisAction['action'] = $actionRow->afa_consequence; - $thisAction['parameters'] = array_filter( explode( "\n", $actionRow->afa_parameters ) ); - - $actions[$actionRow->afa_consequence] = $thisAction; + $actions[$actionRow->afa_consequence] = + array_filter( explode( "\n", $actionRow->afa_parameters ) ); } return [ $row, $actions ]; } /** - * Load filter data to show in the edit view. - * Either from the HTTP request or from the filter/history_id given. - * The HTTP request always takes precedence. - * Includes caching. - * @param int $filter The filter ID being requested. + * Load filter data to show in the edit view from the DB. + * @param int|string $filter The filter ID being requested or 'new'. * @param int|null $history_id If any, the history ID being requested. * @return array|null Array with filter data if available, otherwise null. * The first element contains the abuse_filter database row, * the second element is an array of related abuse_filter_action rows. */ - public function loadRequest( $filter, $history_id = null ) { - $row = self::$mLoadedRow; - $actions = self::$mLoadedActions; - $request = $this->getRequest(); - - if ( !is_null( $actions ) && !is_null( $row ) ) { - return [ $row, $actions ]; - } elseif ( $request->wasPosted() ) { - // Nothing, we do it all later - } elseif ( $history_id ) { + private function loadFromDatabase( $filter, $history_id = null ) { + if ( $history_id ) { return $this->loadHistoryItem( $history_id ); } else { return $this->loadFilterData( $filter ); } + } + + /** + * Load data from the already-POSTed HTTP request. + * + * @throws BadMethodCallException If called without the request being POSTed or when trying + * to import a filter but $filter is not 'new' + * @param int|string $filter The filter ID being requested. + * @return Status If good, the value is the array [ row, actions ]. If not, it contains an + * error message. + */ + public function loadRequest( $filter ): Status { + $request = $this->getRequest(); + if ( !$request->wasPosted() ) { + // Sanity + throw new BadMethodCallException( __METHOD__ . ' called without the request being POSTed.' ); + } // We need some details like last editor - list( $row, $origActions ) = $this->loadFilterData( $filter ); + list( $origRow, $origActions ) = $this->loadFilterData( $filter ); - $row->mOriginalRow = clone $row; + // Default values + $row = (object)[ + 'af_throttled' => $origRow->af_throttled, + 'af_hit_count' => $origRow->af_hit_count, + ]; + $row->mOriginalRow = $origRow; $row->mOriginalActions = $origActions; // Check for importing $import = $request->getVal( 'wpImportText' ); if ( $import ) { + if ( $filter !== 'new' ) { + // Sanity + throw new BadMethodCallException( __METHOD__ . ' called for importing on existing filter.' ); + } $data = FormatJson::decode( $import ); + if ( !$this->isValidImportData( $data ) ) { + return Status::newFatal( 'abusefilter-import-invalid-data' ); + } + $importRow = $data->row; $actions = wfObjectToArray( $data->actions ); + // Some more default values + $row->af_group = 'default'; + $row->af_global = 0; + $copy = [ 'af_public_comments', 'af_pattern', @@ -1151,6 +1239,15 @@ class AbuseFilterViewEdit extends AbuseFilterView { $row->$name = $importRow->$name; } } else { + if ( $filter !== 'new' ) { + // These aren't needed when saving the filter, but they are otherwise (e.g. if + // saving fails and we need to show the edit interface again). + $row->af_id = $origRow->af_id; + $row->af_user = $origRow->af_user; + $row->af_user_text = $origRow->af_user_text; + $row->af_timestamp = $origRow->af_timestamp; + } + $textLoads = [ 'af_public_comments' => 'wpFilterDescription', 'af_pattern' => 'wpFilterRules', @@ -1169,7 +1266,6 @@ class AbuseFilterViewEdit extends AbuseFilterView { $row->af_global = $request->getCheck( 'wpFilterGlobal' ) && $this->getConfig()->get( 'AbuseFilterIsCentral' ); - // Actions $actions = []; foreach ( array_filter( $this->getConfig()->get( 'AbuseFilterActions' ) ) as $action => $_ ) { // Check if it's set @@ -1178,7 +1274,7 @@ class AbuseFilterViewEdit extends AbuseFilterView { if ( $enabled ) { $parameters = []; - if ( $action == 'throttle' ) { + if ( $action === 'throttle' ) { // We need to load the parameters $throttleCount = $request->getIntOrNull( 'wpFilterThrottleCount' ); $throttlePeriod = $request->getIntOrNull( 'wpFilterThrottlePeriod' ); @@ -1198,52 +1294,55 @@ class AbuseFilterViewEdit extends AbuseFilterView { $parameters[0] = $this->mFilter; $parameters[1] = "$throttleCount,$throttlePeriod"; $parameters = array_merge( $parameters, $throttleGroups ); - } elseif ( $action == 'warn' ) { + } elseif ( $action === 'warn' ) { $specMsg = $request->getVal( 'wpFilterWarnMessage' ); - if ( $specMsg == 'other' ) { + if ( $specMsg === 'other' ) { $specMsg = $request->getVal( 'wpFilterWarnMessageOther' ); } $parameters[0] = $specMsg; - } elseif ( $action == 'block' ) { + } elseif ( $action === 'block' ) { $parameters[0] = $request->getCheck( 'wpFilterBlockTalk' ) ? 'blocktalk' : 'noTalkBlockSet'; $parameters[1] = $request->getVal( 'wpBlockAnonDuration' ); $parameters[2] = $request->getVal( 'wpBlockUserDuration' ); - } elseif ( $action == 'disallow' ) { + } elseif ( $action === 'disallow' ) { $specMsg = $request->getVal( 'wpFilterDisallowMessage' ); - if ( $specMsg == 'other' ) { + if ( $specMsg === 'other' ) { $specMsg = $request->getVal( 'wpFilterDisallowMessageOther' ); } $parameters[0] = $specMsg; - } elseif ( $action == 'tag' ) { + } elseif ( $action === 'tag' ) { $parameters = explode( ',', trim( $request->getText( 'wpFilterTags' ) ) ); + if ( $parameters === [ '' ] ) { + // Since it's not possible to manually add an empty tag, this only happens + // if the form is submitted without touching the tag input field. + // We pass an empty array so that the widget won't show an empty tag in the topbar + $parameters = []; + } } - $thisAction = [ 'action' => $action, 'parameters' => $parameters ]; - $actions[$action] = $thisAction; + $actions[$action] = $parameters; } } } - $row->af_actions = implode( ',', array_keys( array_filter( $actions ) ) ); + $row->af_actions = implode( ',', array_keys( $actions ) ); - self::$mLoadedRow = $row; - self::$mLoadedActions = $actions; - return [ $row, $actions ]; + return Status::newGood( [ $row, $actions ] ); } /** * Loads historical data in a form that the editor can understand. * @param int $id History ID - * @return array|bool False if the history ID is not valid, otherwise array in the usual format: + * @return array|null Null if the history ID is not valid, otherwise array in the usual format: * First element contains the abuse_filter row (as it was). * Second element contains an array of abuse_filter_action rows. */ - public function loadHistoryItem( $id ) { + private function loadHistoryItem( $id ) : ?array { $dbr = wfGetDB( DB_REPLICA ); $row = $dbr->selectRow( 'abuse_filter_history', @@ -1253,7 +1352,7 @@ class AbuseFilterViewEdit extends AbuseFilterView { ); if ( !$row ) { - return false; + return null; } return AbuseFilter::translateFromHistory( $row ); @@ -1272,4 +1371,42 @@ class AbuseFilterViewEdit extends AbuseFilterView { $this->getConfig()->get( 'AbuseFilterDefaultDisallowMessage' ) ); } + + /** + * Perform basic validation on the JSON-decoded import data. This doesn't check if parameters + * are valid etc., but only if the shape of the object is right. + * + * @param mixed $data Already JSON-decoded + * @return bool + */ + private function isValidImportData( $data ) { + global $wgAbuseFilterActions; + + if ( !is_object( $data ) ) { + return false; + } + + $arr = get_object_vars( $data ); + + $expectedKeys = [ 'row' => true, 'actions' => true ]; + if ( count( $arr ) !== count( $expectedKeys ) || array_diff_key( $arr, $expectedKeys ) ) { + return false; + } + + if ( !is_object( $arr['row'] ) || !is_object( $arr['actions'] ) ) { + return false; + } + + foreach ( $arr['actions'] as $action => $params ) { + if ( !array_key_exists( $action, $wgAbuseFilterActions ) || !is_array( $params ) ) { + return false; + } + } + + if ( !AbuseFilter::isFullAbuseFilterRow( $arr['row'] ) ) { + return false; + } + + return true; + } } diff --git a/AbuseFilter/includes/Views/AbuseFilterViewExamine.php b/AbuseFilter/includes/Views/AbuseFilterViewExamine.php index 6c3d065c..6ef6354d 100644 --- a/AbuseFilter/includes/Views/AbuseFilterViewExamine.php +++ b/AbuseFilter/includes/Views/AbuseFilterViewExamine.php @@ -1,10 +1,29 @@ <?php -class AbuseFilterViewExamine extends AbuseFilterView { - public static $examineType = null; - public static $examineId = null; +use MediaWiki\Extension\AbuseFilter\VariableGenerator\RCVariableGenerator; +use MediaWiki\MediaWikiServices; +use MediaWiki\Revision\RevisionRecord; - public $mCounter, $mSearchUser, $mSearchPeriodStart, $mSearchPeriodEnd; +class AbuseFilterViewExamine extends AbuseFilterView { + /** + * @var int Line number of the row, see RecentChange::$counter + */ + public $mCounter; + /** + * @var string The user whose entries we're examinating + */ + public $mSearchUser; + /** + * @var string The start time of the search period + */ + public $mSearchPeriodStart; + /** + * @var string The end time of the search period + */ + public $mSearchPeriodEnd; + /** + * @var string The ID of the filter we're examinating + */ public $mTestFilter; /** @@ -21,7 +40,7 @@ class AbuseFilterViewExamine extends AbuseFilterView { if ( count( $this->mParams ) > 1 && is_numeric( $this->mParams[1] ) ) { $this->showExaminerForRC( $this->mParams[1] ); } elseif ( count( $this->mParams ) > 2 - && $this->mParams[1] == 'log' + && $this->mParams[1] === 'log' && is_numeric( $this->mParams[2] ) ) { $this->showExaminerForLogEntry( $this->mParams[2] ); @@ -96,32 +115,26 @@ class AbuseFilterViewExamine extends AbuseFilterView { */ public function showExaminerForRC( $rcid ) { // Get data - $dbr = wfGetDB( DB_REPLICA ); - $rcQuery = RecentChange::getQueryInfo(); - $row = $dbr->selectRow( - $rcQuery['tables'], - $rcQuery['fields'], - [ 'rc_id' => $rcid ], - __METHOD__, - [], - $rcQuery['joins'] - ); + $rc = RecentChange::newFromId( $rcid ); $out = $this->getOutput(); - if ( !$row ) { + if ( !$rc ) { $out->addWikiMsg( 'abusefilter-examine-notfound' ); return; } - if ( !ChangesList::userCan( RecentChange::newFromRow( $row ), Revision::SUPPRESSED_ALL ) ) { + if ( !ChangesList::userCan( $rc, RevisionRecord::SUPPRESSED_ALL ) ) { $out->addWikiMsg( 'abusefilter-log-details-hidden-implicit' ); return; } - self::$examineType = 'rc'; - self::$examineId = $rcid; + $vars = new AbuseFilterVariableHolder(); + $varGenerator = new RCVariableGenerator( $vars, $rc, $this->getUser() ); + $vars = $varGenerator->getVars(); + $out->addJsConfigVars( [ + 'wgAbuseFilterVariables' => $vars ? $vars->dumpAllVars( true ) : [], + 'abuseFilterExamine' => [ 'type' => 'rc', 'id' => $rcid ] + ] ); - $vars = AbuseFilter::getVarsFromRCRow( $row ); - $out->addJsConfigVars( 'wgAbuseFilterVariables', $vars->dumpAllVars( true ) ); $this->showExaminer( $vars ); } @@ -131,6 +144,9 @@ class AbuseFilterViewExamine extends AbuseFilterView { public function showExaminerForLogEntry( $logid ) { // Get data $dbr = wfGetDB( DB_REPLICA ); + $user = $this->getUser(); + $out = $this->getOutput(); + $row = $dbr->selectRow( 'abuse_filter_log', [ @@ -142,35 +158,37 @@ class AbuseFilterViewExamine extends AbuseFilterView { [ 'afl_id' => $logid ], __METHOD__ ); - $out = $this->getOutput(); if ( !$row ) { $out->addWikiMsg( 'abusefilter-examine-notfound' ); return; } - self::$examineType = 'log'; - self::$examineId = $logid; - - if ( !SpecialAbuseLog::canSeeDetails( $row->afl_filter ) ) { + list( $filterID, $global ) = AbuseFilter::splitGlobalName( $row->afl_filter ); + if ( !SpecialAbuseLog::canSeeDetails( $user, $filterID, $global ) ) { $out->addWikiMsg( 'abusefilter-log-cannot-see-details' ); return; } - if ( $row->afl_deleted && !SpecialAbuseLog::canSeeHidden() ) { + if ( $row->afl_deleted && !SpecialAbuseLog::canSeeHidden( $user ) ) { $out->addWikiMsg( 'abusefilter-log-details-hidden' ); return; } if ( SpecialAbuseLog::isHidden( $row ) === 'implicit' ) { - $rev = Revision::newFromId( $row->afl_rev_id ); - if ( !$rev->userCan( Revision::SUPPRESSED_ALL, $this->getUser() ) ) { + $revRec = MediaWikiServices::getInstance() + ->getRevisionLookup() + ->getRevisionById( (int)$row->afl_rev_id ); + if ( !AbuseFilter::userCanViewRev( $revRec, $user ) ) { $out->addWikiMsg( 'abusefilter-log-details-hidden-implicit' ); return; } } $vars = AbuseFilter::loadVarDump( $row->afl_var_dump ); - $out->addJsConfigVars( 'wgAbuseFilterVariables', $vars->dumpAllVars( true ) ); + $out->addJsConfigVars( [ + 'wgAbuseFilterVariables' => $vars->dumpAllVars( true ), + 'abuseFilterExamine' => [ 'type' => 'log', 'id' => $logid ] + ] ); $this->showExaminer( $vars ); } @@ -195,10 +213,10 @@ class AbuseFilterViewExamine extends AbuseFilterView { $output->addModules( 'ext.abuseFilter.examine' ); // Add test bit - if ( $this->canViewPrivate() ) { + if ( AbuseFilter::canViewPrivate( $this->getUser() ) ) { $tester = Xml::tags( 'h2', null, $this->msg( 'abusefilter-examine-test' )->parse() ); - $tester .= $this->buildEditBox( $this->mTestFilter, 'wpTestFilter', false, false, false ); - $tester .= AbuseFilter::buildFilterLoader(); + $tester .= $this->buildEditBox( $this->mTestFilter, false, false, false ); + $tester .= $this->buildFilterLoader(); $html .= Xml::tags( 'div', [ 'id' => 'mw-abusefilter-examine-editor' ], $tester ); $html .= Xml::tags( 'p', null, diff --git a/AbuseFilter/includes/Views/AbuseFilterViewHistory.php b/AbuseFilter/includes/Views/AbuseFilterViewHistory.php index 66a14a56..f25d0a4e 100644 --- a/AbuseFilter/includes/Views/AbuseFilterViewHistory.php +++ b/AbuseFilter/includes/Views/AbuseFilterViewHistory.php @@ -5,7 +5,7 @@ class AbuseFilterViewHistory extends AbuseFilterView { * @param SpecialAbuseFilter $page * @param array $params */ - public function __construct( $page, $params ) { + public function __construct( SpecialAbuseFilter $page, $params ) { parent::__construct( $page, $params ); $this->mFilter = $page->mFilter; } @@ -17,6 +17,8 @@ class AbuseFilterViewHistory extends AbuseFilterView { $out = $this->getOutput(); $out->enableOOUI(); $filter = $this->getRequest()->getText( 'filter' ) ?: $this->mFilter; + // Ensure the parameter is a valid filter ID + $filter = (int)$filter; if ( $filter ) { $out->setPageTitle( $this->msg( 'abusefilter-history' )->numParams( $filter ) ); @@ -24,9 +26,8 @@ class AbuseFilterViewHistory extends AbuseFilterView { $out->setPageTitle( $this->msg( 'abusefilter-filter-log' ) ); } - // Check perms. abusefilter-modify is a superset of abusefilter-view-private if ( $filter && AbuseFilter::filterHidden( $filter ) - && !$this->getUser()->isAllowedAny( 'abusefilter-modify', 'abusefilter-view-private' ) + && !AbuseFilter::canViewPrivate( $this->getUser() ) ) { $out->addWikiMsg( 'abusefilter-history-error-hidden' ); return; @@ -75,9 +76,9 @@ class AbuseFilterViewHistory extends AbuseFilterView { 'label-message' => 'abusefilter-history-select-user' ], 'filter' => [ - 'type' => 'text', + 'type' => 'int', 'name' => 'filter', - 'default' => $filter, + 'default' => $filter ?: '', 'size' => '45', 'label-message' => 'abusefilter-history-select-filter' ], @@ -93,10 +94,6 @@ class AbuseFilterViewHistory extends AbuseFilterView { $pager = new AbuseFilterHistoryPager( $filter, $this, $user, $this->linkRenderer ); - $out->addHTML( - $pager->getNavigationBar() . - $pager->getBody() . - $pager->getNavigationBar() - ); + $out->addParserOutputContent( $pager->getFullOutput() ); } } diff --git a/AbuseFilter/includes/Views/AbuseFilterViewImport.php b/AbuseFilter/includes/Views/AbuseFilterViewImport.php index 01e2fc85..80dc8c98 100644 --- a/AbuseFilter/includes/Views/AbuseFilterViewImport.php +++ b/AbuseFilter/includes/Views/AbuseFilterViewImport.php @@ -6,7 +6,7 @@ class AbuseFilterViewImport extends AbuseFilterView { */ public function show() { $out = $this->getOutput(); - if ( !$this->getUser()->isAllowed( 'abusefilter-modify' ) ) { + if ( !AbuseFilter::canEdit( $this->getUser() ) ) { $out->addWikiMsg( 'abusefilter-edit-notallowed' ); return; } @@ -17,9 +17,10 @@ class AbuseFilterViewImport extends AbuseFilterView { $formDescriptor = [ 'ImportText' => [ 'type' => 'textarea', + 'required' => true ] ]; - $htmlform = HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() ) + HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() ) ->setSubmitTextMsg( 'abusefilter-import-submit' ) ->setAction( $url ) ->show(); diff --git a/AbuseFilter/includes/Views/AbuseFilterViewList.php b/AbuseFilter/includes/Views/AbuseFilterViewList.php index ad92ad6c..efbf6217 100644 --- a/AbuseFilter/includes/Views/AbuseFilterViewList.php +++ b/AbuseFilter/includes/Views/AbuseFilterViewList.php @@ -1,5 +1,7 @@ <?php +use MediaWiki\MediaWikiServices; + /** * The default view used in Special:AbuseFilter */ @@ -11,6 +13,7 @@ class AbuseFilterViewList extends AbuseFilterView { $out = $this->getOutput(); $request = $this->getRequest(); $config = $this->getConfig(); + $user = $this->getUser(); // Show filter performance statistics $this->showStatus(); @@ -18,18 +21,27 @@ class AbuseFilterViewList extends AbuseFilterView { $out->addWikiMsg( 'abusefilter-intro' ); // New filter button - if ( $this->canEdit() ) { + if ( AbuseFilter::canEdit( $user ) ) { $out->enableOOUI(); - $link = new OOUI\ButtonWidget( [ - 'label' => $this->msg( 'abusefilter-new' )->text(), - 'href' => $this->getTitle( 'new' )->getFullURL(), + $buttons = new OOUI\HorizontalLayout( [ + 'items' => [ + new OOUI\ButtonWidget( [ + 'label' => $this->msg( 'abusefilter-new' )->text(), + 'href' => $this->getTitle( 'new' )->getFullURL(), + ] ), + new OOUI\ButtonWidget( [ + 'label' => $this->msg( 'abusefilter-import-button' )->text(), + 'href' => $this->getTitle( 'import' )->getFullURL(), + ] ) + ] ] ); - $out->addHTML( $link ); + $out->addHTML( $buttons ); } $conds = []; $deleted = $request->getVal( 'deletedfilters' ); $furtherOptions = $request->getArray( 'furtheroptions', [] ); + '@phan-var array $furtherOptions'; // Backward compatibility with old links if ( $request->getBool( 'hidedisabled' ) ) { $furtherOptions[] = 'hidedisabled'; @@ -45,22 +57,22 @@ class AbuseFilterViewList extends AbuseFilterView { } $scope = $request->getVal( 'rulescope', $defaultscope ); - $searchEnabled = $this->canViewPrivate() && !( + $searchEnabled = AbuseFilter::canViewPrivate( $user ) && !( $config->get( 'AbuseFilterCentralDB' ) !== null && !$config->get( 'AbuseFilterIsCentral' ) && - $scope == 'global' ); + $scope === 'global' ); if ( $searchEnabled ) { - $querypattern = $request->getVal( 'querypattern' ); + $querypattern = $request->getVal( 'querypattern', '' ); $searchmode = $request->getVal( 'searchoption', 'LIKE' ); } else { $querypattern = ''; $searchmode = ''; } - if ( $deleted == 'show' ) { + if ( $deleted === 'show' ) { // Nothing - } elseif ( $deleted == 'only' ) { + } elseif ( $deleted === 'only' ) { $conds['af_deleted'] = 1; } else { // hide, or anything else. @@ -75,79 +87,57 @@ class AbuseFilterViewList extends AbuseFilterView { $conds['af_hidden'] = 0; } - if ( $scope == 'local' ) { + if ( $scope === 'local' ) { $conds['af_global'] = 0; - } elseif ( $scope == 'global' ) { + } elseif ( $scope === 'global' ) { $conds['af_global'] = 1; } - $dbr = wfGetDB( DB_REPLICA ); - if ( $querypattern !== '' ) { - if ( $searchmode !== 'LIKE' ) { - // Check regex pattern validity - Wikimedia\suppressWarnings(); - $validreg = preg_match( '/' . $querypattern . '/', null ); - Wikimedia\restoreWarnings(); + // Check the search pattern. Filtering the results is done in AbuseFilterPager + $error = null; + if ( !in_array( $searchmode, [ 'LIKE', 'RLIKE', 'IRLIKE' ] ) ) { + $error = 'abusefilter-list-invalid-searchmode'; + } elseif ( $searchmode !== 'LIKE' && !StringUtils::isValidPCRERegex( "/$querypattern/" ) ) { + $error = 'abusefilter-list-regexerror'; + } - if ( $validreg === false ) { - $out->addHTML( - Xml::tags( - 'p', - null, - Html::errorBox( $this->msg( 'abusefilter-list-regexerror' )->parse() ) - ) - ); - $this->showList( - [ 'af_deleted' => 0 ], - compact( - 'deleted', - 'furtherOptions', - 'querypattern', - 'searchmode', - 'scope', - 'searchEnabled' - ) - ); - return; - } - if ( $searchmode === 'RLIKE' ) { - $conds[] = 'af_pattern RLIKE ' . - $dbr->addQuotes( $querypattern ); - } else { - $conds[] = 'LOWER( CAST( af_pattern AS char ) ) RLIKE ' . - strtolower( $dbr->addQuotes( $querypattern ) ); - } - } else { - // Build like query escaping tokens and encapsulating in % to search everywhere - $conds[] = 'LOWER( CAST( af_pattern AS char ) ) ' . - $dbr->buildLike( - $dbr->anyString(), - strtolower( $querypattern ), - $dbr->anyString() - ); + if ( $error !== null ) { + $out->addHTML( + Xml::tags( + 'p', + null, + Html::errorBox( $this->msg( $error )->escaped() ) + ) + ); + + // Reset the conditions in case of error + $conds = [ 'af_deleted' => 0 ]; + $querypattern = ''; } } $this->showList( - $conds, compact( 'deleted', 'furtherOptions', 'querypattern', 'searchmode', - 'scope', - 'searchEnabled' - ) + 'scope' + ), + $conds ); } /** - * @param array $conds * @param array $optarray + * @param array $conds */ - public function showList( $conds = [ 'af_deleted' => 0 ], $optarray = [] ) { + private function showList( array $optarray, array $conds = [ 'af_deleted' => 0 ] ) { + $user = $this->getUser(); $config = $this->getConfig(); + $centralDB = $config->get( 'AbuseFilterCentralDB' ); + $dbIsCentral = $config->get( 'AbuseFilterIsCentral' ); $this->getOutput()->addHTML( Xml::tags( 'h2', null, $this->msg( 'abusefilter-list' )->parse() ) ); @@ -155,15 +145,10 @@ class AbuseFilterViewList extends AbuseFilterView { $deleted = $optarray['deleted']; $furtherOptions = $optarray['furtherOptions']; $scope = $optarray['scope']; - $searchEnabled = $optarray['searchEnabled']; $querypattern = $optarray['querypattern']; $searchmode = $optarray['searchmode']; - if ( - $config->get( 'AbuseFilterCentralDB' ) !== null - && !$config->get( 'AbuseFilterIsCentral' ) - && $scope == 'global' - ) { + if ( $centralDB !== null && !$dbIsCentral && $scope === 'global' ) { $pager = new GlobalAbuseFilterPager( $this, $conds, @@ -174,31 +159,20 @@ class AbuseFilterViewList extends AbuseFilterView { $this, $conds, $this->linkRenderer, - [ $querypattern, $searchmode ] + $querypattern, + $searchmode ); } // Options form $formDescriptor = []; - $formDescriptor['deletedfilters'] = [ - 'name' => 'deletedfilters', - 'type' => 'radio', - 'flatlist' => true, - 'label-message' => 'abusefilter-list-options-deleted', - 'options-messages' => [ - 'abusefilter-list-options-deleted-show' => 'show', - 'abusefilter-list-options-deleted-hide' => 'hide', - 'abusefilter-list-options-deleted-only' => 'only', - ], - 'default' => $deleted, - ]; - if ( $config->get( 'AbuseFilterCentralDB' ) !== null ) { + if ( $centralDB !== null ) { $optionsMsg = [ 'abusefilter-list-options-scope-local' => 'local', 'abusefilter-list-options-scope-global' => 'global', ]; - if ( $config->get( 'AbuseFilterIsCentral' ) ) { + if ( $dbIsCentral ) { // For central wiki: add third scope option $optionsMsg['abusefilter-list-options-scope-all'] = 'all'; } @@ -212,6 +186,19 @@ class AbuseFilterViewList extends AbuseFilterView { ]; } + $formDescriptor['deletedfilters'] = [ + 'name' => 'deletedfilters', + 'type' => 'radio', + 'flatlist' => true, + 'label-message' => 'abusefilter-list-options-deleted', + 'options-messages' => [ + 'abusefilter-list-options-deleted-show' => 'show', + 'abusefilter-list-options-deleted-hide' => 'hide', + 'abusefilter-list-options-deleted-only' => 'only', + ], + 'default' => $deleted, + ]; + $formDescriptor['furtheroptions'] = [ 'name' => 'furtheroptions', 'type' => 'multiselect', @@ -224,11 +211,12 @@ class AbuseFilterViewList extends AbuseFilterView { 'default' => $furtherOptions ]; - // ToDo: Since this is only for saving space, we should convert it to use a 'hide-if' - if ( $searchEnabled ) { + if ( AbuseFilter::canViewPrivate( $user ) ) { + $globalEnabled = $centralDB !== null && !$dbIsCentral; $formDescriptor['querypattern'] = [ 'name' => 'querypattern', 'type' => 'text', + 'hide-if' => $globalEnabled ? [ '===', 'rulescope', 'global' ] : [], 'label-message' => 'abusefilter-list-options-searchfield', 'placeholder' => $this->msg( 'abusefilter-list-options-searchpattern' )->text(), 'default' => $querypattern @@ -239,6 +227,9 @@ class AbuseFilterViewList extends AbuseFilterView { 'type' => 'radio', 'flatlist' => true, 'label-message' => 'abusefilter-list-options-searchoptions', + 'hide-if' => $globalEnabled ? + [ 'OR', [ '===', 'querypattern', '' ], $formDescriptor['querypattern']['hide-if'] ] : + [ '===', 'querypattern', '' ], 'options-messages' => [ 'abusefilter-list-options-search-like' => 'LIKE', 'abusefilter-list-options-search-rlike' => 'RLIKE', @@ -265,37 +256,39 @@ class AbuseFilterViewList extends AbuseFilterView { ->prepareForm() ->displayForm( false ); - $this->getOutput()->addHTML( - $pager->getNavigationBar() . - $pager->getBody() . - $pager->getNavigationBar() - ); + $this->getOutput()->addParserOutputContent( $pager->getFullOutput() ); } /** - * Show stats + * Generates a summary of filter activity using the internal statistics. */ public function showStatus() { - $stash = ObjectCache::getMainStashInstance(); - $overflow_count = (int)$stash->get( AbuseFilter::filterLimitReachedKey() ); - $match_count = (int)$stash->get( AbuseFilter::filterMatchesKey() ); - $total_count = 0; + $stash = MediaWikiServices::getInstance()->getMainObjectStash(); + + $totalCount = 0; + $matchCount = 0; + $overflowCount = 0; foreach ( $this->getConfig()->get( 'AbuseFilterValidGroups' ) as $group ) { - $total_count += (int)$stash->get( AbuseFilter::filterUsedKey( $group ) ); + $profile = $stash->get( AbuseFilter::filterProfileGroupKey( $group ) ); + if ( $profile !== false ) { + $totalCount += $profile[ 'total' ]; + $overflowCount += $profile[ 'overflow' ]; + $matchCount += $profile[ 'matches' ]; + } } - if ( $total_count > 0 ) { - $overflow_percent = sprintf( "%.2f", 100 * $overflow_count / $total_count ); - $match_percent = sprintf( "%.2f", 100 * $match_count / $total_count ); + if ( $totalCount > 0 ) { + $overflowPercent = round( 100 * $overflowCount / $totalCount, 2 ); + $matchPercent = round( 100 * $matchCount / $totalCount, 2 ); $status = $this->msg( 'abusefilter-status' ) ->numParams( - $total_count, - $overflow_count, - $overflow_percent, + $totalCount, + $overflowCount, + $overflowPercent, $this->getConfig()->get( 'AbuseFilterConditionLimit' ), - $match_count, - $match_percent + $matchCount, + $matchPercent )->parse(); $status = Xml::tags( 'div', [ 'class' => 'mw-abusefilter-status' ], $status ); diff --git a/AbuseFilter/includes/Views/AbuseFilterViewRevert.php b/AbuseFilter/includes/Views/AbuseFilterViewRevert.php index 38a0d073..ab873b22 100644 --- a/AbuseFilter/includes/Views/AbuseFilterViewRevert.php +++ b/AbuseFilter/includes/Views/AbuseFilterViewRevert.php @@ -1,7 +1,28 @@ <?php +use MediaWiki\Block\DatabaseBlock; +use MediaWiki\MediaWikiServices; + class AbuseFilterViewRevert extends AbuseFilterView { - public $origPeriodStart, $origPeriodEnd, $mPeriodStart, $mPeriodEnd; + /** + * @var string The start time of the lookup period + */ + public $origPeriodStart; + /** + * @var string The end time of the lookup period + */ + public $origPeriodEnd; + /** + * @var string|null The same as $origPeriodStart + */ + public $mPeriodStart; + /** + * @var string|null The same as $origPeriodEnd + */ + public $mPeriodEnd; + /** + * @var string|null The reason provided for the revert + */ public $mReason; /** @@ -14,10 +35,17 @@ class AbuseFilterViewRevert extends AbuseFilterView { $user = $this->getUser(); $out = $this->getOutput(); - if ( !$user->isAllowed( 'abusefilter-revert' ) ) { + if ( !MediaWikiServices::getInstance()->getPermissionManager() + ->userHasRight( $user, 'abusefilter-revert' ) + ) { throw new PermissionsError( 'abusefilter-revert' ); } + $block = $user->getBlock(); + if ( $block && $block->isSitewide() ) { + throw new UserBlockedError( $block ); + } + $this->loadParameters(); if ( $this->attemptRevert() ) { @@ -33,8 +61,8 @@ class AbuseFilterViewRevert extends AbuseFilterView { $max = wfTimestampNow(); $filterLink = $this->linkRenderer->makeLink( - SpecialPage::getTitleFor( 'AbuseFilter', intval( $filter ) ), - $lang->formatNum( intval( $filter ) ) + SpecialPage::getTitleFor( 'AbuseFilter', $filter ), + $lang->formatNum( $filter ) ); $searchFields = []; $searchFields['filterid'] = [ @@ -77,10 +105,12 @@ class AbuseFilterViewRevert extends AbuseFilterView { $results = $this->doLookup(); $list = []; + $context = $this->getContext(); foreach ( $results as $result ) { - $displayActions = array_map( - [ 'AbuseFilter', 'getActionDisplay' ], - $result['actions'] ); + $displayActions = []; + foreach ( $result['actions'] as $action ) { + $displayActions[] = AbuseFilter::getActionDisplay( $action, $context ); + } $msg = $this->msg( 'abusefilter-revert-preview-item' ) ->params( @@ -146,7 +176,7 @@ class AbuseFilterViewRevert extends AbuseFilterView { } /** - * @return array + * @return array[] */ public function doLookup() { $periodStart = $this->mPeriodStart; @@ -157,14 +187,13 @@ class AbuseFilterViewRevert extends AbuseFilterView { $dbr = wfGetDB( DB_REPLICA ); - if ( $periodStart ) { + if ( $periodStart !== null ) { $conds[] = 'afl_timestamp >= ' . $dbr->addQuotes( $dbr->timestamp( $periodStart ) ); } - if ( $periodEnd ) { + if ( $periodEnd !== null ) { $conds[] = 'afl_timestamp <= ' . $dbr->addQuotes( $dbr->timestamp( $periodEnd ) ); } - // All but afl_filter, afl_ip, afl_deleted, afl_patrolled_by, afl_rev_id and afl_log_id $selectFields = [ 'afl_id', 'afl_user', @@ -213,10 +242,10 @@ class AbuseFilterViewRevert extends AbuseFilterView { $request = $this->getRequest(); $this->origPeriodStart = $request->getText( 'wpPeriodStart' ); - $this->mPeriodStart = strtotime( $this->origPeriodStart ); + $this->mPeriodStart = strtotime( $this->origPeriodStart ) ?: null; $this->origPeriodEnd = $request->getText( 'wpPeriodEnd' ); - $this->mPeriodEnd = strtotime( $this->origPeriodEnd ); - $this->mSubmit = $request->getVal( 'submit' ); + $this->mPeriodEnd = strtotime( $this->origPeriodEnd ) ?: null; + $this->mSubmit = $request->getBool( 'submit' ); $this->mReason = $request->getVal( 'wpReason' ); } @@ -258,8 +287,8 @@ class AbuseFilterViewRevert extends AbuseFilterView { public function revertAction( $action, $result ) { switch ( $action ) { case 'block': - $block = Block::newFromTarget( $result['user'] ); - if ( !( $block && $block->getBy() == AbuseFilter::getFilterUser()->getId() ) ) { + $block = DatabaseBlock::newFromTarget( $result['user'] ); + if ( !( $block && $block->getBy() === AbuseFilter::getFilterUser()->getId() ) ) { // Not blocked by abuse filter return false; } @@ -275,17 +304,16 @@ class AbuseFilterViewRevert extends AbuseFilterView { $logEntry->publish( $logEntry->insert() ); return true; case 'blockautopromote': - ObjectCache::getMainStashInstance()->delete( - AbuseFilter::autoPromoteBlockKey( User::newFromId( $result['userid'] ) ) - ); - return true; + $target = User::newFromId( $result['userid'] ); + $msg = $this->msg( + 'abusefilter-revert-reason', $this->mPage->mFilter, $this->mReason + )->inContentLanguage()->text(); + + return AbuseFilter::unblockAutopromote( $target, $this->getUser(), $msg ); case 'degroup': // Pull the user's groups from the vars. $oldGroups = $result['vars']->getVar( 'user_groups' )->toNative(); - $oldGroups = array_diff( - $oldGroups, - array_intersect( $oldGroups, User::getImplicitGroups() ) - ); + $oldGroups = array_diff( $oldGroups, User::getImplicitGroups() ); $rows = []; foreach ( $oldGroups as $group ) { diff --git a/AbuseFilter/includes/Views/AbuseFilterViewTestBatch.php b/AbuseFilter/includes/Views/AbuseFilterViewTestBatch.php index 168933ec..89ae088a 100644 --- a/AbuseFilter/includes/Views/AbuseFilterViewTestBatch.php +++ b/AbuseFilter/includes/Views/AbuseFilterViewTestBatch.php @@ -1,11 +1,45 @@ <?php +use MediaWiki\Extension\AbuseFilter\VariableGenerator\RCVariableGenerator; + class AbuseFilterViewTestBatch extends AbuseFilterView { - // Hard-coded for now. + /** + * @var int The limit of changes to test, hard coded for now + */ protected static $mChangeLimit = 100; - public $mShowNegative, $mTestPeriodStart, $mTestPeriodEnd, $mTestPage; - public $mTestUser, $mExcludeBots, $mTestAction; + /** + * @var bool Whether to show changes that don't trigger the specified pattern + */ + public $mShowNegative; + /** + * @var string The start time of the lookup period + */ + public $mTestPeriodStart; + /** + * @var string The end time of the lookup period + */ + public $mTestPeriodEnd; + /** + * @var string The page of which edits we're interested in + */ + public $mTestPage; + /** + * @var string The user whose actions we want to test + */ + public $mTestUser; + /** + * @var bool Whether to exclude bot edits + */ + public $mExcludeBots; + /** + * @var string The action (performed by the user) we want to search for + */ + public $mTestAction; + /** + * @var string The text of the rule to test changes against + */ + private $testPattern; /** * Shows the page @@ -13,9 +47,7 @@ class AbuseFilterViewTestBatch extends AbuseFilterView { public function show() { $out = $this->getOutput(); - AbuseFilter::disableConditionLimit(); - - if ( !$this->canViewPrivate() ) { + if ( !AbuseFilter::canViewPrivate( $this->getUser() ) ) { $out->addWikiMsg( 'abusefilter-mustviewprivateoredit' ); return; } @@ -29,14 +61,13 @@ class AbuseFilterViewTestBatch extends AbuseFilterView { $output = ''; $output .= $this->buildEditBox( - $this->mFilter, - 'wpTestFilter', + $this->testPattern, true, true, false ) . "\n"; - $output .= AbuseFilter::buildFilterLoader(); + $output .= $this->buildFilterLoader(); $output = Xml::tags( 'div', [ 'id' => 'mw-abusefilter-test-editor' ], $output ); $RCMaxAge = $this->getConfig()->get( 'RCMaxAge' ); @@ -54,8 +85,8 @@ class AbuseFilterViewTestBatch extends AbuseFilterView { $this->msg( 'abusefilter-test-search-type-edit' )->text() => 'edit', $this->msg( 'abusefilter-test-search-type-move' )->text() => 'move', $this->msg( 'abusefilter-test-search-type-delete' )->text() => 'delete', - $this->msg( 'abusefilter-test-search-type-createaccount' )->text() => 'createaccount' - // @ToDo: add 'upload' once T170249 is resolved + $this->msg( 'abusefilter-test-search-type-createaccount' )->text() => 'createaccount', + $this->msg( 'abusefilter-test-search-type-upload' )->text() => 'upload' ] ]; $formFields['wpTestUser'] = [ @@ -126,8 +157,10 @@ class AbuseFilterViewTestBatch extends AbuseFilterView { public function doTest() { // Quick syntax check. $out = $this->getOutput(); - $result = AbuseFilter::checkSyntax( $this->mFilter ); - if ( $result !== true ) { + $parser = AbuseFilter::getDefaultParser(); + + $validSyntax = $parser->checkSyntax( $this->testPattern ); + if ( $validSyntax !== true ) { $out->addWikiMsg( 'abusefilter-test-syntaxerr' ); return; } @@ -160,18 +193,15 @@ class AbuseFilterViewTestBatch extends AbuseFilterView { } } - $action = $this->mTestAction != '0' ? $this->mTestAction : false; - $conds[] = $this->buildTestConditions( $dbr, $action ); - - $conds = array_filter( $conds ); - - // To be added after filtering, otherwise it gets stripped if ( $this->mExcludeBots ) { $conds['rc_bot'] = 0; } + $action = $this->mTestAction !== '0' ? $this->mTestAction : false; + $conds[] = $this->buildTestConditions( $dbr, $action ); + // Get our ChangesList - $changesList = new AbuseFilterChangesList( $this->getSkin(), $this->mFilter ); + $changesList = new AbuseFilterChangesList( $this->getSkin(), $this->testPattern ); $output = $changesList->beginRecentChangesList(); $rcQuery = RecentChange::getQueryInfo(); @@ -186,19 +216,24 @@ class AbuseFilterViewTestBatch extends AbuseFilterView { $counter = 1; + $contextUser = $this->getUser(); + $parser->toggleConditionLimit( false ); foreach ( $res as $row ) { - $vars = AbuseFilter::getVarsFromRCRow( $row ); + $vars = new AbuseFilterVariableHolder(); + $rc = RecentChange::newFromRow( $row ); + $varGenerator = new RCVariableGenerator( $vars, $rc, $contextUser ); + $vars = $varGenerator->getVars(); if ( !$vars ) { continue; } - $result = AbuseFilter::checkConditions( $this->mFilter, $vars ); + $parser->setVariables( $vars ); + $result = $parser->checkConditions( $this->testPattern ); if ( $result || $this->mShowNegative ) { // Stash result in RC item - $rc = RecentChange::newFromRow( $row ); - /** @suppress PhanUndeclaredProperty for $rc->filterResult, which isn't a big deal */ + // @phan-suppress-next-line PhanUndeclaredProperty not a big deal $rc->filterResult = $result; $rc->counter = $counter++; $output .= $changesList->recentChangesLine( $rc, false ); @@ -216,7 +251,7 @@ class AbuseFilterViewTestBatch extends AbuseFilterView { public function loadParameters() { $request = $this->getRequest(); - $this->mFilter = $request->getText( 'wpTestFilter' ); + $this->testPattern = $request->getText( 'wpFilterRules' ); $this->mShowNegative = $request->getBool( 'wpShowNegative' ); $testUsername = $request->getText( 'wpTestUser' ); $this->mTestPeriodEnd = $request->getText( 'wpTestPeriodEnd' ); @@ -225,12 +260,12 @@ class AbuseFilterViewTestBatch extends AbuseFilterView { $this->mExcludeBots = $request->getBool( 'wpExcludeBots' ); $this->mTestAction = $request->getText( 'wpTestAction' ); - if ( !$this->mFilter + if ( !$this->testPattern && count( $this->mParams ) > 1 && is_numeric( $this->mParams[1] ) ) { $dbr = wfGetDB( DB_REPLICA ); - $this->mFilter = $dbr->selectField( 'abuse_filter', + $this->testPattern = $dbr->selectField( 'abuse_filter', 'af_pattern', [ 'af_id' => $this->mParams[1] ], __METHOD__ diff --git a/AbuseFilter/includes/Views/AbuseFilterViewTools.php b/AbuseFilter/includes/Views/AbuseFilterViewTools.php index 44ee0eb4..70c1091f 100644 --- a/AbuseFilter/includes/Views/AbuseFilterViewTools.php +++ b/AbuseFilter/includes/Views/AbuseFilterViewTools.php @@ -9,7 +9,7 @@ class AbuseFilterViewTools extends AbuseFilterView { $out->enableOOUI(); $request = $this->getRequest(); - if ( !$this->canViewPrivate() ) { + if ( !AbuseFilter::canViewPrivate( $this->getUser() ) ) { $out->addWikiMsg( 'abusefilter-mustviewprivateoredit' ); return; } @@ -20,8 +20,7 @@ class AbuseFilterViewTools extends AbuseFilterView { // Expression evaluator $eval = ''; $eval .= $this->buildEditBox( - $request->getText( 'wpTestExpr' ), - 'wpTestExpr', + $request->getText( 'wpFilterRules' ), true, false, false @@ -31,32 +30,35 @@ class AbuseFilterViewTools extends AbuseFilterView { Xml::tags( 'p', null, new OOUI\ButtonInputWidget( [ 'label' => $this->msg( 'abusefilter-tools-submitexpr' )->text(), - 'id' => 'mw-abusefilter-submitexpr' + 'id' => 'mw-abusefilter-submitexpr', + 'flags' => [ 'primary', 'progressive' ] ] ) ); - $eval .= Xml::element( 'p', [ 'id' => 'mw-abusefilter-expr-result' ], ' ' ); + $eval .= Xml::element( 'pre', [ 'id' => 'mw-abusefilter-expr-result' ], ' ' ); $eval = Xml::fieldset( $this->msg( 'abusefilter-tools-expr' )->text(), $eval ); $out->addHTML( $eval ); $out->addModules( 'ext.abuseFilter.tools' ); - // Hacky little box to re-enable autoconfirmed if it got disabled - $formDescriptor = [ - 'RestoreAutoconfirmed' => [ - 'label-message' => 'abusefilter-tools-reautoconfirm-user', - 'type' => 'user', - 'name' => 'wpReAutoconfirmUser', - 'id' => 'reautoconfirm-user', - 'infusable' => true - ], - ]; - $htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() ); - $htmlForm->setWrapperLegendMsg( 'abusefilter-tools-reautoconfirm' ) - ->setSubmitTextMsg( 'abusefilter-tools-reautoconfirm-submit' ) - ->setSubmitName( 'wpReautoconfirmSubmit' ) - ->setSubmitId( 'mw-abusefilter-reautoconfirmsubmit' ) - ->prepareForm() - ->displayForm( false ); + if ( AbuseFilter::canEdit( $this->getUser() ) ) { + // Hacky little box to re-enable autoconfirmed if it got disabled + $formDescriptor = [ + 'RestoreAutoconfirmed' => [ + 'label-message' => 'abusefilter-tools-reautoconfirm-user', + 'type' => 'user', + 'name' => 'wpReAutoconfirmUser', + 'id' => 'reautoconfirm-user', + 'infusable' => true + ], + ]; + $htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() ); + $htmlForm->setWrapperLegendMsg( 'abusefilter-tools-reautoconfirm' ) + ->setSubmitTextMsg( 'abusefilter-tools-reautoconfirm-submit' ) + ->setSubmitName( 'wpReautoconfirmSubmit' ) + ->setSubmitId( 'mw-abusefilter-reautoconfirmsubmit' ) + ->prepareForm() + ->displayForm( false ); + } } } diff --git a/AbuseFilter/includes/api/ApiAbuseFilterCheckMatch.php b/AbuseFilter/includes/api/ApiAbuseFilterCheckMatch.php index 9d4fd8c3..517ea804 100644 --- a/AbuseFilter/includes/api/ApiAbuseFilterCheckMatch.php +++ b/AbuseFilter/includes/api/ApiAbuseFilterCheckMatch.php @@ -1,5 +1,7 @@ <?php +use MediaWiki\Extension\AbuseFilter\VariableGenerator\RCVariableGenerator; + class ApiAbuseFilterCheckMatch extends ApiBase { /** * @see ApiBase::execute @@ -9,34 +11,25 @@ class ApiAbuseFilterCheckMatch extends ApiBase { $this->requireOnlyOneParameter( $params, 'vars', 'rcid', 'logid' ); // "Anti-DoS" - if ( !$this->getUser()->isAllowedAny( 'abusefilter-modify', 'abusefilter-view-private' ) ) { + if ( !AbuseFilter::canViewPrivate( $this->getUser() ) ) { $this->dieWithError( 'apierror-abusefilter-canttest', 'permissiondenied' ); } $vars = null; if ( $params['vars'] ) { - $vars = new AbuseFilterVariableHolder; $pairs = FormatJson::decode( $params['vars'], true ); - foreach ( $pairs as $name => $value ) { - $vars->setVar( $name, $value ); - } + $vars = AbuseFilterVariableHolder::newFromArray( $pairs ); } elseif ( $params['rcid'] ) { - $dbr = wfGetDB( DB_REPLICA ); - $rcQuery = RecentChange::getQueryInfo(); - $row = $dbr->selectRow( - $rcQuery['tables'], - $rcQuery['fields'], - [ 'rc_id' => $params['rcid'] ], - __METHOD__, - [], - $rcQuery['joins'] - ); + $rc = RecentChange::newFromId( $params['rcid'] ); - if ( !$row ) { + if ( !$rc ) { $this->dieWithError( [ 'apierror-nosuchrcid', $params['rcid'] ] ); } - $vars = AbuseFilter::getVarsFromRCRow( $row ); + $vars = new AbuseFilterVariableHolder(); + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable T240141 + $varGenerator = new RCVariableGenerator( $vars, $rc, $this->getUser() ); + $vars = $varGenerator->getVars(); } elseif ( $params['logid'] ) { $dbr = wfGetDB( DB_REPLICA ); $row = $dbr->selectRow( @@ -52,14 +45,19 @@ class ApiAbuseFilterCheckMatch extends ApiBase { $vars = AbuseFilter::loadVarDump( $row->afl_var_dump ); } + if ( $vars === null ) { + throw new LogicException( 'Impossible.' ); + } - if ( AbuseFilter::checkSyntax( $params[ 'filter' ] ) !== true ) { + $parser = AbuseFilter::getDefaultParser(); + if ( $parser->checkSyntax( $params[ 'filter' ] ) !== true ) { $this->dieWithError( 'apierror-abusefilter-badsyntax', 'badsyntax' ); } + $parser->setVariables( $vars ); $result = [ ApiResult::META_BC_BOOLS => [ 'result' ], - 'result' => AbuseFilter::checkConditions( $params['filter'], $vars ), + 'result' => $parser->checkConditions( $params['filter'] ), ]; $this->getResult()->addValue( diff --git a/AbuseFilter/includes/api/ApiAbuseFilterCheckSyntax.php b/AbuseFilter/includes/api/ApiAbuseFilterCheckSyntax.php index 213fb904..819906ac 100644 --- a/AbuseFilter/includes/api/ApiAbuseFilterCheckSyntax.php +++ b/AbuseFilter/includes/api/ApiAbuseFilterCheckSyntax.php @@ -7,12 +7,12 @@ class ApiAbuseFilterCheckSyntax extends ApiBase { */ public function execute() { // "Anti-DoS" - if ( !$this->getUser()->isAllowedAny( 'abusefilter-modify', 'abusefilter-view-private' ) ) { + if ( !AbuseFilter::canViewPrivate( $this->getUser() ) ) { $this->dieWithError( 'apierror-abusefilter-cantcheck', 'permissiondenied' ); } $params = $this->extractRequestParams(); - $result = AbuseFilter::checkSyntax( $params[ 'filter' ] ); + $result = AbuseFilter::getDefaultParser()->checkSyntax( $params[ 'filter' ] ); $r = []; if ( $result === true ) { diff --git a/AbuseFilter/includes/api/ApiAbuseFilterEvalExpression.php b/AbuseFilter/includes/api/ApiAbuseFilterEvalExpression.php index 18701670..5b707012 100644 --- a/AbuseFilter/includes/api/ApiAbuseFilterEvalExpression.php +++ b/AbuseFilter/includes/api/ApiAbuseFilterEvalExpression.php @@ -1,15 +1,51 @@ <?php +use MediaWiki\Extension\AbuseFilter\VariableGenerator\VariableGenerator; + class ApiAbuseFilterEvalExpression extends ApiBase { /** * @see ApiBase::execute() */ public function execute() { + // "Anti-DoS" + if ( !AbuseFilter::canViewPrivate( $this->getUser() ) ) { + $this->dieWithError( 'apierror-abusefilter-canteval', 'permissiondenied' ); + } + $params = $this->extractRequestParams(); - $result = AbuseFilter::evaluateExpression( $params['expression'] ); + $status = $this->evaluateExpression( $params['expression'] ); + if ( !$status->isGood() ) { + $this->dieWithError( $status->getErrors()[0] ); + } else { + $res = $status->getValue(); + $res = $params['prettyprint'] ? AbuseFilter::formatVar( $res ) : $res; + $this->getResult()->addValue( + null, + $this->getModuleName(), + ApiResult::addMetadataToResultVars( [ 'result' => $res ] ) + ); + } + } + + /** + * @param string $expr + * @return Status + */ + private function evaluateExpression( string $expr ) : Status { + $parser = AbuseFilter::getDefaultParser(); + if ( $parser->checkSyntax( $expr ) !== true ) { + return Status::newFatal( 'abusefilter-tools-syntax-error' ); + } + + $vars = new AbuseFilterVariableHolder(); + // Generic vars are the only ones available + $generator = new VariableGenerator( $vars ); + $vars = $generator->addGenericVars()->getVariableHolder(); + $vars->setVar( 'timestamp', wfTimestamp( TS_UNIX ) ); + $parser->setVariables( $vars ); - $this->getResult()->addValue( null, $this->getModuleName(), [ 'result' => $result ] ); + return Status::newGood( $parser->evaluateExpression( $expr ) ); } /** @@ -21,6 +57,9 @@ class ApiAbuseFilterEvalExpression extends ApiBase { 'expression' => [ ApiBase::PARAM_REQUIRED => true, ], + 'prettyprint' => [ + ApiBase::PARAM_TYPE => 'boolean' + ] ]; } @@ -32,6 +71,8 @@ class ApiAbuseFilterEvalExpression extends ApiBase { return [ 'action=abusefilterevalexpression&expression=lcase("FOO")' => 'apihelp-abusefilterevalexpression-example-1', + 'action=abusefilterevalexpression&expression=lcase("FOO")&prettyprint=1' + => 'apihelp-abusefilterevalexpression-example-2', ]; } } diff --git a/AbuseFilter/includes/api/ApiAbuseFilterUnblockAutopromote.php b/AbuseFilter/includes/api/ApiAbuseFilterUnblockAutopromote.php index 195e72d3..e39da558 100644 --- a/AbuseFilter/includes/api/ApiAbuseFilterUnblockAutopromote.php +++ b/AbuseFilter/includes/api/ApiAbuseFilterUnblockAutopromote.php @@ -8,9 +8,9 @@ class ApiAbuseFilterUnblockAutopromote extends ApiBase { $this->checkUserRightsAny( 'abusefilter-modify' ); $params = $this->extractRequestParams(); - $user = User::newFromName( $params['user'] ); + $target = User::newFromName( $params['user'] ); - if ( $user === false ) { + if ( $target === false ) { $encParamName = $this->encodeParamName( 'user' ); $this->dieWithError( [ 'apierror-baduser', $encParamName, wfEscapeWikiText( $params['user'] ) ], @@ -18,16 +18,20 @@ class ApiAbuseFilterUnblockAutopromote extends ApiBase { ); } - $key = AbuseFilter::autoPromoteBlockKey( $user ); - $stash = ObjectCache::getMainStashInstance(); - if ( !$stash->get( $key ) ) { - $this->dieWithError( [ 'abusefilter-reautoconfirm-none', $user->getName() ], 'notsuspended' ); + $block = $this->getUser()->getBlock(); + if ( $block && $block->isSitewide() ) { + $this->dieBlocked( $block ); } - $stash->delete( $key ); + $msg = $this->msg( 'abusefilter-tools-restoreautopromote' )->inContentLanguage()->text(); + $res = AbuseFilter::unblockAutopromote( $target, $this->getUser(), $msg ); - $res = [ 'user' => $params['user'] ]; - $this->getResult()->addValue( null, $this->getModuleName(), $res ); + if ( $res === false ) { + $this->dieWithError( [ 'abusefilter-reautoconfirm-none', $target->getName() ], 'notsuspended' ); + } + + $finalResult = [ 'user' => $params['user'] ]; + $this->getResult()->addValue( null, $this->getModuleName(), $finalResult ); } /** diff --git a/AbuseFilter/includes/api/ApiAbuseLogPrivateDetails.php b/AbuseFilter/includes/api/ApiAbuseLogPrivateDetails.php new file mode 100644 index 00000000..0554c942 --- /dev/null +++ b/AbuseFilter/includes/api/ApiAbuseLogPrivateDetails.php @@ -0,0 +1,110 @@ +<?php +/** + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + */ + +/** + * API module to allow accessing private details (the user's IP) from AbuseLog entries + * + * @ingroup API + * @ingroup Extensions + */ +class ApiAbuseLogPrivateDetails extends ApiBase { + /** + * @inheritDoc + */ + public function mustBePosted() { + return true; + } + + /** + * @inheritDoc + */ + public function isWriteMode() { + return true; + } + + /** + * @inheritDoc + */ + public function needsToken() { + return 'csrf'; + } + + /** + * @inheritDoc + */ + public function execute() { + $user = $this->getUser(); + + if ( !SpecialAbuseLog::canSeePrivateDetails( $user ) ) { + $this->dieWithError( 'abusefilter-log-cannot-see-privatedetails' ); + } + $params = $this->extractRequestParams(); + + if ( !SpecialAbuseLog::checkPrivateDetailsAccessReason( $params['reason'] ) ) { + // Double check, in case we add some extra validation + $this->dieWithError( 'abusefilter-noreason' ); + } + $status = SpecialAbuseLog::getPrivateDetailsRow( $user, $params['logid'] ); + if ( !$status->isGood() ) { + $this->dieWithError( $status->getErrors()[0] ); + } + $row = $status->getValue(); + // Log accessing private details + if ( $this->getConfig()->get( 'AbuseFilterLogPrivateDetailsAccess' ) ) { + SpecialAbuseLog::addPrivateDetailsAccessLogEntry( + $params['logid'], + $params['reason'], + $user + ); + } + + $result = [ + 'log-id' => $params['logid'], + 'user' => $row->afl_user_text, + 'filter-id' => $row->af_id, + 'filter-description' => $row->af_public_comments, + 'ip-address' => $row->afl_ip !== '' ? $row->afl_ip : null + ]; + $this->getResult()->addValue( null, $this->getModuleName(), $result ); + } + + /** + * @inheritDoc + */ + public function getAllowedParams() { + return [ + 'logid' => [ + ApiBase::PARAM_TYPE => 'integer' + ], + 'reason' => [ + ApiBase::PARAM_TYPE => 'string', + ApiBase::PARAM_REQUIRED => $this->getConfig()->get( 'AbuseFilterPrivateDetailsForceReason' ), + ] + ]; + } + + /** + * @inheritDoc + */ + protected function getExamplesMessages() { + return [ + 'action=abuselogprivatedetails&logid=1&reason=example&token=ABC123' + => 'apihelp-abuselogprivatedetails-example-1' + ]; + } +} diff --git a/AbuseFilter/includes/api/ApiQueryAbuseFilters.php b/AbuseFilter/includes/api/ApiQueryAbuseFilters.php index cafe20d1..54e28997 100644 --- a/AbuseFilter/includes/api/ApiQueryAbuseFilters.php +++ b/AbuseFilter/includes/api/ApiQueryAbuseFilters.php @@ -34,7 +34,7 @@ class ApiQueryAbuseFilters extends ApiQueryBase { * @param ApiQuery $query * @param string $moduleName */ - public function __construct( $query, $moduleName ) { + public function __construct( ApiQuery $query, $moduleName ) { parent::__construct( $query, $moduleName, 'abf' ); } @@ -79,7 +79,7 @@ class ApiQueryAbuseFilters extends ApiQueryBase { $this->addWhereRange( 'af_id', $params['dir'], $params['startid'], $params['endid'] ); - if ( !is_null( $params['show'] ) ) { + if ( $params['show'] !== null ) { $show = array_flip( $params['show'] ); /* Check for conflicting parameters. */ @@ -100,18 +100,19 @@ class ApiQueryAbuseFilters extends ApiQueryBase { $res = $this->select( __METHOD__ ); - $showhidden = $user->isAllowedAny( 'abusefilter-modify', 'abusefilter-view-private' ); + $showhidden = AbuseFilter::canViewPrivate( $user ); $count = 0; foreach ( $res as $row ) { + $filterId = intval( $row->af_id ); if ( ++$count > $params['limit'] ) { // We've had enough - $this->setContinueEnumParameter( 'startid', $row->af_id ); + $this->setContinueEnumParameter( 'startid', $filterId ); break; } $entry = []; if ( $fld_id ) { - $entry['id'] = intval( $row->af_id ); + $entry['id'] = $filterId; } if ( $fld_desc ) { $entry['description'] = $row->af_public_comments; @@ -149,7 +150,7 @@ class ApiQueryAbuseFilters extends ApiQueryBase { if ( $entry ) { $fit = $result->addValue( [ 'query', $this->getModuleName() ], null, $entry ); if ( !$fit ) { - $this->setContinueEnumParameter( 'startid', $row->af_id ); + $this->setContinueEnumParameter( 'startid', $filterId ); break; } } diff --git a/AbuseFilter/includes/api/ApiQueryAbuseLog.php b/AbuseFilter/includes/api/ApiQueryAbuseLog.php index bf085318..0a088b22 100644 --- a/AbuseFilter/includes/api/ApiQueryAbuseLog.php +++ b/AbuseFilter/includes/api/ApiQueryAbuseLog.php @@ -23,6 +23,9 @@ * http://www.gnu.org/copyleft/gpl.html */ +use MediaWiki\MediaWikiServices; +use Wikimedia\IPUtils; + /** * Query module to list abuse log entries. * @@ -34,22 +37,18 @@ class ApiQueryAbuseLog extends ApiQueryBase { * @param ApiQuery $query * @param string $moduleName */ - public function __construct( $query, $moduleName ) { + public function __construct( ApiQuery $query, $moduleName ) { parent::__construct( $query, $moduleName, 'afl' ); } /** - * @see ApiQueryBase::execute() + * @inheritDoc */ public function execute() { - $user = $this->getUser(); - $errors = $this->getTitle()->getUserPermissionsErrors( - 'abusefilter-log', $user, true, [ 'ns-specialprotected' ] ); - if ( count( $errors ) ) { - $this->dieStatus( $this->errorArrayToStatus( $errors ) ); - return; - } + // Same check as in SpecialAbuseLog + $this->checkUserRightsAny( 'abusefilter-log' ); + $user = $this->getUser(); $params = $this->extractRequestParams(); $prop = array_flip( $params['prop'] ); @@ -71,14 +70,16 @@ class ApiQueryAbuseLog extends ApiQueryBase { } // Match permissions for viewing events on private filters to SpecialAbuseLog (bug 42814) if ( $params['filter'] && - !( AbuseFilterView::canViewPrivate() || $user->isAllowed( 'abusefilter-log-private' ) ) + !( AbuseFilter::canViewPrivate( $user ) || + $this->getPermissionManager()->userHasRight( $user, 'abusefilter-log-private' ) ) ) { // A specific filter parameter is set but the user isn't allowed to view all filters if ( !is_array( $params['filter'] ) ) { $params['filter'] = [ $params['filter'] ]; } foreach ( $params['filter'] as $filter ) { - if ( AbuseFilter::filterHidden( $filter ) ) { + list( $filterID, $global ) = AbuseFilter::splitGlobalName( $filter ); + if ( AbuseFilter::filterHidden( $filterID, $global ) ) { $this->dieWithError( [ 'apierror-permissiondenied', $this->msg( 'action-abusefilter-log-private' ) ] ); @@ -114,18 +115,15 @@ class ApiQueryAbuseLog extends ApiQueryBase { $this->addWhereRange( 'afl_timestamp', $params['dir'], $params['start'], $params['end'] ); - $db = $this->getDB(); - $notDeletedCond = SpecialAbuseLog::getNotDeletedCond( $db ); - if ( isset( $params['user'] ) ) { $u = User::newFromName( $params['user'] ); if ( $u ) { // Username normalisation $params['user'] = $u->getName(); $userId = $u->getId(); - } elseif ( IP::isIPAddress( $params['user'] ) ) { + } elseif ( IPUtils::isIPAddress( $params['user'] ) ) { // It's an IP, sanitize it - $params['user'] = IP::sanitizeIP( $params['user'] ); + $params['user'] = IPUtils::sanitizeIP( $params['user'] ); $userId = 0; } @@ -141,17 +139,19 @@ class ApiQueryAbuseLog extends ApiQueryBase { } } - $this->addWhereIf( [ 'afl_filter' => $params['filter'] ], isset( $params['filter'] ) ); - $this->addWhereIf( $notDeletedCond, !SpecialAbuseLog::canSeeHidden() ); + if ( isset( $params['filter'] ) && $params['filter'] !== [] ) { + $this->addWhere( [ 'afl_filter' => $params['filter'] ] ); + } + $this->addWhereIf( [ 'afl_deleted' => 0 ], !SpecialAbuseLog::canSeeHidden( $user ) ); if ( isset( $params['wiki'] ) ) { // 'wiki' won't be set if $wgAbuseFilterIsCentral = false $this->addWhereIf( [ 'afl_wiki' => $params['wiki'] ], $isCentral ); } $title = $params['title']; - if ( !is_null( $title ) ) { + if ( $title !== null ) { $titleObj = Title::newFromText( $title ); - if ( is_null( $titleObj ) ) { + if ( $titleObj === null ) { $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $title ) ] ); } $this->addWhereFld( 'afl_namespace', $titleObj->getNamespace() ); @@ -168,15 +168,19 @@ class ApiQueryAbuseLog extends ApiQueryBase { break; } $hidden = SpecialAbuseLog::isHidden( $row ); - if ( $hidden === true && !SpecialAbuseLog::canSeeHidden() ) { + if ( $hidden === true && !SpecialAbuseLog::canSeeHidden( $user ) ) { continue; - } elseif ( $hidden === 'implicit' ) { - $rev = Revision::newFromId( $row->afl_rev_id ); - if ( !$rev->userCan( Revision::SUPPRESSED_ALL, $user ) ) { + } + if ( $hidden === 'implicit' ) { + $revRec = MediaWikiServices::getInstance() + ->getRevisionLookup() + ->getRevisionById( (int)$row->afl_rev_id ); + if ( !AbuseFilter::userCanViewRev( $revRec, $user ) ) { continue; } } - $canSeeDetails = SpecialAbuseLog::canSeeDetails( $row->afl_filter ); + list( $filterID, $global ) = AbuseFilter::splitGlobalName( $row->afl_filter ); + $canSeeDetails = SpecialAbuseLog::canSeeDetails( $user, $filterID, $global ); $entry = []; if ( $fld_ids ) { @@ -184,9 +188,8 @@ class ApiQueryAbuseLog extends ApiQueryBase { $entry['filter_id'] = $canSeeDetails ? $row->afl_filter : ''; } if ( $fld_filter ) { - $globalIndex = AbuseFilter::decodeGlobalName( $row->afl_filter ); - if ( $globalIndex ) { - $entry['filter'] = AbuseFilter::getGlobalFilterDescription( $globalIndex ); + if ( $global ) { + $entry['filter'] = AbuseFilter::getGlobalFilterDescription( $filterID ); } else { $entry['filter'] = $row->af_public_comments; } @@ -207,7 +210,7 @@ class ApiQueryAbuseLog extends ApiQueryBase { if ( $fld_result ) { $entry['result'] = $row->afl_actions; } - if ( $fld_revid && !is_null( $row->afl_rev_id ) ) { + if ( $fld_revid && $row->afl_rev_id !== null ) { $entry['revid'] = $canSeeDetails ? $row->afl_rev_id : ''; } if ( $fld_timestamp ) { @@ -218,11 +221,7 @@ class ApiQueryAbuseLog extends ApiQueryBase { $entry['details'] = []; if ( $canSeeDetails ) { $vars = AbuseFilter::loadVarDump( $row->afl_var_dump ); - if ( $vars instanceof AbuseFilterVariableHolder ) { - $entry['details'] = $vars->exportAllVars(); - } else { - $entry['details'] = array_change_key_case( $vars, CASE_LOWER ); - } + $entry['details'] = $vars->exportAllVars(); } } @@ -269,7 +268,11 @@ class ApiQueryAbuseLog extends ApiQueryBase { 'title' => null, 'filter' => [ ApiBase::PARAM_TYPE => 'string', - ApiBase::PARAM_ISMULTI => true + ApiBase::PARAM_ISMULTI => true, + ApiBase::PARAM_HELP_MSG => [ + 'apihelp-query+abuselog-param-filter', + AbuseFilter::GLOBAL_FILTER_PREFIX + ] ], 'limit' => [ ApiBase::PARAM_DFLT => 10, @@ -301,6 +304,7 @@ class ApiQueryAbuseLog extends ApiQueryBase { ]; $params['prop'][ApiBase::PARAM_DFLT] .= '|wiki'; $params['prop'][ApiBase::PARAM_TYPE][] = 'wiki'; + $params['filter'][ApiBase::PARAM_HELP_MSG] = 'apihelp-query+abuselog-param-filter-central'; } return $params; } diff --git a/AbuseFilter/includes/pagers/AbuseFilterExaminePager.php b/AbuseFilter/includes/pagers/AbuseFilterExaminePager.php index 02b13755..cbae7a9d 100644 --- a/AbuseFilter/includes/pagers/AbuseFilterExaminePager.php +++ b/AbuseFilter/includes/pagers/AbuseFilterExaminePager.php @@ -1,13 +1,20 @@ <?php class AbuseFilterExaminePager extends ReverseChronologicalPager { - public $mChangesList, $mPage; + /** + * @var AbuseFilterChangesList Our changes list + */ + public $mChangesList; + /** + * @var AbuseFilterViewExamine The associated view + */ + public $mPage; /** * @param AbuseFilterViewExamine $page * @param AbuseFilterChangesList $changesList */ - public function __construct( $page, $changesList ) { + public function __construct( AbuseFilterViewExamine $page, AbuseFilterChangesList $changesList ) { parent::__construct(); $this->mChangesList = $changesList; $this->mPage = $page; diff --git a/AbuseFilter/includes/pagers/AbuseFilterHistoryPager.php b/AbuseFilter/includes/pagers/AbuseFilterHistoryPager.php index 265c97f1..550b6fab 100644 --- a/AbuseFilter/includes/pagers/AbuseFilterHistoryPager.php +++ b/AbuseFilter/includes/pagers/AbuseFilterHistoryPager.php @@ -3,22 +3,32 @@ use MediaWiki\Linker\LinkRenderer; class AbuseFilterHistoryPager extends TablePager { - public $mFilter, $mPage, $mUser; + /** + * @var int The filter ID + */ + public $mFilter; + /** + * @var AbuseFilterViewHistory The associated page + */ + public $mPage; + /** + * @var string The user whose changes we're looking up for + */ + public $mUser; - protected $linkRenderer; /** - * @param string $filter + * @param int $filter * @param AbuseFilterViewHistory $page * @param string $user User name * @param LinkRenderer $linkRenderer */ - public function __construct( $filter, $page, $user, $linkRenderer ) { + public function __construct( int $filter, AbuseFilterViewHistory $page, $user, + LinkRenderer $linkRenderer ) { + parent::__construct( $page->getContext(), $linkRenderer ); $this->mFilter = $filter; $this->mPage = $page; $this->mUser = $user; $this->mDefaultDirection = true; - $this->linkRenderer = $linkRenderer; - parent::__construct( $this->mPage->getContext() ); } /** @@ -44,7 +54,6 @@ class AbuseFilterHistoryPager extends TablePager { if ( !$this->mFilter ) { // awful hack $headers = [ 'afh_filter' => 'abusefilter-history-filterid' ] + $headers; - unset( $headers['afh_comments'] ); } foreach ( $headers as &$msg ) { @@ -61,20 +70,21 @@ class AbuseFilterHistoryPager extends TablePager { */ public function formatValue( $name, $value ) { $lang = $this->getLanguage(); + $linkRenderer = $this->getLinkRenderer(); $row = $this->mCurrentRow; switch ( $name ) { case 'afh_filter': - $formatted = $this->linkRenderer->makeLink( - SpecialPage::getTitleFor( 'AbuseFilter', intval( $row->afh_filter ) ), + $formatted = $linkRenderer->makeLink( + SpecialPage::getTitleFor( 'AbuseFilter', $row->afh_filter ), $lang->formatNum( $row->afh_filter ) ); break; case 'afh_timestamp': $title = SpecialPage::getTitleFor( 'AbuseFilter', 'history/' . $row->afh_filter . '/item/' . $row->afh_id ); - $formatted = $this->linkRenderer->makeLink( + $formatted = $linkRenderer->makeLink( $title, $lang->timeanddate( $row->afh_timestamp, true ) ); @@ -88,7 +98,7 @@ class AbuseFilterHistoryPager extends TablePager { $formatted = htmlspecialchars( $value, ENT_QUOTES, 'UTF-8', false ); break; case 'afh_flags': - $formatted = AbuseFilter::formatFlags( $value ); + $formatted = AbuseFilter::formatFlags( $value, $lang ); break; case 'afh_actions': $actions = unserialize( $value ); @@ -96,7 +106,7 @@ class AbuseFilterHistoryPager extends TablePager { $display_actions = ''; foreach ( $actions as $action => $parameters ) { - $displayAction = AbuseFilter::formatAction( $action, $parameters ); + $displayAction = AbuseFilter::formatAction( $action, $parameters, $lang ); $display_actions .= Xml::tags( 'li', null, $displayAction ); } $display_actions = Xml::tags( 'ul', null, $display_actions ); @@ -104,15 +114,36 @@ class AbuseFilterHistoryPager extends TablePager { $formatted = $display_actions; break; case 'afh_id': + // Set a link to a diff with the previous version if this isn't the first edit to the filter. + // Like in AbuseFilterViewDiff, don't show it if the user cannot see private filters and any + // of the versions is hidden. $formatted = ''; if ( AbuseFilter::getFirstFilterChange( $row->afh_filter ) != $value ) { - // Set a link to a diff with the previous version if this isn't the first edit to the filter - $title = $this->mPage->getTitle( - 'history/' . $row->afh_filter . "/diff/prev/$value" ); - $formatted = $this->linkRenderer->makeLink( - $title, - new HtmlArmor( $this->msg( 'abusefilter-history-diff' )->parse() ) + // @todo This is subpar, it should be cached at least. Should we also hide actions? + $dbr = wfGetDB( DB_REPLICA ); + $oldFlags = $dbr->selectField( + 'abuse_filter_history', + 'afh_flags', + [ + 'afh_filter' => $row->afh_filter, + 'afh_id <' . $dbr->addQuotes( $row->afh_id ), + ], + __METHOD__, + [ 'ORDER BY' => 'afh_id DESC' ] ); + if ( AbuseFilter::canViewPrivate( $this->getUser() ) || + ( + !in_array( 'hidden', explode( ',', $row->afh_flags ) ) && + !in_array( 'hidden', explode( ',', $oldFlags ) ) + ) + ) { + $title = $this->mPage->getTitle( + 'history/' . $row->afh_filter . "/diff/prev/$value" ); + $formatted = $linkRenderer->makeLink( + $title, + new HtmlArmor( $this->msg( 'abusefilter-history-diff' )->parse() ) + ); + } } break; default: @@ -120,29 +151,6 @@ class AbuseFilterHistoryPager extends TablePager { break; } - $mappings = array_flip( AbuseFilter::$history_mappings ) + - [ 'afh_actions' => 'actions', 'afh_id' => 'id' ]; - $changed = explode( ',', $row->afh_changed_fields ); - - $fieldChanged = false; - if ( $name == 'afh_flags' ) { - // This is a bit freaky, but it works. - // Basically, returns true if any of those filters are in the $changed array. - $filters = [ 'af_enabled', 'af_hidden', 'af_deleted', 'af_global' ]; - if ( count( array_diff( $filters, $changed ) ) < count( $filters ) ) { - $fieldChanged = true; - } - } elseif ( in_array( $mappings[$name], $changed ) ) { - $fieldChanged = true; - } - - if ( $fieldChanged ) { - $formatted = Xml::tags( 'div', - [ 'class' => 'mw-abusefilter-history-changed' ], - $formatted - ); - } - return $formatted; } @@ -185,9 +193,7 @@ class AbuseFilterHistoryPager extends TablePager { $info['conds']['afh_filter'] = $this->mFilter; } - if ( !$this->getUser()->isAllowedAny( - 'abusefilter-modify', 'abusefilter-view-private' ) - ) { + if ( !AbuseFilter::canViewPrivate( $this->getUser() ) ) { // Hide data the user can't see. $info['conds']['af_hidden'] = 0; } @@ -219,6 +225,36 @@ class AbuseFilterHistoryPager extends TablePager { } /** + * @see TablePager::getCellAttrs + * + * @param string $field + * @param string $value + * @return array + */ + public function getCellAttrs( $field, $value ) { + $row = $this->mCurrentRow; + $mappings = array_flip( AbuseFilter::HISTORY_MAPPINGS ) + + [ 'afh_actions' => 'actions', 'afh_id' => 'id' ]; + $changed = explode( ',', $row->afh_changed_fields ); + + $fieldChanged = false; + if ( $field === 'afh_flags' ) { + // The field is changed if any of these filters are in the $changed array. + $filters = [ 'af_enabled', 'af_hidden', 'af_deleted', 'af_global' ]; + if ( count( array_intersect( $filters, $changed ) ) ) { + $fieldChanged = true; + } + } elseif ( in_array( $mappings[$field], $changed ) ) { + $fieldChanged = true; + } + + $class = $fieldChanged ? ' mw-abusefilter-history-changed' : ''; + $attrs = parent::getCellAttrs( $field, $value ); + $attrs['class'] .= $class; + return $attrs; + } + + /** * Title used for self-links. * * @return Title diff --git a/AbuseFilter/includes/pagers/AbuseFilterPager.php b/AbuseFilter/includes/pagers/AbuseFilterPager.php index 2092b850..482f5d78 100644 --- a/AbuseFilter/includes/pagers/AbuseFilterPager.php +++ b/AbuseFilter/includes/pagers/AbuseFilterPager.php @@ -1,6 +1,7 @@ <?php use MediaWiki\Linker\LinkRenderer; +use Wikimedia\AtEase\AtEase; /** * Class to build paginated filter list @@ -8,24 +9,43 @@ use MediaWiki\Linker\LinkRenderer; class AbuseFilterPager extends TablePager { /** - * @var LinkRenderer + * @var AbuseFilterViewList The associated page */ - protected $linkRenderer; - - public $mPage, $mConds, $mQuery; + public $mPage; + /** + * @var array Query WHERE conditions + */ + public $mConds; + /** + * @var string The pattern being searched + */ + private $mSearchPattern; + /** + * @var string The pattern search mode (LIKE, RLIKE or IRLIKE) + */ + private $mSearchMode; /** * @param AbuseFilterViewList $page * @param array $conds * @param LinkRenderer $linkRenderer - * @param array $query + * @param string $searchPattern Empty string if no pattern was specified + * @param string $searchMode */ - public function __construct( $page, $conds, $linkRenderer, $query ) { + public function __construct( + AbuseFilterViewList $page, + $conds, + LinkRenderer $linkRenderer, + string $searchPattern, + string $searchMode + ) { $this->mPage = $page; $this->mConds = $conds; - $this->linkRenderer = $linkRenderer; - $this->mQuery = $query; - parent::__construct( $this->mPage->getContext() ); + $this->mSearchPattern = $searchPattern; + $this->mSearchMode = $searchMode; + // needs to be at the end, some attributes are needed by methods + // called from ancestors' constructors + parent::__construct( $page->getContext(), $linkRenderer ); } /** @@ -56,6 +76,61 @@ class AbuseFilterPager extends TablePager { } /** + * @inheritDoc + * This is the same as the parent implementation if no search pattern was specified. + * Otherwise, it does a query with no limit and then slices the results à la ContribsPager. + */ + public function reallyDoQuery( $offset, $limit, $order ) { + if ( !strlen( $this->mSearchPattern ) ) { + return parent::reallyDoQuery( $offset, $limit, $order ); + } + + list( $tables, $fields, $conds, $fname, $options, $join_conds ) = + $this->buildQueryInfo( $offset, $limit, $order ); + + unset( $options['LIMIT'] ); + $res = $this->mDb->select( $tables, $fields, $conds, $fname, $options, $join_conds ); + + $filtered = []; + foreach ( $res as $row ) { + if ( $this->matchesPattern( $row->af_pattern ) ) { + $filtered[ $row->af_id ] = $row; + } + } + + // sort results and enforce limit like ContribsPager + if ( $order === self::QUERY_ASCENDING ) { + ksort( $filtered ); + } else { + krsort( $filtered ); + } + $filtered = array_slice( $filtered, 0, $limit ); + $filtered = array_values( $filtered ); + return new FakeResultWrapper( $filtered ); + } + + /** + * Check whether $subject matches the given $pattern. + * + * @param string $subject + * @return bool + * @throws LogicException + */ + private function matchesPattern( $subject ) { + $pattern = $this->mSearchPattern; + switch ( $this->mSearchMode ) { + case 'RLIKE': + return (bool)preg_match( "/$pattern/u", $subject ); + case 'IRLIKE': + return (bool)preg_match( "/$pattern/ui", $subject ); + case 'LIKE': + return mb_stripos( $subject, $pattern ) !== false; + default: + throw new LogicException( "Unknown search type {$this->mSearchMode}" ); + } + } + + /** * @see Pager::getFieldNames() * @return array */ @@ -75,11 +150,12 @@ class AbuseFilterPager extends TablePager { 'af_hidden' => 'abusefilter-list-visibility', ]; - if ( $this->mPage->getUser()->isAllowed( 'abusefilter-log-detail' ) ) { + $user = $this->getUser(); + if ( SpecialAbuseLog::canSeeDetails( $user ) ) { $headers['af_hit_count'] = 'abusefilter-list-hitcount'; } - if ( AbuseFilterView::canViewPrivate() && !empty( $this->mQuery[0] ) ) { + if ( AbuseFilter::canViewPrivate( $user ) && $this->mSearchPattern !== '' ) { $headers['af_pattern'] = 'abusefilter-list-pattern'; } @@ -101,79 +177,29 @@ class AbuseFilterPager extends TablePager { */ public function formatValue( $name, $value ) { $lang = $this->getLanguage(); + $user = $this->getUser(); + $linkRenderer = $this->getLinkRenderer(); $row = $this->mCurrentRow; switch ( $name ) { case 'af_id': - return $this->linkRenderer->makeLink( - SpecialPage::getTitleFor( 'AbuseFilter', intval( $value ) ), + return $linkRenderer->makeLink( + SpecialPage::getTitleFor( 'AbuseFilter', $value ), $lang->formatNum( intval( $value ) ) ); case 'af_pattern': - if ( $this->mQuery[1] === 'LIKE' ) { - $position = mb_stripos( $row->af_pattern, $this->mQuery[0] ); - if ( $position === false ) { - // This may happen due to problems with character encoding - // which aren't easy to solve - return htmlspecialchars( mb_substr( $row->af_pattern, 0, 50 ) ); - } - $length = mb_strlen( $this->mQuery[0] ); - } else { - $regex = '/' . $this->mQuery[0] . '/u'; - if ( $this->mQuery[1] === 'IRLIKE' ) { - $regex .= 'i'; - } - - $matches = []; - Wikimedia\suppressWarnings(); - $check = preg_match( - $regex, - $row->af_pattern, - $matches - ); - Wikimedia\restoreWarnings(); - // This may happen in case of catastrophic backtracking - if ( $check === false ) { - return htmlspecialchars( mb_substr( $row->af_pattern, 0, 50 ) ); - } - - $length = mb_strlen( $matches[0] ); - $position = mb_strpos( $row->af_pattern, $matches[0] ); - } - - $remaining = 50 - $length; - if ( $remaining <= 0 ) { - // Truncate the filter pattern and only show the first 50 characters of the match - $pattern = '<b>' . - htmlspecialchars( mb_substr( $row->af_pattern, $position, 50 ) ) . - '</b>'; - } else { - // Center the snippet on the matched string - $minoffset = max( $position - round( $remaining / 2 ), 0 ); - $pattern = mb_substr( $row->af_pattern, $minoffset, 50 ); - $pattern = - htmlspecialchars( mb_substr( $pattern, 0, $position - $minoffset ) ) . - '<b>' . - htmlspecialchars( mb_substr( $pattern, $position - $minoffset, $length ) ) . - '</b>' . - htmlspecialchars( mb_substr( - $pattern, - $position - $minoffset + $length, - $remaining - ( $position - $minoffset + $length ) - ) - ); - } - return $pattern; + return $this->getHighlightedPattern( $row ); case 'af_public_comments': - return $this->linkRenderer->makeLink( - SpecialPage::getTitleFor( 'AbuseFilter', intval( $row->af_id ) ), + return $linkRenderer->makeLink( + SpecialPage::getTitleFor( 'AbuseFilter', $row->af_id ), $value ); case 'af_actions': $actions = explode( ',', $value ); $displayActions = []; + $context = $this->getContext(); foreach ( $actions as $action ) { - $displayActions[] = AbuseFilter::getActionDisplay( $action ); + $displayActions[] = AbuseFilter::getActionDisplay( $action, $context ); } return $lang->commaList( $displayActions ); case 'af_enabled': @@ -198,10 +224,13 @@ class AbuseFilterPager extends TablePager { $msg = $value ? 'abusefilter-hidden' : 'abusefilter-unhidden'; return $this->msg( $msg )->parse(); case 'af_hit_count': - if ( SpecialAbuseLog::canSeeDetails( $row->af_id, $row->af_hidden ) ) { + // Global here is used to determine whether the log entry is for an external, global + // filter, but all filters shown on Special:AbuseFilter are local. + $global = false; + if ( SpecialAbuseLog::canSeeDetails( $user, $row->af_id, $global, $row->af_hidden ) ) { $count_display = $this->msg( 'abusefilter-hitcount' ) ->numParams( $value )->text(); - $link = $this->linkRenderer->makeKnownLink( + $link = $linkRenderer->makeKnownLink( SpecialPage::getTitleFor( 'AbuseLog' ), $count_display, [], @@ -239,7 +268,7 @@ class AbuseFilterPager extends TablePager { ) )->params( wfEscapeWikiText( $row->af_user_text ) - )->parse(); + )->parse(); case 'af_group': return AbuseFilter::nameGroup( $value ); default: @@ -248,6 +277,65 @@ class AbuseFilterPager extends TablePager { } /** + * Get the filter pattern with <b> elements surrounding the searched pattern + * + * @param stdClass $row + * @return string + */ + private function getHighlightedPattern( stdClass $row ) { + $maxLen = 50; + if ( $this->mSearchMode === 'LIKE' ) { + $position = mb_stripos( $row->af_pattern, $this->mSearchPattern ); + $length = mb_strlen( $this->mSearchPattern ); + } else { + $regex = '/' . $this->mSearchPattern . '/u'; + if ( $this->mSearchMode === 'IRLIKE' ) { + $regex .= 'i'; + } + + $matches = []; + AtEase::suppressWarnings(); + $check = preg_match( + $regex, + $row->af_pattern, + $matches + ); + AtEase::restoreWarnings(); + // This may happen in case of catastrophic backtracking, or regexps matching + // the empty string. + if ( $check === false || strlen( $matches[0] ) === 0 ) { + return htmlspecialchars( mb_substr( $row->af_pattern, 0, 50 ) ); + } + + $length = mb_strlen( $matches[0] ); + $position = mb_strpos( $row->af_pattern, $matches[0] ); + } + + $remaining = $maxLen - $length; + if ( $remaining <= 0 ) { + $pattern = '<b>' . + htmlspecialchars( mb_substr( $row->af_pattern, $position, $maxLen ) ) . + '</b>'; + } else { + // Center the snippet on the matched string + $minoffset = max( $position - round( $remaining / 2 ), 0 ); + $pattern = mb_substr( $row->af_pattern, $minoffset, $maxLen ); + $pattern = + htmlspecialchars( mb_substr( $pattern, 0, $position - $minoffset ) ) . + '<b>' . + htmlspecialchars( mb_substr( $pattern, $position - $minoffset, $length ) ) . + '</b>' . + htmlspecialchars( mb_substr( + $pattern, + $position - $minoffset + $length, + $remaining - ( $position - $minoffset + $length ) + ) + ); + } + return $pattern; + } + + /** * @return string */ public function getDefaultSort() { @@ -258,7 +346,7 @@ class AbuseFilterPager extends TablePager { * @return string */ public function getTableClass() { - return 'TablePager mw-abusefilter-list-scrollable'; + return parent::getTableClass() . ' mw-abusefilter-list-scrollable'; } /** @@ -288,9 +376,18 @@ class AbuseFilterPager extends TablePager { 'af_hidden', 'af_group', ]; - if ( $this->mPage->getUser()->isAllowed( 'abusefilter-log-detail' ) ) { + if ( SpecialAbuseLog::canSeeDetails( $this->getUser() ) ) { $sortable_fields[] = 'af_hit_count'; + $sortable_fields[] = 'af_public_comments'; } return in_array( $name, $sortable_fields ); } + + /** + * @see IndexPager::getExtraSortFields + * @return array + */ + public function getExtraSortFields() { + return [ 'af_enabled' => 'af_deleted' ]; + } } diff --git a/AbuseFilter/includes/pagers/AbuseLogPager.php b/AbuseFilter/includes/pagers/AbuseLogPager.php index 5c4f1a66..95ae8543 100644 --- a/AbuseFilter/includes/pagers/AbuseLogPager.php +++ b/AbuseFilter/includes/pagers/AbuseLogPager.php @@ -1,5 +1,6 @@ <?php +use MediaWiki\Cache\LinkBatchFactory; use Wikimedia\Rdbms\IResultWrapper; class AbuseLogPager extends ReverseChronologicalPager { @@ -13,14 +14,29 @@ class AbuseLogPager extends ReverseChronologicalPager { */ public $mConds; + /** @var LinkBatchFactory */ + private $linkBatchFactory; + + /** @var bool */ + private $joinWithArchive; + /** * @param SpecialAbuseLog $form * @param array $conds + * @param LinkBatchFactory $linkBatchFactory + * @param bool $joinWithArchive */ - public function __construct( $form, $conds = [] ) { + public function __construct( + SpecialAbuseLog $form, + array $conds, + LinkBatchFactory $linkBatchFactory, + bool $joinWithArchive = false + ) { + parent::__construct( $form->getContext(), $form->getLinkRenderer() ); $this->mForm = $form; $this->mConds = $conds; - parent::__construct(); + $this->linkBatchFactory = $linkBatchFactory; + $this->joinWithArchive = $joinWithArchive; } /** @@ -38,21 +54,45 @@ class AbuseLogPager extends ReverseChronologicalPager { $conds = $this->mConds; $info = [ - 'tables' => [ 'abuse_filter_log', 'abuse_filter' ], - 'fields' => '*', + 'tables' => [ 'abuse_filter_log', 'abuse_filter', 'revision' ], + 'fields' => [ + $this->mDb->tableName( 'abuse_filter_log' ) . '.*', + $this->mDb->tableName( 'abuse_filter' ) . '.*', + 'rev_id', + ], 'conds' => $conds, - 'join_conds' => - [ 'abuse_filter' => + 'join_conds' => [ + 'abuse_filter' => [ + 'LEFT JOIN', + 'af_id=afl_filter', + ], + 'revision' => [ + 'LEFT JOIN', [ - 'LEFT JOIN', - 'af_id=afl_filter', - ], + 'afl_wiki IS NULL', + 'afl_rev_id IS NOT NULL', + 'rev_id=afl_rev_id', + ] ], + ], ]; - if ( !$this->mForm->canSeeHidden() ) { - $db = $this->mDb; - $info['conds'][] = SpecialAbuseLog::getNotDeletedCond( $db ); + if ( $this->joinWithArchive ) { + $info['tables'][] = 'archive'; + $info['fields'][] = 'ar_timestamp'; + $info['join_conds']['archive'] = [ + 'LEFT JOIN', + [ + 'afl_wiki IS NULL', + 'afl_rev_id IS NOT NULL', + 'rev_id IS NULL', + 'ar_rev_id=afl_rev_id', + ] + ]; + } + + if ( !$this->mForm->canSeeHidden( $this->getUser() ) ) { + $info['conds']['afl_deleted'] = 0; } return $info; @@ -66,7 +106,7 @@ class AbuseLogPager extends ReverseChronologicalPager { return; } - $lb = new LinkBatch(); + $lb = $this->linkBatchFactory->newLinkBatch(); $lb->setCaller( __METHOD__ ); foreach ( $result as $row ) { // Only for local wiki results diff --git a/AbuseFilter/includes/pagers/GlobalAbuseFilterPager.php b/AbuseFilter/includes/pagers/GlobalAbuseFilterPager.php index 30173475..9c8033ce 100644 --- a/AbuseFilter/includes/pagers/GlobalAbuseFilterPager.php +++ b/AbuseFilter/includes/pagers/GlobalAbuseFilterPager.php @@ -11,8 +11,8 @@ class GlobalAbuseFilterPager extends AbuseFilterPager { * @param array $conds * @param LinkRenderer $linkRenderer */ - public function __construct( $page, $conds, $linkRenderer ) { - parent::__construct( $page, $conds, $linkRenderer, [ '', 'LIKE' ] ); + public function __construct( AbuseFilterViewList $page, $conds, LinkRenderer $linkRenderer ) { + parent::__construct( $page, $conds, $linkRenderer, '', 'LIKE' ); $this->mDb = wfGetDB( DB_REPLICA, [], $this->getConfig()->get( 'AbuseFilterCentralDB' ) ); } @@ -30,12 +30,13 @@ class GlobalAbuseFilterPager extends AbuseFilterPager { case 'af_id': return $lang->formatNum( intval( $value ) ); case 'af_public_comments': - return $this->getOutput()->parseInline( $value ); + return $this->getOutput()->parseInlineAsInterface( $value ); case 'af_actions': $actions = explode( ',', $value ); $displayActions = []; + $context = $this->getContext(); foreach ( $actions as $action ) { - $displayActions[] = AbuseFilter::getActionDisplay( $action ); + $displayActions[] = AbuseFilter::getActionDisplay( $action, $context ); } return $lang->commaList( $displayActions ); case 'af_enabled': diff --git a/AbuseFilter/includes/parser/AFPData.php b/AbuseFilter/includes/parser/AFPData.php index de8d8270..de7c1978 100644 --- a/AbuseFilter/includes/parser/AFPData.php +++ b/AbuseFilter/includes/parser/AFPData.php @@ -2,16 +2,23 @@ class AFPData { // Datatypes - const DINT = 'int'; - const DSTRING = 'string'; - const DNULL = 'null'; - const DBOOL = 'bool'; - const DFLOAT = 'float'; - const DARRAY = 'array'; - - // Translation table mapping shell-style wildcards to PCRE equivalents. - // Derived from <http://www.php.net/manual/en/function.fnmatch.php#100207> - private static $wildcardMap = [ + public const DINT = 'int'; + public const DSTRING = 'string'; + public const DNULL = 'null'; + public const DBOOL = 'bool'; + public const DFLOAT = 'float'; + public const DARRAY = 'array'; + // Special purpose type for non-initialized stuff + public const DUNDEFINED = 'undefined'; + // Special purpose for creating instances that will be populated later + public const DEMPTY = 'empty'; + + /** + * Translation table mapping shell-style wildcards to PCRE equivalents. + * Derived from <http://www.php.net/manual/en/function.fnmatch.php#100207> + * @internal + */ + public const WILDCARD_MAP = [ '\*' => '.*', '\+' => '\+', '\-' => '\-', @@ -23,14 +30,40 @@ class AFPData { '\]' => ']', ]; + /** + * @var string One of the D* const from this class + * @private Use $this->getType() + */ public $type; + /** + * @var mixed|null|AFPData[] The actual data contained in this object + * @private Use $this->getData() + */ public $data; /** + * @return string + */ + public function getType() { + return $this->type; + } + + /** + * @return AFPData[]|mixed|null + */ + public function getData() { + return $this->data; + } + + /** * @param string $type - * @param mixed|null $val + * @param AFPData[]|mixed|null $val */ - public function __construct( $type = self::DNULL, $val = null ) { + public function __construct( $type, $val = null ) { + if ( ( $type === self::DUNDEFINED || $type === self::DEMPTY ) && $val !== null ) { + // Sanity + throw new InvalidArgumentException( 'DUNDEFINED and DEMPTY cannot have a non-null value' ); + } $this->type = $type; $this->data = $val; } @@ -41,61 +74,57 @@ class AFPData { * @throws AFPException */ public static function newFromPHPVar( $var ) { - if ( is_string( $var ) ) { - return new AFPData( self::DSTRING, $var ); - } elseif ( is_int( $var ) ) { - return new AFPData( self::DINT, $var ); - } elseif ( is_float( $var ) ) { - return new AFPData( self::DFLOAT, $var ); - } elseif ( is_bool( $var ) ) { - return new AFPData( self::DBOOL, $var ); - } elseif ( is_array( $var ) ) { - $result = []; - foreach ( $var as $item ) { - $result[] = self::newFromPHPVar( $item ); - } - - return new AFPData( self::DARRAY, $result ); - } elseif ( is_null( $var ) ) { - return new AFPData(); - } else { - throw new AFPException( - 'Data type ' . gettype( $var ) . ' is not supported by AbuseFilter' - ); + switch ( gettype( $var ) ) { + case 'string': + return new AFPData( self::DSTRING, $var ); + case 'integer': + return new AFPData( self::DINT, $var ); + case 'double': + return new AFPData( self::DFLOAT, $var ); + case 'boolean': + return new AFPData( self::DBOOL, $var ); + case 'array': + $result = []; + foreach ( $var as $item ) { + $result[] = self::newFromPHPVar( $item ); + } + return new AFPData( self::DARRAY, $result ); + case 'NULL': + return new AFPData( self::DNULL ); + default: + throw new AFPException( + 'Data type ' . gettype( $var ) . ' is not supported by AbuseFilter' + ); } } /** - * @return AFPData - */ - public function dup() { - return new AFPData( $this->type, $this->data ); - } - - /** * @param AFPData $orig * @param string $target * @return AFPData */ - public static function castTypes( $orig, $target ) { - if ( $orig->type == $target ) { - return $orig->dup(); + public static function castTypes( AFPData $orig, $target ) { + if ( $orig->type === $target ) { + return $orig; + } + if ( $orig->type === self::DUNDEFINED ) { + // This case should be handled at a higher level, to avoid implicitly relying on what + // this method will do for the specific case. + throw new AFPException( 'Refusing to cast DUNDEFINED to something else' ); } - if ( $target == self::DNULL ) { - return new AFPData(); + if ( $target === self::DNULL ) { + // We don't expose any method to cast to null. And, actually, should we? + return new AFPData( self::DNULL ); } - if ( $orig->type == self::DARRAY ) { - if ( $target == self::DBOOL ) { + if ( $orig->type === self::DARRAY ) { + if ( $target === self::DBOOL ) { return new AFPData( self::DBOOL, (bool)count( $orig->data ) ); - } - if ( $target == self::DFLOAT ) { + } elseif ( $target === self::DFLOAT ) { return new AFPData( self::DFLOAT, floatval( count( $orig->data ) ) ); - } - if ( $target == self::DINT ) { - return new AFPData( self::DINT, intval( count( $orig->data ) ) ); - } - if ( $target == self::DSTRING ) { + } elseif ( $target === self::DINT ) { + return new AFPData( self::DINT, count( $orig->data ) ); + } elseif ( $target === self::DSTRING ) { $s = ''; foreach ( $orig->data as $item ) { $s .= $item->toString() . "\n"; @@ -105,97 +134,72 @@ class AFPData { } } - if ( $target == self::DBOOL ) { + if ( $target === self::DBOOL ) { return new AFPData( self::DBOOL, (bool)$orig->data ); - } - if ( $target == self::DFLOAT ) { + } elseif ( $target === self::DFLOAT ) { return new AFPData( self::DFLOAT, floatval( $orig->data ) ); - } - if ( $target == self::DINT ) { + } elseif ( $target === self::DINT ) { return new AFPData( self::DINT, intval( $orig->data ) ); - } - if ( $target == self::DSTRING ) { + } elseif ( $target === self::DSTRING ) { return new AFPData( self::DSTRING, strval( $orig->data ) ); - } - if ( $target == self::DARRAY ) { + } elseif ( $target === self::DARRAY ) { + // We don't expose any method to cast to array return new AFPData( self::DARRAY, [ $orig ] ); } + throw new AFPException( 'Cannot cast ' . $orig->type . " to $target." ); } /** - * @param AFPData $value - * @return AFPData - */ - public static function boolInvert( $value ) { - return new AFPData( self::DBOOL, !$value->toBool() ); - } - - /** - * @param AFPData $base - * @param AFPData $exponent - * @return AFPData - */ - public static function pow( $base, $exponent ) { - $res = pow( $base->toNumber(), $exponent->toNumber() ); - if ( $res === (int)$res ) { - return new AFPData( self::DINT, $res ); - } else { - return new AFPData( self::DFLOAT, $res ); - } - } - - /** - * @param AFPData $a - * @param AFPData $b * @return AFPData */ - public static function keywordIn( $a, $b ) { - $a = $a->toString(); - $b = $b->toString(); - - if ( $a == '' || $b == '' ) { - return new AFPData( self::DBOOL, false ); + public function boolInvert() { + if ( $this->type === self::DUNDEFINED ) { + return new AFPData( self::DUNDEFINED ); } - - return new AFPData( self::DBOOL, strpos( $b, $a ) !== false ); + return new AFPData( self::DBOOL, !$this->toBool() ); } /** - * @param AFPData $a - * @param AFPData $b + * @param AFPData $exponent * @return AFPData */ - public static function keywordContains( $a, $b ) { - $a = $a->toString(); - $b = $b->toString(); - - if ( $a == '' || $b == '' ) { - return new AFPData( self::DBOOL, false ); + public function pow( AFPData $exponent ) { + if ( $this->type === self::DUNDEFINED || $exponent->type === self::DUNDEFINED ) { + return new AFPData( self::DUNDEFINED ); } + $res = pow( $this->toNumber(), $exponent->toNumber() ); + $type = is_int( $res ) ? self::DINT : self::DFLOAT; - return new AFPData( self::DBOOL, strpos( $a, $b ) !== false ); + return new AFPData( $type, $res ); } /** - * @param AFPData $d1 * @param AFPData $d2 * @param bool $strict whether to also check types * @return bool + * @throws AFPException if $this or $d2 is a DUNDEFINED. This shouldn't happen, because this method + * only returns a boolean, and thus the type of the result has already been decided and cannot + * be changed to be a DUNDEFINED from here. + * @internal */ - public static function equals( $d1, $d2, $strict = false ) { - if ( $d1->type != self::DARRAY && $d2->type != self::DARRAY ) { - $typecheck = $d1->type == $d2->type || !$strict; - return $typecheck && $d1->toString() === $d2->toString(); - } elseif ( $d1->type == self::DARRAY && $d2->type == self::DARRAY ) { - $data1 = $d1->data; + public function equals( AFPData $d2, $strict = false ) { + if ( $this->type === self::DUNDEFINED || $d2->type === self::DUNDEFINED ) { + throw new AFPException( + __METHOD__ . " got a DUNDEFINED. This should be handled at a higher level" + ); + } elseif ( $this->type !== self::DARRAY && $d2->type !== self::DARRAY ) { + $typecheck = $this->type === $d2->type || !$strict; + return $typecheck && $this->toString() === $d2->toString(); + } elseif ( $this->type === self::DARRAY && $d2->type === self::DARRAY ) { + $data1 = $this->data; $data2 = $d2->data; if ( count( $data1 ) !== count( $data2 ) ) { return false; } $length = count( $data1 ); for ( $i = 0; $i < $length; $i++ ) { - $result = self::equals( $data1[$i], $data2[$i], $strict ); - if ( $result === false ) { + // @phan-suppress-next-line PhanTypeArraySuspiciousNullable Array type + if ( $data1[$i]->equals( $data2[$i], $strict ) === false ) { return false; } } @@ -205,10 +209,11 @@ class AFPData { if ( $strict ) { return false; } - if ( $d1->type == self::DARRAY && count( $d1->data ) === 0 ) { - return ( $d2->type == self::DBOOL && $d2->toBool() == false ) || $d2->type == self::DNULL; - } elseif ( $d2->type == self::DARRAY && count( $d2->data ) === 0 ) { - return ( $d1->type == self::DBOOL && $d1->toBool() == false ) || $d1->type == self::DNULL; + if ( $this->type === self::DARRAY && count( $this->data ) === 0 ) { + return ( $d2->type === self::DBOOL && $d2->toBool() === false ) || $d2->type === self::DNULL; + } elseif ( $d2->type === self::DARRAY && count( $d2->data ) === 0 ) { + return ( $this->type === self::DBOOL && $this->toBool() === false ) || + $this->type === self::DNULL; } else { return false; } @@ -216,138 +221,80 @@ class AFPData { } /** - * @param AFPData $str - * @param AFPData $pattern * @return AFPData */ - public static function keywordLike( $str, $pattern ) { - $str = $str->toString(); - $pattern = '#^' . strtr( preg_quote( $pattern->toString(), '#' ), self::$wildcardMap ) . '$#u'; - Wikimedia\suppressWarnings(); - $result = preg_match( $pattern, $str ); - Wikimedia\restoreWarnings(); - - return new AFPData( self::DBOOL, (bool)$result ); - } - - /** - * @param AFPData $str - * @param AFPData $regex - * @param int $pos - * @param bool $insensitive - * @return AFPData - * @throws Exception - */ - public static function keywordRegex( $str, $regex, $pos, $insensitive = false ) { - $str = $str->toString(); - $pattern = $regex->toString(); - - $pattern = preg_replace( '!(\\\\\\\\)*(\\\\)?/!', '$1\/', $pattern ); - $pattern = "/$pattern/u"; - - if ( $insensitive ) { - $pattern .= 'i'; - } - - Wikimedia\suppressWarnings(); - $result = preg_match( $pattern, $str ); - Wikimedia\restoreWarnings(); - if ( $result === false ) { - throw new AFPUserVisibleException( - 'regexfailure', - $pos, - [ $pattern ] - ); - } - - return new AFPData( self::DBOOL, (bool)$result ); - } - - /** - * @param AFPData $str - * @param AFPData $regex - * @param int $pos - * @return AFPData - */ - public static function keywordRegexInsensitive( $str, $regex, $pos ) { - return self::keywordRegex( $str, $regex, $pos, true ); - } - - /** - * @param AFPData $data - * @return AFPData - */ - public static function unaryMinus( $data ) { - if ( $data->type == self::DINT ) { - return new AFPData( $data->type, -$data->toInt() ); + public function unaryMinus() { + if ( $this->type === self::DUNDEFINED ) { + return new AFPData( self::DUNDEFINED ); + } elseif ( $this->type === self::DINT ) { + return new AFPData( $this->type, -$this->toInt() ); } else { - return new AFPData( $data->type, -$data->toFloat() ); + $type = $this->type === self::DEMPTY ? self::DNULL : $this->type; + return new AFPData( $type, -$this->toFloat() ); } } /** - * @param AFPData $a * @param AFPData $b * @param string $op * @return AFPData * @throws AFPException */ - public static function boolOp( $a, $b, $op ) { - $a = $a->toBool(); - $b = $b->toBool(); - if ( $op == '|' ) { + public function boolOp( AFPData $b, $op ) { + $a = $this->type === self::DUNDEFINED ? false : $this->toBool(); + $b = $b->type === self::DUNDEFINED ? false : $b->toBool(); + + if ( $op === '|' ) { return new AFPData( self::DBOOL, $a || $b ); - } - if ( $op == '&' ) { + } elseif ( $op === '&' ) { return new AFPData( self::DBOOL, $a && $b ); - } - if ( $op == '^' ) { + } elseif ( $op === '^' ) { return new AFPData( self::DBOOL, $a xor $b ); } // Should never happen. + // @codeCoverageIgnoreStart throw new AFPException( "Invalid boolean operation: {$op}" ); + // @codeCoverageIgnoreEnd } /** - * @param AFPData $a * @param AFPData $b * @param string $op * @return AFPData * @throws AFPException */ - public static function compareOp( $a, $b, $op ) { - if ( $op == '==' || $op == '=' ) { - return new AFPData( self::DBOOL, self::equals( $a, $b ) ); + public function compareOp( AFPData $b, $op ) { + if ( $this->type === self::DUNDEFINED || $b->type === self::DUNDEFINED ) { + return new AFPData( self::DUNDEFINED ); } - if ( $op == '!=' ) { - return new AFPData( self::DBOOL, !self::equals( $a, $b ) ); + if ( $op === '==' || $op === '=' ) { + return new AFPData( self::DBOOL, $this->equals( $b ) ); + } elseif ( $op === '!=' ) { + return new AFPData( self::DBOOL, !$this->equals( $b ) ); + } elseif ( $op === '===' ) { + return new AFPData( self::DBOOL, $this->equals( $b, true ) ); + } elseif ( $op === '!==' ) { + return new AFPData( self::DBOOL, !$this->equals( $b, true ) ); } - if ( $op == '===' ) { - return new AFPData( self::DBOOL, self::equals( $a, $b, true ) ); - } - if ( $op == '!==' ) { - return new AFPData( self::DBOOL, !self::equals( $a, $b, true ) ); - } - $a = $a->toString(); + + $a = $this->toString(); $b = $b->toString(); - if ( $op == '>' ) { + if ( $op === '>' ) { return new AFPData( self::DBOOL, $a > $b ); - } - if ( $op == '<' ) { + } elseif ( $op === '<' ) { return new AFPData( self::DBOOL, $a < $b ); - } - if ( $op == '>=' ) { + } elseif ( $op === '>=' ) { return new AFPData( self::DBOOL, $a >= $b ); - } - if ( $op == '<=' ) { + } elseif ( $op === '<=' ) { return new AFPData( self::DBOOL, $a <= $b ); } // Should never happen + // @codeCoverageIgnoreStart throw new AFPException( "Invalid comparison operation: {$op}" ); + // @codeCoverageIgnoreEnd } /** - * @param AFPData $a * @param AFPData $b * @param string $op * @param int $pos @@ -355,68 +302,114 @@ class AFPData { * @throws AFPUserVisibleException * @throws AFPException */ - public static function mulRel( $a, $b, $op, $pos ) { - $a = $a->toNumber(); + public function mulRel( AFPData $b, $op, $pos ) { + if ( $b->type === self::DUNDEFINED ) { + // The LHS type is checked later, because we first need to ensure we're not + // dividing or taking modulo by 0 (and that should throw regardless of whether + // the LHS is undefined). + return new AFPData( self::DUNDEFINED ); + } + $b = $b->toNumber(); - if ( $op != '*' && $b == 0 ) { - throw new AFPUserVisibleException( 'dividebyzero', $pos, [ $a ] ); + if ( + ( $op === '/' && (float)$b === 0.0 ) || + ( $op === '%' && (int)$b === 0 ) + ) { + $lhs = $this->type === self::DUNDEFINED ? 0 : $this->toNumber(); + throw new AFPUserVisibleException( 'dividebyzero', $pos, [ $lhs ] ); + } + + if ( $this->type === self::DUNDEFINED ) { + return new AFPData( self::DUNDEFINED ); } + $a = $this->toNumber(); - if ( $op == '*' ) { + if ( $op === '*' ) { $data = $a * $b; - } elseif ( $op == '/' ) { + } elseif ( $op === '/' ) { $data = $a / $b; - } elseif ( $op == '%' ) { + } elseif ( $op === '%' ) { $data = $a % $b; } else { // Should never happen + // @codeCoverageIgnoreStart throw new AFPException( "Invalid multiplication-related operation: {$op}" ); + // @codeCoverageIgnoreEnd } - if ( $data === (int)$data ) { - $data = intval( $data ); - $type = self::DINT; - } else { - $data = floatval( $data ); - $type = self::DFLOAT; - } + $type = is_int( $data ) ? self::DINT : self::DFLOAT; return new AFPData( $type, $data ); } /** - * @param AFPData $a * @param AFPData $b * @return AFPData */ - public static function sum( $a, $b ) { - if ( $a->type == self::DSTRING || $b->type == self::DSTRING ) { - return new AFPData( self::DSTRING, $a->toString() . $b->toString() ); - } elseif ( $a->type == self::DARRAY && $b->type == self::DARRAY ) { - return new AFPData( self::DARRAY, array_merge( $a->toArray(), $b->toArray() ) ); + public function sum( AFPData $b ) { + if ( $this->type === self::DUNDEFINED || $b->type === self::DUNDEFINED ) { + return new AFPData( self::DUNDEFINED ); + } elseif ( $this->type === self::DSTRING || $b->type === self::DSTRING ) { + return new AFPData( self::DSTRING, $this->toString() . $b->toString() ); + } elseif ( $this->type === self::DARRAY && $b->type === self::DARRAY ) { + return new AFPData( self::DARRAY, array_merge( $this->toArray(), $b->toArray() ) ); } else { - $res = $a->toNumber() + $b->toNumber(); - if ( $res === (int)$res ) { - return new AFPData( self::DINT, $res ); - } else { - return new AFPData( self::DFLOAT, $res ); - } + $res = $this->toNumber() + $b->toNumber(); + $type = is_int( $res ) ? self::DINT : self::DFLOAT; + + return new AFPData( $type, $res ); } } /** - * @param AFPData $a * @param AFPData $b * @return AFPData */ - public static function sub( $a, $b ) { - $res = $a->toNumber() - $b->toNumber(); - if ( $res === (int)$res ) { - return new AFPData( self::DINT, $res ); - } else { - return new AFPData( self::DFLOAT, $res ); + public function sub( AFPData $b ) { + if ( $this->type === self::DUNDEFINED || $b->type === self::DUNDEFINED ) { + return new AFPData( self::DUNDEFINED ); + } + $res = $this->toNumber() - $b->toNumber(); + $type = is_int( $res ) ? self::DINT : self::DFLOAT; + + return new AFPData( $type, $res ); + } + + /** + * Check whether this instance contains the DUNDEFINED type, recursively + * @return bool + */ + public function hasUndefined() : bool { + if ( $this->type === self::DUNDEFINED ) { + return true; + } + if ( $this->type === self::DARRAY ) { + foreach ( $this->data as $el ) { + if ( $el->hasUndefined() ) { + return true; + } + } + } + return false; + } + + /** + * Return a clone of this instance where DUNDEFINED is replaced with DNULL + * @return $this + */ + public function cloneAsUndefinedReplacedWithNull() : self { + if ( $this->type === self::DUNDEFINED ) { + return new self( self::DNULL ); + } + if ( $this->type === self::DARRAY ) { + $data = []; + foreach ( $this->data as $el ) { + $data[] = $el->cloneAsUndefinedReplacedWithNull(); + } + return new self( self::DARRAY, $data ); } + return clone $this; } /** Convert shorteners */ @@ -444,9 +437,13 @@ class AFPData { return $output; case self::DNULL: + case self::DUNDEFINED: + case self::DEMPTY: return null; default: + // @codeCoverageIgnoreStart throw new MWException( "Unknown type" ); + // @codeCoverageIgnoreEnd } } @@ -482,7 +479,13 @@ class AFPData { * @return int|float */ public function toNumber() { - return $this->type == self::DINT ? $this->toInt() : $this->toFloat(); + // Types that can be cast to int + $intLikeTypes = [ + self::DINT, + self::DBOOL, + self::DNULL + ]; + return in_array( $this->type, $intLikeTypes, true ) ? $this->toInt() : $this->toFloat(); } /** diff --git a/AbuseFilter/includes/parser/AFPParserState.php b/AbuseFilter/includes/parser/AFPParserState.php index 453948d1..ee345d94 100644 --- a/AbuseFilter/includes/parser/AFPParserState.php +++ b/AbuseFilter/includes/parser/AFPParserState.php @@ -7,7 +7,7 @@ class AFPParserState { * @param AFPToken $token * @param int $pos */ - public function __construct( $token, $pos ) { + public function __construct( AFPToken $token, $pos ) { $this->token = $token; $this->pos = $pos; } diff --git a/AbuseFilter/includes/parser/AFPSyntaxTree.php b/AbuseFilter/includes/parser/AFPSyntaxTree.php new file mode 100644 index 00000000..ffca3eb9 --- /dev/null +++ b/AbuseFilter/includes/parser/AFPSyntaxTree.php @@ -0,0 +1,27 @@ +<?php + +/** + * A class representing a whole AST generated by AFPTreeParser, holding AFPTreeNode's. This wrapper + * could be expanded in the future. For now, it's mostly useful for typehints, and to have an + * evalTree function in the CachingParser. + */ +class AFPSyntaxTree { + /** + * @var AFPTreeNode|null + */ + private $rootNode; + + /** + * @param AFPTreeNode|null $root + */ + public function __construct( AFPTreeNode $root = null ) { + $this->rootNode = $root; + } + + /** + * @return AFPTreeNode|null + */ + public function getRoot() { + return $this->rootNode; + } +} diff --git a/AbuseFilter/includes/parser/AFPToken.php b/AbuseFilter/includes/parser/AFPToken.php index 897f5ded..78fdd7c3 100644 --- a/AbuseFilter/includes/parser/AFPToken.php +++ b/AbuseFilter/includes/parser/AFPToken.php @@ -36,20 +36,29 @@ * * Atom (A) - return value */ class AFPToken { - const TNONE = 'T_NONE'; - const TID = 'T_ID'; - const TKEYWORD = 'T_KEYWORD'; - const TSTRING = 'T_STRING'; - const TINT = 'T_INT'; - const TFLOAT = 'T_FLOAT'; - const TOP = 'T_OP'; - const TBRACE = 'T_BRACE'; - const TSQUAREBRACKET = 'T_SQUARE_BRACKET'; - const TCOMMA = 'T_COMMA'; - const TSTATEMENTSEPARATOR = 'T_STATEMENT_SEPARATOR'; + public const TNONE = 'T_NONE'; + public const TID = 'T_ID'; + public const TKEYWORD = 'T_KEYWORD'; + public const TSTRING = 'T_STRING'; + public const TINT = 'T_INT'; + public const TFLOAT = 'T_FLOAT'; + public const TOP = 'T_OP'; + public const TBRACE = 'T_BRACE'; + public const TSQUAREBRACKET = 'T_SQUARE_BRACKET'; + public const TCOMMA = 'T_COMMA'; + public const TSTATEMENTSEPARATOR = 'T_STATEMENT_SEPARATOR'; + /** + * @var string One of the T* constant from this class + */ public $type; + /** + * @var mixed|null The actual value of the token + */ public $value; + /** + * @var int The code offset where this token is found + */ public $pos; /** diff --git a/AbuseFilter/includes/parser/AFPTransitionBase.php b/AbuseFilter/includes/parser/AFPTransitionBase.php new file mode 100644 index 00000000..e784a2a5 --- /dev/null +++ b/AbuseFilter/includes/parser/AFPTransitionBase.php @@ -0,0 +1,143 @@ +<?php + +use MediaWiki\Extension\AbuseFilter\KeywordsManager; + +/** + * Base parse-related class to be used while the old parser is being phased out + * + * @internal This is a temporary class until things are settled down + * @property KeywordsManager $keywordsManager + */ +abstract class AFPTransitionBase { + public const FUNCTIONS = [ + 'lcase' => 'funcLc', + 'ucase' => 'funcUc', + 'length' => 'funcLen', + 'string' => 'castString', + 'int' => 'castInt', + 'float' => 'castFloat', + 'bool' => 'castBool', + 'norm' => 'funcNorm', + 'ccnorm' => 'funcCCNorm', + 'ccnorm_contains_any' => 'funcCCNormContainsAny', + 'ccnorm_contains_all' => 'funcCCNormContainsAll', + 'specialratio' => 'funcSpecialRatio', + 'rmspecials' => 'funcRMSpecials', + 'rmdoubles' => 'funcRMDoubles', + 'rmwhitespace' => 'funcRMWhitespace', + 'count' => 'funcCount', + 'rcount' => 'funcRCount', + 'get_matches' => 'funcGetMatches', + 'ip_in_range' => 'funcIPInRange', + 'contains_any' => 'funcContainsAny', + 'contains_all' => 'funcContainsAll', + 'equals_to_any' => 'funcEqualsToAny', + 'substr' => 'funcSubstr', + 'strlen' => 'funcLen', + 'strpos' => 'funcStrPos', + 'str_replace' => 'funcStrReplace', + 'rescape' => 'funcStrRegexEscape', + 'set' => 'funcSetVar', + 'set_var' => 'funcSetVar', + 'sanitize' => 'funcSanitize', + ]; + + /** + * The minimum and maximum amount of arguments required by each function. + * @var int[][] + */ + public const FUNC_ARG_COUNT = [ + 'lcase' => [ 1, 1 ], + 'ucase' => [ 1, 1 ], + 'length' => [ 1, 1 ], + 'string' => [ 1, 1 ], + 'int' => [ 1, 1 ], + 'float' => [ 1, 1 ], + 'bool' => [ 1, 1 ], + 'norm' => [ 1, 1 ], + 'ccnorm' => [ 1, 1 ], + 'ccnorm_contains_any' => [ 2, INF ], + 'ccnorm_contains_all' => [ 2, INF ], + 'specialratio' => [ 1, 1 ], + 'rmspecials' => [ 1, 1 ], + 'rmdoubles' => [ 1, 1 ], + 'rmwhitespace' => [ 1, 1 ], + 'count' => [ 1, 2 ], + 'rcount' => [ 1, 2 ], + 'get_matches' => [ 2, 2 ], + 'ip_in_range' => [ 2, 2 ], + 'contains_any' => [ 2, INF ], + 'contains_all' => [ 2, INF ], + 'equals_to_any' => [ 2, INF ], + 'substr' => [ 2, 3 ], + 'strlen' => [ 1, 1 ], + 'strpos' => [ 2, 3 ], + 'str_replace' => [ 3, 3 ], + 'rescape' => [ 1, 1 ], + 'set' => [ 2, 2 ], + 'set_var' => [ 2, 2 ], + 'sanitize' => [ 1, 1 ], + ]; + + /** + * @var int The position of the current token + */ + protected $mPos; + + /** + * Check that a built-in function has been provided the right amount of arguments + * + * @param array $args The arguments supplied to the function + * @param string $func The function name + * @throws AFPUserVisibleException + */ + protected function checkArgCount( $args, $func ) { + if ( !array_key_exists( $func, self::FUNC_ARG_COUNT ) ) { + // @codeCoverageIgnoreStart + throw new InvalidArgumentException( "$func is not a valid function." ); + // @codeCoverageIgnoreEnd + } + list( $min, $max ) = self::FUNC_ARG_COUNT[ $func ]; + if ( count( $args ) < $min ) { + throw new AFPUserVisibleException( + $min === 1 ? 'noparams' : 'notenoughargs', + $this->mPos, + [ $func, $min, count( $args ) ] + ); + } elseif ( count( $args ) > $max ) { + throw new AFPUserVisibleException( + 'toomanyargs', + $this->mPos, + [ $func, $max, count( $args ) ] + ); + } + } + + /** + * Check whether the given name is a reserved identifier, e.g. the name of a built-in variable, + * function, or keyword. + * + * @param string $name + * @return bool + */ + protected function isReservedIdentifier( $name ) { + return $this->keywordsManager->varExists( $name ) || + array_key_exists( $name, self::FUNCTIONS ) || + // We need to check for true, false, if/then/else etc. because, even if they have a different + // AFPToken type, they may be used inside set/set_var() + in_array( $name, AbuseFilterTokenizer::KEYWORDS, true ); + } + + /** + * @param string $fname + * @return bool + */ + protected function functionIsVariadic( $fname ) { + if ( !array_key_exists( $fname, self::FUNC_ARG_COUNT ) ) { + // @codeCoverageIgnoreStart + throw new InvalidArgumentException( "Function $fname is not valid" ); + // @codeCoverageIgnoreEnd + } + return self::FUNC_ARG_COUNT[$fname][1] === INF; + } +} diff --git a/AbuseFilter/includes/parser/AFPTreeNode.php b/AbuseFilter/includes/parser/AFPTreeNode.php index a3c2a063..65dc5a7f 100644 --- a/AbuseFilter/includes/parser/AFPTreeNode.php +++ b/AbuseFilter/includes/parser/AFPTreeNode.php @@ -10,7 +10,7 @@ class AFPTreeNode { // SEMICOLON is a many-children node, denoting that the nodes have to be // evaluated in order and the last value has to be returned. - const SEMICOLON = 'SEMICOLON'; + public const SEMICOLON = 'SEMICOLON'; // ASSIGNMENT (formerly known as SET) is a node which is responsible for // assigning values to variables. ASSIGNMENT is a (variable name [string], @@ -18,47 +18,47 @@ class AFPTreeNode { // values at array offsets) is a (variable name [string], index [tree node], // value [tree node]) tuple, and ARRAY_APPEND has the form of (variable name // [string], value [tree node]). - const ASSIGNMENT = 'ASSIGNMENT'; - const INDEX_ASSIGNMENT = 'INDEX_ASSIGNMENT'; - const ARRAY_APPEND = 'ARRAY_APPEND'; + public const ASSIGNMENT = 'ASSIGNMENT'; + public const INDEX_ASSIGNMENT = 'INDEX_ASSIGNMENT'; + public const ARRAY_APPEND = 'ARRAY_APPEND'; // CONDITIONAL represents both a ternary operator and an if-then-else-end - // construct. The format is (condition, evaluated-if-true, - // evaluated-in-false), all tree nodes. - const CONDITIONAL = 'CONDITIONAL'; + // construct. The format is (condition, evaluated-if-true, evaluated-in-false). + // The first two are tree nodes, the last one can be a node, or null if there's no else. + public const CONDITIONAL = 'CONDITIONAL'; // LOGIC is a logic operator accepted by AFPData::boolOp. The format is // (operation, left operand, right operand). - const LOGIC = 'LOGIC'; + public const LOGIC = 'LOGIC'; // COMPARE is a comparison operator accepted by AFPData::boolOp. The format is // (operation, left operand, right operand). - const COMPARE = 'COMPARE'; + public const COMPARE = 'COMPARE'; // SUM_REL is either '+' or '-'. The format is (operation, left operand, // right operand). - const SUM_REL = 'SUM_REL'; + public const SUM_REL = 'SUM_REL'; // MUL_REL is a multiplication-related operation accepted by AFPData::mulRel. // The format is (operation, left operand, right operand). - const MUL_REL = 'MUL_REL'; + public const MUL_REL = 'MUL_REL'; // POW is an exponentiation operator. The format is (base, exponent). - const POW = 'POW'; + public const POW = 'POW'; // BOOL_INVERT is a boolean inversion operator. The format is (operand). - const BOOL_INVERT = 'BOOL_INVERT'; + public const BOOL_INVERT = 'BOOL_INVERT'; // KEYWORD_OPERATOR is one of the binary keyword operators supported by the // filter language. The format is (keyword, left operand, right operand). - const KEYWORD_OPERATOR = 'KEYWORD_OPERATOR'; + public const KEYWORD_OPERATOR = 'KEYWORD_OPERATOR'; // UNARY is either unary minus or unary plus. The format is (operator, operand). - const UNARY = 'UNARY'; + public const UNARY = 'UNARY'; // ARRAY_INDEX is an operation of accessing an array by an offset. The format // is (array, offset). - const ARRAY_INDEX = 'ARRAY_INDEX'; + public const ARRAY_INDEX = 'ARRAY_INDEX'; // Since parenthesis only manipulate precedence of the operators, they are // not explicitly represented in the tree. @@ -66,15 +66,15 @@ class AFPTreeNode { // FUNCTION_CALL is an invocation of built-in function. The format is a // tuple where the first element is a function name, and all subsequent // elements are the arguments. - const FUNCTION_CALL = 'FUNCTION_CALL'; + public const FUNCTION_CALL = 'FUNCTION_CALL'; // ARRAY_DEFINITION is an array literal. The $children field contains tree // nodes for the values of each of the array element used. - const ARRAY_DEFINITION = 'ARRAY_DEFINITION'; + public const ARRAY_DEFINITION = 'ARRAY_DEFINITION'; // ATOM is a node representing a literal. The only element of $children is a // token corresponding to the literal. - const ATOM = 'ATOM'; + public const ATOM = 'ATOM'; /** @var string Type of the node, one of the constants above */ public $type; @@ -86,29 +86,92 @@ class AFPTreeNode { */ public $children; - // Position used for error reporting. + /** @var int Position used for error reporting. */ public $position; /** + * @var string[] Names of the variables assigned in this node or any of its descendants + * @todo We could change this to be an instance of a new AFPScope class (holding a var map) + * if we'll have the need to store other scope-specific data, + * see <https://phabricator.wikimedia.org/T230982#5475400>. + */ + private $innerAssignments = []; + + /** * @param string $type - * @param AFPTreeNode[]|string[]|AFPToken $children + * @param (AFPTreeNode|null)[]|string[]|AFPToken $children * @param int $position */ public function __construct( $type, $children, $position ) { $this->type = $type; $this->children = $children; $this->position = $position; + $this->populateInnerAssignments(); + } + + /** + * Save in this node all the variable names used in the children, and in this node if it's an + * assignment-related node. Note that this doesn't check whether the variable is custom or builtin: + * this is already checked when calling setUserVariable. + * In case we'll ever need to store other data in a node, or maybe even a Scope object, this could + * be moved to a different class which could also re-visit the whole AST. + */ + private function populateInnerAssignments() { + if ( $this->type === self::ATOM ) { + return; + } + + if ( + $this->type === self::ASSIGNMENT || + $this->type === self::INDEX_ASSIGNMENT || + $this->type === self::ARRAY_APPEND + ) { + $this->innerAssignments = [ $this->children[0] ]; + } elseif ( + $this->type === self::FUNCTION_CALL && + in_array( $this->children[0], [ 'set', 'set_var' ] ) && + // If unset, parsing will fail when checking arguments + isset( $this->children[1] ) + ) { + $varnameNode = $this->children[1]; + if ( $varnameNode->type !== self::ATOM ) { + // Shouldn't happen since variable variables are not allowed + // @codeCoverageIgnoreStart + throw new AFPException( "Got non-atom type {$varnameNode->type} for set_var" ); + // @codeCoverageIgnoreEnd + } + $this->innerAssignments = [ $varnameNode->children->value ]; + } + + // @phan-suppress-next-line PhanTypeSuspiciousNonTraversableForeach ATOM excluded above + foreach ( $this->children as $child ) { + if ( $child instanceof self ) { + $this->innerAssignments = array_merge( $this->innerAssignments, $child->getInnerAssignments() ); + } + } + } + + /** + * @return string[] + */ + public function getInnerAssignments() : array { + return $this->innerAssignments; } /** * @return string + * @codeCoverageIgnore */ public function toDebugString() { return implode( "\n", $this->toDebugStringInner() ); } + /** + * @return array + * @codeCoverageIgnore + */ private function toDebugStringInner() { - if ( $this->type == self::ATOM ) { + if ( $this->type === self::ATOM ) { return [ "ATOM({$this->children->type} {$this->children->value})" ]; } @@ -117,6 +180,7 @@ class AFPTreeNode { }; $lines = [ "{$this->type}" ]; + // @phan-suppress-next-line PhanTypeSuspiciousNonTraversableForeach children is array here foreach ( $this->children as $subnode ) { if ( $subnode instanceof AFPTreeNode ) { $sublines = array_map( $align, $subnode->toDebugStringInner() ); diff --git a/AbuseFilter/includes/parser/AFPTreeParser.php b/AbuseFilter/includes/parser/AFPTreeParser.php index 4fa35356..b4befd0f 100644 --- a/AbuseFilter/includes/parser/AFPTreeParser.php +++ b/AbuseFilter/includes/parser/AFPTreeParser.php @@ -5,33 +5,82 @@ * evaluating it into different passes, allowing the parse tree to be cached. * * @file + * @phan-file-suppress PhanPossiblyInfiniteRecursionSameParams Recursion controlled by class props */ +use MediaWiki\Extension\AbuseFilter\KeywordsManager; +use Psr\Log\LoggerInterface; + /** * A parser that transforms the text of the filter into a parse tree. */ -class AFPTreeParser { - // The tokenized representation of the filter parsed. +class AFPTreeParser extends AFPTransitionBase { + /** + * @var array[] Contains the AFPTokens for the code being parsed + */ public $mTokens; + /** + * @var AFPToken The current token + */ + public $mCur; + /** + * @var string|null The ID of the filter being parsed, if available. Can also be "global-$ID" + */ + protected $mFilter; - // Current token handled by the parser and its position. - public $mCur, $mPos; + public const CACHE_VERSION = 2; - const CACHE_VERSION = 2; + /** + * @var BagOStuff Used to cache tokens + */ + protected $cache; /** - * Create a new instance + * @var LoggerInterface Used for debugging */ - public function __construct() { + protected $logger; + + /** + * @var IBufferingStatsdDataFactory + */ + protected $statsd; + + /** @var KeywordsManager */ + protected $keywordsManager; + + /** + * @param BagOStuff $cache + * @param LoggerInterface $logger Used for debugging + * @param IBufferingStatsdDataFactory $statsd + * @param KeywordsManager $keywordsManager + */ + public function __construct( + BagOStuff $cache, + LoggerInterface $logger, + IBufferingStatsdDataFactory $statsd, + KeywordsManager $keywordsManager + ) { + $this->cache = $cache; + $this->logger = $logger; + $this->statsd = $statsd; + $this->keywordsManager = $keywordsManager; $this->resetState(); } /** + * @param string $filter + */ + public function setFilter( $filter ) { + $this->mFilter = $filter; + } + + /** * Resets the state */ public function resetState() { $this->mTokens = []; $this->mPos = 0; + $this->mFilter = null; } /** @@ -42,6 +91,16 @@ class AFPTreeParser { } /** + * Get the next token. This is similar to move() but doesn't change class members, + * allowing to look ahead without rolling back the state. + * + * @return AFPToken + */ + protected function getNextToken() { + return $this->mTokens[$this->mPos][0]; + } + + /** * getState() function allows parser state to be rollbacked to several tokens * back. * @@ -67,26 +126,37 @@ class AFPTreeParser { * * @param string $code * @throws AFPUserVisibleException - * @return AFPTreeNode|null + * @return AFPSyntaxTree */ - public function parse( $code ) { - $this->mTokens = AbuseFilterTokenizer::tokenize( $code ); + public function parse( $code ) : AFPSyntaxTree { + $tokenizer = new AbuseFilterTokenizer( $this->cache, $this->logger ); + $this->mTokens = $tokenizer->getTokens( $code ); $this->mPos = 0; - return $this->doLevelEntry(); + return $this->buildSyntaxTree(); + } + + /** + * @return AFPSyntaxTree + */ + public function buildSyntaxTree() : AFPSyntaxTree { + $startTime = microtime( true ); + $root = $this->doLevelEntry(); + $this->statsd->timing( 'abusefilter_cachingParser_buildtree', microtime( true ) - $startTime ); + return new AFPSyntaxTree( $root ); } /* Levels */ /** * Handles unexpected characters after the expression. - * @return AFPTreeNode|null + * @return AFPTreeNode|null Null only if no statements * @throws AFPUserVisibleException */ protected function doLevelEntry() { $result = $this->doLevelSemicolon(); - if ( $this->mCur->type != AFPToken::TNONE ) { + if ( $this->mCur->type !== AFPToken::TNONE ) { throw new AFPUserVisibleException( 'unexpectedatend', $this->mPos, [ $this->mCur->type ] @@ -108,23 +178,27 @@ class AFPTreeParser { $this->move(); $position = $this->mPos; - if ( $this->mCur->type == AFPToken::TNONE ) { + if ( + $this->mCur->type === AFPToken::TNONE || + ( $this->mCur->type === AFPToken::TBRACE && $this->mCur->value == ')' ) + ) { + // Handle special cases which the other parser handled in doLevelAtom break; } // Allow empty statements. - if ( $this->mCur->type == AFPToken::TSTATEMENTSEPARATOR ) { + if ( $this->mCur->type === AFPToken::TSTATEMENTSEPARATOR ) { continue; } $statements[] = $this->doLevelSet(); $position = $this->mPos; - } while ( $this->mCur->type == AFPToken::TSTATEMENTSEPARATOR ); + } while ( $this->mCur->type === AFPToken::TSTATEMENTSEPARATOR ); // Flatten the tree if possible. - if ( count( $statements ) == 0 ) { + if ( count( $statements ) === 0 ) { return null; - } elseif ( count( $statements ) == 1 ) { + } elseif ( count( $statements ) === 1 ) { return $statements[0]; } else { return new AFPTreeNode( AFPTreeNode::SEMICOLON, $statements, $position ); @@ -138,15 +212,16 @@ class AFPTreeParser { * @throws AFPUserVisibleException */ protected function doLevelSet() { - if ( $this->mCur->type == AFPToken::TID ) { - $varname = $this->mCur->value; + if ( $this->mCur->type === AFPToken::TID ) { + $varname = (string)$this->mCur->value; // Speculatively parse the assignment statement assuming it can // potentially be an assignment, but roll back if it isn't. + // @todo Use $this->getNextToken for clearer code $initialState = $this->getState(); $this->move(); - if ( $this->mCur->type == AFPToken::TOP && $this->mCur->value == ':=' ) { + if ( $this->mCur->type === AFPToken::TOP && $this->mCur->value === ':=' ) { $position = $this->mPos; $this->move(); $value = $this->doLevelSet(); @@ -154,24 +229,24 @@ class AFPTreeParser { return new AFPTreeNode( AFPTreeNode::ASSIGNMENT, [ $varname, $value ], $position ); } - if ( $this->mCur->type == AFPToken::TSQUAREBRACKET && $this->mCur->value == '[' ) { + if ( $this->mCur->type === AFPToken::TSQUAREBRACKET && $this->mCur->value === '[' ) { $this->move(); - if ( $this->mCur->type == AFPToken::TSQUAREBRACKET && $this->mCur->value == ']' ) { + if ( $this->mCur->type === AFPToken::TSQUAREBRACKET && $this->mCur->value === ']' ) { $index = 'append'; } else { // Parse index offset. $this->setState( $initialState ); $this->move(); $index = $this->doLevelSemicolon(); - if ( !( $this->mCur->type == AFPToken::TSQUAREBRACKET && $this->mCur->value == ']' ) ) { + if ( !( $this->mCur->type === AFPToken::TSQUAREBRACKET && $this->mCur->value === ']' ) ) { throw new AFPUserVisibleException( 'expectednotfound', $this->mPos, [ ']', $this->mCur->type, $this->mCur->value ] ); } } $this->move(); - if ( $this->mCur->type == AFPToken::TOP && $this->mCur->value == ':=' ) { + if ( $this->mCur->type === AFPToken::TOP && $this->mCur->value === ':=' ) { $position = $this->mPos; $this->move(); $value = $this->doLevelSet(); @@ -203,12 +278,12 @@ class AFPTreeParser { * @throws AFPUserVisibleException */ protected function doLevelConditions() { - if ( $this->mCur->type == AFPToken::TKEYWORD && $this->mCur->value == 'if' ) { + if ( $this->mCur->type === AFPToken::TKEYWORD && $this->mCur->value === 'if' ) { $position = $this->mPos; $this->move(); $condition = $this->doLevelBoolOps(); - if ( !( $this->mCur->type == AFPToken::TKEYWORD && $this->mCur->value == 'then' ) ) { + if ( !( $this->mCur->type === AFPToken::TKEYWORD && $this->mCur->value === 'then' ) ) { throw new AFPUserVisibleException( 'expectednotfound', $this->mPos, [ @@ -222,21 +297,14 @@ class AFPTreeParser { $valueIfTrue = $this->doLevelConditions(); - if ( !( $this->mCur->type == AFPToken::TKEYWORD && $this->mCur->value == 'else' ) ) { - throw new AFPUserVisibleException( 'expectednotfound', - $this->mPos, - [ - 'else', - $this->mCur->type, - $this->mCur->value - ] - ); + if ( $this->mCur->type === AFPToken::TKEYWORD && $this->mCur->value === 'else' ) { + $this->move(); + $valueIfFalse = $this->doLevelConditions(); + } else { + $valueIfFalse = null; } - $this->move(); - - $valueIfFalse = $this->doLevelConditions(); - if ( !( $this->mCur->type == AFPToken::TKEYWORD && $this->mCur->value == 'end' ) ) { + if ( !( $this->mCur->type === AFPToken::TKEYWORD && $this->mCur->value === 'end' ) ) { throw new AFPUserVisibleException( 'expectednotfound', $this->mPos, [ @@ -256,12 +324,12 @@ class AFPTreeParser { } $condition = $this->doLevelBoolOps(); - if ( $this->mCur->type == AFPToken::TOP && $this->mCur->value == '?' ) { + if ( $this->mCur->type === AFPToken::TOP && $this->mCur->value === '?' ) { $position = $this->mPos; $this->move(); $valueIfTrue = $this->doLevelConditions(); - if ( !( $this->mCur->type == AFPToken::TOP && $this->mCur->value == ':' ) ) { + if ( !( $this->mCur->type === AFPToken::TOP && $this->mCur->value === ':' ) ) { throw new AFPUserVisibleException( 'expectednotfound', $this->mPos, [ @@ -292,7 +360,7 @@ class AFPTreeParser { protected function doLevelBoolOps() { $leftOperand = $this->doLevelCompares(); $ops = [ '&', '|', '^' ]; - while ( $this->mCur->type == AFPToken::TOP && in_array( $this->mCur->value, $ops ) ) { + while ( $this->mCur->type === AFPToken::TOP && in_array( $this->mCur->value, $ops ) ) { $op = $this->mCur->value; $position = $this->mPos; $this->move(); @@ -315,9 +383,16 @@ class AFPTreeParser { */ protected function doLevelCompares() { $leftOperand = $this->doLevelSumRels(); - $ops = [ '==', '===', '!=', '!==', '<', '>', '<=', '>=', '=' ]; - while ( $this->mCur->type == AFPToken::TOP && in_array( $this->mCur->value, $ops ) ) { + $equalityOps = [ '==', '===', '!=', '!==', '=' ]; + $orderOps = [ '<', '>', '<=', '>=' ]; + // Only allow either a single operation, or a combination of a single equalityOps and a single + // orderOps. This resembles what PHP does, and allows `a < b == c` while rejecting `a < b < c` + $allowedOps = array_merge( $equalityOps, $orderOps ); + while ( $this->mCur->type === AFPToken::TOP && in_array( $this->mCur->value, $allowedOps ) ) { $op = $this->mCur->value; + $allowedOps = in_array( $op, $equalityOps ) ? + array_diff( $allowedOps, $equalityOps ) : + array_diff( $allowedOps, $orderOps ); $position = $this->mPos; $this->move(); $rightOperand = $this->doLevelSumRels(); @@ -338,7 +413,7 @@ class AFPTreeParser { protected function doLevelSumRels() { $leftOperand = $this->doLevelMulRels(); $ops = [ '+', '-' ]; - while ( $this->mCur->type == AFPToken::TOP && in_array( $this->mCur->value, $ops ) ) { + while ( $this->mCur->type === AFPToken::TOP && in_array( $this->mCur->value, $ops ) ) { $op = $this->mCur->value; $position = $this->mPos; $this->move(); @@ -360,7 +435,7 @@ class AFPTreeParser { protected function doLevelMulRels() { $leftOperand = $this->doLevelPow(); $ops = [ '*', '/', '%' ]; - while ( $this->mCur->type == AFPToken::TOP && in_array( $this->mCur->value, $ops ) ) { + while ( $this->mCur->type === AFPToken::TOP && in_array( $this->mCur->value, $ops ) ) { $op = $this->mCur->value; $position = $this->mPos; $this->move(); @@ -381,7 +456,7 @@ class AFPTreeParser { */ protected function doLevelPow() { $base = $this->doLevelBoolInvert(); - while ( $this->mCur->type == AFPToken::TOP && $this->mCur->value == '**' ) { + while ( $this->mCur->type === AFPToken::TOP && $this->mCur->value === '**' ) { $position = $this->mPos; $this->move(); $exponent = $this->doLevelBoolInvert(); @@ -396,7 +471,7 @@ class AFPTreeParser { * @return AFPTreeNode */ protected function doLevelBoolInvert() { - if ( $this->mCur->type == AFPToken::TOP && $this->mCur->value == '!' ) { + if ( $this->mCur->type === AFPToken::TOP && $this->mCur->value === '!' ) { $position = $this->mPos; $this->move(); $argument = $this->doLevelKeywordOperators(); @@ -414,8 +489,8 @@ class AFPTreeParser { protected function doLevelKeywordOperators() { $leftOperand = $this->doLevelUnarys(); $keyword = strtolower( $this->mCur->value ); - if ( $this->mCur->type == AFPToken::TKEYWORD && - isset( AbuseFilterParser::$mKeywords[$keyword] ) + if ( $this->mCur->type === AFPToken::TKEYWORD && + isset( AbuseFilterParser::KEYWORDS[$keyword] ) ) { $position = $this->mPos; $this->move(); @@ -438,7 +513,7 @@ class AFPTreeParser { */ protected function doLevelUnarys() { $op = $this->mCur->value; - if ( $this->mCur->type == AFPToken::TOP && ( $op == "+" || $op == "-" ) ) { + if ( $this->mCur->type === AFPToken::TOP && ( $op === "+" || $op === "-" ) ) { $position = $this->mPos; $this->move(); $argument = $this->doLevelArrayElements(); @@ -455,12 +530,12 @@ class AFPTreeParser { */ protected function doLevelArrayElements() { $array = $this->doLevelParenthesis(); - while ( $this->mCur->type == AFPToken::TSQUAREBRACKET && $this->mCur->value == '[' ) { + while ( $this->mCur->type === AFPToken::TSQUAREBRACKET && $this->mCur->value === '[' ) { $position = $this->mPos; $index = $this->doLevelSemicolon(); $array = new AFPTreeNode( AFPTreeNode::ARRAY_INDEX, [ $array, $index ], $position ); - if ( !( $this->mCur->type == AFPToken::TSQUAREBRACKET && $this->mCur->value == ']' ) ) { + if ( !( $this->mCur->type === AFPToken::TSQUAREBRACKET && $this->mCur->value === ']' ) ) { throw new AFPUserVisibleException( 'expectednotfound', $this->mPos, [ ']', $this->mCur->type, $this->mCur->value ] ); } @@ -477,10 +552,22 @@ class AFPTreeParser { * @throws AFPUserVisibleException */ protected function doLevelParenthesis() { - if ( $this->mCur->type == AFPToken::TBRACE && $this->mCur->value == '(' ) { + if ( $this->mCur->type === AFPToken::TBRACE && $this->mCur->value === '(' ) { + $next = $this->getNextToken(); + if ( $next->type === AFPToken::TBRACE && $next->value === ')' ) { + // Empty parentheses are never allowed + throw new AFPUserVisibleException( + 'unexpectedtoken', + $this->mPos, + [ + $this->mCur->type, + $this->mCur->value + ] + ); + } $result = $this->doLevelSemicolon(); - if ( !( $this->mCur->type == AFPToken::TBRACE && $this->mCur->value == ')' ) ) { + if ( !( $this->mCur->type === AFPToken::TBRACE && $this->mCur->value === ')' ) ) { throw new AFPUserVisibleException( 'expectednotfound', $this->mPos, @@ -502,13 +589,13 @@ class AFPTreeParser { * @throws AFPUserVisibleException */ protected function doLevelFunction() { - if ( $this->mCur->type == AFPToken::TID && - isset( AbuseFilterParser::$mFunctions[$this->mCur->value] ) + if ( $this->mCur->type === AFPToken::TID && + isset( AbuseFilterParser::FUNCTIONS[$this->mCur->value] ) ) { $func = $this->mCur->value; $position = $this->mPos; $this->move(); - if ( $this->mCur->type != AFPToken::TBRACE || $this->mCur->value != '(' ) { + if ( $this->mCur->type !== AFPToken::TBRACE || $this->mCur->value !== '(' ) { throw new AFPUserVisibleException( 'expectednotfound', $this->mPos, [ @@ -519,12 +606,47 @@ class AFPTreeParser { ); } + if ( ( $func === 'set' || $func === 'set_var' ) ) { + $state = $this->getState(); + $this->move(); + $next = $this->getNextToken(); + if ( + $this->mCur->type !== AFPToken::TSTRING || + ( + $next->type !== AFPToken::TCOMMA && + // Let this fail later, when checking parameters count + !( $next->type === AFPToken::TBRACE && $next->value === ')' ) + ) + ) { + throw new AFPUserVisibleException( 'variablevariable', $this->mPos, [] ); + } else { + $this->setState( $state ); + } + } + $args = []; - do { - $args[] = $this->doLevelSemicolon(); - } while ( $this->mCur->type == AFPToken::TCOMMA ); + $next = $this->getNextToken(); + if ( $next->type !== AFPToken::TBRACE || $next->value !== ')' ) { + do { + $thisArg = $this->doLevelSemicolon(); + if ( $thisArg === null && !$this->functionIsVariadic( $func ) ) { + throw new AFPUserVisibleException( + 'unexpectedtoken', + $this->mPos, + [ + $this->mCur->type, + $this->mCur->value + ] + ); + } elseif ( $thisArg !== null ) { + $args[] = $thisArg; + } + } while ( $this->mCur->type === AFPToken::TCOMMA ); + } else { + $this->move(); + } - if ( $this->mCur->type != AFPToken::TBRACE || $this->mCur->value != ')' ) { + if ( $this->mCur->type !== AFPToken::TBRACE || $this->mCur->value !== ')' ) { throw new AFPUserVisibleException( 'expectednotfound', $this->mPos, [ @@ -534,6 +656,11 @@ class AFPTreeParser { ] ); } + // Giving too few arguments to a function is a pretty common error. If we check it here + // (as well as at runtime, for OCD), we can make checkSyntax only try to build the AST, as + // there would be way less runtime errors. Moreover, this check will also be performed inside + // skipped branches, e.g. the discarded if/else branch. + $this->checkArgCount( $args, $func ); $this->move(); array_unshift( $args, $func ); @@ -552,6 +679,8 @@ class AFPTreeParser { $tok = $this->mCur->value; switch ( $this->mCur->type ) { case AFPToken::TID: + $this->checkLogDeprecatedVar( strtolower( $tok ) ); + // Fallthrough intended case AFPToken::TSTRING: case AFPToken::TFLOAT: case AFPToken::TINT: @@ -570,20 +699,20 @@ class AFPTreeParser { ); /** @noinspection PhpMissingBreakStatementInspection */ case AFPToken::TSQUAREBRACKET: - if ( $this->mCur->value == '[' ) { + if ( $this->mCur->value === '[' ) { $array = []; while ( true ) { $this->move(); - if ( $this->mCur->type == AFPToken::TSQUAREBRACKET && $this->mCur->value == ']' ) { + if ( $this->mCur->type === AFPToken::TSQUAREBRACKET && $this->mCur->value === ']' ) { break; } $array[] = $this->doLevelSet(); - if ( $this->mCur->type == AFPToken::TSQUAREBRACKET && $this->mCur->value == ']' ) { + if ( $this->mCur->type === AFPToken::TSQUAREBRACKET && $this->mCur->value === ']' ) { break; } - if ( $this->mCur->type != AFPToken::TCOMMA ) { + if ( $this->mCur->type !== AFPToken::TCOMMA ) { throw new AFPUserVisibleException( 'expectednotfound', $this->mPos, @@ -609,6 +738,20 @@ class AFPTreeParser { } $this->move(); + // @phan-suppress-next-next-line PhanPossiblyUndeclaredVariable + // @phan-suppress-next-line PhanTypeMismatchReturnNullable Until phan can understand the switch return $result; } + + /** + * Given a variable name, check if the variable is deprecated. If it is, log the use. + * Do that here, and not every time the AST is eval'ed. This means less logging, but more + * performance. + * @param string $varname + */ + protected function checkLogDeprecatedVar( $varname ) { + if ( $this->keywordsManager->isVarDeprecated( $varname ) ) { + $this->logger->debug( "Deprecated variable $varname used in filter {$this->mFilter}." ); + } + } } diff --git a/AbuseFilter/includes/parser/AFPUserVisibleException.php b/AbuseFilter/includes/parser/AFPUserVisibleException.php index ab4b2264..0ffce7b1 100644 --- a/AbuseFilter/includes/parser/AFPUserVisibleException.php +++ b/AbuseFilter/includes/parser/AFPUserVisibleException.php @@ -20,9 +20,23 @@ class AFPUserVisibleException extends AFPException { $this->mPosition = $position; $this->mParams = $params; - // Exception message text for logs should be in English. - $msg = $this->getMessageObj()->inLanguage( 'en' )->useDatabase( false )->text(); - parent::__construct( $msg ); + parent::__construct( $exception_id ); + } + + /** + * Change the message of the exception to a localized version + */ + public function setLocalizedMessage() { + $this->message = $this->getMessageObj()->text(); + } + + /** + * Returns the error message in English for use in logs + * + * @return string + */ + public function getMessageForLogs() { + return $this->getMessageObj()->inLanguage( 'en' )->useDatabase( false )->text(); } /** @@ -39,6 +53,8 @@ class AFPUserVisibleException extends AFPException { // abusefilter-exception-overridebuiltin, abusefilter-exception-outofbounds // abusefilter-exception-notarray, abusefilter-exception-unclosedcomment // abusefilter-exception-invalidiprange, abusefilter-exception-disabledvar + // abusefilter-exception-variablevariable, abusefilter-exception-toomanyargs + // abusefilter-exception-negativeoffset return wfMessage( 'abusefilter-exception-' . $this->mExceptionID, $this->mPosition, ...$this->mParams diff --git a/AbuseFilter/includes/parser/AbuseFilterCachingParser.php b/AbuseFilter/includes/parser/AbuseFilterCachingParser.php index ef634fd4..b5bc0cb9 100644 --- a/AbuseFilter/includes/parser/AbuseFilterCachingParser.php +++ b/AbuseFilter/includes/parser/AbuseFilterCachingParser.php @@ -6,8 +6,15 @@ * * It currently inherits AbuseFilterParser in order to avoid code duplication. * In future, this code will replace current AbuseFilterParser entirely. + * + * @todo Override checkSyntax and make it only try to build the AST. That would mean faster results, + * and no need to mess with DUNDEFINED and the like. However, we must first try to reduce the + * amount of runtime-only exceptions, and try to detect them in the AFPTreeParser instead. + * Otherwise, people may be able to save a broken filter without the syntax check reporting that. */ class AbuseFilterCachingParser extends AbuseFilterParser { + private const CACHE_VERSION = 1; + /** * Return the generated version of the parser for cache invalidation * purposes. Automatically tracks list of all functions and invalidates the @@ -21,10 +28,11 @@ class AbuseFilterCachingParser extends AbuseFilterParser { } $versionKey = [ + self::CACHE_VERSION, AFPTreeParser::CACHE_VERSION, AbuseFilterTokenizer::CACHE_VERSION, - array_keys( AbuseFilterParser::$mFunctions ), - array_keys( AbuseFilterParser::$mKeywords ), + array_keys( AbuseFilterParser::FUNCTIONS ), + array_keys( AbuseFilterParser::KEYWORDS ), ]; $version = hash( 'sha256', serialize( $versionKey ) ); @@ -35,36 +43,64 @@ class AbuseFilterCachingParser extends AbuseFilterParser { * Resets the state of the parser */ public function resetState() { - $this->mVars = new AbuseFilterVariableHolder; + $this->mVariables = new AbuseFilterVariableHolder( $this->keywordsManager ); $this->mCur = new AFPToken(); + $this->mCondCount = 0; + $this->mAllowShort = true; } /** * @param string $code * @return AFPData */ - public function intEval( $code ) { - static $cache = null; - if ( !$cache ) { - $cache = ObjectCache::getLocalServerInstance( 'hash' ); + public function intEval( $code ) : AFPData { + $startTime = microtime( true ); + $tree = $this->getTree( $code ); + + $res = $this->evalTree( $tree ); + + if ( $res->getType() === AFPData::DUNDEFINED ) { + $res = new AFPData( AFPData::DBOOL, false ); } + $this->statsd->timing( 'abusefilter_cachingParser_full', microtime( true ) - $startTime ); + return $res; + } - $tree = $cache->getWithSetCallback( - $cache->makeGlobalKey( + /** + * @param string $code + * @return AFPSyntaxTree + */ + private function getTree( $code ) : AFPSyntaxTree { + return $this->cache->getWithSetCallback( + $this->cache->makeGlobalKey( __CLASS__, self::getCacheVersion(), hash( 'sha256', $code ) ), - $cache::TTL_DAY, + BagOStuff::TTL_DAY, function () use ( $code ) { - $parser = new AFPTreeParser(); - return $parser->parse( $code ) ?: false; + $parser = new AFPTreeParser( $this->cache, $this->logger, $this->statsd, $this->keywordsManager ); + $parser->setFilter( $this->mFilter ); + return $parser->parse( $code ); } ); + } + + /** + * @param AFPSyntaxTree $tree + * @return AFPData + */ + private function evalTree( AFPSyntaxTree $tree ) : AFPData { + $startTime = microtime( true ); + $root = $tree->getRoot(); + + if ( !$root ) { + return new AFPData( AFPData::DNULL ); + } - return $tree - ? $this->evalNode( $tree ) - : new AFPData( AFPData::DNULL, null ); + $ret = $this->evalNode( $root ); + $this->statsd->timing( 'abusefilter_cachingParser_eval', microtime( true ) - $startTime ); + return $ret; } /** @@ -76,7 +112,7 @@ class AbuseFilterCachingParser extends AbuseFilterParser { * @throws AFPUserVisibleException * @throws MWException */ - public function evalNode( AFPTreeNode $node ) { + private function evalNode( AFPTreeNode $node ) { // A lot of AbuseFilterParser features rely on $this->mCur->pos or // $this->mPos for error reporting. // FIXME: this is a hack which needs to be removed when the parsers are merged. @@ -103,55 +139,56 @@ class AbuseFilterCachingParser extends AbuseFilterParser { case "false": return new AFPData( AFPData::DBOOL, false ); case "null": - return new AFPData(); + return new AFPData( AFPData::DNULL ); } // Fallthrough intended default: + // @codeCoverageIgnoreStart throw new AFPException( "Unknown token provided in the ATOM node" ); + // @codeCoverageIgnoreEnd } case AFPTreeNode::ARRAY_DEFINITION: - $items = array_map( [ $this, 'evalNode' ], $node->children ); + $items = []; + // Foreach is usually faster than array_map + // @phan-suppress-next-line PhanTypeSuspiciousNonTraversableForeach children is array here + foreach ( $node->children as $el ) { + $items[] = $this->evalNode( $el ); + } return new AFPData( AFPData::DARRAY, $items ); case AFPTreeNode::FUNCTION_CALL: $functionName = $node->children[0]; $args = array_slice( $node->children, 1 ); - $func = self::$mFunctions[$functionName]; - $dataArgs = array_map( [ $this, 'evalNode' ], $args ); - - /** @noinspection PhpToStringImplementationInspection */ - $funcHash = md5( $func . serialize( $dataArgs ) ); - - if ( isset( self::$funcCache[$funcHash] ) && - !in_array( $func, self::$ActiveFunctions ) - ) { - $result = self::$funcCache[$funcHash]; - } else { - AbuseFilter::triggerLimiter(); - $result = self::$funcCache[$funcHash] = $this->$func( $dataArgs ); - } - - if ( count( self::$funcCache ) > 1000 ) { - self::$funcCache = []; + $dataArgs = []; + // Foreach is usually faster than array_map + foreach ( $args as $arg ) { + $dataArgs[] = $this->evalNode( $arg ); } - return $result; - + return $this->callFunc( $functionName, $dataArgs ); case AFPTreeNode::ARRAY_INDEX: list( $array, $offset ) = $node->children; $array = $this->evalNode( $array ); - if ( $array->type != AFPData::DARRAY ) { - throw new AFPUserVisibleException( 'notarray', $node->position, [] ); + // Note: we MUST evaluate the offset to ensure it is valid, regardless + // of $array! + $offset = $this->evalNode( $offset )->toInt(); + + if ( $array->getType() === AFPData::DUNDEFINED ) { + return new AFPData( AFPData::DUNDEFINED ); } - $offset = $this->evalNode( $offset )->toInt(); + if ( $array->getType() !== AFPData::DARRAY ) { + throw new AFPUserVisibleException( 'notarray', $node->position, [] ); + } $array = $array->toArray(); if ( count( $array ) <= $offset ) { throw new AFPUserVisibleException( 'outofbounds', $node->position, [ $offset, count( $array ) ] ); + } elseif ( $offset < 0 ) { + throw new AFPUserVisibleException( 'negativeindex', $node->position, [ $offset ] ); } return $array[$offset]; @@ -159,38 +196,33 @@ class AbuseFilterCachingParser extends AbuseFilterParser { case AFPTreeNode::UNARY: list( $operation, $argument ) = $node->children; $argument = $this->evalNode( $argument ); - if ( $operation == '-' ) { - return AFPData::unaryMinus( $argument ); + if ( $operation === '-' ) { + return $argument->unaryMinus(); } return $argument; case AFPTreeNode::KEYWORD_OPERATOR: list( $keyword, $leftOperand, $rightOperand ) = $node->children; - $func = self::$mKeywords[$keyword]; $leftOperand = $this->evalNode( $leftOperand ); $rightOperand = $this->evalNode( $rightOperand ); - AbuseFilter::triggerLimiter(); - $result = AFPData::$func( $leftOperand, $rightOperand, $node->position ); - - return $result; + return $this->callKeyword( $keyword, $leftOperand, $rightOperand ); case AFPTreeNode::BOOL_INVERT: list( $argument ) = $node->children; $argument = $this->evalNode( $argument ); - return AFPData::boolInvert( $argument ); + return $argument->boolInvert(); case AFPTreeNode::POW: list( $base, $exponent ) = $node->children; $base = $this->evalNode( $base ); $exponent = $this->evalNode( $exponent ); - return AFPData::pow( $base, $exponent ); + return $base->pow( $exponent ); case AFPTreeNode::MUL_REL: list( $op, $leftOperand, $rightOperand ) = $node->children; $leftOperand = $this->evalNode( $leftOperand ); $rightOperand = $this->evalNode( $rightOperand ); - // FIXME - return AFPData::mulRel( $leftOperand, $rightOperand, $op, 0 ); + return $leftOperand->mulRel( $rightOperand, $op, $node->position ); case AFPTreeNode::SUM_REL: list( $op, $leftOperand, $rightOperand ) = $node->children; @@ -198,38 +230,51 @@ class AbuseFilterCachingParser extends AbuseFilterParser { $rightOperand = $this->evalNode( $rightOperand ); switch ( $op ) { case '+': - return AFPData::sum( $leftOperand, $rightOperand ); + return $leftOperand->sum( $rightOperand ); case '-': - return AFPData::sub( $leftOperand, $rightOperand ); + return $leftOperand->sub( $rightOperand ); default: + // @codeCoverageIgnoreStart throw new AFPException( "Unknown sum-related operator: {$op}" ); + // @codeCoverageIgnoreEnd } case AFPTreeNode::COMPARE: list( $op, $leftOperand, $rightOperand ) = $node->children; $leftOperand = $this->evalNode( $leftOperand ); $rightOperand = $this->evalNode( $rightOperand ); - AbuseFilter::triggerLimiter(); - return AFPData::compareOp( $leftOperand, $rightOperand, $op ); + $this->raiseCondCount(); + return $leftOperand->compareOp( $rightOperand, $op ); case AFPTreeNode::LOGIC: list( $op, $leftOperand, $rightOperand ) = $node->children; $leftOperand = $this->evalNode( $leftOperand ); - $value = $leftOperand->toBool(); + $value = $leftOperand->getType() === AFPData::DUNDEFINED ? false : $leftOperand->toBool(); // Short-circuit. - if ( ( !$value && $op == '&' ) || ( $value && $op == '|' ) ) { + if ( ( !$value && $op === '&' ) || ( $value && $op === '|' ) ) { + if ( $rightOperand instanceof AFPTreeNode ) { + $this->maybeDiscardNode( $rightOperand ); + } return $leftOperand; } $rightOperand = $this->evalNode( $rightOperand ); - return AFPData::boolOp( $leftOperand, $rightOperand, $op ); + return $leftOperand->boolOp( $rightOperand, $op ); case AFPTreeNode::CONDITIONAL: list( $condition, $valueIfTrue, $valueIfFalse ) = $node->children; $condition = $this->evalNode( $condition ); - if ( $condition->toBool() ) { + $isTrue = $condition->getType() === AFPData::DUNDEFINED ? false : $condition->toBool(); + if ( $isTrue ) { + if ( $valueIfFalse !== null ) { + $this->maybeDiscardNode( $valueIfFalse ); + } return $this->evalNode( $valueIfTrue ); } else { - return $this->evalNode( $valueIfFalse ); + $this->maybeDiscardNode( $valueIfTrue ); + return $valueIfFalse !== null + ? $this->evalNode( $valueIfFalse ) + // We assume null as default if the else is missing + : new AFPData( AFPData::DNULL ); } case AFPTreeNode::ASSIGNMENT: @@ -241,45 +286,120 @@ class AbuseFilterCachingParser extends AbuseFilterParser { case AFPTreeNode::INDEX_ASSIGNMENT: list( $varName, $offset, $value ) = $node->children; - $array = $this->mVars->getVar( $varName ); - if ( $array->type != AFPData::DARRAY ) { - throw new AFPUserVisibleException( 'notarray', $node->position, [] ); + if ( $this->isReservedIdentifier( $varName ) ) { + throw new AFPUserVisibleException( 'overridebuiltin', $node->position, [ $varName ] ); } + $array = $this->getVarValue( $varName ); - $offset = $this->evalNode( $offset )->toInt(); - - $array = $array->toArray(); - if ( count( $array ) <= $offset ) { - throw new AFPUserVisibleException( 'outofbounds', $node->position, - [ $offset, count( $array ) ] ); + $value = $this->evalNode( $value ); + if ( $array->getType() !== AFPData::DUNDEFINED ) { + // If it's a DUNDEFINED, leave it as is + if ( $array->getType() !== AFPData::DARRAY ) { + throw new AFPUserVisibleException( 'notarray', $node->position, [] ); + } + + $offset = $this->evalNode( $offset )->toInt(); + + $array = $array->toArray(); + if ( count( $array ) <= $offset ) { + throw new AFPUserVisibleException( 'outofbounds', $node->position, + [ $offset, count( $array ) ] ); + } elseif ( $offset < 0 ) { + throw new AFPUserVisibleException( 'negativeindex', $node->position, [ $offset ] ); + } + + $array[$offset] = $value; + $this->setUserVariable( $varName, new AFPData( AFPData::DARRAY, $array ) ); } - $array[$offset] = $this->evalNode( $value ); - $this->setUserVariable( $varName, new AFPData( AFPData::DARRAY, $array ) ); return $value; case AFPTreeNode::ARRAY_APPEND: list( $varName, $value ) = $node->children; - $array = $this->mVars->getVar( $varName ); - if ( $array->type != AFPData::DARRAY ) { - throw new AFPUserVisibleException( 'notarray', $node->position, [] ); + if ( $this->isReservedIdentifier( $varName ) ) { + throw new AFPUserVisibleException( 'overridebuiltin', $node->position, [ $varName ] ); } - $array = $array->toArray(); - $array[] = $this->evalNode( $value ); - $this->setUserVariable( $varName, new AFPData( AFPData::DARRAY, $array ) ); + $array = $this->getVarValue( $varName ); + $value = $this->evalNode( $value ); + if ( $array->getType() !== AFPData::DUNDEFINED ) { + // If it's a DUNDEFINED, leave it as is + if ( $array->getType() !== AFPData::DARRAY ) { + throw new AFPUserVisibleException( 'notarray', $node->position, [] ); + } + + $array = $array->toArray(); + $array[] = $value; + $this->setUserVariable( $varName, new AFPData( AFPData::DARRAY, $array ) ); + } return $value; case AFPTreeNode::SEMICOLON: $lastValue = null; + // @phan-suppress-next-line PhanTypeSuspiciousNonTraversableForeach children is array here foreach ( $node->children as $statement ) { $lastValue = $this->evalNode( $statement ); } + // @phan-suppress-next-next-line PhanTypeMismatchReturnNullable Can never be null because + // empty statements are discarded in AFPTreeParser return $lastValue; default: + // @codeCoverageIgnoreStart throw new AFPException( "Unknown node type passed: {$node->type}" ); + // @codeCoverageIgnoreEnd } } + + /** + * Given a node that we don't need to evaluate, decide what to do with it. The nodes passed in + * will usually be discarded by short-circuit evaluation. If we allow it, then we just hoist + * the variables assigned in any descendant of the node. Otherwise, we fully evaluate the node. + * + * @param AFPTreeNode $node + */ + private function maybeDiscardNode( AFPTreeNode $node ) { + if ( $this->mAllowShort ) { + $this->discardWithHoisting( $node ); + } else { + $this->evalNode( $node ); + } + } + + /** + * Intended to be used for short-circuit as a solution for T214674. + * Given a node, check it and its children; if there are assignments of non-existing variables, + * hoist them. In case of index assignment or array append, the old value is always erased and + * overwritten with a DUNDEFINED. This is used to allow stuff like: + * false & ( var := 'foo' ); var == 2 + * or + * if ( false ) then ( var := 'foo' ) else ( 1 ) end; var == 2 + * where `false` is something evaluated as false at runtime. + * + * @note This method doesn't check whether the variable exists in case of index assignments. + * Hence, in `false & (nonexistent[] := 2)`, `nonexistent` would be hoisted without errors. + * However, that would by caught by checkSyntax, so we can avoid checking here: we'd need + * way more context than we currently have. + * + * @param AFPTreeNode $node + */ + private function discardWithHoisting( AFPTreeNode $node ) { + foreach ( $node->getInnerAssignments() as $name ) { + if ( + !$this->mVariables->varIsSet( $name ) || + $this->mVariables->getVar( $name )->getType() === AFPData::DARRAY + ) { + $this->setUserVariable( $name, new AFPData( AFPData::DUNDEFINED ) ); + } + } + } + + /** + * @inheritDoc + * This parser should not log, because that's handled in AFPTreeParser + */ + protected function logsDeprecatedVars() { + return false; + } } diff --git a/AbuseFilter/includes/parser/AbuseFilterParser.php b/AbuseFilter/includes/parser/AbuseFilterParser.php index 89ddea0f..aed48007 100644 --- a/AbuseFilter/includes/parser/AbuseFilterParser.php +++ b/AbuseFilter/includes/parser/AbuseFilterParser.php @@ -1,58 +1,78 @@ <?php +use MediaWiki\Extension\AbuseFilter\KeywordsManager; +use Psr\Log\LoggerInterface; +use Wikimedia\AtEase\AtEase; use Wikimedia\Equivset\Equivset; -use MediaWiki\Logger\LoggerFactory; +use Wikimedia\IPUtils; -class AbuseFilterParser { - public $mCode, $mTokens, $mPos, $mShortCircuit, $mAllowShort, $mLen; - /** @var AFPToken The current token */ +class AbuseFilterParser extends AFPTransitionBase { + /** + * @var array[] Contains the AFPTokens for the code being parsed + */ + public $mTokens; + /** + * @var bool Are we inside a short circuit evaluation? + */ + public $mShortCircuit; + /** + * @var bool Are we allowed to use short-circuit evaluation? + */ + public $mAllowShort; + /** + * @var AFPToken The current token + */ public $mCur; - /** * @var AbuseFilterVariableHolder */ - public $mVars; - - // length,lcase,ucase,ccnorm,rmdoubles,specialratio,rmspecials,norm,count,get_matches - public static $mFunctions = [ - 'lcase' => 'funcLc', - 'ucase' => 'funcUc', - 'length' => 'funcLen', - 'string' => 'castString', - 'int' => 'castInt', - 'float' => 'castFloat', - 'bool' => 'castBool', - 'norm' => 'funcNorm', - 'ccnorm' => 'funcCCNorm', - 'ccnorm_contains_any' => 'funcCCNormContainsAny', - 'ccnorm_contains_all' => 'funcCCNormContainsAll', - 'specialratio' => 'funcSpecialRatio', - 'rmspecials' => 'funcRMSpecials', - 'rmdoubles' => 'funcRMDoubles', - 'rmwhitespace' => 'funcRMWhitespace', - 'count' => 'funcCount', - 'rcount' => 'funcRCount', - 'get_matches' => 'funcGetMatches', - 'ip_in_range' => 'funcIPInRange', - 'contains_any' => 'funcContainsAny', - 'contains_all' => 'funcContainsAll', - 'equals_to_any' => 'funcEqualsToAny', - 'substr' => 'funcSubstr', - 'strlen' => 'funcLen', - 'strpos' => 'funcStrPos', - 'str_replace' => 'funcStrReplace', - 'rescape' => 'funcStrRegexEscape', - 'set' => 'funcSetVar', - 'set_var' => 'funcSetVar', - 'sanitize' => 'funcSanitize', - ]; + public $mVariables; + + /** + * @var int The current amount of conditions being consumed + */ + protected $mCondCount; + + /** + * @var bool Whether the condition limit is enabled. + */ + protected $condLimitEnabled = true; + + /** + * @var string|null The ID of the filter being parsed, if available. Can also be "global-$ID" + */ + protected $mFilter; + /** + * @var bool Whether we can allow retrieving _builtin_ variables not included in $this->mVariables + */ + protected $allowMissingVariables = false; + + /** + * @var BagOStuff Used to cache the AST (in CachingParser) and the tokens + */ + protected $cache; + /** + * @var LoggerInterface Used for debugging + */ + protected $logger; + /** + * @var Language Content language, used for language-dependent functions + */ + protected $contLang; + /** + * @var IBufferingStatsdDataFactory + */ + protected $statsd; + + /** @var KeywordsManager */ + protected $keywordsManager; // Functions that affect parser state, and shouldn't be cached. - public static $ActiveFunctions = [ + public const ACTIVE_FUNCTIONS = [ 'funcSetVar', ]; - public static $mKeywords = [ + public const KEYWORDS = [ 'in' => 'keywordIn', 'like' => 'keywordLike', 'matches' => 'keywordLike', @@ -62,7 +82,10 @@ class AbuseFilterParser { 'regex' => 'keywordRegex', ]; - public static $funcCache = []; + /** + * @var array Cached results of functions + */ + protected $funcCache = []; /** * @var Equivset @@ -72,12 +95,93 @@ class AbuseFilterParser { /** * Create a new instance * + * @param Language $contLang Content language, used for language-dependent function + * @param BagOStuff $cache Used to cache the AST (in CachingParser) and the tokens + * @param LoggerInterface $logger Used for debugging + * @param KeywordsManager $keywordsManager * @param AbuseFilterVariableHolder|null $vars */ - public function __construct( $vars = null ) { + public function __construct( + Language $contLang, + BagOStuff $cache, + LoggerInterface $logger, + KeywordsManager $keywordsManager, + AbuseFilterVariableHolder $vars = null + ) { + $this->contLang = $contLang; + $this->cache = $cache; + $this->logger = $logger; + $this->statsd = new NullStatsdDataFactory; + $this->keywordsManager = $keywordsManager; $this->resetState(); - if ( $vars instanceof AbuseFilterVariableHolder ) { - $this->mVars = $vars; + if ( $vars ) { + $this->mVariables = $vars; + } + $this->mVariables->setLogger( $logger ); + } + + /** + * @param string $filter + */ + public function setFilter( $filter ) { + $this->mFilter = $filter; + } + + /** + * @param BagOStuff $cache + */ + public function setCache( BagOStuff $cache ) { + $this->cache = $cache; + } + + /** + * @param LoggerInterface $logger + */ + public function setLogger( LoggerInterface $logger ) { + $this->logger = $logger; + } + + /** + * @param IBufferingStatsdDataFactory $statsd + */ + public function setStatsd( IBufferingStatsdDataFactory $statsd ) { + $this->statsd = $statsd; + } + + /** + * @return int + */ + public function getCondCount() { + return $this->mCondCount; + } + + /** + * Reset the conditions counter + */ + public function resetCondCount() { + $this->mCondCount = 0; + } + + /** + * For use in batch scripts and the like + * + * @param bool $enable True to enable the limit, false to disable it + */ + public function toggleConditionLimit( $enable ) { + $this->condLimitEnabled = $enable; + } + + /** + * @param int $val The amount to increase the conditions count of. + * @throws MWException + */ + protected function raiseCondCount( $val = 1 ) { + global $wgAbuseFilterConditionLimit; + + $this->mCondCount += $val; + + if ( $this->condLimitEnabled && $this->mCondCount > $wgAbuseFilterConditionLimit ) { + throw new MWException( 'Condition limit reached.' ); } } @@ -85,35 +189,101 @@ class AbuseFilterParser { * Resets the state of the parser. */ public function resetState() { - $this->mCode = ''; $this->mTokens = []; - $this->mVars = new AbuseFilterVariableHolder; + $this->mVariables = new AbuseFilterVariableHolder( $this->keywordsManager ); $this->mPos = 0; $this->mShortCircuit = false; $this->mAllowShort = true; + $this->mCondCount = 0; + $this->mFilter = null; + } + + /** + * Clears the array of cached function results + */ + public function clearFuncCache() { + $this->funcCache = []; } /** + * @param AbuseFilterVariableHolder $vars + */ + public function setVariables( AbuseFilterVariableHolder $vars ) { + $this->mVariables = $vars; + } + + /** + * Check the syntax of $filter, throwing an exception if invalid * @param string $filter - * @return true|array True when successful, otherwise a two-element array with exception message - * and character position of the syntax error + * @return true When successful + * @throws AFPUserVisibleException */ - public function checkSyntax( $filter ) { + public function checkSyntaxThrow( string $filter ) { + $this->allowMissingVariables = true; $origAS = $this->mAllowShort; try { $this->mAllowShort = false; - $this->parse( $filter ); - } catch ( AFPUserVisibleException $excep ) { + $this->intEval( $filter ); + } finally { $this->mAllowShort = $origAS; - - return [ $excep->getMessageObj()->text(), $excep->mPosition ]; + $this->allowMissingVariables = false; } - $this->mAllowShort = $origAS; return true; } /** + * Check the syntax of $filter, without throwing + * + * @param string $filter + * @return true|array True when successful, otherwise a two-element array with exception message + * and character position of the syntax error + */ + public function checkSyntax( string $filter ) { + try { + $res = $this->checkSyntaxThrow( $filter ); + } catch ( AFPUserVisibleException $excep ) { + $res = [ $excep->getMessageObj()->text(), $excep->mPosition ]; + } + return $res; + } + + /** + * This is the main entry point. It checks the given conditions and returns whether + * they match. In case of bad syntax, this is always logged, and $ignoreError can + * be used to determine whether this method should throw. + * + * @param string $conds + * @param bool $ignoreError + * @param string|null $filter The ID of the filter being parsed + * @return bool + * @throws Exception + */ + public function checkConditions( string $conds, $ignoreError = true, $filter = null ) : bool { + try { + $result = $this->parse( $conds ); + } catch ( Exception $excep ) { + $result = false; + + if ( $excep instanceof AFPUserVisibleException ) { + $msg = $excep->getMessageForLogs(); + $excep->setLocalizedMessage(); + } else { + $msg = $excep->getMessage(); + } + + $extraInfo = $filter !== null ? " for filter $filter" : ''; + $this->logger->warning( "AbuseFilter parser error$extraInfo: $msg" ); + + if ( !$ignoreError ) { + throw $excep; + } + } + + return $result; + } + + /** * Move to the next token */ protected function move() { @@ -121,6 +291,16 @@ class AbuseFilterParser { } /** + * Get the next token. This is similar to move() but doesn't change class members, + * allowing to look ahead without rolling back the state. + * + * @return AFPToken + */ + protected function getNextToken() { + return $this->mTokens[$this->mPos][0]; + } + + /** * getState() function allows parser state to be rollbacked to several tokens back * @return AFPParserState */ @@ -142,17 +322,52 @@ class AbuseFilterParser { */ protected function skipOverBraces() { $braces = 1; - while ( $this->mCur->type != AFPToken::TNONE && $braces > 0 ) { + while ( $this->mCur->type !== AFPToken::TNONE && $braces > 0 ) { $this->move(); - if ( $this->mCur->type == AFPToken::TBRACE ) { - if ( $this->mCur->value == '(' ) { + if ( $this->mCur->type === AFPToken::TBRACE ) { + if ( $this->mCur->value === '(' ) { $braces++; - } elseif ( $this->mCur->value == ')' ) { + } elseif ( $this->mCur->value === ')' ) { $braces--; } + } elseif ( $this->mCur->type === AFPToken::TID ) { + // T214674, define non-existing variables. @see docs of + // AbuseFilterCachingParser::discardWithHoisting for a detailed explanation of this branch + $next = $this->getNextToken(); + if ( + in_array( $this->mCur->value, [ 'set', 'set_var' ] ) && + $next->type === AFPToken::TBRACE && $next->value === '(' + ) { + // This is for setter functions. + $this->move(); + $braces++; + $next = $this->getNextToken(); + if ( $next->type === AFPToken::TSTRING ) { + if ( !$this->mVariables->varIsSet( $next->value ) ) { + $this->setUserVariable( $next->value, new AFPData( AFPData::DUNDEFINED ) ); + } + } + } else { + // Simple assignment with := + $varname = $this->mCur->value; + $next = $this->getNextToken(); + if ( $next->type === AFPToken::TOP && $next->value === ':=' ) { + if ( !$this->mVariables->varIsSet( $varname ) ) { + $this->setUserVariable( $varname, new AFPData( AFPData::DUNDEFINED ) ); + } + } elseif ( $next->type === AFPToken::TSQUAREBRACKET && $next->value === '[' ) { + if ( !$this->mVariables->varIsSet( $varname ) ) { + throw new AFPUserVisibleException( 'unrecognisedvar', + $next->pos, + [ $varname ] + ); + } + $this->setUserVariable( $varname, new AFPData( AFPData::DUNDEFINED ) ); + } + } } } - if ( !( $this->mCur->type == AFPToken::TBRACE && $this->mCur->value == ')' ) ) { + if ( !( $this->mCur->type === AFPToken::TBRACE && $this->mCur->value === ')' ) ) { throw new AFPUserVisibleException( 'expectednotfound', $this->mCur->pos, [ ')' ] ); } } @@ -170,7 +385,7 @@ class AbuseFilterParser { * @return string */ public function evaluateExpression( $filter ) { - return $this->intEval( $filter )->toString(); + return $this->intEval( $filter )->toNative(); } /** @@ -178,16 +393,21 @@ class AbuseFilterParser { * @return AFPData */ public function intEval( $code ) { + $startTime = microtime( true ); // Reset all class members to their default value - $this->mCode = $code; - $this->mTokens = AbuseFilterTokenizer::tokenize( $code ); + $tokenizer = new AbuseFilterTokenizer( $this->cache, $this->logger ); + $this->mTokens = $tokenizer->getTokens( $code ); $this->mPos = 0; - $this->mLen = strlen( $code ); $this->mShortCircuit = false; - $result = new AFPData(); + $result = new AFPData( AFPData::DEMPTY ); $this->doLevelEntry( $result ); + if ( $result->getType() === AFPData::DUNDEFINED ) { + $result = new AFPData( AFPData::DBOOL, false ); + } + + $this->statsd->timing( 'abusefilter_oldparser_full', microtime( true ) - $startTime ); return $result; } @@ -202,7 +422,7 @@ class AbuseFilterParser { protected function doLevelEntry( &$result ) { $this->doLevelSemicolon( $result ); - if ( $this->mCur->type != AFPToken::TNONE ) { + if ( $this->mCur->type !== AFPToken::TNONE ) { throw new AFPUserVisibleException( 'unexpectedatend', $this->mCur->pos, [ $this->mCur->type ] @@ -218,10 +438,10 @@ class AbuseFilterParser { protected function doLevelSemicolon( &$result ) { do { $this->move(); - if ( $this->mCur->type != AFPToken::TSTATEMENTSEPARATOR ) { + if ( $this->mCur->type !== AFPToken::TSTATEMENTSEPARATOR ) { $this->doLevelSet( $result ); } - } while ( $this->mCur->type == AFPToken::TSTATEMENTSEPARATOR ); + } while ( $this->mCur->type === AFPToken::TSTATEMENTSEPARATOR ); } /** @@ -231,57 +451,76 @@ class AbuseFilterParser { * @throws AFPUserVisibleException */ protected function doLevelSet( &$result ) { - if ( $this->mCur->type == AFPToken::TID ) { + if ( $this->mCur->type === AFPToken::TID ) { $varname = $this->mCur->value; $prev = $this->getState(); $this->move(); - if ( $this->mCur->type == AFPToken::TOP && $this->mCur->value == ':=' ) { + if ( $this->mCur->type === AFPToken::TOP && $this->mCur->value === ':=' ) { $this->move(); + $checkEmpty = $result->getType() === AFPData::DEMPTY; $this->doLevelSet( $result ); + if ( $checkEmpty && $result->getType() === AFPData::DEMPTY ) { + $this->logEmptyOperand( 'var assignment' ); + } $this->setUserVariable( $varname, $result ); return; - } elseif ( $this->mCur->type == AFPToken::TSQUAREBRACKET && $this->mCur->value == '[' ) { - if ( !$this->mVars->varIsSet( $varname ) ) { - throw new AFPUserVisibleException( 'unrecognisedvar', - $this->mCur->pos, - [ $varname ] - ); - } - $array = $this->mVars->getVar( $varname ); - if ( $array->type != AFPData::DARRAY ) { + } elseif ( $this->mCur->type === AFPToken::TSQUAREBRACKET && $this->mCur->value === '[' ) { + // We allow builtin variables to both check for override (e.g. added_lines[] :='x') + // and for T198531 + $array = $this->getVarValue( $varname ); + if ( + $array->getType() !== AFPData::DARRAY && $array->getType() !== AFPData::DUNDEFINED + // NOTE: we cannot throw for overridebuiltin yet, in case this turns out not to be an assignment. + && !$this->keywordsManager->varExists( $varname ) + ) { throw new AFPUserVisibleException( 'notarray', $this->mCur->pos, [] ); } - $array = $array->toArray(); + $this->move(); - if ( $this->mCur->type == AFPToken::TSQUAREBRACKET && $this->mCur->value == ']' ) { + if ( $this->mCur->type === AFPToken::TSQUAREBRACKET && $this->mCur->value === ']' ) { $idx = 'new'; } else { $this->setState( $prev ); $this->move(); - $idx = new AFPData(); + $idx = new AFPData( AFPData::DEMPTY ); $this->doLevelSemicolon( $idx ); $idx = $idx->toInt(); - if ( !( $this->mCur->type == AFPToken::TSQUAREBRACKET && $this->mCur->value == ']' ) ) { + if ( !( $this->mCur->type === AFPToken::TSQUAREBRACKET && $this->mCur->value === ']' ) ) { throw new AFPUserVisibleException( 'expectednotfound', $this->mCur->pos, [ ']', $this->mCur->type, $this->mCur->value ] ); } - if ( count( $array ) <= $idx ) { - throw new AFPUserVisibleException( 'outofbounds', $this->mCur->pos, - [ $idx, count( $result->data ) ] ); + if ( $array->getType() === AFPData::DARRAY ) { + if ( count( $array->toArray() ) <= $idx ) { + throw new AFPUserVisibleException( 'outofbounds', $this->mCur->pos, + [ $idx, count( $array->getData() ) ] ); + } elseif ( $idx < 0 ) { + throw new AFPUserVisibleException( 'negativeindex', $this->mCur->pos, [ $idx ] ); + } } } $this->move(); - if ( $this->mCur->type == AFPToken::TOP && $this->mCur->value == ':=' ) { + if ( $this->mCur->type === AFPToken::TOP && $this->mCur->value === ':=' ) { + if ( $this->isReservedIdentifier( $varname ) ) { + // Ideally we should've aborted before trying to parse the index + throw new AFPUserVisibleException( 'overridebuiltin', $this->mCur->pos, [ $varname ] ); + } $this->move(); + if ( $this->mCur->type === AFPToken::TNONE ) { + $this->logEmptyOperand( 'array assignment' ); + } $this->doLevelSet( $result ); - if ( $idx === 'new' ) { - $array[] = $result; - } else { - $array[$idx] = $result; + if ( $array->getType() === AFPData::DARRAY ) { + // If it's a DUNDEFINED, leave it as is + $array = $array->toArray(); + if ( $idx === 'new' ) { + $array[] = $result; + } else { + $array[$idx] = $result; + } + $this->setUserVariable( $varname, new AFPData( AFPData::DARRAY, $array ) ); } - $this->setUserVariable( $varname, new AFPData( AFPData::DARRAY, $array ) ); return; } else { @@ -299,13 +538,14 @@ class AbuseFilterParser { * * @param AFPData &$result * @throws AFPUserVisibleException + * @suppress PhanPossiblyUndeclaredVariable */ protected function doLevelConditions( &$result ) { - if ( $this->mCur->type == AFPToken::TKEYWORD && $this->mCur->value == 'if' ) { + if ( $this->mCur->type === AFPToken::TKEYWORD && $this->mCur->value === 'if' ) { $this->move(); $this->doLevelBoolOps( $result ); - if ( !( $this->mCur->type == AFPToken::TKEYWORD && $this->mCur->value == 'then' ) ) { + if ( !( $this->mCur->type === AFPToken::TKEYWORD && $this->mCur->value === 'then' ) ) { throw new AFPUserVisibleException( 'expectednotfound', $this->mCur->pos, [ @@ -317,42 +557,35 @@ class AbuseFilterParser { } $this->move(); - $r1 = new AFPData(); - $r2 = new AFPData(); + $r1 = new AFPData( AFPData::DEMPTY ); + $r2 = new AFPData( AFPData::DEMPTY ); - $isTrue = $result->toBool(); + $isTrue = $result->getType() === AFPData::DUNDEFINED ? false : $result->toBool(); if ( !$isTrue ) { - $scOrig = $this->mShortCircuit; - $this->mShortCircuit = $this->mAllowShort; + $scOrig = wfSetVar( $this->mShortCircuit, $this->mAllowShort, true ); } $this->doLevelConditions( $r1 ); if ( !$isTrue ) { $this->mShortCircuit = $scOrig; } - if ( !( $this->mCur->type == AFPToken::TKEYWORD && $this->mCur->value == 'else' ) ) { - throw new AFPUserVisibleException( 'expectednotfound', - $this->mCur->pos, - [ - 'else', - $this->mCur->type, - $this->mCur->value - ] - ); - } - $this->move(); + if ( $this->mCur->type === AFPToken::TKEYWORD && $this->mCur->value === 'else' ) { + $this->move(); - if ( $isTrue ) { - $scOrig = $this->mShortCircuit; - $this->mShortCircuit = $this->mAllowShort; - } - $this->doLevelConditions( $r2 ); - if ( $isTrue ) { - $this->mShortCircuit = $scOrig; + if ( $isTrue ) { + $scOrig = wfSetVar( $this->mShortCircuit, $this->mAllowShort, true ); + } + $this->doLevelConditions( $r2 ); + if ( $isTrue ) { + $this->mShortCircuit = $scOrig; + } + } else { + // DNULL is assumed as default in case of a missing else + $r2 = new AFPData( AFPData::DNULL ); } - if ( !( $this->mCur->type == AFPToken::TKEYWORD && $this->mCur->value == 'end' ) ) { + if ( !( $this->mCur->type === AFPToken::TKEYWORD && $this->mCur->value === 'end' ) ) { throw new AFPUserVisibleException( 'expectednotfound', $this->mCur->pos, [ @@ -364,30 +597,30 @@ class AbuseFilterParser { } $this->move(); - if ( $result->toBool() ) { + $isTrue = $result->getType() === AFPData::DUNDEFINED ? false : $result->toBool(); + if ( $isTrue ) { $result = $r1; } else { $result = $r2; } } else { $this->doLevelBoolOps( $result ); - if ( $this->mCur->type == AFPToken::TOP && $this->mCur->value == '?' ) { + if ( $this->mCur->type === AFPToken::TOP && $this->mCur->value === '?' ) { $this->move(); - $r1 = new AFPData(); - $r2 = new AFPData(); + $r1 = new AFPData( AFPData::DEMPTY ); + $r2 = new AFPData( AFPData::DEMPTY ); - $isTrue = $result->toBool(); + $isTrue = $result->getType() === AFPData::DUNDEFINED ? false : $result->toBool(); if ( !$isTrue ) { - $scOrig = $this->mShortCircuit; - $this->mShortCircuit = $this->mAllowShort; + $scOrig = wfSetVar( $this->mShortCircuit, $this->mAllowShort, true ); } $this->doLevelConditions( $r1 ); if ( !$isTrue ) { $this->mShortCircuit = $scOrig; } - if ( !( $this->mCur->type == AFPToken::TOP && $this->mCur->value == ':' ) ) { + if ( !( $this->mCur->type === AFPToken::TOP && $this->mCur->value === ':' ) ) { throw new AFPUserVisibleException( 'expectednotfound', $this->mCur->pos, [ @@ -400,10 +633,12 @@ class AbuseFilterParser { $this->move(); if ( $isTrue ) { - $scOrig = $this->mShortCircuit; - $this->mShortCircuit = $this->mAllowShort; + $scOrig = wfSetVar( $this->mShortCircuit, $this->mAllowShort, true ); } $this->doLevelConditions( $r2 ); + if ( $r2->getType() === AFPData::DEMPTY ) { + $this->logEmptyOperand( 'ternary else' ); + } if ( $isTrue ) { $this->mShortCircuit = $scOrig; } @@ -425,24 +660,29 @@ class AbuseFilterParser { protected function doLevelBoolOps( &$result ) { $this->doLevelCompares( $result ); $ops = [ '&', '|', '^' ]; - while ( $this->mCur->type == AFPToken::TOP && in_array( $this->mCur->value, $ops ) ) { + while ( $this->mCur->type === AFPToken::TOP && in_array( $this->mCur->value, $ops ) ) { $op = $this->mCur->value; $this->move(); - $r2 = new AFPData(); + $r2 = new AFPData( AFPData::DEMPTY ); + $curVal = $result->getType() === AFPData::DUNDEFINED ? false : $result->toBool(); // We can go on quickly as either one statement with | is true or one with & is false - if ( ( $op == '&' && !$result->toBool() ) || ( $op == '|' && $result->toBool() ) ) { - $orig = $this->mShortCircuit; - $this->mShortCircuit = $this->mAllowShort; + if ( ( $op === '&' && !$curVal ) || ( $op === '|' && $curVal ) ) { + $scOrig = wfSetVar( $this->mShortCircuit, $this->mAllowShort, true ); $this->doLevelCompares( $r2 ); - $this->mShortCircuit = $orig; - $result = new AFPData( AFPData::DBOOL, $result->toBool() ); + if ( $r2->getType() === AFPData::DEMPTY ) { + $this->logEmptyOperand( 'bool operand' ); + } + $this->mShortCircuit = $scOrig; + $result = new AFPData( AFPData::DBOOL, $curVal ); continue; } $this->doLevelCompares( $r2 ); - - $result = AFPData::boolOp( $result, $r2, $op ); + if ( $r2->getType() === AFPData::DEMPTY ) { + $this->logEmptyOperand( 'bool operand' ); + } + $result = $result->boolOp( $r2, $op ); } } @@ -453,18 +693,28 @@ class AbuseFilterParser { */ protected function doLevelCompares( &$result ) { $this->doLevelSumRels( $result ); - $ops = [ '==', '===', '!=', '!==', '<', '>', '<=', '>=', '=' ]; - while ( $this->mCur->type == AFPToken::TOP && in_array( $this->mCur->value, $ops ) ) { + $equalityOps = [ '==', '===', '!=', '!==', '=' ]; + $orderOps = [ '<', '>', '<=', '>=' ]; + // Only allow either a single operation, or a combination of a single equalityOps and a single + // orderOps. This resembles what PHP does, and allows `a < b == c` while rejecting `a < b < c` + $allowedOps = array_merge( $equalityOps, $orderOps ); + while ( $this->mCur->type === AFPToken::TOP && in_array( $this->mCur->value, $allowedOps ) ) { + $allowedOps = in_array( $this->mCur->value, $equalityOps ) ? + array_diff( $allowedOps, $equalityOps ) : + array_diff( $allowedOps, $orderOps ); $op = $this->mCur->value; $this->move(); - $r2 = new AFPData(); + $r2 = new AFPData( AFPData::DEMPTY ); $this->doLevelSumRels( $r2 ); + if ( $r2->getType() === AFPData::DEMPTY ) { + $this->logEmptyOperand( 'compare operand' ); + } if ( $this->mShortCircuit ) { // The result doesn't matter. - break; + continue; } - AbuseFilter::triggerLimiter(); - $result = AFPData::compareOp( $result, $r2, $op ); + $this->raiseCondCount(); + $result = $result->compareOp( $r2, $op ); } } @@ -476,20 +726,23 @@ class AbuseFilterParser { protected function doLevelSumRels( &$result ) { $this->doLevelMulRels( $result ); $ops = [ '+', '-' ]; - while ( $this->mCur->type == AFPToken::TOP && in_array( $this->mCur->value, $ops ) ) { + while ( $this->mCur->type === AFPToken::TOP && in_array( $this->mCur->value, $ops ) ) { $op = $this->mCur->value; $this->move(); - $r2 = new AFPData(); + $r2 = new AFPData( AFPData::DEMPTY ); $this->doLevelMulRels( $r2 ); + if ( $r2->getType() === AFPData::DEMPTY ) { + $this->logEmptyOperand( 'sum operand' ); + } if ( $this->mShortCircuit ) { // The result doesn't matter. - break; + continue; } - if ( $op == '+' ) { - $result = AFPData::sum( $result, $r2 ); + if ( $op === '+' ) { + $result = $result->sum( $r2 ); } - if ( $op == '-' ) { - $result = AFPData::sub( $result, $r2 ); + if ( $op === '-' ) { + $result = $result->sub( $r2 ); } } } @@ -502,16 +755,19 @@ class AbuseFilterParser { protected function doLevelMulRels( &$result ) { $this->doLevelPow( $result ); $ops = [ '*', '/', '%' ]; - while ( $this->mCur->type == AFPToken::TOP && in_array( $this->mCur->value, $ops ) ) { + while ( $this->mCur->type === AFPToken::TOP && in_array( $this->mCur->value, $ops ) ) { $op = $this->mCur->value; $this->move(); - $r2 = new AFPData(); + $r2 = new AFPData( AFPData::DEMPTY ); $this->doLevelPow( $r2 ); + if ( $r2->getType() === AFPData::DEMPTY ) { + $this->logEmptyOperand( 'multiplication operand' ); + } if ( $this->mShortCircuit ) { // The result doesn't matter. - break; + continue; } - $result = AFPData::mulRel( $result, $r2, $op, $this->mCur->pos ); + $result = $result->mulRel( $r2, $op, $this->mCur->pos ); } } @@ -522,15 +778,18 @@ class AbuseFilterParser { */ protected function doLevelPow( &$result ) { $this->doLevelBoolInvert( $result ); - while ( $this->mCur->type == AFPToken::TOP && $this->mCur->value == '**' ) { + while ( $this->mCur->type === AFPToken::TOP && $this->mCur->value === '**' ) { $this->move(); - $expanent = new AFPData(); + $expanent = new AFPData( AFPData::DEMPTY ); $this->doLevelBoolInvert( $expanent ); + if ( $expanent->getType() === AFPData::DEMPTY ) { + $this->logEmptyOperand( 'power operand' ); + } if ( $this->mShortCircuit ) { // The result doesn't matter. - break; + continue; } - $result = AFPData::pow( $result, $expanent ); + $result = $result->pow( $expanent ); } } @@ -540,14 +799,18 @@ class AbuseFilterParser { * @param AFPData &$result */ protected function doLevelBoolInvert( &$result ) { - if ( $this->mCur->type == AFPToken::TOP && $this->mCur->value == '!' ) { + if ( $this->mCur->type === AFPToken::TOP && $this->mCur->value === '!' ) { $this->move(); + $checkEmpty = $result->getType() === AFPData::DEMPTY; $this->doLevelSpecialWords( $result ); + if ( $checkEmpty && $result->getType() === AFPData::DEMPTY ) { + $this->logEmptyOperand( 'bool inversion' ); + } if ( $this->mShortCircuit ) { // The result doesn't matter. return; } - $result = AFPData::boolInvert( $result ); + $result = $result->boolInvert(); } else { $this->doLevelSpecialWords( $result ); } @@ -561,22 +824,23 @@ class AbuseFilterParser { protected function doLevelSpecialWords( &$result ) { $this->doLevelUnarys( $result ); $keyword = strtolower( $this->mCur->value ); - if ( $this->mCur->type == AFPToken::TKEYWORD - && isset( self::$mKeywords[$keyword] ) + if ( $this->mCur->type === AFPToken::TKEYWORD + && isset( self::KEYWORDS[$keyword] ) ) { - $func = self::$mKeywords[$keyword]; $this->move(); - $r2 = new AFPData(); + $r2 = new AFPData( AFPData::DEMPTY ); $this->doLevelUnarys( $r2 ); + if ( $r2->getType() === AFPData::DEMPTY ) { + $this->logEmptyOperand( 'keyword operand' ); + } + if ( $this->mShortCircuit ) { // The result doesn't matter. return; } - AbuseFilter::triggerLimiter(); - - $result = AFPData::$func( $result, $r2, $this->mCur->pos ); + $result = $this->callKeyword( $keyword, $result, $r2 ); } } @@ -587,15 +851,19 @@ class AbuseFilterParser { */ protected function doLevelUnarys( &$result ) { $op = $this->mCur->value; - if ( $this->mCur->type == AFPToken::TOP && ( $op == "+" || $op == "-" ) ) { + if ( $this->mCur->type === AFPToken::TOP && ( $op === "+" || $op === "-" ) ) { $this->move(); + $checkEmpty = $result->getType() === AFPData::DEMPTY; $this->doLevelArrayElements( $result ); + if ( $checkEmpty && $result->getType() === AFPData::DEMPTY ) { + $this->logEmptyOperand( 'unary operand' ); + } if ( $this->mShortCircuit ) { // The result doesn't matter. return; } - if ( $op == '-' ) { - $result = AFPData::unaryMinus( $result ); + if ( $op === '-' ) { + $result = $result->unaryMinus(); } } else { $this->doLevelArrayElements( $result ); @@ -610,20 +878,25 @@ class AbuseFilterParser { */ protected function doLevelArrayElements( &$result ) { $this->doLevelBraces( $result ); - while ( $this->mCur->type == AFPToken::TSQUAREBRACKET && $this->mCur->value == '[' ) { - $idx = new AFPData(); + while ( $this->mCur->type === AFPToken::TSQUAREBRACKET && $this->mCur->value === '[' ) { + $idx = new AFPData( AFPData::DEMPTY ); $this->doLevelSemicolon( $idx ); - if ( !( $this->mCur->type == AFPToken::TSQUAREBRACKET && $this->mCur->value == ']' ) ) { + if ( !( $this->mCur->type === AFPToken::TSQUAREBRACKET && $this->mCur->value === ']' ) ) { throw new AFPUserVisibleException( 'expectednotfound', $this->mCur->pos, [ ']', $this->mCur->type, $this->mCur->value ] ); } $idx = $idx->toInt(); - if ( $result->type == AFPData::DARRAY ) { - if ( count( $result->data ) <= $idx ) { + if ( $result->getType() === AFPData::DARRAY ) { + if ( count( $result->getData() ) <= $idx ) { throw new AFPUserVisibleException( 'outofbounds', $this->mCur->pos, - [ $idx, count( $result->data ) ] ); + [ $idx, count( $result->getData() ) ] ); + } elseif ( $idx < 0 ) { + throw new AFPUserVisibleException( 'negativeindex', $this->mCur->pos, [ $idx ] ); } - $result = $result->data[$idx]; + // @phan-suppress-next-line PhanTypeArraySuspiciousNullable Guaranteed to be array + $result = $result->getData()[$idx]; + } elseif ( $result->getType() === AFPData::DUNDEFINED ) { + $result = new AFPData( AFPData::DUNDEFINED ); } else { throw new AFPUserVisibleException( 'notarray', $this->mCur->pos, [] ); } @@ -638,20 +911,29 @@ class AbuseFilterParser { * @throws AFPUserVisibleException */ protected function doLevelBraces( &$result ) { - if ( $this->mCur->type == AFPToken::TBRACE && $this->mCur->value == '(' ) { - if ( $this->mShortCircuit ) { - $this->skipOverBraces(); + if ( $this->mCur->type === AFPToken::TBRACE && $this->mCur->value === '(' ) { + $next = $this->getNextToken(); + if ( $next->type === AFPToken::TBRACE && $next->value === ')' ) { + $this->logEmptyOperand( 'parenthesized expression' ); + // We don't need DUNDEFINED here + $this->move(); + $this->move(); } else { - $this->doLevelSemicolon( $result ); - } - if ( !( $this->mCur->type == AFPToken::TBRACE && $this->mCur->value == ')' ) ) { - throw new AFPUserVisibleException( - 'expectednotfound', - $this->mCur->pos, - [ ')', $this->mCur->type, $this->mCur->value ] - ); + if ( $this->mShortCircuit ) { + $result = new AFPData( AFPData::DUNDEFINED ); + $this->skipOverBraces(); + } else { + $this->doLevelSemicolon( $result ); + } + if ( !( $this->mCur->type === AFPToken::TBRACE && $this->mCur->value === ')' ) ) { + throw new AFPUserVisibleException( + 'expectednotfound', + $this->mCur->pos, + [ ')', $this->mCur->type, $this->mCur->value ] + ); + } + $this->move(); } - $this->move(); } else { $this->doLevelFunction( $result ); } @@ -664,10 +946,10 @@ class AbuseFilterParser { * @throws AFPUserVisibleException */ protected function doLevelFunction( &$result ) { - if ( $this->mCur->type == AFPToken::TID && isset( self::$mFunctions[$this->mCur->value] ) ) { - $func = self::$mFunctions[$this->mCur->value]; + if ( $this->mCur->type === AFPToken::TID && isset( self::FUNCTIONS[$this->mCur->value] ) ) { + $fname = $this->mCur->value; $this->move(); - if ( $this->mCur->type != AFPToken::TBRACE || $this->mCur->value != '(' ) { + if ( $this->mCur->type !== AFPToken::TBRACE || $this->mCur->value !== '(' ) { throw new AFPUserVisibleException( 'expectednotfound', $this->mCur->pos, [ @@ -679,6 +961,7 @@ class AbuseFilterParser { } if ( $this->mShortCircuit ) { + $result = new AFPData( AFPData::DUNDEFINED ); $this->skipOverBraces(); $this->move(); @@ -687,18 +970,38 @@ class AbuseFilterParser { } $args = []; - $state = $this->getState(); - $this->move(); - if ( $this->mCur->type != AFPToken::TBRACE || $this->mCur->value != ')' ) { - $this->setState( $state ); + $next = $this->getNextToken(); + if ( $next->type !== AFPToken::TBRACE || $next->value !== ')' ) { + if ( ( $fname === 'set' || $fname === 'set_var' ) ) { + $state = $this->getState(); + $this->move(); + $next = $this->getNextToken(); + if ( + $this->mCur->type !== AFPToken::TSTRING || + ( + $next->type !== AFPToken::TCOMMA && + // Let this fail later, when checking parameters count + !( $next->type === AFPToken::TBRACE && $next->value === ')' ) + ) + ) { + throw new AFPUserVisibleException( 'variablevariable', $this->mCur->pos, [] ); + } else { + $this->setState( $state ); + } + } do { - $r = new AFPData(); + $r = new AFPData( AFPData::DEMPTY ); $this->doLevelSemicolon( $r ); + if ( $r->getType() === AFPData::DEMPTY && !$this->functionIsVariadic( $fname ) ) { + $this->logEmptyOperand( 'non-variadic function argument' ); + } $args[] = $r; - } while ( $this->mCur->type == AFPToken::TCOMMA ); + } while ( $this->mCur->type === AFPToken::TCOMMA ); + } else { + $this->move(); } - if ( $this->mCur->type != AFPToken::TBRACE || $this->mCur->value != ')' ) { + if ( $this->mCur->type !== AFPToken::TBRACE || $this->mCur->value !== ')' ) { throw new AFPUserVisibleException( 'expectednotfound', $this->mCur->pos, [ @@ -710,20 +1013,7 @@ class AbuseFilterParser { } $this->move(); - $funcHash = md5( $func . serialize( $args ) ); - - if ( isset( self::$funcCache[$funcHash] ) && - !in_array( $func, self::$ActiveFunctions ) - ) { - $result = self::$funcCache[$funcHash]; - } else { - AbuseFilter::triggerLimiter(); - $result = self::$funcCache[$funcHash] = $this->$func( $args ); - } - - if ( count( self::$funcCache ) > 1000 ) { - self::$funcCache = []; - } + $result = $this->callFunc( $fname, $args ); } else { $this->doLevelAtom( $result ); } @@ -740,10 +1030,11 @@ class AbuseFilterParser { switch ( $this->mCur->type ) { case AFPToken::TID: if ( $this->mShortCircuit ) { - break; + $result = new AFPData( AFPData::DUNDEFINED ); + } else { + $var = strtolower( $tok ); + $result = $this->getVarValue( $var ); } - $var = strtolower( $tok ); - $result = $this->getVarValue( $var ); break; case AFPToken::TSTRING: $result = new AFPData( AFPData::DSTRING, $tok ); @@ -755,12 +1046,12 @@ class AbuseFilterParser { $result = new AFPData( AFPData::DINT, $tok ); break; case AFPToken::TKEYWORD: - if ( $tok == "true" ) { + if ( $tok === "true" ) { $result = new AFPData( AFPData::DBOOL, true ); - } elseif ( $tok == "false" ) { + } elseif ( $tok === "false" ) { $result = new AFPData( AFPData::DBOOL, false ); - } elseif ( $tok == "null" ) { - $result = new AFPData(); + } elseif ( $tok === "null" ) { + $result = new AFPData( AFPData::DNULL ); } else { throw new AFPUserVisibleException( 'unrecognisedkeyword', @@ -773,25 +1064,25 @@ class AbuseFilterParser { // Handled at entry level return; case AFPToken::TBRACE: - if ( $this->mCur->value == ')' ) { + if ( $this->mCur->value === ')' ) { // Handled at the entry level return; } case AFPToken::TSQUAREBRACKET: - if ( $this->mCur->value == '[' ) { + if ( $this->mCur->value === '[' ) { $array = []; while ( true ) { $this->move(); - if ( $this->mCur->type == AFPToken::TSQUAREBRACKET && $this->mCur->value == ']' ) { + if ( $this->mCur->type === AFPToken::TSQUAREBRACKET && $this->mCur->value === ']' ) { break; } - $item = new AFPData(); + $item = new AFPData( AFPData::DEMPTY ); $this->doLevelSet( $item ); $array[] = $item; - if ( $this->mCur->type == AFPToken::TSQUAREBRACKET && $this->mCur->value == ']' ) { + if ( $this->mCur->type === AFPToken::TSQUAREBRACKET && $this->mCur->value === ']' ) { break; } - if ( $this->mCur->type != AFPToken::TCOMMA ) { + if ( $this->mCur->type !== AFPToken::TCOMMA ) { throw new AFPUserVisibleException( 'expectednotfound', $this->mCur->pos, @@ -818,34 +1109,61 @@ class AbuseFilterParser { /* End of levels */ /** + * Check whether a variable exists, being either built-in or user-defined. Doesn't include + * disabled variables. + * + * @param string $varname + * @return bool + */ + protected function varExists( $varname ) { + return $this->keywordsManager->isVarInUse( $varname ) || + $this->mVariables->varIsSet( $varname ); + } + + /** * @param string $var * @return AFPData * @throws AFPUserVisibleException */ protected function getVarValue( $var ) { $var = strtolower( $var ); - $builderValues = AbuseFilter::getBuilderValues(); - $deprecatedVars = AbuseFilter::getDeprecatedVariables(); + $deprecatedVars = $this->keywordsManager->getDeprecatedVariables(); + if ( array_key_exists( $var, $deprecatedVars ) ) { - $logger = LoggerFactory::getInstance( 'AbuseFilterDeprecatedVars' ); - $logger->debug( "AbuseFilter: deprecated variable $var used." ); - $var = $deprecatedVars[$var]; + if ( $this->logsDeprecatedVars() ) { + $this->logger->debug( "Deprecated variable $var used in filter {$this->mFilter}." ); + } + $var = $deprecatedVars[ $var ]; } - if ( !( array_key_exists( $var, $builderValues['vars'] ) - || $this->mVars->varIsSet( $var ) ) - ) { - $msg = array_key_exists( $var, AbuseFilter::$disabledVars ) ? - 'disabledvar' : - 'unrecognisedvar'; - // If the variable is invalid, throw an exception + if ( $this->keywordsManager->isVarDisabled( $var ) ) { throw new AFPUserVisibleException( - $msg, + 'disabledvar', + $this->mCur->pos, + [ $var ] + ); + } + if ( !$this->varExists( $var ) ) { + throw new AFPUserVisibleException( + 'unrecognisedvar', $this->mCur->pos, [ $var ] ); - } else { - return $this->mVars->getVar( $var ); } + + // It's a built-in, non-disabled variable (either set or unset), or a set custom variable + $flags = $this->allowMissingVariables + ? AbuseFilterVariableHolder::GET_LAX + // TODO: This should be GET_STRICT, but that's going to be very hard (see T230256) + : AbuseFilterVariableHolder::GET_BC; + return $this->mVariables->getVar( $var, $flags, $this->mFilter ); + } + + /** + * Whether this parser should log deprecated vars use. + * @return bool + */ + protected function logsDeprecatedVars() { + return true; } /** @@ -854,16 +1172,99 @@ class AbuseFilterParser { * @throws AFPUserVisibleException */ protected function setUserVariable( $name, $value ) { - $builderValues = AbuseFilter::getBuilderValues(); - $deprecatedVars = AbuseFilter::getDeprecatedVariables(); - $blacklistedValues = AbuseFilterVariableHolder::$varBlacklist; - if ( array_key_exists( $name, $builderValues['vars'] ) || - array_key_exists( $name, AbuseFilter::$disabledVars ) || - array_key_exists( $name, $deprecatedVars ) || - in_array( $name, $blacklistedValues ) ) { + if ( $this->isReservedIdentifier( $name ) ) { throw new AFPUserVisibleException( 'overridebuiltin', $this->mCur->pos, [ $name ] ); } - $this->mVars->setVar( $name, $value ); + $this->mVariables->setVar( $name, $value ); + } + + /** + * Helper to call a built-in function. + * + * @param string $fname The name of the function as found in the filter code + * @param AFPData[] $args Arguments for the function + * @return AFPData The return value of the function + * @throws InvalidArgumentException if given an invalid func + */ + protected function callFunc( $fname, array $args ) : AFPData { + if ( !array_key_exists( $fname, self::FUNCTIONS ) ) { + // @codeCoverageIgnoreStart + throw new InvalidArgumentException( "$fname is not a valid function." ); + // @codeCoverageIgnoreEnd + } + + $funcHandler = self::FUNCTIONS[$fname]; + $funcHash = md5( $funcHandler . serialize( $args ) ); + + if ( isset( $this->funcCache[$funcHash] ) && + !in_array( $funcHandler, self::ACTIVE_FUNCTIONS ) + ) { + $result = $this->funcCache[$funcHash]; + } else { + $this->checkArgCount( $args, $fname ); + $this->raiseCondCount(); + + // Any undefined argument should be special-cased by the function, but that would be too + // much overhead. We also cannot skip calling the handler in case it's making further + // validation (T234339). So temporarily replace the DUNDEFINED with a DNULL. + // @todo This is subpar. + $hasUndefinedArg = false; + foreach ( $args as $i => $arg ) { + if ( $arg->hasUndefined() ) { + $args[$i] = $arg->cloneAsUndefinedReplacedWithNull(); + $hasUndefinedArg = true; + } + } + if ( $hasUndefinedArg ) { + $this->$funcHandler( $args ); + $result = new AFPData( AFPData::DUNDEFINED ); + } else { + $result = $this->$funcHandler( $args ); + } + $this->funcCache[$funcHash] = $result; + } + + if ( count( $this->funcCache ) > 1000 ) { + // @codeCoverageIgnoreStart + $this->clearFuncCache(); + // @codeCoverageIgnoreEnd + } + return $result; + } + + /** + * Helper to invoke a built-in keyword. Note that this assumes that $kname is + * a valid keyword name. + * + * @param string $kname + * @param AFPData $lhs + * @param AFPData $rhs + * @return AFPData + */ + protected function callKeyword( $kname, AFPData $lhs, AFPData $rhs ) : AFPData { + $func = self::KEYWORDS[$kname]; + $this->raiseCondCount(); + + $hasUndefinedOperand = false; + if ( $lhs->hasUndefined() ) { + $lhs = $lhs->cloneAsUndefinedReplacedWithNull(); + $hasUndefinedOperand = true; + } + if ( $rhs->hasUndefined() ) { + $rhs = $rhs->cloneAsUndefinedReplacedWithNull(); + $hasUndefinedOperand = true; + } + if ( $hasUndefinedOperand ) { + // We need to run the handler with bogus args, see the comment in self::callFunc (T234339) + // @todo Likewise, this is subpar. + // @phan-suppress-next-line PhanParamTooMany Not every function needs the position + $this->$func( $lhs, $rhs, $this->mCur->pos ); + $result = new AFPData( AFPData::DUNDEFINED ); + } else { + // @phan-suppress-next-line PhanParamTooMany Not every function needs the position + $result = $this->$func( $lhs, $rhs, $this->mCur->pos ); + } + return $result; } // Built-in functions @@ -871,76 +1272,43 @@ class AbuseFilterParser { /** * @param array $args * @return AFPData - * @throws AFPUserVisibleException */ protected function funcLc( $args ) { - global $wgContLang; - if ( count( $args ) === 0 ) { - throw new AFPUserVisibleException( - 'noparams', - $this->mCur->pos, - [ 'lc', 1 ] - ); - } $s = $args[0]->toString(); - return new AFPData( AFPData::DSTRING, $wgContLang->lc( $s ) ); + return new AFPData( AFPData::DSTRING, $this->contLang->lc( $s ) ); } /** * @param array $args * @return AFPData - * @throws AFPUserVisibleException */ protected function funcUc( $args ) { - global $wgContLang; - if ( count( $args ) === 0 ) { - throw new AFPUserVisibleException( - 'noparams', - $this->mCur->pos, - [ 'uc', 1 ] - ); - } $s = $args[0]->toString(); - return new AFPData( AFPData::DSTRING, $wgContLang->uc( $s ) ); + return new AFPData( AFPData::DSTRING, $this->contLang->uc( $s ) ); } /** * @param array $args * @return AFPData - * @throws AFPUserVisibleException */ protected function funcLen( $args ) { - if ( count( $args ) === 0 ) { - throw new AFPUserVisibleException( - 'noparams', - $this->mCur->pos, - [ 'len', 1 ] - ); - } - if ( $args[0]->type == AFPData::DARRAY ) { + if ( $args[0]->type === AFPData::DARRAY ) { // Don't use toString on arrays, but count - return new AFPData( AFPData::DINT, count( $args[0]->data ) ); + $val = count( $args[0]->data ); + } else { + $val = mb_strlen( $args[0]->toString(), 'utf-8' ); } - $s = $args[0]->toString(); - return new AFPData( AFPData::DINT, mb_strlen( $s, 'utf-8' ) ); + return new AFPData( AFPData::DINT, $val ); } /** * @param array $args * @return AFPData - * @throws AFPUserVisibleException */ protected function funcSpecialRatio( $args ) { - if ( count( $args ) === 0 ) { - throw new AFPUserVisibleException( - 'noparams', - $this->mCur->pos, - [ 'specialratio', 1 ] - ); - } $s = $args[0]->toString(); if ( !strlen( $s ) ) { @@ -957,22 +1325,13 @@ class AbuseFilterParser { /** * @param array $args * @return AFPData - * @throws AFPUserVisibleException */ protected function funcCount( $args ) { - if ( count( $args ) === 0 ) { - throw new AFPUserVisibleException( - 'noparams', - $this->mCur->pos, - [ 'count', 1 ] - ); - } - - if ( $args[0]->type == AFPData::DARRAY && count( $args ) == 1 ) { + if ( $args[0]->type === AFPData::DARRAY && count( $args ) === 1 ) { return new AFPData( AFPData::DINT, count( $args[0]->data ) ); } - if ( count( $args ) == 1 ) { + if ( count( $args ) === 1 ) { $count = count( explode( ',', $args[0]->toString() ) ); } else { $needle = $args[0]->toString(); @@ -993,18 +1352,9 @@ class AbuseFilterParser { * @param array $args * @return AFPData * @throws AFPUserVisibleException - * @throws Exception */ protected function funcRCount( $args ) { - if ( count( $args ) === 0 ) { - throw new AFPUserVisibleException( - 'noparams', - $this->mCur->pos, - [ 'rcount', 1 ] - ); - } - - if ( count( $args ) == 1 ) { + if ( count( $args ) === 1 ) { $count = count( explode( ',', $args[0]->toString() ) ); } else { $needle = $args[0]->toString(); @@ -1015,9 +1365,9 @@ class AbuseFilterParser { $needle = "/$needle/u"; // Suppress and restore needed per T177744 - Wikimedia\suppressWarnings(); + AtEase::suppressWarnings(); $count = preg_match_all( $needle, $haystack ); - Wikimedia\restoreWarnings(); + AtEase::restoreWarnings(); if ( $count === false ) { throw new AFPUserVisibleException( @@ -1040,23 +1390,19 @@ class AbuseFilterParser { * @throws AFPUserVisibleException */ protected function funcGetMatches( $args ) { - if ( count( $args ) < 2 ) { - throw new AFPUserVisibleException( - 'notenoughargs', - $this->mCur->pos, - [ 'get_matches', 2, count( $args ) ] - ); - } $needle = $args[0]->toString(); $haystack = $args[1]->toString(); // Count the amount of capturing groups in the submitted pattern. // This way we can return a fixed-dimension array, much easier to manage. + // ToDo: Find a better way to do this. // First, strip away escaped parentheses $sanitized = preg_replace( '/(\\\\\\\\)*\\\\\(/', '', $needle ); - // Then strip starting parentheses of non-capturing groups - // (also atomics, lookahead and so on, even if not every of them is supported) - $sanitized = preg_replace( '/\(\?/', '', $sanitized ); + // Then strip starting parentheses of non-capturing groups, including + // atomics, lookaheads and so on, even if not every of them is supported. + $sanitized = str_replace( '(?', '', $sanitized ); + // And also strip "(*", used with backtracking verbs like (*FAIL) + $sanitized = str_replace( '(*', '', $sanitized ); // Finally create an array of falses with dimension = # of capturing groups $groupscount = substr_count( $sanitized, '(' ) + 1; $falsy = array_fill( 0, $groupscount, false ); @@ -1066,9 +1412,9 @@ class AbuseFilterParser { $needle = "/$needle/u"; // Suppress and restore are here for the same reason as T177744 - Wikimedia\suppressWarnings(); + AtEase::suppressWarnings(); $check = preg_match( $needle, $haystack, $matches ); - Wikimedia\restoreWarnings(); + AtEase::restoreWarnings(); if ( $check === false ) { throw new AFPUserVisibleException( @@ -1090,18 +1436,10 @@ class AbuseFilterParser { * @throws AFPUserVisibleException */ protected function funcIPInRange( $args ) { - if ( count( $args ) < 2 ) { - throw new AFPUserVisibleException( - 'notenoughargs', - $this->mCur->pos, - [ 'ip_in_range', 2, count( $args ) ] - ); - } - $ip = $args[0]->toString(); $range = $args[1]->toString(); - if ( !IP::isValidRange( $range ) ) { + if ( !IPUtils::isValidRange( $range ) ) { throw new AFPUserVisibleException( 'invalidiprange', $this->mCur->pos, @@ -1109,7 +1447,7 @@ class AbuseFilterParser { ); } - $result = IP::isInRange( $ip, $range ); + $result = IPUtils::isInRange( $ip, $range ); return new AFPData( AFPData::DBOOL, $result ); } @@ -1117,16 +1455,8 @@ class AbuseFilterParser { /** * @param array $args * @return AFPData - * @throws AFPUserVisibleException */ protected function funcCCNorm( $args ) { - if ( count( $args ) === 0 ) { - throw new AFPUserVisibleException( - 'noparams', - $this->mCur->pos, - [ 'ccnorm', 1 ] - ); - } $s = $args[0]->toString(); $s = html_entity_decode( $s, ENT_QUOTES, 'UTF-8' ); @@ -1138,16 +1468,8 @@ class AbuseFilterParser { /** * @param array $args * @return AFPData - * @throws AFPUserVisibleException */ protected function funcSanitize( $args ) { - if ( count( $args ) === 0 ) { - throw new AFPUserVisibleException( - 'noparams', - $this->mCur->pos, - [ 'sanitize', 1 ] - ); - } $s = $args[0]->toString(); $s = html_entity_decode( $s, ENT_QUOTES, 'UTF-8' ); @@ -1159,17 +1481,8 @@ class AbuseFilterParser { /** * @param array $args * @return AFPData - * @throws AFPUserVisibleException */ protected function funcContainsAny( $args ) { - if ( count( $args ) < 2 ) { - throw new AFPUserVisibleException( - 'notenoughargs', - $this->mCur->pos, - [ 'contains_any', 2, count( $args ) ] - ); - } - $s = array_shift( $args ); return new AFPData( AFPData::DBOOL, self::contains( $s, $args, true ) ); @@ -1178,17 +1491,8 @@ class AbuseFilterParser { /** * @param array $args * @return AFPData - * @throws AFPUserVisibleException */ protected function funcContainsAll( $args ) { - if ( count( $args ) < 2 ) { - throw new AFPUserVisibleException( - 'notenoughargs', - $this->mCur->pos, - [ 'contains_all', 2, count( $args ) ] - ); - } - $s = array_shift( $args ); return new AFPData( AFPData::DBOOL, self::contains( $s, $args, false, false ) ); @@ -1199,17 +1503,8 @@ class AbuseFilterParser { * * @param array $args * @return AFPData - * @throws AFPUserVisibleException */ protected function funcCCNormContainsAny( $args ) { - if ( count( $args ) < 2 ) { - throw new AFPUserVisibleException( - 'notenoughargs', - $this->mCur->pos, - [ 'ccnorm_contains_any', 2, count( $args ) ] - ); - } - $s = array_shift( $args ); return new AFPData( AFPData::DBOOL, self::contains( $s, $args, true, true ) ); @@ -1220,17 +1515,8 @@ class AbuseFilterParser { * * @param array $args * @return AFPData - * @throws AFPUserVisibleException */ protected function funcCCNormContainsAll( $args ) { - if ( count( $args ) < 2 ) { - throw new AFPUserVisibleException( - 'notenoughargs', - $this->mCur->pos, - [ 'ccnorm_contains_all', 2, count( $args ) ] - ); - } - $s = array_shift( $args ); return new AFPData( AFPData::DBOOL, self::contains( $s, $args, false, true ) ); @@ -1283,23 +1569,14 @@ class AbuseFilterParser { // If I'm here and it's ANY (OR) => nothing was found: return false ($is_any is true) // If I'm here and it's ALL (AND) => everything was found: return true ($is_any is false) - return ! $is_any; + return !$is_any; } /** * @param array $args * @return AFPData - * @throws AFPUserVisibleException */ protected function funcEqualsToAny( $args ) { - if ( count( $args ) < 2 ) { - throw new AFPUserVisibleException( - 'notenoughargs', - $this->mCur->pos, - [ 'equals_to_any', 2, count( $args ) ] - ); - } - $s = array_shift( $args ); return new AFPData( AFPData::DBOOL, self::equalsToAny( $s, $args ) ); @@ -1314,12 +1591,8 @@ class AbuseFilterParser { * @return bool */ protected static function equalsToAny( $string, $values ) { - $string = $string->toString(); - foreach ( $values as $needle ) { - $needle = $needle->toString(); - - if ( $string === $needle ) { + if ( $string->equals( $needle, true ) ) { return true; } } @@ -1367,76 +1640,38 @@ class AbuseFilterParser { /** * @param array $args * @return AFPData - * @throws AFPUserVisibleException */ protected function funcRMSpecials( $args ) { - if ( count( $args ) === 0 ) { - throw new AFPUserVisibleException( - 'noparams', - $this->mCur->pos, - [ 'rmspecials', 1 ] - ); - } $s = $args[0]->toString(); - $s = $this->rmspecials( $s ); - - return new AFPData( AFPData::DSTRING, $s ); + return new AFPData( AFPData::DSTRING, $this->rmspecials( $s ) ); } /** * @param array $args * @return AFPData - * @throws AFPUserVisibleException */ protected function funcRMWhitespace( $args ) { - if ( count( $args ) === 0 ) { - throw new AFPUserVisibleException( - 'noparams', - $this->mCur->pos, - [ 'rmwhitespace', 1 ] - ); - } $s = $args[0]->toString(); - $s = $this->rmwhitespace( $s ); - - return new AFPData( AFPData::DSTRING, $s ); + return new AFPData( AFPData::DSTRING, $this->rmwhitespace( $s ) ); } /** * @param array $args * @return AFPData - * @throws AFPUserVisibleException */ protected function funcRMDoubles( $args ) { - if ( count( $args ) === 0 ) { - throw new AFPUserVisibleException( - 'noparams', - $this->mCur->pos, - [ 'rmdoubles', 1 ] - ); - } $s = $args[0]->toString(); - $s = $this->rmdoubles( $s ); - - return new AFPData( AFPData::DSTRING, $s ); + return new AFPData( AFPData::DSTRING, $this->rmdoubles( $s ) ); } /** * @param array $args * @return AFPData - * @throws AFPUserVisibleException */ protected function funcNorm( $args ) { - if ( count( $args ) === 0 ) { - throw new AFPUserVisibleException( - 'noparams', - $this->mCur->pos, - [ 'norm', 1 ] - ); - } $s = $args[0]->toString(); $s = $this->ccnorm( $s ); @@ -1450,27 +1685,13 @@ class AbuseFilterParser { /** * @param array $args * @return AFPData - * @throws AFPUserVisibleException */ protected function funcSubstr( $args ) { - if ( count( $args ) < 2 ) { - throw new AFPUserVisibleException( - 'notenoughargs', - $this->mCur->pos, - [ 'substr', 2, count( $args ) ] - ); - } - $s = $args[0]->toString(); $offset = $args[1]->toInt(); + $length = isset( $args[2] ) ? $args[2]->toInt() : null; - if ( isset( $args[2] ) ) { - $length = $args[2]->toInt(); - - $result = mb_substr( $s, $offset, $length ); - } else { - $result = mb_substr( $s, $offset ); - } + $result = mb_substr( $s, $offset, $length ); return new AFPData( AFPData::DSTRING, $result ); } @@ -1478,32 +1699,18 @@ class AbuseFilterParser { /** * @param array $args * @return AFPData - * @throws AFPUserVisibleException */ protected function funcStrPos( $args ) { - if ( count( $args ) < 2 ) { - throw new AFPUserVisibleException( - 'notenoughargs', - $this->mCur->pos, - [ 'strpos', 2, count( $args ) ] - ); - } - $haystack = $args[0]->toString(); $needle = $args[1]->toString(); + $offset = isset( $args[2] ) ? $args[2]->toInt() : 0; // T62203: Keep empty parameters from causing PHP warnings if ( $needle === '' ) { return new AFPData( AFPData::DINT, -1 ); } - if ( isset( $args[2] ) ) { - $offset = $args[2]->toInt(); - - $result = mb_strpos( $haystack, $needle, $offset ); - } else { - $result = mb_strpos( $haystack, $needle ); - } + $result = mb_strpos( $haystack, $needle, $offset ); if ( $result === false ) { $result = -1; @@ -1515,17 +1722,8 @@ class AbuseFilterParser { /** * @param array $args * @return AFPData - * @throws AFPUserVisibleException */ protected function funcStrReplace( $args ) { - if ( count( $args ) < 3 ) { - throw new AFPUserVisibleException( - 'notenoughargs', - $this->mCur->pos, - [ 'str_replace', 3, count( $args ) ] - ); - } - $subject = $args[0]->toString(); $search = $args[1]->toString(); $replace = $args[2]->toString(); @@ -1536,17 +1734,8 @@ class AbuseFilterParser { /** * @param array $args * @return AFPData - * @throws AFPUserVisibleException */ protected function funcStrRegexEscape( $args ) { - if ( count( $args ) === 0 ) { - throw new AFPUserVisibleException( - 'noparams', - $this->mCur->pos, - [ 'rescape', 1 ] - ); - } - $string = $args[0]->toString(); // preg_quote does not need the second parameter, since rlike takes @@ -1557,17 +1746,8 @@ class AbuseFilterParser { /** * @param array $args * @return mixed - * @throws AFPUserVisibleException */ protected function funcSetVar( $args ) { - if ( count( $args ) < 2 ) { - throw new AFPUserVisibleException( - 'notenoughargs', - $this->mCur->pos, - [ 'set_var', 2, count( $args ) ] - ); - } - $varName = $args[0]->toString(); $value = $args[1]; @@ -1577,74 +1757,151 @@ class AbuseFilterParser { } /** - * @param array $args + * Checks if $a contains $b + * + * @param AFPData $a + * @param AFPData $b * @return AFPData - * @throws AFPUserVisibleException */ - protected function castString( $args ) { - if ( count( $args ) === 0 ) { - throw new AFPUserVisibleException( - 'noparams', - $this->mCur->pos, - [ 'string', 1 ] - ); + protected function containmentKeyword( AFPData $a, AFPData $b ) { + $a = $a->toString(); + $b = $b->toString(); + + if ( $a === '' || $b === '' ) { + return new AFPData( AFPData::DBOOL, false ); } - $val = $args[0]; - return AFPData::castTypes( $val, AFPData::DSTRING ); + return new AFPData( AFPData::DBOOL, strpos( $a, $b ) !== false ); } /** - * @param array $args + * @param AFPData $a + * @param AFPData $b * @return AFPData - * @throws AFPUserVisibleException */ - protected function castInt( $args ) { - if ( count( $args ) === 0 ) { + protected function keywordIn( AFPData $a, AFPData $b ) { + return $this->containmentKeyword( $b, $a ); + } + + /** + * @param AFPData $a + * @param AFPData $b + * @return AFPData + */ + protected function keywordContains( AFPData $a, AFPData $b ) { + return $this->containmentKeyword( $a, $b ); + } + + /** + * @param AFPData $str + * @param AFPData $pattern + * @return AFPData + */ + protected function keywordLike( AFPData $str, AFPData $pattern ) { + $str = $str->toString(); + $pattern = '#^' . strtr( preg_quote( $pattern->toString(), '#' ), AFPData::WILDCARD_MAP ) . '$#u'; + AtEase::suppressWarnings(); + $result = preg_match( $pattern, $str ); + AtEase::restoreWarnings(); + + return new AFPData( AFPData::DBOOL, (bool)$result ); + } + + /** + * @param AFPData $str + * @param AFPData $regex + * @param int $pos + * @param bool $insensitive + * @return AFPData + * @throws Exception + */ + protected function keywordRegex( AFPData $str, AFPData $regex, $pos, $insensitive = false ) { + $str = $str->toString(); + $pattern = $regex->toString(); + + $pattern = preg_replace( '!(\\\\\\\\)*(\\\\)?/!', '$1\/', $pattern ); + $pattern = "/$pattern/u"; + + if ( $insensitive ) { + $pattern .= 'i'; + } + + AtEase::suppressWarnings(); + $result = preg_match( $pattern, $str ); + AtEase::restoreWarnings(); + if ( $result === false ) { throw new AFPUserVisibleException( - 'noparams', - $this->mCur->pos, - [ 'int', 1 ] + 'regexfailure', + // Coverage bug + // @codeCoverageIgnoreStart + $pos, + // @codeCoverageIgnoreEnd + [ $pattern ] ); } - $val = $args[0]; - return AFPData::castTypes( $val, AFPData::DINT ); + return new AFPData( AFPData::DBOOL, (bool)$result ); + } + + /** + * @param AFPData $str + * @param AFPData $regex + * @param int $pos + * @return AFPData + */ + protected function keywordRegexInsensitive( AFPData $str, AFPData $regex, $pos ) { + return $this->keywordRegex( $str, $regex, $pos, true ); + } + + /** + * @param array $args + * @return AFPData + */ + protected function castString( $args ) { + return AFPData::castTypes( $args[0], AFPData::DSTRING ); } /** * @param array $args * @return AFPData - * @throws AFPUserVisibleException */ - protected function castFloat( $args ) { - if ( count( $args ) === 0 ) { - throw new AFPUserVisibleException( - 'noparams', - $this->mCur->pos, - [ 'float', 1 ] - ); - } - $val = $args[0]; + protected function castInt( $args ) { + return AFPData::castTypes( $args[0], AFPData::DINT ); + } - return AFPData::castTypes( $val, AFPData::DFLOAT ); + /** + * @param array $args + * @return AFPData + */ + protected function castFloat( $args ) { + return AFPData::castTypes( $args[0], AFPData::DFLOAT ); } /** * @param array $args * @return AFPData - * @throws AFPUserVisibleException */ protected function castBool( $args ) { - if ( count( $args ) === 0 ) { - throw new AFPUserVisibleException( - 'noparams', - $this->mCur->pos, - [ 'bool', 1 ] + return AFPData::castTypes( $args[0], AFPData::DBOOL ); + } + + /** + * Log empty operands for T156096 + * + * @param string $type Type of the empty operand + */ + protected function logEmptyOperand( $type ) { + if ( $this->mFilter !== null ) { + $this->logger->warning( + 'DEPRECATED! Found empty operand of type `{op_type}` when parsing filter: {filter}. ' . + 'This is deprecated since 1.34 and support will be discontinued soon. Please fix ' . + 'the affected filter!', + [ + 'op_type' => $type, + 'filter' => $this->mFilter + ] ); } - $val = $args[0]; - - return AFPData::castTypes( $val, AFPData::DBOOL ); } + } diff --git a/AbuseFilter/includes/parser/AbuseFilterTokenizer.php b/AbuseFilter/includes/parser/AbuseFilterTokenizer.php index d95a6864..b814b670 100644 --- a/AbuseFilter/includes/parser/AbuseFilterTokenizer.php +++ b/AbuseFilter/includes/parser/AbuseFilterTokenizer.php @@ -1,24 +1,27 @@ <?php -use MediaWiki\MediaWikiServices; +use Psr\Log\LoggerInterface; /** * Tokenizer for AbuseFilter rules. */ class AbuseFilterTokenizer { - /** @var int Tokenizer cache version. Increment this when changing the syntax. **/ - const CACHE_VERSION = 1; - const COMMENT_START_RE = '/\s*\/\*/A'; - const ID_SYMBOL_RE = '/[0-9A-Za-z_]+/A'; - const OPERATOR_RE = + /** @var int Tokenizer cache version. Increment this when changing the syntax. */ + public const CACHE_VERSION = 4; + private const COMMENT_START_RE = '/\s*\/\*/A'; + private const ID_SYMBOL_RE = '/[0-9A-Za-z_]+/A'; + public const OPERATOR_RE = '/(\!\=\=|\!\=|\!|\*\*|\*|\/|\+|\-|%|&|\||\^|\:\=|\?|\:|\<\=|\<|\>\=|\>|\=\=\=|\=\=|\=)/A'; - const RADIX_RE = '/([0-9A-Fa-f]+(?:\.\d*)?|\.\d+)([bxo])?/Au'; - const WHITESPACE = "\011\012\013\014\015\040"; + private const BASE = '0(?<base>[xbo])'; + private const DIGIT = '[0-9A-Fa-f]'; + private const DIGITS = self::DIGIT . '+' . '(?:\.\d*)?|\.\d+'; + private const RADIX_RE = '/(?:' . self::BASE . ')?(?<input>' . self::DIGITS . ')(?!\w)/Au'; + private const WHITESPACE = "\011\012\013\014\015\040"; // Order is important. The punctuation-matching regex requires that // ** comes before *, etc. They are sorted to make it easy to spot // such errors. - public static $operators = [ + public const OPERATORS = [ // Inequality '!==', '!=', '!', // Multiplication/exponentiation @@ -39,7 +42,7 @@ class AbuseFilterTokenizer { '===', '==', '=', ]; - public static $punctuation = [ + public const PUNCTUATION = [ ',' => AFPToken::TCOMMA, '(' => AFPToken::TBRACE, ')' => AFPToken::TBRACE, @@ -48,64 +51,86 @@ class AbuseFilterTokenizer { ';' => AFPToken::TSTATEMENTSEPARATOR, ]; - public static $bases = [ + public const BASES = [ 'b' => 2, 'x' => 16, 'o' => 8 ]; - public static $baseCharsRe = [ + public const BASE_CHARS_RES = [ 2 => '/^[01]+$/', - 8 => '/^[0-8]+$/', + 8 => '/^[0-7]+$/', 16 => '/^[0-9A-Fa-f]+$/', 10 => '/^[0-9.]+$/', ]; - public static $keywords = [ + public const KEYWORDS = [ 'in', 'like', 'true', 'false', 'null', 'contains', 'matches', 'rlike', 'irlike', 'regex', 'if', 'then', 'else', 'end', ]; /** - * @param string $code - * @return array - * @throws AFPException - * @throws AFPUserVisibleException + * @var BagOStuff */ - public static function tokenize( $code ) { - static $tokenizerCache = null; - - if ( !$tokenizerCache ) { - $tokenizerCache = ObjectCache::getLocalServerInstance( 'hash' ); - } + private $cache; - static $stats = null; + /** + * @var LoggerInterface + */ + private $logger; - if ( !$stats ) { - $stats = MediaWikiServices::getInstance()->getStatsdDataFactory(); - } + /** + * @param BagOStuff $cache + * @param LoggerInterface $logger + */ + public function __construct( BagOStuff $cache, LoggerInterface $logger ) { + $this->cache = $cache; + $this->logger = $logger; + } - $cacheKey = wfGlobalCacheKey( __CLASS__, self::CACHE_VERSION, crc32( $code ) ); + /** + * Get a cache key used to store the tokenized code + * + * @param string $code Not yet tokenized + * @return string + * @internal + */ + public function getCacheKey( $code ) { + return $this->cache->makeGlobalKey( __CLASS__, self::CACHE_VERSION, crc32( $code ) ); + } - $tokens = $tokenizerCache->get( $cacheKey ); + /** + * Get the tokens for the given code. + * + * @param string $code + * @return array[] + */ + public function getTokens( $code ) { + $tokens = $this->cache->getWithSetCallback( + $this->getCacheKey( $code ), + BagOStuff::TTL_DAY, + function () use ( $code ) { + return $this->tokenize( $code ); + } + ); - if ( $tokens ) { - $stats->increment( 'AbuseFilter.tokenizerCache.hit' ); - return $tokens; - } + return $tokens; + } - $stats->increment( 'AbuseFilter.tokenizerCache.miss' ); + /** + * @param string $code + * @return array[] + */ + private function tokenize( $code ) { $tokens = []; $curPos = 0; do { $prevPos = $curPos; - $token = self::nextToken( $code, $curPos ); + $token = $this->nextToken( $code, $curPos ); $tokens[ $token->pos ] = [ $token, $curPos ]; } while ( $curPos !== $prevPos ); - $tokenizerCache->set( $cacheKey, $tokens, 60 * 60 * 24 ); - return $tokens; } @@ -116,7 +141,7 @@ class AbuseFilterTokenizer { * @throws AFPException * @throws AFPUserVisibleException */ - protected static function nextToken( $code, &$offset ) { + private function nextToken( $code, &$offset ) { $matches = []; $start = $offset; @@ -138,9 +163,9 @@ class AbuseFilterTokenizer { $chr = $code[$offset]; // Punctuation - if ( isset( self::$punctuation[$chr] ) ) { + if ( isset( self::PUNCTUATION[$chr] ) ) { $offset++; - return new AFPToken( self::$punctuation[$chr], $chr, $start ); + return new AFPToken( self::PUNCTUATION[$chr], $chr, $start ); } // String literal @@ -158,23 +183,13 @@ class AbuseFilterTokenizer { } // Numbers - if ( preg_match( self::RADIX_RE, $code, $matches, 0, $offset ) ) { - $token = $matches[0]; - $input = $matches[1]; - $baseChar = $matches[2] ?? null; - // Sometimes the base char gets mixed in with the rest of it because - // the regex targets hex, too. - // This mostly happens with binary - if ( !$baseChar && !empty( self::$bases[ substr( $input, - 1 ) ] ) ) { - $baseChar = substr( $input, - 1, 1 ); - $input = substr( $input, 0, - 1 ); - } - - $base = $baseChar ? self::$bases[$baseChar] : 10; - - // Check against the appropriate character class for input validation - - if ( preg_match( self::$baseCharsRe[$base], $input ) ) { + $matchesv2 = []; + if ( preg_match( self::RADIX_RE, $code, $matchesv2, 0, $offset ) ) { + $token = $matchesv2[0]; + $baseChar = $matchesv2['base']; + $input = $matchesv2['input']; + $base = $baseChar ? self::BASES[$baseChar] : 10; + if ( preg_match( self::BASE_CHARS_RES[$base], $input ) ) { $num = $base !== 10 ? base_convert( $input, $base, 10 ) : $input; $offset += strlen( $token ); return ( strpos( $input, '.' ) !== false ) @@ -188,7 +203,7 @@ class AbuseFilterTokenizer { if ( preg_match( self::ID_SYMBOL_RE, $code, $matches, 0, $offset ) ) { $token = $matches[0]; $offset += strlen( $token ); - $type = in_array( $token, self::$keywords ) + $type = in_array( $token, self::KEYWORDS ) ? AFPToken::TKEYWORD : AFPToken::TID; return new AFPToken( $type, $token, $start ); @@ -206,7 +221,7 @@ class AbuseFilterTokenizer { * @throws AFPException * @throws AFPUserVisibleException */ - protected static function readStringLiteral( $code, &$offset, $start ) { + private static function readStringLiteral( $code, &$offset, $start ) { $type = $code[$offset]; $offset++; $length = strlen( $code ); @@ -223,7 +238,7 @@ class AbuseFilterTokenizer { if ( $addLength ) { $token .= substr( $code, $offset, $addLength ); $offset += $addLength; - } elseif ( $code[$offset] == '\\' ) { + } elseif ( $code[$offset] === '\\' ) { switch ( $code[$offset + 1] ) { case '\\': $token .= '\\'; @@ -244,12 +259,11 @@ class AbuseFilterTokenizer { $chr = substr( $code, $offset + 2, 2 ); if ( preg_match( '/^[0-9A-Fa-f]{2}$/', $chr ) ) { - $chr = base_convert( $chr, 16, 10 ); - $token .= chr( $chr ); + $token .= chr( hexdec( $chr ) ); // \xXX -- 2 done later $offset += 2; } else { - $token .= 'x'; + $token .= '\\x'; } break; default: @@ -260,8 +274,10 @@ class AbuseFilterTokenizer { } else { // Should never happen + // @codeCoverageIgnoreStart $token .= $code[$offset]; $offset++; + // @codeCoverageIgnoreEnd } } throw new AFPUserVisibleException( 'unclosedstring', $offset, [] ); diff --git a/AbuseFilter/includes/special/AbuseFilterSpecialPage.php b/AbuseFilter/includes/special/AbuseFilterSpecialPage.php new file mode 100644 index 00000000..0c1b4171 --- /dev/null +++ b/AbuseFilter/includes/special/AbuseFilterSpecialPage.php @@ -0,0 +1,65 @@ +<?php + +use MediaWiki\MediaWikiServices; + +/** + * Parent class for AbuseFilter special pages. + */ +abstract class AbuseFilterSpecialPage extends SpecialPage { + /** + * Add topbar navigation links + * + * @param string $pageType + */ + protected function addNavigationLinks( $pageType ) { + $user = $this->getUser(); + + $linkDefs = [ + 'home' => 'Special:AbuseFilter', + 'recentchanges' => 'Special:AbuseFilter/history', + 'examine' => 'Special:AbuseFilter/examine', + ]; + + if ( MediaWikiServices::getInstance()->getPermissionManager() + ->userHasRight( $user, 'abusefilter-log' ) + ) { + $linkDefs = array_merge( $linkDefs, [ + 'log' => 'Special:AbuseLog' + ] ); + } + + if ( AbuseFilter::canViewPrivate( $user ) ) { + $linkDefs = array_merge( $linkDefs, [ + 'test' => 'Special:AbuseFilter/test', + 'tools' => 'Special:AbuseFilter/tools' + ] ); + } + + $links = []; + + foreach ( $linkDefs as $name => $page ) { + // Give grep a chance to find the usages: + // abusefilter-topnav-home, abusefilter-topnav-recentchanges, abusefilter-topnav-test, + // abusefilter-topnav-log, abusefilter-topnav-tools, abusefilter-topnav-examine + $msgName = "abusefilter-topnav-$name"; + + $msg = $this->msg( $msgName )->parse(); + $title = Title::newFromText( $page ); + + if ( $name === $pageType ) { + $links[] = Xml::tags( 'strong', null, $msg ); + } else { + $links[] = $this->getLinkRenderer()->makeLink( $title, new HtmlArmor( $msg ) ); + } + } + + $linkStr = $this->msg( 'parentheses' ) + ->rawParams( $this->getLanguage()->pipeList( $links ) ) + ->text(); + $linkStr = $this->msg( 'abusefilter-topnav' )->parse() . " $linkStr"; + + $linkStr = Xml::tags( 'div', [ 'class' => 'mw-abusefilter-navigation' ], $linkStr ); + + $this->getOutput()->setSubtitle( $linkStr ); + } +} diff --git a/AbuseFilter/includes/special/SpecialAbuseFilter.php b/AbuseFilter/includes/special/SpecialAbuseFilter.php index ccd2f8ee..03fc9d6b 100644 --- a/AbuseFilter/includes/special/SpecialAbuseFilter.php +++ b/AbuseFilter/includes/special/SpecialAbuseFilter.php @@ -1,20 +1,38 @@ <?php -class SpecialAbuseFilter extends SpecialPage { - public $mFilter, $mHistoryID; +class SpecialAbuseFilter extends AbuseFilterSpecialPage { + public const PAGE_NAME = 'AbuseFilter'; + /** + * @var int|string|null The current filter + */ + public $mFilter; + /** + * @var int|null The history ID of the current version + */ + public $mHistoryID; + /** + * @inheritDoc + */ public function __construct() { - parent::__construct( 'AbuseFilter', 'abusefilter-view' ); + parent::__construct( self::PAGE_NAME, 'abusefilter-view' ); } /** - * @return bool + * @inheritDoc */ public function doesWrites() { return true; } /** + * @inheritDoc + */ + protected function getGroupName() { + return 'wiki'; + } + + /** * @param string|null $subpage */ public function execute( $subpage ) { @@ -25,13 +43,13 @@ class SpecialAbuseFilter extends SpecialPage { $view = 'AbuseFilterViewList'; $this->setHeaders(); + $this->addHelpLink( 'Extension:AbuseFilter' ); $this->loadParameters( $subpage ); - $out->setPageTitle( $this->msg( 'abusefilter-management' ) ); $this->checkPermissions(); - if ( $request->getVal( 'result' ) == 'success' ) { + if ( $request->getVal( 'result' ) === 'success' ) { $out->setSubtitle( $this->msg( 'abusefilter-edit-done-subtitle' ) ); $changedFilter = intval( $request->getVal( 'changedfilter' ) ); $changeId = intval( $request->getVal( 'changeid' ) ); @@ -58,64 +76,63 @@ class SpecialAbuseFilter extends SpecialPage { } $params = array_values( $params ); - if ( $subpage == 'tools' ) { + if ( $subpage === 'tools' ) { $view = 'AbuseFilterViewTools'; $pageType = 'tools'; $out->addHelpLink( 'Extension:AbuseFilter/Rules format' ); } - if ( count( $params ) == 2 && $params[0] == 'revert' && is_numeric( $params[1] ) ) { + if ( count( $params ) === 2 && $params[0] === 'revert' && is_numeric( $params[1] ) ) { $this->mFilter = $params[1]; $view = 'AbuseFilterViewRevert'; $pageType = 'revert'; } - if ( count( $params ) && $params[0] == 'test' ) { + if ( count( $params ) && $params[0] === 'test' ) { $view = 'AbuseFilterViewTestBatch'; $pageType = 'test'; $out->addHelpLink( 'Extension:AbuseFilter/Rules format' ); } - if ( count( $params ) && $params[0] == 'examine' ) { + if ( count( $params ) && $params[0] === 'examine' ) { $view = 'AbuseFilterViewExamine'; $pageType = 'examine'; $out->addHelpLink( 'Extension:AbuseFilter/Rules format' ); } - if ( !empty( $params[0] ) && ( $params[0] == 'history' || $params[0] == 'log' ) ) { + if ( !empty( $params[0] ) && ( $params[0] === 'history' || $params[0] === 'log' ) ) { $pageType = ''; - if ( count( $params ) == 1 ) { + if ( count( $params ) === 1 ) { $view = 'AbuseFilterViewHistory'; $pageType = 'recentchanges'; - } elseif ( count( $params ) == 2 ) { + } elseif ( count( $params ) === 2 ) { // Second param is a filter ID $view = 'AbuseFilterViewHistory'; $pageType = 'recentchanges'; $this->mFilter = $params[1]; - } elseif ( count( $params ) == 4 && $params[2] == 'item' ) { + } elseif ( count( $params ) === 4 && $params[2] === 'item' ) { $this->mFilter = $params[1]; - $this->mHistoryID = $params[3]; + $this->mHistoryID = (int)$params[3]; $view = 'AbuseFilterViewEdit'; - } elseif ( count( $params ) == 5 && $params[2] == 'diff' ) { + } elseif ( count( $params ) === 5 && $params[2] === 'diff' ) { // Special:AbuseFilter/history/<filter>/diff/<oldid>/<newid> $view = 'AbuseFilterViewDiff'; } } - if ( is_numeric( $subpage ) || $subpage == 'new' ) { + if ( is_numeric( $subpage ) || $subpage === 'new' ) { $this->mFilter = $subpage; $view = 'AbuseFilterViewEdit'; $pageType = 'edit'; } - if ( $subpage == 'import' ) { + if ( $subpage === 'import' ) { $view = 'AbuseFilterViewImport'; $pageType = 'import'; } // Links at the top - AbuseFilter::addNavigationLinks( - $this->getContext(), $pageType, $this->getLinkRenderer() ); + $this->addNavigationLinks( $pageType ); /** @var AbuseFilterView $v */ $v = new $view( $this, $params ); @@ -123,21 +140,12 @@ class SpecialAbuseFilter extends SpecialPage { } /** - * @param string|null $subpage + * @param string|null $filter */ - public function loadParameters( $subpage ) { - $filter = $subpage; - - if ( !is_numeric( $filter ) && $filter != 'new' ) { + public function loadParameters( $filter ) { + if ( !is_numeric( $filter ) && $filter !== 'new' ) { $filter = $this->getRequest()->getIntOrNull( 'wpFilter' ); } $this->mFilter = $filter; } - - /** - * @return string - */ - protected function getGroupName() { - return 'wiki'; - } } diff --git a/AbuseFilter/includes/special/SpecialAbuseLog.php b/AbuseFilter/includes/special/SpecialAbuseLog.php index ab2e2cbc..31d85699 100644 --- a/AbuseFilter/includes/special/SpecialAbuseLog.php +++ b/AbuseFilter/includes/special/SpecialAbuseLog.php @@ -1,50 +1,97 @@ <?php -class SpecialAbuseLog extends SpecialPage { +use MediaWiki\Cache\LinkBatchFactory; +use MediaWiki\Linker\LinkTarget; +use MediaWiki\Logger\LoggerFactory; +use MediaWiki\MediaWikiServices; +use MediaWiki\Permissions\PermissionManager; +use MediaWiki\User\UserIdentity; + +class SpecialAbuseLog extends AbuseFilterSpecialPage { /** - * @var User + * @var User The user whose AbuseLog entries are being searched */ protected $mSearchUser; + /** + * @var string The start time of the search period + */ protected $mSearchPeriodStart; + /** + * @var string The end time of the search period + */ protected $mSearchPeriodEnd; /** - * @var Title + * @var Title The page of which AbuseLog entries are being searched */ protected $mSearchTitle; /** - * @var string + * @var string The action performed by the user */ protected $mSearchAction; /** - * @var string + * @var string The action taken by AbuseFilter */ protected $mSearchActionTaken; + /** + * @var string The wiki name where we're performing the search + */ protected $mSearchWiki; + /** + * @var string|null The filter IDs we're looking for. Either a single one, or a pipe-separated list + */ protected $mSearchFilter; + /** + * @var string The visibility of entries we're interested in + */ protected $mSearchEntries; + /** + * @var string The impact of the user action, i.e. if the change has been saved + */ protected $mSearchImpact; - public function __construct() { + /** @var string The filter group to search, as defined in $wgAbuseFilterValidGroups */ + protected $mSearchGroup; + + /** @var LinkBatchFactory */ + private $linkBatchFactory; + + /** @var PermissionManager */ + private $permissionManager; + + /** + * @param LinkBatchFactory $linkBatchFactory + * @param PermissionManager $permissionManager + */ + public function __construct( LinkBatchFactory $linkBatchFactory, PermissionManager $permissionManager ) { parent::__construct( 'AbuseLog', 'abusefilter-log' ); + $this->linkBatchFactory = $linkBatchFactory; + $this->permissionManager = $permissionManager; } /** - * @return bool + * @inheritDoc */ public function doesWrites() { return true; } /** + * @inheritDoc + */ + protected function getGroupName() { + return 'changes'; + } + + /** * Main routine * * $parameter string is converted into the $args array, which can come in @@ -66,41 +113,29 @@ class SpecialAbuseLog extends SpecialPage { * used as the identifier of the log entry that we want to hide; otherwise, * the abuse logs are shown as a list, with a search form above the list. * - * @param string $parameter URL parameters + * @param string|null $parameter URL parameters */ public function execute( $parameter ) { $out = $this->getOutput(); $request = $this->getRequest(); - AbuseFilter::addNavigationLinks( - $this->getContext(), 'log', $this->getLinkRenderer() ); + $this->addNavigationLinks( 'log' ); $this->setHeaders(); - $this->outputHeader( 'abusefilter-log-summary' ); + $this->addHelpLink( 'Extension:AbuseFilter' ); $this->loadParameters(); - $out->setPageTitle( $this->msg( 'abusefilter-log' ) ); - $out->setRobotPolicy( "noindex,nofollow" ); - $out->setArticleRelated( false ); $out->enableClientCache( false ); $out->addModuleStyles( 'ext.abuseFilter' ); - // Are we allowed? - $errors = $this->getPageTitle()->getUserPermissionsErrors( - 'abusefilter-log', $this->getUser(), true, [ 'ns-specialprotected' ] ); - if ( count( $errors ) ) { - $out->showPermissionsErrorPage( $errors, 'abusefilter-log' ); - - return; - } + $this->checkPermissions(); - $detailsid = $request->getIntOrNull( 'details' ); $hideid = $request->getIntOrNull( 'hide' ); $args = explode( '/', $parameter ); if ( count( $args ) === 2 && $args[0] === 'private' ) { - $this->showPrivateDetails( $args[1] ); + $this->showPrivateDetails( (int)$args[1] ); } elseif ( count( $args ) === 1 && $args[0] !== '' ) { if ( $args[0] === 'private' ) { $out->addWikiMsg( 'abusefilter-invalid-request-noid' ); @@ -133,10 +168,13 @@ class SpecialAbuseLog extends SpecialPage { $this->mSearchPeriodStart = $request->getText( 'wpSearchPeriodStart' ); $this->mSearchPeriodEnd = $request->getText( 'wpSearchPeriodEnd' ); $this->mSearchTitle = $request->getText( 'wpSearchTitle' ); + if ( count( $this->getConfig()->get( 'AbuseFilterValidGroups' ) ) > 1 ) { + $this->mSearchGroup = $request->getText( 'wpSearchGroup' ); + } $this->mSearchFilter = null; $this->mSearchAction = $request->getText( 'wpSearchAction' ); $this->mSearchActionTaken = $request->getText( 'wpSearchActionTaken' ); - if ( self::canSeeDetails() ) { + if ( self::canSeeDetails( $this->getUser() ) ) { $this->mSearchFilter = $request->getText( 'wpSearchFilter' ); } @@ -176,6 +214,7 @@ class SpecialAbuseLog extends SpecialPage { * Builds the search form */ public function searchForm() { + $user = $this->getUser(); $formDescriptor = [ 'SearchUser' => [ 'label-message' => 'abusefilter-log-search-user', @@ -211,29 +250,36 @@ class SpecialAbuseLog extends SpecialPage { ]; $filterableActions = $this->getAllFilterableActions(); $actions = array_combine( $filterableActions, $filterableActions ); - $actions[ $this->msg( 'abusefilter-log-search-action-other' )->text() ] = 'other'; - $actions[ $this->msg( 'abusefilter-log-search-action-any' )->text() ] = 'any'; + ksort( $actions ); + $actions = array_merge( + [ $this->msg( 'abusefilter-log-search-action-any' )->text() => 'any' ], + $actions, + [ $this->msg( 'abusefilter-log-search-action-other' )->text() => 'other' ] + ); $formDescriptor['SearchAction'] = [ 'label-message' => 'abusefilter-log-search-action-label', 'type' => 'select', 'options' => $actions, 'default' => 'any', ]; - $options = [ - $this->msg( 'abusefilter-log-noactions' )->text() => 'noactions', - $this->msg( 'abusefilter-log-search-action-taken-any' )->text() => '', - ]; + $options = []; + $context = $this->getContext(); foreach ( $this->getAllActions() as $action ) { - $key = AbuseFilter::getActionDisplay( $action ); + $key = AbuseFilter::getActionDisplay( $action, $context ); $options[$key] = $action; } ksort( $options ); + $options = array_merge( + [ $this->msg( 'abusefilter-log-search-action-taken-any' )->text() => '' ], + $options, + [ $this->msg( 'abusefilter-log-noactions-filter' )->text() => 'noactions' ] + ); $formDescriptor['SearchActionTaken'] = [ 'label-message' => 'abusefilter-log-search-action-taken-label', 'type' => 'select', 'options' => $options, ]; - if ( self::canSeeHidden() ) { + if ( self::canSeeHidden( $user ) ) { $formDescriptor['SearchEntries'] = [ 'type' => 'select', 'label-message' => 'abusefilter-log-search-entries-label', @@ -244,15 +290,34 @@ class SpecialAbuseLog extends SpecialPage { ], ]; } - if ( self::canSeeDetails() ) { + + $groups = $this->getConfig()->get( 'AbuseFilterValidGroups' ); + if ( count( $groups ) > 1 ) { + $options = array_merge( + [ $this->msg( 'abusefilter-log-search-group-any' )->text() => 0 ], + array_combine( $groups, $groups ) + ); + $formDescriptor['SearchGroup'] = [ + 'label-message' => 'abusefilter-log-search-group', + 'type' => 'select', + 'options' => $options + ]; + } + + if ( self::canSeeDetails( $user ) ) { + $helpmsg = $this->getConfig()->get( 'AbuseFilterIsCentral' ) + ? $this->msg( 'abusefilter-log-search-filter-help-central' )->escaped() + : $this->msg( 'abusefilter-log-search-filter-help' ) + ->params( AbuseFilter::GLOBAL_FILTER_PREFIX )->escaped(); $formDescriptor['SearchFilter'] = [ 'label-message' => 'abusefilter-log-search-filter', 'type' => 'text', 'default' => $this->mSearchFilter, + 'help' => $helpmsg ]; } if ( $this->getConfig()->get( 'AbuseFilterIsCentral' ) ) { - // Add free form input for wiki name. Would be nice to generate + // @todo Add free form input for wiki name. Would be nice to generate // a select with unique names in the db at some point. $formDescriptor['SearchWiki'] = [ 'label-message' => 'abusefilter-log-search-wiki', @@ -265,16 +330,17 @@ class SpecialAbuseLog extends SpecialPage { ->setWrapperLegendMsg( 'abusefilter-log-search' ) ->setSubmitTextMsg( 'abusefilter-log-search-submit' ) ->setMethod( 'get' ) + ->setCollapsibleOptions( true ) ->prepareForm() ->displayForm( false ); } /** - * @param string $id + * @param int $id */ public function showHideForm( $id ) { $output = $this->getOutput(); - if ( !$this->getUser()->isAllowed( 'abusefilter-hide-log' ) ) { + if ( !$this->permissionManager->userHasRight( $this->getUser(), 'abusefilter-hide-log' ) ) { $output->addWikiMsg( 'abusefilter-log-hide-forbidden' ); return; @@ -282,21 +348,20 @@ class SpecialAbuseLog extends SpecialPage { $dbr = wfGetDB( DB_REPLICA ); - $row = $dbr->selectRow( - [ 'abuse_filter_log', 'abuse_filter' ], + $deleted = $dbr->selectField( + 'abuse_filter_log', 'afl_deleted', [ 'afl_id' => $id ], - __METHOD__, - [], - [ 'abuse_filter' => [ 'LEFT JOIN', 'af_id=afl_filter' ] ] + __METHOD__ ); - if ( !$row ) { + if ( $deleted === false ) { + $output->addWikiMsg( 'abusefilter-log-nonexistent' ); return; } $hideReasonsOther = $this->msg( 'revdelete-reasonotherlist' )->text(); - $hideReasons = $this->msg( 'revdelete-reason-dropdown' )->inContentLanguage()->text(); + $hideReasons = $this->msg( 'revdelete-reason-dropdown-suppress' )->inContentLanguage()->text(); $hideReasons = Xml::listDropDownOptions( $hideReasons, [ 'other' => $hideReasonsOther ] ); $formInfo = [ @@ -316,7 +381,7 @@ class SpecialAbuseLog extends SpecialPage { ], 'hidden' => [ 'type' => 'toggle', - 'default' => $row->afl_deleted, + 'default' => $deleted, 'label-message' => 'abusefilter-log-hide-hidden', ], ]; @@ -331,7 +396,7 @@ class SpecialAbuseLog extends SpecialPage { // Show suppress log for this entry $suppressLogPage = new LogPage( 'suppress' ); $output->addHTML( "<h2>" . $suppressLogPage->getName()->escaped() . "</h2>\n" ); - LogEventsList::showLogExtract( $output, 'suppress', $this->getPageTitle( $id ) ); + LogEventsList::showLogExtract( $output, 'suppress', $this->getPageTitle( (string)$id ) ); } /** @@ -375,19 +440,21 @@ class SpecialAbuseLog extends SpecialPage { */ public function showList() { $out = $this->getOutput(); + $user = $this->getUser(); + $this->outputHeader( 'abusefilter-log-summary' ); // Generate conditions list. $conds = []; if ( $this->mSearchUser ) { - $user = User::newFromName( $this->mSearchUser ); + $searchedUser = User::newFromName( $this->mSearchUser ); - if ( !$user ) { + if ( !$searchedUser ) { $conds['afl_user'] = 0; $conds['afl_user_text'] = $this->mSearchUser; } else { - $conds['afl_user'] = $user->getId(); - $conds['afl_user_text'] = $user->getName(); + $conds['afl_user'] = $searchedUser->getId(); + $conds['afl_user_text'] = $searchedUser->getName(); } } @@ -403,24 +470,58 @@ class SpecialAbuseLog extends SpecialPage { } if ( $this->mSearchWiki ) { - if ( $this->mSearchWiki == wfWikiID() ) { + if ( $this->mSearchWiki === WikiMap::getCurrentWikiDbDomain()->getId() ) { $conds['afl_wiki'] = null; } else { $conds['afl_wiki'] = $this->mSearchWiki; } } + $groupFilters = []; + if ( $this->mSearchGroup ) { + $groupFilters = $dbr->selectFieldValues( + 'abuse_filter', + 'af_id', + [ 'af_group' => $this->mSearchGroup ], + __METHOD__ + ); + } + + $searchFilters = []; if ( $this->mSearchFilter ) { - $searchFilters = array_map( 'trim', explode( '|', $this->mSearchFilter ) ); + $rawFilters = array_map( 'trim', explode( '|', $this->mSearchFilter ) ); + // Map of [ [ id, global ], ... ] + $filtersList = []; + $foundInvalid = false; + foreach ( $rawFilters as $filter ) { + try { + $filtersList[] = AbuseFilter::splitGlobalName( $filter ); + } catch ( InvalidArgumentException $e ) { + $foundInvalid = true; + continue; + } + } + + // @phan-suppress-next-line PhanImpossibleCondition + if ( $foundInvalid ) { + $out->addHTML( + Html::rawElement( + 'p', + [], + Html::warningBox( $this->msg( 'abusefilter-log-invalid-filter' )->escaped() ) + ) + ); + } + // if a filter is hidden, users who can't view private filters should // not be able to find log entries generated by it. - if ( !AbuseFilterView::canViewPrivate() - && !$this->getUser()->isAllowed( 'abusefilter-log-private' ) + if ( !AbuseFilter::canViewPrivate( $user ) + && !$this->permissionManager->userHasRight( $user, 'abusefilter-log-private' ) ) { $searchedForPrivate = false; - foreach ( $searchFilters as $index => $filter ) { - if ( AbuseFilter::filterHidden( $filter ) ) { - unset( $searchFilters[$index] ); + foreach ( $filtersList as $index => $filterData ) { + if ( AbuseFilter::filterHidden( ...$filterData ) ) { + unset( $filtersList[$index] ); $searchedForPrivate = true; } } @@ -428,12 +529,28 @@ class SpecialAbuseLog extends SpecialPage { $out->addWikiMsg( 'abusefilter-log-private-not-included' ); } } - if ( empty( $searchFilters ) ) { - $out->addWikiMsg( 'abusefilter-log-noresults' ); + foreach ( $filtersList as $filterData ) { + $searchFilters[] = AbuseFilter::buildGlobalName( ...$filterData ); + } + } + + $searchIDs = null; + if ( $this->mSearchGroup && !$this->mSearchFilter ) { + $searchIDs = $groupFilters; + } elseif ( !$this->mSearchGroup && $this->mSearchFilter ) { + $searchIDs = $searchFilters; + } elseif ( $this->mSearchGroup && $this->mSearchFilter ) { + $searchIDs = array_intersect( $groupFilters, $searchFilters ); + } + + if ( $searchIDs !== null ) { + if ( !count( $searchIDs ) ) { + $out->addWikiMsg( 'abusefilter-log-noresults' ); return; } - $conds['afl_filter'] = $searchFilters; + + $conds['afl_filter'] = $searchIDs; } $searchTitle = Title::newFromText( $this->mSearchTitle ); @@ -442,20 +559,17 @@ class SpecialAbuseLog extends SpecialPage { $conds['afl_title'] = $searchTitle->getDBkey(); } - if ( self::canSeeHidden() ) { - if ( $this->mSearchEntries == '1' ) { + if ( self::canSeeHidden( $user ) ) { + if ( $this->mSearchEntries === '1' ) { $conds['afl_deleted'] = 1; - } elseif ( $this->mSearchEntries == '2' ) { - $conds[] = self::getNotDeletedCond( $dbr ); + } elseif ( $this->mSearchEntries === '2' ) { + $conds['afl_deleted'] = 0; } } if ( in_array( $this->mSearchImpact, [ '1', '2' ] ) ) { - $unsuccessfulActionConds = $dbr->makeList( [ - 'afl_rev_id' => null, - 'afl_log_id' => null, - ], LIST_AND ); - if ( $this->mSearchImpact == '1' ) { + $unsuccessfulActionConds = 'afl_rev_id IS NULL'; + if ( $this->mSearchImpact === '1' ) { $conds[] = "NOT ( $unsuccessfulActionConds )"; } else { $conds[] = $unsuccessfulActionConds; @@ -490,7 +604,12 @@ class SpecialAbuseLog extends SpecialPage { } } - $pager = new AbuseLogPager( $this, $conds ); + $pager = new AbuseLogPager( + $this, + $conds, + $this->linkBatchFactory, + $this->canSeeUndeleteDiffs() + ); $pager->doQuery(); $result = $pager->getResult(); if ( $result && $result->numRows() !== 0 ) { @@ -503,51 +622,65 @@ class SpecialAbuseLog extends SpecialPage { } /** - * @param string $id + * @param string|int $id + * @suppress SecurityCheck-SQLInjection */ public function showDetails( $id ) { $out = $this->getOutput(); + $user = $this->getUser(); - $dbr = wfGetDB( DB_REPLICA ); + $pager = new AbuseLogPager( + $this, + [], + $this->linkBatchFactory, + $this->canSeeUndeleteDiffs() + ); + [ + 'tables' => $tables, + 'fields' => $fields, + 'join_conds' => $join_conds, + ] = $pager->getQueryInfo(); + + $dbr = wfGetDB( DB_REPLICA ); $row = $dbr->selectRow( - [ 'abuse_filter_log', 'abuse_filter' ], - '*', + $tables, + $fields, [ 'afl_id' => $id ], __METHOD__, [], - [ 'abuse_filter' => [ 'LEFT JOIN', 'af_id=afl_filter' ] ] + $join_conds ); + $error = null; if ( !$row ) { - $out->addWikiMsg( 'abusefilter-log-nonexistent' ); - - return; - } - - if ( AbuseFilter::decodeGlobalName( $row->afl_filter ) ) { - $filter_hidden = null; + $error = 'abusefilter-log-nonexistent'; } else { - $filter_hidden = $row->af_hidden; - } - - if ( !self::canSeeDetails( $row->afl_filter, $filter_hidden ) ) { - $out->addWikiMsg( 'abusefilter-log-cannot-see-details' ); + list( $filterID, $global ) = AbuseFilter::splitGlobalName( $row->afl_filter ); + if ( $global ) { + $filter_hidden = null; + } else { + $filter_hidden = $row->af_hidden; + } - return; + if ( !self::canSeeDetails( $user, $filterID, $global, $filter_hidden ) ) { + $error = 'abusefilter-log-cannot-see-details'; + } elseif ( self::isHidden( $row ) === true && !self::canSeeHidden( $user ) ) { + $error = 'abusefilter-log-details-hidden'; + } elseif ( self::isHidden( $row ) === 'implicit' ) { + $revRec = MediaWikiServices::getInstance() + ->getRevisionLookup() + ->getRevisionById( (int)$row->afl_rev_id ); + if ( !AbuseFilter::userCanViewRev( $revRec, $user ) ) { + // The log is visible, but refers to a deleted revision + $error = 'abusefilter-log-details-hidden-implicit'; + } + } } - if ( self::isHidden( $row ) === true && !self::canSeeHidden() ) { - $out->addWikiMsg( 'abusefilter-log-details-hidden' ); - + if ( $error ) { + $out->addWikiMsg( $error ); return; - } elseif ( self::isHidden( $row ) === 'implicit' ) { - $rev = Revision::newFromId( $row->afl_rev_id ); - // The log is visible, but refers to a deleted revision - if ( !$rev->userCan( Revision::SUPPRESSED_ALL, $this->getUser() ) ) { - $out->addWikiMsg( 'abusefilter-log-details-hidden-implicit' ); - return; - } } $output = Xml::element( @@ -564,7 +697,8 @@ class SpecialAbuseLog extends SpecialPage { $out->addJsConfigVars( 'wgAbuseFilterVariables', $vars->dumpAllVars( true ) ); // Diff, if available - if ( $vars && $vars->getVar( 'action' )->toString() == 'edit' ) { + if ( $row->afl_action === 'edit' ) { + $vars->setLogger( LoggerFactory::getInstance( 'AbuseFilter' ) ); $old_wikitext = $vars->getVar( 'old_wikitext' )->toString(); $new_wikitext = $vars->getVar( 'new_wikitext' )->toString(); @@ -592,19 +726,19 @@ class SpecialAbuseLog extends SpecialPage { // Build a table. $output .= AbuseFilter::buildVarDumpTable( $vars, $this->getContext() ); - if ( self::canSeePrivate() ) { + if ( self::canSeePrivateDetails( $user ) ) { $formDescriptor = [ 'Reason' => [ - 'label-message' => 'abusefilter-view-private-reason', + 'label-message' => 'abusefilter-view-privatedetails-reason', 'type' => 'text', 'size' => 45, ], ]; $htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() ); - $htmlForm->setWrapperLegendMsg( 'abusefilter-view-private' ) + $htmlForm->setWrapperLegendMsg( 'abusefilter-view-privatedetails-legend' ) ->setAction( $this->getPageTitle( 'private/' . $id )->getLocalURL() ) - ->setSubmitTextMsg( 'abusefilter-view-private-submit' ) + ->setSubmitTextMsg( 'abusefilter-view-privatedetails-submit' ) ->setMethod( 'post' ) ->prepareForm(); @@ -615,38 +749,54 @@ class SpecialAbuseLog extends SpecialPage { } /** - * @param string $id - * @return void + * Can this user see diffs generated by Special:Undelete? + * @see \SpecialUndelete + * + * @return bool */ - public function showPrivateDetails( $id ) { - $lang = $this->getLanguage(); - $out = $this->getOutput(); - $request = $this->getRequest(); - - $dbr = wfGetDB( DB_REPLICA ); - - $reason = $request->getText( 'wpReason' ); + private function canSeeUndeleteDiffs() : bool { + if ( !$this->permissionManager->userHasRight( $this->getUser(), 'deletedhistory' ) ) { + return false; + } - // Make sure it is a valid request - $token = $request->getVal( 'wpEditToken' ); - if ( !$request->wasPosted() || !$this->getUser()->matchEditToken( $token ) ) { - $out->addHTML( - Xml::tags( - 'p', - null, - Html::errorBox( $this->msg( 'abusefilter-invalid-request' )->params( $id )->parse() ) - ) - ); + return $this->permissionManager->userHasAnyRight( + $this->getUser(), 'deletedtext', 'undelete' ); + } - return; + /** + * Can this user see diffs generated by Special:Undelete for the page? + * @see \SpecialUndelete + * @param LinkTarget $page + * + * @return bool + */ + private function canSeeUndeleteDiffForPage( LinkTarget $page ) : bool { + if ( !$this->canSeeUndeleteDiffs() ) { + return false; } - if ( !$this->checkReason( $reason ) ) { - $out->addWikiMsg( 'abusefilter-noreason' ); - $this->showDetails( $id ); - return; + foreach ( [ 'deletedtext', 'undelete' ] as $action ) { + if ( $this->permissionManager->userCan( + $action, $this->getUser(), $page, PermissionManager::RIGOR_QUICK + ) ) { + return true; + } } + return false; + } + + /** + * Helper function to select a row with private details and some more context + * for an AbuseLog entry. + * + * @param User $user The user who's trying to view the row + * @param int $id The ID of the log entry + * @return Status A status object with the requested row stored in the value property, + * or an error and no row. + */ + public static function getPrivateDetailsRow( User $user, $id ) { + $dbr = wfGetDB( DB_REPLICA ); $row = $dbr->selectRow( [ 'abuse_filter_log', 'abuse_filter' ], [ 'afl_id', 'afl_filter', 'afl_user_text', 'afl_timestamp', 'afl_ip', 'af_id', @@ -657,41 +807,38 @@ class SpecialAbuseLog extends SpecialPage { [ 'abuse_filter' => [ 'LEFT JOIN', 'af_id=afl_filter' ] ] ); + $status = Status::newGood(); if ( !$row ) { - $out->addWikiMsg( 'abusefilter-log-nonexistent' ); - - return; + $status->fatal( 'abusefilter-log-nonexistent' ); + return $status; } - if ( AbuseFilter::decodeGlobalName( $row->afl_filter ) ) { - $filter_hidden = null; + list( $filterID, $global ) = AbuseFilter::splitGlobalName( $row->afl_filter ); + if ( $global ) { + $filterHidden = null; } else { - $filter_hidden = $row->af_hidden; - } - - if ( !self::canSeeDetails( $row->afl_filter, $filter_hidden ) ) { - $out->addWikiMsg( 'abusefilter-log-cannot-see-details' ); - - return; - } - - if ( !self::canSeePrivate() ) { - $out->addWikiMsg( 'abusefilter-log-cannot-see-private-details' ); - - return; + $filterHidden = $row->af_hidden; } - // Log accessing private details - if ( $this->getConfig()->get( 'AbuseFilterPrivateLog' ) ) { - $user = $this->getUser(); - self::addLogEntry( $id, $reason, $user ); + if ( !self::canSeeDetails( $user, $filterID, $global, $filterHidden ) ) { + $status->fatal( 'abusefilter-log-cannot-see-details' ); + return $status; } + $status->setResult( true, $row ); + return $status; + } - // Show private details (IP). + /** + * Builds an HTML table with the private details for a given abuseLog entry. + * + * @param stdClass $row The row, as returned by self::getPrivateDetailsRow() + * @return string The HTML output + */ + protected function buildPrivateDetailsTable( $row ) { $output = Xml::element( 'legend', null, - $this->msg( 'abusefilter-log-details-private' )->text() + $this->msg( 'abusefilter-log-details-privatedetails' )->text() ); $header = @@ -719,7 +866,7 @@ class SpecialAbuseLog extends SpecialPage { Xml::openElement( 'td' ) . $linkRenderer->makeKnownLink( $this->getPageTitle( $row->afl_id ), - $lang->formatNum( $row->afl_id ) + $this->getLanguage()->formatNum( $row->afl_id ) ) . Xml::closeElement( 'td' ) ); @@ -733,7 +880,7 @@ class SpecialAbuseLog extends SpecialPage { ) . Xml::element( 'td', null, - $lang->timeanddate( $row->afl_timestamp, true ) + $this->getLanguage()->timeanddate( $row->afl_timestamp, true ) ) ); @@ -760,7 +907,7 @@ class SpecialAbuseLog extends SpecialPage { Xml::openElement( 'td' ) . $linkRenderer->makeKnownLink( SpecialPage::getTitleFor( 'AbuseFilter', $row->af_id ), - $lang->formatNum( $row->af_id ) + $this->getLanguage()->formatNum( $row->af_id ) ) . Xml::closeElement( 'td' ) ); @@ -781,14 +928,15 @@ class SpecialAbuseLog extends SpecialPage { // IP address if ( $row->afl_ip !== '' ) { if ( ExtensionRegistry::getInstance()->isLoaded( 'CheckUser' ) && - $this->getUser()->isAllowed( 'checkuser' ) ) { - $CULink = ' · ' . $linkRenderer->makeKnownLink( - SpecialPage::getTitleFor( - 'CheckUser', - $row->afl_ip - ), - $this->msg( 'abusefilter-log-details-checkuser' )->text() - ); + $this->permissionManager->userHasRight( $this->getUser(), 'checkuser' ) + ) { + $CULink = ' · ' . $linkRenderer->makeKnownLink( + SpecialPage::getTitleFor( + 'CheckUser', + $row->afl_ip + ), + $this->msg( 'abusefilter-log-details-checkuser' )->text() + ); } else { $CULink = ''; } @@ -822,8 +970,60 @@ class SpecialAbuseLog extends SpecialPage { $output .= Xml::closeElement( 'tbody' ) . Xml::closeElement( 'table' ); $output = Xml::tags( 'fieldset', null, $output ); + return $output; + } - $out->addHTML( $output ); + /** + * @param int $id + * @return void + */ + public function showPrivateDetails( $id ) { + $out = $this->getOutput(); + $user = $this->getUser(); + + if ( !self::canSeePrivateDetails( $user ) ) { + $out->addWikiMsg( 'abusefilter-log-cannot-see-privatedetails' ); + + return; + } + $request = $this->getRequest(); + + // Make sure it is a valid request + $token = $request->getVal( 'wpEditToken' ); + if ( !$request->wasPosted() || !$user->matchEditToken( $token ) ) { + $out->addHTML( + Xml::tags( + 'p', + null, + Html::errorBox( $this->msg( 'abusefilter-invalid-request' )->params( $id )->parse() ) + ) + ); + + return; + } + + $reason = $request->getText( 'wpReason' ); + if ( !self::checkPrivateDetailsAccessReason( $reason ) ) { + $out->addWikiMsg( 'abusefilter-noreason' ); + $this->showDetails( $id ); + return; + } + + $status = self::getPrivateDetailsRow( $user, $id ); + if ( !$status->isGood() ) { + $out->addWikiMsg( $status->getErrors()[0] ); + return; + } + $row = $status->getValue(); + + // Log accessing private details + if ( $this->getConfig()->get( 'AbuseFilterLogPrivateDetailsAccess' ) ) { + self::addPrivateDetailsAccessLogEntry( $id, $reason, $user ); + } + + // Show private details (IP). + $table = $this->buildPrivateDetailsTable( $row ); + $out->addHTML( $table ); } /** @@ -833,8 +1033,9 @@ class SpecialAbuseLog extends SpecialPage { * @param string $reason * @return bool */ - protected function checkReason( $reason ) { - return ( !$this->getConfig()->get( 'AbuseFilterForceSummary' ) || strlen( $reason ) > 0 ); + public static function checkPrivateDetailsAccessReason( $reason ) { + global $wgAbuseFilterPrivateDetailsForceReason; + return ( !$wgAbuseFilterPrivateDetailsForceReason || strlen( $reason ) > 0 ); } /** @@ -843,8 +1044,8 @@ class SpecialAbuseLog extends SpecialPage { * @param User $user The user who accessed the private details * @return void */ - public static function addLogEntry( $logID, $reason, $user ) { - $target = self::getTitleFor( 'AbuseLog', $logID ); + public static function addPrivateDetailsAccessLogEntry( $logID, $reason, User $user ) { + $target = self::getTitleFor( 'AbuseLog', (string)$logID ); $logEntry = new ManualLogEntry( 'abusefilterprivatedetails', 'access' ); $logEntry->setPerformer( $user ); @@ -858,49 +1059,50 @@ class SpecialAbuseLog extends SpecialPage { } /** - * @param string|null $filter_id - * @param bool|int|null $filter_hidden + * @param User $user + * @param int|null $id The ID of the filter + * @param bool|int|null $global Whether the filter is global + * @param bool|int|null $hidden Whether the filter is hidden * @return bool */ - public static function canSeeDetails( $filter_id = null, $filter_hidden = null ) { - global $wgUser; - - if ( $filter_id !== null ) { - if ( $filter_hidden === null ) { - $filter_hidden = AbuseFilter::filterHidden( $filter_id ); + public static function canSeeDetails( User $user, $id = null, $global = false, $hidden = null ) { + $pm = MediaWikiServices::getInstance()->getPermissionManager(); + if ( $id !== null ) { + if ( $hidden === null ) { + $hidden = AbuseFilter::filterHidden( $id, $global ); } - if ( $filter_hidden ) { - return $wgUser->isAllowed( 'abusefilter-log-detail' ) && ( - AbuseFilterView::canViewPrivate() || $wgUser->isAllowed( 'abusefilter-log-private' ) - ); + if ( $hidden ) { + return $pm->userHasRight( $user, 'abusefilter-log-detail' ) + && ( AbuseFilter::canViewPrivate( $user ) || + $pm->userHasRight( $user, 'abusefilter-log-private' ) ); } } - return $wgUser->isAllowed( 'abusefilter-log-detail' ); + return $pm->userHasRight( $user, 'abusefilter-log-detail' ); } /** + * @param UserIdentity $user * @return bool */ - public static function canSeePrivate() { - global $wgUser; - - return $wgUser->isAllowed( 'abusefilter-private' ); + public static function canSeePrivateDetails( UserIdentity $user ) { + return MediaWikiServices::getInstance()->getPermissionManager() + ->userHasRight( $user, 'abusefilter-privatedetails' ); } /** + * @param User $user * @return bool */ - public static function canSeeHidden() { - global $wgUser; - - return $wgUser->isAllowed( 'abusefilter-hidden-log' ); + public static function canSeeHidden( User $user ) { + return MediaWikiServices::getInstance()->getPermissionManager() + ->userHasRight( $user, 'abusefilter-hidden-log' ); } /** * @param stdClass $row * @param bool $isListItem - * @return String + * @return string */ public function formatRow( $row, $isListItem = true ) { $user = $this->getUser(); @@ -913,20 +1115,42 @@ class SpecialAbuseLog extends SpecialPage { $diffLink = false; $isHidden = self::isHidden( $row ); - if ( !self::canSeeHidden() && $isHidden === true ) { + // @todo T224203 Try to show the details if the revision is deleted but the AbuseLog entry + // is not. However, watch out to avoid showing too much stuff. + if ( !self::canSeeHidden( $user ) && $isHidden ) { return ''; } $linkRenderer = $this->getLinkRenderer(); if ( !$row->afl_wiki ) { - $pageLink = $linkRenderer->makeLink( $title ); - if ( $row->afl_rev_id && $title->exists() ) { + $pageLink = $linkRenderer->makeLink( + $title, + null, + [], + [ 'redirect' => 'no' ] + ); + if ( $row->rev_id ) { $diffLink = $linkRenderer->makeKnownLink( $title, new HtmlArmor( $this->msg( 'abusefilter-log-diff' )->parse() ), [], - [ 'diff' => 'prev', 'oldid' => $row->afl_rev_id ] ); + [ 'diff' => 'prev', 'oldid' => $row->rev_id ] + ); + } elseif ( + isset( $row->ar_timestamp ) && $row->ar_timestamp + && $this->canSeeUndeleteDiffForPage( $title ) + ) { + $diffLink = $linkRenderer->makeKnownLink( + SpecialPage::getTitleFor( 'Undelete' ), + new HtmlArmor( $this->msg( 'abusefilter-log-diff' )->parse() ), + [], + [ + 'diff' => 'prev', + 'target' => $title->getPrefixedText(), + 'timestamp' => $row->ar_timestamp, + ] + ); } } else { $pageLink = WikiMap::makeForeignLink( $row->afl_wiki, $row->afl_title ); @@ -937,7 +1161,7 @@ class SpecialAbuseLog extends SpecialPage { [ 'diff' => 'prev', 'oldid' => $row->afl_rev_id ] ); $diffLink = Linker::makeExternalLink( $diffUrl, - $this->msg( 'abusefilter-log-diff' )->parse() ); + $this->msg( 'abusefilter-log-diff' )->text() ); } } @@ -949,27 +1173,28 @@ class SpecialAbuseLog extends SpecialPage { $userLink .= ' (' . WikiMap::getWikiName( $row->afl_wiki ) . ')'; } - $timestamp = $lang->timeanddate( $row->afl_timestamp, true ); + $timestamp = htmlspecialchars( $lang->timeanddate( $row->afl_timestamp, true ) ); - $actions_taken = $row->afl_actions; - if ( !strlen( trim( $actions_taken ) ) ) { + $actions_takenRaw = $row->afl_actions; + if ( !strlen( trim( $actions_takenRaw ) ) ) { $actions_taken = $this->msg( 'abusefilter-log-noactions' )->escaped(); } else { - $actions = explode( ',', $actions_taken ); + $actions = explode( ',', $actions_takenRaw ); $displayActions = []; + $context = $this->getContext(); foreach ( $actions as $action ) { - $displayActions[] = AbuseFilter::getActionDisplay( $action ); + $displayActions[] = AbuseFilter::getActionDisplay( $action, $context ); } $actions_taken = $lang->commaList( $displayActions ); } - $globalIndex = AbuseFilter::decodeGlobalName( $row->afl_filter ); + list( $filterID, $global ) = AbuseFilter::splitGlobalName( $row->afl_filter ); - if ( $globalIndex ) { + if ( $global ) { // Pull global filter description $escaped_comments = Sanitizer::escapeHtmlAllowEntities( - AbuseFilter::getGlobalFilterDescription( $globalIndex ) ); + AbuseFilter::getGlobalFilterDescription( $filterID ) ); $filter_hidden = null; } else { $escaped_comments = Sanitizer::escapeHtmlAllowEntities( @@ -977,7 +1202,7 @@ class SpecialAbuseLog extends SpecialPage { $filter_hidden = $row->af_hidden; } - if ( self::canSeeDetails( $row->afl_filter, $filter_hidden ) ) { + if ( self::canSeeDetails( $user, $filterID, $global, $filter_hidden ) ) { if ( $isListItem ) { $detailsLink = $linkRenderer->makeKnownLink( $this->getPageTitle( $row->afl_id ), @@ -997,7 +1222,7 @@ class SpecialAbuseLog extends SpecialPage { $actionLinks[] = $diffLink; } - if ( $user->isAllowed( 'abusefilter-hide-log' ) ) { + if ( $this->permissionManager->userHasRight( $user, 'abusefilter-hide-log' ) ) { $hideLink = $linkRenderer->makeKnownLink( $this->getPageTitle(), $this->msg( 'abusefilter-log-hidelink' )->text(), @@ -1008,25 +1233,25 @@ class SpecialAbuseLog extends SpecialPage { $actionLinks[] = $hideLink; } - if ( $globalIndex ) { + if ( $global ) { $globalURL = WikiMap::getForeignURL( $this->getConfig()->get( 'AbuseFilterCentralDB' ), - 'Special:AbuseFilter/' . $globalIndex + 'Special:AbuseFilter/' . $filterID ); $linkText = $this->msg( 'abusefilter-log-detailedentry-global' ) - ->numParams( $globalIndex )->escaped(); + ->numParams( $filterID )->text(); $filterLink = Linker::makeExternalLink( $globalURL, $linkText ); } else { - $title = SpecialPage::getTitleFor( 'AbuseFilter', $row->afl_filter ); + $title = SpecialPage::getTitleFor( 'AbuseFilter', $filterID ); $linkText = $this->msg( 'abusefilter-log-detailedentry-local' ) - ->numParams( $row->afl_filter )->text(); + ->numParams( $filterID )->text(); $filterLink = $linkRenderer->makeKnownLink( $title, $linkText ); } $description = $this->msg( 'abusefilter-log-detailedentry-meta' )->rawParams( $timestamp, $userLink, $filterLink, - $row->afl_action, + htmlspecialchars( $row->afl_action ), $pageLink, $actions_taken, $escaped_comments, @@ -1041,7 +1266,7 @@ class SpecialAbuseLog extends SpecialPage { $description = $this->msg( $msg )->rawParams( $timestamp, $userLink, - $row->afl_action, + htmlspecialchars( $row->afl_action ), $pageLink, $actions_taken, $escaped_comments, @@ -1050,19 +1275,18 @@ class SpecialAbuseLog extends SpecialPage { )->params( $row->afl_user_text )->parse(); } + $attribs = null; if ( $isHidden === true ) { - $description .= ' ' . - $this->msg( 'abusefilter-log-hidden' )->parse(); - $class = 'afl-hidden'; + $attribs = [ 'class' => 'mw-abusefilter-log-hidden-entry' ]; } elseif ( $isHidden === 'implicit' ) { $description .= ' ' . $this->msg( 'abusefilter-log-hidden-implicit' )->parse(); } if ( $isListItem ) { - return Xml::tags( 'li', isset( $class ) ? [ 'class' => $class ] : null, $description ); + return Xml::tags( 'li', $attribs, $description ); } else { - return Xml::tags( 'span', isset( $class ) ? [ 'class' => $class ] : null, $description ); + return Xml::tags( 'span', $attribs, $description ); } } @@ -1083,21 +1307,6 @@ class SpecialAbuseLog extends SpecialPage { } /** - * @param \Wikimedia\Rdbms\IDatabase $db - * @return string - */ - public static function getNotDeletedCond( $db ) { - $deletedZeroCond = $db->makeList( - [ 'afl_deleted' => 0 ], LIST_AND ); - $deletedNullCond = $db->makeList( - [ 'afl_deleted' => null ], LIST_AND ); - $notDeletedCond = $db->makeList( - [ $deletedZeroCond, $deletedNullCond ], LIST_OR ); - - return $notDeletedCond; - } - - /** * Given a log entry row, decides whether or not it can be viewed by the public. * * @param stdClass $row The abuse_filter_log row object. @@ -1112,19 +1321,14 @@ class SpecialAbuseLog extends SpecialPage { return true; } if ( $row->afl_rev_id ) { - $revision = Revision::newFromId( $row->afl_rev_id ); - if ( $revision && $revision->getVisibility() != 0 ) { + $revision = MediaWikiServices::getInstance() + ->getRevisionLookup() + ->getRevisionById( $row->afl_rev_id ); + if ( $revision && $revision->getVisibility() !== 0 ) { return 'implicit'; } } return false; } - - /** - * @return string - */ - protected function getGroupName() { - return 'changes'; - } } diff --git a/AbuseFilter/maintenance/addMissingLoggingEntries.php b/AbuseFilter/maintenance/addMissingLoggingEntries.php index 3a4d8658..17a1b77d 100644 --- a/AbuseFilter/maintenance/addMissingLoggingEntries.php +++ b/AbuseFilter/maintenance/addMissingLoggingEntries.php @@ -7,34 +7,56 @@ if ( getenv( 'MW_INSTALL_PATH' ) ) { } require_once "$IP/maintenance/Maintenance.php"; +use MediaWiki\MediaWikiServices; + /** - * Adds rows missing per https://bugzilla.wikimedia.org/show_bug.cgi?id=52919 + * Adds rows missing per T54919 + * @codeCoverageIgnore + * No need to cover: old, single-use script. */ -class AddMissingLoggingEntries extends Maintenance { +class AddMissingLoggingEntries extends LoggedUpdateMaintenance { public function __construct() { parent::__construct(); + $this->addDescription( 'Add missing logging entries for abusefilter-modify T54919' ); + $this->addOption( 'dry-run', 'Perform a dry run' ); + $this->addOption( 'verbose', 'Print a list of affected afh_id' ); $this->requireExtension( 'Abuse Filter' ); } /** - * @see Maintenance::execute + * @inheritDoc + */ + public function getUpdateKey() { + return __CLASS__; + } + + /** + * @inheritDoc */ - public function execute() { + public function doDBUpdates() { + $dryRun = $this->hasOption( 'dry-run' ); $logParams = []; $afhRows = []; + $db = wfGetDB( DB_REPLICA, 'vslow' ); + $logParamsConcat = $db->buildConcat( [ 'afh_id', $db->addQuotes( "\n" ) ] ); + $legacyParamsLike = $db->buildLike( $logParamsConcat, $db->anyString() ); + // Non-legacy entries are a serialized array with 'newId' and 'historyId' keys + $newLogParamsLike = $db->buildLike( $db->anyString(), 'historyId', $db->anyString() ); // Find all entries in abuse_filter_history without logging entry of same timestamp - $afhResult = wfGetDB( DB_REPLICA, 'vslow' )->select( + $afhResult = $db->select( [ 'abuse_filter_history', 'logging' ], [ 'afh_id', 'afh_filter', 'afh_timestamp', 'afh_user', 'afh_deleted', 'afh_user_text' ], - [ 'log_id IS NULL' ], + [ + 'log_id IS NULL', + "NOT log_params $newLogParamsLike" + ], __METHOD__, [], [ 'logging' => [ 'LEFT JOIN', - 'afh_timestamp = log_timestamp AND ' . - 'SUBSTRING_INDEX(log_params, \'\n\', 1) = afh_id AND log_type = \'abusefilter\'' + "afh_timestamp = log_timestamp AND log_params $legacyParamsLike AND log_type = 'abusefilter'" ] ] ); @@ -47,7 +69,8 @@ class AddMissingLoggingEntries extends Maintenance { } if ( !count( $afhRows ) ) { - $this->error( "Nothing to do.", 1 ); + $this->output( "Nothing to do.\n" ); + return !$dryRun; } $logResult = wfGetDB( DB_REPLICA )->select( @@ -58,46 +81,62 @@ class AddMissingLoggingEntries extends Maintenance { ); foreach ( $logResult as $row ) { - // id . '\n' . filter - $params = explode( "\n", $row->log_params ); - // id - $afhId = $params[0]; + // id . "\n" . filter + $afhId = explode( "\n", $row->log_params, 2 )[0]; // Forget this row had any issues - it just has a different timestamp in the log unset( $afhRows[$afhId] ); } if ( !count( $afhRows ) ) { - $this->error( "Nothing to do.", 1 ); + $this->output( "Nothing to do.\n" ); + return !$dryRun; + } + + if ( $dryRun ) { + $msg = count( $afhRows ) . " rows to insert."; + if ( $this->hasOption( 'verbose' ) ) { + $msg .= " Affected IDs (afh_id):\n" . implode( ', ', array_keys( $afhRows ) ); + } + $this->output( "$msg\n" ); + return false; } $dbw = wfGetDB( DB_MASTER ); + $factory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory(); $count = 0; foreach ( $afhRows as $row ) { - if ( $count % 100 == 0 ) { - wfWaitForSlaves(); + if ( $count % 100 === 0 ) { + $factory->waitForReplication(); } $user = User::newFromAnyId( $row->afh_user, $row->afh_user_text, null ); - $dbw->insert( - 'logging', - [ - 'log_type' => 'abusefilter', - 'log_action' => 'modify', - 'log_timestamp' => $row->afh_timestamp, - 'log_namespace' => -1, - 'log_title' => SpecialPageFactory::getLocalNameFor( 'AbuseFilter' ) . '/' . $row->afh_filter, - 'log_params' => $row->afh_id . '\n' . $row->afh_filter, - 'log_deleted' => $row->afh_deleted, - ] + CommentStore::getStore()->insert( $dbw, 'log_comment', '' ) - + ActorMigration::newMigration()->getInsertValues( $dbw, 'log_user', $user ), - __METHOD__ + + if ( $user === null ) { + // This isn't supposed to happen. + continue; + } + + // This copies the code in AbuseFilter::doSaveFilter + $logEntry = new ManualLogEntry( 'abusefilter', 'modify' ); + $logEntry->setPerformer( $user ); + $logEntry->setTarget( + SpecialPage::getTitleFor( SpecialAbuseFilter::PAGE_NAME, $row->afh_filter ) ); + // Use the new format! + $logEntry->setParameters( [ + 'historyId' => $row->afh_id, + 'newId' => $row->afh_filter + ] ); + $logEntry->setTimestamp( $row->afh_timestamp ); + $logEntry->insert( $dbw ); + $count++; } - $this->output( "Inserted " . $count . " rows.\n" ); + $this->output( "Inserted $count rows.\n" ); + return true; } } -$maintClass = 'AddMissingLoggingEntries'; +$maintClass = AddMissingLoggingEntries::class; require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/AbuseFilter/maintenance/fixOldLogEntries.php b/AbuseFilter/maintenance/fixOldLogEntries.php new file mode 100644 index 00000000..0c10818e --- /dev/null +++ b/AbuseFilter/maintenance/fixOldLogEntries.php @@ -0,0 +1,288 @@ +<?php + +if ( getenv( 'MW_INSTALL_PATH' ) ) { + $IP = getenv( 'MW_INSTALL_PATH' ); +} else { + $IP = __DIR__ . '/../../..'; +} +require_once "$IP/maintenance/Maintenance.php"; +/** + * Fix old log entries with log_type = 'abusefilter' where log_params are imploded with '\n' + * instead of "\n" (using single quotes), which causes a broken display. + * This was caused by the addMissingLoggingEntries script creating broken entries, see T208931 + * and T228655. + * It also fixes a problem which caused addMissingLoggingEntries to insert duplicate rows foreach + * non-legacy entries + * + * @codeCoverageIgnore + * No need to cover: old, single-use script. + */ +class FixOldLogEntries extends LoggedUpdateMaintenance { + /** @var bool */ + private $dryRun; + + /** @var int Amount of rows in the logging table */ + private $loggingRowsCount; + + /** + * @inheritDoc + */ + public function __construct() { + parent::__construct(); + $this->addDescription( 'Fix old rows in logging which hold broken log_params' ); + + $this->addOption( 'verbose', 'Print some more debug info' ); + $this->addOption( 'dry-run', 'Perform a dry run' ); + $this->requireExtension( 'Abuse Filter' ); + $this->setBatchSize( 500 ); + } + + /** + * @inheritDoc + */ + public function getUpdateKey() { + return __CLASS__; + } + + /** + * This method will delete duplicated logging rows created by addMissingLoggingEntries. This + * happened because the script couldn't recognize non-legacy entries, and considered them to be + * absent if the script was ran after the format update. See T228655#5360754 and T228655#5408193 + * + * @return int[] The IDs of the affected rows + */ + private function deleteDuplicatedRows() { + $dbr = wfGetDB( DB_REPLICA, 'vslow' ); + $dbw = wfGetDB( DB_MASTER ); + $newFormatLike = $dbr->buildLike( $dbr->anyString(), 'historyId', $dbr->anyString() ); + $batchSize = $this->getBatchSize(); + $prevID = 0; + $curID = $batchSize; + $ret = []; + + // Select all non-legacy entries + do { + $res = $dbr->selectFieldValues( + 'logging', + 'log_params', + [ + 'log_type' => 'abusefilter', + "log_params $newFormatLike", + "log_id > $prevID", + "log_id <= $curID", + ], + __METHOD__ + ); + $prevID = $curID; + $curID += $batchSize; + + if ( !$res ) { + continue; + } + + $legacyParams = []; + foreach ( $res as $logParams ) { + $params = unserialize( $logParams ); + if ( $params === false ) { + // Sanity check + $this->fatalError( __METHOD__ . ": Cannot unserialize $logParams" ); + } + // The script always inserted duplicates with the wrong '\n' + $legacyParams[] = $params['historyId'] . '\n' . $params['newId']; + } + + // Save the IDs for later. Note: it is guaranteed that we'll get all and only the entries + // that we want, because they contain a reference to afh_id, which is unique. + $deleteIDs = $dbr->selectFieldValues( + 'logging', + 'log_id', + [ + 'log_type' => 'abusefilter', + 'log_params' => $legacyParams + ], + __METHOD__ + ); + $ret = array_merge( $ret, $deleteIDs ); + + if ( !$this->dryRun && $deleteIDs ) { + // Note that we delete entries with legacy format, which are the ones erroneously inserted + // by the script. + $dbw->delete( + 'logging', + [ 'log_id' => $deleteIDs ], + __METHOD__ + ); + } + } while ( $prevID <= $this->loggingRowsCount ); + + return $ret; + } + + /** + * Change single-quote newlines to double-quotes newlines + * + * @param int[] $deleted log_id's that deleteDuplicatedRows would delete/has deleted. + * This is used in dry-run to avoid reporting them twice. + * @return int[] Affected log_id's + */ + private function changeNewlineType( array $deleted ) { + $dbr = wfGetDB( DB_REPLICA, 'vslow' ); + $dbw = wfGetDB( DB_MASTER ); + $batchSize = $this->getBatchSize(); + $prevID = 1; + $curID = $batchSize; + $ret = []; + + $likeClause = $dbr->buildLike( + $dbr->anyString(), + '\n', + $dbr->anyString() + ); + $replaceClause = $dbw->strreplace( + 'log_params', + $dbw->addQuotes( '\n' ), + $dbw->addQuotes( "\n" ) + ); + // Don't pass an empty array to makeList + $extraConds = $this->dryRun && $deleted ? + [ 'log_id NOT IN (' . $dbr->makeList( $deleted ) . ')' ] : + []; + do { + $ids = $dbr->selectFieldValues( + 'logging', + 'log_id', + array_merge( + [ + 'log_type' => 'abusefilter', + 'log_params ' . $likeClause, + "log_id >= $prevID", + "log_id <= $curID", + ], + $extraConds + ), + __METHOD__ + ); + $prevID = $curID + 1; + $curID += $batchSize; + + if ( !$this->dryRun && $ids ) { + // Keep the entries legacy + $dbw->update( + 'logging', + [ 'log_params = ' . $replaceClause ], + [ 'log_id' => $ids ], + __METHOD__ + ); + } + $ret = array_merge( $ret, $ids ); + } while ( $prevID <= $this->loggingRowsCount ); + return $ret; + } + + /** + * Fix other minor errors caused by addMissingLoggingEntries, and align the values to the + * ones inserted by the actual code. Namely: + * - Set log_page to 0 instead of NULL + * - Don't set log_deleted based on afh_deleted (note: this will miss any log entry created + * by addMissingLoggingEntries and manually deleted afterwards. However, there shouldn't + * be any reason to delete these entries) + * + * @param int[] $deleted Same as self::changeNewlineType + * @return int[] + */ + private function updateLoggingFields( array $deleted ) { + $dbr = wfGetDB( DB_REPLICA, 'vslow' ); + $dbw = wfGetDB( DB_MASTER ); + $batchSize = $this->getBatchSize(); + $prevID = 1; + $curID = $batchSize; + $ret = []; + + // Don't pass an empty array to makeList + $extraConds = $this->dryRun && $deleted ? + [ 'log_id NOT IN (' . $dbr->makeList( $deleted ) . ')' ] : + []; + do { + // 'log_page IS NULL' is guaranteed to return all and only the entries created by the script + $legacyIDs = $dbr->selectFieldValues( + 'logging', + 'log_id', + array_merge( + [ + 'log_type' => 'abusefilter', + 'log_page IS NULL', + "log_id >= $prevID", + "log_id <= $curID", + ], + $extraConds + ), + __METHOD__ + ); + $prevID = $curID + 1; + $curID += $batchSize; + + if ( !$this->dryRun && $legacyIDs ) { + $dbw->update( + 'logging', + [ + 'log_page' => 0, + 'log_deleted' => 0 + ], + [ 'log_id' => $legacyIDs ], + __METHOD__ + ); + } + $ret = array_merge( $ret, $legacyIDs ); + } while ( $prevID <= $this->loggingRowsCount ); + return $ret; + } + + /** + * @inheritDoc + */ + public function doDBUpdates() { + $this->dryRun = $this->hasOption( 'dry-run' ); + $this->loggingRowsCount = (int)wfGetDB( DB_REPLICA )->selectField( + 'logging', + 'MAX(log_id)', + [], + __METHOD__ + ); + + $deleted = $this->deleteDuplicatedRows(); + + $deleteVerb = $this->dryRun ? 'would delete' : 'deleted'; + $numDel = count( $deleted ); + $this->output( + __CLASS__ . " $deleteVerb $numDel rows.\n" + ); + if ( $deleted && $this->hasOption( 'verbose' ) ) { + $this->output( 'The affected log_id\'s are: ' . implode( ', ', $deleted ) . "\n" ); + } + + $updatedNewLines = $this->changeNewlineType( $deleted ); + $updatedFields = $this->updateLoggingFields( $deleted ); + $updateVerb = $this->dryRun ? 'would update' : 'updated'; + + $numNewLine = count( $updatedNewLines ); + $this->output( + __CLASS__ . " $updateVerb newlines for $numNewLine rows.\n" + ); + if ( $updatedNewLines && $this->hasOption( 'verbose' ) ) { + $this->output( 'The affected log_id\'s are: ' . implode( ', ', $updatedNewLines ) . "\n" ); + } + + $numFields = count( $updatedFields ); + $this->output( + __CLASS__ . " $updateVerb fields for $numFields rows.\n" + ); + if ( $updatedFields && $this->hasOption( 'verbose' ) ) { + $this->output( 'The affected log_id\'s are: ' . implode( ', ', $updatedFields ) . "\n" ); + } + + return !$this->dryRun; + } +} + +$maintClass = 'FixOldLogEntries'; +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/AbuseFilter/maintenance/normalizeThrottleParameters.php b/AbuseFilter/maintenance/normalizeThrottleParameters.php index d4595c7f..8fde5037 100644 --- a/AbuseFilter/maintenance/normalizeThrottleParameters.php +++ b/AbuseFilter/maintenance/normalizeThrottleParameters.php @@ -11,6 +11,10 @@ * highly unlikely to happen anyway. (T203585) * - If throttle groups are empty (or only contain unknown keywords), ask users to fix every case * by hand. (T203584) + * - Change some edge cases of throttle parameters saved in abuse_filter_history (T215787): + * - parameters = null ==> parameters = [ filterID, "0,0", 'none' ] + * - at least a number missing from parameters[1] ==> insert 0 in place of the missing param + * - empty groups ==> 'none' (special case, uses the message abusefilter-throttle-none) * * @ingroup Maintenance */ @@ -23,12 +27,14 @@ require_once "$IP/maintenance/Maintenance.php"; /** * Normalizes throttle parameters, see T203587 + * @codeCoverageIgnore + * No need to cover: old, single-use script. */ class NormalizeThrottleParameters extends LoggedUpdateMaintenance { public function __construct() { parent::__construct(); - $this->mDescription = 'Normalize AbuseFilter throttle parameters - T203587'; + $this->addDescription( 'Normalize AbuseFilter throttle parameters - T203587' ); $this->addOption( 'dry-run', 'Perform a dry run' ); $this->requireExtension( 'Abuse Filter' ); } @@ -41,7 +47,7 @@ class NormalizeThrottleParameters extends LoggedUpdateMaintenance { return __CLASS__; } - /** @var \Wikimedia\Rdbms\IDatabase $db The master database */ + /** @var \Wikimedia\Rdbms\Database $dbw The master database */ private $dbw; /** @@ -133,12 +139,12 @@ class NormalizeThrottleParameters extends LoggedUpdateMaintenance { } /** - * @see Maintenance::doDBUpdates - * @return bool + * Main logic of parameters normalization + * + * @return int Amount of normalized rows */ - public function doDBUpdates() { + protected function normalizeParameters() { $user = AbuseFilter::getFilterUser(); - $this->dbw = wfGetDB( DB_MASTER ); $dryRun = $this->hasOption( 'dry-run' ); // IDs of filters with invalid rate (count or period) @@ -152,8 +158,6 @@ class NormalizeThrottleParameters extends LoggedUpdateMaintenance { // holds an empty string and (unserialize(afh_actions))['throttle'] is null. $totallyEmpty = []; - $this->beginTransaction( $this->dbw, __METHOD__ ); - // Only select throttle actions $actionRows = $this->dbw->select( 'abuse_filter_action', @@ -320,8 +324,7 @@ class NormalizeThrottleParameters extends LoggedUpdateMaintenance { $touchedIDs = array_merge( $changeActionIDs, $deleteActionIDs ); if ( count( $touchedIDs ) === 0 ) { $this->output( "No throttle parameters to normalize.\n" ); - $this->commitTransaction( $this->dbw, __METHOD__ ); - return !$dryRun; + return 0; } // Create new history rows for every changed filter @@ -332,13 +335,16 @@ class NormalizeThrottleParameters extends LoggedUpdateMaintenance { $histRow = $this->dbw->selectRow( 'abuse_filter_history', [ + // All columns in the table, aside from afh_id that we don't need, and the + // ones where we're going to put something new, plus afh_actions. 'afh_filter', 'afh_pattern', 'afh_comments', 'afh_flags', 'afh_public_comments', 'afh_deleted', - 'afh_group' + 'afh_group', + 'afh_actions' ], [ 'afh_filter' => $filter ], __METHOD__, @@ -396,16 +402,100 @@ class NormalizeThrottleParameters extends LoggedUpdateMaintenance { ); } } + return $affectedActionRows + $historyCount; + } + + /** + * Beautify empty/missing/corrupted parameters in abuse_filter_history + * + * @return int Amount of beautified rows + */ + protected function beautifyHistory() { + $dryRun = $this->hasOption( 'dry-run' ); + + // We need any row containing throttle, but there's no + // need to lock as these rows aren't changed by the actual code. + $likeClause = $this->dbw->buildLike( + $this->dbw->anyString(), + 'throttle', + $this->dbw->anyString() + ); + $histRows = $this->dbw->select( + 'abuse_filter_history', + [ 'afh_id', 'afh_actions', 'afh_filter' ], + [ 'afh_actions ' . $likeClause ], + __METHOD__ + ); + + $beautyIDs = []; + foreach ( $histRows as $row ) { + $acts = unserialize( $row->afh_actions ); + if ( !array_key_exists( 'throttle', $acts ) ) { + // The LIKE clause is very raw, so this could happen + continue; + } + + if ( $acts['throttle'] === null ) { + // Corrupted row, rebuild it (T215787) + $acts['throttle'] = [ $row->afh_filter, '0,0', 'none' ]; + } elseif ( $this->checkThrottleRate( $acts['throttle'][1] ) !== null ) { + // Missing count, make it explicitly 0 + $acts['throttle'][1] = preg_replace( '/^,/', '0,', $acts['throttle'][1] ); + // Missing period, make it explicitly 0 + $acts['throttle'][1] = preg_replace( '/,$/', ',0', $acts['throttle'][1] ); + } elseif ( count( $acts['throttle'] ) === 2 ) { + // Missing groups, make them explicitly "none" (special group) + $acts['throttle'][] = 'none'; + } else { + // Everything's fine! + continue; + } + + $beautyIDs[] = $row->afh_id; + if ( !$dryRun ) { + $this->dbw->update( + 'abuse_filter_history', + [ 'afh_actions' => serialize( $acts ) ], + [ 'afh_id' => $row->afh_id ], + __METHOD__ + ); + } + } + + $changed = count( $beautyIDs ); + if ( $changed ) { + $verb = $dryRun ? 'would beautify' : 'beautified'; + $this->output( + "normalizeThrottleParameter $verb $changed rows in abuse_filter_history" . + " for the following history IDs: " . implode( ', ', $beautyIDs ) . "\n" + ); + } + return $changed; + } + + /** + * @inheritDoc + */ + public function doDBUpdates() { + $dryRun = $this->hasOption( 'dry-run' ); + $this->dbw = wfGetDB( DB_MASTER ); + $this->beginTransaction( $this->dbw, __METHOD__ ); + + $normalized = $this->normalizeParameters(); + $beautified = $this->beautifyHistory(); $this->commitTransaction( $this->dbw, __METHOD__ ); - $changed = $affectedActionRows + $historyCount; + + $changed = $normalized + $beautified; + $resultMsg = $dryRun ? "Throttle parameter normalization would change a total of $changed rows.\n" : "Throttle parameters successfully normalized. Changed $changed rows.\n"; $this->output( $resultMsg ); + return !$dryRun; } } -$maintClass = 'NormalizeThrottleParameters'; +$maintClass = NormalizeThrottleParameters::class; require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/AbuseFilter/maintenance/purgeOldLogIPData.php b/AbuseFilter/maintenance/purgeOldLogIPData.php index 10f000fe..8e8e4930 100644 --- a/AbuseFilter/maintenance/purgeOldLogIPData.php +++ b/AbuseFilter/maintenance/purgeOldLogIPData.php @@ -7,10 +7,12 @@ if ( getenv( 'MW_INSTALL_PATH' ) ) { } require_once "$IP/maintenance/Maintenance.php"; +use MediaWiki\MediaWikiServices; + class PurgeOldLogIPData extends Maintenance { public function __construct() { parent::__construct(); - $this->mDescription = 'Purge old IP Address data from AbuseFilter logs'; + $this->addDescription( 'Purge old IP Address data from AbuseFilter logs' ); $this->setBatchSize( 200 ); $this->requireExtension( 'Abuse Filter' ); @@ -22,6 +24,7 @@ class PurgeOldLogIPData extends Maintenance { public function execute() { $this->output( "Purging old IP Address data from abuse_filter_log...\n" ); $dbw = wfGetDB( DB_MASTER ); + $factory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory(); $cutoffUnix = time() - $this->getConfig()->get( 'AbuseFilterLogIPMaxAge' ); $count = 0; @@ -47,7 +50,7 @@ class PurgeOldLogIPData extends Maintenance { $count += $dbw->affectedRows(); $this->output( "$count\n" ); - wfWaitForSlaves(); + $factory->waitForReplication(); } } while ( count( $ids ) >= $this->getBatchSize() ); @@ -58,5 +61,5 @@ class PurgeOldLogIPData extends Maintenance { } -$maintClass = "PurgeOldLogIPData"; +$maintClass = PurgeOldLogIPData::class; require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/AbuseFilter/maintenance/searchFilters.php b/AbuseFilter/maintenance/searchFilters.php new file mode 100644 index 00000000..2d59846c --- /dev/null +++ b/AbuseFilter/maintenance/searchFilters.php @@ -0,0 +1,67 @@ +<?php + +if ( getenv( 'MW_INSTALL_PATH' ) ) { + $IP = getenv( 'MW_INSTALL_PATH' ); +} else { + $IP = __DIR__ . '/../../..'; +} +require_once "$IP/maintenance/Maintenance.php"; + +class SearchFilters extends Maintenance { + public function __construct() { + parent::__construct(); + $this->addDescription( 'Find all filters matching a regular expression pattern' ); + $this->addOption( 'pattern', 'Regular expression pattern', true, true ); + + $this->requireExtension( 'Abuse Filter' ); + } + + /** + * @see Maintenance:execute() + */ + public function execute() { + global $wgConf, $wgDBtype; + + if ( $wgDBtype !== 'mysql' ) { + $this->fatalError( 'This maintenance script only works with MySQL databases' ); + } + + $this->output( "wiki\tfilter\n" ); + if ( $this->getOption( 'pattern' ) === '' ) { + $this->fatalError( 'Pattern cannot be empty' ); + } + + if ( count( $wgConf->wikis ) > 0 ) { + foreach ( $wgConf->wikis as $dbname ) { + $this->getMatchingFilters( $dbname ); + } + } else { + $this->getMatchingFilters(); + } + } + + /** + * @param string|false $dbname Name of database, or false if the wiki is not part of a wikifarm + */ + public function getMatchingFilters( $dbname = false ) { + $dbr = wfGetDB( DB_REPLICA, [], $dbname ); + $pattern = $dbr->addQuotes( $this->getOption( 'pattern' ) ); + + if ( $dbr->tableExists( 'abuse_filter' ) ) { + $rows = $dbr->select( + 'abuse_filter', + 'DATABASE() AS dbname, af_id', + [ + "af_pattern RLIKE $pattern" + ] + ); + + foreach ( $rows as $row ) { + $this->output( $row->dbname . "\t" . $row->af_id . "\n" ); + } + } + } +} + +$maintClass = SearchFilters::class; +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/AbuseFilter/maintenance/updateVarDumps.php b/AbuseFilter/maintenance/updateVarDumps.php new file mode 100644 index 00000000..a29e3553 --- /dev/null +++ b/AbuseFilter/maintenance/updateVarDumps.php @@ -0,0 +1,700 @@ +<?php + +use MediaWiki\Extension\AbuseFilter\AbuseFilterServices; +use MediaWiki\Extension\AbuseFilter\KeywordsManager; +use MediaWiki\MediaWikiServices; +use Wikimedia\AtEase\AtEase; +use Wikimedia\Rdbms\Database; +use Wikimedia\Rdbms\IResultWrapper; + +/** + * Performs several tasks aiming to update the stored var dumps for filter hits. + * See T213006 for a list. + * + * @ingroup Maintenance + */ +if ( getenv( 'MW_INSTALL_PATH' ) ) { + $IP = getenv( 'MW_INSTALL_PATH' ); +} else { + $IP = __DIR__ . '/../../..'; +} +require_once "$IP/maintenance/Maintenance.php"; + +class UpdateVarDumps extends LoggedUpdateMaintenance { + /** @var Database A connection to replica */ + private $dbr; + /** @var Database A connection to the master */ + private $dbw; + /** @var bool Whether we're performing a dry run */ + private $dryRun = false; + /** @var int Count of rows in the abuse_filter_log table */ + private $allRowsCount; + /** @var bool Whether to print progress markers */ + private $progressMarkers; + /** @var string|null */ + private $printOrphanedFile; + /** @var int|null How many seconds to sleep after each batch. */ + private $sleep; + /** @var KeywordsManager */ + private $keywordsManager; + + /** + * @inheritDoc + */ + public function __construct() { + parent::__construct(); + + $this->addDescription( 'Update AbuseFilter var dumps - T213006' ); + $this->addOption( 'dry-run-verbose', 'Perform a verbose dry run' ); + $this->addOption( 'dry-run', 'Perform a dry run' ); + $this->addOption( 'progress-markers', 'Print progress markers every 10 batches' ); + $this->addOption( + 'print-orphaned-records-to', + 'Print ExternalStore urls of orphaned ExternalStore records (if any) ' . + 'to the given file. Can use stdout, but it\'s not recommended for big databases.', + false, + true + ); + $this->addOption( 'sleep', 'Sleep this many seconds after each batch', false, true ); + $this->requireExtension( 'Abuse Filter' ); + $this->setBatchSize( 500 ); + $this->keywordsManager = AbuseFilterServices::getKeywordsManager(); + } + + /** + * @inheritDoc + */ + public function getUpdateKey() { + return __CLASS__; + } + + /** + * @inheritDoc + */ + public function doDBUpdates() { + if ( $this->hasOption( 'dry-run-verbose' ) || $this->hasOption( 'dry-run' ) ) { + // This way the script can be called with dry-run-verbose only and we can check for dry-run + $this->dryRun = true; + } + $this->progressMarkers = $this->hasOption( 'progress-markers' ); + $this->printOrphanedFile = $this->getOption( 'print-orphaned-records-to' ); + $this->sleep = $this->getOption( 'sleep' ); + + // Faulty rows aren't inserted anymore, hence we can query the replica and update the master. + $this->dbr = wfGetDB( DB_REPLICA ); + $this->dbw = wfGetDB( DB_MASTER ); + + // Control batching with the primary key to keep the queries performant and allow gaps + $this->allRowsCount = (int)$this->dbr->selectField( + 'abuse_filter_log', + 'MAX(afl_id)', + [], + __METHOD__ + ); + + if ( $this->allRowsCount === 0 ) { + $this->output( "...the abuse_filter_log table is empty.\n" ); + return !$this->dryRun; + } + + // Do the actual work. Note that several actions are superfluous (e.g. in fixMissingDumps + // we use "stored-text" but then we replace it in updateAflVarDump), but that's because of SRP. + + // First, ensure that afl_var_dump isn't empty + $this->fixMissingDumps(); + // Then, ensure that abuse_filter_log.afl_var_dump only contains "stored-text:xxxx" + $this->moveToText(); + // Then update the storage format in the text table + $this->updateText(); + // Finally, replace "stored-text:xxxx" with "tt:xxxx" for all rows + $this->updateAflVarDump(); + + return !$this->dryRun; + } + + /** + * Handle empty afl_var_dump. gerrit/16527 fixed a bug which caused an extra abuse_filter_log + * row to be inserted without the var dump for a given action. If we find a row identical to + * the current one but with a valid dump, just delete the current one. Otherwise, store a + * very basic var dump for sanity. + * This handles point 7. of T213006. + */ + private function fixMissingDumps() { + $this->output( "...Checking for missing dumps (1/4)\n" ); + $batchSize = $this->getBatchSize(); + + $prevID = 0; + $curID = $batchSize; + $deleted = $rebuilt = 0; + do { + $this->maybePrintProgress( $prevID ); + $brokenRows = $this->dbr->select( + 'abuse_filter_log', + '*', + [ + 'afl_var_dump' => '', + "afl_id > $prevID", + "afl_id <= $curID" + ], + __METHOD__, + [ 'ORDER BY' => 'afl_id ASC' ] + ); + $prevID = $curID; + $curID += $batchSize; + + $res = $this->doFixMissingDumps( $brokenRows ); + $deleted += $res['deleted']; + $rebuilt += $res['rebuilt']; + MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->waitForReplication(); + $this->maybeSleep(); + } while ( $prevID <= $this->allRowsCount ); + + if ( $this->dryRun ) { + $this->output( + "...found $deleted rows with blank afl_var_dump to delete, and " . + "$rebuilt rows to rebuild.\n" + ); + } else { + $this->output( + "...deleted $deleted rows with blank afl_var_dump, and rebuilt " . + "$rebuilt rows.\n" + ); + } + } + + /** + * @param IResultWrapper $brokenRows + * @return int[] + */ + private function doFixMissingDumps( IResultWrapper $brokenRows ) { + $deleted = 0; + foreach ( $brokenRows as $row ) { + if ( $row->afl_var_dump === '' ) { + $findRow = array_diff_key( + get_object_vars( $row ), + [ 'afl_var_dump' => true, 'afl_id' => true ] + ); + // This is the case where we may have a duplicate row. The wrong insertion happened + // right before the correct one, so their afl_id should only differ by 1, but let's + // play safe and only assume it's greater. Note that the two entries are guaranteed + // to have the same timestamp. + $findRow[] = 'afl_id > ' . $this->dbr->addQuotes( $row->afl_id ); + $saneDuplicate = $this->dbr->selectRow( + 'abuse_filter_log', + '1', + $findRow, + __METHOD__ + ); + + if ( $saneDuplicate ) { + // Just delete the row! + $deleted++; + if ( !$this->dryRun ) { + $this->dbw->delete( + 'abuse_filter_log', + [ 'afl_id' => $row->afl_id ], + __METHOD__ + ); + } + continue; + } + } + if ( $this->dryRun ) { + continue; + } + // Build a VariableHolder with the only values we can be sure of + $vars = AbuseFilterVariableHolder::newFromArray( [ + 'timestamp' => wfTimestamp( TS_UNIX, $row->afl_timestamp ), + 'action' => $row->afl_action + ] ); + // Add some action-specific variables + if ( strpos( $row->afl_action, 'createaccount' ) !== false ) { + $vars->setVar( 'accountname', $row->afl_user_text ); + } else { + $vars->setVar( 'user_name', $row->afl_user_text ); + $title = Title::makeTitle( $row->afl_namespace, $row->afl_title ); + if ( $row->afl_action !== 'move' ) { + $vars->setVar( 'page_title', $title->getText() ); + $vars->setVar( 'page_prefixedtitle', $title->getPrefixedText() ); + } else { + $vars->setVar( 'moved_from_title', $title->getText() ); + $vars->setVar( 'moved_from_prefixedtitle', $title->getPrefixedText() ); + } + } + + $storedID = AbuseFilter::storeVarDump( $vars ); + $this->dbw->update( + 'abuse_filter_log', + [ 'afl_var_dump' => "tt:$storedID" ], + [ 'afl_id' => $row->afl_id ], + __METHOD__ + ); + } + $rebuilt = $brokenRows->numRows() - $deleted; + return [ 'rebuilt' => $rebuilt, 'deleted' => $deleted ]; + } + + /** + * If afl_var_dump contains serialized data, move the dump to the text table. + * This handles point 1. of T213006. + */ + private function moveToText() { + $this->output( "...Moving serialized data away from the abuse_filter_log table (2/4).\n" ); + $batchSize = $this->getBatchSize(); + + $prevID = 0; + $curID = $batchSize; + $changeRows = $truncatedDumps = 0; + do { + $this->maybePrintProgress( $prevID ); + $res = $this->dbr->select( + 'abuse_filter_log', + [ 'afl_id', 'afl_var_dump' ], + [ + 'afl_var_dump NOT ' . $this->dbr->buildLike( + 'stored-text:', + $this->dbr->anyString() + ), + 'afl_var_dump NOT ' . $this->dbr->buildLike( + 'tt:', + $this->dbr->anyString() + ), + "afl_id > $prevID", + "afl_id <= $curID" + ], + __METHOD__, + [ 'ORDER BY' => 'afl_id ASC' ] + ); + + $prevID = $curID; + $curID += $batchSize; + + $result = $this->doMoveToText( $res ); + $changeRows += $result['change']; + $truncatedDumps += $result['truncated']; + MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->waitForReplication(); + $this->maybeSleep(); + } while ( $prevID <= $this->allRowsCount ); + + $msg = $this->dryRun ? + "...found $changeRows abuse_filter_log rows with serialized data and $truncatedDumps " . + "truncated dumps to rebuild.\n" : + "...moved $changeRows abuse_filter_log rows and rebuilt $truncatedDumps " . + "truncated dumps.\n"; + + $this->output( $msg ); + } + + /** + * @param IResultWrapper $rows + * @return int[] + */ + private function doMoveToText( IResultWrapper $rows ) { + $changeRows = $truncatedDumps = 0; + foreach ( $rows as $row ) { + // Sanity: perform a very raw check to confirm that the dump is indeed a serialized value + $re = '/^(a:\d+:{|O:25:"[Aa]buse[Ff]ilter[Vv]ariable[Hh]older":\d+:{)/'; + if ( !preg_match( $re, $row->afl_var_dump ) ) { + $this->fatalError( + "...found a value in afl_var_dump for afl_id {$row->afl_id} which is " . + "neither a reference to the text table or a serialized value: {$row->afl_var_dump}.\n" + ); + } + + AtEase::suppressWarnings(); + $stored = unserialize( $row->afl_var_dump ); + AtEase::restoreWarnings(); + if ( !$stored ) { + $re = '/^O:25:"[Aa]buse[Ff]ilter[Vv]ariable[Hh]older":\d+:{/'; + if ( preg_match( $re, $row->afl_var_dump ) ) { + $this->fatalError( + "...found a corrupted afl_var_dump for afl_id {$row->afl_id} containing " . + "a truncated object: {$row->afl_var_dump}.\n" + ); + } + $stored = $this->restoreTruncatedDump( $row->afl_var_dump ); + $truncatedDumps++; + } + if ( !is_array( $stored ) && !( $stored instanceof AbuseFilterVariableHolder ) ) { + $this->fatalError( + '...found unexpected data type ( ' . gettype( $stored ) . ' ) in ' . + "afl_var_dump for afl_id {$row->afl_id}.\n" + ); + } + $changeRows++; + + if ( !$this->dryRun ) { + $holder = is_array( $stored ) ? AbuseFilterVariableHolder::newFromArray( $stored ) : $stored; + // Note: this will upgrade to the new JSON format, so we use tt: + $newDump = AbuseFilter::storeVarDump( $holder ); + $this->dbw->update( + 'abuse_filter_log', + [ 'afl_var_dump' => "tt:$newDump" ], + [ 'afl_id' => $row->afl_id ], + __METHOD__ + ); + } + } + return [ 'change' => $changeRows, 'truncated' => $truncatedDumps ]; + } + + /** + * Try to restore a truncated dumps. This could happen for very old rows, where afl_var_dump + * was a blob instead of a longblob, and we tried to insert very long strings there. + * This handles point 9. of T214193. + * + * @param string $dump The broken serialized dump + * @return array With everything that we can restore from $dump on success + */ + private function restoreTruncatedDump( $dump ) { + // This method makes various assumptions: + // 1 - Everything is wrapped inside an array + // 2 - Array elements can only be strings, integers, bools or null + // 3 - Array keys can only be strings + // As this is what a serialized dump should look like. + $string = preg_replace( '/^a:\d+:{/', '', $dump ); + + $ret = []; + $key = null; + + while ( strlen( $string ) > 2 || $string === 'N;' ) { + $type = substr( $string, 0, 2 ); + switch ( $type ) { + case 's:': + // Quotes aren't escaped, so we need to figure out how many characters to include + $matches = []; + if ( !preg_match( '/^s:(\d+):"/', $string, $matches ) ) { + break 2; + } + $len = (int)$matches[1]; + $val = substr( $string, strlen( $matches[0] ), $len ); + if ( strlen( $val ) === $len ) { + if ( $key === null ) { + // It's an array key + $key = $val; + } else { + $ret[$key] = $val; + $key = null; + } + $offset = strlen( $matches[0] ) + $len + 2; + break; + } else { + // The truncation happened in the middle of the string + break 2; + } + case 'i:': + if ( preg_match( '/^i:(-?\d+);/', $string, $matches ) ) { + if ( $key === null ) { + throw new UnexpectedValueException( "Unexpected integer key: $string" ); + } + $ret[$key] = intval( $matches[1] ); + $key = null; + $offset = strlen( $matches[0] ); + break; + } else { + break 2; + } + case 'b:': + if ( preg_match( '/^b:([01]);/', $string, $matches ) ) { + if ( $key === null ) { + throw new UnexpectedValueException( "Unexpected bool key: $string" ); + } + $ret[$key] = (bool)$matches[1]; + $key = null; + $offset = 4; + break; + } else { + break 2; + } + case 'N;': + if ( $key === null ) { + throw new UnexpectedValueException( "Unexpected null key: $string" ); + } + $ret[$key] = null; + $key = null; + $offset = 2; + break; + default: + break 2; + } + + // Remove the value we have just parsed + // @phan-suppress-next-next-line PhanPossiblyUndeclaredVariable + // @phan-suppress-next-line PhanTypeMismatchArgumentNullableInternal + $string = substr( $string, $offset ); + } + + if ( $this->hasOption( 'dry-run-verbose' ) ) { + $this->output( + "...converted the following corrupted dump:\n\n$dump\n\n to this:\n\n" . + var_export( $ret, true ) . "\n\n" + ); + } + + return $ret; + } + + /** + * If the text table (or the External Storage) contains a serialized AbuseFilterVariableHolder + * or array, re-store it as a JSON-encoded array. This assumes that afl_var_dump rows starting + * with 'tt:' already point to JSON dumps, and afl_var_dump rows starting with 'stored-text:' + * only point to serialized dumps. + * This handles point 2. and 6. of T213006. + */ + private function updateText() { + $this->output( + "...Re-storing serialized dumps as JSON-encoded arrays for all rows (3/4).\n" + ); + if ( $this->printOrphanedFile !== null && !$this->dryRun ) { + $this->output( "Printing orphaned records to $this->printOrphanedFile.\n" ); + file_put_contents( + $this->printOrphanedFile, + "Records orphaned by AbuseFilter's updateVarDumps sccript\n", + FILE_APPEND + ); + } + + $batchSize = $this->getBatchSize(); + $prevID = 0; + $curID = $batchSize; + $count = 0; + + $idSQL = $this->dbr->buildIntegerCast( $this->dbr->strreplace( + 'afl_var_dump', + $this->dbr->addQuotes( 'stored-text:' ), + $this->dbr->addQuotes( '' ) + ) ); + + $dumpLike = $this->dbr->buildLike( 'stored-text:', $this->dbr->anyString() ); + $esAccess = MediaWikiServices::getInstance()->getExternalStoreAccess(); + do { + $this->maybePrintProgress( $prevID ); + $res = $this->dbr->select( + [ 'text', 'abuse_filter_log' ], + [ 'old_id', 'old_text', 'old_flags' ], + [ + "afl_var_dump $dumpLike", + "afl_id > $prevID", + "afl_id <= $curID" + ], + __METHOD__, + [ 'DISTINCT', 'ORDER BY' => 'old_id ASC' ], + [ 'abuse_filter_log' => [ 'JOIN', "old_id = $idSQL" ] ] + ); + + $prevID = $curID; + $curID += $batchSize; + $count += $res->numRows(); + + if ( !$this->dryRun ) { + $this->doUpdateText( $res, $esAccess ); + MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->waitForReplication(); + } + $this->maybeSleep(); + } while ( $prevID <= $this->allRowsCount ); + + $msg = $this->dryRun + ? "...found $count text rows to update.\n" + : "...updated $count text rows.\n"; + $this->output( $msg ); + } + + /** + * @param IResultWrapper $res text rows + * @param ExternalStoreAccess $esAccess + */ + private function doUpdateText( IResultWrapper $res, ExternalStoreAccess $esAccess ) { + $orphaned = []; + foreach ( $res as $row ) { + // This is copied from AbuseFilter::loadVarDump + $oldFlags = explode( ',', $row->old_flags ); + $text = $row->old_text; + if ( in_array( 'external', $oldFlags ) ) { + $text = $esAccess->fetchFromURL( $row->old_text ); + } + if ( in_array( 'gzip', $oldFlags ) ) { + $text = gzinflate( $text ); + } + + if ( FormatJson::decode( $text ) !== null ) { + // Already in the new format, apparently. + if ( + !in_array( 'utf-8', $oldFlags, true ) || + in_array( 'nativeDataArray', $oldFlags, true ) + ) { + // Sanity + $this->fatalError( "Row {$row->old_id} is JSON-encoded with wrong flags: {$row->old_flags}" ); + } + continue; + } + + $obj = unserialize( $text ); + + $varArray = $obj instanceof AbuseFilterVariableHolder + ? $obj->dumpAllVars( [ 'old_wikitext', 'new_wikitext' ] ) + : $obj; + $varArray = $this->updateVariables( $varArray ); + // Recreating flags will also ensure that we don't add 'nativeDataArray' + $newFlags = [ 'utf-8' ]; + // This is copied from AbuseFilter::storeVarDump + $toStore = FormatJson::encode( $varArray ); + if ( in_array( 'gzip', $oldFlags ) && function_exists( 'gzdeflate' ) ) { + $toStore = gzdeflate( $toStore ); + $newFlags[] = 'gzip'; + } + if ( in_array( 'external', $oldFlags ) ) { + $orphaned[] = $row->old_text; + $toStore = $esAccess->insert( $toStore ); + $newFlags[] = 'external'; + } + + $this->dbw->update( + 'text', + [ + 'old_text' => $toStore, + 'old_flags' => implode( ',', $newFlags ) + ], + [ 'old_id' => $row->old_id ], + __METHOD__ + ); + } + if ( $this->printOrphanedFile !== null && $orphaned ) { + file_put_contents( $this->printOrphanedFile, implode( ', ', $orphaned ) . "\n", FILE_APPEND ); + } + } + + /** + * Given a stored object, removes some disabled variables and update deprecated ones. + * Also ensure that core variables are lowercase. + * Handles points 4., 5. and 8. of T213006. + * + * @param array $vars The stored vars. + * @return array + */ + private function updateVariables( array $vars ) { + // Remove all variables used in the past to store metadata + unset( $vars['context'], $vars['logged_local_ids'], $vars['logged_global_ids'] ); + + $builtinVars = $this->getBuiltinVarNames(); + $newVars = []; + foreach ( $vars as $oldName => $value ) { + $lowerName = strtolower( $oldName ); + if ( $lowerName !== $oldName && array_key_exists( $lowerName, $builtinVars ) ) { + $oldName = $lowerName; + } + $deprecatedVars = $this->keywordsManager->getDeprecatedVariables(); + $newName = $deprecatedVars[$oldName] ?? $oldName; + $newVars[$newName] = $value; + } + return $newVars; + } + + /** + * Get a set of builtin variable names. Copied from AbuseFilterVariableHolder::dumpAllVars. + * @return array [ varname => true ] for instantaneous search. All names are lowercase + */ + private function getBuiltinVarNames() { + global $wgRestrictionTypes; + + static $coreVariables = null; + + if ( $coreVariables ) { + return $coreVariables; + } + + $activeVariables = array_keys( $this->keywordsManager->getVarsMappings() ); + $deprecatedVariables = array_keys( $this->keywordsManager->getDeprecatedVariables() ); + $disabledVariables = array_keys( $this->keywordsManager->getDisabledVariables() ); + $coreVariables = array_merge( $activeVariables, $deprecatedVariables, $disabledVariables ); + + $prefixes = [ 'moved_from', 'moved_to', 'page' ]; + foreach ( $wgRestrictionTypes as $action ) { + foreach ( $prefixes as $prefix ) { + $coreVariables[] = "{$prefix}_restrictions_$action"; + } + } + + $coreVariables = array_fill_keys( $coreVariables, true ); + $coreVariables = array_change_key_case( $coreVariables ); + + return $coreVariables; + } + + /** + * Replace 'stored-text:' with 'tt:' in afl_var_dump. Handles point 3. of T213006. + */ + private function updateAflVarDump() { + $this->output( + "...Replacing the 'stored-text:' prefix with 'tt:' (4/4).\n" + ); + + $batchSize = $this->getBatchSize(); + + // Use native SQL functions so that we can update all rows at the same time. + $newIdSQL = $this->dbw->strreplace( + 'afl_var_dump', + $this->dbr->addQuotes( 'stored-text:' ), + $this->dbr->addQuotes( 'tt:' ) + ); + + $prevID = 0; + $curID = $batchSize; + $numRows = 0; + do { + $this->maybePrintProgress( $prevID ); + $args = [ + 'abuse_filter_log', + [ "afl_var_dump = $newIdSQL" ], + [ + "afl_id > $prevID", + "afl_id <= $curID", + 'afl_var_dump ' . $this->dbr->buildLike( 'stored-text:', $this->dbr->anyString() ) + ], + __METHOD__, + [ 'ORDER BY' => 'afl_id ASC' ] + ]; + if ( $this->dryRun ) { + $numRows += $this->dbr->selectRowCount( ...$args ); + } else { + $this->dbw->update( ...$args ); + $numRows += $this->dbw->affectedRows(); + MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->waitForReplication(); + } + + $prevID = $curID; + $curID += $batchSize; + $this->maybeSleep(); + } while ( $prevID <= $this->allRowsCount ); + + if ( $this->dryRun ) { + $this->output( "...would change afl_var_dump for $numRows rows.\n" ); + } else { + $this->output( "...updated afl_var_dump prefix for $numRows rows.\n" ); + } + } + + /** + * Print a progress marker if the respective option is enabled + * + * @param int $start + */ + private function maybePrintProgress( int $start ) : void { + if ( $this->progressMarkers && $start % ( 10 * $this->getBatchSize() ) === 0 ) { + $end = $start + $this->getBatchSize(); + $this->output( "...Doing range $start - $end\n" ); + } + } + + /** + * Sleep for a while, if required. Note: checking the value is several + * orders of magnitude faster than calling sleep(0). + */ + private function maybeSleep() : void { + if ( $this->sleep ) { + sleep( $this->sleep ); + } + } +} + +$maintClass = 'UpdateVarDumps'; +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/AbuseFilter/modules/ext.abuseFilter.css b/AbuseFilter/modules/ext.abuseFilter.css index 2f6cab1e..598fd08a 100644 --- a/AbuseFilter/modules/ext.abuseFilter.css +++ b/AbuseFilter/modules/ext.abuseFilter.css @@ -23,7 +23,13 @@ table.mw-abuselog-details caption { font-weight: bold; } -.mw-abusefilter-history-changed { +.mw-abusefilter-log-hidden-entry { + text-decoration: line-through; + color: #72777d; + font-style: italic; +} + +body td.mw-abusefilter-history-changed { background: #ffe0e0; font-weight: bold; } @@ -107,14 +113,33 @@ li.mw-abusefilter-changeslist-nomatch { background-image: url( red_x.png ); } +#mw-abusefilter-edit-rules .mw-input { + width: 100%; /* So that we can use relative width for mw-abusefilter-editor */ +} + div.mw-abusefilter-editor { - max-width: 75em; - height: 30em; + width: 65%; /* Same as wpFilterRules and mw-abusefilter-notes-editor */ + height: 30em; /* Similar to wpFilterRules */ line-height: 1.5em; border: 1px solid #a2a9b1; display: none; } +#wpFilterRules { + width: 65%; /* Same as mw-abusefilter-editor */ + height: 27em; /* Same as mw-abusefilter-editor, minus extra space */ +} + +#mw-abusefilter-notes-editor { + width: 65%; /* Same as mw-abusefilter-editor */ + max-width: unset; /* OOUI's default of 50em is too low for this field */ +} + +#mw-abusefilter-switcheditor { + /* Hidden until the click handler is installed */ + display: none; +} + fieldset.mw-abusefilter-edit-buttons { margin-top: 1em; } @@ -151,10 +176,20 @@ ul li.mw-abusefilter-changeslist-match { display: inline; } +#mw-abusefilter-expr-result { + word-break: break-all; + /* Shown dinamically via JS */ + display: none; +} + .mw-abusefilter-history-buttons { text-align: center; } +.mw-abusefilter-tools-error { + color: #f00; +} + /* Ace highlight customisation */ span.ace_invalid.ace_deprecated { diff --git a/AbuseFilter/modules/ext.abuseFilter.edit.js b/AbuseFilter/modules/ext.abuseFilter.edit.js index 93008139..908111b3 100644 --- a/AbuseFilter/modules/ext.abuseFilter.edit.js +++ b/AbuseFilter/modules/ext.abuseFilter.edit.js @@ -6,7 +6,7 @@ */ /* global ace */ -( function ( mw, $, OO ) { +( function () { 'use strict'; // @var {jQuery} Filter editor for JS and jQuery handling @@ -76,11 +76,11 @@ /** * Takes the data retrieved in doSyntaxCheck and processes it. * - * @param {Object} data Data returned from the AJAX request + * @param {Object} response Data returned from the AJAX request */ - function processSyntaxResult( data ) { - var position; - data = data.abusefilterchecksyntax; + function processSyntaxResult( response ) { + var position, + data = response.abusefilterchecksyntax; if ( data.status === 'ok' ) { // Successful @@ -105,7 +105,7 @@ filterEditor.scrollToRow( position.row ); } else { $plainTextBox - .focus() + .trigger( 'focus' ) .textSelection( 'setSelection', { start: data.character } ); } } @@ -118,9 +118,11 @@ * @param {Object} details Details about the error */ function processSyntaxResultFailure( error, details ) { - var msg = error === 'http' ? 'abusefilter-http-error' : 'unknown-error'; processSyntaxResultAlways( - mw.msg( msg, details && details.exception ), + mw.msg( + error === 'http' ? 'abusefilter-http-error' : 'unknown-error', + details && details.exception + ), 'mw-abusefilter-syntaxresult-error', false ); @@ -129,18 +131,17 @@ /** * Sends the current filter text to be checked for syntax issues. * - * @context HTMLElement + * @this HTMLElement * @param {jQuery.Event} e The event fired when the function is called */ function doSyntaxCheck() { - var filter = $plainTextBox.val(), - api = new mw.Api(); + var filter = $plainTextBox.val(); $( this ) .prop( 'disabled', true ) .injectSpinner( { id: 'abusefilter-syntaxcheck', size: 'large' } ); - api.post( { + new mw.Api().post( { action: 'abusefilterchecksyntax', filter: filter } ) @@ -174,12 +175,11 @@ /** * Fetches a filter from the API and inserts it into the filter box. * - * @context HTMLElement + * @this HTMLElement * @param {jQuery.Event} e The event fired when the function is called */ function fetchFilter() { - var filterId = $.trim( $( '#mw-abusefilter-load-filter input' ).val() ), - api; + var filterId = $( '#mw-abusefilter-load-filter input' ).val().trim(); if ( filterId === '' ) { return; @@ -188,8 +188,7 @@ $( this ).injectSpinner( { id: 'fetch-spinner', size: 'large' } ); // We just ignore errors or unexisting filters over here - api = new mw.Api(); - api.get( { + new mw.Api().get( { action: 'query', list: 'abusefilters', abfprop: 'pattern', @@ -197,10 +196,10 @@ abfendid: filterId, abflimit: 1 } ) - .always( function () { + .always( function removeSpinner() { $.removeSpinner( 'fetch-spinner' ); } ) - .done( function ( data ) { + .done( function insertFilter( data ) { if ( data.query.abusefilters[ 0 ] !== undefined ) { if ( useAce ) { filterEditor.setValue( data.query.abusefilters[ 0 ].pattern ); @@ -215,7 +214,7 @@ * that don't have checked boxes */ function hideDeselectedActions() { - $( '.mw-abusefilter-action-checkbox input' ).each( function () { + $( '.mw-abusefilter-action-checkbox input' ).each( function showHideParams() { // mw-abusefilter-action-checkbox-{$action} var action = this.parentNode.id.substr( 31 ), $params = $( '#mw-abusefilter-' + action + '-parameters' ); @@ -236,7 +235,7 @@ * @param {string} action The action the message refers to */ function previewMessage( action ) { - var api = new mw.Api(), + var api, args = [ '<nowiki>' + $( 'input[name=wpFilterDescription]' ).val() + '</nowiki>', $( '#mw-abusefilter-edit-id' ).children().last().text() @@ -246,30 +245,31 @@ $element = $( '#mw-abusefilter-' + action + '-preview' ), previewButton = action === 'warn' ? toggleWarnPreviewButton : toggleDisallowPreviewButton; - if ( !$element.is( ':visible' ) ) { + if ( $element.css( 'display' ) !== 'none' ) { + $element.hide(); + previewButton.setFlags( { destructive: false, progressive: true } ); + } else { + api = new mw.Api(); api.get( { action: 'query', meta: 'allmessages', ammessages: message, amargs: args.join( '|' ) } ) - .done( function ( data ) { + .done( function parseMessage( data ) { api.parse( data.query.allmessages[ 0 ][ '*' ], { disablelimitreport: '', preview: '', prop: 'text', title: 'MediaWiki:' + message } ) - .done( function ( html ) { + .done( function showMessage( html ) { $element.show().html( html ); previewButton.setFlags( { destructive: true, progressive: false } ); } ); } ); - } else { - $element.hide(); - previewButton.setFlags( { destructive: false, progressive: true } ); } } @@ -281,9 +281,10 @@ function editMessage( action ) { var message = getCurrentMessage( action ), defaultMsg = action === 'warn' ? 'warning' : 'disallowed', - url = mw.config.get( 'wgScript' ) + - '?title=MediaWiki:' + mw.util.wikiUrlencode( message ) + - '&action=edit&preload=MediaWiki:abusefilter-' + defaultMsg; + url = mw.util.getUrl( 'MediaWiki:' + message, { + action: 'edit', + preload: 'MediaWiki:abusefilter-' + defaultMsg + } ); window.open( url, '_blank' ); } @@ -291,7 +292,7 @@ /** * Called if the filter group (#mw-abusefilter-edit-group-input select) is changed. * - * @context HTMLELement + * @this HTMLELement * @param {jQuery.Event} e The event fired when the function is called */ function onFilterGroupChange() { @@ -348,48 +349,70 @@ /** * Called if the user presses a key in the load filter field. * - * @context HTMLELement + * @this HTMLELement * @param {jQuery.Event} e The event fired when the function is called */ function onFilterKeypress( e ) { if ( e.type === 'keypress' && e.which === 13 ) { e.preventDefault(); - $( '#mw-abusefilter-load' ).click(); + $( '#mw-abusefilter-load' ).trigger( 'click' ); } } /** + * Warn if the user changed anything and tries to leave the window + */ + function setWarnOnLeave() { + var warnOnLeave, + $form = $( '#mw-abusefilter-editing-form' ), + origValues = $form.serialize(); + + warnOnLeave = mw.confirmCloseWindow( { + test: function () { + return $form.serialize() !== origValues; + }, + message: mw.msg( 'abusefilter-edit-warn-leave' ) + } ); + + $form.on( 'submit', function () { + warnOnLeave.release(); + } ); + } + + /** * Builds a TagMultiselectWidget, to be used both for throttle groups and change tags * * @param {string} action Either 'throttle' or 'tag', will be used to build element IDs * @param {Array} config The array with configuration passed from PHP code */ function buildSelector( action, config ) { - var disabled = config.disabled.length !== 0, - // mw-abusefilter-throttle-parameters, mw-abusefilter-tag-parameters - $container = $( '#mw-abusefilter-' + action + '-parameters' ), + // mw-abusefilter-throttle-parameters, mw-abusefilter-tag-parameters + var $container = $( '#mw-abusefilter-' + action + '-parameters' ), // Character used to separate elements in the textarea. separator = action === 'throttle' ? '\n' : ',', - selector, field, hiddenField; - - selector = - new OO.ui.TagMultiselectWidget( { - inputPosition: 'outline', - allowArbitrary: true, - allowEditTags: true, - selected: config.values, - // abusefilter-edit-throttle-placeholder, abusefilter-edit-tag-placeholder - placeholder: OO.ui.msg( 'abusefilter-edit-' + action + '-placeholder' ), - disabled: disabled - } ); - field = - new OO.ui.FieldLayout( - selector, - { - label: $( $.parseHTML( config.label ) ), - align: 'top' - } - ); + selector, field, fieldOpts, hiddenField; + + selector = new OO.ui.TagMultiselectWidget( { + inputPosition: 'outline', + allowArbitrary: true, + allowEditTags: true, + selected: config.values, + // The following messages are used here: + // * abusefilter-edit-throttle-placeholder + // * abusefilter-edit-tag-placeholder + placeholder: OO.ui.msg( 'abusefilter-edit-' + action + '-placeholder' ), + disabled: config.disabled + } ); + + fieldOpts = { + label: $( $.parseHTML( config.label ) ), + align: 'top' + }; + if ( action === 'throttle' ) { + fieldOpts.help = new OO.ui.HtmlSnippet( config.help ); + } + + field = new OO.ui.FieldLayout( selector, fieldOpts ); // mw-abusefilter-hidden-throttle-field, mw-abusefilter-hidden-tag-field hiddenField = OO.ui.infuse( $( '#mw-abusefilter-hidden-' + action + '-field' ) ); @@ -403,12 +426,13 @@ } // On ready initialization - $( document ).ready( function () { + $( function () { var basePath, readOnly, $exportBox = $( '#mw-abusefilter-export' ), isFilterEditor = mw.config.get( 'isFilterEditor' ), tagConfig = mw.config.get( 'tagConfig' ), throttleConfig = mw.config.get( 'throttleConfig' ), + $switchEditorBtn = $( '#mw-abusefilter-switcheditor' ), cbEnabled, cbDeleted; if ( isFilterEditor ) { @@ -428,9 +452,10 @@ toggleDisallowPreviewButton = OO.ui.infuse( $( '#mw-abusefilter-disallow-preview-button' ) ); disallowMessageExisting = OO.ui.infuse( $( '#mw-abusefilter-disallow-message-existing' ) ); disallowMessageOther = OO.ui.infuse( $( '#mw-abusefilter-disallow-message-other' ) ); + setWarnOnLeave(); } - $plainTextBox = $( '#' + mw.config.get( 'abuseFilterBoxName' ) ); + $plainTextBox = $( '#wpFilterRules' ); if ( $( '#wpAceFilterEditor' ).length ) { // CodeEditor is installed. @@ -472,12 +497,13 @@ $plainTextBox.val( filterEditor.getSession().getValue() ); } ); - $( '#mw-abusefilter-switcheditor' ).click( switchEditor ); + $switchEditorBtn.on( 'click', switchEditor ); + $switchEditorBtn.show(); } ); } // Hide the syntax ok message when the text changes - $plainTextBox.change( function () { + $plainTextBox.on( 'change', function () { var $el = $( '#mw-abusefilter-syntaxresult' ); if ( $el.data( 'syntaxOk' ) ) { @@ -485,27 +511,27 @@ } } ); - $( '#mw-abusefilter-load' ).click( fetchFilter ); - $( '#mw-abusefilter-load-filter' ).keypress( onFilterKeypress ); + $( '#mw-abusefilter-load' ).on( 'click', fetchFilter ); + $( '#mw-abusefilter-load-filter' ).on( 'keypress', onFilterKeypress ); if ( isFilterEditor ) { // Add logic for flags and consequences - $( '#mw-abusefilter-warn-preview-button' ).click( + $( '#mw-abusefilter-warn-preview-button' ).on( 'click', function () { previewMessage( 'warn' ); } ); - $( '#mw-abusefilter-disallow-preview-button' ).click( + $( '#mw-abusefilter-disallow-preview-button' ).on( 'click', function () { previewMessage( 'disallow' ); } ); - $( '#mw-abusefilter-warn-edit-button' ).click( + $( '#mw-abusefilter-warn-edit-button' ).on( 'click', function () { editMessage( 'warn' ); } ); - $( '#mw-abusefilter-disallow-edit-button' ).click( + $( '#mw-abusefilter-disallow-edit-button' ).on( 'click', function () { editMessage( 'disallow' ); } ); - $( '.mw-abusefilter-action-checkbox input' ).click( hideDeselectedActions ); + $( '.mw-abusefilter-action-checkbox input' ).on( 'click', hideDeselectedActions ); hideDeselectedActions(); - $( '#wpFilterGlobal' ).change( toggleCustomMessages ); + $( '#wpFilterGlobal' ).on( 'change', toggleCustomMessages ); toggleCustomMessages(); cbEnabled = OO.ui.infuse( $( '#wpFilterEnabled' ) ); @@ -528,9 +554,9 @@ } ); - $( '#mw-abusefilter-edit-group-input select' ).change( onFilterGroupChange ); + $( '#mw-abusefilter-edit-group-input select' ).on( 'change', onFilterGroupChange ); - $( '#mw-abusefilter-export-link' ).click( + $( '#mw-abusefilter-export-link' ).on( 'click', function ( e ) { e.preventDefault(); $exportBox.toggle(); @@ -538,8 +564,7 @@ ); } - $( '#mw-abusefilter-syntaxcheck' ).click( doSyntaxCheck ); - $( '#wpFilterBuilder' ).change( addText ); - + $( '#mw-abusefilter-syntaxcheck' ).on( 'click', doSyntaxCheck ); + $( '#wpFilterBuilder' ).on( 'change', addText ); } ); -}( mediaWiki, jQuery, OO ) ); +}() ); diff --git a/AbuseFilter/modules/ext.abuseFilter.examine.js b/AbuseFilter/modules/ext.abuseFilter.examine.js index b8d4591a..2a235041 100644 --- a/AbuseFilter/modules/ext.abuseFilter.examine.js +++ b/AbuseFilter/modules/ext.abuseFilter.examine.js @@ -5,7 +5,7 @@ * @author Marius Hoch <hoo@online.de> */ -( function ( mw, $ ) { +( function () { 'use strict'; // @var {jQuery} Syntax result div @@ -29,6 +29,8 @@ } $syntaxResult .attr( 'class', exClass ) + // Messages listed above + // eslint-disable-next-line mediawiki/msg-doc .text( mw.msg( msg ) ) .show(); } @@ -61,6 +63,8 @@ } $syntaxResult + // Messages listed above + // eslint-disable-next-line mediawiki/msg-doc .text( mw.msg( msg, details && details.exception ) ) .show(); } @@ -68,11 +72,11 @@ /** * Tests the filter against an rc event or abuse log entry. * - * @context HTMLElement + * @this HTMLElement * @param {jQuery.Event} e The event fired when the function is called */ function examinerTestFilter() { - var filter = $( '#wpTestFilter' ).val(), + var filter = $( '#wpFilterRules' ).val(), examine = mw.config.get( 'abuseFilterExamine' ), params = { action: 'abusefiltercheckmatch', @@ -94,8 +98,8 @@ .fail( examinerTestProcessFailure ); } - $( document ).ready( function () { + $( function initialize() { $syntaxResult = $( '#mw-abusefilter-syntaxresult' ); - $( '#mw-abusefilter-examine-test' ).click( examinerTestFilter ); + $( '#mw-abusefilter-examine-test' ).on( 'click', examinerTestFilter ); } ); -}( mediaWiki, jQuery ) ); +}() ); diff --git a/AbuseFilter/modules/ext.abuseFilter.tools.js b/AbuseFilter/modules/ext.abuseFilter.tools.js index 52e2712e..c8af5eeb 100644 --- a/AbuseFilter/modules/ext.abuseFilter.tools.js +++ b/AbuseFilter/modules/ext.abuseFilter.tools.js @@ -5,34 +5,50 @@ * @author Marius Hoch <hoo@online.de> */ -( function ( mw, $, OO ) { +( function () { 'use strict'; /** * Submits the expression to be evaluated. - * @context HTMLElement + * + * @this HTMLElement * @param {jQuery.Event} e The event fired when the function is called */ function doExprSubmit() { - var expr = $( '#wpTestExpr' ).val(), + var expr = $( '#wpFilterRules' ).val(), api = new mw.Api(); $( this ).injectSpinner( { id: 'abusefilter-expr', size: 'large' } ); api.post( { action: 'abusefilterevalexpression', - expression: expr + expression: expr, + prettyprint: 1 } ) - .fail( function ( error, details ) { - var msg = error === 'http' ? 'abusefilter-http-error' : 'unknown-error'; + .fail( function showError( error, details ) { + // TODO This might use api.getErrorMessage() + var msg; + if ( error === 'http' ) { + msg = 'abusefilter-http-error'; + } else if ( error === 'abusefilter-tools-syntax-error' ) { + msg = 'abusefilter-tools-syntax-error'; + } else { + msg = 'unknown-error'; + } $.removeSpinner( 'abusefilter-expr' ); $( '#mw-abusefilter-expr-result' ) - .text( mw.msg( msg, details.exception ) ); + // Message keys are listed above + // eslint-disable-next-line mediawiki/msg-doc + .text( mw.msg( msg, details.exception ) ) + .addClass( 'mw-abusefilter-tools-error' ) + .show(); } ) - .done( function ( data ) { + .done( function showResult( data ) { $.removeSpinner( 'abusefilter-expr' ); $( '#mw-abusefilter-expr-result' ) - .text( data.abusefilterevalexpression.result ); + .text( data.abusefilterevalexpression.result ) + .removeClass( 'mw-abusefilter-tools-error' ) + .show(); } ); } @@ -43,7 +59,10 @@ */ function processReautoconfirm( data ) { mw.notify( - mw.message( 'abusefilter-reautoconfirm-done', data.abusefilterunblockautopromote.user ).toString() + mw.message( + 'abusefilter-reautoconfirm-done', + data.abusefilterunblockautopromote.user + ).toString() ); $.removeSpinner( 'abusefilter-reautoconfirm' ); @@ -79,7 +98,8 @@ /** * Submits a call to reautoconfirm a user. - * @context HTMLElement + * + * @this HTMLElement * @param {jQuery.Event} e The event fired when the function is called * @return {boolean} False to prevent form submission */ @@ -98,15 +118,17 @@ api.post( { action: 'abusefilterunblockautopromote', user: name, - token: mw.user.tokens.get( 'editToken' ) + token: mw.user.tokens.get( 'csrfToken' ) } ) .done( processReautoconfirm ) .fail( processReautoconfirmFailure ); return false; } - $( document ).ready( function () { - $( '#mw-abusefilter-submitexpr' ).click( doExprSubmit ); - $( '#mw-abusefilter-reautoconfirmsubmit' ).click( doReautoSubmit ); + $( function initialize() { + $( '#mw-abusefilter-submitexpr' ).on( 'click', doExprSubmit ); + if ( $( '#mw-abusefilter-reautoconfirmsubmit' ).length ) { + $( '#mw-abusefilter-reautoconfirmsubmit' ).on( 'click', doReautoSubmit ); + } } ); -}( mediaWiki, jQuery, OO ) ); +}() ); diff --git a/AbuseFilter/modules/mode-abusefilter.js b/AbuseFilter/modules/mode-abusefilter.js index a4d82a8f..d3c05ee0 100644 --- a/AbuseFilter/modules/mode-abusefilter.js +++ b/AbuseFilter/modules/mode-abusefilter.js @@ -1,4 +1,4 @@ -/* global ace, mw */ +/* global ace */ ace.define( 'ace/mode/abusefilter_highlight_rules', [ 'require', 'exports', 'module', 'ace/lib/oop', 'ace/mode/text_highlight_rules' ], function ( require, exports ) { 'use strict'; @@ -7,17 +7,31 @@ ace.define( 'ace/mode/abusefilter_highlight_rules', [ 'require', 'exports', 'mod AFHighlightRules = function () { var cfg = mw.config.get( 'aceConfig' ), constants = ( 'true|false|null' ), - keywordMapper = this.createKeywordMapper( + keywords = this.createKeywordMapper( { keyword: cfg.keywords, 'support.function': cfg.functions, - 'constant.language': constants, + 'constant.language': constants + }, + // Null as default used in isKeywordOrVariable + null + ), + variables = this.createKeywordMapper( + { 'variable.language': cfg.variables, 'invalid.deprecated': cfg.deprecated, 'invalid.illegal': cfg.disabled }, - 'identifier' + 'identifier', + true ), + isKeywordOrVariable = function ( value ) { + if ( keywords( value ) !== null ) { + return keywords( value ); + } else { + return variables( value ); + } + }, integer = '(?:(?:[1-9]\\d*)|(?:0))', fraction = '(?:\\.\\d+)', intPart = '(?:\\d+)', @@ -44,7 +58,7 @@ ace.define( 'ace/mode/abusefilter_highlight_rules', [ 'require', 'exports', 'mod token: 'constant.numeric', regex: integer + '\\b' }, { - token: keywordMapper, + token: isKeywordOrVariable, regex: '[a-zA-Z_][a-zA-Z0-9_]*\\b' }, { token: 'keyword.operator', diff --git a/AbuseFilter/modules/ve-abusefilter/.eslintrc.json b/AbuseFilter/modules/ve-abusefilter/.eslintrc.json new file mode 100644 index 00000000..a343cf99 --- /dev/null +++ b/AbuseFilter/modules/ve-abusefilter/.eslintrc.json @@ -0,0 +1,5 @@ +{ + "globals": { + "ve": true + } +} diff --git a/AbuseFilter/modules/ve-abusefilter/ve.init.mw.AbuseFilterSaveErrorHandler.js b/AbuseFilter/modules/ve-abusefilter/ve.init.mw.AbuseFilterSaveErrorHandler.js new file mode 100644 index 00000000..6c8d20c2 --- /dev/null +++ b/AbuseFilter/modules/ve-abusefilter/ve.init.mw.AbuseFilterSaveErrorHandler.js @@ -0,0 +1,29 @@ +mw.loader.using( 'ext.visualEditor.targetLoader' ).then( function () { + mw.libs.ve.targetLoader.addPlugin( function () { + + ve.init.mw.AbuseFilterSaveErrorHandler = function () {}; + + OO.inheritClass( ve.init.mw.AbuseFilterSaveErrorHandler, ve.init.mw.SaveErrorHandler ); + + ve.init.mw.AbuseFilterSaveErrorHandler.static.name = 'abuseFilter'; + + ve.init.mw.AbuseFilterSaveErrorHandler.static.matchFunction = function ( data ) { + return data.errors && data.errors.some( function ( err ) { + return err.code === 'abusefilter-disallowed' || err.code === 'abusefilter-warning'; + } ); + }; + + ve.init.mw.AbuseFilterSaveErrorHandler.static.process = function ( data, target ) { + var isWarning = data.errors.every( function ( err ) { + return err.code === 'abusefilter-warning'; + } ); + // Handle warnings/errors from Extension:AbuseFilter + target.showSaveError( target.extractErrorMessages( data ), isWarning, isWarning ); + // Emit event for tracking. TODO: This is a bad design + target.emit( 'saveErrorAbuseFilter' ); + }; + + ve.init.mw.saveErrorHandlerFactory.register( ve.init.mw.AbuseFilterSaveErrorHandler ); + + } ); +} ); diff --git a/AbuseFilter/package-lock.json b/AbuseFilter/package-lock.json new file mode 100644 index 00000000..d6fd1b11 --- /dev/null +++ b/AbuseFilter/package-lock.json @@ -0,0 +1,8493 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/core": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.6.tgz", + "integrity": "sha512-nD3deLvbsApbHAHttzIssYqgb883yU/d9roe4RZymBCDaZryMJDbptVpEpeQuRh4BJ+SYI8le9YGxKvFEvl1Wg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.6", + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helpers": "^7.9.6", + "@babel/parser": "^7.9.6", + "@babel/template": "^7.8.6", + "@babel/traverse": "^7.9.6", + "@babel/types": "^7.9.6", + "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" + }, + "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 + } + } + }, + "@babel/generator": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", + "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", + "dev": true, + "requires": { + "@babel/types": "^7.9.6", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", + "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-module-imports": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", + "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-module-transforms": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz", + "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", + "@babel/helper-simple-access": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/template": "^7.8.6", + "@babel/types": "^7.9.0", + "lodash": "^4.17.13" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", + "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-replace-supers": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.9.6.tgz", + "integrity": "sha512-qX+chbxkbArLyCImk3bWV+jB5gTNU/rsze+JlcF6Nf8tVTigPJSI1o1oBow/9Resa1yehUO9lIipsmu9oG4RzA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/traverse": "^7.9.6", + "@babel/types": "^7.9.6" + } + }, + "@babel/helper-simple-access": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", + "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "dev": true, + "requires": { + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "dev": true + }, + "@babel/helpers": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.6.tgz", + "integrity": "sha512-tI4bUbldloLcHWoRUMAj4g1bF313M/o6fBKhIsb3QnGVPwRm9JsNf/gqMkQ7zjqReABiffPV6RWj7hEglID5Iw==", + "dev": true, + "requires": { + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.9.6", + "@babel/types": "^7.9.6" + } + }, + "@babel/highlight": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", + "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.0", + "chalk": "^2.0.0", + "js-tokens": "^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==", + "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" + } + } + } + }, + "@babel/parser": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", + "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", + "dev": true + }, + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/traverse": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", + "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.6", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + }, + "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==", + "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==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", + "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "@eslint/eslintrc": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.1.3.tgz", + "integrity": "sha512-4YVwPkANLeNtRjMekzux1ci8hIaH5eGKktGqR0d3LWsKNn5B2X/1Z6Trxy7jQXl9EBGE6Yj02O+t09FMeRllaA==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "lodash": "^4.17.19", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "acorn": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", + "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", + "dev": true + }, + "ajv": { + "version": "6.12.4", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz", + "integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==", + "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" + } + }, + "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" + } + }, + "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": "7.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz", + "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.3.0" + } + }, + "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 + }, + "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 + }, + "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 + } + } + }, + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "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" + } + } + } + }, + "@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==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.3", + "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==", + "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==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "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==", + "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==", + "dev": true, + "requires": { + "defer-to-connect": "^2.0.0" + } + }, + "@types/cacheable-request": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.1.tgz", + "integrity": "sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==", + "dev": true, + "requires": { + "@types/http-cache-semantics": "*", + "@types/keyv": "*", + "@types/node": "*", + "@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==", + "dev": true + }, + "@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==", + "dev": true + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.2.tgz", + "integrity": "sha512-rsZg7eL+Xcxsxk2XlBt9KcG8nOp9iYdKCOikY9x2RFJCyOdNj4MKPQty0e8oZr29vVAzKXr1BmR+kZauti3o1w==", + "dev": true + }, + "@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, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@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==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "@types/keyv": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.1.tgz", + "integrity": "sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=", + "dev": true + }, + "@types/node": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.4.tgz", + "integrity": "sha512-k3NqigXWRzQZVBDS5D1U70A5E8Qk4Kh+Ha/x4M8Bt9pF0X05eggfnC9+63Usc9Q928hRUIpIhTQaXsZwZBl4Ew==", + "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==", + "dev": true + }, + "@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 + }, + "@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "@types/unist": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", + "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==", + "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==", + "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==", + "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==", + "dev": true, + "optional": true, + "requires": { + "@types/node": "*" + } + }, + "@wdio/cli": { + "version": "6.1.12", + "resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-6.1.12.tgz", + "integrity": "sha512-KXGTCNcoEywYqT67qyv58I/YGowinfNWlzRoD2uP/shVZn8a0ebZam8CyXl3SJtL9pfELUcaIO1Hqxwtf6BBAg==", + "dev": true, + "requires": { + "@wdio/config": "6.1.2", + "@wdio/logger": "6.0.16", + "@wdio/utils": "6.1.8", + "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", + "lodash.flattendeep": "^4.4.0", + "lodash.pickby": "^4.6.0", + "lodash.union": "^4.6.0", + "log-update": "^4.0.0", + "webdriverio": "6.1.12", + "yargs": "^15.0.1", + "yarn-install": "^1.0.0" + } + }, + "@wdio/config": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-6.1.2.tgz", + "integrity": "sha512-mMatdM9RLNZI0dzHWGPl/8lU8+GX5q0K2Esd+VyDOLQNg/9pykidEQURwvoQb6YvvV5wiX4IXqLSIYh1ELjyOA==", + "dev": true, + "requires": { + "@wdio/logger": "6.0.16", + "deepmerge": "^4.0.0", + "glob": "^7.1.2" + } + }, + "@wdio/local-runner": { + "version": "6.1.12", + "resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-6.1.12.tgz", + "integrity": "sha512-hNNKdvkE5uNn4aTNT6ayYD321yltNvpHCRGTBftGg8Guxm2DjE2OwE/S5sIZ2152xs4QYfSKAOXI4mEjWjZV9g==", + "dev": true, + "requires": { + "@wdio/logger": "6.0.16", + "@wdio/repl": "6.1.8", + "@wdio/runner": "6.1.12", + "async-exit-hook": "^2.0.1", + "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==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "loglevel": "^1.6.0", + "loglevel-plugin-prefix": "^0.8.4", + "strip-ansi": "^6.0.0" + } + }, + "@wdio/mocha-framework": { + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-6.1.8.tgz", + "integrity": "sha512-qxetJAYIK8aoL6qHGfVM2OrR0XNnFcI0iy6qUwDhcbKpGsk/fyR+l+8xT75LonW93hLSXDI83PBGkfyQVnMgbQ==", + "dev": true, + "requires": { + "@wdio/logger": "6.0.16", + "@wdio/utils": "6.1.8", + "expect-webdriverio": "^1.1.5", + "mocha": "^7.0.1" + } + }, + "@wdio/protocols": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-6.1.11.tgz", + "integrity": "sha512-opauqB8kxsUOHrNxHv24D+DjULOvxQUfwSIGL4pv6u/b/Jzni4Nmjy4wcIb8TFXvWWvp7JfFQM1DntM0gQ0d3g==", + "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==", + "dev": true, + "requires": { + "@wdio/utils": "6.1.8" + } + }, + "@wdio/reporter": { + "version": "6.1.9", + "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-6.1.9.tgz", + "integrity": "sha512-3eQ8VcloL27Ev27EQIGS/BlmRrAeSu/e7ZHbQ3SN6E8eDpbJ7UZauO5mh+XqAq7a2LF8Sd5PMLnJ3RKlGtw+kA==", + "dev": true, + "requires": { + "fs-extra": "^9.0.0" + } + }, + "@wdio/runner": { + "version": "6.1.12", + "resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-6.1.12.tgz", + "integrity": "sha512-mEDx2VSO1mZ1ndJM0Dz2CK1sntYBNXo/EJEnjPYkf+STHPYOfeZEE/hpcabLmOjlCxW4XekLljC0UZnhqJt2+A==", + "dev": true, + "requires": { + "@wdio/config": "6.1.2", + "@wdio/logger": "6.0.16", + "@wdio/utils": "6.1.8", + "deepmerge": "^4.0.0", + "gaze": "^1.1.2", + "webdriver": "6.1.11", + "webdriverio": "6.1.12" + } + }, + "@wdio/spec-reporter": { + "version": "6.1.12", + "resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-6.1.12.tgz", + "integrity": "sha512-84hRQZvnrp2URoKsxi+9l0T3Qr/vueMKz1WPKNaDEiIqB1dP3L6Fl09THXXr5uy+FwMUJ1aee+twH0VwRV5haQ==", + "dev": true, + "requires": { + "@wdio/reporter": "6.1.9", + "chalk": "^4.0.0", + "easy-table": "^1.1.1", + "pretty-ms": "^7.0.0" + } + }, + "@wdio/sync": { + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/@wdio/sync/-/sync-6.1.8.tgz", + "integrity": "sha512-oghYrfMcLrVc0zxWUw9TQmUmdPQ8HmE2VMK6tifpOaF+Zo0jfsj2huajos1GPgdYqJV+LoZ3nXtdSYllG6n4gg==", + "dev": true, + "requires": { + "@wdio/logger": "6.0.16", + "fibers": "^4.0.1" + } + }, + "@wdio/utils": { + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-6.1.8.tgz", + "integrity": "sha512-qzvD8qCPpIpDrZ0HNOx1hTlfKY26p8WByUXgr52ll6DXxtAYXZLIJ8GAYFJUi87NVfwtv6+O7owQGSM/jtr8AQ==", + "dev": true, + "requires": { + "@wdio/logger": "6.0.16" + } + }, + "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 + }, + "acorn": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz", + "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==", + "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==", + "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 + }, + "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==", + "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.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "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==", + "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==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "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==", + "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==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "archiver": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-4.0.1.tgz", + "integrity": "sha512-/YV1pU4Nhpf/rJArM23W6GTUjT0l++VbjykrCRua1TSXrn+yM8Qs7XvtwSiRse0iCe49EPNf7ktXnPsWuSb91Q==", + "dev": true, + "requires": { + "archiver-utils": "^2.1.0", + "async": "^2.6.3", + "buffer-crc32": "^0.2.1", + "glob": "^7.1.6", + "readable-stream": "^3.6.0", + "tar-stream": "^2.1.2", + "zip-stream": "^3.0.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" + } + } + } + }, + "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, + "requires": { + "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" + }, + "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" + } + } + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "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": { + "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 + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "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 + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "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 + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "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 + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "autoprefixer": { + "version": "9.8.0", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.0.tgz", + "integrity": "sha512-D96ZiIHXbDmU02dBaemyAg53ez+6F5yZmapmgKcjm35yEe1uVDYI8hGW3VYoGRaG290ZFf91YxHrR518vC0u/A==", + "dev": true, + "requires": { + "browserslist": "^4.12.0", + "caniuse-lite": "^1.0.30001061", + "chalk": "^2.4.2", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^7.0.30", + "postcss-value-parser": "^4.1.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" + } + } + } + }, + "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 + }, + "aws4": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", + "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", + "dev": true + }, + "bail": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "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==", + "dev": true + }, + "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, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "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==", + "dev": true + }, + "bl": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", + "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "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, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "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 + }, + "browserslist": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.0.tgz", + "integrity": "sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001043", + "electron-to-chromium": "^1.3.413", + "node-releases": "^1.1.53", + "pkg-up": "^2.0.0" + } + }, + "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==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "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 + }, + "cac": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/cac/-/cac-3.0.4.tgz", + "integrity": "sha1-bSTO7Dcu/lybeYgIvH9JtHJCpO8=", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "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", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "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" + } + }, + "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, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "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 + } + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "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==", + "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==", + "dev": true, + "requires": { + "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": "^4.1.0", + "responselike": "^2.0.0" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001062", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001062.tgz", + "integrity": "sha512-ei9ZqeOnN7edDrb24QfJ0OZicpEbsWxv7WusOiQGz/f2SfvBgHHbOEwBJ8HKGVSyx8Z6ndPjxzR6m0NQq+0bfw==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "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.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.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", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "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==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "chrome-launcher": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.13.2.tgz", + "integrity": "sha512-zWD9RVVKd8Nx2xKGY4G08lb3nCD+2hmICxovvRE9QjBKQzHFvCYqGlsw15b4zUxLKq3wXEwVbR/yLtMbfk7JbQ==", + "dev": true, + "requires": { + "@types/node": "*", + "escape-string-regexp": "^1.0.5", + "is-wsl": "^2.2.0", + "lighthouse-logger": "^1.0.0", + "mkdirp": "^0.5.3", + "rimraf": "^3.0.2" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "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, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-spinners": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.3.0.tgz", + "integrity": "sha512-Xs2Hf2nzrvJMFKimOR7YR0QwZ8fc0u98kdtwN1eNAZzNQgH3vK2pXzff6GJtKh7S5hoJ87ECiAiZFS2fb5Ii2w==", + "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==", + "dev": true + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true, + "optional": true + }, + "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, + "requires": { + "is-regexp": "^2.0.0" + } + }, + "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, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "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 + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + }, + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + }, + "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, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "comment-parser": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-0.7.6.tgz", + "integrity": "sha512-GKNxVA7/iuTnAqGADlTWX4tkhzxZKXp5fLJqKTlQLHkE65XDUKutZ3BHaJC5IGcper2tT3QRD1xr4o3jNpgXXg==", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "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==", + "dev": true, + "requires": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^3.0.1", + "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" + } + } + } + }, + "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 + }, + "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" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "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 + }, + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "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 + } + } + }, + "crc": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", + "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", + "dev": true, + "requires": { + "buffer": "^5.1.0" + } + }, + "crc32-stream": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", + "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", + "dev": true, + "requires": { + "crc": "^3.4.4", + "readable-stream": "^3.4.0" + } + }, + "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, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "dependencies": { + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "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 + }, + "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 + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "dateformat": { + "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==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + } + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "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, + "requires": { + "mimic-response": "^3.1.0" + }, + "dependencies": { + "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 + } + } + }, + "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=", + "dev": true + }, + "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 + }, + "defaults": { + "version": "1.0.3", + "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==", + "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" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "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-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "dev": true + }, + "devtools": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/devtools/-/devtools-6.1.11.tgz", + "integrity": "sha512-jqCkkIcFTUq7xAPRwUApq8IMUn6v5XWoroaIec27ALXehFdGpEmO4p6Uehbn2580HOa2JYB+FdR9yzTw+MAuQA==", + "dev": true, + "requires": { + "@wdio/config": "6.1.2", + "@wdio/logger": "6.0.16", + "@wdio/protocols": "6.1.11", + "@wdio/utils": "6.1.8", + "chrome-launcher": "^0.13.1", + "puppeteer-core": "^3.0.0", + "ua-parser-js": "^0.7.21", + "uuid": "^8.0.0" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "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==", + "dev": true + }, + "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, + "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": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "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==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "entities": "^2.0.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 + }, + "entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.2.tgz", + "integrity": "sha512-dmD3AvJQBUjKpcNkoqr+x+IF0SdRtPz9Vk0uTy4yWqga9ibB6s4v++QFWNohjiUGoMlF552ZvNyXDxz5iW0qmw==", + "dev": true + } + } + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "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==", + "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 + } + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ejs": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.3.tgz", + "integrity": "sha512-wmtrUGyfSC23GC/B1SMv2ogAUgbQEtDmTIhfqielrG5ExIM9TP4UoYdi90jLF1aTcsWCJNEO0UrgKzP0y3nTSg==", + "dev": true, + "requires": { + "jake": "^10.6.1" + } + }, + "electron-to-chromium": { + "version": "1.3.448", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.448.tgz", + "integrity": "sha512-WOr3SrZ55lUFYugA6sUu3H3ZoxVIH5o3zTSqYS+2DOJJP4hnHmBiD1w432a2YFW/H2G5FIxE6DB06rv+9dUL5g==", + "dev": true + }, + "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 + }, + "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, + "requires": { + "once": "^1.4.0" + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + }, + "dependencies": { + "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 + } + } + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "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, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "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.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.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" + } + }, + "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 + }, + "eslint": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.8.1.tgz", + "integrity": "sha512-/2rX2pfhyUG0y+A123d0ccXtMm7DV7sH1m3lk9nk2DZ2LReq39FXHueR9xZwshE5MdfSf0xunSaMWRqyIA6M1w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@eslint/eslintrc": "^0.1.3", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.0", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^1.3.0", + "espree": "^7.3.0", + "esquery": "^1.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash": "^4.17.19", + "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", + "strip-json-comments": "^3.1.0", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "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" + } + }, + "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, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "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 + }, + "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 + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "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 + } + } + }, + "eslint-config-wikimedia": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.17.0.tgz", + "integrity": "sha512-zxTlSJkNvKNfWRBGxXoFbI4jCKFMDLdclPQZyvlCC4z35xPh81SuhIW1CfYoTmL4DvJEj+2X7wVXlHs5E/WaxQ==", + "dev": true, + "requires": { + "eslint": "^7.6.0", + "eslint-plugin-es": "^3.0.1", + "eslint-plugin-jsdoc": "^30.2.1", + "eslint-plugin-json": "^2.1.2", + "eslint-plugin-mediawiki": "^0.2.5", + "eslint-plugin-mocha": "^8.0.0", + "eslint-plugin-no-jquery": "^2.5.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-qunit": "^4.3.0", + "eslint-plugin-vue": "^6.2.2", + "eslint-plugin-wdio": "^6.0.12" + }, + "dependencies": { + "acorn": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", + "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", + "dev": true + }, + "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" + } + }, + "eslint": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.8.1.tgz", + "integrity": "sha512-/2rX2pfhyUG0y+A123d0ccXtMm7DV7sH1m3lk9nk2DZ2LReq39FXHueR9xZwshE5MdfSf0xunSaMWRqyIA6M1w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@eslint/eslintrc": "^0.1.3", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.0", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^1.3.0", + "espree": "^7.3.0", + "esquery": "^1.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash": "^4.17.19", + "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", + "strip-json-comments": "^3.1.0", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + } + }, + "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, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "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": "7.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz", + "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.3.0" + } + }, + "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 + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "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 + } + } + }, + "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" + } + }, + "eslint-plugin-jsdoc": { + "version": "30.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-30.3.1.tgz", + "integrity": "sha512-185ARou6Wj/68DP0g9kLLBnvmVwgg6/E/7Z8Z7Dz7Z63WgvRNaSvOLQiXkzIOEwstQfwI9PCuFPh4qBJov907A==", + "dev": true, + "requires": { + "comment-parser": "^0.7.6", + "debug": "^4.1.1", + "jsdoctypeparser": "^9.0.0", + "lodash": "^4.17.20", + "regextras": "^0.7.1", + "semver": "^7.3.2", + "spdx-expression-parse": "^3.0.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" + } + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "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==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, + "eslint-plugin-json": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-json/-/eslint-plugin-json-2.1.2.tgz", + "integrity": "sha512-isM/fsUxS4wN1+nLsWoV5T4gLgBQnsql3nMTr8u+cEls1bL8rRQO5CP5GtxJxaOfbcKqnz401styw+H/P+e78Q==", + "dev": true, + "requires": { + "lodash": "^4.17.19", + "vscode-json-languageservice": "^3.7.0" + } + }, + "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": "8.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-8.0.0.tgz", + "integrity": "sha512-n67etbWDz6NQM+HnTwZHyBwz/bLlYPOxUbw7bPuCyFujv7ZpaT/Vn6KTAbT02gf7nRljtYIjWcTxK/n8a57rQQ==", + "dev": true, + "requires": { + "eslint-utils": "^2.1.0", + "ramda": "^0.27.1" + }, + "dependencies": { + "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, + "requires": { + "eslint-visitor-keys": "^1.1.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==", + "dev": true + }, + "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, + "requires": { + "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" + }, + "dependencies": { + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "eslint-plugin-qunit": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-qunit/-/eslint-plugin-qunit-4.3.0.tgz", + "integrity": "sha512-xyQtwoDHWDuIqH5cp8SV0N++gFGwxfMKwRyumsBnJ3INM6Mz/qWUhrCTastOvvAc98aoieu2X5Ht4LgaZ3a75Q==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "natural-compare": "^1.4.0", + "semver": "^5.6.0", + "vue-eslint-parser": "^7.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==", + "dev": true + }, + "eslint-scope": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", + "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", + "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.2.0.tgz", + "integrity": "sha512-WFb4ihckKil6hu3Dp798xdzSfddwKKU3+nGniKF6HfeW6OLd2OUDEPP7TcHtB5+QXOKg2s6B2DaMPE1Nn/kxKQ==", + "dev": true + }, + "espree": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz", + "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "acorn": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", + "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", + "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==", + "dev": true + } + } + }, + "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 + }, + "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==", + "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==", + "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==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "eventemitter2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", + "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", + "dev": true + }, + "execall": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz", + "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==", + "dev": true, + "requires": { + "clone-regexp": "^2.1.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "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==", + "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" + } + }, + "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==", + "dev": true, + "requires": { + "expect": "^25.2.1", + "jest-matcher-utils": "^25.1.0" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "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, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extract-zip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.0.tgz", + "integrity": "sha512-i42GQ498yibjdvIhivUsRslx608whtGoFIhF26Z7O4MYncBxp8CwalOs1lnHy21A9sIohWO2+uiE4SRtC9JXDg==", + "dev": true, + "requires": { + "@types/yauzl": "^2.9.1", + "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": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "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=", + "dev": true + }, + "fast-glob": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.2.tgz", + "integrity": "sha512-UDV82o4uQyljznxwMxyVRJgZZt3O5wENYojjzbaGEGZgeOxkLFf+V4cnUD+krzb2F72E18RhamkMZ7AdeggF7A==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, + "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 + }, + "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 + }, + "fastq": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", + "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "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, + "requires": { + "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" + } + }, + "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==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "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==", + "dev": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "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, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "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": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "findup-sync": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", + "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", + "dev": true, + "requires": { + "glob": "~5.0.0" + }, + "dependencies": { + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "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": { + "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": "4.1.0", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", + "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "dev": true, + "requires": { + "is-buffer": "~2.0.3" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "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": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "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", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "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, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "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 + }, + "fs-extra": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.0.tgz", + "integrity": "sha512-pmEYSk3vYsG/bF651KPUXZ+hvjpgWYw/Gc7W9NFUe3ZVLczKKWIij3IKpOrQcdw4TILtibFslZ0UmR8Vvzig4g==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^1.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "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", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "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 + }, + "gaze": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", + "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "dev": true, + "requires": { + "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-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getobject": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz", + "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "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" + } + }, + "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==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "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, + "requires": { + "global-prefix": "^3.0.0" + } + }, + "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, + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + } + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "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 + } + } + }, + "globby": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.0.tgz", + "integrity": "sha512-iuehFnR3xu5wBBtm4xi0dMe92Ob87ufyu/dHwpDYfbcpYpIbrO5OnS8M1vWvrBhSGEJ3/Ecj7gnX76P8YxpPEg==", + "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", + "slash": "^3.0.0" + }, + "dependencies": { + "ignore": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", + "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "dev": true + } + } + }, + "globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=", + "dev": true + }, + "globule": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.1.tgz", + "integrity": "sha512-OVyWOHgw29yosRHCHo7NncwR1hW5ew0W/UrvtwvjefVJeQ26q4/8r8FmPsSF1hJ93IgWkyv16pCTz6WblMzm/g==", + "dev": true, + "requires": { + "glob": "~7.1.1", + "lodash": "~4.17.12", + "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" + } + }, + "got": { + "version": "11.1.4", + "resolved": "https://registry.npmjs.org/got/-/got-11.1.4.tgz", + "integrity": "sha512-z94KIXHhFSpJONuY6C6w1wC+igE7P1d0b5h3H2CvrOXn0/tum/OgFblIGUAxI5PBXukGLvKb9MJXVHW8vsYaBA==", + "dev": true, + "requires": { + "@sindresorhus/is": "^2.1.1", + "@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", + "decompress-response": "^6.0.0", + "get-stream": "^5.1.0", + "http2-wrapper": "^1.0.0-beta.4.5", + "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==", + "dev": true + }, + "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 + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "grunt": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.3.0.tgz", + "integrity": "sha512-6ILlMXv11/4cxuhSMfSU+SfvbxrPuqZrAtLN64+tZpQ3DAKfSQPQHRbTjSbdtxfyQhGZPtN0bDZJ/LdCM5WXXA==", + "dev": true, + "requires": { + "dateformat": "~3.0.3", + "eventemitter2": "~0.4.13", + "exit": "~0.1.2", + "findup-sync": "~0.3.0", + "glob": "~7.1.6", + "grunt-cli": "~1.3.2", + "grunt-known-options": "~1.1.0", + "grunt-legacy-log": "~3.0.0", + "grunt-legacy-util": "~2.0.0", + "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" + }, + "dependencies": { + "grunt-cli": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.3.2.tgz", + "integrity": "sha512-8OHDiZZkcptxVXtMfDxJvmN7MVJNE8L/yIcPb4HB7TlyFD1kDvjHrb62uhySsU14wJx9ORMnTuhRMQ40lH/orQ==", + "dev": true, + "requires": { + "grunt-known-options": "~1.1.0", + "interpret": "~1.1.0", + "liftoff": "~2.5.0", + "nopt": "~4.0.1", + "v8flags": "~3.1.1" + }, + "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" + } + } + } + }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + } + } + }, + "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==", + "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==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "eslint": "^7.0.0" + }, + "dependencies": { + "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==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + }, + "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 + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "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==", + "dev": true + }, + "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, + "requires": { + "colors": "~1.1.2", + "grunt-legacy-log-utils": "~2.1.0", + "hooker": "~0.2.3", + "lodash": "~4.17.19" + } + }, + "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, + "requires": { + "chalk": "~4.1.0", + "lodash": "~4.17.19" + }, + "dependencies": { + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "grunt-legacy-util": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-2.0.0.tgz", + "integrity": "sha512-ZEmYFB44bblwPE2oz3q3ygfF6hseQja9tx8I3UZIwbUik32FMWewA+d1qSFicMFB+8dNXDkh35HcDCWlpRsGlA==", + "dev": true, + "requires": { + "async": "~1.5.2", + "exit": "~0.1.1", + "getobject": "~0.1.0", + "hooker": "~0.2.3", + "lodash": "~4.17.20", + "underscore.string": "~3.3.5", + "which": "~1.3.0" + }, + "dependencies": { + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "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" + } + } + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "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==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "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 + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "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, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } + } + }, + "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 + }, + "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==", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "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 + }, + "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", + "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", + "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==", + "dev": true + }, + "html-tags": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz", + "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==", + "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" + } + }, + "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 + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "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==", + "dev": true, + "requires": { + "quick-lru": "^5.0.0", + "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==", + "dev": true, + "requires": { + "agent-base": "5", + "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": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "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==", + "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==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "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 + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "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=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "inquirer": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", + "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.5.3", + "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" + } + }, + "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, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "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==", + "requires": { + "color-name": "~1.1.4" + } + }, + "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==" + }, + "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 + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "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 + }, + "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 + }, + "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 + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "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, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "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 + }, + "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==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.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==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==" + } + } + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "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, + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "dev": true + }, + "is-alphanumeric": { + "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==", + "dev": true, + "requires": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "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, + "requires": { + "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.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "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-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "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==", + "dev": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "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 + }, + "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 + }, + "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==", + "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==", + "dev": true + }, + "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 + }, + "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 + }, + "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": { + "isobject": "^3.0.1" + } + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "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 + }, + "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": { + "is-unc-path": "^1.0.0" + } + }, + "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==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "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-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-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-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==", + "dev": true + }, + "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, + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "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", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "jake": { + "version": "10.6.1", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.6.1.tgz", + "integrity": "sha512-pHUK3+V0BjOb1XSi95rbBksrMdIqLVC9bJqDnshVyleYsET3H0XAq+3VB2E3notcYvv4wRdRHn13p7vobG+wfQ==", + "dev": true, + "requires": { + "async": "0.9.x", + "chalk": "^2.4.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" + } + }, + "async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", + "dev": true + }, + "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" + } + } + } + }, + "jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "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" + } + } + } + }, + "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==", + "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==", + "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" + } + } + } + }, + "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==", + "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", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + }, + "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" + } + } + } + }, + "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", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsdoctypeparser": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-9.0.0.tgz", + "integrity": "sha512-jrTA2jJIL6/DAEILBEh2/w9QxCuwmvNXIry39Ay/HVfhE3o2yVV0U44blYkqdHA/OKloJEqvJy0xU+GSdE2SIw==", + "dev": true + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "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 + }, + "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==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "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 + }, + "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 + }, + "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 + }, + "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.3.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.3.0.tgz", + "integrity": "sha512-b0EBt8SWFNnixVdvoR2ZtEGa9ZqLhbJnOjezn+WP+8kspFm+PFYDN8Z4Bc7pRlDjvuVcADSUkroIuTWWn/YiIA==", + "dev": true + }, + "jsonfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", + "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^1.0.0" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "keyv": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.1.tgz", + "integrity": "sha512-xz6Jv6oNkbhrFCvCP7HQa8AaII8y8LRpoSm661NOKLr4uHuBwhX4epXrPQgF3+xdJnN4Esm5X0xwY4bOlALOtw==", + "dev": true, + "requires": { + "json-buffer": "3.0.1" + } + }, + "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 + }, + "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==", + "dev": true + }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "dev": true, + "requires": { + "readable-stream": "^2.0.5" + }, + "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" + } + } + } + }, + "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 + }, + "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, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "liftoff": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", + "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=", + "dev": true, + "requires": { + "extend": "^3.0.0", + "findup-sync": "^2.0.0", + "fined": "^1.0.1", + "flagged-respawn": "^1.0.0", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.0", + "rechoir": "^0.6.2", + "resolve": "^1.1.7" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "findup-sync": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^3.1.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.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==", + "dev": true, + "requires": { + "debug": "^2.6.8", + "marky": "^1.2.0" + } + }, + "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=", + "dev": true + }, + "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, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "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": { + "p-locate": "^4.1.0" + } + }, + "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 + }, + "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 + }, + "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 + }, + "lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", + "dev": true + }, + "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 + }, + "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 + }, + "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 + }, + "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 + }, + "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 + }, + "lodash.pickby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", + "integrity": "sha1-feoh2MGNdwOifHBMFdO4SmfjOv8=", + "dev": true + }, + "lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", + "dev": true + }, + "lodash.zip": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", + "integrity": "sha1-7GZi5IlkCO1KtsVCo5kLcswIACA=", + "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==", + "dev": true, + "requires": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.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==", + "dev": true + }, + "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 + }, + "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 + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "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" + } + }, + "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": { + "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": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "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 + }, + "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==", + "dev": true, + "requires": { + "repeat-string": "^1.0.0" + } + }, + "marky": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/marky/-/marky-1.2.1.tgz", + "integrity": "sha512-md9k+Gxa3qLH6sUKpeC2CNkJK/Ld+bEz5X96nYwloqphQE0CKCVEKco/6jxEZixinqNdz5RFi/KaCyfbMDMAXQ==", + "dev": true + }, + "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 + }, + "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" + } + }, + "merge2": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", + "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "mime": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.5.tgz", + "integrity": "sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w==", + "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==", + "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==", + "dev": true, + "requires": { + "mime-db": "1.44.0" + } + }, + "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 + }, + "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 + }, + "min-indent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.0.tgz", + "integrity": "sha1-z8RcN+nsDY8KDsPdTvf3w6vjklY=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "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==", + "dev": true + }, + "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, + "requires": { + "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 + } + } + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "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" + } + }, + "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 + }, + "mocha": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.1.2.tgz", + "integrity": "sha512-o96kdRKMKI3E8U0bjnfqW4QMk12MwZ4mhdBTf+B5a1q9+aq2HRnj+3ZdJu0B/ZhJeK78MgYuv6L8d/rA5AeBJA==", + "dev": true, + "requires": { + "ansi-colors": "3.2.3", + "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", + "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" + }, + "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==", + "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" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "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" + } + }, + "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=", + "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==", + "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" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mwbot": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/mwbot/-/mwbot-1.0.10.tgz", + "integrity": "sha1-pEC9ZmOnYoq1t5lgnpjLL8ThM8k=", + "dev": true, + "requires": { + "bluebird": "^3.4.6", + "request": "^2.75.0", + "semlog": "^0.6.10" + } + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "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==", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + } + }, + "node-releases": { + "version": "1.1.56", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.56.tgz", + "integrity": "sha512-EVo605FhWLygH8a64TjgpjyHYOihkxECwX1bHHr8tETJKWEiWS2YJjPbvsX2jFjnjTNEgBCmk9mLjKG1Mf11cw==", + "dev": true + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "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, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "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 + }, + "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", + "integrity": "sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=", + "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==", + "dev": true + }, + "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", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "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-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "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": { + "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==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "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": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + } + }, + "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": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "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" + } + }, + "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==", + "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==", + "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" + } + }, + "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 + }, + "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, + "requires": { + "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==", + "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" + } + }, + "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": { + "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=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "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 + }, + "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 + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "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 + }, + "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 + }, + "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 + }, + "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==", + "dev": true + }, + "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": { + "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": "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" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "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, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "postcss": { + "version": "7.0.30", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.30.tgz", + "integrity": "sha512-nu/0m+NtIzoubO+xdAlwZl/u5S5vi/y6BCsoL8D+8IxsD3XvBS8X4YEADNIVXKVuQvduiucnRv+vPIqj56EGMQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.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" + }, + "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" + } + } + } + }, + "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 + }, + "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 + }, + "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==", + "dev": true, + "requires": { + "has-flag": "^3.0.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==", + "dev": true, + "requires": { + "htmlparser2": "^3.10.0" + } + }, + "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" + } + }, + "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 + }, + "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", + "integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=", + "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" + } + }, + "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==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + }, + "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==", + "dev": true + }, + "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 + }, + "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==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "pretty-ms": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.0.tgz", + "integrity": "sha512-J3aPWiC5e9ZeZFuSeBraGxSkGMOvulSWsxDByOcbD1Pr75YL3LSNIKIb52WXbCLE1sS5s4inBBbryjF4Y05Ceg==", + "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=", + "dev": true, + "requires": { + "colors": "^1.1.2", + "minimist": "^1.2.0" + } + }, + "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 + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "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 + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "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 + }, + "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, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "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 + }, + "puppeteer-core": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-3.1.0.tgz", + "integrity": "sha512-o0dlA3g+Dzc8mrKvCrlmn79upNhLfTQwtnPbS4hxuH6tWOwFFEbet8WHtYjQbUPZOqIt0GmoyM93VQKm6ogO+Q==", + "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" + }, + "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 + } + } + }, + "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 + }, + "quick-lru": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.0.tgz", + "integrity": "sha512-WjAKQ9ORzvqjLijJXiXWqc3Gcs1ivoxCj6KJmEjoWBE6OtHwuaDLSAUqGHALUiid7A1KqGqsSHZs8prxF5xxAQ==", + "dev": true + }, + "ramda": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz", + "integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==", + "dev": true + }, + "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==", + "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" + }, + "dependencies": { + "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" + } + }, + "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" + } + } + } + }, + "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, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "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==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "^1.1.6" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "regextras": { + "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==", + "dev": true, + "requires": { + "remark-parse": "^8.0.0", + "remark-stringify": "^8.0.0", + "unified": "^9.0.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==", + "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" + } + }, + "remark-stringify": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-8.0.0.tgz", + "integrity": "sha512-cABVYVloFH+2ZI5bdqzoOmemcz/ZuhQSH6W6ZNYnLojAUUn3xtX7u+6BpnYp35qHoGr2NFBsERV14t4vCIeW8w==", + "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" + } + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "dev": true + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } + } + }, + "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 + }, + "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==", + "dev": true + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-alpn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.0.0.tgz", + "integrity": "sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA==", + "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" + } + } + } + }, + "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 + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "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, + "requires": { + "lowercase-keys": "^2.0.0" + } + }, + "resq": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/resq/-/resq-1.7.1.tgz", + "integrity": "sha512-09u9Q5SAuJfAW5UoVAmvRtLvCOMaKP+djiixTXsZvPaojGKhuvc0Nfvp84U1rIfopJWEOXi5ywpCFwCk7mj8Xw==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1" + } + }, + "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, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rgb2hex": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.1.10.tgz", + "integrity": "sha512-vKz+kzolWbL3rke/xeTE2+6vHmZnNxGyDnaVW4OckntAIcc7DcZzWkQSfxMDwqHS8vhgySnIFyBUH7lIk6PxvQ==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "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 + }, + "rxjs": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", + "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "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 + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semlog": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/semlog/-/semlog-0.6.10.tgz", + "integrity": "sha1-DyJa6o6zwvJM6TWNhnjQ9Bp/4Fs=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "prettyjson": "^1.1.3" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "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" + } + }, + "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, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "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 + } + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "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==", + "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 + } + } + }, + "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-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "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, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "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 + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "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, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "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 + }, + "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, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "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==", + "dev": true + }, + "specificity": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz", + "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "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" + } + }, + "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 + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "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 + }, + "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==", + "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.trimleft": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", + "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "string.prototype.trimstart": "^1.0.0" + } + }, + "string.prototype.trimright": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", + "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "string.prototype.trimend": "^1.0.0" + } + }, + "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": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "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, + "requires": { + "is-utf8": "^0.2.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=", + "dev": true + }, + "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 + }, + "stylelint": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.3.2.tgz", + "integrity": "sha512-kpO3/Gz2ZY40EWUwFYYkgpzhf8ZDUyKpcui5+pS0XKJBj/EMYmZpOJoL8IFAz2yApYeg91NVy5yAjE39hDzWvQ==", + "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", + "execall": "^2.0.0", + "file-entry-cache": "^5.0.1", + "get-stdin": "^7.0.0", + "global-modules": "^2.0.0", + "globby": "^11.0.0", + "globjoin": "^0.1.4", + "html-tags": "^3.1.0", + "ignore": "^5.1.4", + "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", + "mathml-tag-names": "^2.1.3", + "meow": "^6.1.0", + "micromatch": "^4.0.2", + "normalize-selector": "^0.2.0", + "postcss": "^7.0.27", + "postcss-html": "^0.36.0", + "postcss-less": "^3.1.4", + "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", + "resolve-from": "^5.0.0", + "slash": "^3.0.0", + "specificity": "^0.4.1", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "style-search": "^0.1.0", + "sugarss": "^2.0.0", + "svg-tags": "^1.0.0", + "table": "^5.4.6", + "v8-compile-cache": "^2.1.0", + "write-file-atomic": "^3.0.3" + }, + "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.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", + "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "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==", + "dev": true + }, + "meow": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-6.1.1.tgz", + "integrity": "sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==", + "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": { + "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": { + "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==", + "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-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==", + "dev": true, + "requires": { + "stylelint": "13.3.2" + } + }, + "suffix": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/suffix/-/suffix-0.1.1.tgz", + "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==", + "dev": true, + "requires": { + "postcss": "^7.0.2" + } + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", + "dev": true + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.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" + } + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "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==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.0.0" + } + }, + "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==", + "dev": true, + "requires": { + "bl": "^4.0.1", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + }, + "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 + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "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-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "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, + "requires": { + "is-number": "^7.0.0" + } + }, + "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, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "trim": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", + "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", + "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==", + "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==", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "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, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "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==", + "dev": true + }, + "unbzip2-stream": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.2.tgz", + "integrity": "sha512-pZMVAofMrrHX6Ik39hCk470kulCbmZ2SWfQLPmTWqfJV/oUm0gn1CblvHdUu4+54Je6Jq34x8kY6XjTy6dMkOg==", + "dev": true, + "requires": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "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 + }, + "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" + } + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "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==", + "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==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + }, + "universalify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", + "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "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==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.1.0.tgz", + "integrity": "sha512-CI18flHDznR0lq54xBycOVmphdCYnQLKn8abKn7PXUiKUGdEd+/l9LWNJmugXel4hXq7S+RMNl34ecyC9TntWg==", + "dev": true + }, + "v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "dev": true + }, + "v8flags": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", + "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==", + "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", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "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.8.3", + "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.8.3.tgz", + "integrity": "sha512-8yPag/NQHCuTthahyaTtzK0DHT0FKM/xBU0mFBQ8nMo8C1i2P+FCyIVqICoNoHkRI2BTGlXKomPUpsqjSz0TnQ==", + "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" + }, + "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" + } + }, + "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" + } + }, + "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 + } + } + }, + "wcwidth": { + "version": "1.0.1", + "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==", + "dev": true, + "requires": { + "mwbot": "1.0.10" + } + }, + "webdriver": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-6.1.11.tgz", + "integrity": "sha512-CWCsTSz4J5uSQD8PHtDyHCdzqWr/8GD9feesJSiftHvauegikTFCC8nUtI68EfYlNO5gYpnI0eF90prKTz8SnA==", + "dev": true, + "requires": { + "@wdio/config": "6.1.2", + "@wdio/logger": "6.0.16", + "@wdio/protocols": "6.1.11", + "@wdio/utils": "6.1.8", + "got": "^11.0.2", + "lodash.merge": "^4.6.1" + } + }, + "webdriverio": { + "version": "6.1.12", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-6.1.12.tgz", + "integrity": "sha512-i3x6x3CSRl2CkYFWvuvhf1NcUbBZeTuw6jdLiHUB3OaxdoP/nCuCzTx2ZT9uhZgZNDk081tK0auJBGF0S9p+ow==", + "dev": true, + "requires": { + "@wdio/config": "6.1.2", + "@wdio/logger": "6.0.16", + "@wdio/repl": "6.1.8", + "@wdio/utils": "6.1.8", + "archiver": "^4.0.1", + "css-value": "^0.0.1", + "devtools": "6.1.11", + "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.1.0", + "serialize-error": "^7.0.0", + "webdriver": "6.1.11" + } + }, + "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" + } + }, + "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==", + "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" + } + } + } + }, + "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 + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "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==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "ws": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz", + "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "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==", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yaml": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", + "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==", + "dev": true + }, + "yargs": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", + "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", + "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" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "dev": true, + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.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==", + "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=", + "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=", + "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" + } + } + } + }, + "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, + "requires": { + "cac": "^3.0.3", + "chalk": "^1.1.3", + "cross-spawn": "^4.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "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" + } + }, + "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" + } + }, + "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, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "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 + } + } + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "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==", + "dev": true, + "requires": { + "archiver-utils": "^2.1.0", + "compress-commons": "^3.0.0", + "readable-stream": "^3.6.0" + } + } + } +} diff --git a/AbuseFilter/package.json b/AbuseFilter/package.json index 4745d1fd..14ba346d 100644 --- a/AbuseFilter/package.json +++ b/AbuseFilter/package.json @@ -2,17 +2,23 @@ "private": true, "description": "Build tools for the AbuseFilter mediawiki extension.", "scripts": { - "test": "grunt test" + "test": "grunt test", + "selenium-daily": "npm run selenium-test", + "selenium-test": "wdio tests/selenium/wdio.conf.js" }, "devDependencies": { - "eslint-config-wikimedia": "0.7.2", - "eslint-plugin-qunit": "3.3.1", - "grunt": "1.0.3", - "grunt-banana-checker": "0.6.0", - "grunt-eslint": "21.0.0", - "grunt-jsonlint": "1.1.0", - "grunt-stylelint": "0.10.0", - "stylelint": "9.2.0", - "stylelint-config-wikimedia": "0.4.3" + "@wdio/cli": "6.1.12", + "@wdio/local-runner": "6.1.12", + "@wdio/mocha-framework": "6.1.8", + "@wdio/spec-reporter": "6.1.12", + "@wdio/sync": "6.1.8", + "eslint-config-wikimedia": "0.17.0", + "grunt": "1.3.0", + "grunt-banana-checker": "0.9.0", + "grunt-eslint": "23.0.0", + "grunt-stylelint": "0.15.0", + "stylelint-config-wikimedia": "0.10.1", + "wdio-mediawiki": "1.0.0", + "webdriverio": "6.1.12" } } diff --git a/AbuseFilter/tests/legacyParserTest.php b/AbuseFilter/tests/legacyParserTest.php deleted file mode 100644 index c3055c15..00000000 --- a/AbuseFilter/tests/legacyParserTest.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php -/** - * Runs tests against the PHP parser. - */ - -require_once getenv( 'MW_INSTALL_PATH' ) !== false - ? getenv( 'MW_INSTALL_PATH' ) . "/maintenance/commandLine.inc" - : __DIR__ . '/../../../maintenance/commandLine.inc'; - -$tester = new AbuseFilterParser; - -$test_path = __DIR__ . "/parserTests"; -$tests = glob( $test_path . "/*.t" ); - -$check = 0; -$pass = 0; - -foreach ( $tests as $test ) { - $result = substr( $test, 0, -2 ) . ".r"; - - $rule = trim( file_get_contents( $test ) ); - $output = trim( file_get_contents( $result ) ) == 'MATCH'; - - $testname = basename( $test ); - - print "Trying test $testname...\n"; - - try { - $check++; - $actual = intval( $tester->parse( $rule ) ); - - if ( $actual == $output ) { - print "-PASSED.\n"; - $pass++; - } else { - print "-FAILED - expected output $output, actual output $actual.\n"; - print "-Expression: $rule\n"; - - // export - $vars = var_export( $tester->mTokens, true ); - file_put_contents( $test . '.parsed', $vars ); - } - } catch ( AFPException $excep ) { - print "-FAILED - exception " . $excep->getMessage() . " with input $rule\n"; - - // export - $vars = var_export( $tester->mTokens, true ); - file_put_contents( $test . '.parsed', $vars ); - } -} - -print "$pass tests passed out of $check\n"; diff --git a/AbuseFilter/tests/parserTests/almost-empty.r b/AbuseFilter/tests/parserTests/almost-empty.r deleted file mode 100644 index 8093d2ab..00000000 --- a/AbuseFilter/tests/parserTests/almost-empty.r +++ /dev/null @@ -1 +0,0 @@ -NOT_MATCH diff --git a/AbuseFilter/tests/parserTests/almost-empty.t b/AbuseFilter/tests/parserTests/almost-empty.t deleted file mode 100644 index e57b08b4..00000000 --- a/AbuseFilter/tests/parserTests/almost-empty.t +++ /dev/null @@ -1 +0,0 @@ -;;;; diff --git a/AbuseFilter/tests/parserTests/arith.r b/AbuseFilter/tests/parserTests/arith.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/arith.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/arith.t b/AbuseFilter/tests/parserTests/arith.t index 1f88e9df..a0faca87 100644 --- a/AbuseFilter/tests/parserTests/arith.t +++ b/AbuseFilter/tests/parserTests/arith.t @@ -1,3 +1,6 @@ ++1 + -1 === 0 & +-1 + +2 === 1 & +-0 === 0 & (1 + 1 === 2) & (1.5 + 1.5 === 3.0) & (2.5 + 1 === 3.5) & @@ -24,4 +27,4 @@ (2 ** 4 === 16) & (2.5 ** 2 === 6.25) & (2.5 ** 0 === 1.0) & -(1000 ** 0 === 1)
\ No newline at end of file +(1000 ** 0 === 1) diff --git a/AbuseFilter/tests/parserTests/array-assignment.r b/AbuseFilter/tests/parserTests/array-assignment.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/array-assignment.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/array-assignment.t b/AbuseFilter/tests/parserTests/array-assignment.t index a22294e3..42378a9e 100644 --- a/AbuseFilter/tests/parserTests/array-assignment.t +++ b/AbuseFilter/tests/parserTests/array-assignment.t @@ -1,6 +1,7 @@ -test_array := [ [1, 2], [3, 4] ]; +test_array := [ [1, 2], [3, 4], 'useless' ]; test_array[1] := 42; +test_array[ if true then 2 else 0 end] := 'foo'; test_array[] := 17; -test_array[0][0] == 1 & test_array[0][1] == 2 & test_array[1] == 42 & test_array[2] == 17 +test_array[0][0] == 1 & test_array[0][1] == 2 & test_array[1] == 42 & test_array[2] === 'foo' & test_array[3] == 17 diff --git a/AbuseFilter/tests/parserTests/array-comparisons.r b/AbuseFilter/tests/parserTests/array-comparisons.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/array-comparisons.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/array-comparisons.t b/AbuseFilter/tests/parserTests/array-comparisons.t index dc6122f5..0d41b89c 100644 --- a/AbuseFilter/tests/parserTests/array-comparisons.t +++ b/AbuseFilter/tests/parserTests/array-comparisons.t @@ -10,6 +10,9 @@ i := [['1', 2], '3']; j := [1]; k := ['1']; l := []; +m := 42; +n := [0,1]; a == b & a === b & a != c & b != d & a == e & a !== e & f == g & f !== g & h == i & h !== i & e != i & j != 1 & -k != '1' & l == false & l == null & l !== false & l !== null & false == l & null == l & false !== l & null !== l +k != '1' & l == false & l == null & l !== false & l !== null & false == l & null == l & false !== l & null !== l & +b[5**2/((4+1)*5)] == a[43-m] & a[n[0]] === b[n[m-42]] diff --git a/AbuseFilter/tests/parserTests/array-statements.t b/AbuseFilter/tests/parserTests/array-statements.t new file mode 100644 index 00000000..7bc7287c --- /dev/null +++ b/AbuseFilter/tests/parserTests/array-statements.t @@ -0,0 +1,3 @@ +/* CachingParser's intEval used to return AFPTreeNode for this */ +var := [1]; +var[0] := 2;
\ No newline at end of file diff --git a/AbuseFilter/tests/parserTests/array-statements2.t b/AbuseFilter/tests/parserTests/array-statements2.t new file mode 100644 index 00000000..5e7479d2 --- /dev/null +++ b/AbuseFilter/tests/parserTests/array-statements2.t @@ -0,0 +1,3 @@ +/* CachingParser's intEval used to return AFPTreeNode for this */ +var := [1]; +var[0] := str_replace('a','b','c');
\ No newline at end of file diff --git a/AbuseFilter/tests/parserTests/array-statements3.t b/AbuseFilter/tests/parserTests/array-statements3.t new file mode 100644 index 00000000..239fbfa4 --- /dev/null +++ b/AbuseFilter/tests/parserTests/array-statements3.t @@ -0,0 +1,3 @@ +/* CachingParser's intEval used to return AFPTreeNode for this - T236870 */ +a := []; +a[] := 2;
\ No newline at end of file diff --git a/AbuseFilter/tests/parserTests/arrays.r b/AbuseFilter/tests/parserTests/arrays.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/arrays.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/atombraces.r b/AbuseFilter/tests/parserTests/atombraces.r deleted file mode 100644 index f4efce9f..00000000 --- a/AbuseFilter/tests/parserTests/atombraces.r +++ /dev/null @@ -1 +0,0 @@ -NOT MATCH diff --git a/AbuseFilter/tests/parserTests/atombraces.t b/AbuseFilter/tests/parserTests/atombraces.t deleted file mode 100644 index 5bb50190..00000000 --- a/AbuseFilter/tests/parserTests/atombraces.t +++ /dev/null @@ -1 +0,0 @@ -( ) diff --git a/AbuseFilter/tests/parserTests/bool-assoc.r b/AbuseFilter/tests/parserTests/bool-assoc.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/bool-assoc.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/bug25373.r b/AbuseFilter/tests/parserTests/bug25373.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/bug25373.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/cast.r b/AbuseFilter/tests/parserTests/cast.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/cast.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/cast.t b/AbuseFilter/tests/parserTests/cast.t index c0bc317c..e13803d6 100644 --- a/AbuseFilter/tests/parserTests/cast.t +++ b/AbuseFilter/tests/parserTests/cast.t @@ -1 +1,17 @@ -(string(1) === "1") & (int("1") === 1) & (float(1) === 1.0) & bool(1) & !bool(0) +(string(1) === "1") & +(int("1") === 1) & +(float(1) === 1.0) & +bool(1) & !bool(0) & +bool([]) === false & +bool( [false] ) === true & +bool( [1,2,3,4,5,6] ) === true & +float([]) === 0.0 & +float( [false] ) === 1.0 & +float( [1,2,3,4,5,6] ) === 6.0 & +int([]) === 0 & +int( [false] ) === 1 & +int( [1,2,3,4,5,6] ) === 6 & +true + true === 2 & +null - null === 0 & +true * false === 0 & +163 % true === 0 diff --git a/AbuseFilter/tests/parserTests/ccnorm-contains-all.r b/AbuseFilter/tests/parserTests/ccnorm-contains-all.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/ccnorm-contains-all.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/ccnorm-contains-any.r b/AbuseFilter/tests/parserTests/ccnorm-contains-any.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/ccnorm-contains-any.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/ccnorm.r b/AbuseFilter/tests/parserTests/ccnorm.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/ccnorm.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/comment.r b/AbuseFilter/tests/parserTests/comment.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/comment.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/concatenation.r b/AbuseFilter/tests/parserTests/concatenation.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/concatenation.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/conditional-shortcircuit.t b/AbuseFilter/tests/parserTests/conditional-shortcircuit.t new file mode 100644 index 00000000..39b2f8ae --- /dev/null +++ b/AbuseFilter/tests/parserTests/conditional-shortcircuit.t @@ -0,0 +1,69 @@ +if ( 1 === 1 ) then +( var1 := 1 ) +else +( var1 := 2 ) +end; + +var2 := 0; +if ( 1 === 1 ) then +( var2 := 1 ) +else +( var2 := 2 ) +end; + +var4 := 'foo'; +if ( 1=== 1 ) then +( var3 := 1; false & ( var4 := 'foobar' ) ) +else +( var3 := 2 ) +end; + +if ( 1 === 1 ) then +( var5 := 1 ) +else +( ( ( var5 := 2 ) ) ) +end; + + +if ( 1 === 1 ) then +( var6 := 1 ) +else +( + if ( 1 == 1 ) then + ( var6 := 2 ) + else + ( var6 := 3 ) + end; +) +end; + + +var7 := 'foo'; +if ( 1=== 1 ) then +(0) +else +( false & ( var7 := 'foobar' ) ) +end; + +var8 := 'foo'; +false & ( + if ( 1 == 1 ) then + (var8 := 3) + else + (var8 := 4) + end; +); + +var9 := 'foo'; +if ( 1=== 1 ) then + ( false & ( var9 := 'foobar' ) ) +end; + +var1 === 1 & +var2 === 1 & +var3 === 1 & +var5 === 1 & +var6 === 1 & +var7 === 'foo' & +var8 === 'foo' & +var9 === 'foo' diff --git a/AbuseFilter/tests/parserTests/contains-all.r b/AbuseFilter/tests/parserTests/contains-all.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/contains-all.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/contains-all.t b/AbuseFilter/tests/parserTests/contains-all.t index f8b81b24..c3980d13 100644 --- a/AbuseFilter/tests/parserTests/contains-all.t +++ b/AbuseFilter/tests/parserTests/contains-all.t @@ -1 +1,10 @@ -contains_all("the foo is on the bar", "foo", "is on", "bar") & !(contains_all(['foo', 'bar', 'hey'], 'foo', 'bar', 'sup')) & contains_all([1, 2, 3], '1', '2', '3')
\ No newline at end of file +contains_all("the foo is on the bar", "foo", "is on", "bar") & +!(contains_all(['foo', 'bar', 'hey'], 'foo', 'bar', 'sup')) & +contains_all([1, 2, 3], '1', '2', '3') & +contains_all( + 'base', + 'b', + 'a', + 's', + 'e', +) diff --git a/AbuseFilter/tests/parserTests/contains-any.r b/AbuseFilter/tests/parserTests/contains-any.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/contains-any.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/contains-any.t b/AbuseFilter/tests/parserTests/contains-any.t index 56f1c8bd..fc9445ff 100644 --- a/AbuseFilter/tests/parserTests/contains-any.t +++ b/AbuseFilter/tests/parserTests/contains-any.t @@ -1 +1,4 @@ -contains_any("like anyone else", "else", "someone") & contains_any("street fighter", "fight") & !(contains_any('My foo is cute', 'bar', 'wtf')) & contains_any([[1], [2,3]], 1) +contains_any("like anyone else", "else", "someone") & +contains_any("street fighter", "fight") & +!(contains_any('My foo is cute', 'bar', 'wtf')) & +contains_any([[1], [2,3]], 1) diff --git a/AbuseFilter/tests/parserTests/contains.r b/AbuseFilter/tests/parserTests/contains.r deleted file mode 100644 index f629599c..00000000 --- a/AbuseFilter/tests/parserTests/contains.r +++ /dev/null @@ -1 +0,0 @@ -MATCH
\ No newline at end of file diff --git a/AbuseFilter/tests/parserTests/containsfunction.r b/AbuseFilter/tests/parserTests/containsfunction.r deleted file mode 100644 index f629599c..00000000 --- a/AbuseFilter/tests/parserTests/containsfunction.r +++ /dev/null @@ -1 +0,0 @@ -MATCH
\ No newline at end of file diff --git a/AbuseFilter/tests/parserTests/count.r b/AbuseFilter/tests/parserTests/count.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/count.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/dundefined-parens.t b/AbuseFilter/tests/parserTests/dundefined-parens.t new file mode 100644 index 00000000..6edf03b4 --- /dev/null +++ b/AbuseFilter/tests/parserTests/dundefined-parens.t @@ -0,0 +1 @@ +false | (var := 'foo')
\ No newline at end of file diff --git a/AbuseFilter/tests/parserTests/dundefined.t b/AbuseFilter/tests/parserTests/dundefined.t new file mode 100644 index 00000000..aac08390 --- /dev/null +++ b/AbuseFilter/tests/parserTests/dundefined.t @@ -0,0 +1 @@ +old_wikitext | true diff --git a/AbuseFilter/tests/parserTests/empty.r b/AbuseFilter/tests/parserTests/empty.r deleted file mode 100644 index 8093d2ab..00000000 --- a/AbuseFilter/tests/parserTests/empty.r +++ /dev/null @@ -1 +0,0 @@ -NOT_MATCH diff --git a/AbuseFilter/tests/parserTests/empty.t b/AbuseFilter/tests/parserTests/empty.t deleted file mode 100644 index e69de29b..00000000 --- a/AbuseFilter/tests/parserTests/empty.t +++ /dev/null diff --git a/AbuseFilter/tests/parserTests/eq.r b/AbuseFilter/tests/parserTests/eq.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/eq.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/equals-to-any.r b/AbuseFilter/tests/parserTests/equals-to-any.r deleted file mode 100644 index f629599c..00000000 --- a/AbuseFilter/tests/parserTests/equals-to-any.r +++ /dev/null @@ -1 +0,0 @@ -MATCH
\ No newline at end of file diff --git a/AbuseFilter/tests/parserTests/equals-to-any.t b/AbuseFilter/tests/parserTests/equals-to-any.t index e10220ca..c46462af 100644 --- a/AbuseFilter/tests/parserTests/equals-to-any.t +++ b/AbuseFilter/tests/parserTests/equals-to-any.t @@ -1,4 +1,13 @@ equals_to_any( "foo", "bar", "foo", "pizza" ) & equals_to_any( 15, 3, 77, 18, 15 ) & equals_to_any( "", 3, 77, 18, 15, "duh" ) === false & -equals_to_any( "", 3, 77, 18, 15, "duh", "" )
\ No newline at end of file +equals_to_any( "", 3, 77, 18, 15, "duh", "" ) & +equals_to_any( true, 1, "true" ) === false & +equals_to_any( "1", 1, [ 1 ], true ) === false & +equals_to_any( [ 1, "1" ], 1, "1" ) === false & +equals_to_any( [ 1, 2, 3 ], [ 1, 2, 3 ] ) & +equals_to_any( [ 1, 2, 3 ], [ 3, 2, 1 ] ) === false & +equals_to_any( [ "foo", "bar" ], [ ] ) === false & +equals_to_any( [ "foo", "bar" ], [ "foo", "bar" ] ) & +equals_to_any( [], [] ) & +equals_to_any( [ 0 ], [] ) === false diff --git a/AbuseFilter/tests/parserTests/expn.r b/AbuseFilter/tests/parserTests/expn.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/expn.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/float.r b/AbuseFilter/tests/parserTests/float.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/float.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/get-matches.r b/AbuseFilter/tests/parserTests/get-matches.r deleted file mode 100644 index f629599c..00000000 --- a/AbuseFilter/tests/parserTests/get-matches.r +++ /dev/null @@ -1 +0,0 @@ -MATCH
\ No newline at end of file diff --git a/AbuseFilter/tests/parserTests/get-matches.t b/AbuseFilter/tests/parserTests/get-matches.t index 88e163b4..45c4ac85 100644 --- a/AbuseFilter/tests/parserTests/get-matches.t +++ b/AbuseFilter/tests/parserTests/get-matches.t @@ -1,4 +1,5 @@ -/* More complete tests for get_matches are in AbuseFilterParserTest.php */ -a := get_matches('I am a (dog|cat)', 'What did you say?'); +get_matches('I am a (dog|cat)', 'What did you say?') === [ false, false ] & get_matches('The (truth|pineapple) is (?:rarely)? pure and (nee*v(ah|er) sh?imple)', 'The truth is rarely pure and never simple, Wilde said') == ['The truth is rarely pure and never simple', 'truth', 'never simple', 'er'] & -a === [false, false]
\ No newline at end of file +get_matches('You say (.*) \(and I say (.*)\)\.', 'You say hello (and I say goodbye).') === [ 'You say hello (and I say goodbye).', 'hello', 'goodbye' ] & +get_matches('I(?: am)? the ((walrus|egg man).*)\!', 'I am the egg man, I am the walrus !') === [ 'I am the egg man, I am the walrus !', 'egg man, I am the walrus ', 'egg man' ] & +get_matches('this (does) not match', 'foo bar') === [ false, false ]
\ No newline at end of file diff --git a/AbuseFilter/tests/parserTests/ifthen.r b/AbuseFilter/tests/parserTests/ifthen.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/ifthen.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/ifthen.t b/AbuseFilter/tests/parserTests/ifthen.t index c22a3947..ce3e0aa3 100644 --- a/AbuseFilter/tests/parserTests/ifthen.t +++ b/AbuseFilter/tests/parserTests/ifthen.t @@ -1,2 +1,4 @@ (if 1 then 2 else 3 end) === 2 & -(if false then 2 else 3 end) === 3 +(if false then 2 else 3 end) === 3 & +(if true then 3 end) === 3 & +(if false then 3 end) === null diff --git a/AbuseFilter/tests/parserTests/in.r b/AbuseFilter/tests/parserTests/in.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/in.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/ip-in-range.t b/AbuseFilter/tests/parserTests/ip-in-range.t new file mode 100644 index 00000000..782ea83c --- /dev/null +++ b/AbuseFilter/tests/parserTests/ip-in-range.t @@ -0,0 +1,5 @@ +ip_in_range( '12.34.56.78', '12.34.56.0/24' ) & +ip_in_range( '12.34.56.78', '12.34.0.0/16' ) & +ip_in_range( '12.34.56.78', '12.0.0.0/8' ) & +ip_in_range( '1.1.1.1', '1.1.1.1/32' ) & +ip_in_range( '1.1.1.1', '0.0.0.0/1' )
\ No newline at end of file diff --git a/AbuseFilter/tests/parserTests/lazyboolinvert.r b/AbuseFilter/tests/parserTests/lazyboolinvert.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/lazyboolinvert.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/lazyfunction.r b/AbuseFilter/tests/parserTests/lazyfunction.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/lazyfunction.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/lazykeyword.r b/AbuseFilter/tests/parserTests/lazykeyword.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/lazykeyword.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/lazypow.r b/AbuseFilter/tests/parserTests/lazypow.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/lazypow.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/lazysum.r b/AbuseFilter/tests/parserTests/lazysum.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/lazysum.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/lazyunarys.r b/AbuseFilter/tests/parserTests/lazyunarys.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/lazyunarys.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/lcase.r b/AbuseFilter/tests/parserTests/lcase.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/lcase.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/length.r b/AbuseFilter/tests/parserTests/length.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/length.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/like.r b/AbuseFilter/tests/parserTests/like.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/like.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/multipleconditionals.t b/AbuseFilter/tests/parserTests/multipleconditionals.t new file mode 100644 index 00000000..74a7b9fb --- /dev/null +++ b/AbuseFilter/tests/parserTests/multipleconditionals.t @@ -0,0 +1,28 @@ +/* For T152281 */ +v1 := 0; v2 := 0; +if ( 1 == 1 ) then +( + v1 := 1; v2 := 1; +) +else +( + v1 := 2; v2 := 2; +) +end; + +if ( 1 == 1 ) then + ( v1 := 1; ) +else +( + v1 := 2; v2 := 2; +) +end; + +if ( 1 == 1 ) then + ( v1 := 2 === 2 ? 1 : 3; ) +else +( + v1 := 'x' === 'y' ? 2 : 3; + v2 := v1 ** 2; +) +end; diff --git a/AbuseFilter/tests/parserTests/multipleskipbraces.r b/AbuseFilter/tests/parserTests/multipleskipbraces.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/multipleskipbraces.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/mwexamples-arithmetic.r b/AbuseFilter/tests/parserTests/mwexamples-arithmetic.r deleted file mode 100644 index f629599c..00000000 --- a/AbuseFilter/tests/parserTests/mwexamples-arithmetic.r +++ /dev/null @@ -1 +0,0 @@ -MATCH
\ No newline at end of file diff --git a/AbuseFilter/tests/parserTests/mwexamples-arrays.r b/AbuseFilter/tests/parserTests/mwexamples-arrays.r deleted file mode 100644 index f629599c..00000000 --- a/AbuseFilter/tests/parserTests/mwexamples-arrays.r +++ /dev/null @@ -1 +0,0 @@ -MATCH
\ No newline at end of file diff --git a/AbuseFilter/tests/parserTests/mwexamples-arrays.t b/AbuseFilter/tests/parserTests/mwexamples-arrays.t index 91538fed..fb589e83 100644 --- a/AbuseFilter/tests/parserTests/mwexamples-arrays.t +++ b/AbuseFilter/tests/parserTests/mwexamples-arrays.t @@ -1,10 +1,18 @@ -/* Examples from [[mw:Extension:AbuseFilter/Rules format#Lists]] */ +/* Examples from [[mw:Extension:AbuseFilter/Rules format#Arrays]] */ -a_array := [ 5, 6, 7, 10]; -a_array[0] == 5 & -length(a_array) == 4 & -string(a_array) == "5\n6\n7\n10\n" & -5 in a_array == true & -'5' in a_array == true & -'5\n6' in a_array == true & -1 in a_array == true
\ No newline at end of file +my_array := [ 5, 6, 7, 10]; +my_array[0] == 5 & +length(my_array) == 4 & +int( my_array ) === 4 & +float( my_array ) === 4.0 & +string(my_array) == "5\n6\n7\n10\n" & +5 in my_array == true & +'5' in my_array == true & +'5\n6' in my_array == true & +1 in my_array == true & ( +my_array[] := 57; +my_array === [ 5, 6, 7, 10, 57 ] +) & ( +my_array[2] := 42; +my_array === [ 5, 6, 42, 10, 57 ] +) diff --git a/AbuseFilter/tests/parserTests/mwexamples-bools.r b/AbuseFilter/tests/parserTests/mwexamples-bools.r deleted file mode 100644 index f629599c..00000000 --- a/AbuseFilter/tests/parserTests/mwexamples-bools.r +++ /dev/null @@ -1 +0,0 @@ -MATCH
\ No newline at end of file diff --git a/AbuseFilter/tests/parserTests/mwexamples-comparisons.r b/AbuseFilter/tests/parserTests/mwexamples-comparisons.r deleted file mode 100644 index f629599c..00000000 --- a/AbuseFilter/tests/parserTests/mwexamples-comparisons.r +++ /dev/null @@ -1 +0,0 @@ -MATCH
\ No newline at end of file diff --git a/AbuseFilter/tests/parserTests/mwexamples-functions.r b/AbuseFilter/tests/parserTests/mwexamples-functions.r deleted file mode 100644 index f629599c..00000000 --- a/AbuseFilter/tests/parserTests/mwexamples-functions.r +++ /dev/null @@ -1 +0,0 @@ -MATCH
\ No newline at end of file diff --git a/AbuseFilter/tests/parserTests/mwexamples-keywords.r b/AbuseFilter/tests/parserTests/mwexamples-keywords.r deleted file mode 100644 index f629599c..00000000 --- a/AbuseFilter/tests/parserTests/mwexamples-keywords.r +++ /dev/null @@ -1 +0,0 @@ -MATCH
\ No newline at end of file diff --git a/AbuseFilter/tests/parserTests/norm.r b/AbuseFilter/tests/parserTests/norm.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/norm.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/numbers.r b/AbuseFilter/tests/parserTests/numbers.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/numbers.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/numbers.t b/AbuseFilter/tests/parserTests/numbers.t index 1959a0fe..da9474b4 100644 --- a/AbuseFilter/tests/parserTests/numbers.t +++ b/AbuseFilter/tests/parserTests/numbers.t @@ -1 +1,9 @@ -ax = 10 & Fx = 15 & 10o = 8 & 10b = 2 +/* Things that are NOT numbers; */ +0xfoo := 'foobar'; +0b10bar := 'bar'; + +0xfoo === 'foobar' & 0b10bar === 'bar' & + +/* Actual numbers */ +0x1A === 0x1a & 0x1a === 26 & 0xa === 10 & 0b11111111 === 255 & 0o123 === 83 & 0x123 === 291 & 0xF === 15 & +0o10 === 8 & 0o1 === 1 & 0b101010 === 42 & 0b101010 === 0x2a & 0x2a === 0o52 diff --git a/AbuseFilter/tests/parserTests/ord.r b/AbuseFilter/tests/parserTests/ord.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/ord.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/prec.r b/AbuseFilter/tests/parserTests/prec.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/prec.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/rcount.r b/AbuseFilter/tests/parserTests/rcount.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/rcount.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/regex.r b/AbuseFilter/tests/parserTests/regex.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/regex.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/regex.t b/AbuseFilter/tests/parserTests/regex.t index 706da02d..4d2e6311 100644 --- a/AbuseFilter/tests/parserTests/regex.t +++ b/AbuseFilter/tests/parserTests/regex.t @@ -1 +1,6 @@ -"foobér" rlike "^[fq]o{2}\\S.r$" & "foo" regex "^f..?.$" +"foobér" rlike "^[fq]o{2}\\S.r$" & +"foo" regex "^f..?.$" & +"UPPERCASE" irlike "uppercase" & +"lowercase" irlike "LOWERCASE" & +"1234567" irlike "12345" & +"FoObAR" irlike "^[a-z]+$" diff --git a/AbuseFilter/tests/parserTests/rmdoubles.r b/AbuseFilter/tests/parserTests/rmdoubles.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/rmdoubles.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/rmspecials.r b/AbuseFilter/tests/parserTests/rmspecials.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/rmspecials.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/rmwhitespace.r b/AbuseFilter/tests/parserTests/rmwhitespace.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/rmwhitespace.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/sanitize.r b/AbuseFilter/tests/parserTests/sanitize.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/sanitize.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/shortcircuit-and.r b/AbuseFilter/tests/parserTests/shortcircuit-and.r deleted file mode 100644 index 33a8a805..00000000 --- a/AbuseFilter/tests/parserTests/shortcircuit-and.r +++ /dev/null @@ -1 +0,0 @@ -NOT_MATCH
\ No newline at end of file diff --git a/AbuseFilter/tests/parserTests/shortcircuit-and.t b/AbuseFilter/tests/parserTests/shortcircuit-and.t index d87746de..013d6f6f 100644 --- a/AbuseFilter/tests/parserTests/shortcircuit-and.t +++ b/AbuseFilter/tests/parserTests/shortcircuit-and.t @@ -1,2 +1,2 @@ /* The division by zero should not be executed and not crash the filter */ -false & 1/0
\ No newline at end of file +!(false & 1/0)
\ No newline at end of file diff --git a/AbuseFilter/tests/parserTests/shortcircuit-ops.t b/AbuseFilter/tests/parserTests/shortcircuit-ops.t new file mode 100644 index 00000000..ea64ce7b --- /dev/null +++ b/AbuseFilter/tests/parserTests/shortcircuit-ops.t @@ -0,0 +1,2 @@ +/* See T214642 */ +!(1 = 0 & 1 < 3 * 24 * ( 3600 + 47 ) ** 2) diff --git a/AbuseFilter/tests/parserTests/shortcircuit-or.r b/AbuseFilter/tests/parserTests/shortcircuit-or.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/shortcircuit-or.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/specialratio.r b/AbuseFilter/tests/parserTests/specialratio.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/specialratio.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/string.r b/AbuseFilter/tests/parserTests/string.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/string.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/string.t b/AbuseFilter/tests/parserTests/string.t index 47685ed9..d1467ef0 100644 --- a/AbuseFilter/tests/parserTests/string.t +++ b/AbuseFilter/tests/parserTests/string.t @@ -3,4 +3,9 @@ "a\"b" === 'a"b' & "a\rb" !== "a\r\nb" & "\x66\x6f\x6f" === "foo" & -"some\xstring" === "somexstring" +"some\xstring" === "some\\xstring" & +"some\vstring" === "some\\vstring" & +/* T238475 */ +'\x{}' === '\x' + '{}' & +length('\x{}') === 4 & +'foobar' rlike '[\x{61}-\x{7a}]' diff --git a/AbuseFilter/tests/parserTests/strpos.r b/AbuseFilter/tests/parserTests/strpos.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/strpos.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/substr.r b/AbuseFilter/tests/parserTests/substr.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/substr.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/tern.r b/AbuseFilter/tests/parserTests/tern.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/tern.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/ucase.r b/AbuseFilter/tests/parserTests/ucase.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/ucase.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/utf8.r b/AbuseFilter/tests/parserTests/utf8.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/utf8.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/vars.r b/AbuseFilter/tests/parserTests/vars.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/vars.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/whitespace1.r b/AbuseFilter/tests/parserTests/whitespace1.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/whitespace1.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/wptest1.r b/AbuseFilter/tests/parserTests/wptest1.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/wptest1.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/wptest2.r b/AbuseFilter/tests/parserTests/wptest2.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/wptest2.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/wptest3.r b/AbuseFilter/tests/parserTests/wptest3.r deleted file mode 100644 index 4736e080..00000000 --- a/AbuseFilter/tests/parserTests/wptest3.r +++ /dev/null @@ -1 +0,0 @@ -MATCH diff --git a/AbuseFilter/tests/parserTests/ccnorm-contains-all.t b/AbuseFilter/tests/parserTestsEquivset/ccnorm-contains-all.t index 9a8635c8..9a8635c8 100644 --- a/AbuseFilter/tests/parserTests/ccnorm-contains-all.t +++ b/AbuseFilter/tests/parserTestsEquivset/ccnorm-contains-all.t diff --git a/AbuseFilter/tests/parserTests/ccnorm-contains-any.t b/AbuseFilter/tests/parserTestsEquivset/ccnorm-contains-any.t index 6aeac35c..6aeac35c 100644 --- a/AbuseFilter/tests/parserTests/ccnorm-contains-any.t +++ b/AbuseFilter/tests/parserTestsEquivset/ccnorm-contains-any.t diff --git a/AbuseFilter/tests/parserTests/ccnorm.t b/AbuseFilter/tests/parserTestsEquivset/ccnorm.t index f233e42e..f233e42e 100644 --- a/AbuseFilter/tests/parserTests/ccnorm.t +++ b/AbuseFilter/tests/parserTestsEquivset/ccnorm.t diff --git a/AbuseFilter/tests/parserTests/mwexamples-functions.t b/AbuseFilter/tests/parserTestsEquivset/mwexamples-functions.t index ea5bf1b1..ea5bf1b1 100644 --- a/AbuseFilter/tests/parserTests/mwexamples-functions.t +++ b/AbuseFilter/tests/parserTestsEquivset/mwexamples-functions.t diff --git a/AbuseFilter/tests/parserTests/norm.t b/AbuseFilter/tests/parserTestsEquivset/norm.t index ed2d442a..ed2d442a 100644 --- a/AbuseFilter/tests/parserTests/norm.t +++ b/AbuseFilter/tests/parserTestsEquivset/norm.t diff --git a/AbuseFilter/tests/phan/config.php b/AbuseFilter/tests/phan/config.php deleted file mode 100644 index 99685d08..00000000 --- a/AbuseFilter/tests/phan/config.php +++ /dev/null @@ -1,19 +0,0 @@ -<?php - -$cfg = require __DIR__ . '/../../vendor/mediawiki/mediawiki-phan-config/src/config.php'; - -$cfg['directory_list'] = array_merge( - $cfg['directory_list'], - [ - './../../extensions/CheckUser', - ] -); - -$cfg['exclude_analysis_directory_list'] = array_merge( - $cfg['exclude_analysis_directory_list'], - [ - './../../extensions/CheckUser', - ] -); - -return $cfg; diff --git a/AbuseFilter/tests/phpunit/AFPDataTest.php b/AbuseFilter/tests/phpunit/AFPDataTest.php deleted file mode 100644 index 88315da4..00000000 --- a/AbuseFilter/tests/phpunit/AFPDataTest.php +++ /dev/null @@ -1,122 +0,0 @@ -<?php -/** - * Tests for the AFPData class - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - * - * @license GPL-2.0-or-later - */ - -/** - * @group Test - * @group AbuseFilter - * - * @covers AFPData - * @covers AbuseFilterTokenizer - * @covers AFPToken - * @covers AFPUserVisibleException - * @covers AFPException - * @covers AbuseFilterParser - */ -class AFPDataTest extends MediaWikiTestCase { - /** - * @return AbuseFilterParser - */ - public static function getParser() { - static $parser = null; - if ( !$parser ) { - $parser = new AbuseFilterParser(); - } else { - $parser->resetState(); - } - return $parser; - } - - /** - * Base method for testing exceptions - * - * @param string $excep Identifier of the exception (e.g. 'unexpectedtoken') - * @param string $expr The expression to test - * @param string $caller The function where the exception is thrown - */ - private function exceptionTest( $excep, $expr, $caller ) { - $parser = self::getParser(); - try { - $parser->parse( $expr ); - } catch ( AFPUserVisibleException $e ) { - $this->assertEquals( - $excep, - $e->mExceptionID, - "Exception $excep not thrown in AFPData::$caller" - ); - return; - } - - $this->fail( "Exception $excep not thrown in AFPData::$caller" ); - } - - /** - * Test the 'regexfailure' exception - * - * @param string $expr The expression to test - * @param string $caller The function where the exception is thrown - * @covers AFPData::keywordRegex - * @dataProvider regexFailure - */ - public function testRegexFailureException( $expr, $caller ) { - $this->exceptionTest( 'regexfailure', $expr, $caller ); - } - - /** - * Data provider for testRegexFailureException - * The second parameter is the function where the exception is raised. - * One expression for each throw. - * - * @return array - */ - public function regexFailure() { - return [ - [ "'a' rlike '('", 'keywordRegex' ], - ]; - } - - /** - * Test the 'dividebyzero' exception - * - * @param string $expr The expression to test - * @param string $caller The function where the exception is thrown - * @covers AFPData::mulRel - * @dataProvider divideByZero - */ - public function testDivideByZeroException( $expr, $caller ) { - $this->exceptionTest( 'dividebyzero', $expr, $caller ); - } - - /** - * Data provider for testRegexFailureException - * The second parameter is the function where the exception is raised. - * One expression for each throw. - * - * @return array - */ - public function divideByZero() { - return [ - [ '1/0', 'mulRel' ], - ]; - } -} diff --git a/AbuseFilter/tests/phpunit/AbuseFilterConsequencesTest.php b/AbuseFilter/tests/phpunit/AbuseFilterConsequencesTest.php index 4be865b5..da794f1a 100644 --- a/AbuseFilter/tests/phpunit/AbuseFilterConsequencesTest.php +++ b/AbuseFilter/tests/phpunit/AbuseFilterConsequencesTest.php @@ -1,4 +1,10 @@ <?php + +use MediaWiki\Block\DatabaseBlock; +use MediaWiki\MediaWikiServices; +use MediaWiki\Storage\PageEditStash; +use PHPUnit\Framework\MockObject\MockObject; + /** * Complete tests where filters are saved, actions are executed and the right * consequences are expected to be taken @@ -28,18 +34,32 @@ * @group AbuseFilter * @group AbuseFilterConsequences * @group Database + * @group Large * * @covers AbuseFilter + * @covers AbuseFilterRunner * @covers AbuseFilterHooks + * @covers \MediaWiki\Extension\AbuseFilter\VariableGenerator\VariableGenerator + * @covers \MediaWiki\Extension\AbuseFilter\VariableGenerator\RunVariableGenerator + * @covers AbuseFilterPreAuthenticationProvider * @covers AbuseFilterParser - * @covers AFPData - * @covers AbuseFilterTokenizer - * @covers AFPToken - * @covers AbuseFilterVariableHolder - * @covers AFComputedVariable */ class AbuseFilterConsequencesTest extends MediaWikiTestCase { - protected static $mUser; + /** + * @var User The user performing actions + */ + private $user; + /** To be used as fake timestamp in several tests */ + private const MAGIC_TIMESTAMP = 2051222400; + /** Prefix for tables to emulate an external DB */ + public const DB_EXTERNAL_PREFIX = 'external_'; + /** Tables to create in the external DB */ + public static $externalTables = [ + 'abuse_filter', + 'abuse_filter_action', + 'abuse_filter_log', + 'text', + ]; /** * @var array This tables will be deleted in parent::tearDown @@ -49,32 +69,20 @@ class AbuseFilterConsequencesTest extends MediaWikiTestCase { 'abuse_filter_action', 'abuse_filter_history', 'abuse_filter_log', - 'page' - ]; - - // Properties of the filter rows that we're not interested in changing. - // Write them once to save space - protected static $defaultRowSection = [ - 'af_user_text' => 'FilterTester', - 'af_user' => 0, - 'af_timestamp' => '20180707105743', - 'af_group' => 'default', - 'af_hit_count' => 0, + 'page', + 'ipblocks', + 'logging', + 'change_tag', + 'user', + 'text' ]; + // phpcs:disable Generic.Files.LineLength // Filters that may be created, their key is the ID. protected static $filters = [ 1 => [ - 'af_id' => 1, 'af_pattern' => 'added_lines irlike "foo"', - 'af_enabled' => 1, - 'af_comments' => 'Comments', 'af_public_comments' => 'Mock filter for edit', - 'af_hidden' => 0, - 'af_throttled' => 0, - 'af_deleted' => 0, - 'af_actions' => 'warn,tag', - 'af_global' => 0, 'actions' => [ 'warn' => [ 'abusefilter-my-warning' @@ -85,16 +93,9 @@ class AbuseFilterConsequencesTest extends MediaWikiTestCase { ] ], 2 => [ - 'af_id' => 2, 'af_pattern' => 'action = "move" & moved_to_title contains "test" & moved_to_title === moved_to_text', - 'af_enabled' => 1, - 'af_comments' => 'No comment', 'af_public_comments' => 'Mock filter for move', 'af_hidden' => 1, - 'af_throttled' => 0, - 'af_deleted' => 0, - 'af_actions' => 'disallow,block', - 'af_global' => 0, 'actions' => [ 'disallow' => [], 'block' => [ @@ -105,44 +106,22 @@ class AbuseFilterConsequencesTest extends MediaWikiTestCase { ] ], 3 => [ - 'af_id' => 3, 'af_pattern' => 'action = "delete" & "test" in lcase(page_prefixedtitle) & page_prefixedtitle === article_prefixedtext', - 'af_enabled' => 1, - 'af_comments' => '', 'af_public_comments' => 'Mock filter for delete', - 'af_hidden' => 0, - 'af_throttled' => 0, - 'af_deleted' => 0, - 'af_actions' => 'degroup', - 'af_global' => 0, + 'af_global' => 1, 'actions' => [ 'degroup' => [] ] ], 4 => [ - 'af_id' => 4, 'af_pattern' => 'action contains "createaccount" & accountname rlike "user" & page_title === article_text', - 'af_enabled' => 1, - 'af_comments' => '1', 'af_public_comments' => 'Mock filter for createaccount', 'af_hidden' => 1, - 'af_throttled' => 0, - 'af_deleted' => 0, - 'af_actions' => '', - 'af_global' => 0, 'actions' => [] ], 5 => [ - 'af_id' => 5, 'af_pattern' => 'user_name == "FilteredUser"', - 'af_enabled' => 1, - 'af_comments' => '', 'af_public_comments' => 'Mock filter', - 'af_hidden' => 0, - 'af_throttled' => 0, - 'af_deleted' => 0, - 'af_actions' => 'tag', - 'af_global' => 0, 'actions' => [ 'tag' => [ 'firstTag', @@ -151,46 +130,26 @@ class AbuseFilterConsequencesTest extends MediaWikiTestCase { ] ], 6 => [ - 'af_id' => 6, 'af_pattern' => 'edit_delta === 7', - 'af_enabled' => 1, - 'af_comments' => '', 'af_public_comments' => 'Mock filter with edit_delta', 'af_hidden' => 1, - 'af_throttled' => 0, - 'af_deleted' => 0, - 'af_actions' => 'disallow', - 'af_global' => 0, + 'af_global' => 1, 'actions' => [ - 'disallow' => [] + 'disallow' => [ + 'abusefilter-disallowed-really' + ] ] ], 7 => [ - 'af_id' => 7, 'af_pattern' => 'timestamp === int(timestamp)', - 'af_enabled' => 1, - 'af_comments' => '', 'af_public_comments' => 'Mock filter with timestamp', - 'af_hidden' => 0, - 'af_throttled' => 0, - 'af_deleted' => 0, - 'af_actions' => 'degroup', - 'af_global' => 0, 'actions' => [ 'degroup' => [] ] ], 8 => [ - 'af_id' => 8, 'af_pattern' => 'added_lines_pst irlike "\\[\\[Link\\|Link\\]\\]"', - 'af_enabled' => 1, - 'af_comments' => '', 'af_public_comments' => 'Mock filter with pst', - 'af_hidden' => 0, - 'af_hit_count' => 0, - 'af_deleted' => 0, - 'af_actions' => 'disallow,block', - 'af_global' => 0, 'actions' => [ 'disallow' => [], 'block' => [ @@ -201,16 +160,9 @@ class AbuseFilterConsequencesTest extends MediaWikiTestCase { ] ], 9 => [ - 'af_id' => 9, 'af_pattern' => 'new_size > old_size', - 'af_enabled' => 1, - 'af_comments' => '', 'af_public_comments' => 'Mock filter with size', 'af_hidden' => 1, - 'af_throttled' => 0, - 'af_deleted' => 0, - 'af_actions' => 'disallow,block', - 'af_global' => 0, 'actions' => [ 'disallow' => [], 'block' => [ @@ -221,16 +173,10 @@ class AbuseFilterConsequencesTest extends MediaWikiTestCase { ] ], 10 => [ - 'af_id' => 10, 'af_pattern' => '1 == 1', - 'af_enabled' => 1, - 'af_comments' => '', 'af_public_comments' => 'Mock throttled filter', 'af_hidden' => 1, 'af_throttled' => 1, - 'af_deleted' => 0, - 'af_actions' => 'tag,block', - 'af_global' => 0, 'actions' => [ 'tag' => [ 'testTag' @@ -243,36 +189,20 @@ class AbuseFilterConsequencesTest extends MediaWikiTestCase { ] ], 11 => [ - 'af_id' => 11, 'af_pattern' => '1 == 1', - 'af_enabled' => 1, - 'af_comments' => '', - 'af_public_comments' => 'Mock filter which throttles', - 'af_hidden' => 0, - 'af_throttled' => 0, - 'af_deleted' => 0, - 'af_actions' => 'throttle,disallow', - 'af_global' => 0, + 'af_public_comments' => 'Catch-all filter which throttles', 'actions' => [ 'throttle' => [ 11, '1,3600', - 'user' + 'site' ], 'disallow' => [] ] ], 12 => [ - 'af_id' => 12, 'af_pattern' => 'page_title == user_name & user_name === page_title', - 'af_enabled' => 1, - 'af_comments' => '', 'af_public_comments' => 'Mock filter for userpage', - 'af_hidden' => 0, - 'af_throttled' => 0, - 'af_deleted' => 0, - 'af_actions' => 'disallow,block,degroup', - 'af_global' => 0, 'actions' => [ 'disallow' => [], 'block' => [ @@ -284,16 +214,9 @@ class AbuseFilterConsequencesTest extends MediaWikiTestCase { ] ], 13 => [ - 'af_id' => 13, 'af_pattern' => '2 == 2', - 'af_enabled' => 1, - 'af_comments' => '', 'af_public_comments' => 'Another throttled mock filter', - 'af_hidden' => 0, 'af_throttled' => 1, - 'af_deleted' => 0, - 'af_actions' => 'block,degroup', - 'af_global' => 0, 'actions' => [ 'block' => [ 'blocktalk', @@ -304,38 +227,126 @@ class AbuseFilterConsequencesTest extends MediaWikiTestCase { ] ], 14 => [ - 'af_id' => 14, 'af_pattern' => '5/int(article_text) == 3', - 'af_enabled' => 1, - 'af_comments' => '', 'af_public_comments' => 'Filter with a possible division by zero', - 'af_hidden' => 0, - 'af_throttled' => 0, - 'af_deleted' => 0, - 'af_actions' => 'disallow', - 'af_global' => 0, 'actions' => [ 'disallow' => [] ] + ], + 15 => [ + 'af_pattern' => 'action contains "createaccount"', + 'af_public_comments' => 'Catch-all for account creations', + 'af_hidden' => 1, + 'actions' => [ + 'disallow' => [] + ] + ], + 16 => [ + 'af_pattern' => 'random := "adruhaoerihouhae"; added_lines contains random | ' . + 'edit_diff_pst contains random | new_pst contains random | new_html contains random |' . + '1=1 | /*Superfluous condition to set a lazyLoader but not compute*/all_links contains random', + 'af_public_comments' => 'Filter computing several non-lazy variables', + 'actions' => [ + 'disallow' => [] + ] + ], + 17 => [ + 'af_pattern' => 'timestamp = "' . self::MAGIC_TIMESTAMP . '" | 3 = 2 | 1 = 4 | 5 = 7 | 6 = 3', + 'af_comments' => 'This will normally consume 5 conditions, unless the timestamp is set to' . + 'the magic value of self::MAGIC_TIMESTAMP.', + 'af_public_comments' => 'Test with variable conditions', + 'actions' => [ + 'tag' => [ + 'testTagProfiling' + ] + ] + ], + 18 => [ + 'af_pattern' => '1 == 1', + 'af_public_comments' => 'Global filter', + 'af_global' => 1, + 'actions' => [ + 'warn' => [ + 'abusefilter-warning' + ], + 'disallow' => [] + ] + ], + 19 => [ + 'af_pattern' => 'user_name === "FilteredUser"', + 'af_public_comments' => 'Another global filter', + 'af_global' => 1, + 'actions' => [ + 'tag' => [ + 'globalTag' + ] + ] + ], + 20 => [ + 'af_pattern' => 'page_title === "Cellar door"', + 'af_public_comments' => 'Yet another global filter', + 'af_global' => 1, + 'actions' => [ + 'disallow' => [], + ] + ], + 21 => [ + 'af_pattern' => '1==1', + 'af_public_comments' => 'Dangerous filter', + 'actions' => [ + 'blockautopromote' => [] + ] + ], + 22 => [ + 'af_pattern' => 'action contains "upload" & "Block me" in added_lines & file_size > 0 & ' . + 'file_mime contains "/" & file_width + file_height > 0 & summary !== ""', + 'af_public_comments' => 'Filter for uploads', + 'actions' => [ + 'warn' => [ + 'abusefilter-random-upload' + ], + 'blockautopromote' => [] + ] ] ]; + // phpcs:enable Generic.Files.LineLength + + /** + * Add tables for global filters to the list of used tables + * + * @inheritDoc + */ + public function __construct( $name = null, array $data = [], $dataName = '' ) { + $prefixedTables = array_map( + function ( $table ) { + return self::DB_EXTERNAL_PREFIX . $table; + }, + self::$externalTables + ); + $this->tablesUsed = array_merge( $this->tablesUsed, $prefixedTables ); + $this->user = User::newFromName( 'FilteredUser' ); + parent::__construct( $name, $data, $dataName ); + } /** - * @see MediaWikiTestCase::setUp + * @inheritDoc */ - protected function setUp() { + protected function setUp() : void { parent::setUp(); - $user = User::newFromName( 'FilteredUser' ); - $user->addToDatabase(); - $user->addGroup( 'sysop' ); - if ( $user->isBlocked() ) { - $block = Block::newFromTarget( $user ); + // Ensure that our user is not blocked and is a sysop (matched filters could block or + // degroup the user) + $this->user->addToDatabase(); + $this->user->addGroup( 'sysop' ); + $block = DatabaseBlock::newFromTarget( $this->user ); + if ( $block ) { $block->delete(); } - self::$mUser = $user; + // Make sure that the config we're using is the one we're expecting $this->setMwGlobals( [ - 'wgUser' => $user, + 'wgUser' => $this->user, + // Exclude noisy creation log + 'wgPageCreationLog' => false, 'wgAbuseFilterActions' => [ 'throttle' => true, 'warn' => true, @@ -346,224 +357,368 @@ class AbuseFilterConsequencesTest extends MediaWikiTestCase { 'degroup' => true, 'tag' => true ], - 'wgAbuseFilterRuntimeProfile' => true, - 'wgAbuseFilterProfile' => true + 'wgAbuseFilterCentralDB' => $this->db->getDBname() . '-' . $this->dbPrefix() . + self::DB_EXTERNAL_PREFIX, + 'wgAbuseFilterIsCentral' => false, + 'wgMainCacheType' => 'hash', ] ); } /** - * Performs an edit. Freely adapted from EditPageTest::assertEdit + * @inheritDoc + */ + protected function tearDown() : void { + // Paranoia: ensure no fake timestamp leftover + MWTimestamp::setFakeTime( false ); + // Clear any upload + $_FILES = []; + parent::tearDown(); + } + + /** + * Creates new filters with the given ids, referred to self::$filters + * + * @param int[] $ids IDs of the filters to create + * @param bool $external Whether to create filters in the external table + */ + private function createFilters( $ids, $external = false ) { + global $wgAbuseFilterActions; + $tablePrefix = $external ? self::DB_EXTERNAL_PREFIX : ''; + $defaultRowSection = [ + 'af_user_text' => 'FilterTester', + 'af_user' => 0, + 'af_timestamp' => $this->db->timestamp(), + 'af_group' => 'default', + 'af_comments' => '', + 'af_hit_count' => 0, + 'af_enabled' => 1, + 'af_hidden' => 0, + 'af_throttled' => 0, + 'af_deleted' => 0, + 'af_global' => 0 + ]; + + foreach ( $ids as $id ) { + $filter = self::$filters[$id] + $defaultRowSection; + $actions = $filter['actions']; + unset( $filter['actions'] ); + $filter[ 'af_actions' ] = implode( ',', array_keys( $actions ) ); + $filter[ 'af_id' ] = $id; + + $this->db->insert( + "{$tablePrefix}abuse_filter", + $filter, + __METHOD__ + ); + + $actionsRows = []; + foreach ( array_filter( $wgAbuseFilterActions ) as $action => $_ ) { + if ( isset( $actions[$action] ) ) { + $parameters = $actions[$action]; + + $thisRow = [ + 'afa_filter' => $id, + 'afa_consequence' => $action, + 'afa_parameters' => implode( "\n", $parameters ) + ]; + $actionsRows[] = $thisRow; + } + } + + $this->db->insert( + "{$tablePrefix}abuse_filter_action", + $actionsRows, + __METHOD__ + ); + } + } + + /** + * Stash the edit. * * @param Title $title Title of the page to edit + * @param string $text The new content of the page + * @param string $summary The summary of the edit + * @return string The status of the operation, as returned by the API. + */ + private function stashEdit( $title, $text, $summary ) { + $editStash = new PageEditStash( + new HashBagOStuff( [] ), + MediaWikiServices::getInstance()->getDBLoadBalancer(), + new Psr\Log\NullLogger(), + new NullStatsdDataFactory(), + MediaWikiServices::getInstance()->getHookContainer(), + PageEditStash::INITIATOR_USER + ); + return $editStash->parseAndCache( + WikiPage::factory( $title ), + new WikitextContent( $text ), + $this->user, + $summary + ); + } + + /** + * @param Title $title Title of the page to edit * @param string $oldText Old content of the page * @param string $newText The new content of the page * @param string $summary The summary of the edit + * @param bool|null $fromStash Whether to stash the edit. Null means no stashing, false means + * stash the edit but don't reuse it for saving, true means stash and reuse. * @return Status */ - private static function doEdit( $title, $oldText, $newText, $summary ) { + private function doEdit( Title $title, $oldText, $newText, $summary, $fromStash = null ) { $page = WikiPage::factory( $title ); - $content = ContentHandler::makeContent( $oldText, $title ); - $page->doEditContent( $content, 'Creating the page for testing AbuseFilter.' ); - - $params = [ - 'wpTextbox1' => $newText, - 'wpSummary' => $summary, - 'wpEditToken' => self::$mUser->getEditToken(), - 'wpEdittime' => $page->getTimestamp(), - 'wpStarttime' => wfTimestampNow(), - 'wpUnicodeCheck' => EditPage::UNICODE_CHECK, - 'wpSectionTitle' => '', - 'wpMinorEdit' => false, - 'wpWatchthis' => false + if ( !$page->exists() ) { + $status = $this->editPage( + $title->getText(), + $oldText, + __METHOD__ . ' page creation', + $title->getNamespace() + ); + if ( !$status->isGood() ) { + throw new Exception( "Could not create test page. $status" ); + } + $title->resetArticleID( -1 ); + } + + if ( $fromStash !== null ) { + // If we want to save from stash, submit the same text + $stashText = $newText; + if ( $fromStash === false ) { + // Otherwise, stash some random text which won't match the actual edit + $stashText = md5( uniqid( rand(), true ) ); + } + $stashResult = $this->stashEdit( $title, $stashText, $summary ); + if ( $stashResult !== PageEditStash::ERROR_NONE ) { + throw new MWException( "The edit cannot be stashed, got the following error: $stashResult" ); + } + } + + $content = ContentHandler::makeContent( $newText, $title ); + $status = Status::newGood(); + $context = RequestContext::getMain(); + $context->setTitle( $title ); + $context->setUser( $this->user ); + + AbuseFilterHooks::onEditFilterMergedContent( $context, $content, $status, $summary, + $this->user, false ); + + if ( $status->isGood() ) { + // Edit the page in case the test will expect for it to exist + $this->editPage( + $title->getText(), + $newText, + $summary, + $title->getNamespace(), + $this->user + ); + } + + return $status; + } + + /** + * Upload a file. This is based on ApiUploadTestCase::fakeUploadFile + * @param string $fileName + * @param string $pageText + * @param string $summary + * @return Status + */ + private function doUpload( string $fileName, string $pageText, string $summary ) : Status { + $imgGen = new RandomImageGenerator(); + // Use SVG, since the ImageGenerator doesn't need anything special to create it + $format = 'svg'; + $mime = 'image/svg+xml'; + $filePath = $imgGen->writeImages( 1, $format, $this->getNewTempDirectory() )[0]; + clearstatcache(); + $_FILES[ 'wpUploadFile' ] = [ + 'name' => $fileName, + 'type' => $mime, + 'tmp_name' => $filePath, + 'error' => UPLOAD_ERR_OK, + 'size' => filesize( $filePath ), ]; - $req = new FauxRequest( $params, true ); - - $article = new Article( $title ); - $article->getContext()->setTitle( $title ); - $article->getContext()->setUser( self::$mUser ); - $ep = new EditPage( $article ); - $ep->setContextTitle( $title ); - $ep->importFormData( $req ); - return $ep->internalAttemptSave( $result ); + $request = new FauxRequest( [ + 'wpDestFile' => $fileName + ] ); + $ub = UploadBase::createFromRequest( $request ); + $ub->verifyUpload(); + return $ub->performUpload( $summary, $pageText, false, $this->user ); } /** * Executes an action to filter * * @param array $params Parameters of the action - * @param array $options Further options - * @return Status|Status[] + * @return Status */ - private static function doAction( $params, $options ) { - $type = array_shift( $params ); - $target = array_shift( $params ); - $target = Title::newFromText( $target ); + private function doAction( $params ) { + $target = Title::newFromText( $params['target'] ); // Make sure that previous blocks don't affect the test - self::$mUser->clearInstanceCache(); + $this->user->clearInstanceCache(); - switch ( $type ) { + switch ( $params['action'] ) { case 'edit': - if ( in_array( 'makeGoodEditFirst', $options ) ) { - $firstStatus = self::doEdit( - $target, $params['oldText'], $params['firstNewText'], $params['summary'] - ); - $secondStatus = self::doEdit( - $target, $params['firstNewText'], $params['secondNewText'], $params['summary'] - ); - $status = [ $firstStatus, $secondStatus ]; - } else { - $status = self::doEdit( $target, $params['oldText'], $params['newText'], $params['summary'] ); - } + $status = $this->doEdit( $target, $params['oldText'], $params['newText'], $params['summary'] ); + break; + case 'stashedit': + $stashStatus = $params['stashType'] === 'hit'; + $status = $this->doEdit( + $target, + $params['oldText'], + $params['newText'], + $params['summary'], + $stashStatus + ); break; case 'move': - $move = new MovePage( $target, Title::newFromText( $params['newTitle'] ) ); - $status = $move->checkPermissions( self::$mUser, 'AbuseFilter move test' ); + // Ensure that the page exists + $this->getExistingTestPage( $target ); + $newTitle = isset( $params['newTitle'] ) + ? Title::newFromText( $params['newTitle'] ) + : $this->getNonExistingTestPage()->getTitle(); + /** @var MockObject|MovePage $mp */ + $mp = $this->getMockBuilder( MovePage::class ) + ->setMethods( [ 'isValidMove' ] ) + ->setConstructorArgs( [ $target, $newTitle ] ) + ->getMock(); + $mp->expects( $this->any() ) + ->method( 'isValidMove' ) + ->willReturn( Status::newGood() ); + $status = $mp->move( $this->user, 'AbuseFilter move test', false ); break; case 'delete': - $page = WikiPage::factory( $target ); - $content = ContentHandler::makeContent( 'Page to be deleted in AbuseFilter test', $target ); - $page->doEditContent( $content, 'Creating the page for testing deletion AbuseFilter.' ); - $status = $page->doDeleteArticleReal( 'Testing deletion in AbuseFilter' ); + $page = $this->getExistingTestPage( $target ); + $status = $page->doDeleteArticleReal( + 'Testing deletion in AbuseFilter', + $this->user + ); break; case 'createaccount': $user = User::newFromName( $params['username'] ); + // A creatable username must exist to be passed to $logEntry->setPerformer(), + // so create the account. + $user->addToDatabase(); + $provider = new AbuseFilterPreAuthenticationProvider(); $status = $provider->testForAccountCreation( $user, $user, [] ); + + $logEntry = new ManualLogEntry( 'newusers', 'create' ); + $logEntry->setPerformer( $user ); + $logEntry->setTarget( $user->getUserPage() ); + $logid = $logEntry->insert(); + $logEntry->publish( $logid ); + break; + case 'upload': + $status = $this->doUpload( + $params['target'], + $params['newText'] ?? 'AbuseFilter test upload', + $params['summary'] ?? 'Test' + ); break; + default: + throw new UnexpectedValueException( 'Unrecognized action ' . $params['action'] ); } // Clear cache since we'll need to retrieve some fresh data about the user // like blocks and groups later when checking expected values - self::$mUser->clearInstanceCache(); + $this->user->clearInstanceCache(); return $status; } /** - * Creates new filters with the given ids, referred to self::$filters - * - * @param int[] $ids IDs of the filters to create + * @param array[] $actionsParams Arrays of parameters for every action + * @return Status[] */ - private static function createFilters( $ids ) { - global $wgAbuseFilterActions; - $dbw = wfGetDB( DB_MASTER ); - - foreach ( $ids as $id ) { - $filter = array_merge( self::$filters[$id], self::$defaultRowSection ); - $actions = $filter['actions']; - unset( $filter['actions'] ); - - $dbw->replace( - 'abuse_filter', - [ 'af_id' ], - $filter, - __METHOD__ - ); - - $actionRows = []; - foreach ( array_filter( $wgAbuseFilterActions ) as $action => $_ ) { - if ( isset( $actions[$action] ) ) { - $parameters = $actions[$action]; - - $thisRow = [ - 'afa_filter' => $id, - 'afa_consequence' => $action, - 'afa_parameters' => implode( "\n", $parameters ) - ]; - $actionsRows[] = $thisRow; - } - } - - $dbw->replace( - 'abuse_filter_action', - [ 'afa_filter' ], - $actionsRows, - __METHOD__ - ); + private function doActions( $actionsParams ) { + $ret = []; + foreach ( $actionsParams as $params ) { + $ret[] = $this->doAction( $params ); } + return $ret; } /** - * Creates new filters, execute an action and check the consequences + * Helper function to retrieve change tags applied to an edit or log entry * - * @param string $testDescription A short description of the test, used for error reporting - * @param int[] $createIds IDs of the filters to create - * @param array $actionParams Details of the action we need to execute to trigger filters - * @param array $consequences The consequences we're expecting - * @param array $options Further options for the test - * @covers AbuseFilter - * @dataProvider provideFilters + * @param array $actionParams As given by the data provider + * @return string[] The applied tags */ - public function testFilterConsequences( - $testDescription, - $createIds, - $actionParams, - $consequences, - $options - ) { - global $wgLang; - self::createFilters( $createIds ); - - if ( in_array( 'makeGoodEditFirst', $options ) ) { - $this->setMwGlobals( [ - // Necessary to test throttle - 'wgMainCacheType' => CACHE_ANYTHING - ] ); - } - if ( in_array( 'hitCondsLimit', $options ) ) { - $this->setMwGlobals( [ - 'wgAbuseFilterConditionLimit' => 0 - ] ); + private function getActionTags( $actionParams ) { + if ( $actionParams['action'] === 'edit' || $actionParams['action'] === 'stashedit' ) { + $page = WikiPage::factory( Title::newFromText( $actionParams['target'] ) ); + return ChangeTags::getTags( $this->db, null, $page->getLatest() ); } - if ( in_array( 'hitTimeLimit', $options ) ) { - $this->setMwGlobals( [ - 'wgAbuseFilterSlowFilterRuntimeLimit' => 0 - ] ); - } - if ( in_array( 'hitThrottleLimit', $options ) ) { - $this->setMwGlobals( [ - 'wgAbuseFilterEmergencyDisableCount' => [ - 'default' => 0 - ] - ] ); + + $logType = $actionParams['action'] === 'createaccount' ? 'newusers' : $actionParams['action']; + $logAction = $logType === 'newusers' ? 'create' : $logType; + $title = Title::newFromText( $actionParams['target'] ); + $id = $this->db->selectField( + 'logging', + 'log_id', + [ + 'log_title' => $title->getDBkey(), + 'log_type' => $logType, + 'log_action' => $logAction + ], + __METHOD__, + [], + [ 'ORDER BY' => 'log_id DESC' ] + ); + if ( !$id ) { + $this->fail( 'Could not find the action in the logging table.' ); } + return ChangeTags::getTags( $this->db, null, null, $id ); + } - $result = self::doAction( $actionParams, $options ); + /** + * Checks that consequences are effectively taken and builds an array of expected and actual + * consequences which can be compared. + * + * @param Status $result As returned by self::doAction + * @param array $actionParams As it's given by data providers + * @param array $consequences As it's given by data providers + * @return array [ expected consequences, actual consequences ] + */ + private function checkConsequences( $result, $actionParams, $consequences ) { + global $wgAbuseFilterRestrictions; $expectedErrors = []; $testErrorMessage = false; foreach ( $consequences as $consequence => $ids ) { foreach ( $ids as $id ) { $params = self::$filters[$id]['actions'][$consequence]; - $success = true; switch ( $consequence ) { case 'warn': // Aborts the hook with the warning message as error. - $expectedErrors['warn'][] = $params[0]; + $expectedErrors['warn'][] = $params[0] ?? 'abusefilter-warning'; break; case 'disallow': - // Aborts the hook with 'abusefilter-disallowed' error. - $expectedErrors['disallow'][] = 'abusefilter-disallowed'; + // Aborts the hook with the disallow message error. + $expectedErrors['disallow'][] = $params[0] ?? 'abusefilter-disallowed'; break; case 'block': // Aborts the hook with 'abusefilter-blocked-display' error. Should block // the user with expected duration and options. - $userBlock = self::$mUser->getBlock( false ); + $userBlock = $this->user->getBlock( false ); if ( !$userBlock ) { $testErrorMessage = "User isn't blocked."; break; } - $shouldPreventTalkEdit = $params[0] === 'blocktalk'; - $edittalkCheck = $userBlock->prevents( 'editownusertalk' ) === $shouldPreventTalkEdit; + $shouldPreventTalkEdit = $params[0] === 'blocktalk'; + $edittalkCheck = $userBlock->appliesToUsertalk( $this->user->getTalkPage() ) === + $shouldPreventTalkEdit; if ( !$edittalkCheck ) { $testErrorMessage = 'The expected block option "edittalk" options does not ' . 'match the actual one.'; break; } - $expectedExpiry = SpecialBlock::parseExpiryInput( $params[2] ); + $expectedExpiry = SpecialBlock::parseExpiryInput( $params[2] ); // Get rid of non-numeric 'infinity' by setting it to 0 $actualExpiry = wfIsInfinity( $userBlock->getExpiry() ) ? 0 : $userBlock->getExpiry(); $expectedExpiry = wfIsInfinity( $expectedExpiry ) ? 0 : $expectedExpiry; @@ -575,328 +730,1401 @@ class AbuseFilterConsequencesTest extends MediaWikiTestCase { break; } - $expectedErrors['block'][] = 'abusefilter-blocked-display'; + $expectedErrors['block'][] = 'abusefilter-blocked-display'; break; case 'degroup': // Aborts the hook with 'abusefilter-degrouped' error and degroups the user. $expectedErrors['degroup'][] = 'abusefilter-degrouped'; - $groupCheck = !in_array( 'sysop', self::$mUser->getEffectiveGroups() ); + $groupCheck = !in_array( 'sysop', $this->user->getEffectiveGroups() ); if ( !$groupCheck ) { $testErrorMessage = 'The user was not degrouped.'; } break; case 'tag': - // Only add tags, to be retrieved in tag_summary table. - if ( $actionParams[1] === null ) { - // It's an account creation, so no tags. - break; - } - $title = Title::newFromText( $actionParams[1] ); - $page = WikiPage::factory( $title ); - $revId = $page->getLatest(); - $dbr = wfGetDB( DB_REPLICA ); - $appliedTags = $dbr->selectField( - 'tag_summary', - 'ts_tags', - [ 'ts_rev_id' => $revId ], - __METHOD__ - ); - $appliedTags = explode( ',', $appliedTags ); - - $tagCheck = count( array_diff( $params, $appliedTags ) ) === 0; + // Only adds tags, to be retrieved in change_tag table. + $appliedTags = $this->getActionTags( $actionParams ); + $tagCheck = count( array_diff( $params, $appliedTags ) ) === 0; if ( !$tagCheck ) { - $expectedTags = $wgLang->commaList( $params ); - $actualTags = $wgLang->commaList( $appliedTags ); + $expectedTags = implode( ', ', $params ); + $actualTags = implode( ', ', $appliedTags ); - $testErrorMessage = "Expected the edit to have the following tags: $expectedTags. " . + $testErrorMessage = "Expected the action to have the following tags: $expectedTags. " . "Got the following instead: $actualTags."; } break; case 'throttle': - // The action was executed twice and $result is an array of two Status objects. - if ( !$result[0]->isGood() ) { - // The first one should be fine - $testErrorMessage = "The first edit should have been saved, being only throttled."; - break; + throw new UnexpectedValueException( 'Use self::testThrottleConsequence to test throttling' ); + case 'blockautopromote': + // Aborts the hook with 'abusefilter-autopromote-blocked' error and prevent promotion. + $expectedErrors['blockautopromote'][] = 'abusefilter-autopromote-blocked'; + $value = AbuseFilter::getAutoPromoteBlockStatus( $this->user ); + if ( !$value ) { + $testErrorMessage = "The key for blocking autopromotion wasn't set."; } - - $result = $result[1]; break; + default: + throw new UnexpectedValueException( "Consequence not recognized: $consequence." ); } if ( $testErrorMessage ) { - $this->fail( "$testErrorMessage Test description: $testDescription" ); + $this->fail( $testErrorMessage ); } } } - if ( in_array( 'hitThrottleLimit', $options ) ) { - $dbr = wfGetDB( DB_REPLICA ); - $throttled = true; - foreach ( $createIds as $filter ) { - $curThrottle = $dbr->selectField( - 'abuse_filter', - 'af_throttled', - [ 'af_id' => $filter ], - __METHOD__ - ); - $throttled &= $curThrottle; + if ( array_intersect_key( $expectedErrors, array_filter( $wgAbuseFilterRestrictions ) ) ) { + $filteredExpected = array_intersect_key( + $expectedErrors, + array_filter( $wgAbuseFilterRestrictions ) + ); + $expected = []; + foreach ( $filteredExpected as $values ) { + $expected = array_merge( $expected, $values ); } - - if ( !$throttled ) { - $expectedThrottled = $wgLang->commaList( $createIds ); - $this->fail( 'Expected the following filters to be automatically ' . - "throttled: $expectedThrottled." ); + } else { + $expected = $expectedErrors['warn'] ?? $expectedErrors['disallow'] ?? null; + if ( !is_array( $expected ) ) { + $expected = (array)$expected; } } - // Errors have a priority order - $expected = $expectedErrors['warn'] ?? $expectedErrors['degroup'] ?? - $expectedErrors['block'] ?? $expectedErrors['disallow'] ?? null; - if ( isset( $expectedErrors['degroup'] ) && $expected === $expectedErrors['degroup'] && - isset( $expectedErrors['block'] ) ) { - // Degroup and block warning can be fired together - $expected = array_merge( $expectedErrors['degroup'], $expectedErrors['block'] ); - } elseif ( !is_array( $expected ) ) { - $expected = (array)$expected; - } - $errors = $result->getErrors(); $actual = []; foreach ( $errors as $error ) { - $msg = $error['message']; + // We don't use any of the "API" stuff in ApiMessage here, but this is the most + // convenient way to get a Message from a StatusValue error structure. + $msg = ApiMessage::create( $error )->getKey(); if ( strpos( $msg, 'abusefilter' ) !== false ) { $actual[] = $msg; } } - $expectedDisplay = $wgLang->commaList( $expected ); - $actualDisplay = $wgLang->commaList( $actual ); + sort( $expected ); + sort( $actual ); + return [ $expected, $actual ]; + } + + /** + * Creates new filters, execute an action and check the consequences + * + * @param int[] $createIds IDs of the filters to create + * @param array $actionParams Details of the action we need to execute to trigger filters + * @param array $consequences The consequences we're expecting + * @dataProvider provideFilters + */ + public function testFilterConsequences( $createIds, $actionParams, $consequences ) { + $this->createFilters( $createIds ); + $result = $this->doAction( $actionParams ); + list( $expected, $actual ) = $this->checkConsequences( $result, $actionParams, $consequences ); $this->assertEquals( $expected, $actual, - "The edit should have returned the following error messages: $expectedDisplay. " . - "Got $actualDisplay instead. Test description: $testDescription" + 'The error messages obtained by performing the action do not match.' ); } /** - * Data provider for creating and editing filters. For every test case, we pass + * Data provider for testFilterConsequences. For every test case, we pass * - an array with the IDs of the filters to be created (listed in self::$filters), * - an array with details of the action to execute in order to trigger the filters, * - an array of expected consequences of the form * [ 'consequence name' => [ IDs of the filter to take its parameters from ] ] * Such IDs may be more than one if we have a warning that is shown twice. - * - an array with further options for testing * * @return array */ public function provideFilters() { return [ - [ - 'Basic test for "edit" action.', + 'Basic test for "edit" action' => [ [ 1, 2 ], [ - 'edit', - 'Test page', + 'action' => 'edit', + 'target' => 'Test page', 'oldText' => 'Some old text for the test.', 'newText' => 'I like foo', 'summary' => 'Test AbuseFilter for edit action.' ], - [ 'warn' => [ 1 ] ], + [ 'warn' => [ 1 ] ] + ], + 'Basic test for "move" action' => [ + [ 2 ], + [ + 'action' => 'move', + 'target' => 'Test page', + 'newTitle' => 'Another test page' + ], + [ 'disallow' => [ 2 ], 'block' => [ 2 ] ] + ], + 'Basic test for "delete" action' => [ + [ 2, 3 ], + [ + 'action' => 'delete', + 'target' => 'Test page' + ], + [ 'degroup' => [ 3 ] ] + ], + 'Basic test for "createaccount", no consequences.' => [ + [ 1, 2, 3, 4 ], + [ + 'action' => 'createaccount', + 'target' => 'User:AnotherUser', + 'username' => 'AnotherUser' + ], + [] + ], + 'Basic test for "createaccount", disallowed.' => [ + [ 15 ], + [ + 'action' => 'createaccount', + 'target' => 'User:AnotherUser', + 'username' => 'AnotherUser' + ], + [ 'disallow' => [ 15 ] ] + ], + 'Check that all tags are applied' => [ + [ 5 ], + [ + 'action' => 'edit', + 'target' => 'User:FilteredUser', + 'oldText' => 'Hey.', + 'newText' => 'I am a very nice user, really!', + 'summary' => '' + ], + [ 'tag' => [ 5 ] ] + ], + [ + [ 6 ], + [ + 'action' => 'edit', + 'target' => 'Help:Help', + 'oldText' => 'Some help.', + 'newText' => 'Some help for you', + 'summary' => 'Help! I need somebody' + ], + [ 'disallow' => [ 6 ] ] + ], + 'Check that degroup and block are executed together' => [ + [ 2, 3, 7, 8 ], + [ + 'action' => 'edit', + 'target' => 'Link', + 'oldText' => 'What is a link?', + 'newText' => 'A link is something like this: [[Link|]].', + 'summary' => 'Explaining' + ], + [ 'degroup' => [ 7 ], 'block' => [ 8 ] ] + ], + 'Check that the block duration is the longer one' => [ + [ 8, 9 ], + [ + 'action' => 'edit', + 'target' => 'Whatever', + 'oldText' => 'Whatever is whatever', + 'newText' => 'Whatever is whatever, whatever it is. BTW, here is a [[Link|]]', + 'summary' => 'Whatever' + ], + [ 'disallow' => [ 8 ], 'block' => [ 8 ] ] + ], + 'Check that throttled filters only execute "safe" actions' => [ + [ 10 ], + [ + 'action' => 'edit', + 'target' => 'Buffalo', + 'oldText' => 'Buffalo', + 'newText' => 'Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo.', + 'summary' => 'Buffalo!' + ], + [ 'tag' => [ 10 ] ] + ], + 'Check that degroup and block are both executed and degroup warning is shown twice' => [ + [ 1, 3, 7, 12 ], + [ + 'action' => 'edit', + 'target' => 'User:FilteredUser', + 'oldText' => '', + 'newText' => 'A couple of lines about me...', + 'summary' => 'My user page' + ], + [ 'block' => [ 12 ], 'degroup' => [ 7, 12 ] ] + ], + 'Check that every throttled filter only executes "safe" actions' => [ + [ 10, 13 ], + [ + 'action' => 'edit', + 'target' => 'Tyger! Tyger! Burning bright', + 'oldText' => 'In the forests of the night', + 'newText' => 'What immortal hand or eye', + 'summary' => 'Could frame thy fearful symmetry?' + ], + [ 'tag' => [ 10 ] ] + ], + 'Check that runtime exceptions (division by zero) are correctly handled' => [ + [ 14 ], + [ + 'action' => 'edit', + 'target' => '0', + 'oldText' => 'Old text', + 'newText' => 'New text', + 'summary' => 'Some summary' + ], [] ], + 'Test for blockautopromote action.' => [ + [ 21 ], + [ + 'action' => 'edit', + 'target' => 'Rainbow', + 'oldText' => '', + 'newText' => '...', + 'summary' => '' + ], + [ 'blockautopromote' => [ 21 ] ], + ], + [ + [ 8, 10 ], + [ + 'action' => 'edit', + 'target' => 'Anything', + 'oldText' => 'Bar', + 'newText' => 'Foo', + 'summary' => '' + ], + [] + ], + [ + [ 7, 12 ], + [ + 'action' => 'edit', + 'target' => 'Something', + 'oldText' => 'Please allow me', + 'newText' => 'to introduce myself', + 'summary' => '' + ], + [ 'degroup' => [ 7 ] ] + ], + [ + [ 13 ], + [ + 'action' => 'edit', + 'target' => 'My page', + 'oldText' => '', + 'newText' => 'AbuseFilter will not block me', + 'summary' => '' + ], + [] + ], + 'Test upload action' => [ + [ 5 ], + [ + 'action' => 'upload', + 'target' => 'MyFile.jpg', + ], + [ 'tag' => [ 5 ] ] + ], + 'Test upload action 2' => [ + [ 22 ], + [ + 'action' => 'upload', + 'target' => 'MyFile.jpg', + 'newText' => 'Block me please!', + 'summary' => 'Asking to be blocked' + ], + [ 'warn' => [ 22 ] ] + ], + ]; + } + + /** + * Check that hitting the conditions limit stops the execution, and thus no actions are taken. + * + * @param int[] $createIds IDs of the filters to create + * @param array $actionParams Details of the action we need to execute to trigger filters + * @covers AbuseFilterParser::getCondCount + * @covers AbuseFilterParser::raiseCondCount + * @covers AbuseFilterRunner::checkAllFilters + * @dataProvider provideFiltersNoConsequences + */ + public function testCondsLimit( $createIds, $actionParams ) { + $this->createFilters( $createIds ); + $this->setMwGlobals( [ 'wgAbuseFilterConditionLimit' => 0 ] ); + $res = $this->doAction( $actionParams ); + + $this->assertTrue( + $res->isGood(), + "The action should succeed when testing the conds limit. Error: $res" + ); + $appliedTags = $this->getActionTags( $actionParams ); + $this->assertContains( + 'abusefilter-condition-limit', + $appliedTags, + "The action wasn't tagged with 'abusefilter-condition-limit' upon hitting the limit" + ); + } + + /** + * Check that hitting the time limit is logged + * + * @param int[] $createIds IDs of the filters to create + * @param array $actionParams Details of the action we need to execute to trigger filters + * @covers AbuseFilterRunner::checkFilter + * @covers AbuseFilterRunner::recordSlowFilter + * @dataProvider provideFiltersNoConsequences + */ + public function testTimeLimit( $createIds, $actionParams ) { + $loggerMock = new TestLogger(); + $loggerMock->setCollect( true ); + $this->setLogger( 'AbuseFilter', $loggerMock ); + $this->setMwGlobals( [ 'wgAbuseFilterSlowFilterRuntimeLimit' => -1 ] ); + + $this->createFilters( $createIds ); + // We don't care about consequences here + $this->doAction( $actionParams ); + + // Ensure slow filters are logged + $loggerBuffer = $loggerMock->getBuffer(); + $found = false; + foreach ( $loggerBuffer as $entry ) { + $check = preg_match( '/Edit filter [^ ]+ on [^ ]+ is taking longer than expected/', $entry[1] ); + if ( $check ) { + $found = true; + break; + } + } + $this->assertTrue( $found, 'The time limit hit was not logged.' ); + } + + /** + * Similar to self::provideFilters, but for tests where we don't care about consequences. + * + * @return array + */ + public function provideFiltersNoConsequences() { + return [ + [ + [ 1, 2 ], + [ + 'action' => 'edit', + 'target' => 'Test page', + 'oldText' => 'Some old text for the test.', + 'newText' => 'I like foo', + 'summary' => 'Test AbuseFilter for edit action.' + ] + ], + [ + [ 2 ], + [ + 'action' => 'move', + 'target' => 'Test page', + ] + ], + [ + [ 5 ], + [ + 'action' => 'edit', + 'target' => 'User:FilteredUser', + 'oldText' => 'Hey.', + 'newText' => 'I am a very nice user, really!', + 'summary' => '' + ] + ], + [ + [ 2, 3, 7, 8 ], + [ + 'action' => 'edit', + 'target' => 'Link', + 'oldText' => 'What is a link?', + 'newText' => 'A link is something like this: [[Link|]].', + 'summary' => 'Explaining' + ] + ], + [ + [ 8, 10 ], + [ + 'action' => 'edit', + 'target' => 'Anything', + 'oldText' => 'Bar', + 'newText' => 'Foo', + 'summary' => '' + ] + ], + [ + [ 2, 3 ], + [ + 'action' => 'delete', + 'target' => 'Test page' + ] + ], + [ + [ 10, 13 ], + [ + 'action' => 'edit', + 'target' => 'Tyger! Tyger! Burning bright', + 'oldText' => 'In the forests of the night', + 'newText' => 'What immortal hand or eye', + 'summary' => 'Could frame thy fearful symmetry?' + ] + ], + [ + [ 15 ], + [ + 'action' => 'createaccount', + 'target' => 'User:AnotherUser', + 'username' => 'AnotherUser' + ] + ] + ]; + } + + /** + * Check that hitting the throttle effectively updates abuse_filter.af_throttled. + * + * @param int[] $createIds IDs of the filters to create + * @param array $actionParams Details of the action we need to execute to trigger filters + * @covers AbuseFilterRunner::checkEmergencyDisable + * @dataProvider provideThrottleLimitFilters + */ + public function testThrottleLimit( $createIds, $actionParams ) { + $this->createFilters( $createIds ); + $this->setMwGlobals( [ + 'wgAbuseFilterEmergencyDisableCount' => [ 'default' => -1 ], + 'wgAbuseFilterEmergencyDisableThreshold' => [ 'default' => -1 ], + ] ); + // We don't care about consequences here + $this->doAction( $actionParams ); + + $throttled = []; + foreach ( $createIds as $filter ) { + $curThrottle = $this->db->selectField( + 'abuse_filter', + 'af_throttled', + [ 'af_id' => $filter ], + __METHOD__ + ); + if ( $curThrottle ) { + $throttled[] = $filter; + } + } + + $this->assertEquals( $createIds, $throttled, 'Some filters weren\'t automatically throttled.' ); + } + + /** + * Data provider for testThrottleLimit. Note that using filters with af_throttled = 1 in + * self::$filters makes the test case useless. + * + * @return array + */ + public function provideThrottleLimitFilters() { + return [ + [ + [ 1 ], + [ + 'action' => 'edit', + 'target' => 'Test page', + 'oldText' => 'Some old text for the test.', + 'newText' => 'I like foo', + 'summary' => 'Test AbuseFilter for edit action.' + ] + ], [ - 'Basic test for "move" action.', [ 2 ], [ - 'move', - 'Test page', + 'action' => 'move', + 'target' => 'Test page', 'newTitle' => 'Another test page' + ] + ], + [ + [ 5 ], + [ + 'action' => 'edit', + 'target' => 'User:FilteredUser', + 'oldText' => 'Hey.', + 'newText' => 'I am a very nice user, really!', + 'summary' => '' + ] + ], + [ + [ 7, 8 ], + [ + 'action' => 'edit', + 'target' => 'Link', + 'oldText' => 'What is a link?', + 'newText' => 'A link is something like this: [[Link|]].', + 'summary' => 'Explaining' + ] + ], + [ + [ 3 ], + [ + 'action' => 'delete', + 'target' => 'Test page' + ] + ], + [ + [ 15 ], + [ + 'action' => 'createaccount', + 'target' => 'User:AnotherUser', + 'username' => 'AnotherUser' + ] + ] + ]; + } + + /** + * Check an array of results from self::doAction to ensure that all but the last actions have been + * executed (i.e. no errors). + * @param Status[] $results As returned by self::doActions + * @return Status The Status of the last action, to be later checked with self::checkConsequences + */ + private function checkThrottleConsequence( $results ) { + $finalRes = array_pop( $results ); + foreach ( $results as $result ) { + if ( !$result->isGood() ) { + $this->fail( 'Only the last actions should have triggered a filter; the other ones ' . + 'should have been allowed.' ); + } + } + + return $finalRes; + } + + /** + * Like self::testFilterConsequences but for throttle, which deserves a special treatment + * + * @param int[] $createIds IDs of the filters to create + * @param array[] $actionsParams Details of the action we need to execute to trigger filters + * @param array $consequences The consequences we're expecting + * @dataProvider provideThrottleFilters + */ + public function testThrottle( $createIds, $actionsParams, $consequences ) { + $this->createFilters( $createIds ); + $results = self::doActions( $actionsParams ); + $res = $this->checkThrottleConsequence( $results ); + $lastParams = array_pop( $actionsParams ); + list( $expected, $actual ) = $this->checkConsequences( $res, $lastParams, $consequences ); + + $this->assertEquals( + $expected, + $actual, + 'The error messages obtained by performing the action do not match.' + ); + } + + /** + * Data provider for testThrottle. For every test case, we pass + * - an array with the IDs of the filters to be created (listed in self::$filters), + * - an array of array, where every sub-array holds the details of the action to execute in + * order to trigger the filters, each one like in self::provideFilters + * - an array of expected consequences for the last action (i.e. after throttling) of the form + * [ 'consequence name' => [ IDs of the filter to take its parameters from ] ] + * Such IDs may be more than one if we have a warning that is shown twice. + * + * + * @return array + */ + public function provideThrottleFilters() { + return [ + 'Basic test for throttling edits' => [ + [ 11 ], + [ + [ + 'action' => 'edit', + 'target' => 'Throttle', + 'oldText' => 'What is throttle?', + 'newText' => 'Throttle is something that should happen...', + 'summary' => 'Throttle' + ], + [ + 'action' => 'edit', + 'target' => 'Throttle', + 'oldText' => 'Throttle is something that should happen...', + 'newText' => '... Right now!', + 'summary' => 'Throttle' + ] ], - [ 'disallow' => [ 2 ], 'block' => [ 2 ] ], - [] + [ 'disallow' => [ 11 ] ] + ], + 'Basic test for throttling "move"' => [ + [ 11 ], + [ + [ + 'action' => 'move', + 'target' => 'Throttle test', + 'newTitle' => 'Another throttle test' + ], + [ + 'action' => 'move', + 'target' => 'Another throttle test', + 'newTitle' => 'Yet another throttle test' + ], + ], + [ 'disallow' => [ 11 ] ] + ], + 'Basic test for throttling "delete"' => [ + [ 11 ], + [ + [ + 'action' => 'delete', + 'target' => 'Test page' + ], + [ + 'action' => 'delete', + 'target' => 'Test page' + ] + ], + [ 'disallow' => [ 11 ] ] + ], + 'Basic test for throttling "createaccount"' => [ + [ 11 ], + [ + [ + 'action' => 'createaccount', + 'target' => 'User:AnotherUser', + 'username' => 'AnotherUser' + ], + [ + 'action' => 'createaccount', + 'target' => 'User:YetAnotherUser', + 'username' => 'YetAnotherUser' + ] + ], + [ 'disallow' => [ 11 ] ] + ], + ]; + } + + /** + * Test storing and loading the var dump. See also AbuseFilterDBTest::testVarDump + * + * @param int[] $createIds IDs of the filters to create + * @param array $actionParams Details of the action we need to execute to trigger filters + * @param string[] $usedVars The variables effectively computed by filters in $createIds. + * We'll search these in the stored dump. + * @covers AbuseFilter::storeVarDump + * @covers AbuseFilter::loadVarDump + * @covers AbuseFilterVariableHolder::dumpAllVars + * @dataProvider provideFiltersAndVariables + */ + public function testVarDump( $createIds, $actionParams, $usedVars ) { + $this->createFilters( $createIds ); + // We don't care about consequences here + $this->doAction( $actionParams ); + + // We just take a dump from a single filters, as they're all identical for the same action + $dumpID = $this->db->selectField( + 'abuse_filter_log', + 'afl_var_dump', + '', + __METHOD__, + [ 'ORDER BY' => 'afl_timestamp DESC' ] + ); + + $vars = AbuseFilter::loadVarDump( $dumpID )->getVars(); + + $interestingVars = array_intersect_key( $vars, array_fill_keys( $usedVars, true ) ); + + sort( $usedVars ); + ksort( $interestingVars ); + $this->assertEquals( + $usedVars, + array_keys( $interestingVars ), + "The saved variables aren't the expected ones." + ); + $this->assertContainsOnlyInstancesOf( + AFPData::class, + $interestingVars, + 'Some variables have not been computed.' + ); + } + + /** + * Data provider for testVarDump + * + * @return array + */ + public function provideFiltersAndVariables() { + return [ + [ + [ 1, 2 ], + [ + 'action' => 'edit', + 'target' => 'Test page', + 'oldText' => 'Some old text for the test.', + 'newText' => 'I like foo', + 'summary' => 'Test AbuseFilter for edit action.' + ], + [ 'added_lines', 'action' ] + ], + [ + [ 1, 2 ], + [ + 'action' => 'stashedit', + 'target' => 'Test page', + 'oldText' => 'Some old text for the test.', + 'newText' => 'I like foo', + 'summary' => 'Test AbuseFilter for edit action.', + 'stashType' => 'hit' + ], + [ 'added_lines', 'action' ] + ], + [ + [ 1, 2 ], + [ + 'action' => 'stashedit', + 'target' => 'Test page', + 'oldText' => 'Some old text for the test.', + 'newText' => 'I like foo', + 'summary' => 'Test AbuseFilter for edit action.', + 'stashType' => 'miss' + ], + [ 'added_lines', 'action' ] + ], + [ + [ 2 ], + [ + 'action' => 'move', + 'target' => 'Test page', + 'newTitle' => 'Another test page' + ], + [ 'action', 'moved_to_title' ] + ], + [ + [ 5 ], + [ + 'action' => 'edit', + 'target' => 'User:FilteredUser', + 'oldText' => 'Hey.', + 'newText' => 'I am a very nice user, really!', + 'summary' => '' + ], + [ 'user_name' ] + ], + [ + [ 2, 3, 7, 8 ], + [ + 'action' => 'edit', + 'target' => 'Link', + 'oldText' => 'What is a link?', + 'newText' => 'A link is something like this: [[Link|]].', + 'summary' => 'Explaining' + ], + [ 'action', 'timestamp', 'added_lines_pst' ] + ], + [ + [ 2, 3, 7, 8 ], + [ + 'action' => 'stashedit', + 'target' => 'Link', + 'oldText' => 'What is a link?', + 'newText' => 'A link is something like this: [[Link|]].', + 'summary' => 'Explaining', + 'stashType' => 'hit' + ], + [ 'action', 'timestamp', 'added_lines_pst' ] + ], + [ + [ 2, 3, 7, 8 ], + [ + 'action' => 'stashedit', + 'target' => 'Link', + 'oldText' => 'What is a link?', + 'newText' => 'A link is something like this: [[Link|]].', + 'summary' => 'Explaining', + 'stashType' => 'miss' + ], + [ 'action', 'timestamp', 'added_lines_pst' ] + ], + [ + [ 8, 10 ], + [ + 'action' => 'edit', + 'target' => 'Anything', + 'oldText' => 'Bar', + 'newText' => 'Foo', + 'summary' => '' + ], + [ 'added_lines_pst' ] ], [ - 'Basic test for "delete" action.', [ 2, 3 ], [ - 'delete', - 'Test page' + 'action' => 'delete', + 'target' => 'Test page' + ], + [ 'action', 'page_prefixedtitle' ] + ], + [ + [ 10, 13 ], + [ + 'action' => 'edit', + 'target' => 'Tyger! Tyger! Burning bright', + 'oldText' => 'In the forests of the night', + 'newText' => 'What immortal hand or eye', + 'summary' => 'Could frame thy fearful symmetry?' ], - [ 'degroup' => [ 3 ] ], [] ], [ - 'Basic test for "createaccount" action.', - [ 1, 2, 3, 4 ], + [ 15 ], [ - 'createaccount', - null, + 'action' => 'createaccount', + 'target' => 'User:AnotherUser', 'username' => 'AnotherUser' ], - [], - [] + [ 'action' ] + ], + [ + [ 16 ], + [ + 'action' => 'edit', + 'target' => 'Random', + 'oldText' => 'Old text', + 'newText' => 'Some new text which will not match', + 'summary' => 'No summary' + ], + [ 'edit_diff_pst', 'new_pst', 'new_html' ] + ], + [ + [ 16 ], + [ + 'action' => 'stashedit', + 'target' => 'Random', + 'oldText' => 'Old text', + 'newText' => 'Some new text which will not match', + 'summary' => 'No summary', + 'stashType' => 'miss' + ], + [ 'edit_diff_pst', 'new_pst', 'new_html' ] + ], + [ + [ 16 ], + [ + 'action' => 'stashedit', + 'target' => 'Random', + 'oldText' => 'Old text', + 'newText' => 'Some new text which will not match', + 'summary' => 'No summary', + 'stashType' => 'hit' + ], + [ 'edit_diff_pst', 'new_pst', 'new_html' ] + ], + ]; + } + + /** + * Same as testFilterConsequences but only for stashed edits + * + * @param string $type Either "hit" or "miss". The former saves the edit from stash, the second + * stashes the edit but doesn't reuse it. + * @param int[] $createIds IDs of the filters to create + * @param array $actionParams Details of the action we need to execute to trigger filters + * @param array $consequences The consequences we're expecting + * @dataProvider provideStashedEdits + */ + public function testStashedEdit( $type, $createIds, $actionParams, $consequences ) { + if ( $type !== 'hit' && $type !== 'miss' ) { + throw new InvalidArgumentException( '$type must be either "hit" or "miss"' ); + } + // Add some info in actionParams identical for all tests + $actionParams['action'] = 'stashedit'; + $actionParams['stashType'] = $type; + + $loggerMock = new TestLogger(); + $loggerMock->setCollect( true ); + $this->setLogger( 'StashEdit', $loggerMock ); + + $this->createFilters( $createIds ); + $result = $this->doAction( $actionParams ); + + // Check that we stored the edit and then hit/missed the cache + $foundStore = false; + $foundHitOrMiss = false; + // The conversion back and forth is needed because if the wiki language is not english + // the given namespace has been localized and thus wouldn't match. + $pageName = Title::newFromText( $actionParams['target'] )->getPrefixedText(); + foreach ( $loggerMock->getBuffer() as $entry ) { + if ( preg_match( "/AbuseFilterRunner::logCache: cache $type for '$pageName'/", $entry[1] ) ) { + $foundHitOrMiss = true; + } + if ( preg_match( "/AbuseFilterRunner::logCache: cache store for '$pageName'/", $entry[1] ) ) { + $foundStore = true; + } + if ( $foundStore && $foundHitOrMiss ) { + break; + } + } + if ( !$foundStore ) { + $this->fail( 'Did not store the edit in cache as expected for a stashed edit.' ); + } elseif ( !$foundHitOrMiss ) { + $this->fail( "Did not $type the cache as expected for a stashed edit." ); + } + + list( $expected, $actual ) = $this->checkConsequences( $result, $actionParams, $consequences ); + + $this->assertEquals( + $expected, + $actual, + 'The error messages obtained by performing the action do not match.' + ); + } + + /** + * Data provider for testStashedEdit + * + * @return array + */ + public function provideStashedEdits() { + $sets = [ + [ + [ 1, 2 ], + [ + 'target' => 'Test page', + 'oldText' => 'Some old text for the test.', + 'newText' => 'I like foo', + 'summary' => 'Test AbuseFilter for edit action.' + ], + [ 'warn' => [ 1 ] ] ], [ - 'Test to check that all tags are applied.', [ 5 ], [ - 'edit', - 'User:FilteredUser', + 'target' => 'User:FilteredUser', 'oldText' => 'Hey.', 'newText' => 'I am a very nice user, really!', 'summary' => '' ], - [ 'tag' => [ 5 ] ], - [] + [ 'tag' => [ 5 ] ] ], [ - 'Test to check that the edit is disallowed.', [ 6 ], [ - 'edit', - 'Help:Help', + 'target' => 'Help:Help', 'oldText' => 'Some help.', 'newText' => 'Some help for you', 'summary' => 'Help! I need somebody' ], - [ 'disallow' => [ 6 ] ], - [] + [ 'disallow' => [ 6 ] ] ], [ - 'Test to check that degroup and block are executed together.', [ 2, 3, 7, 8 ], [ - 'edit', - 'Link', + 'target' => 'Link', 'oldText' => 'What is a link?', 'newText' => 'A link is something like this: [[Link|]].', 'summary' => 'Explaining' ], - [ 'degroup' => [ 7 ], 'block' => [ 8 ] ], - [] + [ 'degroup' => [ 7 ], 'block' => [ 8 ] ] ], [ - 'Test to check that the block duration is the longest one.', [ 8, 9 ], [ - 'edit', - 'Whatever', + 'target' => 'Whatever', 'oldText' => 'Whatever is whatever', 'newText' => 'Whatever is whatever, whatever it is. BTW, here is a [[Link|]]', 'summary' => 'Whatever' ], - [ 'disallow' => [ 8 ], 'block' => [ 8 ] ], - [] + [ 'disallow' => [ 8 ], 'block' => [ 8 ] ] ], [ - 'Test to check that throttled filters only execute "safe" actions.', [ 10 ], [ - 'edit', - 'Buffalo', + 'target' => 'Buffalo', 'oldText' => 'Buffalo', 'newText' => 'Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo.', 'summary' => 'Buffalo!' ], - [ 'tag' => [ 10 ] ], - [] + [ 'tag' => [ 10 ] ] ], [ - 'Test to see that throttling works well.', - [ 11 ], - [ - 'edit', - 'Throttle', - 'oldText' => 'What is throttle?', - 'firstNewText' => 'Throttle is something that should happen...', - 'secondNewText' => '... Right now!', - 'summary' => 'Throttle' - ], - [ 'throttle' => [ 11 ], 'disallow' => [ 11 ] ], - [ 'makeGoodEditFirst' ] - ], - [ - 'Test to check that degroup and block are both executed and degroup warning is shown twice.', [ 1, 3, 7, 12 ], [ - 'edit', - 'User:FilteredUser', + 'target' => 'User:FilteredUser', 'oldText' => '', 'newText' => 'A couple of lines about me...', 'summary' => 'My user page' ], - [ 'block' => [ 12 ], 'degroup' => [ 7, 12 ] ], - [] + [ 'block' => [ 12 ], 'degroup' => [ 7, 12 ] ] ], [ - 'Test to check that every throttled filter only executes "safe" actions.', [ 10, 13 ], [ - 'edit', - 'Tyger! Tyger! Burning bright', + 'target' => 'Tyger! Tyger! Burning bright', 'oldText' => 'In the forests of the night', 'newText' => 'What immortal hand or eye', 'summary' => 'Could frame thy fearful symmetry?' ], - [ 'tag' => [ 10 ] ], - [] + [ 'tag' => [ 10 ] ] ], [ - 'Test to check that runtime exceptions (division by zero) are correctly handled.', [ 14 ], [ - 'edit', - '0', + 'target' => '0', 'oldText' => 'Old text', 'newText' => 'New text', 'summary' => 'Some summary' ], - [], [] ], [ - 'Test to check that the conditions limit works.', [ 8, 10 ], [ - 'edit', - 'Anything', + 'target' => 'Anything', 'oldText' => 'Bar', 'newText' => 'Foo', 'summary' => '' ], - [], - [ 'hitCondsLimit' ] + [] ], [ - 'Test slow executions.', [ 7, 12 ], [ - 'edit', - 'Something', + 'target' => 'Something', 'oldText' => 'Please allow me', 'newText' => 'to introduce myself', 'summary' => '' ], - [ 'degroup' => [ 7 ] ], - [ 'hitTimeLimit' ] + [ 'degroup' => [ 7 ] ] ], [ - 'Test throttling a dangerous filter.', [ 13 ], [ - 'edit', - 'My page', + 'target' => 'My page', 'oldText' => '', 'newText' => 'AbuseFilter will not block me', 'summary' => '' ], - [], - [ 'hitThrottleLimit' ] + [] + ], + ]; + + $finalSets = []; + foreach ( $sets as $set ) { + // Test both successfully saving a stashed edit and stashing the edit but re-executing filters + $finalSets[] = array_merge( [ 'miss' ], $set ); + $finalSets[] = array_merge( [ 'hit' ], $set ); + } + return $finalSets; + } + + /** + * Test filter profiling, both for total and per-filter stats. NOTE: This test performs several + * actions for every test set, and is thus HEAVY. + * + * @param int[] $createIds IDs of the filters to create + * @param array $actionParams Details of the action we need to execute to trigger filters + * @param array $expectedGlobal Expected global stats + * @param array $expectedPerFilter Expected stats for every created filter + * @covers AbuseFilter::filterProfileKey + * @covers AbuseFilter::filterProfileGroupKey + * @covers AbuseFilter::getFilterProfile + * @covers AbuseFilterRunner::checkAllFilters + * @covers AbuseFilterRunner::recordStats + * @dataProvider provideProfilingFilters + */ + public function testProfiling( $createIds, $actionParams, $expectedGlobal, $expectedPerFilter ) { + $this->setMwGlobals( [ + 'wgAbuseFilterConditionLimit' => $actionParams[ 'condsLimit' ] + ] ); + $this->createFilters( $createIds ); + for ( $i = 1; $i <= $actionParams['repeatAction'] - 1; $i++ ) { + // First make some other actions to increase stats + // @ToDo This doesn't works well with account creations + $this->doAction( $actionParams ); + $actionParams['target'] .= $i; + } + // This is the magic value used by filter 16 to change the amount of used condition + MWTimestamp::setFakeTime( self::MAGIC_TIMESTAMP ); + // We don't care about consequences here + $this->doAction( $actionParams ); + MWTimestamp::setFakeTime( false ); + + $stash = MediaWikiServices::getInstance()->getMainObjectStash(); + // Global stats shown on the top of Special:AbuseFilter + $globalStats = $stash->get( AbuseFilter::filterProfileGroupKey( 'default' ) ); + $actualGlobalStats = [ + 'totalMatches' => $globalStats['matches'], + 'totalActions' => $globalStats['total'], + 'totalOverflows' => $globalStats['overflow'] + ]; + $this->assertSame( + $expectedGlobal, + $actualGlobalStats, + 'Global profiling stats are not computed correctly.' + ); + + // Per-filter stats shown on the top of Special:AbuseFilter/xxx + foreach ( $createIds as $id ) { + list( $totalActions, $matches, , $conds ) = AbuseFilter::getFilterProfile( $id ); + $actualStats = [ + 'matches' => $matches, + 'actions' => $totalActions, + 'averageConditions' => $conds + ]; + $this->assertSame( + $expectedPerFilter[ $id ], + $actualStats, + "Profiling stats are not computed correctly for filter $id." + ); + } + } + + /** + * Data provider for testProfiling. We only want filters which let the edit pass, since + * we'll perform multiple edits. How this test works: we repeat the action X times. For 1 to + * X - 1, it would take 1 + 1 + 5 + 1 conditions, but it will overflow without checking filter + * 19 (since the conds limit is 7). Then we perform the last execution using a trick that will + * make filter 17 only consume 1 condition. + * + * @todo All these values should be more customizable, or just hardcoded in the test method. + * + * @return array + */ + public function provideProfilingFilters() { + return [ + 'Basic test for statistics recording on edit.' => [ + [ 4, 5, 17, 19 ], + [ + 'action' => 'edit', + 'target' => 'Some page', + 'oldText' => 'Some old text', + 'newText' => 'Some new text', + 'summary' => 'Some summary', + 'condsLimit' => 7, + 'repeatAction' => 3 + ], + [ + 'totalMatches' => 3, + 'totalActions' => 3, + 'totalOverflows' => 2 + ], + [ + 4 => [ + 'matches' => 0, + 'actions' => 3, + 'averageConditions' => 1.0 + ], + 5 => [ + 'matches' => 3, + 'actions' => 3, + 'averageConditions' => 1.0 + ], + 17 => [ + 'matches' => 1, + 'actions' => 3, + 'averageConditions' => 3.7 + ], + 19 => [ + 'matches' => 1, + 'actions' => 3, + 'averageConditions' => 1.0 + ], + ] + ], + 'Test for statistics recording on a successfully stashed edit.' => [ + [ 4, 5, 17, 19 ], + [ + 'action' => 'stashedit', + 'target' => 'Some page', + 'oldText' => 'Some old text', + 'newText' => 'Some new text', + 'summary' => 'Some summary', + 'stashType' => 'hit', + 'condsLimit' => 7, + 'repeatAction' => 3 + ], + [ + 'totalMatches' => 3, + 'totalActions' => 3, + 'totalOverflows' => 2 + ], + [ + 4 => [ + 'matches' => 0, + 'actions' => 3, + 'averageConditions' => 1.0 + ], + 5 => [ + 'matches' => 3, + 'actions' => 3, + 'averageConditions' => 1.0 + ], + 17 => [ + 'matches' => 1, + 'actions' => 3, + 'averageConditions' => 3.7 + ], + 19 => [ + 'matches' => 1, + 'actions' => 3, + 'averageConditions' => 1.0 + ], + ] + ], + 'Test for statistics recording on an unsuccessfully stashed edit.' => [ + [ 4, 5, 17, 19 ], + [ + 'action' => 'stashedit', + 'target' => 'Some page', + 'oldText' => 'Some old text', + 'newText' => 'Some new text', + 'summary' => 'Some summary', + 'stashType' => 'miss', + 'condsLimit' => 7, + 'repeatAction' => 3 + ], + [ + 'totalMatches' => 3, + 'totalActions' => 3, + 'totalOverflows' => 2 + ], + [ + 4 => [ + 'matches' => 0, + 'actions' => 3, + 'averageConditions' => 1.0 + ], + 5 => [ + 'matches' => 3, + 'actions' => 3, + 'averageConditions' => 1.0 + ], + 17 => [ + 'matches' => 1, + 'actions' => 3, + 'averageConditions' => 3.7 + ], + 19 => [ + 'matches' => 1, + 'actions' => 3, + 'averageConditions' => 1.0 + ], + ] + ] + ]; + } + + /** + * Tests for global filters, defined on a central wiki and executed on another (e.g. a filter + * defined on meta but triggered on another wiki using meta's global filters). + * We emulate an external database by using different tables prefixed with + * self::DB_EXTERNAL_PREFIX + * + * @param int[] $createIds IDs of the filters to create + * @param array $actionParams Details of the action we need to execute to trigger filters + * @param array $consequences The consequences we're expecting + * @dataProvider provideGlobalFilters + */ + public function testGlobalFilters( $createIds, $actionParams, $consequences ) { + $this->createFilters( $createIds, true ); + + $result = $this->doAction( $actionParams ); + + list( $expected, $actual ) = $this->checkConsequences( $result, $actionParams, $consequences ); + + // First check that the filter work as expected + $this->assertEquals( + $expected, + $actual, + 'The error messages obtained by performing the action do not match.' + ); + + // Check that the hits were logged on the "external" DB + $logged = $this->db->selectFieldValues( + self::DB_EXTERNAL_PREFIX . 'abuse_filter_log', + 'afl_filter', + [ 'afl_wiki IS NOT NULL' ], + __METHOD__ + ); + // Don't use assertSame because the DB holds strings here (T42757) + $this->assertEquals( + $createIds, + $logged, + 'Some filter hits were not logged in the external DB.' + ); + } + + /** + * Data provider for testGlobalFilters + * + * @return array + */ + public function provideGlobalFilters() { + return [ + [ + [ 18 ], + [ + 'action' => 'edit', + 'target' => 'Global', + 'oldText' => 'Old text', + 'newText' => 'New text', + 'summary' => '' + ], + [ 'disallow' => [ 18 ], 'warn' => [ 18 ] ] ], + [ + [ 19 ], + [ + 'action' => 'edit', + 'target' => 'A global page', + 'oldText' => 'Foo', + 'newText' => 'Bar', + 'summary' => 'Baz' + ], + [ 'tag' => [ 19 ] ] + ], + [ + [ 19, 20 ], + [ + 'action' => 'edit', + 'target' => 'Cellar door', + 'oldText' => '', + 'newText' => 'Yay, that\'s cool', + 'summary' => 'Unit test' + ], + [ 'disallow' => [ 20 ] ] + ], + [ + [ 18 ], + [ + 'action' => 'move', + 'target' => 'Cellar door', + 'newTitle' => 'Attic door' + ], + [ 'warn' => [ 18 ] ] + ], + [ + [ 19, 20 ], + [ + 'action' => 'delete', + 'target' => 'Cellar door', + ], + [ 'disallow' => [ 20 ] ] + ], + [ + [ 19 ], + [ + 'action' => 'stashedit', + 'target' => 'Cellar door', + 'oldText' => '', + 'newText' => 'Too many doors', + 'summary' => '', + 'stashType' => 'hit' + ], + [ 'tag' => [ 19 ] ] + ], + [ + [ 18 ], + [ + 'action' => 'createaccount', + 'target' => 'User:AbuseFilterGlobalUser', + 'username' => 'AbuseFilterGlobalUser' + ], + [ 'warn' => [ 18 ] ] + ] ]; } } diff --git a/AbuseFilter/tests/phpunit/AbuseFilterDBTest.php b/AbuseFilter/tests/phpunit/AbuseFilterDBTest.php new file mode 100644 index 00000000..c0358109 --- /dev/null +++ b/AbuseFilter/tests/phpunit/AbuseFilterDBTest.php @@ -0,0 +1,362 @@ +<?php + +use MediaWiki\Revision\MutableRevisionRecord; +use MediaWiki\Revision\RevisionRecord; +use MediaWiki\Revision\SlotRecord; +use PHPUnit\Framework\MockObject\MockObject; + +/** + * Generic tests for utility functions in AbuseFilter that require DB access + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * + * @license GPL-2.0-or-later + */ + +/** + * @group Test + * @group AbuseFilter + * @group AbuseFilterGeneric + * @group Database + */ +class AbuseFilterDBTest extends MediaWikiTestCase { + /** + * @var array These tables will be deleted in parent::tearDown. + * We need it to happen to make tests on fresh pages. + */ + protected $tablesUsed = [ + 'abuse_filter', + 'abuse_filter_history', + 'abuse_filter_log' + ]; + + /** + * Test storing and loading the var dump. See also AbuseFilterConsequencesTest::testVarDump + * + * @param array $variables Map of [ name => value ] to build an AbuseFilterVariableHolder with + * @param ?array $expectedValues Null to use $variables + * @covers AbuseFilter::storeVarDump + * @covers AbuseFilter::loadVarDump + * @covers AbuseFilterVariableHolder::dumpAllVars + * @dataProvider provideVariables + */ + public function testVarDump( array $variables, array $expectedValues = null ) { + global $wgCompressRevisions, $wgDefaultExternalStore; + + $holder = AbuseFilterVariableHolder::newFromArray( $variables ); + + $insertID = AbuseFilter::storeVarDump( $holder ); + + $flags = $this->db->selectField( + 'text', + 'old_flags', + '', + __METHOD__, + [ 'ORDER BY' => 'old_id DESC' ] + ); + $this->assertNotFalse( $flags, 'The var dump has not been saved.' ); + $flags = $flags === '' ? [] : explode( ',', $flags ); + + $expectedFlags = [ 'utf-8' ]; + if ( $wgCompressRevisions ) { + $expectedFlags[] = 'gzip'; + } + if ( $wgDefaultExternalStore ) { + $expectedFlags[] = 'external'; + } + + $this->assertEquals( $expectedFlags, $flags, 'The var dump does not have the correct flags' ); + + $dump = AbuseFilter::loadVarDump( "stored-text:$insertID" ); + $expected = $expectedValues ? AbuseFilterVariableHolder::newFromArray( $expectedValues ) : $holder; + $this->assertEquals( $expected, $dump, 'The var dump is not saved correctly' ); + } + + /** + * Data provider for testVarDump + * + * @return array + */ + public function provideVariables() { + return [ + 'Only basic variables' => [ + [ + 'action' => 'edit', + 'old_wikitext' => 'Old text', + 'new_wikitext' => 'New text' + ] + ], + 'Normal case' => [ + [ + 'action' => 'edit', + 'old_wikitext' => 'Old text', + 'new_wikitext' => 'New text', + 'user_editcount' => 15, + 'added_lines' => [ 'Foo', '', 'Bar' ] + ] + ], + 'Deprecated variables' => [ + [ + 'action' => 'edit', + 'old_wikitext' => 'Old text', + 'new_wikitext' => 'New text', + 'article_articleid' => 11745, + 'article_first_contributor' => 'Good guy' + ], + [ + 'action' => 'edit', + 'old_wikitext' => 'Old text', + 'new_wikitext' => 'New text', + 'page_id' => 11745, + 'page_first_contributor' => 'Good guy' + ] + ], + 'Move action' => [ + [ + 'action' => 'move', + 'old_wikitext' => 'Old text', + 'new_wikitext' => 'New text', + 'all_links' => [ 'https://en.wikipedia.org' ], + 'moved_to_id' => 156, + 'moved_to_prefixedtitle' => 'MediaWiki:Foobar.js', + 'new_content_model' => CONTENT_MODEL_JAVASCRIPT + ] + ], + 'Delete action' => [ + [ + 'old_wikitext' => 'Old text', + 'new_wikitext' => 'New text', + 'timestamp' => 1546000295, + 'action' => 'delete', + 'page_namespace' => 114 + ] + ], + 'Disabled vars' => [ + [ + 'action' => 'edit', + 'old_wikitext' => 'Old text', + 'new_wikitext' => 'New text', + 'old_html' => 'Foo <small>bar</small> <s>lol</s>.', + 'old_text' => 'Foobar' + ] + ], + 'Account creation' => [ + [ + 'action' => 'createaccount', + 'accountname' => 'XXX' + ] + ] + ]; + } + + /** + * @param RevisionRecord|null $rev The revision being converted + * @param bool $sysop Whether the user should be a sysop (i.e. able to see deleted stuff) + * @param string $expected The expected textual representation of the Revision + * @covers AbuseFilter::revisionToString + * @dataProvider provideRevisionToString + * @todo This should be a unit test... + */ + public function testRevisionToString( ?RevisionRecord $rev, bool $sysop, string $expected ) { + /** @var MockObject|User $user */ + $user = $this->getMockBuilder( User::class ) + ->setMethods( [ 'getEffectiveGroups' ] ) + ->getMock(); + if ( $sysop ) { + $user->expects( $this->atLeastOnce() ) + ->method( 'getEffectiveGroups' ) + ->willReturn( [ 'user', 'sysop' ] ); + } else { + $user->expects( $this->any() ) + ->method( 'getEffectiveGroups' ) + ->willReturn( [ 'user' ] ); + } + + $user->clearInstanceCache(); + + $actual = AbuseFilter::revisionToString( $rev, $user ); + $this->assertSame( $expected, $actual ); + } + + /** + * Data provider for testRevisionToString + * + * @return Generator|array + */ + public function provideRevisionToString() { + yield 'no revision' => [ null, false, '' ]; + + $title = Title::newFromText( __METHOD__ ); + $revRec = new MutableRevisionRecord( $title ); + $revRec->setContent( SlotRecord::MAIN, new TextContent( 'Main slot text.' ) ); + + yield 'RevisionRecord instance' => [ + $revRec, + false, + 'Main slot text.' + ]; + + $revRec = new MutableRevisionRecord( $title ); + $revRec->setContent( SlotRecord::MAIN, new TextContent( 'Main slot text.' ) ); + $revRec->setContent( 'aux', new TextContent( 'Aux slot content.' ) ); + yield 'Multi-slot' => [ + $revRec, + false, + "Main slot text.\n\nAux slot content." + ]; + + $revRec = new MutableRevisionRecord( $title ); + $revRec->setContent( SlotRecord::MAIN, new TextContent( 'Main slot text.' ) ); + $revRec->setVisibility( RevisionRecord::DELETED_TEXT ); + yield 'Suppressed revision, unprivileged' => [ + $revRec, + false, + '' + ]; + + yield 'Suppressed revision, privileged' => [ + $revRec, + true, + 'Main slot text.' + ]; + } + + /** + * Check that our tag validation is working properly. Note that we only need one test + * for each called function. Consistency within ChangeTags functions should be + * assured by tests in core. The test for canAddTagsAccompanyingChange and canCreateTag + * are missing because they won't actually fail, never. Resolving T173917 would + * greatly improve the situation and could help writing better tests. + * + * @param string $tag The tag to validate + * @param string|null $error The expected error message. Null if validations should pass + * @covers AbuseFilter::isAllowedTag + * @dataProvider provideTags + */ + public function testIsAllowedTag( $tag, $error ) { + $status = AbuseFilter::isAllowedTag( $tag ); + + if ( !$status->isGood() ) { + $actualError = $status->getErrors(); + $actualError = $actualError[0]['message']; + } else { + $actualError = null; + if ( $error !== null ) { + $this->fail( "Tag validation returned a valid status instead of the expected '$error' error." ); + } + } + + $this->assertSame( + $error, + $actualError, + "Expected message '$error', got '$actualError' while validating the tag '$tag'." + ); + } + + /** + * Data provider for testIsAllowedTag + * @return array + */ + public function provideTags() { + return [ + [ 'a|b', 'tags-create-invalid-chars' ], + [ 'mw-undo', 'abusefilter-edit-bad-tags' ], + [ 'abusefilter-condition-limit', 'abusefilter-tag-reserved' ], + [ 'my_tag', null ], + ]; + } + + /** + * Test for the wiki_name variable. + * + * @covers AbuseFilter::generateGenericVars + * @covers AFComputedVariable::compute + */ + public function testWikiNameVar() { + $name = 'foo'; + $prefix = 'bar'; + $this->setMwGlobals( [ + 'wgDBname' => $name, + 'wgDBprefix' => $prefix + ] ); + + $vars = new AbuseFilterVariableHolder(); + $vars->setLazyLoadVar( 'wiki_name', 'get-wiki-name', [] ); + $this->assertSame( + "$name-$prefix", + $vars->getVar( 'wiki_name' )->toNative() + ); + } + + /** + * Test for the wiki_language variable. + * + * @covers AbuseFilter::generateGenericVars + * @covers AFComputedVariable::compute + */ + public function testWikiLanguageVar() { + $fakeCode = 'foobar'; + $fakeLang = $this->getMockBuilder( Language::class ) + ->setMethods( [ 'getCode' ] ) + ->getMock(); + $fakeLang->method( 'getCode' )->willReturn( $fakeCode ); + $this->setService( 'ContentLanguage', $fakeLang ); + + $vars = new AbuseFilterVariableHolder(); + $vars->setLazyLoadVar( 'wiki_language', 'get-wiki-language', [] ); + $this->assertSame( + $fakeCode, + $vars->getVar( 'wiki_language' )->toNative() + ); + } + + /** + * @param RevisionRecord $revRec + * @param bool $privileged + * @param bool $expected + * @dataProvider provideUserCanViewRev + * @covers AbuseFilter::userCanViewRev + */ + public function testUserCanViewRev( RevisionRecord $revRec, bool $privileged, bool $expected ) { + $user = $privileged + ? $this->getTestUser( 'suppress' )->getUser() + : $this->getTestUser()->getUser(); + $this->assertSame( $expected, AbuseFilter::userCanViewRev( $revRec, $user ) ); + } + + /** + * @return Generator|array + */ + public function provideUserCanViewRev() { + $title = Title::newFromText( __METHOD__ ); + + $visible = new MutableRevisionRecord( $title ); + yield 'Visible, not privileged' => [ $visible, false, true ]; + yield 'Visible, privileged' => [ $visible, true, true ]; + + $userSup = new MutableRevisionRecord( $title ); + $userSup->setVisibility( RevisionRecord::SUPPRESSED_USER ); + yield 'User suppressed, not privileged' => [ $userSup, false, false ]; + yield 'User suppressed, privileged' => [ $userSup, true, true ]; + + $allSupp = new MutableRevisionRecord( $title ); + $allSupp->setVisibility( RevisionRecord::SUPPRESSED_ALL ); + yield 'All suppressed, not privileged' => [ $allSupp, false, false ]; + yield 'All suppressed, privileged' => [ $allSupp, true, true ]; + } +} diff --git a/AbuseFilter/tests/phpunit/AbuseFilterParserEquivsetTest.php b/AbuseFilter/tests/phpunit/AbuseFilterParserEquivsetTest.php new file mode 100644 index 00000000..9b46337a --- /dev/null +++ b/AbuseFilter/tests/phpunit/AbuseFilterParserEquivsetTest.php @@ -0,0 +1,129 @@ +<?php +/** + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * + * @license GPL-2.0-or-later + */ + +use MediaWiki\Extension\AbuseFilter\AbuseFilterServices; + +/** + * Tests that require Equivset, separated from the parser unit tests. + * + * @group Test + * @group AbuseFilter + * @group AbuseFilterParser + * + * @covers AbuseFilterCachingParser + * @covers AFPTreeParser + * @covers AFPTransitionBase + * @covers AFPTreeNode + * @covers AFPSyntaxTree + * @covers AFPParserState + * @covers AbuseFilterParser + * @covers AbuseFilterTokenizer + * @covers AFPToken + * @covers AFPData + */ +class AbuseFilterParserEquivsetTest extends MediaWikiIntegrationTestCase { + /** + * @see AbuseFilterParserTestCase::getParsers() - we cannot reuse that due to inheritance + * @return AbuseFilterParser[] + */ + protected function getParsers() { + static $parsers = null; + if ( !$parsers ) { + // We're not interested in caching or logging; tests should call respectively setCache + // and setLogger if they want to test any of those. + $contLang = new LanguageEn(); + $cache = new EmptyBagOStuff(); + $logger = new \Psr\Log\NullLogger(); + $keywordsManager = AbuseFilterServices::getKeywordsManager(); + + $parser = new AbuseFilterParser( $contLang, $cache, $logger, $keywordsManager ); + $parser->toggleConditionLimit( false ); + $cachingParser = new AbuseFilterCachingParser( $contLang, $cache, $logger, $keywordsManager ); + $cachingParser->toggleConditionLimit( false ); + $parsers = [ $parser, $cachingParser ]; + } else { + // Reset so that already executed tests don't influence new ones + $parsers[0]->resetState(); + $parsers[0]->clearFuncCache(); + $parsers[1]->resetState(); + $parsers[1]->clearFuncCache(); + } + return $parsers; + } + + /** + * @param string $rule The rule to parse + * @dataProvider provideGenericTests + */ + public function testGeneric( $rule ) { + if ( !class_exists( 'Wikimedia\Equivset\Equivset' ) ) { + $this->markTestSkipped( 'Equivset is not installed' ); + } + foreach ( $this->getParsers() as $parser ) { + $this->assertTrue( $parser->parse( $rule ), 'Parser used: ' . get_class( $parser ) ); + } + } + + /** + * @return Generator|array + */ + public function provideGenericTests() { + $testPath = __DIR__ . "/../parserTestsEquivset"; + $testFiles = glob( $testPath . "/*.t" ); + + foreach ( $testFiles as $testFile ) { + $testName = basename( substr( $testFile, 0, -2 ) ); + $rule = trim( file_get_contents( $testFile ) ); + + yield $testName => [ $rule ]; + } + } + + /** + * @param string $func + * @see AbuseFilterParserTest::testVariadicFuncsArbitraryArgsAllowed() + * @dataProvider variadicFuncs + */ + public function testVariadicFuncsArbitraryArgsAllowed( $func ) { + $argsList = str_repeat( ', "arg"', 50 ); + $code = "$func( 'arg' $argsList )"; + foreach ( $this->getParsers() as $parser ) { + $pname = get_class( $parser ); + try { + $parser->parse( $code ); + $this->assertTrue( true ); + } catch ( AFPException $e ) { + $this->fail( "Got exception with parser $pname.\n$e" ); + } + } + } + + /** + * @return array + */ + public function variadicFuncs() { + return [ + [ 'ccnorm_contains_any' ], + [ 'ccnorm_contains_all' ], + ]; + } +} diff --git a/AbuseFilter/tests/phpunit/AbuseFilterParserTest.php b/AbuseFilter/tests/phpunit/AbuseFilterParserTest.php deleted file mode 100644 index 747e500a..00000000 --- a/AbuseFilter/tests/phpunit/AbuseFilterParserTest.php +++ /dev/null @@ -1,744 +0,0 @@ -<?php -/** - * Tests for the AbuseFilter parser - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - * - * @license GPL-2.0-or-later - * @author Marius Hoch < hoo@online.de > - */ - -/** - * @group Test - * @group AbuseFilter - * @group AbuseFilterParser - * - * @covers AbuseFilterCachingParser - * @covers AFPTreeParser - * @covers AFPTreeNode - * @covers AFPParserState - * @covers AbuseFilterParser - * @covers AbuseFilterTokenizer - * @covers AFPToken - * @covers AFPUserVisibleException - * @covers AFPException - * @covers AFPData - * @covers AbuseFilterVariableHolder - * @covers AFComputedVariable - */ -class AbuseFilterParserTest extends MediaWikiTestCase { - /** - * @return AbuseFilterParser - */ - public static function getParser() { - static $parser = null; - if ( !$parser ) { - $parser = new AbuseFilterParser(); - } else { - $parser->resetState(); - } - return $parser; - } - - /** - * @return AbuseFilterParser[] - */ - public static function getParsers() { - static $parsers = null; - if ( !$parsers ) { - $parsers = [ - new AbuseFilterParser() - // @ToDo: Here we should also instantiate an AbuseFilterCachingParser as we'll have - // fixed its problems (T156095). Right now it may break otherwise working tests (see T201193) - ]; - } - return $parsers; - } - - /** - * @dataProvider readTests - */ - public function testParser( $testName, $rule, $expected ) { - foreach ( self::getParsers() as $parser ) { - $actual = $parser->parse( $rule ); - $this->assertEquals( $expected, $actual, 'Running parser test ' . $testName ); - } - } - - /** - * @return array - */ - public function readTests() { - $tests = []; - $testPath = __DIR__ . "/../parserTests"; - $testFiles = glob( $testPath . "/*.t" ); - - foreach ( $testFiles as $testFile ) { - $testName = substr( $testFile, 0, -2 ); - - $resultFile = $testName . '.r'; - $rule = trim( file_get_contents( $testFile ) ); - $result = trim( file_get_contents( $resultFile ) ) === 'MATCH'; - - $tests[] = [ - basename( $testName ), - $rule, - $result - ]; - } - - return $tests; - } - - /** - * Test expression evaluation - * - * @dataProvider provideExpressions - */ - public function testEvaluateExpression( $expr, $expected ) { - foreach ( self::getParsers() as $parser ) { - $actual = $parser->evaluateExpression( $expr ); - $this->assertEquals( $expected, $actual ); - } - } - - /** - * Data provider for testEvaluateExpression - * - * @return array - */ - public function provideExpressions() { - return [ - [ '1 === 1', true ], - [ 'rescape( "abc* (def)" )', 'abc\* \(def\)' ], - [ 'str_replace( "foobarbaz", "bar", "-" )', 'foo-baz' ], - [ 'rmdoubles( "foobybboo" )', 'fobybo' ], - [ 'lcase("FÁmí")', 'fámí' ], - [ 'substr( "foobar", 0, 3 )', 'foo' ] - ]; - } - - /** - * Ensure that AbuseFilterTokenizer::OPERATOR_RE matches the contents - * and order of AbuseFilterTokenizer::$operators. - */ - public function testOperatorRe() { - $operatorRe = '/(' . implode( '|', array_map( function ( $op ) { - return preg_quote( $op, '/' ); - }, AbuseFilterTokenizer::$operators ) ) . ')/A'; - $this->assertEquals( $operatorRe, AbuseFilterTokenizer::OPERATOR_RE ); - } - - /** - * Ensure that AbuseFilterTokenizer::RADIX_RE matches the contents - * and order of AbuseFilterTokenizer::$bases. - */ - public function testRadixRe() { - $baseClass = implode( '', array_keys( AbuseFilterTokenizer::$bases ) ); - $radixRe = "/([0-9A-Fa-f]+(?:\.\d*)?|\.\d+)([$baseClass])?/Au"; - $this->assertEquals( $radixRe, AbuseFilterTokenizer::RADIX_RE ); - } - - /** - * Ensure the number of conditions counted for given expressions is right. - * - * @dataProvider condCountCases - */ - public function testCondCount( $rule, $expected ) { - $parser = self::getParser(); - $countBefore = AbuseFilter::$condCount; - $parser->parse( $rule ); - $countAfter = AbuseFilter::$condCount; - $actual = $countAfter - $countBefore; - $this->assertEquals( $expected, $actual, 'Condition count for ' . $rule ); - } - - /** - * Data provider for testCondCount method. - * @return array - */ - public function condCountCases() { - return [ - [ '((("a" == "b")))', 1 ], - [ 'contains_any("a", "b", "c")', 1 ], - [ '"a" == "b" == "c"', 2 ], - [ '"a" in "b" + "c" in "d" + "e" in "f"', 3 ], - [ 'true', 0 ], - [ '"a" == "a" | "c" == "d"', 1 ], - [ '"a" == "b" & "c" == "d"', 1 ], - ]; - } - - /** - * Ensure get_matches function captures returns expected output. - * @param string $needle Regex to pass to get_matches. - * @param string $haystack String to run regex against. - * @param string[] $expected The expected values of the matched groups. - * @covers AbuseFilterParser::funcGetMatches - * @dataProvider getMatchesCases - */ - public function testGetMatches( $needle, $haystack, $expected ) { - $parser = self::getParser(); - $afpData = $parser->intEval( "get_matches('$needle', '$haystack')" )->data; - - // Extract matches from AFPData. - $matches = array_map( function ( $afpDatum ) { - return $afpDatum->data; - }, $afpData ); - - $this->assertEquals( $expected, $matches ); - } - - /** - * Data provider for get_matches method. - * @return array - */ - public function getMatchesCases() { - return [ - [ - 'You say (.*) \(and I say (.*)\)\.', - 'You say hello (and I say goodbye).', - [ - 'You say hello (and I say goodbye).', - 'hello', - 'goodbye', - ], - ], - [ - 'I(?: am)? the ((walrus|egg man).*)\!', - 'I am the egg man, I am the walrus !', - [ - 'I am the egg man, I am the walrus !', - 'egg man, I am the walrus ', - 'egg man', - ], - ], - [ - 'this (does) not match', - 'foo bar', - [ - false, - false, - ], - ], - ]; - } - - /** - * Base method for testing exceptions - * - * @param string $excep Identifier of the exception (e.g. 'unexpectedtoken') - * @param string $expr The expression to test - * @param string $caller The function where the exception is thrown - */ - private function exceptionTest( $excep, $expr, $caller ) { - $parser = self::getParser(); - try { - $parser->parse( $expr ); - } catch ( AFPUserVisibleException $e ) { - $this->assertEquals( - $excep, - $e->mExceptionID, - "Exception $excep not thrown in AbuseFilterParser::$caller" - ); - return; - } - - $this->fail( "Exception $excep not thrown in AbuseFilterParser::$caller" ); - } - - /** - * Test the 'expectednotfound' exception - * - * @param string $expr The expression to test - * @param string $caller The function where the exception is thrown - * @covers AbuseFilterParser::doLevelSet - * @covers AbuseFilterParser::doLevelConditions - * @covers AbuseFilterParser::doLevelBraces - * @covers AbuseFilterParser::doLevelFunction - * @covers AbuseFilterParser::doLevelAtom - * @covers AbuseFilterParser::skipOverBraces - * @covers AbuseFilterParser::doLevelArrayElements - * @dataProvider expectedNotFound - */ - public function testExpectedNotFoundException( $expr, $caller ) { - $this->exceptionTest( 'expectednotfound', $expr, $caller ); - } - - /** - * Data provider for testExpectedNotFoundException. - * The second parameter is the function where the exception is raised. - * One expression for each throw. - * - * @return array - */ - public function expectedNotFound() { - return [ - [ 'a:= [1,2,3]; a[1 = 4', 'doLevelSet' ], - [ "if 1 = 1 'foo'", 'doLevelConditions' ], - [ "if 1 = 1 then 'foo'", 'doLevelConditions' ], - [ "if 1 = 1 then 'foo' else 'bar'", 'doLevelConditions' ], - [ "a := 1 = 1 ? 'foo'", 'doLevelConditions' ], - [ '(1 = 1', 'doLevelBraces' ], - [ 'lcase = 3', 'doLevelFunction' ], - [ 'lcase( 3 = 1', 'doLevelFunction' ], - [ 'a := [1,2', 'doLevelAtom' ], - [ '1 = 1 | (', 'skipOverBraces' ], - [ 'a := [1,2,3]; 3 = a[5', 'doLevelArrayElements' ], - ]; - } - - /** - * Test the 'unexpectedatend' exception - * - * @param string $expr The expression to test - * @param string $caller The function where the exception is thrown - * @covers AbuseFilterParser::doLevelEntry - * @dataProvider unexpectedAtEnd - */ - public function testUnexpectedAtEndException( $expr, $caller ) { - $this->exceptionTest( 'unexpectedatend', $expr, $caller ); - } - - /** - * Data provider for testUnexpectedAtEndException - * The second parameter is the function where the exception is raised. - * One expression for each throw. - * - * @return array - */ - public function unexpectedAtEnd() { - return [ - [ "'a' = 1 )", 'doLevelEntry' ], - ]; - } - - /** - * Test the 'unrecognisedvar' exception - * - * @param string $expr The expression to test - * @param string $caller The function where the exception is thrown - * @covers AbuseFilterParser::doLevelSet - * @covers AbuseFilterParser::getVarValue - * @dataProvider unrecognisedVar - */ - public function testUnrecognisedVarException( $expr, $caller ) { - $this->exceptionTest( 'unrecognisedvar', $expr, $caller ); - } - - /** - * Data provider for testUnrecognisedVarException - * The second parameter is the function where the exception is raised. - * One expression for each throw. - * - * @return array - */ - public function unrecognisedVar() { - return [ - [ 'a[1] := 5', 'doLevelSet' ], - [ 'a = 5', 'getVarValue' ], - ]; - } - - /** - * Test the 'notarray' exception - * - * @param string $expr The expression to test - * @param string $caller The function where the exception is thrown - * @covers AbuseFilterParser::doLevelSet - * @covers AbuseFilterParser::doLevelArrayElements - * @dataProvider notArray - */ - public function testNotArrayException( $expr, $caller ) { - $this->exceptionTest( 'notarray', $expr, $caller ); - } - - /** - * Data provider for testNotArrayException - * The second parameter is the function where the exception is raised. - * One expression for each throw. - * - * @return array - */ - public function notArray() { - return [ - [ 'a := 5; a[1] = 5', 'doLevelSet' ], - [ 'a := 1; 3 = a[5]', 'doLevelArrayElements' ], - ]; - } - - /** - * Test the 'outofbounds' exception - * - * @param string $expr The expression to test - * @param string $caller The function where the exception is thrown - * @covers AbuseFilterParser::doLevelSet - * @covers AbuseFilterParser::doLevelArrayElements - * @dataProvider outOfBounds - */ - public function testOutOfBoundsException( $expr, $caller ) { - $this->exceptionTest( 'outofbounds', $expr, $caller ); - } - - /** - * Data provider for testOutOfBoundsException - * The second parameter is the function where the exception is raised. - * One expression for each throw. - * - * @return array - */ - public function outOfBounds() { - return [ - [ 'a := [2]; a[5] = 9', 'doLevelSet' ], - [ 'a := [1,2,3]; 3 = a[5]', 'doLevelArrayElements' ], - ]; - } - - /** - * Test the 'unrecognisedkeyword' exception - * - * @param string $expr The expression to test - * @param string $caller The function where the exception is thrown - * @covers AbuseFilterParser::doLevelAtom - * @dataProvider unrecognisedKeyword - */ - public function testUnrecognisedKeywordException( $expr, $caller ) { - $this->exceptionTest( 'unrecognisedkeyword', $expr, $caller ); - } - - /** - * Data provider for testUnrecognisedKeywordException - * The second parameter is the function where the exception is raised. - * One expression for each throw. - * - * @return array - */ - public function unrecognisedKeyword() { - return [ - [ '5 = rlike', 'doLevelAtom' ], - ]; - } - - /** - * Test the 'unexpectedtoken' exception - * - * @param string $expr The expression to test - * @param string $caller The function where the exception is thrown - * @covers AbuseFilterParser::doLevelAtom - * @dataProvider unexpectedToken - */ - public function testUnexpectedTokenException( $expr, $caller ) { - $this->exceptionTest( 'unexpectedtoken', $expr, $caller ); - } - - /** - * Data provider for testUnexpectedTokenException - * The second parameter is the function where the exception is raised. - * One expression for each throw. - * - * @return array - */ - public function unexpectedToken() { - return [ - [ '1 =? 1', 'doLevelAtom' ], - ]; - } - - /** - * Test the 'disabledvar' exception - * - * @param string $expr The expression to test - * @param string $caller The function where the exception is thrown - * @covers AbuseFilterParser::getVarValue - * @dataProvider disabledVar - */ - public function testDisabledVarException( $expr, $caller ) { - $this->exceptionTest( 'disabledvar', $expr, $caller ); - } - - /** - * Data provider for testDisabledVarException - * The second parameter is the function where the exception is raised. - * One expression for each throw. - * - * @return array - */ - public function disabledVar() { - return [ - [ 'old_text = 1', 'getVarValue' ], - ]; - } - - /** - * Test the 'overridebuiltin' exception - * - * @param string $expr The expression to test - * @param string $caller The function where the exception is thrown - * @covers AbuseFilterParser::setUserVariable - * @dataProvider overrideBuiltin - */ - public function testOverrideBuiltinException( $expr, $caller ) { - $this->exceptionTest( 'overridebuiltin', $expr, $caller ); - } - - /** - * Data provider for testOverrideBuiltinException - * The second parameter is the function where the exception is raised. - * One expression for each throw. - * - * @return array - */ - public function overrideBuiltin() { - return [ - [ 'added_lines := 1', 'setUserVariable' ], - ]; - } - - /** - * Test the 'regexfailure' exception - * - * @param string $expr The expression to test - * @param string $caller The function where the exception is thrown - * @covers AbuseFilterParser::funcRCount - * @covers AbuseFilterParser::funcGetMatches - * @dataProvider regexFailure - */ - public function testRegexFailureException( $expr, $caller ) { - $this->exceptionTest( 'regexfailure', $expr, $caller ); - } - - /** - * Data provider for testRegexFailureException - * The second parameter is the function where the exception is raised. - * One expression for each throw. - * - * @return array - */ - public function regexFailure() { - return [ - [ "rcount('(','a')", 'funcRCount' ], - [ "get_matches('this (should fail', 'any haystack')", 'funcGetMatches' ], - ]; - } - - /** - * Test the 'invalidiprange' exception - * - * @param string $expr The expression to test - * @param string $caller The function where the exception is thrown - * @covers AbuseFilterParser::funcIPInRange - * @dataProvider invalidIPRange - */ - public function testInvalidIPRangeException( $expr, $caller ) { - $this->exceptionTest( 'invalidiprange', $expr, $caller ); - } - - /** - * Data provider for testInvalidIPRangeException - * The second parameter is the function where the exception is raised. - * One expression for each throw. - * - * @return array - */ - public function invalidIPRange() { - return [ - [ "ip_in_range('0.0.0.0', 'lol')", 'funcIPInRange' ], - ]; - } - - /** - * Test functions which take exactly one parameters calling them - * without 0 params. They should throw a 'noparams' exception. - * - * @param string $func The function to test - * @covers AbuseFilterParser::funcLc - * @covers AbuseFilterParser::funcUc - * @covers AbuseFilterParser::funcLen - * @covers AbuseFilterParser::funcSpecialRatio - * @covers AbuseFilterParser::funcCount - * @covers AbuseFilterParser::funcRCount - * @covers AbuseFilterParser::funcCCNorm - * @covers AbuseFilterParser::funcSanitize - * @covers AbuseFilterParser::funcRMSpecials - * @covers AbuseFilterParser::funcRMWhitespace - * @covers AbuseFilterParser::funcRMDoubles - * @covers AbuseFilterParser::funcNorm - * @covers AbuseFilterParser::funcStrRegexEscape - * @covers AbuseFilterParser::castString - * @covers AbuseFilterParser::castInt - * @covers AbuseFilterParser::castFloat - * @covers AbuseFilterParser::castBool - * @dataProvider oneParamFuncs - * @expectedException AFPUserVisibleException - * @expectedExceptionMessageRegExp /^No parameters given to function/ - */ - public function testNoParamsException( $func ) { - $parser = self::getParser(); - $parser->parse( "$func()" ); - } - - /** - * Data provider for testNoParamsException, returns a list of - * functions taking a single parameter - * - * @return array - */ - public function oneParamFuncs() { - return [ - [ 'lcase' ], - [ 'ucase' ], - [ 'length' ], - [ 'strlen' ], - [ 'specialratio' ], - [ 'count' ], - [ 'rcount' ], - [ 'ccnorm' ], - [ 'sanitize' ], - [ 'rmspecials' ], - [ 'rmwhitespace' ], - [ 'rmdoubles' ], - [ 'norm' ], - [ 'rescape' ], - [ 'string' ], - [ 'int' ], - [ 'float' ], - [ 'bool' ], - ]; - } - - /** - * Test functions taking two parameters by providing only one. - * They should throw a 'notenoughargs' exception. - * - * @param string $func The function to test - * @covers AbuseFilterParser::funcGetMatches - * @covers AbuseFilterParser::funcIPInRange - * @covers AbuseFilterParser::funcContainsAny - * @covers AbuseFilterParser::funcContainsAll - * @covers AbuseFilterParser::funcCCNormContainsAny - * @covers AbuseFilterParser::funcCCNormContainsAll - * @covers AbuseFilterParser::funcEqualsToAny - * @covers AbuseFilterParser::funcSubstr - * @covers AbuseFilterParser::funcStrPos - * @covers AbuseFilterParser::funcSetVar - * @dataProvider twoParamsFuncs - * @expectedException AFPUserVisibleException - * @expectedExceptionMessageRegExp /^Not enough arguments to function [^ ]+ called at character \d+.\nExpected 2 arguments, got 1/ - */ - public function testNotEnoughArgsExceptionTwo( $func ) { - $parser = self::getParser(); - // Nevermind if the argument can't be string since we check the amount - // of parameters before anything else. - $parser->parse( "$func('foo')" ); - } - - /** - * Data provider for testNotEnoughArgsExceptionTwo, returns the list of - * functions taking two parameters. - * - * @return array - */ - public function twoParamsFuncs() { - return [ - [ 'get_matches' ], - [ 'ip_in_range' ], - [ 'contains_any' ], - [ 'contains_all' ], - [ 'ccnorm_contains_any' ], - [ 'ccnorm_contains_all' ], - [ 'equals_to_any' ], - [ 'substr' ], - [ 'strpos' ], - [ 'set_var' ], - ]; - } - - /** - * Test functions taking three parameters by providing only two. - * They should throw a 'notenoughargs' exception. - * - * @param string $func The function to test - * @covers AbuseFilterParser::funcStrReplace - * @dataProvider threeParamsFuncs - * @expectedException AFPUserVisibleException - * @expectedExceptionMessageRegExp /^Not enough arguments to function [^ ]+ called at character \d+.\nExpected 3 arguments, got 2/ - */ - public function testNotEnoughArgsExceptionThree( $func ) { - $parser = self::getParser(); - // Nevermind if the argument can't be string since we check the amount - // of parameters before anything else. - $parser->parse( "$func('foo', 'bar')" ); - } - - /** - * Data provider for testNotEnoughArgsExceptionThree, returns the list of - * functions taking three parameters. - * - * @return array - */ - public function threeParamsFuncs() { - return [ - [ 'str_replace' ], - ]; - } - - /** - * Check that deprecated variables are correctly translated to the new ones with a debug notice - * - * @param string $old The old name of the variable - * @param string $new The new name of the variable - * @dataProvider provideDeprecatedVars - */ - public function testDeprecatedVars( $old, $new ) { - $loggerMock = new TestLogger(); - $loggerMock->setCollect( true ); - $this->setLogger( 'AbuseFilterDeprecatedVars', $loggerMock ); - - $parser = self::getParser(); - $actual = $parser->parse( "$old === $new" ); - - $loggerBuffer = $loggerMock->getBuffer(); - // Check that the use has been logged - $found = false; - foreach ( $loggerBuffer as $entry ) { - $check = preg_match( '/AbuseFilter: deprecated variable/', $entry[1] ); - if ( $check ) { - $found = true; - break; - } - } - if ( !$found ) { - $this->fail( "The use of the deprecated variable $old was not logged." ); - } - - $this->assertTrue( $actual, "AbuseFilter deprecated variable $old is not parsed correctly" ); - } - - /** - * Data provider for testDeprecatedVars - * @return array - */ - public function provideDeprecatedVars() { - $deprecated = AbuseFilter::$deprecatedVars; - $data = []; - foreach ( $deprecated as $old => $new ) { - $data[] = [ $old, $new ]; - } - return $data; - } -} diff --git a/AbuseFilter/tests/phpunit/AbuseFilterSaveTest.php b/AbuseFilter/tests/phpunit/AbuseFilterSaveTest.php index 6a5b3121..e226a3c2 100644 --- a/AbuseFilter/tests/phpunit/AbuseFilterSaveTest.php +++ b/AbuseFilter/tests/phpunit/AbuseFilterSaveTest.php @@ -22,47 +22,52 @@ * @license GPL-2.0-or-later */ +use MediaWiki\Linker\LinkRenderer; +use PHPUnit\Framework\MockObject\MockObject; +use Wikimedia\Rdbms\IDatabase; + /** * @group Test * @group AbuseFilter * @group AbuseFilterSave - * @group Database * * @covers AbuseFilter * @covers AbuseFilterViewEdit - * @covers AbuseFilterParser */ class AbuseFilterSaveTest extends MediaWikiTestCase { - protected static $mUser, $mParameters; - - /** - * @var array This tables will be deleted in parent::tearDown - */ - protected $tablesUsed = [ - 'abuse_filter', - 'abuse_filter_action', - 'abuse_filter_history', - 'abuse_filter_log' + private static $defaultFilterRow = [ + 'af_pattern' => '/**/', + 'af_user' => 0, + 'af_user_text' => 'FilterTester', + 'af_timestamp' => '20190826000000', + 'af_enabled' => 1, + 'af_comments' => '', + 'af_public_comments' => 'Mock filter', + 'af_hidden' => 0, + 'af_hit_count' => 0, + 'af_throttled' => 0, + 'af_deleted' => 0, + 'af_actions' => '', + 'af_global' => 0, + 'af_group' => 'default' ]; /** - * @see MediaWikiTestCase::setUp + * Gets an instance of AbuseFilterViewEdit ready for creating or editing filter + * + * @param User $user + * @param array $params + * @param bool $existing Whether the filter already exists + * @return AbuseFilterViewEdit|MockObject */ - protected function setUp() { - parent::setUp(); - $user = User::newFromName( 'FilterTester' ); - $user->addToDatabase(); - $user->addGroup( 'filterEditor' ); - RequestContext::getMain()->setUser( $user ); - self::$mUser = $user; - // Make sure that the config we're using is the one we're expecting - $this->setMwGlobals( [ - 'wgUser' => $user, - 'wgAbuseFilterRestrictions' => [ - 'degroup' => true - ], - 'wgAbuseFilterIsCentral' => true, - 'wgAbuseFilterActions' => [ + private function getViewEdit( User $user, array $params, $existing ) { + $special = new SpecialAbuseFilter(); + $context = new RequestContext(); + $context->setRequest( $this->getRequest( $params ) ); + $context->setUser( $user ); + $cfgOpts = [ + 'LanguageCode' => 'en', + 'AbuseFilterActions' => [ 'throttle' => true, 'warn' => true, 'disallow' => true, @@ -72,40 +77,50 @@ class AbuseFilterSaveTest extends MediaWikiTestCase { 'degroup' => true, 'tag' => true ], - 'wgAbuseFilterValidGroups' => [ + 'AbuseFilterValidGroups' => [ 'default', 'flow' - ] - ] ); - $this->setGroupPermissions( [ - 'filterEditor' => [ - 'abusefilter-modify' => true, - 'abusefilter-modify-restricted' => false, - 'abusefilter-modify-global' => false, ], - 'filterEditorGlobal' => [ - 'abusefilter-modify' => true, - 'abusefilter-modify-global' => true, - ] - ] ); - } + 'AbuseFilterRestrictions' => [ + 'degroup' => true + ], + 'AbuseFilterIsCentral' => true, + ]; - /** - * Gets an instance of AbuseFilterViewEdit ready for creating or editing filter - * - * @param string $filter 'new' for a new filter, its ID otherwise - * @return AbuseFilterViewEdit - */ - private static function getViewEdit( $filter ) { - $special = new SpecialAbuseFilter(); - $context = RequestContext::getMain( self::getRequest() ); - $context->setRequest( self::getRequest() ); + $context->setConfig( new HashConfig( $cfgOpts ) ); $special->setContext( $context ); + $filter = $params['id']; $special->mFilter = $filter; - $viewEdit = new AbuseFilterViewEdit( $special, [ $filter ] ); - // Being a static property, it's not deleted between tests - $viewEdit::$mLoadedRow = null; + /** @var LinkRenderer|MockObject $lr */ + $lr = $this->getMockBuilder( LinkRenderer::class ) + ->disableOriginalConstructor() + ->getMock(); + $special->setLinkRenderer( $lr ); + /** @var AbuseFilterViewEdit|MockObject $viewEdit */ + $viewEdit = $this->getMockBuilder( AbuseFilterViewEdit::class ) + ->setConstructorArgs( [ $special, [ $filter ] ] ) + ->setMethods( [ 'loadFilterData' ] ) + ->getMock(); + + if ( $existing ) { + $origValues = [ (object)( self::$defaultFilterRow + [ 'af_id' => 1 ] ), [] ]; + } else { + $origValues = [ + (object)[ + 'af_pattern' => '', + 'af_enabled' => 1, + 'af_hidden' => 0, + 'af_global' => 0, + 'af_throttled' => 0, + 'af_hit_count' => 0, + ], + [] + ]; + } + $viewEdit->expects( $this->once() ) + ->method( 'loadFilterData' ) + ->willReturn( $origValues ); return $viewEdit; } @@ -113,79 +128,70 @@ class AbuseFilterSaveTest extends MediaWikiTestCase { /** * Creates a FauxRequest object * + * @param array $params * @return FauxRequest */ - private static function getRequest() { - $params = [ - 'wpFilterRules' => self::$mParameters['rules'], - 'wpFilterDescription' => self::$mParameters['description'], - 'wpFilterNotes' => self::$mParameters['notes'], - 'wpFilterGroup' => self::$mParameters['group'], - 'wpFilterEnabled' => self::$mParameters['enabled'], - 'wpFilterHidden' => self::$mParameters['hidden'], - 'wpFilterDeleted' => self::$mParameters['deleted'], - 'wpFilterGlobal' => self::$mParameters['global'], - 'wpFilterActionThrottle' => self::$mParameters['throttleEnabled'], - 'wpFilterThrottleCount' => self::$mParameters['throttleCount'], - 'wpFilterThrottlePeriod' => self::$mParameters['throttlePeriod'], - 'wpFilterThrottleGroups' => self::$mParameters['throttleGroups'], - 'wpFilterActionWarn' => self::$mParameters['warnEnabled'], - 'wpFilterWarnMessage' => self::$mParameters['warnMessage'], - 'wpFilterWarnMessageOther' => self::$mParameters['warnMessageOther'], - 'wpFilterActionDisallow' => self::$mParameters['disallowEnabled'], - 'wpFilterActionBlockautopromote' => self::$mParameters['blockautopromoteEnabled'], - 'wpFilterActionDegroup' => self::$mParameters['degroupEnabled'], - 'wpFilterActionBlock' => self::$mParameters['blockEnabled'], - 'wpFilterBlockTalk' => self::$mParameters['blockTalk'], - 'wpBlockAnonDuration' => self::$mParameters['blockAnons'], - 'wpBlockUserDuration' => self::$mParameters['blockUsers'], - 'wpFilterActionRangeblock' => self::$mParameters['rangeblockEnabled'], - 'wpFilterActionTag' => self::$mParameters['tagEnabled'], - 'wpFilterTags' => self::$mParameters['tagTags'], + private function getRequest( array $params ) { + $reqParams = [ + 'wpFilterRules' => $params['rules'], + 'wpFilterDescription' => $params['description'], + 'wpFilterNotes' => $params['notes'] ?? '', + 'wpFilterGroup' => $params['group'] ?? 'default', + 'wpFilterEnabled' => $params['enabled'] ?? true, + 'wpFilterHidden' => $params['hidden'] ?? false, + 'wpFilterDeleted' => $params['deleted'] ?? false, + 'wpFilterGlobal' => $params['global'] ?? false, + 'wpFilterActionThrottle' => $params['throttleEnabled'] ?? false, + 'wpFilterThrottleCount' => $params['throttleCount'] ?? 0, + 'wpFilterThrottlePeriod' => $params['throttlePeriod'] ?? 0, + 'wpFilterThrottleGroups' => $params['throttleGroups'] ?? '', + 'wpFilterActionWarn' => $params['warnEnabled'] ?? false, + 'wpFilterWarnMessage' => $params['warnMessage'] ?? 'abusefilter-warning', + 'wpFilterWarnMessageOther' => $params['warnMessageOther'] ?? '', + 'wpFilterActionDisallow' => $params['disallowEnabled'] ?? false, + 'wpFilterDisallowMessage' => $params['disallowMessage'] ?? 'abusefilter-disallowed', + 'wpFilterDisallowMessageOther' => $params['disallowMessageOther'] ?? '', + 'wpFilterActionBlockautopromote' => $params['blockautopromoteEnabled'] ?? false, + 'wpFilterActionDegroup' => $params['degroupEnabled'] ?? false, + 'wpFilterActionBlock' => $params['blockEnabled'] ?? false, + 'wpFilterBlockTalk' => $params['blockTalk'] ?? false, + 'wpBlockAnonDuration' => $params['blockAnons'] ?? 'infinity', + 'wpBlockUserDuration' => $params['blockUsers'] ?? 'infinity', + 'wpFilterActionRangeblock' => $params['rangeblockEnabled'] ?? false, + 'wpFilterActionTag' => $params['tagEnabled'] ?? false, + 'wpFilterTags' => $params['tagTags'] ?? '', ]; // Checkboxes aren't included at all if they aren't selected. We can remove them // this way (instead of iterating a hardcoded list) since they're the only false values - $params = array_filter( $params, function ( $el ) { + $reqParams = array_filter( $reqParams, function ( $el ) { return $el !== false; } ); - $request = new FauxRequest( $params, true ); - return $request; + return new FauxRequest( $reqParams, true ); } /** - * Creates $amount new filters, in case we need to test updating an existing one - * - * @param int $amount How many filters to create + * @param array $testPerms + * @return User|MockObject */ - private static function createNewFilters( $amount ) { - $defaultRow = [ - 'af_pattern' => '/**/', - 'af_user' => 0, - 'af_user_text' => 'FilterTester', - 'af_timestamp' => wfTimestampNow(), - 'af_enabled' => 1, - 'af_comments' => '', - 'af_public_comments' => 'Mock filter', - 'af_hidden' => 0, - 'af_hit_count' => 0, - 'af_throttled' => 0, - 'af_deleted' => 0, - 'af_actions' => '', - 'af_global' => 0, - 'af_group' => 'default' - ]; + private function getUserMock( $testPerms ) { + $perms = array_merge( $testPerms, [ 'abusefilter-modify' ] ); + $user = $this->getMockBuilder( User::class ) + ->setMethods( [ 'getBlock', 'getName', 'getId', 'getActorId' ] ) + ->getMock(); - $dbw = wfGetDB( DB_MASTER ); - for ( $i = 1; $i <= $amount; $i++ ) { - $dbw->replace( - 'abuse_filter', - [ 'af_id' ], - $defaultRow, - __METHOD__ - ); - } + $user->expects( $this->any() ) + ->method( 'getName' ) + ->willReturn( 'FilterUser' ); + $user->expects( $this->any() ) + ->method( 'getId' ) + ->willReturn( 1 ); + $user->expects( $this->any() ) + ->method( 'getActorId' ) + ->willReturn( 1 ); + $this->overrideUserPermissions( $user, $perms ); + return $user; } /** @@ -196,93 +202,54 @@ class AbuseFilterSaveTest extends MediaWikiTestCase { * @dataProvider provideFilters */ public function testSaveFilter( $args ) { - // Preliminar stuff for the test - if ( $args['testData']['customUserGroup'] ) { - self::$mUser->addGroup( $args['testData']['customUserGroup'] ); - } + $user = $this->getUserMock( $args['testData']['userPerms'] ?? [] ); - if ( $args['testData']['needsOtherFilters'] ) { - self::createNewFilters( $args['testData']['needsOtherFilters'] ); - } - - $fixedParameters = [ - 'id' => 'new', - 'notes' => '', - 'group' => 'default', - 'enabled' => true, - 'hidden' => false, - 'global' => false, - 'deleted' => false, - 'throttled' => 0, - 'throttleEnabled' => false, - 'throttleCount' => 0, - 'throttlePeriod' => 0, - 'throttleGroups' => '', - 'warnEnabled' => false, - 'warnMessage' => 'abusefilter-warning', - 'warnMessageOther' => '', - 'disallowEnabled' => false, - 'blockautopromoteEnabled' => false, - 'degroupEnabled' => false, - 'blockEnabled' => false, - 'blockTalk' => false, - 'blockAnons' => 'infinity', - 'blockUsers' => 'infinity', - 'rangeblockEnabled' => false, - 'tagEnabled' => false, - 'tagTags' => '' - ]; + $params = $args['filterParameters']; + $filter = $params['id'] = $params['id'] ?? 'new'; + $existing = isset( $args['testData']['existing'] ); + $viewEdit = $this->getViewEdit( $user, $params, $existing ); - // Extract parameters from testset and build what we need to save a filter - // The values specified in the testset will overwrite the fixed ones. - self::$mParameters = $args['filterParameters'] + $fixedParameters; - $filter = self::$mParameters['id']; - $viewEdit = self::getViewEdit( $filter ); - $request = self::getRequest(); - list( $newRow, $actions ) = $viewEdit->loadRequest( $filter ); - self::$mParameters['rowActions'] = implode( ',', array_keys( array_filter( $actions ) ) ); - - // Send data for validation and saving - $status = AbuseFilter::saveFilter( $viewEdit, $filter, $request, $newRow, $actions ); - - // Must be removed for the next test - if ( $args['testData']['customUserGroup'] ) { - self::$mUser->removeGroup( $args['testData']['customUserGroup'] ); + $reqStatus = $viewEdit->loadRequest( $filter ); + if ( !$reqStatus->isGood() ) { + $this->fail( 'Cannot retrieve request data correctly' ); } + list( $newRow, $actions ) = $reqStatus->getValue(); - $shouldFail = $args['testData']['shouldFail']; - $shouldBeSaved = $args['testData']['shouldBeSaved']; - $furtherInfo = null; - $expected = true; - if ( $shouldFail ) { - if ( $status->isGood() ) { - $furtherInfo = 'The filter validation returned a valid status.'; - $result = false; - } else { - $result = $status->getErrors(); - $result = $result[0]['message']; - $expected = $args['testData']['expectedMessage']; - } + /** @var IDatabase|MockObject $dbw */ + $dbw = $this->getMockForAbstractClass( IDatabase::class ); + $dbw->expects( $this->any() ) + ->method( 'insertId' ) + ->willReturn( 1 ); + $row = new stdClass(); + $row->actor_id = '1'; + $dbw->expects( $this->any() ) + ->method( 'selectRow' ) + ->willReturn( $row ); + $status = AbuseFilter::saveFilter( $viewEdit, $filter, $newRow, $actions, $dbw ); + + if ( $args['testData']['shouldFail'] ) { + $this->assertFalse( $status->isGood(), 'The filter validation returned a valid status.' ); + $actual = $status->getErrors()[0]['message']; + $expected = $args['testData']['expectedMessage']; + $this->assertEquals( $expected, $actual ); } else { - if ( $shouldBeSaved ) { + if ( $args['testData']['shouldBeSaved'] ) { + $this->assertTrue( + $status->isGood(), + "Save failed with status: $status" + ); $value = $status->getValue(); - $result = $status->isGood() && is_array( $value ) && count( $value ) === 2 && - is_numeric( $value[0] ) && is_numeric( $value[1] ); + $this->assertIsArray( $value ); + $this->assertCount( 2, $value ); + $this->assertContainsOnly( 'int', $value ); } else { - $result = $status->isGood() && $status->getValue() === false; + $this->assertTrue( + $status->isGood(), + "Got a non-good status: $status" + ); + $this->assertFalse( $status->getValue(), 'Status value should be false' ); } } - - $errorMessage = $args['testData']['doingWhat'] . '. Expected: ' . - $args['testData']['expectedResult'] . '.'; - if ( $furtherInfo ) { - $errorMessage .= "\nFurther info: " . $furtherInfo; - } - $this->assertEquals( - $expected, - $result, - $errorMessage - ); } /** @@ -291,7 +258,7 @@ class AbuseFilterSaveTest extends MediaWikiTestCase { */ public function provideFilters() { return [ - [ + 'Fail due to empty description and rules' => [ [ 'filterParameters' => [ 'rules' => '', @@ -299,17 +266,13 @@ class AbuseFilterSaveTest extends MediaWikiTestCase { 'blockautopromoteEnabled' => true, ], 'testData' => [ - 'doingWhat' => 'Trying to save a filter without description and rules', - 'expectedResult' => 'a "missing required fields" error message', 'expectedMessage' => 'abusefilter-edit-missingfields', 'shouldFail' => true, - 'shouldBeSaved' => false, - 'customUserGroup' => '', - 'needsOtherFilters' => false + 'shouldBeSaved' => false ] ] ], - [ + 'Success for only rules and description' => [ [ 'filterParameters' => [ 'rules' => '/* My rules */', @@ -318,17 +281,12 @@ class AbuseFilterSaveTest extends MediaWikiTestCase { 'deleted' => true, ], 'testData' => [ - 'doingWhat' => 'Trying to save a filter with only rules and description', - 'expectedResult' => 'the saving to be successful', - 'expectedMessage' => '', 'shouldFail' => false, - 'shouldBeSaved' => true, - 'customUserGroup' => '', - 'needsOtherFilters' => false + 'shouldBeSaved' => true ] ] ], - [ + 'Fail due to syntax error' => [ [ 'filterParameters' => [ 'rules' => 'rlike', @@ -338,17 +296,13 @@ class AbuseFilterSaveTest extends MediaWikiTestCase { 'blockAnons' => '8 hours', ], 'testData' => [ - 'doingWhat' => 'Trying to save a filter with wrong syntax', - 'expectedResult' => 'a "wrong syntax" error message', 'expectedMessage' => 'abusefilter-edit-badsyntax', 'shouldFail' => true, - 'shouldBeSaved' => false, - 'customUserGroup' => '', - 'needsOtherFilters' => false + 'shouldBeSaved' => false ] ] ], - [ + 'Fail due to both "enabled" and "deleted" selected' => [ [ 'filterParameters' => [ 'rules' => '1==1', @@ -359,17 +313,13 @@ class AbuseFilterSaveTest extends MediaWikiTestCase { 'blockAnons' => '8 hours', ], 'testData' => [ - 'doingWhat' => 'Trying to save a filter marking it both enabled and deleted', - 'expectedResult' => 'an error message', 'expectedMessage' => 'abusefilter-edit-deleting-enabled', 'shouldFail' => true, - 'shouldBeSaved' => false, - 'customUserGroup' => '', - 'needsOtherFilters' => false + 'shouldBeSaved' => false ] ] ], - [ + 'Fail due to a reserved tag' => [ [ 'filterParameters' => [ 'rules' => '1==1', @@ -380,17 +330,13 @@ class AbuseFilterSaveTest extends MediaWikiTestCase { 'tagTags' => 'mw-undo' ], 'testData' => [ - 'doingWhat' => 'Trying to save a filter with a reserved tag', - 'expectedResult' => 'an error message saying that the tag cannot be used', 'expectedMessage' => 'abusefilter-edit-bad-tags', 'shouldFail' => true, - 'shouldBeSaved' => false, - 'customUserGroup' => '', - 'needsOtherFilters' => false + 'shouldBeSaved' => false ] ] ], - [ + 'Fail due to an invalid tag' => [ [ 'filterParameters' => [ 'rules' => '1==1', @@ -400,17 +346,29 @@ class AbuseFilterSaveTest extends MediaWikiTestCase { 'tagTags' => 'some|tag' ], 'testData' => [ - 'doingWhat' => 'Trying to save a filter with an invalid tag', - 'expectedResult' => 'an error message saying that the tag cannot be used', 'expectedMessage' => 'tags-create-invalid-chars', 'shouldFail' => true, - 'shouldBeSaved' => false, - 'customUserGroup' => '', - 'needsOtherFilters' => false + 'shouldBeSaved' => false ] ] ], - [ + 'Fail due to an empty tag' => [ + [ + 'filterParameters' => [ + 'rules' => '1!=0', + 'description' => 'Empty tag', + 'notes' => '', + 'tagEnabled' => true, + 'tagTags' => '' + ], + 'testData' => [ + 'expectedMessage' => 'tags-create-no-name', + 'shouldFail' => true, + 'shouldBeSaved' => false + ] + ] + ], + 'Fail due to lack of modify-global right' => [ [ 'filterParameters' => [ 'rules' => '1==1', @@ -419,17 +377,13 @@ class AbuseFilterSaveTest extends MediaWikiTestCase { 'disallowEnabled' => true, ], 'testData' => [ - 'doingWhat' => 'Trying to save a global filter without enough rights', - 'expectedResult' => 'an error message saying that I do not have the required rights', 'expectedMessage' => 'abusefilter-edit-notallowed-global', 'shouldFail' => true, - 'shouldBeSaved' => false, - 'customUserGroup' => '', - 'needsOtherFilters' => false + 'shouldBeSaved' => false ] ] ], - [ + 'Fail due to custom warn message on global filter' => [ [ 'filterParameters' => [ 'rules' => '1==1', @@ -439,18 +393,31 @@ class AbuseFilterSaveTest extends MediaWikiTestCase { 'warnMessage' => 'abusefilter-beautiful-warning', ], 'testData' => [ - 'doingWhat' => 'Trying to save a global filter with a custom warn message', - 'expectedResult' => 'an error message saying that custom warn messages ' . - 'cannot be used for global rules', 'expectedMessage' => 'abusefilter-edit-notallowed-global-custom-msg', 'shouldFail' => true, 'shouldBeSaved' => false, - 'customUserGroup' => 'filterEditorGlobal', - 'needsOtherFilters' => false + 'userPerms' => [ 'abusefilter-modify-global' ] ] ] ], - [ + 'Fail due to custom disallow message on global filter' => [ + [ + 'filterParameters' => [ + 'rules' => '1==1', + 'description' => 'Global with invalid disallow message', + 'global' => true, + 'disallowEnabled' => true, + 'disallowMessage' => 'abusefilter-disallowed-something', + ], + 'testData' => [ + 'expectedMessage' => 'abusefilter-edit-notallowed-global-custom-msg', + 'shouldFail' => true, + 'shouldBeSaved' => false, + 'userPerms' => [ 'abusefilter-modify-global' ] + ] + ] + ], + 'Fail due to a restricted action' => [ [ 'filterParameters' => [ 'rules' => '1==1', @@ -458,17 +425,13 @@ class AbuseFilterSaveTest extends MediaWikiTestCase { 'degroupEnabled' => true, ], 'testData' => [ - 'doingWhat' => 'Trying to save a filter with a restricted action', - 'expectedResult' => 'an error message saying that the action is restricted', 'expectedMessage' => 'abusefilter-edit-restricted', 'shouldFail' => true, - 'shouldBeSaved' => false, - 'customUserGroup' => '', - 'needsOtherFilters' => false + 'shouldBeSaved' => false ] ] ], - [ + 'Pass validation but do not save when there are no changes' => [ [ 'filterParameters' => [ 'id' => '1', @@ -476,17 +439,13 @@ class AbuseFilterSaveTest extends MediaWikiTestCase { 'description' => 'Mock filter', ], 'testData' => [ - 'doingWhat' => 'Trying to save a filter without changing anything', - 'expectedResult' => 'the validation to pass without the filter being saved', - 'expectedMessage' => '', 'shouldFail' => false, 'shouldBeSaved' => false, - 'customUserGroup' => '', - 'needsOtherFilters' => 1 + 'existing' => true ] ] ], - [ + 'Fail due to invalid throttle groups' => [ [ 'filterParameters' => [ 'rules' => '1==1', @@ -498,99 +457,42 @@ class AbuseFilterSaveTest extends MediaWikiTestCase { 'throttleGroups' => 'user\nfoo' ], 'testData' => [ - 'doingWhat' => 'Trying to save a filter with invalid throttle groups', - 'expectedResult' => 'an error message saying that throttle groups are invalid', 'expectedMessage' => 'abusefilter-edit-invalid-throttlegroups', 'shouldFail' => true, - 'shouldBeSaved' => false, - 'customUserGroup' => '', - 'needsOtherFilters' => false + 'shouldBeSaved' => false ] ] - ] - ]; - } - - /** - * Check that our tag validation is working properly. Note that we only need one test - * for each called function. Consistency within ChangeTags functions should be - * assured by tests in core. The test for canAddTagsAccompanyingChange and canCreateTag - * are missing because they won't actually fail, never. Resolving T173917 would - * greatly improve the situation and could help writing better tests. - * - * @param string $tag The tag to validate - * @param string|null $error The expected error message. Null if validations should pass - * @covers AbuseFilter::isAllowedTag - * @dataProvider provideTags - */ - public function testIsAllowedTag( $tag, $error ) { - $status = AbuseFilter::isAllowedTag( $tag ); - - if ( !$status->isGood() ) { - $actualError = $status->getErrors(); - $actualError = $actualError[0]['message']; - } else { - $actualError = null; - if ( $error !== null ) { - $this->fail( "Tag validation returned a valid status instead of the expected '$error' error." ); - } - } - - $this->assertSame( - $error, - $actualError, - "Expected message '$error', got '$actualError' while validating the tag '$tag'." - ); - } - - /** - * Data provider for testIsAllowedTag - * @return array - */ - public function provideTags() { - return [ - [ 'a|b', 'tags-create-invalid-chars' ], - [ 'mw-undo', 'abusefilter-edit-bad-tags' ], - [ 'abusefilter-condition-limit', 'abusefilter-tag-reserved' ], - [ 'my_tag', null ], - ]; - } - - /** - * Check that throttle parameters validation works fine - * - * @param array $params Throttle parameters - * @param string|null $error The expected error message. Null if validations should pass - * @covers AbuseFilter::checkThrottleParameters - * @dataProvider provideThrottleParameters - */ - public function testCheckThrottleParameters( $params, $error ) { - $result = AbuseFilter::checkThrottleParameters( $params ); - $this->assertSame( $error, $result, 'Throttle parameter validation does not work as expected.' ); - } - - /** - * Data provider for testCheckThrottleParameters - * @return array - */ - public function provideThrottleParameters() { - return [ - [ [ '1', '5,23', 'user', 'ip', 'page,range', 'ip,user', 'range,ip' ], null ], - [ [ '1', '5.3,23', 'user', 'ip' ], 'abusefilter-edit-invalid-throttlecount' ], - [ [ '1', '-3,23', 'user', 'ip' ], 'abusefilter-edit-invalid-throttlecount' ], - [ [ '1', '5,2.3', 'user', 'ip' ], 'abusefilter-edit-invalid-throttleperiod' ], - [ [ '1', '4,-14', 'user', 'ip' ], 'abusefilter-edit-invalid-throttleperiod' ], - [ [ '1', '3,33' ], 'abusefilter-edit-empty-throttlegroups' ], - [ [ '1', '3,33', 'user', 'ip,foo,user' ], 'abusefilter-edit-invalid-throttlegroups' ], - [ [ '1', '3,33', 'foo', 'ip,user' ], 'abusefilter-edit-invalid-throttlegroups' ], - [ [ '1', '3,33', 'foo', 'ip,user,bar' ], 'abusefilter-edit-invalid-throttlegroups' ], - [ [ '1', '3,33', 'user', 'ip,page,user' ], null ], - [ - [ '1', '3,33', 'ip', 'user','user,ip', 'ip,user', 'user,ip,user', 'user', 'ip,ip,user' ], - 'abusefilter-edit-duplicated-throttlegroups' ], - [ [ '1', '3,33', 'ip,ip,user' ], 'abusefilter-edit-duplicated-throttlegroups' ], - [ [ '1', '3,33', 'user,ip', 'ip,user' ], 'abusefilter-edit-duplicated-throttlegroups' ], + 'Fail due to empty warning message' => [ + [ + 'filterParameters' => [ + 'rules' => '1==1', + 'description' => 'Empty warning message', + 'warnEnabled' => true, + 'warnMessage' => '', + ], + 'testData' => [ + 'expectedMessage' => 'abusefilter-edit-invalid-warn-message', + 'shouldFail' => true, + 'shouldBeSaved' => false + ] + ] + ], + 'Fail due to empty disallow message' => [ + [ + 'filterParameters' => [ + 'rules' => '1==1', + 'description' => 'Empty disallow message', + 'disallowEnabled' => true, + 'disallowMessage' => '', + ], + 'testData' => [ + 'expectedMessage' => 'abusefilter-edit-invalid-disallow-message', + 'shouldFail' => true, + 'shouldBeSaved' => false + ] + ] + ] ]; } } diff --git a/AbuseFilter/tests/phpunit/AbuseFilterTest.php b/AbuseFilter/tests/phpunit/AbuseFilterTest.php deleted file mode 100644 index 926116e2..00000000 --- a/AbuseFilter/tests/phpunit/AbuseFilterTest.php +++ /dev/null @@ -1,1413 +0,0 @@ -<?php -/** - * Generic tests for utility functions in AbuseFilter - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - * - * @license GPL-2.0-or-later - */ - -/** - * @group Test - * @group AbuseFilter - * @group AbuseFilterGeneric - * @group Database - * - * @covers AbuseFilter - * @covers AFPData - * @covers AbuseFilterVariableHolder - * @covers AFComputedVariable - */ -class AbuseFilterTest extends MediaWikiTestCase { - /** @var User */ - protected static $mUser; - /** @var Title */ - protected static $mTitle; - /** @var WikiPage */ - protected static $mPage; - /** @var AbuseFilterVariableHolder */ - protected static $mVariables; - - /** - * @var array These tables will be deleted in parent::tearDown. - * We need it to happen to make tests on fresh pages. - */ - protected $tablesUsed = [ - 'page', - 'page_restrictions', - 'abuse_filter', - 'abuse_filter_history', - 'abuse_filter_log', - 'abuse_filter_actions' - ]; - - /** - * @see MediaWikiTestCase::setUp - */ - protected function setUp() { - parent::setUp(); - MWTimestamp::setFakeTime( 1514700000 ); - $user = User::newFromName( 'AnotherFilteredUser' ); - $user->addToDatabase(); - $user->addGroup( 'basicFilteredUser' ); - self::$mUser = $user; - MWTimestamp::setFakeTime( false ); - - self::$mVariables = new AbuseFilterVariableHolder(); - - // Make sure that the config we're using is the one we're expecting - $this->setMwGlobals( [ - 'wgUser' => $user, - 'wgRestrictionTypes' => [ - 'create', - 'edit', - 'move', - 'upload' - ], - 'wgAbuseFilterRestrictions' => [ - 'degroup' => true - ], - 'wgAbuseFilterIsCentral' => true, - 'wgAbuseFilterActions' => [ - 'throttle' => true, - 'warn' => true, - 'disallow' => true, - 'blockautopromote' => true, - 'block' => true, - 'rangeblock' => true, - 'degroup' => true, - 'tag' => true - ], - 'wgAbuseFilterValidGroups' => [ - 'default', - 'flow' - ], - 'wgEnableParserLimitReporting' => false - ] ); - $this->setGroupPermissions( [ - 'basicFilteredUser' => [ - 'abusefilter-view' => true - ], - 'intermediateFilteredUser' => [ - 'abusefilter-log' => true - ], - 'privilegedFilteredUser' => [ - 'abusefilter-private' => true, - 'abusefilter-revert' => true - ] - ] ); - } - - /** - * @see MediaWikiTestCase::tearDown - */ - protected function tearDown() { - MWTimestamp::setFakeTime( false ); - $userGroups = self::$mUser->getGroups(); - // We want to start fresh - foreach ( $userGroups as $group ) { - self::$mUser->removeGroup( $group ); - } - parent::tearDown(); - } - - /** - * Given the name of a variable, naturally sets it to a determined amount - * - * @param string $var The variable name - * @return array the first position is the result (mixed), the second is a boolean - * indicating whether we've been able to compute the given variable - */ - private static function computeExpectedUserVariable( $var ) { - $success = true; - switch ( $var ) { - case 'user_editcount': - // Create a page and make the user edit it 7 times - $page = WikiPage::factory( Title::newFromText( 'UTPage' ) ); - $page->doEditContent( - new WikitextContent( 'AbuseFilter test, page creation' ), - 'Testing page for AbuseFilter', - EDIT_NEW, - false, - self::$mUser - ); - for ( $i = 1; $i <= 7; $i++ ) { - $page->doEditContent( - new WikitextContent( "AbuseFilter test, page revision #$i" ), - 'Testing page for AbuseFilter', - EDIT_UPDATE, - false, - self::$mUser - ); - } - // Reload to reflect deferred update - self::$mUser->clearInstanceCache(); - $result = 7; - break; - case 'user_name': - $result = self::$mUser->getName(); - break; - case 'user_emailconfirm': - $time = wfTimestampNow(); - self::$mUser->setEmailAuthenticationTimestamp( $time ); - $result = $time; - break; - case 'user_groups': - self::$mUser->addGroup( 'intermediateFilteredUser' ); - $result = self::$mUser->getEffectiveGroups(); - break; - case 'user_rights': - self::$mUser->addGroup( 'privilegedFilteredUser' ); - $result = self::$mUser->getRights(); - break; - case 'user_blocked': - $block = new Block(); - $block->setTarget( self::$mUser ); - $block->setBlocker( 'UTSysop' ); - $block->mReason = 'Testing AbuseFilter variable user_blocked'; - $block->mExpiry = 'infinity'; - - $block->insert(); - $result = true; - break; - default: - $success = false; - $result = null; - } - return [ $result, $success ]; - } - - /** - * Check that the generated user-related variables are correct - * - * @param string $varName The name of the variable we're currently testing - * @covers AbuseFilter::generateUserVars - * @dataProvider provideUserVars - */ - public function testGenerateUserVars( $varName ) { - list( $computed, $successfully ) = self::computeExpectedUserVariable( $varName ); - if ( !$successfully ) { - $this->fail( "Given unknown user-related variable $varName." ); - } - - $variableHolder = AbuseFilter::generateUserVars( self::$mUser ); - $actual = $variableHolder->getVar( $varName )->toNative(); - $this->assertSame( - $computed, - $actual, - "AbuseFilter variable $varName is computed wrongly." - ); - } - - /** - * Data provider for testGenerateUserVars - * @return array - */ - public function provideUserVars() { - return [ - [ 'user_editcount' ], - [ 'user_name' ], - [ 'user_emailconfirm' ], - [ 'user_groups' ], - [ 'user_rights' ], - [ 'user_blocked' ] - ]; - } - - /** - * Check that user_age is correct. Needs a separate function to take into account the - * difference between timestamps due to test execution time - * - * @covers AbuseFilter::generateUserVars - */ - public function testUserAgeVar() { - // Set a fake timestamp so that execution time won't be a problem - MWTimestamp::setFakeTime( 1514700163 ); - $variableHolder = AbuseFilter::generateUserVars( self::$mUser ); - $actual = $variableHolder->getVar( 'user_age' )->toNative(); - - $this->assertEquals( - 163, - $actual, - "AbuseFilter variable user_age is computed wrongly. Expected: 163, actual: $actual." - ); - } - - /** - * Given the name of a variable, naturally sets it to a determined amount - * - * @param string $suffix The suffix of the variable - * @param string|null $options Further options for the test - * @return array the first position is the result (mixed), the second is a boolean - * indicating whether we've been able to compute the given variable. If false, then - * the result may be null if the requested variable doesn't exist, or false if there - * has been some other problem. - */ - private static function computeExpectedTitleVariable( $suffix, $options = null ) { - self::$mTitle = Title::newFromText( 'AbuseFilter test' ); - $page = WikiPage::factory( self::$mTitle ); - - if ( $options === 'restricted' ) { - $action = str_replace( '_restrictions_', '', $suffix ); - $namespace = 0; - if ( $action === 'upload' ) { - // Only files can have it - $namespace = 6; - } - self::$mTitle = Title::makeTitle( $namespace, 'AbuseFilter restrictions test' ); - $page = WikiPage::factory( self::$mTitle ); - if ( $action !== 'create' ) { - // To apply other restrictions, the title has to exist - $page->doEditContent( - new WikitextContent( 'AbuseFilter test for title variables' ), - 'Testing page for AbuseFilter', - EDIT_NEW, - false, - self::$mUser - ); - } - $_ = false; - $s = $page->doUpdateRestrictions( - [ $action => true ], - [ $action => 'infinity' ], - $_, - 'Testing restrictions for AbuseFilter', - self::$mUser - ); - } - $success = true; - switch ( $suffix ) { - case '_id': - $result = self::$mTitle->getArticleID(); - break; - case '_namespace': - $result = self::$mTitle->getNamespace(); - break; - case '_title': - $result = self::$mTitle->getText(); - break; - case '_prefixedtitle': - $result = self::$mTitle->getPrefixedText(); - break; - case '_restrictions_create': - $restrictions = self::$mTitle->getRestrictions( 'create' ); - $restrictions = count( $restrictions ) ? $restrictions : []; - $preliminarCheck = !( $options === 'restricted' xor count( $restrictions ) ); - if ( $preliminarCheck ) { - $result = $restrictions; - } else { - $success = false; - $result = false; - } - break; - case '_restrictions_edit': - $restrictions = self::$mTitle->getRestrictions( 'edit' ); - $restrictions = count( $restrictions ) ? $restrictions : []; - $preliminarCheck = !( $options === 'restricted' xor count( $restrictions ) ); - if ( $preliminarCheck ) { - $result = $restrictions; - } else { - $success = false; - $result = false; - } - break; - case '_restrictions_move': - $restrictions = self::$mTitle->getRestrictions( 'move' ); - $restrictions = count( $restrictions ) ? $restrictions : []; - $preliminarCheck = !( $options === 'restricted' xor count( $restrictions ) ); - if ( $preliminarCheck ) { - $result = $restrictions; - } else { - $success = false; - $result = false; - } - break; - case '_restrictions_upload': - $restrictions = self::$mTitle->getRestrictions( 'upload' ); - $restrictions = count( $restrictions ) ? $restrictions : []; - $preliminarCheck = !( $options === 'restricted' xor count( $restrictions ) ); - if ( $preliminarCheck ) { - $result = $restrictions; - } else { - $success = false; - $result = false; - } - break; - case '_recent_contributors': - // Create the page and make a couple of edits from different users - $page->doEditContent( - new WikitextContent( 'AbuseFilter test for title variables' ), - 'Testing page for AbuseFilter', - EDIT_NEW, - false, - self::$mUser - ); - $mockContributors = [ 'Alice', 'Bob', 'Charlie' ]; - foreach ( $mockContributors as $user ) { - $page->doEditContent( - new WikitextContent( "AbuseFilter test, page revision by $user" ), - 'Testing page for AbuseFilter', - EDIT_UPDATE, - false, - User::newFromName( $user ) - ); - } - $contributors = array_reverse( $mockContributors ); - array_push( $contributors, self::$mUser->getName() ); - $result = $contributors; - break; - case '_first_contributor': - // Create the page and make a couple of edits from different users - $page->doEditContent( - new WikitextContent( 'AbuseFilter test for title variables' ), - 'Testing page for AbuseFilter', - EDIT_NEW, - false, - self::$mUser - ); - $mockContributors = [ 'Alice', 'Bob', 'Charlie' ]; - foreach ( $mockContributors as $user ) { - $page->doEditContent( - new WikitextContent( "AbuseFilter test, page revision by $user" ), - 'Testing page for AbuseFilter', - EDIT_UPDATE, - false, - User::newFromName( $user ) - ); - } - $result = self::$mUser->getName(); - break; - default: - $success = false; - $result = null; - } - return [ $result, $success ]; - } - - /** - * Check that the generated title-related variables are correct - * - * @param string $prefix The prefix of the variables we're currently testing - * @param string $suffix The suffix of the variables we're currently testing - * @param string|null $options Whether we want to execute the test with specific options - * Right now, this can only be 'restricted' for restrictions variables; in this case, - * the tested title will have the requested restriction. - * @covers AbuseFilter::generateTitleVars - * @dataProvider provideTitleVars - */ - public function testGenerateTitleVars( $prefix, $suffix, $options = null ) { - $varName = $prefix . $suffix; - list( $computed, $successfully ) = self::computeExpectedTitleVariable( $suffix, $options ); - if ( !$successfully ) { - if ( $computed === null ) { - $this->fail( "Given unknown title-related variable $varName." ); - } else { - $this->fail( "AbuseFilter variable $varName is computed wrongly." ); - } - } - - $variableHolder = AbuseFilter::generateTitleVars( self::$mTitle, $prefix ); - $actual = $variableHolder->getVar( $varName )->toNative(); - $this->assertSame( - $computed, - $actual, - "AbuseFilter variable $varName is computed wrongly." - ); - } - - /** - * Data provider for testGenerateUserVars - * @return array - */ - public function provideTitleVars() { - return [ - [ 'page', '_id' ], - [ 'page', '_namespace' ], - [ 'page', '_title' ], - [ 'page', '_prefixedtitle' ], - [ 'page', '_restrictions_create' ], - [ 'page', '_restrictions_create', 'restricted' ], - [ 'page', '_restrictions_edit' ], - [ 'page', '_restrictions_edit', 'restricted' ], - [ 'page', '_restrictions_move' ], - [ 'page', '_restrictions_move', 'restricted' ], - [ 'page', '_restrictions_upload' ], - [ 'page', '_restrictions_upload', 'restricted' ], - [ 'page', '_first_contributor' ], - [ 'page', '_recent_contributors' ], - [ 'moved_from', '_id' ], - [ 'moved_from', '_namespace' ], - [ 'moved_from', '_title' ], - [ 'moved_from', '_prefixedtitle' ], - [ 'moved_from', '_restrictions_create' ], - [ 'moved_from', '_restrictions_create', 'restricted' ], - [ 'moved_from', '_restrictions_edit' ], - [ 'moved_from', '_restrictions_edit', 'restricted' ], - [ 'moved_from', '_restrictions_move' ], - [ 'moved_from', '_restrictions_move', 'restricted' ], - [ 'moved_from', '_restrictions_upload' ], - [ 'moved_from', '_restrictions_upload', 'restricted' ], - [ 'moved_from', '_first_contributor' ], - [ 'moved_from', '_recent_contributors' ], - [ 'moved_to', '_id' ], - [ 'moved_to', '_namespace' ], - [ 'moved_to', '_title' ], - [ 'moved_to', '_prefixedtitle' ], - [ 'moved_to', '_restrictions_create' ], - [ 'moved_to', '_restrictions_create', 'restricted' ], - [ 'moved_to', '_restrictions_edit' ], - [ 'moved_to', '_restrictions_edit', 'restricted' ], - [ 'moved_to', '_restrictions_move' ], - [ 'moved_to', '_restrictions_move', 'restricted' ], - [ 'moved_to', '_restrictions_upload' ], - [ 'moved_to', '_restrictions_upload', 'restricted' ], - [ 'moved_to', '_first_contributor' ], - [ 'moved_to', '_recent_contributors' ], - ]; - } - - /** - * Check that _age variables are correct. They need a separate function to take into - * account the difference between timestamps due to test execution time - * - * @param string $prefix Prefix of the variable to test - * @covers AbuseFilter::generateTitleVars - * @dataProvider provideAgeVars - */ - public function testAgeVars( $prefix ) { - $varName = $prefix . '_age'; - - MWTimestamp::setFakeTime( 1514700000 ); - self::$mTitle = Title::newFromText( 'AbuseFilter test' ); - $page = WikiPage::factory( self::$mTitle ); - $page->doEditContent( - new WikitextContent( 'AbuseFilter _age variables test' ), - 'Testing page for AbuseFilter', - EDIT_NEW, - false, - self::$mUser - ); - - MWTimestamp::setFakeTime( 1514700123 ); - $variableHolder = AbuseFilter::generateTitleVars( self::$mTitle, $prefix ); - $actual = $variableHolder->getVar( $varName )->toNative(); - $this->assertEquals( - 123, - $actual, - "AbuseFilter variable $varName is computed wrongly. Expected: 123, actual: $actual." - ); - } - - /** - * Data provider for testAgeVars - * @return array - */ - public function provideAgeVars() { - return [ - [ 'page' ], - [ 'moved_from' ], - [ 'moved_to' ], - ]; - } - - /** - * Check that version comparing works well - * - * @param array $firstVersion [ stdClass, array ] - * @param array $secondVersion [ stdClass, array ] - * @param array $expected The differences - * @covers AbuseFilter::compareVersions - * @dataProvider provideVersions - */ - public function testCompareVersions( $firstVersion, $secondVersion, $expected ) { - $differences = AbuseFilter::compareVersions( $firstVersion, $secondVersion ); - - $this->assertSame( - $expected, - $differences, - 'AbuseFilter::compareVersions did not output the expected result.' - ); - } - - /** - * Data provider for testCompareVersions - * @return array - */ - public function provideVersions() { - return [ - [ - [ - (object)[ - 'af_public_comments' => 'Comments', - 'af_pattern' => '/*Pattern*/', - 'af_comments' => 'Comments', - 'af_deleted' => 0, - 'af_enabled' => 1, - 'af_hidden' => 0, - 'af_global' => 0, - 'af_group' => 'default' - ], - [ - 'disallow' => [ - 'action' => 'disallow', - 'parameters' => [] - ] - ] - ], - [ - (object)[ - 'af_public_comments' => 'OtherComments', - 'af_pattern' => '/*Other pattern*/', - 'af_comments' => 'Other comments', - 'af_deleted' => 1, - 'af_enabled' => 0, - 'af_hidden' => 1, - 'af_global' => 1, - 'af_group' => 'flow' - ], - [ - 'disallow' => [ - 'action' => 'disallow', - 'parameters' => [] - ] - ] - ], - [ - 'af_public_comments', - 'af_pattern', - 'af_comments', - 'af_deleted', - 'af_enabled', - 'af_hidden', - 'af_global', - 'af_group', - ] - ], - [ - [ - (object)[ - 'af_public_comments' => 'Comments', - 'af_pattern' => '/*Pattern*/', - 'af_comments' => 'Comments', - 'af_deleted' => 0, - 'af_enabled' => 1, - 'af_hidden' => 0, - 'af_global' => 0, - 'af_group' => 'default' - ], - [ - 'disallow' => [ - 'action' => 'disallow', - 'parameters' => [] - ] - ] - ], - [ - (object)[ - 'af_public_comments' => 'Comments', - 'af_pattern' => '/*Pattern*/', - 'af_comments' => 'Comments', - 'af_deleted' => 0, - 'af_enabled' => 1, - 'af_hidden' => 0, - 'af_global' => 0, - 'af_group' => 'default' - ], - [ - 'disallow' => [ - 'action' => 'disallow', - 'parameters' => [] - ] - ] - ], - [] - ], - [ - [ - (object)[ - 'af_public_comments' => 'Comments', - 'af_pattern' => '/*Pattern*/', - 'af_comments' => 'Comments', - 'af_deleted' => 0, - 'af_enabled' => 1, - 'af_hidden' => 0, - 'af_global' => 0, - 'af_group' => 'default' - ], - [ - 'disallow' => [ - 'action' => 'disallow', - 'parameters' => [] - ] - ] - ], - [ - (object)[ - 'af_public_comments' => 'Comments', - 'af_pattern' => '/*Pattern*/', - 'af_comments' => 'Comments', - 'af_deleted' => 0, - 'af_enabled' => 1, - 'af_hidden' => 0, - 'af_global' => 0, - 'af_group' => 'default' - ], - [ - 'degroup' => [ - 'action' => 'degroup', - 'parameters' => [] - ] - ] - ], - [ 'actions' ] - ], - [ - [ - (object)[ - 'af_public_comments' => 'Comments', - 'af_pattern' => '/*Pattern*/', - 'af_comments' => 'Comments', - 'af_deleted' => 0, - 'af_enabled' => 1, - 'af_hidden' => 0, - 'af_global' => 0, - 'af_group' => 'default' - ], - [ - 'disallow' => [ - 'action' => 'disallow', - 'parameters' => [] - ] - ] - ], - [ - (object)[ - 'af_public_comments' => 'OtherComments', - 'af_pattern' => '/*Other pattern*/', - 'af_comments' => 'Other comments', - 'af_deleted' => 1, - 'af_enabled' => 0, - 'af_hidden' => 1, - 'af_global' => 1, - 'af_group' => 'flow' - ], - [ - 'blockautopromote' => [ - 'action' => 'blockautopromote', - 'parameters' => [] - ] - ] - ], - [ - 'af_public_comments', - 'af_pattern', - 'af_comments', - 'af_deleted', - 'af_enabled', - 'af_hidden', - 'af_global', - 'af_group', - 'actions' - ] - ], - [ - [ - (object)[ - 'af_public_comments' => 'Comments', - 'af_pattern' => '/*Pattern*/', - 'af_comments' => 'Comments', - 'af_deleted' => 0, - 'af_enabled' => 1, - 'af_hidden' => 0, - 'af_global' => 0, - 'af_group' => 'default' - ], - [ - 'disallow' => [ - 'action' => 'disallow', - 'parameters' => [] - ] - ] - ], - [ - (object)[ - 'af_public_comments' => 'Comments', - 'af_pattern' => '/*Pattern*/', - 'af_comments' => 'Comments', - 'af_deleted' => 0, - 'af_enabled' => 1, - 'af_hidden' => 0, - 'af_global' => 0, - 'af_group' => 'default' - ], - [ - 'warn' => [ - 'action' => 'warn', - 'parameters' => [ - 'abusefilter-warning' - ] - ] - ] - ], - [ 'actions' ] - ], - [ - [ - (object)[ - 'af_public_comments' => 'Comments', - 'af_pattern' => '/*Pattern*/', - 'af_comments' => 'Comments', - 'af_deleted' => 0, - 'af_enabled' => 1, - 'af_hidden' => 0, - 'af_global' => 0, - 'af_group' => 'default' - ], - [ - 'warn' => [ - 'action' => 'warn', - 'parameters' => [ - 'abusefilter-warning' - ] - ] - ] - ], - [ - (object)[ - 'af_public_comments' => 'Comments', - 'af_pattern' => '/*Pattern*/', - 'af_comments' => 'Comments', - 'af_deleted' => 0, - 'af_enabled' => 1, - 'af_hidden' => 0, - 'af_global' => 0, - 'af_group' => 'default' - ], - [ - 'disallow' => [ - 'action' => 'disallow', - 'parameters' => [] - ] - ] - ], - [ 'actions' ] - ], - [ - [ - (object)[ - 'af_public_comments' => 'Comments', - 'af_pattern' => '/*Pattern*/', - 'af_comments' => 'Comments', - 'af_deleted' => 0, - 'af_enabled' => 1, - 'af_hidden' => 0, - 'af_global' => 0, - 'af_group' => 'default' - ], - [ - 'warn' => [ - 'action' => 'warn', - 'parameters' => [ - 'abusefilter-warning' - ] - ] - ] - ], - [ - (object)[ - 'af_public_comments' => 'Comments', - 'af_pattern' => '/*Pattern*/', - 'af_comments' => 'Comments', - 'af_deleted' => 0, - 'af_enabled' => 1, - 'af_hidden' => 0, - 'af_global' => 0, - 'af_group' => 'default' - ], - [ - 'warn' => [ - 'action' => 'warn', - 'parameters' => [ - 'abusefilter-my-best-warning' - ] - ], - 'degroup' => [ - 'action' => 'degroup', - 'parameters' => [] - ] - ] - ], - [ 'actions' ] - ], - [ - [ - (object)[ - 'af_public_comments' => 'Comments', - 'af_pattern' => '/*Pattern*/', - 'af_comments' => 'Comments', - 'af_deleted' => 0, - 'af_enabled' => 1, - 'af_hidden' => 0, - 'af_global' => 0, - 'af_group' => 'default' - ], - [ - 'warn' => [ - 'action' => 'warn', - 'parameters' => [ - 'abusefilter-warning' - ] - ] - ] - ], - [ - (object)[ - 'af_public_comments' => 'Comments', - 'af_pattern' => '/*Other Pattern*/', - 'af_comments' => 'Comments', - 'af_deleted' => 0, - 'af_enabled' => 1, - 'af_hidden' => 1, - 'af_global' => 0, - 'af_group' => 'flow' - ], - [ - 'warn' => [ - 'action' => 'warn', - 'parameters' => [ - 'abusefilter-my-best-warning' - ] - ] - ] - ], - [ - 'af_pattern', - 'af_hidden', - 'af_group', - 'actions' - ] - ], - [ - [ - (object)[ - 'af_public_comments' => 'Comments', - 'af_pattern' => '/*Pattern*/', - 'af_comments' => 'Comments', - 'af_deleted' => 0, - 'af_enabled' => 1, - 'af_hidden' => 0, - 'af_global' => 0, - 'af_group' => 'default' - ], - [ - 'warn' => [ - 'action' => 'warn', - 'parameters' => [ - 'abusefilter-beautiful-warning' - ] - ] - ] - ], - [ - (object)[ - 'af_public_comments' => 'Comments', - 'af_pattern' => '/*Pattern*/', - 'af_comments' => 'Comments', - 'af_deleted' => 0, - 'af_enabled' => 1, - 'af_hidden' => 0, - 'af_global' => 0, - 'af_group' => 'flow' - ], - [ - 'warn' => [ - 'action' => 'warn', - 'parameters' => [ - 'abusefilter-my-best-warning' - ] - ] - ] - ], - [ - 'af_group', - 'actions' - ] - ], - ]; - } - - /** - * Check that row translating from abuse_filter_history to abuse_filter is working fine - * - * @param stdClass $row The row to translate - * @param array $expected The expected result - * @covers AbuseFilter::translateFromHistory - * @dataProvider provideHistoryRows - */ - public function testTranslateFromHistory( $row, $expected ) { - $actual = AbuseFilter::translateFromHistory( $row ); - - $this->assertEquals( - $expected, - $actual, - 'AbuseFilter::translateFromHistory produced a wrong output.' - ); - } - - /** - * Data provider for testTranslateFromHistory - * @return array - */ - public function provideHistoryRows() { - return [ - [ - (object)[ - 'afh_filter' => 1, - 'afh_user' => 0, - 'afh_user_text' => 'FilteredUser', - 'afh_timestamp' => '20180706142932', - 'afh_pattern' => '/*Pattern*/', - 'afh_comments' => 'Comments', - 'afh_flags' => 'enabled,hidden', - 'afh_public_comments' => 'Description', - 'afh_actions' => serialize( [ - 'degroup' => [], - 'disallow' => [] - ] ), - 'afh_deleted' => 0, - 'afh_changed_fields' => 'actions', - 'afh_group' => 'default' - ], - [ - (object)[ - 'af_pattern' => '/*Pattern*/', - 'af_user' => 0, - 'af_user_text' => 'FilteredUser', - 'af_timestamp' => '20180706142932', - 'af_comments' => 'Comments', - 'af_public_comments' => 'Description', - 'af_deleted' => 0, - 'af_id' => 1, - 'af_group' => 'default', - 'af_hidden' => 1, - 'af_enabled' => 1 - ], - [ - 'degroup' => [ - 'action' => 'degroup', - 'parameters' => [] - ], - 'disallow' => [ - 'action' => 'disallow', - 'parameters' => [] - ] - ] - ] - ], - [ - (object)[ - 'afh_filter' => 5, - 'afh_user' => 0, - 'afh_user_text' => 'FilteredUser', - 'afh_timestamp' => '20180706145516', - 'afh_pattern' => '1 === 1', - 'afh_comments' => '', - 'afh_flags' => '', - 'afh_public_comments' => 'Our best filter', - 'afh_actions' => serialize( [ - 'warn' => [ - 'abusefilter-warning', - '' - ], - 'disallow' => [], - ] ), - 'afh_deleted' => 0, - 'afh_changed_fields' => 'af_pattern,af_comments,af_enabled,actions', - 'afh_group' => 'flow' - ], - [ - (object)[ - 'af_pattern' => '1 === 1', - 'af_user' => 0, - 'af_user_text' => 'FilteredUser', - 'af_timestamp' => '20180706145516', - 'af_comments' => '', - 'af_public_comments' => 'Our best filter', - 'af_deleted' => 0, - 'af_id' => 5, - 'af_group' => 'flow', - 'af_hidden' => 0, - 'af_enabled' => 0 - ], - [ - 'warn' => [ - 'action' => 'warn', - 'parameters' => [ - 'abusefilter-warning', - '' - ] - ], - 'disallow' => [ - 'action' => 'disallow', - 'parameters' => [] - ] - ] - ] - ], - [ - (object)[ - 'afh_filter' => 7, - 'afh_user' => 1, - 'afh_user_text' => 'AnotherUser', - 'afh_timestamp' => '20160511185604', - 'afh_pattern' => 'added_lines irlike "lol" & summary == "ggwp"', - 'afh_comments' => 'Show vandals no mercy, for you shall receive none.', - 'afh_flags' => 'enabled,hidden', - 'afh_public_comments' => 'Whatever', - 'afh_actions' => serialize( [ - 'warn' => [ - 'abusefilter-warning', - '' - ], - 'disallow' => [], - 'block' => [ - 'blocktalk', - '8 hours', - 'infinity' - ] - ] ), - 'afh_deleted' => 0, - 'afh_changed_fields' => 'af_pattern,af_comments,af_enabled,af_public_comments,actions', - 'afh_group' => 'default' - ], - [ - (object)[ - 'af_pattern' => 'added_lines irlike "lol" & summary == "ggwp"', - 'af_user' => 1, - 'af_user_text' => 'AnotherUser', - 'af_timestamp' => '20160511185604', - 'af_comments' => 'Show vandals no mercy, for you shall receive none.', - 'af_public_comments' => 'Whatever', - 'af_deleted' => 0, - 'af_id' => 7, - 'af_group' => 'default', - 'af_hidden' => 1, - 'af_enabled' => 1 - ], - [ - 'warn' => [ - 'action' => 'warn', - 'parameters' => [ - 'abusefilter-warning', - '' - ] - ], - 'disallow' => [ - 'action' => 'disallow', - 'parameters' => [] - ], - 'block' => [ - 'action' => 'block', - 'parameters' => [ - 'blocktalk', - '8 hours', - 'infinity' - ] - ] - ] - ] - ], - [ - (object)[ - 'afh_filter' => 131, - 'afh_user' => 15, - 'afh_user_text' => 'YetAnotherUser', - 'afh_timestamp' => '20180511185604', - 'afh_pattern' => 'user_name == "Thatguy"', - 'afh_comments' => '', - 'afh_flags' => 'hidden,deleted', - 'afh_public_comments' => 'No comment.', - 'afh_actions' => serialize( [ - 'throttle' => [ - '131', - '3,60', - 'user' - ], - 'tag' => [ - 'mytag', - 'yourtag' - ] - ] ), - 'afh_deleted' => 1, - 'afh_changed_fields' => 'af_pattern', - 'afh_group' => 'default' - ], - [ - (object)[ - 'af_pattern' => 'user_name == "Thatguy"', - 'af_user' => 15, - 'af_user_text' => 'YetAnotherUser', - 'af_timestamp' => '20180511185604', - 'af_comments' => '', - 'af_public_comments' => 'No comment.', - 'af_deleted' => 1, - 'af_id' => 131, - 'af_group' => 'default', - 'af_hidden' => 1, - 'af_enabled' => 0 - ], - [ - 'throttle' => [ - 'action' => 'throttle', - 'parameters' => [ - '131', - '3,60', - 'user' - ] - ], - 'tag' => [ - 'action' => 'tag', - 'parameters' => [ - 'mytag', - 'yourtag' - ] - ] - ] - ] - ] - ]; - } - - /** - * Given the name of a variable, naturally sets it to a determined amount - * - * @param string $old The old wikitext of the page - * @param string $new The new wikitext of the page - * @return array - */ - private static function computeExpectedEditVariable( $old, $new ) { - global $wgParser; - $popts = ParserOptions::newFromUser( self::$mUser ); - // Order matters here. Some variables rely on other ones. - $variables = [ - 'new_html', - 'new_pst', - 'new_text', - 'edit_diff', - 'edit_diff_pst', - 'new_size', - 'old_size', - 'edit_delta', - 'added_lines', - 'removed_lines', - 'added_lines_pst', - 'all_links', - 'old_links', - 'added_links', - 'removed_links' - ]; - - // Set required variables - self::$mVariables->setVar( 'old_wikitext', $old ); - self::$mVariables->setVar( 'new_wikitext', $new ); - self::$mVariables->setVar( 'summary', 'Testing page for AbuseFilter' ); - - $computedVariables = []; - foreach ( $variables as $var ) { - $success = true; - // Reset text variables since some operations are changing them. - $oldText = $old; - $newText = $new; - switch ( $var ) { - case 'edit_diff_pst': - $newText = self::$mVariables->getVar( 'new_pst' )->toString(); - // Intentional fall-through - case 'edit_diff': - $diffs = new Diff( explode( "\n", $oldText ), explode( "\n", $newText ) ); - $format = new UnifiedDiffFormatter(); - $result = $format->format( $diffs ); - break; - case 'new_size': - $result = strlen( $newText ); - break; - case 'old_size': - $result = strlen( $oldText ); - break; - case 'edit_delta': - $result = strlen( $newText ) - strlen( $oldText ); - break; - case 'added_lines_pst': - case 'added_lines': - case 'removed_lines': - $diffVariable = $var === 'added_lines_pst' ? 'edit_diff_pst' : 'edit_diff'; - $diff = self::$mVariables->getVar( $diffVariable )->toString(); - $line_prefix = $var === 'removed_lines' ? '-' : '+'; - $diff_lines = explode( "\n", $diff ); - $interest_lines = []; - foreach ( $diff_lines as $line ) { - if ( substr( $line, 0, 1 ) === $line_prefix ) { - $interest_lines[] = substr( $line, strlen( $line_prefix ) ); - } - } - $result = $interest_lines; - break; - case 'new_text': - $newHtml = self::$mVariables->getVar( 'new_html' )->toString(); - $result = StringUtils::delimiterReplace( '<', '>', '', $newHtml ); - break; - case 'new_pst': - case 'new_html': - $article = self::$mPage; - $content = ContentHandler::makeContent( $newText, $article->getTitle() ); - $editInfo = $article->prepareContentForEdit( $content ); - - if ( $var === 'new_pst' ) { - $result = $editInfo->pstContent->serialize( $editInfo->format ); - } else { - $result = $editInfo->output->getText(); - } - break; - case 'all_links': - $article = self::$mPage; - $content = ContentHandler::makeContent( $newText, $article->getTitle() ); - $editInfo = $article->prepareContentForEdit( $content ); - $result = array_keys( $editInfo->output->getExternalLinks() ); - break; - case 'old_links': - $article = self::$mPage; - $popts->setTidy( true ); - $edit = $wgParser->parse( $oldText, $article->getTitle(), $popts ); - $result = array_keys( $edit->getExternalLinks() ); - break; - case 'added_links': - case 'removed_links': - $oldLinks = self::$mVariables->getVar( 'old_links' )->toString(); - $newLinks = self::$mVariables->getVar( 'all_links' )->toString(); - $oldLinks = explode( "\n", $oldLinks ); - $newLinks = explode( "\n", $newLinks ); - - if ( $var === 'added_links' ) { - $result = array_diff( $newLinks, $oldLinks ); - } else { - $result = array_diff( $oldLinks, $newLinks ); - } - break; - default: - $success = false; - $result = null; - } - $computedVariables[$var] = [ $result, $success ]; - self::$mVariables->setVar( $var, $result ); - } - return $computedVariables; - } - - /** - * Check that the generated variables for edits are correct - * - * @param string $oldText The old wikitext of the page - * @param string $newText The new wikitext of the page - * @covers AbuseFilter::getEditVars - * @dataProvider provideEditVars - */ - public function testGetEditVars( $oldText, $newText ) { - global $wgLang; - self::$mTitle = Title::makeTitle( 0, 'AbuseFilter test' ); - self::$mPage = WikiPage::factory( self::$mTitle ); - - self::$mPage->doEditContent( - new WikitextContent( $oldText ), - 'Creating the test page', - EDIT_NEW, - false, - self::$mUser - ); - self::$mPage->doEditContent( - new WikitextContent( $newText ), - 'Testing page for AbuseFilter', - EDIT_UPDATE, - false, - self::$mUser - ); - - $computeResult = self::computeExpectedEditVariable( $oldText, $newText ); - - $computedVariables = []; - foreach ( $computeResult as $varName => $computed ) { - if ( !$computed[1] ) { - $this->fail( "Given unknown edit variable $varName." ); - } - $computedVariables[$varName] = $computed[0]; - } - - self::$mVariables->addHolders( AbuseFilter::getEditVars( self::$mTitle, self::$mPage ) ); - - $actualVariables = []; - foreach ( self::$mVariables->mVars as $varName => $_ ) { - $actualVariables[$varName] = self::$mVariables->getVar( $varName )->toNative(); - } - - $differences = []; - foreach ( $computedVariables as $var => $computed ) { - if ( !isset( $actualVariables[$var] ) ) { - $this->fail( "AbuseFilter::getEditVars didn't set the $var variable." ); - } elseif ( $computed !== $actualVariables[$var] ) { - $differences[] = $var; - } - } - - $this->assertCount( - 0, - $differences, - 'The following AbuseFilter variables are computed wrongly: ' . $wgLang->commaList( $differences ) - ); - } - - /** - * Data provider for testGetEditVars - * @return array - */ - public function provideEditVars() { - return [ - [ - '[https://www.mediawiki.it/wiki/Extension:AbuseFilter AbuseFilter] test page', - 'Adding something to compute edit variables. Here are some diacritics to make sure ' . - "the test behaves well with unicode: Là giù cascherò io altresì.\n名探偵コナン.\n" . - "[[Help:Pre Save Transform|]] should make the difference as well.\n" . - 'Instead, [https://www.mediawiki.it this] is an external link.' - ], - [ - 'Adding something to compute edit variables. Here are some diacritics to make sure ' . - "the test behaves well with unicode: Là giù cascherò io altresì.\n名探偵コナン.\n" . - "[[Help:Pre Save Transform|]] should make the difference as well.\n" . - 'Instead, [https://www.mediawiki.it this] is an external link.', - '[https://www.mediawiki.it/wiki/Extension:AbuseFilter AbuseFilter] test page' - ], - [ - "A '''foo''' is not a ''bar''.", - "Actually, according to [http://en.wikipedia.org ''Wikipedia''], a '''''foo''''' " . - 'is <small>more or less</small> the same as a <b>bar</b>, except that a foo is ' . - 'usually provided together with a [[cellar door|]] to make it work<ref>Yes, really</ref>.' - ], - [ - 'This edit will be pretty smll', - 'This edit will be pretty small' - ] - ]; - } -} diff --git a/AbuseFilter/tests/phpunit/AbuseFilterVariableGeneratorDBTest.php b/AbuseFilter/tests/phpunit/AbuseFilterVariableGeneratorDBTest.php new file mode 100644 index 00000000..7c27c61f --- /dev/null +++ b/AbuseFilter/tests/phpunit/AbuseFilterVariableGeneratorDBTest.php @@ -0,0 +1,228 @@ +<?php + +use MediaWiki\Extension\AbuseFilter\VariableGenerator\VariableGenerator; + +/** + * @group Test + * @group AbuseFilter + * @group AbuseFilterGeneric + * @group Database + */ +class AbuseFilterVariableGeneratorDBTest extends MediaWikiIntegrationTestCase { + protected $tablesUsed = [ + 'page', + 'text', + 'page_restrictions', + 'user', + ]; + + /** + * Check that the generated variables for edits are correct + * + * @param string $oldText The old wikitext of the page + * @param string $newText The new wikitext of the page + * @param string $summary + * @param array $expected Expected edit vars + * @covers \MediaWiki\Extension\AbuseFilter\VariableGenerator\VariableGenerator::addEditVars + * @covers AFComputedVariable + * @dataProvider provideEditVars + */ + public function testAddEditVars( $oldText, $newText, $summary, array $expected ) { + $pageName = __METHOD__; + $title = Title::makeTitle( 0, $pageName ); + $page = WikiPage::factory( $title ); + + $this->editPage( $pageName, $oldText, 'Creating the test page' ); + $this->editPage( $pageName, $newText, $summary ); + + $baseVars = AbuseFilterVariableHolder::newFromArray( [ + 'old_wikitext' => $oldText, + 'new_wikitext' => $newText, + 'summary' => $summary + ] ); + + $generator = new VariableGenerator( $baseVars ); + $actual = $generator->addEditVars( $title, $page )->getVariableHolder()->exportAllVars( true ); + + // Special case for new_html: avoid flaky tests, and only check containment + $this->assertStringContainsString( '<div class="mw-parser-output', $actual['new_html'] ); + $this->assertNotRegExp( "/<!--\s*NewPP limit/", $actual['new_html'] ); + $this->assertNotRegExp( "/<!--\s*Transclusion/", $actual['new_html'] ); + foreach ( $expected['new_html'] as $needle ) { + $this->assertStringContainsString( $needle, $actual['new_html'], 'Checking new_html' ); + } + unset( $actual['new_html'], $expected['new_html'] ); + + $this->assertEquals( $expected, $actual ); + } + + /** + * Data provider for testAddEditVars + * @return Generator|array + */ + public function provideEditVars() { + $summary = __METHOD__; + + // phpcs:disable Generic.Files.LineLength + $old = '[https://a.com Test] foo'; + $new = "'''Random'''.\nSome ''special'' chars: àèìòù 名探偵コナン.\n[[Help:PST|]] test, [//www.b.com link]"; + $expected = [ + 'old_wikitext' => $old, + 'new_wikitext' => $new, + 'summary' => $summary, + 'new_html' => [ '<p><b>Random</b>', '<i>special</i>', 'PST</a>', 'link</a>' ], + 'new_pst' => "'''Random'''.\nSome ''special'' chars: àèìòù 名探偵コナン.\n[[Help:PST|PST]] test, [//www.b.com link]", + 'new_text' => "Random.\nSome special chars: àèìòù 名探偵コナン.\nPST test, link", + 'edit_diff' => "@@ -1,1 +1,3 @@\n-[https://a.com Test] foo\n+'''Random'''.\n+Some ''special'' chars: àèìòù 名探偵コナン.\n+[[Help:PST|]] test, [//www.b.com link]\n", + 'edit_diff_pst' => "@@ -1,1 +1,3 @@\n-[https://a.com Test] foo\n+'''Random'''.\n+Some ''special'' chars: àèìòù 名探偵コナン.\n+[[Help:PST|PST]] test, [//www.b.com link]\n", + 'new_size' => strlen( $new ), + 'old_size' => strlen( $old ), + 'edit_delta' => strlen( $new ) - strlen( $old ), + 'added_lines' => explode( "\n", $new ), + 'removed_lines' => [ $old ], + 'added_lines_pst' => [ "'''Random'''.", "Some ''special'' chars: àèìòù 名探偵コナン.", '[[Help:PST|PST]] test, [//www.b.com link]' ], + 'all_links' => [ '//www.b.com' ], + 'old_links' => [ 'https://a.com' ], + 'added_links' => [ '//www.b.com' ], + 'removed_links' => [ 'https://a.com' ] + ]; + + yield 'PST and special chars' => [ $old, $new, $summary, $expected ]; + + $old = "'''Random'''.\nSome ''special'' chars: àèìòù 名探偵コナン.\n[[Help:PST|]] test, [//www.b.com link]"; + $new = '[https://a.com Test] foo'; + $expected = [ + 'old_wikitext' => $old, + 'new_wikitext' => $new, + 'summary' => $summary, + 'new_html' => [ 'Test</a>' ], + 'new_pst' => '[https://a.com Test] foo', + 'new_text' => 'Test foo', + 'edit_diff' => "@@ -1,3 +1,1 @@\n-'''Random'''.\n-Some ''special'' chars: àèìòù 名探偵コナン.\n-[[Help:PST|]] test, [//www.b.com link]\n+[https://a.com Test] foo\n", + 'edit_diff_pst' => "@@ -1,3 +1,1 @@\n-'''Random'''.\n-Some ''special'' chars: àèìòù 名探偵コナン.\n-[[Help:PST|]] test, [//www.b.com link]\n+[https://a.com Test] foo\n", + 'new_size' => strlen( $new ), + 'old_size' => strlen( $old ), + 'edit_delta' => strlen( $new ) - strlen( $old ), + 'added_lines' => [ $new ], + 'removed_lines' => explode( "\n", $old ), + 'added_lines_pst' => [ $new ], + 'all_links' => [ 'https://a.com' ], + 'old_links' => [ '//www.b.com' ], + 'added_links' => [ 'https://a.com' ], + 'removed_links' => [ '//www.b.com' ] + ]; + + yield 'PST and special chars, reverse' => [ $old, $new, $summary, $expected ]; + // phpcs:enable Generic.Files.LineLength + + $old = 'This edit will be pretty smal'; + $new = $old . 'l'; + + $expected = [ + 'old_wikitext' => $old, + 'new_wikitext' => $new, + 'summary' => $summary, + 'new_html' => [ "<p>This edit will be pretty small\n</p>" ], + 'new_pst' => $new, + 'new_text' => $new, + 'edit_diff' => "@@ -1,1 +1,1 @@\n-$old\n+$new\n", + 'edit_diff_pst' => "@@ -1,1 +1,1 @@\n-$old\n+$new\n", + 'new_size' => strlen( $new ), + 'old_size' => strlen( $old ), + 'edit_delta' => 1, + 'added_lines' => [ $new ], + 'removed_lines' => [ $old ], + 'added_lines_pst' => [ $new ], + 'all_links' => [], + 'old_links' => [], + 'added_links' => [], + 'removed_links' => [] + ]; + + yield 'Small edit' => [ $old, $new, $summary, $expected ]; + } + + /** + * Make different users edit a page, so that we can check their names against + * the actual value of a _recent_contributors variable + * @param Title $title + * @return string[] + */ + private function computeRecentContributors( Title $title ) { + // This test uses a custom DB query and it's hard to use mocks + $user = $this->getMutableTestUser()->getUser(); + // Create the page and make a couple of edits from different users + $this->editPage( + $title->getText(), + 'AbuseFilter test for title variables', + '', + $title->getNamespace(), + $user + ); + $mockContributors = [ 'X>Alice', 'X>Bob', 'X>Charlie' ]; + foreach ( $mockContributors as $contributor ) { + $this->editPage( + $title->getText(), + "page revision by $contributor", + '', + $title->getNamespace(), + User::newFromName( $contributor, false ) + ); + } + $contributors = array_reverse( $mockContributors ); + $contributors[] = $user->getName(); + return $contributors; + } + + /** + * Test _recent_contributors variables. They perform a custom DB query and thus are tested + * here instead of in AbuseFilterTest. + * + * @covers MediaWiki\Extension\AbuseFilter\VariableGenerator\VariableGenerator::addTitleVars + * @covers AFComputedVariable::getLastPageAuthors + */ + public function testRecentContributors() { + $prefixes = [ 'page', 'moved_from', 'moved_to' ]; + foreach ( $prefixes as $prefix ) { + $varName = "{$prefix}_recent_contributors"; + $pageName = "Page to test $varName"; + $title = Title::newFromText( $pageName ); + + $expected = $this->computeRecentContributors( $title ); + $vars = new AbuseFilterVariableHolder; + $generator = new VariableGenerator( $vars ); + $vars = $generator->addTitleVars( $title, $prefix )->getVariableHolder(); + $actual = $vars->getVar( $varName )->toNative(); + $this->assertSame( $expected, $actual, "Prefix: $prefix" ); + } + } + + /** + * Test for the page_first_contributor variable. + * + * @covers MediaWiki\Extension\AbuseFilter\VariableGenerator\VariableGenerator::addTitleVars + * @covers AFComputedVariable::compute + */ + public function testFirstContributorVar() { + $prefixes = [ 'page', 'moved_from', 'moved_to' ]; + foreach ( $prefixes as $prefix ) { + $varName = "{$prefix}_first_contributor"; + $title = Title::makeTitle( NS_MAIN, "Page to test $varName" ); + $user = $this->getMutableTestUser()->getUser(); + $this->editPage( + $title->getText(), + 'AbuseFilter test for title variables', + '', + $title->getNamespace(), + $user + ); + $expected = $user->getName(); + + $vars = new AbuseFilterVariableHolder; + $generator = new VariableGenerator( $vars ); + $vars = $generator->addTitleVars( $title, $prefix )->getVariableHolder(); + $actual = $vars->getVar( $varName )->toNative(); + $this->assertSame( $expected, $actual, "Prefix: $prefix" ); + } + } +} diff --git a/AbuseFilter/tests/phpunit/UpdateVarDumpsTest.php b/AbuseFilter/tests/phpunit/UpdateVarDumpsTest.php new file mode 100644 index 00000000..68311874 --- /dev/null +++ b/AbuseFilter/tests/phpunit/UpdateVarDumpsTest.php @@ -0,0 +1,483 @@ +<?php + +use MediaWiki\Tests\Maintenance\MaintenanceBaseTestCase; +use Wikimedia\Rdbms\IResultWrapper; +use Wikimedia\TestingAccessWrapper; + +/** + * @group Database + * @coversDefaultClass UpdateVarDumps + * @property TestingAccessWrapper|UpdateVarDumps $maintenance + * + * NOTE: This test is likely going to break once we remove the BC code after T213006 is done. + * Since maintaining the test would be expensive, and the script was single-use anyway, this + * test can be just removed (and the script marked as codeCoverageIgnore) as soon as it starts breaking. + */ +class UpdateVarDumpsTest extends MaintenanceBaseTestCase { + private const TIMESTAMP = '20000102030405'; + private static $aflRow = [ + // 'afl_id' + 'afl_filter' => 1, + 'afl_global' => 0, + 'afl_filter_id' => 1, + 'afl_user' => 1, + 'afl_user_text' => 'Foo', + 'afl_ip' => '127.0.0.1', + 'afl_action' => 'edit', + 'afl_actions' => '', + // 'afl_var_dump' + // 'afl_timestamp' added in __construct + 'afl_namespace' => 1, + 'afl_title' => 'Foobar', + 'afl_wiki' => null, + 'afl_deleted' => 0, + 'afl_patrolled_by' => 1, + 'afl_rev_id' => 123 + ]; + + private const TEXT_ROW = [ + // 'old_id' + 'old_flags' => '' + // 'old_text' + ]; + + private const VARS = [ + 'action' => 'edit', + 'page_id' => 12, + 'user_blocked' => true, + 'accountname' => null, + 'user_groups' => [ 'x', 'y' ] + ]; + + /** + * A serialized AbuseFilterVariableHolder object holding self::VARS. Don't try serializing + * the object in tests, because that's going to break too easily. + */ + private const SERIALIZED_VH = 'O:25:"AbuseFilterVariableHolder":3:{s:5:"mVars";a:5:{s:6:"action";O:7:"AFPData":' . + '2:{s:4:"type";s:6:"string";s:4:"data";s:4:"edit";}s:7:"page_id";O:7:"AFPData":2:{s:4:"type";s:3:"int";s:4:' . + '"data";i:12;}s:12:"user_blocked";O:7:"AFPData":2:{s:4:"type";s:4:"bool";s:4:"data";b:1;}s:11:"accountname";' . + 'O:7:"AFPData":2:{s:4:"type";s:4:"null";s:4:"data";N;}s:11:"user_groups";O:7:"AFPData":2:{s:4:"type";s:5:' . + '"array";s:4:"data";a:2:{i:0;O:7:"AFPData":2:{s:4:"type";s:6:"string";s:4:"data";s:1:"x";}i:1;O:7:"AFPData"' . + ':2:{s:4:"type";s:6:"string";s:4:"data";s:1:"y";}}}}s:9:"forFilter";b:0;s:12:"mVarsVersion";i:2;}'; + + /** + * @inheritDoc + */ + protected $tablesUsed = [ 'abuse_filter_log', 'text' ]; + + /** + * @inheritDoc + */ + public function __construct( $name = null, array $data = [], $dataName = '' ) { + parent::__construct( $name, $data, $dataName ); + self::$aflRow['afl_timestamp'] = wfGetDB( DB_REPLICA )->timestamp( self::TIMESTAMP ); + } + + /** + * @inheritDoc + */ + public function setUp(): void { + parent::setUp(); + $this->maintenance->dbr = $this->maintenance->dbw = $this->db; + // This isn't really necessary + $this->maintenance->allRowsCount = 50; + } + + /** + * @inheritDoc + */ + public function getMaintenanceClass() { + return UpdateVarDumps::class; + } + + /** + * Shorthand to select all rows on a table (either abuse_filter_log or text), ordering + * by pkey ASC + * @param string $table + * @return IResultWrapper + */ + private function selectAllAscending( string $table ) : IResultWrapper { + $key = $table === 'abuse_filter_log' ? 'afl_id' : 'old_id'; + return $this->db->select( + $table, + '*', + '', + wfGetCaller(), + [ 'ORDER_BY' => "$key ASC" ] + ); + } + + /** + * @covers ::doDBUpdates + */ + public function testOnEmptyDB() { + $this->expectOutputRegex( '/the abuse_filter_log table is empty/' ); + $this->maintenance->execute(); + } + + /** + * @covers ::fixMissingDumps + * @covers ::doFixMissingDumps + */ + public function testFixMissingDumps() { + $expected = $this->insertMissingDumps(); + $this->maintenance->fixMissingDumps(); + $rows = $this->selectAllAscending( 'abuse_filter_log' ); + $actual = []; + foreach ( $rows as $row ) { + $actual[] = [ 'afl_id' => (int)$row->afl_id, 'afl_var_dump' => $row->afl_var_dump ]; + } + $this->assertSame( $expected, $actual ); + } + + /** + * @return array Expected content of abuse_filter_log after the cleanup + */ + private function insertMissingDumps() : array { + $insertRows = [ + 'Wrong duplicate 1' => [ 'afl_id' => 1, 'afl_var_dump' => '' ] + self::$aflRow, + 'Good duplicate 1' => [ 'afl_id' => 2, 'afl_var_dump' => 'stored-text:12345' ] + self::$aflRow, + + 'Wrong duplicate 2' => [ 'afl_id' => 3, 'afl_var_dump' => '' ] + self::$aflRow, + 'Good duplicate 2' => [ 'afl_id' => 4, 'afl_var_dump' => 'stored-text:12345' ] + self::$aflRow, + + 'Wrong duplicate, 3' => [ 'afl_id' => 5, 'afl_var_dump' => '' ] + self::$aflRow, + 'Extraneous row' => [ 'afl_id' => 6, 'afl_var_dump' => 'stored-text:444' ] + self::$aflRow, + 'Good duplicate 3' => [ 'afl_id' => 7, 'afl_var_dump' => 'stored-text:12345' ] + self::$aflRow, + ]; + $this->db->insert( 'abuse_filter_log', array_values( $insertRows ), __METHOD__ ); + $expected = [ + [ 'afl_id' => 2, 'afl_var_dump' => 'stored-text:12345' ], + [ 'afl_id' => 4, 'afl_var_dump' => 'stored-text:12345' ], + [ 'afl_id' => 6, 'afl_var_dump' => 'stored-text:444' ], + [ 'afl_id' => 7, 'afl_var_dump' => 'stored-text:12345' ], + ]; + return $expected; + } + + /** + * @covers ::fixMissingDumps + * @covers ::doFixMissingDumps + */ + public function testFixMissingDumpsToRebuild() { + $expected = $this->insertMissingDumpsToRebuild(); + $this->maintenance->fixMissingDumps(); + $aflRows = $this->selectAllAscending( 'abuse_filter_log' ); + $aflActual = []; + foreach ( $aflRows as $aflRow ) { + $aflActual[] = [ 'afl_id' => (int)$aflRow->afl_id, 'afl_var_dump' => $aflRow->afl_var_dump ]; + } + $this->assertSame( $expected['abuse_filter_log'], $aflActual ); + + $textRows = $this->selectAllAscending( 'text' ); + $textActual = []; + foreach ( $textRows as $textRow ) { + $textActual[] = [ 'old_id' => (int)$textRow->old_id, 'old_text' => $textRow->old_text ]; + } + $this->assertSame( $expected['text'], $textActual ); + } + + /** + * @return array Expected content of abuse_filter_log after the cleanup + */ + private function insertMissingDumpsToRebuild() : array { + $baseVars = [ + 'timestamp' => wfTimestamp( TS_UNIX, self::TIMESTAMP ), + ]; + + $insertRows = [ + 'Edit' => [ 'afl_id' => 1, 'afl_var_dump' => '' ] + self::$aflRow, + // afl_action added below in order to keep the same order of rows + 'Createaccount' => [ 'afl_id' => 2, 'afl_var_dump' => '' ] + self::$aflRow, + 'Move' => [ 'afl_id' => 3, 'afl_var_dump' => '' ] + self::$aflRow, + ]; + $insertRows['Createaccount']['afl_action'] = 'createaccount'; + $insertRows['Move']['afl_action'] = 'move'; + + $this->db->insert( 'abuse_filter_log', array_values( $insertRows ), __METHOD__ ); + + $title = Title::makeTitle( self::$aflRow['afl_namespace'], self::$aflRow['afl_title'] ); + $expected = [ + 'abuse_filter_log' => [ + [ 'afl_id' => 1, 'afl_var_dump' => 'tt:1' ], + [ 'afl_id' => 2, 'afl_var_dump' => 'tt:2' ], + [ 'afl_id' => 3, 'afl_var_dump' => 'tt:3' ], + ], + 'text' => [ + [ + 'old_id' => 1, + 'old_text' => FormatJson::encode( $baseVars + [ + 'action' => 'edit', + 'user_name' => self::$aflRow['afl_user_text'], + 'page_title' => self::$aflRow['afl_title'], + 'page_prefixedtitle' => $title->getPrefixedText() + ] ) + ], + [ + 'old_id' => 2, + 'old_text' => FormatJson::encode( $baseVars + [ + 'action' => 'createaccount', + 'accountname' => self::$aflRow['afl_user_text'] + ] ) + ], + [ + 'old_id' => 3, + 'old_text' => FormatJson::encode( $baseVars + [ + 'action' => 'move', + 'user_name' => self::$aflRow['afl_user_text'], + 'moved_from_title' => self::$aflRow['afl_title'], + 'moved_from_prefixedtitle' => $title->getPrefixedText() + ] ) + ], + ] + ]; + return $expected; + } + + /** + * @covers ::moveToText + * @covers ::doMoveToText + */ + public function testMoveToText() { + $expected = $this->insertMoveToText(); + $this->maintenance->moveToText(); + + $aflRows = $this->selectAllAscending( 'abuse_filter_log' ); + $aflActual = []; + foreach ( $aflRows as $row ) { + $aflActual[] = [ 'afl_id' => (int)$row->afl_id, 'afl_var_dump' => $row->afl_var_dump ]; + } + $this->assertSame( $expected['abuse_filter_log'], $aflActual ); + + $textRows = $this->selectAllAscending( 'text' ); + $textActual = []; + foreach ( $textRows as $row ) { + $textActual[] = [ 'old_id' => (int)$row->old_id, 'old_text' => $row->old_text ]; + } + $this->assertSame( $expected['text'], $textActual ); + } + + /** + * @return array Expected contents of abuse_filter_log and text tables + */ + private function insertMoveToText() : array { + $serializedArr = serialize( self::VARS ); + + $truncatedArr = substr( $serializedArr, 0, -5 ); + $expectedTruncated = FormatJson::encode( array_diff_key( self::VARS, [ 'user_groups' => 1 ] ) ); + + $insertRows = [ + 'Truncated arr' => [ 'afl_id' => 1, 'afl_var_dump' => $truncatedArr ] + self::$aflRow, + 'Serialized array' => [ 'afl_id' => 2, 'afl_var_dump' => $serializedArr ] + self::$aflRow, + 'Serialized VariableHolder' => + [ 'afl_id' => 3, 'afl_var_dump' => self::SERIALIZED_VH ] + self::$aflRow, + ]; + $this->db->insert( 'abuse_filter_log', array_values( $insertRows ), __METHOD__ ); + $expected = [ + 'abuse_filter_log' => [ + [ 'afl_id' => 1, 'afl_var_dump' => 'tt:1' ], + [ 'afl_id' => 2, 'afl_var_dump' => 'tt:2' ], + [ 'afl_id' => 3, 'afl_var_dump' => 'tt:3' ], + ], + 'text' => [ + [ 'old_id' => 1, 'old_text' => $expectedTruncated ], + [ 'old_id' => 2, 'old_text' => FormatJson::encode( self::VARS ) ], + [ 'old_id' => 3, 'old_text' => FormatJson::encode( self::VARS ) ], + ] + ]; + return $expected; + } + + /** + * @return TestingAccessWrapper|UpdateVarDumps + */ + private function getMaintenanceWithoutExit() { + // We first need to mock UpdateVarDumps, because fatalError kills PHP. + $maint = $this->getMockBuilder( UpdateVarDumps::class ) + ->setMethods( [ 'fatalError' ] ) + ->getMock(); + $maint->method( 'fatalError' )->willThrowException( new LogicException() ); + // Then use an access wrapper to call private methods. + $wrapper = TestingAccessWrapper::newFromObject( $maint ); + $wrapper->allRowsCount = 50; + $wrapper->dbr = $wrapper->dbw = $this->db; + return $wrapper; + } + + /** + * @param array $row + * @dataProvider provideMoveToTextUnexpectedTypes + * @covers ::doMoveToText + */ + public function testMoveToTextUnexpectedTypes( array $row ) { + $this->db->insert( 'abuse_filter_log', $row, __METHOD__ ); + $maint = $this->getMaintenanceWithoutExit(); + $this->expectException( LogicException::class ); + $maint->moveToText(); + } + + /** + * @return array + */ + public function provideMoveToTextUnexpectedTypes() { + return [ + 'Truncated obj' => [ + [ 'afl_id' => 1, 'afl_var_dump' => substr( self::SERIALIZED_VH, 0, -5 ) ] + self::$aflRow + ], + 'Wrong type' => [ + [ 'afl_id' => 3, 'afl_var_dump' => serialize( 'foo bar baz' ) ] + self::$aflRow + ] + ]; + } + + /** + * @param string $str + * @param array $expected + * @covers UpdateVarDumps::restoreTruncatedDump + * @dataProvider provideTruncatedDump + */ + public function testRestoreTruncatedDump( string $str, array $expected ) { + $this->assertSame( $expected, $this->maintenance->restoreTruncatedDump( $str ) ); + } + + /** + * @return array + */ + public function provideTruncatedDump() { + $serialized = serialize( self::VARS ); + $varsWithoutKeys = function ( ...$keys ) { + return array_diff_key( self::VARS, array_fill_keys( $keys, 1 ) ); + }; + return [ + [ substr( $serialized, 0, -1 ), $varsWithoutKeys( 'user_groups' ) ], + [ substr( $serialized, 0, -7 ), $varsWithoutKeys( 'user_groups' ) ], + [ substr( $serialized, 0, -16 ), $varsWithoutKeys( 'user_groups' ) ], + [ substr( $serialized, 0, -32 ), $varsWithoutKeys( 'user_groups' ) ], + [ substr( $serialized, 0, -46 ), $varsWithoutKeys( 'user_groups' ) ], + [ substr( $serialized, 0, -56 ), $varsWithoutKeys( 'user_groups', 'accountname' ) ], + [ + substr( $serialized, 0, -72 ), + $varsWithoutKeys( 'user_groups', 'accountname', 'user_blocked' ) + ], + [ + substr( $serialized, 0, -96 ), + $varsWithoutKeys( 'user_groups', 'accountname', 'user_blocked', 'page_id' ) + ], + [ substr( $serialized, 0, 17 ), [] ], + [ substr( $serialized, 0, 10 ), [] ], + [ substr( $serialized, 0, 5 ), [] ], + ]; + } + + /** + * @covers ::updateText + * @covers ::doUpdateText + */ + public function testUpdateText() { + $expected = $this->insertUpdateText(); + $this->maintenance->updateText(); + $rows = $this->selectAllAscending( 'text' ); + $actual = []; + foreach ( $rows as $row ) { + $actual[] = [ + 'old_id' => (int)$row->old_id, + 'old_flags' => $row->old_flags, + 'old_text' => $row->old_text + ]; + } + $this->assertSame( $expected, $actual ); + } + + /** + * @return array Expected content of the text table + */ + private function insertUpdateText() { + $serializedArr = serialize( self::VARS ); + $jsonArr = FormatJson::encode( self::VARS ); + + $textRows = [ + 'Serialized VH' => [ 'old_text' => self::SERIALIZED_VH ] + self::TEXT_ROW, + 'Serialized array' => + [ 'old_text' => $serializedArr, 'old_flags' => 'nativeDataArray' ] + self::TEXT_ROW, + 'JSON array' => [ 'old_text' => $jsonArr, 'old_flags' => 'utf-8' ] + self::TEXT_ROW, + ]; + $this->db->insert( 'text', array_values( $textRows ), __METHOD__ ); + + $pointerRows = [ + [ 'afl_var_dump' => 'stored-text:1' ] + self::$aflRow, + [ 'afl_var_dump' => 'stored-text:2' ] + self::$aflRow, + [ 'afl_var_dump' => 'stored-text:3' ] + self::$aflRow, + ]; + $this->db->insert( 'abuse_filter_log', $pointerRows, __METHOD__ ); + + return [ + [ 'old_id' => 1, 'old_flags' => 'utf-8', 'old_text' => $jsonArr ], + [ 'old_id' => 2, 'old_flags' => 'utf-8', 'old_text' => $jsonArr ], + [ 'old_id' => 3, 'old_flags' => 'utf-8', 'old_text' => $jsonArr ], + ]; + } + + /** + * @covers ::doUpdateText + */ + public function testUpdateTextWrongFlags() { + $jsonArr = FormatJson::encode( self::VARS ); + $textRow = [ 'old_id' => 1, 'old_flags' => 'nativeDataArray,utf-8', 'old_text' => $jsonArr ]; + $this->db->insert( 'text', $textRow, __METHOD__ ); + + $pointerRow = [ 'afl_var_dump' => 'stored-text:1' ] + self::$aflRow; + $this->db->insert( 'abuse_filter_log', $pointerRow, __METHOD__ ); + + $maint = $this->getMaintenanceWithoutExit(); + $this->expectException( LogicException::class ); + $maint->updateText(); + } + + /** + * @covers ::updateAflVarDump + */ + public function testUpdateAflVarDump() { + $this->insertAflVarDump(); + $this->maintenance->updateAflVarDump(); + $vals = $this->db->selectFieldValues( 'abuse_filter_log', 'afl_var_dump' ); + + $this->assertSame( [ 'tt:123' ], array_unique( $vals ) ); + } + + private function insertAflVarDump() { + $rows = [ + 'Old prefix' => [ 'afl_var_dump' => 'stored-text:123' ] + self::$aflRow, + 'New prefix' => [ 'afl_var_dump' => 'tt:123' ] + self::$aflRow + ]; + $this->db->insert( 'abuse_filter_log', array_values( $rows ), __METHOD__ ); + } + + /** + * @param array $old + * @param array $expected + * @covers UpdateVarDumps::updateVariables + * @dataProvider provideUpdateVariables + */ + public function testUpdateVariables( array $old, array $expected ) { + $this->assertSame( $expected, $this->maintenance->updateVariables( $old ) ); + } + + /** + * @return array + */ + public function provideUpdateVariables() { + return [ + 'Fine' => [ self::VARS, self::VARS ], + 'Meta-variable' => [ [ 'action' => 'edit', 'context' => 'foo' ], [ 'action' => 'edit' ] ], + 'Uppercase' => [ [ 'USER_GROUPS' => [ 'bot' ] ], [ 'user_groups' => [ 'bot' ] ] ], + 'Deprecated' => [ + [ 'article_text' => 'foo', 'moved_to_prefixedtext' => 'bar' ], + [ 'page_title' => 'foo', 'moved_to_prefixedtitle' => 'bar' ] + ], + 'Mixed' => [ + [ 'ARTICLE_ARTICLEID' => 1, 'logged_local_ids' => [ 1, 2, 3 ], 'OLD_HTML' => '' ], + [ 'page_id' => 1, 'old_html' => '' ] + ] + ]; + } +} diff --git a/AbuseFilter/tests/phpunit/unit/AFPDataTest.php b/AbuseFilter/tests/phpunit/unit/AFPDataTest.php new file mode 100644 index 00000000..c0b0c008 --- /dev/null +++ b/AbuseFilter/tests/phpunit/unit/AFPDataTest.php @@ -0,0 +1,320 @@ +<?php +/** + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * + * @license GPL-2.0-or-later + */ + +/** + * @group Test + * @group AbuseFilter + * @group AbuseFilterParser + */ +class AFPDataTest extends AbuseFilterParserTestCase { + /** + * Test the 'dividebyzero' exception + * + * @param string $expr The expression to test + * @param string $caller The function where the exception is thrown + * @covers AFPData::mulRel + * @covers AbuseFilterParser + * @covers AbuseFilterCachingParser + * @covers AFPTreeParser + * + * @dataProvider divideByZero + */ + public function testDivideByZeroException( $expr, $caller ) { + $this->exceptionTest( 'dividebyzero', $expr, $caller ); + $this->exceptionTestInSkippedBlock( 'dividebyzero', $expr, $caller ); + } + + /** + * Data provider for testDivideByZeroException + * The second parameter is the function where the exception is raised. + * One expression for each throw. + * + * @return array + */ + public function divideByZero() { + return [ + [ '1/0', 'mulRel' ], + [ '1/0.0', 'mulRel' ], + [ '1/(-0.0)', 'mulRel' ], + [ '1%0', 'mulRel' ], + [ '1%0.0', 'mulRel' ], + [ '1%0.3', 'mulRel' ], + [ '1%(-0.7)', 'mulRel' ], + 'DUNDEFINED numerator 1' => [ 'timestamp % 0', 'mulRel' ], + 'DUNDEFINED numerator 2' => [ 'timestamp / 0.0', 'mulRel' ], + ]; + } + + /** + * @param mixed $raw + * @param AFPData|null $expected If null, we expect an exception due to unsupported data type + * @covers AFPData::newFromPHPVar + * @dataProvider providePHPVars + */ + public function testNewFromPHPVar( $raw, $expected ) { + if ( $expected === null ) { + $this->expectException( AFPException::class ); + } + $this->assertEquals( $expected, AFPData::newFromPHPVar( $raw ) ); + } + + /** + * Data provider for testNewFromPHPVar + * + * @return array + */ + public function providePHPVars() { + return [ + [ 15, new AFPData( AFPData::DINT, 15 ) ], + [ '42', new AFPData( AFPData::DSTRING, '42' ) ], + [ 0.123, new AFPData( AFPData::DFLOAT, 0.123 ) ], + [ false, new AFPData( AFPData::DBOOL, false ) ], + [ true, new AFPData( AFPData::DBOOL, true ) ], + [ null, new AFPData( AFPData::DNULL ) ], + [ + [ 1, 'foo', [], [ null ], false ], + new AFPData( AFPData::DARRAY, [ + new AFPData( AFPData::DINT, 1 ), + new AFPData( AFPData::DSTRING, 'foo' ), + new AFPData( AFPData::DARRAY, [] ), + new AFPData( AFPData::DARRAY, [ new AFPData( AFPData::DNULL ) ] ), + new AFPData( AFPData::DBOOL, false ) + ] ) + ], + // Invalid data types + [ new stdClass, null ], + [ new AFPData( AFPData::DUNDEFINED ), null ] + ]; + } + + /** + * Test casts to null and to arrays, for which we don't expose any method for use in actual + * filters. Other casts are already covered in parserTests. + * + * @param AFPData $orig + * @param string $newType One of the AFPData::D* constants + * @param AFPData|null $expected If null, we expect an exception due to unsupported data type + * @covers AFPData::castTypes + * @dataProvider provideMissingCastTypes + */ + public function testMissingCastTypes( $orig, $newType, $expected ) { + if ( $expected === null ) { + $this->expectException( AFPException::class ); + } + $this->assertEquals( $expected, AFPData::castTypes( $orig, $newType ) ); + } + + /** + * Data provider for testMissingCastTypes + * + * @return array + */ + public function provideMissingCastTypes() { + return [ + [ new AFPData( AFPData::DINT, 1 ), AFPData::DNULL, new AFPData( AFPData::DNULL ) ], + [ new AFPData( AFPData::DBOOL, false ), AFPData::DNULL, new AFPData( AFPData::DNULL ) ], + [ new AFPData( AFPData::DSTRING, 'foo' ), AFPData::DNULL, new AFPData( AFPData::DNULL ) ], + [ new AFPData( AFPData::DFLOAT, 3.14 ), AFPData::DNULL, new AFPData( AFPData::DNULL ) ], + [ + new AFPData( AFPData::DARRAY, [ + new AFPData( AFPData::DSTRING, 'foo' ), + new AFPData( AFPData::DNULL ) + ] ), + AFPData::DNULL, + new AFPData( AFPData::DNULL ) + ], + [ + new AFPData( AFPData::DINT, 1 ), + AFPData::DARRAY, + new AFPData( AFPData::DARRAY, [ new AFPData( AFPData::DINT, 1 ) ] ) + ], + [ + new AFPData( AFPData::DBOOL, false ), + AFPData::DARRAY, + new AFPData( AFPData::DARRAY, [ new AFPData( AFPData::DBOOL, false ) ] ) + ], + [ + new AFPData( AFPData::DSTRING, 'foo' ), + AFPData::DARRAY, + new AFPData( AFPData::DARRAY, [ new AFPData( AFPData::DSTRING, 'foo' ) ] ) + ], + [ + new AFPData( AFPData::DFLOAT, 3.14 ), + AFPData::DARRAY, + new AFPData( AFPData::DARRAY, [ new AFPData( AFPData::DFLOAT, 3.14 ) ] ) + ], + [ + new AFPData( AFPData::DNULL ), + AFPData::DARRAY, + new AFPData( AFPData::DARRAY, [ new AFPData( AFPData::DNULL ) ] ) + ], + [ new AFPData( AFPData::DSTRING, 'foo' ), 'foobaz', null ], + [ new AFPData( AFPData::DNULL ), null, null ] + ]; + } + + /** + * @param AFPData $orig + * @param mixed $expected + * @covers AFPData::toNative + * @dataProvider provideToNative + */ + public function testToNative( $orig, $expected ) { + $this->assertEquals( $expected, $orig->toNative() ); + } + + /** + * Data provider for testToNative + * + * @return array + */ + public function provideToNative() { + return [ + [ new AFPData( AFPData::DFLOAT, 1.2345 ), 1.2345 ], + [ new AFPData( AFPData::DFLOAT, 0.1 ), 0.1 ], + [ new AFPData( AFPData::DUNDEFINED ), null ], + [ new AFPData( AFPData::DNULL, null ), null ], + [ new AFPData( AFPData::DBOOL, false ), false ], + [ new AFPData( AFPData::DSTRING, '12' ), '12' ], + [ new AFPData( AFPData::DINT, 123 ), 123 ], + [ + new AFPData( + AFPData::DARRAY, + [ new AFPData( AFPData::DSTRING, 'foo' ), new AFPData( AFPData::DBOOL, true ) ] + ), + [ 'foo', true ] + ], + ]; + } + + /** + * Ensure that we don't allow DUNDEFINED in AFPData::equals + * + * @param AFPData $lhs + * @param AFPData $rhs + * @dataProvider provideDUNDEFINEDEquals + * + * @covers AFPData::equals + */ + public function testNoDUNDEFINEDEquals( $lhs, $rhs ) { + $this->expectException( AFPException::class ); + $lhs->equals( $rhs ); + } + + /** + * Data provider for testNoDUNDEFINEDEquals + * + * @return array + */ + public function provideDUNDEFINEDEquals() { + $undefined = new AFPData( AFPData::DUNDEFINED ); + $nonempty = new AFPData( AFPData::DSTRING, 'foo' ); + return [ + 'left' => [ $undefined, $nonempty ], + 'right' => [ $nonempty, $undefined ], + 'both' => [ $undefined, $undefined ] + ]; + } + + /** + * Test that DUNDEFINED can only have null value + * + * @covers AFPData::__construct + */ + public function testDUNDEFINEDRequiresNullValue() { + $this->expectException( InvalidArgumentException::class ); + new AFPData( AFPData::DUNDEFINED, 'non-null' ); + } + + /** + * Test that casting DUNDEFINED to something else is forbidden + * + * @covers AFPData::castTypes + */ + public function testDUNDEFINEDCannotBeCast() { + $data = new AFPData( AFPData::DUNDEFINED ); + $this->expectException( AFPException::class ); + $this->expectExceptionMessage( 'Refusing to cast' ); + AFPData::castTypes( $data, AFPData::DNULL ); + } + + /** + * @param AFPData $obj + * @param bool $expected + * @covers AFPData::hasUndefined + * @dataProvider provideHasUndefined + */ + public function testHasUndefined( AFPData $obj, bool $expected ) { + $this->assertSame( $expected, $obj->hasUndefined() ); + } + + /** + * Provider for testHasUndefined + */ + public function provideHasUndefined() { + return [ + [ new AFPData( AFPData::DUNDEFINED ), true ], + [ new AFPData( AFPData::DNULL ), false ], + [ new AFPData( AFPData::DSTRING, '' ), false ], + [ new AFPData( AFPData::DARRAY, [ new AFPData( AFPData::DUNDEFINED ) ] ), true ], + [ new AFPData( AFPData::DARRAY, [ new AFPData( AFPData::DNULL ) ] ), false ], + ]; + } + + /** + * @param AFPData $obj + * @param AFPData $expected + * @covers AFPData::cloneAsUndefinedReplacedWithNull + * @dataProvider provideCloneAsUndefinedReplacedWithNull + */ + public function testCloneAsUndefinedReplacedWithNull( AFPData $obj, AFPData $expected ) { + $this->assertEquals( $expected, $obj->cloneAsUndefinedReplacedWithNull() ); + } + + /** + * Provider for testHasUndefined + */ + public function provideCloneAsUndefinedReplacedWithNull() { + return [ + [ + new AFPData( AFPData::DUNDEFINED ), + new AFPData( AFPData::DNULL ) + ], + [ + new AFPData( AFPData::DNULL ), + new AFPData( AFPData::DNULL ) + ], + [ + new AFPData( AFPData::DSTRING, '' ), + new AFPData( AFPData::DSTRING, '' ) + ], + [ + new AFPData( AFPData::DARRAY, [ new AFPData( AFPData::DUNDEFINED ) ] ), + new AFPData( AFPData::DARRAY, [ new AFPData( AFPData::DNULL ) ] ) + ], + [ + new AFPData( AFPData::DARRAY, [ new AFPData( AFPData::DNULL ) ] ), + new AFPData( AFPData::DARRAY, [ new AFPData( AFPData::DNULL ) ] ) + ], + ]; + } +} diff --git a/AbuseFilter/tests/phpunit/unit/AbuseFilterKeywordsManagerTest.php b/AbuseFilter/tests/phpunit/unit/AbuseFilterKeywordsManagerTest.php new file mode 100644 index 00000000..cff5be8c --- /dev/null +++ b/AbuseFilter/tests/phpunit/unit/AbuseFilterKeywordsManagerTest.php @@ -0,0 +1,198 @@ +<?php + +use MediaWiki\Extension\AbuseFilter\Hooks\AbuseFilterHookRunner; +use MediaWiki\Extension\AbuseFilter\KeywordsManager; + +/** + * @group Test + * @group AbuseFilter + * @group AbuseFilterParser + */ +class AbuseFilterKeywordsManagerTest extends MediaWikiUnitTestCase { + /** + * Convenience wrapper + * @return KeywordsManager + */ + private function getKeywordsManager() : KeywordsManager { + return new KeywordsManager( $this->createMock( AbuseFilterHookRunner::class ) ); + } + + /** + * @covers \MediaWiki\Extension\AbuseFilter\KeywordsManager::getDisabledVariables + */ + public function testGetDisabledVariables() { + $actual = $this->getKeywordsManager()->getDisabledVariables(); + // Value should be an associative array mapping var names to i18n strings + $this->assertIsArray( $actual ); + $this->assertContainsOnly( 'string', $actual, true ); + $this->assertContainsOnly( 'string', array_keys( $actual ), true ); + } + + /** + * @covers \MediaWiki\Extension\AbuseFilter\KeywordsManager::getDeprecatedVariables + */ + public function testGetDeprecatedVariables() { + $actual = $this->getKeywordsManager()->getDisabledVariables(); + // Value should be an associative array mapping old names to new names + $this->assertIsArray( $actual ); + $this->assertContainsOnly( 'string', $actual, true ); + $this->assertContainsOnly( 'string', array_keys( $actual ), true ); + } + + /** + * @covers \MediaWiki\Extension\AbuseFilter\KeywordsManager::getDeprecatedVariables + */ + public function testGetDeprecatedVariables_hook() { + $oldVarName = 'foobardeprecated'; + $newVarName = 'foobarpleaseuseme'; + $runner = $this->createMock( AbuseFilterHookRunner::class ); + $runner->method( 'onAbuseFilterDeprecatedVariables' ) + ->willReturnCallback( function ( &$val ) use ( $oldVarName, $newVarName ) { + $val[$oldVarName] = $newVarName; + } ); + $actual = ( new KeywordsManager( $runner ) )->getDeprecatedVariables(); + $this->assertArrayHasKey( $oldVarName, $actual ); + $this->assertSame( $newVarName, $actual[$oldVarName] ); + } + + /** + * @covers \MediaWiki\Extension\AbuseFilter\KeywordsManager::getBuilderValues + */ + public function testGetBuilderValues() { + $actual = $this->getKeywordsManager()->getBuilderValues(); + // Value should be an associative array mapping old names to new names + $this->assertIsArray( $actual ); + $this->assertContainsOnly( 'array', $actual, true ); + foreach ( $actual as $name => $section ) { + $this->assertIsString( $name ); + $this->assertContainsOnly( 'string', $section, true, "Section $name" ); + $this->assertContainsOnly( 'string', array_keys( $section ), true, "Section $name" ); + } + } + + /** + * @covers \MediaWiki\Extension\AbuseFilter\KeywordsManager::getBuilderValues + */ + public function testGetBuilderValues_hook() { + $varName = 'magic_stuff'; + $varMessage = 'magic-stuff'; + $runner = $this->createMock( AbuseFilterHookRunner::class ); + $runner->method( 'onAbuseFilterBuilder' ) + ->willReturnCallback( function ( &$val ) use ( $varName, $varMessage ) { + $val['vars'][$varName] = $varMessage; + } ); + $actual = ( new KeywordsManager( $runner ) )->getBuilderValues(); + $this->assertArrayHasKey( 'vars', $actual ); + $this->assertArrayHasKey( $varName, $actual['vars'] ); + $this->assertSame( $varMessage, $actual['vars'][$varName] ); + } + + /** + * @param string $varName + * @param bool $expected + * @covers \MediaWiki\Extension\AbuseFilter\KeywordsManager::isVarDisabled + * @dataProvider provideIsVarDisabled + */ + public function testIsVarDisabled( string $varName, bool $expected ) { + $km = $this->getKeywordsManager(); + $this->assertSame( $expected, $km->isVarDisabled( $varName ) ); + } + + /** + * @return array[] + */ + public function provideIsVarDisabled() { + return [ + 'disabled' => [ 'old_text', true ], + 'deprecated' => [ 'article_text', false ], + 'unknown' => [ 'vnaioygbaeuioryvvbrra', false ] + ]; + } + + /** + * @param string $varName + * @param bool $expected + * @covers \MediaWiki\Extension\AbuseFilter\KeywordsManager::isVarDeprecated + * @dataProvider provideIsVarDeprecated + */ + public function testIsVarDeprecated( string $varName, bool $expected ) { + $km = $this->getKeywordsManager(); + $this->assertSame( $expected, $km->isVarDeprecated( $varName ) ); + } + + /** + * @return array[] + */ + public function provideIsVarDeprecated() { + return [ + 'disabled' => [ 'old_text', false ], + 'deprecated' => [ 'article_text', true ], + 'unknown' => [ 'vnaioygbaeuioryvvbrra', false ] + ]; + } + + /** + * @covers \MediaWiki\Extension\AbuseFilter\KeywordsManager::isVarInUse + */ + public function testIsVarInUse() { + // Add a new variable to avoid relying on what's currently valid + $varName = 'my_new_var'; + $runner = $this->createMock( AbuseFilterHookRunner::class ); + $runner->method( 'onAbuseFilterBuilder' ) + ->willReturnCallback( function ( &$val ) use ( $varName ) { + $val['vars'][$varName] = 'some-message'; + } ); + $km = new KeywordsManager( $runner ); + $this->assertTrue( $km->isVarInUse( $varName ) ); + } + + /** + * @param string $varName + * @param bool $expected + * @covers \MediaWiki\Extension\AbuseFilter\KeywordsManager::varExists + * @dataProvider provideVarExists + */ + public function testVarExists( string $varName, bool $expected ) { + $km = $this->getKeywordsManager(); + $this->assertSame( $expected, $km->varExists( $varName ) ); + } + + /** + * @param string $varName + * @param bool $exists + * @covers \MediaWiki\Extension\AbuseFilter\KeywordsManager::getMessageKeyForVar + * @dataProvider provideVarExists + */ + public function testGetMessageKeyForVar( string $varName, bool $exists ) { + $km = $this->getKeywordsManager(); + if ( $exists ) { + $val = $km->getMessageKeyForVar( $varName ); + $this->assertIsString( $val ); + $this->assertStringContainsString( 'abusefilter-edit-builder-vars', $val ); + } else { + $this->assertNull( $km->getMessageKeyForVar( $varName ) ); + } + } + + /** + * @return array[] + */ + public function provideVarExists() { + return [ + 'disabled' => [ 'old_text', true ], + 'deprecated' => [ 'article_text', true ], + 'unknown' => [ 'vnaioygbaeuioryvvbrra', false ] + ]; + } + + /** + * @covers \MediaWiki\Extension\AbuseFilter\KeywordsManager::getVarsMappings + */ + public function testGetVarsMappings() { + $actual = $this->getKeywordsManager()->getVarsMappings(); + // Value should be an associative array mapping var names to i18n strings + $this->assertIsArray( $actual ); + $this->assertContainsOnly( 'string', $actual, true ); + $this->assertContainsOnly( 'string', array_keys( $actual ), true ); + } +} diff --git a/AbuseFilter/tests/phpunit/unit/AbuseFilterParserTest.php b/AbuseFilter/tests/phpunit/unit/AbuseFilterParserTest.php new file mode 100644 index 00000000..4449852b --- /dev/null +++ b/AbuseFilter/tests/phpunit/unit/AbuseFilterParserTest.php @@ -0,0 +1,1374 @@ +<?php +/** + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * + * @license GPL-2.0-or-later + * @author Marius Hoch < hoo@online.de > + */ + +use MediaWiki\Extension\AbuseFilter\Hooks\AbuseFilterHookRunner; +use MediaWiki\Extension\AbuseFilter\KeywordsManager; +use Psr\Log\NullLogger; +use Wikimedia\TestingAccessWrapper; + +/** + * @group Test + * @group AbuseFilter + * @group AbuseFilterParser + * + * @covers AbuseFilterCachingParser + * @covers AFPTreeParser + * @covers AFPTransitionBase + * @covers AFPTreeNode + * @covers AFPSyntaxTree + * @covers AFPParserState + * @covers AbuseFilterParser + * @covers AbuseFilterTokenizer + * @covers AFPToken + * @covers AFPUserVisibleException + * @covers AFPException + * @covers AFPData + * @covers AFComputedVariable + */ +class AbuseFilterParserTest extends AbuseFilterParserTestCase { + /** + * @param string $rule The rule to parse + * @dataProvider readTests + */ + public function testParser( $rule ) { + foreach ( $this->getParsers() as $parser ) { + $this->assertTrue( $parser->parse( $rule ), 'Parser used: ' . get_class( $parser ) ); + } + } + + /** + * @return Generator|array + */ + public function readTests() { + $testPath = __DIR__ . "/../../parserTests"; + $testFiles = glob( $testPath . "/*.t" ); + + foreach ( $testFiles as $testFile ) { + $testName = basename( substr( $testFile, 0, -2 ) ); + $rule = trim( file_get_contents( $testFile ) ); + + yield $testName => [ $rule ]; + } + } + + /** + * Test expression evaluation + * + * @param string $expr The expression to evaluate + * @param string $expected The expected result + * @dataProvider provideExpressions + */ + public function testEvaluateExpression( $expr, $expected ) { + foreach ( $this->getParsers() as $parser ) { + $actual = $parser->evaluateExpression( $expr ); + $this->assertEquals( $expected, $actual ); + } + } + + /** + * Data provider for testEvaluateExpression + * + * @return array + */ + public function provideExpressions() { + return [ + [ '1 === 1', true ], + [ 'rescape( "abc* (def)" )', 'abc\* \(def\)' ], + [ 'str_replace( "foobarbaz", "bar", "-" )', 'foo-baz' ], + [ 'rmdoubles( "foobybboo" )', 'fobybo' ], + [ 'lcase("FÁmí")', 'fámí' ], + [ 'substr( "foobar", 0, 3 )', 'foo' ] + ]; + } + + /** + * Test empty (or almost empty) syntax and ensure it doesn't match + * + * @param string $code + * @dataProvider provideEmptySyntax + */ + public function testEmptySyntax( $code ) { + foreach ( $this->getParsers() as $parser ) { + $this->assertFalse( $parser->parse( $code ) ); + } + } + + /** + * Data provider for testEmptySyntax + * + * @return array + */ + public function provideEmptySyntax() { + return [ + [ '' ], + [ ';;;;' ] + ]; + } + + /** + * Test a filter only containing a pair of empty parentheses. In the old parser, this should simply + * return false. In the new parser, it will throw. + */ + public function testEmptyParenthesisOnly() { + $code = '()'; + $constrArgs = [ + $this->getLanguageMock(), + new EmptyBagOStuff(), + new NullLogger(), + new KeywordsManager( $this->createMock( AbuseFilterHookRunner::class ) ) + ]; + + $parser = new AbuseFilterParser( ...$constrArgs ); + $this->assertFalse( $parser->parse( $code ) ); + $cachingParser = new AbuseFilterCachingParser( ...$constrArgs ); + $this->expectException( AFPUserVisibleException::class ); + $this->expectExceptionMessage( 'unexpectedtoken' ); + $cachingParser->parse( $code ); + } + + /** + * Ensure that AbuseFilterTokenizer::OPERATOR_RE matches the contents + * and order of AbuseFilterTokenizer::$operators. + */ + public function testOperatorRe() { + $quotedOps = array_map( + function ( $op ) { + return preg_quote( $op, '/' ); + }, + AbuseFilterTokenizer::OPERATORS + ); + $operatorRe = '/(' . implode( '|', $quotedOps ) . ')/A'; + $this->assertEquals( $operatorRe, AbuseFilterTokenizer::OPERATOR_RE ); + } + + /** + * Ensure the number of conditions counted for given expressions is right. + * + * @param string $rule The rule to parse + * @param int $expected The expected amount of used conditions + * @dataProvider condCountCases + */ + public function testCondCount( $rule, $expected ) { + foreach ( $this->getParsers() as $parser ) { + $parserClass = get_class( $parser ); + $countBefore = $parser->getCondCount(); + $parser->parse( $rule ); + $countAfter = $parser->getCondCount(); + $actual = $countAfter - $countBefore; + $this->assertEquals( $expected, $actual, "Wrong condition count for $rule with $parserClass" ); + } + } + + /** + * Data provider for testCondCount method. + * @return array + */ + public function condCountCases() { + return [ + [ '((("a" == "b")))', 1 ], + [ 'contains_any("a", "b", "c")', 1 ], + [ '"a" == "b" & "b" == "c"', 1 ], + [ '"a" == "b" | "b" == "c"', 2 ], + [ '"a" in "b" + "c" in "d" + "e" in "f"', 3 ], + [ 'true', 0 ], + [ '"a" == "a" | "c" == "d"', 1 ], + [ '"a" == "b" & "c" == "d"', 1 ], + [ '1 = 0 & 2 * 3 * 4 <= 560 & "a" = "b"', 1 ], + [ '1 = 1 & 2 * 3 * 4 <= 560 & "a" = "b"', 3 ], + [ '1 = 1 | 2 * 3 * 4 <= 560 | "a" = "b"', 1 ], + [ '1 = 0 | 2 * 3 * 4 <= 560 | "a" = "b"', 2 ], + ]; + } + + /** + * Test for T204841 + */ + public function testArrayShortcircuit() { + $code = 'a := [false, false]; b := [false, false]; c := 42; d := [0,1];' . + 'a[0] != false & b[1] != false & (b[5**2/(5*(4+1))] !== a[43-c] | a[d[0]] === b[d[c-41]])'; + foreach ( $this->getParsers() as $parser ) { + $this->assertFalse( $parser->parse( $code ), 'Parser: ' . get_class( $parser ) ); + } + } + + /** + * Test the 'expectednotfound' exception + * + * @param string $expr The expression to test + * @param string $caller The function where the exception is thrown + * @dataProvider expectedNotFound + */ + public function testExpectedNotFoundException( $expr, $caller ) { + $this->exceptionTest( 'expectednotfound', $expr, $caller ); + $this->exceptionTestInSkippedBlock( 'expectednotfound', $expr, $caller ); + } + + /** + * Data provider for testExpectedNotFoundException. + * The second parameter is the function where the exception is raised. + * One expression for each throw. + * + * @return array + */ + public function expectedNotFound() { + return [ + [ 'a:= [1,2,3]; a[1 = 4', 'doLevelSet' ], + [ "if 1 = 1 'foo'", 'doLevelConditions' ], + [ "if 1 = 1 then 'foo'", 'doLevelConditions' ], + [ "if 1 = 1 then 'foo' else 'bar'", 'doLevelConditions' ], + [ "a := 1 = 1 ? 'foo'", 'doLevelConditions' ], + [ '(1 = 1', 'doLevelBraces' ], + [ 'lcase = 3', 'doLevelFunction' ], + [ 'lcase( 3 = 1', 'doLevelFunction' ], + [ 'a := [1,2', 'doLevelAtom' ], + [ '1 = 1 | (1', 'skipOverBraces/doLevelParenthesis' ], + [ 'a := [1,2,3]; 3 = a[5', 'doLevelArrayElements' ], + [ 'if[3] := 1', 'doLevelConditions' ], + ]; + } + + /** + * Test the 'unexpectedatend' exception + * + * @param string $expr The expression to test + * @param string $caller The function where the exception is thrown + * @dataProvider unexpectedAtEnd + */ + public function testUnexpectedAtEndException( $expr, $caller ) { + $this->exceptionTest( 'unexpectedatend', $expr, $caller ); + $this->exceptionTestInSkippedBlock( 'unexpectedatend', $expr, $caller ); + } + + /** + * Data provider for testUnexpectedAtEndException + * The second parameter is the function where the exception is raised. + * One expression for each throw. + * + * @return array + */ + public function unexpectedAtEnd() { + return [ + [ "'a' = 1 )", 'doLevelEntry' ], + ]; + } + + /** + * Test the 'unrecognisedvar' exception + * + * @param string $expr The expression to test + * @param string $caller The function where the exception is thrown + * @dataProvider unrecognisedVar + */ + public function testUnrecognisedVarException( $expr, $caller ) { + $this->exceptionTest( 'unrecognisedvar', $expr, $caller ); + $this->exceptionTestInSkippedBlock( 'unrecognisedvar', $expr, $caller ); + } + + /** + * Data provider for testUnrecognisedVarException + * The second parameter is the function where the exception is raised. + * One expression for each throw. + * + * @return array + */ + public function unrecognisedVar() { + return [ + [ 'a[1] := 5', 'getVarValue' ], + [ 'a[] := 5', 'getVarValue' ], + [ 'a = 5', 'getVarValue' ], + [ 'timestamp[a]', 'getVarValue' ], + [ 'x := []; x[a] := 1', 'getVarValue' ], + ]; + } + + /** + * Special case, cannot use exceptionTestInSkippedBlock because that calls checkSyntax + */ + public function testUnrecognisedArrayInSkippedBlock() { + $code = 'false & ( nonex[1] := 2 )'; + // Old parser only + $parser = $this->getParsers()[0]; + $this->expectException( AFPUserVisibleException::class ); + $this->expectExceptionMessage( 'unrecognisedvar' ); + $parser->parse( $code ); + } + + /** + * Test the 'notarray' exception + * + * @param string $expr The expression to test + * @param string $caller The function where the exception is thrown + * @dataProvider notArray + */ + public function testNotArrayException( $expr, $caller ) { + $this->exceptionTest( 'notarray', $expr, $caller ); + $this->exceptionTestInSkippedBlock( 'notarray', $expr, $caller ); + } + + /** + * Data provider for testNotArrayException + * The second parameter is the function where the exception is raised. + * One expression for each throw. + * + * @return array + */ + public function notArray() { + return [ + [ 'a := 5; a[1] = 5', 'doLevelSet' ], + [ 'a := 1; 3 = a[5]', 'doLevelArrayElements' ], + [ 'a := 2; a[] := 2', '[different callers]' ], + [ 'a := 3; a[3] := 5', '[different callers]' ] + ]; + } + + /** + * Test the 'outofbounds' exception + * + * @param string $expr The expression to test + * @param string $caller The function where the exception is thrown + * @dataProvider outOfBounds + */ + public function testOutOfBoundsException( $expr, $caller ) { + $this->exceptionTest( 'outofbounds', $expr, $caller ); + $this->exceptionTestInSkippedBlock( 'outofbounds', $expr, $caller ); + } + + /** + * Data provider for testOutOfBoundsException + * The second parameter is the function where the exception is raised. + * One expression for each throw. + * + * @return array + */ + public function outOfBounds() { + return [ + [ 'a := [2]; a[5] = 9', 'doLevelSet' ], + [ 'a := [1,2,3]; 3 = a[5]', 'doLevelArrayElements' ], + [ 'a := [1]; a[15] := 5', '[different callers]' ] + ]; + } + + /** + * Test the 'negativeindex' exception + * + * @param string $expr The expression to test + * @param string $caller The function where the exception is thrown + * @dataProvider negativeIndex + */ + public function testNegativeIndexException( $expr, $caller ) { + $this->exceptionTest( 'negativeindex', $expr, $caller ); + $this->exceptionTestInSkippedBlock( 'negativeindex', $expr, $caller ); + } + + /** + * Data provider for testNegativeIndexException + * The second parameter is the function where the exception is raised. + * One expression for each throw. + * + * @return array + */ + public function negativeIndex() { + return [ + [ '[0][-1]', '' ], + [ "x := ['foo']; x[-1]", '' ], + [ "x := ['foo']; x[-1] := 2; x[-1] == 2", '' ], + [ "x := ['foo']; x[-5] := 2;", '' ] + ]; + } + + /** + * Test the 'unrecognisedkeyword' exception + * + * @param string $expr The expression to test + * @param string $caller The function where the exception is thrown + * @dataProvider unrecognisedKeyword + */ + public function testUnrecognisedKeywordException( $expr, $caller ) { + $this->exceptionTest( 'unrecognisedkeyword', $expr, $caller ); + $this->exceptionTestInSkippedBlock( 'unrecognisedkeyword', $expr, $caller ); + } + + /** + * Data provider for testUnrecognisedKeywordException + * The second parameter is the function where the exception is raised. + * One expression for each throw. + * + * @return array + */ + public function unrecognisedKeyword() { + return [ + [ '5 = rlike', 'doLevelAtom' ], + [ 'then := 45', 'doLevelAtom' ], + ]; + } + + /** + * Test the 'unexpectedtoken' exception + * + * @param string $expr The expression to test + * @param string $caller The function where the exception is thrown + * @dataProvider unexpectedToken + */ + public function testUnexpectedTokenException( $expr, $caller ) { + $this->exceptionTest( 'unexpectedtoken', $expr, $caller ); + $this->exceptionTestInSkippedBlock( 'unexpectedtoken', $expr, $caller ); + } + + /** + * Data provider for testUnexpectedTokenException + * The second parameter is the function where the exception is raised. + * One expression for each throw. + * + * @return array + */ + public function unexpectedToken() { + return [ + [ '1 =? 1', 'doLevelAtom' ], + ]; + } + + /** + * Test the 'disabledvar' exception + * + * @param string $expr The expression to test + * @param string $caller The function where the exception is thrown + * @dataProvider disabledVar + */ + public function testDisabledVarException( $expr, $caller ) { + $this->exceptionTest( 'disabledvar', $expr, $caller ); + $this->exceptionTestInSkippedBlock( 'disabledvar', $expr, $caller ); + } + + /** + * Data provider for testDisabledVarException + * The second parameter is the function where the exception is raised. + * One expression for each throw. + * + * @return array + */ + public function disabledVar() { + return [ + [ 'old_text = 1', 'getVarValue' ], + ]; + } + + /** + * Test the 'variablevariable' exception + * + * @param string $expr The expression to test + * @param string $caller The function where the exception is thrown + * @dataProvider variableVariable + */ + public function testVariableVariableException( $expr, $caller ) { + $this->exceptionTest( 'variablevariable', $expr, $caller ); + $this->exceptionTestInSkippedBlock( 'variablevariable', $expr, $caller ); + } + + /** + * Data provider for testVariableVariableException + * The second parameter is the function where the exception is raised. + * One expression for each throw. + * + * @return array + */ + public function variableVariable() { + return [ + [ "set( 'x' + 'y', 1 )", 'doLevelFunction' ], + [ "set( 'x' + page_title, 1 )", 'doLevelFunction' ], + [ "set( page_title, 1 )", 'doLevelFunction' ], + [ "set( page_title + 'x' + ( page_namespace == 0 ? 'x' : 'y' )", 'doLevelFunction' ], + ]; + } + + /** + * Test the 'overridebuiltin' exception + * + * @param string $expr The expression to test + * @param string $caller The function where the exception is thrown + * @dataProvider overrideBuiltin + */ + public function testOverrideBuiltinException( $expr, $caller ) { + $this->exceptionTest( 'overridebuiltin', $expr, $caller ); + $this->exceptionTestInSkippedBlock( 'overridebuiltin', $expr, $caller ); + } + + /** + * Data provider for testOverrideBuiltinException + * The second parameter is the function where the exception is raised. + * One expression for each throw. + * + * @return array + */ + public function overrideBuiltin() { + return [ + [ 'added_lines := 1', 'setUserVariable' ], + [ 'added_lines[] := 1', 'doLevelSet' ], + [ 'added_lines[3] := 1', 'doLevelSet' ], + [ 'page_id[3] := 1', 'doLevelSet' ], + [ 'true | (added_lines := 1);','setUserVariable' ], + [ 'if(true) then 1 else (added_lines := 1) end;', 'setUserVariable' ], + [ 'length := 45', 'setUserVariable' ], + [ 'set("added_lines", 45)', 'setUserVariable' ], + [ 'set("length", 45)', 'setUserVariable' ], + [ 'set("true", true)', 'setUserVariable' ], + ]; + } + + /** + * Test for overriding a function name. The parsers cannot agree on this: the old parser + * will try to get the value of the variable before knowing that it's parsing an assignment, + * hence throwing unrecognisedvar. The new parser already knows it's an assignment and immediately + * throws an overridebuiltin (which is more correct). + * @todo Merge this into testOverrideBuiltin as soon as the old parser is deleted + */ + public function testOverrideFuncName() { + $code = 'contains_any[1] := "foo"'; + foreach ( $this->getParsers() as $parser ) { + $pname = get_class( $parser ); + $exc = $parser instanceof AbuseFilterCachingParser ? 'overridebuiltin' : 'unrecognisedvar'; + try { + $parser->parse( $code ); + } catch ( AFPException $e ) { + $this->assertEquals( $exc, $e->mExceptionID, "Wrong exception with parser $pname, got:\n$e" ); + continue; + } + $this->fail( "Exception $exc not thrown with parser $pname." ); + } + } + + /** + * Test the 'regexfailure' exception + * + * @param string $expr The expression to test + * @param string $caller The function where the exception is thrown + * @dataProvider regexFailure + */ + public function testRegexFailureException( $expr, $caller ) { + $this->exceptionTest( 'regexfailure', $expr, $caller ); + $this->exceptionTestInSkippedBlock( 'regexfailure', $expr, $caller ); + } + + /** + * Data provider for testRegexFailureException + * The second parameter is the function where the exception is raised. + * One expression for each throw. + * + * @return array + */ + public function regexFailure() { + return [ + [ "rcount('(','a')", 'funcRCount' ], + [ "get_matches('this (should fail', 'any haystack')", 'funcGetMatches' ], + [ "'a' rlike '('", 'keywordRegex' ], + ]; + } + + /** + * Test the 'invalidiprange' exception + * + * @param string $expr The expression to test + * @param string $caller The function where the exception is thrown + * @dataProvider invalidIPRange + */ + public function testInvalidIPRangeException( $expr, $caller ) { + $this->exceptionTest( 'invalidiprange', $expr, $caller ); + $this->exceptionTestInSkippedBlock( 'invalidiprange', $expr, $caller ); + } + + /** + * Data provider for testInvalidIPRangeException + * The second parameter is the function where the exception is raised. + * One expression for each throw. + * + * @return array + */ + public function invalidIPRange() { + return [ + [ "ip_in_range('0.0.0.0', 'lol')", 'funcIPInRange' ], + ]; + } + + /** + * Test functions which take exactly one parameters calling them + * without 0 params. They should throw a 'noparams' exception. + * + * @param string $func The function to test + * @dataProvider oneParamFuncs + */ + public function testNoParamsException( $func ) { + $this->exceptionTest( 'noparams', "$func()", 'checkArgCount' ); + $this->exceptionTestInSkippedBlock( 'noparams', "$func()", 'checkArgCount' ); + } + + /** + * Data provider for testNoParamsException, returns a list of + * functions taking a single parameter + * + * @return array + */ + public function oneParamFuncs() { + return [ + [ 'lcase' ], + [ 'ucase' ], + [ 'length' ], + [ 'strlen' ], + [ 'specialratio' ], + [ 'count' ], + [ 'rcount' ], + [ 'ccnorm' ], + [ 'sanitize' ], + [ 'rmspecials' ], + [ 'rmwhitespace' ], + [ 'rmdoubles' ], + [ 'norm' ], + [ 'rescape' ], + [ 'string' ], + [ 'int' ], + [ 'float' ], + [ 'bool' ], + ]; + } + + /** + * Test functions taking two parameters by providing only one. + * They should throw a 'notenoughargs' exception. + * + * @param string $func The function to test + * @dataProvider twoParamsFuncs + */ + public function testNotEnoughArgsExceptionTwo( $func ) { + // Nevermind if the argument can't be string since we check the amount + // of parameters before anything else. + $code = "$func('foo')"; + $this->exceptionTest( 'notenoughargs', $code, 'checkArgCount' ); + $this->exceptionTestInSkippedBlock( 'notenoughargs', $code, 'checkArgCount' ); + } + + /** + * Data provider for testNotEnoughArgsExceptionTwo, returns the list of + * functions taking two parameters. + * + * @return array + */ + public function twoParamsFuncs() { + return [ + [ 'get_matches' ], + [ 'ip_in_range' ], + [ 'contains_any' ], + [ 'contains_all' ], + [ 'ccnorm_contains_any' ], + [ 'ccnorm_contains_all' ], + [ 'equals_to_any' ], + [ 'substr' ], + [ 'strpos' ], + [ 'set_var' ], + ]; + } + + /** + * Test functions taking three parameters by providing only two. + * They should throw a 'notenoughargs' exception. + * + * @param string $func The function to test + * @dataProvider threeParamsFuncs + */ + public function testNotEnoughArgsExceptionThree( $func ) { + // Nevermind if the argument can't be string since we check the amount + // of parameters before anything else. + $code = "$func('foo', 'bar')"; + $this->exceptionTest( 'notenoughargs', $code, 'checkArgCount' ); + $this->exceptionTestInSkippedBlock( 'notenoughargs', $code, 'checkArgCount' ); + } + + /** + * Data provider for testNotEnoughArgsExceptionThree, returns the list of + * functions taking three parameters. + * + * @return array + */ + public function threeParamsFuncs() { + return [ + [ 'str_replace' ], + ]; + } + + /** + * @param string $code + * @dataProvider tooManyArgsFuncs + */ + public function testTooManyArgumentsException( $code ) { + $this->exceptionTest( 'toomanyargs', $code, 'checkArgCount' ); + $this->exceptionTestInSkippedBlock( 'toomanyargs', $code, 'checkArgCount' ); + } + + /** + * @return array + */ + public function tooManyArgsFuncs() { + return [ + [ "lcase( 'a', 'b' )" ], + [ "norm( 'a', 'b', 'c' )" ], + [ "count( 'a', 'b', 'c' )" ], + [ "ip_in_range( 'a', 'b', 'c' )" ], + [ "substr( 'a', 'b', 'c', 'd' )" ], + [ "str_replace( 'a', 'b', 'c', 'd', 'e' )" ], + ]; + } + + /** + * @param string $func + * @dataProvider variadicFuncs + */ + public function testVariadicFuncsArbitraryArgsAllowed( $func ) { + $argsList = str_repeat( ', "arg"', 50 ); + $code = "$func( 'arg' $argsList )"; + foreach ( self::getParsers() as $parser ) { + $pname = get_class( $parser ); + try { + $parser->parse( $code ); + $this->assertTrue( true ); + } catch ( AFPException $e ) { + $this->fail( "Got exception with parser $pname.\n$e" ); + } + } + } + + /** + * @return array + */ + public function variadicFuncs() { + return [ + [ 'contains_any' ], + [ 'contains_all' ], + [ 'equals_to_any' ], + ]; + } + + /** + * Check that calling a function with less arguments than required throws an exception + * when inside a skipped conditional branch. + * + * @param string $funcCode Code for a function call + * @param string $exceptionCode The ID of the expected exception + * @dataProvider provideFuncsForConditional + */ + public function testCheckArgCountInConditional( $funcCode, $exceptionCode ) { + $code = "if ( 1==1 ) then ( 1 ) else ( $funcCode ) end;"; + // AbuseFilterParser skips the parentheses altogether, so this is not supposed to work + $parser = new AbuseFilterCachingParser( + $this->getLanguageMock(), + new EmptyBagOStuff(), + new NullLogger(), + $this->createMock( KeywordsManager::class ) + ); + $parser->toggleConditionLimit( false ); + try { + $parser->parse( $code ); + $this->fail( 'No exception was thrown.' ); + } catch ( AFPUserVisibleException $e ) { + $this->assertSame( $exceptionCode, $e->mExceptionID ); + } + } + + /** + * Data provider for testCheckArgCountInConditional + * @return array + */ + public function provideFuncsForConditional() { + return [ + [ 'count()', 'noparams' ], + [ 'bool()', 'noparams' ], + [ 'ip_in_range(1)', 'notenoughargs' ], + [ 'set_var("x")', 'notenoughargs' ], + [ 'str_replace("x","y")', 'notenoughargs' ] + ]; + } + + /** + * Check that deprecated variables are correctly translated to the new ones with a debug notice + * + * @param string $old The old name of the variable + * @param string $new The new name of the variable + * @dataProvider provideDeprecatedVars + * + * @covers AbuseFilterParser::getVarValue + * @covers AFPTreeParser::checkLogDeprecatedVar + */ + public function testDeprecatedVars( $old, $new ) { + $keywordsManager = new KeywordsManager( $this->createMock( AbuseFilterHookRunner::class ) ); + // Set it under the new name, and check that the old name points to it + $vars = AbuseFilterVariableHolder::newFromArray( [ $new => 'value' ], $keywordsManager ); + + foreach ( $this->getParsers() as $parser ) { + $pname = get_class( $parser ); + $loggerMock = new TestLogger(); + $loggerMock->setCollect( true ); + $parser->setLogger( $loggerMock ); + + $parser->setVariables( $vars ); + $actual = $parser->parse( "$old === $new" ); + + $loggerBuffer = $loggerMock->getBuffer(); + // Check that the use has been logged + $found = false; + foreach ( $loggerBuffer as $entry ) { + $check = preg_match( '/^Deprecated variable/', $entry[1] ); + if ( $check ) { + $found = true; + break; + } + } + if ( !$found ) { + $this->fail( "The use of the deprecated variable $old was not logged. Parser: $pname" ); + } + + $this->assertTrue( $actual, "Parser: $pname" ); + } + } + + /** + * Data provider for testDeprecatedVars + * @return Generator|array + */ + public function provideDeprecatedVars() { + $keywordsManager = new KeywordsManager( $this->createMock( AbuseFilterHookRunner::class ) ); + foreach ( $keywordsManager->getDeprecatedVariables() as $old => $new ) { + yield $old => [ $old, $new ]; + } + } + + /** + * Ensure that things like `'a' === 'b' === 'c'` or `1 < 2 < 3` are rejected, while `1 < 2 == 3` + * and `1 == 2 < 3` are not. (T218906) + * @param string $code Code to parse + * @param bool $valid Whether $code is valid (or should throw an exception) + * @dataProvider provideConsecutiveComparisons + */ + public function testDisallowConsecutiveComparisons( $code, $valid ) { + foreach ( $this->getParsers() as $parser ) { + $pname = get_class( $parser ); + $actuallyValid = true; + try { + $parser->parse( $code ); + } catch ( AFPUserVisibleException $e ) { + $actuallyValid = false; + } + + $this->assertSame( + $valid, + $actuallyValid, + 'The code should' . ( $valid ? ' ' : ' NOT ' ) . "be parsed correctly. Parser: $pname" + ); + } + } + + /** + * Data provider for testDisallowConsecutiveComparisons + * + * @return Generator + */ + public function provideConsecutiveComparisons() { + // Same as AbuseFilterParser::doLevelCompares + $eqOps = [ '==', '===', '!=', '!==', '=' ]; + $ordOps = [ '<', '>', '<=', '>=' ]; + $ops = array_merge( $eqOps, $ordOps ); + foreach ( $ops as $op1 ) { + foreach ( $ops as $op2 ) { + $testStr = "1 $op1 3.14 $op2 -1"; + $valid = ( in_array( $op1, $eqOps ) && in_array( $op2, $ordOps ) ) || + ( in_array( $op1, $ordOps ) && in_array( $op2, $eqOps ) ); + yield $testStr => [ $testStr, $valid ]; + } + } + // Some more cases with more than 2 comparisons + $extra = [ + '1 === 1 < 3 === 0', + '1 === 1 < 3 === 0 < 555', + '1 < 3 === 0 < 555', + '1 < 3 === 0 < 555 !== 444', + '1 != 0 < 3 == 1 > 0 != 0' + ]; + foreach ( $extra as $case ) { + yield $case => [ $case, false ]; + } + } + + /** + * Test that code declaring a variable in a skipped brace (because of shortcircuit) + * will be parsed without throwing an exception when later trying to use that var. T214674 + * + * @param string $code Code to parse + * @dataProvider provideVarDeclarationInSkippedBlock + */ + public function testVarDeclarationInSkippedBlock( $code ) { + foreach ( $this->getParsers() as $parser ) { + $pname = get_class( $parser ); + try { + $this->assertFalse( + $parser->parse( $code ), + "Parser: $pname" + ); + } catch ( AFPException $e ) { + $this->fail( "Got exception with parser: $pname\n$e" ); + } + } + } + + /** + * Data provider for testVarDeclarationInSkippedBlock + * @return array + */ + public function provideVarDeclarationInSkippedBlock() { + return [ + [ "x := [5]; false & (1 == 1; y := 'b'; x[1] := 'x'; 3 < 4); y != 'b' & x[1] != 'x'" ], + [ "(var := [1]); false & ( var[] := 'baz' ); count(var) > -1" ], + [ "(var := [1]); false & ( var[1] := 'baz' ); var[1] === 'baz'" ], + [ "false & (set('myvar', 1)); myvar contains 1" ], + [ "false & ( ( false & ( var := [1] ) ) | ( var[] := 2 ) ); var" ], + [ "false & ( ( false & ( var := [1] ); true ) | ( var[] := 2 ) ); var" ], + // The following tests are to ensure that we don't get a match + [ "false & ( var := 'foo'; x := get_matches( var, added_lines )[1] ); x != false" ], + [ "false & ( var := 'foo'); var !== null" ], + [ "false & ( var := 'foo'); var === null" ], + [ "false & (set('myvar', 'foo')); myvar === 'foo' | myvar !== 'foo'" ], + [ "false & ( var := 'foo'); var[0] !== 123456" ], + [ "false & ( var := 'foo'); var[0][123] !== 123456" ], + [ "false & (set('myvar', 'foo')); myvar[1][2] === 'foo' | myvar[1][2] !== 'foo'" ], + // Identifier before closing skipped brace, T214674#5374757 + [ "false & ( var := 'foo'; 'x' in var )" ], + [ "false & ( var := 'foo'; added_lines irlike var )" ], + [ "false & ( if ( 1 == 1 ) then (var := 3) else (var := 4) end;); var !== 'foo'" ], + [ "if ( 1 === 1 ) then ( 0 ) else ( var := 1 ) end; var !== 'foo'" ], + [ "if ( 1=== 1 ) then (0) else ( false & ( var := 1 ) ) end; var !== 'foo'" ], + ]; + } + + /** + * Tests for the AFPData::DUNDEFINED type. No exceptions should be thrown. + * + * @param string $code To be parsed + * @dataProvider provideDUNDEFINED + */ + public function testDUNDEFINED( $code ) { + foreach ( $this->getParsers() as $parser ) { + $pname = get_class( $parser ); + // Note that some of the data sets will actually match at runtime, even if the variable + // they refer to is not set, due to the parser using GET_BC rather than GET_STRICT. + // TODO: Once T230256 is done, this can be changed to $this->assertFalse( $parser->parse( $code ) ) + $this->assertTrue( $parser->checkSyntax( $code ), "Parser: $pname" ); + } + } + + /** + * Data provider for testDUNDEFINED. These bits of code must NOT match + * + * @return array + */ + public function provideDUNDEFINED() { + return [ + [ "5 / length( new_wikitext ) !== 3 ** edit_delta & " . + "float( timestamp / (user_age + 0.000001) ) !== 0.0" ], + [ "amount := float( timestamp / user_age); amount !== 0.0 & 64 / ( amount - 0.1 ) !== -640.0" ], + [ "36 / ( length( user_rights ) + 0.00001 ) !== 0" ], + [ "!('something' in added_lines)" ], + [ "!(user_groups rlike 'foo')" ], + [ "rcount('x', rescape(page_title) ) !== 0" ], + [ "norm(user_name) !== rmspecials('')" ], + [ "-user_editcount !== 1234567890" ], + [ "added_lines" ], + [ "removed_lines[0] !== 123456" ], + [ "-new_size" ], + [ "new_wikitext !== null" ], + [ "true & user_editcount" ], + [ "var:= 5; added_lines contains var" ], + [ "false & (var := [ 1,2,3 ]); var === [ 1,2,3 ]" ], + [ "page_age - user_editcount !== 1234567 - page_namespace" ], + [ "added_lines contains 'foo' ? 'foo' : false" ], + [ "timestamp / 12345 !== 'foobar'" ], + // Refuse to modify a DUNDEFINED offset as if it were an array + [ "false & (var := [ 1,2,3 ]); var[0] := true; var[0] === true" ], + [ "false & (var := [ 1,2,3 ]); var[] := 'baz'; 'baz' in var" ], + // But allow overwriting the whole variable + [ "false & (var := [ 1,2,3 ]); var := [4,5,6]; var !== [4,5,6]" ], + // Recursive DUNDEFINED replacement, T250570 + [ '"x" in [ user_name ]' ], + [ 'string(user_name) in [ user_name ]' ], + [ 'string(user_name) in [ "x" ]' ], + [ '[ [ user_name ] ] in [ [ user_name ] ]' ], + [ 'equals_to_any( [ user_name ], [ user_name ] )' ], + ]; + } + + /** + * Test accessing builtin variables as arrays. This is always allowed when checking syntax, even + * if the variable is not an array (e.g. new_wikitext), but should fail when parsing. + * + * @param string $code + * @dataProvider provideBuiltinArrays + */ + public function testBuiltinArrays( string $code ) { + foreach ( $this->getParsers() as $parser ) { + $pname = get_class( $parser ); + $this->assertTrue( $parser->checkSyntax( $code ), "Parser: $pname" ); + + try { + $parser->parse( $code ); + $this->fail( "Got no exception at parse-time. Parser: $pname" ); + } catch ( AFPException $e ) { + $this->assertSame( 'notarray', $e->getMessage(), "Parser: $pname" ); + } + } + } + + /** + * Data provider for testBuiltinArrays + * @return array + */ + public function provideBuiltinArrays() { + return [ + [ "removed_lines[1] == 2" ], + [ "added_lines[0] contains 'x'" ], + [ "new_wikitext[1] !== 'xxx'" ] + ]; + } + + /** + * Test that empty operands are correctly logged in the old parser. Note that this test doesn't + * generate coverage *intentionally*. This is so that if the logEmptyOperand method becomes + * covered, there's likely a bug somewhere in the parser. + * + * @param string $code + * @param string $operandType + * @dataProvider provideEmptyOperands + */ + public function testEmptyOperandsOldParser( $code, $operandType ) { + /** @var PHPUnit\Framework\MockObject\MockObject|AbuseFilterParser $mock */ + $mock = $this->getMockBuilder( AbuseFilterParser::class ) + ->setConstructorArgs( [ + $this->getLanguageMock(), + new EmptyBagOStuff(), + new NullLogger(), + new KeywordsManager( $this->createMock( AbuseFilterHookRunner::class ) ) + ] ) + ->setMethods( [ 'logEmptyOperand' ] ) + ->getMock(); + + $mock->expects( $this->once() ) + ->method( 'logEmptyOperand' ) + ->with( $operandType ); + + $mock->toggleConditionLimit( false ); + $mock->parse( $code ); + } + + /** + * Test that empty operands raise an exception in the CachingParser + * + * @param string $code + * @dataProvider provideEmptyOperands + */ + public function testEmptyOperandsCachingParser( $code ) { + static $parser = null; + if ( !$parser ) { + $parser = new AbuseFilterCachingParser( + $this->getLanguageMock(), + new EmptyBagOStuff(), + new NullLogger(), + $this->createMock( KeywordsManager::class ) + ); + $parser->toggleConditionLimit( false ); + } + $this->expectException( AFPUserVisibleException::class ); + $this->expectExceptionMessage( 'unexpectedtoken' ); + $parser->parse( $code ); + } + + /** + * @return array + */ + public function provideEmptyOperands() { + return [ + [ '(0 |)', 'bool operand' ], + [ '(1 |)', 'bool operand' ], + [ '(0 &)', 'bool operand' ], + [ '(1 &)', 'bool operand' ], + [ '1==', 'compare operand' ], + [ '0<=', 'compare operand' ], + [ '1+', 'sum operand' ], + [ '0-', 'sum operand' ], + [ '1*', 'multiplication operand' ], + [ '1**', 'power operand' ], + [ '"string" contains', 'keyword operand' ], + [ '1 in', 'keyword operand' ], + [ "str_replace('a','b',)", 'non-variadic function argument' ], + [ "count('a',)", 'non-variadic function argument' ], + [ "(!)", 'bool inversion' ], + // `(false &!)` and `(true &!)`, originally reported in T156096, + // should be used in the future to test that they throw. However, + // using them now would log twice and thus make the test fail. + [ "var :=", 'var assignment' ], + [ "var :=[];var[] :=", 'array assignment' ], + [ "var :=[1];var[0] :=", 'array assignment' ], + [ "false ? false :", 'ternary else' ], + [ "true ? false :", 'ternary else' ], + [ "-", 'unary operand' ], + [ "+", 'unary operand' ], + [ 'if () then (1) end', 'parenthesized expression' ], + [ 'if () then (1) else (1) end', 'parenthesized expression' ], + [ 'if (true) then () end', 'parenthesized expression' ], + [ 'if (false) then () end', 'parenthesized expression' ], + [ 'if (true) then () else (3) end', 'parenthesized expression' ], + [ 'if (false) then () else (3) end', 'parenthesized expression' ], + [ 'if (true) then (1) else () end', 'parenthesized expression' ], + [ 'if (false) then (1) else () end', 'parenthesized expression' ], + [ '()', 'parenthesized expression' ] + ]; + } + + /** + * For the old parser, ensure that dangling commas for variadic functions aren't logged + * @param string $code + * @dataProvider provideDanglingCommasInVariargs + */ + public function testDanglingCommasInVariargsNotLogged( $code ) { + /** @var PHPUnit\Framework\MockObject\MockObject|AbuseFilterParser $mock */ + $mock = $this->getMockBuilder( AbuseFilterParser::class ) + ->setConstructorArgs( [ + $this->getLanguageMock(), + new EmptyBagOStuff(), + new NullLogger(), + new KeywordsManager( $this->createMock( AbuseFilterHookRunner::class ) ) + ] ) + ->setMethods( [ 'logEmptyOperand' ] ) + ->getMock(); + + $mock->expects( $this->never() ) + ->method( 'logEmptyOperand' ) + ->with( 'non-variadic function argument' ); + + $mock->toggleConditionLimit( false ); + $mock->parse( $code ); + } + + /** + * Ensure that the both parsers won't throw for dangling commas in variadic functions + * @param string $code + * @dataProvider provideDanglingCommasInVariargs + */ + public function testDanglingCommasInVariargsAreValid( $code ) { + foreach ( $this->getParsers() as $parser ) { + $pname = get_class( $parser ); + try { + $parser->parse( $code ); + $this->assertTrue( true ); + } catch ( AFPException $e ) { + $this->fail( "Got exception for dangling commas with parser $pname:\n$e" ); + } + } + } + + /** + * @return array + */ + public function provideDanglingCommasInVariargs() { + return [ + [ "contains_any('a','b','c',)" ], + [ "contains_all(1,1,1,1,1,1,1,)" ], + [ "equals_to_any(1,'foo',)" ], + ]; + } + + /** + * Ensure that an exception is thrown where there are extra commas in function calls, which + * are not the kind of allowed dangling commas. + * + * @param string $code + * @dataProvider provideExtraCommas + */ + public function testExtraCommasNotAllowed( $code ) { + $this->exceptionTest( 'unexpectedtoken', $code, 'doLevelAtom' ); + $this->exceptionTestInSkippedBlock( 'unexpectedtoken', $code, 'doLevelAtom' ); + } + + /** + * @return array + */ + public function provideExtraCommas() { + return [ + [ "norm(,,,)" ], + [ "str_replace(,'x','y')" ], + [ "contains_any(,)" ], + [ "contains_any(,,)" ], + [ "contains_any(1,2,,)" ], + [ "contains_any(1,2,,3,)" ], + ]; + } + + /** + * Ensure that any error in the arguments to a keyword or function is reported when + * checking syntax (T234339) + * @param string $code + * @param string $expID Expected exception ID + * @dataProvider provideArgsErrorsInSyntaxCheck + */ + public function testArgsErrorsInSyntaxCheck( $code, $expID ) { + $caller = '[unavailable]'; + $this->exceptionTest( $expID, $code, $caller ); + $this->exceptionTestInSkippedBlock( $expID, $code, $caller ); + } + + /** + * @return array + */ + public function provideArgsErrorsInSyntaxCheck() { + return [ + [ 'accountname rlike "("', 'regexfailure' ], + [ 'contains_any( new_wikitext, "foo", 3/0 )', 'dividebyzero' ], + [ 'contains_any( added_lines, [ user_name, [ 3/0 ] ] )', 'dividebyzero' ], + [ 'rcount( "(", added_lines )', 'regexfailure' ], + [ 'get_matches( "(", new_wikitext )', 'regexfailure' ], + [ 'added_lines contains string(3/0)', 'dividebyzero' ], + [ 'norm(new_text) irlike ")"', 'regexfailure' ], + [ 'ip_in_range( user_name, "foobar" )', 'invalidiprange' ], + ]; + } + + /** + * Ensure that every function in AbuseFilterParser::FUNCTIONS is also listed in + * AbuseFilterParser::FUNC_ARG_COUNT + */ + public function testAllFunctionsHaveArgCount() { + $funcs = array_keys( AbuseFilterParser::FUNCTIONS ); + sort( $funcs ); + $argsCount = array_keys( AbuseFilterParser::FUNC_ARG_COUNT ); + sort( $argsCount ); + $this->assertSame( $funcs, $argsCount ); + } + + /** + * @covers AbuseFilterParser::__construct + */ + public function testConstructorInitsVars() { + $lang = $this->getLanguageMock(); + $cache = $this->createMock( BagOStuff::class ); + $logger = new NullLogger(); + $keywordsManager = $this->createMock( KeywordsManager::class ); + $vars = new AbuseFilterVariableHolder( $keywordsManager ); + + $parser = new AbuseFilterParser( $lang, $cache, $logger, $keywordsManager, $vars ); + $this->assertEquals( $vars, $parser->mVariables, 'Variables should be initialized' ); + $pVars = TestingAccessWrapper::newFromObject( $parser->mVariables ); + $this->assertSame( $logger, $pVars->logger, 'VarHolder logger should be initialized' ); + } + + /** + * @covers AbuseFilterParser::setFilter + */ + public function testSetFilter() { + $parser = TestingAccessWrapper::newFromObject( $this->getParsers()[0] ); + $this->assertNull( $parser->mFilter, 'precondition' ); + $filter = 42; + $parser->setFilter( $filter ); + $this->assertSame( $filter, $parser->mFilter ); + } + + /** + * @covers AbuseFilterParser::setCache + */ + public function testSetCache() { + $parser = TestingAccessWrapper::newFromObject( $this->getParsers()[0] ); + $cache = $this->createMock( BagOStuff::class ); + $parser->setCache( $cache ); + $this->assertSame( $cache, $parser->cache ); + } + + /** + * @covers AbuseFilterParser::setLogger + */ + public function testSetLogger() { + $parser = TestingAccessWrapper::newFromObject( $this->getParsers()[0] ); + $logger = new NullLogger(); + $parser->setLogger( $logger ); + $this->assertSame( $logger, $parser->logger ); + } + + /** + * @covers AbuseFilterParser::setStatsd + */ + public function testSetStatsd() { + $parser = TestingAccessWrapper::newFromObject( $this->getParsers()[0] ); + $statsd = $this->createMock( IBufferingStatsdDataFactory::class ); + $parser->setStatsd( $statsd ); + $this->assertSame( $statsd, $parser->statsd ); + } + + /** + * @covers AbuseFilterParser::getCondCount + * @covers AbuseFilterParser::resetCondCount + */ + public function testCondCountMethods() { + $parser = TestingAccessWrapper::newFromObject( $this->getParsers()[0] ); + $this->assertSame( 0, $parser->mCondCount, 'precondition' ); + $val = 42; + $parser->mCondCount = $val; + $this->assertSame( $val, $parser->getCondCount(), 'after set' ); + $parser->resetCondCount( $val ); + $this->assertSame( 0, $parser->getCondCount(), 'after reset' ); + } + + /** + * @covers AbuseFilterParser::toggleConditionLimit + */ + public function testToggleConditionLimit() { + $parser = TestingAccessWrapper::newFromObject( $this->getParsers()[0] ); + + $parser->toggleConditionLimit( false ); + $this->assertFalse( $parser->condLimitEnabled ); + + $parser->toggleConditionLimit( true ); + $this->assertTrue( $parser->condLimitEnabled ); + } + + /** + * @covers AbuseFilterParser::clearFuncCache + */ + public function testClearFuncCache() { + $parser = TestingAccessWrapper::newFromObject( $this->getParsers()[0] ); + + $parser->funcCache = [ 1, 2, 3 ]; + + $parser->clearFuncCache(); + $this->assertSame( [], $parser->funcCache ); + } + + /** + * @covers AbuseFilterParser::setVariables + */ + public function testSetVariables() { + $parser = TestingAccessWrapper::newFromObject( $this->getParsers()[0] ); + $keywordsManager = new KeywordsManager( $this->createMock( AbuseFilterHookRunner::class ) ); + $vars = new AbuseFilterVariableHolder( $keywordsManager ); + $parser->setVariables( $vars ); + $this->assertSame( $vars, $parser->mVariables ); + } +} diff --git a/AbuseFilter/tests/phpunit/unit/AbuseFilterParserTestCase.php b/AbuseFilter/tests/phpunit/unit/AbuseFilterParserTestCase.php new file mode 100644 index 00000000..c2d19b71 --- /dev/null +++ b/AbuseFilter/tests/phpunit/unit/AbuseFilterParserTestCase.php @@ -0,0 +1,127 @@ +<?php +/** + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * + * @license GPL-2.0-or-later + */ + +use MediaWiki\Extension\AbuseFilter\Hooks\AbuseFilterHookRunner; +use MediaWiki\Extension\AbuseFilter\KeywordsManager; +use PHPUnit\Framework\MockObject\MockObject; + +/** + * Helper for parser-related tests + */ +abstract class AbuseFilterParserTestCase extends MediaWikiUnitTestCase { + /** + * @return AbuseFilterParser[] + */ + protected function getParsers() { + // We're not interested in caching or logging; tests should call respectively setCache + // and setLogger if they want to test any of those. + $contLang = $this->getLanguageMock(); + $cache = new EmptyBagOStuff(); + $logger = new \Psr\Log\NullLogger(); + $keywordsManager = new KeywordsManager( $this->createMock( AbuseFilterHookRunner::class ) ); + + $parser = new AbuseFilterParser( $contLang, $cache, $logger, $keywordsManager ); + $parser->toggleConditionLimit( false ); + $cachingParser = new AbuseFilterCachingParser( $contLang, $cache, $logger, $keywordsManager ); + $cachingParser->toggleConditionLimit( false ); + return [ $parser, $cachingParser ]; + } + + /** + * @param string $excep + * @param string $expr + * @param string $caller + * @param bool $skippedBlock Whether we're testing code inside a short-circuited block + */ + private function exceptionTestInternal( $excep, $expr, $caller, $skippedBlock ) { + foreach ( $this->getParsers() as $parser ) { + $pname = get_class( $parser ); + $msg = "Exception $excep not thrown in $caller"; + if ( $skippedBlock ) { + $msg .= " inside a short-circuited block"; + } + $msg .= ". Parser: $pname."; + try { + if ( $skippedBlock ) { + // Skipped blocks are, well, skipped when actually parsing. + $parser->checkSyntaxThrow( $expr ); + } else { + $parser->parse( $expr ); + } + } catch ( AFPUserVisibleException $e ) { + $this->assertEquals( $excep, $e->mExceptionID, $msg . " Got instead:\n$e" ); + continue; + } + + $this->fail( $msg ); + } + } + + /** + * Base method for testing exceptions + * + * @param string $excep Identifier of the exception (e.g. 'unexpectedtoken') + * @param string $expr The expression to test + * @param string $caller The function where the exception is thrown, if available + * The method may be different in Parser and CachingParser, but this parameter is + * just used for debugging purposes. + */ + protected function exceptionTest( $excep, $expr, $caller ) { + $this->exceptionTestInternal( $excep, $expr, $caller, false ); + } + + /** + * Same as self::exceptionTest, but wraps the given code in a block that will be short-circuited. + * Note that this is executed using Parser::checkSyntax, as errors inside a skipped branch won't + * ever be reported at runtime. + * + * @param string $excep + * @param string $expr + * @param string $caller + */ + protected function exceptionTestInSkippedBlock( $excep, $expr, $caller ) { + $expr = "false & ( $expr )"; + $this->exceptionTestInternal( $excep, $expr, $caller, true ); + } + + /** + * Get a mock of LanguageEn with only the methods we need in the parser + * + * @return Language|MockObject + */ + protected function getLanguageMock() { + $lang = $this->getMockBuilder( LanguageEn::class ) + ->disableOriginalConstructor() + ->getMock(); + $lang->expects( $this->any() ) + ->method( 'uc' ) + ->willReturnCallback( function ( $x ) { + return mb_strtoupper( $x ); + } ); + $lang->expects( $this->any() ) + ->method( 'lc' ) + ->willReturnCallback( function ( $x ) { + return mb_strtolower( $x ); + } ); + return $lang; + } +} diff --git a/AbuseFilter/tests/phpunit/unit/AbuseFilterTest.php b/AbuseFilter/tests/phpunit/unit/AbuseFilterTest.php new file mode 100644 index 00000000..6d77703f --- /dev/null +++ b/AbuseFilter/tests/phpunit/unit/AbuseFilterTest.php @@ -0,0 +1,742 @@ +<?php + +/** + * Generic tests for utility functions in AbuseFilter that do NOT require DB access + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * + * @license GPL-2.0-or-later + */ + +/** + * @group Test + * @group AbuseFilter + * @group AbuseFilterGeneric + */ +class AbuseFilterTest extends MediaWikiUnitTestCase { + /** + * @covers AbuseFilter::bufferTagsToSetByAction + */ + public function testTagsToSetWillNotContainDuplicates() { + AbuseFilter::$tagsToSet = []; + + $iterations = 3; + $actionID = wfRandomString( 30 ); + while ( $iterations-- ) { + AbuseFilter::bufferTagsToSetByAction( [ $actionID => [ 'uniqueTag' ] ] ); + $this->assertSame( [ 'uniqueTag' ], reset( AbuseFilter::$tagsToSet ) ); + } + } + + /** + * Check that version comparing works well + * + * @param array $firstVersion [ stdClass, array ] + * @param array $secondVersion [ stdClass, array ] + * @param array $expected The differences + * @covers AbuseFilter::compareVersions + * @dataProvider provideVersions + */ + public function testCompareVersions( $firstVersion, $secondVersion, $expected ) { + $allActions = [ + 'throttle', 'warn', 'disallow', 'blockautopromote', 'block', 'rangeblock', 'degroup', 'tag' + ]; + $differences = AbuseFilter::compareVersions( $firstVersion, $secondVersion, $allActions ); + + $this->assertSame( + $expected, + $differences, + 'AbuseFilter::compareVersions did not output the expected result.' + ); + } + + /** + * Data provider for testCompareVersions + * @return array + */ + public function provideVersions() { + return [ + [ + [ + (object)[ + 'af_public_comments' => 'Comments', + 'af_pattern' => '/*Pattern*/', + 'af_comments' => 'Comments', + 'af_deleted' => 0, + 'af_enabled' => 1, + 'af_hidden' => 0, + 'af_global' => 0, + 'af_group' => 'default' + ], + [ + 'disallow' => [] + ] + ], + [ + (object)[ + 'af_public_comments' => 'OtherComments', + 'af_pattern' => '/*Other pattern*/', + 'af_comments' => 'Other comments', + 'af_deleted' => 1, + 'af_enabled' => 0, + 'af_hidden' => 1, + 'af_global' => 1, + 'af_group' => 'flow' + ], + [ + 'disallow' => [] + ] + ], + [ + 'af_public_comments', + 'af_pattern', + 'af_comments', + 'af_deleted', + 'af_enabled', + 'af_hidden', + 'af_global', + 'af_group', + ] + ], + [ + [ + (object)[ + 'af_public_comments' => 'Comments', + 'af_pattern' => '/*Pattern*/', + 'af_comments' => 'Comments', + 'af_deleted' => 0, + 'af_enabled' => 1, + 'af_hidden' => 0, + 'af_global' => 0, + 'af_group' => 'default' + ], + [ + 'disallow' => [] + ] + ], + [ + (object)[ + 'af_public_comments' => 'Comments', + 'af_pattern' => '/*Pattern*/', + 'af_comments' => 'Comments', + 'af_deleted' => 0, + 'af_enabled' => 1, + 'af_hidden' => 0, + 'af_global' => 0, + 'af_group' => 'default' + ], + [ + 'disallow' => [] + ] + ], + [] + ], + [ + [ + (object)[ + 'af_public_comments' => 'Comments', + 'af_pattern' => '/*Pattern*/', + 'af_comments' => 'Comments', + 'af_deleted' => 0, + 'af_enabled' => 1, + 'af_hidden' => 0, + 'af_global' => 0, + 'af_group' => 'default' + ], + [ + 'disallow' => [] + ] + ], + [ + (object)[ + 'af_public_comments' => 'Comments', + 'af_pattern' => '/*Pattern*/', + 'af_comments' => 'Comments', + 'af_deleted' => 0, + 'af_enabled' => 1, + 'af_hidden' => 0, + 'af_global' => 0, + 'af_group' => 'default' + ], + [ + 'degroup' => [] + ] + ], + [ 'actions' ] + ], + [ + [ + (object)[ + 'af_public_comments' => 'Comments', + 'af_pattern' => '/*Pattern*/', + 'af_comments' => 'Comments', + 'af_deleted' => 0, + 'af_enabled' => 1, + 'af_hidden' => 0, + 'af_global' => 0, + 'af_group' => 'default' + ], + [ + 'disallow' => [] + ] + ], + [ + (object)[ + 'af_public_comments' => 'OtherComments', + 'af_pattern' => '/*Other pattern*/', + 'af_comments' => 'Other comments', + 'af_deleted' => 1, + 'af_enabled' => 0, + 'af_hidden' => 1, + 'af_global' => 1, + 'af_group' => 'flow' + ], + [ + 'blockautopromote' => [] + ] + ], + [ + 'af_public_comments', + 'af_pattern', + 'af_comments', + 'af_deleted', + 'af_enabled', + 'af_hidden', + 'af_global', + 'af_group', + 'actions' + ] + ], + [ + [ + (object)[ + 'af_public_comments' => 'Comments', + 'af_pattern' => '/*Pattern*/', + 'af_comments' => 'Comments', + 'af_deleted' => 0, + 'af_enabled' => 1, + 'af_hidden' => 0, + 'af_global' => 0, + 'af_group' => 'default' + ], + [ + 'disallow' => [] + ] + ], + [ + (object)[ + 'af_public_comments' => 'Comments', + 'af_pattern' => '/*Pattern*/', + 'af_comments' => 'Comments', + 'af_deleted' => 0, + 'af_enabled' => 1, + 'af_hidden' => 0, + 'af_global' => 0, + 'af_group' => 'default' + ], + [ + 'warn' => [ + 'abusefilter-warning' + ] + ] + ], + [ 'actions' ] + ], + [ + [ + (object)[ + 'af_public_comments' => 'Comments', + 'af_pattern' => '/*Pattern*/', + 'af_comments' => 'Comments', + 'af_deleted' => 0, + 'af_enabled' => 1, + 'af_hidden' => 0, + 'af_global' => 0, + 'af_group' => 'default' + ], + [ + 'warn' => [ + 'abusefilter-warning' + ] + ] + ], + [ + (object)[ + 'af_public_comments' => 'Comments', + 'af_pattern' => '/*Pattern*/', + 'af_comments' => 'Comments', + 'af_deleted' => 0, + 'af_enabled' => 1, + 'af_hidden' => 0, + 'af_global' => 0, + 'af_group' => 'default' + ], + [ + 'disallow' => [] + ] + ], + [ 'actions' ] + ], + [ + [ + (object)[ + 'af_public_comments' => 'Comments', + 'af_pattern' => '/*Pattern*/', + 'af_comments' => 'Comments', + 'af_deleted' => 0, + 'af_enabled' => 1, + 'af_hidden' => 0, + 'af_global' => 0, + 'af_group' => 'default' + ], + [ + 'warn' => [ + 'abusefilter-warning' + ] + ] + ], + [ + (object)[ + 'af_public_comments' => 'Comments', + 'af_pattern' => '/*Pattern*/', + 'af_comments' => 'Comments', + 'af_deleted' => 0, + 'af_enabled' => 1, + 'af_hidden' => 0, + 'af_global' => 0, + 'af_group' => 'default' + ], + [ + 'warn' => [ + 'abusefilter-my-best-warning' + ], + 'degroup' => [] + ] + ], + [ 'actions' ] + ], + [ + [ + (object)[ + 'af_public_comments' => 'Comments', + 'af_pattern' => '/*Pattern*/', + 'af_comments' => 'Comments', + 'af_deleted' => 0, + 'af_enabled' => 1, + 'af_hidden' => 0, + 'af_global' => 0, + 'af_group' => 'default' + ], + [ + 'warn' => [ + 'abusefilter-warning' + ] + ] + ], + [ + (object)[ + 'af_public_comments' => 'Comments', + 'af_pattern' => '/*Other Pattern*/', + 'af_comments' => 'Comments', + 'af_deleted' => 0, + 'af_enabled' => 1, + 'af_hidden' => 1, + 'af_global' => 0, + 'af_group' => 'flow' + ], + [ + 'warn' => [ + 'abusefilter-my-best-warning' + ] + ] + ], + [ + 'af_pattern', + 'af_hidden', + 'af_group', + 'actions' + ] + ], + [ + [ + (object)[ + 'af_public_comments' => 'Comments', + 'af_pattern' => '/*Pattern*/', + 'af_comments' => 'Comments', + 'af_deleted' => 0, + 'af_enabled' => 1, + 'af_hidden' => 0, + 'af_global' => 0, + 'af_group' => 'default' + ], + [ + 'warn' => [ + 'abusefilter-beautiful-warning' + ] + ] + ], + [ + (object)[ + 'af_public_comments' => 'Comments', + 'af_pattern' => '/*Pattern*/', + 'af_comments' => 'Comments', + 'af_deleted' => 0, + 'af_enabled' => 1, + 'af_hidden' => 0, + 'af_global' => 0, + 'af_group' => 'flow' + ], + [ + 'warn' => [ + 'abusefilter-my-best-warning' + ] + ] + ], + [ + 'af_group', + 'actions' + ] + ], + ]; + } + + /** + * Check that row translating from abuse_filter_history to abuse_filter is working fine + * + * @param stdClass $row The row to translate + * @param array $expected The expected result + * @covers AbuseFilter::translateFromHistory + * @dataProvider provideHistoryRows + */ + public function testTranslateFromHistory( $row, $expected ) { + $actual = AbuseFilter::translateFromHistory( $row ); + + $this->assertEquals( $expected, $actual ); + } + + /** + * Data provider for testTranslateFromHistory + * @return array + */ + public function provideHistoryRows() { + return [ + [ + (object)[ + 'afh_filter' => 1, + 'afh_user' => 0, + 'afh_user_text' => 'FilteredUser', + 'afh_timestamp' => '20180706142932', + 'afh_pattern' => '/*Pattern*/', + 'afh_comments' => 'Comments', + 'afh_flags' => 'enabled,hidden', + 'afh_public_comments' => 'Description', + 'afh_actions' => serialize( [ + 'degroup' => [], + 'disallow' => [] + ] ), + 'afh_deleted' => 0, + 'afh_changed_fields' => 'actions', + 'afh_group' => 'default' + ], + [ + (object)[ + 'af_pattern' => '/*Pattern*/', + 'af_user' => 0, + 'af_user_text' => 'FilteredUser', + 'af_timestamp' => '20180706142932', + 'af_comments' => 'Comments', + 'af_public_comments' => 'Description', + 'af_deleted' => 0, + 'af_id' => 1, + 'af_group' => 'default', + 'af_hidden' => 1, + 'af_enabled' => 1 + ], + [ + 'degroup' => [], + 'disallow' => [] + ] + ] + ], + [ + (object)[ + 'afh_filter' => 5, + 'afh_user' => 0, + 'afh_user_text' => 'FilteredUser', + 'afh_timestamp' => '20180706145516', + 'afh_pattern' => '1 === 1', + 'afh_comments' => '', + 'afh_flags' => '', + 'afh_public_comments' => 'Our best filter', + 'afh_actions' => serialize( [ + 'warn' => [ + 'abusefilter-warning', + '' + ], + 'disallow' => [], + ] ), + 'afh_deleted' => 0, + 'afh_changed_fields' => 'af_pattern,af_comments,af_enabled,actions', + 'afh_group' => 'flow' + ], + [ + (object)[ + 'af_pattern' => '1 === 1', + 'af_user' => 0, + 'af_user_text' => 'FilteredUser', + 'af_timestamp' => '20180706145516', + 'af_comments' => '', + 'af_public_comments' => 'Our best filter', + 'af_deleted' => 0, + 'af_id' => 5, + 'af_group' => 'flow', + 'af_hidden' => 0, + 'af_enabled' => 0 + ], + [ + 'warn' => [ + 'abusefilter-warning', + '' + ], + 'disallow' => [] + ] + ] + ], + [ + (object)[ + 'afh_filter' => 7, + 'afh_user' => 1, + 'afh_user_text' => 'AnotherUser', + 'afh_timestamp' => '20160511185604', + 'afh_pattern' => 'added_lines irlike "lol" & summary == "ggwp"', + 'afh_comments' => 'Show vandals no mercy, for you shall receive none.', + 'afh_flags' => 'enabled,hidden', + 'afh_public_comments' => 'Whatever', + 'afh_actions' => serialize( [ + 'warn' => [ + 'abusefilter-warning', + '' + ], + 'disallow' => [], + 'block' => [ + 'blocktalk', + '8 hours', + 'infinity' + ] + ] ), + 'afh_deleted' => 0, + 'afh_changed_fields' => 'af_pattern,af_comments,af_enabled,af_public_comments,actions', + 'afh_group' => 'default' + ], + [ + (object)[ + 'af_pattern' => 'added_lines irlike "lol" & summary == "ggwp"', + 'af_user' => 1, + 'af_user_text' => 'AnotherUser', + 'af_timestamp' => '20160511185604', + 'af_comments' => 'Show vandals no mercy, for you shall receive none.', + 'af_public_comments' => 'Whatever', + 'af_deleted' => 0, + 'af_id' => 7, + 'af_group' => 'default', + 'af_hidden' => 1, + 'af_enabled' => 1 + ], + [ + 'warn' => [ + 'abusefilter-warning', + '' + ], + 'disallow' => [], + 'block' => [ + 'blocktalk', + '8 hours', + 'infinity' + ] + ] + ] + ], + [ + (object)[ + 'afh_filter' => 131, + 'afh_user' => 15, + 'afh_user_text' => 'YetAnotherUser', + 'afh_timestamp' => '20180511185604', + 'afh_pattern' => 'user_name == "Thatguy"', + 'afh_comments' => '', + 'afh_flags' => 'hidden,deleted', + 'afh_public_comments' => 'No comment.', + 'afh_actions' => serialize( [ + 'throttle' => [ + '131', + '3,60', + 'user' + ], + 'tag' => [ + 'mytag', + 'yourtag' + ] + ] ), + 'afh_deleted' => 1, + 'afh_changed_fields' => 'af_pattern', + 'afh_group' => 'default' + ], + [ + (object)[ + 'af_pattern' => 'user_name == "Thatguy"', + 'af_user' => 15, + 'af_user_text' => 'YetAnotherUser', + 'af_timestamp' => '20180511185604', + 'af_comments' => '', + 'af_public_comments' => 'No comment.', + 'af_deleted' => 1, + 'af_id' => 131, + 'af_group' => 'default', + 'af_hidden' => 1, + 'af_enabled' => 0 + ], + [ + 'throttle' => [ + '131', + '3,60', + 'user' + ], + 'tag' => [ + 'mytag', + 'yourtag' + ] + ] + ] + ] + ]; + } + + /** + * @param string $name The name of a filter + * @param array|null $expected If array, the expected result like [ id, isGlobal ]. + * If null it means that we're expecting an exception. + * @covers AbuseFilter::splitGlobalName + * @dataProvider provideGlobalNames + */ + public function testSplitGlobalName( $name, $expected ) { + if ( $expected !== null ) { + $actual = AbuseFilter::splitGlobalName( $name ); + $this->assertSame( $expected, $actual ); + } else { + $this->expectException( InvalidArgumentException::class ); + AbuseFilter::splitGlobalName( $name ); + } + } + + /** + * Data provider for testSplitGlobalName + * + * @return array + */ + public function provideGlobalNames() { + return [ + [ '15', [ 15, false ] ], + [ 15, [ 15, false ] ], + [ 'global-1', [ 1, true ] ], + [ 'new', null ], + [ false, null ], + [ 'global-15-global', null ], + [ 0, [ 0, false ] ], + [ 'global-', null ], + [ 'global-lol', null ], + [ 'global-17.2', null ], + [ '17,2', null ], + ]; + } + + /** + * Check that throttle parameters validation works fine + * + * @param array $params Throttle parameters + * @param string|null $error The expected error message. Null if validations should pass + * @covers AbuseFilter::checkThrottleParameters + * @dataProvider provideThrottleParameters + */ + public function testCheckThrottleParameters( $params, $error ) { + $result = AbuseFilter::checkThrottleParameters( $params ); + $this->assertSame( $error, $result, 'Throttle parameter validation does not work as expected.' ); + } + + /** + * Data provider for testCheckThrottleParameters + * @return array + */ + public function provideThrottleParameters() { + return [ + [ [ '1', '5,23', 'user', 'ip', 'page,range', 'ip,user', 'range,ip' ], null ], + [ [ '1', '5.3,23', 'user', 'ip' ], 'abusefilter-edit-invalid-throttlecount' ], + [ [ '1', '-3,23', 'user', 'ip' ], 'abusefilter-edit-invalid-throttlecount' ], + [ [ '1', '5,2.3', 'user', 'ip' ], 'abusefilter-edit-invalid-throttleperiod' ], + [ [ '1', '4,-14', 'user', 'ip' ], 'abusefilter-edit-invalid-throttleperiod' ], + [ [ '1', '3,33,44', 'user', 'ip' ], 'abusefilter-edit-invalid-throttleperiod' ], + [ [ '1', '3,33' ], 'abusefilter-edit-empty-throttlegroups' ], + [ [ '1', '3,33', 'user', 'ip,foo,user' ], 'abusefilter-edit-invalid-throttlegroups' ], + [ [ '1', '3,33', 'foo', 'ip,user' ], 'abusefilter-edit-invalid-throttlegroups' ], + [ [ '1', '3,33', 'foo', 'ip,user,bar' ], 'abusefilter-edit-invalid-throttlegroups' ], + [ [ '1', '3,33', 'user', 'ip,page,user' ], null ], + [ + [ '1', '3,33', 'ip', 'user','user,ip', 'ip,user', 'user,ip,user', 'user', 'ip,ip,user' ], + 'abusefilter-edit-duplicated-throttlegroups' + ], + [ [ '1', '3,33', 'ip,ip,user' ], 'abusefilter-edit-duplicated-throttlegroups' ], + [ [ '1', '3,33', 'user,ip', 'ip,user' ], 'abusefilter-edit-duplicated-throttlegroups' ], + ]; + } + + /** + * @param $var + * @param string $expected + * @covers AbuseFilter::formatVar + * @dataProvider provideFormatVar + */ + public function testFormatVar( $var, string $expected ) { + $this->assertSame( $expected, AbuseFilter::formatVar( $var ) ); + } + + /** + * Provider for testFormatVar + * @return array + */ + public function provideFormatVar() { + return [ + 'boolean' => [ true, 'true' ], + 'single-quote string' => [ 'foo', "'foo'" ], + 'string with quotes' => [ "ba'r'", "'ba'r''" ], + 'integer' => [ 42, '42' ], + 'float' => [ 0.1, '0.1' ], + 'null' => [ null, 'null' ], + 'simple list' => [ [ true, 1, 'foo' ], "[\n\t0 => true,\n\t1 => 1,\n\t2 => 'foo'\n]" ], + 'assoc array' => [ [ 'foo' => 1, 'bar' => 'bar' ], "[\n\t'foo' => 1,\n\t'bar' => 'bar'\n]" ], + 'nested array' => [ + [ 'a1' => 1, [ 'a2' => 2, [ 'a3' => 3, [ 'a4' => 4 ] ] ] ], + "[\n\t'a1' => 1,\n\t0 => [\n\t\t'a2' => 2,\n\t\t0 => [\n\t\t\t'a3' => 3,\n\t\t\t0 => " . + "[\n\t\t\t\t'a4' => 4\n\t\t\t]\n\t\t]\n\t]\n]" + ], + 'empty array' => [ [], '[]' ], + 'mixed array' => [ + [ 3 => true, 'foo' => false, 1, [ 1, 'foo' => 42 ] ], + "[\n\t3 => true,\n\t'foo' => false,\n\t4 => 1,\n\t5 => [\n\t\t0 => 1,\n\t\t'foo' => 42\n\t]\n]" + ] + ]; + } +} diff --git a/AbuseFilter/tests/phpunit/AbuseFilterTokenizerTest.php b/AbuseFilter/tests/phpunit/unit/AbuseFilterTokenizerTest.php index f573126f..911fa2b1 100644 --- a/AbuseFilter/tests/phpunit/AbuseFilterTokenizerTest.php +++ b/AbuseFilter/tests/phpunit/unit/AbuseFilterTokenizerTest.php @@ -1,7 +1,5 @@ <?php /** - * Tests for the AFPData class - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -25,56 +23,15 @@ /** * @group Test * @group AbuseFilter - * - * @covers AbuseFilterTokenizer - * @covers AFPToken - * @covers AbuseFilterParser - * @covers AFPUserVisibleException - * @covers AFPException + * @group AbuseFilterParser */ -class AbuseFilterTokenizerTest extends MediaWikiTestCase { - /** - * @return AbuseFilterParser - */ - public static function getParser() { - static $parser = null; - if ( !$parser ) { - $parser = new AbuseFilterParser(); - } else { - $parser->resetState(); - } - return $parser; - } - - /** - * Base method for testing exceptions - * - * @param string $excep Identifier of the exception (e.g. 'unexpectedtoken') - * @param string $expr The expression to test - * @param string $caller The function where the exception is thrown - */ - private function exceptionTest( $excep, $expr, $caller ) { - $parser = self::getParser(); - try { - $parser->parse( $expr ); - } catch ( AFPUserVisibleException $e ) { - $this->assertEquals( - $excep, - $e->mExceptionID, - "Exception $excep not thrown in AbuseFilterTokenizer::$caller" - ); - return; - } - - $this->fail( "Exception $excep not thrown in AbuseFilterTokenizer::$caller" ); - } - +class AbuseFilterTokenizerTest extends AbuseFilterParserTestCase { /** * Test the 'unclosedcomment' exception * * @param string $expr The expression to test * @param string $caller The function where the exception is thrown - * @covers AbuseFilterTokenizer::nextToken + * @covers AbuseFilterTokenizer * @dataProvider unclosedComment */ public function testUnclosedCommentException( $expr, $caller ) { @@ -99,7 +56,7 @@ class AbuseFilterTokenizerTest extends MediaWikiTestCase { * * @param string $expr The expression to test * @param string $caller The function where the exception is thrown - * @covers AbuseFilterTokenizer::nextToken + * @covers AbuseFilterTokenizer * @dataProvider unrecognisedToken */ public function testUnrecognisedTokenException( $expr, $caller ) { @@ -124,7 +81,7 @@ class AbuseFilterTokenizerTest extends MediaWikiTestCase { * * @param string $expr The expression to test * @param string $caller The function where the exception is thrown - * @covers AbuseFilterTokenizer::readStringLiteral + * @covers AbuseFilterTokenizer * @dataProvider unclosedString */ public function testUnclosedStringException( $expr, $caller ) { @@ -143,4 +100,35 @@ class AbuseFilterTokenizerTest extends MediaWikiTestCase { [ '"', 'readStringLiteral' ], ]; } + + /** + * Test that tokenized code is saved in cache. + * + * @param string $code To be tokenized + * @dataProvider provideCode + * @covers AbuseFilterTokenizer::getTokens + */ + public function testCaching( $code ) { + $cache = new HashBagOStuff(); + $tokenizer = new AbuseFilterTokenizer( $cache, new Psr\Log\NullLogger() ); + + $key = $tokenizer->getCacheKey( $code ); + + $tokenizer->getTokens( $code ); + $this->assertNotFalse( $cache->get( $key ) ); + } + + /** + * Data provider for testCaching + * + * @return array + */ + public function provideCode() { + return [ + [ '1 === 1' ], + [ 'added_lines irlike "test"' ], + [ 'edit_delta > 57 & action === "edit"' ], + [ '!("confirmed") in user_groups' ] + ]; + } } diff --git a/AbuseFilter/tests/phpunit/unit/AbuseFilterVariableGeneratorTest.php b/AbuseFilter/tests/phpunit/unit/AbuseFilterVariableGeneratorTest.php new file mode 100644 index 00000000..80370237 --- /dev/null +++ b/AbuseFilter/tests/phpunit/unit/AbuseFilterVariableGeneratorTest.php @@ -0,0 +1,256 @@ +<?php + +use MediaWiki\Extension\AbuseFilter\Hooks\AbuseFilterHookRunner; +use MediaWiki\Extension\AbuseFilter\KeywordsManager; +use MediaWiki\Extension\AbuseFilter\VariableGenerator\VariableGenerator; +use PHPUnit\Framework\MockObject\MockObject; + +/** + * @group Test + * @group AbuseFilter + * @group AbuseFilterGeneric + * + * @covers AFComputedVariable::compute + */ +class AbuseFilterVariableGeneratorTest extends MediaWikiUnitTestCase { + /** A fake timestamp to use in several time-related tests. */ + private const FAKE_TIME = 1514700000; + + /** + * @inheritDoc + */ + protected function tearDown() : void { + MWTimestamp::setFakeTime( false ); + parent::tearDown(); + } + + /** + * @param string $method + * @param mixed $result + * @return MockObject|User User type is here for IDE-friendliness + */ + private function getUserWithMockedMethod( $method, $result ) { + $user = $this->getMockBuilder( User::class ) + ->disableOriginalConstructor() + ->getMock(); + + $user->expects( $this->atLeastOnce() ) + ->method( $method ) + ->willReturn( $result ); + + return $user; + } + + /** + * Given the name of a variable, create a User mock with that value + * + * @param string $var The variable name + * @return array the first position is the User mock, the second is the expected value + * for the given variable + */ + private function getUserAndExpectedVariable( $var ) { + switch ( $var ) { + case 'user_editcount': + $result = 7; + $user = $this->getUserWithMockedMethod( 'getEditCount', $result ); + break; + case 'user_name': + $result = 'UniqueUserName'; + $user = $this->getUserWithMockedMethod( 'getName', $result ); + break; + case 'user_emailconfirm': + $result = wfTimestampNow(); + $user = $this->getUserWithMockedMethod( 'getEmailAuthenticationTimestamp', $result ); + break; + case 'user_groups': + $result = [ '*', 'group1', 'group2' ]; + $user = $this->getUserWithMockedMethod( 'getEffectiveGroups', $result ); + break; + case 'user_rights': + $result = [ 'abusefilter-foo', 'abusefilter-bar' ]; + $user = $this->getUserWithMockedMethod( 'getRights', $result ); + break; + case 'user_blocked': + $result = true; + $user = $this->getUserWithMockedMethod( 'getBlock', $result ); + break; + case 'user_age': + MWTimestamp::setFakeTime( self::FAKE_TIME ); + $result = 163; + $user = $this->getUserWithMockedMethod( 'getRegistration', self::FAKE_TIME - $result ); + break; + default: + throw new LogicException( "Given unknown user-related variable $var." ); + } + + return [ $user, $result ]; + } + + /** + * Check that the generated user-related variables are correct + * + * @param string $varName The name of the variable we're currently testing + * @covers \MediaWiki\Extension\AbuseFilter\VariableGenerator\VariableGenerator::addUserVars + * @dataProvider provideUserVars + */ + public function testAddUserVars( $varName ) { + list( $user, $computed ) = $this->getUserAndExpectedVariable( $varName ); + + $keywordsManager = new KeywordsManager( $this->createMock( AbuseFilterHookRunner::class ) ); + $variableHolder = new AbuseFilterVariableHolder( $keywordsManager ); + $generator = new VariableGenerator( $variableHolder ); + $variableHolder = $generator->addUserVars( $user )->getVariableHolder(); + $actual = $variableHolder->getVar( $varName )->toNative(); + $this->assertSame( $computed, $actual ); + } + + /** + * Data provider for testAddUserVars + * @return Generator|array + */ + public function provideUserVars() { + $vars = [ + 'user_editcount', + 'user_name', + 'user_emailconfirm', + 'user_groups', + 'user_rights', + 'user_blocked', + 'user_age' + ]; + foreach ( $vars as $var ) { + yield $var => [ $var ]; + } + } + + /** + * @param string $method + * @param mixed $result + * @return MockObject|Title Title type is here for IDE-friendliness + */ + private function getTitleWithMockedMethod( $method, $result ) { + $title = $this->getMockBuilder( Title::class ) + ->disableOriginalConstructor() + ->getMock(); + + $title->expects( $this->atLeastOnce() ) + ->method( $method ) + ->willReturn( $result ); + + return $title; + } + + /** + * Given the name of a variable, create a Title mock with that value + * + * @param string $prefix The prefix of the variable + * @param string $suffix The suffix of the variable + * @param bool $restricted Whether the title should be restricted + * @return array the first position is the mocked Title, the second the expected value of the var + */ + private function getTitleAndExpectedVariable( $prefix, $suffix, $restricted = false ) { + switch ( $suffix ) { + case '_id': + $result = 1234; + $title = $this->getTitleWithMockedMethod( 'getArticleID', $result ); + break; + case '_namespace': + $result = 5; + $title = $this->getTitleWithMockedMethod( 'getNamespace', $result ); + break; + case '_title': + $result = 'Page title'; + $title = $this->getTitleWithMockedMethod( 'getText', $result ); + break; + case '_prefixedtitle': + $result = 'Page prefixedtitle'; + $title = $this->getTitleWithMockedMethod( 'getPrefixedText', $result ); + break; + case '_restrictions_create': + case '_restrictions_edit': + case '_restrictions_move': + case '_restrictions_upload': + $result = $restricted ? [ 'sysop' ] : []; + $title = $this->getTitleWithMockedMethod( 'getRestrictions', $result ); + break; + // case '_recent_contributors' handled in AbuseFilterVariableGeneratorDBTest + // case '_first_contributor' is handled in AbuseFilterDBTest + case '_age': + $result = 123; + MWTimestamp::setFakeTime( self::FAKE_TIME ); + $title = $this->getTitleWithMockedMethod( 'getEarliestRevTime', self::FAKE_TIME - $result ); + break; + default: + throw new LogicException( "Given unknown title-related variable $prefix$suffix." ); + } + + return [ $title, $result ]; + } + + /** + * Check that the generated title-related variables are correct + * + * @param string $prefix The prefix of the variables we're currently testing + * @param string $suffix The suffix of the variables we're currently testing + * @param bool $restricted Used for _restrictions variable. If true, + * the tested title will have the requested restriction. + * @covers \MediaWiki\Extension\AbuseFilter\VariableGenerator\VariableGenerator::addTitleVars + * @dataProvider provideTitleVars + */ + public function testAddTitleVars( $prefix, $suffix, $restricted = false ) { + $varName = $prefix . $suffix; + list( $title, $computed ) = $this->getTitleAndExpectedVariable( $prefix, $suffix, $restricted ); + + $keywordsManager = new KeywordsManager( $this->createMock( AbuseFilterHookRunner::class ) ); + $variableHolder = $this->getMockBuilder( AbuseFilterVariableHolder::class ) + ->setConstructorArgs( [ $keywordsManager ] ) + ->setMethods( [ 'getLazyLoader' ] ) + ->getMock(); + + /** @var MockObject|AbuseFilterVariableHolder $variableHolder */ + $variableHolder + ->method( 'getLazyLoader' ) + ->willReturnCallback( function ( $method, $params ) use ( $title ) { + $lazyLoader = $this->getMockBuilder( AFComputedVariable::class ) + ->setMethods( [ 'buildTitle' ] ) + ->setConstructorArgs( [ $method, $params ] ) + ->getMock(); + + $lazyLoader->method( 'buildTitle' )->willReturn( $title ); + return $lazyLoader; + } ); + + $generator = new VariableGenerator( $variableHolder ); + $variableHolder = $generator->addTitleVars( $title, $prefix )->getVariableHolder(); + $actual = $variableHolder->getVar( $varName )->toNative(); + $this->assertSame( $computed, $actual ); + } + + /** + * Data provider for testAddTitleVars + * @return Generator|array + */ + public function provideTitleVars() { + $prefixes = [ 'page', 'moved_from', 'moved_to' ]; + $suffixes = [ + '_id', + '_namespace', + '_title', + '_prefixedtitle', + '_restrictions_create', + '_restrictions_edit', + '_restrictions_move', + '_restrictions_upload', + '_age' + ]; + foreach ( $prefixes as $prefix ) { + foreach ( $suffixes as $suffix ) { + yield $prefix . $suffix => [ $prefix, $suffix ]; + if ( strpos( $suffix, 'restrictions' ) !== false ) { + // Add a case where the page has the restriction + yield $prefix . $suffix . ', restricted' => [ $prefix, $suffix, true ]; + } + } + } + } +} diff --git a/AbuseFilter/tests/phpunit/unit/AbuseFilterVariableHolderTest.php b/AbuseFilter/tests/phpunit/unit/AbuseFilterVariableHolderTest.php new file mode 100644 index 00000000..226bed3d --- /dev/null +++ b/AbuseFilter/tests/phpunit/unit/AbuseFilterVariableHolderTest.php @@ -0,0 +1,404 @@ +<?php +/** + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * + * @license GPL-2.0-or-later + */ + +use MediaWiki\Extension\AbuseFilter\Hooks\AbuseFilterHookRunner; +use MediaWiki\Extension\AbuseFilter\KeywordsManager; +use Psr\Log\NullLogger; +use Wikimedia\TestingAccessWrapper; + +/** + * @group Test + * @group AbuseFilter + * @group AbuseFilterParser + */ +class AbuseFilterVariableHolderTest extends MediaWikiUnitTestCase { + /** + * Convenience wrapper + * @return AbuseFilterVariableHolder + */ + private function getVariableHolder() : AbuseFilterVariableHolder { + $keywordsManager = new KeywordsManager( $this->createMock( AbuseFilterHookRunner::class ) ); + return new AbuseFilterVariableHolder( $keywordsManager ); + } + + /** + * @covers AbuseFilterVariableHolder::__construct + * @covers AbuseFilterVariableHolder::setLogger + */ + public function testLogger() { + $vars = $this->getVariableHolder(); + $tw = TestingAccessWrapper::newFromObject( $vars ); + $this->assertInstanceOf( NullLogger::class, $tw->logger, 'Default logger is NullLogger' ); + + $loggerClass = TestLogger::class; + $logger = $this->createMock( $loggerClass ); + $tw->setLogger( $logger ); + $this->assertInstanceOf( $loggerClass, $tw->logger, 'Logger can be changed' ); + } + + /** + * @covers AbuseFilterVariableHolder::newFromArray + */ + public function testNewFromArray() { + $vars = [ + 'foo' => 12, + 'bar' => [ 'x', 'y' ], + 'baz' => false + ]; + $keywordsManager = new KeywordsManager( $this->createMock( AbuseFilterHookRunner::class ) ); + $actual = AbuseFilterVariableHolder::newFromArray( $vars, $keywordsManager ); + $expected = $this->getVariableHolder(); + foreach ( $vars as $var => $value ) { + $expected->setVar( $var, $value ); + } + + $this->assertEquals( $expected, $actual ); + } + + /** + * @covers AbuseFilterVariableHolder::setVar + */ + public function testVarsAreLowercased() { + $vars = $this->getVariableHolder(); + $this->assertCount( 0, $vars->getVars(), 'precondition' ); + $vars->setVar( 'FOO', 42 ); + $this->assertCount( 1, $vars->getVars(), 'variable should be set' ); + $this->assertArrayHasKey( 'foo', $vars->getVars(), 'var should be lowercase' ); + } + + /** + * @covers AbuseFilterVariableHolder::translateDeprecatedVars + */ + public function testTranslateDeprecatedVars() { + $varsMap = [ + 'timestamp' => new AFPData( AFPData::DSTRING, '123' ), + 'added_lines' => new AFPData( AFPData::DSTRING, 'foobar' ), + 'article_text' => new AFPData( AFPData::DSTRING, 'FOO' ), + 'article_articleid' => new AFPData( AFPData::DINT, 42 ) + ]; + $translatedVarsMap = [ + 'timestamp' => $varsMap['timestamp'], + 'added_lines' => $varsMap['added_lines'], + 'page_title' => $varsMap['article_text'], + 'page_id' => $varsMap['article_articleid'] + ]; + $keywordsManager = new KeywordsManager( $this->createMock( AbuseFilterHookRunner::class ) ); + $holder = AbuseFilterVariableHolder::newFromArray( $varsMap, $keywordsManager ); + $holder->translateDeprecatedVars(); + $this->assertEquals( $translatedVarsMap, $holder->getVars() ); + } + + /** + * @param string $name + * @param mixed $val + * @param mixed $expected + * + * @dataProvider provideSetVar + * + * @covers AbuseFilterVariableHolder::setVar + */ + public function testSetVar( $name, $val, $expected ) { + $vars = $this->getVariableHolder(); + $vars->setVar( $name, $val ); + $this->assertEquals( $expected, $vars->getVars()[$name] ); + } + + public function provideSetVar() { + yield 'native' => [ 'foo', 12, new AFPData( AFPData::DINT, 12 ) ]; + + $afpdata = new AFPData( AFPData::DSTRING, 'foobar' ); + yield 'AFPData' => [ 'foo', $afpdata, $afpdata ]; + + $afcompvar = new AFComputedVariable( 'foo', [] ); + yield 'AFComputedVariable' => [ 'foo', $afcompvar, $afcompvar ]; + } + + /** + * @covers AbuseFilterVariableHolder::getVars + */ + public function testGetVars() { + $vars = $this->getVariableHolder(); + $this->assertSame( [], $vars->getVars(), 'precondition' ); + + $vars->setVar( 'foo', [ true ] ); + $vars->setVar( 'bar', 'bar' ); + $exp = [ + 'foo' => new AFPData( AFPData::DARRAY, [ new AFPData( AFPData::DBOOL, true ) ] ), + 'bar' => new AFPData( AFPData::DSTRING, 'bar' ) + ]; + + $this->assertEquals( $exp, $vars->getVars() ); + } + + /** + * @param AbuseFilterVariableHolder $vars + * @param string $name + * @param int $flags + * @param AFPData $expected + * @covers AbuseFilterVariableHolder::getVar + * + * @dataProvider provideGetVar + */ + public function testGetVar( AbuseFilterVariableHolder $vars, $name, $flags, AFPData $expected ) { + $this->assertEquals( $expected, $vars->getVar( $name, $flags ) ); + } + + /** + * @return Generator|array + */ + public function provideGetVar() { + $vars = $this->getVariableHolder(); + + $afcv = $this->getMockBuilder( AFComputedVariable::class ) + ->setMethods( [ 'compute' ] ) + ->disableOriginalConstructor() + ->getMock(); + $name = 'foo'; + $expected = new AFPData( AFPData::DSTRING, 'foobarbaz' ); + $afcv->method( 'compute' )->willReturn( $expected ); + $vars->setVar( $name, $afcv ); + yield 'set, AFComputedVariable' => [ $vars, $name, 0, $expected ]; + + $name = 'afpd'; + $afpd = new AFPData( AFPData::DINT, 42 ); + $vars->setVar( $name, $afpd ); + yield 'set, AFPData' => [ $vars, $name, 0, $afpd ]; + + $name = 'not-set'; + $expected = new AFPData( AFPData::DUNDEFINED ); + yield 'unset, lax' => [ $vars, $name, AbuseFilterVariableHolder::GET_LAX, $expected ]; + // For now, strict is the same as lax. + yield 'unset, strict' => [ $vars, $name, AbuseFilterVariableHolder::GET_STRICT, $expected ]; + yield 'unset, bc' => [ $vars, $name, AbuseFilterVariableHolder::GET_BC, new AFPData( AFPData::DNULL ) ]; + } + + /** + * @covers AbuseFilterVariableHolder::getVar + */ + public function testGetVarInvalidType() { + $vars = $this->getVariableHolder(); + $tw = TestingAccessWrapper::newFromObject( $vars ); + $name = 'foo'; + $tw->mVars = [ $name => 'INVALID TYPE' ]; + + $this->expectException( UnexpectedValueException::class ); + $tw->getVar( $name ); + } + + /** + * @param array $expected + * @param AbuseFilterVariableHolder ...$holders + * @dataProvider provideHoldersForAddition + * + * @covers AbuseFilterVariableHolder::addHolders + */ + public function testAddHolders( $expected, AbuseFilterVariableHolder ...$holders ) { + $actual = $this->getVariableHolder(); + $actual->addHolders( ...$holders ); + + $this->assertEquals( $expected, $actual->getVars() ); + } + + public function provideHoldersForAddition() { + $keywordsManager = new KeywordsManager( $this->createMock( AbuseFilterHookRunner::class ) ); + $v1 = AbuseFilterVariableHolder::newFromArray( [ 'a' => 1, 'b' => 2 ], $keywordsManager ); + $v2 = AbuseFilterVariableHolder::newFromArray( [ 'b' => 3, 'c' => 4 ], $keywordsManager ); + $v3 = AbuseFilterVariableHolder::newFromArray( [ 'c' => 5, 'd' => 6 ], $keywordsManager ); + + $expected = [ + 'a' => new AFPData( AFPData::DINT, 1 ), + 'b' => new AFPData( AFPData::DINT, 3 ), + 'c' => new AFPData( AFPData::DINT, 5 ), + 'd' => new AFPData( AFPData::DINT, 6 ) + ]; + + return [ [ $expected, $v1, $v2, $v3 ] ]; + } + + /** + * @covers AbuseFilterVariableHolder::varIsSet + */ + public function testVarIsSet() { + $vars = $this->getVariableHolder(); + $vars->setVar( 'foo', null ); + $this->assertTrue( $vars->varIsSet( 'foo' ), 'Set variable should be set' ); + $this->assertFalse( $vars->varIsSet( 'foobarbaz' ), 'Unset variable should be unset' ); + } + + /** + * @covers AbuseFilterVariableHolder::setLazyLoadVar + * @covers AbuseFilterVariableHolder::getLazyLoader + */ + public function testLazyLoader() { + $var = 'foobar'; + $method = 'compute-foo'; + $params = [ 'baz', 1 ]; + $exp = new AFComputedVariable( $method, $params ); + + $vars = $this->getVariableHolder(); + $vars->setLazyLoadVar( $var, $method, $params ); + $this->assertEquals( $exp, $vars->getVars()[$var] ); + } + + /** + * @covers AbuseFilterVariableHolder::exportAllVars + */ + public function testExportAllVars() { + $pairs = [ + 'foo' => 42, + 'bar' => [ 'bar', 'baz' ], + 'var' => false, + 'boo' => null + ]; + $keywordsManager = new KeywordsManager( $this->createMock( AbuseFilterHookRunner::class ) ); + $vars = AbuseFilterVariableHolder::newFromArray( $pairs, $keywordsManager ); + + $this->assertSame( $pairs, $vars->exportAllVars() ); + } + + /** + * @covers AbuseFilterVariableHolder::exportNonLazyVars + */ + public function testExportNonLazyVars() { + $keywordsManager = new KeywordsManager( $this->createMock( AbuseFilterHookRunner::class ) ); + $afcv = $this->createMock( AFComputedVariable::class ); + $pairs = [ + 'lazy1' => $afcv, + 'lazy2' => $afcv, + 'native1' => 42, + 'native2' => 'foo', + 'native3' => null, + 'afpd' => new AFPData( AFPData::DSTRING, 'hey' ), + ]; + $vars = AbuseFilterVariableHolder::newFromArray( $pairs, $keywordsManager ); + + $nonLazy = [ + 'native1' => '42', + 'native2' => 'foo', + 'native3' => '', + 'afpd' => 'hey' + ]; + + $this->assertSame( $nonLazy, $vars->exportNonLazyVars() ); + } + + /** + * @param AbuseFilterVariableHolder $vars + * @param array|bool $compute + * @param bool $includeUser + * @param array $expected + * @dataProvider provideDumpAllVars + * + * @covers AbuseFilterVariableHolder::dumpAllVars + */ + public function testDumpAllVars( $vars, $compute, $includeUser, $expected ) { + $this->assertEquals( $expected, $vars->dumpAllVars( $compute, $includeUser ) ); + } + + /** + * @return Generator|array + */ + public function provideDumpAllVars() { + $afcv = $this->getMockBuilder( AFComputedVariable::class ) + ->disableOriginalConstructor() + ->setMethods( [ 'compute' ] ); + + $preftitle = $afcv->getMock(); + $titleVal = 'title'; + $preftitle->method( 'compute' )->willReturn( new AFPData( AFPData::DSTRING, $titleVal ) ); + $lines = $afcv->getMock(); + $linesVal = 'lines'; + $lines->method( 'compute' )->willReturn( new AFPData( AFPData::DSTRING, $linesVal ) ); + $pairs = [ + 'page_title' => 'foo', + 'page_prefixedtitle' => $preftitle, + 'added_lines' => $lines, + 'user_name' => 'bar', + 'custom-var' => 'foo' + ]; + $keywordsManager = new KeywordsManager( $this->createMock( AbuseFilterHookRunner::class ) ); + $vars = AbuseFilterVariableHolder::newFromArray( $pairs, $keywordsManager ); + + $nonLazy = array_fill_keys( [ 'page_title', 'user_name', 'custom-var' ], 1 ); + $nonLazyExpect = array_intersect_key( $pairs, $nonLazy ); + yield 'lazy-loaded vars are excluded if not computed' => [ + clone $vars, + [], + true, + $nonLazyExpect + ]; + + $nonUserExpect = array_diff_key( $nonLazyExpect, [ 'custom-var' => 1 ] ); + yield 'user-set vars are excluded' => [ clone $vars, [], false, $nonUserExpect ]; + + $allExpect = $pairs; + $allExpect['page_prefixedtitle'] = $titleVal; + $allExpect['added_lines'] = $linesVal; + yield 'all vars computed' => [ clone $vars, true, true, $allExpect ]; + + $titleOnlyComputed = array_merge( $nonLazyExpect, [ 'page_prefixedtitle' => $titleVal ] ); + yield 'Only a specific var computed' => [ + clone $vars, + [ 'page_prefixedtitle' ], + true, + $titleOnlyComputed + ]; + } + + /** + * @covers AbuseFilterVariableHolder::computeDBVars + */ + public function testComputeDBVars() { + $afcv = $this->getMockBuilder( AFComputedVariable::class ) + ->disableOriginalConstructor() + ->setMethods( [ 'compute' ] ); + + $nonDBMet = [ 'unknown', 'certainly-not-db' ]; + $dbMet = [ 'page-age', 'user-rights', 'load-recent-authors' ]; + $methods = array_merge( $nonDBMet, $dbMet ); + $objs = []; + foreach ( $methods as $method ) { + $cur = $afcv->getMock(); + $cur->method( 'compute' )->willReturn( $method ); + $cur->mMethod = $method; + $objs[ $method ] = $cur; + } + + $keywordsManager = new KeywordsManager( $this->createMock( AbuseFilterHookRunner::class ) ); + $vars = AbuseFilterVariableHolder::newFromArray( $objs, $keywordsManager ); + $vars->computeDBVars(); + + $expAFCV = array_intersect_key( $vars->getVars(), array_fill_keys( $nonDBMet, 1 ) ); + $this->assertContainsOnlyInstancesOf( + AFComputedVariable::class, + $expAFCV, + "non-DB methods shouldn't have been computed" + ); + + $expComputed = array_intersect_key( $vars->getVars(), array_fill_keys( $dbMet, 1 ) ); + $this->assertContainsOnlyInstancesOf( + AFPData::class, + $expComputed, + 'DB methods should have been computed' + ); + } +} diff --git a/AbuseFilter/tests/selenium/.eslintrc.json b/AbuseFilter/tests/selenium/.eslintrc.json new file mode 100644 index 00000000..b27406cf --- /dev/null +++ b/AbuseFilter/tests/selenium/.eslintrc.json @@ -0,0 +1,6 @@ +{ + "root": true, + "extends": [ + "wikimedia/selenium" + ] +} diff --git a/AbuseFilter/tests/selenium/README.md b/AbuseFilter/tests/selenium/README.md new file mode 100644 index 00000000..efc0904e --- /dev/null +++ b/AbuseFilter/tests/selenium/README.md @@ -0,0 +1,33 @@ +# Selenium tests + +For more information see https://www.mediawiki.org/wiki/Selenium/Node.js and [PATH]/mediawiki/vagrant/mediawiki/tests/selenium/README.md. + +## Setup + +Set up MediaWiki-Vagrant: + + cd [PATH]/mediawiki/vagrant/mediawiki/extensions/AbuseFilter + vagrant up + vagrant roles enable abusefilter + vagrant provision + npm install + +Chromedriver has to run in one terminal window: + + chromedriver --url-base=wd/hub --port=4444 + +## Run all specs + +In another terminal window: + + npm run selenium-test + +## Run specific tests + +Filter by file name: + + 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] --mochaOpts.grep [TEST-NAME]
\ No newline at end of file diff --git a/AbuseFilter/tests/selenium/pageobjects/viewedit.page.js b/AbuseFilter/tests/selenium/pageobjects/viewedit.page.js new file mode 100644 index 00000000..558209ed --- /dev/null +++ b/AbuseFilter/tests/selenium/pageobjects/viewedit.page.js @@ -0,0 +1,52 @@ +'use strict'; + +const Page = require( 'wdio-mediawiki/Page' ); + +class ViewEditPage extends Page { + // Here we avoid things depending on the config, e.g. group and global + get filterId() { return $( '#mw-abusefilter-edit-id .mw-input' ); } + get name() { return $( 'input[name="wpFilterDescription"]' ); } + get rules() { return $( '#wpFilterRules' ); } + get comments() { return $( 'textarea[name="wpFilterNotes"]' ); } + get hidden() { return $( 'input[name="wpFilterHidden"]' ); } + get enabled() { return $( 'input[name="wpFilterEnabled"]' ); } + get deleted() { return $( 'input[name="wpFilterDeleted"]' ); } + + // @todo This assumes that warn is enabled in the config, which is true by default + get warnCheckbox() { return $( 'input[name="wpFilterActionWarn"]' ); } + get warnOtherMessage() { return $( 'input[name="wpFilterWarnMessageOther"]' ); } + + get submitButton() { return $( '#mw-abusefilter-editing-form input[type="submit"]' ); } + + get error() { return $( '.errorbox' ); } + get warning() { return $( '.warningbox' ); } + + submit() { + this.submitButton.waitForClickable(); + this.submitButton.click(); + } + + /** + * Conveniency: the ace editor is hard to manipulate, and working with + * the hidden textarea isn't great (sendKeys is not processed) + */ + switchEditor() { + const button = $( '#mw-abusefilter-switcheditor' ); + button.waitForClickable(); + button.click(); + } + + setWarningMessage( msg ) { + $( 'select[name="wpFilterWarnMessage"]' ).selectByAttribute( 'value', 'other' ); + this.warnOtherMessage.setValue( msg ); + } + + invalidateToken() { + $( '#mw-abusefilter-editing-form input[name="wpEditToken"]' ).setValue( '' ); + } + + open( subpage ) { + super.openTitle( 'Special:AbuseFilter/' + subpage ); + } +} +module.exports = new ViewEditPage(); diff --git a/AbuseFilter/tests/selenium/pageobjects/viewimport.page.js b/AbuseFilter/tests/selenium/pageobjects/viewimport.page.js new file mode 100644 index 00000000..4c3077a2 --- /dev/null +++ b/AbuseFilter/tests/selenium/pageobjects/viewimport.page.js @@ -0,0 +1,19 @@ +'use strict'; + +const Page = require( 'wdio-mediawiki/Page' ); + +class ViewImportPage extends Page { + get importData() { return $( 'textarea[name="wpImportText"]' ); } + get submit() { return $( 'button[type="submit"]' ); } + + importText( text ) { + this.open(); + this.importData.setValue( text ); + this.submit.click(); + } + + open() { + super.openTitle( 'Special:AbuseFilter/import' ); + } +} +module.exports = new ViewImportPage(); diff --git a/AbuseFilter/tests/selenium/pageobjects/viewlist.page.js b/AbuseFilter/tests/selenium/pageobjects/viewlist.page.js new file mode 100644 index 00000000..44484c64 --- /dev/null +++ b/AbuseFilter/tests/selenium/pageobjects/viewlist.page.js @@ -0,0 +1,27 @@ +'use strict'; + +const Page = require( 'wdio-mediawiki/Page' ); + +class ViewListPage extends Page { + get title() { return $( '#firstHeading' ); } + get newFilterButton() { return $( '.oo-ui-buttonElement a' ); } + + get filterSavedNotice() { return $( '.success' ); } + + get savedFilterID() { + const succesMsg = this.filterSavedNotice.getHTML(), + regexp = /\/history\/(\d+)\//; + return regexp.exec( succesMsg )[ 1 ]; + } + + get savedFilterHistoryID() { + const succesMsg = this.filterSavedNotice.getHTML(), + regexp = /\/diff\/prev\/(\d+)/; + return regexp.exec( succesMsg )[ 1 ]; + } + + open() { + super.openTitle( 'Special:AbuseFilter' ); + } +} +module.exports = new ViewListPage(); diff --git a/AbuseFilter/tests/selenium/specs/ViewList.basic.js b/AbuseFilter/tests/selenium/specs/ViewList.basic.js new file mode 100644 index 00000000..cd9b03fe --- /dev/null +++ b/AbuseFilter/tests/selenium/specs/ViewList.basic.js @@ -0,0 +1,21 @@ +'use strict'; + +const assert = require( 'assert' ), + LoginPage = require( 'wdio-mediawiki/LoginPage' ), + ViewListPage = require( '../pageobjects/viewlist.page' ); + +describe( 'Special:AbuseFilter', function () { + it( 'page should exist on installation', function () { + ViewListPage.open(); + assert.equal( ViewListPage.title.getText(), 'Abuse filter management' ); + } ); + it( 'page should have the button for creating a new filter', function () { + LoginPage.loginAdmin(); + ViewListPage.open(); + assert.equal( ViewListPage.newFilterButton.getText(), 'Create a new filter' ); + assert.notEqual( + ViewListPage.newFilterButton.getAttribute( 'href' ).indexOf( 'Special:AbuseFilter/new' ), + -1 + ); + } ); +} ); diff --git a/AbuseFilter/tests/selenium/specs/editingFilters.js b/AbuseFilter/tests/selenium/specs/editingFilters.js new file mode 100644 index 00000000..34e83d57 --- /dev/null +++ b/AbuseFilter/tests/selenium/specs/editingFilters.js @@ -0,0 +1,141 @@ +'use strict'; + +const assert = require( 'assert' ), + LoginPage = require( 'wdio-mediawiki/LoginPage' ), + ViewEditPage = require( '../pageobjects/viewedit.page' ), + ViewListPage = require( '../pageobjects/viewlist.page' ); + +describe( 'Filter editing', function () { + describe( 'The editing interface', function () { + it( 'is not visible to logged-out users', function () { + ViewEditPage.open( 'new' ); + assert( ViewEditPage.error.isDisplayed() ); + } ); + + it( 'is visible to logged-in admins', function () { + LoginPage.loginAdmin(); + ViewEditPage.open( 'new' ); + assert( ViewEditPage.name.isDisplayed() ); + } ); + } ); + + describe( 'Trying to open a non-existing filter', function () { + it( 'I should receive an error', function () { + ViewEditPage.open( 1234567 ); + assert( ViewEditPage.error.isDisplayed() ); + } ); + } ); + + const filterSpecs = { + name: 'My test filter', + rules: '"confirmed" in user_groups & true === false', + comments: 'Some notes', + warnMsg: 'abusefilter-warning-foobar' + }; + let filterID, historyID; + + function assertFirstVersionSaved() { + assert.strictEqual( ViewEditPage.name.getValue(), filterSpecs.name ); + assert.strictEqual( ViewEditPage.rules.getValue(), filterSpecs.rules + '\n' ); + assert.strictEqual( ViewEditPage.comments.getValue(), filterSpecs.comments + '\n' ); + ViewEditPage.warnCheckbox.isSelected(); + assert.strictEqual( ViewEditPage.warnOtherMessage.getValue(), filterSpecs.warnMsg ); + } + + describe( 'Creating a new filter', function () { + before( function () { + ViewEditPage.open( 'new' ); + } ); + + it( 'edit can be saved (1)', function () { + ViewEditPage.switchEditor(); + + ViewEditPage.name.setValue( filterSpecs.name ); + ViewEditPage.rules.setValue( filterSpecs.rules ); + ViewEditPage.comments.setValue( filterSpecs.comments ); + ViewEditPage.warnCheckbox.click(); + ViewEditPage.setWarningMessage( filterSpecs.warnMsg ); + + ViewEditPage.submit(); + assert( ViewListPage.filterSavedNotice.isDisplayed() ); + filterID = ViewListPage.savedFilterID; + assert.ok( filterID ); + historyID = ViewListPage.savedFilterHistoryID; + assert.ok( historyID ); + } ); + + it( 'saved data is retained (1)', function () { + ViewEditPage.open( filterID ); + assertFirstVersionSaved(); + } ); + } ); + + describe( 'Editing an existing filter', function () { + const newName = 'New filter name', + newNotes = 'More filter notes'; + + it( 'edit can be saved (2)', function () { + ViewEditPage.name.setValue( newName ); + ViewEditPage.comments.addValue( newNotes ); + ViewEditPage.submit(); + assert( ViewListPage.filterSavedNotice.isDisplayed() ); + } ); + + it( 'saved data is retained (2)', function () { + ViewEditPage.open( filterID ); + assert.strictEqual( ViewEditPage.name.getValue(), newName ); + assert.strictEqual( ViewEditPage.comments.getValue(), newNotes + filterSpecs.comments + '\n' ); + } ); + } ); + + describe( 'Restoring an old version of a filter', function () { + it( 'edit can be saved (3)', function () { + ViewEditPage.open( 'history/' + filterID + '/item/' + historyID ); + ViewEditPage.submit(); + assert( ViewListPage.filterSavedNotice.isDisplayed() ); + } ); + + it( 'saved data is retained (3)', function () { + ViewEditPage.open( filterID ); + assertFirstVersionSaved(); + } ); + } ); + + describe( 'CSRF protection', function () { + const filterName = 'Testing CSRF'; + + it( 'a CSRF token is required to save the filter', function () { + ViewEditPage.invalidateToken(); + ViewEditPage.name.setValue( filterName ); + ViewEditPage.submit(); + assert( ViewEditPage.warning.isDisplayed() ); + } ); + it( 'even if the token is invalid, the ongoing edit is not lost', function () { + assert.strictEqual( ViewEditPage.name.getValue(), filterName ); + } ); + } ); + + describe( 'Trying to save a filter with bad data', function () { + before( function () { + ViewEditPage.open( 'new' ); + } ); + + it( 'cannot save an empty filter', function () { + ViewEditPage.submit(); + assert( ViewEditPage.error.isDisplayed() ); + } ); + + const rules = 'null'; + + it( 'cannot save a filter with rules but no name', function () { + ViewEditPage.switchEditor(); + ViewEditPage.rules.setValue( rules ); + ViewEditPage.submit(); + assert( ViewEditPage.error.isDisplayed() ); + } ); + + it( 'data is retained if saving fails', function () { + assert.strictEqual( ViewEditPage.rules.getValue(), rules + '\n' ); + } ); + } ); +} ); diff --git a/AbuseFilter/tests/selenium/specs/importingFilters.js b/AbuseFilter/tests/selenium/specs/importingFilters.js new file mode 100644 index 00000000..6a4e1fd6 --- /dev/null +++ b/AbuseFilter/tests/selenium/specs/importingFilters.js @@ -0,0 +1,73 @@ +'use strict'; + +const assert = require( 'assert' ), + LoginPage = require( 'wdio-mediawiki/LoginPage' ), + ViewEditPage = require( '../pageobjects/viewedit.page' ), + ViewListPage = require( '../pageobjects/viewlist.page' ), + ViewImportPage = require( '../pageobjects/viewimport.page' ); + +describe( 'When importing a filter', function () { + const filterSpecs = { + name: 'My filter name', + comments: 'Notes go here.', + rules: 'true === false', + enabled: 1, + hidden: 1, + deleted: 0 + }, + warnMessage = 'abusefilter-warning-foobar'; + + function getImportData() { + return `{"row":{"af_id":"242","af_pattern":"${filterSpecs.rules}","af_user":"1","af_user_text":\ +"Daimona Eaytoy","af_timestamp":"20200924132008","af_enabled":"${filterSpecs.enabled}","af_comments":"\ +${filterSpecs.comments}","af_public_comments":"${filterSpecs.name}","af_hidden":"${filterSpecs.hidden}",\ +"af_hit_count":"0","af_throttled":"0","af_deleted":"${filterSpecs.deleted}","af_actions":"warn","af_global":\ +"0","af_group":"default"},"actions":{"warn":["${warnMessage}"]}}`; + } + + before( function () { + LoginPage.loginAdmin(); + } ); + + it( 'the interface should be visible', function () { + ViewImportPage.open(); + assert( ViewImportPage.importData.isDisplayed() ); + } ); + + it( 'it should redirect to ViewEdit after submission', function () { + ViewImportPage.importText( 'SOME INVALID GIBBERISH' ); + assert( /\/new$/.test( browser.getUrl() ) ); + } ); + + it( 'bad data results in an error', function () { + assert( ViewEditPage.error.isDisplayed() ); + } ); + + it( 'valid data shows the editing interface', function () { + ViewImportPage.open(); + ViewImportPage.importText( getImportData() ); + assert( ViewEditPage.name.isDisplayed() ); + } ); + + describe( 'Data on the editing interface is correct', function () { + it( 'filter specs are copied', function () { + assert.strictEqual( ViewEditPage.name.getValue(), filterSpecs.name ); + assert.strictEqual( ViewEditPage.comments.getValue(), filterSpecs.comments + '\n' ); + assert.strictEqual( ViewEditPage.rules.getValue(), filterSpecs.rules + '\n' ); + } ); + it( 'filter flags are copied', function () { + assert.strictEqual( ViewEditPage.enabled.isSelected(), !!filterSpecs.enabled ); + assert.strictEqual( ViewEditPage.hidden.isSelected(), !!filterSpecs.hidden ); + assert.strictEqual( ViewEditPage.deleted.isSelected(), !!filterSpecs.deleted ); + } ); + it( 'filter actions are copied', function () { + assert.strictEqual( ViewEditPage.warnCheckbox.isSelected(), true ); + assert.strictEqual( ViewEditPage.warnOtherMessage.getValue(), warnMessage ); + } ); + + it( 'the imported data can be saved', function () { + ViewEditPage.submit(); + assert( ViewListPage.filterSavedNotice.isDisplayed() ); + } ); + } ); +} ); diff --git a/AbuseFilter/tests/selenium/wdio.conf.js b/AbuseFilter/tests/selenium/wdio.conf.js new file mode 100644 index 00000000..29346a2f --- /dev/null +++ b/AbuseFilter/tests/selenium/wdio.conf.js @@ -0,0 +1,90 @@ +/** + * See also: http://webdriver.io/guide/testrunner/configurationfile.html + */ + +'use strict'; + +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 capturing 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' ); + } + } +}; diff --git a/AbuseFilter/version b/AbuseFilter/version deleted file mode 100644 index 8e3b7f7f..00000000 --- a/AbuseFilter/version +++ /dev/null @@ -1,4 +0,0 @@ -AbuseFilter: REL1_32 -2019-03-17T10:00:20 - -01df828 |