This run took 40 seconds.
From 0147d9bbefb6323eb23c632b06d1f43c3e0fc3f4 Mon Sep 17 00:00:00 2001
From: libraryupgrader <tools.libraryupgrader@tools.wmflabs.org>
Date: Fri, 28 Nov 2025 06:24:22 +0000
Subject: [PATCH] build: Updating eslint-config-wikimedia to 0.32.2
Change-Id: Ie18e6822f10a6218a729c1018ea2c53a91f56931
---
package-lock.json | 14 +++++++-------
package.json | 2 +-
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 1c709ca..831f847 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6,7 +6,7 @@
"": {
"name": "InlineCategorizer",
"devDependencies": {
- "eslint-config-wikimedia": "0.32.1",
+ "eslint-config-wikimedia": "0.32.2",
"grunt": "1.6.1",
"grunt-banana-checker": "0.13.0",
"grunt-eslint": "24.3.0"
@@ -1124,9 +1124,9 @@
}
},
"node_modules/eslint-config-wikimedia": {
- "version": "0.32.1",
- "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.32.1.tgz",
- "integrity": "sha512-gPvhyVFNlpKFOcJfoVTNlzg3A0b6qjhAbjjBIJ9xp5m+om0oqix5gkqIIEav5BaGxdDxYNmrY4ge3DAPP3u/lg==",
+ "version": "0.32.2",
+ "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.32.2.tgz",
+ "integrity": "sha512-vAGz50AJPk23qQ701sL4tAgaF8FEAkP/E3kgojSTVrGgmDqjnRvq8z3EItDNI/EAkb5Ys15WPPFsoBH8YhTdSg==",
"dev": true,
"dependencies": {
"@stylistic/eslint-plugin": "^3.1.0",
@@ -4642,9 +4642,9 @@
}
},
"eslint-config-wikimedia": {
- "version": "0.32.1",
- "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.32.1.tgz",
- "integrity": "sha512-gPvhyVFNlpKFOcJfoVTNlzg3A0b6qjhAbjjBIJ9xp5m+om0oqix5gkqIIEav5BaGxdDxYNmrY4ge3DAPP3u/lg==",
+ "version": "0.32.2",
+ "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.32.2.tgz",
+ "integrity": "sha512-vAGz50AJPk23qQ701sL4tAgaF8FEAkP/E3kgojSTVrGgmDqjnRvq8z3EItDNI/EAkb5Ys15WPPFsoBH8YhTdSg==",
"dev": true,
"requires": {
"@stylistic/eslint-plugin": "^3.1.0",
diff --git a/package.json b/package.json
index 988357f..33ecef2 100644
--- a/package.json
+++ b/package.json
@@ -5,7 +5,7 @@
"test": "grunt test"
},
"devDependencies": {
- "eslint-config-wikimedia": "0.32.1",
+ "eslint-config-wikimedia": "0.32.2",
"grunt": "1.6.1",
"grunt-banana-checker": "0.13.0",
"grunt-eslint": "24.3.0"
--
2.47.3
$ date
--- stdout ---
Fri Nov 28 06:23:52 UTC 2025
--- end ---
$ git clone file:///srv/git/mediawiki-extensions-InlineCategorizer.git repo --depth=1 -b master
--- stderr ---
Cloning into 'repo'...
--- stdout ---
--- end ---
$ git config user.name libraryupgrader
--- stdout ---
--- end ---
$ git config user.email tools.libraryupgrader@tools.wmflabs.org
--- stdout ---
--- end ---
$ git submodule update --init
--- stdout ---
--- end ---
$ grr init
--- stdout ---
Installed commit-msg hook.
--- end ---
$ git show-ref refs/heads/master
--- stdout ---
498bacec63fb455b5fa93ad95ce7f75f767f0a69 refs/heads/master
--- end ---
$ /usr/bin/npm audit --json
--- stdout ---
{
"auditReportVersion": 2,
"vulnerabilities": {},
"metadata": {
"vulnerabilities": {
"info": 0,
"low": 0,
"moderate": 0,
"high": 0,
"critical": 0,
"total": 0
},
"dependencies": {
"prod": 1,
"dev": 318,
"optional": 0,
"peer": 1,
"peerOptional": 0,
"total": 318
}
}
}
--- end ---
$ /usr/bin/composer install
--- stderr ---
No composer.lock file present. Updating dependencies to latest instead of installing from lock file. See https://getcomposer.org/install for more information.
Loading composer repositories with package information
Updating dependencies
Lock file operations: 38 installs, 0 updates, 0 removals
- Locking composer/pcre (3.3.2)
- Locking composer/semver (3.4.4)
- Locking composer/spdx-licenses (1.5.9)
- Locking composer/xdebug-handler (3.0.5)
- Locking dealerdirect/phpcodesniffer-composer-installer (v1.2.0)
- Locking doctrine/deprecations (1.1.5)
- Locking felixfbecker/advanced-json-rpc (v3.2.1)
- Locking mediawiki/mediawiki-codesniffer (v48.0.0)
- Locking mediawiki/mediawiki-phan-config (0.17.0)
- Locking mediawiki/minus-x (1.1.3)
- Locking mediawiki/phan-taint-check-plugin (7.0.0)
- Locking microsoft/tolerant-php-parser (v0.1.2)
- Locking netresearch/jsonmapper (v4.5.0)
- Locking phan/phan (5.5.1)
- Locking php-parallel-lint/php-console-color (v1.0.1)
- Locking php-parallel-lint/php-console-highlighter (v1.0.0)
- Locking php-parallel-lint/php-parallel-lint (v1.4.0)
- Locking phpcsstandards/phpcsextra (1.4.0)
- Locking phpcsstandards/phpcsutils (1.1.1)
- Locking phpdocumentor/reflection-common (2.2.0)
- Locking phpdocumentor/reflection-docblock (5.6.5)
- Locking phpdocumentor/type-resolver (1.12.0)
- Locking phpstan/phpdoc-parser (2.3.0)
- Locking psr/container (2.0.2)
- Locking psr/log (3.0.2)
- Locking sabre/event (5.1.7)
- Locking squizlabs/php_codesniffer (3.13.2)
- Locking symfony/console (v7.4.0)
- Locking symfony/deprecation-contracts (v3.6.0)
- Locking symfony/polyfill-ctype (v1.33.0)
- Locking symfony/polyfill-intl-grapheme (v1.33.0)
- Locking symfony/polyfill-intl-normalizer (v1.33.0)
- Locking symfony/polyfill-mbstring (v1.33.0)
- Locking symfony/polyfill-php80 (v1.33.0)
- Locking symfony/service-contracts (v3.6.1)
- Locking symfony/string (v8.0.0)
- Locking tysonandre/var_representation_polyfill (0.1.3)
- Locking webmozart/assert (1.12.1)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 38 installs, 0 updates, 0 removals
0 [>---------------------------] 0 [->--------------------------]
- Installing squizlabs/php_codesniffer (3.13.2): Extracting archive
- Installing dealerdirect/phpcodesniffer-composer-installer (v1.2.0): Extracting archive
- Installing composer/pcre (3.3.2): Extracting archive
- Installing phpcsstandards/phpcsutils (1.1.1): Extracting archive
- Installing phpcsstandards/phpcsextra (1.4.0): Extracting archive
- Installing symfony/polyfill-mbstring (v1.33.0): Extracting archive
- Installing composer/spdx-licenses (1.5.9): Extracting archive
- Installing composer/semver (3.4.4): Extracting archive
- Installing mediawiki/mediawiki-codesniffer (v48.0.0): Extracting archive
- Installing tysonandre/var_representation_polyfill (0.1.3): Extracting archive
- Installing symfony/polyfill-php80 (v1.33.0): Extracting archive
- Installing symfony/polyfill-intl-normalizer (v1.33.0): Extracting archive
- Installing symfony/polyfill-intl-grapheme (v1.33.0): Extracting archive
- Installing symfony/polyfill-ctype (v1.33.0): Extracting archive
- Installing symfony/string (v8.0.0): Extracting archive
- Installing symfony/deprecation-contracts (v3.6.0): Extracting archive
- Installing psr/container (2.0.2): Extracting archive
- Installing symfony/service-contracts (v3.6.1): Extracting archive
- Installing symfony/console (v7.4.0): Extracting archive
- Installing sabre/event (5.1.7): Extracting archive
- Installing netresearch/jsonmapper (v4.5.0): Extracting archive
- Installing microsoft/tolerant-php-parser (v0.1.2): Extracting archive
- Installing webmozart/assert (1.12.1): Extracting archive
- Installing phpstan/phpdoc-parser (2.3.0): Extracting archive
- Installing phpdocumentor/reflection-common (2.2.0): Extracting archive
- Installing doctrine/deprecations (1.1.5): Extracting archive
- Installing phpdocumentor/type-resolver (1.12.0): Extracting archive
- Installing phpdocumentor/reflection-docblock (5.6.5): Extracting archive
- Installing felixfbecker/advanced-json-rpc (v3.2.1): Extracting archive
- Installing psr/log (3.0.2): Extracting archive
- Installing composer/xdebug-handler (3.0.5): Extracting archive
- Installing phan/phan (5.5.1): Extracting archive
- Installing mediawiki/phan-taint-check-plugin (7.0.0): Extracting archive
- Installing mediawiki/mediawiki-phan-config (0.17.0): Extracting archive
- Installing mediawiki/minus-x (1.1.3): Extracting archive
- Installing php-parallel-lint/php-console-color (v1.0.1): Extracting archive
- Installing php-parallel-lint/php-console-highlighter (v1.0.0): Extracting archive
- Installing php-parallel-lint/php-parallel-lint (v1.4.0): Extracting archive
0/36 [>---------------------------] 0%
28/36 [=====================>------] 77%
35/36 [===========================>] 97%
36/36 [============================] 100%
1 package suggestions were added by new dependencies, use `composer suggest` to see details.
Generating autoload files
17 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
--- stdout ---
PHP CodeSniffer Config installed_paths set to ../../mediawiki/mediawiki-codesniffer,../../phpcsstandards/phpcsextra,../../phpcsstandards/phpcsutils
--- end ---
Upgrading n:eslint-config-wikimedia from 0.32.1 -> 0.32.2
$ /usr/bin/npm install
--- stdout ---
added 318 packages, and audited 319 packages in 4s
68 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
--- end ---
$ package-lock-lint /src/repo/package-lock.json
--- stdout ---
Checking /src/repo/package-lock.json
--- end ---
$ /usr/bin/npm install grunt-eslint@24.3.0 --save-exact
--- stdout ---
up to date, audited 319 packages in 996ms
68 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
--- end ---
$ package-lock-lint /src/repo/package-lock.json
--- stdout ---
Checking /src/repo/package-lock.json
--- end ---
$ ./node_modules/.bin/eslint . --fix
--- stdout ---
/src/repo/modules/ext.inlineCategorizer.core.js
19:16 warning Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible no-jquery/no-global-selector
20:22 warning Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible no-jquery/no-global-selector
33:22 warning Unexpected control character(s) in regular expression: \x00, \x1f no-control-regex
50:10 warning Prefer `String#slice()` over `String#substring()` unicorn/prefer-string-slice
174:63 warning Unexpected string concatenation of literals no-useless-concat
174:69 warning Unexpected string concatenation of literals no-useless-concat
174:105 warning Unexpected string concatenation of literals no-useless-concat
215:28 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign
317:20 warning Where possible, maintain application state in JS to avoid slower DOM queries no-jquery/no-class-state
351:34 warning Where possible, maintain application state in JS to avoid slower DOM queries no-jquery/no-class-state
371:29 warning Prefer Array#filter to $.grep no-jquery/no-grep
383:25 warning Prefer Array#filter to $.grep no-jquery/no-grep
442:4 warning Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible no-jquery/no-global-selector
593:6 warning Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible no-jquery/no-global-selector
901:6 warning Prefer Array#forEach to $.each no-jquery/no-each-util
1122:23 warning Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible no-jquery/no-global-selector
✖ 16 problems (0 errors, 16 warnings)
--- end ---
$ ./node_modules/.bin/eslint . -f json
--- stdout ---
[{"filePath":"/src/repo/.eslintrc.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/Gruntfile.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/bundlesize.config.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/composer.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/extension.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/i18n/en.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/i18n/qqq.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/modules/.eslintrc.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"indent","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/modules/ext.inlineCategorizer.core.js","messages":[{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":19,"column":16,"nodeType":"CallExpression","endLine":19,"endColumn":32},{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":20,"column":22,"nodeType":"CallExpression","endLine":20,"endColumn":48},{"ruleId":"no-control-regex","severity":1,"message":"Unexpected control character(s) in regular expression: \\x00, \\x1f.","line":33,"column":22,"nodeType":"Literal","messageId":"unexpected","endLine":33,"endColumn":75},{"ruleId":"unicorn/prefer-string-slice","severity":1,"message":"Prefer `String#slice()` over `String#substring()`.","line":50,"column":10,"nodeType":"CallExpression","messageId":"substring","endLine":50,"endColumn":36},{"ruleId":"no-useless-concat","severity":1,"message":"Unexpected string concatenation of literals.","line":174,"column":63,"nodeType":"BinaryExpression","messageId":"unexpectedConcat","endLine":174,"endColumn":64},{"ruleId":"no-useless-concat","severity":1,"message":"Unexpected string concatenation of literals.","line":174,"column":69,"nodeType":"BinaryExpression","messageId":"unexpectedConcat","endLine":174,"endColumn":70},{"ruleId":"no-useless-concat","severity":1,"message":"Unexpected string concatenation of literals.","line":174,"column":105,"nodeType":"BinaryExpression","messageId":"unexpectedConcat","endLine":174,"endColumn":106},{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":215,"column":28,"nodeType":"MemberExpression","messageId":"forbidden","endLine":215,"endColumn":41},{"ruleId":"no-jquery/no-class-state","severity":1,"message":"Where possible, maintain application state in JS to avoid slower DOM queries","line":317,"column":20,"nodeType":"CallExpression","endLine":317,"endColumn":57},{"ruleId":"no-jquery/no-class-state","severity":1,"message":"Where possible, maintain application state in JS to avoid slower DOM queries","line":351,"column":34,"nodeType":"CallExpression","endLine":351,"endColumn":71},{"ruleId":"no-jquery/no-grep","severity":1,"message":"Prefer Array#filter to $.grep","line":371,"column":29,"nodeType":"CallExpression","endLine":371,"endColumn":83},{"ruleId":"no-jquery/no-grep","severity":1,"message":"Prefer Array#filter to $.grep","line":383,"column":25,"nodeType":"CallExpression","endLine":383,"endColumn":74},{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":442,"column":4,"nodeType":"CallExpression","endLine":442,"endColumn":20},{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":593,"column":6,"nodeType":"CallExpression","endLine":593,"endColumn":33},{"ruleId":"no-jquery/no-each-util","severity":1,"message":"Prefer Array#forEach to $.each","line":901,"column":6,"nodeType":"CallExpression","endLine":940,"endColumn":9},{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":1122,"column":23,"nodeType":"CallExpression","endLine":1122,"endColumn":53}],"suppressedMessages":[{"ruleId":"mediawiki/class-doc","severity":2,"message":"All possible CSS classes should be documented. See https://w.wiki/PS2 for details.","line":192,"column":19,"nodeType":"CallExpression","endLine":193,"endColumn":32,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"mediawiki/class-doc","severity":2,"message":"All possible CSS classes should be documented. See https://w.wiki/PS2 for details.","line":198,"column":18,"nodeType":"CallExpression","endLine":198,"endColumn":58,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"mediawiki/class-doc","severity":2,"message":"All possible CSS classes should be documented. See https://w.wiki/PS2 for details.","line":202,"column":4,"nodeType":"CallExpression","endLine":202,"endColumn":38,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":16,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*!\n * The core of InlineCategorizer\n *\n * @author Michael Dale, 2009\n * @author Leo Koppelkamm, 2011\n * @author Timo Tijhof, 2011\n */\n\n( function () {\n\n\t/* Local scope */\n\n\tconst catNsId = mw.config.get( 'wgNamespaceIds' ).category;\n\tconst isCatNsSensitive = mw.config.get( 'wgCaseSensitiveNamespaces' ).includes( catNsId );\n\n\tfunction getDefaultOptions() {\n\t\treturn {\n\t\t\tcatLinkWrapper: '<li>',\n\t\t\t$container: $( '.catlinks' ),\n\t\t\t$containerNormal: $( '#mw-normal-catlinks' ),\n\t\t\tcategoryLinkSelector: 'li a:not(.icon)',\n\t\t\tmultiEdit: mw.config.get( 'wgUserGroups', [] ).includes( 'user' ),\n\t\t\tresolveRedirects: true\n\t\t};\n\t}\n\n\t/**\n\t * @param {string} s\n\t * @return {string}\n\t */\n\tfunction clean( s ) {\n\t\tif ( typeof s === 'string' ) {\n\t\t\treturn s.replace( /[\\x00-\\x1f\\x23\\x3c\\x3e\\x5b\\x5d\\x7b\\x7c\\x7d\\x7f\\s]+/g, '' );\n\t\t}\n\t\treturn '';\n\t}\n\n\t/**\n\t * Generates a random id out of 62 alpha-numeric characters.\n\t *\n\t * @param {number} idLength Length of id (optional, defaults to 32)\n\t * @return {string}\n\t */\n\tfunction generateRandomId( idLength ) {\n\t\tidLength = typeof idLength === 'number' ? idLength : 32;\n\t\tconst seed = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';\n\t\tlet id = '';\n\t\tfor ( let i = 0; i < idLength; i++ ) {\n\t\t\tconst r = Math.floor( Math.random() * seed.length );\n\t\t\tid += seed.substring( r, r + 1 );\n\t\t}\n\t\treturn id;\n\t}\n\n\t/**\n\t * Helper function for $.fn.suggestions\n\t *\n\t * @this {jQuery}\n\t * @param {string} value Textbox value.\n\t */\n\tfunction fetchSuggestions( value ) {\n\t\tconst $el = this;\n\t\tconst catName = clean( value );\n\t\tconst request = $.ajax( {\n\t\t\turl: mw.util.wikiScript( 'api' ),\n\t\t\tdata: {\n\t\t\t\taction: 'query',\n\t\t\t\tlist: 'allpages',\n\t\t\t\tapnamespace: catNsId,\n\t\t\t\tapprefix: catName,\n\t\t\t\tformat: 'json'\n\t\t\t},\n\t\t\tdataType: 'json',\n\t\t\tsuccess: function ( data ) {\n\t\t\t\t// Process data.query.allpages into an array of titles\n\t\t\t\tconst pages = data.query.allpages;\n\t\t\t\tconst titleArr = pages.map( ( page ) => new mw.Title( page.title ).getMainText() );\n\n\t\t\t\t$el.suggestions( 'suggestions', titleArr );\n\t\t\t}\n\t\t} );\n\t\t$el.data( 'suggestions-request', request );\n\t}\n\n\t/**\n\t * Replace <nowiki> and comments with unique keys in the page text.\n\t *\n\t * @param {string} text\n\t * @param {string} id Unique key for this nowiki replacement layer call.\n\t * @param {Array} keys Array where fragments will be stored in.\n\t * @return {string}\n\t */\n\tfunction replaceNowikis( text, id, keys ) {\n\t\tconst matches = text.match( /(<nowiki>[\\s\\S]*?<\\/nowiki>|<!--[\\s\\S]*?-->)/g );\n\t\tif ( matches ) {\n\t\t\tfor ( let i = 0; i < matches.length; i++ ) {\n\t\t\t\tkeys[ i ] = matches[ i ];\n\t\t\t\ttext = text.replace( matches[ i ], String( id ) + '-' + i );\n\t\t\t}\n\t\t}\n\t\treturn text;\n\t}\n\n\t/**\n\t * Restore <nowiki> and comments from unique keys in the page text.\n\t *\n\t * @param {string} text\n\t * @param {string} id Unique key of the layer to be restored, as passed to replaceNowikis().\n\t * @param {Array} keys Array where fragements should be fetched from.\n\t * @return {string}\n\t */\n\tfunction restoreNowikis( text, id, keys ) {\n\t\tfor ( let i = 0; i < keys.length; i++ ) {\n\t\t\ttext = text.replace( String( id ) + '-' + i, keys[ i ] );\n\t\t}\n\t\treturn text;\n\t}\n\n\t/**\n\t * Make string to case-insensitive RegExp string.\n\t * Useful when 'i' flag can't be used.\n\t * Return stuff like [Ff][Oo][Oo]\n\t * TODO: Support characters outside of the Unicode BMP\n\t *\n\t * @param {string} string String for RegExp\n\t * @return {string} Processed RegExp string\n\t */\n\tfunction makeCaseInsensitive( string ) {\n\t\tlet newString = '';\n\t\tfor ( let i = 0; i < string.length; i++ ) {\n\t\t\tconst char = string.charAt( i );\n\t\t\tconst upper = char.toUpperCase();\n\t\t\tconst lower = char.toLowerCase();\n\t\t\tnewString += upper === lower ?\n\t\t\t\t// Escape special RegExp characters\n\t\t\t\tmw.util.escapeRegExp( char ) :\n\t\t\t\t// Escaping of special RegExp characters is not needed\n\t\t\t\t// because they never have upper !== lower.\n\t\t\t\t'[' + upper + lower + ']';\n\t\t}\n\t\treturn newString;\n\t}\n\n\t/**\n\t * Build a regex that matches legal invocations of the passed category.\n\t *\n\t * @param {string} category\n\t * @param {boolean} matchLineBreak Match one following linebreak as well?\n\t * @return {RegExp}\n\t */\n\tfunction buildRegex( category, matchLineBreak ) {\n\t\t// Filter out all names for category namespace\n\t\tconst namespaceIds = mw.config.get( 'wgNamespaceIds' );\n\t\tconst categoryNames = [];\n\t\tfor ( const name in namespaceIds ) {\n\t\t\tconst id = namespaceIds[ name ];\n\t\t\tif ( id === catNsId ) {\n\t\t\t\tcategoryNames.push( !isCatNsSensitive ?\n\t\t\t\t\tmakeCaseInsensitive( name ) :\n\t\t\t\t\tmw.util.escapeRegExp( name )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tconst categoryNSFragment = '(' + categoryNames.join( '|' ) + ')';\n\n\t\t// Ignore case of the first character of the category name.\n\t\tconst titleFragment = (\n\t\t\tmakeCaseInsensitive( category.charAt( 0 ) ) +\n\t\t\tmw.util.escapeRegExp( category.slice( 1 ) )\n\t\t)\n\t\t\t// Support ' ' and '_' as space.\n\t\t\t.replace( /( |_)/g, '[ _]' );\n\n\t\tlet categoryRegex = '\\\\[\\\\[' + categoryNSFragment + '[ _]*' + ':' + '[ _]*' + titleFragment + '[ _]*' + '(\\\\|[^\\\\]]*)?\\\\]\\\\]';\n\t\tif ( matchLineBreak ) {\n\t\t\tcategoryRegex += '[ \\\\t\\\\r]*\\\\n?';\n\t\t}\n\t\treturn new RegExp( categoryRegex, 'g' );\n\t}\n\n\t/**\n\t * Manufacture iconed button, with or without text.\n\t *\n\t * @param {string} icon The icon class\n\t * @param {string} title Title attribute\n\t * @param {string} [className] Additional classes to be added to the button\n\t * @param {string} [text] Text label of button\n\t * @return {jQuery} The button\n\t */\n\tfunction createButton( icon, title, className, text ) {\n\t\t// eslint-disable-next-line mediawiki/class-doc\n\t\tconst $button = $( '<a>' )\n\t\t\t.addClass( className || '' )\n\t\t\t.attr( 'title', title );\n\n\t\tif ( text ) {\n\t\t\t// eslint-disable-next-line mediawiki/class-doc\n\t\t\tconst $icon = $( '<span>' ).addClass( 'icon ' + icon );\n\t\t\t$button.addClass( 'icon-parent' ).text( text ).prepend( $icon );\n\t\t} else {\n\t\t\t// eslint-disable-next-line mediawiki/class-doc\n\t\t\t$button.addClass( 'icon ' + icon );\n\t\t}\n\t\treturn $button;\n\t}\n\n\t/**\n\t * mw.InlineCategorizer\n\t *\n\t * @constructor\n\t * @param {Object} options\n\t */\n\tmw.InlineCategorizer = function ( options ) {\n\n\t\tthis.options = options = Object.assign( getDefaultOptions(), options );\n\n\t\t// Save scope in shortcut\n\t\tconst ajaxcat = this;\n\n\t\t// Elements tied to this instance\n\t\tthis.saveAllButton = null;\n\t\tthis.cancelAllButton = null;\n\t\tthis.addContainer = null;\n\n\t\tthis.request = null;\n\n\t\t// Stash and hooks\n\t\tthis.stash = {\n\t\t\tdialogDescriptions: [],\n\t\t\teditSummaries: [],\n\t\t\tfns: []\n\t\t};\n\t\tthis.hooks = {\n\t\t\tbeforeAdd: [],\n\t\t\tbeforeChange: [],\n\t\t\tbeforeDelete: [],\n\t\t\tafterAdd: [],\n\t\t\tafterChange: [],\n\t\t\tafterDelete: []\n\t\t};\n\n\t\t/* Event handlers */\n\n\t\t/**\n\t\t * Handle add category submit. Not to be called directly.\n\t\t *\n\t\t * @this Element\n\t\t */\n\t\tthis.handleAddLink = function () {\n\t\t\tconst $el = $( this );\n\t\t\tconst $link = $( [] );\n\t\t\tconst categoryText = $el.parent().find( '.mw-addcategory-input' ).val() || '';\n\n\t\t\t// Resolve redirects\n\t\t\tajaxcat.resolveRedirects( categoryText, ( resolvedCatTitle ) => {\n\t\t\t\tajaxcat.handleCategoryAdd( $link, resolvedCatTitle, '', false );\n\t\t\t} );\n\t\t};\n\n\t\t/**\n\t\t * @this Element\n\t\t */\n\t\tthis.createEditInterface = function () {\n\t\t\tconst $el = $( this );\n\t\t\tconst $link = $el.data( 'link' );\n\t\t\tconst category = $link.text();\n\t\t\tconst $input = ajaxcat.makeSuggestionBox( category,\n\t\t\t\tajaxcat.handleEditLink,\n\t\t\t\tmw.msg( ajaxcat.options.multiEdit ? 'inlinecategorizer-confirm-ok' : 'inlinecategorizer-confirm-save' )\n\t\t\t);\n\n\t\t\t$link.after( $input ).hide();\n\n\t\t\t$input.find( '.mw-addcategory-input' ).trigger( 'focus' );\n\n\t\t\t// Get the editButton associated with this category link,\n\t\t\t// and hide it.\n\t\t\t$link.data( 'editButton' ).hide();\n\n\t\t\t// Get the deleteButton associated with this category link,\n\t\t\t$link.data( 'deleteButton' )\n\t\t\t\t// (re)set click handler\n\t\t\t\t.off( 'click' )\n\t\t\t\t.click( function () {\n\t\t\t\t\t// When the delete button is clicked:\n\t\t\t\t\t// - Remove the suggestion box\n\t\t\t\t\t// - Show the link and it's edit button\n\t\t\t\t\t// - (re)set the click handler again\n\t\t\t\t\t$input.remove();\n\t\t\t\t\t$link.show().data( 'editButton' ).show();\n\t\t\t\t\t$( this )\n\t\t\t\t\t\t.off( 'click' )\n\t\t\t\t\t\t.on( 'click', ajaxcat.handleDeleteLink )\n\t\t\t\t\t\t.attr( 'title', mw.msg( 'inlinecategorizer-remove-category' ) );\n\t\t\t\t} )\n\t\t\t\t.attr( 'title', mw.msg( 'inlinecategorizer-cancel' ) );\n\t\t};\n\n\t\t/**\n\t\t * Handle edit category submit. Not to be called directly.\n\t\t *\n\t\t * @this Element\n\t\t */\n\t\tthis.handleEditLink = function () {\n\t\t\tconst $el = $( this );\n\t\t\tconst $link = $el.parent().parent().find( 'a:not(.icon)' );\n\n\t\t\t// Grab category text\n\t\t\tconst input = $el.parent().find( '.mw-addcategory-input' ).val();\n\n\t\t\t// Split categoryname and sortkey\n\t\t\tconst arr = input.split( '|', 2 );\n\t\t\tconst category = arr[ 0 ];\n\t\t\tconst sortkey = arr[ 1 ]; // Is usually undefined, ie. if there was no '|' in the input.\n\n\t\t\t// Grab text\n\t\t\tconst isAdded = $link.hasClass( 'mw-added-category' );\n\t\t\tajaxcat.resetCatLink( $link );\n\t\t\tconst categoryOld = $link.text();\n\n\t\t\t// If something changed and the new cat is already on the page, delete it.\n\t\t\tif ( categoryOld !== category && ajaxcat.containsCat( category ) ) {\n\t\t\t\t$link.data( 'deleteButton' ).click();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Resolve redirects\n\t\t\tajaxcat.resolveRedirects( category, ( resolvedCatTitle ) => {\n\t\t\t\tajaxcat.handleCategoryEdit(\n\t\t\t\t\t$link,\n\t\t\t\t\tcategoryOld,\n\t\t\t\t\tresolvedCatTitle,\n\t\t\t\t\tsortkey,\n\t\t\t\t\tisAdded\n\t\t\t\t);\n\t\t\t} );\n\t\t};\n\n\t\t/**\n\t\t * Handle delete category submit. Not to be called directly.\n\t\t *\n\t\t * @this Element\n\t\t */\n\t\tthis.handleDeleteLink = function () {\n\t\t\tconst $el = $( this );\n\t\t\tconst $link = $el.parent().find( 'a:not(.icon)' );\n\t\t\tconst category = $link.text();\n\n\t\t\tif ( $link.is( '.mw-added-category, .mw-changed-category' ) ) {\n\t\t\t\t// We're just cancelling the addition or edit\n\t\t\t\tajaxcat.resetCatLink( $link, $link.hasClass( 'mw-added-category' ) );\n\t\t\t\treturn;\n\t\t\t} else if ( $link.is( '.mw-removed-category' ) ) {\n\t\t\t\t// It's already removed...\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tajaxcat.handleCategoryDelete( $link, category );\n\t\t};\n\n\t\t/**\n\t\t * When multiEdit mode is enabled,\n\t\t * this is called when the user clicks \"save all\"\n\t\t * Combines the dialogDescriptions and edit functions.\n\t\t *\n\t\t * @this Element\n\t\t */\n\t\tthis.handleStashedCategories = function () {\n\t\t\t// Remove \"holes\" in array\n\t\t\t// Replace this by .flat() when supported by all Grade A browsers.\n\t\t\tlet dialogDescriptions = $.grep( ajaxcat.stash.dialogDescriptions, ( n ) => n );\n\n\t\t\tif ( dialogDescriptions.length < 1 ) {\n\t\t\t\t// Nothing to do here.\n\t\t\t\tajaxcat.saveAllButton.hide();\n\t\t\t\tajaxcat.cancelAllButton.hide();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdialogDescriptions = dialogDescriptions.join( '<br/>' );\n\n\t\t\t// Remove \"holes\" in array\n\t\t\t// Replace this by .flat() when supported by all Grade A browsers.\n\t\t\tconst summaryShort = $.grep( ajaxcat.stash.editSummaries, ( n ) => n )\n\t\t\t\t.join( ', ' );\n\n\t\t\tconst fns = ajaxcat.stash.fns;\n\n\t\t\tajaxcat.doConfirmEdit( {\n\t\t\t\tmodFn: function ( oldtext ) {\n\t\t\t\t\t// Run the text through all action functions\n\t\t\t\t\tlet newtext = oldtext;\n\t\t\t\t\tfor ( let i = 0; i < fns.length; i++ ) {\n\t\t\t\t\t\tif ( typeof fns[ i ] === 'function' ) {\n\t\t\t\t\t\t\tnewtext = fns[ i ]( newtext );\n\t\t\t\t\t\t\tif ( newtext === false ) {\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn newtext;\n\t\t\t\t},\n\t\t\t\tdialogDescription: dialogDescriptions,\n\t\t\t\teditSummary: summaryShort,\n\t\t\t\tdoneFn: function () {\n\t\t\t\t\tajaxcat.resetAll( true );\n\t\t\t\t},\n\t\t\t\t$link: null,\n\t\t\t\taction: 'all'\n\t\t\t} );\n\t\t};\n\t};\n\n\t/* Public methods */\n\n\tmw.InlineCategorizer.prototype = {\n\t\t/**\n\t\t * Create the UI\n\t\t */\n\t\tsetup: function () {\n\t\t\t// Only do it for articles.\n\t\t\tif ( !mw.config.get( 'wgIsArticle' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst options = this.options;\n\t\t\tconst ajaxcat = this;\n\t\t\t// Create [Add Category] link\n\t\t\tconst $addLink = createButton( 'icon-add',\n\t\t\t\tmw.msg( 'inlinecategorizer-add-category' ),\n\t\t\t\t'mw-ajax-addcategory',\n\t\t\t\tmw.msg( 'inlinecategorizer-add-category' )\n\t\t\t).click( function () {\n\t\t\t\t$( this ).nextAll().toggle().filter( '.mw-addcategory-input' ).trigger( 'focus' );\n\t\t\t} );\n\n\t\t\t// Create add category prompt\n\t\t\tthis.addContainer = this.makeSuggestionBox( '', this.handleAddLink, mw.msg( 'inlinecategorizer-add-category-submit' ) );\n\t\t\tthis.addContainer.children().hide();\n\t\t\tthis.addContainer.prepend( $addLink );\n\n\t\t\t// Create edit & delete link for each category.\n\t\t\t$( '#catlinks' ).find( 'li a' ).each( function () {\n\t\t\t\tajaxcat.createCatButtons( $( this ) );\n\t\t\t} );\n\n\t\t\toptions.$containerNormal.append( this.addContainer );\n\n\t\t\t// @todo Make more clickable\n\t\t\tthis.saveAllButton = createButton( 'icon-tick',\n\t\t\t\tmw.msg( 'inlinecategorizer-confirm-save-all' ),\n\t\t\t\t'',\n\t\t\t\tmw.msg( 'inlinecategorizer-confirm-save-all' )\n\t\t\t);\n\t\t\tthis.cancelAllButton = createButton( 'icon-close',\n\t\t\t\tmw.msg( 'inlinecategorizer-cancel-all' ),\n\t\t\t\t'',\n\t\t\t\tmw.msg( 'inlinecategorizer-cancel-all' )\n\t\t\t);\n\t\t\tthis.saveAllButton.click( this.handleStashedCategories ).hide();\n\t\t\tthis.cancelAllButton.click( () => {\n\t\t\t\tajaxcat.resetAll( false );\n\t\t\t} ).hide();\n\t\t\toptions.$containerNormal.append( this.saveAllButton ).append( this.cancelAllButton );\n\t\t\toptions.$container.append( this.addContainer );\n\t\t},\n\n\t\t/**\n\t\t * Insert a newly added category into the DOM.\n\t\t *\n\t\t * @param {mw.Title} catTitle Category title for which a link should be created.\n\t\t * @return {jQuery}\n\t\t */\n\t\tcreateCatLink: function ( catTitle ) {\n\t\t\tconst catName = catTitle.getMainText();\n\t\t\tconst $catLinkWrapper = $( this.options.catLinkWrapper );\n\t\t\tconst $anchor = $( '<a>' )\n\t\t\t\t.text( catName )\n\t\t\t\t.attr( {\n\t\t\t\t\ttarget: '_blank',\n\t\t\t\t\thref: catTitle.getUrl()\n\t\t\t\t} );\n\n\t\t\t$catLinkWrapper.append( $anchor );\n\n\t\t\tthis.createCatButtons( $anchor );\n\n\t\t\treturn $anchor;\n\t\t},\n\n\t\t/**\n\t\t * Create a suggestion box for use in edit/add dialogs\n\t\t *\n\t\t * @param {string} prefill Prefill input\n\t\t * @param {Function} callback Called on submit\n\t\t * @param {string} buttonVal Button text\n\t\t * @return {jQuery}\n\t\t */\n\t\tmakeSuggestionBox: function ( prefill, callback, buttonVal ) {\n\t\t\t// Create add category prompt\n\t\t\tconst $promptContainer = $( '<div>' )\n\t\t\t\t.addClass( 'mw-addcategory-prompt' );\n\t\t\tconst $promptTextbox = $( '<input>' )\n\t\t\t\t.attr( { type: 'text', size: 30 } )\n\t\t\t\t.addClass( 'mw-addcategory-input' );\n\t\t\tconst $addButton = $( '<input>' )\n\t\t\t\t.attr( 'type', 'button' )\n\t\t\t\t.addClass( 'mw-addcategory-button' );\n\n\t\t\tif ( prefill !== '' ) {\n\t\t\t\t$promptTextbox.val( prefill );\n\t\t\t}\n\n\t\t\t$addButton\n\t\t\t\t.val( buttonVal )\n\t\t\t\t.on( 'click', callback );\n\n\t\t\t$promptTextbox\n\t\t\t\t.on( 'keyup', ( e ) => {\n\t\t\t\t\tif ( e.keyCode === 13 ) {\n\t\t\t\t\t\t$addButton.trigger( 'click' );\n\t\t\t\t\t}\n\t\t\t\t} )\n\t\t\t\t.suggestions( {\n\t\t\t\t\tfetch: fetchSuggestions,\n\t\t\t\t\tcancel: function () {\n\t\t\t\t\t\tconst req = this.data( 'suggestions-request' );\n\t\t\t\t\t\tif ( req && req.abort ) {\n\t\t\t\t\t\t\treq.abort();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} )\n\t\t\t\t.suggestions();\n\n\t\t\t$promptContainer\n\t\t\t\t.append( $promptTextbox )\n\t\t\t\t.append( $addButton );\n\n\t\t\treturn $promptContainer;\n\t\t},\n\n\t\t/**\n\t\t * Execute or queue a category addition.\n\t\t *\n\t\t * @param {jQuery} $link Anchor tag of category link inside #catlinks.\n\t\t * @param {mw.Title} catTitle Instance of mw.Title of the category to be added.\n\t\t * @param {string} [catSortkey] sort key\n\t\t * @param {boolean} [noAppend]\n\t\t * @return {mw.inlineCategorizer}\n\t\t */\n\t\thandleCategoryAdd: function ( $link, catTitle, catSortkey, noAppend ) {\n\t\t\tconst ajaxcat = this;\n\t\t\t// Suffix is wikitext between '[[Category:Foo' and ']]'.\n\t\t\tconst suffix = catSortkey ? '|' + catSortkey : '';\n\t\t\tconst catName = catTitle.getMainText();\n\t\t\tconst catFull = catTitle.toText();\n\n\t\t\tif ( this.containsCat( catName ) ) {\n\t\t\t\tthis.showError( mw.msg( 'inlinecategorizer-category-already-present', catName ) );\n\t\t\t\treturn this;\n\t\t\t}\n\n\t\t\tif ( !$link.length ) {\n\t\t\t\t$link = this.createCatLink( catTitle );\n\t\t\t}\n\n\t\t\t// Mark red if missing\n\t\t\t$link.toggleClass( 'new', !catTitle.exists() );\n\n\t\t\tthis.doConfirmEdit( {\n\t\t\t\tmodFn: function ( oldText ) {\n\t\t\t\t\tconst newText = ajaxcat.runHooks( oldText, 'beforeAdd', catName ) +\n\t\t\t\t\t\t'\\n[[' + catFull + suffix + ']]\\n';\n\t\t\t\t\treturn ajaxcat.runHooks( newText, 'afterAdd', catName );\n\t\t\t\t},\n\t\t\t\tdialogDescription: mw.message( 'inlinecategorizer-add-category-summary', catName ).escaped(),\n\t\t\t\teditSummary: '+[[' + catFull + ']]',\n\t\t\t\tdoneFn: function ( unsaved ) {\n\t\t\t\t\tif ( !noAppend ) {\n\t\t\t\t\t\tajaxcat.options.$container\n\t\t\t\t\t\t\t.find( '#mw-normal-catlinks > .mw-addcategory-prompt' ).children( 'input' ).hide();\n\t\t\t\t\t\tajaxcat.options.$container\n\t\t\t\t\t\t\t.find( '#mw-normal-catlinks ul' ).append( $link.parent() );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Remove input box & button\n\t\t\t\t\t\t$link.data( 'deleteButton' ).click();\n\n\t\t\t\t\t\t// Update link text and href\n\t\t\t\t\t\t$link.show().text( catName ).attr( 'href', catTitle.getUrl() );\n\t\t\t\t\t}\n\t\t\t\t\tif ( unsaved ) {\n\t\t\t\t\t\t$link.addClass( 'mw-added-category' );\n\t\t\t\t\t}\n\t\t\t\t\t$( '.mw-ajax-addcategory' ).trigger( 'click' );\n\t\t\t\t},\n\t\t\t\t$link: $link,\n\t\t\t\taction: 'add'\n\t\t\t} );\n\t\t\treturn this;\n\t\t},\n\n\t\t/**\n\t\t * Execute or queue a category edit.\n\t\t *\n\t\t * @param {jQuery} $link Anchor tag of category link in #catlinks.\n\t\t * @param {string} oldCatName Name of category before edit\n\t\t * @param {mw.Title} catTitle Instance of mw.Title for new category\n\t\t * @param {string} catSortkey Sort key of new category link (optional)\n\t\t * @param {boolean} isAdded True if this is a new link, false if it changed an existing one\n\t\t */\n\t\thandleCategoryEdit: function ( $link, oldCatName, catTitle, catSortkey, isAdded ) {\n\t\t\tconst ajaxcat = this;\n\t\t\tconst catName = catTitle.getMainText();\n\n\t\t\t// Category add needs to be handled differently\n\t\t\tif ( isAdded ) {\n\t\t\t\t// Pass sortkey back\n\t\t\t\tthis.handleCategoryAdd( $link, catTitle, catSortkey, true );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// User didn't change anything, trigger delete\n\t\t\t// @todo Document why it's deleted.\n\t\t\tif ( oldCatName === catName ) {\n\t\t\t\t$link.data( 'deleteButton' ).click();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Mark red if missing\n\t\t\t$link.toggleClass( 'new', !catTitle.exists() );\n\n\t\t\tconst categoryRegex = buildRegex( oldCatName );\n\t\t\tconst editSummary = '[[' + new mw.Title( oldCatName, catNsId ).toText() + ']] -> [[' + catTitle.toText() + ']]';\n\n\t\t\tajaxcat.doConfirmEdit( {\n\t\t\t\tmodFn: function ( oldText ) {\n\t\t\t\t\tlet newText = ajaxcat.runHooks( oldText, 'beforeChange', oldCatName, catName );\n\t\t\t\t\tconst matches = newText.match( categoryRegex );\n\n\t\t\t\t\t// Old cat wasn't found, likely to be transcluded\n\t\t\t\t\tif ( !Array.isArray( matches ) ) {\n\t\t\t\t\t\tajaxcat.showError( mw.msg( 'inlinecategorizer-edit-category-error', oldCatName ) );\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst suffix = catSortkey ? '|' + catSortkey : matches[ 0 ].replace( categoryRegex, '$2' );\n\t\t\t\t\tconst newCategoryWikitext = '[[' + catTitle + suffix + ']]';\n\n\t\t\t\t\tif ( matches.length > 1 ) {\n\t\t\t\t\t\t// The category is duplicated. Remove all but one match\n\t\t\t\t\t\tfor ( let i = 1; i < matches.length; i++ ) {\n\t\t\t\t\t\t\toldText = oldText.replace( matches[ i ], '' );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tnewText = oldText.replace( categoryRegex, newCategoryWikitext );\n\n\t\t\t\t\treturn ajaxcat.runHooks( newText, 'afterChange', oldCatName, catName );\n\t\t\t\t},\n\t\t\t\tdialogDescription: mw.message( 'inlinecategorizer-edit-category-summary', oldCatName, catName ).escaped(),\n\t\t\t\teditSummary: editSummary,\n\t\t\t\tdoneFn: function ( unsaved ) {\n\t\t\t\t\t// Remove input box & button\n\t\t\t\t\t$link.data( 'deleteButton' ).click();\n\n\t\t\t\t\t// Update link text and href\n\t\t\t\t\t$link.show().text( catName ).attr( 'href', catTitle.getUrl() );\n\t\t\t\t\tif ( unsaved ) {\n\t\t\t\t\t\t$link.data( 'origCat', oldCatName ).addClass( 'mw-changed-category' );\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t$link: $link,\n\t\t\t\taction: 'edit'\n\t\t\t} );\n\t\t},\n\n\t\t/**\n\t\t * Checks the API whether the category in question is a redirect.\n\t\t * Also returns existance info (to color link red/blue)\n\t\t *\n\t\t * @param {string} category Name of category to resolve\n\t\t * @param {Function} callback Called with 1 argument (mw.Title object)\n\t\t */\n\t\tresolveRedirects: function ( category, callback ) {\n\t\t\tif ( !this.options.resolveRedirects ) {\n\t\t\t\tcallback( category, true );\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet catTitle = new mw.Title( category, catNsId );\n\t\t\tconst queryVars = {\n\t\t\t\taction: 'query',\n\t\t\t\ttitles: catTitle.toString(),\n\t\t\t\tredirects: 1,\n\t\t\t\tformat: 'json'\n\t\t\t};\n\n\t\t\t$.getJSON( mw.util.wikiScript( 'api' ), queryVars, ( json ) => {\n\t\t\t\tconst redirect = json.query.redirects;\n\t\t\t\tconst exists = !json.query.pages[ -1 ];\n\n\t\t\t\t// If it's a redirect 'exists' is for the target, not the origin\n\t\t\t\tif ( redirect ) {\n\t\t\t\t\t// Register existance of redirect origin as well,\n\t\t\t\t\t// a non-existent page can't be a redirect.\n\t\t\t\t\tmw.Title.exist.set( catTitle.toString(), true );\n\n\t\t\t\t\t// Override title with the redirect target\n\t\t\t\t\tcatTitle = new mw.Title( redirect[ 0 ].to ).getMainText();\n\t\t\t\t}\n\n\t\t\t\t// Register existence\n\t\t\t\tmw.Title.exist.set( catTitle.toString(), exists );\n\n\t\t\t\tcallback( catTitle );\n\t\t\t} );\n\t\t},\n\n\t\t/**\n\t\t * Append edit and remove buttons to a given category link\n\t\t *\n\t\t * @param {jQuery} $element Anchor element, to which the buttons should be appended.\n\t\t * @return {mw.inlineCategorizer}\n\t\t */\n\t\tcreateCatButtons: function ( $element ) {\n\t\t\tconst deleteButton = createButton( 'icon-close', mw.msg( 'inlinecategorizer-remove-category' ) );\n\t\t\tconst editButton = createButton( 'icon-edit', mw.msg( 'inlinecategorizer-edit-category' ) );\n\t\t\tconst saveButton = createButton( 'icon-tick', mw.msg( 'inlinecategorizer-confirm-save' ) ).hide();\n\t\t\tconst ajaxcat = this;\n\n\t\t\tdeleteButton.click( this.handleDeleteLink );\n\t\t\teditButton.click( ajaxcat.createEditInterface );\n\n\t\t\t$element.after( deleteButton ).after( editButton );\n\n\t\t\t// Save references to all links and buttons\n\t\t\t$element.data( {\n\t\t\t\tdeleteButton: deleteButton,\n\t\t\t\teditButton: editButton,\n\t\t\t\tsaveButton: saveButton\n\t\t\t} );\n\t\t\teditButton.data( {\n\t\t\t\tlink: $element\n\t\t\t} );\n\t\t\treturn this;\n\t\t},\n\n\t\t/**\n\t\t * Append spinner wheel to element.\n\t\t *\n\t\t * @param {jQuery} $el\n\t\t * @return {mw.inlineCategorizer}\n\t\t */\n\t\taddProgressIndicator: function ( $el ) {\n\t\t\t$el.append( $( '<div>' ).addClass( 'mw-ajax-loader' ) );\n\t\t\treturn this;\n\t\t},\n\n\t\t/**\n\t\t * Find and remove spinner wheel from inside element.\n\t\t *\n\t\t * @param {jQuery} $el\n\t\t * @return {mw.inlineCategorizer}\n\t\t */\n\t\tremoveProgressIndicator: function ( $el ) {\n\t\t\t$el.find( '.mw-ajax-loader' ).remove();\n\t\t\treturn this;\n\t\t},\n\n\t\t/**\n\t\t * Parse the DOM $container and build a list of\n\t\t * present categories.\n\t\t *\n\t\t * @return {Array} All categories\n\t\t */\n\t\tgetCats: function () {\n\t\t\treturn this.options.$container\n\t\t\t\t.find( this.options.categoryLinkSelector )\n\t\t\t\t.map( function () {\n\t\t\t\t\tconst title = mw.Title.makeTitle( catNsId, $( this ).text() );\n\t\t\t\t\treturn title ? title.getNameText() : null;\n\t\t\t\t} ).get();\n\t\t},\n\n\t\t/**\n\t\t * Check whether a passed category is present in the DOM.\n\t\t *\n\t\t * @param {string} newCat Category name to be checked for.\n\t\t * @return {boolean}\n\t\t */\n\t\tcontainsCat: function ( newCat ) {\n\t\t\tnewCat = mw.Title.makeTitle( catNsId, newCat ).getNameText();\n\t\t\treturn this.getCats().includes( newCat );\n\t\t},\n\n\t\t/**\n\t\t * Execute or queue a category delete.\n\t\t *\n\t\t * @param {jQuery} $link\n\t\t * @param {string} category\n\t\t */\n\t\thandleCategoryDelete: function ( $link, category ) {\n\t\t\tconst categoryRegex = buildRegex( category, true );\n\t\t\tconst ajaxcat = this;\n\n\t\t\tthis.doConfirmEdit( {\n\t\t\t\tmodFn: function ( oldText ) {\n\t\t\t\t\tconst newText = ajaxcat.runHooks( oldText, 'beforeDelete', category )\n\t\t\t\t\t\t.replace( categoryRegex, '' );\n\n\t\t\t\t\tif ( newText === oldText ) {\n\t\t\t\t\t\tajaxcat.showError( mw.msg( 'inlinecategorizer-remove-category-error', category ) );\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn ajaxcat.runHooks( newText, 'afterDelete', category );\n\t\t\t\t},\n\t\t\t\tdialogDescription: mw.message( 'inlinecategorizer-remove-category-summary', category ).escaped(),\n\t\t\t\teditSummary: '-[[' + new mw.Title( category, catNsId ) + ']]',\n\t\t\t\tdoneFn: function ( unsaved ) {\n\t\t\t\t\tif ( unsaved ) {\n\t\t\t\t\t\t$link.addClass( 'mw-removed-category' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$link.parent().remove();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t$link: $link,\n\t\t\t\taction: 'delete'\n\t\t\t} );\n\t\t},\n\n\t\t/**\n\t\t * Takes a category link element\n\t\t * and strips all data from it.\n\t\t *\n\t\t * @param {jQuery} $link\n\t\t * @param {boolean} del\n\t\t * @param {boolean} dontRestoreText\n\t\t */\n\t\tresetCatLink: function ( $link, del, dontRestoreText ) {\n\t\t\t$link.removeClass( 'mw-removed-category mw-added-category mw-changed-category' );\n\t\t\tconst data = $link.data();\n\n\t\t\tif ( typeof data.stashIndex === 'number' ) {\n\t\t\t\tthis.removeStashItem( data.stashIndex );\n\t\t\t}\n\t\t\tif ( del ) {\n\t\t\t\t$link.parent().remove();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif ( data.origCat && !dontRestoreText ) {\n\t\t\t\tconst catTitle = new mw.Title( data.origCat, catNsId );\n\t\t\t\t$link.text( catTitle.getMainText() );\n\t\t\t\t$link.attr( 'href', catTitle.getUrl() );\n\t\t\t}\n\n\t\t\t$link.removeData();\n\n\t\t\t// Re-add data\n\t\t\t$link.data( {\n\t\t\t\tsaveButton: data.saveButton,\n\t\t\t\tdeleteButton: data.deleteButton,\n\t\t\t\teditButton: data.editButton\n\t\t\t} );\n\t\t},\n\n\t\t/**\n\t\t * Do the actual edit.\n\t\t * Gets token & text from api, runs it through fn and saves it with summary.\n\t\t *\n\t\t * @param {string} page Pagename\n\t\t * @param {Function} fn edit function\n\t\t * @param {string} summary\n\t\t * @param {Function} doneFn Callback after all is done\n\t\t */\n\t\tdoEdit: function ( page, fn, summary, doneFn ) {\n\t\t\t// Get an edit token for the page.\n\t\t\tconst getTokenVars = {\n\t\t\t\taction: 'query',\n\t\t\t\tprop: 'info|revisions',\n\t\t\t\tintoken: 'edit',\n\t\t\t\ttitles: page,\n\t\t\t\trvprop: 'content|timestamp',\n\t\t\t\tformat: 'json'\n\t\t\t};\n\t\t\tconst ajaxcat = this;\n\n\t\t\t$.post(\n\t\t\t\tmw.util.wikiScript( 'api' ),\n\t\t\t\tgetTokenVars,\n\t\t\t\t( json ) => {\n\t\t\t\t\tif ( 'error' in json ) {\n\t\t\t\t\t\tajaxcat.showError(\n\t\t\t\t\t\t\tmw.msg( 'inlinecategorizer-api-error', json.error.code, json.error.info )\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif ( !json.query || !json.query.pages ) {\n\t\t\t\t\t\tajaxcat.showError( mw.msg( 'inlinecategorizer-api-unknown-error' ) );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst infos = json.query.pages;\n\n\t\t\t\t\t$.each( infos, ( pageid, data ) => {\n\t\t\t\t\t\tconst token = data.edittoken;\n\t\t\t\t\t\tconst timestamp = data.revisions[ 0 ].timestamp;\n\t\t\t\t\t\tlet oldText = data.revisions[ 0 ][ '*' ];\n\t\t\t\t\t\t// Unique ID for nowiki replacement\n\t\t\t\t\t\tconst nowikiKey = generateRandomId();\n\t\t\t\t\t\t// Nowiki fragments will be stored here during the changes\n\t\t\t\t\t\tconst nowikiFragments = [];\n\n\t\t\t\t\t\t// Replace all nowiki parts with unique keys..\n\t\t\t\t\t\toldText = replaceNowikis( oldText, nowikiKey, nowikiFragments );\n\n\t\t\t\t\t\t// ..then apply the changes to the page text..\n\t\t\t\t\t\tlet newText = fn( oldText );\n\t\t\t\t\t\tif ( newText === false ) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// ..and restore the nowiki parts back.\n\t\t\t\t\t\tnewText = restoreNowikis( newText, nowikiKey, nowikiFragments );\n\n\t\t\t\t\t\tconst postEditVars = {\n\t\t\t\t\t\t\taction: 'edit',\n\t\t\t\t\t\t\ttitle: page,\n\t\t\t\t\t\t\ttext: newText,\n\t\t\t\t\t\t\tsummary: summary,\n\t\t\t\t\t\t\ttoken: token,\n\t\t\t\t\t\t\tbasetimestamp: timestamp,\n\t\t\t\t\t\t\tformat: 'json'\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t$.post(\n\t\t\t\t\t\t\tmw.util.wikiScript( 'api' ),\n\t\t\t\t\t\t\tpostEditVars,\n\t\t\t\t\t\t\tdoneFn,\n\t\t\t\t\t\t\t'json'\n\t\t\t\t\t\t).catch( ( xhr, text, error ) => {\n\t\t\t\t\t\t\tajaxcat.showError( mw.msg( 'inlinecategorizer-api-error', text, error ) );\n\t\t\t\t\t\t} );\n\t\t\t\t\t} );\n\t\t\t\t},\n\t\t\t\t'json'\n\t\t\t).catch( ( xhr, text, error ) => {\n\t\t\t\tajaxcat.showError( mw.msg( 'inlinecategorizer-api-error', text, error ) );\n\t\t\t} );\n\t\t},\n\n\t\t/**\n\t\t * This gets called by all action buttons\n\t\t * Displays a dialog to confirm the action\n\t\t * Afterwards do the actual edit.\n\t\t *\n\t\t * @param {Object} props\n\t\t * - {Function} modFn text-modifying function\n\t\t * - {string} dialogDescription Changes done\n\t\t * (HTML for in the dialog, escape before hand if needed)\n\t\t * - {string} editSummary Changes done (text for the edit summary)\n\t\t * - {Function} doneFn callback after everything is done\n\t\t * - {jQuery} $link\n\t\t * - {string} action\n\t\t * @return {mw.inlineCategorizer}\n\t\t */\n\t\tdoConfirmEdit: function ( props ) {\n\t\t\tconst ajaxcat = this;\n\n\t\t\t// Check whether to use multiEdit mode:\n\t\t\tif ( this.options.multiEdit && props.action !== 'all' ) {\n\t\t\t\t// Stash away\n\t\t\t\tprops.$link\n\t\t\t\t\t.data( 'stashIndex', this.stash.fns.length )\n\t\t\t\t\t.data( 'summary', props.dialogDescription );\n\n\t\t\t\tthis.stash.dialogDescriptions.push( props.dialogDescription );\n\t\t\t\tthis.stash.editSummaries.push( props.editSummary );\n\t\t\t\tthis.stash.fns.push( props.modFn );\n\n\t\t\t\tthis.saveAllButton.show();\n\t\t\t\tthis.cancelAllButton.show();\n\n\t\t\t\t// Clear input field after action\n\t\t\t\tajaxcat.addContainer.find( '.mw-addcategory-input' ).val( '' );\n\n\t\t\t\t// This only does visual changes, fire done and return.\n\t\t\t\tprops.doneFn( true );\n\t\t\t\treturn this;\n\t\t\t}\n\n\t\t\t// Summary of the action to be taken\n\t\t\tconst $summaryHolder = $( '<p>' ).append(\n\t\t\t\t$( '<strong>' ).text( mw.msg( 'inlinecategorizer-category-question' ) ),\n\t\t\t\t$( '<br>' ),\n\t\t\t\tprops.dialogDescription\n\t\t\t);\n\n\t\t\t// Reason textbox.\n\t\t\tconst $reasonBox = $( '<input>' )\n\t\t\t\t.attr( { type: 'text', size: 45 } )\n\t\t\t\t.addClass( 'mw-ajax-confirm-reason' );\n\n\t\t\t// Produce a confirmation dialog\n\t\t\tconst $dialog = $( '<div>' )\n\t\t\t\t.addClass( 'mw-ajax-confirm-dialog' )\n\t\t\t\t.attr( 'title', mw.msg( 'inlinecategorizer-confirm-title' ) )\n\t\t\t\t.append(\n\t\t\t\t\t$summaryHolder,\n\t\t\t\t\t$reasonBox\n\t\t\t\t);\n\n\t\t\t// Submit button\n\t\t\tconst submitFunction = function () {\n\t\t\t\tajaxcat.addProgressIndicator( $dialog );\n\t\t\t\tajaxcat.doEdit(\n\t\t\t\t\tmw.config.get( 'wgPageName' ),\n\t\t\t\t\tprops.modFn,\n\t\t\t\t\tprops.editSummary + ': ' + $reasonBox.val(),\n\t\t\t\t\t() => {\n\t\t\t\t\t\tprops.doneFn();\n\n\t\t\t\t\t\t// Clear input field after successful edit\n\t\t\t\t\t\tajaxcat.addContainer.find( '.mw-addcategory-input' ).val( '' );\n\n\t\t\t\t\t\t$dialog.dialog( 'close' );\n\t\t\t\t\t\tajaxcat.removeProgressIndicator( $dialog );\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t};\n\n\t\t\tconst buttons = {};\n\t\t\tconst dialogOptions = {\n\t\t\t\tAutoOpen: true,\n\t\t\t\tbuttons: buttons,\n\t\t\t\twidth: 450\n\t\t\t};\n\t\t\tbuttons[ mw.msg( 'inlinecategorizer-confirm-save' ) ] = submitFunction;\n\n\t\t\t$dialog.dialog( dialogOptions ).keyup( ( e ) => {\n\t\t\t\t// Close on enter\n\t\t\t\tif ( e.keyCode === 13 ) {\n\t\t\t\t\tsubmitFunction();\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\treturn this;\n\t\t},\n\n\t\t/**\n\t\t * @param {number|jQuery} i Stash index or jQuery object of stash item.\n\t\t * @return {mw.inlineCategorizer}\n\t\t */\n\t\tremoveStashItem: function ( i ) {\n\t\t\tif ( typeof i !== 'number' ) {\n\t\t\t\ti = i.data( 'stashIndex' );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tdelete this.stash.fns[ i ];\n\t\t\t\tdelete this.stash.dialogDescriptions[ i ];\n\t\t\t} catch ( e ) {}\n\n\t\t\tif ( $.isEmptyObject( this.stash.fns ) ) {\n\t\t\t\tthis.stash.fns = [];\n\t\t\t\tthis.stash.dialogDescriptions = [];\n\t\t\t\tthis.stash.editSummaries = [];\n\t\t\t\tthis.saveAllButton.hide();\n\t\t\t\tthis.cancelAllButton.hide();\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\n\t\t/**\n\t\t * Reset all data from the category links and the stash.\n\t\t *\n\t\t * @param {boolean} del Delete any category links with .mw-removed-category\n\t\t * @return {mw.inlineCategorizer}\n\t\t */\n\t\tresetAll: function ( del ) {\n\t\t\tconst $links = this.options.$container.find( this.options.categoryLinkSelector );\n\t\t\tlet $del = $( [] );\n\t\t\tconst ajaxcat = this;\n\n\t\t\tif ( del ) {\n\t\t\t\t$del = $links.filter( '.mw-removed-category' ).parent();\n\t\t\t}\n\n\t\t\t$links.each( function () {\n\t\t\t\tajaxcat.resetCatLink( $( this ), false, del );\n\t\t\t} );\n\n\t\t\t$del.remove();\n\n\t\t\tthis.options.$container.find( '#mw-hidden-catlinks' ).remove();\n\n\t\t\treturn this;\n\t\t},\n\n\t\t/**\n\t\t * Add hooks\n\t\t * Currently available: beforeAdd, beforeChange, beforeDelete,\n\t\t * afterAdd, afterChange, afterDelete\n\t\t * If the hook function returns false, all changes are aborted.\n\t\t *\n\t\t * @param {string} type Type of hook to add\n\t\t * @param {Function} fn Hook function. The following vars are passed to it:\n\t\t * 1. oldtext: The wikitext before the hook\n\t\t * 2. category: The deleted, added, or changed category\n\t\t * 3. (only for beforeChange/afterChange): newcategory\n\t\t */\n\t\taddHook: function ( type, fn ) {\n\t\t\tif ( !this.hooks[ type ] || typeof fn !== 'function' ) {\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\tthis.hooks[ type ].push( fn );\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Open a dismissable error dialog\n\t\t *\n\t\t * @param {string} str The error description\n\t\t */\n\t\tshowError: function ( str ) {\n\t\t\tconst $oldDialog = $( '.mw-ajax-confirm-dialog' );\n\t\t\tthis.removeProgressIndicator( $oldDialog );\n\t\t\t$oldDialog.dialog( 'close' );\n\n\t\t\tconst $dialog = $( '<div>' ).text( str );\n\n\t\t\tconst buttons = {};\n\t\t\tbuttons[ mw.msg( 'inlinecategorizer-confirm-ok' ) ] = function () {\n\t\t\t\t$dialog.dialog( 'close' );\n\t\t\t};\n\n\t\t\tconst dialogOptions = {\n\t\t\t\tbuttons: buttons,\n\t\t\t\tAutoOpen: true,\n\t\t\t\ttitle: mw.msg( 'inlinecategorizer-error-title' )\n\t\t\t};\n\t\t\t$dialog.dialog( dialogOptions ).keyup( ( e ) => {\n\t\t\t\tif ( e.keyCode === 13 ) {\n\t\t\t\t\t$dialog.dialog( 'close' );\n\t\t\t\t}\n\t\t\t} );\n\t\t},\n\n\t\t/**\n\t\t * @param {string} oldtext\n\t\t * @param {string} type\n\t\t * @param {string} category\n\t\t * @param {string} [categoryNew]\n\t\t * @return {string}\n\t\t */\n\t\trunHooks: function ( oldtext, type, category, categoryNew ) {\n\t\t\t// No hooks registered\n\t\t\tif ( !this.hooks[ type ] ) {\n\t\t\t\treturn oldtext;\n\t\t\t} else {\n\t\t\t\tfor ( let i = 0; i < this.hooks[ type ].length; i++ ) {\n\t\t\t\t\toldtext = this.hooks[ type ][ i ]( oldtext, category, categoryNew );\n\t\t\t\t\tif ( oldtext === false ) {\n\t\t\t\t\t\tthis.showError( mw.msg( 'inlinecategorizer-category-hook-error', category ) );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn oldtext;\n\t\t\t}\n\t\t}\n\t};\n\n\t$( () => {\n\t\tconst categorizer = new mw.InlineCategorizer();\n\t\t// Separate function for call to prevent jQuery\n\t\t// from executing it in the document context.\n\t\tcategorizer.setup();\n\t} );\n\n\t// Expose private functions for QUnit tests.\n\tif ( window.QUnit ) {\n\t\tmodule.exports = {\n\t\t\tmakeCaseInsensitive: makeCaseInsensitive,\n\t\t\tbuildRegex: buildRegex\n\t\t};\n\t}\n\n}() );\n","usedDeprecatedRules":[{"ruleId":"max-len","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/package-lock.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/package.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/tests/qunit/.eslintrc.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"indent","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/tests/qunit/ext.inlineCategorizer.core.test.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"max-len","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]}]
--- end ---
$ /usr/bin/npm ci
--- stdout ---
added 318 packages, and audited 319 packages in 3s
68 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
--- end ---
$ /usr/bin/npm test
--- stdout ---
> test
> grunt test
Running "eslint:all" (eslint) task
/src/repo/modules/ext.inlineCategorizer.core.js
19:16 warning Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible no-jquery/no-global-selector
20:22 warning Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible no-jquery/no-global-selector
33:22 warning Unexpected control character(s) in regular expression: \x00, \x1f no-control-regex
50:10 warning Prefer `String#slice()` over `String#substring()` unicorn/prefer-string-slice
174:63 warning Unexpected string concatenation of literals no-useless-concat
174:69 warning Unexpected string concatenation of literals no-useless-concat
174:105 warning Unexpected string concatenation of literals no-useless-concat
215:28 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign
317:20 warning Where possible, maintain application state in JS to avoid slower DOM queries no-jquery/no-class-state
351:34 warning Where possible, maintain application state in JS to avoid slower DOM queries no-jquery/no-class-state
371:29 warning Prefer Array#filter to $.grep no-jquery/no-grep
383:25 warning Prefer Array#filter to $.grep no-jquery/no-grep
442:4 warning Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible no-jquery/no-global-selector
593:6 warning Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible no-jquery/no-global-selector
901:6 warning Prefer Array#forEach to $.each no-jquery/no-each-util
1122:23 warning Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible no-jquery/no-global-selector
✖ 16 problems (0 errors, 16 warnings)
Running "banana:all" (banana) task
>> 1 message directory checked.
Done.
--- end ---
$ /usr/bin/npm audit --json
--- stdout ---
{
"auditReportVersion": 2,
"vulnerabilities": {},
"metadata": {
"vulnerabilities": {
"info": 0,
"low": 0,
"moderate": 0,
"high": 0,
"critical": 0,
"total": 0
},
"dependencies": {
"prod": 1,
"dev": 318,
"optional": 0,
"peer": 1,
"peerOptional": 0,
"total": 318
}
}
}
--- end ---
$ package-lock-lint /src/repo/package-lock.json
--- stdout ---
Checking /src/repo/package-lock.json
--- end ---
build: Updating eslint-config-wikimedia to 0.32.2
$ git add .
--- stdout ---
--- end ---
$ git commit -F /tmp/tmpy3gnkxx_
--- stdout ---
[master 0147d9b] build: Updating eslint-config-wikimedia to 0.32.2
2 files changed, 8 insertions(+), 8 deletions(-)
--- end ---
$ git format-patch HEAD~1 --stdout
--- stdout ---
From 0147d9bbefb6323eb23c632b06d1f43c3e0fc3f4 Mon Sep 17 00:00:00 2001
From: libraryupgrader <tools.libraryupgrader@tools.wmflabs.org>
Date: Fri, 28 Nov 2025 06:24:22 +0000
Subject: [PATCH] build: Updating eslint-config-wikimedia to 0.32.2
Change-Id: Ie18e6822f10a6218a729c1018ea2c53a91f56931
---
package-lock.json | 14 +++++++-------
package.json | 2 +-
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 1c709ca..831f847 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6,7 +6,7 @@
"": {
"name": "InlineCategorizer",
"devDependencies": {
- "eslint-config-wikimedia": "0.32.1",
+ "eslint-config-wikimedia": "0.32.2",
"grunt": "1.6.1",
"grunt-banana-checker": "0.13.0",
"grunt-eslint": "24.3.0"
@@ -1124,9 +1124,9 @@
}
},
"node_modules/eslint-config-wikimedia": {
- "version": "0.32.1",
- "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.32.1.tgz",
- "integrity": "sha512-gPvhyVFNlpKFOcJfoVTNlzg3A0b6qjhAbjjBIJ9xp5m+om0oqix5gkqIIEav5BaGxdDxYNmrY4ge3DAPP3u/lg==",
+ "version": "0.32.2",
+ "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.32.2.tgz",
+ "integrity": "sha512-vAGz50AJPk23qQ701sL4tAgaF8FEAkP/E3kgojSTVrGgmDqjnRvq8z3EItDNI/EAkb5Ys15WPPFsoBH8YhTdSg==",
"dev": true,
"dependencies": {
"@stylistic/eslint-plugin": "^3.1.0",
@@ -4642,9 +4642,9 @@
}
},
"eslint-config-wikimedia": {
- "version": "0.32.1",
- "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.32.1.tgz",
- "integrity": "sha512-gPvhyVFNlpKFOcJfoVTNlzg3A0b6qjhAbjjBIJ9xp5m+om0oqix5gkqIIEav5BaGxdDxYNmrY4ge3DAPP3u/lg==",
+ "version": "0.32.2",
+ "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.32.2.tgz",
+ "integrity": "sha512-vAGz50AJPk23qQ701sL4tAgaF8FEAkP/E3kgojSTVrGgmDqjnRvq8z3EItDNI/EAkb5Ys15WPPFsoBH8YhTdSg==",
"dev": true,
"requires": {
"@stylistic/eslint-plugin": "^3.1.0",
diff --git a/package.json b/package.json
index 988357f..33ecef2 100644
--- a/package.json
+++ b/package.json
@@ -5,7 +5,7 @@
"test": "grunt test"
},
"devDependencies": {
- "eslint-config-wikimedia": "0.32.1",
+ "eslint-config-wikimedia": "0.32.2",
"grunt": "1.6.1",
"grunt-banana-checker": "0.13.0",
"grunt-eslint": "24.3.0"
--
2.47.3
--- end ---