This run took 105 seconds.
From 38631ab1fe7ee83b8e993c041e314a7e0e682c6b Mon Sep 17 00:00:00 2001 From: libraryupgrader <tools.libraryupgrader@tools.wmflabs.org> Date: Fri, 6 Jun 2025 02:50:32 +0000 Subject: [PATCH] build: Updating dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit composer: * mediawiki/mediawiki-codesniffer: 45.0.0 → 47.0.0 npm: * eslint-config-wikimedia: 0.28.2 → 0.30.0 The following rules are failing and were disabled: * prefer-const * implicit-arrow-linebreak * no-mixed-spaces-and-tabs * no-jquery/no-done-fail * no-redeclare * tests/qunit: * no-jquery/no-done-fail * prefer-const * stylelint-config-wikimedia: 0.17.2 → 0.18.0 * cross-spawn: 7.0.3 → 7.0.6 * https://github.com/advisories/GHSA-3xgq-45jj-v275 Additional changes: * eslint: Replaced `wikimedia/client-es5` with `wikimedia/client`. * Enable stylelint caching. Change-Id: Ia730ad52e2026c7af9d42668f7c1921f9b703c75 --- .eslintrc.json | 9 +- .gitignore | 1 + Gruntfile.js | 5 +- composer.json | 2 +- package-lock.json | 1283 +++++++---------- package.json | 4 +- resources/controller/uw.controller.Deed.js | 18 +- resources/controller/uw.controller.Details.js | 54 +- resources/controller/uw.controller.Step.js | 42 +- resources/controller/uw.controller.Thanks.js | 4 +- .../controller/uw.controller.Tutorial.js | 12 +- resources/controller/uw.controller.Upload.js | 28 +- resources/deed/uw.deed.OwnWork.js | 32 +- resources/deed/uw.deed.ThirdParty.js | 8 +- .../details/uw.CategoriesDetailsWidget.js | 40 +- resources/details/uw.DateDetailsWidget.js | 14 +- .../details/uw.DeedChooserDetailsWidget.js | 4 +- resources/details/uw.DropdownWidget.js | 8 +- .../details/uw.LanguageDropdownWidget.js | 16 +- resources/details/uw.LocationDetailsWidget.js | 26 +- .../details/uw.MultipleLanguageInputWidget.js | 42 +- .../details/uw.SingleLanguageInputWidget.js | 10 +- resources/details/uw.TextWidget.js | 4 +- resources/details/uw.TitleDetailsWidget.js | 28 +- resources/details/uw.UlsWidget.js | 8 +- resources/ext.mediaUploader.campaignEditor.js | 2 +- .../handlers/mw.ApiUploadFormDataHandler.js | 12 +- resources/handlers/mw.ApiUploadHandler.js | 56 +- .../jquery.arrowSteps/jquery.arrowSteps.js | 6 +- resources/jquery/jquery.morphCrossfade.js | 12 +- resources/mw.DestinationChecker.js | 36 +- resources/mw.Escaper.js | 20 +- resources/mw.GroupProgressBar.js | 24 +- resources/mw.QuickTitleChecker.js | 8 +- resources/mw.UploadWizard.js | 22 +- resources/mw.UploadWizardDeedChooser.js | 22 +- resources/mw.UploadWizardDetails.js | 88 +- resources/mw.UploadWizardLicenseInput.js | 56 +- resources/mw.UploadWizardPage.js | 6 +- resources/mw.UploadWizardUpload.js | 74 +- resources/mw.UploadWizardUploadInterface.js | 16 +- resources/mw.fileApi.js | 6 +- resources/transports/mw.FormDataTransport.js | 36 +- resources/ui/steps/uw.ui.Deed.js | 4 +- resources/ui/steps/uw.ui.Details.js | 16 +- resources/ui/steps/uw.ui.Thanks.js | 12 +- resources/ui/steps/uw.ui.Tutorial.js | 10 +- resources/ui/steps/uw.ui.Upload.js | 36 +- resources/ui/uw.ui.DeedPreview.js | 4 +- resources/ui/uw.ui.Step.js | 14 +- resources/ui/uw.ui.Wizard.js | 14 +- resources/uw.ConcurrentQueue.js | 8 +- resources/uw.CopyMetadataWidget.js | 14 +- resources/uw.FieldLayout.js | 2 +- resources/uw.LicenseGroup.js | 58 +- resources/uw.LicensePreviewDialog.js | 8 +- resources/uw.ValidationMessageElement.js | 8 +- resources/uw.units.js | 4 +- tests/qunit/.eslintrc.json | 4 + .../controller/uw.controller.Deed.test.js | 6 +- .../controller/uw.controller.Details.test.js | 20 +- .../controller/uw.controller.Step.test.js | 4 +- .../controller/uw.controller.Thanks.test.js | 10 +- .../controller/uw.controller.Tutorial.test.js | 6 +- .../controller/uw.controller.Upload.test.js | 12 +- .../qunit/mw.UploadWizardLicenseInput.test.js | 12 +- tests/qunit/mw.UploadWizardUpload.test.js | 10 +- tests/qunit/mw.fileApi.test.js | 4 +- .../transports/mw.FormDataTransport.test.js | 34 +- tests/qunit/uw.ConcurrentQueue.test.js | 70 +- tests/qunit/uw.TitleDetailsWidget.test.js | 10 +- 71 files changed, 1164 insertions(+), 1454 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index feb9364..66461eb 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,7 +1,7 @@ { "root": true, "extends": [ - "wikimedia/client-es5", + "wikimedia/client", "wikimedia/jquery", "wikimedia/mediawiki" ], @@ -23,6 +23,11 @@ "es-x/no-regexp-u-flag": "warn", "es-x/no-typed-arrays": "warn", "no-unused-vars": "warn", - "es-x/no-object-assign": "warn" + "es-x/no-object-assign": "warn", + "no-mixed-spaces-and-tabs": "warn", + "prefer-const": "warn", + "implicit-arrow-linebreak": "warn", + "no-jquery/no-done-fail": "warn", + "no-redeclare": "warn" } } diff --git a/.gitignore b/.gitignore index de0ffeb..39e6140 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ vendor composer.lock .DS_Store .eslintcache +/.stylelintcache diff --git a/Gruntfile.js b/Gruntfile.js index d870d7c..3b065aa 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -5,7 +5,7 @@ /* eslint-env node */ module.exports = function ( grunt ) { - var conf = grunt.file.readJSON( 'extension.json' ); + const conf = grunt.file.readJSON( 'extension.json' ); grunt.loadNpmTasks( 'grunt-banana-checker' ); grunt.loadNpmTasks( 'grunt-contrib-watch' ); @@ -21,6 +21,9 @@ module.exports = function ( grunt ) { all: '.' }, stylelint: { + options: { + cache: true + }, all: 'resources/{**/,}*.{css,less}' }, banana: conf.MessagesDirs, diff --git a/composer.json b/composer.json index ca9ae93..3e0546b 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,7 @@ "ext-json": "*" }, "require-dev": { - "mediawiki/mediawiki-codesniffer": "45.0.0", + "mediawiki/mediawiki-codesniffer": "47.0.0", "mediawiki/mediawiki-phan-config": "0.15.1", "mediawiki/minus-x": "1.1.3", "php-parallel-lint/php-console-highlighter": "1.0.0", diff --git a/package-lock.json b/package-lock.json index 89c6fb1..3b9381f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,13 +6,13 @@ "": { "name": "MediaUploader", "devDependencies": { - "eslint-config-wikimedia": "0.28.2", + "eslint-config-wikimedia": "0.30.0", "grunt": "1.6.1", "grunt-banana-checker": "0.13.0", "grunt-contrib-watch": "1.1.0", "grunt-eslint": "24.3.0", "grunt-stylelint": "0.20.1", - "stylelint-config-wikimedia": "0.17.2" + "stylelint-config-wikimedia": "0.18.0" } }, "node_modules/@babel/code-frame": { @@ -124,9 +124,9 @@ } }, "node_modules/@csstools/css-parser-algorithms": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.7.1.tgz", - "integrity": "sha512-2SJS42gxmACHgikc1WGesXLIT8d/q2l0UFM7TaEeIzdFCE/FPMtTiizcPGGJtlPo2xuQzY09OhrLTzRxqJqwGw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", "dev": true, "funding": [ { @@ -139,16 +139,16 @@ } ], "engines": { - "node": "^14 || ^16 || >=18" + "node": ">=18" }, "peerDependencies": { - "@csstools/css-tokenizer": "^2.4.1" + "@csstools/css-tokenizer": "^3.0.4" } }, "node_modules/@csstools/css-tokenizer": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.4.1.tgz", - "integrity": "sha512-eQ9DIktFJBhGjioABJRtUucoWR2mwllurfnM8LuNGAqX3ViZXaUchqk+1s7jjtkFiT9ySdACsFEA3etErkALUg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", "dev": true, "funding": [ { @@ -161,36 +161,13 @@ } ], "engines": { - "node": "^14 || ^16 || >=18" + "node": ">=18" } }, "node_modules/@csstools/media-query-list-parser": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.13.tgz", - "integrity": "sha512-XaHr+16KRU9Gf8XLi3q8kDlI18d5vzKSKCY510Vrtc9iNR0NJzbY9hhTmwhzYZj/ZwGL4VmB3TA9hJW0Um2qFA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "engines": { - "node": "^14 || ^16 || >=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^2.7.1", - "@csstools/css-tokenizer": "^2.4.1" - } - }, - "node_modules/@csstools/selector-specificity": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.1.1.tgz", - "integrity": "sha512-a7cxGcJ2wIlMFLlh8z2ONm+715QkPHiyJcxwQlKOz/03GPw1COpfhcmC9wm4xlZfp//jWHNNMwzjtqHXVWU9KA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-3.0.1.tgz", + "integrity": "sha512-HNo8gGD02kHmcbX6PvCoUuOQvn4szyB9ca63vZHKX5A81QytgDG4oxG4IaEfHTlEZSZ6MjPEMWIVU+zF2PZcgw==", "dev": true, "funding": [ { @@ -203,10 +180,11 @@ } ], "engines": { - "node": "^14 || ^16 || >=18" + "node": ">=18" }, "peerDependencies": { - "postcss-selector-parser": "^6.0.13" + "@csstools/css-parser-algorithms": "^3.0.1", + "@csstools/css-tokenizer": "^3.0.1" } }, "node_modules/@dual-bundle/import-meta-resolve": { @@ -397,40 +375,40 @@ } }, "node_modules/@stylistic/stylelint-config": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@stylistic/stylelint-config/-/stylelint-config-1.0.1.tgz", - "integrity": "sha512-JgFP88HZEyo34k9RpWVdcQJtLPrMxYE58IO3qypXhmvE/NmZohj+xjDtQ8UfaarnYsLecnldw57/GHum07Ctdw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@stylistic/stylelint-config/-/stylelint-config-2.0.0.tgz", + "integrity": "sha512-8J4YAxggy2Nzkb8KJIOLbtMXTPZ5gpKVmyhiiuKEUgCl9XFND5lM0e/ZZBMGEYZ68h5qcsS/jgg1wh235erRAw==", "dev": true, "dependencies": { - "@stylistic/stylelint-plugin": "^2.0.0" + "@stylistic/stylelint-plugin": "^3.0.0" }, "engines": { "node": "^18.12 || >=20.9" }, "peerDependencies": { - "stylelint": "^16.0.2" + "stylelint": "^16.8.0" } }, "node_modules/@stylistic/stylelint-plugin": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-2.0.0.tgz", - "integrity": "sha512-dHKuT6PGd1WGZLOTuozAM7GdQzdmlmnFXYzvV1jYJXXpcCpV/OJ3+n8TXpMkoOeKHpJydY43EOoZTO1W/FOA4Q==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-3.1.1.tgz", + "integrity": "sha512-XagAHHIa528EvyGybv8EEYGK5zrVW74cHpsjhtovVATbhDRuJYfE+X4HCaAieW9lCkwbX6L+X0I4CiUG3w/hFw==", "dev": true, "dependencies": { - "@csstools/css-parser-algorithms": "^2.3.2", - "@csstools/css-tokenizer": "^2.2.1", - "@csstools/media-query-list-parser": "^2.1.5", + "@csstools/css-parser-algorithms": "^3.0.1", + "@csstools/css-tokenizer": "^3.0.1", + "@csstools/media-query-list-parser": "^3.0.1", "is-plain-object": "^5.0.0", - "postcss-selector-parser": "^6.0.13", + "postcss-selector-parser": "^6.1.2", "postcss-value-parser": "^4.2.0", "style-search": "^0.1.0", - "stylelint": "^16.0.2" + "stylelint": "^16.8.2" }, "engines": { "node": "^18.12 || >=20.9" }, "peerDependencies": { - "stylelint": "^16.0.2" + "stylelint": "^16.8.0" } }, "node_modules/@stylistic/stylelint-plugin/node_modules/is-plain-object": { @@ -442,6 +420,19 @@ "node": ">=0.10.0" } }, + "node_modules/@stylistic/stylelint-plugin/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@types/eslint": { "version": "8.56.10", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", @@ -804,9 +795,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.0.tgz", + "integrity": "sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==", "dev": true, "funding": [ { @@ -823,10 +814,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001718", + "electron-to-chromium": "^1.5.160", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" @@ -882,9 +873,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001612", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz", - "integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==", + "version": "1.0.30001721", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001721.tgz", + "integrity": "sha512-cOuvmUVtKrtEaoKiO0rSc29jcjwMwX5tOHDy4MgVFEWiUXj4uBMJkwI8MDySkgXidpMiHUcviogAvFi4pA2hDQ==", "dev": true, "funding": [ { @@ -1085,9 +1076,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "dependencies": { "path-key": "^3.1.0", @@ -1114,9 +1105,9 @@ } }, "node_modules/css-functions-list": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.2.tgz", - "integrity": "sha512-c+N0v6wbKVxTu5gOBBFkr9BEdBWaqqjQeiJ8QvSRIJOf+UxlJh930m8e6/WNeODIK0mYLFkoONrnj16i2EcvfQ==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz", + "integrity": "sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==", "dev": true, "engines": { "node": ">=12 || >=16" @@ -1133,12 +1124,12 @@ } }, "node_modules/css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", "dev": true, "dependencies": { - "mdn-data": "2.0.30", + "mdn-data": "2.12.2", "source-map-js": "^1.0.1" }, "engines": { @@ -1167,12 +1158,12 @@ } }, "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "dev": true, "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -1223,20 +1214,19 @@ } }, "node_modules/doiuse": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/doiuse/-/doiuse-6.0.2.tgz", - "integrity": "sha512-eBTs23NOX+EAYPr4RbCR6J4DRW/TML3uMo37y0X1whlkersDYFCk9HmCl09KX98cis22VKsV1QaxfVNauJ3NBw==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/doiuse/-/doiuse-6.0.5.tgz", + "integrity": "sha512-ljuf9ndGqKST0GlPAYyCg04hbQAeR1xIIWVDjQaDDkoTY/Y1Vb+8FNoy6NuVuJIEEKe/nKUH8NRWjG7JJxZ9Eg==", "dev": true, "dependencies": { - "browserslist": "^4.21.5", - "caniuse-lite": "^1.0.30001487", + "browserslist": "^4.24.0", + "caniuse-lite": "^1.0.30001669", "css-tokenize": "^1.0.1", - "duplexify": "^4.1.2", - "ldjson-stream": "^1.2.1", + "duplexify": "^4.1.3", "multimatch": "^5.0.0", - "postcss": "^8.4.21", + "postcss": "^8.4.47", "source-map": "^0.7.4", - "yargs": "^17.7.1" + "yargs": "^17.7.2" }, "bin": { "doiuse": "bin/cli.js" @@ -1287,9 +1277,9 @@ } }, "node_modules/domutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", "dev": true, "dependencies": { "dom-serializer": "^2.0.0", @@ -1336,9 +1326,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.750", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.750.tgz", - "integrity": "sha512-9ItEpeu15hW5m8jKdriL+BQrgwDTXEL9pn4SkillWFu73ZNNNQ2BKKLS+ZHv2vC9UkNhosAeyfxOf/5OSeTCPA==", + "version": "1.5.165", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.165.tgz", + "integrity": "sha512-naiMx1Z6Nb2TxPU6fiFrUrDTjyPMLdTtaOd2oLmG8zVSg2hCWGkhPyxwk+qRmZ1ytwVqUv0u7ZcDA5+ALhaUtw==", "dev": true }, "node_modules/emoji-regex": { @@ -1410,9 +1400,9 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "engines": { "node": ">=6" @@ -1501,9 +1491,9 @@ } }, "node_modules/eslint-config-wikimedia": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.28.2.tgz", - "integrity": "sha512-5+rdnT7wH1gpKAO6tHYThg78eMhZMruJzvqku3Y5iaEY/A7kSKLFpA/vOj/snys9fKjDHC9BXmArQh+agkOoJQ==", + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.30.0.tgz", + "integrity": "sha512-i8ESzSoo0x3Jur/0JhAgCVPxbV51zfdI3MN3MVQPnjiFdmo21CNKmiBBmw8JnJ3fx/d5zHDrBa+yDjxSLpnDlA==", "dev": true, "dependencies": { "browserslist-config-wikimedia": "^0.7.0", @@ -1516,13 +1506,16 @@ "eslint-plugin-mediawiki": "^0.7.0", "eslint-plugin-mocha": "^10.4.3", "eslint-plugin-n": "^17.7.0", - "eslint-plugin-no-jquery": "^3.0.1", + "eslint-plugin-no-jquery": "^3.1.1", "eslint-plugin-qunit": "^8.1.1", "eslint-plugin-security": "^1.7.1", "eslint-plugin-unicorn": "^53.0.0", "eslint-plugin-vue": "^9.26.0", "eslint-plugin-wdio": "^8.24.12", "eslint-plugin-yml": "^1.14.0" + }, + "engines": { + "node": ">=18 <23" } }, "node_modules/eslint-plugin-compat": { @@ -1720,9 +1713,9 @@ } }, "node_modules/eslint-plugin-no-jquery": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-3.0.2.tgz", - "integrity": "sha512-n/+6p6PFhWDNPVLJj1463hw4OTIRBbROGcbhmtOHTgw7yihSKzkwZiQ00EJTneyeR3jRiw5lpWSMCCBhtb8t2g==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-3.1.1.tgz", + "integrity": "sha512-LTLO3jH/Tjr1pmxCEqtV6qmt+OChv8La4fwgG470JRpgxyFF4NOzoC9CRy92GIWD3Yjl0qLEgPmD2FLQWcNEjg==", "dev": true, "peerDependencies": { "eslint": ">=8.0.0" @@ -2167,10 +2160,20 @@ "dev": true }, "node_modules/fast-uri": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", - "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", - "dev": true + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ] }, "node_modules/fastest-levenshtein": { "version": "1.0.16", @@ -3156,21 +3159,11 @@ } }, "node_modules/known-css-properties": { - "version": "0.34.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.34.0.tgz", - "integrity": "sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==", + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.35.0.tgz", + "integrity": "sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==", "dev": true }, - "node_modules/ldjson-stream": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ldjson-stream/-/ldjson-stream-1.2.1.tgz", - "integrity": "sha512-xw/nNEXafuPSLu8NjjG3+atVVw+8U1APZAQylmwQn19Hgw6rC7QjHvP6MupnHWCrzSm9m0xs5QWkCLuRvBPjgQ==", - "dev": true, - "dependencies": { - "split2": "^0.2.1", - "through2": "^0.6.1" - } - }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -3301,9 +3294,9 @@ } }, "node_modules/mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", "dev": true }, "node_modules/meow": { @@ -3362,9 +3355,9 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "node_modules/multimatch": { @@ -3387,9 +3380,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, "funding": [ { @@ -3411,9 +3404,9 @@ "dev": true }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "dev": true }, "node_modules/nopt": { @@ -3738,9 +3731,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true }, "node_modules/picomatch": { @@ -3765,9 +3758,9 @@ } }, "node_modules/postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.4.tgz", + "integrity": "sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==", "dev": true, "funding": [ { @@ -3784,22 +3777,22 @@ } ], "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" } }, "node_modules/postcss-html": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.6.0.tgz", - "integrity": "sha512-OWgQ9/Pe23MnNJC0PL4uZp8k0EDaUvqpJFSiwFxOLClAhmD7UEisyhO3x5hVsD4xFrjReVTXydlrMes45dJ71w==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.7.0.tgz", + "integrity": "sha512-MfcMpSUIaR/nNgeVS8AyvyDugXlADjN9AcV7e5rDfrF1wduIAGSkL4q2+wgrZgA3sHVAHLDO9FuauHhZYW2nBw==", "dev": true, "dependencies": { "htmlparser2": "^8.0.0", - "js-tokens": "^8.0.0", + "js-tokens": "^9.0.0", "postcss": "^8.4.0", "postcss-safe-parser": "^6.0.0" }, @@ -3808,27 +3801,11 @@ } }, "node_modules/postcss-html/node_modules/js-tokens": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.3.tgz", - "integrity": "sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", "dev": true }, - "node_modules/postcss-html/node_modules/postcss-safe-parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", - "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", - "dev": true, - "engines": { - "node": ">=12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.3.3" - } - }, "node_modules/postcss-less": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-6.0.0.tgz", @@ -3842,35 +3819,25 @@ } }, "node_modules/postcss-resolve-nested-selector": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", - "integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz", + "integrity": "sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==", "dev": true }, "node_modules/postcss-safe-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.0.tgz", - "integrity": "sha512-ovehqRNVCpuFzbXoTb4qLtyzK3xn3t/CUBxOs8LsnQjQrShaB4lKiHoVqY8ANaC0hBMHq5QVWk77rwGklFUDrg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", + "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss-safe-parser" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "engines": { - "node": ">=18.0" + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" }, "peerDependencies": { - "postcss": "^8.4.31" + "postcss": "^8.3.3" } }, "node_modules/postcss-selector-parser": { @@ -4409,9 +4376,9 @@ } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -4459,15 +4426,6 @@ "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", "dev": true }, - "node_modules/split2": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/split2/-/split2-0.2.1.tgz", - "integrity": "sha512-D/oTExYAkC9nWleOCTOyNmAuzfAT/6rHGBA9LIK7FVnGo13CSvrKCUzKenwH6U1s2znY9MqH6v0UQTEDa3vJmg==", - "dev": true, - "dependencies": { - "through2": "~0.6.1" - } - }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -4549,9 +4507,9 @@ "dev": true }, "node_modules/stylelint": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.7.0.tgz", - "integrity": "sha512-Q1ATiXlz+wYr37a7TGsfvqYn2nSR3T/isw3IWlZQzFzCNoACHuGBb6xBplZXz56/uDRJHIygxjh7jbV/8isewA==", + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.12.0.tgz", + "integrity": "sha512-F8zZ3L/rBpuoBZRvI4JVT20ZanPLXfQLzMOZg1tzPflRVh9mKpOZ8qcSIhh1my3FjAjZWG4T2POwGnmn6a6hbg==", "dev": true, "funding": [ { @@ -4564,44 +4522,43 @@ } ], "dependencies": { - "@csstools/css-parser-algorithms": "^2.7.1", - "@csstools/css-tokenizer": "^2.4.1", - "@csstools/media-query-list-parser": "^2.1.13", - "@csstools/selector-specificity": "^3.1.1", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/media-query-list-parser": "^4.0.2", + "@csstools/selector-specificity": "^5.0.0", "@dual-bundle/import-meta-resolve": "^4.1.0", "balanced-match": "^2.0.0", "colord": "^2.9.3", "cosmiconfig": "^9.0.0", - "css-functions-list": "^3.2.2", - "css-tree": "^2.3.1", - "debug": "^4.3.5", + "css-functions-list": "^3.2.3", + "css-tree": "^3.0.1", + "debug": "^4.3.7", "fast-glob": "^3.3.2", "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^9.0.0", + "file-entry-cache": "^9.1.0", "global-modules": "^2.0.0", "globby": "^11.1.0", "globjoin": "^0.1.4", "html-tags": "^3.3.1", - "ignore": "^5.3.1", + "ignore": "^6.0.2", "imurmurhash": "^0.1.4", "is-plain-object": "^5.0.0", - "known-css-properties": "^0.34.0", + "known-css-properties": "^0.35.0", "mathml-tag-names": "^2.1.3", "meow": "^13.2.0", - "micromatch": "^4.0.7", + "micromatch": "^4.0.8", "normalize-path": "^3.0.0", - "picocolors": "^1.0.1", - "postcss": "^8.4.39", - "postcss-resolve-nested-selector": "^0.1.1", - "postcss-safe-parser": "^7.0.0", - "postcss-selector-parser": "^6.1.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.49", + "postcss-resolve-nested-selector": "^0.1.6", + "postcss-safe-parser": "^7.0.1", + "postcss-selector-parser": "^7.0.0", "postcss-value-parser": "^4.2.0", "resolve-from": "^5.0.0", "string-width": "^4.2.3", - "strip-ansi": "^7.1.0", - "supports-hyperlinks": "^3.0.0", + "supports-hyperlinks": "^3.1.0", "svg-tags": "^1.0.0", - "table": "^6.8.2", + "table": "^6.9.0", "write-file-atomic": "^5.0.1" }, "bin": { @@ -4612,200 +4569,105 @@ } }, "node_modules/stylelint-config-recommended": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-14.0.0.tgz", - "integrity": "sha512-jSkx290CglS8StmrLp2TxAppIajzIBZKYm3IxT89Kg6fGlxbPiTiyH9PS5YUuVAFwaJLl1ikiXX0QWjI0jmgZQ==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-14.0.1.tgz", + "integrity": "sha512-bLvc1WOz/14aPImu/cufKAZYfXs/A/owZfSMZ4N+16WGXLoX5lOir53M6odBxvhgmgdxCVnNySJmZKx73T93cg==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + }, + { + "type": "github", + "url": "https://github.com/sponsors/stylelint" + } + ], "engines": { "node": ">=18.12.0" }, "peerDependencies": { - "stylelint": "^16.0.0" + "stylelint": "^16.1.0" } }, "node_modules/stylelint-config-wikimedia": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/stylelint-config-wikimedia/-/stylelint-config-wikimedia-0.17.2.tgz", - "integrity": "sha512-cc3PYhe1O/GTgsMOp+Ri3ru579YBbZ3Me0oU7xNb06n4iwyXYPz8qO5G4iQ13UH19UW2NIS8Tk0goPRrJ1RAfw==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/stylelint-config-wikimedia/-/stylelint-config-wikimedia-0.18.0.tgz", + "integrity": "sha512-Lr45NIe7pG8i7BPcMc6EddO1pRK8/KNG8gp4o/oOG1Ez10hglJuJb/QT17BlzX8NPkhtP2KdY63NS2f/Wcj6Ww==", "dev": true, "dependencies": { - "@stylistic/stylelint-config": "1.0.1", - "@stylistic/stylelint-plugin": "2.0.0", + "@stylistic/stylelint-config": "2.0.0", + "@stylistic/stylelint-plugin": "3.1.1", "browserslist-config-wikimedia": "0.7.0", - "postcss-html": "1.6.0", + "postcss-html": "1.7.0", "postcss-less": "6.0.0", - "stylelint": "16.2.0", - "stylelint-config-recommended": "14.0.0", - "stylelint-no-unsupported-browser-features": "8.0.1" + "stylelint": "16.12.0", + "stylelint-config-recommended": "14.0.1", + "stylelint-no-unsupported-browser-features": "8.0.2" }, "peerDependencies": { "postcss-less": "^6.0.0" } }, - "node_modules/stylelint-config-wikimedia/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/stylelint-config-wikimedia/node_modules/balanced-match": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", - "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", - "dev": true - }, - "node_modules/stylelint-config-wikimedia/node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/stylelint-config-wikimedia/node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/stylelint-config-wikimedia/node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stylelint-config-wikimedia/node_modules/known-css-properties": { - "version": "0.29.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.29.0.tgz", - "integrity": "sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==", - "dev": true - }, - "node_modules/stylelint-config-wikimedia/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/stylelint-config-wikimedia/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/stylelint-config-wikimedia/node_modules/stylelint": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.2.0.tgz", - "integrity": "sha512-gwqU5AkIb52wrAzzn+359S3NIJDMl02TXLUaV2tzA/L6jUdpTwNt+MCxHlc8+Hb2bUHlYVo92YeSIryF2gJthA==", + "node_modules/stylelint-no-unsupported-browser-features": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/stylelint-no-unsupported-browser-features/-/stylelint-no-unsupported-browser-features-8.0.2.tgz", + "integrity": "sha512-4PY2qJ3ZTEje9RgGfaQ82eJoPioXxs6hazeKpji/wzLNVzTX2wd4b0Ds3ewdLkH3ID+o63IInuTquU2MNJO3YQ==", "dev": true, "dependencies": { - "@csstools/css-parser-algorithms": "^2.5.0", - "@csstools/css-tokenizer": "^2.2.3", - "@csstools/media-query-list-parser": "^2.1.7", - "@csstools/selector-specificity": "^3.0.1", - "balanced-match": "^2.0.0", - "colord": "^2.9.3", - "cosmiconfig": "^9.0.0", - "css-functions-list": "^3.2.1", - "css-tree": "^2.3.1", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^8.0.0", - "global-modules": "^2.0.0", - "globby": "^11.1.0", - "globjoin": "^0.1.4", - "html-tags": "^3.3.1", - "ignore": "^5.3.0", - "imurmurhash": "^0.1.4", - "is-plain-object": "^5.0.0", - "known-css-properties": "^0.29.0", - "mathml-tag-names": "^2.1.3", - "meow": "^13.1.0", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.33", - "postcss-resolve-nested-selector": "^0.1.1", - "postcss-safe-parser": "^7.0.0", - "postcss-selector-parser": "^6.0.15", - "postcss-value-parser": "^4.2.0", - "resolve-from": "^5.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^7.1.0", - "supports-hyperlinks": "^3.0.0", - "svg-tags": "^1.0.0", - "table": "^6.8.1", - "write-file-atomic": "^5.0.1" - }, - "bin": { - "stylelint": "bin/stylelint.mjs" + "doiuse": "^6.0.5", + "postcss": "^8.4.32" }, "engines": { "node": ">=18.12.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/stylelint" + "peerDependencies": { + "stylelint": "^16.0.2" } }, - "node_modules/stylelint-no-unsupported-browser-features": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/stylelint-no-unsupported-browser-features/-/stylelint-no-unsupported-browser-features-8.0.1.tgz", - "integrity": "sha512-tc8Xn5DaqJhxTmbA4H8gZbYdAz027NfuSZv5+cVieQb7BtBrF/1/iKYdpcGwXPl3GtqkQrisiXuGqKkKnzWcLw==", + "node_modules/stylelint/node_modules/@csstools/media-query-list-parser": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz", + "integrity": "sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==", "dev": true, - "dependencies": { - "doiuse": "^6.0.2", - "postcss": "^8.4.32" - }, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "engines": { - "node": ">=18.12.0" + "node": ">=18" }, "peerDependencies": { - "stylelint": "^16.0.2" + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" } }, - "node_modules/stylelint/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "node_modules/stylelint/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "engines": { - "node": ">=12" + "node": ">=18" }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" } }, "node_modules/stylelint/node_modules/balanced-match": { @@ -4815,9 +4677,9 @@ "dev": true }, "node_modules/stylelint/node_modules/file-entry-cache": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.0.0.tgz", - "integrity": "sha512-6MgEugi8p2tiUhqO7GnPsmbCCzj0YRCwwaTbpGRyKZesjRSzkqkAE9fPp7V2yMs5hwfgbQLgdvSSkGNg1s5Uvw==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.1.0.tgz", + "integrity": "sha512-/pqPFG+FdxWQj+/WSuzXSDaNzxgTLr/OrR1QuqfEZzDakpdYE70PwUxL7BPUa8hpjbvY1+qvCl8k+8Tq34xJgg==", "dev": true, "dependencies": { "flat-cache": "^5.0.0" @@ -4839,6 +4701,15 @@ "node": ">=18" } }, + "node_modules/stylelint/node_modules/ignore": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-6.0.2.tgz", + "integrity": "sha512-InwqeHHN2XpumIkMvpl/DCJVrAHgCsG5+cn1XlnLWGwtZBm8QJfSusItfrwx81CTp5agNZqpKU2J/ccC5nGT4A==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/stylelint/node_modules/is-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", @@ -4848,28 +4719,52 @@ "node": ">=0.10.0" } }, - "node_modules/stylelint/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "node_modules/stylelint/node_modules/postcss-safe-parser": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz", + "integrity": "sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-safe-parser" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "engines": { - "node": ">=8" + "node": ">=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/stylelint/node_modules/strip-ansi": { + "node_modules/stylelint/node_modules/postcss-selector-parser": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", "dev": true, "dependencies": { - "ansi-regex": "^6.0.1" + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": ">=4" + } + }, + "node_modules/stylelint/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" } }, "node_modules/supports-color": { @@ -4885,9 +4780,9 @@ } }, "node_modules/supports-hyperlinks": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", - "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", + "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", "dev": true, "dependencies": { "has-flag": "^4.0.0", @@ -4895,6 +4790,9 @@ }, "engines": { "node": ">=14.18" + }, + "funding": { + "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" } }, "node_modules/supports-preserve-symlinks-flag": { @@ -4916,9 +4814,9 @@ "dev": true }, "node_modules/table": { - "version": "6.8.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", - "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", + "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", "dev": true, "dependencies": { "ajv": "^8.0.1", @@ -4968,28 +4866,6 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, - "node_modules/through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha512-RkK/CCESdTKQZHdmKICijdKKsCRVHs5KsLZ6pACAmF/1GPUQhonHSXWNERctxEp7RmvjdNbZTL5z9V7nSCXKcg==", - "dev": true, - "dependencies": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - } - }, - "node_modules/through2/node_modules/readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, "node_modules/tiny-lr": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", @@ -5108,9 +4984,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", "dev": true, "funding": [ { @@ -5127,8 +5003,8 @@ } ], "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -5471,29 +5347,22 @@ } }, "@csstools/css-parser-algorithms": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.7.1.tgz", - "integrity": "sha512-2SJS42gxmACHgikc1WGesXLIT8d/q2l0UFM7TaEeIzdFCE/FPMtTiizcPGGJtlPo2xuQzY09OhrLTzRxqJqwGw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", "dev": true, "requires": {} }, "@csstools/css-tokenizer": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.4.1.tgz", - "integrity": "sha512-eQ9DIktFJBhGjioABJRtUucoWR2mwllurfnM8LuNGAqX3ViZXaUchqk+1s7jjtkFiT9ySdACsFEA3etErkALUg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", "dev": true }, "@csstools/media-query-list-parser": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.13.tgz", - "integrity": "sha512-XaHr+16KRU9Gf8XLi3q8kDlI18d5vzKSKCY510Vrtc9iNR0NJzbY9hhTmwhzYZj/ZwGL4VmB3TA9hJW0Um2qFA==", - "dev": true, - "requires": {} - }, - "@csstools/selector-specificity": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.1.1.tgz", - "integrity": "sha512-a7cxGcJ2wIlMFLlh8z2ONm+715QkPHiyJcxwQlKOz/03GPw1COpfhcmC9wm4xlZfp//jWHNNMwzjtqHXVWU9KA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-3.0.1.tgz", + "integrity": "sha512-HNo8gGD02kHmcbX6PvCoUuOQvn4szyB9ca63vZHKX5A81QytgDG4oxG4IaEfHTlEZSZ6MjPEMWIVU+zF2PZcgw==", "dev": true, "requires": {} }, @@ -5637,28 +5506,28 @@ } }, "@stylistic/stylelint-config": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@stylistic/stylelint-config/-/stylelint-config-1.0.1.tgz", - "integrity": "sha512-JgFP88HZEyo34k9RpWVdcQJtLPrMxYE58IO3qypXhmvE/NmZohj+xjDtQ8UfaarnYsLecnldw57/GHum07Ctdw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@stylistic/stylelint-config/-/stylelint-config-2.0.0.tgz", + "integrity": "sha512-8J4YAxggy2Nzkb8KJIOLbtMXTPZ5gpKVmyhiiuKEUgCl9XFND5lM0e/ZZBMGEYZ68h5qcsS/jgg1wh235erRAw==", "dev": true, "requires": { - "@stylistic/stylelint-plugin": "^2.0.0" + "@stylistic/stylelint-plugin": "^3.0.0" } }, "@stylistic/stylelint-plugin": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-2.0.0.tgz", - "integrity": "sha512-dHKuT6PGd1WGZLOTuozAM7GdQzdmlmnFXYzvV1jYJXXpcCpV/OJ3+n8TXpMkoOeKHpJydY43EOoZTO1W/FOA4Q==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-3.1.1.tgz", + "integrity": "sha512-XagAHHIa528EvyGybv8EEYGK5zrVW74cHpsjhtovVATbhDRuJYfE+X4HCaAieW9lCkwbX6L+X0I4CiUG3w/hFw==", "dev": true, "requires": { - "@csstools/css-parser-algorithms": "^2.3.2", - "@csstools/css-tokenizer": "^2.2.1", - "@csstools/media-query-list-parser": "^2.1.5", + "@csstools/css-parser-algorithms": "^3.0.1", + "@csstools/css-tokenizer": "^3.0.1", + "@csstools/media-query-list-parser": "^3.0.1", "is-plain-object": "^5.0.0", - "postcss-selector-parser": "^6.0.13", + "postcss-selector-parser": "^6.1.2", "postcss-value-parser": "^4.2.0", "style-search": "^0.1.0", - "stylelint": "^16.0.2" + "stylelint": "^16.8.2" }, "dependencies": { "is-plain-object": { @@ -5666,6 +5535,16 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true + }, + "postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } } } }, @@ -5939,15 +5818,15 @@ } }, "browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.0.tgz", + "integrity": "sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001718", + "electron-to-chromium": "^1.5.160", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" } }, "browserslist-config-wikimedia": { @@ -5985,9 +5864,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001612", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz", - "integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==", + "version": "1.0.30001721", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001721.tgz", + "integrity": "sha512-cOuvmUVtKrtEaoKiO0rSc29jcjwMwX5tOHDy4MgVFEWiUXj4uBMJkwI8MDySkgXidpMiHUcviogAvFi4pA2hDQ==", "dev": true }, "chalk": { @@ -6124,9 +6003,9 @@ } }, "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "requires": { "path-key": "^3.1.0", @@ -6146,9 +6025,9 @@ } }, "css-functions-list": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.2.tgz", - "integrity": "sha512-c+N0v6wbKVxTu5gOBBFkr9BEdBWaqqjQeiJ8QvSRIJOf+UxlJh930m8e6/WNeODIK0mYLFkoONrnj16i2EcvfQ==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz", + "integrity": "sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==", "dev": true }, "css-tokenize": { @@ -6162,12 +6041,12 @@ } }, "css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", "dev": true, "requires": { - "mdn-data": "2.0.30", + "mdn-data": "2.12.2", "source-map-js": "^1.0.1" } }, @@ -6184,12 +6063,12 @@ "dev": true }, "debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "dev": true, "requires": { - "ms": "2.1.2" + "ms": "^2.1.3" } }, "deep-is": { @@ -6223,20 +6102,19 @@ } }, "doiuse": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/doiuse/-/doiuse-6.0.2.tgz", - "integrity": "sha512-eBTs23NOX+EAYPr4RbCR6J4DRW/TML3uMo37y0X1whlkersDYFCk9HmCl09KX98cis22VKsV1QaxfVNauJ3NBw==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/doiuse/-/doiuse-6.0.5.tgz", + "integrity": "sha512-ljuf9ndGqKST0GlPAYyCg04hbQAeR1xIIWVDjQaDDkoTY/Y1Vb+8FNoy6NuVuJIEEKe/nKUH8NRWjG7JJxZ9Eg==", "dev": true, "requires": { - "browserslist": "^4.21.5", - "caniuse-lite": "^1.0.30001487", + "browserslist": "^4.24.0", + "caniuse-lite": "^1.0.30001669", "css-tokenize": "^1.0.1", - "duplexify": "^4.1.2", - "ldjson-stream": "^1.2.1", + "duplexify": "^4.1.3", "multimatch": "^5.0.0", - "postcss": "^8.4.21", + "postcss": "^8.4.47", "source-map": "^0.7.4", - "yargs": "^17.7.1" + "yargs": "^17.7.2" } }, "dom-serializer": { @@ -6266,9 +6144,9 @@ } }, "domutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", "dev": true, "requires": { "dom-serializer": "^2.0.0", @@ -6311,9 +6189,9 @@ } }, "electron-to-chromium": { - "version": "1.4.750", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.750.tgz", - "integrity": "sha512-9ItEpeu15hW5m8jKdriL+BQrgwDTXEL9pn4SkillWFu73ZNNNQ2BKKLS+ZHv2vC9UkNhosAeyfxOf/5OSeTCPA==", + "version": "1.5.165", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.165.tgz", + "integrity": "sha512-naiMx1Z6Nb2TxPU6fiFrUrDTjyPMLdTtaOd2oLmG8zVSg2hCWGkhPyxwk+qRmZ1ytwVqUv0u7ZcDA5+ALhaUtw==", "dev": true }, "emoji-regex": { @@ -6373,9 +6251,9 @@ } }, "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true }, "escape-string-regexp": { @@ -6475,9 +6353,9 @@ } }, "eslint-config-wikimedia": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.28.2.tgz", - "integrity": "sha512-5+rdnT7wH1gpKAO6tHYThg78eMhZMruJzvqku3Y5iaEY/A7kSKLFpA/vOj/snys9fKjDHC9BXmArQh+agkOoJQ==", + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.30.0.tgz", + "integrity": "sha512-i8ESzSoo0x3Jur/0JhAgCVPxbV51zfdI3MN3MVQPnjiFdmo21CNKmiBBmw8JnJ3fx/d5zHDrBa+yDjxSLpnDlA==", "dev": true, "requires": { "browserslist-config-wikimedia": "^0.7.0", @@ -6490,7 +6368,7 @@ "eslint-plugin-mediawiki": "^0.7.0", "eslint-plugin-mocha": "^10.4.3", "eslint-plugin-n": "^17.7.0", - "eslint-plugin-no-jquery": "^3.0.1", + "eslint-plugin-no-jquery": "^3.1.1", "eslint-plugin-qunit": "^8.1.1", "eslint-plugin-security": "^1.7.1", "eslint-plugin-unicorn": "^53.0.0", @@ -6625,9 +6503,9 @@ } }, "eslint-plugin-no-jquery": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-3.0.2.tgz", - "integrity": "sha512-n/+6p6PFhWDNPVLJj1463hw4OTIRBbROGcbhmtOHTgw7yihSKzkwZiQ00EJTneyeR3jRiw5lpWSMCCBhtb8t2g==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-3.1.1.tgz", + "integrity": "sha512-LTLO3jH/Tjr1pmxCEqtV6qmt+OChv8La4fwgG470JRpgxyFF4NOzoC9CRy92GIWD3Yjl0qLEgPmD2FLQWcNEjg==", "dev": true, "requires": {} }, @@ -6914,9 +6792,9 @@ "dev": true }, "fast-uri": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", - "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", "dev": true }, "fastest-levenshtein": { @@ -7659,21 +7537,11 @@ "dev": true }, "known-css-properties": { - "version": "0.34.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.34.0.tgz", - "integrity": "sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==", + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.35.0.tgz", + "integrity": "sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==", "dev": true }, - "ldjson-stream": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ldjson-stream/-/ldjson-stream-1.2.1.tgz", - "integrity": "sha512-xw/nNEXafuPSLu8NjjG3+atVVw+8U1APZAQylmwQn19Hgw6rC7QjHvP6MupnHWCrzSm9m0xs5QWkCLuRvBPjgQ==", - "dev": true, - "requires": { - "split2": "^0.2.1", - "through2": "^0.6.1" - } - }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -7781,9 +7649,9 @@ "dev": true }, "mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", "dev": true }, "meow": { @@ -7824,9 +7692,9 @@ } }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "multimatch": { @@ -7843,9 +7711,9 @@ } }, "nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true }, "natural-compare": { @@ -7855,9 +7723,9 @@ "dev": true }, "node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "dev": true }, "nopt": { @@ -8100,9 +7968,9 @@ "dev": true }, "picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true }, "picomatch": { @@ -8118,40 +7986,33 @@ "dev": true }, "postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.4.tgz", + "integrity": "sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==", "dev": true, "requires": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" } }, "postcss-html": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.6.0.tgz", - "integrity": "sha512-OWgQ9/Pe23MnNJC0PL4uZp8k0EDaUvqpJFSiwFxOLClAhmD7UEisyhO3x5hVsD4xFrjReVTXydlrMes45dJ71w==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.7.0.tgz", + "integrity": "sha512-MfcMpSUIaR/nNgeVS8AyvyDugXlADjN9AcV7e5rDfrF1wduIAGSkL4q2+wgrZgA3sHVAHLDO9FuauHhZYW2nBw==", "dev": true, "requires": { "htmlparser2": "^8.0.0", - "js-tokens": "^8.0.0", + "js-tokens": "^9.0.0", "postcss": "^8.4.0", "postcss-safe-parser": "^6.0.0" }, "dependencies": { "js-tokens": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.3.tgz", - "integrity": "sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", "dev": true - }, - "postcss-safe-parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", - "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", - "dev": true, - "requires": {} } } }, @@ -8163,15 +8024,15 @@ "requires": {} }, "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=", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz", + "integrity": "sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==", "dev": true }, "postcss-safe-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.0.tgz", - "integrity": "sha512-ovehqRNVCpuFzbXoTb4qLtyzK3xn3t/CUBxOs8LsnQjQrShaB4lKiHoVqY8ANaC0hBMHq5QVWk77rwGklFUDrg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", + "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", "dev": true, "requires": {} }, @@ -8544,9 +8405,9 @@ "dev": true }, "source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true }, "spdx-correct": { @@ -8593,15 +8454,6 @@ "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", "dev": true }, - "split2": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/split2/-/split2-0.2.1.tgz", - "integrity": "sha512-D/oTExYAkC9nWleOCTOyNmAuzfAT/6rHGBA9LIK7FVnGo13CSvrKCUzKenwH6U1s2znY9MqH6v0UQTEDa3vJmg==", - "dev": true, - "requires": { - "through2": "~0.6.1" - } - }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -8668,57 +8520,64 @@ "dev": true }, "stylelint": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.7.0.tgz", - "integrity": "sha512-Q1ATiXlz+wYr37a7TGsfvqYn2nSR3T/isw3IWlZQzFzCNoACHuGBb6xBplZXz56/uDRJHIygxjh7jbV/8isewA==", + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.12.0.tgz", + "integrity": "sha512-F8zZ3L/rBpuoBZRvI4JVT20ZanPLXfQLzMOZg1tzPflRVh9mKpOZ8qcSIhh1my3FjAjZWG4T2POwGnmn6a6hbg==", "dev": true, "requires": { - "@csstools/css-parser-algorithms": "^2.7.1", - "@csstools/css-tokenizer": "^2.4.1", - "@csstools/media-query-list-parser": "^2.1.13", - "@csstools/selector-specificity": "^3.1.1", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/media-query-list-parser": "^4.0.2", + "@csstools/selector-specificity": "^5.0.0", "@dual-bundle/import-meta-resolve": "^4.1.0", "balanced-match": "^2.0.0", "colord": "^2.9.3", "cosmiconfig": "^9.0.0", - "css-functions-list": "^3.2.2", - "css-tree": "^2.3.1", - "debug": "^4.3.5", + "css-functions-list": "^3.2.3", + "css-tree": "^3.0.1", + "debug": "^4.3.7", "fast-glob": "^3.3.2", "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^9.0.0", + "file-entry-cache": "^9.1.0", "global-modules": "^2.0.0", "globby": "^11.1.0", "globjoin": "^0.1.4", "html-tags": "^3.3.1", - "ignore": "^5.3.1", + "ignore": "^6.0.2", "imurmurhash": "^0.1.4", "is-plain-object": "^5.0.0", - "known-css-properties": "^0.34.0", + "known-css-properties": "^0.35.0", "mathml-tag-names": "^2.1.3", "meow": "^13.2.0", - "micromatch": "^4.0.7", + "micromatch": "^4.0.8", "normalize-path": "^3.0.0", - "picocolors": "^1.0.1", - "postcss": "^8.4.39", - "postcss-resolve-nested-selector": "^0.1.1", - "postcss-safe-parser": "^7.0.0", - "postcss-selector-parser": "^6.1.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.49", + "postcss-resolve-nested-selector": "^0.1.6", + "postcss-safe-parser": "^7.0.1", + "postcss-selector-parser": "^7.0.0", "postcss-value-parser": "^4.2.0", "resolve-from": "^5.0.0", "string-width": "^4.2.3", - "strip-ansi": "^7.1.0", - "supports-hyperlinks": "^3.0.0", + "supports-hyperlinks": "^3.1.0", "svg-tags": "^1.0.0", - "table": "^6.8.2", + "table": "^6.9.0", "write-file-atomic": "^5.0.1" }, "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true + "@csstools/media-query-list-parser": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz", + "integrity": "sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==", + "dev": true, + "requires": {} + }, + "@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "dev": true, + "requires": {} }, "balanced-match": { "version": "2.0.0", @@ -8727,9 +8586,9 @@ "dev": true }, "file-entry-cache": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.0.0.tgz", - "integrity": "sha512-6MgEugi8p2tiUhqO7GnPsmbCCzj0YRCwwaTbpGRyKZesjRSzkqkAE9fPp7V2yMs5hwfgbQLgdvSSkGNg1s5Uvw==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.1.0.tgz", + "integrity": "sha512-/pqPFG+FdxWQj+/WSuzXSDaNzxgTLr/OrR1QuqfEZzDakpdYE70PwUxL7BPUa8hpjbvY1+qvCl8k+8Tq34xJgg==", "dev": true, "requires": { "flat-cache": "^5.0.0" @@ -8745,165 +8604,73 @@ "keyv": "^4.5.4" } }, + "ignore": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-6.0.2.tgz", + "integrity": "sha512-InwqeHHN2XpumIkMvpl/DCJVrAHgCsG5+cn1XlnLWGwtZBm8QJfSusItfrwx81CTp5agNZqpKU2J/ccC5nGT4A==", + "dev": true + }, "is-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true }, - "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 + "postcss-safe-parser": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz", + "integrity": "sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==", + "dev": true, + "requires": {} }, - "strip-ansi": { + "postcss-selector-parser": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", "dev": true, "requires": { - "ansi-regex": "^6.0.1" + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" } + }, + "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 } } }, "stylelint-config-recommended": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-14.0.0.tgz", - "integrity": "sha512-jSkx290CglS8StmrLp2TxAppIajzIBZKYm3IxT89Kg6fGlxbPiTiyH9PS5YUuVAFwaJLl1ikiXX0QWjI0jmgZQ==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-14.0.1.tgz", + "integrity": "sha512-bLvc1WOz/14aPImu/cufKAZYfXs/A/owZfSMZ4N+16WGXLoX5lOir53M6odBxvhgmgdxCVnNySJmZKx73T93cg==", "dev": true, "requires": {} }, "stylelint-config-wikimedia": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/stylelint-config-wikimedia/-/stylelint-config-wikimedia-0.17.2.tgz", - "integrity": "sha512-cc3PYhe1O/GTgsMOp+Ri3ru579YBbZ3Me0oU7xNb06n4iwyXYPz8qO5G4iQ13UH19UW2NIS8Tk0goPRrJ1RAfw==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/stylelint-config-wikimedia/-/stylelint-config-wikimedia-0.18.0.tgz", + "integrity": "sha512-Lr45NIe7pG8i7BPcMc6EddO1pRK8/KNG8gp4o/oOG1Ez10hglJuJb/QT17BlzX8NPkhtP2KdY63NS2f/Wcj6Ww==", "dev": true, "requires": { - "@stylistic/stylelint-config": "1.0.1", - "@stylistic/stylelint-plugin": "2.0.0", + "@stylistic/stylelint-config": "2.0.0", + "@stylistic/stylelint-plugin": "3.1.1", "browserslist-config-wikimedia": "0.7.0", - "postcss-html": "1.6.0", + "postcss-html": "1.7.0", "postcss-less": "6.0.0", - "stylelint": "16.2.0", - "stylelint-config-recommended": "14.0.0", - "stylelint-no-unsupported-browser-features": "8.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true - }, - "balanced-match": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", - "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", - "dev": true - }, - "file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, - "requires": { - "flat-cache": "^4.0.0" - } - }, - "flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, - "requires": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - } - }, - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true - }, - "known-css-properties": { - "version": "0.29.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.29.0.tgz", - "integrity": "sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==", - "dev": true - }, - "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-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - }, - "stylelint": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.2.0.tgz", - "integrity": "sha512-gwqU5AkIb52wrAzzn+359S3NIJDMl02TXLUaV2tzA/L6jUdpTwNt+MCxHlc8+Hb2bUHlYVo92YeSIryF2gJthA==", - "dev": true, - "requires": { - "@csstools/css-parser-algorithms": "^2.5.0", - "@csstools/css-tokenizer": "^2.2.3", - "@csstools/media-query-list-parser": "^2.1.7", - "@csstools/selector-specificity": "^3.0.1", - "balanced-match": "^2.0.0", - "colord": "^2.9.3", - "cosmiconfig": "^9.0.0", - "css-functions-list": "^3.2.1", - "css-tree": "^2.3.1", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^8.0.0", - "global-modules": "^2.0.0", - "globby": "^11.1.0", - "globjoin": "^0.1.4", - "html-tags": "^3.3.1", - "ignore": "^5.3.0", - "imurmurhash": "^0.1.4", - "is-plain-object": "^5.0.0", - "known-css-properties": "^0.29.0", - "mathml-tag-names": "^2.1.3", - "meow": "^13.1.0", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.33", - "postcss-resolve-nested-selector": "^0.1.1", - "postcss-safe-parser": "^7.0.0", - "postcss-selector-parser": "^6.0.15", - "postcss-value-parser": "^4.2.0", - "resolve-from": "^5.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^7.1.0", - "supports-hyperlinks": "^3.0.0", - "svg-tags": "^1.0.0", - "table": "^6.8.1", - "write-file-atomic": "^5.0.1" - } - } + "stylelint": "16.12.0", + "stylelint-config-recommended": "14.0.1", + "stylelint-no-unsupported-browser-features": "8.0.2" } }, "stylelint-no-unsupported-browser-features": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/stylelint-no-unsupported-browser-features/-/stylelint-no-unsupported-browser-features-8.0.1.tgz", - "integrity": "sha512-tc8Xn5DaqJhxTmbA4H8gZbYdAz027NfuSZv5+cVieQb7BtBrF/1/iKYdpcGwXPl3GtqkQrisiXuGqKkKnzWcLw==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/stylelint-no-unsupported-browser-features/-/stylelint-no-unsupported-browser-features-8.0.2.tgz", + "integrity": "sha512-4PY2qJ3ZTEje9RgGfaQ82eJoPioXxs6hazeKpji/wzLNVzTX2wd4b0Ds3ewdLkH3ID+o63IInuTquU2MNJO3YQ==", "dev": true, "requires": { - "doiuse": "^6.0.2", + "doiuse": "^6.0.5", "postcss": "^8.4.32" } }, @@ -8917,9 +8684,9 @@ } }, "supports-hyperlinks": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", - "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", + "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", "dev": true, "requires": { "has-flag": "^4.0.0", @@ -8939,9 +8706,9 @@ "dev": true }, "table": { - "version": "6.8.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", - "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", + "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", "dev": true, "requires": { "ajv": "^8.0.1", @@ -8983,30 +8750,6 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha512-RkK/CCESdTKQZHdmKICijdKKsCRVHs5KsLZ6pACAmF/1GPUQhonHSXWNERctxEp7RmvjdNbZTL5z9V7nSCXKcg==", - "dev": true, - "requires": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } - } - }, "tiny-lr": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", @@ -9093,13 +8836,13 @@ "dev": true }, "update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", "dev": true, "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" } }, "uri-js": { diff --git a/package.json b/package.json index ee929ed..6bb576e 100644 --- a/package.json +++ b/package.json @@ -6,12 +6,12 @@ "test-fix": "grunt test --fix" }, "devDependencies": { - "eslint-config-wikimedia": "0.28.2", + "eslint-config-wikimedia": "0.30.0", "grunt": "1.6.1", "grunt-banana-checker": "0.13.0", "grunt-contrib-watch": "1.1.0", "grunt-eslint": "24.3.0", "grunt-stylelint": "0.20.1", - "stylelint-config-wikimedia": "0.17.2" + "stylelint-config-wikimedia": "0.18.0" } } diff --git a/resources/controller/uw.controller.Deed.js b/resources/controller/uw.controller.Deed.js index d843eaf..533e591 100644 --- a/resources/controller/uw.controller.Deed.js +++ b/resources/controller/uw.controller.Deed.js @@ -40,7 +40,7 @@ OO.inheritClass( uw.controller.Deed, uw.controller.Step ); uw.controller.Deed.prototype.moveNext = function () { - var + let deedController = this, valid, fields, validityPromises; @@ -52,10 +52,10 @@ valid = this.deedChooser.valid(); if ( valid ) { fields = this.deedChooser.deed.getFields(); - validityPromises = fields.map( function ( fieldLayout ) { + validityPromises = fields.map( ( fieldLayout ) => // Update any error/warning messages - return fieldLayout.checkValidity( true ); - } ); + fieldLayout.checkValidity( true ) + ); if ( validityPromises.length === 1 ) { // validityPromises will hold all promises for all uploads; // adding a bogus promise (no warnings & errors) to @@ -73,7 +73,7 @@ // TODO Handle warnings with a confirmation dialog - var i; + let i; for ( i = 0; i < arguments.length; i++ ) { if ( arguments[ i ][ 1 ].length ) { // One of the fields has errors; refuse to proceed! @@ -87,10 +87,10 @@ }; uw.controller.Deed.prototype.unload = function () { - var deedController = this; + const deedController = this; uw.controller.Step.prototype.unload.call( this ); - Object.keys( this.deeds ).forEach( function ( name ) { + Object.keys( this.deeds ).forEach( ( name ) => { deedController.deeds[ name ].unload(); } ); }; @@ -101,7 +101,7 @@ * @param {mw.UploadWizardUpload[]} uploads */ uw.controller.Deed.prototype.load = function ( uploads ) { - var customDeed, previousDeed; + let customDeed, previousDeed; uw.controller.Step.prototype.load.call( this, uploads ); @@ -130,7 +130,7 @@ .insertBefore( this.deedChooser.$selector.find( '.mediauploader-deed-ownwork' ) ) .msg( 'mediauploader-deeds-macro-prompt', this.uploads.length, mw.user ); - uploads.forEach( function ( upload ) { + uploads.forEach( ( upload ) => { // Add previews and details to the DOM upload.deedPreview = new uw.ui.DeedPreview( upload ); } ); diff --git a/resources/controller/uw.controller.Details.js b/resources/controller/uw.controller.Details.js index 843a65b..82aa27b 100644 --- a/resources/controller/uw.controller.Details.js +++ b/resources/controller/uw.controller.Details.js @@ -51,15 +51,15 @@ * @param {mw.UploadWizardUpload[]} uploads List of uploads being carried forward. */ uw.controller.Details.prototype.load = function ( uploads ) { - var controller = this; + const controller = this; uw.controller.Step.prototype.load.call( this, uploads ); // make sure queue is empty before starting this step this.queue.abortExecuting(); - this.uploads.forEach( function ( upload ) { - var serialized; + this.uploads.forEach( ( upload ) => { + let serialized; // get existing details serialized = upload.details ? upload.details.getSerialized() : null; @@ -90,7 +90,7 @@ }; uw.controller.Details.prototype.addCopyMetadataFeature = function () { - var first, + let first, // uploads can only be edited when they're in a certain state: // a flat out upload failure or a completed upload can not be edited invalidStates = [ 'aborted', 'error', 'complete' ], @@ -107,8 +107,8 @@ // rest failed because of abusefilter (or another recoverable error), in // which case we'll want the "copy" feature to appear below the 2nd // upload (or the first not-yet-completed not flat-out-failed upload) - this.uploads.some( function ( upload ) { - if ( upload && invalidStates.indexOf( upload.state ) === -1 ) { + this.uploads.some( ( upload ) => { + if ( upload && !invalidStates.includes( upload.state ) ) { first = upload; return true; // Break Array.some loop } @@ -148,9 +148,9 @@ * TODO move the rest of the logic here from mw.UploadWizard */ uw.controller.Details.prototype.startDetails = function () { - var details = this; + const details = this; - this.valid().done( function ( valid ) { + this.valid().done( ( valid ) => { if ( valid ) { details.ui.hideEndButtons(); details.submit(); @@ -166,7 +166,7 @@ * @return {jQuery.Promise} */ uw.controller.Details.prototype.valid = function () { - var detailsController = this, + const detailsController = this, // validityPromises will hold all promises for all uploads; // prefilling with a bogus promise (no warnings & errors) to // ensure $.when always resolves with an array of multiple @@ -176,14 +176,14 @@ validityPromises = [ $.Deferred().resolve( [], [] ).promise() ], titles = []; - this.uploads.forEach( function ( upload ) { + this.uploads.forEach( ( upload ) => { // Update any error/warning messages about all DetailsWidgets - var promise = upload.details.checkValidity( true ).then( function () { - var warnings = [], + const promise = upload.details.checkValidity( true ).then( function () { + let warnings = [], errors = [], title; - Array.prototype.forEach.call( arguments, function ( result ) { + Array.prototype.forEach.call( arguments, ( result ) => { warnings = warnings.concat( result[ 0 ] ); errors = errors.concat( result[ 1 ] ); } ); @@ -211,10 +211,10 @@ // validityPromises is an array of promises that each resolve with [warnings, errors] // for each upload - now iterate them all to figure out if we can proceed return $.when.apply( $, validityPromises ).then( function () { - var warnings = [], + let warnings = [], errors = []; - Array.prototype.forEach.call( arguments, function ( result ) { + Array.prototype.forEach.call( arguments, ( result ) => { warnings = warnings.concat( result[ 0 ] ); errors = errors.concat( result[ 1 ] ); } ); @@ -234,19 +234,15 @@ }; uw.controller.Details.prototype.confirmationDialog = function ( warnings ) { - var i, + let i, $message = $( '<p>' ).text( mw.message( 'mediauploader-dialog-warning' ).text() ), $ul = $( '<ul>' ); // parse warning messages - warnings = warnings.map( function ( warning ) { - return warning.text(); - } ); + warnings = warnings.map( ( warning ) => warning.text() ); // omit duplicates - warnings = warnings.filter( function ( warning, j, warningsOld ) { - return warningsOld.indexOf( warning ) === j; - } ); + warnings = warnings.filter( ( warning, j, warningsOld ) => warningsOld.indexOf( warning ) === j ); for ( i = 0; i < warnings.length; i++ ) { $ul.append( $( '<li>' ).text( warnings[ i ] ) ); @@ -265,9 +261,7 @@ label: mw.msg( 'mediauploader-dialog-continue' ) } ] - } ).closed.then( function ( data ) { - return !!( data && data.action === 'continue' ); - } ); + } ).closed.then( ( data ) => !!( data && data.action === 'continue' ) ); }; uw.controller.Details.prototype.canTransition = function ( upload ) { @@ -293,11 +287,11 @@ * @return {jQuery.Promise} */ uw.controller.Details.prototype.transitionAll = function () { - var + const deferred = $.Deferred(), details = this; - this.uploads.forEach( function ( upload ) { + this.uploads.forEach( ( upload ) => { if ( details.canTransition( upload ) ) { details.queue.addItem( upload ); } @@ -315,9 +309,9 @@ * @return {jQuery.Promise} */ uw.controller.Details.prototype.submit = function () { - var details = this; + const details = this; - this.uploads.forEach( function ( upload ) { + this.uploads.forEach( ( upload ) => { // Clear error state if ( upload.state === 'error' || upload.state === 'recoverable-error' ) { upload.state = details.stepName; @@ -331,7 +325,7 @@ this.ui.disableEdits(); this.removeCopyMetadataFeature(); - return this.transitionAll().then( function () { + return this.transitionAll().then( () => { details.showErrors(); if ( details.showNext() ) { diff --git a/resources/controller/uw.controller.Step.js b/resources/controller/uw.controller.Step.js index f981299..fcea7f8 100644 --- a/resources/controller/uw.controller.Step.js +++ b/resources/controller/uw.controller.Step.js @@ -26,7 +26,7 @@ * @param {Object} config UploadWizard config object. */ uw.controller.Step = function UWControllerStep( ui, api, config ) { - var step = this; + const step = this; OO.EventEmitter.call( this ); @@ -60,11 +60,11 @@ 'remove-upload': this.removeUpload }; - this.ui.on( 'next-step', function () { + this.ui.on( 'next-step', () => { step.moveNext(); } ); - this.ui.on( 'previous-step', function () { + this.ui.on( 'previous-step', () => { step.movePrevious(); } ); @@ -109,7 +109,7 @@ * @param {mw.UploadWizardUpload[]} uploads List of uploads being carried forward. */ uw.controller.Step.prototype.load = function ( uploads ) { - var step = this; + const step = this; this.emit( 'load' ); @@ -120,7 +120,7 @@ test: step.hasData.bind( this ) } ); - this.uploads.forEach( function ( upload ) { + this.uploads.forEach( ( upload ) => { upload.state = step.stepName; step.bindUploadHandlers( upload ); @@ -133,9 +133,9 @@ * Cleanup this step. */ uw.controller.Step.prototype.unload = function () { - var step = this; + const step = this; - this.uploads.forEach( function ( upload ) { + this.uploads.forEach( ( upload ) => { step.unbindUploadHandlers( upload ); } ); @@ -173,10 +173,10 @@ * @param {mw.UploadWizardUpload} upload */ uw.controller.Step.prototype.bindUploadHandlers = function ( upload ) { - var controller = this; + const controller = this; - Object.keys( this.uploadHandlers ).forEach( function ( event ) { - var callback = controller.uploadHandlers[ event ]; + Object.keys( this.uploadHandlers ).forEach( ( event ) => { + const callback = controller.uploadHandlers[ event ]; upload.on( event, callback, [ upload ], controller ); } ); }; @@ -187,10 +187,10 @@ * @param {mw.UploadWizardUpload} upload */ uw.controller.Step.prototype.unbindUploadHandlers = function ( upload ) { - var controller = this; + const controller = this; - Object.keys( this.uploadHandlers ).forEach( function ( event ) { - var callback = controller.uploadHandlers[ event ]; + Object.keys( this.uploadHandlers ).forEach( ( event ) => { + const callback = controller.uploadHandlers[ event ]; upload.off( event, callback, controller ); } ); }; @@ -220,7 +220,7 @@ * @return {boolean} Whether all of the uploads are in a successful state. */ uw.controller.Step.prototype.showNext = function () { - var okCount = this.getUploadStatesCount( this.finishState ), + let okCount = this.getUploadStatesCount( this.finishState ), $buttons; // abort if all uploads have been removed @@ -256,13 +256,13 @@ * @return {number} */ uw.controller.Step.prototype.getUploadStatesCount = function ( states ) { - var count = 0; + let count = 0; // normalize to array of states, even though input can be 1 string states = Array.isArray( states ) ? states : [ states ]; - this.uploads.forEach( function ( upload ) { - if ( states.indexOf( upload.state ) > -1 ) { + this.uploads.forEach( ( upload ) => { + if ( states.includes( upload.state ) ) { count++; } } ); @@ -302,7 +302,7 @@ */ uw.controller.Step.prototype.removeUpload = function ( upload ) { // remove the upload from the uploads array - var index = this.uploads.indexOf( upload ); + const index = this.uploads.indexOf( upload ); if ( index !== -1 ) { this.uploads.splice( index, 1 ); } @@ -317,7 +317,7 @@ * @param {mw.UploadWizardUpload[]} uploads */ uw.controller.Step.prototype.removeUploads = function ( uploads ) { - var i, + let i, // clone the array of uploads, just to be sure it's not a reference // to this.uploads, which will be modified (and we can't have that // while we're looping it) @@ -334,8 +334,8 @@ uw.controller.Step.prototype.removeErrorUploads = function () { // We must not remove items from an array while iterating over it with $.each (it causes the // next item to be skipped). Find and queue them first, then remove them. - var toRemove = []; - this.uploads.forEach( function ( upload ) { + const toRemove = []; + this.uploads.forEach( ( upload ) => { if ( upload.state === 'error' || upload.state === 'recoverable-error' ) { toRemove.push( upload ); } diff --git a/resources/controller/uw.controller.Thanks.js b/resources/controller/uw.controller.Thanks.js index 45a81ac..e660395 100644 --- a/resources/controller/uw.controller.Thanks.js +++ b/resources/controller/uw.controller.Thanks.js @@ -38,7 +38,7 @@ OO.inheritClass( uw.controller.Thanks, uw.controller.Step ); uw.controller.Thanks.prototype.load = function ( uploads ) { - var thanks = this; + const thanks = this; uw.controller.Step.prototype.load.call( this, uploads ); @@ -48,7 +48,7 @@ return; } - uploads.forEach( function ( upload ) { + uploads.forEach( ( upload ) => { thanks.ui.addUpload( upload ); } ); }; diff --git a/resources/controller/uw.controller.Tutorial.js b/resources/controller/uw.controller.Tutorial.js index 2aee890..5c26eb8 100644 --- a/resources/controller/uw.controller.Tutorial.js +++ b/resources/controller/uw.controller.Tutorial.js @@ -26,7 +26,7 @@ * @param {Object} config UploadWizard config object. */ uw.controller.Tutorial = function UWControllerTutorial( api, config ) { - var controller = this; + const controller = this; this.skipPreference = Boolean( mw.user.options.get( 'upwiz_skiptutorial' ) ); this.newSkipPreference = this.skipPreference; @@ -35,7 +35,7 @@ uw.controller.Step.call( this, new uw.ui.Tutorial() - .on( 'skip-tutorial-click', function ( skipped ) { + .on( 'skip-tutorial-click', ( skipped ) => { // indicate that the skip preference has changed, so we can // alter the preference when we move to another step controller.newSkipPreference = skipped; @@ -57,23 +57,23 @@ * @param {boolean} skip */ uw.controller.Tutorial.prototype.setSkipPreference = function ( skip ) { - var controller = this, + const controller = this, allowCloseWindow = mw.confirmCloseWindow(); this.api.postWithToken( 'options', { action: 'options', change: skip ? 'upwiz_skiptutorial=1' : 'upwiz_skiptutorial' - } ).done( function () { + } ).done( () => { allowCloseWindow.release(); controller.skipPreference = skip; - } ).fail( function ( code, err ) { + } ).fail( ( code, err ) => { mw.notify( err.textStatus ); } ); }; uw.controller.Tutorial.prototype.load = function ( uploads ) { // tutorial can be skipped via preference, or config (e.g. campaign config) - var shouldSkipTutorial = this.skipPreference || ( this.config.tutorial && this.config.tutorial.skip ); + const shouldSkipTutorial = this.skipPreference || ( this.config.tutorial && this.config.tutorial.skip ); uw.controller.Step.prototype.load.call( this, uploads ); diff --git a/resources/controller/uw.controller.Upload.js b/resources/controller/uw.controller.Upload.js index 1fb75e2..43d416e 100644 --- a/resources/controller/uw.controller.Upload.js +++ b/resources/controller/uw.controller.Upload.js @@ -26,7 +26,7 @@ * @param {Object} config UploadWizard config object. */ uw.controller.Upload = function UWControllerUpload( api, config ) { - var step = this; + const step = this; uw.controller.Step.call( this, @@ -47,8 +47,8 @@ } ); this.queue.on( 'complete', this.showNext.bind( this ) ); - this.ui.on( 'files-added', function ( files ) { - var totalFiles = files.length + step.uploads.length, + this.ui.on( 'files-added', ( files ) => { + const totalFiles = files.length + step.uploads.length, tooManyFiles = totalFiles > step.config.maxUploads; if ( tooManyFiles ) { @@ -65,7 +65,7 @@ * Updates the upload step data when a file is added or removed. */ uw.controller.Upload.prototype.updateFileCounts = function () { - var fewerThanMax, haveUploads, + let fewerThanMax, haveUploads, max = this.config.maxUploads; haveUploads = this.uploads.length > 0; @@ -76,7 +76,7 @@ }; uw.controller.Upload.prototype.load = function ( uploads ) { - var controller = this; + const controller = this; uw.controller.Step.prototype.load.call( this, uploads ); this.updateFileCounts(); @@ -96,7 +96,7 @@ * with new uploads, and still understand the existing files that * we've just reset the state for. */ - uploads.forEach( function ( upload ) { + uploads.forEach( ( upload ) => { upload.state = upload.fileKey === undefined ? 'error' : controller.finishState; } ); @@ -167,7 +167,7 @@ * @return {jQuery.Promise} */ uw.controller.Upload.prototype.transitionOne = function ( upload ) { - var promise = upload.start(); + const promise = upload.start(); this.maybeStartProgressBar(); return promise; }; @@ -191,9 +191,9 @@ }; uw.controller.Upload.prototype.retry = function () { - var controller = this; + const controller = this; - this.uploads.forEach( function ( upload ) { + this.uploads.forEach( ( upload ) => { if ( upload.state === 'error' ) { // reset any uploads in error state back to be shiny & new upload.state = 'new'; @@ -214,7 +214,7 @@ * @return {mw.UploadWizardUpload|boolean} The new upload, or false if it can't be added */ uw.controller.Upload.prototype.addFile = function ( file ) { - var upload; + let upload; if ( this.uploads.length >= this.config.maxUploads ) { return false; @@ -244,7 +244,7 @@ * @param {FileList} files */ uw.controller.Upload.prototype.addFiles = function ( files ) { - var + let uploadObj, i, file, @@ -302,7 +302,7 @@ * @return {boolean} Error in [code, info] format, or empty [] for no errors */ uw.controller.Upload.prototype.validateFile = function ( upload ) { - var extension, + let extension, i, actualMaxSize = mw.UploadWizard.config.maxMwUploadSize, @@ -322,7 +322,7 @@ // check if the filename is valid upload.setTitle( basename ); if ( !upload.title ) { - if ( basename.indexOf( '.' ) === -1 ) { + if ( !basename.includes( '.' ) ) { this.ui.showMissingExtensionError( filename ); return false; } else { @@ -340,7 +340,7 @@ if ( mw.UploadWizard.config.fileExtensions !== null && - mw.UploadWizard.config.fileExtensions.indexOf( extension.toLowerCase() ) === -1 + !mw.UploadWizard.config.fileExtensions.includes( extension.toLowerCase() ) ) { this.ui.showBadExtensionError( filename, extension ); return false; diff --git a/resources/deed/uw.deed.OwnWork.js b/resources/deed/uw.deed.OwnWork.js index 50881cb..f287b98 100644 --- a/resources/deed/uw.deed.OwnWork.js +++ b/resources/deed/uw.deed.OwnWork.js @@ -26,7 +26,7 @@ * @param {mw.Api} api API object - useful for doing previews */ uw.deed.OwnWork = function UWDeedOwnWork( config, uploads, api ) { - var deed = this, + let deed = this, prefAuthName = mw.user.options.get( 'upwiz_licensename' ); uw.deed.Abstract.call( this, 'ownwork', config ); @@ -49,7 +49,7 @@ value: prefAuthName, classes: [ 'mediauploader-sign' ] } ); - this.authorInput.on( 'change', function () { + this.authorInput.on( 'change', () => { deed.fakeAuthorInput.setValue( deed.authorInput.getValue() ); } ); @@ -80,7 +80,7 @@ }; uw.deed.OwnWork.prototype.setFormFields = function ( $selector ) { - var $customDiv, $formFields, $toggler, crossfaderWidget, defaultLicense, + let $customDiv, $formFields, $toggler, crossfaderWidget, defaultLicense, defaultLicenseURL, $defaultLicenseLink, $standardDiv, $crossfader, deed, languageCode, defaultLicConfig; @@ -141,7 +141,7 @@ this.authorInputField = new uw.FieldLayout( crossfaderWidget ); // Aggregate 'change' event - this.authorInput.on( 'change', OO.ui.debounce( function () { + this.authorInput.on( 'change', OO.ui.debounce( () => { crossfaderWidget.emit( 'change' ); }, 500 ) ); @@ -152,7 +152,7 @@ $toggler = $( '<p>' ).addClass( 'mwe-more-options' ).css( 'text-align', 'right' ) .append( $( '<a>' ) .msg( 'mediauploader-license-show-all' ) - .on( 'click', function () { + .on( 'click', () => { if ( $crossfader.data( 'crossfadeDisplay' ).get( 0 ) === $customDiv.get( 0 ) ) { deed.standardLicense(); } else { @@ -171,8 +171,8 @@ }; uw.deed.OwnWork.prototype.setDefaultLicenses = function () { - var defaultLicenses = {}; - this.getDefaultLicenses().forEach( function ( licName ) { + const defaultLicenses = {}; + this.getDefaultLicenses().forEach( ( licName ) => { defaultLicenses[ licName ] = true; } ); this.licenseInput.setValues( defaultLicenses ); @@ -189,10 +189,10 @@ * @inheritdoc */ uw.deed.OwnWork.prototype.getAuthorWikiText = function () { - var author = this.authorInput.getValue(), + let author = this.authorInput.getValue(), userPageTitle; - if ( author.indexOf( '[' ) >= 0 || author.indexOf( '{' ) >= 0 ) { + if ( author.includes( '[' ) || author.includes( '{' ) ) { return author; } @@ -236,7 +236,7 @@ }; uw.deed.OwnWork.prototype.swapNodes = function ( a, b ) { - var + const parentA = a.parentNode, parentB = b.parentNode, nextA = a.nextSibling, @@ -252,7 +252,7 @@ * @return {string[]} */ uw.deed.OwnWork.prototype.getDefaultLicenses = function () { - var license, ownWork = this.config.licensing.ownWork; + let license, ownWork = this.config.licensing.ownWork; if ( this.config.licensing.defaultType === 'ownWork' ) { license = ownWork.defaults; @@ -267,7 +267,7 @@ }; uw.deed.OwnWork.prototype.standardLicense = function () { - var deed = this, + const deed = this, $crossfader = this.$selector.find( '.mediauploader-crossfader' ), $standardDiv = this.$selector.find( '.mediauploader-standard' ), $toggler = this.$selector.find( '.mwe-more-options a' ); @@ -275,7 +275,7 @@ this.setDefaultLicenses(); $crossfader.morphCrossfade( $standardDiv ) - .promise().done( function () { + .promise().done( () => { deed.swapNodes( deed.authorInput.$element[ 0 ], deed.fakeAuthorInput.$element[ 0 ] ); } ); @@ -289,13 +289,13 @@ }; uw.deed.OwnWork.prototype.customLicense = function () { - var deed = this, + const deed = this, $crossfader = this.$selector.find( '.mediauploader-crossfader' ), $customDiv = this.$selector.find( '.mediauploader-custom' ), $toggler = this.$selector.find( '.mwe-more-options a' ); $crossfader.morphCrossfade( $customDiv ) - .promise().done( function () { + .promise().done( () => { deed.swapNodes( deed.authorInput.$element[ 0 ], deed.fakeAuthorInput.$element[ 0 ] ); } ); @@ -313,7 +313,7 @@ * @return {jQuery.Promise} */ uw.deed.OwnWork.prototype.getAuthorErrors = function ( input ) { - var + const errors = [], minLength = this.config.minAuthorLength, maxLength = this.config.maxAuthorLength, diff --git a/resources/deed/uw.deed.ThirdParty.js b/resources/deed/uw.deed.ThirdParty.js index 0d70235..e2eebf8 100644 --- a/resources/deed/uw.deed.ThirdParty.js +++ b/resources/deed/uw.deed.ThirdParty.js @@ -26,7 +26,7 @@ * @param {mw.Api} api API object - useful for doing previews */ uw.deed.ThirdParty = function UWDeedThirdParty( config, uploads, api ) { - var deed = this; + const deed = this; uw.deed.Abstract.call( this, 'thirdparty', config ); @@ -40,7 +40,7 @@ this.sourceInput.$input.attr( 'id', 'mwe-source-' + this.getInstanceCount() ); // See uw.DetailsWidget this.sourceInput.getErrors = function () { - var + const errors = [], minLength = deed.config.minSourceLength, maxLength = deed.config.maxSourceLength, @@ -74,7 +74,7 @@ this.authorInput.$input.attr( 'id', 'mwe-author-' + this.getInstanceCount() ); // See uw.DetailsWidget this.authorInput.getErrors = function () { - var + const errors = [], minLength = deed.config.minAuthorLength, maxLength = deed.config.maxAuthorLength, @@ -127,7 +127,7 @@ }; uw.deed.ThirdParty.prototype.setFormFields = function ( $selector ) { - var $formFields = $( '<div>' ).addClass( 'mediauploader-deed-form-internal' ); + const $formFields = $( '<div>' ).addClass( 'mediauploader-deed-form-internal' ); this.$form = $( '<form>' ); diff --git a/resources/details/uw.CategoriesDetailsWidget.js b/resources/details/uw.CategoriesDetailsWidget.js index 1d12511..90c456a 100644 --- a/resources/details/uw.CategoriesDetailsWidget.js +++ b/resources/details/uw.CategoriesDetailsWidget.js @@ -1,6 +1,6 @@ ( function ( uw ) { - var NS_CATEGORY = mw.config.get( 'wgNamespaceIds' ).category; + const NS_CATEGORY = mw.config.get( 'wgNamespaceIds' ).category; /** * A categories field in UploadWizard's "Details" step form. @@ -9,7 +9,7 @@ * @param {Object} config */ uw.CategoriesDetailsWidget = function UWCategoriesDetailsWidget( config ) { - var catDetails = this; + const catDetails = this; this.config = config; uw.CategoriesDetailsWidget.parent.call( this, this.config ); @@ -19,7 +19,7 @@ } ); this.categoriesWidget.createTagItemWidget = function ( data ) { - var widget = this.constructor.prototype.createTagItemWidget.call( this, data ); + const widget = this.constructor.prototype.createTagItemWidget.call( this, data ); if ( !widget ) { return null; } @@ -43,7 +43,7 @@ * @inheritdoc */ uw.CategoriesDetailsWidget.prototype.getErrors = function () { - var errors = []; + const errors = []; if ( this.config.required && this.categoriesWidget.getItems().length === 0 ) { errors.push( mw.message( 'mediauploader-error-blank' ) ); @@ -56,12 +56,10 @@ * @inheritdoc */ uw.CategoriesDetailsWidget.prototype.getWarnings = function () { - var warnings = []; + const warnings = []; this.getEmptyWarning( this.categoriesWidget.getItems().length === 0, warnings ); - if ( this.categoriesWidget.getItems().some( function ( item ) { - return item.missing; - } ) ) { + if ( this.categoriesWidget.getItems().some( ( item ) => item.missing ) ) { warnings.push( mw.message( 'mediauploader-categories-missing' ) ); } return $.Deferred().resolve( warnings ).promise(); @@ -71,7 +69,7 @@ * @inheritdoc */ uw.CategoriesDetailsWidget.prototype.getWikiText = function () { - var hiddenCats, missingCatsWikiText, categories, wikiText; + let hiddenCats, missingCatsWikiText, categories, wikiText; hiddenCats = []; if ( this.config.hiddenDefault ) { @@ -84,10 +82,10 @@ hiddenCats.push( mw.UploadWizard.config.trackingCategory.campaign ); } } - hiddenCats = hiddenCats.filter( function ( cat ) { + hiddenCats = hiddenCats.filter( ( cat ) => // Keep only valid titles - return !!mw.Title.makeTitle( NS_CATEGORY, cat ); - } ); + !!mw.Title.makeTitle( NS_CATEGORY, cat ) + ); missingCatsWikiText = null; if ( @@ -97,15 +95,11 @@ missingCatsWikiText = this.config.missingWikitext; } - categories = this.categoriesWidget.getItems().map( function ( item ) { - return item.data; - } ); + categories = this.categoriesWidget.getItems().map( ( item ) => item.data ); // add all categories wikiText = categories.concat( hiddenCats ) - .map( function ( cat ) { - return '[[' + mw.Title.makeTitle( NS_CATEGORY, cat ).getPrefixedText() + ']]'; - } ) + .map( ( cat ) => '[[' + mw.Title.makeTitle( NS_CATEGORY, cat ).getPrefixedText() + ']]' ) .join( '\n' ); // if so configured, and there are no user-visible categories, add warning @@ -121,9 +115,7 @@ * @return {Object} See #setSerialized */ uw.CategoriesDetailsWidget.prototype.getSerialized = function () { - return this.categoriesWidget.getItems().map( function ( item ) { - return item.data; - } ); + return this.categoriesWidget.getItems().map( ( item ) => item.data ); }; /** @@ -131,10 +123,10 @@ * @param {string[]} serialized List of categories */ uw.CategoriesDetailsWidget.prototype.setSerialized = function ( serialized ) { - var categories = ( serialized || [] ).filter( function ( cat ) { + const categories = ( serialized || [] ).filter( ( cat ) => // Keep only valid titles - return !!mw.Title.makeTitle( NS_CATEGORY, cat ); - } ); + !!mw.Title.makeTitle( NS_CATEGORY, cat ) + ); this.categoriesWidget.setValue( categories ); }; diff --git a/resources/details/uw.DateDetailsWidget.js b/resources/details/uw.DateDetailsWidget.js index 198e7e2..f2fabc5 100644 --- a/resources/details/uw.DateDetailsWidget.js +++ b/resources/details/uw.DateDetailsWidget.js @@ -31,10 +31,10 @@ disabled: this.config.disabled } ) .selectItemByData( 'calendar' ) - .on( 'choose', function ( selectedItem ) { + .on( 'choose', ( selectedItem ) => { this.setupDateInput( selectedItem.getData() ); this.dateInputWidget.focus(); - }.bind( this ) ); + } ); this.$element.addClass( 'mediauploader-dateDetailsWidget' ); this.$element.append( @@ -52,7 +52,7 @@ * @private */ uw.DateDetailsWidget.prototype.setupDateInput = function ( mode ) { - var + const oldDateInputWidget = this.dateInputWidget; if ( mode === undefined ) { @@ -75,13 +75,13 @@ } ); // If the user types '{{', assume that they are trying to input template wikitext and switch // to 'arbitrary' mode. This might help confused power-users (T110026#1567714). - this.dateInputWidget.textInput.on( 'change', function ( value ) { + this.dateInputWidget.textInput.on( 'change', ( value ) => { if ( value === '{{' ) { this.setupDateInput( 'arbitrary' ); this.dateInputWidget.setValue( '{{' ); this.dateInputWidget.moveCursorToEnd(); } - }.bind( this ) ); + } ); } if ( oldDateInputWidget ) { @@ -121,7 +121,7 @@ * @inheritdoc */ uw.DateDetailsWidget.prototype.getWarnings = function () { - var warnings = [], + const warnings = [], dateVal = Date.parse( this.dateInputWidget.getValue().trim() ), now = new Date(); @@ -143,7 +143,7 @@ * @inheritdoc */ uw.DateDetailsWidget.prototype.getErrors = function () { - var errors = []; + const errors = []; if ( this.config.required && this.dateInputWidget.getValue().trim() === '' ) { errors.push( mw.message( 'mediauploader-error-blank' ) ); diff --git a/resources/details/uw.DeedChooserDetailsWidget.js b/resources/details/uw.DeedChooserDetailsWidget.js index 94e4fd9..1560271 100644 --- a/resources/details/uw.DeedChooserDetailsWidget.js +++ b/resources/details/uw.DeedChooserDetailsWidget.js @@ -25,7 +25,7 @@ * @param {mw.UploadWizardUpload} upload */ uw.DeedChooserDetailsWidget.prototype.useCustomDeedChooser = function ( upload ) { - var $deedDiv; + let $deedDiv; // Defining own deedChooser for uploads coming from external service if ( upload.file.fromURL ) { @@ -74,7 +74,7 @@ * @inheritdoc */ uw.DeedChooserDetailsWidget.prototype.getErrors = function () { - var errors = []; + const errors = []; if ( this.deedChooser ) { if ( !this.deedChooser.deed ) { errors.push( mw.message( 'mediauploader-deeds-need-deed' ) ); diff --git a/resources/details/uw.DropdownWidget.js b/resources/details/uw.DropdownWidget.js index ab6ec70..17db404 100644 --- a/resources/details/uw.DropdownWidget.js +++ b/resources/details/uw.DropdownWidget.js @@ -17,9 +17,7 @@ this.wikitext = config.wikitext; this.input = new OO.ui.DropdownInputWidget( { classes: [ 'mwe-idfield', 'mediauploader-dropdownWidget-input' ], - options: Object.keys( config.options ).map( function ( key ) { - return { data: key, label: config.options[ key ] }; - } ) + options: Object.keys( config.options ).map( ( key ) => ( { data: key, label: config.options[ key ] } ) ) } ); // Aggregate 'change' event @@ -37,7 +35,7 @@ * @inheritdoc */ uw.DropdownWidget.prototype.getErrors = function () { - var errors = []; + const errors = []; if ( this.required && this.input.getValue().trim() === '' ) { errors.push( mw.message( 'mediauploader-error-blank' ) ); } @@ -48,7 +46,7 @@ * @inheritdoc */ uw.DropdownWidget.prototype.getWarnings = function () { - var warnings = []; + const warnings = []; this.getEmptyWarning( this.input.getValue().trim() === '', warnings ); return $.Deferred().resolve( warnings ).promise(); diff --git a/resources/details/uw.LanguageDropdownWidget.js b/resources/details/uw.LanguageDropdownWidget.js index 8865ae8..b9e163d 100644 --- a/resources/details/uw.LanguageDropdownWidget.js +++ b/resources/details/uw.LanguageDropdownWidget.js @@ -28,15 +28,13 @@ * @param {Object} languages */ uw.LanguageDropdownWidget.prototype.updateLanguages = function ( languages ) { - var menu = this.languageDropdown.getMenu(), + const menu = this.languageDropdown.getMenu(), currentMenuItems = menu.getItems(), currentValue = this.getValue(); // remove all items except the one currently selected (don't want // to trigger another select by removing it) - menu.removeItems( currentMenuItems.filter( function ( item ) { - return !item.isSelected(); - } ) ); + menu.removeItems( currentMenuItems.filter( ( item ) => !item.isSelected() ) ); // and add the rest of the languages back in there delete languages[ currentValue ]; @@ -72,12 +70,10 @@ * @return {OO.ui.MenuOptionWidget[]} */ uw.LanguageDropdownWidget.prototype.getLanguageMenuOptionWidgets = function ( languages ) { - return Object.keys( languages ).map( function ( code ) { - return new OO.ui.MenuOptionWidget( { - data: code, - label: languages[ code ] - } ); - } ); + return Object.keys( languages ).map( ( code ) => new OO.ui.MenuOptionWidget( { + data: code, + label: languages[ code ] + } ) ); }; }( mw.uploadWizard ) ); diff --git a/resources/details/uw.LocationDetailsWidget.js b/resources/details/uw.LocationDetailsWidget.js index 76a0c18..b89a46e 100644 --- a/resources/details/uw.LocationDetailsWidget.js +++ b/resources/details/uw.LocationDetailsWidget.js @@ -68,10 +68,10 @@ this.connect( this, { change: 'onChange' } ); this.mapButton.toggle( false ); - mw.loader.using( [ 'ext.kartographer.box', 'ext.kartographer.editing' ] ).done( function () { + mw.loader.using( [ 'ext.kartographer.box', 'ext.kartographer.editing' ] ).done( () => { // Kartographer is installed and we'll be able to show the map. Display the button. this.mapButton.toggle( true ); - }.bind( this ) ); + } ); }; OO.inheritClass( uw.LocationDetailsWidget, uw.DetailsWidget ); @@ -80,8 +80,8 @@ * @private */ uw.LocationDetailsWidget.prototype.onChange = function () { - var widget = this; - this.getErrors().done( function ( errors ) { + const widget = this; + this.getErrors().done( ( errors ) => { widget.mapButton.setDisabled( !( errors.length === 0 && widget.getWikiText() !== '' ) ); } ); }; @@ -90,7 +90,7 @@ * @private */ uw.LocationDetailsWidget.prototype.onMapButtonClick = function () { - var coords = this.getSerializedParsed(); + const coords = this.getSerializedParsed(); // Disable clipping because it doesn't play nicely with the map this.mapButton.getPopup().toggleClipping( false ); @@ -112,7 +112,7 @@ * @inheritdoc */ uw.LocationDetailsWidget.prototype.getErrors = function () { - var errors = [], + let errors = [], serialized = this.getSerialized(), parsed = this.getSerializedParsed(), field; @@ -132,13 +132,13 @@ // coordinates that were derived from the input are 0, without a 0 even // being present in the input if ( this.config.showField.latitude && serialized.latitude ) { - if ( isNaN( parsed.latitude ) || parsed.latitude > 90 || parsed.latitude < -90 || ( parsed.latitude === 0 && serialized.latitude.indexOf( '0' ) < 0 ) ) { + if ( isNaN( parsed.latitude ) || parsed.latitude > 90 || parsed.latitude < -90 || ( parsed.latitude === 0 && !serialized.latitude.includes( '0' ) ) ) { errors.push( mw.message( 'mediauploader-error-latitude' ) ); } } if ( this.config.showField.longitude && serialized.longitude ) { - if ( isNaN( parsed.longitude ) || parsed.longitude > 180 || parsed.longitude < -180 || ( parsed.longitude === 0 && serialized.longitude.indexOf( '0' ) < 0 ) ) { + if ( isNaN( parsed.longitude ) || parsed.longitude > 180 || parsed.longitude < -180 || ( parsed.longitude === 0 && !serialized.longitude.includes( '0' ) ) ) { errors.push( mw.message( 'mediauploader-error-longitude' ) ); } } @@ -160,7 +160,7 @@ * @inheritdoc */ uw.LocationDetailsWidget.prototype.getWikiText = function () { - var field, + let field, result = '', serialized = this.getSerializedParsed(); @@ -190,7 +190,7 @@ * @return {Object} See #setSerialized */ uw.LocationDetailsWidget.prototype.getSerialized = function () { - var field, + let field, result = {}; for ( field in this.config.showField ) { @@ -206,7 +206,7 @@ * @return {Object} Serialized, parsed values of the subfields (numbers) */ uw.LocationDetailsWidget.prototype.getSerializedParsed = function () { - var field, + let field, result = {}, serialized = this.getSerialized(); @@ -232,7 +232,7 @@ * @param {string} serialized.heading Heading value */ uw.LocationDetailsWidget.prototype.setSerialized = function ( serialized ) { - var field; + let field; for ( field in this.config.showField ) { if ( serialized[ field ] !== undefined ) { @@ -255,7 +255,7 @@ * @return {number} */ uw.LocationDetailsWidget.prototype.normalizeCoordinate = function ( coordinate ) { - var sign = coordinate.match( /[sw]/i ) ? -1 : 1, + let sign = coordinate.match( /[sw]/i ) ? -1 : 1, parts, value; // fix commonly used character alternatives diff --git a/resources/details/uw.MultipleLanguageInputWidget.js b/resources/details/uw.MultipleLanguageInputWidget.js index 7816114..e3dcf27 100644 --- a/resources/details/uw.MultipleLanguageInputWidget.js +++ b/resources/details/uw.MultipleLanguageInputWidget.js @@ -57,7 +57,7 @@ * @param {string} [text] */ uw.MultipleLanguageInputWidget.prototype.addLanguageInput = function ( config, text ) { - var allLanguages = this.config.languages, + let allLanguages = this.config.languages, unusedLanguages = this.getUnusedLanguages(), languages = {}, item; @@ -97,7 +97,7 @@ * with the updated language selections. */ uw.MultipleLanguageInputWidget.prototype.onChangeLanguages = function () { - var allLanguages = this.config.languages, + let allLanguages = this.config.languages, unusedLanguages = this.getUnusedLanguages(), items = this.getItems(), languages, @@ -123,11 +123,11 @@ * @return {Object} */ uw.MultipleLanguageInputWidget.prototype.getUsedLanguages = function () { - var allLanguages = this.config.languages, + const allLanguages = this.config.languages, items = this.getItems(); - return items.reduce( function ( obj, item ) { - var languageCode = item.getLanguage(); + return items.reduce( ( obj, item ) => { + const languageCode = item.getLanguage(); obj[ languageCode ] = allLanguages[ languageCode ]; return obj; }, {} ); @@ -140,11 +140,11 @@ * @return {Object} */ uw.MultipleLanguageInputWidget.prototype.getUnusedLanguages = function () { - var allLanguages = this.config.languages, + const allLanguages = this.config.languages, usedLanguageCodes = Object.keys( this.getUsedLanguages() ); - return Object.keys( allLanguages ).reduce( function ( remaining, language ) { - if ( usedLanguageCodes.indexOf( language ) < 0 ) { + return Object.keys( allLanguages ).reduce( ( remaining, language ) => { + if ( !usedLanguageCodes.includes( language ) ) { remaining[ language ] = allLanguages[ language ]; } return remaining; @@ -155,7 +155,7 @@ * Update the button label after adding or removing inputs. */ uw.MultipleLanguageInputWidget.prototype.recount = function () { - var text = this.getLabelText(), + const text = this.getLabelText(), unusedLanguages = this.getUnusedLanguages(); this.addButton.setLabel( text ); @@ -174,7 +174,7 @@ * @inheritdoc */ uw.MultipleLanguageInputWidget.prototype.getWarnings = function () { - var warnings = []; + const warnings = []; this.getEmptyWarning( this.getWikiText() === '', warnings ); return $.Deferred().resolve( warnings ).promise(); @@ -185,12 +185,10 @@ */ uw.MultipleLanguageInputWidget.prototype.getErrors = function () { // Gather errors from each item - var errorPromises = this.getItems().map( function ( item ) { - return item.getErrors(); - } ); + const errorPromises = this.getItems().map( ( item ) => item.getErrors() ); return $.when.apply( $, errorPromises ).then( function () { - var i, errors; + let i, errors; errors = []; // Fold all errors into a single one (they are displayed in the UI for each item, but we still // need to return an error here to prevent form submission). @@ -214,7 +212,7 @@ * @return {Object} Object where the properties are language codes & values are input */ uw.MultipleLanguageInputWidget.prototype.getValues = function () { - var values = {}, + let values = {}, widgets = this.getItems(), language, text, @@ -238,11 +236,7 @@ uw.MultipleLanguageInputWidget.prototype.getWikiText = function () { // Some code here and in mw.UploadWizardDetails relies on this function returning an empty // string when there are some inputs, but all are empty. - return this.getItems().map( function ( widget ) { - return widget.getWikiText(); - } ).filter( function ( wikiText ) { - return !!wikiText; - } ).join( '\n' ); + return this.getItems().map( ( widget ) => widget.getWikiText() ).filter( ( wikiText ) => !!wikiText ).join( '\n' ); }; /** @@ -250,9 +244,7 @@ * @return {Object} See #setSerialized */ uw.MultipleLanguageInputWidget.prototype.getSerialized = function () { - var inputs = this.getItems().map( function ( widget ) { - return widget.getSerialized(); - } ); + const inputs = this.getItems().map( ( widget ) => widget.getSerialized() ); return { inputs: inputs }; @@ -265,7 +257,7 @@ * see uw.SingleLanguageInputWidget#setSerialized */ uw.MultipleLanguageInputWidget.prototype.setSerialized = function ( serialized ) { - var config = this.config, + let config = this.config, i; if ( typeof serialized === 'string' ) { @@ -288,7 +280,7 @@ * @return {string} */ uw.MultipleLanguageInputWidget.prototype.getCaption = function () { - var items = this.getItems(); + const items = this.getItems(); if ( items.length > 0 ) { return items[ 0 ].getCaption(); diff --git a/resources/details/uw.SingleLanguageInputWidget.js b/resources/details/uw.SingleLanguageInputWidget.js index 53cf62b..7107d37 100644 --- a/resources/details/uw.SingleLanguageInputWidget.js +++ b/resources/details/uw.SingleLanguageInputWidget.js @@ -81,7 +81,7 @@ * @private */ uw.SingleLanguageInputWidget.prototype.onRemoveClick = function () { - var element = this.getElementGroup(); + const element = this.getElementGroup(); if ( element && typeof element.removeItems === 'function' ) { element.removeItems( [ this ] ); @@ -120,7 +120,7 @@ * @return {string} */ uw.SingleLanguageInputWidget.prototype.getDefaultLanguage = function () { - var defaultLanguage; + let defaultLanguage; if ( this.defaultLanguage !== undefined ) { return this.defaultLanguage; @@ -153,7 +153,7 @@ * @inheritdoc */ uw.SingleLanguageInputWidget.prototype.getWarnings = function () { - var warnings = []; + const warnings = []; this.getEmptyWarning( this.textInput.getValue().trim() === '', warnings ); return $.Deferred().resolve( warnings ).promise(); @@ -163,7 +163,7 @@ * @inheritdoc */ uw.SingleLanguageInputWidget.prototype.getErrors = function () { - var + const errors = [], text = this.textInput.getValue().trim(); @@ -221,7 +221,7 @@ * @inheritdoc */ uw.SingleLanguageInputWidget.prototype.getWikiText = function () { - var + let language = this.getLanguage(), text = this.getText(); diff --git a/resources/details/uw.TextWidget.js b/resources/details/uw.TextWidget.js index 634e005..4a7f1f3 100644 --- a/resources/details/uw.TextWidget.js +++ b/resources/details/uw.TextWidget.js @@ -49,7 +49,7 @@ * @inheritdoc */ uw.TextWidget.prototype.getWarnings = function () { - var warnings = []; + const warnings = []; this.getEmptyWarning( this.textInput.getValue().trim() === '', warnings ); return $.Deferred().resolve( warnings ).promise(); @@ -59,7 +59,7 @@ * @inheritdoc */ uw.TextWidget.prototype.getErrors = function () { - var + const errors = [], text = this.textInput.getValue().trim(); diff --git a/resources/details/uw.TitleDetailsWidget.js b/resources/details/uw.TitleDetailsWidget.js index cce0d4c..8e69895 100644 --- a/resources/details/uw.TitleDetailsWidget.js +++ b/resources/details/uw.TitleDetailsWidget.js @@ -1,6 +1,6 @@ ( function ( uw ) { - var NS_FILE = mw.config.get( 'wgNamespaceIds' ).file, + const NS_FILE = mw.config.get( 'wgNamespaceIds' ).file, byteLength = require( 'mediawiki.String' ).byteLength; /** @@ -44,7 +44,7 @@ * @return {mw.Title|null} */ uw.TitleDetailsWidget.static.makeTitleInFileNS = function ( filename ) { - var + let mwTitle = mw.Title.newFromText( filename, NS_FILE ), illegalFileChars = new RegExp( '[' + mw.config.get( 'wgIllegalFileChars', '' ) + ']' ); if ( mwTitle && mwTitle.getNamespaceId() !== NS_FILE ) { @@ -78,7 +78,7 @@ * @return {mw.Title|null} */ uw.TitleDetailsWidget.prototype.getTitle = function () { - var value, extRegex, cleaned, title; + let value, extRegex, cleaned, title; value = this.titleInput.getValue().trim(); if ( !value ) { return null; @@ -99,7 +99,7 @@ * @inheritdoc */ uw.TitleDetailsWidget.prototype.getWarnings = function () { - var warnings = []; + const warnings = []; this.getEmptyWarning( this.titleInput.getValue().trim() === '', warnings ); return $.Deferred().resolve( warnings ).promise(); @@ -109,7 +109,7 @@ * @return {jQuery.Promise} */ uw.TitleDetailsWidget.prototype.getErrors = function () { - var + const errors = [], value = this.titleInput.getValue().trim(), processDestinationCheck = this.processDestinationCheck, @@ -142,28 +142,24 @@ } return mw.DestinationChecker.checkTitle( title.getPrefixedText() ) - .then( function ( result ) { - var moreErrors = processDestinationCheck( result ); + .then( ( result ) => { + let moreErrors = processDestinationCheck( result ); if ( result.blacklist.unavailable ) { // We don't have a title blacklist, so just check for some likely undesirable patterns. moreErrors = moreErrors.concat( - mw.QuickTitleChecker.checkTitle( title.getNameText() ).map( function ( errorCode ) { + mw.QuickTitleChecker.checkTitle( title.getNameText() ).map( ( errorCode ) => // Messages that can be used here: // * mediauploader-error-title-invalid // * mediauploader-error-title-senselessimagename // * mediauploader-error-title-thumbnail // * mediauploader-error-title-extension - return mw.message( 'mediauploader-error-title-' + errorCode ); - } ) + mw.message( 'mediauploader-error-title-' + errorCode ) + ) ); } return moreErrors; } ) - .then( function ( moreErrors ) { - return [].concat( errors, moreErrors ); - }, function () { - return $.Deferred().resolve( errors ); - } ); + .then( ( moreErrors ) => [].concat( errors, moreErrors ), () => $.Deferred().resolve( errors ) ); }; /** @@ -175,7 +171,7 @@ * @return {mw.Message[]} Error messages */ uw.TitleDetailsWidget.prototype.processDestinationCheck = function ( result ) { - var messageParams, errors, titleString; + let messageParams, errors, titleString; if ( result.unique.isUnique && result.blacklist.notBlacklisted && !result.unique.isProtected ) { return []; diff --git a/resources/details/uw.UlsWidget.js b/resources/details/uw.UlsWidget.js index 826aef6..54813ae 100644 --- a/resources/details/uw.UlsWidget.js +++ b/resources/details/uw.UlsWidget.js @@ -9,7 +9,7 @@ * @cfg {Array} [classes] Classes to apply to the ULS container div */ uw.UlsWidget = function UWUlsWidget( config ) { - var i; + let i; uw.UlsWidget.parent.call( this, config ); @@ -49,7 +49,7 @@ OO.mixinClass( uw.UlsWidget, OO.EventEmitter ); uw.UlsWidget.prototype.initialiseUls = function ( languages ) { - var ulsWidget = this; + const ulsWidget = this; this.languages = languages; @@ -63,7 +63,7 @@ onVisible: function () { // Re-position the ULS *after* the widget has been rendered, so that we can be // sure it's in the right place - var offset = ulsWidget.$element.offset(); + const offset = ulsWidget.$element.offset(); if ( this.$menu.css( 'direction' ) === 'rtl' ) { offset.left = offset.left - parseInt( this.$menu.css( 'width' ) ) + ulsWidget.$element.width(); @@ -85,7 +85,7 @@ * @param {string} value */ uw.UlsWidget.prototype.setValue = function ( value ) { - var current = this.languageValue; + const current = this.languageValue; this.languageValue = value; this.$element.find( '.oo-ui-labelElement-label' ).text( this.languages[ value ] ); if ( current !== value ) { diff --git a/resources/ext.mediaUploader.campaignEditor.js b/resources/ext.mediaUploader.campaignEditor.js index 3ca08a3..49d3aaf 100644 --- a/resources/ext.mediaUploader.campaignEditor.js +++ b/resources/ext.mediaUploader.campaignEditor.js @@ -3,7 +3,7 @@ /** * Sets up indentation settings appropriate for YAML if CodeEditor is loaded. */ - mw.hook( 'codeEditor.configure' ).add( function ( session ) { + mw.hook( 'codeEditor.configure' ).add( ( session ) => { session.setOptions( { useSoftTabs: true, tabSize: 2 diff --git a/resources/handlers/mw.ApiUploadFormDataHandler.js b/resources/handlers/mw.ApiUploadFormDataHandler.js index d4ec9b1..e1a571f 100644 --- a/resources/handlers/mw.ApiUploadFormDataHandler.js +++ b/resources/handlers/mw.ApiUploadFormDataHandler.js @@ -18,7 +18,7 @@ this.transport = new mw.FormDataTransport( this.api, this.formData - ).on( 'update-stage', function ( stage ) { + ).on( 'update-stage', ( stage ) => { upload.ui.setStatus( 'mediauploader-' + stage ); } ); }; @@ -33,15 +33,15 @@ * @return {jQuery.Promise} */ mw.ApiUploadFormDataHandler.prototype.submit = function () { - var handler = this; + const handler = this; - return this.configureEditToken().then( function () { + return this.configureEditToken().then( () => { handler.beginTime = Date.now(); handler.upload.ui.setStatus( 'mediauploader-transport-started' ); handler.upload.ui.showTransportProgress(); return handler.transport.upload( handler.upload.file, handler.upload.title.getMainText() ) - .progress( function ( fraction ) { + .progress( ( fraction ) => { if ( handler.upload.state === 'aborted' ) { handler.abort(); return; @@ -61,9 +61,9 @@ * @return {jQuery.Promise} */ mw.ApiUploadFormDataHandler.prototype.configureEditToken = function () { - var handler = this; + const handler = this; - return this.api.getEditToken().then( function ( token ) { + return this.api.getEditToken().then( ( token ) => { handler.formData.token = token; } ); }; diff --git a/resources/handlers/mw.ApiUploadHandler.js b/resources/handlers/mw.ApiUploadHandler.js index e84b50a..93beff8 100644 --- a/resources/handlers/mw.ApiUploadHandler.js +++ b/resources/handlers/mw.ApiUploadHandler.js @@ -1,5 +1,5 @@ ( function () { - var NS_FILE = mw.config.get( 'wgNamespaceIds' ).file; + const NS_FILE = mw.config.get( 'wgNamespaceIds' ).file; /** * @param {mw.UploadWizardUpload} upload @@ -51,7 +51,7 @@ * @param {Object} result */ mw.ApiUploadHandler.prototype.setTransported = function ( result ) { - var code; + let code; if ( result.upload && result.upload.warnings ) { for ( code in result.upload.warnings ) { if ( !this.isIgnoredWarning( code ) ) { @@ -81,7 +81,7 @@ * @param {Object} result The API result in parsed JSON form */ mw.ApiUploadHandler.prototype.setTransportWarning = function ( code, result ) { - var param, duplicates, links; + let param, duplicates, links; switch ( code ) { case 'duplicate': @@ -124,7 +124,7 @@ * @param {Object} result The API result in parsed JSON form */ mw.ApiUploadHandler.prototype.setTransportError = function ( code, result ) { - var $extra; + let $extra; if ( code === 'badtoken' ) { this.api.badToken( 'csrf' ); @@ -142,10 +142,10 @@ title: mw.message( 'mediauploader-override-upload' ).text(), flags: 'progressive', framed: false - } ).on( 'click', function () { + } ).on( 'click', () => { // No need to ignore the error, AbuseFilter will only return it once this.start(); - }.bind( this ) ).$element; + } ).$element; } this.setError( code, result.errors[ 0 ].html, $extra ); @@ -161,18 +161,18 @@ * @return {jQuery.Promise} */ mw.ApiUploadHandler.prototype.processDuplicateError = function ( code, result, duplicates ) { - var files = this.getFileLinks( duplicates ), + const files = this.getFileLinks( duplicates ), unknownAmount = duplicates.length - Object.keys( files ).length; return this.getDuplicateSource( Object.keys( files ) ).then( - function ( data ) { + ( data ) => { this.setDuplicateError( code, result, data.local, data.foreign, unknownAmount ); - }.bind( this ), - function () { + }, + () => { // if anything goes wrong trying to figure out the source of // duplicates, just move on with local duplicate handling this.setDuplicateError( code, result, files, {}, unknownAmount ); - }.bind( this ) + } ); }; @@ -181,8 +181,8 @@ * @return {jQuery.Promise} */ mw.ApiUploadHandler.prototype.getDuplicateSource = function ( duplicates ) { - return this.getImageInfo( duplicates, 'url' ).then( function ( result ) { - var local = [], + return this.getImageInfo( duplicates, 'url' ).then( ( result ) => { + const local = [], foreign = [], normalized = []; @@ -192,13 +192,13 @@ // map of normalized titles, so we can find original title if ( result.query.normalized ) { - result.query.normalized.forEach( function ( data ) { + result.query.normalized.forEach( ( data ) => { normalized[ data.to ] = data.from; } ); } - Object.keys( result.query.pages ).forEach( function ( pageId ) { - var page = result.query.pages[ pageId ], + Object.keys( result.query.pages ).forEach( ( pageId ) => { + const page = result.query.pages[ pageId ], title = page.title in normalized ? normalized[ page.title ] : page.title; if ( page.imagerepository === 'local' ) { local[ title ] = page.imageinfo[ 0 ].descriptionurl; @@ -221,7 +221,7 @@ * @param {number} unknownAmount Amount of unknown filenames (e.g. revdeleted) */ mw.ApiUploadHandler.prototype.setDuplicateError = function ( code, result, localDuplicates, foreignDuplicates, unknownAmount ) { - var allDuplicates = Object.assign( {}, localDuplicates, foreignDuplicates ), + let allDuplicates = Object.assign( {}, localDuplicates, foreignDuplicates ), $extra = $( '<div>' ), $ul = $( '<ul>' ).appendTo( $extra ), $a, @@ -230,8 +230,8 @@ unknownAmount = unknownAmount || 0; - Object.keys( allDuplicates ).forEach( function ( filename ) { - var href = allDuplicates[ filename ]; + Object.keys( allDuplicates ).forEach( ( filename ) => { + const href = allDuplicates[ filename ]; $a = $( '<a>' ).text( filename ); $a.attr( { href: href, target: '_blank' } ); $ul.append( $( '<li>' ).append( $a ) ); @@ -254,11 +254,11 @@ title: mw.message( 'mediauploader-override-upload' ).text(), flags: 'progressive', framed: false - } ).on( 'click', function () { + } ).on( 'click', () => { // mark this warning as ignored & process the API result again this.ignoreWarning( 'duplicate' ); this.setTransported( result ); - }.bind( this ) ); + } ); override.$element.appendTo( $extra ); } @@ -274,17 +274,17 @@ * @param {string} duplicate Duplicate filename */ mw.ApiUploadHandler.prototype.setDuplicateArchiveError = function ( code, result, duplicate ) { - var filename = mw.Title.makeTitle( NS_FILE, duplicate ).getPrefixedText(), + const filename = mw.Title.makeTitle( NS_FILE, duplicate ).getPrefixedText(), uploadDuplicate = new OO.ui.ButtonWidget( { label: mw.message( 'mediauploader-override' ).text(), title: mw.message( 'mediauploader-override-upload' ).text(), flags: 'progressive', framed: false - } ).on( 'click', function () { + } ).on( 'click', () => { // mark this warning as ignored & process the API result again this.ignoreWarning( 'duplicate-archive' ); this.setTransported( result ); - }.bind( this ) ); + } ); this.setError( code, mw.message( 'file-deleted-duplicate', filename ).parse(), uploadDuplicate.$element ); }; @@ -310,10 +310,10 @@ * @return {Object} Map of [prefixed filename => url] */ mw.ApiUploadHandler.prototype.getFileLinks = function ( filenames ) { - var files = []; + const files = []; - filenames.forEach( function ( filename ) { - var title; + filenames.forEach( ( filename ) => { + let title; try { title = mw.Title.makeTitle( NS_FILE, filename ); files[ title.getPrefixedText() ] = title.getUrl( {} ); @@ -357,6 +357,6 @@ * @return {boolean} */ mw.ApiUploadHandler.prototype.isIgnoredWarning = function ( code ) { - return this.ignoreWarnings.indexOf( code ) > -1; + return this.ignoreWarnings.includes( code ); }; }( mw.uploadWizard ) ); diff --git a/resources/jquery.arrowSteps/jquery.arrowSteps.js b/resources/jquery.arrowSteps/jquery.arrowSteps.js index 81115f8..b098721 100644 --- a/resources/jquery.arrowSteps/jquery.arrowSteps.js +++ b/resources/jquery.arrowSteps/jquery.arrowSteps.js @@ -35,7 +35,7 @@ * @chainable */ $.fn.arrowSteps = function () { - var $steps, width, + let $steps, width, $el = this; $el.addClass( 'arrowSteps' ); @@ -67,10 +67,10 @@ * @param {string} selector */ $.fn.arrowStepsHighlight = function ( selector ) { - var $previous, + let $previous, $steps = this.data( 'arrowSteps' ); $steps.each( function () { - var $step = $( this ); + const $step = $( this ); if ( $step.is( selector ) ) { if ( $previous ) { $previous.addClass( 'tail' ); diff --git a/resources/jquery/jquery.morphCrossfade.js b/resources/jquery/jquery.morphCrossfade.js index bc159ca..d6f79f3 100644 --- a/resources/jquery/jquery.morphCrossfade.js +++ b/resources/jquery/jquery.morphCrossfade.js @@ -47,7 +47,7 @@ * @chainable */ $.fn.morphCrossfader = function () { - var $this = $( this ); + const $this = $( this ); // the elements that are immediate children are the crossfadables // they must all be "on top" of each other, so position them relative $this.css( { @@ -64,7 +64,7 @@ // should achieve the same result as crossfade( this.children().first() ) but without // animation etc. $this.each( function () { - var $container = $( this ); + const $container = $( this ); $container.morphCrossfade( $container.children().first(), 0 ); } ); @@ -80,14 +80,14 @@ * @chainable */ $.fn.morphCrossfade = function ( newPanelSelector, speed ) { - var $this = $( this ); + const $this = $( this ); if ( typeof speed === 'undefined' ) { speed = 400; } $this.each( function () { - var $container = $( this ), + const $container = $( this ), $oldPanel = $( $container.data( 'crossfadeDisplay' ) ), $newPanel = ( typeof newPanelSelector === 'string' ) ? $container.find( newPanelSelector ) : $( newPanelSelector ); @@ -102,7 +102,7 @@ $oldPanel.css( { position: 'absolute' } ); // fade WITHOUT hiding when opacity = 0 // eslint-disable-next-line no-jquery/no-animate - $oldPanel.stop().animate( { opacity: 0 }, speed, 'linear', function () { + $oldPanel.stop().animate( { opacity: 0 }, speed, 'linear', () => { $oldPanel.css( { visibility: 'hidden' } ); } ); } @@ -110,7 +110,7 @@ $newPanel.css( { visibility: 'visible' } ); // eslint-disable-next-line no-jquery/no-animate - $container.stop().animate( { height: $newPanel.outerHeight() }, speed, 'linear', function () { + $container.stop().animate( { height: $newPanel.outerHeight() }, speed, 'linear', () => { // we place it back into the flow, in case its size changes. $newPanel.css( { position: 'relative' } ); // and allow the container to grow with it. diff --git a/resources/mw.DestinationChecker.js b/resources/mw.DestinationChecker.js index 6768d22..bcc18f6 100644 --- a/resources/mw.DestinationChecker.js +++ b/resources/mw.DestinationChecker.js @@ -22,13 +22,11 @@ return $.when( this.checkUnique( title ), this.checkBlacklist( title ) - ).then( function ( unique, blacklist ) { - return { - unique: unique, - blacklist: blacklist, - title: title - }; - } ); + ).then( ( unique, blacklist ) => ( { + unique: unique, + blacklist: blacklist, + title: title + } ) ); }, /** @@ -43,7 +41,7 @@ * {string} [return.done.blacklistLine] See mw.Api#isBlacklisted */ checkBlacklist: function ( title ) { - var checker = this; + const checker = this; /** * Process result of a TitleBlacklist API call. @@ -53,7 +51,7 @@ * @return {Object} */ function blacklistResultProcessor( blacklistResult ) { - var result; + let result; if ( blacklistResult === false ) { result = { notBlacklisted: true }; @@ -74,12 +72,10 @@ return $.Deferred().resolve( this.cachedBlacklist[ title ] ); } - return mw.loader.using( 'mediawiki.api.titleblacklist' ).then( function () { - return checker.api.isBlacklisted( title ).then( blacklistResultProcessor ); - }, function () { + return mw.loader.using( 'mediawiki.api.titleblacklist' ).then( () => checker.api.isBlacklisted( title ).then( blacklistResultProcessor ), () => // it's not blacklisted, because the API isn't even available - return $.Deferred().resolve( { notBlacklisted: true, unavailable: true } ); - } ); + $.Deferred().resolve( { notBlacklisted: true, unavailable: true } ) + ); }, /** @@ -95,7 +91,7 @@ * {string} [return.done.href] URL to file description page */ checkUnique: function ( title ) { - var checker = this, + let checker = this, NS_FILE = mw.config.get( 'wgNamespaceIds' ).file, titleObj, prefix, ext; @@ -112,7 +108,7 @@ * @return {Object} */ function checkUniqueProcessor( data ) { - var result, protection, pageId, ntitle, ntitleObj, img; + let result, protection, pageId, ntitle, ntitleObj, img; result = { isUnique: true }; @@ -124,8 +120,8 @@ if ( data.query.pages[ -1 ] && !data.query.pages[ -1 ].imageinfo ) { protection = data.query.pages[ -1 ].protection; if ( protection && protection.length > 0 ) { - protection.forEach( function ( val ) { - if ( mw.config.get( 'wgUserGroups' ).indexOf( val.level ) === -1 ) { + protection.forEach( ( val ) => { + if ( !mw.config.get( 'wgUserGroups' ).includes( val.level ) ) { result = { isUnique: true, isProtected: true @@ -211,8 +207,8 @@ iiprop: 'url|mime|size', iiurlwidth: 150 } ).then( checkUniqueProcessor ) - ).then( function ( exact, fuzzy ) { - var result; + ).then( ( exact, fuzzy ) => { + let result; if ( !exact.isUnique || exact.isProtected ) { result = exact; } else if ( !fuzzy.isUnique || fuzzy.isProtected ) { diff --git a/resources/mw.Escaper.js b/resources/mw.Escaper.js index d34b1d4..b5cfb7e 100644 --- a/resources/mw.Escaper.js +++ b/resources/mw.Escaper.js @@ -18,14 +18,12 @@ * @return {string} */ escapePipes: function ( wikitext ) { - var extractedTemplates, extractedLinks; + let extractedTemplates, extractedLinks; // Pipes (`|`) must be escaped because we'll be inserting this // content into a templates & pipes would mess up the syntax. // First, urlencode pipes inside links: - wikitext = wikitext.replace( /\bhttps?:\/\/[^\s]+/g, function ( match ) { - return match.replace( /\|/g, '%7C' ); - } ); + wikitext = wikitext.replace( /\bhttps?:\/\/[^\s]+/g, ( match ) => match.replace( /\|/g, '%7C' ) ); // Second, pipes can be valid inside other templates or links in // wikitext, so we'll first extract those from the content, then @@ -51,7 +49,7 @@ * @return {Array} [{string} wikitext, {Object} replacements] */ extractTemplates: function ( wikitext ) { - var extracts = {}, + let extracts = {}, previousExtracts = {}, extracted = wikitext, // the regex explained: @@ -62,7 +60,7 @@ // sequence, generated by an earlier run of this regex regex = /\{\{([^{]|\{(?!\{)|\{\{[0-9]+\}\})*?\}\}/g, callback = function ( match ) { - var replacement = '{{' + Object.keys( extracts ).length + '}}'; + const replacement = '{{' + Object.keys( extracts ).length + '}}'; // safeguard for not replacing already-replaced matches // this makes sure that when real content contains something @@ -96,10 +94,10 @@ * @return {Array} [{string} wikitext, {Object} replacements] */ extractLinks: function ( wikitext ) { - var extracts = {}; + const extracts = {}; - wikitext = wikitext.replace( /\[\[.*?\]\]/g, function ( match ) { - var replacement = '[[' + Object.keys( extracts ).length + ']]'; + wikitext = wikitext.replace( /\[\[.*?\]\]/g, ( match ) => { + const replacement = '[[' + Object.keys( extracts ).length + ']]'; extracts[ replacement ] = match; return replacement; } ); @@ -117,10 +115,10 @@ restoreExtracts: function ( wikitext, replacements ) { // turn search keys into a regular expression, allowing us to match // all of them at once - var searchValues = Object.keys( replacements ).map( mw.util.escapeRegExp ), + const searchValues = Object.keys( replacements ).map( mw.util.escapeRegExp ), searchRegex = new RegExp( '(' + searchValues.join( '|' ) + ')', 'g' ), callback = function ( match ) { - var replacement = replacements[ match ]; + const replacement = replacements[ match ]; // we matched something that has no replacement, must be valid // user input that just happens to look like on of the diff --git a/resources/mw.GroupProgressBar.js b/resources/mw.GroupProgressBar.js index 10c2bbe..d9c5fe3 100644 --- a/resources/mw.GroupProgressBar.js +++ b/resources/mw.GroupProgressBar.js @@ -56,30 +56,30 @@ * loop around the uploads, summing certain properties for a weighted total fraction */ start: function () { - var bar = this, + let bar = this, shown = false; this.setBeginTime(); function displayer() { - var totalWeight = 0.0, + let totalWeight = 0.0, fraction = 0.0, successStateCount = 0, errorStateCount = 0, hasData = false; - bar.uploads.forEach( function ( upload ) { + bar.uploads.forEach( ( upload ) => { totalWeight += upload[ bar.weightProperty ]; } ); - bar.uploads.forEach( function ( upload ) { + bar.uploads.forEach( ( upload ) => { if ( upload.state === 'aborted' ) { return; } - if ( bar.successStates.indexOf( upload.state ) !== -1 ) { + if ( bar.successStates.includes( upload.state ) ) { successStateCount++; } - if ( bar.errorStates.indexOf( upload.state ) !== -1 ) { + if ( bar.errorStates.includes( upload.state ) ) { errorStateCount++; } if ( upload[ bar.progressProperty ] !== undefined ) { @@ -106,7 +106,7 @@ } else { bar.showProgress( 1.0 ); bar.finished = true; - setTimeout( function () { + setTimeout( () => { bar.hideBar(); }, 500 ); } @@ -142,7 +142,7 @@ * @param {number} fraction The amount of whatever it is that's done whatever it's done */ showProgress: function ( fraction ) { - var t, timeString, + let t, timeString, remainingTime = this.getRemainingTime( fraction ); this.progressBarWidget.setProgress( parseInt( fraction * 100, 10 ) ); @@ -168,7 +168,7 @@ * @return {number} Estimated time remaining (in milliseconds) */ getRemainingTime: function ( fraction ) { - var elapsedTime, rate; + let elapsedTime, rate; if ( this.beginTime ) { elapsedTime = Date.now() - this.beginTime; if ( fraction > 0.0 && elapsedTime > 0 ) { // or some other minimums for good data @@ -185,7 +185,7 @@ * @param {number} completed The number of items that have done whatever has been done e.g. in "uploaded 2 of 5", this is the 2 */ showCount: function ( completed ) { - var total = this.uploads.length - this.countRemoved(); + const total = this.uploads.length - this.countRemoved(); this.$selector .find( '.mediauploader-count' ) // Hide if there are no uploads, show otherwise @@ -194,8 +194,8 @@ }, countRemoved: function () { - var count = 0; - this.uploads.forEach( function ( upload ) { + let count = 0; + this.uploads.forEach( ( upload ) => { if ( !upload || upload.state === 'aborted' ) { count += 1; } diff --git a/resources/mw.QuickTitleChecker.js b/resources/mw.QuickTitleChecker.js index 589cf37..d6723d5 100644 --- a/resources/mw.QuickTitleChecker.js +++ b/resources/mw.QuickTitleChecker.js @@ -70,10 +70,10 @@ * Possible error codes are 'invalid', 'senselessimagename', 'thumbnail', 'extension'. */ mw.QuickTitleChecker.checkTitle = function ( title ) { - var errors = []; - Object.keys( mw.QuickTitleChecker.regexSets ).forEach( function ( setName ) { - var regexes = mw.QuickTitleChecker.regexSets[ setName ]; - regexes.forEach( function ( regex ) { + const errors = []; + Object.keys( mw.QuickTitleChecker.regexSets ).forEach( ( setName ) => { + const regexes = mw.QuickTitleChecker.regexSets[ setName ]; + regexes.forEach( ( regex ) => { if ( title.match( regex ) ) { errors.push( setName ); } diff --git a/resources/mw.UploadWizard.js b/resources/mw.UploadWizard.js index a96c38e..5f3a29e 100644 --- a/resources/mw.UploadWizard.js +++ b/resources/mw.UploadWizard.js @@ -7,7 +7,7 @@ ( function ( uw ) { mw.UploadWizard = function ( config ) { - var maxSimPref; + let maxSimPref; this.api = this.getApi( { ajax: { timeout: 0 } } ); @@ -49,7 +49,7 @@ createInterface: function ( selector ) { this.ui = new uw.ui.Wizard( selector ); - this.initialiseSteps().then( function ( steps ) { + this.initialiseSteps().then( ( steps ) => { // "select" the first step - highlight, make it visible, hide all others steps[ 0 ].load( [] ); } ); @@ -61,7 +61,7 @@ * @return {jQuery.Promise} */ initialiseSteps: function () { - var self = this, + let self = this, steps = [], i, uploadStep; @@ -98,7 +98,7 @@ steps[ steps.length - 1 ].setNextStep( uploadStep ); return $.Deferred().resolve( steps ).promise() - .always( function ( stepsInner ) { + .always( ( stepsInner ) => { self.steps = stepsInner; self.ui.initialiseSteps( stepsInner ); } ); @@ -119,10 +119,10 @@ * @return {mw.Api} */ getApi: function ( options ) { - var api = new mw.Api( options ); + const api = new mw.Api( options ); api.ajax = function ( parameters, ajaxOptions ) { - var original, override; + let original, override; Object.assign( parameters, { errorformat: 'html', @@ -137,8 +137,8 @@ // output is always, reliably, in the same format override = original.then( null, // done handler - doesn't need overriding - function ( code, result ) { // fail handler - var response = { errors: [ { + ( code, result ) => { // fail handler + let response = { errors: [ { code: code, html: result.textStatus || mw.message( 'api-clientside-error-invalidresponse' ).parse() } ] }; @@ -183,10 +183,10 @@ * @return {mw.deed.Abstract[]} */ mw.UploadWizard.getLicensingDeeds = function ( uploads, config ) { - var deed, api, + let deed, api, deeds = {}, - doOwnWork = config.licensing.showTypes.indexOf( 'ownWork' ) > -1, - doThirdParty = config.licensing.showTypes.indexOf( 'thirdParty' ) > -1; + doOwnWork = config.licensing.showTypes.includes( 'ownWork' ), + doThirdParty = config.licensing.showTypes.includes( 'thirdParty' ); if ( !config.licensing.enabled ) { return { diff --git a/resources/mw.UploadWizardDeedChooser.js b/resources/mw.UploadWizardDeedChooser.js index 3cf37e3..88a7429 100644 --- a/resources/mw.UploadWizardDeedChooser.js +++ b/resources/mw.UploadWizardDeedChooser.js @@ -9,7 +9,7 @@ * @param {mw.UploadWizardUpload[]} uploads Uploads that this applies to (this is just to make deleting and plurals work) */ mw.UploadWizardDeedChooser = function ( config, selector, deeds, uploads ) { - var chooser = this; + const chooser = this; this.$selector = $( selector ); this.uploads = uploads; this.deeds = deeds; @@ -20,8 +20,8 @@ this.onLayoutReady = function () {}; - Object.keys( this.deeds ).forEach( function ( name ) { - var deed = chooser.deeds[ name ], + Object.keys( this.deeds ).forEach( ( name ) => { + const deed = chooser.deeds[ name ], radio = new OO.ui.RadioSelectWidget( { items: [ new OO.ui.RadioOptionWidget( { // eslint-disable-next-line mediawiki/msg-doc @@ -53,7 +53,7 @@ if ( config.licensing.defaultType.toLowerCase() === deed.name ) { chooser.onLayoutReady = chooser.selectDeed.bind( chooser, deed ); } - radio.on( 'choose', function () { + radio.on( 'choose', () => { chooser.selectDeed( deed ); } ); } @@ -84,7 +84,7 @@ uploads: [], selectDeed: function ( deed ) { - var $deedInterface = this.$selector.find( '.mediauploader-deed.mediauploader-deed-' + deed.name ); + const $deedInterface = this.$selector.find( '.mediauploader-deed.mediauploader-deed-' + deed.name ); this.choose( deed ); this.selectDeedInterface( $deedInterface ); @@ -92,11 +92,11 @@ }, choose: function ( deed ) { - var chooser = this; + const chooser = this; this.deed = deed; - this.uploads.forEach( function ( upload ) { + this.uploads.forEach( ( upload ) => { upload.deedChooser = chooser; } ); @@ -112,7 +112,7 @@ deselectDeedInterface: function ( $deedSelector ) { $deedSelector.removeClass( 'selected' ); $deedSelector.find( '.mediauploader-deed-form' ).each( function () { - var $form = $( this ); + const $form = $( this ); // Prevent validation of deselected deeds by disabling all form inputs // TODO: Use a tag selector // eslint-disable-next-line no-jquery/no-sizzle @@ -134,13 +134,13 @@ * @param {jQuery} $deedSelector */ selectDeedInterface: function ( $deedSelector ) { - var $otherDeeds = $deedSelector.siblings().filter( '.mediauploader-deed' ); + const $otherDeeds = $deedSelector.siblings().filter( '.mediauploader-deed' ); this.deselectDeedInterface( $otherDeeds ); // FIXME: Use CSS transition // eslint-disable-next-line no-jquery/no-fade $deedSelector.addClass( 'selected' ).fadeTo( 'fast', 1.0 ); $deedSelector.find( '.mediauploader-deed-form' ).each( function () { - var $form = $( this ); + const $form = $( this ); // (Re-)enable all form inputs // TODO: Use a tag selector // eslint-disable-next-line no-jquery/no-sizzle @@ -173,7 +173,7 @@ * @param {Object} serialized */ setSerialized: function ( serialized ) { - var deed; + let deed; if ( serialized.name && serialized.name in this.deeds ) { deed = this.deeds[ serialized.name ]; diff --git a/resources/mw.UploadWizardDetails.js b/resources/mw.UploadWizardDetails.js index c47e21e..30a63a6 100644 --- a/resources/mw.UploadWizardDetails.js +++ b/resources/mw.UploadWizardDetails.js @@ -1,6 +1,6 @@ ( function ( uw ) { - var NS_FILE = mw.config.get( 'wgNamespaceIds' ).file; + const NS_FILE = mw.config.get( 'wgNamespaceIds' ).file; /** * Object that represents the Details (step 2) portion of the UploadWizard @@ -42,7 +42,7 @@ * Build the interface and attach all elements - do this on demand. */ buildInterface: function () { - var $moreDetailsWrapperDiv, $moreDetailsDiv, + let $moreDetailsWrapperDiv, $moreDetailsDiv, fKey, fSpec, fieldWidget, fieldWrapper, fConfigBase, details = this, config = mw.UploadWizard.config; @@ -135,7 +135,7 @@ this.fieldMap[ fKey ] = fieldWidget; } - this.fieldList.sort( function ( a, b ) { + this.fieldList.sort( ( a, b ) => { if ( a.order < b.order ) { return -1; } @@ -175,7 +175,7 @@ $moreDetailsDiv.append( fieldWrapper.$element ); // If something changes the input "hidden" in the collapsed section, // expand it. - fieldWidget.on( 'change', function () { + fieldWidget.on( 'change', () => { $moreDetailsWrapperDiv.data( 'mw-collapsible' ).expand(); } ); } else { @@ -194,7 +194,7 @@ ) .makeCollapsible( { collapsed: true } ); - this.$form.on( 'submit', function ( e ) { + this.$form.on( 'submit', ( e ) => { // Prevent actual form submission e.preventDefault(); } ); @@ -211,10 +211,10 @@ flags: 'destructive', icon: 'trash', framed: false - } ).on( 'click', function () { + } ).on( 'click', () => { OO.ui.confirm( mw.message( 'mediauploader-license-confirm-remove' ).text(), { title: mw.message( 'mediauploader-license-confirm-remove-title' ).text() - } ).done( function ( confirmed ) { + } ).done( ( confirmed ) => { if ( confirmed ) { details.upload.emit( 'remove-upload' ); } @@ -272,7 +272,7 @@ * Will only append once. */ attach: function () { - var $window = $( window ), + const $window = $( window ), details = this; function maybeBuild() { @@ -301,7 +301,7 @@ * @return {mw.Title|null} */ getTitle: function () { - var titleField = mw.UploadWizard.config.content.titleField; + const titleField = mw.UploadWizard.config.content.titleField; // title will not be set until we've actually submitted the file if ( this.title === undefined ) { @@ -320,7 +320,7 @@ * @chainable */ setDuplicateTitleError: function () { - var titleField = mw.UploadWizard.config.content.titleField; + const titleField = mw.UploadWizard.config.content.titleField; // TODO This should give immediate response, not only when submitting the form this.fieldWrapperMap[ titleField ].setErrors( [ mw.message( 'mediauploader-error-title-duplicate' ) ] @@ -357,9 +357,7 @@ * empty arrays. */ getErrors: function () { - return $.when.apply( $, this.getAllFields().map( function ( fieldLayout ) { - return fieldLayout.fieldWidget.getErrors(); - } ) ); + return $.when.apply( $, this.getAllFields().map( ( fieldLayout ) => fieldLayout.fieldWidget.getErrors() ) ); }, /** @@ -368,9 +366,7 @@ * @return {jQuery.Promise} Same as #getErrors */ getWarnings: function () { - return $.when.apply( $, this.getAllFields().map( function ( fieldLayout ) { - return fieldLayout.fieldWidget.getWarnings(); - } ) ); + return $.when.apply( $, this.getAllFields().map( ( fieldLayout ) => fieldLayout.fieldWidget.getWarnings() ) ); }, /** @@ -380,12 +376,12 @@ * @return {jQuery.Promise} Combined promise of all fields' validation results. */ checkValidity: function ( thorough ) { - var fields = this.getAllFields(); + const fields = this.getAllFields(); - return $.when.apply( $, fields.map( function ( fieldLayout ) { + return $.when.apply( $, fields.map( ( fieldLayout ) => // Update any error/warning messages - return fieldLayout.checkValidity( thorough ); - } ) ); + fieldLayout.checkValidity( thorough ) + ) ); }, /** @@ -394,7 +390,7 @@ * @return {string} */ getThumbnailCaption: function () { - var captionField = mw.UploadWizard.config.content.captionField; + const captionField = mw.UploadWizard.config.content.captionField; // The caption field should be one of: // TextWidget, SingleLanguageInputWidget, MultipleLanguageInputWidget @@ -409,7 +405,7 @@ * @param {uw.DetailsWidget} widget */ prefillField: function ( fSpec, widget ) { - var dynPrefilled = false; + let dynPrefilled = false; // Try dynamic prefilling, if requested and available for this type if ( fSpec.autoFill ) { @@ -447,7 +443,7 @@ * @return {boolean} */ prefillDate: function ( widget ) { - var dateObj, metadata, dateStr, saneTime, + let dateObj, metadata, dateStr, saneTime, dateMode = 'calendar', yyyyMmDdRegex = /^(\d\d\d\d)[:/-](\d\d)[:/-](\d\d)\D.*/, timeRegex = /\D(\d\d):(\d\d):(\d\d)/; @@ -458,7 +454,7 @@ } function getSaneTime( date ) { - var str = ''; + let str = ''; str += pad( date.getHours() ) + ':'; str += pad( date.getMinutes() ) + ':'; @@ -469,8 +465,8 @@ if ( this.upload.imageinfo.metadata ) { metadata = this.upload.imageinfo.metadata; - [ 'datetimeoriginal', 'datetimedigitized', 'datetime', 'date' ].some( function ( propName ) { - var matches, timeMatches, + [ 'datetimeoriginal', 'datetimedigitized', 'datetime', 'date' ].some( ( propName ) => { + let matches, timeMatches, dateInfo = metadata[ propName ]; if ( dateInfo ) { matches = dateInfo.trim().match( yyyyMmDdRegex ); @@ -551,7 +547,7 @@ * @return {boolean} */ prefillDescription: function ( type, widget ) { - var m, descText; + let m, descText; if ( widget.getWikiText() === '' && @@ -601,7 +597,7 @@ * @return {boolean} */ prefillLocation: function ( widget ) { - var dir, + let dir, m = this.upload.imageinfo.metadata, modified = false, values = {}; @@ -652,7 +648,7 @@ * @return {Object} */ getLanguageOptions: function () { - var languages, code; + let languages, code; languages = {}; for ( code in mw.UploadWizard.config.languages ) { @@ -673,7 +669,7 @@ * @return {Object.<string,Object>} */ getSerialized: function () { - var fieldWidget, serialized = {}; + let fieldWidget, serialized = {}; if ( !this.interfaceBuilt ) { // We don't have the interface yet, but it'll get filled out as @@ -734,7 +730,7 @@ * @return {string} wikitext representing all details */ getWikiText: function () { - var wikiText = mw.UploadWizard.config.content.wikitext, + let wikiText = mw.UploadWizard.config.content.wikitext, substitutions = {}, substList = [], deed = this.upload.deedChooser.deed, fieldWidget, serialized, valueType, re, escapedKey, replaceValue; @@ -750,7 +746,7 @@ } function addSubstitution( key, value ) { - var v = value; + let v = value; if ( key in substitutions ) { return; } @@ -781,7 +777,7 @@ return; } // Also add "subfields" based on the serialized values. Just in case. - Object.keys( serialized ).forEach( function ( key ) { + Object.keys( serialized ).forEach( ( key ) => { replaceValue = serialized[ key ]; valueType = typeof replaceValue; if ( valueType === 'string' || valueType === 'number' || valueType === 'boolean' ) { @@ -791,11 +787,11 @@ }, this ); // Do the substitutions - substList.forEach( function ( substKey ) { + substList.forEach( ( substKey ) => { replaceValue = substitutions[ substKey ].trim(); escapedKey = substKey.replace( /[.*+?^${}()|[\]\\]/g, '\\$&' ); re = new RegExp( '\\{\\{\\{ *' + escapedKey + ' *(\\|(.*?))?\\}\\}\\}', 'giu' ); - wikiText = wikiText.replace( re, function ( match, _, defaultValue ) { + wikiText = wikiText.replace( re, ( match, _, defaultValue ) => { if ( !replaceValue ) { return defaultValue || ''; } else { @@ -814,7 +810,7 @@ * @return {jQuery.Promise} */ submit: function () { - var details = this, + let details = this, wikitext, promise; this.$containerDiv.find( 'form' ).trigger( 'submit' ); @@ -827,7 +823,7 @@ wikitext = this.getWikiText(); promise = this.submitWikiText( wikitext ); - return promise.then( function () { + return promise.then( () => { details.showIndicator( 'success' ); details.setStatus( mw.message( 'mediauploader-published' ).text() ); } ); @@ -843,7 +839,7 @@ * @return {jQuery.Promise} */ submitWikiText: function ( wikiText ) { - var params, + let params, tags = [ 'uploadwizard' ], deed = this.upload.deedChooser.deed, comment = '', @@ -900,7 +896,7 @@ * @return {jQuery.Promise} */ submitWikiTextInternal: function ( params ) { - var details = this, + const details = this, apiPromise = this.upload.api.postWithEditToken( params ); return apiPromise @@ -910,7 +906,7 @@ .then( this.validateWikiTextSubmitResult.bind( this, params ) ) // making it here means the upload is a success, or it would've been // rejected by now (either by HTTP status code, or in validateWikiTextSubmitResult) - .then( function ( result ) { + .then( ( result ) => { details.title = mw.Title.makeTitle( 6, result.upload.filename ); details.upload.extractImageInfo( result.upload.imageinfo ); details.upload.thisProgress = 1.0; @@ -918,7 +914,7 @@ return result; } ) // uh-oh - something went wrong! - .catch( function ( code, result ) { + .catch( ( code, result ) => { details.upload.state = 'error'; details.processError( code, result ); return $.Deferred().reject( code, result ); @@ -936,7 +932,7 @@ * @return {jQuery.Promise} */ validateWikiTextSubmitResult: function ( params, result ) { - var wx, warningsKeys, existingFile, existingFileUrl, existingFileExt, ourFileExt, code, message, + let wx, warningsKeys, existingFile, existingFileUrl, existingFileExt, ourFileExt, code, message, details = this, warnings = null, ignoreTheseWarnings = false, @@ -961,7 +957,7 @@ // * mediauploader-publish // * mediauploader-assembling this.setStatus( mw.message( 'mediauploader-' + result.upload.stage ).text() ); - setTimeout( function () { + setTimeout( () => { if ( details.upload.state !== 'aborted' ) { details.submitWikiTextInternal( { action: 'upload', @@ -1055,7 +1051,7 @@ * @param {string} html Error message to show. */ recoverFromError: function ( code, html ) { - var titleField = mw.UploadWizard.config.content.titleField; + const titleField = mw.UploadWizard.config.content.titleField; this.upload.state = 'recoverable-error'; this.$dataDiv.morphCrossfade( '.detailsForm' ); @@ -1080,7 +1076,7 @@ * @param {Object} result Result from ajax call */ processError: function ( code, result ) { - var recoverable = [ + const recoverable = [ 'abusefilter-disallowed', 'abusefilter-warning', 'spamblacklist', @@ -1117,7 +1113,7 @@ code = 'ratelimited'; } - if ( recoverable.indexOf( code ) > -1 ) { + if ( recoverable.includes( code ) ) { this.recoverFromError( code, result.errors[ 0 ].html ); return; } diff --git a/resources/mw.UploadWizardLicenseInput.js b/resources/mw.UploadWizardLicenseInput.js index b3696aa..00416ef 100644 --- a/resources/mw.UploadWizardLicenseInput.js +++ b/resources/mw.UploadWizardLicenseInput.js @@ -14,7 +14,7 @@ * @param {mw.Api} api API object, used for wikitext previews */ mw.UploadWizardLicenseInput = function ( config, count, api ) { - var self = this, + let self = this, groups = [], group; @@ -45,7 +45,7 @@ group = new uw.LicenseGroup( config, this.type, this.api, this.count ); groups.push( group ); } else { - config.licenseGroups.forEach( function ( groupConfig ) { + config.licenseGroups.forEach( ( groupConfig ) => { group = new uw.LicenseGroup( groupConfig, self.type, self.api, self.count ); groups.push( group ); @@ -54,8 +54,8 @@ // upon selecting a new item in any group, iterate the other groups and make // sure they're updated accordingly, deselecting previously selected items if ( self.type === 'radio' ) { - group.on( 'change', function ( currentGroup ) { - var value = currentGroup.getValue(), + group.on( 'change', ( currentGroup ) => { + const value = currentGroup.getValue(), group2 = currentGroup.getGroup(); self.setValues( value, group2 ); } ); @@ -76,7 +76,7 @@ Object.assign( mw.UploadWizardLicenseInput.prototype, { unload: function () { - this.getItems().forEach( function ( group ) { + this.getItems().forEach( ( group ) => { group.unload(); } ); }, @@ -89,10 +89,10 @@ * @param {string} [groupName] Name of group, when values are only relevant to this group */ setValues: function ( values, groupName ) { - var self = this, + const self = this, selectedGroups = []; - this.getItems().forEach( function ( group ) { + this.getItems().forEach( ( group ) => { if ( groupName === undefined || group.getGroup() === groupName ) { group.setValue( values ); if ( Object.keys( group.getValue() ).length > 0 ) { @@ -115,7 +115,7 @@ // 1 group // in that case, we're only going to select the *last* occurrence, which is what // a browser would do when trying to find/select a radio that occurs twice - selectedGroups.forEach( function ( group ) { + selectedGroups.forEach( ( group ) => { group.setValue( {} ); } ); } @@ -125,8 +125,8 @@ * Set the default configured licenses */ setDefaultValues: function () { - var values = {}; - this.defaults.forEach( function ( license ) { + const values = {}; + this.defaults.forEach( ( license ) => { values[ license ] = true; } ); this.setValues( values ); @@ -139,11 +139,11 @@ * @return {Object} */ getLicenses: function () { - var licenses = {}; + const licenses = {}; - this.getItems().forEach( function ( group ) { - var licenseNames = Object.keys( group.getValue() ); - licenseNames.forEach( function ( name ) { + this.getItems().forEach( ( group ) => { + const licenseNames = Object.keys( group.getValue() ); + licenseNames.forEach( ( name ) => { licenses[ name ] = mw.UploadWizard.config.licenses[ name ] || {}; } ); } ); @@ -157,9 +157,7 @@ * @return {string} of wikitext (empty string if no inputs set) */ getWikiText: function () { - return this.getItems().map( function ( group ) { - return group.getWikiText(); - } ).join( '' ).trim(); + return this.getItems().map( ( group ) => group.getWikiText() ).join( '' ).trim(); }, /** @@ -169,7 +167,7 @@ * @return {jQuery.Promise} Promise that resolves with an array of template names */ getUsedTemplates: function ( wikitext ) { - var input = this; + const input = this; if ( wikitext in this.templateCache ) { return $.Deferred().resolve( this.templateCache[ wikitext ] ).promise(); @@ -181,8 +179,8 @@ prop: 'templates', title: 'File:UploadWizard license verification.png', text: wikitext - } ).then( function ( result ) { - var templates = [], + } ).then( ( result ) => { + let templates = [], template, title, i; for ( i = 0; i < result.parse.templates.length; i++ ) { @@ -207,9 +205,9 @@ * @return {jQuery.Promise} */ getErrors: function () { - var errors = $.Deferred().resolve( [] ).promise(), + let errors = $.Deferred().resolve( [] ).promise(), addError = function ( message ) { - errors = errors.then( function ( errorsCopy ) { + errors = errors.then( ( errorsCopy ) => { // eslint-disable-next-line mediawiki/msg-doc errorsCopy.push( mw.message( message ) ); return errorsCopy; @@ -223,8 +221,8 @@ // It's pretty hard to screw up a radio button, so if even one of them is selected it's okay. // But also check that associated textareas are filled for if the input is selected, and that // they are the appropriate size. - Object.keys( selectedInputs ).forEach( function ( name ) { - var wikitext, + Object.keys( selectedInputs ).forEach( ( name ) => { + let wikitext, data = selectedInputs[ name ]; if ( typeof data !== 'string' ) { @@ -259,10 +257,10 @@ * @return {Object} */ getSerialized: function () { - var values = {}; + const values = {}; - this.getItems().forEach( function ( group ) { - var groupName = group.getGroup(), + this.getItems().forEach( ( group ) => { + const groupName = group.getGroup(), value = group.getValue(); if ( Object.keys( value ).length > 0 ) { @@ -278,9 +276,9 @@ * @param {Object} serialized */ setSerialized: function ( serialized ) { - var self = this; + const self = this; - Object.keys( serialized ).forEach( function ( group ) { + Object.keys( serialized ).forEach( ( group ) => { self.setValues( serialized[ group ], group ); } ); } diff --git a/resources/mw.UploadWizardPage.js b/resources/mw.UploadWizardPage.js index c874700..02f8086 100644 --- a/resources/mw.UploadWizardPage.js +++ b/resources/mw.UploadWizardPage.js @@ -10,7 +10,7 @@ ( function () { function isCompatible() { - var + const profile = $.client.profile(), // Firefox < 7.0 sends an empty string as filename for Blobs in FormData. // requests. https://bugzilla.mozilla.org/show_bug.cgi?id=649150 @@ -27,7 +27,7 @@ mw.UploadWizardPage = function () { - var uploadWizard, + let uploadWizard, config = mw.config.get( 'MediaUploaderConfig' ); // Default configuration value that cannot be removed @@ -54,7 +54,7 @@ uploadWizard.createInterface( '#upload-wizard' ); }; - $( function () { + $( () => { // show page. mw.UploadWizardPage(); } ); diff --git a/resources/mw.UploadWizardUpload.js b/resources/mw.UploadWizardUpload.js index a8ce368..b6db80f 100644 --- a/resources/mw.UploadWizardUpload.js +++ b/resources/mw.UploadWizardUpload.js @@ -167,7 +167,7 @@ * @return {string} basename */ mw.UploadWizardUpload.prototype.getBasename = function () { - var path = this.getFilename(); + const path = this.getFilename(); if ( path === undefined || path === null ) { return ''; @@ -200,7 +200,7 @@ * @return {jQuery.Promise} A promise, resolved when we're done */ mw.UploadWizardUpload.prototype.extractMetadataFromJpegMeta = function () { - var binReader, jpegmeta, + let binReader, jpegmeta, deferred = $.Deferred(), upload = this; if ( this.file && this.file.type === 'image/jpeg' ) { @@ -209,7 +209,7 @@ deferred.resolve(); }; binReader.onload = function () { - var binStr, arr, i, meta; + let binStr, arr, i, meta; if ( binReader.result === null ) { // Contrary to documentation, this sometimes fires for unsuccessful loads (T136235) deferred.resolve(); @@ -254,7 +254,7 @@ * @param {Object} meta As returned by jpegmeta */ mw.UploadWizardUpload.prototype.extractMetadataFromJpegMetaCallback = function ( meta ) { - var pixelHeightDim, pixelWidthDim, degrees; + let pixelHeightDim, pixelWidthDim, degrees; if ( meta !== undefined && meta !== null && typeof meta === 'object' ) { if ( this.imageinfo.metadata === undefined ) { @@ -310,7 +310,7 @@ * @param {Object} imageinfo JSON object obtained from API result. */ mw.UploadWizardUpload.prototype.extractImageInfo = function ( imageinfo ) { - var key, + let key, upload = this; for ( key in imageinfo ) { @@ -320,7 +320,7 @@ this.imageinfo.metadata = {}; } if ( imageinfo.metadata && imageinfo.metadata.length ) { - imageinfo.metadata.forEach( function ( pair ) { + imageinfo.metadata.forEach( ( pair ) => { if ( pair !== undefined ) { upload.imageinfo.metadata[ pair.name.toLowerCase() ] = pair.value; } @@ -343,7 +343,7 @@ * @param {number} [height] Height of thumbnail. Will force 'url' to be added to props */ mw.UploadWizardUpload.prototype.getStashImageInfo = function ( callback, props, width, height ) { - var params = { + const params = { prop: 'stashimageinfo', siifilekey: this.fileKey, siiprop: props.join( '|' ) @@ -368,7 +368,7 @@ } if ( width !== undefined || height !== undefined ) { - if ( props.indexOf( 'url' ) === -1 ) { + if ( !props.includes( 'url' ) ) { props.push( 'url' ); } if ( width !== undefined ) { @@ -393,15 +393,15 @@ * @param {number} [height] Height of thumbnail. Will force 'url' to be added to props */ mw.UploadWizardUpload.prototype.getImageInfo = function ( callback, props, width, height ) { - var requestedTitle, params; + let requestedTitle, params; function ok( data ) { - var found; + let found; if ( data && data.query && data.query.pages ) { found = false; - Object.keys( data.query.pages ).forEach( function ( pageId ) { - var page = data.query.pages[ pageId ]; + Object.keys( data.query.pages ).forEach( ( pageId ) => { + const page = data.query.pages[ pageId ]; if ( page.title && page.title === requestedTitle && page.imageinfo ) { found = true; callback( page.imageinfo ); @@ -434,7 +434,7 @@ }; if ( width !== undefined || height !== undefined ) { - if ( props.indexOf( 'url' ) === -1 ) { + if ( !props.includes( 'url' ) ) { props.push( 'url' ); } if ( width !== undefined ) { @@ -454,7 +454,7 @@ * @return {mw.ApiUploadFormDataHandler} upload handler object */ mw.UploadWizardUpload.prototype.getUploadHandler = function () { - var constructor; // must be the name of a function in 'mw' namespace + let constructor; // must be the name of a function in 'mw' namespace if ( !this.uploadHandler ) { constructor = 'ApiUploadFormDataHandler'; @@ -473,7 +473,7 @@ * couldn't be generated */ mw.UploadWizardUpload.prototype.getApiThumbnail = function ( width, height ) { - var deferred = $.Deferred(); + const deferred = $.Deferred(); function thumbnailPublisher( thumbnails ) { if ( thumbnails === null ) { @@ -484,8 +484,8 @@ // they are actually there yet. Keep trying to set the source ( which should trigger "error" or "load" event ) // on the image. If it loads publish the event with the image. If it errors out too many times, give up and publish // the event with a null. - thumbnails.forEach( function ( thumb ) { - var timeoutMs, image; + thumbnails.forEach( ( thumb ) => { + let timeoutMs, image; if ( thumb.thumberror || ( !( thumb.thumburl && thumb.thumbwidth && thumb.thumbheight ) ) ) { mw.log.warn( 'mw.UploadWizardUpload::getThumbnail> Thumbnail error or missing information' ); @@ -507,14 +507,14 @@ image.width = thumb.thumbwidth; image.height = thumb.thumbheight; $( image ) - .on( 'load', function () { + .on( 'load', () => { // publish the image to anyone who wanted it deferred.resolve( image ); } ) - .on( 'error', function () { + .on( 'error', () => { // retry with exponential backoff if ( timeoutMs < 8000 ) { - setTimeout( function () { + setTimeout( () => { timeoutMs = timeoutMs * 2 + Math.round( Math.random() * ( timeoutMs / 10 ) ); setSrc(); }, timeoutMs ); @@ -545,7 +545,7 @@ * @return {number} orientation in degrees: 0, 90, 180 or 270 */ mw.UploadWizardUpload.prototype.getOrientationDegrees = function () { - var orientation = 0; + let orientation = 0; if ( this.imageinfo && this.imageinfo.metadata && this.imageinfo.metadata.orientation ) { switch ( this.imageinfo.metadata.orientation ) { case 8: @@ -579,9 +579,9 @@ * @return {number} */ mw.UploadWizardUpload.prototype.getScalingFromConstraints = function ( image, constraints ) { - var scaling = 1; - Object.keys( constraints ).forEach( function ( dim ) { - var s, + let scaling = 1; + Object.keys( constraints ).forEach( ( dim ) => { + let s, constraint = constraints[ dim ]; if ( constraint && image[ dim ] > constraint ) { s = constraint / image[ dim ]; @@ -603,7 +603,7 @@ * @return {HTMLCanvasElement|null} */ mw.UploadWizardUpload.prototype.getTransformedCanvasElement = function ( image, constraints ) { - var angle, scaling, width, height, + let angle, scaling, width, height, dimensions, dx, dy, x, y, $canvas, ctx, scaleConstraints = constraints, rotation = 0; @@ -693,7 +693,7 @@ * @return {HTMLImageElement} with same src, but different attrs */ mw.UploadWizardUpload.prototype.getBrowserScaledImageElement = function ( image, constraints ) { - var scaling = this.getScalingFromConstraints( image, constraints ); + const scaling = this.getScalingFromConstraints( image, constraints ); return $( '<img>' ) .attr( { width: parseInt( image.width * scaling, 10 ), @@ -712,7 +712,7 @@ * @return {HTMLCanvasElement|HTMLImageElement} */ mw.UploadWizardUpload.prototype.getScaledImageElement = function ( image, width, height ) { - var constraints = {}, + let constraints = {}, transform; if ( width ) { @@ -742,7 +742,7 @@ * containing a thumbnail, or resolved with `null` when one can't be produced */ mw.UploadWizardUpload.prototype.getThumbnail = function ( width, height ) { - var upload = this, + const upload = this, deferred = $.Deferred(); if ( this.thumbnailPromise[ width + 'x' + height ] ) { @@ -767,14 +767,14 @@ this.extractMetadataFromJpegMeta() .then( upload.makePreview.bind( upload, width ) ) .done( imageCallback ) - .fail( function () { + .fail( () => { // Can't generate the thumbnail locally, get the thumbnail via API after // the file is uploaded. Queries are cached, so if this thumbnail was // already fetched for some reason, we'll get it immediately. if ( upload.state !== 'new' && upload.state !== 'transporting' && upload.state !== 'error' ) { upload.getApiThumbnail( width, height ).done( imageCallback ); } else { - upload.once( 'success', function () { + upload.once( 'success', () => { upload.getApiThumbnail( width, height ).done( imageCallback ); } ); } @@ -798,7 +798,7 @@ * @return {jQuery.Promise} */ mw.UploadWizardUpload.prototype.makePreview = function ( width ) { - var first, video, url, dataUrlReader, + let first, video, url, dataUrlReader, deferred = $.Deferred(), upload = this; @@ -809,12 +809,12 @@ first = true; video = document.createElement( 'video' ); - video.addEventListener( 'loadedmetadata', function () { + video.addEventListener( 'loadedmetadata', () => { // seek 2 seconds into video or to half if shorter video.currentTime = Math.min( 2, video.duration / 2 ); video.volume = 0; } ); - video.addEventListener( 'seeked', function () { + video.addEventListener( 'seeked', () => { // Firefox 16 sometimes does not work on first seek, seek again if ( first ) { first = false; @@ -823,8 +823,8 @@ } else { // Chrome sometimes shows black frames if grabbing right away. // wait 500ms before grabbing frame - setTimeout( function () { - var context, + setTimeout( () => { + let context, canvas = document.createElement( 'canvas' ); canvas.width = width; canvas.height = Math.round( canvas.width * video.videoHeight / video.videoWidth ); @@ -844,7 +844,7 @@ video.src = url; // If we can't get a frame within 10 seconds, something is probably seriously wrong. // This can happen for broken files where we can't actually seek to the time we wanted. - setTimeout( function () { + setTimeout( () => { deferred.reject(); upload.URL().revokeObjectURL( video.url ); }, 10000 ); @@ -871,7 +871,7 @@ * @param {jQuery.Deferred} deferred */ mw.UploadWizardUpload.prototype.loadImage = function ( url, deferred ) { - var image = document.createElement( 'img' ); + const image = document.createElement( 'img' ); image.onload = function () { deferred.resolve( image ); }; diff --git a/resources/mw.UploadWizardUploadInterface.js b/resources/mw.UploadWizardUploadInterface.js index 263787d..610a2bb 100644 --- a/resources/mw.UploadWizardUploadInterface.js +++ b/resources/mw.UploadWizardUploadInterface.js @@ -7,7 +7,7 @@ * @param {mw.UploadWizardUpload} upload */ mw.UploadWizardUploadInterface = function MWUploadWizardUploadInterface( upload ) { - var ui = this; + const ui = this; OO.EventEmitter.call( this ); @@ -47,7 +47,7 @@ flags: 'destructive', icon: 'trash', framed: false - } ).on( 'click', function () { + } ).on( 'click', () => { ui.emit( 'upload-removed' ); } ); @@ -63,7 +63,7 @@ // this.progressBar = ( no progress bar for individual uploads yet ) // we bind to the ui div since .off() doesn't work for non-DOM objects // TODO Convert this to an OO.EventEmitter, and use OOjs events - this.$div.on( 'transportProgressEvent', function () { + this.$div.on( 'transportProgressEvent', () => { ui.showTransportProgress(); } ); }; @@ -96,7 +96,7 @@ */ mw.UploadWizardUploadInterface.prototype.setStatus = function ( msgKey, args ) { // get the status line for our upload - var $status = this.$div.find( '.mediauploader-file-status' ); + const $status = this.$div.find( '.mediauploader-file-status' ); // eslint-disable-next-line mediawiki/msg-doc $status.msg( msgKey, args || [] ).show(); }; @@ -176,7 +176,7 @@ * @param {File} file */ mw.UploadWizardUploadInterface.prototype.fileChangedOk = function ( imageinfo, file ) { - var statusItems = []; + const statusItems = []; this.updateFilename(); @@ -200,10 +200,10 @@ * fails */ mw.UploadWizardUploadInterface.prototype.showThumbnail = function () { - var $preview = this.$div.find( '.mediauploader-file-preview' ), + const $preview = this.$div.find( '.mediauploader-file-preview' ), deferred = $.Deferred(); // This must match the CSS dimensions of .mediauploader-file-preview - this.upload.getThumbnail( 120, 120 ).done( function ( thumb ) { + this.upload.getThumbnail( 120, 120 ).done( ( thumb ) => { mw.UploadWizard.placeThumbnail( $preview, thumb ); deferred.resolve(); } ); @@ -219,7 +219,7 @@ * TODO silently fix to have unique filename? unnecessary at this point... */ mw.UploadWizardUploadInterface.prototype.updateFilename = function () { - var path = this.upload.getFilename(); + const path = this.upload.getFilename(); // visible filename this.$form.find( '.mediauploader-visible-file-filename-text' ) diff --git a/resources/mw.fileApi.js b/resources/mw.fileApi.js index cb80590..9216c24 100644 --- a/resources/mw.fileApi.js +++ b/resources/mw.fileApi.js @@ -15,9 +15,9 @@ * @return {boolean} */ isPreviewableFile: function ( file ) { - var known = [ 'image/png', 'image/gif', 'image/jpeg' ], + const known = [ 'image/png', 'image/gif', 'image/jpeg' ], tooHuge = 10 * 1024 * 1024; - return this.isPreviewableVideo( file ) || ( known.indexOf( file.type ) !== -1 ) && file.size > 0 && file.size < tooHuge; + return this.isPreviewableVideo( file ) || ( known.includes( file.type ) ) && file.size > 0 && file.size < tooHuge; }, /** @@ -27,7 +27,7 @@ * @return {boolean} */ isPreviewableVideo: function ( file ) { - var video = document.createElement( 'video' ); + const video = document.createElement( 'video' ); return video.canPlayType && video.canPlayType( file.type ).replace( 'no', '' ) !== ''; } diff --git a/resources/transports/mw.FormDataTransport.js b/resources/transports/mw.FormDataTransport.js index 95daece..b1c86ec 100644 --- a/resources/transports/mw.FormDataTransport.js +++ b/resources/transports/mw.FormDataTransport.js @@ -48,7 +48,7 @@ * @return {jQuery.Promise} */ mw.FormDataTransport.prototype.post = function ( params ) { - var deferred = $.Deferred(); + const deferred = $.Deferred(); this.request = this.api.post( params, { /* @@ -66,9 +66,9 @@ * out how much of the upload has already gone out, so let's add it! */ xhr: function () { - var xhr = $.ajaxSettings.xhr(); - xhr.upload.addEventListener( 'progress', function ( evt ) { - var fraction = null; + const xhr = $.ajaxSettings.xhr(); + xhr.upload.addEventListener( 'progress', ( evt ) => { + let fraction = null; if ( evt.lengthComputable ) { fraction = parseFloat( evt.loaded / evt.total ); } @@ -92,7 +92,7 @@ * @return {Object} */ mw.FormDataTransport.prototype.createParams = function ( filename, offset ) { - var params = OO.cloneObject( this.formData ); + const params = OO.cloneObject( this.formData ); Object.assign( params, { filename: filename, @@ -118,7 +118,7 @@ * @return {jQuery.Promise} */ mw.FormDataTransport.prototype.upload = function ( file, tempFileName ) { - var params, ext; + let params, ext; this.tempname = tempFileName; // Limit length to 240 bytes (limit hardcoded in UploadBase.php). @@ -150,7 +150,7 @@ * promise from #upload */ mw.FormDataTransport.prototype.chunkedUpload = function ( file ) { - var + let offset, prevPromise = $.Deferred().resolve(), deferred = $.Deferred(), @@ -162,15 +162,15 @@ // Capture offset in a closure // eslint-disable-next-line no-loop-func ( function ( offset2 ) { - var + const newPromise = $.Deferred(), isLastChunk = offset2 + chunkSize >= fileSize, thisChunkSize = isLastChunk ? ( fileSize % chunkSize ) : chunkSize; - prevPromise.done( function () { + prevPromise.done( () => { transport.uploadChunk( file, offset2 ) .done( isLastChunk ? deferred.resolve : newPromise.resolve ) .fail( deferred.reject ) - .progress( function ( fraction ) { + .progress( ( fraction ) => { // The progress notifications give us per-chunk progress. // Calculate progress for the whole file. deferred.notify( ( offset2 + fraction * thisChunkSize ) / fileSize ); @@ -191,7 +191,7 @@ * @return {jQuery.Promise} */ mw.FormDataTransport.prototype.uploadChunk = function ( file, offset ) { - var params = this.createParams( this.tempname, offset ), + let params = this.createParams( this.tempname, offset ), transport = this, bytesAvailable = file.size, chunk; @@ -229,7 +229,7 @@ params.filesize = bytesAvailable; params.chunk = chunk; - return this.post( params ).then( function ( response ) { + return this.post( params ).then( ( response ) => { if ( response.upload && response.upload.filekey ) { transport.filekey = response.upload.filekey; } @@ -256,7 +256,7 @@ file, offset ); } - }, function ( code, result ) { + }, ( code, result ) => { // Ain't this some great machine readable output eh if ( result.errors && @@ -323,7 +323,7 @@ * @return {jQuery.Promise} */ mw.FormDataTransport.prototype.retryWithMethod = function ( methodName, file, offset ) { - var + const transport = this, retryDeferred = $.Deferred(), retry = function () { @@ -345,7 +345,7 @@ * @return {jQuery.Promise} */ mw.FormDataTransport.prototype.checkStatus = function () { - var transport = this, + const transport = this, params = OO.cloneObject( this.formData ); if ( this.aborted ) { @@ -363,7 +363,7 @@ params.checkstatus = true; params.filekey = this.filekey; this.request = this.api.post( params ) - .then( function ( response ) { + .then( ( response ) => { if ( response.upload && response.upload.result === 'Poll' ) { // If concatenation takes longer than 10 minutes give up if ( ( Date.now() - transport.firstPoll ) > 10 * 60 * 1000 ) { @@ -390,9 +390,7 @@ } return response; - }, function ( code, result ) { - return $.Deferred().reject( code, result ); - } ); + }, ( code, result ) => $.Deferred().reject( code, result ) ); return this.request; }; diff --git a/resources/ui/steps/uw.ui.Deed.js b/resources/ui/steps/uw.ui.Deed.js index 21dcf59..e556430 100644 --- a/resources/ui/steps/uw.ui.Deed.js +++ b/resources/ui/steps/uw.ui.Deed.js @@ -36,7 +36,7 @@ OO.inheritClass( uw.ui.Deed, uw.ui.Step ); uw.ui.Deed.prototype.load = function ( uploads ) { - var ui = this; + const ui = this; uw.ui.Step.prototype.load.call( this, uploads ); @@ -52,7 +52,7 @@ .addClass( 'ui-helper-clearfix' ) ); - this.nextButtonPromise.done( function () { + this.nextButtonPromise.done( () => { // hide "next" button, controller will only show it once license has // been selected ui.nextButton.$element.hide(); diff --git a/resources/ui/steps/uw.ui.Details.js b/resources/ui/steps/uw.ui.Details.js index e5117db..793da75 100644 --- a/resources/ui/steps/uw.ui.Details.js +++ b/resources/ui/steps/uw.ui.Details.js @@ -24,7 +24,7 @@ * @constructor */ uw.ui.Details = function UWUIDetails() { - var details = this; + const details = this; function startDetails() { details.emit( 'start-details' ); @@ -48,7 +48,7 @@ this.nextButtonDespiteFailures = new OO.ui.ButtonWidget( { label: mw.message( 'mediauploader-next-file-despite-failures' ).text(), flags: [ 'progressive' ] - } ).on( 'click', function () { + } ).on( 'click', () => { details.emit( 'finalize-details-after-removal' ); } ); @@ -85,9 +85,9 @@ }; uw.ui.Details.prototype.addNextButton = function () { - var ui = this; + const ui = this; - this.nextButtonPromise.done( function () { + this.nextButtonPromise.done( () => { ui.$buttons.append( $( '<div>' ) .addClass( 'mediauploader-file-next-all-ok mediauploader-file-endchoice' ) @@ -164,14 +164,14 @@ * This method also opens up "more info" if the form has errors. */ uw.ui.Details.prototype.showErrors = function () { - var $errorElements = this.$div + const $errorElements = this.$div // TODO Evil .find( '.oo-ui-fieldLayout-messages-error' ), errorCount = $errorElements.length; // Open "more info" if that part of the form has errors $errorElements.each( function () { - var $collapsibleWrapper = $( this ).closest( '.mwe-more-details' ); + const $collapsibleWrapper = $( this ).closest( '.mwe-more-details' ); if ( $collapsibleWrapper.length ) { $collapsibleWrapper.data( 'mw-collapsible' ).expand(); } @@ -199,14 +199,14 @@ * See #showErrors for details. */ uw.ui.Details.prototype.showWarnings = function () { - var $warningElements = this.$div + const $warningElements = this.$div // TODO Evil .find( '.oo-ui-fieldLayout-messages-notice' ), warningCount = $warningElements.length; // Open "more info" if that part of the form has warnings $warningElements.each( function () { - var $collapsibleWrapper = $( this ).closest( '.mwe-more-details' ); + const $collapsibleWrapper = $( this ).closest( '.mwe-more-details' ); if ( $collapsibleWrapper.length ) { $collapsibleWrapper.data( 'mw-collapsible' ).expand(); } diff --git a/resources/ui/steps/uw.ui.Thanks.js b/resources/ui/steps/uw.ui.Thanks.js index 62290aa..fc56af0 100644 --- a/resources/ui/steps/uw.ui.Thanks.js +++ b/resources/ui/steps/uw.ui.Thanks.js @@ -25,7 +25,7 @@ * @param {Object} config */ uw.ui.Thanks = function UWUIThanks( config ) { - var $header, + let $header, beginButtonTarget, thanks = this; @@ -68,13 +68,13 @@ // TODO: make the step order configurable by campaign definitions instead of using these hacks beginButtonTarget = this.getButtonConfig( 'beginButton', 'target' ); if ( !beginButtonTarget ) { - this.beginButton.on( 'click', function () { + this.beginButton.on( 'click', () => { thanks.emit( 'next-step' ); } ); } else { this.beginButton.setHref( beginButtonTarget ); } - this.beginButton.on( 'click', function () { + this.beginButton.on( 'click', () => { mw.DestinationChecker.clearCache(); } ); @@ -93,7 +93,7 @@ * @param {mw.UploadWizardUpload} upload */ uw.ui.Thanks.prototype.addUpload = function ( upload ) { - var thumbWikiText, $thanksDiv, $thumbnailWrapDiv, $thumbnailDiv, $thumbnailCaption, $thumbnailLink; + let thumbWikiText, $thanksDiv, $thumbnailWrapDiv, $thumbnailDiv, $thumbnailCaption, $thumbnailLink; thumbWikiText = '[[' + [ upload.details.getTitle().getPrefixedText(), @@ -125,7 +125,7 @@ ); // This must match the CSS dimensions of .mediauploader-thumbnail - upload.getThumbnail( 120, 120 ).done( function ( thumb ) { + upload.getThumbnail( 120, 120 ).done( ( thumb ) => { mw.UploadWizard.placeThumbnail( $thumbnailDiv, thumb ); } ); @@ -148,7 +148,7 @@ * @return {jQuery} */ uw.ui.Thanks.prototype.makeReadOnlyInput = function ( value, label, useEditFont ) { - var copyText = new mw.widgets.CopyTextLayout( { + const copyText = new mw.widgets.CopyTextLayout( { align: 'top', label: label, copyText: value diff --git a/resources/ui/steps/uw.ui.Tutorial.js b/resources/ui/steps/uw.ui.Tutorial.js index 1b8d0d4..fa7fd0f 100644 --- a/resources/ui/steps/uw.ui.Tutorial.js +++ b/resources/ui/steps/uw.ui.Tutorial.js @@ -51,7 +51,7 @@ * @constructor */ uw.ui.Tutorial = function UWUITutorial() { - var ui = this; + const ui = this; uw.ui.Step.call( this, @@ -78,7 +78,7 @@ label: mw.message( 'mediauploader-skip-tutorial-future' ).text() } ); - this.skipCheckbox.on( 'change', function () { + this.skipCheckbox.on( 'change', () => { ui.emit( 'skip-tutorial-click', ui.skipCheckbox.isSelected() ); } ); @@ -112,17 +112,17 @@ }; uw.ui.Tutorial.prototype.addNextButton = function () { - var ui = this; + const ui = this; this.nextButton = new OO.ui.ButtonWidget( { classes: [ 'mediauploader-button-next' ], label: mw.message( 'mediauploader-next' ).text(), flags: [ 'progressive', 'primary' ] - } ).on( 'click', function () { + } ).on( 'click', () => { ui.emit( 'next-step' ); } ); - this.nextButtonPromise.done( function () { + this.nextButtonPromise.done( () => { ui.$buttons.append( new OO.ui.HorizontalLayout( { items: [ ui.skipCheckbox, ui.skipCheckboxLabel, ui.nextButton ] diff --git a/resources/ui/steps/uw.ui.Upload.js b/resources/ui/steps/uw.ui.Upload.js index 4ec5509..b7e38bf 100644 --- a/resources/ui/steps/uw.ui.Upload.js +++ b/resources/ui/steps/uw.ui.Upload.js @@ -25,7 +25,7 @@ * @param {Object} config UploadWizard config object. */ uw.ui.Upload = function UWUIUpload( config ) { - var upload = this; + const upload = this; this.config = config; @@ -58,14 +58,14 @@ this.nextStepButtonAllOk = new OO.ui.ButtonWidget( { label: mw.message( 'mediauploader-next-file' ).text(), flags: [ 'progressive', 'primary' ] - } ).on( 'click', function () { + } ).on( 'click', () => { upload.emit( 'next-step' ); } ); this.retryButtonSomeFailed = new OO.ui.ButtonWidget( { label: mw.message( 'mediauploader-file-retry' ).text(), flags: [ 'progressive' ] - } ).on( 'click', function () { + } ).on( 'click', () => { upload.hideEndButtons(); upload.emit( 'retry' ); } ); @@ -73,14 +73,14 @@ this.nextStepButtonSomeFailed = new OO.ui.ButtonWidget( { label: mw.message( 'mediauploader-next-file-despite-failures' ).text(), flags: [ 'progressive', 'primary' ] - } ).on( 'click', function () { + } ).on( 'click', () => { upload.emit( 'next-step' ); } ); this.retryButtonAllFailed = new OO.ui.ButtonWidget( { label: mw.message( 'mediauploader-file-retry' ).text(), flags: [ 'progressive' ] - } ).on( 'click', function () { + } ).on( 'click', () => { upload.hideEndButtons(); upload.emit( 'retry' ); } ); @@ -145,7 +145,7 @@ * @param {boolean} more */ uw.ui.Upload.prototype.setAddButtonText = function ( more ) { - var msg = 'mediauploader-add-file-'; + let msg = 'mediauploader-add-file-'; if ( more ) { msg += 'n'; @@ -160,7 +160,7 @@ }; uw.ui.Upload.prototype.load = function ( uploads ) { - var ui = this; + const ui = this; uw.ui.Step.prototype.load.call( this, uploads ); @@ -177,17 +177,17 @@ ) ); - this.addFile.on( 'change', function ( files ) { + this.addFile.on( 'change', ( files ) => { ui.emit( 'files-added', files ); ui.addFile.setValue( null ); } ); }; uw.ui.Upload.prototype.displayUploads = function ( uploads ) { - var thumbPromise, + let thumbPromise, $uploadInterfaceDivs = $( [] ); - uploads.forEach( function ( upload ) { + uploads.forEach( ( upload ) => { // We'll attach all interfaces to the DOM at once rather than one-by-one, for better // performance $uploadInterfaceDivs = $uploadInterfaceDivs.add( upload.ui.$div ); @@ -199,15 +199,15 @@ // Display thumbnails, but not all at once because they're somewhat expensive to generate. // This will wait for each thumbnail to be complete before starting the next one. thumbPromise = $.Deferred().resolve(); - uploads.forEach( function ( upload ) { - thumbPromise = thumbPromise.then( function () { - var deferred = $.Deferred(); + uploads.forEach( ( upload ) => { + thumbPromise = thumbPromise.then( () => { + const deferred = $.Deferred(); setTimeout( function () { if ( this.movedFrom ) { // We're no longer displaying any of these thumbnails, stop deferred.reject(); } - upload.ui.showThumbnail().done( function () { + upload.ui.showThumbnail().done( () => { deferred.resolve(); } ); } ); @@ -217,9 +217,9 @@ }; uw.ui.Upload.prototype.addNextButton = function () { - var ui = this; + const ui = this; - this.nextButtonPromise.done( function () { + this.nextButtonPromise.done( () => { ui.$buttons.append( $( '<div>' ) .addClass( 'mediauploader-file-next-all-ok mediauploader-file-endchoice' ) @@ -319,12 +319,12 @@ * @param {string} extension */ uw.ui.Upload.prototype.showBadExtensionError = function ( filename, extension ) { - var $errorMessage = $( '<p>' ).msg( 'mediauploader-upload-error-bad-filename-extension', extension ); + const $errorMessage = $( '<p>' ).msg( 'mediauploader-upload-error-bad-filename-extension', extension ); this.showFilenameError( $errorMessage ); }; uw.ui.Upload.prototype.showMissingExtensionError = function () { - var $errorMessage = $( '<p>' ).msg( 'mediauploader-upload-error-bad-filename-no-extension' ); + const $errorMessage = $( '<p>' ).msg( 'mediauploader-upload-error-bad-filename-no-extension' ); this.showFilenameError( $( '<div>' ).append( $errorMessage, diff --git a/resources/ui/uw.ui.DeedPreview.js b/resources/ui/uw.ui.DeedPreview.js index a30f6fb..a7b30b5 100644 --- a/resources/ui/uw.ui.DeedPreview.js +++ b/resources/ui/uw.ui.DeedPreview.js @@ -24,10 +24,10 @@ * @param {mw.UploadWizardUpload} upload */ uw.ui.DeedPreview = function UWUIDeedPreview( upload ) { - var $thumbnailDiv = $( '<div>' ).addClass( 'mediauploader-thumbnail' ); + const $thumbnailDiv = $( '<div>' ).addClass( 'mediauploader-thumbnail' ); this.$thumbnailDiv = $thumbnailDiv; // This must match the CSS dimensions of .mediauploader-thumbnail - upload.getThumbnail( 120, 120 ).done( function ( thumb ) { + upload.getThumbnail( 120, 120 ).done( ( thumb ) => { mw.UploadWizard.placeThumbnail( $thumbnailDiv, thumb ); } ); // eslint-disable-next-line no-jquery/no-global-selector diff --git a/resources/ui/uw.ui.Step.js b/resources/ui/uw.ui.Step.js index 6b19ffb..af3d8ae 100644 --- a/resources/ui/uw.ui.Step.js +++ b/resources/ui/uw.ui.Step.js @@ -53,7 +53,7 @@ */ uw.ui.Step.prototype.load = function ( uploads ) { // eslint-disable-next-line no-jquery/no-global-selector - var offset = $( 'h1' ).first().offset(); + const offset = $( 'h1' ).first().offset(); this.movedFrom = false; @@ -88,17 +88,17 @@ * Add a 'next' button to the step's button container */ uw.ui.Step.prototype.addNextButton = function () { - var ui = this; + const ui = this; this.nextButton = new OO.ui.ButtonWidget( { classes: [ 'mediauploader-button-next' ], label: mw.message( 'mediauploader-next' ).text(), flags: [ 'progressive', 'primary' ] - } ).on( 'click', function () { + } ).on( 'click', () => { ui.emit( 'next-step' ); } ); - this.nextButtonPromise.done( function () { + this.nextButtonPromise.done( () => { ui.$buttons.append( ui.nextButton.$element ); } ); }; @@ -107,16 +107,16 @@ * Add a 'previous' button to the step's button container */ uw.ui.Step.prototype.addPreviousButton = function () { - var ui = this; + const ui = this; this.previousButton = new OO.ui.ButtonWidget( { classes: [ 'mediauploader-button-previous' ], label: mw.message( 'mediauploader-previous' ).text() - } ).on( 'click', function () { + } ).on( 'click', () => { ui.emit( 'previous-step' ); } ); - this.previousButtonPromise.done( function () { + this.previousButtonPromise.done( () => { ui.$buttons.append( ui.previousButton.$element ); } ); }; diff --git a/resources/ui/uw.ui.Wizard.js b/resources/ui/uw.ui.Wizard.js index 804fbaa..5472285 100644 --- a/resources/ui/uw.ui.Wizard.js +++ b/resources/ui/uw.ui.Wizard.js @@ -46,7 +46,7 @@ */ uw.ui.Wizard.prototype.initHeader = function ( config ) { // eslint-disable-next-line no-jquery/no-global-selector - var $contentSub = $( '#contentSub' ); + const $contentSub = $( '#contentSub' ); if ( config.alternativeUploadToolsPage ) { this.$alternativeUploads = $( '<a>' ) @@ -72,7 +72,7 @@ * @param {Object|string} configAltUploadForm A link or map of languages to links, pointing at an alternate form. */ uw.ui.Wizard.prototype.initAltUploadForm = function ( configAltUploadForm ) { - var altUploadForm, userLanguage, title; + let altUploadForm, userLanguage, title; if ( typeof configAltUploadForm === 'object' ) { userLanguage = mw.config.get( 'wgUserLanguage' ); @@ -108,13 +108,13 @@ * @param {uw.controller.Step[]} steps */ uw.ui.Wizard.prototype.initialiseSteps = function ( steps ) { - var $steps = $( '<ul>' ) + const $steps = $( '<ul>' ) .attr( 'id', 'mediauploader-steps' ) .addClass( 'ui-helper-clearfix' ) .insertBefore( '#mediauploader-content' ); - steps.forEach( function ( step ) { - var $arrow = $( '<li>' ) + steps.forEach( ( step ) => { + const $arrow = $( '<li>' ) .attr( 'id', 'mediauploader-step-' + step.stepName ) .append( // Messages that can be used here: @@ -128,9 +128,9 @@ $steps.append( $arrow ); // once a (new) step loads, highlight it - step.on( 'load', function ( $arrow2 ) { + step.on( 'load', ( ( $arrow2 ) => { $steps.arrowStepsHighlight( $arrow2 ); - }.bind( step, $arrow ) ); + } ).bind( step, $arrow ) ); } ); $steps.arrowSteps(); diff --git a/resources/uw.ConcurrentQueue.js b/resources/uw.ConcurrentQueue.js index 2ec018f..48383eb 100644 --- a/resources/uw.ConcurrentQueue.js +++ b/resources/uw.ConcurrentQueue.js @@ -70,7 +70,7 @@ * @return {boolean} Whether the item was removed */ uw.ConcurrentQueue.prototype.removeItem = function ( item ) { - var index, found; + let index, found; found = false; @@ -113,7 +113,7 @@ * @param {Object} item */ uw.ConcurrentQueue.prototype.promiseComplete = function ( item ) { - var index; + let index; index = this.running.indexOf( item ); // Check that this item wasn't removed while it was being executed if ( index !== -1 ) { @@ -132,7 +132,7 @@ * @private */ uw.ConcurrentQueue.prototype.executeNext = function () { - var item, promise; + let item, promise; if ( this.running.length === this.count || !this.executing ) { return; } @@ -153,7 +153,7 @@ * When the queue finishes executing, a 'complete' event will be emitted. */ uw.ConcurrentQueue.prototype.startExecuting = function () { - var i; + let i; if ( this.executing ) { return; } diff --git a/resources/uw.CopyMetadataWidget.js b/resources/uw.CopyMetadataWidget.js index 784aab0..5fa1180 100644 --- a/resources/uw.CopyMetadataWidget.js +++ b/resources/uw.CopyMetadataWidget.js @@ -10,7 +10,7 @@ * @cfg {mw.UploadWizardUpload[]} copyTo Uploads to copy the details to */ uw.CopyMetadataWidget = function UWCopyMetadataWidget( config ) { - var metadataType, defaultStatus, copyMetadataMsg, + let metadataType, defaultStatus, copyMetadataMsg, checkboxes = [], $copyMetadataWrapperDiv = $( '<div>' ), $copyMetadataDiv = $( '<div>' ); @@ -118,7 +118,7 @@ * @private */ uw.CopyMetadataWidget.prototype.onCopyClick = function () { - var metadataTypes = this.checkboxesWidget.findSelectedItemsData(); + const metadataTypes = this.checkboxesWidget.findSelectedItemsData(); this.copyMetadata( metadataTypes ); this.undoButton.toggle( true ); @@ -153,7 +153,7 @@ * @param {string[]} metadataTypes Types to copy, as defined in the copyMetadataTypes property */ uw.CopyMetadataWidget.prototype.copyMetadata = function ( metadataTypes ) { - var titleZero, matches, i, + let titleZero, matches, i, uploads = this.copyTo, sourceUpload = this.copyFrom, serialized = sourceUpload.details.getSerialized(), @@ -164,7 +164,7 @@ copyingOther = false; // Filter serialized data to only the types we want to copy - metadataTypes.forEach( function ( type ) { + metadataTypes.forEach( ( type ) => { sourceValue[ type ] = serialized[ type ]; copyingTitle = copyingTitle || type === 'title'; copyingOther = copyingOther || type === 'other'; @@ -193,8 +193,8 @@ // numbers. sourceValue.title.title = titleZero.replace( /(\D+)(\d{1,3})(\D*)$/, // eslint-disable-next-line no-loop-func - function ( str, m1, m2, m3 ) { - var newstr = String( +m2 + i ); + ( str, m1, m2, m3 ) => { + const newstr = String( +m2 + i ); return m1 + new Array( m2.length + 1 - newstr.length ) .join( '0' ) + newstr + m3; } @@ -210,7 +210,7 @@ * Restore previously saved metadata that we backed up when copying. */ uw.CopyMetadataWidget.prototype.restoreMetadata = function () { - var i, + let i, uploads = this.copyTo; for ( i = 0; i < uploads.length; i++ ) { diff --git a/resources/uw.FieldLayout.js b/resources/uw.FieldLayout.js index 8d52198..7c5f4a5 100644 --- a/resources/uw.FieldLayout.js +++ b/resources/uw.FieldLayout.js @@ -16,7 +16,7 @@ // FieldLayout will add an icon which, when clicked, reveals more information // about the input. We'll want to display that by default, so we're getting // rid of the "help" property here & will later append that after the header - var help = config && config.help ? config.help : ''; + const help = config && config.help ? config.help : ''; config = Object.assign( { align: 'top', required: false }, config, { help: '' } ); uw.FieldLayout.parent.call( this, fieldWidget, config ); diff --git a/resources/uw.LicenseGroup.js b/resources/uw.LicenseGroup.js index c5d4f6f..5277ac0 100644 --- a/resources/uw.LicenseGroup.js +++ b/resources/uw.LicenseGroup.js @@ -22,7 +22,7 @@ * @param {number} count Number of the things we are licensing (it matters to some texts) */ uw.LicenseGroup = function UWLicenseGroup( config, type, api, count ) { - var self = this; + const self = this; uw.LicenseGroup.parent.call( this, {} ); @@ -30,7 +30,7 @@ throw new Error( 'improper license config' ); } - if ( [ 'radio', 'checkbox' ].indexOf( type ) < 0 ) { + if ( ![ 'radio', 'checkbox' ].includes( type ) ) { throw new Error( 'Invalid type: ' + type ); } @@ -58,12 +58,12 @@ } // when selecting an item that has a custom textarea, we'll immediately focus it - this.on( 'change', function ( group, item ) { + this.on( 'change', ( group, item ) => { if ( item && item.isSelected && item.isSelected() ) { // wrapped inside setTimeout to ensure it goes at the end of the call stack, // just in case something steals focus in the meantime... - setTimeout( function () { - var name = item.getData(); + setTimeout( () => { + const name = item.getData(); if ( self.textareas[ name ] ) { self.textareas[ name ].focus(); } @@ -86,7 +86,7 @@ */ uw.LicenseGroup.prototype.createFieldset = function ( group ) { /* eslint-disable mediawiki/msg-doc */ - var $head = this.config.head && $( '<a>' ) + const $head = this.config.head && $( '<a>' ) .addClass( 'mediauploader-deed-license-group-head' ) .msg( this.config.head, this.count ) .prepend( $( '<span>' ).addClass( 'mw-toggle-icon' ) ), @@ -118,11 +118,11 @@ * @return {OO.ui.RadioSelectWidget} */ uw.LicenseGroup.prototype.createRadioGroup = function ( classes ) { - var self = this, + const self = this, options = []; - this.config.licenses.forEach( function ( licenseName ) { - var option; + this.config.licenses.forEach( ( licenseName ) => { + let option; if ( mw.UploadWizard.config.licenses[ licenseName ] === undefined ) { // unknown license @@ -136,7 +136,7 @@ // when custom text area receives focus, we should make sure this element is selected if ( self.textareas[ licenseName ] ) { - self.textareas[ licenseName ].on( 'focus', function () { + self.textareas[ licenseName ].on( 'focus', () => { option.setSelected( true ); } ); } @@ -153,11 +153,11 @@ * @return {OO.ui.CheckboxMultiselectInputWidget} */ uw.LicenseGroup.prototype.createCheckboxGroup = function ( classes ) { - var self = this, + const self = this, options = []; - this.config.licenses.forEach( function ( licenseName ) { - var option; + this.config.licenses.forEach( ( licenseName ) => { + let option; if ( mw.UploadWizard.config.licenses[ licenseName ] === undefined ) { // unknown license @@ -171,7 +171,7 @@ // when custom text area receives focus, we should make sure this element is selected if ( self.textareas[ licenseName ] ) { - self.textareas[ licenseName ].on( 'focus', function () { + self.textareas[ licenseName ].on( 'focus', () => { option.setSelected( true ); } ); } @@ -187,12 +187,12 @@ * @return {string} */ uw.LicenseGroup.prototype.getWikiText = function () { - var wikiTexts, + let wikiTexts, self = this, values = this.getValue(); - wikiTexts = Object.keys( values ).map( function ( name ) { - var wikiText = self.getLicenseWikiText( name ), + wikiTexts = Object.keys( values ).map( ( name ) => { + let wikiText = self.getLicenseWikiText( name ), value = values[ name ]; if ( typeof value === 'string' ) { // `value` is custom input @@ -219,7 +219,7 @@ * @return {Object} Map of { licenseName: true }, or { licenseName: "custom input" } */ uw.LicenseGroup.prototype.getValue = function () { - var self = this, + let self = this, result = {}, selected, name; @@ -232,7 +232,7 @@ } } else if ( this.type === 'checkbox' ) { selected = this.group.findSelectedItems(); - selected.forEach( function ( item ) { + selected.forEach( ( item ) => { name = item.getData(); result[ name ] = !self.textareas[ name ] || self.textareas[ name ].getValue(); } ); @@ -245,12 +245,12 @@ * @param {Object} values Map of { licenseName: true }, or { licenseName: "custom input" } */ uw.LicenseGroup.prototype.setValue = function ( values ) { - var self = this, + let self = this, selectArray = [], selected; - Object.keys( values ).forEach( function ( name ) { - var value = values[ name ]; + Object.keys( values ).forEach( ( name ) => { + const value = values[ name ]; if ( typeof value === 'string' && self.textareas[ name ] ) { self.textareas[ name ].setValue( value ); // add to list of items to select @@ -300,7 +300,7 @@ * @return {string} of wikitext */ uw.LicenseGroup.prototype.getLicenseWikiText = function ( name ) { - var licenseInfo = this.getLicenseInfo( name ), + let licenseInfo = this.getLicenseInfo( name ), licenseText; licenseText = licenseInfo.props.wikitext !== undefined ? @@ -316,7 +316,7 @@ * @return {jQuery} */ uw.LicenseGroup.prototype.createLabel = function ( name ) { - var licenseInfo = this.getLicenseInfo( name ), + let licenseInfo = this.getLicenseInfo( name ), messageKey = licenseInfo.props.msg === undefined ? '[missing msg for ' + licenseInfo.name + ']' : licenseInfo.props.msg, @@ -333,7 +333,7 @@ } $licenseLink = $( '<a>' ).attr( { target: '_blank', href: licenseURL } ); if ( licenseInfo.props.icons !== undefined ) { - licenseInfo.props.icons.forEach( function ( icon ) { + licenseInfo.props.icons.forEach( ( icon ) => { // eslint-disable-next-line mediawiki/class-doc $icons.append( $( '<span>' ).addClass( 'mediauploader-license-icon mediauploader-' + icon + '-icon' ) ); } ); @@ -358,7 +358,7 @@ * @return {jQuery} Wrapped textarea */ uw.LicenseGroup.prototype.createCustom = function ( name, defaultText ) { - var self = this, + let self = this, button; this.textareas[ name ] = new OO.ui.MultilineTextInputWidget( { @@ -372,7 +372,7 @@ button = new OO.ui.ButtonWidget( { label: mw.message( 'mediauploader-license-custom-preview' ).text(), flags: [ 'progressive' ] - } ).on( 'click', function () { + } ).on( 'click', () => { self.showPreview( self.textareas[ name ].getValue() ); } ); @@ -389,7 +389,7 @@ * @param {string} wikiText */ uw.LicenseGroup.prototype.showPreview = function ( wikiText ) { - var input; + let input; this.previewDialog.setLoading( true ); this.windowManager.openWindow( this.previewDialog ); @@ -402,7 +402,7 @@ } function error( code, result ) { - var message = result.errors[ 0 ].html; + const message = result.errors[ 0 ].html; show( $( '<div>' ).append( $( '<h3>' ).append( code ), diff --git a/resources/uw.LicensePreviewDialog.js b/resources/uw.LicensePreviewDialog.js index 133d1b5..08f5231 100644 --- a/resources/uw.LicensePreviewDialog.js +++ b/resources/uw.LicensePreviewDialog.js @@ -7,7 +7,7 @@ uw.LicensePreviewDialog.static.name = 'licensePreviewDialog'; uw.LicensePreviewDialog.prototype.initialize = function () { - var dialog = this; + const dialog = this; uw.LicensePreviewDialog.parent.prototype.initialize.call( this ); @@ -16,7 +16,7 @@ this.$spinner = $.createSpinner( { size: 'large', type: 'block' } ) .css( { width: 200, padding: 20, float: 'none', margin: '0 auto' } ); - $( document.body ).on( 'click', function ( e ) { + $( document.body ).on( 'click', ( e ) => { if ( !$.contains( dialog.$body.get( 0 ), e.target ) ) { dialog.close(); } @@ -24,12 +24,12 @@ }; uw.LicensePreviewDialog.prototype.addCloseButton = function () { - var dialog = this, + const dialog = this, closeButton = new OO.ui.ButtonWidget( { label: OO.ui.msg( 'ooui-dialog-process-dismiss' ) } ); - closeButton.on( 'click', function () { + closeButton.on( 'click', () => { dialog.close(); } ); diff --git a/resources/uw.ValidationMessageElement.js b/resources/uw.ValidationMessageElement.js index 1a50d13..72c5e89 100644 --- a/resources/uw.ValidationMessageElement.js +++ b/resources/uw.ValidationMessageElement.js @@ -43,7 +43,7 @@ * @return {jQuery.Promise} */ uw.ValidationMessageElement.prototype.checkValidity = function ( thorough ) { - var element = this; + const element = this; thorough = thorough || false; if ( !this.validatedWidget.getWarnings || !this.validatedWidget.getErrors ) { @@ -57,13 +57,13 @@ return $.when( this.validatedWidget.getWarnings( thorough ), this.validatedWidget.getErrors( thorough ) - ).then( function ( warnings, errors ) { + ).then( ( warnings, errors ) => { // this.notices and this.errors are arrays of mw.Messages and not strings in this subclass element.setNotices( warnings ); element.setErrors( errors ); return $.Deferred().resolve( warnings, errors ).promise(); - } ).always( function () { + } ).always( () => { if ( element.validatedWidget.popPending ) { element.validatedWidget.popPending(); } @@ -77,7 +77,7 @@ * @return {jQuery} */ uw.ValidationMessageElement.prototype.makeMessage = function ( kind, error ) { - var code, $content, $listItem; + let code, $content, $listItem; if ( error.parseDom ) { // mw.Message object code = error.key; diff --git a/resources/uw.units.js b/resources/uw.units.js index 9720982..f36f63c 100644 --- a/resources/uw.units.js +++ b/resources/uw.units.js @@ -1,6 +1,6 @@ ( function ( uw ) { - var scaleMsgKeys = [ 'size-bytes', 'size-kilobytes', 'size-megabytes', 'size-gigabytes' ]; + const scaleMsgKeys = [ 'size-bytes', 'size-kilobytes', 'size-megabytes', 'size-gigabytes' ]; uw.units = { /** @@ -13,7 +13,7 @@ * @return {string} formatted size */ bytes: function ( size ) { - var i = 0; + let i = 0; while ( size >= 1024 && i < scaleMsgKeys.length - 1 ) { size /= 1024.0; i++; diff --git a/tests/qunit/.eslintrc.json b/tests/qunit/.eslintrc.json index a4f3832..f2a8a28 100644 --- a/tests/qunit/.eslintrc.json +++ b/tests/qunit/.eslintrc.json @@ -5,5 +5,9 @@ ], "globals": { "sinon": false + }, + "rules": { + "no-jquery/no-done-fail": "warn", + "prefer-const": "warn" } } diff --git a/tests/qunit/controller/uw.controller.Deed.test.js b/tests/qunit/controller/uw.controller.Deed.test.js index fa5b40c..98b5cbb 100644 --- a/tests/qunit/controller/uw.controller.Deed.test.js +++ b/tests/qunit/controller/uw.controller.Deed.test.js @@ -18,15 +18,15 @@ ( function ( uw ) { QUnit.module( 'uw.controller.Deed', QUnit.newMwEnvironment() ); - QUnit.test( 'Constructor sanity test', function ( assert ) { - var step = new uw.controller.Deed(); + QUnit.test( 'Constructor sanity test', ( assert ) => { + const step = new uw.controller.Deed(); assert.true( !!step ); assert.true( step instanceof uw.controller.Step ); assert.true( !!step.ui ); } ); QUnit.test( 'load', function ( assert ) { - var step = new uw.controller.Deed( + const step = new uw.controller.Deed( new mw.Api(), { licensing: { enabled: true, diff --git a/tests/qunit/controller/uw.controller.Details.test.js b/tests/qunit/controller/uw.controller.Details.test.js index 689c5f7..7b6a5d9 100644 --- a/tests/qunit/controller/uw.controller.Details.test.js +++ b/tests/qunit/controller/uw.controller.Details.test.js @@ -19,7 +19,7 @@ QUnit.module( 'uw.controller.Details', QUnit.newMwEnvironment() ); function createTestUpload( sandbox, customDeedChooser, aborted ) { - var stubs = { + const stubs = { ucdc: sandbox.stub(), getSerialized: sandbox.stub(), setSerialized: sandbox.stub(), @@ -44,8 +44,8 @@ }; } - QUnit.test( 'Constructor sanity test', function ( assert ) { - var step = new uw.controller.Details( new mw.Api(), { + QUnit.test( 'Constructor sanity test', ( assert ) => { + const step = new uw.controller.Details( new mw.Api(), { maxSimultaneousConnections: 1 } ); assert.true( !!step ); @@ -54,7 +54,7 @@ } ); QUnit.test( 'load', function ( assert ) { - var step = new uw.controller.Details( new mw.Api(), { + let step = new uw.controller.Details( new mw.Api(), { maxSimultaneousConnections: 1 } ), testUpload = createTestUpload( this.sandbox ), @@ -92,8 +92,8 @@ assert.true( stepUiStub.called ); } ); - QUnit.test( 'canTransition', function ( assert ) { - var upload = {}, + QUnit.test( 'canTransition', ( assert ) => { + const upload = {}, step = new uw.controller.Details( new mw.Api(), { maxSimultaneousConnections: 1 } ); @@ -106,7 +106,7 @@ } ); QUnit.test( 'transitionAll', function ( assert ) { - var tostub, + let tostub, done = assert.async(), donestub = this.sandbox.stub(), ds = [ $.Deferred(), $.Deferred(), $.Deferred() ], @@ -133,7 +133,7 @@ ]; step.transitionAll().done( donestub ); - setTimeout( function () { + setTimeout( () => { calls = [ tostub.getCall( 0 ), tostub.getCall( 1 ), tostub.getCall( 2 ) ]; assert.strictEqual( calls[ 0 ].args[ 0 ].id, 15 ); @@ -141,11 +141,11 @@ ds[ 0 ].resolve(); ds[ 1 ].resolve(); - setTimeout( function () { + setTimeout( () => { assert.strictEqual( donestub.called, false ); ds[ 2 ].resolve(); - setTimeout( function () { + setTimeout( () => { assert.true( donestub.called ); done(); diff --git a/tests/qunit/controller/uw.controller.Step.test.js b/tests/qunit/controller/uw.controller.Step.test.js index a30f7ae..17a5901 100644 --- a/tests/qunit/controller/uw.controller.Step.test.js +++ b/tests/qunit/controller/uw.controller.Step.test.js @@ -18,8 +18,8 @@ ( function ( uw ) { QUnit.module( 'uw.controller.Step', QUnit.newMwEnvironment() ); - QUnit.test( 'Constructor sanity test', function ( assert ) { - var step = new uw.controller.Step( { on: function () {} }, new mw.Api(), {} ); + QUnit.test( 'Constructor sanity test', ( assert ) => { + const step = new uw.controller.Step( { on: function () {} }, new mw.Api(), {} ); assert.true( !!step ); assert.true( !!step.ui ); } ); diff --git a/tests/qunit/controller/uw.controller.Thanks.test.js b/tests/qunit/controller/uw.controller.Thanks.test.js index c19f4d5..0929619 100644 --- a/tests/qunit/controller/uw.controller.Thanks.test.js +++ b/tests/qunit/controller/uw.controller.Thanks.test.js @@ -18,15 +18,15 @@ ( function ( uw ) { QUnit.module( 'uw.controller.Thanks', QUnit.newMwEnvironment() ); - QUnit.test( 'Constructor sanity test', function ( assert ) { - var step = new uw.controller.Thanks( new mw.Api(), { display: { thanksLabel: 'Thanks!' } } ); + QUnit.test( 'Constructor sanity test', ( assert ) => { + const step = new uw.controller.Thanks( new mw.Api(), { display: { thanksLabel: 'Thanks!' } } ); assert.true( !!step ); assert.true( step instanceof uw.controller.Step ); assert.true( !!step.ui ); } ); QUnit.test( 'load', function ( assert ) { - var step = new uw.controller.Thanks( new mw.Api(), {} ), + const step = new uw.controller.Thanks( new mw.Api(), {} ), auStub = this.sandbox.stub( step.ui, 'addUpload' ); this.sandbox.stub( step.ui, 'load' ); @@ -39,8 +39,8 @@ assert.strictEqual( auStub.callCount, 3 ); } ); - QUnit.test( 'Custom button configuration', function ( assert ) { - var config = { + QUnit.test( 'Custom button configuration', ( assert ) => { + const config = { display: { homeButton: { label: 'This is just a test', diff --git a/tests/qunit/controller/uw.controller.Tutorial.test.js b/tests/qunit/controller/uw.controller.Tutorial.test.js index 2a780a4..86122c1 100644 --- a/tests/qunit/controller/uw.controller.Tutorial.test.js +++ b/tests/qunit/controller/uw.controller.Tutorial.test.js @@ -18,8 +18,8 @@ ( function ( uw ) { QUnit.module( 'uw.controller.Tutorial', QUnit.newMwEnvironment() ); - QUnit.test( 'Constructor sanity test', function ( assert ) { - var step = new uw.controller.Tutorial( new mw.Api() ); + QUnit.test( 'Constructor sanity test', ( assert ) => { + const step = new uw.controller.Tutorial( new mw.Api() ); assert.true( !!step ); assert.true( step instanceof uw.controller.Step ); assert.true( !!step.ui ); @@ -27,7 +27,7 @@ } ); QUnit.test( 'setSkipPreference', function ( assert ) { - var mnStub, + let mnStub, api = new mw.Api(), step = new uw.controller.Tutorial( api ), acwStub = { release: this.sandbox.stub() }, diff --git a/tests/qunit/controller/uw.controller.Upload.test.js b/tests/qunit/controller/uw.controller.Upload.test.js index 4cd12dd..09febdd 100644 --- a/tests/qunit/controller/uw.controller.Upload.test.js +++ b/tests/qunit/controller/uw.controller.Upload.test.js @@ -18,8 +18,8 @@ ( function ( uw ) { QUnit.module( 'uw.controller.Upload', QUnit.newMwEnvironment() ); - QUnit.test( 'Constructor sanity test', function ( assert ) { - var step = new uw.controller.Upload( new mw.Api(), { + QUnit.test( 'Constructor sanity test', ( assert ) => { + const step = new uw.controller.Upload( new mw.Api(), { maxUploads: 10, maxSimultaneousConnections: 3 } ); @@ -29,7 +29,7 @@ } ); QUnit.test( 'updateFileCounts', function ( assert ) { - var step = new uw.controller.Upload( new mw.Api(), { + const step = new uw.controller.Upload( new mw.Api(), { maxUploads: 5, maxSimultaneousConnections: 3 } ), @@ -50,8 +50,8 @@ assert.true( ufcStub.calledWith( true, false ) ); } ); - QUnit.test( 'canTransition', function ( assert ) { - var upload = {}, + QUnit.test( 'canTransition', ( assert ) => { + const upload = {}, step = new uw.controller.Upload( new mw.Api(), { maxSimultaneousConnections: 1 } ); @@ -64,7 +64,7 @@ } ); QUnit.test( 'transitionOne', function ( assert ) { - var upload = { + const upload = { start: this.sandbox.stub() }, step = new uw.controller.Upload( new mw.Api(), { diff --git a/tests/qunit/mw.UploadWizardLicenseInput.test.js b/tests/qunit/mw.UploadWizardLicenseInput.test.js index f135b4b..2f84303 100644 --- a/tests/qunit/mw.UploadWizardLicenseInput.test.js +++ b/tests/qunit/mw.UploadWizardLicenseInput.test.js @@ -13,8 +13,8 @@ QUnit.module( 'ext.uploadWizardLicenseInput', QUnit.newMwEnvironment( { } } ) ); -QUnit.test( 'Smoke test', function ( assert ) { - var config = { type: 'radio', licenses: [] }, +QUnit.test( 'Smoke test', ( assert ) => { + let config = { type: 'radio', licenses: [] }, $fixture = $( '<div>' ), uwLicenseInput; @@ -23,8 +23,8 @@ QUnit.test( 'Smoke test', function ( assert ) { assert.true( !!uwLicenseInput, 'LicenseInput object created !' ); } ); -QUnit.test( 'createInputs()', function ( assert ) { - var config = { type: 'radio', licenses: [ 'cc-by-sa-3.0' ] }, +QUnit.test( 'createInputs()', ( assert ) => { + let config = { type: 'radio', licenses: [ 'cc-by-sa-3.0' ] }, $fixture = $( '<div>' ), uwLicenseInput, $input, @@ -42,8 +42,8 @@ QUnit.test( 'createInputs()', function ( assert ) { assert.strictEqual( $label.length, 1, 'Label created.' ); } ); -QUnit.test( 'createGroupedInputs()', function ( assert ) { - var config = { +QUnit.test( 'createGroupedInputs()', ( assert ) => { + let config = { type: 'checkbox', licenseGroups: [ { diff --git a/tests/qunit/mw.UploadWizardUpload.test.js b/tests/qunit/mw.UploadWizardUpload.test.js index ad76777..0d7673d 100644 --- a/tests/qunit/mw.UploadWizardUpload.test.js +++ b/tests/qunit/mw.UploadWizardUpload.test.js @@ -19,7 +19,7 @@ QUnit.module( 'mw.UploadWizardUpload', QUnit.newMwEnvironment() ); function createUpload( filename ) { - var upload, + let upload, oldconf = mw.UploadWizard.config; mw.UploadWizard.config = {}; @@ -39,14 +39,14 @@ return upload; } - QUnit.test( 'constructor sanity test', function ( assert ) { - var upload = createUpload(); + QUnit.test( 'constructor sanity test', ( assert ) => { + const upload = createUpload(); assert.true( !!upload ); } ); - QUnit.test( 'getBasename', function ( assert ) { - var upload; + QUnit.test( 'getBasename', ( assert ) => { + let upload; upload = createUpload( 'path/to/filename.png' ); assert.strictEqual( upload.getBasename(), 'filename.png', 'Path is stripped' ); diff --git a/tests/qunit/mw.fileApi.test.js b/tests/qunit/mw.fileApi.test.js index 9405e7c..cde0c62 100644 --- a/tests/qunit/mw.fileApi.test.js +++ b/tests/qunit/mw.fileApi.test.js @@ -19,7 +19,7 @@ QUnit.module( 'mw.fileApi', QUnit.newMwEnvironment() ); QUnit.test( 'isPreviewableFile', function ( assert ) { - var testFile = {}; + const testFile = {}; testFile.type = 'image/png'; testFile.size = 5 * 1024 * 1024; @@ -43,7 +43,7 @@ } ); QUnit.test( 'isPreviewableVideo', function ( assert ) { - var result, testFile = {}, + let result, testFile = {}, fakeVideo = { canPlayType: this.sandbox.stub().returns( 'yes' ) }; diff --git a/tests/qunit/transports/mw.FormDataTransport.test.js b/tests/qunit/transports/mw.FormDataTransport.test.js index 76b9c4b..f6c3a87 100644 --- a/tests/qunit/transports/mw.FormDataTransport.test.js +++ b/tests/qunit/transports/mw.FormDataTransport.test.js @@ -19,7 +19,7 @@ QUnit.module( 'mw.FormDataTransport', QUnit.newMwEnvironment() ); function createTransport( chunkSize, api ) { - var config; + let config; chunkSize = chunkSize || 0; api = api || {}; @@ -33,14 +33,14 @@ return new mw.FormDataTransport( api, {}, config ); } - QUnit.test( 'Constructor sanity test', function ( assert ) { - var transport = createTransport(); + QUnit.test( 'Constructor sanity test', ( assert ) => { + const transport = createTransport(); assert.true( !!transport ); } ); QUnit.test( 'abort', function ( assert ) { - var transport = createTransport( 0 ), + const transport = createTransport( 0 ), request = $.Deferred().promise( { abort: this.sandbox.stub() } ); transport.request = request; @@ -53,8 +53,8 @@ assert.true( transport.aborted ); } ); - QUnit.test( 'createParams', function ( assert ) { - var transport = createTransport( 10 ), + QUnit.test( 'createParams', ( assert ) => { + const transport = createTransport( 10 ), params = transport.createParams( 'foobar.jpg', 0 ); assert.true( !!params ); @@ -64,7 +64,7 @@ } ); QUnit.test( 'post', function ( assert ) { - var stub = this.sandbox.stub(), + const stub = this.sandbox.stub(), // post() works on a promise and binds .then, so we have to make // sure it actually is a promise, but also that it calls our stub transport = createTransport( 10, { post: function () { @@ -82,7 +82,7 @@ } ); QUnit.test( 'upload', function ( assert ) { - var request, + let request, transport = createTransport( 10, new mw.Api() ), fakeFile = { name: 'test file for fdt.jpg', @@ -103,7 +103,7 @@ } ); QUnit.test( 'uploadChunk', function ( assert ) { - var request, + let request, transport = createTransport( 10, new mw.Api() ), fakeFile = { name: 'test file for fdt.jpg', @@ -132,7 +132,7 @@ // test invalid server response (in missing 'stage' param) QUnit.test( 'checkStatus invalid API response', function ( assert ) { - var done = assert.async(), + const done = assert.async(), transport = createTransport( 10, new mw.Api() ), tstub = this.sandbox.stub(), poststub = this.sandbox.stub( transport.api, 'post' ), @@ -143,7 +143,7 @@ postd.resolve( { upload: { result: 'Poll' } } ); // call tstub upon checkStatus failure, and verify it got called correctly - transport.checkStatus().fail( tstub, function () { + transport.checkStatus().fail( tstub, () => { assert.true( tstub.calledWith( 'server-error', { errors: [ { code: 'server-error', html: mw.message( 'api-clientside-error-invalidresponse' ).parse() @@ -154,7 +154,7 @@ // test retry after server responds upload is still incomplete QUnit.test( 'checkStatus retry', function ( assert ) { - var transport = createTransport( 10, new mw.Api() ), + const transport = createTransport( 10, new mw.Api() ), usstub = this.sandbox.stub(), poststub = this.sandbox.stub( transport.api, 'post' ), postd = $.Deferred(), @@ -176,14 +176,14 @@ // confirm that, once second API call was successful, status resolves, // 2 API calls have gone out & the failed call updates stage accordingly - return transport.checkStatus().done( function () { + return transport.checkStatus().done( () => { assert.true( poststub.calledTwice ); assert.true( usstub.firstCall.calledWith( 'queued' ) ); } ); } ); QUnit.test( 'checkStatus success', function ( assert ) { - var transport = createTransport( 10, new mw.Api() ), + const transport = createTransport( 10, new mw.Api() ), tstub = this.sandbox.stub(), usstub = this.sandbox.stub(), poststub = this.sandbox.stub( transport.api, 'post' ), @@ -195,14 +195,14 @@ poststub.returns( postd.promise() ); postd.resolve( 'testing' ); - return transport.checkStatus().done( tstub, function () { + return transport.checkStatus().done( tstub, () => { assert.true( tstub.calledWith( 'testing' ) ); assert.false( usstub.called ); } ); } ); QUnit.test( 'checkStatus error API response', function ( assert ) { - var done = assert.async(), + const done = assert.async(), transport = createTransport( 10, new mw.Api() ), tstub = this.sandbox.stub(), usstub = this.sandbox.stub(), @@ -215,7 +215,7 @@ poststub.returns( postd.promise() ); postd.reject( 'testing', { error: 'testing' } ); - transport.checkStatus().fail( tstub, function () { + transport.checkStatus().fail( tstub, () => { assert.true( tstub.calledWith( 'testing', { error: 'testing' } ) ); assert.false( usstub.called ); done(); diff --git a/tests/qunit/uw.ConcurrentQueue.test.js b/tests/qunit/uw.ConcurrentQueue.test.js index 2bf97e4..c288d3e 100644 --- a/tests/qunit/uw.ConcurrentQueue.test.js +++ b/tests/qunit/uw.ConcurrentQueue.test.js @@ -25,7 +25,7 @@ // trigger the next one to execute, which would terminate immediately, // instead of giving time for a second new thingy to be added) function queueAction() { - var deferred = $.Deferred(); + const deferred = $.Deferred(); setTimeout( deferred.resolve, 10 ); return deferred.promise(); } @@ -33,9 +33,9 @@ // Asserts that the given stub functions were called in the given order. // SinonJS's assert.callOrder doesn't allow to check individual calls. function assertCalledInOrder() { - var calls, i, currSpyCall, nextSpyCall; + let calls, i, currSpyCall, nextSpyCall; // Map stubs to specific calls - calls = Array.prototype.map.call( arguments, function ( spy ) { + calls = Array.prototype.map.call( arguments, ( spy ) => { if ( !spy.assertCallsInOrderLastCall ) { spy.assertCallsInOrderLastCall = 0; } @@ -60,8 +60,8 @@ ); } - QUnit.test( 'Basic behavior', function ( assert ) { - var done, action, queue; + QUnit.test( 'Basic behavior', ( assert ) => { + let done, action, queue; done = assert.async(); action = sinon.spy( queueAction ); queue = new uw.ConcurrentQueue( { @@ -69,11 +69,11 @@ action: action } ); - queue.on( 'progress', function () { + queue.on( 'progress', () => { QUnit.assert.true( queue.running.length <= 3, 'No more than 3 items are executing' ); } ); - queue.on( 'complete', function () { + queue.on( 'complete', () => { // All items executed sinon.assert.callCount( action, 5 ); // All items executed in the expected order @@ -86,15 +86,15 @@ done(); } ); - [ 'a', 'b', 'c', 'd', 'e' ].forEach( function ( v ) { + [ 'a', 'b', 'c', 'd', 'e' ].forEach( ( v ) => { queue.addItem( v ); } ); queue.startExecuting(); } ); - QUnit.test( 'Event emitting', function ( assert ) { - var done, changeHandler, progressHandler, completeHandler, queue; + QUnit.test( 'Event emitting', ( assert ) => { + let done, changeHandler, progressHandler, completeHandler, queue; done = assert.async(); changeHandler = sinon.stub(); progressHandler = sinon.stub(); @@ -110,7 +110,7 @@ complete: completeHandler } ); - queue.on( 'complete', function () { + queue.on( 'complete', () => { sinon.assert.callCount( changeHandler, 3 ); sinon.assert.callCount( progressHandler, 3 ); sinon.assert.callCount( completeHandler, 1 ); @@ -134,8 +134,8 @@ queue.startExecuting(); } ); - QUnit.test( 'Restarting a completed queue', function ( assert ) { - var done, queue; + QUnit.test( 'Restarting a completed queue', ( assert ) => { + let done, queue; done = assert.async(); queue = new uw.ConcurrentQueue( { count: 3, @@ -146,12 +146,12 @@ queue.addItem( 'b' ); queue.addItem( 'c' ); - queue.once( 'complete', function () { + queue.once( 'complete', () => { QUnit.assert.equal( queue.completed, true ); queue.addItem( 'd' ); queue.addItem( 'e' ); - queue.once( 'complete', function () { + queue.once( 'complete', () => { QUnit.assert.equal( queue.completed, true ); done(); } ); @@ -162,15 +162,15 @@ queue.startExecuting(); } ); - QUnit.test( 'Empty queue completes', function ( assert ) { - var done, queue; + QUnit.test( 'Empty queue completes', ( assert ) => { + let done, queue; done = assert.async(); queue = new uw.ConcurrentQueue( { count: 3, action: queueAction } ); - queue.on( 'complete', function () { + queue.on( 'complete', () => { QUnit.assert.equal( queue.completed, true ); done(); @@ -179,8 +179,8 @@ queue.startExecuting(); } ); - QUnit.test( 'Adding new items while queue running', function ( assert ) { - var done, changeHandler, progressHandler, completeHandler, queue; + QUnit.test( 'Adding new items while queue running', ( assert ) => { + let done, changeHandler, progressHandler, completeHandler, queue; done = assert.async(); changeHandler = sinon.stub(); progressHandler = sinon.stub(); @@ -196,7 +196,7 @@ complete: completeHandler } ); - queue.on( 'complete', function () { + queue.on( 'complete', () => { sinon.assert.callCount( changeHandler, 6 ); sinon.assert.callCount( progressHandler, 6 ); sinon.assert.callCount( completeHandler, 1 ); @@ -223,11 +223,11 @@ queue.addItem( 'a' ); queue.addItem( 'b' ); queue.addItem( 'c' ); - queue.once( 'progress', function () { + queue.once( 'progress', () => { queue.addItem( 'd' ); queue.addItem( 'e' ); } ); - queue.on( 'progress', function () { + queue.on( 'progress', () => { if ( queue.done.length === 5 ) { queue.addItem( 'f' ); } @@ -235,8 +235,8 @@ queue.startExecuting(); } ); - QUnit.test( 'Deleting items while queue running', function ( assert ) { - var done, changeHandler, progressHandler, completeHandler, queue; + QUnit.test( 'Deleting items while queue running', ( assert ) => { + let done, changeHandler, progressHandler, completeHandler, queue; done = assert.async(); changeHandler = sinon.stub(); progressHandler = sinon.stub(); @@ -252,7 +252,7 @@ complete: completeHandler } ); - queue.on( 'complete', function () { + queue.on( 'complete', () => { sinon.assert.callCount( changeHandler, 8 ); sinon.assert.callCount( progressHandler, 4 ); sinon.assert.callCount( completeHandler, 1 ); @@ -282,18 +282,18 @@ queue.addItem( 'd' ); queue.addItem( 'e' ); queue.addItem( 'f' ); - queue.once( 'progress', function () { + queue.once( 'progress', () => { queue.removeItem( queue.queued[ 0 ] ); - queue.once( 'progress', function () { + queue.once( 'progress', () => { queue.removeItem( queue.queued[ 0 ] ); } ); } ); queue.startExecuting(); } ); - QUnit.test( 'Deleting currently running item', function ( assert ) { - var done, action, changeHandler, progressHandler, completeHandler, queue; + QUnit.test( 'Deleting currently running item', ( assert ) => { + let done, action, changeHandler, progressHandler, completeHandler, queue; done = assert.async(); action = sinon.spy( queueAction ); changeHandler = sinon.stub(); @@ -310,7 +310,7 @@ complete: completeHandler } ); - queue.on( 'complete', function () { + queue.on( 'complete', () => { // Every item in the queue was executed... sinon.assert.callCount( action, 4 ); @@ -342,14 +342,14 @@ queue.addItem( 'b' ); queue.addItem( 'c' ); queue.addItem( 'd' ); - queue.once( 'progress', function () { + queue.once( 'progress', () => { queue.removeItem( queue.running[ 0 ] ); } ); queue.startExecuting(); } ); - QUnit.test( 'Adding a new item when almost done', function ( assert ) { - var done, action, changeHandler, progressHandler, completeHandler, queue, onProgress; + QUnit.test( 'Adding a new item when almost done', ( assert ) => { + let done, action, changeHandler, progressHandler, completeHandler, queue, onProgress; done = assert.async(); // This test seems extra flaky and was occasionally failing, double the delays action = sinon.spy( queueAction ); @@ -367,7 +367,7 @@ complete: completeHandler } ); - queue.on( 'complete', function () { + queue.on( 'complete', () => { sinon.assert.callCount( action, 5 ); sinon.assert.callCount( changeHandler, 5 ); sinon.assert.callCount( progressHandler, 5 ); diff --git a/tests/qunit/uw.TitleDetailsWidget.test.js b/tests/qunit/uw.TitleDetailsWidget.test.js index 8992c60..571ab1c 100644 --- a/tests/qunit/uw.TitleDetailsWidget.test.js +++ b/tests/qunit/uw.TitleDetailsWidget.test.js @@ -1,7 +1,7 @@ ( function ( uw ) { 'use strict'; - var fileNs, makeTitleInFileNSCases; + let fileNs, makeTitleInFileNSCases; fileNs = mw.config.get( 'wgFormattedNamespaces' )[ 6 ]; makeTitleInFileNSCases = [ { filename: 'foo.png', @@ -35,11 +35,11 @@ QUnit.module( 'uw.TitleDetailsWidget', QUnit.newMwEnvironment() ); - QUnit.test( '.static.makeTitleInFileNS()', function ( assert ) { - var makeTitleInFileNS = uw.TitleDetailsWidget.static.makeTitleInFileNS; + QUnit.test( '.static.makeTitleInFileNS()', ( assert ) => { + const makeTitleInFileNS = uw.TitleDetailsWidget.static.makeTitleInFileNS; - makeTitleInFileNSCases.forEach( function ( test ) { - var title = makeTitleInFileNS( test.filename ); + makeTitleInFileNSCases.forEach( ( test ) => { + const title = makeTitleInFileNS( test.filename ); assert.strictEqual( title ? title.getPrefixedText() : title, test.prefixedText, -- 2.39.5
$ date --- stdout --- Fri Jun 6 02:48:59 UTC 2025 --- end --- $ git clone file:///srv/git/mediawiki-extensions-MediaUploader.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 --- 058de7433f7a19034f35f1290ac44867f1318b58 refs/heads/master --- end --- $ /usr/bin/npm audit --json --- stdout --- { "auditReportVersion": 2, "vulnerabilities": { "cross-spawn": { "name": "cross-spawn", "severity": "high", "isDirect": false, "via": [ { "source": 1104664, "name": "cross-spawn", "dependency": "cross-spawn", "title": "Regular Expression Denial of Service (ReDoS) in cross-spawn", "url": "https://github.com/advisories/GHSA-3xgq-45jj-v275", "severity": "high", "cwe": [ "CWE-1333" ], "cvss": { "score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H" }, "range": ">=7.0.0 <7.0.5" } ], "effects": [], "range": "7.0.0 - 7.0.4", "nodes": [ "node_modules/cross-spawn" ], "fixAvailable": true }, "nanoid": { "name": "nanoid", "severity": "moderate", "isDirect": false, "via": [ { "source": 1101163, "name": "nanoid", "dependency": "nanoid", "title": "Predictable results in nanoid generation when given non-integer values", "url": "https://github.com/advisories/GHSA-mwcw-c2x4-8c55", "severity": "moderate", "cwe": [ "CWE-835" ], "cvss": { "score": 4.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N" }, "range": "<3.3.8" } ], "effects": [], "range": "<3.3.8", "nodes": [ "node_modules/nanoid" ], "fixAvailable": true } }, "metadata": { "vulnerabilities": { "info": 0, "low": 0, "moderate": 1, "high": 1, "critical": 0, "total": 2 }, "dependencies": { "prod": 1, "dev": 449, "optional": 0, "peer": 1, "peerOptional": 0, "total": 449 } } } --- 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: 40 installs, 0 updates, 0 removals - Locking composer/pcre (3.3.2) - Locking composer/semver (3.4.3) - Locking composer/spdx-licenses (1.5.9) - Locking composer/xdebug-handler (3.0.5) - Locking dealerdirect/phpcodesniffer-composer-installer (v1.0.0) - Locking doctrine/deprecations (1.1.5) - Locking felixfbecker/advanced-json-rpc (v3.2.1) - Locking justinrainbow/json-schema (5.3.0) - Locking mediawiki/mediawiki-codesniffer (v45.0.0) - Locking mediawiki/mediawiki-phan-config (0.15.1) - Locking mediawiki/minus-x (1.1.3) - Locking mediawiki/phan-taint-check-plugin (6.1.0) - Locking microsoft/tolerant-php-parser (v0.1.2) - Locking netresearch/jsonmapper (v4.5.0) - Locking phan/phan (5.4.5) - 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.2.1) - Locking phpcsstandards/phpcsutils (1.0.12) - Locking phpdocumentor/reflection-common (2.2.0) - Locking phpdocumentor/reflection-docblock (5.6.2) - Locking phpdocumentor/type-resolver (1.10.0) - Locking phpstan/phpdoc-parser (2.1.0) - Locking psr/container (2.0.2) - Locking psr/log (3.0.2) - Locking sabre/event (5.1.7) - Locking squizlabs/php_codesniffer (3.10.3) - Locking symfony/console (v7.3.0) - Locking symfony/deprecation-contracts (v3.6.0) - Locking symfony/polyfill-ctype (v1.32.0) - Locking symfony/polyfill-intl-grapheme (v1.32.0) - Locking symfony/polyfill-intl-normalizer (v1.32.0) - Locking symfony/polyfill-mbstring (v1.32.0) - Locking symfony/polyfill-php80 (v1.32.0) - Locking symfony/service-contracts (v3.6.0) - Locking symfony/string (v7.3.0) - Locking symfony/yaml (v5.4.45) - Locking tysonandre/var_representation_polyfill (0.1.3) - Locking webmozart/assert (1.11.0) Writing lock file Installing dependencies from lock file (including require-dev) Package operations: 40 installs, 0 updates, 0 removals 0 [>---------------------------] 0 [->--------------------------] - Installing squizlabs/php_codesniffer (3.10.3): Extracting archive - Installing dealerdirect/phpcodesniffer-composer-installer (v1.0.0): Extracting archive - Installing composer/pcre (3.3.2): Extracting archive - Installing justinrainbow/json-schema (5.3.0): Extracting archive - Installing symfony/polyfill-php80 (v1.32.0): Extracting archive - Installing phpcsstandards/phpcsutils (1.0.12): Extracting archive - Installing phpcsstandards/phpcsextra (1.2.1): Extracting archive - Installing symfony/polyfill-mbstring (v1.32.0): Extracting archive - Installing composer/spdx-licenses (1.5.9): Extracting archive - Installing composer/semver (3.4.3): Extracting archive - Installing mediawiki/mediawiki-codesniffer (v45.0.0): Extracting archive - Installing tysonandre/var_representation_polyfill (0.1.3): Extracting archive - Installing symfony/polyfill-intl-normalizer (v1.32.0): Extracting archive - Installing symfony/polyfill-intl-grapheme (v1.32.0): Extracting archive - Installing symfony/polyfill-ctype (v1.32.0): Extracting archive - Installing symfony/string (v7.3.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.0): Extracting archive - Installing symfony/console (v7.3.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.11.0): Extracting archive - Installing phpstan/phpdoc-parser (2.1.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.10.0): Extracting archive - Installing phpdocumentor/reflection-docblock (5.6.2): 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.4.5): Extracting archive - Installing mediawiki/phan-taint-check-plugin (6.1.0): Extracting archive - Installing mediawiki/mediawiki-phan-config (0.15.1): 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 - Installing symfony/yaml (v5.4.45): Extracting archive 0/38 [>---------------------------] 0% 20/38 [==============>-------------] 52% 32/38 [=======================>----] 84% 38/38 [============================] 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.28.2 -> 0.30.0 Upgrading n:stylelint-config-wikimedia from 0.17.2 -> 0.18.0 $ /usr/bin/npm install --- stdout --- added 438 packages, and audited 439 packages in 7s 97 packages are looking for funding run `npm fund` for details 1 high severity vulnerability To address all issues, run: npm audit fix Run `npm audit` for details. --- end --- $ package-lock-lint package-lock.json --- stdout --- Checking package-lock.json --- end --- $ /usr/bin/npm install grunt-eslint@24.3.0 --save-exact --- stdout --- up to date, audited 439 packages in 2s 97 packages are looking for funding run `npm fund` for details 1 high severity vulnerability To address all issues, run: npm audit fix Run `npm audit` for details. --- end --- $ package-lock-lint package-lock.json --- stdout --- Checking package-lock.json --- end --- $ ./node_modules/.bin/eslint . --fix --- stdout --- /src/repo/resources/controller/uw.controller.Deed.js 44:4 error 'deedController' is never reassigned. Use 'const' instead prefer-const 52:3 error 'valid' is never reassigned. Use 'const' instead prefer-const 57:4 error Mixed spaces and tabs no-mixed-spaces-and-tabs 57:6 error Expected no linebreak before this expression implicit-arrow-linebreak 58:3 error Mixed spaces and tabs no-mixed-spaces-and-tabs /src/repo/resources/controller/uw.controller.Details.js 65:4 error 'serialized' is never reassigned. Use 'const' instead prefer-const 96:4 error 'invalidStates' is never reassigned. Use 'const' instead prefer-const 97:4 error 'invalids' is never reassigned. Use 'const' instead prefer-const 98:4 error 'valids' is never reassigned. Use 'const' instead prefer-const 153:3 error Prefer .then to .done no-jquery/no-done-fail 238:4 error '$message' is never reassigned. Use 'const' instead prefer-const 239:4 error '$ul' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/controller/uw.controller.Step.js 223:7 error 'okCount' is never reassigned. Use 'const' instead prefer-const 233:3 error '$buttons' is never reassigned. Use 'const' instead prefer-const 324:4 error 'copy' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/controller/uw.controller.Tutorial.js 63:3 error Prefer .then to .done no-jquery/no-done-fail 63:3 error Prefer .then to .fail no-jquery/no-done-fail /src/repo/resources/controller/uw.controller.Upload.js 69:4 error 'max' is never reassigned. Use 'const' instead prefer-const 71:3 error 'haveUploads' is never reassigned. Use 'const' instead prefer-const 72:3 error 'fewerThanMax' is never reassigned. Use 'const' instead prefer-const 223:3 error 'upload' is never reassigned. Use 'const' instead prefer-const 251:4 error 'uploadObjs' is never reassigned. Use 'const' instead prefer-const 252:4 error 'controller' is never reassigned. Use 'const' instead prefer-const 307:4 error 'actualMaxSize' is never reassigned. Use 'const' instead prefer-const 311:4 error 'filename' is never reassigned. Use 'const' instead prefer-const 312:4 error 'basename' is never reassigned. Use 'const' instead prefer-const 335:3 error 'extension' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/deed/uw.deed.External.js 66:10 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign /src/repo/resources/deed/uw.deed.OwnWork.js 29:7 error 'deed' is never reassigned. Use 'const' instead prefer-const 88:3 error 'deed' is never reassigned. Use 'const' instead prefer-const 89:3 error 'languageCode' is never reassigned. Use 'const' instead prefer-const 91:3 error 'defaultLicense' is never reassigned. Use 'const' instead prefer-const 92:3 error 'defaultLicConfig' is never reassigned. Use 'const' instead prefer-const 99:3 error '$defaultLicenseLink' is never reassigned. Use 'const' instead prefer-const 125:3 error '$crossfader' is never reassigned. Use 'const' instead prefer-const 128:3 error '$customDiv' is never reassigned. Use 'const' instead prefer-const 136:3 error 'crossfaderWidget' is never reassigned. Use 'const' instead prefer-const 148:3 error '$formFields' is never reassigned. Use 'const' instead prefer-const 152:3 error '$toggler' is never reassigned. Use 'const' instead prefer-const 192:7 error 'author' is never reassigned. Use 'const' instead prefer-const 200:3 error 'userPageTitle' is never reassigned. Use 'const' instead prefer-const 215:10 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 255:16 error 'ownWork' is never reassigned. Use 'const' instead prefer-const 277:3 error Prefer .then to .done no-jquery/no-done-fail 297:3 error Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/deed/uw.deed.ThirdParty.js 178:10 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign /src/repo/resources/details/uw.CategoriesDetailsWidget.js 87:3 error Mixed spaces and tabs no-mixed-spaces-and-tabs 87:5 error Expected no linebreak before this expression implicit-arrow-linebreak 88:2 error Mixed spaces and tabs no-mixed-spaces-and-tabs 98:3 error 'categories' is never reassigned. Use 'const' instead prefer-const 128:3 error Mixed spaces and tabs no-mixed-spaces-and-tabs 128:5 error Expected no linebreak before this expression implicit-arrow-linebreak 129:2 error Mixed spaces and tabs no-mixed-spaces-and-tabs /src/repo/resources/details/uw.DropdownWidget.js 13:12 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign /src/repo/resources/details/uw.LocationDetailsWidget.js 12:17 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 71:3 error Prefer .then to .done no-jquery/no-done-fail 84:3 error Prefer .then to .done no-jquery/no-done-fail 115:7 error 'errors' is never reassigned. Use 'const' instead prefer-const 116:4 error 'serialized' is never reassigned. Use 'const' instead prefer-const 117:4 error 'parsed' is never reassigned. Use 'const' instead prefer-const 165:4 error 'serialized' is never reassigned. Use 'const' instead prefer-const 194:4 error 'result' is never reassigned. Use 'const' instead prefer-const 210:4 error 'result' is never reassigned. Use 'const' instead prefer-const 211:4 error 'serialized' is never reassigned. Use 'const' instead prefer-const 258:7 error 'sign' is never reassigned. Use 'const' instead prefer-const 268:3 error 'parts' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/details/uw.MultipleLanguageInputWidget.js 16:17 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 50:26 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 60:7 error 'allLanguages' is never reassigned. Use 'const' instead prefer-const 61:4 error 'unusedLanguages' is never reassigned. Use 'const' instead prefer-const 73:16 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 78:12 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 82:3 error 'item' is never reassigned. Use 'const' instead prefer-const 100:7 error 'allLanguages' is never reassigned. Use 'const' instead prefer-const 101:4 error 'unusedLanguages' is never reassigned. Use 'const' instead prefer-const 102:4 error 'items' is never reassigned. Use 'const' instead prefer-const 114:16 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 192:4 error 'errors' is never reassigned. Use 'const' instead prefer-const 215:7 error 'values' is never reassigned. Use 'const' instead prefer-const 216:4 error 'widgets' is never reassigned. Use 'const' instead prefer-const 272:13 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign /src/repo/resources/details/uw.SingleLanguageInputWidget.js 17:17 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 226:4 error 'text' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/details/uw.TextWidget.js 13:17 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign /src/repo/resources/details/uw.TitleDetailsWidget.js 49:4 error 'illegalFileChars' is never reassigned. Use 'const' instead prefer-const 82:3 error 'value' is never reassigned. Use 'const' instead prefer-const 94:3 error 'title' is never reassigned. Use 'const' instead prefer-const 156:7 error Mixed spaces and tabs no-mixed-spaces-and-tabs 156:9 error Expected no linebreak before this expression implicit-arrow-linebreak 157:6 error Mixed spaces and tabs no-mixed-spaces-and-tabs 181:3 error 'errors' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/handlers/mw.ApiUploadHandler.js 224:7 error 'allDuplicates' is never reassigned. Use 'const' instead prefer-const 224:23 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 225:4 error '$extra' is never reassigned. Use 'const' instead prefer-const 226:4 error '$ul' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/jquery.arrowSteps/jquery.arrowSteps.js 39:4 error '$el' is never reassigned. Use 'const' instead prefer-const 42:3 error '$steps' is never reassigned. Use 'const' instead prefer-const 44:3 error 'width' is never reassigned. Use 'const' instead prefer-const 71:4 error '$steps' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.DestinationChecker.js 77:4 error Mixed spaces and tabs no-mixed-spaces-and-tabs 77:6 error Expected no linebreak before this expression implicit-arrow-linebreak 78:3 error Mixed spaces and tabs no-mixed-spaces-and-tabs 94:8 error 'checker' is never reassigned. Use 'const' instead prefer-const 95:5 error 'NS_FILE' is never reassigned. Use 'const' instead prefer-const 98:4 error 'titleObj' is never reassigned. Use 'const' instead prefer-const 99:4 error 'ext' is never reassigned. Use 'const' instead prefer-const 101:4 error 'prefix' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.Escaper.js 31:4 error 'extractedTemplates' is never reassigned. Use 'const' instead prefer-const 32:4 error 'extractedLinks' is never reassigned. Use 'const' instead prefer-const 34:43 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 52:8 error 'extracts' is never reassigned. Use 'const' instead prefer-const 61:5 error 'regex' is never reassigned. Use 'const' instead prefer-const 62:5 error 'callback' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.GroupProgressBar.js 59:8 error 'bar' is never reassigned. Use 'const' instead prefer-const 146:5 error 'remainingTime' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.UploadWizard.js 4:1 warning Missing JSDoc @param "uw" type jsdoc/require-param-type 22:3 error 'maxSimPref' is never reassigned. Use 'const' instead prefer-const 64:8 error 'self' is never reassigned. Use 'const' instead prefer-const 65:5 error 'steps' is never reassigned. Use 'const' instead prefer-const 74:4 error 'uploadStep' is never reassigned. Use 'const' instead prefer-const 127:5 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 134:5 error 'original' is never reassigned. Use 'const' instead prefer-const 138:5 error 'override' is never reassigned. Use 'const' instead prefer-const 187:4 error 'deeds' is never reassigned. Use 'const' instead prefer-const 188:4 error 'doOwnWork' is never reassigned. Use 'const' instead prefer-const 189:4 error 'doThirdParty' is never reassigned. Use 'const' instead prefer-const 197:3 error 'api' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.UploadWizardDetails.js 45:8 error '$moreDetailsWrapperDiv' is never reassigned. Use 'const' instead prefer-const 47:5 error 'details' is never reassigned. Use 'const' instead prefer-const 48:5 error 'config' is never reassigned. Use 'const' instead prefer-const 56:13 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 73:48 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 83:40 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 90:55 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 98:57 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 105:44 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 113:47 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 118:51 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 123:53 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 151:4 error '$moreDetailsDiv' is never reassigned. Use 'const' instead prefer-const 215:5 error Prefer .then to .done no-jquery/no-done-fail 255:4 error Prefer .then to .done no-jquery/no-done-fail 383:4 error Mixed spaces and tabs no-mixed-spaces-and-tabs 383:6 error Expected no linebreak before this expression implicit-arrow-linebreak 384:3 error Mixed spaces and tabs no-mixed-spaces-and-tabs 448:5 error 'yyyyMmDdRegex' is never reassigned. Use 'const' instead prefer-const 449:5 error 'timeRegex' is never reassigned. Use 'const' instead prefer-const 470:7 error 'dateInfo' is never reassigned. Use 'const' instead prefer-const 508:4 error 'saneTime' is never reassigned. Use 'const' instead prefer-const 601:5 error 'm' is never reassigned. Use 'const' instead prefer-const 603:5 error 'values' is never reassigned. Use 'const' instead prefer-const 653:4 error 'languages' is never reassigned. Use 'const' instead prefer-const 662:3 warning JSDoc @return declaration present but return expression not available in function jsdoc/require-returns-check 672:21 error 'serialized' is never reassigned. Use 'const' instead prefer-const 734:5 error 'substitutions' is never reassigned. Use 'const' instead prefer-const 734:25 error 'substList' is never reassigned. Use 'const' instead prefer-const 735:5 error 'deed' is never reassigned. Use 'const' instead prefer-const 793:10 warning ES2015 RegExp 'u' flag is forbidden es-x/no-regexp-u-flag 813:8 error 'details' is never reassigned. Use 'const' instead prefer-const 823:4 error 'wikitext' is never reassigned. Use 'const' instead prefer-const 824:4 error 'promise' is never reassigned. Use 'const' instead prefer-const 843:5 error 'tags' is never reassigned. Use 'const' instead prefer-const 844:5 error 'deed' is never reassigned. Use 'const' instead prefer-const 846:5 error 'config' is never reassigned. Use 'const' instead prefer-const 869:4 error 'params' is never reassigned. Use 'const' instead prefer-const 936:5 error 'details' is never reassigned. Use 'const' instead prefer-const 939:5 error 'deferred' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.UploadWizardLicenseInput.js 17:7 error 'self' is never reassigned. Use 'const' instead prefer-const 18:4 error 'groups' is never reassigned. Use 'const' instead prefer-const 77:2 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 183:9 error 'templates' is never reassigned. Use 'const' instead prefer-const 209:5 error 'addError' is never reassigned. Use 'const' instead prefer-const 216:5 error 'selectedInputs' is never reassigned. Use 'const' instead prefer-const 226:7 error 'data' is never reassigned. Use 'const' instead prefer-const 232:6 error 'wikitext' is never reassigned. Use 'const' instead prefer-const 268:28 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign /src/repo/resources/mw.UploadWizardPage.js 31:4 error 'config' is never reassigned. Use 'const' instead prefer-const 53:3 error 'uploadWizard' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.UploadWizardUpload.js 8:1 warning Missing JSDoc @param "uw" type jsdoc/require-param-type 11:14 warning 'uw' is defined but never used no-unused-vars 204:4 error 'deferred' is never reassigned. Use 'const' instead prefer-const 205:4 error 'upload' is never reassigned. Use 'const' instead prefer-const 222:16 error 'Uint8Array' is already defined as a built-in global variable no-redeclare 223:16 warning ES2015 'Uint8Array' is forbidden es-x/no-typed-arrays 314:4 error 'upload' is never reassigned. Use 'const' instead prefer-const 382:3 error Prefer .then to .done no-jquery/no-done-fail 382:3 error Prefer .then to .fail no-jquery/no-done-fail 396:7 error 'requestedTitle' is never reassigned. Use 'const' instead prefer-const 430:3 error 'params' is never reassigned. Use 'const' instead prefer-const 448:3 error Prefer .then to .done no-jquery/no-done-fail 448:3 error Prefer .then to .fail no-jquery/no-done-fail 488:21 error 'image' is never reassigned. Use 'const' instead prefer-const 585:5 error 'constraint' is never reassigned. Use 'const' instead prefer-const 629:3 error 'scaling' is never reassigned. Use 'const' instead prefer-const 631:3 error 'width' is never reassigned. Use 'const' instead prefer-const 632:3 error 'height' is never reassigned. Use 'const' instead prefer-const 640:3 error 'dx' is never reassigned. Use 'const' instead prefer-const 641:3 error 'dy' is never reassigned. Use 'const' instead prefer-const 666:3 error '$canvas' is never reassigned. Use 'const' instead prefer-const 667:3 error 'ctx' is never reassigned. Use 'const' instead prefer-const 715:7 error 'constraints' is never reassigned. Use 'const' instead prefer-const 767:3 error Prefer .then to .done no-jquery/no-done-fail 767:3 error Prefer .then to .fail no-jquery/no-done-fail 775:6 error Prefer .then to .done no-jquery/no-done-fail 778:7 error Prefer .then to .done no-jquery/no-done-fail 802:4 error 'deferred' is never reassigned. Use 'const' instead prefer-const 803:4 error 'upload' is never reassigned. Use 'const' instead prefer-const 828:9 error 'canvas' is never reassigned. Use 'const' instead prefer-const 831:8 error 'context' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.UploadWizardUploadInterface.js 206:3 error Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/transports/mw.FormDataTransport.js 97:3 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 156:4 error 'deferred' is never reassigned. Use 'const' instead prefer-const 157:4 error 'fileSize' is never reassigned. Use 'const' instead prefer-const 158:4 error 'chunkSize' is never reassigned. Use 'const' instead prefer-const 159:4 error 'transport' is never reassigned. Use 'const' instead prefer-const 169:5 error Prefer .then to .done no-jquery/no-done-fail 170:6 error Prefer .then to .done no-jquery/no-done-fail 170:6 error Prefer .then to .fail no-jquery/no-done-fail 194:7 error 'params' is never reassigned. Use 'const' instead prefer-const 195:4 error 'transport' is never reassigned. Use 'const' instead prefer-const 196:4 error 'bytesAvailable' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/ui/steps/uw.ui.Deed.js 55:3 error Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/ui/steps/uw.ui.Details.js 90:3 error Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/ui/steps/uw.ui.Thanks.js 30:4 error 'thanks' is never reassigned. Use 'const' instead prefer-const 48:3 error '$header' is never reassigned. Use 'const' instead prefer-const 69:3 error 'beginButtonTarget' is never reassigned. Use 'const' instead prefer-const 98:3 error 'thumbWikiText' is never reassigned. Use 'const' instead prefer-const 104:3 error '$thanksDiv' is never reassigned. Use 'const' instead prefer-const 106:3 error '$thumbnailWrapDiv' is never reassigned. Use 'const' instead prefer-const 109:3 error '$thumbnailDiv' is never reassigned. Use 'const' instead prefer-const 112:3 error '$thumbnailCaption' is never reassigned. Use 'const' instead prefer-const 115:3 error '$thumbnailLink' is never reassigned. Use 'const' instead prefer-const 128:3 error Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/ui/steps/uw.ui.Tutorial.js 125:3 error Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/ui/steps/uw.ui.Upload.js 210:6 error Prefer .then to .done no-jquery/no-done-fail 222:3 error Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/ui/uw.ui.DeedPreview.js 30:3 error Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/ui/uw.ui.Step.js 101:3 error Prefer .then to .done no-jquery/no-done-fail 119:3 error Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/uw.ConcurrentQueue.js 117:3 error 'index' is never reassigned. Use 'const' instead prefer-const 139:3 error 'item' is never reassigned. Use 'const' instead prefer-const 145:3 error 'promise' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/uw.CopyMetadataWidget.js 14:4 error 'checkboxes' is never reassigned. Use 'const' instead prefer-const 15:4 error '$copyMetadataWrapperDiv' is never reassigned. Use 'const' instead prefer-const 16:4 error '$copyMetadataDiv' is never reassigned. Use 'const' instead prefer-const 157:4 error 'uploads' is never reassigned. Use 'const' instead prefer-const 158:4 error 'sourceUpload' is never reassigned. Use 'const' instead prefer-const 159:4 error 'serialized' is never reassigned. Use 'const' instead prefer-const 161:4 error 'sourceValue' is never reassigned. Use 'const' instead prefer-const 214:4 error 'uploads' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/uw.FieldLayout.js 20:12 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign /src/repo/resources/uw.LicenseGroup.js 37:17 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 132:4 error 'option' is never reassigned. Use 'const' instead prefer-const 167:4 error 'option' is never reassigned. Use 'const' instead prefer-const 191:4 error 'self' is never reassigned. Use 'const' instead prefer-const 192:4 error 'values' is never reassigned. Use 'const' instead prefer-const 194:3 error 'wikiTexts' is never reassigned. Use 'const' instead prefer-const 196:5 error 'value' is never reassigned. Use 'const' instead prefer-const 222:7 error 'self' is never reassigned. Use 'const' instead prefer-const 223:4 error 'result' is never reassigned. Use 'const' instead prefer-const 248:7 error 'self' is never reassigned. Use 'const' instead prefer-const 249:4 error 'selectArray' is never reassigned. Use 'const' instead prefer-const 303:7 error 'licenseInfo' is never reassigned. Use 'const' instead prefer-const 306:3 error 'licenseText' is never reassigned. Use 'const' instead prefer-const 319:7 error 'licenseInfo' is never reassigned. Use 'const' instead prefer-const 320:4 error 'messageKey' is never reassigned. Use 'const' instead prefer-const 323:4 error 'languageCode' is never reassigned. Use 'const' instead prefer-const 328:4 error '$icons' is never reassigned. Use 'const' instead prefer-const 334:3 error '$licenseLink' is never reassigned. Use 'const' instead prefer-const 343:3 error '$label' is never reassigned. Use 'const' instead prefer-const 361:7 error 'self' is never reassigned. Use 'const' instead prefer-const 372:3 error 'button' is never reassigned. Use 'const' instead prefer-const 397:3 error 'input' is never reassigned. Use 'const' instead prefer-const 413:3 error Prefer .then to .done no-jquery/no-done-fail 413:3 error Prefer .then to .fail no-jquery/no-done-fail /src/repo/resources/uw.ValidationMessageElement.js 39:2 warning JSDoc @return declaration present but return expression not available in function jsdoc/require-returns-check 91:3 error '$listItem' is never reassigned. Use 'const' instead prefer-const /src/repo/tests/qunit/controller/uw.controller.Details.test.js 57:7 error 'step' is never reassigned. Use 'const' instead prefer-const 61:4 error 'stepUiStub' is never reassigned. Use 'const' instead prefer-const 110:4 error 'done' is never reassigned. Use 'const' instead prefer-const 111:4 error 'donestub' is never reassigned. Use 'const' instead prefer-const 112:4 error 'ds' is never reassigned. Use 'const' instead prefer-const 113:4 error 'ps' is never reassigned. Use 'const' instead prefer-const 117:3 error 'tostub' is never reassigned. Use 'const' instead prefer-const 124:3 error 'step' is never reassigned. Use 'const' instead prefer-const 135:3 error Prefer .then to .done no-jquery/no-done-fail /src/repo/tests/qunit/controller/uw.controller.Tutorial.test.js 33:4 error 'acwStub' is never reassigned. Use 'const' instead prefer-const 54:3 error 'mnStub' is never reassigned. Use 'const' instead prefer-const /src/repo/tests/qunit/mw.UploadWizardLicenseInput.test.js 17:6 error 'config' is never reassigned. Use 'const' instead prefer-const 18:3 error '$fixture' is never reassigned. Use 'const' instead prefer-const 21:2 error 'uwLicenseInput' is never reassigned. Use 'const' instead prefer-const 27:6 error 'config' is never reassigned. Use 'const' instead prefer-const 28:3 error '$fixture' is never reassigned. Use 'const' instead prefer-const 33:2 error 'uwLicenseInput' is never reassigned. Use 'const' instead prefer-const 37:2 error '$input' is never reassigned. Use 'const' instead prefer-const 41:2 error '$label' is never reassigned. Use 'const' instead prefer-const 46:6 error 'config' is never reassigned. Use 'const' instead prefer-const 56:3 error '$fixture' is never reassigned. Use 'const' instead prefer-const 59:2 error 'uwLicenseInput' is never reassigned. Use 'const' instead prefer-const /src/repo/tests/qunit/mw.UploadWizardUpload.test.js 23:4 error 'oldconf' is never reassigned. Use 'const' instead prefer-const 27:3 error 'upload' is never reassigned. Use 'const' instead prefer-const /src/repo/tests/qunit/mw.fileApi.test.js 46:15 error 'testFile' is never reassigned. Use 'const' instead prefer-const 47:4 error 'fakeVideo' is never reassigned. Use 'const' instead prefer-const /src/repo/tests/qunit/transports/mw.FormDataTransport.test.js 27:3 error 'config' is never reassigned. Use 'const' instead prefer-const 86:4 error 'transport' is never reassigned. Use 'const' instead prefer-const 87:4 error 'fakeFile' is never reassigned. Use 'const' instead prefer-const 97:3 error 'request' is never reassigned. Use 'const' instead prefer-const 107:4 error 'transport' is never reassigned. Use 'const' instead prefer-const 108:4 error 'fakeFile' is never reassigned. Use 'const' instead prefer-const 125:3 error 'request' is never reassigned. Use 'const' instead prefer-const 146:3 error Prefer .then to .fail no-jquery/no-done-fail 179:10 error Prefer .then to .done no-jquery/no-done-fail 198:10 error Prefer .then to .done no-jquery/no-done-fail 218:3 error Prefer .then to .fail no-jquery/no-done-fail /src/repo/tests/qunit/uw.ConcurrentQueue.test.js 38:3 error 'calls' is never reassigned. Use 'const' instead prefer-const 65:3 error 'done' is never reassigned. Use 'const' instead prefer-const 66:3 error 'action' is never reassigned. Use 'const' instead prefer-const 67:3 error 'queue' is never reassigned. Use 'const' instead prefer-const 98:3 error 'done' is never reassigned. Use 'const' instead prefer-const 99:3 error 'changeHandler' is never reassigned. Use 'const' instead prefer-const 100:3 error 'progressHandler' is never reassigned. Use 'const' instead prefer-const 101:3 error 'completeHandler' is never reassigned. Use 'const' instead prefer-const 102:3 error 'queue' is never reassigned. Use 'const' instead prefer-const 139:3 error 'done' is never reassigned. Use 'const' instead prefer-const 140:3 error 'queue' is never reassigned. Use 'const' instead prefer-const 167:3 error 'done' is never reassigned. Use 'const' instead prefer-const 168:3 error 'queue' is never reassigned. Use 'const' instead prefer-const 184:3 error 'done' is never reassigned. Use 'const' instead prefer-const 185:3 error 'changeHandler' is never reassigned. Use 'const' instead prefer-const 186:3 error 'progressHandler' is never reassigned. Use 'const' instead prefer-const 187:3 error 'completeHandler' is never reassigned. Use 'const' instead prefer-const 188:3 error 'queue' is never reassigned. Use 'const' instead prefer-const 240:3 error 'done' is never reassigned. Use 'const' instead prefer-const 241:3 error 'changeHandler' is never reassigned. Use 'const' instead prefer-const 242:3 error 'progressHandler' is never reassigned. Use 'const' instead prefer-const 243:3 error 'completeHandler' is never reassigned. Use 'const' instead prefer-const 244:3 error 'queue' is never reassigned. Use 'const' instead prefer-const 297:3 error 'done' is never reassigned. Use 'const' instead prefer-const 298:3 error 'action' is never reassigned. Use 'const' instead prefer-const 299:3 error 'changeHandler' is never reassigned. Use 'const' instead prefer-const 300:3 error 'progressHandler' is never reassigned. Use 'const' instead prefer-const 301:3 error 'completeHandler' is never reassigned. Use 'const' instead prefer-const 302:3 error 'queue' is never reassigned. Use 'const' instead prefer-const 353:3 error 'done' is never reassigned. Use 'const' instead prefer-const 355:3 error 'action' is never reassigned. Use 'const' instead prefer-const 356:3 error 'changeHandler' is never reassigned. Use 'const' instead prefer-const 357:3 error 'progressHandler' is never reassigned. Use 'const' instead prefer-const 358:3 error 'completeHandler' is never reassigned. Use 'const' instead prefer-const 359:3 error 'queue' is never reassigned. Use 'const' instead prefer-const 402:3 error 'onProgress' is never reassigned. Use 'const' instead prefer-const /src/repo/tests/qunit/uw.TitleDetailsWidget.test.js 5:2 error 'fileNs' is never reassigned. Use 'const' instead prefer-const 6:2 error 'makeTitleInFileNSCases' is never reassigned. Use 'const' instead prefer-const ✖ 352 problems (315 errors, 37 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":"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/.stylelintrc.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/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-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/composer.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/docs/external.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-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/docs/jsduck-config.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/extension.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/i18n/api/ar.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/i18n/api/de.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/i18n/api/en.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/i18n/api/eu.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/i18n/api/fr.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/i18n/api/he.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/i18n/api/ia.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/i18n/api/it.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/i18n/api/lt.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/i18n/api/mk.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/i18n/api/nb.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/i18n/api/nl.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/i18n/api/qqq.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/i18n/api/roa-tara.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/i18n/api/skr-arab.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/i18n/api/sl.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/i18n/api/zh-hant.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/i18n/ar.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/i18n/av.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/i18n/bg.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/i18n/bug-bugi.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/i18n/cs.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/i18n/de.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/i18n/en.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/i18n/es.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/i18n/eu.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/i18n/fa.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/i18n/fi.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/i18n/fr.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/i18n/gu.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/i18n/he.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/i18n/hi.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/i18n/hr.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/i18n/hy.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/i18n/ia.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/i18n/id.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/i18n/it.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/i18n/ja.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/i18n/kaa.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/i18n/ko.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/i18n/krc.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/i18n/ky.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/i18n/lb.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/i18n/license/ar.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/i18n/license/de.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/i18n/license/en.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/i18n/license/es.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/i18n/license/eu.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/i18n/license/fi.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/i18n/license/fr.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/i18n/license/he.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/i18n/license/hy.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/i18n/license/ia.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/i18n/license/it.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/i18n/license/ko.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/i18n/license/lt.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/i18n/license/mk.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/i18n/license/my.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/i18n/license/nl.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/i18n/license/qqq.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/i18n/license/roa-tara.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/i18n/license/ru.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/i18n/license/skr-arab.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/i18n/license/sl.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/i18n/license/sr-ec.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/i18n/license/sr-el.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/i18n/license/zh-hant.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/i18n/lt.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/i18n/mk.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/i18n/ms.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/i18n/nb.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/i18n/ne.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/i18n/nl.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/i18n/or.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/i18n/pa.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/i18n/pl.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/i18n/pnb.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/i18n/pt-br.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/i18n/pt.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/i18n/qqq.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/i18n/ru.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/i18n/rw.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/i18n/sd.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/i18n/se.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/i18n/sh-latn.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/i18n/shn.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/i18n/si.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/i18n/skr-arab.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/i18n/sl.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/i18n/smn.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/i18n/sms.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/i18n/sr-ec.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/i18n/sr-el.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/i18n/sv.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/i18n/th.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/i18n/tly.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/i18n/tr.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/i18n/uk.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/i18n/vi.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/i18n/zh-hans.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/i18n/zh-hant.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/package-lock.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/package.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/resources/controller/uw.controller.Deed.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'deedController' is never reassigned. Use 'const' instead.","line":44,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":44,"endColumn":18},{"ruleId":"prefer-const","severity":2,"message":"'valid' is never reassigned. Use 'const' instead.","line":52,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":52,"endColumn":8},{"ruleId":"no-mixed-spaces-and-tabs","severity":2,"message":"Mixed spaces and tabs.","line":57,"column":4,"nodeType":"Program","messageId":"mixedSpacesAndTabs","endLine":57,"endColumn":6},{"ruleId":"implicit-arrow-linebreak","severity":2,"message":"Expected no linebreak before this expression.","line":57,"column":6,"nodeType":"Identifier","messageId":"unexpected","endLine":57,"endColumn":17},{"ruleId":"no-mixed-spaces-and-tabs","severity":2,"message":"Mixed spaces and tabs.","line":58,"column":3,"nodeType":"Program","messageId":"mixedSpacesAndTabs","endLine":58,"endColumn":5}],"suppressedMessages":[],"errorCount":5,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*\n * This file is part of the MediaWiki extension MediaUploader.\n *\n * MediaUploader is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * MediaUploader is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with MediaUploader. If not, see <http://www.gnu.org/licenses/>.\n */\n\n( function ( uw ) {\n\t/**\n\t * Deed step controller.\n\t *\n\t * @class\n\t * @extends uw.controller.Step\n\t * @param {mw.Api} api\n\t * @param {Object} config UploadWizard config object.\n\t */\n\tuw.controller.Deed = function UWControllerDeed( api, config ) {\n\t\tuw.controller.Step.call(\n\t\t\tthis,\n\t\t\tnew uw.ui.Deed(),\n\t\t\tapi,\n\t\t\tconfig\n\t\t);\n\n\t\tthis.stepName = 'deeds';\n\n\t\tthis.deeds = {};\n\t};\n\n\tOO.inheritClass( uw.controller.Deed, uw.controller.Step );\n\n\tuw.controller.Deed.prototype.moveNext = function () {\n\t\tlet\n\t\t\tdeedController = this,\n\t\t\tvalid, fields, validityPromises;\n\n\t\tif ( !this.deedChooser ) {\n\t\t\tuw.controller.Step.prototype.moveNext.call( this );\n\t\t\treturn;\n\t\t}\n\n\t\tvalid = this.deedChooser.valid();\n\t\tif ( valid ) {\n\t\t\tfields = this.deedChooser.deed.getFields();\n\t\t\tvalidityPromises = fields.map( ( fieldLayout ) =>\n\t\t\t\t// Update any error/warning messages\n\t\t\t\t fieldLayout.checkValidity( true )\n\t\t\t );\n\t\t\tif ( validityPromises.length === 1 ) {\n\t\t\t\t// validityPromises will hold all promises for all uploads;\n\t\t\t\t// adding a bogus promise (no warnings & errors) to\n\t\t\t\t// ensure $.when always resolves with an array of multiple\n\t\t\t\t// results (if there's just 1, it would otherwise have just\n\t\t\t\t// that one's arguments, instead of a multi-dimensional array\n\t\t\t\t// of upload warnings & failures)\n\t\t\t\tvalidityPromises.push( $.Deferred().resolve( [], [] ).promise() );\n\t\t\t}\n\n\t\t\t$.when.apply( $, validityPromises ).then( function () {\n\t\t\t\t// `arguments` will be an array of all fields, with their warnings & errors\n\t\t\t\t// e.g. `[[something], []], [[], [something]]` for 2 fields, where the first one has\n\t\t\t\t// a warning and the last one an error\n\n\t\t\t\t// TODO Handle warnings with a confirmation dialog\n\n\t\t\t\tlet i;\n\t\t\t\tfor ( i = 0; i < arguments.length; i++ ) {\n\t\t\t\t\tif ( arguments[ i ][ 1 ].length ) {\n\t\t\t\t\t\t// One of the fields has errors; refuse to proceed!\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tuw.controller.Step.prototype.moveNext.call( deedController );\n\t\t\t} );\n\t\t}\n\t};\n\n\tuw.controller.Deed.prototype.unload = function () {\n\t\tconst deedController = this;\n\t\tuw.controller.Step.prototype.unload.call( this );\n\n\t\tObject.keys( this.deeds ).forEach( ( name ) => {\n\t\t\tdeedController.deeds[ name ].unload();\n\t\t} );\n\t};\n\n\t/**\n\t * Move to this step.\n\t *\n\t * @param {mw.UploadWizardUpload[]} uploads\n\t */\n\tuw.controller.Deed.prototype.load = function ( uploads ) {\n\t\tlet customDeed, previousDeed;\n\n\t\tuw.controller.Step.prototype.load.call( this, uploads );\n\n\t\t// grab a serialized copy of previous deeds' details (if any)\n\t\tif ( this.deedChooser ) {\n\t\t\tpreviousDeed = this.deedChooser.getSerialized();\n\t\t}\n\n\t\tthis.deeds = mw.UploadWizard.getLicensingDeeds( this.uploads, this.config );\n\n\t\t// if we have multiple uploads, also give them the option to set\n\t\t// licenses individually\n\t\tif ( this.uploads.length > 1 ) {\n\t\t\tcustomDeed = new uw.deed.Custom( this.config );\n\t\t\tthis.deeds[ customDeed.name ] = customDeed;\n\t\t}\n\n\t\tthis.deedChooser = new mw.UploadWizardDeedChooser(\n\t\t\tthis.config,\n\t\t\t'#mediauploader-deeds',\n\t\t\tthis.deeds,\n\t\t\tthis.uploads\n\t\t);\n\n\t\t$( '<div>' )\n\t\t\t.insertBefore( this.deedChooser.$selector.find( '.mediauploader-deed-ownwork' ) )\n\t\t\t.msg( 'mediauploader-deeds-macro-prompt', this.uploads.length, mw.user );\n\n\t\tuploads.forEach( ( upload ) => {\n\t\t\t// Add previews and details to the DOM\n\t\t\tupload.deedPreview = new uw.ui.DeedPreview( upload );\n\t\t} );\n\n\t\tthis.deedChooser.onLayoutReady();\n\n\t\t// restore the previous input (if any) for all deeds\n\t\tif ( previousDeed ) {\n\t\t\tthis.deedChooser.setSerialized( previousDeed );\n\t\t}\n\t};\n\n\t/**\n\t * @param {mw.UploadWizardUpload} upload\n\t */\n\tuw.controller.Deed.prototype.removeUpload = function ( upload ) {\n\t\tuw.controller.Step.prototype.removeUpload.call( this, upload );\n\n\t\tif ( upload.deedPreview ) {\n\t\t\tupload.deedPreview.remove();\n\t\t}\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/controller/uw.controller.Details.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'serialized' is never reassigned. Use 'const' instead.","line":65,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":65,"endColumn":14},{"ruleId":"prefer-const","severity":2,"message":"'invalidStates' is never reassigned. Use 'const' instead.","line":96,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":96,"endColumn":17},{"ruleId":"prefer-const","severity":2,"message":"'invalids' is never reassigned. Use 'const' instead.","line":97,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":97,"endColumn":12},{"ruleId":"prefer-const","severity":2,"message":"'valids' is never reassigned. Use 'const' instead.","line":98,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":98,"endColumn":10},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":153,"column":3,"nodeType":"CallExpression","endLine":160,"endColumn":6},{"ruleId":"prefer-const","severity":2,"message":"'$message' is never reassigned. Use 'const' instead.","line":238,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":238,"endColumn":12},{"ruleId":"prefer-const","severity":2,"message":"'$ul' is never reassigned. Use 'const' instead.","line":239,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":239,"endColumn":7}],"suppressedMessages":[{"ruleId":"no-jquery/no-global-selector","severity":2,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":143,"column":56,"nodeType":"CallExpression","endLine":143,"endColumn":89,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":7,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*\n * This file is part of the MediaWiki extension MediaUploader.\n *\n * MediaUploader is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * MediaUploader is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with MediaUploader. If not, see <http://www.gnu.org/licenses/>.\n */\n\n( function ( uw ) {\n\t/**\n\t * Represents the details step in the wizard.\n\t *\n\t * @class\n\t * @extends uw.controller.Step\n\t * @param {mw.Api} api\n\t * @param {Object} config UploadWizard config object.\n\t */\n\tuw.controller.Details = function UWControllerDetails( api, config ) {\n\t\tuw.controller.Step.call(\n\t\t\tthis,\n\t\t\tnew uw.ui.Details()\n\t\t\t\t.on( 'start-details', this.startDetails.bind( this ) )\n\t\t\t\t.on( 'finalize-details-after-removal', this.moveNext.bind( this ) ),\n\t\t\tapi,\n\t\t\tconfig\n\t\t);\n\n\t\tthis.stepName = 'details';\n\t\tthis.finishState = 'complete';\n\n\t\tthis.queue = new uw.ConcurrentQueue( {\n\t\t\tcount: this.config.maxSimultaneousConnections,\n\t\t\taction: this.transitionOne.bind( this )\n\t\t} );\n\t};\n\n\tOO.inheritClass( uw.controller.Details, uw.controller.Step );\n\n\t/**\n\t * Move to this step.\n\t *\n\t * @param {mw.UploadWizardUpload[]} uploads List of uploads being carried forward.\n\t */\n\tuw.controller.Details.prototype.load = function ( uploads ) {\n\t\tconst controller = this;\n\n\t\tuw.controller.Step.prototype.load.call( this, uploads );\n\n\t\t// make sure queue is empty before starting this step\n\t\tthis.queue.abortExecuting();\n\n\t\tthis.uploads.forEach( ( upload ) => {\n\t\t\tlet serialized;\n\n\t\t\t// get existing details\n\t\t\tserialized = upload.details ? upload.details.getSerialized() : null;\n\n\t\t\tcontroller.createDetails( upload );\n\t\t\tif ( upload.deedChooser && upload.deedChooser.deed.name === 'custom' ) {\n\t\t\t\tupload.details.useCustomDeedChooser();\n\t\t\t}\n\t\t\tupload.details.attach();\n\n\t\t\t// restore earlier details (user may have started inputting details,\n\t\t\t// then went back some steps, and now got here again)\n\t\t\tif ( serialized ) {\n\t\t\t\tupload.details.setSerialized( serialized );\n\t\t\t}\n\t\t} );\n\n\t\t// Show the widget allowing to copy selected metadata if there's more than one successful upload\n\t\tif ( this.config.copyMetadataFeature ) {\n\t\t\tthis.addCopyMetadataFeature();\n\t\t}\n\t};\n\n\tuw.controller.Details.prototype.moveNext = function () {\n\t\tthis.removeErrorUploads();\n\n\t\tuw.controller.Step.prototype.moveNext.call( this );\n\t};\n\n\tuw.controller.Details.prototype.addCopyMetadataFeature = function () {\n\t\tlet first,\n\t\t\t// uploads can only be edited when they're in a certain state:\n\t\t\t// a flat out upload failure or a completed upload can not be edited\n\t\t\tinvalidStates = [ 'aborted', 'error', 'complete' ],\n\t\t\tinvalids = this.getUploadStatesCount( invalidStates ),\n\t\t\tvalids = this.uploads.length - invalids;\n\n\t\t// no point in having this feature if there's no target to copy to\n\t\tif ( valids < 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// The first upload is not necessarily the one we want to copy from\n\t\t// E.g. the first upload could've gone through successfully, but the\n\t\t// rest failed because of abusefilter (or another recoverable error), in\n\t\t// which case we'll want the \"copy\" feature to appear below the 2nd\n\t\t// upload (or the first not-yet-completed not flat-out-failed upload)\n\t\tthis.uploads.some( ( upload ) => {\n\t\t\tif ( upload && !invalidStates.includes( upload.state ) ) {\n\t\t\t\tfirst = upload;\n\t\t\t\treturn true; // Break Array.some loop\n\t\t\t}\n\t\t\treturn false;\n\t\t} );\n\n\t\t// could not find a source upload to copy from\n\t\tif ( !first ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.copyMetadataWidget = new uw.CopyMetadataWidget( {\n\t\t\tcopyFrom: first,\n\t\t\t// Include the \"source\" upload in the targets too\n\t\t\tcopyTo: this.uploads\n\t\t} );\n\n\t\tfirst.details.$div.after( this.copyMetadataWidget.$element );\n\t};\n\n\tuw.controller.Details.prototype.removeCopyMetadataFeature = function () {\n\t\tif ( this.copyMetadataWidget ) {\n\t\t\tthis.copyMetadataWidget.$element.remove();\n\t\t}\n\t};\n\n\t/**\n\t * @param {mw.UploadWizardUpload} upload\n\t */\n\tuw.controller.Details.prototype.createDetails = function ( upload ) {\n\t\t// eslint-disable-next-line no-jquery/no-global-selector\n\t\tupload.details = new mw.UploadWizardDetails( upload, $( '#mediauploader-macro-files' ) );\n\t};\n\n\t/**\n\t * Start details submit.\n\t * TODO move the rest of the logic here from mw.UploadWizard\n\t */\n\tuw.controller.Details.prototype.startDetails = function () {\n\t\tconst details = this;\n\n\t\tthis.valid().done( ( valid ) => {\n\t\t\tif ( valid ) {\n\t\t\t\tdetails.ui.hideEndButtons();\n\t\t\t\tdetails.submit();\n\t\t\t} else {\n\t\t\t\tdetails.showErrors();\n\t\t\t}\n\t\t} );\n\t};\n\n\t/**\n\t * Check details for validity.\n\t *\n\t * @return {jQuery.Promise}\n\t */\n\tuw.controller.Details.prototype.valid = function () {\n\t\tconst detailsController = this,\n\t\t\t// validityPromises will hold all promises for all uploads;\n\t\t\t// prefilling with a bogus promise (no warnings & errors) to\n\t\t\t// ensure $.when always resolves with an array of multiple\n\t\t\t// results (if there's just 1, it would otherwise have just\n\t\t\t// that one's arguments, instead of a multi-dimensional array\n\t\t\t// of upload warnings & failures)\n\t\t\tvalidityPromises = [ $.Deferred().resolve( [], [] ).promise() ],\n\t\t\ttitles = [];\n\n\t\tthis.uploads.forEach( ( upload ) => {\n\t\t\t// Update any error/warning messages about all DetailsWidgets\n\t\t\tconst promise = upload.details.checkValidity( true ).then( function () {\n\t\t\t\tlet warnings = [],\n\t\t\t\t\terrors = [],\n\t\t\t\t\ttitle;\n\n\t\t\t\tArray.prototype.forEach.call( arguments, ( result ) => {\n\t\t\t\t\twarnings = warnings.concat( result[ 0 ] );\n\t\t\t\t\terrors = errors.concat( result[ 1 ] );\n\t\t\t\t} );\n\n\t\t\t\t// Seen this title before?\n\t\t\t\ttitle = upload.details.getTitle();\n\t\t\t\tif ( title ) {\n\t\t\t\t\ttitle = title.getName() + '.' + mw.Title.normalizeExtension( title.getExtension() );\n\t\t\t\t\tif ( titles[ title ] ) {\n\t\t\t\t\t\t// Don't submit. Instead, set an error in details step.\n\t\t\t\t\t\tupload.details.setDuplicateTitleError();\n\t\t\t\t\t\terrors.push( mw.message( 'mediauploader-error-title-duplicate' ) );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttitles[ title ] = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn $.Deferred().resolve( warnings, errors ).promise();\n\t\t\t} );\n\n\t\t\t// Will hold an array of validation promises, one for each upload\n\t\t\tvalidityPromises.push( promise );\n\t\t} );\n\n\t\t// validityPromises is an array of promises that each resolve with [warnings, errors]\n\t\t// for each upload - now iterate them all to figure out if we can proceed\n\t\treturn $.when.apply( $, validityPromises ).then( function () {\n\t\t\tlet warnings = [],\n\t\t\t\terrors = [];\n\n\t\t\tArray.prototype.forEach.call( arguments, ( result ) => {\n\t\t\t\twarnings = warnings.concat( result[ 0 ] );\n\t\t\t\terrors = errors.concat( result[ 1 ] );\n\t\t\t} );\n\n\t\t\tif ( errors.length > 0 ) {\n\t\t\t\treturn $.Deferred().resolve( false );\n\t\t\t}\n\n\t\t\tif ( warnings.length > 0 ) {\n\t\t\t\t// Update warning count before dialog\n\t\t\t\tdetailsController.showErrors();\n\t\t\t\treturn detailsController.confirmationDialog( warnings );\n\t\t\t}\n\n\t\t\treturn $.Deferred().resolve( true );\n\t\t} );\n\t};\n\n\tuw.controller.Details.prototype.confirmationDialog = function ( warnings ) {\n\t\tlet i,\n\t\t\t$message = $( '<p>' ).text( mw.message( 'mediauploader-dialog-warning' ).text() ),\n\t\t\t$ul = $( '<ul>' );\n\n\t\t// parse warning messages\n\t\twarnings = warnings.map( ( warning ) => warning.text() );\n\n\t\t// omit duplicates\n\t\twarnings = warnings.filter( ( warning, j, warningsOld ) => warningsOld.indexOf( warning ) === j );\n\n\t\tfor ( i = 0; i < warnings.length; i++ ) {\n\t\t\t$ul.append( $( '<li>' ).text( warnings[ i ] ) );\n\t\t}\n\n\t\treturn OO.ui.getWindowManager().openWindow( 'message', {\n\t\t\tmessage: $message.append( $ul ),\n\t\t\ttitle: mw.message( 'mediauploader-dialog-title' ).text(),\n\t\t\tactions: [\n\t\t\t\t{\n\t\t\t\t\taction: 'back',\n\t\t\t\t\tlabel: mw.msg( 'mediauploader-dialog-back' )\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\taction: 'continue',\n\t\t\t\t\tlabel: mw.msg( 'mediauploader-dialog-continue' )\n\t\t\t\t}\n\t\t\t]\n\t\t} ).closed.then( ( data ) => !!( data && data.action === 'continue' ) );\n\t};\n\n\tuw.controller.Details.prototype.canTransition = function ( upload ) {\n\t\treturn (\n\t\t\tuw.controller.Step.prototype.canTransition.call( this, upload ) &&\n\t\t\tupload.state === this.stepName\n\t\t);\n\t};\n\n\t/**\n\t * Perform this step's changes on one upload.\n\t *\n\t * @param {mw.UploadWizardUpload} upload\n\t * @return {jQuery.Promise}\n\t */\n\tuw.controller.Details.prototype.transitionOne = function ( upload ) {\n\t\treturn upload.details.submit();\n\t};\n\n\t/**\n\t * Perform this step's changes on all uploads.\n\t *\n\t * @return {jQuery.Promise}\n\t */\n\tuw.controller.Details.prototype.transitionAll = function () {\n\t\tconst\n\t\t\tdeferred = $.Deferred(),\n\t\t\tdetails = this;\n\n\t\tthis.uploads.forEach( ( upload ) => {\n\t\t\tif ( details.canTransition( upload ) ) {\n\t\t\t\tdetails.queue.addItem( upload );\n\t\t\t}\n\t\t} );\n\n\t\tthis.queue.on( 'complete', deferred.resolve );\n\t\tthis.queue.startExecuting();\n\n\t\treturn deferred.promise();\n\t};\n\n\t/**\n\t * Submit details to the API.\n\t *\n\t * @return {jQuery.Promise}\n\t */\n\tuw.controller.Details.prototype.submit = function () {\n\t\tconst details = this;\n\n\t\tthis.uploads.forEach( ( upload ) => {\n\t\t\t// Clear error state\n\t\t\tif ( upload.state === 'error' || upload.state === 'recoverable-error' ) {\n\t\t\t\tupload.state = details.stepName;\n\t\t\t}\n\n\t\t\t// Set details view to have correct title\n\t\t\tupload.details.setVisibleTitle( upload.details.getTitle().getMain() );\n\t\t} );\n\n\t\t// Disable edit interface\n\t\tthis.ui.disableEdits();\n\t\tthis.removeCopyMetadataFeature();\n\n\t\treturn this.transitionAll().then( () => {\n\t\t\tdetails.showErrors();\n\n\t\t\tif ( details.showNext() ) {\n\t\t\t\tdetails.moveNext();\n\t\t\t}\n\t\t} );\n\t};\n\n\t/**\n\t * Show warnings and errors in the form.\n\t * See UI class for more.\n\t */\n\tuw.controller.Details.prototype.showErrors = function () {\n\t\tthis.ui.enableEdits();\n\n\t\tthis.removeCopyMetadataFeature();\n\t\tthis.addCopyMetadataFeature();\n\n\t\tthis.ui.showWarnings(); // Scroll to the warning first so that any errors will have precedence\n\t\tthis.ui.showErrors();\n\t};\n\n\t/**\n\t * Handler for when an upload is removed.\n\t *\n\t * @param {mw.UploadWizardUpload} upload\n\t */\n\tuw.controller.Details.prototype.removeUpload = function ( upload ) {\n\t\tuw.controller.Step.prototype.removeUpload.call( this, upload );\n\n\t\tthis.queue.removeItem( upload );\n\n\t\tif ( upload.details && upload.details.$div ) {\n\t\t\tupload.details.$div.remove();\n\t\t}\n\n\t\tif ( this.uploads.length === 0 ) {\n\t\t\t// If we have no more uploads, go to the \"Upload\" step. (This will go to \"Thanks\" step,\n\t\t\t// which will skip itself in load() because there are no uploads left.)\n\t\t\tthis.moveNext();\n\t\t\treturn;\n\t\t}\n\n\t\tthis.removeCopyMetadataFeature();\n\t\t// Make sure we still have more multiple uploads adding the\n\t\t// copy feature again\n\t\tif ( this.config.copyMetadataFeature ) {\n\t\t\tthis.addCopyMetadataFeature();\n\t\t}\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/controller/uw.controller.Step.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'okCount' is never reassigned. Use 'const' instead.","line":223,"column":7,"nodeType":"Identifier","messageId":"useConst","endLine":223,"endColumn":14},{"ruleId":"prefer-const","severity":2,"message":"'$buttons' is never reassigned. Use 'const' instead.","line":233,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":233,"endColumn":11},{"ruleId":"prefer-const","severity":2,"message":"'copy' is never reassigned. Use 'const' instead.","line":324,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":324,"endColumn":8}],"suppressedMessages":[],"errorCount":3,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*\n * This file is part of the MediaWiki extension MediaUploader.\n *\n * MediaUploader is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * MediaUploader is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with MediaUploader. If not, see <http://www.gnu.org/licenses/>.\n */\n\n( function ( uw ) {\n\t/**\n\t * Represents a step in the wizard.\n\t *\n\t * @class\n\t * @abstract\n\t * @param {uw.ui.Step} ui The UI object that controls this step.\n\t * @param {mw.Api} api\n\t * @param {Object} config UploadWizard config object.\n\t */\n\tuw.controller.Step = function UWControllerStep( ui, api, config ) {\n\t\tconst step = this;\n\n\t\tOO.EventEmitter.call( this );\n\n\t\t/**\n\t\t * @property {Object} config\n\t\t */\n\t\tthis.config = config;\n\t\t/**\n\t\t * @property {mw.Api} api\n\t\t */\n\t\tthis.api = api;\n\n\t\tthis.ui = ui;\n\n\t\tthis.uploads = [];\n\n\t\t// children are expected to override this with the actual step name\n\t\tthis.stepName = new Error( 'Undefined stepName' );\n\n\t\t/**\n\t\t * Upload object event handlers to be bound on load & unbound on unload.\n\t\t * This is an object literal where the keys are callback names, and\n\t\t * values all callback. These callbacks will be called with the\n\t\t * controller as content (`this`), and the upload as first argument.\n\t\t * This'll effectively be:\n\t\t * `upload.on( <key>, <value>.bind( this, upload ) );`\n\t\t *\n\t\t * @property {Object}\n\t\t */\n\t\tthis.uploadHandlers = {\n\t\t\t'remove-upload': this.removeUpload\n\t\t};\n\n\t\tthis.ui.on( 'next-step', () => {\n\t\t\tstep.moveNext();\n\t\t} );\n\n\t\tthis.ui.on( 'previous-step', () => {\n\t\t\tstep.movePrevious();\n\t\t} );\n\n\t\t/**\n\t\t * @property {uw.controller.Step} nextStep\n\t\t * The next step in the process.\n\t\t */\n\t\tthis.nextStep = null;\n\n\t\t/**\n\t\t * @property {uw.controller.Step} previousStep\n\t\t * The previous step in the process.\n\t\t */\n\t\tthis.previousStep = null;\n\t};\n\n\tOO.mixinClass( uw.controller.Step, OO.EventEmitter );\n\n\t/**\n\t * Set the next step in the process.\n\t *\n\t * @param {uw.controller.Step} step\n\t */\n\tuw.controller.Step.prototype.setNextStep = function ( step ) {\n\t\tthis.nextStep = step;\n\t\tthis.ui.enableNextButton();\n\t};\n\n\t/**\n\t * Set the previous step in the process.\n\t *\n\t * @param {uw.controller.Step} step\n\t */\n\tuw.controller.Step.prototype.setPreviousStep = function ( step ) {\n\t\tthis.previousStep = step;\n\t\tthis.ui.enablePreviousButton();\n\t};\n\n\t/**\n\t * Initialize this step.\n\t *\n\t * @param {mw.UploadWizardUpload[]} uploads List of uploads being carried forward.\n\t */\n\tuw.controller.Step.prototype.load = function ( uploads ) {\n\t\tconst step = this;\n\n\t\tthis.emit( 'load' );\n\n\t\tthis.uploads = uploads || [];\n\n\t\t// prevent the window from being closed as long as we have data\n\t\tthis.allowCloseWindow = mw.confirmCloseWindow( {\n\t\t\ttest: step.hasData.bind( this )\n\t\t} );\n\n\t\tthis.uploads.forEach( ( upload ) => {\n\t\t\tupload.state = step.stepName;\n\n\t\t\tstep.bindUploadHandlers( upload );\n\t\t} );\n\n\t\tthis.ui.load( uploads );\n\t};\n\n\t/**\n\t * Cleanup this step.\n\t */\n\tuw.controller.Step.prototype.unload = function () {\n\t\tconst step = this;\n\n\t\tthis.uploads.forEach( ( upload ) => {\n\t\t\tstep.unbindUploadHandlers( upload );\n\t\t} );\n\n\t\tthis.allowCloseWindow.release();\n\t\tthis.ui.unload();\n\n\t\tthis.emit( 'unload' );\n\t};\n\n\t/**\n\t * Move to the next step.\n\t */\n\tuw.controller.Step.prototype.moveNext = function () {\n\t\tthis.unload();\n\n\t\tif ( this.nextStep ) {\n\t\t\tthis.nextStep.load( this.uploads );\n\t\t}\n\t};\n\n\t/**\n\t * Move to the previous step.\n\t */\n\tuw.controller.Step.prototype.movePrevious = function () {\n\t\tthis.unload();\n\n\t\tif ( this.previousStep ) {\n\t\t\tthis.previousStep.load( this.uploads );\n\t\t}\n\t};\n\n\t/**\n\t * Attaches controller-specific upload event handlers.\n\t *\n\t * @param {mw.UploadWizardUpload} upload\n\t */\n\tuw.controller.Step.prototype.bindUploadHandlers = function ( upload ) {\n\t\tconst controller = this;\n\n\t\tObject.keys( this.uploadHandlers ).forEach( ( event ) => {\n\t\t\tconst callback = controller.uploadHandlers[ event ];\n\t\t\tupload.on( event, callback, [ upload ], controller );\n\t\t} );\n\t};\n\n\t/**\n\t * Removes controller-specific upload event handlers.\n\t *\n\t * @param {mw.UploadWizardUpload} upload\n\t */\n\tuw.controller.Step.prototype.unbindUploadHandlers = function ( upload ) {\n\t\tconst controller = this;\n\n\t\tObject.keys( this.uploadHandlers ).forEach( ( event ) => {\n\t\t\tconst callback = controller.uploadHandlers[ event ];\n\t\t\tupload.off( event, callback, controller );\n\t\t} );\n\t};\n\n\t/**\n\t * Check if upload is able to be put through this step's changes.\n\t *\n\t * @return {boolean}\n\t */\n\tuw.controller.Step.prototype.canTransition = function () {\n\t\treturn true;\n\t};\n\n\t/**\n\t * Figure out what to do and what options to show after the uploads have stopped.\n\t * Uploading has stopped for one of the following reasons:\n\t * 1) The user removed all uploads before they completed, in which case we are at upload.length === 0. We should start over and allow them to add new ones\n\t * 2) All succeeded - show link to next step\n\t * 3) Some failed, some succeeded - offer them the chance to retry the failed ones or go on to the next step\n\t * 4) All failed -- have to retry, no other option\n\t * In principle there could be other configurations, like having the uploads not all in error or stashed state, but\n\t * we trust that this hasn't happened.\n\t *\n\t * For uploads that have succeeded, now is the best time to add the relevant previews and details to the DOM\n\t * in the right order.\n\t *\n\t * @return {boolean} Whether all of the uploads are in a successful state.\n\t */\n\tuw.controller.Step.prototype.showNext = function () {\n\t\tlet okCount = this.getUploadStatesCount( this.finishState ),\n\t\t\t$buttons;\n\n\t\t// abort if all uploads have been removed\n\t\tif ( this.uploads.length === 0 ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.updateProgressBarCount( okCount );\n\n\t\t$buttons = this.ui.$div.find( '.mediauploader-buttons' );\n\t\t$buttons.show();\n\n\t\t$buttons.find( '.mediauploader-file-next-all-ok' ).hide();\n\t\t$buttons.find( '.mediauploader-file-next-some-failed' ).hide();\n\t\t$buttons.find( '.mediauploader-file-next-all-failed' ).hide();\n\n\t\tif ( okCount === this.uploads.length ) {\n\t\t\t$buttons.find( '.mediauploader-file-next-all-ok' ).show();\n\t\t\treturn true;\n\t\t}\n\n\t\tif ( this.getUploadStatesCount( [ 'error', 'recoverable-error' ] ) === this.uploads.length ) {\n\t\t\t$buttons.find( '.mediauploader-file-next-all-failed' ).show();\n\t\t} else if ( this.getUploadStatesCount( 'transporting' ) === 0 ) {\n\t\t\t$buttons.find( '.mediauploader-file-next-some-failed' ).show();\n\t\t}\n\n\t\treturn false;\n\t};\n\n\t/**\n\t * @param {string|string[]} states List of upload states we want the count for\n\t * @return {number}\n\t */\n\tuw.controller.Step.prototype.getUploadStatesCount = function ( states ) {\n\t\tlet count = 0;\n\n\t\t// normalize to array of states, even though input can be 1 string\n\t\tstates = Array.isArray( states ) ? states : [ states ];\n\n\t\tthis.uploads.forEach( ( upload ) => {\n\t\t\tif ( states.includes( upload.state ) ) {\n\t\t\t\tcount++;\n\t\t\t}\n\t\t} );\n\n\t\treturn count;\n\t};\n\n\t/**\n\t * Function used by some steps to update progress bar for the whole\n\t * batch of uploads.\n\t */\n\tuw.controller.Step.prototype.updateProgressBarCount = function () {};\n\n\t/**\n\t * Check if this step has data, to test if the window can be close (i.e. if\n\t * content is going to be lost)\n\t *\n\t * @return {boolean}\n\t */\n\tuw.controller.Step.prototype.hasData = function () {\n\t\treturn this.uploads.length !== 0;\n\t};\n\n\t/**\n\t * Add an upload.\n\t *\n\t * @param {mw.UploadWizardUpload} upload\n\t */\n\tuw.controller.Step.prototype.addUpload = function ( upload ) {\n\t\tthis.uploads.push( upload );\n\t};\n\n\t/**\n\t * Remove an upload.\n\t *\n\t * @param {mw.UploadWizardUpload} upload\n\t */\n\tuw.controller.Step.prototype.removeUpload = function ( upload ) {\n\t\t// remove the upload from the uploads array\n\t\tconst index = this.uploads.indexOf( upload );\n\t\tif ( index !== -1 ) {\n\t\t\tthis.uploads.splice( index, 1 );\n\t\t}\n\n\t\t// let the upload object cleanup itself!\n\t\tupload.remove();\n\t};\n\n\t/**\n\t * Remove multiple uploads.\n\t *\n\t * @param {mw.UploadWizardUpload[]} uploads\n\t */\n\tuw.controller.Step.prototype.removeUploads = function ( uploads ) {\n\t\tlet i,\n\t\t\t// clone the array of uploads, just to be sure it's not a reference\n\t\t\t// to this.uploads, which will be modified (and we can't have that\n\t\t\t// while we're looping it)\n\t\t\tcopy = uploads.slice();\n\n\t\tfor ( i = 0; i < copy.length; i++ ) {\n\t\t\tthis.removeUpload( copy[ i ] );\n\t\t}\n\t};\n\n\t/**\n\t * Clear out uploads that are in error mode, perhaps before proceeding to the next step\n\t */\n\tuw.controller.Step.prototype.removeErrorUploads = function () {\n\t\t// We must not remove items from an array while iterating over it with $.each (it causes the\n\t\t// next item to be skipped). Find and queue them first, then remove them.\n\t\tconst toRemove = [];\n\t\tthis.uploads.forEach( ( upload ) => {\n\t\t\tif ( upload.state === 'error' || upload.state === 'recoverable-error' ) {\n\t\t\t\ttoRemove.push( upload );\n\t\t\t}\n\t\t} );\n\n\t\tthis.removeUploads( toRemove );\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/controller/uw.controller.Thanks.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-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/resources/controller/uw.controller.Tutorial.js","messages":[{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":63,"column":3,"nodeType":"CallExpression","endLine":69,"endColumn":6},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .fail","line":63,"column":3,"nodeType":"CallExpression","endLine":71,"endColumn":6}],"suppressedMessages":[],"errorCount":2,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*\n * This file is part of the MediaWiki extension MediaUploader.\n *\n * MediaUploader is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * MediaUploader is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with MediaUploader. If not, see <http://www.gnu.org/licenses/>.\n */\n\n( function ( uw ) {\n\n\t/**\n\t * Tutorial step controller.\n\t *\n\t * @class\n\t * @extends uw.controller.Step\n\t * @param {mw.Api} api\n\t * @param {Object} config UploadWizard config object.\n\t */\n\tuw.controller.Tutorial = function UWControllerTutorial( api, config ) {\n\t\tconst controller = this;\n\n\t\tthis.skipPreference = Boolean( mw.user.options.get( 'upwiz_skiptutorial' ) );\n\t\tthis.newSkipPreference = this.skipPreference;\n\t\tthis.skipped = false;\n\n\t\tuw.controller.Step.call(\n\t\t\tthis,\n\t\t\tnew uw.ui.Tutorial()\n\t\t\t\t.on( 'skip-tutorial-click', ( skipped ) => {\n\t\t\t\t\t// indicate that the skip preference has changed, so we can\n\t\t\t\t\t// alter the preference when we move to another step\n\t\t\t\t\tcontroller.newSkipPreference = skipped;\n\t\t\t\t} ),\n\t\t\tapi,\n\t\t\tconfig\n\t\t);\n\n\t\tthis.stepName = 'tutorial';\n\n\t\tthis.ui.setSelected( this.skipPreference );\n\t};\n\n\tOO.inheritClass( uw.controller.Tutorial, uw.controller.Step );\n\n\t/**\n\t * Set the skip tutorial user preference via the options API\n\t *\n\t * @param {boolean} skip\n\t */\n\tuw.controller.Tutorial.prototype.setSkipPreference = function ( skip ) {\n\t\tconst controller = this,\n\t\t\tallowCloseWindow = mw.confirmCloseWindow();\n\n\t\tthis.api.postWithToken( 'options', {\n\t\t\taction: 'options',\n\t\t\tchange: skip ? 'upwiz_skiptutorial=1' : 'upwiz_skiptutorial'\n\t\t} ).done( () => {\n\t\t\tallowCloseWindow.release();\n\t\t\tcontroller.skipPreference = skip;\n\t\t} ).fail( ( code, err ) => {\n\t\t\tmw.notify( err.textStatus );\n\t\t} );\n\t};\n\n\tuw.controller.Tutorial.prototype.load = function ( uploads ) {\n\t\t// tutorial can be skipped via preference, or config (e.g. campaign config)\n\t\tconst shouldSkipTutorial = this.skipPreference || ( this.config.tutorial && this.config.tutorial.skip );\n\n\t\tuw.controller.Step.prototype.load.call( this, uploads );\n\n\t\t// we only want to skip the tutorial once - if we come back to it, we\n\t\t// don't want it to get auto-skipped again\n\t\tif ( !this.skipped && shouldSkipTutorial ) {\n\t\t\tthis.skipped = true;\n\t\t\tthis.moveNext();\n\t\t}\n\t};\n\n\tuw.controller.Tutorial.prototype.moveNext = function () {\n\t\tuw.controller.Step.prototype.moveNext.call( this );\n\t};\n\n\tuw.controller.Tutorial.prototype.unload = function () {\n\t\tif ( this.skipPreference !== this.newSkipPreference ) {\n\t\t\tthis.setSkipPreference( this.newSkipPreference );\n\t\t}\n\n\t\tuw.controller.Step.prototype.unload.call( this );\n\t};\n\n\tuw.controller.Tutorial.prototype.hasData = function () {\n\t\treturn false;\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/controller/uw.controller.Upload.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'max' is never reassigned. Use 'const' instead.","line":69,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":69,"endColumn":7},{"ruleId":"prefer-const","severity":2,"message":"'haveUploads' is never reassigned. Use 'const' instead.","line":71,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":71,"endColumn":14},{"ruleId":"prefer-const","severity":2,"message":"'fewerThanMax' is never reassigned. Use 'const' instead.","line":72,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":72,"endColumn":15},{"ruleId":"prefer-const","severity":2,"message":"'upload' is never reassigned. Use 'const' instead.","line":223,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":223,"endColumn":9},{"ruleId":"prefer-const","severity":2,"message":"'uploadObjs' is never reassigned. Use 'const' instead.","line":251,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":251,"endColumn":14},{"ruleId":"prefer-const","severity":2,"message":"'controller' is never reassigned. Use 'const' instead.","line":252,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":252,"endColumn":14},{"ruleId":"prefer-const","severity":2,"message":"'actualMaxSize' is never reassigned. Use 'const' instead.","line":307,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":307,"endColumn":17},{"ruleId":"prefer-const","severity":2,"message":"'filename' is never reassigned. Use 'const' instead.","line":311,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":311,"endColumn":12},{"ruleId":"prefer-const","severity":2,"message":"'basename' is never reassigned. Use 'const' instead.","line":312,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":312,"endColumn":12},{"ruleId":"prefer-const","severity":2,"message":"'extension' is never reassigned. Use 'const' instead.","line":335,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":335,"endColumn":12}],"suppressedMessages":[],"errorCount":10,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*\n * This file is part of the MediaWiki extension MediaUploader.\n *\n * MediaUploader is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * MediaUploader is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with MediaUploader. If not, see <http://www.gnu.org/licenses/>.\n */\n\n( function ( uw ) {\n\n\t/**\n\t * Upload step controller.\n\t *\n\t * @class\n\t * @extends uw.controller.Step\n\t * @param {mw.Api} api\n\t * @param {Object} config UploadWizard config object.\n\t */\n\tuw.controller.Upload = function UWControllerUpload( api, config ) {\n\t\tconst step = this;\n\n\t\tuw.controller.Step.call(\n\t\t\tthis,\n\t\t\tnew uw.ui.Upload( config )\n\t\t\t\t.connect( this, {\n\t\t\t\t\tretry: 'retry'\n\t\t\t\t} ),\n\t\t\tapi,\n\t\t\tconfig\n\t\t);\n\n\t\tthis.stepName = 'file';\n\t\tthis.finishState = 'stashed';\n\n\t\tthis.queue = new uw.ConcurrentQueue( {\n\t\t\tcount: this.config.maxSimultaneousConnections,\n\t\t\taction: this.transitionOne.bind( this )\n\t\t} );\n\t\tthis.queue.on( 'complete', this.showNext.bind( this ) );\n\n\t\tthis.ui.on( 'files-added', ( files ) => {\n\t\t\tconst totalFiles = files.length + step.uploads.length,\n\t\t\t\ttooManyFiles = totalFiles > step.config.maxUploads;\n\n\t\t\tif ( tooManyFiles ) {\n\t\t\t\tstep.ui.showTooManyFilesError( totalFiles );\n\t\t\t} else {\n\t\t\t\tstep.addFiles( files );\n\t\t\t}\n\t\t} );\n\t};\n\n\tOO.inheritClass( uw.controller.Upload, uw.controller.Step );\n\n\t/**\n\t * Updates the upload step data when a file is added or removed.\n\t */\n\tuw.controller.Upload.prototype.updateFileCounts = function () {\n\t\tlet fewerThanMax, haveUploads,\n\t\t\tmax = this.config.maxUploads;\n\n\t\thaveUploads = this.uploads.length > 0;\n\t\tfewerThanMax = this.uploads.length < max;\n\n\t\tthis.updateProgressBarCount( this.uploads.length );\n\t\tthis.ui.updateFileCounts( haveUploads, fewerThanMax );\n\t};\n\n\tuw.controller.Upload.prototype.load = function ( uploads ) {\n\t\tconst controller = this;\n\n\t\tuw.controller.Step.prototype.load.call( this, uploads );\n\t\tthis.updateFileCounts();\n\t\tthis.startProgressBar();\n\n\t\t// make sure queue is empty before starting this step\n\t\tthis.queue.abortExecuting();\n\n\t\tif ( uploads.length > 0 ) {\n\t\t\t/*\n\t\t\t * If we have uploads already, we'll want to to update the \"next\"\n\t\t\t * buttons accordingly. showNext() does that, but relies on upload\n\t\t\t * state being set correctly.\n\t\t\t * Since every step overwrites the upload state, we'll need to reset\n\t\t\t * it to reflect the correct upload success state.\n\t\t\t * If other files are to be added, the showNext() callback will deal\n\t\t\t * with new uploads, and still understand the existing files that\n\t\t\t * we've just reset the state for.\n\t\t\t */\n\t\t\tuploads.forEach( ( upload ) => {\n\t\t\t\tupload.state = upload.fileKey === undefined ? 'error' : controller.finishState;\n\t\t\t} );\n\n\t\t\tthis.showNext();\n\t\t}\n\t};\n\n\tuw.controller.Upload.prototype.moveNext = function () {\n\t\tthis.removeErrorUploads();\n\n\t\tuw.controller.Step.prototype.moveNext.call( this );\n\t};\n\n\t/**\n\t * Starts the upload progress bar.\n\t */\n\tuw.controller.Upload.prototype.startProgressBar = function () {\n\t\tthis.ui.showProgressBar();\n\t\tthis.progressBar = new mw.GroupProgressBar( this.ui.$progress,\n\t\t\tthis.uploads,\n\t\t\t[ 'stashed' ],\n\t\t\t[ 'error' ],\n\t\t\t'transportProgress',\n\t\t\t'transportWeight' );\n\t\tthis.progressBar.start();\n\t};\n\n\t/**\n\t * Starts progress bar if there's not an existing one.\n\t */\n\tuw.controller.Upload.prototype.maybeStartProgressBar = function () {\n\t\tif ( this.progressBarEmptyOrFinished() ) {\n\t\t\tthis.startProgressBar();\n\t\t}\n\t};\n\n\t/**\n\t * Check if there is a vacancy for a new progress bar.\n\t *\n\t * @return {boolean}\n\t */\n\tuw.controller.Upload.prototype.progressBarEmptyOrFinished = function () {\n\t\treturn !this.progressBar || this.progressBar.finished === true;\n\t};\n\n\t/**\n\t * Update success count on the progress bar.\n\t *\n\t * @param {number} okCount\n\t */\n\tuw.controller.Upload.prototype.updateProgressBarCount = function ( okCount ) {\n\t\tif ( this.progressBar ) {\n\t\t\tthis.progressBar.showCount( okCount );\n\t\t}\n\t};\n\n\tuw.controller.Upload.prototype.canTransition = function ( upload ) {\n\t\treturn (\n\t\t\tuw.controller.Step.prototype.canTransition.call( this, upload ) &&\n\t\t\tupload.state === 'new'\n\t\t);\n\t};\n\n\t/**\n\t * Perform this step's changes on one upload.\n\t *\n\t * @param {mw.UploadWizardUpload} upload\n\t * @return {jQuery.Promise}\n\t */\n\tuw.controller.Upload.prototype.transitionOne = function ( upload ) {\n\t\tconst promise = upload.start();\n\t\tthis.maybeStartProgressBar();\n\t\treturn promise;\n\t};\n\n\t/**\n\t * Queue an upload object to be uploaded.\n\t *\n\t * @param {mw.UploadWizardUpload} upload\n\t */\n\tuw.controller.Upload.prototype.queueUpload = function ( upload ) {\n\t\tif ( this.canTransition( upload ) ) {\n\t\t\tthis.queue.addItem( upload );\n\t\t}\n\t};\n\n\t/**\n\t * Kick off the upload processes.\n\t */\n\tuw.controller.Upload.prototype.startQueuedUploads = function () {\n\t\tthis.queue.startExecuting();\n\t};\n\n\tuw.controller.Upload.prototype.retry = function () {\n\t\tconst controller = this;\n\n\t\tthis.uploads.forEach( ( upload ) => {\n\t\t\tif ( upload.state === 'error' ) {\n\t\t\t\t// reset any uploads in error state back to be shiny & new\n\t\t\t\tupload.state = 'new';\n\t\t\t\tupload.ui.clearStatus();\n\t\t\t\t// and queue them\n\t\t\t\tcontroller.queueUpload( upload );\n\t\t\t}\n\t\t} );\n\n\t\tthis.startQueuedUploads();\n\t};\n\n\t/**\n\t * Create the upload interface, a handler to transport it to the server, and UI for the upload\n\t * itself; and immediately fill it with a file and add it to the list of uploads.\n\t *\n\t * @param {File} file\n\t * @return {mw.UploadWizardUpload|boolean} The new upload, or false if it can't be added\n\t */\n\tuw.controller.Upload.prototype.addFile = function ( file ) {\n\t\tlet upload;\n\n\t\tif ( this.uploads.length >= this.config.maxUploads ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tupload = new mw.UploadWizardUpload( this, file );\n\n\t\tif ( !this.validateFile( upload ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tupload.fileChangedOk();\n\n\t\t// attach controller-specific event handlers (they're automatically\n\t\t// bound on load already, but we've only just added these files...)\n\t\tthis.bindUploadHandlers( upload );\n\n\t\tthis.setUploadFilled( upload );\n\n\t\treturn upload;\n\t};\n\n\t/**\n\t * Do everything that needs to be done to start uploading a file. Calls #addFile, then appends\n\t * each mw.UploadWizardUploadInterface to the DOM and queues thumbnails to be generated.\n\t *\n\t * @param {FileList} files\n\t */\n\tuw.controller.Upload.prototype.addFiles = function ( files ) {\n\t\tlet\n\t\t\tuploadObj,\n\t\t\ti,\n\t\t\tfile,\n\t\t\tuploadObjs = [],\n\t\t\tcontroller = this;\n\n\t\tfor ( i = 0; i < files.length; i++ ) {\n\t\t\tfile = files[ i ];\n\t\t\tuploadObj = controller.addFile( file );\n\t\t\tif ( uploadObj ) {\n\t\t\t\tuploadObjs.push( uploadObj );\n\t\t\t}\n\t\t}\n\n\t\tthis.ui.displayUploads( uploadObjs );\n\t\tthis.updateFileCounts();\n\t};\n\n\t/**\n\t * Remove an upload from our array of uploads, and the HTML UI\n\t * We can remove the HTML UI directly, as jquery will just get the parent.\n\t * We need to grep through the array of uploads, since we don't know the current index.\n\t * We need to update file counts for obvious reasons.\n\t *\n\t * @param {mw.UploadWizardUpload} upload\n\t */\n\tuw.controller.Upload.prototype.removeUpload = function ( upload ) {\n\t\tuw.controller.Step.prototype.removeUpload.call( this, upload );\n\n\t\tthis.queue.removeItem( upload );\n\n\t\tthis.updateFileCounts();\n\n\t\t// check all uploads, if they're complete, show the next button\n\t\tthis.showNext();\n\t};\n\n\t/**\n\t * When an upload is filled with a real file, accept it in the list of uploads\n\t * and set up some other interfaces\n\t *\n\t * @param {mw.UploadWizardUpload} upload\n\t */\n\tuw.controller.Upload.prototype.setUploadFilled = function ( upload ) {\n\t\tthis.addUpload( upload );\n\t\t// Start uploads now, no reason to wait--leave the remove button alone\n\t\tthis.queueUpload( upload );\n\t\tthis.startQueuedUploads();\n\t};\n\n\t/**\n\t * Checks for file validity.\n\t *\n\t * @param {mw.UploadWizardUpload} upload\n\t * @return {boolean} Error in [code, info] format, or empty [] for no errors\n\t */\n\tuw.controller.Upload.prototype.validateFile = function ( upload ) {\n\t\tlet extension,\n\t\t\ti,\n\t\t\tactualMaxSize = mw.UploadWizard.config.maxMwUploadSize,\n\n\t\t\t// Check if filename is acceptable\n\t\t\t// TODO sanitize filename\n\t\t\tfilename = upload.getFilename(),\n\t\t\tbasename = upload.getBasename();\n\n\t\t// check to see if this file has already been selected for upload\n\t\tfor ( i = 0; i < this.uploads.length; i++ ) {\n\t\t\tif ( upload !== this.uploads[ i ] && filename === this.uploads[ i ].getFilename() ) {\n\t\t\t\tthis.ui.showDuplicateError( filename, basename );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// check if the filename is valid\n\t\tupload.setTitle( basename );\n\t\tif ( !upload.title ) {\n\t\t\tif ( !basename.includes( '.' ) ) {\n\t\t\t\tthis.ui.showMissingExtensionError( filename );\n\t\t\t\treturn false;\n\t\t\t} else {\n\t\t\t\tthis.ui.showUnparseableFilenameError( filename );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// check if extension is acceptable\n\t\textension = upload.title.getExtension();\n\t\tif ( !extension ) {\n\t\t\tthis.ui.showMissingExtensionError( filename );\n\t\t\treturn false;\n\t\t}\n\n\t\tif (\n\t\t\tmw.UploadWizard.config.fileExtensions !== null &&\n\t\t\t!mw.UploadWizard.config.fileExtensions.includes( extension.toLowerCase() )\n\t\t) {\n\t\t\tthis.ui.showBadExtensionError( filename, extension );\n\t\t\treturn false;\n\t\t}\n\n\t\t// make sure the file isn't too large\n\t\tif ( upload.file.size ) {\n\t\t\tupload.transportWeight = upload.file.size;\n\t\t\tif ( upload.transportWeight > actualMaxSize ) {\n\t\t\t\tthis.ui.showFileTooLargeError( actualMaxSize, upload.transportWeight );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/controller/uw.controller.base.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-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/resources/deed/uw.deed.Abstract.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-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/resources/deed/uw.deed.Custom.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-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/resources/deed/uw.deed.External.js","messages":[{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":66,"column":10,"nodeType":"MemberExpression","messageId":"forbidden","endLine":66,"endColumn":23}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*\n * This file is part of the MediaWiki extension MediaUploader.\n *\n * MediaUploader is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * MediaUploader is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with MediaUploader. If not, see <http://www.gnu.org/licenses/>.\n */\n\n( function ( uw ) {\n\t/**\n\t * @param {Object} config The UW config\n\t * @param {mw.UploadWizardUpload} upload Uploads that this deed refers to\n\t * @class uw.deed.External\n\t * @constructor\n\t */\n\tuw.deed.External = function UWDeedExternal( config, upload ) {\n\t\tuw.deed.Custom.call( this, config, upload );\n\n\t\tthis.licenseInput = new mw.UploadWizardLicenseInput(\n\t\t\tconfig.licensing.thirdParty,\n\t\t\t1,\n\t\t\tupload.api\n\t\t);\n\t\tthis.licenseInput.$element.addClass( 'mediauploader-External-deed' );\n\t\tthis.licenseInputField = new uw.FieldLayout( this.licenseInput );\n\t\tthis.licenseInput.setDefaultValues();\n\t};\n\n\tOO.inheritClass( uw.deed.External, uw.deed.Custom );\n\n\tuw.deed.External.prototype.unload = function () {\n\t\tthis.licenseInput.unload();\n\t};\n\n\t/**\n\t * @return {uw.FieldLayout[]} Fields that need validation\n\t */\n\tuw.deed.External.prototype.getFields = function () {\n\t\treturn [ this.licenseInputField ];\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.deed.External.prototype.getLicenseWikiText = function () {\n\t\tif ( this.upload.file.licenseValue ) {\n\t\t\treturn this.upload.file.licenseValue + this.licenseInput.getWikiText();\n\t\t} else {\n\t\t\treturn this.licenseInput.getWikiText();\n\t\t}\n\t};\n\n\t/**\n\t * @return {Object}\n\t */\n\tuw.deed.External.prototype.getSerialized = function () {\n\t\treturn Object.assign( uw.deed.Custom.prototype.getSerialized.call( this ), {\n\t\t\tlicense: this.licenseInput.getSerialized()\n\t\t} );\n\t};\n\n\t/**\n\t * @param {Object} serialized\n\t */\n\tuw.deed.External.prototype.setSerialized = function ( serialized ) {\n\t\tuw.deed.Custom.prototype.setSerialized.call( this, serialized );\n\n\t\tif ( serialized.license ) {\n\t\t\tthis.licenseInput.setSerialized( serialized.license );\n\t\t}\n\t};\n}( mw.uploadWizard ) );\n","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-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/resources/deed/uw.deed.None.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-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/resources/deed/uw.deed.OwnWork.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'deed' is never reassigned. Use 'const' instead.","line":29,"column":7,"nodeType":"Identifier","messageId":"useConst","endLine":29,"endColumn":11},{"ruleId":"prefer-const","severity":2,"message":"'deed' is never reassigned. Use 'const' instead.","line":88,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":88,"endColumn":7},{"ruleId":"prefer-const","severity":2,"message":"'languageCode' is never reassigned. Use 'const' instead.","line":89,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":89,"endColumn":15},{"ruleId":"prefer-const","severity":2,"message":"'defaultLicense' is never reassigned. Use 'const' instead.","line":91,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":91,"endColumn":17},{"ruleId":"prefer-const","severity":2,"message":"'defaultLicConfig' is never reassigned. Use 'const' instead.","line":92,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":92,"endColumn":19},{"ruleId":"prefer-const","severity":2,"message":"'$defaultLicenseLink' is never reassigned. Use 'const' instead.","line":99,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":99,"endColumn":22},{"ruleId":"prefer-const","severity":2,"message":"'$crossfader' is never reassigned. Use 'const' instead.","line":125,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":125,"endColumn":14},{"ruleId":"prefer-const","severity":2,"message":"'$customDiv' is never reassigned. Use 'const' instead.","line":128,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":128,"endColumn":13},{"ruleId":"prefer-const","severity":2,"message":"'crossfaderWidget' is never reassigned. Use 'const' instead.","line":136,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":136,"endColumn":19},{"ruleId":"prefer-const","severity":2,"message":"'$formFields' is never reassigned. Use 'const' instead.","line":148,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":148,"endColumn":14},{"ruleId":"prefer-const","severity":2,"message":"'$toggler' is never reassigned. Use 'const' instead.","line":152,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":152,"endColumn":11},{"ruleId":"prefer-const","severity":2,"message":"'author' is never reassigned. Use 'const' instead.","line":192,"column":7,"nodeType":"Identifier","messageId":"useConst","endLine":192,"endColumn":13},{"ruleId":"prefer-const","severity":2,"message":"'userPageTitle' is never reassigned. Use 'const' instead.","line":200,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":200,"endColumn":16},{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":215,"column":10,"nodeType":"MemberExpression","messageId":"forbidden","endLine":215,"endColumn":23},{"ruleId":"prefer-const","severity":2,"message":"'ownWork' is never reassigned. Use 'const' instead.","line":255,"column":16,"nodeType":"Identifier","messageId":"useConst","endLine":255,"endColumn":23},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":277,"column":3,"nodeType":"CallExpression","endLine":280,"endColumn":7},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":297,"column":3,"nodeType":"CallExpression","endLine":300,"endColumn":7}],"suppressedMessages":[{"ruleId":"mediawiki/msg-doc","severity":1,"message":"All possible message keys should be documented. See https://w.wiki/4r9a for details.","line":111,"column":28,"nodeType":"CallExpression","endLine":113,"endColumn":5,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"mediawiki/msg-doc","severity":1,"message":"All possible message keys should be documented. See https://w.wiki/4r9a for details.","line":118,"column":5,"nodeType":"CallExpression","endLine":121,"endColumn":6,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-slide","severity":2,"message":"Prefer CSS transitions to .slideUp","line":284,"column":3,"nodeType":"CallExpression","endLine":285,"endColumn":14,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-animate","severity":2,"message":"Prefer CSS transitions to .animate","line":284,"column":3,"nodeType":"CallExpression","endLine":286,"endColumn":66,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-slide","severity":2,"message":"Prefer CSS transitions to .slideDown","line":304,"column":3,"nodeType":"CallExpression","endLine":305,"endColumn":16,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-animate","severity":2,"message":"Prefer CSS transitions to .animate","line":304,"column":3,"nodeType":"CallExpression","endLine":306,"endColumn":88,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":16,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*\n * This file is part of the MediaWiki extension MediaUploader.\n *\n * MediaUploader is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * MediaUploader is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with MediaUploader. If not, see <http://www.gnu.org/licenses/>.\n */\n\n( function ( uw ) {\n\t/**\n\t * Set up the form and deed object for the deed option that says these uploads are all the user's own work.\n\t *\n\t * @class uw.deed.OwnWork\n\t * @constructor\n\t * @param {Object} config The UW config\n\t * @param {mw.UploadWizardUpload[]} uploads Array of uploads that this deed refers to\n\t * @param {mw.Api} api API object - useful for doing previews\n\t */\n\tuw.deed.OwnWork = function UWDeedOwnWork( config, uploads, api ) {\n\t\tlet deed = this,\n\t\t\tprefAuthName = mw.user.options.get( 'upwiz_licensename' );\n\n\t\tuw.deed.Abstract.call( this, 'ownwork', config );\n\n\t\tthis.uploadCount = uploads.length;\n\n\t\tif ( !prefAuthName ) {\n\t\t\tprefAuthName = mw.config.get( 'wgUserName' );\n\t\t}\n\n\t\t// copyright holder\n\t\tthis.authorInput = new OO.ui.TextInputWidget( {\n\t\t\tname: 'author',\n\t\t\ttitle: mw.message( 'mediauploader-tooltip-sign' ).text(),\n\t\t\tvalue: prefAuthName,\n\t\t\tclasses: [ 'mediauploader-sign' ]\n\t\t} );\n\t\tthis.fakeAuthorInput = new OO.ui.TextInputWidget( {\n\t\t\treadOnly: true,\n\t\t\tvalue: prefAuthName,\n\t\t\tclasses: [ 'mediauploader-sign' ]\n\t\t} );\n\t\tthis.authorInput.on( 'change', () => {\n\t\t\tdeed.fakeAuthorInput.setValue( deed.authorInput.getValue() );\n\t\t} );\n\n\t\t// \"use a different license\"\n\t\tthis.licenseInput = new mw.UploadWizardLicenseInput(\n\t\t\tthis.config.licensing.ownWork,\n\t\t\tthis.uploadCount,\n\t\t\tapi\n\t\t);\n\t\tthis.licenseInput.$element.addClass( 'mediauploader-deed-license' );\n\t\tthis.licenseInputField = new uw.FieldLayout( this.licenseInput );\n\t};\n\n\tOO.inheritClass( uw.deed.OwnWork, uw.deed.Abstract );\n\n\tuw.deed.OwnWork.prototype.unload = function () {\n\t\t// No licenseInput is present if there's no custom licenses allowed (e.g. campaigns)\n\t\tif ( this.licenseInput !== undefined ) {\n\t\t\tthis.licenseInput.unload();\n\t\t}\n\t};\n\n\t/**\n\t * @return {uw.FieldLayout[]} Fields that need validation\n\t */\n\tuw.deed.OwnWork.prototype.getFields = function () {\n\t\treturn [ this.authorInputField, this.licenseInputField ];\n\t};\n\n\tuw.deed.OwnWork.prototype.setFormFields = function ( $selector ) {\n\t\tlet $customDiv, $formFields, $toggler, crossfaderWidget, defaultLicense,\n\t\t\tdefaultLicenseURL, $defaultLicenseLink, $standardDiv, $crossfader,\n\t\t\tdeed, languageCode, defaultLicConfig;\n\n\t\tthis.$selector = $selector;\n\t\tdeed = this;\n\t\tlanguageCode = mw.config.get( 'wgUserLanguage' );\n\n\t\tdefaultLicense = this.getDefaultLicenses()[ 0 ];\n\t\tdefaultLicConfig = this.config.licenses[ defaultLicense ];\n\n\t\tdefaultLicenseURL = defaultLicConfig.url === undefined ?\n\t\t\t'#missing license URL' : defaultLicConfig.url;\n\t\tif ( defaultLicConfig.languageCodePrefix !== undefined ) {\n\t\t\tdefaultLicenseURL += defaultLicConfig.languageCodePrefix + languageCode;\n\t\t}\n\t\t$defaultLicenseLink = $( '<a>' ).attr( { target: '_blank', href: defaultLicenseURL } );\n\n\t\tthis.$form = $( '<form>' );\n\n\t\t/* eslint-disable mediawiki/msg-doc */\n\t\t$standardDiv = $( '<div>' ).addClass( 'mediauploader-standard' ).append(\n\t\t\t$( '<p>' ).msg(\n\t\t\t\t'mediauploader-source-ownwork-assert',\n\t\t\t\tthis.uploadCount,\n\t\t\t\tthis.authorInput.$element,\n\t\t\t\t$defaultLicenseLink,\n\t\t\t\tmw.user\n\t\t\t).append( ' ' ).append( mw.message(\n\t\t\t\tdefaultLicConfig.msg, '', defaultLicenseURL\n\t\t\t).parse() )\n\t\t);\n\n\t\tif ( defaultLicConfig.explainMsg !== undefined ) {\n\t\t\t$standardDiv = $standardDiv.append(\n\t\t\t\t$( '<p>' ).addClass( 'mwe-small-print' ).msg(\n\t\t\t\t\tdefaultLicConfig.explainMsg,\n\t\t\t\t\tthis.uploadCount\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t$crossfader = $( '<div>' ).addClass( 'mediauploader-crossfader' ).append( $standardDiv );\n\t\t/* eslint-enable mediawiki/msg-doc */\n\n\t\t$customDiv = $( '<div>' ).addClass( 'mediauploader-custom' ).append(\n\t\t\t$( '<p>' ).msg( 'mediauploader-source-ownwork-assert',\n\t\t\t\tthis.uploadCount,\n\t\t\t\tthis.fakeAuthorInput.$element )\n\t\t);\n\n\t\t$crossfader.append( $customDiv );\n\n\t\tcrossfaderWidget = new OO.ui.Widget();\n\t\tcrossfaderWidget.$element.append( $crossfader );\n\t\t// See uw.DetailsWidget\n\t\tcrossfaderWidget.getErrors = this.getAuthorErrors.bind( this, this.authorInput );\n\t\tcrossfaderWidget.getWarnings = this.getAuthorWarnings.bind( this, this.authorInput );\n\n\t\tthis.authorInputField = new uw.FieldLayout( crossfaderWidget );\n\t\t// Aggregate 'change' event\n\t\tthis.authorInput.on( 'change', OO.ui.debounce( () => {\n\t\t\tcrossfaderWidget.emit( 'change' );\n\t\t}, 500 ) );\n\n\t\t$formFields = $( '<div>' ).addClass( 'mediauploader-deed-form-internal' )\n\t\t\t.append( this.authorInputField.$element );\n\n\t\t// FIXME: Move CSS rule to CSS file\n\t\t$toggler = $( '<p>' ).addClass( 'mwe-more-options' ).css( 'text-align', 'right' )\n\t\t\t.append( $( '<a>' )\n\t\t\t\t.msg( 'mediauploader-license-show-all' )\n\t\t\t\t.on( 'click', () => {\n\t\t\t\t\tif ( $crossfader.data( 'crossfadeDisplay' ).get( 0 ) === $customDiv.get( 0 ) ) {\n\t\t\t\t\t\tdeed.standardLicense();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdeed.customLicense();\n\t\t\t\t\t}\n\t\t\t\t} ) );\n\n\t\t$formFields.append( this.licenseInputField.$element.hide(), $toggler );\n\n\t\tthis.$form.append( $formFields ).appendTo( $selector );\n\n\t\t// done after added to the DOM, so there are true heights\n\t\t$crossfader.morphCrossfader();\n\n\t\tthis.setDefaultLicenses();\n\t};\n\n\tuw.deed.OwnWork.prototype.setDefaultLicenses = function () {\n\t\tconst defaultLicenses = {};\n\t\tthis.getDefaultLicenses().forEach( ( licName ) => {\n\t\t\tdefaultLicenses[ licName ] = true;\n\t\t} );\n\t\tthis.licenseInput.setValues( defaultLicenses );\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.deed.OwnWork.prototype.getSourceWikiText = function () {\n\t\treturn mw.message( 'mediauploader-content-source-ownwork' ).plain();\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.deed.OwnWork.prototype.getAuthorWikiText = function () {\n\t\tlet author = this.authorInput.getValue(),\n\t\t\tuserPageTitle;\n\n\t\tif ( author.includes( '[' ) || author.includes( '{' ) ) {\n\t\t\treturn author;\n\t\t}\n\n\t\t// Construct a Title for the user page to get the localized NS prefix\n\t\tuserPageTitle = new mw.Title( 'User:' + mw.config.get( 'wgUserName' ) );\n\t\treturn '[[' + userPageTitle.getPrefixedText() + '|' + author + ']]';\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.deed.OwnWork.prototype.getLicenseWikiText = function () {\n\t\treturn this.licenseInput.getWikiText();\n\t};\n\n\t/**\n\t * @return {Object}\n\t */\n\tuw.deed.OwnWork.prototype.getSerialized = function () {\n\t\treturn Object.assign( uw.deed.Abstract.prototype.getSerialized.call( this ), {\n\t\t\tauthor: this.authorInput.getValue(),\n\t\t\tlicense: this.licenseInput.getSerialized()\n\t\t} );\n\t};\n\n\t/**\n\t * @param {Object} serialized\n\t */\n\tuw.deed.OwnWork.prototype.setSerialized = function ( serialized ) {\n\t\tuw.deed.Abstract.prototype.setSerialized.call( this, serialized );\n\n\t\tif ( serialized.author ) {\n\t\t\tthis.authorInput.setValue( serialized.author );\n\t\t}\n\n\t\tif ( serialized.license ) {\n\t\t\t// expand licenses container\n\t\t\tthis.customLicense();\n\t\t\tthis.licenseInput.setSerialized( serialized.license );\n\t\t}\n\t};\n\n\tuw.deed.OwnWork.prototype.swapNodes = function ( a, b ) {\n\t\tconst\n\t\t\tparentA = a.parentNode,\n\t\t\tparentB = b.parentNode,\n\t\t\tnextA = a.nextSibling,\n\t\t\tnextB = b.nextSibling;\n\n\t\t// This is not correct if a and b are siblings, or if one is a child of the\n\t\t// other, or if they're detached, or maybe in other cases, but we don't care\n\t\tparentA[ nextA ? 'insertBefore' : 'appendChild' ]( b, nextA );\n\t\tparentB[ nextB ? 'insertBefore' : 'appendChild' ]( a, nextB );\n\t};\n\n\t/**\n\t * @return {string[]}\n\t */\n\tuw.deed.OwnWork.prototype.getDefaultLicenses = function () {\n\t\tlet license, ownWork = this.config.licensing.ownWork;\n\n\t\tif ( this.config.licensing.defaultType === 'ownWork' ) {\n\t\t\tlicense = ownWork.defaults;\n\t\t\treturn license instanceof Array ? license : [ license ];\n\t\t} else {\n\t\t\tif ( ownWork.licenses ) {\n\t\t\t\treturn [ ownWork.licenses[ 0 ] ];\n\t\t\t} else {\n\t\t\t\treturn [ ownWork.licenseGroups[ 0 ].licenses[ 0 ] ];\n\t\t\t}\n\t\t}\n\t};\n\n\tuw.deed.OwnWork.prototype.standardLicense = function () {\n\t\tconst deed = this,\n\t\t\t$crossfader = this.$selector.find( '.mediauploader-crossfader' ),\n\t\t\t$standardDiv = this.$selector.find( '.mediauploader-standard' ),\n\t\t\t$toggler = this.$selector.find( '.mwe-more-options a' );\n\n\t\tthis.setDefaultLicenses();\n\n\t\t$crossfader.morphCrossfade( $standardDiv )\n\t\t\t.promise().done( () => {\n\t\t\t\tdeed.swapNodes( deed.authorInput.$element[ 0 ], deed.fakeAuthorInput.$element[ 0 ] );\n\t\t\t} );\n\n\t\t// FIXME: Use CSS transition\n\t\t// eslint-disable-next-line no-jquery/no-slide, no-jquery/no-animate\n\t\tthis.licenseInputField.$element\n\t\t\t.slideUp()\n\t\t\t.animate( { opacity: 0 }, { queue: false, easing: 'linear' } );\n\n\t\t$toggler.msg( 'mediauploader-license-show-all' );\n\t};\n\n\tuw.deed.OwnWork.prototype.customLicense = function () {\n\t\tconst deed = this,\n\t\t\t$crossfader = this.$selector.find( '.mediauploader-crossfader' ),\n\t\t\t$customDiv = this.$selector.find( '.mediauploader-custom' ),\n\t\t\t$toggler = this.$selector.find( '.mwe-more-options a' );\n\n\t\t$crossfader.morphCrossfade( $customDiv )\n\t\t\t.promise().done( () => {\n\t\t\t\tdeed.swapNodes( deed.authorInput.$element[ 0 ], deed.fakeAuthorInput.$element[ 0 ] );\n\t\t\t} );\n\n\t\t// FIXME: Use CSS transition\n\t\t// eslint-disable-next-line no-jquery/no-slide, no-jquery/no-animate\n\t\tthis.licenseInputField.$element\n\t\t\t.slideDown()\n\t\t\t.css( { opacity: 0 } ).animate( { opacity: 1 }, { queue: false, easing: 'linear' } );\n\n\t\t$toggler.msg( 'mediauploader-license-show-recommended' );\n\t};\n\n\t/**\n\t * @param {OO.ui.InputWidget} input\n\t * @return {jQuery.Promise}\n\t */\n\tuw.deed.OwnWork.prototype.getAuthorErrors = function ( input ) {\n\t\tconst\n\t\t\terrors = [],\n\t\t\tminLength = this.config.minAuthorLength,\n\t\t\tmaxLength = this.config.maxAuthorLength,\n\t\t\ttext = input.getValue().trim();\n\n\t\tif ( text === '' ) {\n\t\t\terrors.push( mw.message( 'mediauploader-error-signature-blank' ) );\n\t\t} else if ( text.length < minLength ) {\n\t\t\terrors.push( mw.message( 'mediauploader-error-signature-too-short', minLength ) );\n\t\t} else if ( text.length > maxLength ) {\n\t\t\terrors.push( mw.message( 'mediauploader-error-signature-too-long', maxLength ) );\n\t\t}\n\n\t\treturn $.Deferred().resolve( errors ).promise();\n\t};\n\n\t/**\n\t * @return {jQuery.Promise}\n\t */\n\tuw.deed.OwnWork.prototype.getAuthorWarnings = function () {\n\t\treturn $.Deferred().resolve( [] ).promise();\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/deed/uw.deed.ThirdParty.js","messages":[{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":178,"column":10,"nodeType":"MemberExpression","messageId":"forbidden","endLine":178,"endColumn":23}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*\n * This file is part of the MediaWiki extension MediaUploader.\n *\n * MediaUploader is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * MediaUploader is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with MediaUploader. If not, see <http://www.gnu.org/licenses/>.\n */\n\n( function ( uw ) {\n\t/**\n\t * Set up the form and deed object for the deed option that says these uploads are the work of a third party.\n\t *\n\t * @class uw.deed.ThirdParty\n\t * @constructor\n\t * @param {Object} config The UW config\n\t * @param {mw.UploadWizardUpload[]} uploads Array of uploads that this deed refers to\n\t * @param {mw.Api} api API object - useful for doing previews\n\t */\n\tuw.deed.ThirdParty = function UWDeedThirdParty( config, uploads, api ) {\n\t\tconst deed = this;\n\n\t\tuw.deed.Abstract.call( this, 'thirdparty', config );\n\n\t\tthis.uploadCount = uploads.length;\n\n\t\tthis.sourceInput = new OO.ui.MultilineTextInputWidget( {\n\t\t\tautosize: true,\n\t\t\tclasses: [ 'mwe-source' ],\n\t\t\tname: 'source'\n\t\t} );\n\t\tthis.sourceInput.$input.attr( 'id', 'mwe-source-' + this.getInstanceCount() );\n\t\t// See uw.DetailsWidget\n\t\tthis.sourceInput.getErrors = function () {\n\t\t\tconst\n\t\t\t\terrors = [],\n\t\t\t\tminLength = deed.config.minSourceLength,\n\t\t\t\tmaxLength = deed.config.maxSourceLength,\n\t\t\t\ttext = this.getValue().trim();\n\n\t\t\tif ( text === '' ) {\n\t\t\t\terrors.push( mw.message( 'mediauploader-error-blank' ) );\n\t\t\t} else if ( text.length < minLength ) {\n\t\t\t\terrors.push( mw.message( 'mediauploader-error-too-short', minLength ) );\n\t\t\t} else if ( text.length > maxLength ) {\n\t\t\t\terrors.push( mw.message( 'mediauploader-error-too-long', maxLength ) );\n\t\t\t}\n\n\t\t\treturn $.Deferred().resolve( errors ).promise();\n\t\t};\n\t\t// See uw.DetailsWidget\n\t\tthis.sourceInput.getWarnings = function () {\n\t\t\treturn $.Deferred().resolve( [] ).promise();\n\t\t};\n\t\tthis.sourceInputField = new uw.FieldLayout( this.sourceInput, {\n\t\t\tlabel: mw.message( 'mediauploader-source' ).text(),\n\t\t\thelp: mw.message( 'mediauploader-tooltip-source' ).text(),\n\t\t\trequired: true\n\t\t} );\n\n\t\tthis.authorInput = new OO.ui.MultilineTextInputWidget( {\n\t\t\tautosize: true,\n\t\t\tclasses: [ 'mwe-author' ],\n\t\t\tname: 'author'\n\t\t} );\n\t\tthis.authorInput.$input.attr( 'id', 'mwe-author-' + this.getInstanceCount() );\n\t\t// See uw.DetailsWidget\n\t\tthis.authorInput.getErrors = function () {\n\t\t\tconst\n\t\t\t\terrors = [],\n\t\t\t\tminLength = deed.config.minAuthorLength,\n\t\t\t\tmaxLength = deed.config.maxAuthorLength,\n\t\t\t\ttext = this.getValue().trim();\n\n\t\t\tif ( text === '' ) {\n\t\t\t\terrors.push( mw.message( 'mediauploader-error-blank' ) );\n\t\t\t} else if ( text.length < minLength ) {\n\t\t\t\terrors.push( mw.message( 'mediauploader-error-too-short', minLength ) );\n\t\t\t} else if ( text.length > maxLength ) {\n\t\t\t\terrors.push( mw.message( 'mediauploader-error-too-long', maxLength ) );\n\t\t\t}\n\n\t\t\treturn $.Deferred().resolve( errors ).promise();\n\t\t};\n\t\t// See uw.DetailsWidget\n\t\tthis.authorInput.getWarnings = function () {\n\t\t\treturn $.Deferred().resolve( [] ).promise();\n\t\t};\n\t\tthis.authorInputField = new uw.FieldLayout( this.authorInput, {\n\t\t\tlabel: mw.message( 'mediauploader-author' ).text(),\n\t\t\thelp: mw.message( 'mediauploader-tooltip-author' ).text(),\n\t\t\trequired: true\n\t\t} );\n\n\t\tthis.licenseInput = new mw.UploadWizardLicenseInput(\n\t\t\tthis.config.licensing.thirdParty,\n\t\t\tthis.uploadCount,\n\t\t\tapi\n\t\t);\n\t\tthis.licenseInput.$element.addClass( 'mediauploader-deed-license-groups' );\n\t\tthis.licenseInput.setDefaultValues();\n\t\tthis.licenseInputField = new uw.FieldLayout( this.licenseInput, {\n\t\t\tlabel: mw.message( 'mediauploader-source-thirdparty-cases', this.uploadCount ).text(),\n\t\t\trequired: true\n\t\t} );\n\t};\n\n\tOO.inheritClass( uw.deed.ThirdParty, uw.deed.Abstract );\n\n\tuw.deed.ThirdParty.prototype.unload = function () {\n\t\tthis.licenseInput.unload();\n\t};\n\n\t/**\n\t * @return {uw.FieldLayout[]} Fields that need validation\n\t */\n\tuw.deed.ThirdParty.prototype.getFields = function () {\n\t\treturn [ this.authorInputField, this.sourceInputField, this.licenseInputField ];\n\t};\n\n\tuw.deed.ThirdParty.prototype.setFormFields = function ( $selector ) {\n\t\tconst $formFields = $( '<div>' ).addClass( 'mediauploader-deed-form-internal' );\n\n\t\tthis.$form = $( '<form>' );\n\n\t\tif ( this.uploadCount > 1 ) {\n\t\t\t$formFields.append( $( '<div>' ).msg( 'mediauploader-source-thirdparty-custom-multiple-intro' ) );\n\t\t}\n\n\t\t$formFields.append(\n\t\t\t$( '<div>' ).addClass( 'mediauploader-source-thirdparty-custom-multiple-intro' ),\n\t\t\t$( '<div>' ).addClass( 'mediauploader-thirdparty-fields' )\n\t\t\t\t.append( this.sourceInputField.$element ),\n\t\t\t$( '<div>' ).addClass( 'mediauploader-thirdparty-fields' )\n\t\t\t\t.append( this.authorInputField.$element ),\n\t\t\t$( '<div>' ).addClass( 'mediauploader-thirdparty-license' )\n\t\t\t\t.append( this.licenseInputField.$element )\n\t\t);\n\n\t\tthis.$form.append( $formFields );\n\n\t\t$selector.append( this.$form );\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.deed.ThirdParty.prototype.getSourceWikiText = function () {\n\t\treturn this.sourceInput.getValue();\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.deed.ThirdParty.prototype.getAuthorWikiText = function () {\n\t\treturn this.authorInput.getValue();\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.deed.ThirdParty.prototype.getLicenseWikiText = function () {\n\t\treturn this.licenseInput.getWikiText();\n\t};\n\n\t/**\n\t * @return {Object}\n\t */\n\tuw.deed.ThirdParty.prototype.getSerialized = function () {\n\t\treturn Object.assign( uw.deed.Abstract.prototype.getSerialized.call( this ), {\n\t\t\tsource: this.sourceInput.getValue(),\n\t\t\tauthor: this.authorInput.getValue(),\n\t\t\tlicense: this.licenseInput.getSerialized()\n\t\t} );\n\t};\n\n\t/**\n\t * @param {Object} serialized\n\t */\n\tuw.deed.ThirdParty.prototype.setSerialized = function ( serialized ) {\n\t\tuw.deed.Abstract.prototype.setSerialized.call( this, serialized );\n\n\t\tif ( serialized.source ) {\n\t\t\tthis.sourceInput.setValue( serialized.source );\n\t\t}\n\t\tif ( serialized.author ) {\n\t\t\tthis.authorInput.setValue( serialized.author );\n\t\t}\n\t\tif ( serialized.license ) {\n\t\t\tthis.licenseInput.setSerialized( serialized.license );\n\t\t}\n\t};\n}( mw.uploadWizard ) );\n","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-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/resources/deed/uw.deed.base.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-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/resources/details/uw.CategoriesDetailsWidget.js","messages":[{"ruleId":"no-mixed-spaces-and-tabs","severity":2,"message":"Mixed spaces and tabs.","line":87,"column":3,"nodeType":"Program","messageId":"mixedSpacesAndTabs","endLine":87,"endColumn":5},{"ruleId":"implicit-arrow-linebreak","severity":2,"message":"Expected no linebreak before this expression.","line":87,"column":5,"nodeType":"Punctuator","messageId":"unexpected","endLine":87,"endColumn":6},{"ruleId":"no-mixed-spaces-and-tabs","severity":2,"message":"Mixed spaces and tabs.","line":88,"column":2,"nodeType":"Program","messageId":"mixedSpacesAndTabs","endLine":88,"endColumn":4},{"ruleId":"prefer-const","severity":2,"message":"'categories' is never reassigned. Use 'const' instead.","line":98,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":98,"endColumn":13},{"ruleId":"no-mixed-spaces-and-tabs","severity":2,"message":"Mixed spaces and tabs.","line":128,"column":3,"nodeType":"Program","messageId":"mixedSpacesAndTabs","endLine":128,"endColumn":5},{"ruleId":"implicit-arrow-linebreak","severity":2,"message":"Expected no linebreak before this expression.","line":128,"column":5,"nodeType":"Punctuator","messageId":"unexpected","endLine":128,"endColumn":6},{"ruleId":"no-mixed-spaces-and-tabs","severity":2,"message":"Mixed spaces and tabs.","line":129,"column":2,"nodeType":"Program","messageId":"mixedSpacesAndTabs","endLine":129,"endColumn":4}],"suppressedMessages":[],"errorCount":7,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"( function ( uw ) {\n\n\tconst NS_CATEGORY = mw.config.get( 'wgNamespaceIds' ).category;\n\n\t/**\n\t * A categories field in UploadWizard's \"Details\" step form.\n\t *\n\t * @extends uw.DetailsWidget\n\t * @param {Object} config\n\t */\n\tuw.CategoriesDetailsWidget = function UWCategoriesDetailsWidget( config ) {\n\t\tconst catDetails = this;\n\t\tthis.config = config;\n\n\t\tuw.CategoriesDetailsWidget.parent.call( this, this.config );\n\n\t\tthis.categoriesWidget = new mw.widgets.CategoryMultiselectWidget( {\n\t\t\tdisabled: this.config.disabled\n\t\t} );\n\n\t\tthis.categoriesWidget.createTagItemWidget = function ( data ) {\n\t\t\tconst widget = this.constructor.prototype.createTagItemWidget.call( this, data );\n\t\t\tif ( !widget ) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\twidget.setMissing = function ( missing ) {\n\t\t\t\tthis.constructor.prototype.setMissing.call( this, missing );\n\t\t\t\t// Aggregate 'change' event\n\t\t\t\tcatDetails.emit( 'change' );\n\t\t\t};\n\t\t\treturn widget;\n\t\t};\n\n\t\tthis.$element.addClass( 'mediauploader-categoriesDetailsWidget' );\n\t\tthis.$element.append( this.categoriesWidget.$element );\n\n\t\t// Aggregate 'change' event\n\t\tthis.categoriesWidget.connect( this, { change: [ 'emit', 'change' ] } );\n\t};\n\tOO.inheritClass( uw.CategoriesDetailsWidget, uw.DetailsWidget );\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.CategoriesDetailsWidget.prototype.getErrors = function () {\n\t\tconst errors = [];\n\n\t\tif ( this.config.required && this.categoriesWidget.getItems().length === 0 ) {\n\t\t\terrors.push( mw.message( 'mediauploader-error-blank' ) );\n\t\t}\n\n\t\treturn $.Deferred().resolve( errors ).promise();\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.CategoriesDetailsWidget.prototype.getWarnings = function () {\n\t\tconst warnings = [];\n\t\tthis.getEmptyWarning( this.categoriesWidget.getItems().length === 0, warnings );\n\n\t\tif ( this.categoriesWidget.getItems().some( ( item ) => item.missing ) ) {\n\t\t\twarnings.push( mw.message( 'mediauploader-categories-missing' ) );\n\t\t}\n\t\treturn $.Deferred().resolve( warnings ).promise();\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.CategoriesDetailsWidget.prototype.getWikiText = function () {\n\t\tlet hiddenCats, missingCatsWikiText, categories, wikiText;\n\n\t\thiddenCats = [];\n\t\tif ( this.config.hiddenDefault ) {\n\t\t\thiddenCats = hiddenCats.concat( this.config.hiddenDefault );\n\t\t}\n\t\tif ( mw.UploadWizard.config.trackingCategory ) {\n\t\t\tif ( mw.UploadWizard.config.trackingCategory.campaign &&\n\t\t\t\tmw.UploadWizard.config.trackingCategory.autoAdd\n\t\t\t) {\n\t\t\t\thiddenCats.push( mw.UploadWizard.config.trackingCategory.campaign );\n\t\t\t}\n\t\t}\n\t\thiddenCats = hiddenCats.filter( ( cat ) =>\n\t\t\t// Keep only valid titles\n\t\t\t !!mw.Title.makeTitle( NS_CATEGORY, cat )\n\t\t );\n\n\t\tmissingCatsWikiText = null;\n\t\tif (\n\t\t\ttypeof this.config.missingWikitext === 'string' &&\n\t\t\tthis.config.missingWikitext.length > 0\n\t\t) {\n\t\t\tmissingCatsWikiText = this.config.missingWikitext;\n\t\t}\n\n\t\tcategories = this.categoriesWidget.getItems().map( ( item ) => item.data );\n\n\t\t// add all categories\n\t\twikiText = categories.concat( hiddenCats )\n\t\t\t.map( ( cat ) => '[[' + mw.Title.makeTitle( NS_CATEGORY, cat ).getPrefixedText() + ']]' )\n\t\t\t.join( '\\n' );\n\n\t\t// if so configured, and there are no user-visible categories, add warning\n\t\tif ( missingCatsWikiText !== null && categories.length === 0 ) {\n\t\t\twikiText += '\\n\\n' + missingCatsWikiText;\n\t\t}\n\n\t\treturn wikiText;\n\t};\n\n\t/**\n\t * @inheritdoc\n\t * @return {Object} See #setSerialized\n\t */\n\tuw.CategoriesDetailsWidget.prototype.getSerialized = function () {\n\t\treturn this.categoriesWidget.getItems().map( ( item ) => item.data );\n\t};\n\n\t/**\n\t * @inheritdoc\n\t * @param {string[]} serialized List of categories\n\t */\n\tuw.CategoriesDetailsWidget.prototype.setSerialized = function ( serialized ) {\n\t\tconst categories = ( serialized || [] ).filter( ( cat ) =>\n\t\t\t// Keep only valid titles\n\t\t\t !!mw.Title.makeTitle( NS_CATEGORY, cat )\n\t\t );\n\t\tthis.categoriesWidget.setValue( categories );\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/details/uw.DateDetailsWidget.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-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/resources/details/uw.DeedChooserDetailsWidget.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-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/resources/details/uw.DropdownWidget.js","messages":[{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":13,"column":12,"nodeType":"MemberExpression","messageId":"forbidden","endLine":13,"endColumn":25}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"( function ( uw ) {\n\n\t/**\n\t * A field with a dropdown.\n\t *\n\t * @extends uw.DetailsWidget\n\t * @constructor\n\t * @param {Object} [config] Configuration options\n\t * @cfg {boolean} [required=false] Whether to mark this field as required\n\t * @cfg {Object} [options] Map of select dropdown options\n\t */\n\tuw.DropdownWidget = function MUDropdownWidget( config ) {\n\t\tconfig = Object.assign( { type: 'text' }, config );\n\t\tuw.DropdownWidget.parent.call( this, config );\n\n\t\tthis.required = !!config.required;\n\t\tthis.wikitext = config.wikitext;\n\t\tthis.input = new OO.ui.DropdownInputWidget( {\n\t\t\tclasses: [ 'mwe-idfield', 'mediauploader-dropdownWidget-input' ],\n\t\t\toptions: Object.keys( config.options ).map( ( key ) => ( { data: key, label: config.options[ key ] } ) )\n\t\t} );\n\n\t\t// Aggregate 'change' event\n\t\t// (but do not flash warnings in the user's face while they're typing)\n\t\tthis.input.on( 'change', OO.ui.debounce( this.emit.bind( this, 'change' ), 500 ) );\n\n\t\tthis.$element.addClass( 'mwe-id-field mediauploader-dropdownWidget' );\n\t\tthis.$element.append(\n\t\t\tthis.input.$element\n\t\t);\n\t};\n\tOO.inheritClass( uw.DropdownWidget, uw.DetailsWidget );\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.DropdownWidget.prototype.getErrors = function () {\n\t\tconst errors = [];\n\t\tif ( this.required && this.input.getValue().trim() === '' ) {\n\t\t\terrors.push( mw.message( 'mediauploader-error-blank' ) );\n\t\t}\n\t\treturn $.Deferred().resolve( errors ).promise();\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.DropdownWidget.prototype.getWarnings = function () {\n\t\tconst warnings = [];\n\t\tthis.getEmptyWarning( this.input.getValue().trim() === '', warnings );\n\n\t\treturn $.Deferred().resolve( warnings ).promise();\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.DropdownWidget.prototype.getWikiText = function () {\n\t\treturn this.input.getValue().trim();\n\t};\n\n\t/**\n\t * @inheritdoc\n\t * @return {Object} See #setSerialized\n\t */\n\tuw.DropdownWidget.prototype.getSerialized = function () {\n\t\treturn {\n\t\t\tvalue: this.input.getValue()\n\t\t};\n\t};\n\n\t/**\n\t * @inheritdoc\n\t * @param {Object} serialized\n\t * @param {string} serialized.value Campaign informations text\n\t */\n\tuw.DropdownWidget.prototype.setSerialized = function ( serialized ) {\n\t\tthis.input.setValue( serialized.value );\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/details/uw.LanguageDropdownWidget.js","messages":[],"suppressedMessages":[{"ruleId":"mediawiki/class-doc","severity":1,"message":"All possible CSS classes should be documented. See https://w.wiki/PS2 for details.","line":17,"column":53,"nodeType":"ObjectExpression","endLine":21,"endColumn":4,"suppressions":[{"kind":"directive","justification":""}]}],"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-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/resources/details/uw.LocationDetailsWidget.js","messages":[{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":12,"column":17,"nodeType":"MemberExpression","messageId":"forbidden","endLine":12,"endColumn":30},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":71,"column":3,"nodeType":"CallExpression","endLine":74,"endColumn":6},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":84,"column":3,"nodeType":"CallExpression","endLine":86,"endColumn":6},{"ruleId":"prefer-const","severity":2,"message":"'errors' is never reassigned. Use 'const' instead.","line":115,"column":7,"nodeType":"Identifier","messageId":"useConst","endLine":115,"endColumn":13},{"ruleId":"prefer-const","severity":2,"message":"'serialized' is never reassigned. Use 'const' instead.","line":116,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":116,"endColumn":14},{"ruleId":"prefer-const","severity":2,"message":"'parsed' is never reassigned. Use 'const' instead.","line":117,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":117,"endColumn":10},{"ruleId":"prefer-const","severity":2,"message":"'serialized' is never reassigned. Use 'const' instead.","line":165,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":165,"endColumn":14},{"ruleId":"prefer-const","severity":2,"message":"'result' is never reassigned. Use 'const' instead.","line":194,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":194,"endColumn":10},{"ruleId":"prefer-const","severity":2,"message":"'result' is never reassigned. Use 'const' instead.","line":210,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":210,"endColumn":10},{"ruleId":"prefer-const","severity":2,"message":"'serialized' is never reassigned. Use 'const' instead.","line":211,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":211,"endColumn":14},{"ruleId":"prefer-const","severity":2,"message":"'sign' is never reassigned. Use 'const' instead.","line":258,"column":7,"nodeType":"Identifier","messageId":"useConst","endLine":258,"endColumn":11},{"ruleId":"prefer-const","severity":2,"message":"'parts' is never reassigned. Use 'const' instead.","line":268,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":268,"endColumn":8}],"suppressedMessages":[],"errorCount":11,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"( function ( uw ) {\n\n\t/**\n\t * A set of location fields in UploadWizard's \"Details\" step form.\n\t *\n\t * @extends uw.DetailsWidget\n\t * @constructor\n\t * @param {Object} [config] Configuration options\n\t * @cfg {string[]} [fields] List of fields to show in the widget\n\t */\n\tuw.LocationDetailsWidget = function UWLocationDetailsWidget( config ) {\n\t\tthis.config = Object.assign( {\n\t\t\tfields: [ 'latitude', 'longitude' ]\n\t\t}, config );\n\n\t\tuw.LocationDetailsWidget.parent.call( this, this.config );\n\n\t\tthis.$element.addClass( 'mediauploader-locationDetailsWidget' );\n\n\t\tthis.config.showField = {};\n\t\tthis.inputs = {};\n\t\tthis.allFields = [ 'latitude', 'longitude', 'altitude', 'heading' ];\n\n\t\tthis.config.fields.forEach( function ( field ) {\n\t\t\tthis.config.showField[ field ] = true;\n\t\t}, this );\n\n\t\t// Go over all available fields in order\n\t\tthis.allFields.forEach( function ( field ) {\n\t\t\tif ( !this.config.showField[ field ] ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.inputs[ field ] = new OO.ui.TextInputWidget( { disabled: this.config.disabled } );\n\n\t\t\t// Messages that can be used here:\n\t\t\t// * mediauploader-location-latitude\n\t\t\t// * mediauploader-location-longitude\n\t\t\t// * mediauploader-location-altitude\n\t\t\t// * mediauploader-location-heading\n\t\t\tthis.$element.append(\n\t\t\t\tnew OO.ui.FieldLayout( this.inputs[ field ], {\n\t\t\t\t\talign: 'top',\n\t\t\t\t\tlabel: mw.message( 'mediauploader-location-' + field ).text(),\n\t\t\t\t\tdisabled: this.config.disabled\n\t\t\t\t} ).$element\n\t\t\t);\n\n\t\t\t// Aggregate 'change' events\n\t\t\tthis.inputs[ field ].connect( this, { change: [ 'emit', 'change' ] } );\n\t\t}, this );\n\n\t\tthis.$map = $( '<div>' ).css( { width: 500, height: 300 } );\n\t\tthis.mapButton = new OO.ui.PopupButtonWidget( {\n\t\t\ticon: 'mapPin',\n\t\t\ttitle: mw.message( 'mediauploader-location-button' ).text(),\n\t\t\tpopup: {\n\t\t\t\t$content: this.$map,\n\t\t\t\twidth: 500,\n\t\t\t\theight: 300\n\t\t\t},\n\t\t\tdisabled: this.config.disabled\n\t\t} );\n\n\t\tthis.mapButton.setDisabled( true );\n\t\tthis.$element.append( this.mapButton.$element );\n\n\t\tthis.mapButton.connect( this, { click: 'onMapButtonClick' } );\n\t\tthis.connect( this, { change: 'onChange' } );\n\n\t\tthis.mapButton.toggle( false );\n\t\tmw.loader.using( [ 'ext.kartographer.box', 'ext.kartographer.editing' ] ).done( () => {\n\t\t\t// Kartographer is installed and we'll be able to show the map. Display the button.\n\t\t\tthis.mapButton.toggle( true );\n\t\t} );\n\t};\n\n\tOO.inheritClass( uw.LocationDetailsWidget, uw.DetailsWidget );\n\n\t/**\n\t * @private\n\t */\n\tuw.LocationDetailsWidget.prototype.onChange = function () {\n\t\tconst widget = this;\n\t\tthis.getErrors().done( ( errors ) => {\n\t\t\twidget.mapButton.setDisabled( !( errors.length === 0 && widget.getWikiText() !== '' ) );\n\t\t} );\n\t};\n\n\t/**\n\t * @private\n\t */\n\tuw.LocationDetailsWidget.prototype.onMapButtonClick = function () {\n\t\tconst coords = this.getSerializedParsed();\n\n\t\t// Disable clipping because it doesn't play nicely with the map\n\t\tthis.mapButton.getPopup().toggleClipping( false );\n\n\t\tif ( !this.map ) {\n\t\t\tthis.map = require( 'ext.kartographer.box' ).map( {\n\t\t\t\tcontainer: this.$map[ 0 ]\n\t\t\t} );\n\t\t}\n\t\trequire( 'ext.kartographer.editing' ).getKartographerLayer( this.map ).setGeoJSON( {\n\t\t\ttype: 'Feature',\n\t\t\tproperties: {},\n\t\t\tgeometry: { type: 'Point', coordinates: [ coords.longitude, coords.latitude ] }\n\t\t} );\n\t\tthis.map.setView( [ coords.latitude, coords.longitude ], 9 );\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.LocationDetailsWidget.prototype.getErrors = function () {\n\t\tlet errors = [],\n\t\t\tserialized = this.getSerialized(),\n\t\t\tparsed = this.getSerializedParsed(),\n\t\t\tfield;\n\n\t\t// If the field is required and any of the subfields is empty\n\t\t// -> throw an error\n\t\tif ( this.config.required ) {\n\t\t\tfor ( field in this.config.showField ) {\n\t\t\t\tif ( !serialized[ field ] ) {\n\t\t\t\t\terrors.push( mw.message( 'mediauploader-error-blank' ) );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// input is invalid if the coordinates are out of bounds, or if the\n\t\t// coordinates that were derived from the input are 0, without a 0 even\n\t\t// being present in the input\n\t\tif ( this.config.showField.latitude && serialized.latitude ) {\n\t\t\tif ( isNaN( parsed.latitude ) || parsed.latitude > 90 || parsed.latitude < -90 || ( parsed.latitude === 0 && !serialized.latitude.includes( '0' ) ) ) {\n\t\t\t\terrors.push( mw.message( 'mediauploader-error-latitude' ) );\n\t\t\t}\n\t\t}\n\n\t\tif ( this.config.showField.longitude && serialized.longitude ) {\n\t\t\tif ( isNaN( parsed.longitude ) || parsed.longitude > 180 || parsed.longitude < -180 || ( parsed.longitude === 0 && !serialized.longitude.includes( '0' ) ) ) {\n\t\t\t\terrors.push( mw.message( 'mediauploader-error-longitude' ) );\n\t\t\t}\n\t\t}\n\n\t\tif ( this.config.showField.heading && serialized.heading !== '' ) {\n\t\t\tif ( isNaN( parsed.heading ) || parsed.heading > 360 || parsed.heading < 0 ) {\n\t\t\t\terrors.push( mw.message( 'mediauploader-error-heading' ) );\n\t\t\t}\n\t\t}\n\n\t\tif ( this.config.showField.altitude && serialized.altitude !== '' && isNaN( parsed.altitude ) ) {\n\t\t\terrors.push( mw.message( 'mediauploader-error-altitude' ) );\n\t\t}\n\n\t\treturn $.Deferred().resolve( errors );\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.LocationDetailsWidget.prototype.getWikiText = function () {\n\t\tlet field,\n\t\t\tresult = '',\n\t\t\tserialized = this.getSerializedParsed();\n\n\t\tif ( 'latitude' in this.config.showField &&\n\t\t\t( !isNaN( serialized.latitude ) || !isNaN( serialized.longitude ) )\n\t\t) {\n\t\t\tresult = ( isNaN( serialized.latitude ) ? '?' : serialized.latitude ).toString() +\n\t\t\t\t'; ' + ( isNaN( serialized.longitude ) ? '?' : serialized.longitude ).toString();\n\t\t}\n\n\t\tfor ( field in [ 'heading', 'altitude' ] ) {\n\t\t\tif ( field in this.config.showField && serialized[ field ] && !isNaN( serialized[ field ] )\n\t\t\t) {\n\t\t\t\t// Messages that can be used here:\n\t\t\t\t// * mediauploader-location-heading\n\t\t\t\t// * mediauploader-location-altitude\n\t\t\t\tresult += ' ' + mw.msg( 'mediauploader-location-' + field ) + ': ' +\n\t\t\t\t\tserialized[ field ].toString();\n\t\t\t}\n\t\t}\n\n\t\treturn result.trim();\n\t};\n\n\t/**\n\t * @inheritdoc\n\t * @return {Object} See #setSerialized\n\t */\n\tuw.LocationDetailsWidget.prototype.getSerialized = function () {\n\t\tlet field,\n\t\t\tresult = {};\n\n\t\tfor ( field in this.config.showField ) {\n\t\t\tresult[ field ] = this.inputs[ field ].getValue();\n\t\t}\n\n\t\treturn result;\n\t};\n\n\t/**\n\t * Returns a serialized representation of the subfields' values that were parsed to a number.\n\t *\n\t * @return {Object} Serialized, parsed values of the subfields (numbers)\n\t */\n\tuw.LocationDetailsWidget.prototype.getSerializedParsed = function () {\n\t\tlet field,\n\t\t\tresult = {},\n\t\t\tserialized = this.getSerialized();\n\n\t\tfor ( field in this.config.showField ) {\n\t\t\tif ( serialized[ field ] === '' || serialized[ field ] === undefined ) {\n\t\t\t\tresult[ field ] = NaN;\n\t\t\t} else if ( field === 'latitude' || field === 'longitude' ) {\n\t\t\t\tresult[ field ] = this.normalizeCoordinate( serialized[ field ] );\n\t\t\t} else {\n\t\t\t\tresult[ field ] = parseFloat( serialized[ field ] );\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t};\n\n\t/**\n\t * @inheritdoc\n\t * @param {Object} serialized\n\t * @param {number} serialized.latitude Latitude value\n\t * @param {number} serialized.longitude Longitude value\n\t * @param {string} serialized.altitude Altitude value\n\t * @param {string} serialized.heading Heading value\n\t */\n\tuw.LocationDetailsWidget.prototype.setSerialized = function ( serialized ) {\n\t\tlet field;\n\n\t\tfor ( field in this.config.showField ) {\n\t\t\tif ( serialized[ field ] !== undefined ) {\n\t\t\t\tthis.inputs[ field ].setValue( serialized[ field ] );\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Interprets a wide variety of coordinate input formats, it'll return the\n\t * coordinate in decimal degrees.\n\t *\n\t * Formats understood include:\n\t * * degrees minutes seconds: 40° 26' 46\" S\n\t * * degrees decimal minutes: 40° 26.767' S\n\t * * decimal degrees: 40.446° S\n\t * * decimal degrees exact value: -40.446\n\t *\n\t * @param {string} coordinate\n\t * @return {number}\n\t */\n\tuw.LocationDetailsWidget.prototype.normalizeCoordinate = function ( coordinate ) {\n\t\tlet sign = coordinate.match( /[sw]/i ) ? -1 : 1,\n\t\t\tparts, value;\n\n\t\t// fix commonly used character alternatives\n\t\tcoordinate = coordinate.replace( /\\s*[,.]\\s*/, '.' );\n\n\t\t// convert degrees, minutes, seconds (or degrees & decimal minutes) to\n\t\t// decimal degrees\n\t\t// there can be a lot of variation in the notation, so let's only\n\t\t// focus on \"groups of digits\" (and not whether e.g. ″ or \" is used)\n\t\tparts = coordinate.match( /(-?[0-9.]+)[^0-9.]+([0-9.]+)(?:[^0-9.]+([0-9.]+))?/ );\n\t\tif ( parts ) {\n\t\t\tvalue = this.dmsToDecimal( parts[ 1 ], parts[ 2 ], parts[ 3 ] || 0 );\n\t\t} else {\n\t\t\tvalue = coordinate.replace( /[^\\-0-9.]/g, '' ) * 1;\n\t\t}\n\n\t\t// round to 6 decimal places\n\t\treturn Math.round( sign * value * 1000000 ) / 1000000;\n\t};\n\n\t/**\n\t * Convert degrees, minutes & seconds to decimal.\n\t *\n\t * @param {number} degrees\n\t * @param {number} minutes\n\t * @param {number} seconds\n\t * @return {number}\n\t */\n\tuw.LocationDetailsWidget.prototype.dmsToDecimal = function ( degrees, minutes, seconds ) {\n\t\treturn ( degrees * 1 ) + ( minutes / 60.0 ) + ( seconds / 3600.0 );\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/details/uw.MultipleLanguageInputWidget.js","messages":[{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":16,"column":17,"nodeType":"MemberExpression","messageId":"forbidden","endLine":16,"endColumn":30},{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":50,"column":26,"nodeType":"MemberExpression","messageId":"forbidden","endLine":50,"endColumn":39},{"ruleId":"prefer-const","severity":2,"message":"'allLanguages' is never reassigned. Use 'const' instead.","line":60,"column":7,"nodeType":"Identifier","messageId":"useConst","endLine":60,"endColumn":19},{"ruleId":"prefer-const","severity":2,"message":"'unusedLanguages' is never reassigned. Use 'const' instead.","line":61,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":61,"endColumn":19},{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":73,"column":16,"nodeType":"MemberExpression","messageId":"forbidden","endLine":73,"endColumn":29},{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":78,"column":12,"nodeType":"MemberExpression","messageId":"forbidden","endLine":78,"endColumn":25},{"ruleId":"prefer-const","severity":2,"message":"'item' is never reassigned. Use 'const' instead.","line":82,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":82,"endColumn":7},{"ruleId":"prefer-const","severity":2,"message":"'allLanguages' is never reassigned. Use 'const' instead.","line":100,"column":7,"nodeType":"Identifier","messageId":"useConst","endLine":100,"endColumn":19},{"ruleId":"prefer-const","severity":2,"message":"'unusedLanguages' is never reassigned. Use 'const' instead.","line":101,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":101,"endColumn":19},{"ruleId":"prefer-const","severity":2,"message":"'items' is never reassigned. Use 'const' instead.","line":102,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":102,"endColumn":9},{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":114,"column":16,"nodeType":"MemberExpression","messageId":"forbidden","endLine":114,"endColumn":29},{"ruleId":"prefer-const","severity":2,"message":"'errors' is never reassigned. Use 'const' instead.","line":192,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":192,"endColumn":10},{"ruleId":"prefer-const","severity":2,"message":"'values' is never reassigned. Use 'const' instead.","line":215,"column":7,"nodeType":"Identifier","messageId":"useConst","endLine":215,"endColumn":13},{"ruleId":"prefer-const","severity":2,"message":"'widgets' is never reassigned. Use 'const' instead.","line":216,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":216,"endColumn":11},{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":272,"column":13,"nodeType":"MemberExpression","messageId":"forbidden","endLine":272,"endColumn":26}],"suppressedMessages":[],"errorCount":9,"fatalErrorCount":0,"warningCount":6,"fixableErrorCount":0,"fixableWarningCount":0,"source":"( function ( uw ) {\n\n\t/**\n\t * A multi-language input field in UploadWizard's \"Details\" step form.\n\t *\n\t * @class uw.MultipleLanguageInputWidget\n\t * @extends uw.DetailsWidget\n\t * @constructor\n\t * @param {Object} [config]\n\t * @cfg {boolean} [required=false]\n\t * @cfg {number} [minLength=0] Minimum input length\n\t * @cfg {number} [maxLength=99999] Maximum input length\n\t * @cfg {Object} [languages] { langcode: text } map of languages\n\t */\n\tuw.MultipleLanguageInputWidget = function UWMultipleLanguageInputWidget( config ) {\n\t\tthis.config = Object.assign( {}, config );\n\t\tuw.MultipleLanguageInputWidget.parent.call( this, this.config );\n\t\tOO.ui.mixin.GroupElement.call( this );\n\n\t\tthis.required = !!this.config.required;\n\t\tthis.addButton = new OO.ui.ButtonWidget( {\n\t\t\tclasses: [ 'mediauploader-multipleLanguageInputWidget-addItem' ],\n\t\t\tframed: true,\n\t\t\ticon: 'add',\n\t\t\tflags: [ 'progressive' ],\n\t\t\tlabel: this.getLabelText()\n\t\t} );\n\t\tthis.addButton.connect( this, { click: [ 'addLanguageInput', this.config ] } );\n\n\t\t// if a language becomes available because the input gets removed,\n\t\t// or unavailable because it gets added, we'll need to update other\n\t\t// language dropdowns to reflect the change\n\t\tthis.connect( this, { add: 'onChangeLanguages' } );\n\t\tthis.connect( this, { remove: 'onChangeLanguages' } );\n\n\t\t// update the 'add language' button accordingly\n\t\tthis.connect( this, { add: 'recount' } );\n\t\tthis.connect( this, { remove: 'recount' } );\n\n\t\t// Aggregate 'change' event\n\t\tthis.aggregate( { change: 'change' } );\n\n\t\tthis.$element.addClass( 'mediauploader-multipleLanguageInputsWidget' );\n\t\tthis.$element.append(\n\t\t\tthis.$group,\n\t\t\tthis.addButton.$element\n\t\t);\n\n\t\t// Add empty input (non-removable if this field is required)\n\t\tthis.addLanguageInput( Object.assign( {}, this.config, { canBeRemoved: !this.required } ) );\n\t};\n\tOO.inheritClass( uw.MultipleLanguageInputWidget, uw.DetailsWidget );\n\tOO.mixinClass( uw.MultipleLanguageInputWidget, OO.ui.mixin.GroupElement );\n\n\t/**\n\t * @param {Object} config\n\t * @param {string} [text]\n\t */\n\tuw.MultipleLanguageInputWidget.prototype.addLanguageInput = function ( config, text ) {\n\t\tlet allLanguages = this.config.languages,\n\t\t\tunusedLanguages = this.getUnusedLanguages(),\n\t\t\tlanguages = {},\n\t\t\titem;\n\n\t\tif ( unusedLanguages.length === 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// only add given language + unused/remaining languages - we don't want\n\t\t// languages that have already been selected to show up in the next dropdown...\n\t\tif ( config.defaultLanguage ) {\n\t\t\tlanguages[ config.defaultLanguage ] = allLanguages[ config.defaultLanguage ];\n\t\t\tlanguages = Object.assign( {}, languages, unusedLanguages );\n\t\t} else {\n\t\t\tlanguages = unusedLanguages;\n\t\t}\n\n\t\tconfig = Object.assign( {}, config, {\n\t\t\tlanguages: languages,\n\t\t\trequired: false\n\t\t} );\n\t\titem = new uw.SingleLanguageInputWidget( config );\n\t\titem.setText( text || '' );\n\n\t\t// if a language is changed, we'll need to update other language dropdowns\n\t\t// to reflect the change\n\t\titem.connect( this, { select: 'onChangeLanguages' } );\n\n\t\tthis.addItems( [ item ] );\n\t};\n\n\t/**\n\t * When a language changes (or an input is removed), the old language\n\t * becomes available again in other language dropdowns, and the new\n\t * language should no longer be selected.\n\t * This will iterate all inputs, destroy then, and construct new ones\n\t * with the updated language selections.\n\t */\n\tuw.MultipleLanguageInputWidget.prototype.onChangeLanguages = function () {\n\t\tlet allLanguages = this.config.languages,\n\t\t\tunusedLanguages = this.getUnusedLanguages(),\n\t\t\titems = this.getItems(),\n\t\t\tlanguages,\n\t\t\titem,\n\t\t\ti;\n\n\t\tfor ( i = 0; i < items.length; i++ ) {\n\t\t\titem = items[ i ];\n\n\t\t\t// only add existing language + unused/remaining languages - we don't want\n\t\t\t// languages that have already been selected to show up in the next dropdown...\n\t\t\tlanguages = {};\n\t\t\tlanguages[ item.getLanguage() ] = allLanguages[ item.getLanguage() ];\n\t\t\tlanguages = Object.assign( {}, languages, unusedLanguages );\n\t\t\titem.updateLanguages( languages );\n\t\t}\n\t};\n\n\t/**\n\t * Returns an object of `langcode: text` pairs with the languages\n\t * already used in dropdowns.\n\t *\n\t * @return {Object}\n\t */\n\tuw.MultipleLanguageInputWidget.prototype.getUsedLanguages = function () {\n\t\tconst allLanguages = this.config.languages,\n\t\t\titems = this.getItems();\n\n\t\treturn items.reduce( ( obj, item ) => {\n\t\t\tconst languageCode = item.getLanguage();\n\t\t\tobj[ languageCode ] = allLanguages[ languageCode ];\n\t\t\treturn obj;\n\t\t}, {} );\n\t};\n\n\t/**\n\t * Returns an object of `langcode: text` pairs with remaining languages\n\t * not yet used in dropdowns.\n\t *\n\t * @return {Object}\n\t */\n\tuw.MultipleLanguageInputWidget.prototype.getUnusedLanguages = function () {\n\t\tconst allLanguages = this.config.languages,\n\t\t\tusedLanguageCodes = Object.keys( this.getUsedLanguages() );\n\n\t\treturn Object.keys( allLanguages ).reduce( ( remaining, language ) => {\n\t\t\tif ( !usedLanguageCodes.includes( language ) ) {\n\t\t\t\tremaining[ language ] = allLanguages[ language ];\n\t\t\t}\n\t\t\treturn remaining;\n\t\t}, {} );\n\t};\n\n\t/**\n\t * Update the button label after adding or removing inputs.\n\t */\n\tuw.MultipleLanguageInputWidget.prototype.recount = function () {\n\t\tconst text = this.getLabelText(),\n\t\t\tunusedLanguages = this.getUnusedLanguages();\n\n\t\tthis.addButton.setLabel( text );\n\t\t// hide the button if there are no remaining languages...\n\t\tthis.addButton.toggle( Object.keys( unusedLanguages ).length > 0 );\n\t};\n\n\t/**\n\t * @return {string}\n\t */\n\tuw.MultipleLanguageInputWidget.prototype.getLabelText = function () {\n\t\treturn mw.message( 'mediauploader-multilang-add' ).params( [ this.items.length ] ).text();\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.MultipleLanguageInputWidget.prototype.getWarnings = function () {\n\t\tconst warnings = [];\n\t\tthis.getEmptyWarning( this.getWikiText() === '', warnings );\n\n\t\treturn $.Deferred().resolve( warnings ).promise();\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.MultipleLanguageInputWidget.prototype.getErrors = function () {\n\t\t// Gather errors from each item\n\t\tconst errorPromises = this.getItems().map( ( item ) => item.getErrors() );\n\n\t\treturn $.when.apply( $, errorPromises ).then( function () {\n\t\t\tlet i, errors;\n\t\t\terrors = [];\n\t\t\t// Fold all errors into a single one (they are displayed in the UI for each item, but we still\n\t\t\t// need to return an error here to prevent form submission).\n\t\t\tfor ( i = 0; i < arguments.length; i++ ) {\n\t\t\t\tif ( arguments[ i ].length ) {\n\t\t\t\t\t// One of the items has errors\n\t\t\t\t\terrors.push( mw.message( 'mediauploader-error-bad-multilang' ) );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// And add some more:\n\t\t\tif ( this.required && this.getWikiText() === '' ) {\n\t\t\t\terrors.push( mw.message( 'mediauploader-error-blank' ) );\n\t\t\t}\n\t\t\t// TODO Check for duplicate languages\n\t\t\treturn errors;\n\t\t}.bind( this ) );\n\t};\n\n\t/**\n\t * @return {Object} Object where the properties are language codes & values are input\n\t */\n\tuw.MultipleLanguageInputWidget.prototype.getValues = function () {\n\t\tlet values = {},\n\t\t\twidgets = this.getItems(),\n\t\t\tlanguage,\n\t\t\ttext,\n\t\t\ti;\n\n\t\tfor ( i = 0; i < widgets.length; i++ ) {\n\t\t\tlanguage = widgets[ i ].getLanguage();\n\t\t\ttext = widgets[ i ].getText();\n\n\t\t\tif ( text !== '' ) {\n\t\t\t\tvalues[ language ] = text;\n\t\t\t}\n\t\t}\n\n\t\treturn values;\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.MultipleLanguageInputWidget.prototype.getWikiText = function () {\n\t\t// Some code here and in mw.UploadWizardDetails relies on this function returning an empty\n\t\t// string when there are some inputs, but all are empty.\n\t\treturn this.getItems().map( ( widget ) => widget.getWikiText() ).filter( ( wikiText ) => !!wikiText ).join( '\\n' );\n\t};\n\n\t/**\n\t * @inheritdoc\n\t * @return {Object} See #setSerialized\n\t */\n\tuw.MultipleLanguageInputWidget.prototype.getSerialized = function () {\n\t\tconst inputs = this.getItems().map( ( widget ) => widget.getSerialized() );\n\t\treturn {\n\t\t\tinputs: inputs\n\t\t};\n\t};\n\n\t/**\n\t * @inheritdoc\n\t * @param {Object|string} serialized\n\t * @param {Object[]} serialized.inputs Array of serialized inputs,\n\t * see uw.SingleLanguageInputWidget#setSerialized\n\t */\n\tuw.MultipleLanguageInputWidget.prototype.setSerialized = function ( serialized ) {\n\t\tlet config = this.config,\n\t\t\ti;\n\n\t\tif ( typeof serialized === 'string' ) {\n\t\t\tthis.setSerialized( { inputs: [ { text: serialized } ] } );\n\t\t\treturn;\n\t\t}\n\n\t\t// remove all existing\n\t\tthis.removeItems( this.getItems() );\n\n\t\tfor ( i = 0; i < serialized.inputs.length; i++ ) {\n\t\t\tconfig = Object.assign( {}, config, { defaultLanguage: serialized.inputs[ i ].language } );\n\t\t\tthis.addLanguageInput( config, serialized.inputs[ i ].text );\n\t\t}\n\t};\n\n\t/**\n\t * Returns the value of the field which can be used as a caption.\n\t *\n\t * @return {string}\n\t */\n\tuw.MultipleLanguageInputWidget.prototype.getCaption = function () {\n\t\tconst items = this.getItems();\n\n\t\tif ( items.length > 0 ) {\n\t\t\treturn items[ 0 ].getCaption();\n\t\t}\n\n\t\treturn '';\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/details/uw.SingleLanguageInputWidget.js","messages":[{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":17,"column":17,"nodeType":"MemberExpression","messageId":"forbidden","endLine":17,"endColumn":30},{"ruleId":"prefer-const","severity":2,"message":"'text' is never reassigned. Use 'const' instead.","line":226,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":226,"endColumn":8}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"( function ( uw ) {\n\n\t/**\n\t * A single language input field in UploadWizard's \"Details\" step form.\n\t *\n\t * @extends uw.DetailsWidget\n\t * @constructor\n\t * @param {Object} config\n\t * @param {Object} config.languages { langcode: text } map of languages\n\t * @param {Object} [config.defaultLanguage]\n\t * @param {Object} [config.required]\n\t * @param {boolean} [config.canBeRemoved=true]\n\t * @param {number} [config.minLength=0] Minimum input length\n\t * @param {number} [config.maxLength=99999] Maximum input length\n\t */\n\tuw.SingleLanguageInputWidget = function UWSingleLanguageInputWidget( config ) {\n\t\tthis.config = Object.assign( {\n\t\t\tminLength: 0,\n\t\t\tmaxLength: 99999\n\t\t}, config );\n\n\t\tuw.SingleLanguageInputWidget.parent.call( this, this.config );\n\t\tuw.ValidationMessageElement.call( this );\n\n\t\tif ( mw.loader.getState( 'ext.uls.mediawiki' ) === 'ready' ) {\n\t\t\tthis.languageSelector = new uw.UlsWidget( {\n\t\t\t\tlanguages: config.languages,\n\t\t\t\tclasses: [ 'mediauploader-singleLanguageInputWidget-language' ],\n\t\t\t\tdisabled: this.config.disabled\n\t\t\t} );\n\t\t} else {\n\t\t\tthis.languageSelector = new uw.LanguageDropdownWidget( {\n\t\t\t\tlanguages: config.languages,\n\t\t\t\tclasses: [ 'mediauploader-singleLanguageInputWidget-language' ],\n\t\t\t\tdisabled: this.config.disabled\n\t\t\t} );\n\t\t}\n\t\tthis.languageSelector.setValue( config.defaultLanguage || this.getDefaultLanguage() );\n\n\t\tthis.textInput = new OO.ui.MultilineTextInputWidget( {\n\t\t\tclasses: [ 'mediauploader-singleLanguageInputWidget-text' ],\n\t\t\tautosize: true,\n\t\t\trows: 2,\n\t\t\tdisabled: this.config.disabled\n\t\t} );\n\t\tthis.removeButton = new OO.ui.ButtonWidget( {\n\t\t\tclasses: [ 'mediauploader-singleLanguageInputWidget-removeItem' ],\n\t\t\ticon: 'trash',\n\t\t\tframed: false,\n\t\t\tflags: [ 'destructive' ],\n\t\t\ttitle: mw.message( 'mediauploader-multilang-remove' ).text(),\n\t\t\tdisabled: this.config.disabled\n\t\t} );\n\n\t\tthis.removeButton.connect( this, {\n\t\t\tclick: 'onRemoveClick'\n\t\t} );\n\n\t\tthis.languageSelector.connect( this, { select: [ 'emit', 'select' ] } );\n\t\t// Aggregate 'change' event\n\t\t// (but do not flash warnings in the user's face while they're typing)\n\t\tthis.textInput.on( 'change', OO.ui.debounce( this.emit.bind( this, 'change' ), 500 ) );\n\n\t\tthis.$element.addClass( 'mediauploader-singleLanguageInputWidget' );\n\t\tthis.$element.append( this.languageSelector.getElement() );\n\t\t// HACK: ValidationMessageElement will append messages after this.$body\n\t\tthis.$body = this.textInput.$element;\n\t\tif ( this.config.canBeRemoved !== false ) {\n\t\t\tthis.$element.append( this.removeButton.$element );\n\t\t\tthis.$body = this.removeButton.$element; // HACK\n\t\t}\n\t\tthis.$element.append( this.textInput.$element );\n\n\t};\n\tOO.inheritClass( uw.SingleLanguageInputWidget, uw.DetailsWidget );\n\tOO.mixinClass( uw.SingleLanguageInputWidget, uw.ValidationMessageElement );\n\n\t/**\n\t * Handle remove button click events.\n\t *\n\t * @private\n\t */\n\tuw.SingleLanguageInputWidget.prototype.onRemoveClick = function () {\n\t\tconst element = this.getElementGroup();\n\n\t\tif ( element && typeof element.removeItems === 'function' ) {\n\t\t\telement.removeItems( [ this ] );\n\t\t}\n\t};\n\n\t/**\n\t * Check if the given language code can be used for inputs.\n\t * If not, try finding a similar language code that can be.\n\t *\n\t * @public\n\t * @param {string} code Language code\n\t * @param {string} [fallback] Language code to use when there's nothing close,\n\t * defaults to result of #getDefaultLanguage\n\t * @return {string|null}\n\t */\n\tuw.SingleLanguageInputWidget.prototype.getClosestAllowedLanguage = function ( code, fallback ) {\n\t\t// Is this still needed?\n\t\tif ( code === 'nan' || code === 'minnan' ) {\n\t\t\tcode = 'zh-min-nan';\n\t\t}\n\t\tif ( this.config.languages[ code ] ) {\n\t\t\treturn code;\n\t\t}\n\t\tif ( code.lastIndexOf( '-' ) !== -1 ) {\n\t\t\treturn this.getClosestAllowedLanguage( code.slice( 0, Math.max( 0, code.lastIndexOf( '-' ) ) ) );\n\t\t}\n\t\treturn arguments.length > 1 ? fallback : this.getDefaultLanguage();\n\t};\n\n\t/**\n\t * Get the default language to use for inputs.\n\t * Choose a sane default based on user preferences and wiki config.\n\t *\n\t * @public\n\t * @return {string}\n\t */\n\tuw.SingleLanguageInputWidget.prototype.getDefaultLanguage = function () {\n\t\tlet defaultLanguage;\n\n\t\tif ( this.defaultLanguage !== undefined ) {\n\t\t\treturn this.defaultLanguage;\n\t\t}\n\n\t\tif ( this.getClosestAllowedLanguage( mw.config.get( 'wgUserLanguage' ), null ) ) {\n\t\t\tdefaultLanguage = this.getClosestAllowedLanguage( mw.config.get( 'wgUserLanguage' ) );\n\t\t} else if ( this.getClosestAllowedLanguage( mw.config.get( 'wgContentLanguage' ), null ) ) {\n\t\t\tdefaultLanguage = this.getClosestAllowedLanguage( mw.config.get( 'wgContentLanguage' ) );\n\t\t} else if ( this.getClosestAllowedLanguage( 'en', null ) ) {\n\t\t\tdefaultLanguage = this.getClosestAllowedLanguage( 'en' );\n\t\t} else {\n\t\t\tdefaultLanguage = Object.keys( this.config.languages )[ 0 ];\n\t\t}\n\n\t\t// Logic copied from MediaWiki:UploadForm.js\n\t\t// Per request from Portuguese and Brazilian users, treat Brazilian Portuguese as Portuguese.\n\t\tif ( defaultLanguage === 'pt-br' ) {\n\t\t\tdefaultLanguage = 'pt';\n\t\t// this was also in UploadForm.js, but without the heartwarming justification\n\t\t} else if ( defaultLanguage === 'en-gb' ) {\n\t\t\tdefaultLanguage = 'en';\n\t\t}\n\n\t\tthis.defaultLanguage = defaultLanguage;\n\t\treturn defaultLanguage;\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.SingleLanguageInputWidget.prototype.getWarnings = function () {\n\t\tconst warnings = [];\n\t\tthis.getEmptyWarning( this.textInput.getValue().trim() === '', warnings );\n\n\t\treturn $.Deferred().resolve( warnings ).promise();\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.SingleLanguageInputWidget.prototype.getErrors = function () {\n\t\tconst\n\t\t\terrors = [],\n\t\t\ttext = this.textInput.getValue().trim();\n\n\t\tif ( this.config.required && text.length === 0 ) {\n\t\t\terrors.push( mw.message( 'mediauploader-error-blank' ) );\n\t\t}\n\n\t\tif ( text.length !== 0 && text.length < this.config.minLength ) {\n\t\t\t// Empty input is allowed\n\t\t\terrors.push( mw.message( 'mediauploader-error-too-short', this.config.minLength ) );\n\t\t}\n\t\tif ( text.length > this.config.maxLength ) {\n\t\t\terrors.push( mw.message( 'mediauploader-error-too-long', this.config.maxLength ) );\n\t\t}\n\n\t\treturn $.Deferred().resolve( errors ).promise();\n\t};\n\n\t/**\n\t * @param {Object} languages\n\t */\n\tuw.SingleLanguageInputWidget.prototype.updateLanguages = function ( languages ) {\n\t\tthis.languageSelector.updateLanguages( languages );\n\t};\n\n\t/**\n\t * @return {string} language code\n\t */\n\tuw.SingleLanguageInputWidget.prototype.getLanguage = function () {\n\t\treturn this.languageSelector.getValue();\n\t};\n\n\t/**\n\t * @param {string} value language code\n\t */\n\tuw.SingleLanguageInputWidget.prototype.setLanguage = function ( value ) {\n\t\tthis.languageSelector.setValue( value );\n\t};\n\n\t/**\n\t * @return {string} text input\n\t */\n\tuw.SingleLanguageInputWidget.prototype.getText = function () {\n\t\treturn this.textInput.getValue().trim();\n\t};\n\n\t/**\n\t * @param {string} value text input\n\t */\n\tuw.SingleLanguageInputWidget.prototype.setText = function ( value ) {\n\t\tthis.textInput.setValue( value );\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.SingleLanguageInputWidget.prototype.getWikiText = function () {\n\t\tlet\n\t\t\tlanguage = this.getLanguage(),\n\t\t\ttext = this.getText();\n\n\t\tif ( !text ) {\n\t\t\treturn '';\n\t\t}\n\n\t\tif ( mw.UploadWizard.config.languageTemplateFixups[ language ] ) {\n\t\t\tlanguage = mw.UploadWizard.config.languageTemplateFixups[ language ];\n\t\t}\n\n\t\treturn '{{' + language + '|1=' + mw.Escaper.escapeForTemplate( text ) + '}}';\n\t};\n\n\t/**\n\t * @inheritdoc\n\t * @return {Object} See #setSerialized\n\t */\n\tuw.SingleLanguageInputWidget.prototype.getSerialized = function () {\n\t\treturn {\n\t\t\tlanguage: this.languageSelector.getValue(),\n\t\t\ttext: this.textInput.getValue()\n\t\t};\n\t};\n\n\t/**\n\t * @inheritdoc\n\t * @param {Object|string} serialized\n\t * @param {string} [serialized.language] Language code\n\t * @param {string} serialized.text Text\n\t */\n\tuw.SingleLanguageInputWidget.prototype.setSerialized = function ( serialized ) {\n\t\tif ( typeof serialized === 'string' ) {\n\t\t\tthis.setSerialized( { text: serialized } );\n\t\t\treturn;\n\t\t}\n\t\tthis.setLanguage( serialized.language );\n\t\tthis.setText( serialized.text );\n\t};\n\n\t/**\n\t * Returns the value of the field which can be used as a caption.\n\t *\n\t * @return {string}\n\t */\n\tuw.SingleLanguageInputWidget.prototype.getCaption = function () {\n\t\treturn this.textInput.getValue().trim();\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/details/uw.TextWidget.js","messages":[{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":13,"column":17,"nodeType":"MemberExpression","messageId":"forbidden","endLine":13,"endColumn":30}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"( function ( uw ) {\n\n\t/**\n\t * A generic text input field.\n\t *\n\t * @extends uw.DetailsWidget\n\t * @param {Object} config\n\t * @param {string} [config.mode] Mode, either 'text' or 'textarea'\n\t * @param {number} [config.minLength=0] Minimum input length\n\t * @param {number} [config.maxLength=99999] Maximum input length\n\t */\n\tuw.TextWidget = function UWTextWidget( config ) {\n\t\tthis.config = Object.assign( {\n\t\t\tminLength: 0,\n\t\t\tmaxLength: 99999,\n\t\t\tmode: 'text'\n\t\t}, config );\n\n\t\tuw.TextWidget.parent.call( this, this.config );\n\n\t\tif ( this.config.mode === 'text' ) {\n\t\t\tthis.textInput = new OO.ui.TextInputWidget( {\n\t\t\t\tclasses: [ 'mediauploader-other-text', 'mediauploader-textWidget-other' ],\n\t\t\t\tmaxLength: this.config.maxLength,\n\t\t\t\tdisabled: this.config.disabled\n\t\t\t} );\n\t\t\tthis.$element.addClass( 'mediauploader-textWidget' );\n\t\t} else {\n\t\t\tthis.textInput = new OO.ui.MultilineTextInputWidget( {\n\t\t\t\tclasses: [ 'mediauploader-other-textarea', 'mediauploader-textAreaWidget-other' ],\n\t\t\t\tautosize: true,\n\t\t\t\trows: 2,\n\t\t\t\tdisabled: this.config.disabled\n\t\t\t} );\n\t\t\tthis.$element.addClass( 'mediauploader-textAreaWidget' );\n\t\t}\n\n\t\t// Aggregate 'change' event\n\t\t// (but do not flash warnings in the user's face while they're typing)\n\t\tthis.textInput.on( 'change', OO.ui.debounce( this.emit.bind( this, 'change' ), 500 ) );\n\n\t\tthis.$element.append(\n\t\t\tthis.textInput.$element\n\t\t);\n\t};\n\tOO.inheritClass( uw.TextWidget, uw.DetailsWidget );\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.TextWidget.prototype.getWarnings = function () {\n\t\tconst warnings = [];\n\t\tthis.getEmptyWarning( this.textInput.getValue().trim() === '', warnings );\n\n\t\treturn $.Deferred().resolve( warnings ).promise();\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.TextWidget.prototype.getErrors = function () {\n\t\tconst\n\t\t\terrors = [],\n\t\t\ttext = this.textInput.getValue().trim();\n\n\t\tif ( this.config.required && text.length === 0 ) {\n\t\t\terrors.push( mw.message( 'mediauploader-error-blank' ) );\n\t\t}\n\n\t\tif ( text.length !== 0 && text.length < this.config.minLength ) {\n\t\t\t// Empty input is allowed\n\t\t\terrors.push( mw.message( 'mediauploader-error-too-short', this.config.minLength ) );\n\t\t}\n\t\tif ( text.length > this.config.maxLength ) {\n\t\t\terrors.push( mw.message( 'mediauploader-error-too-long', this.config.maxLength ) );\n\t\t}\n\n\t\treturn $.Deferred().resolve( errors ).promise();\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.TextWidget.prototype.getWikiText = function () {\n\t\treturn this.textInput.getValue().trim();\n\t};\n\n\t/**\n\t * @inheritdoc\n\t * @return {Object} See #setSerialized\n\t */\n\tuw.TextWidget.prototype.getSerialized = function () {\n\t\treturn this.textInput.getValue();\n\t};\n\n\t/**\n\t * @inheritdoc\n\t * @param {string} serialized\n\t */\n\tuw.TextWidget.prototype.setSerialized = function ( serialized ) {\n\t\tthis.textInput.setValue( serialized );\n\t};\n\n\t/**\n\t * Returns the value of the field which can be used as a caption.\n\t *\n\t * @return {string}\n\t */\n\tuw.TextWidget.prototype.getCaption = function () {\n\t\treturn this.getWikiText();\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/details/uw.TitleDetailsWidget.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'illegalFileChars' is never reassigned. Use 'const' instead.","line":49,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":49,"endColumn":20},{"ruleId":"prefer-const","severity":2,"message":"'value' is never reassigned. Use 'const' instead.","line":82,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":82,"endColumn":8},{"ruleId":"prefer-const","severity":2,"message":"'title' is never reassigned. Use 'const' instead.","line":94,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":94,"endColumn":8},{"ruleId":"no-mixed-spaces-and-tabs","severity":2,"message":"Mixed spaces and tabs.","line":156,"column":7,"nodeType":"Program","messageId":"mixedSpacesAndTabs","endLine":156,"endColumn":9},{"ruleId":"implicit-arrow-linebreak","severity":2,"message":"Expected no linebreak before this expression.","line":156,"column":9,"nodeType":"Identifier","messageId":"unexpected","endLine":156,"endColumn":11},{"ruleId":"no-mixed-spaces-and-tabs","severity":2,"message":"Mixed spaces and tabs.","line":157,"column":6,"nodeType":"Program","messageId":"mixedSpacesAndTabs","endLine":157,"endColumn":8},{"ruleId":"prefer-const","severity":2,"message":"'errors' is never reassigned. Use 'const' instead.","line":181,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":181,"endColumn":9}],"suppressedMessages":[{"ruleId":"mediawiki/msg-doc","severity":1,"message":"All possible message keys should be documented. See https://w.wiki/4r9a for details.","line":212,"column":22,"nodeType":"CallExpression","endLine":212,"endColumn":75,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":7,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"( function ( uw ) {\n\n\tconst NS_FILE = mw.config.get( 'wgNamespaceIds' ).file,\n\t\tbyteLength = require( 'mediawiki.String' ).byteLength;\n\n\t/**\n\t * A title field in UploadWizard's \"Details\" step form.\n\t *\n\t * @class uw.TitleDetailsWidget\n\t * @extends uw.DetailsWidget\n\t * @constructor\n\t * @param {Object} [config]\n\t */\n\tuw.TitleDetailsWidget = function UWTitleDetailsWidget( config ) {\n\t\tconfig = config || {};\n\t\tuw.TitleDetailsWidget.parent.call( this, config );\n\n\t\tthis.config = config;\n\t\t// We wouldn't want or use any of mw.widgets.TitleInputWidget functionality.\n\t\tthis.titleInput = new OO.ui.TextInputWidget( {\n\t\t\tclasses: [ 'mwe-title', 'mediauploader-titleDetailsWidget-title' ],\n\t\t\tmaxLength: config.maxLength,\n\t\t\tdisabled: this.config.disabled\n\t\t} );\n\n\t\t// Aggregate 'change' event (with delay)\n\t\tthis.titleInput.on( 'change', OO.ui.debounce( this.emit.bind( this, 'change' ), 500 ) );\n\n\t\tthis.$element.addClass( 'mediauploader-titleDetailsWidget' );\n\t\tthis.$element.append(\n\t\t\tthis.titleInput.$element\n\t\t);\n\t};\n\tOO.inheritClass( uw.TitleDetailsWidget, uw.DetailsWidget );\n\n\t/**\n\t * Reliably turn input into a MediaWiki title that is located in the 'File:' namespace.\n\t * Also applies file-specific checks ($wgIllegalFileChars).\n\t *\n\t * var title = uw.TitleDetailsWidget.static.makeTitleInFileNS( 'filename.ext' );\n\t *\n\t * @static\n\t * @param {string} filename Desired file name; optionally with 'File:' namespace prefixed\n\t * @return {mw.Title|null}\n\t */\n\tuw.TitleDetailsWidget.static.makeTitleInFileNS = function ( filename ) {\n\t\tlet\n\t\t\tmwTitle = mw.Title.newFromText( filename, NS_FILE ),\n\t\t\tillegalFileChars = new RegExp( '[' + mw.config.get( 'wgIllegalFileChars', '' ) + ']' );\n\t\tif ( mwTitle && mwTitle.getNamespaceId() !== NS_FILE ) {\n\t\t\t// Force file namespace\n\t\t\tmwTitle = mw.Title.makeTitle( NS_FILE, filename );\n\t\t}\n\t\tif ( mwTitle && ( illegalFileChars.test( mwTitle.getMainText() ) || mwTitle.fragment !== null ) ) {\n\t\t\t// Consider the title invalid if it contains characters disallowed in file names\n\t\t\tmwTitle = null;\n\t\t}\n\t\treturn mwTitle;\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.TitleDetailsWidget.prototype.pushPending = function () {\n\t\tthis.titleInput.pushPending();\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.TitleDetailsWidget.prototype.popPending = function () {\n\t\tthis.titleInput.popPending();\n\t};\n\n\t/**\n\t * Get a mw.Title object for current value.\n\t *\n\t * @return {mw.Title|null}\n\t */\n\tuw.TitleDetailsWidget.prototype.getTitle = function () {\n\t\tlet value, extRegex, cleaned, title;\n\t\tvalue = this.titleInput.getValue().trim();\n\t\tif ( !value ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( this.config.extension ) {\n\t\t\textRegex = new RegExp( '\\\\.' + this.extension + '$', 'i' );\n\t\t\tcleaned = value.replace( extRegex, '' ).replace( /\\.+$/g, '' ).trim();\n\t\t\tcleaned = cleaned + '.' + this.config.extension;\n\t\t} else {\n\t\t\tcleaned = value;\n\t\t}\n\t\ttitle = uw.TitleDetailsWidget.static.makeTitleInFileNS( cleaned );\n\t\treturn title;\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.TitleDetailsWidget.prototype.getWarnings = function () {\n\t\tconst warnings = [];\n\t\tthis.getEmptyWarning( this.titleInput.getValue().trim() === '', warnings );\n\n\t\treturn $.Deferred().resolve( warnings ).promise();\n\t};\n\n\t/**\n\t * @return {jQuery.Promise}\n\t */\n\tuw.TitleDetailsWidget.prototype.getErrors = function () {\n\t\tconst\n\t\t\terrors = [],\n\t\t\tvalue = this.titleInput.getValue().trim(),\n\t\t\tprocessDestinationCheck = this.processDestinationCheck,\n\t\t\ttitle = this.getTitle(),\n\t\t\t// title length is dependent on DB column size and is bytes rather than characters\n\t\t\tlength = byteLength( value );\n\n\t\tif ( this.config.required && value === '' ) {\n\t\t\terrors.push( mw.message( 'mediauploader-error-blank' ) );\n\t\t\treturn $.Deferred().resolve( errors ).promise();\n\t\t}\n\n\t\tif ( !this.config.required && value === '' ) {\n\t\t\treturn $.Deferred().resolve( [] ).promise();\n\t\t}\n\n\t\tif ( length !== 0 && this.config.minLength && length < this.config.minLength ) {\n\t\t\terrors.push( mw.message( 'mediauploader-error-title-too-short', this.config.minLength ) );\n\t\t\treturn $.Deferred().resolve( errors ).promise();\n\t\t}\n\n\t\tif ( this.config.maxLength && length > this.config.maxLength ) {\n\t\t\terrors.push( mw.message( 'mediauploader-error-title-too-long', this.config.maxLength ) );\n\t\t\treturn $.Deferred().resolve( errors ).promise();\n\t\t}\n\n\t\tif ( !title ) {\n\t\t\terrors.push( mw.message( 'mediauploader-error-title-invalid' ) );\n\t\t\treturn $.Deferred().resolve( errors ).promise();\n\t\t}\n\n\t\treturn mw.DestinationChecker.checkTitle( title.getPrefixedText() )\n\t\t\t.then( ( result ) => {\n\t\t\t\tlet moreErrors = processDestinationCheck( result );\n\t\t\t\tif ( result.blacklist.unavailable ) {\n\t\t\t\t\t// We don't have a title blacklist, so just check for some likely undesirable patterns.\n\t\t\t\t\tmoreErrors = moreErrors.concat(\n\t\t\t\t\t\tmw.QuickTitleChecker.checkTitle( title.getNameText() ).map( ( errorCode ) =>\n\t\t\t\t\t\t\t// Messages that can be used here:\n\t\t\t\t\t\t\t// * mediauploader-error-title-invalid\n\t\t\t\t\t\t\t// * mediauploader-error-title-senselessimagename\n\t\t\t\t\t\t\t// * mediauploader-error-title-thumbnail\n\t\t\t\t\t\t\t// * mediauploader-error-title-extension\n\t\t\t\t\t\t\t mw.message( 'mediauploader-error-title-' + errorCode )\n\t\t\t\t\t\t )\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn moreErrors;\n\t\t\t} )\n\t\t\t.then( ( moreErrors ) => [].concat( errors, moreErrors ), () => $.Deferred().resolve( errors ) );\n\t};\n\n\t/**\n\t * Process the result of a destination filename check, return array of mw.Messages objects\n\t * representing errors.\n\t *\n\t * @private\n\t * @param {Object} result Result to process, output from mw.DestinationChecker\n\t * @return {mw.Message[]} Error messages\n\t */\n\tuw.TitleDetailsWidget.prototype.processDestinationCheck = function ( result ) {\n\t\tlet messageParams, errors, titleString;\n\n\t\tif ( result.unique.isUnique && result.blacklist.notBlacklisted && !result.unique.isProtected ) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// Something is wrong with this title.\n\t\terrors = [];\n\n\t\ttry {\n\t\t\ttitleString = result.unique.title || result.title;\n\t\t\ttitleString = uw.TitleDetailsWidget.static.makeTitleInFileNS( titleString ).getPrefixedText();\n\t\t} catch ( e ) {\n\t\t\t// Unparseable result? This shouldn't happen, we checked for that earlier...\n\t\t\terrors.push( mw.message( 'mediauploader-error-title-invalid' ) );\n\t\t\treturn errors;\n\t\t}\n\n\t\tif ( !result.unique.isUnique ) {\n\t\t\t// result is NOT unique\n\t\t\tif ( result.unique.href ) {\n\t\t\t\terrors.push( mw.message(\n\t\t\t\t\t'mediauploader-fileexists-replace-on-page',\n\t\t\t\t\ttitleString,\n\t\t\t\t\t$( '<a>' ).attr( { href: result.unique.href, target: '_blank' } )\n\t\t\t\t) );\n\t\t\t} else {\n\t\t\t\terrors.push( mw.message( 'mediauploader-fileexists-replace-no-link', titleString ) );\n\t\t\t}\n\t\t} else if ( result.unique.isProtected ) {\n\t\t\terrors.push( mw.message( 'mediauploader-error-title-protected' ) );\n\t\t} else {\n\t\t\tmw.messages.set( result.blacklist.blacklistMessage, result.blacklist.blacklistReason );\n\t\t\tmessageParams = [\n\t\t\t\t'mediauploader-blacklisted-details',\n\t\t\t\ttitleString,\n\t\t\t\tfunction () {\n\t\t\t\t\t// eslint-disable-next-line mediawiki/msg-doc\n\t\t\t\t\tmw.errorDialog( $( '<div>' ).msg( result.blacklist.blacklistMessage ) );\n\t\t\t\t}\n\t\t\t];\n\n\t\t\terrors.push( mw.message.apply( mw, messageParams ) );\n\t\t}\n\n\t\treturn errors;\n\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuw.TitleDetailsWidget.prototype.getWikiText = function () {\n\t\treturn this.titleInput.getValue().trim();\n\t};\n\n\t/**\n\t * @inheritdoc\n\t * @return {Object} See #setSerialized\n\t */\n\tuw.TitleDetailsWidget.prototype.getSerialized = function () {\n\t\treturn {\n\t\t\ttitle: this.titleInput.getValue()\n\t\t};\n\t};\n\n\t/**\n\t * @inheritdoc\n\t * @param {Object} serialized\n\t * @param {string} serialized.language Title language code\n\t * @param {string} serialized.title Title text\n\t */\n\tuw.TitleDetailsWidget.prototype.setSerialized = function ( serialized ) {\n\t\tthis.titleInput.setValue( serialized.title );\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/details/uw.UlsWidget.js","messages":[],"suppressedMessages":[{"ruleId":"mediawiki/class-doc","severity":1,"message":"All possible CSS classes should be documented. See https://w.wiki/PS2 for details.","line":34,"column":4,"nodeType":"CallExpression","endLine":34,"endColumn":49,"suppressions":[{"kind":"directive","justification":""}]}],"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-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/resources/ext.mediaUploader.campaignEditor.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-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/resources/handlers/mw.ApiUploadFormDataHandler.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-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/resources/handlers/mw.ApiUploadHandler.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'allDuplicates' is never reassigned. Use 'const' instead.","line":224,"column":7,"nodeType":"Identifier","messageId":"useConst","endLine":224,"endColumn":20},{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":224,"column":23,"nodeType":"MemberExpression","messageId":"forbidden","endLine":224,"endColumn":36},{"ruleId":"prefer-const","severity":2,"message":"'$extra' is never reassigned. Use 'const' instead.","line":225,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":225,"endColumn":10},{"ruleId":"prefer-const","severity":2,"message":"'$ul' is never reassigned. Use 'const' instead.","line":226,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":226,"endColumn":7}],"suppressedMessages":[],"errorCount":3,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"( function () {\n\tconst NS_FILE = mw.config.get( 'wgNamespaceIds' ).file;\n\n\t/**\n\t * @param {mw.UploadWizardUpload} upload\n\t * @param {mw.Api} api\n\t */\n\tmw.ApiUploadHandler = function ( upload, api ) {\n\t\tthis.upload = upload;\n\t\tthis.api = api;\n\n\t\tthis.ignoreWarnings = [\n\t\t\t// we ignore these warnings, because the title is not our final title.\n\t\t\t'page-exists',\n\t\t\t'exists',\n\t\t\t'exists-normalized',\n\t\t\t'was-deleted',\n\t\t\t'badfilename',\n\t\t\t'bad-prefix'\n\t\t];\n\n\t\tthis.upload.on( 'remove-upload', this.abort.bind( this ) );\n\t};\n\n\t/**\n\t * @method\n\t * @abstract\n\t */\n\tmw.ApiUploadHandler.prototype.abort = null;\n\n\t/**\n\t * @method\n\t * @abstract\n\t * @return {jQuery.Promise}\n\t */\n\tmw.ApiUploadHandler.prototype.submit = null;\n\n\t/**\n\t * @return {jQuery.Promise}\n\t */\n\tmw.ApiUploadHandler.prototype.start = function () {\n\t\treturn this.submit().then(\n\t\t\tthis.setTransported.bind( this ),\n\t\t\tthis.setTransportError.bind( this )\n\t\t);\n\t};\n\n\t/**\n\t * Process a successful upload.\n\t *\n\t * @param {Object} result\n\t */\n\tmw.ApiUploadHandler.prototype.setTransported = function ( result ) {\n\t\tlet code;\n\t\tif ( result.upload && result.upload.warnings ) {\n\t\t\tfor ( code in result.upload.warnings ) {\n\t\t\t\tif ( !this.isIgnoredWarning( code ) ) {\n\t\t\t\t\tthis.setTransportWarning( code, result );\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( !result.upload || result.upload.result !== 'Success' ) {\n\t\t\tthis.setError( 'unknown', mw.message( 'unknown-error' ).parse() );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !result.upload.imageinfo ) {\n\t\t\tthis.setError( 'noimageinfo', mw.message( 'mediauploader-api-error-noimageinfo' ).parse() );\n\t\t\treturn;\n\t\t}\n\n\t\tthis.upload.setSuccess( result );\n\t};\n\n\t/**\n\t * Process an upload with a warning.\n\t *\n\t * @param {string} code The API warning code\n\t * @param {Object} result The API result in parsed JSON form\n\t */\n\tmw.ApiUploadHandler.prototype.setTransportWarning = function ( code, result ) {\n\t\tlet param, duplicates, links;\n\n\t\tswitch ( code ) {\n\t\t\tcase 'duplicate':\n\t\t\t\tduplicates = result.upload.warnings.duplicate;\n\t\t\t\tif ( result.upload.warnings.exists && result.upload.warnings.nochange ) {\n\t\t\t\t\t// An existing same (nochange) file will not show up as\n\t\t\t\t\t// duplicate, but it should also be present in order to\n\t\t\t\t\t// figure out how to process the attempted upload)\n\t\t\t\t\tduplicates.push( result.upload.warnings.exists );\n\t\t\t\t}\n\t\t\t\tthis.processDuplicateError( code, result, result.upload.warnings.duplicate );\n\t\t\t\treturn;\n\t\t\tcase 'nochange':\n\t\t\t\t// This is like 'duplicate', but also the filename is the same, which doesn't matter\n\t\t\t\tif ( result.upload.warnings.exists ) {\n\t\t\t\t\tlinks = this.getFileLinks( [ result.upload.warnings.exists ] );\n\t\t\t\t\tthis.setDuplicateError( code, result, links, {}, 1 - links.length );\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\tcase 'duplicate-archive':\n\t\t\t\tthis.setDuplicateArchiveError( code, result, result.upload.warnings[ 'duplicate-archive' ] );\n\t\t\t\treturn;\n\t\t\tdefault:\n\t\t\t\tparam = code;\n\t\t\t\tif ( typeof result.upload.warnings[ code ] === 'string' ) {\n\t\t\t\t\t// tack the original error code onto the warning message\n\t\t\t\t\tparam += mw.message( 'colon-separator' ).text() + result.upload.warnings[ code ];\n\t\t\t\t}\n\n\t\t\t\t// we have an unknown warning, so let's say what we know\n\t\t\t\tthis.setError( code, mw.message( 'mediauploader-api-error-unknown-warning', param ).parse() );\n\t\t\t\treturn;\n\t\t}\n\t};\n\n\t/**\n\t * Process an erroneous upload.\n\t *\n\t * @param {string} code The API error code\n\t * @param {Object} result The API result in parsed JSON form\n\t */\n\tmw.ApiUploadHandler.prototype.setTransportError = function ( code, result ) {\n\t\tlet $extra;\n\n\t\tif ( code === 'badtoken' ) {\n\t\t\tthis.api.badToken( 'csrf' );\n\n\t\t\t// Try again once\n\t\t\tif ( this.ignoreWarning( code ) ) {\n\t\t\t\tthis.start();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif ( code === 'abusefilter-warning' ) {\n\t\t\t$extra = new OO.ui.ButtonWidget( {\n\t\t\t\tlabel: mw.message( 'mediauploader-override' ).text(),\n\t\t\t\ttitle: mw.message( 'mediauploader-override-upload' ).text(),\n\t\t\t\tflags: 'progressive',\n\t\t\t\tframed: false\n\t\t\t} ).on( 'click', () => {\n\t\t\t\t// No need to ignore the error, AbuseFilter will only return it once\n\t\t\t\tthis.start();\n\t\t\t} ).$element;\n\t\t}\n\n\t\tthis.setError( code, result.errors[ 0 ].html, $extra );\n\t};\n\n\t/**\n\t * Figure out the source of duplicates (local or foreign) and distribute\n\t * them to the correct function to display the accurate error messages.\n\t *\n\t * @param {string} code\n\t * @param {Object} result\n\t * @param {string[] }duplicates\n\t * @return {jQuery.Promise}\n\t */\n\tmw.ApiUploadHandler.prototype.processDuplicateError = function ( code, result, duplicates ) {\n\t\tconst files = this.getFileLinks( duplicates ),\n\t\t\tunknownAmount = duplicates.length - Object.keys( files ).length;\n\n\t\treturn this.getDuplicateSource( Object.keys( files ) ).then(\n\t\t\t( data ) => {\n\t\t\t\tthis.setDuplicateError( code, result, data.local, data.foreign, unknownAmount );\n\t\t\t},\n\t\t\t() => {\n\t\t\t\t// if anything goes wrong trying to figure out the source of\n\t\t\t\t// duplicates, just move on with local duplicate handling\n\t\t\t\tthis.setDuplicateError( code, result, files, {}, unknownAmount );\n\t\t\t}\n\t\t);\n\t};\n\n\t/**\n\t * @param {string[]} duplicates Array of duplicate filenames\n\t * @return {jQuery.Promise}\n\t */\n\tmw.ApiUploadHandler.prototype.getDuplicateSource = function ( duplicates ) {\n\t\treturn this.getImageInfo( duplicates, 'url' ).then( ( result ) => {\n\t\t\tconst local = [],\n\t\t\t\tforeign = [],\n\t\t\t\tnormalized = [];\n\n\t\t\tif ( !result.query || !result.query.pages ) {\n\t\t\t\treturn $.Deferred().reject();\n\t\t\t}\n\n\t\t\t// map of normalized titles, so we can find original title\n\t\t\tif ( result.query.normalized ) {\n\t\t\t\tresult.query.normalized.forEach( ( data ) => {\n\t\t\t\t\tnormalized[ data.to ] = data.from;\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\tObject.keys( result.query.pages ).forEach( ( pageId ) => {\n\t\t\t\tconst page = result.query.pages[ pageId ],\n\t\t\t\t\ttitle = page.title in normalized ? normalized[ page.title ] : page.title;\n\t\t\t\tif ( page.imagerepository === 'local' ) {\n\t\t\t\t\tlocal[ title ] = page.imageinfo[ 0 ].descriptionurl;\n\t\t\t\t} else if ( page.imagerepository !== '' ) {\n\t\t\t\t\tforeign[ title ] = page.imageinfo[ 0 ].descriptionurl;\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\treturn $.Deferred().resolve( { local: local, foreign: foreign } );\n\t\t} );\n\t};\n\n\t/**\n\t * Helper function to generate existing duplicate errors in a possibly collapsible list.\n\t *\n\t * @param {string} code Warning code, should have matching strings in .i18n.php\n\t * @param {Object} result The API result in parsed JSON form\n\t * @param {Object} localDuplicates Array of [duplicate filenames => local url]\n\t * @param {Object} foreignDuplicates Array of [duplicate filenames => foreign url]\n\t * @param {number} unknownAmount Amount of unknown filenames (e.g. revdeleted)\n\t */\n\tmw.ApiUploadHandler.prototype.setDuplicateError = function ( code, result, localDuplicates, foreignDuplicates, unknownAmount ) {\n\t\tlet allDuplicates = Object.assign( {}, localDuplicates, foreignDuplicates ),\n\t\t\t$extra = $( '<div>' ),\n\t\t\t$ul = $( '<ul>' ).appendTo( $extra ),\n\t\t\t$a,\n\t\t\toverride,\n\t\t\ti;\n\n\t\tunknownAmount = unknownAmount || 0;\n\n\t\tObject.keys( allDuplicates ).forEach( ( filename ) => {\n\t\t\tconst href = allDuplicates[ filename ];\n\t\t\t$a = $( '<a>' ).text( filename );\n\t\t\t$a.attr( { href: href, target: '_blank' } );\n\t\t\t$ul.append( $( '<li>' ).append( $a ) );\n\t\t} );\n\n\t\tfor ( i = 0; i < unknownAmount; i++ ) {\n\t\t\t$a = $( '<em>' ).text( mw.msg( 'mediauploader-deleted-duplicate-unknown-filename' ) );\n\t\t\t$ul.append( $( '<li>' ).append( $a ) );\n\t\t}\n\n\t\tif ( allDuplicates.length > 1 ) {\n\t\t\t$ul.makeCollapsible( { collapsed: true } );\n\t\t}\n\n\t\t// allow upload to continue if it's only a duplicate of files in a\n\t\t// foreign repo, not when it's a local dupe\n\t\tif ( Object.keys( localDuplicates ).length === 0 ) {\n\t\t\toverride = new OO.ui.ButtonWidget( {\n\t\t\t\tlabel: mw.message( 'mediauploader-override' ).text(),\n\t\t\t\ttitle: mw.message( 'mediauploader-override-upload' ).text(),\n\t\t\t\tflags: 'progressive',\n\t\t\t\tframed: false\n\t\t\t} ).on( 'click', () => {\n\t\t\t\t// mark this warning as ignored & process the API result again\n\t\t\t\tthis.ignoreWarning( 'duplicate' );\n\t\t\t\tthis.setTransported( result );\n\t\t\t} );\n\n\t\t\toverride.$element.appendTo( $extra );\n\t\t}\n\n\t\tthis.setError( code, mw.message( 'file-exists-duplicate', allDuplicates.length ).parse(), $extra );\n\t};\n\n\t/**\n\t * Helper function to generate deleted duplicate errors in a possibly collapsible list.\n\t *\n\t * @param {string} code Warning code, should have matching strings in .i18n.php\n\t * @param {Object} result The API result in parsed JSON form\n\t * @param {string} duplicate Duplicate filename\n\t */\n\tmw.ApiUploadHandler.prototype.setDuplicateArchiveError = function ( code, result, duplicate ) {\n\t\tconst filename = mw.Title.makeTitle( NS_FILE, duplicate ).getPrefixedText(),\n\t\t\tuploadDuplicate = new OO.ui.ButtonWidget( {\n\t\t\t\tlabel: mw.message( 'mediauploader-override' ).text(),\n\t\t\t\ttitle: mw.message( 'mediauploader-override-upload' ).text(),\n\t\t\t\tflags: 'progressive',\n\t\t\t\tframed: false\n\t\t\t} ).on( 'click', () => {\n\t\t\t\t// mark this warning as ignored & process the API result again\n\t\t\t\tthis.ignoreWarning( 'duplicate-archive' );\n\t\t\t\tthis.setTransported( result );\n\t\t\t} );\n\n\t\tthis.setError( code, mw.message( 'file-deleted-duplicate', filename ).parse(), uploadDuplicate.$element );\n\t};\n\n\t/**\n\t * @param {string|string[]} titles File title or array of titles\n\t * @param {string|string[]} prop Image props\n\t * @return {jQuery.Promise}\n\t */\n\tmw.ApiUploadHandler.prototype.getImageInfo = function ( titles, prop ) {\n\t\treturn this.api.get( {\n\t\t\taction: 'query',\n\t\t\ttitles: titles,\n\t\t\tprop: 'imageinfo',\n\t\t\tiiprop: prop\n\t\t} );\n\t};\n\n\t/**\n\t * Convert an array of non-prefixed filenames into a [filename => url] map.\n\t *\n\t * @param {string[]} filenames Array of non-prefixed filenames\n\t * @return {Object} Map of [prefixed filename => url]\n\t */\n\tmw.ApiUploadHandler.prototype.getFileLinks = function ( filenames ) {\n\t\tconst files = [];\n\n\t\tfilenames.forEach( ( filename ) => {\n\t\t\tlet title;\n\t\t\ttry {\n\t\t\t\ttitle = mw.Title.makeTitle( NS_FILE, filename );\n\t\t\t\tfiles[ title.getPrefixedText() ] = title.getUrl( {} );\n\t\t\t} catch ( e ) {\n\t\t\t\t// invalid filename (e.g. file was revdeleted)\n\t\t\t}\n\t\t} );\n\n\t\treturn files;\n\t};\n\n\t/**\n\t * @param {string} code Error code from API\n\t * @param {string} html Error message\n\t * @param {jQuery} [$extra]\n\t */\n\tmw.ApiUploadHandler.prototype.setError = function ( code, html, $extra ) {\n\t\tthis.upload.setError( code, html, $extra );\n\t};\n\n\t/**\n\t * Marks a warning to be ignored.\n\t *\n\t * @param {string} code\n\t * @return {boolean}\n\t */\n\tmw.ApiUploadHandler.prototype.ignoreWarning = function ( code ) {\n\t\tif ( this.isIgnoredWarning( code ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// mark the warning as being ignored, then restart the request\n\t\tthis.ignoreWarnings.push( code );\n\t\treturn true;\n\t};\n\n\t/**\n\t * Returns whether or not the warning is being ignored.\n\t *\n\t * @param {string} code\n\t * @return {boolean}\n\t */\n\tmw.ApiUploadHandler.prototype.isIgnoredWarning = function ( code ) {\n\t\treturn this.ignoreWarnings.includes( code );\n\t};\n}( mw.uploadWizard ) );\n","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-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/resources/jquery.arrowSteps/jquery.arrowSteps.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'$el' is never reassigned. Use 'const' instead.","line":39,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":39,"endColumn":7},{"ruleId":"prefer-const","severity":2,"message":"'$steps' is never reassigned. Use 'const' instead.","line":42,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":42,"endColumn":9},{"ruleId":"prefer-const","severity":2,"message":"'width' is never reassigned. Use 'const' instead.","line":44,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":44,"endColumn":8},{"ruleId":"prefer-const","severity":2,"message":"'$steps' is never reassigned. Use 'const' instead.","line":71,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":71,"endColumn":10}],"suppressedMessages":[],"errorCount":4,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*!\n * jQuery arrowSteps plugin\n * Copyright Neil Kandalgaonkar, 2010\n *\n * This work is licensed under the terms of the GNU General Public License,\n * version 2 or later.\n * (see http://www.fsf.org/licensing/licenses/gpl.html).\n * Derivative works and later versions of the code must be free software\n * licensed under the same or a compatible license.\n */\n\n/**\n * @class jQuery.plugin.arrowSteps\n */\n( function () {\n\t/**\n\t * Show users their progress through a series of steps, via a row of items that fit\n\t * together like arrows. One item can be highlighted at a time.\n\t *\n\t * <ul id=\"robin-hood-daffy\">\n\t * <li id=\"guard\"><div>Guard!</div></li>\n\t * <li id=\"turn\"><div>Turn!</div></li>\n\t * <li id=\"parry\"><div>Parry!</div></li>\n\t * <li id=\"dodge\"><div>Dodge!</div></li>\n\t * <li id=\"spin\"><div>Spin!</div></li>\n\t * <li id=\"ha\"><div>Ha!</div></li>\n\t * <li id=\"thrust\"><div>Thrust!</div></li>\n\t * </ul>\n\t *\n\t * <script>\n\t * $( '#robin-hood-daffy' ).arrowSteps();\n\t * </script>\n\t *\n\t * @return {jQuery}\n\t * @chainable\n\t */\n\t$.fn.arrowSteps = function () {\n\t\tlet $steps, width,\n\t\t\t$el = this;\n\n\t\t$el.addClass( 'arrowSteps' );\n\t\t$steps = $el.find( 'li' );\n\n\t\twidth = Math.floor( 100 / $steps.length * 100 ) / 100;\n\t\t$steps.css( 'width', width + '%' );\n\n\t\t// Every step except the last one has an arrow pointing forward:\n\t\t// at the right hand side in LTR languages, and at the left hand side in RTL.\n\t\t$steps.filter( ':not(:last-child)' ).addClass( 'arrow' );\n\n\t\t$el.data( 'arrowSteps', $steps );\n\n\t\treturn this;\n\t};\n\n\t/**\n\t * Highlights the element selected by the selector.\n\t *\n\t * $( '#robin-hood-daffy' ).arrowStepsHighlight( '#guard' );\n\t * // 'Guard!' is highlighted.\n\t *\n\t * // ... user completes the 'guard' step ...\n\t *\n\t * $( '#robin-hood-daffy' ).arrowStepsHighlight( '#turn' );\n\t * // 'Turn!' is highlighted.\n\t *\n\t * @param {string} selector\n\t */\n\t$.fn.arrowStepsHighlight = function ( selector ) {\n\t\tlet $previous,\n\t\t\t$steps = this.data( 'arrowSteps' );\n\t\t$steps.each( function () {\n\t\t\tconst $step = $( this );\n\t\t\tif ( $step.is( selector ) ) {\n\t\t\t\tif ( $previous ) {\n\t\t\t\t\t$previous.addClass( 'tail' );\n\t\t\t\t}\n\t\t\t\t$step.addClass( 'head' );\n\t\t\t} else {\n\t\t\t\t$step.removeClass( 'head tail lasthead' );\n\t\t\t}\n\t\t\t$previous = $step;\n\t\t} );\n\t};\n\n\t/**\n\t * @class jQuery\n\t */\n}() );\n","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-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/resources/jquery/jquery.morphCrossfade.js","messages":[],"suppressedMessages":[{"ruleId":"no-jquery/no-animate","severity":2,"message":"Prefer CSS transitions to .animate","line":105,"column":6,"nodeType":"CallExpression","endLine":107,"endColumn":9,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-animate","severity":2,"message":"Prefer CSS transitions to .animate","line":113,"column":5,"nodeType":"CallExpression","endLine":118,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-animate","severity":2,"message":"Prefer CSS transitions to .animate","line":120,"column":5,"nodeType":"CallExpression","endLine":120,"endColumn":54,"suppressions":[{"kind":"directive","justification":""}]}],"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-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/resources/mw.DestinationChecker.js","messages":[{"ruleId":"no-mixed-spaces-and-tabs","severity":2,"message":"Mixed spaces and tabs.","line":77,"column":4,"nodeType":"Program","messageId":"mixedSpacesAndTabs","endLine":77,"endColumn":6},{"ruleId":"implicit-arrow-linebreak","severity":2,"message":"Expected no linebreak before this expression.","line":77,"column":6,"nodeType":"Identifier","messageId":"unexpected","endLine":77,"endColumn":7},{"ruleId":"no-mixed-spaces-and-tabs","severity":2,"message":"Mixed spaces and tabs.","line":78,"column":3,"nodeType":"Program","messageId":"mixedSpacesAndTabs","endLine":78,"endColumn":5},{"ruleId":"prefer-const","severity":2,"message":"'checker' is never reassigned. Use 'const' instead.","line":94,"column":8,"nodeType":"Identifier","messageId":"useConst","endLine":94,"endColumn":15},{"ruleId":"prefer-const","severity":2,"message":"'NS_FILE' is never reassigned. Use 'const' instead.","line":95,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":95,"endColumn":12},{"ruleId":"prefer-const","severity":2,"message":"'titleObj' is never reassigned. Use 'const' instead.","line":98,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":98,"endColumn":12},{"ruleId":"prefer-const","severity":2,"message":"'ext' is never reassigned. Use 'const' instead.","line":99,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":99,"endColumn":7},{"ruleId":"prefer-const","severity":2,"message":"'prefix' is never reassigned. Use 'const' instead.","line":101,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":101,"endColumn":10}],"suppressedMessages":[],"errorCount":8,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"( function () {\n\n\tmw.DestinationChecker = {\n\n\t\tapi: new mw.Api(),\n\n\t\t// cached results from uniqueness api calls\n\t\tcachedResult: {},\n\t\tcachedBlacklist: {},\n\n\t\t/**\n\t\t * Check title for validity.\n\t\t *\n\t\t * @param {string} title Title to check\n\t\t * @return {jQuery.Promise}\n\t\t * {Function} return.done\n\t\t * {string} return.done.title The title that was passed in\n\t\t * {Object|boolean} return.done.blacklist See #checkBlacklist\n\t\t * {Object|boolean} return.done.unique See #checkUnique\n\t\t */\n\t\tcheckTitle: function ( title ) {\n\t\t\treturn $.when(\n\t\t\t\tthis.checkUnique( title ),\n\t\t\t\tthis.checkBlacklist( title )\n\t\t\t).then( ( unique, blacklist ) => ( {\n\t\t\t\tunique: unique,\n\t\t\t\tblacklist: blacklist,\n\t\t\t\ttitle: title\n\t\t\t} ) );\n\t\t},\n\n\t\t/**\n\t\t * Async check if a title is in the titleblacklist.\n\t\t *\n\t\t * @param {string} title Title to check against the blacklist\n\t\t * @return {jQuery.Promise}\n\t\t * {Function} return.done\n\t\t * {boolean} return.done.notBlacklisted\n\t\t * {string} [return.done.blacklistReason] See mw.Api#isBlacklisted\n\t\t * {string} [return.done.blacklistMessage] See mw.Api#isBlacklisted\n\t\t * {string} [return.done.blacklistLine] See mw.Api#isBlacklisted\n\t\t */\n\t\tcheckBlacklist: function ( title ) {\n\t\t\tconst checker = this;\n\n\t\t\t/**\n\t\t\t * Process result of a TitleBlacklist API call.\n\t\t\t *\n\t\t\t * @private\n\t\t\t * @param {Object|boolean} blacklistResult `false` if not blacklisted, object if blacklisted\n\t\t\t * @return {Object}\n\t\t\t */\n\t\t\tfunction blacklistResultProcessor( blacklistResult ) {\n\t\t\t\tlet result;\n\n\t\t\t\tif ( blacklistResult === false ) {\n\t\t\t\t\tresult = { notBlacklisted: true };\n\t\t\t\t} else {\n\t\t\t\t\tresult = {\n\t\t\t\t\t\tnotBlacklisted: false,\n\t\t\t\t\t\tblacklistReason: blacklistResult.reason,\n\t\t\t\t\t\tblacklistMessage: blacklistResult.message,\n\t\t\t\t\t\tblacklistLine: blacklistResult.line\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tchecker.cachedBlacklist[ title ] = result;\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tif ( this.cachedBlacklist[ title ] !== undefined ) {\n\t\t\t\treturn $.Deferred().resolve( this.cachedBlacklist[ title ] );\n\t\t\t}\n\n\t\t\treturn mw.loader.using( 'mediawiki.api.titleblacklist' ).then( () => checker.api.isBlacklisted( title ).then( blacklistResultProcessor ), () =>\n\t\t\t\t// it's not blacklisted, because the API isn't even available\n\t\t\t\t $.Deferred().resolve( { notBlacklisted: true, unavailable: true } )\n\t\t\t );\n\t\t},\n\n\t\t/**\n\t\t * Async check if a filename is unique. Can be attached to a field's change() event\n\t\t * This is a more abstract version of AddMedia/UploadHandler.js::doDestCheck\n\t\t *\n\t\t * @param {string} title Title to check for uniqueness\n\t\t * @return {jQuery.Promise}\n\t\t * {Function} return.done\n\t\t * {boolean} return.done.isUnique\n\t\t * {boolean} [return.done.isProtected]\n\t\t * {Object} [return.done.img] Image info\n\t\t * {string} [return.done.href] URL to file description page\n\t\t */\n\t\tcheckUnique: function ( title ) {\n\t\t\tlet checker = this,\n\t\t\t\tNS_FILE = mw.config.get( 'wgNamespaceIds' ).file,\n\t\t\t\ttitleObj, prefix, ext;\n\n\t\t\ttitleObj = mw.Title.newFromText( title );\n\t\t\text = mw.Title.normalizeExtension( titleObj.getExtension() || '' );\n\t\t\t// Strip namespace and file extension\n\t\t\tprefix = titleObj.getNameText();\n\n\t\t\t/**\n\t\t\t * Process result of a an imageinfo API call.\n\t\t\t *\n\t\t\t * @private\n\t\t\t * @param {Object} data API result\n\t\t\t * @return {Object}\n\t\t\t */\n\t\t\tfunction checkUniqueProcessor( data ) {\n\t\t\t\tlet result, protection, pageId, ntitle, ntitleObj, img;\n\n\t\t\t\tresult = { isUnique: true };\n\n\t\t\t\tif ( data.query && data.query.pages ) {\n\t\t\t\t\t// The API will check for files with that filename.\n\t\t\t\t\t// If no file found: a page with a key of -1 and no imageinfo\n\t\t\t\t\t// If file found on another repository, such as when the wiki is using InstantCommons: page with a key of -1, plus imageinfo\n\t\t\t\t\t// If file found on this repository: page with some positive numeric key\n\t\t\t\t\tif ( data.query.pages[ -1 ] && !data.query.pages[ -1 ].imageinfo ) {\n\t\t\t\t\t\tprotection = data.query.pages[ -1 ].protection;\n\t\t\t\t\t\tif ( protection && protection.length > 0 ) {\n\t\t\t\t\t\t\tprotection.forEach( ( val ) => {\n\t\t\t\t\t\t\t\tif ( !mw.config.get( 'wgUserGroups' ).includes( val.level ) ) {\n\t\t\t\t\t\t\t\t\tresult = {\n\t\t\t\t\t\t\t\t\t\tisUnique: true,\n\t\t\t\t\t\t\t\t\t\tisProtected: true\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// No conflict found on any repository this wiki uses\n\t\t\t\t\t\t\tresult = { isUnique: true };\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfor ( pageId in data.query.pages ) {\n\t\t\t\t\t\t\tif ( !Object.prototype.hasOwnProperty.call( data.query.pages, pageId ) ) {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tntitle = data.query.pages[ pageId ].title;\n\t\t\t\t\t\t\tntitleObj = mw.Title.newFromText( ntitle );\n\t\t\t\t\t\t\tif ( ntitleObj.getNameText() !== prefix ) {\n\t\t\t\t\t\t\t\t// It's a different file name entirely\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( ext !== mw.Title.normalizeExtension( ntitleObj.getExtension() || '' ) ) {\n\t\t\t\t\t\t\t\t// It's a different extension, that's fine (e.g. to upload a SVG version of a PNG file)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Conflict found, this filename is NOT unique\n\n\t\t\t\t\t\t\tif ( !data.query.pages[ pageId ].imageinfo ) {\n\t\t\t\t\t\t\t\t// This means that there's a page, but it's not a file. Well,\n\t\t\t\t\t\t\t\t// we should really report that anyway, but we shouldn't process\n\t\t\t\t\t\t\t\t// it like a file, and we should defer to other entries that may be files.\n\t\t\t\t\t\t\t\tresult = {\n\t\t\t\t\t\t\t\t\tisUnique: false,\n\t\t\t\t\t\t\t\t\ttitle: ntitle,\n\t\t\t\t\t\t\t\t\timg: null,\n\t\t\t\t\t\t\t\t\thref: null\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\timg = data.query.pages[ pageId ].imageinfo[ 0 ];\n\n\t\t\t\t\t\t\tresult = {\n\t\t\t\t\t\t\t\tisUnique: false,\n\t\t\t\t\t\t\t\timg: img,\n\t\t\t\t\t\t\t\ttitle: ntitle,\n\t\t\t\t\t\t\t\thref: img.descriptionurl\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tif ( this.cachedResult[ title ] !== undefined ) {\n\t\t\t\treturn $.Deferred().resolve( this.cachedResult[ title ] );\n\t\t\t}\n\n\t\t\t// Setup the request -- will return thumbnail data if it finds one\n\t\t\t// XXX do not use iiurlwidth as it will create a thumbnail\n\t\t\treturn $.when(\n\t\t\t\t// Checks for exact matches on this wiki and foreign file repos\n\t\t\t\tthis.api.get( {\n\t\t\t\t\taction: 'query',\n\t\t\t\t\ttitles: title,\n\t\t\t\t\tprop: 'info|imageinfo',\n\t\t\t\t\tinprop: 'protection',\n\t\t\t\t\tiiprop: 'url|mime|size',\n\t\t\t\t\tiiurlwidth: 150\n\t\t\t\t} ).then( checkUniqueProcessor ),\n\t\t\t\t// Checks for matches with different versions of the file extension on this wiki only\n\t\t\t\tthis.api.get( {\n\t\t\t\t\taction: 'query',\n\t\t\t\t\tgenerator: 'allpages',\n\t\t\t\t\tgapnamespace: NS_FILE,\n\t\t\t\t\tgapprefix: prefix,\n\t\t\t\t\tprop: 'info|imageinfo',\n\t\t\t\t\tinprop: 'protection',\n\t\t\t\t\tiiprop: 'url|mime|size',\n\t\t\t\t\tiiurlwidth: 150\n\t\t\t\t} ).then( checkUniqueProcessor )\n\t\t\t).then( ( exact, fuzzy ) => {\n\t\t\t\tlet result;\n\t\t\t\tif ( !exact.isUnique || exact.isProtected ) {\n\t\t\t\t\tresult = exact;\n\t\t\t\t} else if ( !fuzzy.isUnique || fuzzy.isProtected ) {\n\t\t\t\t\tresult = fuzzy;\n\t\t\t\t} else {\n\t\t\t\t\tresult = { isUnique: true };\n\t\t\t\t}\n\n\t\t\t\tchecker.cachedResult[ title ] = result;\n\t\t\t\treturn result;\n\t\t\t} );\n\t\t},\n\n\t\t/**\n\t\t * Clears the result cache\n\t\t */\n\t\tclearCache: function () {\n\t\t\tthis.cachedResult = {};\n\t\t}\n\n\t};\n\n}() );\n","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-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/resources/mw.Escaper.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'extractedTemplates' is never reassigned. Use 'const' instead.","line":31,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":31,"endColumn":22},{"ruleId":"prefer-const","severity":2,"message":"'extractedLinks' is never reassigned. Use 'const' instead.","line":32,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":32,"endColumn":18},{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":34,"column":43,"nodeType":"MemberExpression","messageId":"forbidden","endLine":34,"endColumn":56},{"ruleId":"prefer-const","severity":2,"message":"'extracts' is never reassigned. Use 'const' instead.","line":52,"column":8,"nodeType":"Identifier","messageId":"useConst","endLine":52,"endColumn":16},{"ruleId":"prefer-const","severity":2,"message":"'regex' is never reassigned. Use 'const' instead.","line":61,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":61,"endColumn":10},{"ruleId":"prefer-const","severity":2,"message":"'callback' is never reassigned. Use 'const' instead.","line":62,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":62,"endColumn":13}],"suppressedMessages":[],"errorCount":5,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"( function () {\n\tmw.Escaper = {\n\t\t/**\n\t\t * Escapes wikitext for use inside {{templates}}.\n\t\t *\n\t\t * @param {string} wikitext\n\t\t * @return {string}\n\t\t */\n\t\tescapeForTemplate: function ( wikitext ) {\n\t\t\treturn this.escapePipes( wikitext );\n\t\t},\n\n\t\t/**\n\t\t * Escapes pipe characters, which could be problematic when the content is\n\t\t * inserted in a template.\n\t\t *\n\t\t * @param {string} wikitext\n\t\t * @return {string}\n\t\t */\n\t\tescapePipes: function ( wikitext ) {\n\t\t\tlet extractedTemplates, extractedLinks;\n\n\t\t\t// Pipes (`|`) must be escaped because we'll be inserting this\n\t\t\t// content into a templates & pipes would mess up the syntax.\n\t\t\t// First, urlencode pipes inside links:\n\t\t\twikitext = wikitext.replace( /\\bhttps?:\\/\\/[^\\s]+/g, ( match ) => match.replace( /\\|/g, '%7C' ) );\n\n\t\t\t// Second, pipes can be valid inside other templates or links in\n\t\t\t// wikitext, so we'll first extract those from the content, then\n\t\t\t// replace the pipes, then restore the original (extracted) content:\n\t\t\textractedTemplates = this.extractTemplates( wikitext );\n\t\t\textractedLinks = this.extractLinks( extractedTemplates[ 0 ] );\n\t\t\twikitext = extractedLinks[ 0 ].replace( /\\|/g, '{{!}}' );\n\t\t\treturn this.restoreExtracts( wikitext, Object.assign( extractedTemplates[ 1 ], extractedLinks[ 1 ] ) );\n\t\t},\n\n\t\t/**\n\t\t * Extract all {{templates}} from wikitext, replacing them with\n\t\t * placeholder content in the form of {{1}}, {{2}}.\n\t\t *\n\t\t * Nested templates will safely be extracted by first replacing inner\n\t\t * templates, then moving outwards, ensuring we don't get closing\n\t\t * bracket mismatches.\n\t\t *\n\t\t * Restoring the content is as simple as feeding the returned content &\n\t\t * replacements back into this.restoreExtracts.\n\t\t *\n\t\t * @param {string} wikitext\n\t\t * @return {Array} [{string} wikitext, {Object} replacements]\n\t\t */\n\t\textractTemplates: function ( wikitext ) {\n\t\t\tlet extracts = {},\n\t\t\t\tpreviousExtracts = {},\n\t\t\t\textracted = wikitext,\n\t\t\t\t// the regex explained:\n\t\t\t\t// * `[^\\{]`: character can not be {\n\t\t\t\t// * `\\{(?!\\{)`: or if it is, it can't be followed by another {\n\t\t\t\t// this excludes template opening brackets: {{\n\t\t\t\t// * `\\{\\{[0-9]+\\}\\}`: unless it's a complete {{[0-9]+}}\n\t\t\t\t// sequence, generated by an earlier run of this regex\n\t\t\t\tregex = /\\{\\{([^{]|\\{(?!\\{)|\\{\\{[0-9]+\\}\\})*?\\}\\}/g,\n\t\t\t\tcallback = function ( match ) {\n\t\t\t\t\tconst replacement = '{{' + Object.keys( extracts ).length + '}}';\n\n\t\t\t\t\t// safeguard for not replacing already-replaced matches\n\t\t\t\t\t// this makes sure that when real content contains something\n\t\t\t\t\t// like {{1}}, it will still be replaced, while {{1}}\n\t\t\t\t\t// generated by this code can be recognized & ignored\n\t\t\t\t\tif ( match in previousExtracts ) {\n\t\t\t\t\t\treturn match;\n\t\t\t\t\t}\n\n\t\t\t\t\textracts[ replacement ] = match;\n\t\t\t\t\treturn replacement;\n\t\t\t\t};\n\n\t\t\tdo {\n\t\t\t\twikitext = extracted;\n\t\t\t\tpreviousExtracts = OO.copy( extracts );\n\t\t\t\textracted = wikitext.replace( regex, callback );\n\t\t\t} while ( wikitext !== extracted );\n\n\t\t\treturn [ wikitext, extracts ];\n\t\t},\n\n\t\t/**\n\t\t * Extract all [[links]] from wikitext, replacing them with placeholder\n\t\t * content in the form of [[1]], [[2]].\n\t\t *\n\t\t * Restoring the content is as simple as feeding the returned content &\n\t\t * replacements back into this.restoreExtracts.\n\t\t *\n\t\t * @param {string} wikitext\n\t\t * @return {Array} [{string} wikitext, {Object} replacements]\n\t\t */\n\t\textractLinks: function ( wikitext ) {\n\t\t\tconst extracts = {};\n\n\t\t\twikitext = wikitext.replace( /\\[\\[.*?\\]\\]/g, ( match ) => {\n\t\t\t\tconst replacement = '[[' + Object.keys( extracts ).length + ']]';\n\t\t\t\textracts[ replacement ] = match;\n\t\t\t\treturn replacement;\n\t\t\t} );\n\n\t\t\treturn [ wikitext, extracts ];\n\t\t},\n\n\t\t/**\n\t\t * Restores content that was extracted from wikitext.\n\t\t *\n\t\t * @param {string} wikitext\n\t\t * @param {Object} replacements\n\t\t * @return {string}\n\t\t */\n\t\trestoreExtracts: function ( wikitext, replacements ) {\n\t\t\t// turn search keys into a regular expression, allowing us to match\n\t\t\t// all of them at once\n\t\t\tconst searchValues = Object.keys( replacements ).map( mw.util.escapeRegExp ),\n\t\t\t\tsearchRegex = new RegExp( '(' + searchValues.join( '|' ) + ')', 'g' ),\n\t\t\t\tcallback = function ( match ) {\n\t\t\t\t\tconst replacement = replacements[ match ];\n\n\t\t\t\t\t// we matched something that has no replacement, must be valid\n\t\t\t\t\t// user input that just happens to look like on of the\n\t\t\t\t\t// replacement values\n\t\t\t\t\tif ( replacement === undefined ) {\n\t\t\t\t\t\treturn match;\n\t\t\t\t\t}\n\n\t\t\t\t\t// if we find the replacement itself matches a search value, we\n\t\t\t\t\t// also don't want to go recursive: nesting doesn't work like\n\t\t\t\t\t// that, it's just a coincidence where user input happens to\n\t\t\t\t\t// look just like a replacement value (e.g. `{{1}}`)\n\t\t\t\t\tif ( replacement in replacements ) {\n\t\t\t\t\t\treturn replacement;\n\t\t\t\t\t}\n\n\t\t\t\t\t// we must not replace this one again, to avoid getting stuck in\n\t\t\t\t\t// endless recursion\n\t\t\t\t\tdelete replacements[ match ];\n\n\t\t\t\t\t// go recursive, there may be more replacements nested down there\n\t\t\t\t\treturn this.restoreExtracts( replacement, replacements );\n\t\t\t\t}.bind( this );\n\n\t\t\treturn wikitext.replace( searchRegex, callback );\n\t\t}\n\t};\n}() );\n","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-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/resources/mw.GroupProgressBar.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'bar' is never reassigned. Use 'const' instead.","line":59,"column":8,"nodeType":"Identifier","messageId":"useConst","endLine":59,"endColumn":11},{"ruleId":"prefer-const","severity":2,"message":"'remainingTime' is never reassigned. Use 'const' instead.","line":146,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":146,"endColumn":18}],"suppressedMessages":[{"ruleId":"no-jquery/no-fade","severity":2,"message":"Prefer CSS transitions to .fadeIn","line":52,"column":4,"nodeType":"CallExpression","endLine":52,"endColumn":74,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-fade","severity":2,"message":"Prefer CSS transitions to .fadeOut","line":123,"column":4,"nodeType":"CallExpression","endLine":123,"endColumn":75,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":2,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* global moment */\n( function () {\n\t/**\n\t * This is a progress bar for monitoring multiple objects, giving summary view\n\t *\n\t * @class mw.GroupProgressbar\n\t * @constructor\n\t * @param {string} selector\n\t * @param {mw.UploadWizardUpload[]} uploads\n\t * @param {string[]} successStates\n\t * @param {string[]} errorStates\n\t * @param {string} progressProperty\n\t * @param {string} weightProperty\n\t */\n\tmw.GroupProgressBar = function ( selector, uploads, successStates, errorStates, progressProperty, weightProperty ) {\n\t\tthis.$selector = $( selector );\n\t\tthis.$selector.empty().append(\n\t\t\t$( '<div>' ).addClass( 'mediauploader-progress-inner' ).append(\n\t\t\t\t$( '<div>' ).addClass( 'mediauploader-progress-bar-etr-container' ).append(\n\t\t\t\t\t$( '<div>' ).addClass( 'mediauploader-progress-bar-etr' ).hide().append(\n\t\t\t\t\t\t$( '<div>' ).addClass( 'mediauploader-etr' )\n\t\t\t\t\t)\n\t\t\t\t),\n\t\t\t\t$( '<div>' ).addClass( 'mediauploader-count' )\n\t\t\t)\n\t\t);\n\n\t\tthis.progressBarWidget = new OO.ui.ProgressBarWidget( {\n\t\t\tclasses: [ 'mediauploader-progress-bar' ],\n\t\t\tprogress: 0\n\t\t} );\n\n\t\tthis.$selector.find( '.mediauploader-progress-bar-etr' )\n\t\t\t.prepend( this.progressBarWidget.$element );\n\n\t\tthis.uploads = uploads;\n\t\tthis.successStates = successStates;\n\t\tthis.errorStates = errorStates;\n\t\tthis.progressProperty = progressProperty;\n\t\tthis.weightProperty = weightProperty;\n\t\tthis.beginTime = undefined;\n\t};\n\n\tmw.GroupProgressBar.prototype = {\n\n\t\t/**\n\t\t * Show the progress bar\n\t\t */\n\t\tshowBar: function () {\n\t\t\t// FIXME: Use CSS transition\n\t\t\t// eslint-disable-next-line no-jquery/no-fade\n\t\t\tthis.$selector.find( '.mediauploader-progress-bar-etr' ).fadeIn( 200 );\n\t\t},\n\n\t\t/**\n\t\t * loop around the uploads, summing certain properties for a weighted total fraction\n\t\t */\n\t\tstart: function () {\n\t\t\tlet bar = this,\n\t\t\t\tshown = false;\n\n\t\t\tthis.setBeginTime();\n\n\t\t\tfunction displayer() {\n\t\t\t\tlet totalWeight = 0.0,\n\t\t\t\t\tfraction = 0.0,\n\t\t\t\t\tsuccessStateCount = 0,\n\t\t\t\t\terrorStateCount = 0,\n\t\t\t\t\thasData = false;\n\n\t\t\t\tbar.uploads.forEach( ( upload ) => {\n\t\t\t\t\ttotalWeight += upload[ bar.weightProperty ];\n\t\t\t\t} );\n\n\t\t\t\tbar.uploads.forEach( ( upload ) => {\n\t\t\t\t\tif ( upload.state === 'aborted' ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif ( bar.successStates.includes( upload.state ) ) {\n\t\t\t\t\t\tsuccessStateCount++;\n\t\t\t\t\t}\n\t\t\t\t\tif ( bar.errorStates.includes( upload.state ) ) {\n\t\t\t\t\t\terrorStateCount++;\n\t\t\t\t\t}\n\t\t\t\t\tif ( upload[ bar.progressProperty ] !== undefined ) {\n\t\t\t\t\t\tfraction += upload[ bar.progressProperty ] * ( upload[ bar.weightProperty ] / totalWeight );\n\t\t\t\t\t\tif ( upload[ bar.progressProperty ] > 0 ) {\n\t\t\t\t\t\t\thasData = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\n\t\t\t\t// sometimes, the first data we have just tells us that it's over. So only show the bar\n\t\t\t\t// if we have good data AND the fraction is less than 1.\n\t\t\t\tif ( hasData && fraction < 1.0 ) {\n\t\t\t\t\tif ( !shown ) {\n\t\t\t\t\t\tbar.showBar();\n\t\t\t\t\t\tshown = true;\n\t\t\t\t\t}\n\t\t\t\t\tbar.showProgress( fraction );\n\t\t\t\t}\n\t\t\t\tbar.showCount( successStateCount );\n\n\t\t\t\tif ( successStateCount + errorStateCount < bar.uploads.length - bar.countRemoved() ) {\n\t\t\t\t\tsetTimeout( displayer, 200 );\n\t\t\t\t} else {\n\t\t\t\t\tbar.showProgress( 1.0 );\n\t\t\t\t\tbar.finished = true;\n\t\t\t\t\tsetTimeout( () => {\n\t\t\t\t\t\tbar.hideBar();\n\t\t\t\t\t}, 500 );\n\t\t\t\t}\n\t\t\t}\n\t\t\tdisplayer();\n\t\t},\n\n\t\t/**\n\t\t * Hide the progress bar with a slideup motion\n\t\t */\n\t\thideBar: function () {\n\t\t\t// FIXME: Use CSS transition\n\t\t\t// eslint-disable-next-line no-jquery/no-fade\n\t\t\tthis.$selector.find( '.mediauploader-progress-bar-etr' ).fadeOut( 200 );\n\t\t},\n\n\t\t/**\n\t\t * sets the beginning time (useful for figuring out estimated time remaining)\n\t\t * if time parameter omitted, will set beginning time to now\n\t\t *\n\t\t * @param {number} [time] The time this bar is presumed to have started (epoch milliseconds)\n\t\t */\n\t\tsetBeginTime: function ( time ) {\n\t\t\tthis.beginTime = time || Date.now();\n\t\t},\n\n\t\t/**\n\t\t * Show overall progress for the entire UploadWizard\n\t\t * The current design doesn't have individual progress bars, just one giant one.\n\t\t * We did some tricky calculations in startUploads to try to weight each individual file's progress against\n\t\t * the overall progress.\n\t\t *\n\t\t * @param {number} fraction The amount of whatever it is that's done whatever it's done\n\t\t */\n\t\tshowProgress: function ( fraction ) {\n\t\t\tlet t, timeString,\n\t\t\t\tremainingTime = this.getRemainingTime( fraction );\n\n\t\t\tthis.progressBarWidget.setProgress( parseInt( fraction * 100, 10 ) );\n\n\t\t\tif ( remainingTime !== null ) {\n\t\t\t\tif ( remainingTime === 0 ) {\n\t\t\t\t\ttimeString = mw.message( 'mediauploader-finished' ).text();\n\t\t\t\t} else if ( remainingTime < 1000 ) {\n\t\t\t\t\ttimeString = mw.message( 'mediauploader-almost-finished' ).text();\n\t\t\t\t} else {\n\t\t\t\t\tt = moment.duration( remainingTime );\n\t\t\t\t\ttimeString = t.humanize();\n\t\t\t\t}\n\n\t\t\t\tthis.$selector.find( '.mediauploader-etr' ).text( timeString );\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Calculate remaining time for all uploads to complete.\n\t\t *\n\t\t * @param {number} fraction Fraction of progress to show\n\t\t * @return {number} Estimated time remaining (in milliseconds)\n\t\t */\n\t\tgetRemainingTime: function ( fraction ) {\n\t\t\tlet elapsedTime, rate;\n\t\t\tif ( this.beginTime ) {\n\t\t\t\telapsedTime = Date.now() - this.beginTime;\n\t\t\t\tif ( fraction > 0.0 && elapsedTime > 0 ) { // or some other minimums for good data\n\t\t\t\t\trate = fraction / elapsedTime;\n\t\t\t\t\treturn ( ( 1.0 - fraction ) / rate );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\n\t\t/**\n\t\t * Show the overall count as we upload\n\t\t *\n\t\t * @param {number} completed The number of items that have done whatever has been done e.g. in \"uploaded 2 of 5\", this is the 2\n\t\t */\n\t\tshowCount: function ( completed ) {\n\t\t\tconst total = this.uploads.length - this.countRemoved();\n\t\t\tthis.$selector\n\t\t\t\t.find( '.mediauploader-count' )\n\t\t\t\t// Hide if there are no uploads, show otherwise\n\t\t\t\t.toggle( total !== 0 )\n\t\t\t\t.html( mw.message( 'mediauploader-upload-count', completed, total ).escaped() );\n\t\t},\n\n\t\tcountRemoved: function () {\n\t\t\tlet count = 0;\n\t\t\tthis.uploads.forEach( ( upload ) => {\n\t\t\t\tif ( !upload || upload.state === 'aborted' ) {\n\t\t\t\t\tcount += 1;\n\t\t\t\t}\n\t\t\t} );\n\t\t\treturn count;\n\t\t}\n\t};\n}() );\n","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-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/resources/mw.QuickTitleChecker.js","messages":[],"suppressedMessages":[{"ruleId":"no-control-regex","severity":2,"message":"Unexpected control character(s) in regular expression: \\x00, \\x1f.","line":27,"column":4,"nodeType":"Literal","messageId":"unexpected","endLine":27,"endColumn":17,"suppressions":[{"kind":"directive","justification":""}]}],"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-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/resources/mw.UploadWizard.js","messages":[{"ruleId":"jsdoc/require-param-type","severity":1,"message":"Missing JSDoc @param \"uw\" type.","line":4,"column":1,"nodeType":"Block","endLine":4,"endColumn":1},{"ruleId":"prefer-const","severity":2,"message":"'maxSimPref' is never reassigned. Use 'const' instead.","line":22,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":22,"endColumn":13},{"ruleId":"prefer-const","severity":2,"message":"'self' is never reassigned. Use 'const' instead.","line":64,"column":8,"nodeType":"Identifier","messageId":"useConst","endLine":64,"endColumn":12},{"ruleId":"prefer-const","severity":2,"message":"'steps' is never reassigned. Use 'const' instead.","line":65,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":65,"endColumn":10},{"ruleId":"prefer-const","severity":2,"message":"'uploadStep' is never reassigned. Use 'const' instead.","line":74,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":74,"endColumn":14},{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":127,"column":5,"nodeType":"MemberExpression","messageId":"forbidden","endLine":127,"endColumn":18},{"ruleId":"prefer-const","severity":2,"message":"'original' is never reassigned. Use 'const' instead.","line":134,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":134,"endColumn":13},{"ruleId":"prefer-const","severity":2,"message":"'override' is never reassigned. Use 'const' instead.","line":138,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":138,"endColumn":13},{"ruleId":"prefer-const","severity":2,"message":"'deeds' is never reassigned. Use 'const' instead.","line":187,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":187,"endColumn":9},{"ruleId":"prefer-const","severity":2,"message":"'doOwnWork' is never reassigned. Use 'const' instead.","line":188,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":188,"endColumn":13},{"ruleId":"prefer-const","severity":2,"message":"'doThirdParty' is never reassigned. Use 'const' instead.","line":189,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":189,"endColumn":16},{"ruleId":"prefer-const","severity":2,"message":"'api' is never reassigned. Use 'const' instead.","line":197,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":197,"endColumn":6}],"suppressedMessages":[],"errorCount":10,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Object that represents the entire multi-step Upload Wizard\n *\n * @param uw\n */\n\n( function ( uw ) {\n\n\tmw.UploadWizard = function ( config ) {\n\t\tlet maxSimPref;\n\n\t\tthis.api = this.getApi( { ajax: { timeout: 0 } } );\n\n\t\t// making a sort of global for now, should be done by passing in config or fragments of config\n\t\t// when needed elsewhere\n\t\tmw.UploadWizard.config = config;\n\t\t// Shortcut for local references\n\t\tthis.config = config;\n\n\t\tthis.steps = {};\n\n\t\tmaxSimPref = mw.user.options.get( 'upwiz_maxsimultaneous' );\n\n\t\tif ( maxSimPref !== 'default' ) {\n\t\t\tif ( maxSimPref > 0 ) {\n\t\t\t\tconfig.maxSimultaneousConnections = maxSimPref;\n\t\t\t} else {\n\t\t\t\tconfig.maxSimultaneousConnections = 1;\n\t\t\t}\n\t\t}\n\n\t\tthis.maxSimultaneousConnections = config.maxSimultaneousConnections;\n\n\t\tif ( mw.loader.getState( 'ext.uls.mediawiki' ) !== null ) {\n\t\t\tmw.loader.load( 'ext.uls.mediawiki' );\n\t\t}\n\t};\n\n\tmw.UploadWizard.DEBUG = true;\n\n\tmw.UploadWizard.userAgent = 'UploadWizard';\n\n\tmw.UploadWizard.prototype = {\n\t\t/**\n\t\t * Create the basic interface to make an upload in this div\n\t\t *\n\t\t * @param {string} selector\n\t\t */\n\t\tcreateInterface: function ( selector ) {\n\t\t\tthis.ui = new uw.ui.Wizard( selector );\n\n\t\t\tthis.initialiseSteps().then( ( steps ) => {\n\t\t\t\t// \"select\" the first step - highlight, make it visible, hide all others\n\t\t\t\tsteps[ 0 ].load( [] );\n\t\t\t} );\n\t\t},\n\n\t\t/**\n\t\t * Initialise the steps in the wizard\n\t\t *\n\t\t * @return {jQuery.Promise}\n\t\t */\n\t\tinitialiseSteps: function () {\n\t\t\tlet self = this,\n\t\t\t\tsteps = [],\n\t\t\t\ti,\n\t\t\t\tuploadStep;\n\n\t\t\t// Add the tutorial step if it's enabled\n\t\t\tif ( this.config.tutorial.enabled ) {\n\t\t\t\tsteps.push( new uw.controller.Tutorial( this.api, this.config ) );\n\t\t\t}\n\n\t\t\tuploadStep = new uw.controller.Upload( this.api, this.config );\n\t\t\tsteps.push( uploadStep );\n\n\t\t\t// Add the licensing step if it's enabled\n\t\t\tif ( this.config.licensing.enabled ) {\n\t\t\t\tsteps.push( new uw.controller.Deed( this.api, this.config ) );\n\t\t\t}\n\n\t\t\tsteps.push(\n\t\t\t\tnew uw.controller.Details( this.api, this.config ),\n\t\t\t\tnew uw.controller.Thanks( this.api, this.config )\n\t\t\t);\n\n\t\t\t// The first step obviously does not have a previous step\n\t\t\tsteps[ 0 ].setNextStep( steps[ 1 ] );\n\n\t\t\t// The \"intermediate\" steps can navigate in both directions\n\t\t\tfor ( i = 1; i < steps.length - 1; i++ ) {\n\t\t\t\tsteps[ i ].setPreviousStep( steps[ i - 1 ] );\n\t\t\t\tsteps[ i ].setNextStep( steps[ i + 1 ] );\n\t\t\t}\n\n\t\t\t// The last step does not have a \"previous\" step, there's no undoing uploads!\n\t\t\t// The \"next\" one is always looping back to the upload step\n\t\t\tsteps[ steps.length - 1 ].setNextStep( uploadStep );\n\n\t\t\treturn $.Deferred().resolve( steps ).promise()\n\t\t\t\t.always( ( stepsInner ) => {\n\t\t\t\t\tself.steps = stepsInner;\n\t\t\t\t\tself.ui.initialiseSteps( stepsInner );\n\t\t\t\t} );\n\t\t},\n\n\t\t/**\n\t\t * mw.Api's ajax calls are not very consistent in their error handling.\n\t\t * As long as the response comes back, the response will be fine: it'll\n\t\t * get rejected with the error details there. However, if no response\n\t\t * comes back for whatever reason, things can get confusing.\n\t\t * I'll monkeypatch around such cases so that we can always rely on the\n\t\t * error response the way we want it to be.\n\t\t *\n\t\t * TODO: Instead of this monkeypatching, we could call api.getErrorMessage()\n\t\t * in the error handlers to get nice messages.\n\t\t *\n\t\t * @param {Object} options\n\t\t * @return {mw.Api}\n\t\t */\n\t\tgetApi: function ( options ) {\n\t\t\tconst api = new mw.Api( options );\n\n\t\t\tapi.ajax = function ( parameters, ajaxOptions ) {\n\t\t\t\tlet original, override;\n\n\t\t\t\tObject.assign( parameters, {\n\t\t\t\t\terrorformat: 'html',\n\t\t\t\t\terrorlang: mw.config.get( 'wgUserLanguage' ),\n\t\t\t\t\terrorsuselocal: 1,\n\t\t\t\t\tformatversion: 2\n\t\t\t\t} );\n\n\t\t\t\toriginal = mw.Api.prototype.ajax.apply( this, [ parameters, ajaxOptions ] );\n\n\t\t\t\t// we'll attach a default error handler that makes sure error\n\t\t\t\t// output is always, reliably, in the same format\n\t\t\t\toverride = original.then(\n\t\t\t\t\tnull, // done handler - doesn't need overriding\n\t\t\t\t\t( code, result ) => { // fail handler\n\t\t\t\t\t\tlet response = { errors: [ {\n\t\t\t\t\t\t\tcode: code,\n\t\t\t\t\t\t\thtml: result.textStatus || mw.message( 'api-clientside-error-invalidresponse' ).parse()\n\t\t\t\t\t\t} ] };\n\n\t\t\t\t\t\tif ( result.errors && result.errors[ 0 ] ) {\n\t\t\t\t\t\t\t// in case of success-but-has-errors, we have a valid result\n\t\t\t\t\t\t\tresponse = result;\n\t\t\t\t\t\t} else if ( result && result.textStatus === 'timeout' ) {\n\t\t\t\t\t\t\t// in case of $.ajax.fail(), there is no response json\n\t\t\t\t\t\t\tresponse.errors[ 0 ].html = mw.message( 'api-clientside-error-timeout' ).parse();\n\t\t\t\t\t\t} else if ( result && result.textStatus === 'parsererror' ) {\n\t\t\t\t\t\t\tresponse.errors[ 0 ].html = mw.message( 'mediauploader-api-error-parsererror' ).parse();\n\t\t\t\t\t\t} else if ( code === 'http' && result && result.xhr && result.xhr.status === 0 ) {\n\t\t\t\t\t\t\t// failed to even connect to server\n\t\t\t\t\t\t\tresponse.errors[ 0 ].html = mw.message( 'api-clientside-error-noconnect' ).parse();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn $.Deferred().reject( code, response, response );\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\t/*\n\t\t\t\t * After attaching (.then) our error handler, a new promise is\n\t\t\t\t * returned. The original promise had an 'abort' method, which\n\t\t\t\t * we'll also want to make use of...\n\t\t\t\t */\n\t\t\t\treturn override.promise( { abort: original.abort } );\n\t\t\t};\n\n\t\t\treturn api;\n\t\t}\n\t};\n\n\t/**\n\t * Get the own work and third party licensing deeds if they are needed.\n\t *\n\t * @static\n\t * @since 1.2\n\t * @param {mw.UploadWizardUpload[]} uploads\n\t * @param {Object} config The UW config object.\n\t * @param {string[]} [config.licensing.showTypes]\n\t * @return {mw.deed.Abstract[]}\n\t */\n\tmw.UploadWizard.getLicensingDeeds = function ( uploads, config ) {\n\t\tlet deed, api,\n\t\t\tdeeds = {},\n\t\t\tdoOwnWork = config.licensing.showTypes.includes( 'ownWork' ),\n\t\t\tdoThirdParty = config.licensing.showTypes.includes( 'thirdParty' );\n\n\t\tif ( !config.licensing.enabled ) {\n\t\t\treturn {\n\t\t\t\tnone: new uw.deed.None( config )\n\t\t\t};\n\t\t}\n\n\t\tapi = this.prototype.getApi( { ajax: { timeout: 0 } } );\n\n\t\tif ( doOwnWork ) {\n\t\t\tdeed = new uw.deed.OwnWork( config, uploads, api );\n\t\t\tdeeds[ deed.name ] = deed;\n\t\t}\n\t\tif ( doThirdParty ) {\n\t\t\tdeed = new uw.deed.ThirdParty( config, uploads, api );\n\t\t\tdeeds[ deed.name ] = deed;\n\t\t}\n\n\t\treturn deeds;\n\t};\n\n\t/**\n\t * Helper method to put a thumbnail somewhere.\n\t *\n\t * @param {string|jQuery} selector String representing a jQuery selector, or a jQuery object\n\t * @param {HTMLCanvasElement|HTMLImageElement|null} image\n\t */\n\tmw.UploadWizard.placeThumbnail = function ( selector, image ) {\n\t\tif ( image === null ) {\n\t\t\t$( selector ).addClass( 'mediauploader-file-preview-broken' );\n\t\t\treturn;\n\t\t}\n\n\t\t$( selector )\n\t\t\t.css( { background: 'none' } )\n\t\t\t.prepend(\n\t\t\t\t$( '<a>' )\n\t\t\t\t\t.addClass( 'mediauploader-thumbnail-link' )\n\t\t\t\t\t.append( image )\n\t\t\t);\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/mw.UploadWizardDeedChooser.js","messages":[],"suppressedMessages":[{"ruleId":"mediawiki/msg-doc","severity":1,"message":"All possible message keys should be documented. See https://w.wiki/4r9a for details.","line":28,"column":14,"nodeType":"CallExpression","endLine":28,"endColumn":87,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"mediawiki/class-doc","severity":1,"message":"All possible CSS classes should be documented. See https://w.wiki/PS2 for details.","line":32,"column":22,"nodeType":"CallExpression","endLine":32,"endColumn":99,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-global-selector","severity":2,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":104,"column":4,"nodeType":"CallExpression","endLine":104,"endColumn":66,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-sizzle","severity":2,"message":"Selector extensions are not allowed","line":119,"column":5,"nodeType":"CallExpression","endLine":119,"endColumn":27,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-sizzle","severity":2,"message":"Selector extensions are not allowed","line":121,"column":10,"nodeType":"CallExpression","endLine":121,"endColumn":41,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-slide","severity":2,"message":"Prefer CSS transitions to .slideUp","line":126,"column":6,"nodeType":"CallExpression","endLine":126,"endColumn":26,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-fade","severity":2,"message":"Prefer CSS transitions to .fadeTo","line":141,"column":4,"nodeType":"CallExpression","endLine":141,"endColumn":62,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-sizzle","severity":2,"message":"Selector extensions are not allowed","line":147,"column":5,"nodeType":"CallExpression","endLine":147,"endColumn":27,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-sizzle","severity":2,"message":"Selector extensions are not allowed","line":149,"column":10,"nodeType":"CallExpression","endLine":149,"endColumn":31,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-slide","severity":2,"message":"Prefer CSS transitions to .slideUp","line":153,"column":6,"nodeType":"CallExpression","endLine":153,"endColumn":31,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-slide","severity":2,"message":"Prefer CSS transitions to .slideDown","line":157,"column":5,"nodeType":"CallExpression","endLine":157,"endColumn":27,"suppressions":[{"kind":"directive","justification":""}]}],"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-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/resources/mw.UploadWizardDetails.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'$moreDetailsWrapperDiv' is never reassigned. Use 'const' instead.","line":45,"column":8,"nodeType":"Identifier","messageId":"useConst","endLine":45,"endColumn":30},{"ruleId":"prefer-const","severity":2,"message":"'details' is never reassigned. Use 'const' instead.","line":47,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":47,"endColumn":12},{"ruleId":"prefer-const","severity":2,"message":"'config' is never reassigned. Use 'const' instead.","line":48,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":48,"endColumn":11},{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":56,"column":13,"nodeType":"MemberExpression","messageId":"forbidden","endLine":56,"endColumn":26},{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":73,"column":48,"nodeType":"MemberExpression","messageId":"forbidden","endLine":73,"endColumn":61},{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":83,"column":40,"nodeType":"MemberExpression","messageId":"forbidden","endLine":83,"endColumn":53},{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":90,"column":55,"nodeType":"MemberExpression","messageId":"forbidden","endLine":90,"endColumn":68},{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":98,"column":57,"nodeType":"MemberExpression","messageId":"forbidden","endLine":98,"endColumn":70},{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":105,"column":44,"nodeType":"MemberExpression","messageId":"forbidden","endLine":105,"endColumn":57},{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":113,"column":47,"nodeType":"MemberExpression","messageId":"forbidden","endLine":113,"endColumn":60},{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":118,"column":51,"nodeType":"MemberExpression","messageId":"forbidden","endLine":118,"endColumn":64},{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":123,"column":53,"nodeType":"MemberExpression","messageId":"forbidden","endLine":123,"endColumn":66},{"ruleId":"prefer-const","severity":2,"message":"'$moreDetailsDiv' is never reassigned. Use 'const' instead.","line":151,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":151,"endColumn":19},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":215,"column":5,"nodeType":"CallExpression","endLine":221,"endColumn":8},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":255,"column":4,"nodeType":"CallExpression","endLine":257,"endColumn":13},{"ruleId":"no-mixed-spaces-and-tabs","severity":2,"message":"Mixed spaces and tabs.","line":383,"column":4,"nodeType":"Program","messageId":"mixedSpacesAndTabs","endLine":383,"endColumn":6},{"ruleId":"implicit-arrow-linebreak","severity":2,"message":"Expected no linebreak before this expression.","line":383,"column":6,"nodeType":"Identifier","messageId":"unexpected","endLine":383,"endColumn":17},{"ruleId":"no-mixed-spaces-and-tabs","severity":2,"message":"Mixed spaces and tabs.","line":384,"column":3,"nodeType":"Program","messageId":"mixedSpacesAndTabs","endLine":384,"endColumn":5},{"ruleId":"prefer-const","severity":2,"message":"'yyyyMmDdRegex' is never reassigned. Use 'const' instead.","line":448,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":448,"endColumn":18},{"ruleId":"prefer-const","severity":2,"message":"'timeRegex' is never reassigned. Use 'const' instead.","line":449,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":449,"endColumn":14},{"ruleId":"prefer-const","severity":2,"message":"'dateInfo' is never reassigned. Use 'const' instead.","line":470,"column":7,"nodeType":"Identifier","messageId":"useConst","endLine":470,"endColumn":15},{"ruleId":"prefer-const","severity":2,"message":"'saneTime' is never reassigned. Use 'const' instead.","line":508,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":508,"endColumn":12},{"ruleId":"prefer-const","severity":2,"message":"'m' is never reassigned. Use 'const' instead.","line":601,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":601,"endColumn":6},{"ruleId":"prefer-const","severity":2,"message":"'values' is never reassigned. Use 'const' instead.","line":603,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":603,"endColumn":11},{"ruleId":"prefer-const","severity":2,"message":"'languages' is never reassigned. Use 'const' instead.","line":653,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":653,"endColumn":13},{"ruleId":"jsdoc/require-returns-check","severity":1,"message":"JSDoc @return declaration present but return expression not available in function.","line":662,"column":3,"nodeType":"Block","endLine":670,"endColumn":6},{"ruleId":"prefer-const","severity":2,"message":"'serialized' is never reassigned. Use 'const' instead.","line":672,"column":21,"nodeType":"Identifier","messageId":"useConst","endLine":672,"endColumn":31},{"ruleId":"prefer-const","severity":2,"message":"'substitutions' is never reassigned. Use 'const' instead.","line":734,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":734,"endColumn":18},{"ruleId":"prefer-const","severity":2,"message":"'substList' is never reassigned. Use 'const' instead.","line":734,"column":25,"nodeType":"Identifier","messageId":"useConst","endLine":734,"endColumn":34},{"ruleId":"prefer-const","severity":2,"message":"'deed' is never reassigned. Use 'const' instead.","line":735,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":735,"endColumn":9},{"ruleId":"es-x/no-regexp-u-flag","severity":1,"message":"ES2015 RegExp 'u' flag is forbidden.","line":793,"column":10,"nodeType":"NewExpression","messageId":"forbidden","endLine":793,"endColumn":84},{"ruleId":"prefer-const","severity":2,"message":"'details' is never reassigned. Use 'const' instead.","line":813,"column":8,"nodeType":"Identifier","messageId":"useConst","endLine":813,"endColumn":15},{"ruleId":"prefer-const","severity":2,"message":"'wikitext' is never reassigned. Use 'const' instead.","line":823,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":823,"endColumn":12},{"ruleId":"prefer-const","severity":2,"message":"'promise' is never reassigned. Use 'const' instead.","line":824,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":824,"endColumn":11},{"ruleId":"prefer-const","severity":2,"message":"'tags' is never reassigned. Use 'const' instead.","line":843,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":843,"endColumn":9},{"ruleId":"prefer-const","severity":2,"message":"'deed' is never reassigned. Use 'const' instead.","line":844,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":844,"endColumn":9},{"ruleId":"prefer-const","severity":2,"message":"'config' is never reassigned. Use 'const' instead.","line":846,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":846,"endColumn":11},{"ruleId":"prefer-const","severity":2,"message":"'params' is never reassigned. Use 'const' instead.","line":869,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":869,"endColumn":10},{"ruleId":"prefer-const","severity":2,"message":"'details' is never reassigned. Use 'const' instead.","line":936,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":936,"endColumn":12},{"ruleId":"prefer-const","severity":2,"message":"'deferred' is never reassigned. Use 'const' instead.","line":939,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":939,"endColumn":13}],"suppressedMessages":[],"errorCount":29,"fatalErrorCount":0,"warningCount":11,"fixableErrorCount":0,"fixableWarningCount":0,"source":"( function ( uw ) {\n\n\tconst NS_FILE = mw.config.get( 'wgNamespaceIds' ).file;\n\n\t/**\n\t * Object that represents the Details (step 2) portion of the UploadWizard\n\t * n.b. each upload gets its own details.\n\t *\n\t * @param {mw.UploadWizardUpload} upload\n\t * @param {jQuery} $containerDiv The `div` to put the interface into\n\t */\n\tmw.UploadWizardDetails = function ( upload, $containerDiv ) {\n\t\tthis.upload = upload;\n\t\tthis.$containerDiv = $containerDiv;\n\t\tthis.api = upload.api;\n\n\t\tthis.fieldList = [];\n\t\tthis.fieldMap = {};\n\t\tthis.fieldWrapperList = [];\n\t\tthis.fieldWrapperMap = {};\n\n\t\t// This widget has to be initialized early for\n\t\t// useCustomDeedChooser() to work.\n\t\tthis.deedChooserDetails = new uw.DeedChooserDetailsWidget();\n\t\tthis.customDeedChooser = false;\n\n\t\tif ( !mw.UploadWizard.config.licensing.enabled ) {\n\t\t\t// Create a pseudo-deed chooser if licensing is disabled\n\t\t\tthis.upload.deedChooser = {\n\t\t\t\tdeed: new uw.deed.None( mw.UploadWizard.config )\n\t\t\t};\n\t\t}\n\n\t\tthis.$div = $( '<div>' ).addClass( 'mediauploader-info-file ui-helper-clearfix filled' );\n\t};\n\n\tmw.UploadWizardDetails.prototype = {\n\t\t// Has this details object been attached to the DOM already?\n\t\tisAttached: false,\n\n\t\t/**\n\t\t * Build the interface and attach all elements - do this on demand.\n\t\t */\n\t\tbuildInterface: function () {\n\t\t\tlet $moreDetailsWrapperDiv, $moreDetailsDiv,\n\t\t\t\tfKey, fSpec, fieldWidget, fieldWrapper, fConfigBase,\n\t\t\t\tdetails = this,\n\t\t\t\tconfig = mw.UploadWizard.config;\n\n\t\t\tthis.$thumbnailDiv = $( '<div>' ).addClass( 'mediauploader-thumbnail mediauploader-thumbnail-side' );\n\n\t\t\tthis.$dataDiv = $( '<div>' ).addClass( 'mediauploader-data' );\n\n\t\t\tfor ( fKey in config.fields ) {\n\t\t\t\t// Make a deep copy\n\t\t\t\tfSpec = Object.assign( {}, config.fields[ fKey ] );\n\t\t\t\tfSpec.key = fKey;\n\t\t\t\tfSpec.enabled = fSpec.enabled === undefined ? true : fSpec.enabled;\n\t\t\t\t// Override the label in case it wasn't set\n\t\t\t\tfSpec.label = fSpec.label ? $( $.parseHTML( fSpec.label ) ) : fSpec.key;\n\n\t\t\t\t// Common settings for all fields\n\t\t\t\tfConfigBase = {\n\t\t\t\t\trequired: fSpec.required === 'required',\n\t\t\t\t\trecommended: fSpec.required === 'recommended',\n\t\t\t\t\tfieldName: fSpec.label,\n\t\t\t\t\tdisabled: !fSpec.enabled\n\t\t\t\t};\n\n\t\t\t\tfieldWidget = null;\n\t\t\t\tswitch ( fSpec.type ) {\n\t\t\t\t\tcase 'title':\n\t\t\t\t\t\tfieldWidget = new uw.TitleDetailsWidget( Object.assign( {}, fConfigBase, {\n\t\t\t\t\t\t\t// Normalize file extension, e.g. 'JPEG' to 'jpg'\n\t\t\t\t\t\t\textension: mw.UploadWizard.config.content.titleField === fKey ?\n\t\t\t\t\t\t\t\tmw.Title.normalizeExtension( this.upload.title.getExtension() ) : '',\n\t\t\t\t\t\t\tminLength: fSpec.minLength || 5,\n\t\t\t\t\t\t\tmaxLength: fSpec.maxLength || 240\n\t\t\t\t\t\t} ) );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'text':\n\t\t\t\t\tcase 'textarea':\n\t\t\t\t\t\tfieldWidget = new uw.TextWidget( Object.assign( {}, fConfigBase, {\n\t\t\t\t\t\t\tdisabled: !fSpec.enabled,\n\t\t\t\t\t\t\tminLength: fSpec.minLength,\n\t\t\t\t\t\t\tmaxLength: fSpec.maxLength\n\t\t\t\t\t\t} ) );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'singlelang':\n\t\t\t\t\t\tfieldWidget = new uw.SingleLanguageInputWidget( Object.assign( {}, fConfigBase, {\n\t\t\t\t\t\t\tcanBeRemoved: false,\n\t\t\t\t\t\t\tlanguages: this.getLanguageOptions(),\n\t\t\t\t\t\t\tminLength: fSpec.minLength,\n\t\t\t\t\t\t\tmaxLength: fSpec.maxLength\n\t\t\t\t\t\t} ) );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'multilang':\n\t\t\t\t\t\tfieldWidget = new uw.MultipleLanguageInputWidget( Object.assign( {}, fConfigBase, {\n\t\t\t\t\t\t\tlanguages: this.getLanguageOptions(),\n\t\t\t\t\t\t\tminLength: fSpec.minLength,\n\t\t\t\t\t\t\tmaxLength: fSpec.maxLength\n\t\t\t\t\t\t} ) );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'select':\n\t\t\t\t\t\tfieldWidget = new uw.DropdownWidget( Object.assign( {}, fConfigBase, {\n\t\t\t\t\t\t\toptions: fSpec.options\n\t\t\t\t\t\t} ) );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'license':\n\t\t\t\t\t\tfieldWidget = this.deedChooserDetails;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'date':\n\t\t\t\t\t\tfieldWidget = new uw.DateDetailsWidget( Object.assign( {}, fConfigBase, {\n\t\t\t\t\t\t\tupload: this.upload\n\t\t\t\t\t\t} ) );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'location':\n\t\t\t\t\t\tfieldWidget = new uw.LocationDetailsWidget( Object.assign( {}, fConfigBase, {\n\t\t\t\t\t\t\tfields: fSpec.fields\n\t\t\t\t\t\t} ) );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'categories':\n\t\t\t\t\t\tfieldWidget = new uw.CategoriesDetailsWidget( Object.assign( {}, fConfigBase, {\n\t\t\t\t\t\t\thiddenDefault: fSpec.hiddenDefault,\n\t\t\t\t\t\t\tmissingWikitext: fSpec.missingWikitext\n\t\t\t\t\t\t} ) );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t// Can't build the widget, ignore it\n\t\t\t\t\t\tmw.error( \"Can't build details widget\", fSpec );\n\t\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tthis.fieldList.push( fSpec );\n\t\t\t\tthis.fieldMap[ fKey ] = fieldWidget;\n\t\t\t}\n\n\t\t\tthis.fieldList.sort( ( a, b ) => {\n\t\t\t\tif ( a.order < b.order ) {\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t\tif ( a.order > b.order ) {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\treturn 0;\n\t\t\t} );\n\n\t\t\t// Build the form for the file upload\n\t\t\tthis.$form = $( '<form id=\"mediauploader-detailsform' + this.upload.index + '\"></form>' )\n\t\t\t\t.addClass( 'detailsForm' );\n\t\t\t$moreDetailsDiv = $( '<div>' );\n\n\t\t\tthis.fieldList.forEach( function ( spec ) {\n\t\t\t\tfieldWidget = this.fieldMap[ spec.key ];\n\t\t\t\tfieldWrapper = new uw.FieldLayout( fieldWidget, {\n\t\t\t\t\trequired: spec.type === 'license' || spec.required === 'required',\n\t\t\t\t\tlabel: spec.label,\n\t\t\t\t\thelp: spec.help ? $( $.parseHTML( spec.help ) ) : null\n\t\t\t\t} );\n\t\t\t\tif ( spec.type === 'license' ) {\n\t\t\t\t\tfieldWrapper.toggle( this.customDeedChooser ); // See useCustomDeedChooser()\n\t\t\t\t} else if ( spec.hidden ) {\n\t\t\t\t\tfieldWrapper.toggle( false );\n\t\t\t\t}\n\n\t\t\t\t// Apply field defaults\n\t\t\t\tthis.prefillField( spec, fieldWidget );\n\n\t\t\t\t// List of fields for validation etc.\n\t\t\t\tthis.fieldWrapperList.push( fieldWrapper );\n\t\t\t\tthis.fieldWrapperMap[ spec.key ] = fieldWrapper;\n\n\t\t\t\t// Add the field wrapper to HTML of the form\n\t\t\t\tif ( spec.auxiliary ) {\n\t\t\t\t\t$moreDetailsDiv.append( fieldWrapper.$element );\n\t\t\t\t\t// If something changes the input \"hidden\" in the collapsed section,\n\t\t\t\t\t// expand it.\n\t\t\t\t\tfieldWidget.on( 'change', () => {\n\t\t\t\t\t\t$moreDetailsWrapperDiv.data( 'mw-collapsible' ).expand();\n\t\t\t\t\t} );\n\t\t\t\t} else {\n\t\t\t\t\tthis.$form.append( fieldWrapper.$element );\n\t\t\t\t}\n\t\t\t}, this );\n\n\t\t\t// Wrap the auxiliary fields in a dropdown\n\t\t\t$moreDetailsWrapperDiv = $( '<div>' ).addClass( 'mwe-more-details' );\n\t\t\t$moreDetailsWrapperDiv\n\t\t\t\t.append(\n\t\t\t\t\t$( '<a>' ).text( mw.msg( 'mediauploader-more-options' ) )\n\t\t\t\t\t\t.prepend( $( '<span>' ).addClass( 'mw-toggle-icon' ) )\n\t\t\t\t\t\t.addClass( 'mediauploader-details-more-options mw-collapsible-toggle mw-collapsible-arrow' ),\n\t\t\t\t\t$moreDetailsDiv.addClass( 'mw-collapsible-content' )\n\t\t\t\t)\n\t\t\t\t.makeCollapsible( { collapsed: true } );\n\n\t\t\tthis.$form.on( 'submit', ( e ) => {\n\t\t\t\t// Prevent actual form submission\n\t\t\t\te.preventDefault();\n\t\t\t} );\n\n\t\t\tthis.$form.append(\n\t\t\t\t$moreDetailsWrapperDiv\n\t\t\t);\n\n\t\t\t// Add in remove control to form\n\t\t\tthis.removeCtrl = new OO.ui.ButtonWidget( {\n\t\t\t\tlabel: mw.message( 'mediauploader-remove' ).text(),\n\t\t\t\ttitle: mw.message( 'mediauploader-remove-upload' ).text(),\n\t\t\t\tclasses: [ 'mediauploader-remove-upload' ],\n\t\t\t\tflags: 'destructive',\n\t\t\t\ticon: 'trash',\n\t\t\t\tframed: false\n\t\t\t} ).on( 'click', () => {\n\t\t\t\tOO.ui.confirm( mw.message( 'mediauploader-license-confirm-remove' ).text(), {\n\t\t\t\t\ttitle: mw.message( 'mediauploader-license-confirm-remove-title' ).text()\n\t\t\t\t} ).done( ( confirmed ) => {\n\t\t\t\t\tif ( confirmed ) {\n\t\t\t\t\t\tdetails.upload.emit( 'remove-upload' );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t} );\n\n\t\t\tthis.$thumbnailDiv.append( this.removeCtrl.$element );\n\n\t\t\tthis.statusMessage = new OO.ui.MessageWidget( { inline: true } );\n\t\t\tthis.statusMessage.toggle( false );\n\t\t\tthis.$spinner = $.createSpinner( { size: 'small', type: 'inline' } );\n\t\t\tthis.$spinner.hide();\n\t\t\tthis.$indicator = $( '<div>' ).addClass( 'mediauploader-file-indicator' ).append(\n\t\t\t\tthis.$spinner,\n\t\t\t\tthis.statusMessage.$element\n\t\t\t);\n\n\t\t\tthis.$submittingDiv = $( '<div>' ).addClass( 'mediauploader-submitting' )\n\t\t\t\t.append(\n\t\t\t\t\tthis.$indicator,\n\t\t\t\t\t$( '<div>' ).addClass( 'mediauploader-details-texts' ).append(\n\t\t\t\t\t\t$( '<div>' ).addClass( 'mediauploader-visible-file-filename-text' ),\n\t\t\t\t\t\t$( '<div>' ).addClass( 'mediauploader-file-status-line' )\n\t\t\t\t\t)\n\t\t\t\t);\n\n\t\t\tthis.$dataDiv.append(\n\t\t\t\tthis.$form,\n\t\t\t\tthis.$submittingDiv\n\t\t\t).morphCrossfader();\n\n\t\t\tthis.$div.append(\n\t\t\t\tthis.$thumbnailDiv,\n\t\t\t\tthis.$dataDiv\n\t\t\t);\n\n\t\t\t// This must match the CSS dimensions of .mediauploader-thumbnail\n\t\t\tthis.upload.getThumbnail( 230 ).done( function ( thumb ) {\n\t\t\t\tmw.UploadWizard.placeThumbnail( this.$thumbnailDiv, thumb );\n\t\t\t}, this );\n\n\t\t\tthis.interfaceBuilt = true;\n\n\t\t\tif ( this.savedSerialData ) {\n\t\t\t\tthis.setSerialized( this.savedSerialData );\n\t\t\t\tthis.savedSerialData = undefined;\n\t\t\t}\n\t\t},\n\n\t\t/*\n\t\t * Append the div for this details object to the DOM.\n\t\t * We need to ensure that we add divs in the right order\n\t\t * (the order in which the user selected files).\n\t\t *\n\t\t * Will only append once.\n\t\t */\n\t\tattach: function () {\n\t\t\tconst $window = $( window ),\n\t\t\t\tdetails = this;\n\n\t\t\tfunction maybeBuild() {\n\t\t\t\tif ( !this.interfaceBuilt && $window.scrollTop() + $window.height() + 1000 >= details.$div.offset().top ) {\n\t\t\t\t\tdetails.buildInterface();\n\t\t\t\t\t$window.off( 'scroll', maybeBuild );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( !this.isAttached ) {\n\t\t\t\tthis.$containerDiv.append( this.$div );\n\n\t\t\t\tif ( $window.scrollTop() + $window.height() + 1000 >= this.$div.offset().top ) {\n\t\t\t\t\tthis.buildInterface();\n\t\t\t\t} else {\n\t\t\t\t\t$window.on( 'scroll', maybeBuild );\n\t\t\t\t}\n\n\t\t\t\tthis.isAttached = true;\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Get file page title for this upload.\n\t\t *\n\t\t * @return {mw.Title|null}\n\t\t */\n\t\tgetTitle: function () {\n\t\t\tconst titleField = mw.UploadWizard.config.content.titleField;\n\n\t\t\t// title will not be set until we've actually submitted the file\n\t\t\tif ( this.title === undefined ) {\n\t\t\t\treturn this.fieldMap[ titleField ].getTitle();\n\t\t\t}\n\n\t\t\t// once the file has been submitted, we'll have confirmation on\n\t\t\t// the filename and trust the authoritative source over own input\n\t\t\treturn this.title;\n\t\t},\n\n\t\t/**\n\t\t * Display error message about multiple uploaded files with the same title specified\n\t\t *\n\t\t * @return {mw.UploadWizardDetails}\n\t\t * @chainable\n\t\t */\n\t\tsetDuplicateTitleError: function () {\n\t\t\tconst titleField = mw.UploadWizard.config.content.titleField;\n\t\t\t// TODO This should give immediate response, not only when submitting the form\n\t\t\tthis.fieldWrapperMap[ titleField ].setErrors(\n\t\t\t\t[ mw.message( 'mediauploader-error-title-duplicate' ) ]\n\t\t\t);\n\t\t\treturn this;\n\t\t},\n\n\t\t/**\n\t\t * Toggles whether we use the 'macro' deed or our own.\n\t\t */\n\t\tuseCustomDeedChooser: function () {\n\t\t\tthis.customDeedChooser = true;\n\t\t\tthis.deedChooserDetails.useCustomDeedChooser( this.upload );\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t *\n\t\t * @return {uw.FieldLayout[]}\n\t\t */\n\t\tgetAllFields: function () {\n\t\t\treturn [].concat(\n\t\t\t\tthis.fieldWrapperList,\n\t\t\t\tthis.upload.deedChooser.deed ? this.upload.deedChooser.deed.getFields() : []\n\t\t\t);\n\t\t},\n\n\t\t/**\n\t\t * Check all the fields for validity.\n\t\t *\n\t\t * @return {jQuery.Promise} Promise resolved with multiple array arguments, each containing a\n\t\t * list of error messages for a single field. If API requests necessary to check validity\n\t\t * fail, the promise may be rejected. The form is valid if the promise is resolved with all\n\t\t * empty arrays.\n\t\t */\n\t\tgetErrors: function () {\n\t\t\treturn $.when.apply( $, this.getAllFields().map( ( fieldLayout ) => fieldLayout.fieldWidget.getErrors() ) );\n\t\t},\n\n\t\t/**\n\t\t * Check all the fields for warnings.\n\t\t *\n\t\t * @return {jQuery.Promise} Same as #getErrors\n\t\t */\n\t\tgetWarnings: function () {\n\t\t\treturn $.when.apply( $, this.getAllFields().map( ( fieldLayout ) => fieldLayout.fieldWidget.getWarnings() ) );\n\t\t},\n\n\t\t/**\n\t\t * Check all the fields for errors and warnings and display them in the UI.\n\t\t *\n\t\t * @param {boolean} thorough True to perform a thorough validity check. Defaults to false for a fast on-change check.\n\t\t * @return {jQuery.Promise} Combined promise of all fields' validation results.\n\t\t */\n\t\tcheckValidity: function ( thorough ) {\n\t\t\tconst fields = this.getAllFields();\n\n\t\t\treturn $.when.apply( $, fields.map( ( fieldLayout ) =>\n\t\t\t\t// Update any error/warning messages\n\t\t\t\t fieldLayout.checkValidity( thorough )\n\t\t\t ) );\n\t\t},\n\n\t\t/**\n\t\t * Get a thumbnail caption for this upload (basically, the first caption).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tgetThumbnailCaption: function () {\n\t\t\tconst captionField = mw.UploadWizard.config.content.captionField;\n\n\t\t\t// The caption field should be one of:\n\t\t\t// TextWidget, SingleLanguageInputWidget, MultipleLanguageInputWidget\n\t\t\treturn this.fieldMap[ captionField ].getCaption();\n\t\t},\n\n\t\t/**\n\t\t * Prefills the statically (defaults) and dynamically available info\n\t\t * for the file (from EXIF etc.), for the given field.\n\t\t *\n\t\t * @param {Object} fSpec\n\t\t * @param {uw.DetailsWidget} widget\n\t\t */\n\t\tprefillField: function ( fSpec, widget ) {\n\t\t\tlet dynPrefilled = false;\n\n\t\t\t// Try dynamic prefilling, if requested and available for this type\n\t\t\tif ( fSpec.autoFill ) {\n\t\t\t\tswitch ( fSpec.type ) {\n\t\t\t\t\tcase 'title':\n\t\t\t\t\t\tdynPrefilled = this.prefillTitle( widget );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'text':\n\t\t\t\t\tcase 'textarea':\n\t\t\t\t\tcase 'singlelang':\n\t\t\t\t\tcase 'multilang':\n\t\t\t\t\t\tdynPrefilled = this.prefillDescription( fSpec.type, widget );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'date':\n\t\t\t\t\t\tdynPrefilled = this.prefillDate( widget );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'location':\n\t\t\t\t\t\tdynPrefilled = this.prefillLocation( widget );\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( !dynPrefilled && fSpec.default !== undefined ) {\n\t\t\t\twidget.setSerialized( fSpec.default );\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Check if we got an EXIF date back and enter it into the details\n\t\t * XXX We ought to be using date + time here...\n\t\t * EXIF examples tend to be in ISO 8601, but the separators are sometimes things like colons, and they have lots of trailing info\n\t\t * (which we should actually be using, such as time and timezone)\n\t\t *\n\t\t * @param {uw.DateDetailsWidget} widget\n\t\t * @return {boolean}\n\t\t */\n\t\tprefillDate: function ( widget ) {\n\t\t\tlet dateObj, metadata, dateStr, saneTime,\n\t\t\t\tdateMode = 'calendar',\n\t\t\t\tyyyyMmDdRegex = /^(\\d\\d\\d\\d)[:/-](\\d\\d)[:/-](\\d\\d)\\D.*/,\n\t\t\t\ttimeRegex = /\\D(\\d\\d):(\\d\\d):(\\d\\d)/;\n\n\t\t\t// XXX surely we have this function somewhere already\n\t\t\tfunction pad( n ) {\n\t\t\t\treturn ( n < 10 ? '0' : '' ) + String( n );\n\t\t\t}\n\n\t\t\tfunction getSaneTime( date ) {\n\t\t\t\tlet str = '';\n\n\t\t\t\tstr += pad( date.getHours() ) + ':';\n\t\t\t\tstr += pad( date.getMinutes() ) + ':';\n\t\t\t\tstr += pad( date.getSeconds() );\n\n\t\t\t\treturn str;\n\t\t\t}\n\n\t\t\tif ( this.upload.imageinfo.metadata ) {\n\t\t\t\tmetadata = this.upload.imageinfo.metadata;\n\t\t\t\t[ 'datetimeoriginal', 'datetimedigitized', 'datetime', 'date' ].some( ( propName ) => {\n\t\t\t\t\tlet matches, timeMatches,\n\t\t\t\t\t\tdateInfo = metadata[ propName ];\n\t\t\t\t\tif ( dateInfo ) {\n\t\t\t\t\t\tmatches = dateInfo.trim().match( yyyyMmDdRegex );\n\t\t\t\t\t\tif ( matches ) {\n\t\t\t\t\t\t\ttimeMatches = dateInfo.trim().match( timeRegex );\n\t\t\t\t\t\t\tif ( timeMatches ) {\n\t\t\t\t\t\t\t\tdateObj = new Date( parseInt( matches[ 1 ], 10 ),\n\t\t\t\t\t\t\t\t\tparseInt( matches[ 2 ], 10 ) - 1,\n\t\t\t\t\t\t\t\t\tparseInt( matches[ 3 ], 10 ),\n\t\t\t\t\t\t\t\t\tparseInt( timeMatches[ 1 ], 10 ),\n\t\t\t\t\t\t\t\t\tparseInt( timeMatches[ 2 ], 10 ),\n\t\t\t\t\t\t\t\t\tparseInt( timeMatches[ 3 ], 10 ) );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tdateObj = new Date( parseInt( matches[ 1 ], 10 ),\n\t\t\t\t\t\t\t\t\tparseInt( matches[ 2 ], 10 ) - 1,\n\t\t\t\t\t\t\t\t\tparseInt( matches[ 3 ], 10 ) );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true; // break from Array.some\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\t// if we don't have EXIF or other metadata, just don't put a date in.\n\t\t\t// XXX if we have FileAPI, it might be clever to look at file attrs, saved\n\t\t\t// in the upload object for use here later, perhaps\n\t\t\tif ( dateObj === undefined ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tdateStr = dateObj.getFullYear() + '-' + pad( dateObj.getMonth() + 1 ) + '-' + pad( dateObj.getDate() );\n\n\t\t\t// Add the time\n\t\t\t// If the date but not the time is set in EXIF data, we'll get a bogus\n\t\t\t// time value of '00:00:00'.\n\t\t\t// FIXME: Check for missing time value earlier rather than blacklisting\n\t\t\t// a potentially legitimate time value.\n\t\t\tsaneTime = getSaneTime( dateObj );\n\t\t\tif ( saneTime !== '00:00:00' ) {\n\t\t\t\tdateStr += ' ' + saneTime;\n\n\t\t\t\t// Switch to freeform date field. DateInputWidget (with calendar) handles dates only, not times.\n\t\t\t\tdateMode = 'arbitrary';\n\t\t\t}\n\n\t\t\t// ok by now we should definitely have a dateObj and a date string\n\t\t\twidget.setSerialized( {\n\t\t\t\tmode: dateMode,\n\t\t\t\tvalue: dateStr\n\t\t\t} );\n\n\t\t\treturn true;\n\t\t},\n\n\t\t/**\n\t\t * Set the title of the thing we just uploaded, visibly\n\t\t *\n\t\t * @param {uw.TitleDetailsWidget} widget\n\t\t * @return {boolean}\n\t\t */\n\t\tprefillTitle: function ( widget ) {\n\t\t\twidget.setSerialized( {\n\t\t\t\ttitle: this.upload.title.getNameText()\n\t\t\t} );\n\t\t\treturn true;\n\t\t},\n\n\t\t/**\n\t\t * Prefill the image description if we have a description\n\t\t *\n\t\t * Note that this is not related to specifying the description from the query\n\t\t * string (that happens earlier). This is for when we have retrieved a\n\t\t * description from an upload_by_url upload or from the metadata.\n\t\t *\n\t\t * @param {string} type\n\t\t * @param {uw.TextWidget} widget\n\t\t * @return {boolean}\n\t\t */\n\t\tprefillDescription: function ( type, widget ) {\n\t\t\tlet m, descText;\n\n\t\t\tif (\n\t\t\t\twidget.getWikiText() === '' &&\n\t\t\t\tthis.upload.file !== undefined\n\t\t\t) {\n\t\t\t\tm = this.upload.imageinfo.metadata;\n\t\t\t\tdescText = this.upload.file.description ||\n\t\t\t\t\t( m && m.imagedescription && m.imagedescription[ 0 ] && m.imagedescription[ 0 ].value );\n\n\t\t\t\tif ( !descText ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// strip out any HTML tags\n\t\t\t\tdescText = descText.replace( /<[^>]+>/g, '' );\n\n\t\t\t\t// Set the text – both singlelang and multilang can fall back to\n\t\t\t\t// a simple string serialization.\n\t\t\t\twidget.setSerialized( descText.trim() );\n\n\t\t\t\t// Set the language – probably wrong in many cases...\n\t\t\t\tif ( type === 'singlelang' ) {\n\t\t\t\t\twidget.setLanguage(\n\t\t\t\t\t\twidget.getClosestAllowedLanguage( mw.config.get( 'wgContentLanguage' ) )\n\t\t\t\t\t);\n\t\t\t\t} else if ( type === 'multilang' ) {\n\t\t\t\t\twidget.getItems()[ 0 ].setLanguage(\n\t\t\t\t\t\twidget.getItems()[ 0 ].getClosestAllowedLanguage(\n\t\t\t\t\t\t\tmw.config.get( 'wgContentLanguage' )\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t},\n\n\t\t/**\n\t\t * Prefill location input from image info and metadata\n\t\t *\n\t\t * As of MediaWiki 1.18, the exif parser translates the rational GPS data tagged by the camera\n\t\t * to decimal format. Let's just use that.\n\t\t *\n\t\t * @param {uw.LocationDetailsWidget} widget\n\t\t * @return {boolean}\n\t\t */\n\t\tprefillLocation: function ( widget ) {\n\t\t\tlet dir,\n\t\t\t\tm = this.upload.imageinfo.metadata,\n\t\t\t\tmodified = false,\n\t\t\t\tvalues = {};\n\n\t\t\tif ( m ) {\n\t\t\t\tdir = m.gpsimgdirection || m.gpsdestbearing;\n\n\t\t\t\tif ( dir ) {\n\t\t\t\t\tif ( dir.match( /^\\d+\\/\\d+$/ ) !== null ) {\n\t\t\t\t\t\t// Apparently it can take the form \"x/y\" instead of\n\t\t\t\t\t\t// a decimal value. Mighty silly, but let's save it.\n\t\t\t\t\t\tdir = dir.split( '/' );\n\t\t\t\t\t\tdir = parseInt( dir[ 0 ], 10 ) / parseInt( dir[ 1 ], 10 );\n\t\t\t\t\t}\n\n\t\t\t\t\tvalues.heading = dir;\n\n\t\t\t\t\tmodified = true;\n\t\t\t\t}\n\n\t\t\t\t// Prefill useful stuff only\n\t\t\t\tif ( Number( m.gpslatitude ) && Number( m.gpslongitude ) ) {\n\t\t\t\t\tvalues.latitude = m.gpslatitude;\n\t\t\t\t\tvalues.longitude = m.gpslongitude;\n\t\t\t\t\tmodified = true;\n\t\t\t\t} else if (\n\t\t\t\t\tthis.upload.file &&\n\t\t\t\t\tthis.upload.file.location &&\n\t\t\t\t\tthis.upload.file.location.latitude &&\n\t\t\t\t\tthis.upload.file.location.longitude\n\t\t\t\t) {\n\t\t\t\t\tvalues.latitude = this.upload.file.location.latitude;\n\t\t\t\t\tvalues.longitude = this.upload.file.location.longitude;\n\t\t\t\t\tmodified = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( modified ) {\n\t\t\t\twidget.setSerialized( values );\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\n\t\t/**\n\t\t * Returns the language list to use in (Single|Multiple)LanguageInputWidget\n\t\t *\n\t\t * @return {Object}\n\t\t */\n\t\tgetLanguageOptions: function () {\n\t\t\tlet languages, code;\n\n\t\t\tlanguages = {};\n\t\t\tfor ( code in mw.UploadWizard.config.languages ) {\n\t\t\t\tif ( Object.prototype.hasOwnProperty.call( mw.UploadWizard.config.languages, code ) ) {\n\t\t\t\t\tlanguages[ code ] = mw.UploadWizard.config.languages[ code ];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn languages;\n\t\t},\n\n\t\t/**\n\t\t * Get a machine-readable representation of the current state of the upload details. It can be\n\t\t * passed to #setSerialized to restore this state (or to set it for another instance of the same\n\t\t * class).\n\t\t *\n\t\t * Note that this doesn't include custom deed's state.\n\t\t *\n\t\t * @return {Object.<string,Object>}\n\t\t */\n\t\tgetSerialized: function () {\n\t\t\tlet fieldWidget, serialized = {};\n\n\t\t\tif ( !this.interfaceBuilt ) {\n\t\t\t\t// We don't have the interface yet, but it'll get filled out as\n\t\t\t\t// needed.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.fieldList.forEach( function ( fSpec ) {\n\t\t\t\tfieldWidget = this.fieldMap[ fSpec.key ];\n\t\t\t\tserialized[ fSpec.key ] = fieldWidget.getSerialized();\n\t\t\t}, this );\n\n\t\t\treturn serialized;\n\t\t},\n\n\t\t/**\n\t\t * Set the state of this widget from machine-readable representation, as returned by\n\t\t * #getSerialized.\n\t\t *\n\t\t * Fields from the representation can be omitted to keep the current value.\n\t\t *\n\t\t * @param {Object.<string,Object>} [serialized]\n\t\t */\n\t\tsetSerialized: function ( serialized ) {\n\t\t\tif ( !this.interfaceBuilt ) {\n\t\t\t\t// There's no interface yet! Don't load the data, just keep it\n\t\t\t\t// around.\n\t\t\t\tif ( serialized === undefined ) {\n\t\t\t\t\t// Note: This will happen if we \"undo\" a copy operation while\n\t\t\t\t\t// some of the details interfaces aren't loaded.\n\t\t\t\t\tthis.savedSerialData = undefined;\n\t\t\t\t} else {\n\t\t\t\t\tthis.savedSerialData = $.extend( true,\n\t\t\t\t\t\tthis.savedSerialData || {},\n\t\t\t\t\t\tserialized\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( serialized === undefined ) {\n\t\t\t\t// This is meaningless if the interface is already built.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.fieldList.forEach( function ( fSpec ) {\n\t\t\t\tif ( serialized[ fSpec.key ] ) {\n\t\t\t\t\tthis.fieldMap[ fSpec.key ].setSerialized( serialized[ fSpec.key ] );\n\t\t\t\t}\n\t\t\t}, this );\n\t\t},\n\n\t\t/**\n\t\t * Convert entire details for this file into wikiText, which will then be posted to the file\n\t\t *\n\t\t * This function assumes that all input is valid.\n\t\t *\n\t\t * @return {string} wikitext representing all details\n\t\t */\n\t\tgetWikiText: function () {\n\t\t\tlet wikiText = mw.UploadWizard.config.content.wikitext,\n\t\t\t\tsubstitutions = {}, substList = [],\n\t\t\t\tdeed = this.upload.deedChooser.deed,\n\t\t\t\tfieldWidget, serialized, valueType, re, escapedKey, replaceValue;\n\n\t\t\tif ( !wikiText ) {\n\t\t\t\twikiText = mw.message( 'mediauploader-default-content-wikitext' ).plain();\n\t\t\t}\n\t\t\tif ( mw.UploadWizard.config.content.prepend ) {\n\t\t\t\twikiText = mw.UploadWizard.config.content.prepend + '\\n' + wikiText;\n\t\t\t}\n\t\t\tif ( mw.UploadWizard.config.content.append ) {\n\t\t\t\twikiText += '\\n' + mw.UploadWizard.config.content.append;\n\t\t\t}\n\n\t\t\tfunction addSubstitution( key, value ) {\n\t\t\t\tlet v = value;\n\t\t\t\tif ( key in substitutions ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// Discard funny values that toString poorly\n\t\t\t\tif ( v === undefined || v === null || ( typeof v === 'number' && isNaN( v ) ) ) {\n\t\t\t\t\tv = '';\n\t\t\t\t}\n\t\t\t\tsubstList.push( key );\n\t\t\t\tsubstitutions[ key ] = v.toString();\n\t\t\t}\n\n\t\t\t// Add hardcoded substitutions\n\t\t\taddSubstitution( 'source', deed.getSourceWikiText( this.upload ) );\n\t\t\taddSubstitution( 'author', deed.getAuthorWikiText( this.upload ) );\n\t\t\taddSubstitution( 'license', deed.getLicenseWikiText() );\n\n\t\t\t// Add substitutions for all the defined details fields\n\t\t\tthis.fieldList.forEach( function ( spec ) {\n\t\t\t\tif ( spec.type === 'license' ) {\n\t\t\t\t\t// Skip the license input... it is handled separately above.\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tfieldWidget = this.fieldMap[ spec.key ];\n\t\t\t\taddSubstitution( spec.key, fieldWidget.getWikiText() );\n\t\t\t\tserialized = fieldWidget.getSerializedParsed();\n\t\t\t\tif ( typeof serialized !== 'object' ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// Also add \"subfields\" based on the serialized values. Just in case.\n\t\t\t\tObject.keys( serialized ).forEach( ( key ) => {\n\t\t\t\t\treplaceValue = serialized[ key ];\n\t\t\t\t\tvalueType = typeof replaceValue;\n\t\t\t\t\tif ( valueType === 'string' || valueType === 'number' || valueType === 'boolean' ) {\n\t\t\t\t\t\taddSubstitution( spec.key + '.' + key, replaceValue );\n\t\t\t\t\t}\n\t\t\t\t}, this );\n\t\t\t}, this );\n\n\t\t\t// Do the substitutions\n\t\t\tsubstList.forEach( ( substKey ) => {\n\t\t\t\treplaceValue = substitutions[ substKey ].trim();\n\t\t\t\tescapedKey = substKey.replace( /[.*+?^${}()|[\\]\\\\]/g, '\\\\$&' );\n\t\t\t\tre = new RegExp( '\\\\{\\\\{\\\\{ *' + escapedKey + ' *(\\\\|(.*?))?\\\\}\\\\}\\\\}', 'giu' );\n\t\t\t\twikiText = wikiText.replace( re, ( match, _, defaultValue ) => {\n\t\t\t\t\tif ( !replaceValue ) {\n\t\t\t\t\t\treturn defaultValue || '';\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn replaceValue;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}, this );\n\n\t\t\t// remove too many newlines in a row\n\t\t\twikiText = wikiText.replace( /\\n{3,}/g, '\\n\\n' );\n\n\t\t\treturn wikiText;\n\t\t},\n\n\t\t/**\n\t\t * @return {jQuery.Promise}\n\t\t */\n\t\tsubmit: function () {\n\t\t\tlet details = this,\n\t\t\t\twikitext, promise;\n\n\t\t\tthis.$containerDiv.find( 'form' ).trigger( 'submit' );\n\n\t\t\tthis.upload.title = this.getTitle();\n\t\t\tthis.upload.state = 'submitting-details';\n\t\t\tthis.setStatus( mw.message( 'mediauploader-submitting-details' ).text() );\n\t\t\tthis.showIndicator( 'progress' );\n\n\t\t\twikitext = this.getWikiText();\n\t\t\tpromise = this.submitWikiText( wikitext );\n\n\t\t\treturn promise.then( () => {\n\t\t\t\tdetails.showIndicator( 'success' );\n\t\t\t\tdetails.setStatus( mw.message( 'mediauploader-published' ).text() );\n\t\t\t} );\n\t\t},\n\n\t\t/**\n\t\t * Post wikitext as edited here, to the file\n\t\t *\n\t\t * This function is only called if all input seems valid (which doesn't mean that we can't get\n\t\t * an error, see #processError).\n\t\t *\n\t\t * @param {string} wikiText\n\t\t * @return {jQuery.Promise}\n\t\t */\n\t\tsubmitWikiText: function ( wikiText ) {\n\t\t\tlet params,\n\t\t\t\ttags = [ 'uploadwizard' ],\n\t\t\t\tdeed = this.upload.deedChooser.deed,\n\t\t\t\tcomment = '',\n\t\t\t\tconfig = mw.UploadWizard.config;\n\n\t\t\tthis.firstPoll = Date.now();\n\n\t\t\tif ( this.upload.file.source ) {\n\t\t\t\ttags.push( 'uploadwizard-' + this.upload.file.source );\n\t\t\t}\n\n\t\t\tif ( deed.name === 'ownwork' ) {\n\t\t\t\t// This message does not have any parameters, so there's nothing to substitute\n\t\t\t\tcomment = config.uploadComment.ownWork;\n\t\t\t} else {\n\t\t\t\tmw.messages.set(\n\t\t\t\t\t'mediauploader-upload-comment-third-party',\n\t\t\t\t\tconfig.uploadComment.thirdParty\n\t\t\t\t);\n\t\t\t\tcomment = mw.message(\n\t\t\t\t\t'mediauploader-upload-comment-third-party',\n\t\t\t\t\tdeed.getAuthorWikiText(),\n\t\t\t\t\tdeed.getSourceWikiText()\n\t\t\t\t).plain();\n\t\t\t}\n\n\t\t\tparams = {\n\t\t\t\taction: 'upload',\n\t\t\t\tfilekey: this.upload.fileKey,\n\t\t\t\tfilename: this.getTitle().getMain(),\n\t\t\t\tcomment: comment,\n\t\t\t\ttags: config.CanAddTags ? tags : [],\n\t\t\t\t// we can ignore upload warnings here, we've already checked\n\t\t\t\t// when stashing the file\n\t\t\t\t// not ignoring warnings would prevent us from uploading a file\n\t\t\t\t// that is a duplicate of something in a foreign repo\n\t\t\t\tignorewarnings: true,\n\t\t\t\ttext: wikiText\n\t\t\t};\n\n\t\t\t// Only enable async publishing if file is larger than 10MiB\n\t\t\tif ( this.upload.transportWeight > 10 * 1024 * 1024 ) {\n\t\t\t\tparams.async = true;\n\t\t\t}\n\n\t\t\treturn this.submitWikiTextInternal( params );\n\t\t},\n\n\t\t/**\n\t\t * Perform the API call with given parameters (which is expected to publish this file) and\n\t\t * handle the result.\n\t\t *\n\t\t * @param {Object} params API call parameters\n\t\t * @return {jQuery.Promise}\n\t\t */\n\t\tsubmitWikiTextInternal: function ( params ) {\n\t\t\tconst details = this,\n\t\t\t\tapiPromise = this.upload.api.postWithEditToken( params );\n\n\t\t\treturn apiPromise\n\t\t\t\t// process the successful (in terms of HTTP status...) API call first:\n\t\t\t\t// there may be warnings or other issues with the upload that need\n\t\t\t\t// to be dealt with\n\t\t\t\t.then( this.validateWikiTextSubmitResult.bind( this, params ) )\n\t\t\t\t// making it here means the upload is a success, or it would've been\n\t\t\t\t// rejected by now (either by HTTP status code, or in validateWikiTextSubmitResult)\n\t\t\t\t.then( ( result ) => {\n\t\t\t\t\tdetails.title = mw.Title.makeTitle( 6, result.upload.filename );\n\t\t\t\t\tdetails.upload.extractImageInfo( result.upload.imageinfo );\n\t\t\t\t\tdetails.upload.thisProgress = 1.0;\n\t\t\t\t\tdetails.upload.state = 'complete';\n\t\t\t\t\treturn result;\n\t\t\t\t} )\n\t\t\t\t// uh-oh - something went wrong!\n\t\t\t\t.catch( ( code, result ) => {\n\t\t\t\t\tdetails.upload.state = 'error';\n\t\t\t\t\tdetails.processError( code, result );\n\t\t\t\t\treturn $.Deferred().reject( code, result );\n\t\t\t\t} )\n\t\t\t\t.promise( { abort: apiPromise.abort } );\n\t\t},\n\n\t\t/**\n\t\t * Validates the result of a submission & returns a resolved promise with\n\t\t * the API response if all went well, or rejects with error code & error\n\t\t * message as you would expect from failed mediawiki API calls.\n\t\t *\n\t\t * @param {Object} params What we passed to the API that caused this response.\n\t\t * @param {Object} result API result of an upload or status check.\n\t\t * @return {jQuery.Promise}\n\t\t */\n\t\tvalidateWikiTextSubmitResult: function ( params, result ) {\n\t\t\tlet wx, warningsKeys, existingFile, existingFileUrl, existingFileExt, ourFileExt, code, message,\n\t\t\t\tdetails = this,\n\t\t\t\twarnings = null,\n\t\t\t\tignoreTheseWarnings = false,\n\t\t\t\tdeferred = $.Deferred();\n\n\t\t\tif ( result && result.upload && result.upload.result === 'Poll' ) {\n\t\t\t\t// if async publishing takes longer than 10 minutes give up\n\t\t\t\tif ( ( Date.now() - this.firstPoll ) > 10 * 60 * 1000 ) {\n\t\t\t\t\treturn deferred.reject( 'server-error', { errors: [ {\n\t\t\t\t\t\tcode: 'server-error',\n\t\t\t\t\t\thtml: 'Unknown server error'\n\t\t\t\t\t} ] } );\n\t\t\t\t} else {\n\t\t\t\t\tif ( result.upload.stage === undefined ) {\n\t\t\t\t\t\treturn deferred.reject( 'no-stage', { errors: [ {\n\t\t\t\t\t\t\tcode: 'no-stage',\n\t\t\t\t\t\t\thtml: 'Unable to check file\\'s status'\n\t\t\t\t\t\t} ] } );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Messages that can be returned:\n\t\t\t\t\t\t// * mediauploader-queued\n\t\t\t\t\t\t// * mediauploader-publish\n\t\t\t\t\t\t// * mediauploader-assembling\n\t\t\t\t\t\tthis.setStatus( mw.message( 'mediauploader-' + result.upload.stage ).text() );\n\t\t\t\t\t\tsetTimeout( () => {\n\t\t\t\t\t\t\tif ( details.upload.state !== 'aborted' ) {\n\t\t\t\t\t\t\t\tdetails.submitWikiTextInternal( {\n\t\t\t\t\t\t\t\t\taction: 'upload',\n\t\t\t\t\t\t\t\t\tcheckstatus: true,\n\t\t\t\t\t\t\t\t\tfilekey: details.upload.fileKey\n\t\t\t\t\t\t\t\t} ).then( deferred.resolve, deferred.reject );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tdeferred.resolve( 'aborted' );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}, 3000 );\n\n\t\t\t\t\t\treturn deferred.promise();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( result && result.upload && result.upload.warnings ) {\n\t\t\t\twarnings = result.upload.warnings;\n\t\t\t}\n\t\t\tif ( warnings && warnings.exists ) {\n\t\t\t\texistingFile = warnings.exists;\n\t\t\t} else if ( warnings && warnings[ 'exists-normalized' ] ) {\n\t\t\t\texistingFile = warnings[ 'exists-normalized' ];\n\t\t\t\texistingFileExt = mw.Title.normalizeExtension( existingFile.split( '.' ).pop() );\n\t\t\t\tourFileExt = mw.Title.normalizeExtension( this.getTitle().getExtension() );\n\n\t\t\t\tif ( existingFileExt !== ourFileExt ) {\n\t\t\t\t\tdelete warnings[ 'exists-normalized' ];\n\t\t\t\t\tignoreTheseWarnings = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( warnings && warnings[ 'was-deleted' ] ) {\n\t\t\t\tdelete warnings[ 'was-deleted' ];\n\t\t\t\tignoreTheseWarnings = true;\n\t\t\t}\n\t\t\tfor ( wx in warnings ) {\n\t\t\t\tif ( Object.prototype.hasOwnProperty.call( warnings, wx ) ) {\n\t\t\t\t\t// if there are other warnings, deal with those first\n\t\t\t\t\tignoreTheseWarnings = false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( result && result.upload && result.upload.imageinfo ) {\n\t\t\t\treturn $.Deferred().resolve( result );\n\t\t\t} else if ( ignoreTheseWarnings ) {\n\t\t\t\tparams.ignorewarnings = 1;\n\t\t\t\treturn this.submitWikiTextInternal( params );\n\t\t\t} else if ( result && result.upload && result.upload.warnings ) {\n\t\t\t\tif ( warnings.thumb || warnings[ 'thumb-name' ] ) {\n\t\t\t\t\tcode = 'error-title-thumbnail';\n\t\t\t\t\tmessage = mw.message( 'mediauploader-error-title-thumbnail' ).parse();\n\t\t\t\t} else if ( warnings.badfilename ) {\n\t\t\t\t\tcode = 'title-invalid';\n\t\t\t\t\tmessage = mw.message( 'mediauploader-error-title-invalid' ).parse();\n\t\t\t\t} else if ( warnings[ 'bad-prefix' ] ) {\n\t\t\t\t\tcode = 'title-senselessimagename';\n\t\t\t\t\tmessage = mw.message( 'mediauploader-error-title-senselessimagename' ).parse();\n\t\t\t\t} else if ( existingFile ) {\n\t\t\t\t\texistingFileUrl = mw.config.get( 'wgServer' ) + mw.Title.makeTitle( NS_FILE, existingFile ).getUrl();\n\t\t\t\t\tcode = 'api-warning-exists';\n\t\t\t\t\tmessage = mw.message( 'mediauploader-api-warning-exists', existingFileUrl ).parse();\n\t\t\t\t} else if ( warnings.duplicate ) {\n\t\t\t\t\tcode = 'upload-error-duplicate';\n\t\t\t\t\tmessage = mw.message( 'mediauploader-upload-error-duplicate' ).parse();\n\t\t\t\t} else if ( warnings[ 'duplicate-archive' ] !== undefined ) {\n\t\t\t\t\t// warnings[ 'duplicate-archive' ] may be '' (empty string) for revdeleted files\n\t\t\t\t\tif ( this.upload.handler.isIgnoredWarning( 'duplicate-archive' ) ) {\n\t\t\t\t\t\t// We already told the interface to ignore this warning, so\n\t\t\t\t\t\t// let's steamroll over it and re-call this handler.\n\t\t\t\t\t\tparams.ignorewarnings = true;\n\t\t\t\t\t\treturn this.submitWikiTextInternal( params );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// This should _never_ happen, but just in case....\n\t\t\t\t\t\tcode = 'upload-error-duplicate-archive';\n\t\t\t\t\t\tmessage = mw.message( 'mediauploader-upload-error-duplicate-archive' ).parse();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\twarningsKeys = Object.keys( warnings );\n\t\t\t\t\tcode = 'unknown-warning';\n\t\t\t\t\tmessage = mw.message( 'mediauploader-api-error-unknown-warning', warningsKeys.join( ', ' ) ).parse();\n\t\t\t\t}\n\n\t\t\t\treturn $.Deferred().reject( code, { errors: [ { html: message } ] } );\n\t\t\t} else {\n\t\t\t\treturn $.Deferred().reject( 'this-info-missing', result );\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Create a recoverable error -- show the form again, and highlight the problematic field.\n\t\t *\n\t\t * @param {string} code\n\t\t * @param {string} html Error message to show.\n\t\t */\n\t\trecoverFromError: function ( code, html ) {\n\t\t\tconst titleField = mw.UploadWizard.config.content.titleField;\n\n\t\t\tthis.upload.state = 'recoverable-error';\n\t\t\tthis.$dataDiv.morphCrossfade( '.detailsForm' );\n\t\t\tthis.fieldWrapperMap[ titleField ].setErrors( [ { code: code, html: html } ] );\n\t\t},\n\n\t\t/**\n\t\t * Show error state, possibly using a recoverable error form\n\t\t *\n\t\t * @param {string} code Error code\n\t\t * @param {string} html Error message\n\t\t */\n\t\tshowError: function ( code, html ) {\n\t\t\tthis.showIndicator( 'error' );\n\t\t\tthis.setStatus( html );\n\t\t},\n\n\t\t/**\n\t\t * Decide how to treat various errors\n\t\t *\n\t\t * @param {string} code Error code\n\t\t * @param {Object} result Result from ajax call\n\t\t */\n\t\tprocessError: function ( code, result ) {\n\t\t\tconst recoverable = [\n\t\t\t\t'abusefilter-disallowed',\n\t\t\t\t'abusefilter-warning',\n\t\t\t\t'spamblacklist',\n\t\t\t\t'fileexists-shared-forbidden',\n\t\t\t\t'protectedpage',\n\t\t\t\t'titleblacklist-forbidden',\n\n\t\t\t\t// below are not actual API errors, but recoverable warnings that have\n\t\t\t\t// been discovered in validateWikiTextSubmitResult and fabricated to resemble\n\t\t\t\t// API errors and end up here to be dealt with\n\t\t\t\t'error-title-thumbnail',\n\t\t\t\t'title-invalid',\n\t\t\t\t'title-senselessimagename',\n\t\t\t\t'api-warning-exists',\n\t\t\t\t'upload-error-duplicate',\n\t\t\t\t'upload-error-duplicate',\n\t\t\t\t'upload-error-duplicate-archive',\n\t\t\t\t'unknown-warning'\n\t\t\t];\n\n\t\t\tif ( code === 'badtoken' ) {\n\t\t\t\tthis.api.badToken( 'csrf' );\n\t\t\t\t// TODO Automatically try again instead of requiring the user to bonk the button\n\t\t\t}\n\n\t\t\tif ( code === 'ratelimited' ) {\n\t\t\t\t// None of the remaining uploads is going to succeed, and every failed one is going to\n\t\t\t\t// ping the rate limiter again.\n\t\t\t\tthis.upload.wizard.steps.details.queue.abortExecuting();\n\t\t\t} else if ( code === 'http' && result && result.exception === 'abort' ) {\n\t\t\t\t// This upload has just been aborted because an earlier one got the 'ratelimited' error.\n\t\t\t\t// This could potentially also come up when an upload is removed by the user, but in that\n\t\t\t\t// case the UI is invisible anyway, so whatever.\n\t\t\t\tcode = 'ratelimited';\n\t\t\t}\n\n\t\t\tif ( recoverable.includes( code ) ) {\n\t\t\t\tthis.recoverFromError( code, result.errors[ 0 ].html );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.showError( code, result.errors[ 0 ].html );\n\t\t},\n\n\t\tsetStatus: function ( s ) {\n\t\t\tthis.$div.find( '.mediauploader-file-status-line' ).html( s ).show();\n\t\t},\n\n\t\t// TODO: De-duplicate with code form mw.UploadWizardUploadInterface.js\n\t\tshowIndicator: function ( status ) {\n\t\t\tthis.$spinner.hide();\n\t\t\tthis.statusMessage.toggle( false );\n\n\t\t\tif ( status === 'progress' ) {\n\t\t\t\tthis.$spinner.show();\n\t\t\t} else if ( status ) {\n\t\t\t\tthis.statusMessage.toggle( true ).setType( status );\n\t\t\t}\n\t\t\tthis.$indicator.toggleClass( 'mediauploader-file-indicator-visible', !!status );\n\t\t},\n\n\t\tsetVisibleTitle: function ( s ) {\n\t\t\t$( this.$submittingDiv )\n\t\t\t\t.find( '.mediauploader-visible-file-filename-text' )\n\t\t\t\t.text( s );\n\t\t}\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/mw.UploadWizardLicenseInput.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'self' is never reassigned. Use 'const' instead.","line":17,"column":7,"nodeType":"Identifier","messageId":"useConst","endLine":17,"endColumn":11},{"ruleId":"prefer-const","severity":2,"message":"'groups' is never reassigned. Use 'const' instead.","line":18,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":18,"endColumn":10},{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":77,"column":2,"nodeType":"MemberExpression","messageId":"forbidden","endLine":77,"endColumn":15},{"ruleId":"prefer-const","severity":2,"message":"'templates' is never reassigned. Use 'const' instead.","line":183,"column":9,"nodeType":"Identifier","messageId":"useConst","endLine":183,"endColumn":18},{"ruleId":"prefer-const","severity":2,"message":"'addError' is never reassigned. Use 'const' instead.","line":209,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":209,"endColumn":13},{"ruleId":"prefer-const","severity":2,"message":"'selectedInputs' is never reassigned. Use 'const' instead.","line":216,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":216,"endColumn":19},{"ruleId":"prefer-const","severity":2,"message":"'data' is never reassigned. Use 'const' instead.","line":226,"column":7,"nodeType":"Identifier","messageId":"useConst","endLine":226,"endColumn":11},{"ruleId":"prefer-const","severity":2,"message":"'wikitext' is never reassigned. Use 'const' instead.","line":232,"column":6,"nodeType":"Identifier","messageId":"useConst","endLine":232,"endColumn":14},{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":268,"column":28,"nodeType":"MemberExpression","messageId":"forbidden","endLine":268,"endColumn":41}],"suppressedMessages":[{"ruleId":"mediawiki/msg-doc","severity":1,"message":"All possible message keys should be documented. See https://w.wiki/4r9a for details.","line":212,"column":24,"nodeType":"CallExpression","endLine":212,"endColumn":45,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":7,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"( function ( uw ) {\n\n\t/**\n\t * Create a group of radio buttons for licenses. N.B. the licenses are named after the templates they invoke.\n\t * Note that this is very anti-MVC. The values are held only in the actual form elements themselves.\n\t *\n\t * @extends OO.ui.Widget\n\t * @param {Object} config Configuration. Must have following properties:\n\t * @param {string} config.type Whether inclusive or exclusive license allowed (\"and\"|\"or\")\n\t * @param {string[]} config.licenses Template string names (matching keys in mw.UploadWizard.config.licenses)\n\t * @param {string[]} [config.licenseGroups] Groups of licenses, with more explanation\n\t * @param {string} [config.special] Indicates, don't put licenses here, instead use a special widget\n\t * @param {number} count Number of the things we are licensing (it matters to some texts)\n\t * @param {mw.Api} api API object, used for wikitext previews\n\t */\n\tmw.UploadWizardLicenseInput = function ( config, count, api ) {\n\t\tlet self = this,\n\t\t\tgroups = [],\n\t\t\tgroup;\n\n\t\tmw.UploadWizardLicenseInput.parent.call( this );\n\t\tOO.ui.mixin.GroupElement.call( this );\n\n\t\tthis.count = count;\n\n\t\tthis.api = api;\n\n\t\tif (\n\t\t\tconfig.type === undefined ||\n\t\t\t( config.licenses === undefined && config.licenseGroups === undefined )\n\t\t) {\n\t\t\tthrow new Error( 'improper initialization' );\n\t\t}\n\n\t\tthis.type = config.type;\n\t\tthis.defaults = [];\n\t\tif ( config.defaults ) {\n\t\t\tthis.defaults = config.defaults instanceof Array ? config.defaults : [ config.defaults ];\n\t\t} else if ( config.licenses && config.licenses[ 0 ] ) {\n\t\t\tthis.defaults = [ config.licenses[ 0 ] ];\n\t\t}\n\n\t\t// create inputs and licenses from config\n\t\tif ( config.licenseGroups === undefined ) {\n\t\t\tgroup = new uw.LicenseGroup( config, this.type, this.api, this.count );\n\t\t\tgroups.push( group );\n\t\t} else {\n\t\t\tconfig.licenseGroups.forEach( ( groupConfig ) => {\n\t\t\t\tgroup = new uw.LicenseGroup( groupConfig, self.type, self.api, self.count );\n\t\t\t\tgroups.push( group );\n\n\t\t\t\t// if we have multiple radio groups, it would be possible to select a radio\n\t\t\t\t// from each group; we obviously don't want that to happen!\n\t\t\t\t// upon selecting a new item in any group, iterate the other groups and make\n\t\t\t\t// sure they're updated accordingly, deselecting previously selected items\n\t\t\t\tif ( self.type === 'radio' ) {\n\t\t\t\t\tgroup.on( 'change', ( currentGroup ) => {\n\t\t\t\t\t\tconst value = currentGroup.getValue(),\n\t\t\t\t\t\t\tgroup2 = currentGroup.getGroup();\n\t\t\t\t\t\tself.setValues( value, group2 );\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\tthis.addItems( groups );\n\t\tthis.aggregate( { change: 'change' } );\n\t\tthis.$element.append( this.$group );\n\n\t\t// [wikitext => list of templates used in wikitext] map, used in\n\t\t// getUsedTemplates to reduce amount of API calls\n\t\tthis.templateCache = {};\n\t};\n\tOO.inheritClass( mw.UploadWizardLicenseInput, OO.ui.Widget );\n\tOO.mixinClass( mw.UploadWizardLicenseInput, OO.ui.mixin.GroupElement );\n\n\tObject.assign( mw.UploadWizardLicenseInput.prototype, {\n\t\tunload: function () {\n\t\t\tthis.getItems().forEach( ( group ) => {\n\t\t\t\tgroup.unload();\n\t\t\t} );\n\t\t},\n\n\t\t/**\n\t\t * Sets the value(s) of a license input. This is a little bit klugey because it relies on an inverted dict, and in some\n\t\t * cases we are now letting license inputs create multiple templates.\n\t\t *\n\t\t * @param {Object} values License-key to boolean values, e.g. { 'cc_by_sa_30': true, gfdl: false }\n\t\t * @param {string} [groupName] Name of group, when values are only relevant to this group\n\t\t */\n\t\tsetValues: function ( values, groupName ) {\n\t\t\tconst self = this,\n\t\t\t\tselectedGroups = [];\n\n\t\t\tthis.getItems().forEach( ( group ) => {\n\t\t\t\tif ( groupName === undefined || group.getGroup() === groupName ) {\n\t\t\t\t\tgroup.setValue( values );\n\t\t\t\t\tif ( Object.keys( group.getValue() ).length > 0 ) {\n\t\t\t\t\t\tselectedGroups.push( group );\n\t\t\t\t\t}\n\t\t\t\t} else if ( self.type === 'radio' ) {\n\t\t\t\t\t// when we're dealing with radio buttons and there are changes in another\n\t\t\t\t\t// group, then we'll need to clear out this group...\n\t\t\t\t\tgroup.setValue( {} );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tif ( selectedGroups.length > 1 && this.type === 'radio' ) {\n\t\t\t\t// leave the last one alone - that one can remain selected\n\t\t\t\tselectedGroups.pop();\n\n\t\t\t\t// if we've selected things in multiple groups (= when the group was not defined,\n\t\t\t\t// which is basically only when dealing with defaults, from config or user\n\t\t\t\t// preferences), we need to make sure we're left with only 1 selected radio in\n\t\t\t\t// 1 group\n\t\t\t\t// in that case, we're only going to select the *last* occurrence, which is what\n\t\t\t\t// a browser would do when trying to find/select a radio that occurs twice\n\t\t\t\tselectedGroups.forEach( ( group ) => {\n\t\t\t\t\tgroup.setValue( {} );\n\t\t\t\t} );\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Set the default configured licenses\n\t\t */\n\t\tsetDefaultValues: function () {\n\t\t\tconst values = {};\n\t\t\tthis.defaults.forEach( ( license ) => {\n\t\t\t\tvalues[ license ] = true;\n\t\t\t} );\n\t\t\tthis.setValues( values );\n\t\t},\n\n\t\t/**\n\t\t * Gets the selected license(s). The returned value will be a license\n\t\t * key => license props map, as defined in MediaUploader.config.php.\n\t\t *\n\t\t * @return {Object}\n\t\t */\n\t\tgetLicenses: function () {\n\t\t\tconst licenses = {};\n\n\t\t\tthis.getItems().forEach( ( group ) => {\n\t\t\t\tconst licenseNames = Object.keys( group.getValue() );\n\t\t\t\tlicenseNames.forEach( ( name ) => {\n\t\t\t\t\tlicenses[ name ] = mw.UploadWizard.config.licenses[ name ] || {};\n\t\t\t\t} );\n\t\t\t} );\n\n\t\t\treturn licenses;\n\t\t},\n\n\t\t/**\n\t\t * Gets the wikitext associated with all selected inputs.\n\t\t *\n\t\t * @return {string} of wikitext (empty string if no inputs set)\n\t\t */\n\t\tgetWikiText: function () {\n\t\t\treturn this.getItems().map( ( group ) => group.getWikiText() ).join( '' ).trim();\n\t\t},\n\n\t\t/**\n\t\t * Returns a list of templates used & transcluded in given wikitext\n\t\t *\n\t\t * @param {string} wikitext\n\t\t * @return {jQuery.Promise} Promise that resolves with an array of template names\n\t\t */\n\t\tgetUsedTemplates: function ( wikitext ) {\n\t\t\tconst input = this;\n\n\t\t\tif ( wikitext in this.templateCache ) {\n\t\t\t\treturn $.Deferred().resolve( this.templateCache[ wikitext ] ).promise();\n\t\t\t}\n\n\t\t\treturn this.api.get( {\n\t\t\t\taction: 'parse',\n\t\t\t\tpst: true,\n\t\t\t\tprop: 'templates',\n\t\t\t\ttitle: 'File:UploadWizard license verification.png',\n\t\t\t\ttext: wikitext\n\t\t\t} ).then( ( result ) => {\n\t\t\t\tlet templates = [],\n\t\t\t\t\ttemplate, title, i;\n\n\t\t\t\tfor ( i = 0; i < result.parse.templates.length; i++ ) {\n\t\t\t\t\ttemplate = result.parse.templates[ i ];\n\n\t\t\t\t\t// normalize templates to mw.Title.getPrefixedDb() format\n\t\t\t\t\ttitle = new mw.Title( template.title, template.ns );\n\t\t\t\t\ttemplates.push( title.getPrefixedDb() );\n\t\t\t\t}\n\n\t\t\t\t// cache result so we won't have to fire another API request\n\t\t\t\t// for the same content\n\t\t\t\tinput.templateCache[ wikitext ] = templates;\n\n\t\t\t\treturn templates;\n\t\t\t} );\n\t\t},\n\n\t\t/**\n\t\t * See uw.DetailsWidget\n\t\t *\n\t\t * @return {jQuery.Promise}\n\t\t */\n\t\tgetErrors: function () {\n\t\t\tlet errors = $.Deferred().resolve( [] ).promise(),\n\t\t\t\taddError = function ( message ) {\n\t\t\t\t\terrors = errors.then( ( errorsCopy ) => {\n\t\t\t\t\t\t// eslint-disable-next-line mediawiki/msg-doc\n\t\t\t\t\t\terrorsCopy.push( mw.message( message ) );\n\t\t\t\t\t\treturn errorsCopy;\n\t\t\t\t\t} );\n\t\t\t\t},\n\t\t\t\tselectedInputs = this.getSerialized();\n\n\t\t\tif ( Object.keys( selectedInputs ).length === 0 ) {\n\t\t\t\taddError( 'mediauploader-deeds-need-license' );\n\t\t\t} else {\n\t\t\t\t// It's pretty hard to screw up a radio button, so if even one of them is selected it's okay.\n\t\t\t\t// But also check that associated textareas are filled for if the input is selected, and that\n\t\t\t\t// they are the appropriate size.\n\t\t\t\tObject.keys( selectedInputs ).forEach( ( name ) => {\n\t\t\t\t\tlet wikitext,\n\t\t\t\t\t\tdata = selectedInputs[ name ];\n\n\t\t\t\t\tif ( typeof data !== 'string' ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\twikitext = data.trim();\n\n\t\t\t\t\tif ( wikitext === '' ) {\n\t\t\t\t\t\taddError( 'mediauploader-error-license-wikitext-missing' );\n\t\t\t\t\t} else if ( wikitext.length < mw.UploadWizard.config.minCustomLicenseLength ) {\n\t\t\t\t\t\taddError( 'mediauploader-error-license-wikitext-too-short' );\n\t\t\t\t\t} else if ( wikitext.length > mw.UploadWizard.config.maxCustomLicenseLength ) {\n\t\t\t\t\t\taddError( 'mediauploader-error-license-wikitext-too-long' );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn errors;\n\t\t},\n\n\t\t/**\n\t\t * See uw.DetailsWidget\n\t\t *\n\t\t * @return {jQuery.Promise}\n\t\t */\n\t\tgetWarnings: function () {\n\t\t\treturn $.Deferred().resolve( [] ).promise();\n\t\t},\n\n\t\t/**\n\t\t * @return {Object}\n\t\t */\n\t\tgetSerialized: function () {\n\t\t\tconst values = {};\n\n\t\t\tthis.getItems().forEach( ( group ) => {\n\t\t\t\tconst groupName = group.getGroup(),\n\t\t\t\t\tvalue = group.getValue();\n\n\t\t\t\tif ( Object.keys( value ).length > 0 ) {\n\t\t\t\t\t// $.extend just in case there are multiple groups with the same name...\n\t\t\t\t\tvalues[ groupName ] = Object.assign( {}, values[ groupName ] || {}, value );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\treturn values;\n\t\t},\n\n\t\t/**\n\t\t * @param {Object} serialized\n\t\t */\n\t\tsetSerialized: function ( serialized ) {\n\t\t\tconst self = this;\n\n\t\t\tObject.keys( serialized ).forEach( ( group ) => {\n\t\t\t\tself.setValues( serialized[ group ], group );\n\t\t\t} );\n\t\t}\n\n\t} );\n\n}( mw.uploadWizard ) );\n","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-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/resources/mw.UploadWizardPage.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'config' is never reassigned. Use 'const' instead.","line":31,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":31,"endColumn":10},{"ruleId":"prefer-const","severity":2,"message":"'uploadWizard' is never reassigned. Use 'const' instead.","line":53,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":53,"endColumn":15}],"suppressedMessages":[{"ruleId":"no-jquery/no-global-selector","severity":2,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":38,"column":3,"nodeType":"CallExpression","endLine":38,"endColumn":28,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-global-selector","severity":2,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":41,"column":8,"nodeType":"CallExpression","endLine":41,"endColumn":29,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-global-selector","severity":2,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":49,"column":4,"nodeType":"CallExpression","endLine":49,"endColumn":37,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":2,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*\n * This script is run on [[Special:MediaUploader]].\n * Configures and creates an interface for uploading files in multiple steps, hence \"wizard\".\n *\n * Tries to transform Javascript globals dumped on us by the PHP code into a more\n * compact configuration, owned by the MediaUploader created.\n */\n\n// Create UploadWizard\n( function () {\n\n\tfunction isCompatible() {\n\t\tconst\n\t\t\tprofile = $.client.profile(),\n\t\t\t// Firefox < 7.0 sends an empty string as filename for Blobs in FormData.\n\t\t\t// requests. https://bugzilla.mozilla.org/show_bug.cgi?id=649150\n\t\t\tbadFormDataBlobs = profile.name === 'firefox' && profile.versionNumber < 7;\n\n\t\treturn !!(\n\t\t\twindow.FileReader &&\n\t\t\twindow.FormData &&\n\t\t\twindow.File &&\n\t\t\twindow.File.prototype.slice &&\n\t\t\t!badFormDataBlobs\n\t\t);\n\t}\n\n\tmw.UploadWizardPage = function () {\n\n\t\tlet uploadWizard,\n\t\t\tconfig = mw.config.get( 'MediaUploaderConfig' );\n\n\t\t// Default configuration value that cannot be removed\n\t\tconfig.maxUploads = config.maxUploads || 10;\n\n\t\t// Remove the initial spinner\n\t\t// eslint-disable-next-line no-jquery/no-global-selector\n\t\t$( '.mwe-first-spinner' ).remove();\n\n\t\t// eslint-disable-next-line no-jquery/no-global-selector\n\t\tif ( $( '#upload-wizard' ).length === 0 ) {\n\t\t\tmw.log( 'MediaUploader is disabled, nothing to do.' );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !isCompatible() ) {\n\t\t\t// Display the same error message as for grade-C browsers\n\t\t\t// eslint-disable-next-line no-jquery/no-global-selector\n\t\t\t$( '.mediauploader-unavailable' ).show();\n\t\t\treturn;\n\t\t}\n\n\t\tuploadWizard = new mw.UploadWizard( config );\n\t\tuploadWizard.createInterface( '#upload-wizard' );\n\t};\n\n\t$( () => {\n\t\t// show page.\n\t\tmw.UploadWizardPage();\n\t} );\n\n}() );\n","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-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/resources/mw.UploadWizardUpload.js","messages":[{"ruleId":"jsdoc/require-param-type","severity":1,"message":"Missing JSDoc @param \"uw\" type.","line":8,"column":1,"nodeType":"Block","endLine":8,"endColumn":1},{"ruleId":"no-unused-vars","severity":1,"message":"'uw' is defined but never used.","line":11,"column":14,"nodeType":"Identifier","messageId":"unusedVar","endLine":11,"endColumn":16},{"ruleId":"prefer-const","severity":2,"message":"'deferred' is never reassigned. Use 'const' instead.","line":204,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":204,"endColumn":12},{"ruleId":"prefer-const","severity":2,"message":"'upload' is never reassigned. Use 'const' instead.","line":205,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":205,"endColumn":10},{"ruleId":"no-redeclare","severity":2,"message":"'Uint8Array' is already defined as a built-in global variable.","line":222,"column":16,"nodeType":"Block","messageId":"redeclaredAsBuiltin","endLine":222,"endColumn":26},{"ruleId":"es-x/no-typed-arrays","severity":1,"message":"ES2015 'Uint8Array' is forbidden.","line":223,"column":16,"nodeType":"Identifier","messageId":"forbidden","endLine":223,"endColumn":26},{"ruleId":"prefer-const","severity":2,"message":"'upload' is never reassigned. Use 'const' instead.","line":314,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":314,"endColumn":10},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":382,"column":3,"nodeType":"CallExpression","endLine":382,"endColumn":36},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .fail","line":382,"column":3,"nodeType":"CallExpression","endLine":382,"endColumn":48},{"ruleId":"prefer-const","severity":2,"message":"'requestedTitle' is never reassigned. Use 'const' instead.","line":396,"column":7,"nodeType":"Identifier","messageId":"useConst","endLine":396,"endColumn":21},{"ruleId":"prefer-const","severity":2,"message":"'params' is never reassigned. Use 'const' instead.","line":430,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":430,"endColumn":9},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":448,"column":3,"nodeType":"CallExpression","endLine":448,"endColumn":36},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .fail","line":448,"column":3,"nodeType":"CallExpression","endLine":448,"endColumn":48},{"ruleId":"prefer-const","severity":2,"message":"'image' is never reassigned. Use 'const' instead.","line":488,"column":21,"nodeType":"Identifier","messageId":"useConst","endLine":488,"endColumn":26},{"ruleId":"prefer-const","severity":2,"message":"'constraint' is never reassigned. Use 'const' instead.","line":585,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":585,"endColumn":15},{"ruleId":"prefer-const","severity":2,"message":"'scaling' is never reassigned. Use 'const' instead.","line":629,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":629,"endColumn":10},{"ruleId":"prefer-const","severity":2,"message":"'width' is never reassigned. Use 'const' instead.","line":631,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":631,"endColumn":8},{"ruleId":"prefer-const","severity":2,"message":"'height' is never reassigned. Use 'const' instead.","line":632,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":632,"endColumn":9},{"ruleId":"prefer-const","severity":2,"message":"'dx' is never reassigned. Use 'const' instead.","line":640,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":640,"endColumn":5},{"ruleId":"prefer-const","severity":2,"message":"'dy' is never reassigned. Use 'const' instead.","line":641,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":641,"endColumn":5},{"ruleId":"prefer-const","severity":2,"message":"'$canvas' is never reassigned. Use 'const' instead.","line":666,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":666,"endColumn":10},{"ruleId":"prefer-const","severity":2,"message":"'ctx' is never reassigned. Use 'const' instead.","line":667,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":667,"endColumn":6},{"ruleId":"prefer-const","severity":2,"message":"'constraints' is never reassigned. Use 'const' instead.","line":715,"column":7,"nodeType":"Identifier","messageId":"useConst","endLine":715,"endColumn":18},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":767,"column":3,"nodeType":"CallExpression","endLine":769,"endColumn":26},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .fail","line":767,"column":3,"nodeType":"CallExpression","endLine":781,"endColumn":7},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":775,"column":6,"nodeType":"CallExpression","endLine":775,"endColumn":67},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":778,"column":7,"nodeType":"CallExpression","endLine":778,"endColumn":68},{"ruleId":"prefer-const","severity":2,"message":"'deferred' is never reassigned. Use 'const' instead.","line":802,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":802,"endColumn":12},{"ruleId":"prefer-const","severity":2,"message":"'upload' is never reassigned. Use 'const' instead.","line":803,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":803,"endColumn":10},{"ruleId":"prefer-const","severity":2,"message":"'canvas' is never reassigned. Use 'const' instead.","line":828,"column":9,"nodeType":"Identifier","messageId":"useConst","endLine":828,"endColumn":15},{"ruleId":"prefer-const","severity":2,"message":"'context' is never reassigned. Use 'const' instead.","line":831,"column":8,"nodeType":"Identifier","messageId":"useConst","endLine":831,"endColumn":15}],"suppressedMessages":[{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in '_binary_data'.","line":233,"column":6,"nodeType":"MemberExpression","messageId":"unexpectedUnderscore","endLine":233,"endColumn":23,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"camelcase","severity":2,"message":"Identifier '_binary_data' is not in camel case.","line":233,"column":11,"nodeType":"Identifier","messageId":"notCamelCase","endLine":233,"endColumn":23,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":28,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Represents the upload -- in its local and remote state. (Possibly those could be separate objects too...)\n * This is our 'model' object if we are thinking MVC. Needs to be better factored, lots of feature envy with the UploadWizard\n * states:\n * 'new' 'transporting' 'transported' 'metadata' 'stashed' 'details' 'submitting-details' 'complete' 'error'\n * should fork this into two -- local and remote, e.g. filename\n *\n * @param uw\n */\n\n( function ( uw ) {\n\t/**\n\t * Constructor for objects representing uploads. The workhorse of this entire extension.\n\t *\n\t * The upload knows nothing of other uploads. It manages its own interface, and transporting its own data, to\n\t * the server.\n\t *\n\t * Upload objects are usually created without a file, they are just associated with a form.\n\t * There is an \"empty\" fileInput which is invisibly floating above certain buttons in the interface, like \"Add a file\". When\n\t * this fileInput gets a file, this upload becomes 'filled'.\n\t *\n\t * @class mw.UploadWizardUpload\n\t * @constructor\n\t * @param {uw.controller.Step} controller\n\t * @param {File} file\n\t */\n\tmw.UploadWizardUpload = function MWUploadWizardUpload( controller, file ) {\n\t\tOO.EventEmitter.call( this );\n\n\t\tthis.index = mw.UploadWizardUpload.prototype.count;\n\t\tmw.UploadWizardUpload.prototype.count++;\n\n\t\tthis.controller = controller;\n\t\tthis.api = controller.api;\n\t\tthis.file = file;\n\t\tthis.state = 'new';\n\t\tthis.imageinfo = {};\n\t\tthis.title = undefined;\n\t\tthis.thumbnailPromise = {};\n\n\t\tthis.fileKey = undefined;\n\n\t\t// this should be moved to the interface, if we even keep this\n\t\tthis.transportWeight = 1; // default all same\n\n\t\t// details\n\t\tthis.ui = new mw.UploadWizardUploadInterface( this )\n\t\t\t.connect( this, {\n\t\t\t\t/*\n\t\t\t\t * This may be confusing!\n\t\t\t\t * This object also has a `remove` method, which will also be\n\t\t\t\t * called when an upload is removed. But an upload can be\n\t\t\t\t * removed for multiple reasons (one being clicking the \"remove\"\n\t\t\t\t * button, which triggers this event - but another could be\n\t\t\t\t * removing faulty uploads).\n\t\t\t\t * To simplify things, we'll always initiate the remove from the\n\t\t\t\t * controllers, so we'll relay this event to the controllers,\n\t\t\t\t * which will then eventually come back to call `remove` on this\n\t\t\t\t * object.\n\t\t\t\t */\n\t\t\t\t'upload-removed': [ 'emit', 'remove-upload' ]\n\t\t\t} );\n\t};\n\n\tOO.mixinClass( mw.UploadWizardUpload, OO.EventEmitter );\n\n\t// Upload handler\n\tmw.UploadWizardUpload.prototype.uploadHandler = null;\n\n\t// increments with each upload\n\tmw.UploadWizardUpload.prototype.count = 0;\n\n\t/**\n\t * start\n\t *\n\t * @return {jQuery.Promise}\n\t */\n\tmw.UploadWizardUpload.prototype.start = function () {\n\t\tthis.setTransportProgress( 0.0 );\n\n\t\t// handler -- usually ApiUploadFormDataHandler\n\t\tthis.handler = this.getUploadHandler();\n\t\treturn this.handler.start();\n\t};\n\n\t/**\n\t * Remove this upload. n.b. we trigger a removeUpload this is usually triggered from\n\t */\n\tmw.UploadWizardUpload.prototype.remove = function () {\n\t\t// remove the div that passed along the trigger\n\t\tthis.ui.$div.remove();\n\n\t\tthis.state = 'aborted';\n\t};\n\n\t/**\n\t * Wear our current progress, for observing processes to see\n\t *\n\t * @param {number} fraction\n\t */\n\tmw.UploadWizardUpload.prototype.setTransportProgress = function ( fraction ) {\n\t\tif ( this.state === 'aborted' ) {\n\t\t\t// We shouldn't be transporting anything anymore.\n\t\t\treturn;\n\t\t}\n\t\tthis.state = 'transporting';\n\t\tthis.transportProgress = fraction;\n\t\tthis.ui.$div.trigger( 'transportProgressEvent' );\n\t};\n\n\t/**\n\t * Stop the upload -- we have failed for some reason\n\t *\n\t * @param {string} code Error code from API\n\t * @param {string} html Error message\n\t * @param {jQuery} [$additionalStatus]\n\t */\n\tmw.UploadWizardUpload.prototype.setError = function ( code, html, $additionalStatus ) {\n\t\tif ( this.state === 'aborted' ) {\n\t\t\t// There's no point in reporting an error anymore.\n\t\t\treturn;\n\t\t}\n\t\tthis.state = 'error';\n\t\tthis.transportProgress = 0;\n\t\tthis.ui.showError( code, html, $additionalStatus );\n\t};\n\n\t/**\n\t * Called from any upload success condition\n\t *\n\t * @param {Object} result -- result of AJAX call\n\t */\n\tmw.UploadWizardUpload.prototype.setSuccess = function ( result ) {\n\t\tthis.state = 'transported';\n\t\tthis.transportProgress = 1;\n\n\t\tthis.ui.setStatus( 'mediauploader-getting-metadata' );\n\n\t\tthis.extractUploadInfo( result.upload );\n\t\tthis.state = 'stashed';\n\t\tthis.ui.showStashed();\n\n\t\tthis.emit( 'success' );\n\t\t// check all uploads, if they're complete, show the next button\n\t\t// TODO Make wizard connect to 'success' event\n\t\tthis.controller.showNext();\n\t};\n\n\t/**\n\t * Get just the filename.\n\t *\n\t * @return {string}\n\t */\n\tmw.UploadWizardUpload.prototype.getFilename = function () {\n\t\tif ( this.file.fileName ) {\n\t\t\treturn this.file.fileName;\n\t\t} else {\n\t\t\t// this property has a different name in FF vs Chrome.\n\t\t\treturn this.file.name;\n\t\t}\n\t};\n\n\t/**\n\t * Get the basename of a path.\n\t * For error conditions, returns the empty string.\n\t *\n\t * @return {string} basename\n\t */\n\tmw.UploadWizardUpload.prototype.getBasename = function () {\n\t\tconst path = this.getFilename();\n\n\t\tif ( path === undefined || path === null ) {\n\t\t\treturn '';\n\t\t}\n\n\t\t// find index of last path separator in the path, add 1. (If no separator found, yields 0)\n\t\t// then take the entire string after that.\n\t\treturn path.slice( Math.max( path.lastIndexOf( '/' ), path.lastIndexOf( '\\\\' ) ) + 1 );\n\t};\n\n\t/**\n\t * Sanitize and set the title of the upload.\n\t *\n\t * @param {string} title Unsanitized title.\n\t */\n\tmw.UploadWizardUpload.prototype.setTitle = function ( title ) {\n\t\tthis.title = mw.Title.newFromFileName( title );\n\t};\n\n\t/**\n\t * Extract some JPEG metadata that we need to render thumbnails (EXIF rotation mostly).\n\t *\n\t * For JPEGs, we use the JsJpegMeta library in core to extract metadata,\n\t * including EXIF tags. This is done asynchronously once each file has been\n\t * read.\n\t *\n\t * For all other file types, we don't need or want to run this, and this function does nothing.\n\t *\n\t * @private\n\t * @return {jQuery.Promise} A promise, resolved when we're done\n\t */\n\tmw.UploadWizardUpload.prototype.extractMetadataFromJpegMeta = function () {\n\t\tlet binReader, jpegmeta,\n\t\t\tdeferred = $.Deferred(),\n\t\t\tupload = this;\n\t\tif ( this.file && this.file.type === 'image/jpeg' ) {\n\t\t\tbinReader = new FileReader();\n\t\t\tbinReader.onerror = function () {\n\t\t\t\tdeferred.resolve();\n\t\t\t};\n\t\t\tbinReader.onload = function () {\n\t\t\t\tlet binStr, arr, i, meta;\n\t\t\t\tif ( binReader.result === null ) {\n\t\t\t\t\t// Contrary to documentation, this sometimes fires for unsuccessful loads (T136235)\n\t\t\t\t\tdeferred.resolve();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif ( typeof binReader.result === 'string' ) {\n\t\t\t\t\tbinStr = binReader.result;\n\t\t\t\t} else {\n\t\t\t\t\t// Array buffer; convert to binary string for the library.\n\t\t\t\t\t/* global Uint8Array */\n\t\t\t\t\tarr = new Uint8Array( binReader.result );\n\t\t\t\t\tbinStr = '';\n\t\t\t\t\tfor ( i = 0; i < arr.byteLength; i++ ) {\n\t\t\t\t\t\tbinStr += String.fromCharCode( arr[ i ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tjpegmeta = require( 'mediawiki.libs.jpegmeta' );\n\t\t\t\t\tmeta = jpegmeta( binStr, upload.file.fileName );\n\t\t\t\t\t// eslint-disable-next-line camelcase, no-underscore-dangle\n\t\t\t\t\tmeta._binary_data = null;\n\t\t\t\t} catch ( e ) {\n\t\t\t\t\tmeta = null;\n\t\t\t\t}\n\t\t\t\tupload.extractMetadataFromJpegMetaCallback( meta );\n\t\t\t\tdeferred.resolve();\n\t\t\t};\n\t\t\tif ( 'readAsBinaryString' in binReader ) {\n\t\t\t\tbinReader.readAsBinaryString( upload.file );\n\t\t\t} else if ( 'readAsArrayBuffer' in binReader ) {\n\t\t\t\tbinReader.readAsArrayBuffer( upload.file );\n\t\t\t}\n\t\t} else {\n\t\t\tdeferred.resolve();\n\t\t}\n\t\treturn deferred.promise();\n\t};\n\n\t/**\n\t * Map fields from jpegmeta's metadata return into our format (which is more like the imageinfo returned from the API\n\t *\n\t * @param {Object} meta As returned by jpegmeta\n\t */\n\tmw.UploadWizardUpload.prototype.extractMetadataFromJpegMetaCallback = function ( meta ) {\n\t\tlet pixelHeightDim, pixelWidthDim, degrees;\n\n\t\tif ( meta !== undefined && meta !== null && typeof meta === 'object' ) {\n\t\t\tif ( this.imageinfo.metadata === undefined ) {\n\t\t\t\tthis.imageinfo.metadata = {};\n\t\t\t}\n\t\t\tif ( meta.tiff && meta.tiff.Orientation ) {\n\t\t\t\tthis.imageinfo.metadata.orientation = meta.tiff.Orientation.value;\n\t\t\t}\n\t\t\tif ( meta.general ) {\n\t\t\t\tpixelHeightDim = 'height';\n\t\t\t\tpixelWidthDim = 'width';\n\t\t\t\t// this must be called after orientation is set above. If no orientation set, defaults to 0\n\t\t\t\tdegrees = this.getOrientationDegrees();\n\n\t\t\t\t// jpegmeta reports pixelHeight & width\n\t\t\t\tif ( degrees === 90 || degrees === 270 ) {\n\t\t\t\t\tpixelHeightDim = 'width';\n\t\t\t\t\tpixelWidthDim = 'height';\n\t\t\t\t}\n\t\t\t\tif ( meta.general.pixelHeight ) {\n\t\t\t\t\tthis.imageinfo[ pixelHeightDim ] = meta.general.pixelHeight.value;\n\t\t\t\t}\n\t\t\t\tif ( meta.general.pixelWidth ) {\n\t\t\t\t\tthis.imageinfo[ pixelWidthDim ] = meta.general.pixelWidth.value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Accept the result from a successful API upload transport, and fill our own info\n\t *\n\t * @param {Object} resultUpload The JSON object from a successful API upload result.\n\t */\n\tmw.UploadWizardUpload.prototype.extractUploadInfo = function ( resultUpload ) {\n\t\tif ( resultUpload.filekey ) {\n\t\t\tthis.fileKey = resultUpload.filekey;\n\t\t}\n\n\t\tif ( resultUpload.imageinfo ) {\n\t\t\tthis.extractImageInfo( resultUpload.imageinfo );\n\t\t} else if ( resultUpload.stashimageinfo ) {\n\t\t\tthis.extractImageInfo( resultUpload.stashimageinfo );\n\t\t}\n\n\t};\n\n\t/**\n\t * Extract image info into our upload object\n\t * Image info is obtained from various different API methods\n\t * This may overwrite metadata obtained from FileReader.\n\t *\n\t * @param {Object} imageinfo JSON object obtained from API result.\n\t */\n\tmw.UploadWizardUpload.prototype.extractImageInfo = function ( imageinfo ) {\n\t\tlet key,\n\t\t\tupload = this;\n\n\t\tfor ( key in imageinfo ) {\n\t\t\t// we get metadata as list of key-val pairs; convert to object for easier lookup. Assuming that EXIF fields are unique.\n\t\t\tif ( key === 'metadata' ) {\n\t\t\t\tif ( this.imageinfo.metadata === undefined ) {\n\t\t\t\t\tthis.imageinfo.metadata = {};\n\t\t\t\t}\n\t\t\t\tif ( imageinfo.metadata && imageinfo.metadata.length ) {\n\t\t\t\t\timageinfo.metadata.forEach( ( pair ) => {\n\t\t\t\t\t\tif ( pair !== undefined ) {\n\t\t\t\t\t\t\tupload.imageinfo.metadata[ pair.name.toLowerCase() ] = pair.value;\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.imageinfo[ key ] = imageinfo[ key ];\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Get information about stashed images\n\t *\n\t * See API documentation for prop=stashimageinfo for what 'props' can contain\n\t *\n\t * @param {Function} callback Called with null if failure, with imageinfo data structure if success\n\t * @param {Array} props Properties to extract\n\t * @param {number} [width] Width of thumbnail. Will force 'url' to be added to props\n\t * @param {number} [height] Height of thumbnail. Will force 'url' to be added to props\n\t */\n\tmw.UploadWizardUpload.prototype.getStashImageInfo = function ( callback, props, width, height ) {\n\t\tconst params = {\n\t\t\tprop: 'stashimageinfo',\n\t\t\tsiifilekey: this.fileKey,\n\t\t\tsiiprop: props.join( '|' )\n\t\t};\n\n\t\tfunction ok( data ) {\n\t\t\tif ( !data || !data.query || !data.query.stashimageinfo ) {\n\t\t\t\tmw.log.warn( 'mw.UploadWizardUpload::getStashImageInfo> No data?' );\n\t\t\t\tcallback( null );\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcallback( data.query.stashimageinfo );\n\t\t}\n\n\t\tfunction err( code ) {\n\t\t\tmw.log.warn( 'mw.UploadWizardUpload::getStashImageInfo> ' + code );\n\t\t\tcallback( null );\n\t\t}\n\n\t\tif ( props === undefined ) {\n\t\t\tprops = [];\n\t\t}\n\n\t\tif ( width !== undefined || height !== undefined ) {\n\t\t\tif ( !props.includes( 'url' ) ) {\n\t\t\t\tprops.push( 'url' );\n\t\t\t}\n\t\t\tif ( width !== undefined ) {\n\t\t\t\tparams.siiurlwidth = width;\n\t\t\t}\n\t\t\tif ( height !== undefined ) {\n\t\t\t\tparams.siiurlheight = height;\n\t\t\t}\n\t\t}\n\n\t\tthis.api.get( params ).done( ok ).fail( err );\n\t};\n\n\t/**\n\t * Get information about published images\n\t * (There is some overlap with getStashedImageInfo, but it's different at every stage so it's clearer to have separate functions)\n\t * See API documentation for prop=imageinfo for what 'props' can contain\n\t *\n\t * @param {Function} callback Called with null if failure, with imageinfo data structure if success\n\t * @param {Array} props Properties to extract\n\t * @param {number} [width] Width of thumbnail. Will force 'url' to be added to props\n\t * @param {number} [height] Height of thumbnail. Will force 'url' to be added to props\n\t */\n\tmw.UploadWizardUpload.prototype.getImageInfo = function ( callback, props, width, height ) {\n\t\tlet requestedTitle, params;\n\n\t\tfunction ok( data ) {\n\t\t\tlet found;\n\n\t\t\tif ( data && data.query && data.query.pages ) {\n\t\t\t\tfound = false;\n\t\t\t\tObject.keys( data.query.pages ).forEach( ( pageId ) => {\n\t\t\t\t\tconst page = data.query.pages[ pageId ];\n\t\t\t\t\tif ( page.title && page.title === requestedTitle && page.imageinfo ) {\n\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\tcallback( page.imageinfo );\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\tif ( found ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tmw.log.warn( 'mw.UploadWizardUpload::getImageInfo> No data matching ' + requestedTitle + ' ?' );\n\t\t\tcallback( null );\n\t\t}\n\n\t\tfunction err( code ) {\n\t\t\tmw.log.warn( 'mw.UploadWizardUpload::getImageInfo> ' + code );\n\t\t\tcallback( null );\n\t\t}\n\n\t\tif ( props === undefined ) {\n\t\t\tprops = [];\n\t\t}\n\n\t\trequestedTitle = this.title.getPrefixedText();\n\t\tparams = {\n\t\t\tprop: 'imageinfo',\n\t\t\ttitles: requestedTitle,\n\t\t\tiiprop: props.join( '|' )\n\t\t};\n\n\t\tif ( width !== undefined || height !== undefined ) {\n\t\t\tif ( !props.includes( 'url' ) ) {\n\t\t\t\tprops.push( 'url' );\n\t\t\t}\n\t\t\tif ( width !== undefined ) {\n\t\t\t\tparams.iiurlwidth = width;\n\t\t\t}\n\t\t\tif ( height !== undefined ) {\n\t\t\t\tparams.iiurlheight = height;\n\t\t\t}\n\t\t}\n\n\t\tthis.api.get( params ).done( ok ).fail( err );\n\t};\n\n\t/**\n\t * Get the upload handler per browser capabilities\n\t *\n\t * @return {mw.ApiUploadFormDataHandler} upload handler object\n\t */\n\tmw.UploadWizardUpload.prototype.getUploadHandler = function () {\n\t\tlet constructor; // must be the name of a function in 'mw' namespace\n\n\t\tif ( !this.uploadHandler ) {\n\t\t\tconstructor = 'ApiUploadFormDataHandler';\n\t\t\tthis.uploadHandler = new mw[ constructor ]( this, this.api );\n\t\t}\n\t\treturn this.uploadHandler;\n\t};\n\n\t/**\n\t * Explicitly fetch a thumbnail for a stashed upload of the desired width.\n\t *\n\t * @private\n\t * @param {number} width Desired width of thumbnail\n\t * @param {number} height Maximum height of thumbnail\n\t * @return {jQuery.Promise} Promise resolved with a HTMLImageElement, or null if thumbnail\n\t * couldn't be generated\n\t */\n\tmw.UploadWizardUpload.prototype.getApiThumbnail = function ( width, height ) {\n\t\tconst deferred = $.Deferred();\n\n\t\tfunction thumbnailPublisher( thumbnails ) {\n\t\t\tif ( thumbnails === null ) {\n\t\t\t\t// the api call failed somehow, no thumbnail data.\n\t\t\t\tdeferred.resolve( null );\n\t\t\t} else {\n\t\t\t\t// ok, the api callback has returned us information on where the thumbnail(s) ARE, but that doesn't mean\n\t\t\t\t// they are actually there yet. Keep trying to set the source ( which should trigger \"error\" or \"load\" event )\n\t\t\t\t// on the image. If it loads publish the event with the image. If it errors out too many times, give up and publish\n\t\t\t\t// the event with a null.\n\t\t\t\tthumbnails.forEach( ( thumb ) => {\n\t\t\t\t\tlet timeoutMs, image;\n\n\t\t\t\t\tif ( thumb.thumberror || ( !( thumb.thumburl && thumb.thumbwidth && thumb.thumbheight ) ) ) {\n\t\t\t\t\t\tmw.log.warn( 'mw.UploadWizardUpload::getThumbnail> Thumbnail error or missing information' );\n\t\t\t\t\t\tdeferred.resolve( null );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// executing this should cause a .load() or .error() event on the image\n\t\t\t\t\tfunction setSrc() {\n\t\t\t\t\t\t// IE 11 and Opera 12 will not, ever, re-request an image that they have already loaded\n\t\t\t\t\t\t// once, regardless of caching headers. Append bogus stuff to the URL to make it work.\n\t\t\t\t\t\timage.src = thumb.thumburl + '?' + Math.random();\n\t\t\t\t\t}\n\n\t\t\t\t\t// try to load this image with exponential backoff\n\t\t\t\t\t// if the delay goes past 8 seconds, it gives up and publishes the event with null\n\t\t\t\t\ttimeoutMs = 100;\n\t\t\t\t\timage = document.createElement( 'img' );\n\t\t\t\t\timage.width = thumb.thumbwidth;\n\t\t\t\t\timage.height = thumb.thumbheight;\n\t\t\t\t\t$( image )\n\t\t\t\t\t\t.on( 'load', () => {\n\t\t\t\t\t\t\t// publish the image to anyone who wanted it\n\t\t\t\t\t\t\tdeferred.resolve( image );\n\t\t\t\t\t\t} )\n\t\t\t\t\t\t.on( 'error', () => {\n\t\t\t\t\t\t\t// retry with exponential backoff\n\t\t\t\t\t\t\tif ( timeoutMs < 8000 ) {\n\t\t\t\t\t\t\t\tsetTimeout( () => {\n\t\t\t\t\t\t\t\t\ttimeoutMs = timeoutMs * 2 + Math.round( Math.random() * ( timeoutMs / 10 ) );\n\t\t\t\t\t\t\t\t\tsetSrc();\n\t\t\t\t\t\t\t\t}, timeoutMs );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tdeferred.resolve( null );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t// and, go!\n\t\t\t\t\tsetSrc();\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\n\t\tif ( this.state !== 'complete' ) {\n\t\t\tthis.getStashImageInfo( thumbnailPublisher, [ 'url' ], width, height );\n\t\t} else {\n\t\t\tthis.getImageInfo( thumbnailPublisher, [ 'url' ], width, height );\n\t\t}\n\n\t\treturn deferred.promise();\n\t};\n\n\t/**\n\t * Return the orientation of the image in degrees. Relies on metadata that\n\t * may have been extracted at filereader stage, or after the upload when we fetch metadata. Default returns 0.\n\t *\n\t * @return {number} orientation in degrees: 0, 90, 180 or 270\n\t */\n\tmw.UploadWizardUpload.prototype.getOrientationDegrees = function () {\n\t\tlet orientation = 0;\n\t\tif ( this.imageinfo && this.imageinfo.metadata && this.imageinfo.metadata.orientation ) {\n\t\t\tswitch ( this.imageinfo.metadata.orientation ) {\n\t\t\t\tcase 8:\n\t\t\t\t\t// 'top left' -> 'left bottom'\n\t\t\t\t\torientation = 90;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 3:\n\t\t\t\t\t// 'top left' -> 'bottom right'\n\t\t\t\t\torientation = 180;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 6:\n\t\t\t\t\t// 'top left' -> 'right top'\n\t\t\t\t\torientation = 270;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t// 'top left' -> 'top left'\n\t\t\t\t\torientation = 0;\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\t\t}\n\t\treturn orientation;\n\t};\n\n\t/**\n\t * Fit an image into width & height constraints with scaling factor\n\t *\n\t * @private\n\t * @param {HTMLImageElement} image\n\t * @param {Object} constraints Width & height properties\n\t * @return {number}\n\t */\n\tmw.UploadWizardUpload.prototype.getScalingFromConstraints = function ( image, constraints ) {\n\t\tlet scaling = 1;\n\t\tObject.keys( constraints ).forEach( ( dim ) => {\n\t\t\tlet s,\n\t\t\t\tconstraint = constraints[ dim ];\n\t\t\tif ( constraint && image[ dim ] > constraint ) {\n\t\t\t\ts = constraint / image[ dim ];\n\t\t\t\tif ( s < scaling ) {\n\t\t\t\t\tscaling = s;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t\treturn scaling;\n\t};\n\n\t/**\n\t * Given an image (already loaded), dimension constraints\n\t * return canvas object scaled & transformed ( & rotated if metadata indicates it's needed )\n\t *\n\t * @private\n\t * @param {HTMLImageElement} image\n\t * @param {Object} constraints Width & height constraints\n\t * @return {HTMLCanvasElement|null}\n\t */\n\tmw.UploadWizardUpload.prototype.getTransformedCanvasElement = function ( image, constraints ) {\n\t\tlet angle, scaling, width, height,\n\t\t\tdimensions, dx, dy, x, y, $canvas, ctx,\n\t\t\tscaleConstraints = constraints,\n\t\t\trotation = 0;\n\n\t\t// if this wiki can rotate images to match their EXIF metadata,\n\t\t// we should do the same in our preview\n\t\tif ( mw.config.get( 'wgFileCanRotate' ) ) {\n\t\t\tangle = this.getOrientationDegrees();\n\t\t\trotation = angle ? 360 - angle : 0;\n\t\t}\n\n\t\t// swap scaling constraints if needed by rotation...\n\t\tif ( rotation === 90 || rotation === 270 ) {\n\t\t\tscaleConstraints = {};\n\t\t\tif ( 'height' in constraints ) {\n\t\t\t\tscaleConstraints.width = constraints.height;\n\t\t\t}\n\t\t\tif ( 'width' in constraints ) {\n\t\t\t\tscaleConstraints.height = constraints.width;\n\t\t\t}\n\t\t}\n\n\t\tscaling = this.getScalingFromConstraints( image, scaleConstraints );\n\n\t\twidth = image.width * scaling;\n\t\theight = image.height * scaling;\n\n\t\tdimensions = { width: width, height: height };\n\t\tif ( rotation === 90 || rotation === 270 ) {\n\t\t\tdimensions = { width: height, height: width };\n\t\t}\n\n\t\t// Start drawing at offset 0,0\n\t\tdx = 0;\n\t\tdy = 0;\n\n\t\tswitch ( rotation ) {\n\t\t\t// If a rotation is applied, the direction of the axis\n\t\t\t// changes as well. You can derive the values below by\n\t\t\t// drawing on paper an axis system, rotate it and see\n\t\t\t// where the positive axis direction is\n\t\t\tcase 90:\n\t\t\t\tx = dx;\n\t\t\t\ty = dy - height;\n\t\t\t\tbreak;\n\t\t\tcase 180:\n\t\t\t\tx = dx - width;\n\t\t\t\ty = dy - height;\n\t\t\t\tbreak;\n\t\t\tcase 270:\n\t\t\t\tx = dx - width;\n\t\t\t\ty = dy;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tx = dx;\n\t\t\t\ty = dy;\n\t\t\t\tbreak;\n\t\t}\n\n\t\t$canvas = $( '<canvas>' ).attr( dimensions );\n\t\tctx = $canvas[ 0 ].getContext( '2d' );\n\t\tctx.clearRect( dx, dy, width, height );\n\t\tctx.rotate( rotation / 180 * Math.PI );\n\t\ttry {\n\t\t\t// Calling #drawImage likes to throw all kinds of ridiculous exceptions in various browsers,\n\t\t\t// including but not limited to:\n\t\t\t// * (Firefox) NS_ERROR_NOT_AVAILABLE:\n\t\t\t// * (Internet Explorer / Edge) Not enough storage is available to complete this operation.\n\t\t\t// * (Internet Explorer / Edge) Unspecified error.\n\t\t\t// * (Internet Explorer / Edge) The GPU device instance has been suspended. Use GetDeviceRemovedReason to determine the appropriate action.\n\t\t\t// * (Safari) IndexSizeError: Index or size was negative, or greater than the allowed value.\n\t\t\t// There is nothing we can do about this. It's okay though, there just won't be a thumbnail.\n\t\t\tctx.drawImage( image, x, y, width, height );\n\t\t} catch ( err ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn $canvas;\n\t};\n\n\t/**\n\t * Return a browser-scaled image element, given an image and constraints.\n\t *\n\t * @private\n\t * @param {HTMLImageElement} image\n\t * @param {Object} constraints Width and height properties\n\t * @return {HTMLImageElement} with same src, but different attrs\n\t */\n\tmw.UploadWizardUpload.prototype.getBrowserScaledImageElement = function ( image, constraints ) {\n\t\tconst scaling = this.getScalingFromConstraints( image, constraints );\n\t\treturn $( '<img>' )\n\t\t\t.attr( {\n\t\t\t\twidth: parseInt( image.width * scaling, 10 ),\n\t\t\t\theight: parseInt( image.height * scaling, 10 ),\n\t\t\t\tsrc: image.src\n\t\t\t} );\n\t};\n\n\t/**\n\t * Return an element suitable for the preview of a certain size. Uses canvas when possible\n\t *\n\t * @private\n\t * @param {HTMLImageElement} image\n\t * @param {number} width\n\t * @param {number} height\n\t * @return {HTMLCanvasElement|HTMLImageElement}\n\t */\n\tmw.UploadWizardUpload.prototype.getScaledImageElement = function ( image, width, height ) {\n\t\tlet constraints = {},\n\t\t\ttransform;\n\n\t\tif ( width ) {\n\t\t\tconstraints.width = width;\n\t\t}\n\t\tif ( height ) {\n\t\t\tconstraints.height = height;\n\t\t}\n\n\t\tif ( mw.canvas.isAvailable() ) {\n\t\t\ttransform = this.getTransformedCanvasElement( image, constraints );\n\t\t\tif ( transform ) {\n\t\t\t\treturn transform;\n\t\t\t}\n\t\t}\n\n\t\t// No canvas support or canvas drawing failed mysteriously, fall back\n\t\treturn this.getBrowserScaledImageElement( image, constraints );\n\t};\n\n\t/**\n\t * Acquire a thumbnail for this upload.\n\t *\n\t * @param {number} width\n\t * @param {number} height\n\t * @return {jQuery.Promise} Promise resolved with the HTMLImageElement or HTMLCanvasElement\n\t * containing a thumbnail, or resolved with `null` when one can't be produced\n\t */\n\tmw.UploadWizardUpload.prototype.getThumbnail = function ( width, height ) {\n\t\tconst upload = this,\n\t\t\tdeferred = $.Deferred();\n\n\t\tif ( this.thumbnailPromise[ width + 'x' + height ] ) {\n\t\t\treturn this.thumbnailPromise[ width + 'x' + height ];\n\t\t}\n\t\tthis.thumbnailPromise[ width + 'x' + height ] = deferred.promise();\n\n\t\t/**\n\t\t * @param {HTMLImageElement|null} image\n\t\t */\n\t\tfunction imageCallback( image ) {\n\t\t\tif ( image === null ) {\n\t\t\t\tupload.ui.setStatus( 'mediauploader-thumbnail-failed' );\n\t\t\t\tdeferred.resolve( image );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\timage = upload.getScaledImageElement( image, width, height );\n\t\t\tdeferred.resolve( image );\n\t\t}\n\n\t\tthis.extractMetadataFromJpegMeta()\n\t\t\t.then( upload.makePreview.bind( upload, width ) )\n\t\t\t.done( imageCallback )\n\t\t\t.fail( () => {\n\t\t\t\t// Can't generate the thumbnail locally, get the thumbnail via API after\n\t\t\t\t// the file is uploaded. Queries are cached, so if this thumbnail was\n\t\t\t\t// already fetched for some reason, we'll get it immediately.\n\t\t\t\tif ( upload.state !== 'new' && upload.state !== 'transporting' && upload.state !== 'error' ) {\n\t\t\t\t\tupload.getApiThumbnail( width, height ).done( imageCallback );\n\t\t\t\t} else {\n\t\t\t\t\tupload.once( 'success', () => {\n\t\t\t\t\t\tupload.getApiThumbnail( width, height ).done( imageCallback );\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t} );\n\n\t\treturn this.thumbnailPromise[ width + 'x' + height ];\n\t};\n\n\t/**\n\t * Notification that the file input has changed and it's fine...set info.\n\t */\n\tmw.UploadWizardUpload.prototype.fileChangedOk = function () {\n\t\tthis.ui.fileChangedOk( this.imageinfo, this.file );\n\t};\n\n\t/**\n\t * Make a preview for the file.\n\t *\n\t * @private\n\t * @param {number} width\n\t * @return {jQuery.Promise}\n\t */\n\tmw.UploadWizardUpload.prototype.makePreview = function ( width ) {\n\t\tlet first, video, url, dataUrlReader,\n\t\t\tdeferred = $.Deferred(),\n\t\t\tupload = this;\n\n\t\t// do preview if we can\n\t\tif ( this.isPreviewable() ) {\n\t\t\t// open video and get frame via canvas\n\t\t\tif ( this.isVideo() ) {\n\t\t\t\tfirst = true;\n\t\t\t\tvideo = document.createElement( 'video' );\n\n\t\t\t\tvideo.addEventListener( 'loadedmetadata', () => {\n\t\t\t\t\t// seek 2 seconds into video or to half if shorter\n\t\t\t\t\tvideo.currentTime = Math.min( 2, video.duration / 2 );\n\t\t\t\t\tvideo.volume = 0;\n\t\t\t\t} );\n\t\t\t\tvideo.addEventListener( 'seeked', () => {\n\t\t\t\t\t// Firefox 16 sometimes does not work on first seek, seek again\n\t\t\t\t\tif ( first ) {\n\t\t\t\t\t\tfirst = false;\n\t\t\t\t\t\tvideo.currentTime = Math.min( 2, video.duration / 2 );\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Chrome sometimes shows black frames if grabbing right away.\n\t\t\t\t\t\t// wait 500ms before grabbing frame\n\t\t\t\t\t\tsetTimeout( () => {\n\t\t\t\t\t\t\tlet context,\n\t\t\t\t\t\t\t\tcanvas = document.createElement( 'canvas' );\n\t\t\t\t\t\t\tcanvas.width = width;\n\t\t\t\t\t\t\tcanvas.height = Math.round( canvas.width * video.videoHeight / video.videoWidth );\n\t\t\t\t\t\t\tcontext = canvas.getContext( '2d' );\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t// More ridiculous exceptions, see the comment in #getTransformedCanvasElement\n\t\t\t\t\t\t\t\tcontext.drawImage( video, 0, 0, canvas.width, canvas.height );\n\t\t\t\t\t\t\t} catch ( err ) {\n\t\t\t\t\t\t\t\tdeferred.reject();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tupload.loadImage( canvas.toDataURL(), deferred );\n\t\t\t\t\t\t\tupload.URL().revokeObjectURL( video.url );\n\t\t\t\t\t\t}, 500 );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\turl = this.URL().createObjectURL( this.file );\n\t\t\t\tvideo.src = url;\n\t\t\t\t// If we can't get a frame within 10 seconds, something is probably seriously wrong.\n\t\t\t\t// This can happen for broken files where we can't actually seek to the time we wanted.\n\t\t\t\tsetTimeout( () => {\n\t\t\t\t\tdeferred.reject();\n\t\t\t\t\tupload.URL().revokeObjectURL( video.url );\n\t\t\t\t}, 10000 );\n\t\t\t} else {\n\t\t\t\tdataUrlReader = new FileReader();\n\t\t\t\tdataUrlReader.onload = function () {\n\t\t\t\t\t// this step (inserting image-as-dataurl into image object) is slow for large images, which\n\t\t\t\t\t// is why this is optional and has a control attached to it to load the preview.\n\t\t\t\t\tupload.loadImage( dataUrlReader.result, deferred );\n\t\t\t\t};\n\t\t\t\tdataUrlReader.readAsDataURL( this.file );\n\t\t\t}\n\t\t} else {\n\t\t\tdeferred.reject();\n\t\t}\n\n\t\treturn deferred.promise();\n\t};\n\n\t/**\n\t * Loads an image preview.\n\t *\n\t * @param {string} url\n\t * @param {jQuery.Deferred} deferred\n\t */\n\tmw.UploadWizardUpload.prototype.loadImage = function ( url, deferred ) {\n\t\tconst image = document.createElement( 'img' );\n\t\timage.onload = function () {\n\t\t\tdeferred.resolve( image );\n\t\t};\n\t\timage.onerror = function () {\n\t\t\tdeferred.reject();\n\t\t};\n\t\ttry {\n\t\t\timage.src = url;\n\t\t} catch ( er ) {\n\t\t\t// On Internet Explorer 11 and Edge, this occasionally causes an exception (possibly\n\t\t\t// localised) like \"Not enough storage is available to complete this operation\". (T136239)\n\t\t\tdeferred.reject();\n\t\t}\n\t};\n\n\t/**\n\t * Check if the file is previewable.\n\t *\n\t * @return {boolean}\n\t */\n\tmw.UploadWizardUpload.prototype.isPreviewable = function () {\n\t\treturn this.file && mw.fileApi.isPreviewableFile( this.file );\n\t};\n\n\t/**\n\t * Finds the right URL object to use.\n\t *\n\t * @return {URL}\n\t */\n\tmw.UploadWizardUpload.prototype.URL = function () {\n\t\t// This functionality is missing on IE 11\n\t\treturn window.URL || window.webkitURL || window.mozURL;\n\t};\n\n\t/**\n\t * Checks if this upload is a video.\n\t *\n\t * @return {boolean}\n\t */\n\tmw.UploadWizardUpload.prototype.isVideo = function () {\n\t\treturn mw.fileApi.isPreviewableVideo( this.file );\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/mw.UploadWizardUploadInterface.js","messages":[{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":206,"column":3,"nodeType":"CallExpression","endLine":209,"endColumn":6}],"suppressedMessages":[{"ruleId":"mediawiki/msg-doc","severity":1,"message":"All possible message keys should be documented. See https://w.wiki/4r9a for details.","line":101,"column":3,"nodeType":"CallExpression","endLine":101,"endColumn":36,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":1,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"( function ( uw ) {\n\t/**\n\t * Create an interface fragment corresponding to a file input, suitable for Upload Wizard.\n\t *\n\t * @class mw.UploadWizardUploadInterface\n\t * @constructor\n\t * @param {mw.UploadWizardUpload} upload\n\t */\n\tmw.UploadWizardUploadInterface = function MWUploadWizardUploadInterface( upload ) {\n\t\tconst ui = this;\n\n\t\tOO.EventEmitter.call( this );\n\n\t\tthis.upload = upload;\n\n\t\t// May need to collaborate with the particular upload type sometimes\n\t\t// for the interface, as well as the uploadwizard. OY.\n\t\tthis.$div = $( '<div>' ).addClass( 'mediauploader-file' );\n\n\t\tthis.isFilled = false;\n\n\t\tthis.statusMessage = new OO.ui.MessageWidget( { inline: true } );\n\t\tthis.statusMessage.toggle( false );\n\t\tthis.$spinner = $.createSpinner( { size: 'small', type: 'inline' } );\n\t\tthis.$spinner.hide();\n\t\tthis.$indicator = $( '<div>' ).addClass( 'mediauploader-file-indicator' ).append(\n\t\t\tthis.$spinner,\n\t\t\tthis.statusMessage.$element\n\t\t);\n\n\t\tthis.$visibleFilenameDiv = $( '<div>' ).addClass( 'mediauploader-visible-file' ).append(\n\t\t\tthis.$indicator,\n\t\t\t$( '<div>' ).addClass( 'mediauploader-visible-file-filename' ).append(\n\t\t\t\t$( '<div>' ).addClass( 'mediauploader-file-preview' ),\n\t\t\t\t$( '<div>' ).addClass( 'mediauploader-file-texts' ).append(\n\t\t\t\t\t$( '<div>' ).addClass( 'mediauploader-visible-file-filename-text' ),\n\t\t\t\t\t$( '<div>' ).addClass( 'mediauploader-file-status-line' ).append(\n\t\t\t\t\t\t$( '<div>' ).addClass( 'mediauploader-file-status' )\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\n\t\tthis.removeCtrl = new OO.ui.ButtonWidget( {\n\t\t\tlabel: mw.message( 'mediauploader-remove' ).text(),\n\t\t\ttitle: mw.message( 'mediauploader-remove-upload' ).text(),\n\t\t\tflags: 'destructive',\n\t\t\ticon: 'trash',\n\t\t\tframed: false\n\t\t} ).on( 'click', () => {\n\t\t\tui.emit( 'upload-removed' );\n\t\t} );\n\n\t\tthis.$visibleFilenameDiv.find( '.mediauploader-file-status-line' )\n\t\t\t.append( this.removeCtrl.$element );\n\n\t\tthis.$form = $( '<form>' )\n\t\t\t.addClass( 'mediauploader-form' )\n\t\t\t.append( this.$visibleFilenameDiv );\n\n\t\tthis.$div.append( this.$form );\n\n\t\t// this.progressBar = ( no progress bar for individual uploads yet )\n\t\t// we bind to the ui div since .off() doesn't work for non-DOM objects\n\t\t// TODO Convert this to an OO.EventEmitter, and use OOjs events\n\t\tthis.$div.on( 'transportProgressEvent', () => {\n\t\t\tui.showTransportProgress();\n\t\t} );\n\t};\n\n\tOO.mixinClass( mw.UploadWizardUploadInterface, OO.EventEmitter );\n\n\t/**\n\t * Change the graphic indicator at the far end of the row for this file\n\t *\n\t * @param {string} [status] Either a OO.ui.MessageWidget type (error/success/...) or 'progress'.\n\t * Omit to hide the indicator\n\t */\n\tmw.UploadWizardUploadInterface.prototype.showIndicator = function ( status ) {\n\t\tthis.$spinner.hide();\n\t\tthis.statusMessage.toggle( false );\n\n\t\tif ( status === 'progress' ) {\n\t\t\tthis.$spinner.show();\n\t\t} else if ( status ) {\n\t\t\tthis.statusMessage.toggle( true ).setType( status );\n\t\t}\n\t\tthis.$indicator.toggleClass( 'mediauploader-file-indicator-visible', !!status );\n\t};\n\n\t/**\n\t * Set the status line for this upload with an internationalized message string.\n\t *\n\t * @param {string} msgKey Key for the message\n\t * @param {Array} [args] Array of values, in case any need to be fed to the image.\n\t */\n\tmw.UploadWizardUploadInterface.prototype.setStatus = function ( msgKey, args ) {\n\t\t// get the status line for our upload\n\t\tconst $status = this.$div.find( '.mediauploader-file-status' );\n\t\t// eslint-disable-next-line mediawiki/msg-doc\n\t\t$status.msg( msgKey, args || [] ).show();\n\t};\n\n\t/**\n\t * Set status line directly with a string\n\t *\n\t * @param {string} html\n\t */\n\tmw.UploadWizardUploadInterface.prototype.setStatusString = function ( html ) {\n\t\tthis.$div.find( '.mediauploader-file-status' ).html( html ).show();\n\t};\n\n\t/**\n\t * Set additional status information\n\t *\n\t * @param {jQuery} [$status] If not given or null, additional status is cleared\n\t */\n\tmw.UploadWizardUploadInterface.prototype.setAdditionalStatus = function ( $status ) {\n\t\tif ( this.$additionalStatus ) {\n\t\t\tthis.$additionalStatus.remove();\n\t\t}\n\t\tthis.$additionalStatus = $status;\n\t\tif ( this.$additionalStatus ) {\n\t\t\tthis.$div.find( '.mediauploader-file-status' ).after( this.$additionalStatus );\n\t\t}\n\t};\n\n\t/**\n\t * Clear the status line for this upload (hide it, in case there are paddings and such which offset other things.)\n\t */\n\tmw.UploadWizardUploadInterface.prototype.clearStatus = function () {\n\t\tthis.$div.find( '.mediauploader-file-status' ).hide();\n\t\tthis.setAdditionalStatus( null );\n\t};\n\n\t/**\n\t * Put the visual state of an individual upload into \"progress\"\n\t *\n\t * @param {number} fraction The fraction of progress. Float between 0 and 1\n\t */\n\tmw.UploadWizardUploadInterface.prototype.showTransportProgress = function () {\n\t\t// if fraction available, update individual progress bar / estimates, etc.\n\t\tthis.showIndicator( 'progress' );\n\t\tthis.setStatus( 'mediauploader-uploading' );\n\t\tthis.setAdditionalStatus( null );\n\t};\n\n\t/**\n\t * Show that upload is transported\n\t */\n\tmw.UploadWizardUploadInterface.prototype.showStashed = function () {\n\t\tthis.showIndicator( 'success' );\n\t\tthis.setStatus( 'mediauploader-stashed-upload' );\n\t\tthis.setAdditionalStatus( null );\n\t};\n\n\t/**\n\t * Show that transport has failed\n\t *\n\t * @param {string} code Error code from API\n\t * @param {string} html Error message\n\t * @param {jQuery} [$additionalStatus]\n\t */\n\tmw.UploadWizardUploadInterface.prototype.showError = function ( code, html, $additionalStatus ) {\n\t\tthis.showIndicator( 'error' );\n\t\tthis.setStatusString( html );\n\t\tthis.setAdditionalStatus( $additionalStatus );\n\t};\n\n\t/**\n\t * Run this when the value of the file input has changed and we know it's acceptable -- this\n\t * will update interface to show as much info as possible, including preview.\n\t * n.b. in older browsers we only will know the filename\n\t *\n\t * @param {Object} imageinfo\n\t * @param {File} file\n\t */\n\tmw.UploadWizardUploadInterface.prototype.fileChangedOk = function ( imageinfo, file ) {\n\t\tconst statusItems = [];\n\n\t\tthis.updateFilename();\n\n\t\t// set the status string - e.g. \"256 Kb, 100 x 200\"\n\t\tif ( imageinfo && imageinfo.width && imageinfo.height ) {\n\t\t\tstatusItems.push( imageinfo.width + '\\u00d7' + imageinfo.height );\n\t\t}\n\n\t\tif ( file && file.size ) {\n\t\t\tstatusItems.push( uw.units.bytes( file.size ) );\n\t\t}\n\n\t\tthis.clearStatus();\n\t\tthis.setStatusString( statusItems.join( ' \\u00b7 ' ) );\n\t};\n\n\t/**\n\t * Display thumbnail preview.\n\t *\n\t * @return {jQuery.Promise} Promise resolved when the thumbnail is displayed or when displaying it\n\t * fails\n\t */\n\tmw.UploadWizardUploadInterface.prototype.showThumbnail = function () {\n\t\tconst $preview = this.$div.find( '.mediauploader-file-preview' ),\n\t\t\tdeferred = $.Deferred();\n\t\t// This must match the CSS dimensions of .mediauploader-file-preview\n\t\tthis.upload.getThumbnail( 120, 120 ).done( ( thumb ) => {\n\t\t\tmw.UploadWizard.placeThumbnail( $preview, thumb );\n\t\t\tdeferred.resolve();\n\t\t} );\n\t\treturn deferred.promise();\n\t};\n\n\t/**\n\t * this does two things:\n\t * 1 ) since the file input has been hidden with some clever CSS ( to avoid x-browser styling issues ),\n\t * update the visible filename\n\t *\n\t * 2 ) update the underlying \"title\" which we are targeting to add to mediawiki.\n\t * TODO silently fix to have unique filename? unnecessary at this point...\n\t */\n\tmw.UploadWizardUploadInterface.prototype.updateFilename = function () {\n\t\tconst path = this.upload.getFilename();\n\n\t\t// visible filename\n\t\tthis.$form.find( '.mediauploader-visible-file-filename-text' )\n\t\t\t.text( path );\n\n\t\tif ( !this.isFilled ) {\n\t\t\tthis.isFilled = true;\n\t\t\tthis.$div.addClass( 'filled' );\n\t\t}\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/mw.canvas.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-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/resources/mw.errorDialog.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-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/resources/mw.fileApi.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-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/resources/transports/mw.FormDataTransport.js","messages":[{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":97,"column":3,"nodeType":"MemberExpression","messageId":"forbidden","endLine":97,"endColumn":16},{"ruleId":"prefer-const","severity":2,"message":"'deferred' is never reassigned. Use 'const' instead.","line":156,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":156,"endColumn":12},{"ruleId":"prefer-const","severity":2,"message":"'fileSize' is never reassigned. Use 'const' instead.","line":157,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":157,"endColumn":12},{"ruleId":"prefer-const","severity":2,"message":"'chunkSize' is never reassigned. Use 'const' instead.","line":158,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":158,"endColumn":13},{"ruleId":"prefer-const","severity":2,"message":"'transport' is never reassigned. Use 'const' instead.","line":159,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":159,"endColumn":13},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":169,"column":5,"nodeType":"CallExpression","endLine":178,"endColumn":8},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":170,"column":6,"nodeType":"CallExpression","endLine":171,"endColumn":67},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .fail","line":170,"column":6,"nodeType":"CallExpression","endLine":172,"endColumn":31},{"ruleId":"prefer-const","severity":2,"message":"'params' is never reassigned. Use 'const' instead.","line":194,"column":7,"nodeType":"Identifier","messageId":"useConst","endLine":194,"endColumn":13},{"ruleId":"prefer-const","severity":2,"message":"'transport' is never reassigned. Use 'const' instead.","line":195,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":195,"endColumn":13},{"ruleId":"prefer-const","severity":2,"message":"'bytesAvailable' is never reassigned. Use 'const' instead.","line":196,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":196,"endColumn":18}],"suppressedMessages":[{"ruleId":"no-loop-func","severity":2,"message":"Function declared in a loop contains unsafe references to variable(s) 'prevPromise', 'prevPromise'.","line":164,"column":6,"nodeType":"FunctionExpression","messageId":"unsafeRefs","endLine":180,"endColumn":5,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":10,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"( function () {\n\t/**\n\t * Represents a \"transport\" for files to upload; using HTML5 FormData.\n\t *\n\t * @constructor\n\t * @class mw.FormDataTransport\n\t * @param {mw.Api} api\n\t * @param {Object} formData Additional form fields required for upload api call\n\t * @param {Object} [config]\n\t * @param {Object} [config.chunkSize]\n\t * @param {Object} [config.maxPhpUploadSize]\n\t * @param {Object} [config.useRetryTimeout]\n\t */\n\tmw.FormDataTransport = function ( api, formData, config ) {\n\t\tthis.config = config || mw.UploadWizard.config;\n\n\t\tOO.EventEmitter.call( this );\n\n\t\tthis.formData = formData;\n\t\tthis.aborted = false;\n\t\tthis.api = api;\n\n\t\t// Set chunk size to configured chunk size or max php size,\n\t\t// whichever is smaller.\n\t\tthis.chunkSize = Math.min( this.config.chunkSize, this.config.maxPhpUploadSize );\n\t\tthis.maxRetries = 2;\n\t\tthis.retries = 0;\n\t\tthis.firstPoll = false;\n\n\t\t// running API request\n\t\tthis.request = null;\n\t};\n\n\tOO.mixinClass( mw.FormDataTransport, OO.EventEmitter );\n\n\tmw.FormDataTransport.prototype.abort = function () {\n\t\tthis.aborted = true;\n\n\t\tif ( this.request ) {\n\t\t\tthis.request.abort();\n\t\t}\n\t};\n\n\t/**\n\t * Submits an upload to the API.\n\t *\n\t * @param {Object} params Request params\n\t * @return {jQuery.Promise}\n\t */\n\tmw.FormDataTransport.prototype.post = function ( params ) {\n\t\tconst deferred = $.Deferred();\n\n\t\tthis.request = this.api.post( params, {\n\t\t\t/*\n\t\t\t * $.ajax is not quite equiped to handle File uploads with params.\n\t\t\t * The most convenient way would be to submit it with a FormData\n\t\t\t * object, but mw.Api will already do that for us: it'll transform\n\t\t\t * params if it encounters a multipart/form-data POST request, and\n\t\t\t * submit it accordingly!\n\t\t\t *\n\t\t\t * @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Submitting_forms_and_uploading_files\n\t\t\t */\n\t\t\tcontentType: 'multipart/form-data',\n\t\t\t/*\n\t\t\t * $.ajax also has no progress event that will allow us to figure\n\t\t\t * out how much of the upload has already gone out, so let's add it!\n\t\t\t */\n\t\t\txhr: function () {\n\t\t\t\tconst xhr = $.ajaxSettings.xhr();\n\t\t\t\txhr.upload.addEventListener( 'progress', ( evt ) => {\n\t\t\t\t\tlet fraction = null;\n\t\t\t\t\tif ( evt.lengthComputable ) {\n\t\t\t\t\t\tfraction = parseFloat( evt.loaded / evt.total );\n\t\t\t\t\t}\n\t\t\t\t\tdeferred.notify( fraction );\n\t\t\t\t}, false );\n\t\t\t\treturn xhr;\n\t\t\t}\n\t\t} );\n\n\t\t// just pass on success & failures\n\t\tthis.request.then( deferred.resolve, deferred.reject );\n\n\t\treturn deferred.promise();\n\t};\n\n\t/**\n\t * Creates the upload API params.\n\t *\n\t * @param {string} filename\n\t * @param {number} [offset] For chunked uploads\n\t * @return {Object}\n\t */\n\tmw.FormDataTransport.prototype.createParams = function ( filename, offset ) {\n\t\tconst params = OO.cloneObject( this.formData );\n\n\t\tObject.assign( params, {\n\t\t\tfilename: filename,\n\n\t\t\t// ignorewarnings is turned on, since warnings are presented in a\n\t\t\t// later step and this transport doesn't know how to deal with them.\n\t\t\t// Also, it's important to allow people to upload files with (for\n\t\t\t// example) blacklisted names, and then rename them later in the\n\t\t\t// wizard.\n\t\t\tignorewarnings: true,\n\n\t\t\toffset: offset || 0\n\t\t} );\n\n\t\treturn params;\n\t};\n\n\t/**\n\t * Start the upload with the provided file.\n\t *\n\t * @param {File} file\n\t * @param {string} tempFileName\n\t * @return {jQuery.Promise}\n\t */\n\tmw.FormDataTransport.prototype.upload = function ( file, tempFileName ) {\n\t\tlet params, ext;\n\n\t\tthis.tempname = tempFileName;\n\t\t// Limit length to 240 bytes (limit hardcoded in UploadBase.php).\n\t\tif ( this.tempname.length > 240 ) {\n\t\t\text = this.tempname.split( '.' ).pop();\n\t\t\tthis.tempname = this.tempname.slice( 0, Math.max( 0, 240 - ext.length - 1 ) ) + '.' + ext;\n\t\t}\n\n\t\tif ( file.size > this.chunkSize ) {\n\t\t\treturn this.chunkedUpload( file );\n\t\t} else {\n\t\t\tparams = this.createParams( this.tempname );\n\t\t\tparams.file = file;\n\t\t\treturn this.post( params );\n\t\t}\n\t};\n\n\t/**\n\t * This function exists to safely chain several hundred promises without using .then() or nested\n\t * promises. We might divide a 4 GB file into 800 chunks of 5 MB each.\n\t *\n\t * In jQuery 2.x, nested promises result in nested call stacks when resolving/rejecting/notifying\n\t * the last promise in the chain and listening on the first one, and browsers have call stack\n\t * limits low enough that we previously ran into them for files around a couple hundred megabytes\n\t * (the worst is Firefox 47 with a limit of 1024 calls).\n\t *\n\t * @param {File} file\n\t * @return {jQuery.Promise} Promise which behaves identically to a regular non-chunked upload\n\t * promise from #upload\n\t */\n\tmw.FormDataTransport.prototype.chunkedUpload = function ( file ) {\n\t\tlet\n\t\t\toffset,\n\t\t\tprevPromise = $.Deferred().resolve(),\n\t\t\tdeferred = $.Deferred(),\n\t\t\tfileSize = file.size,\n\t\t\tchunkSize = this.chunkSize,\n\t\t\ttransport = this;\n\n\t\tfor ( offset = 0; offset < fileSize; offset += chunkSize ) {\n\t\t\t// Capture offset in a closure\n\t\t\t// eslint-disable-next-line no-loop-func\n\t\t\t( function ( offset2 ) {\n\t\t\t\tconst\n\t\t\t\t\tnewPromise = $.Deferred(),\n\t\t\t\t\tisLastChunk = offset2 + chunkSize >= fileSize,\n\t\t\t\t\tthisChunkSize = isLastChunk ? ( fileSize % chunkSize ) : chunkSize;\n\t\t\t\tprevPromise.done( () => {\n\t\t\t\t\ttransport.uploadChunk( file, offset2 )\n\t\t\t\t\t\t.done( isLastChunk ? deferred.resolve : newPromise.resolve )\n\t\t\t\t\t\t.fail( deferred.reject )\n\t\t\t\t\t\t.progress( ( fraction ) => {\n\t\t\t\t\t\t\t// The progress notifications give us per-chunk progress.\n\t\t\t\t\t\t\t// Calculate progress for the whole file.\n\t\t\t\t\t\t\tdeferred.notify( ( offset2 + fraction * thisChunkSize ) / fileSize );\n\t\t\t\t\t\t} );\n\t\t\t\t} );\n\t\t\t\tprevPromise = newPromise;\n\t\t\t}( offset ) );\n\t\t}\n\n\t\treturn deferred.promise();\n\t};\n\n\t/**\n\t * Upload a single chunk.\n\t *\n\t * @param {File} file\n\t * @param {number} offset Offset in bytes.\n\t * @return {jQuery.Promise}\n\t */\n\tmw.FormDataTransport.prototype.uploadChunk = function ( file, offset ) {\n\t\tlet params = this.createParams( this.tempname, offset ),\n\t\t\ttransport = this,\n\t\t\tbytesAvailable = file.size,\n\t\t\tchunk;\n\n\t\tif ( this.aborted ) {\n\t\t\treturn $.Deferred().reject( 'aborted', {\n\t\t\t\terrors: [ {\n\t\t\t\t\tcode: 'aborted',\n\t\t\t\t\thtml: mw.message( 'mediauploader-api-error-aborted' ).parse()\n\t\t\t\t} ]\n\t\t\t} );\n\t\t}\n\n\t\t// Slice API was changed and has vendor prefix for now\n\t\t// new version now require start/end and not start/length\n\t\tif ( file.mozSlice ) {\n\t\t\tchunk = file.mozSlice( offset, offset + this.chunkSize, file.type );\n\t\t} else if ( file.webkitSlice ) {\n\t\t\tchunk = file.webkitSlice( offset, offset + this.chunkSize, file.type );\n\t\t} else {\n\t\t\tchunk = file.slice( offset, offset + this.chunkSize, file.type );\n\t\t}\n\n\t\t// only enable async if file is larger 10Mb\n\t\tif ( bytesAvailable > 10 * 1024 * 1024 ) {\n\t\t\tparams.async = true;\n\t\t}\n\n\t\t// If offset is 0, we're uploading the file from scratch. filekey may be set if we're retrying\n\t\t// the first chunk. The API errors out if a filekey is given with zero offset (as it's\n\t\t// nonsensical). TODO Why do we need to retry in this case, if we managed to upload something?\n\t\tif ( this.filekey && offset !== 0 ) {\n\t\t\tparams.filekey = this.filekey;\n\t\t}\n\t\tparams.filesize = bytesAvailable;\n\t\tparams.chunk = chunk;\n\n\t\treturn this.post( params ).then( ( response ) => {\n\t\t\tif ( response.upload && response.upload.filekey ) {\n\t\t\t\ttransport.filekey = response.upload.filekey;\n\t\t\t}\n\n\t\t\tif ( response.upload && response.upload.result ) {\n\t\t\t\tswitch ( response.upload.result ) {\n\t\t\t\t\tcase 'Continue':\n\t\t\t\t\t\t// Reset retry counter\n\t\t\t\t\t\ttransport.retries = 0;\n\t\t\t\t\t\t/* falls through */\n\t\t\t\t\tcase 'Success':\n\t\t\t\t\t\t// Just pass the response through.\n\t\t\t\t\t\treturn response;\n\t\t\t\t\tcase 'Poll':\n\t\t\t\t\t\t// Need to retry with checkStatus.\n\t\t\t\t\t\treturn transport.retryWithMethod( 'checkStatus' );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn transport.maybeRetry(\n\t\t\t\t\t'on unknown response',\n\t\t\t\t\tresponse.error ? response.error.code : 'unknown-error',\n\t\t\t\t\tresponse,\n\t\t\t\t\t'uploadChunk',\n\t\t\t\t\tfile, offset\n\t\t\t\t);\n\t\t\t}\n\t\t}, ( code, result ) => {\n\t\t\t// Ain't this some great machine readable output eh\n\t\t\tif (\n\t\t\t\tresult.errors &&\n\t\t\t\tresult.errors[ 0 ].code === 'stashfailed' &&\n\t\t\t\tresult.errors[ 0 ].html === mw.message( 'apierror-stashfailed-complete' ).parse()\n\t\t\t) {\n\t\t\t\treturn transport.retryWithMethod( 'checkStatus' );\n\t\t\t}\n\n\t\t\t// Failed to upload, try again in 3 seconds\n\t\t\t// This is really dumb, we should only do this for cases where retrying has a chance to work\n\t\t\t// (so basically, network failures). If your upload was blocked by AbuseFilter you're\n\t\t\t// shafted anyway. But some server-side errors really are temporary...\n\t\t\treturn transport.maybeRetry(\n\t\t\t\t'on error event',\n\t\t\t\tcode,\n\t\t\t\tresult,\n\t\t\t\t'uploadChunk',\n\t\t\t\tfile, offset\n\t\t\t);\n\t\t} );\n\t};\n\n\t/**\n\t * Handle possible retry event - rejected if maximum retries already fired.\n\t *\n\t * @param {string} contextMsg\n\t * @param {string} code\n\t * @param {Object} response\n\t * @param {string} retryMethod\n\t * @param {File} [file]\n\t * @param {number} [offset]\n\t * @return {jQuery.Promise}\n\t */\n\tmw.FormDataTransport.prototype.maybeRetry = function ( contextMsg, code, response, retryMethod, file, offset ) {\n\t\tthis.retries++;\n\n\t\tif ( this.tooManyRetries() ) {\n\t\t\tmw.log.warn( 'Max retries exceeded ' + contextMsg );\n\t\t\treturn $.Deferred().reject( code, response );\n\t\t} else if ( this.aborted ) {\n\t\t\treturn $.Deferred().reject( code, response );\n\t\t} else {\n\t\t\tmw.log( 'Retry #' + this.retries + ' ' + contextMsg );\n\t\t\treturn this.retryWithMethod( retryMethod, file, offset );\n\t\t}\n\t};\n\n\t/**\n\t * Have we retried too many times already?\n\t *\n\t * @return {boolean}\n\t */\n\tmw.FormDataTransport.prototype.tooManyRetries = function () {\n\t\treturn this.maxRetries > 0 && this.retries >= this.maxRetries;\n\t};\n\n\t/**\n\t * Either retry uploading or checking the status.\n\t *\n\t * @param {'uploadChunk'|'checkStatus'} methodName\n\t * @param {File} [file]\n\t * @param {number} [offset]\n\t * @return {jQuery.Promise}\n\t */\n\tmw.FormDataTransport.prototype.retryWithMethod = function ( methodName, file, offset ) {\n\t\tconst\n\t\t\ttransport = this,\n\t\t\tretryDeferred = $.Deferred(),\n\t\t\tretry = function () {\n\t\t\t\ttransport[ methodName ]( file, offset ).then( retryDeferred.resolve, retryDeferred.reject );\n\t\t\t};\n\n\t\tif ( this.config.useRetryTimeout !== false ) {\n\t\t\tsetTimeout( retry, 3000 );\n\t\t} else {\n\t\t\tretry();\n\t\t}\n\n\t\treturn retryDeferred.promise();\n\t};\n\n\t/**\n\t * Check the status of the upload.\n\t *\n\t * @return {jQuery.Promise}\n\t */\n\tmw.FormDataTransport.prototype.checkStatus = function () {\n\t\tconst transport = this,\n\t\t\tparams = OO.cloneObject( this.formData );\n\n\t\tif ( this.aborted ) {\n\t\t\treturn $.Deferred().reject( 'aborted', {\n\t\t\t\terrors: [ {\n\t\t\t\t\tcode: 'aborted',\n\t\t\t\t\thtml: mw.message( 'mediauploader-api-error-aborted' ).parse()\n\t\t\t\t} ]\n\t\t\t} );\n\t\t}\n\n\t\tif ( !this.firstPoll ) {\n\t\t\tthis.firstPoll = Date.now();\n\t\t}\n\t\tparams.checkstatus = true;\n\t\tparams.filekey = this.filekey;\n\t\tthis.request = this.api.post( params )\n\t\t\t.then( ( response ) => {\n\t\t\t\tif ( response.upload && response.upload.result === 'Poll' ) {\n\t\t\t\t\t// If concatenation takes longer than 10 minutes give up\n\t\t\t\t\tif ( ( Date.now() - transport.firstPoll ) > 10 * 60 * 1000 ) {\n\t\t\t\t\t\treturn $.Deferred().reject( 'server-error', { errors: [ {\n\t\t\t\t\t\t\tcode: 'server-error',\n\t\t\t\t\t\t\thtml: mw.message( 'api-clientside-error-timeout' ).parse()\n\t\t\t\t\t\t} ] } );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ( response.upload.stage === undefined ) {\n\t\t\t\t\t\t\tmw.log.warn( 'Unable to check file\\'s status' );\n\t\t\t\t\t\t\treturn $.Deferred().reject( 'server-error', { errors: [ {\n\t\t\t\t\t\t\t\tcode: 'server-error',\n\t\t\t\t\t\t\t\thtml: mw.message( 'api-clientside-error-invalidresponse' ).parse()\n\t\t\t\t\t\t\t} ] } );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Statuses that can be returned:\n\t\t\t\t\t\t\t// * queued\n\t\t\t\t\t\t\t// * publish\n\t\t\t\t\t\t\t// * assembling\n\t\t\t\t\t\t\ttransport.emit( 'update-stage', response.upload.stage );\n\t\t\t\t\t\t\treturn transport.retryWithMethod( 'checkStatus' );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn response;\n\t\t\t}, ( code, result ) => $.Deferred().reject( code, result ) );\n\n\t\treturn this.request;\n\t};\n}() );\n","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-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/resources/ui/steps/uw.ui.Deed.js","messages":[{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":55,"column":3,"nodeType":"CallExpression","endLine":59,"endColumn":6}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*\n * This file is part of the MediaWiki extension MediaUploader.\n *\n * MediaUploader is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * MediaUploader is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with MediaUploader. If not, see <http://www.gnu.org/licenses/>.\n */\n\n( function ( uw ) {\n\t/**\n\t * Represents the UI for the wizard's Deed step.\n\t *\n\t * @class uw.ui.Deed\n\t * @extends uw.ui.Step\n\t * @constructor\n\t */\n\tuw.ui.Deed = function UWUIDeed() {\n\t\tuw.ui.Step.call(\n\t\t\tthis,\n\t\t\t'deeds'\n\t\t);\n\n\t\tthis.addPreviousButton();\n\t\tthis.addNextButton();\n\t};\n\n\tOO.inheritClass( uw.ui.Deed, uw.ui.Step );\n\n\tuw.ui.Deed.prototype.load = function ( uploads ) {\n\t\tconst ui = this;\n\n\t\tuw.ui.Step.prototype.load.call( this, uploads );\n\n\t\tthis.$div.prepend(\n\t\t\t$( '<div>' )\n\t\t\t\t.attr( 'id', 'mediauploader-deeds-thumbnails' )\n\t\t\t\t.addClass( 'ui-helper-clearfix' ),\n\t\t\t$( '<div>' )\n\t\t\t\t.attr( 'id', 'mediauploader-deeds' )\n\t\t\t\t.addClass( 'ui-helper-clearfix' ),\n\t\t\t$( '<div>' )\n\t\t\t\t.attr( 'id', 'mediauploader-deeds-custom' )\n\t\t\t\t.addClass( 'ui-helper-clearfix' )\n\t\t);\n\n\t\tthis.nextButtonPromise.done( () => {\n\t\t\t// hide \"next\" button, controller will only show it once license has\n\t\t\t// been selected\n\t\t\tui.nextButton.$element.hide();\n\t\t} );\n\t};\n}( mw.uploadWizard ) );\n","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-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/resources/ui/steps/uw.ui.Details.js","messages":[{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":90,"column":3,"nodeType":"CallExpression","endLine":127,"endColumn":6}],"suppressedMessages":[{"ruleId":"no-jquery/no-global-selector","severity":2,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":183,"column":4,"nodeType":"CallExpression","endLine":183,"endColumn":21,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-global-selector","severity":2,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":191,"column":4,"nodeType":"CallExpression","endLine":191,"endColumn":21,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-global-selector","severity":2,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":222,"column":4,"nodeType":"CallExpression","endLine":222,"endColumn":21,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":1,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*\n * This file is part of the MediaWiki extension MediaUploader.\n *\n * MediaUploader is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * MediaUploader is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with MediaUploader. If not, see <http://www.gnu.org/licenses/>.\n */\n\n( function ( uw ) {\n\t/**\n\t * Represents the UI for the wizard's Details step.\n\t *\n\t * @class uw.ui.Details\n\t * @extends uw.ui.Step\n\t * @constructor\n\t */\n\tuw.ui.Details = function UWUIDetails() {\n\t\tconst details = this;\n\n\t\tfunction startDetails() {\n\t\t\tdetails.emit( 'start-details' );\n\t\t}\n\n\t\tuw.ui.Step.call(\n\t\t\tthis,\n\t\t\t'details'\n\t\t);\n\n\t\tthis.$errorCount = $( '<div>' )\n\t\t\t.attr( 'id', 'mediauploader-details-error-count' );\n\t\tthis.$warningCount = $( '<div>' )\n\t\t\t.attr( 'id', 'mediauploader-details-warning-count' );\n\n\t\tthis.nextButton = new OO.ui.ButtonWidget( {\n\t\t\tlabel: mw.message( 'mediauploader-publish-details' ).text(),\n\t\t\tflags: [ 'progressive', 'primary' ]\n\t\t} ).on( 'click', startDetails );\n\n\t\tthis.nextButtonDespiteFailures = new OO.ui.ButtonWidget( {\n\t\t\tlabel: mw.message( 'mediauploader-next-file-despite-failures' ).text(),\n\t\t\tflags: [ 'progressive' ]\n\t\t} ).on( 'click', () => {\n\t\t\tdetails.emit( 'finalize-details-after-removal' );\n\t\t} );\n\n\t\tthis.retryButtonSomeFailed = new OO.ui.ButtonWidget( {\n\t\t\tlabel: mw.message( 'mediauploader-file-retry' ).text(),\n\t\t\tflags: [ 'progressive', 'primary' ]\n\t\t} ).on( 'click', startDetails );\n\n\t\tthis.retryButtonAllFailed = new OO.ui.ButtonWidget( {\n\t\t\tlabel: mw.message( 'mediauploader-file-retry' ).text(),\n\t\t\tflags: [ 'progressive', 'primary' ]\n\t\t} ).on( 'click', startDetails );\n\n\t\tthis.$buttons.append( this.$errorCount, this.$warningCount );\n\t\tthis.addPreviousButton();\n\t\tthis.addNextButton();\n\t};\n\n\tOO.inheritClass( uw.ui.Details, uw.ui.Step );\n\n\tuw.ui.Details.prototype.load = function ( uploads ) {\n\t\tuw.ui.Step.prototype.load.call( this, uploads );\n\n\t\tthis.$div.prepend(\n\t\t\t$( '<div>' )\n\t\t\t\t.attr( 'id', 'mediauploader-macro-files' )\n\t\t\t\t.addClass( 'mediauploader-filled-filelist ui-corner-all' )\n\t\t);\n\n\t\t// set default buttons visibility (can be altered in controller later)\n\t\tthis.$div.find( '.mediauploader-file-next-some-failed' ).hide();\n\t\tthis.$div.find( '.mediauploader-file-next-all-failed' ).hide();\n\t\tthis.$div.find( '.mediauploader-file-next-all-ok' ).show();\n\t};\n\n\tuw.ui.Details.prototype.addNextButton = function () {\n\t\tconst ui = this;\n\n\t\tthis.nextButtonPromise.done( () => {\n\t\t\tui.$buttons.append(\n\t\t\t\t$( '<div>' )\n\t\t\t\t\t.addClass( 'mediauploader-file-next-all-ok mediauploader-file-endchoice' )\n\t\t\t\t\t.append( ui.nextButton.$element )\n\t\t\t);\n\n\t\t\tui.$buttons.append(\n\t\t\t\t$( '<div>' )\n\t\t\t\t\t.addClass( 'mediauploader-file-next-some-failed mediauploader-file-endchoice' )\n\t\t\t\t\t.append(\n\t\t\t\t\t\tnew OO.ui.HorizontalLayout( {\n\t\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t\tnew OO.ui.LabelWidget( {\n\t\t\t\t\t\t\t\t\tlabel: mw.message( 'mediauploader-file-some-failed' ).text()\n\t\t\t\t\t\t\t\t} ),\n\t\t\t\t\t\t\t\tui.nextButtonDespiteFailures,\n\t\t\t\t\t\t\t\tui.retryButtonSomeFailed\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t} ).$element\n\t\t\t\t\t)\n\t\t\t);\n\n\t\t\tui.$buttons.append(\n\t\t\t\t$( '<div>' )\n\t\t\t\t\t.addClass( 'mediauploader-file-next-all-failed mediauploader-file-endchoice' )\n\t\t\t\t\t.append(\n\t\t\t\t\t\tnew OO.ui.HorizontalLayout( {\n\t\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t\tnew OO.ui.LabelWidget( {\n\t\t\t\t\t\t\t\t\tlabel: mw.message( 'mediauploader-file-all-failed' ).text()\n\t\t\t\t\t\t\t\t} ),\n\t\t\t\t\t\t\t\tui.retryButtonAllFailed\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t} ).$element\n\t\t\t\t\t)\n\t\t\t);\n\t\t} );\n\t};\n\n\t/**\n\t * Hide buttons for moving to the next step.\n\t */\n\tuw.ui.Details.prototype.hideEndButtons = function () {\n\t\tthis.$errorCount.empty();\n\t\tthis.$warningCount.empty();\n\t\tthis.$div\n\t\t\t.find( '.mediauploader-buttons .mediauploader-file-endchoice' )\n\t\t\t.hide();\n\t};\n\n\t/**\n\t * Disable edits to the details.\n\t */\n\tuw.ui.Details.prototype.disableEdits = function () {\n\t\tthis.$div\n\t\t\t.find( '.mediauploader-data' )\n\t\t\t.morphCrossfade( '.mediauploader-submitting' );\n\n\t\tthis.previousButton.$element.hide();\n\t};\n\n\t/**\n\t * Re-enabled edits to the details.\n\t */\n\tuw.ui.Details.prototype.enableEdits = function () {\n\t\tthis.previousButton.$element.show();\n\t};\n\n\t/**\n\t * Show errors in the form.\n\t * The details page can be vertically long so sometimes it is not obvious there are errors above. This counts them and puts the count\n\t * right next to the submit button, so it should be obvious to the user they need to fix things.\n\t * This is a bit of a hack. We should already know how many errors there are, and where.\n\t * This method also opens up \"more info\" if the form has errors.\n\t */\n\tuw.ui.Details.prototype.showErrors = function () {\n\t\tconst $errorElements = this.$div\n\t\t\t\t// TODO Evil\n\t\t\t\t.find( '.oo-ui-fieldLayout-messages-error' ),\n\t\t\terrorCount = $errorElements.length;\n\n\t\t// Open \"more info\" if that part of the form has errors\n\t\t$errorElements.each( function () {\n\t\t\tconst $collapsibleWrapper = $( this ).closest( '.mwe-more-details' );\n\t\t\tif ( $collapsibleWrapper.length ) {\n\t\t\t\t$collapsibleWrapper.data( 'mw-collapsible' ).expand();\n\t\t\t}\n\t\t} );\n\n\t\tif ( errorCount > 0 ) {\n\t\t\t// Errors supersede warnings, so stop any animating to the warnings before we animate to the errors\n\t\t\t// eslint-disable-next-line no-jquery/no-global-selector\n\t\t\t$( 'html, body' ).stop();\n\n\t\t\tthis.$errorCount\n\t\t\t\t.msg( 'mediauploader-details-error-count', errorCount, this.uploads.length )\n\t\t\t\t// TODO The IconWidget and 'warning' flag is specific to MediaWiki theme, looks weird in Apex\n\t\t\t\t.prepend( new OO.ui.IconWidget( { icon: 'alert', flags: [ 'warning' ] } ).$element, ' ' );\n\t\t\t// Scroll to the first error\n\t\t\t// eslint-disable-next-line no-jquery/no-global-selector\n\t\t\t$( 'html, body' ).animate( { scrollTop: $( $errorElements[ 0 ] ).offset().top - 50 }, 'slow' );\n\t\t} else {\n\t\t\tthis.$errorCount.empty();\n\t\t}\n\t};\n\n\t/**\n\t * Show warnings in the form.\n\t * See #showErrors for details.\n\t */\n\tuw.ui.Details.prototype.showWarnings = function () {\n\t\tconst $warningElements = this.$div\n\t\t\t\t// TODO Evil\n\t\t\t\t.find( '.oo-ui-fieldLayout-messages-notice' ),\n\t\t\twarningCount = $warningElements.length;\n\n\t\t// Open \"more info\" if that part of the form has warnings\n\t\t$warningElements.each( function () {\n\t\t\tconst $collapsibleWrapper = $( this ).closest( '.mwe-more-details' );\n\t\t\tif ( $collapsibleWrapper.length ) {\n\t\t\t\t$collapsibleWrapper.data( 'mw-collapsible' ).expand();\n\t\t\t}\n\t\t} );\n\n\t\tif ( warningCount > 0 ) {\n\t\t\tthis.$warningCount\n\t\t\t\t.msg( 'mediauploader-details-warning-count', warningCount, this.uploads.length )\n\t\t\t\t// TODO The IconWidget is specific to MediaWiki theme, looks weird in Apex\n\t\t\t\t.prepend( new OO.ui.IconWidget( { icon: 'info' } ).$element, ' ' );\n\t\t\t// Scroll to the first warning\n\t\t\t// eslint-disable-next-line no-jquery/no-global-selector\n\t\t\t$( 'html, body' ).animate( { scrollTop: $( $warningElements[ 0 ] ).offset().top - 50 }, 'slow' );\n\t\t} else {\n\t\t\tthis.$warningCount.empty();\n\t\t}\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/ui/steps/uw.ui.Thanks.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'thanks' is never reassigned. Use 'const' instead.","line":30,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":30,"endColumn":10},{"ruleId":"prefer-const","severity":2,"message":"'$header' is never reassigned. Use 'const' instead.","line":48,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":48,"endColumn":10},{"ruleId":"prefer-const","severity":2,"message":"'beginButtonTarget' is never reassigned. Use 'const' instead.","line":69,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":69,"endColumn":20},{"ruleId":"prefer-const","severity":2,"message":"'thumbWikiText' is never reassigned. Use 'const' instead.","line":98,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":98,"endColumn":16},{"ruleId":"prefer-const","severity":2,"message":"'$thanksDiv' is never reassigned. Use 'const' instead.","line":104,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":104,"endColumn":13},{"ruleId":"prefer-const","severity":2,"message":"'$thumbnailWrapDiv' is never reassigned. Use 'const' instead.","line":106,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":106,"endColumn":20},{"ruleId":"prefer-const","severity":2,"message":"'$thumbnailDiv' is never reassigned. Use 'const' instead.","line":109,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":109,"endColumn":16},{"ruleId":"prefer-const","severity":2,"message":"'$thumbnailCaption' is never reassigned. Use 'const' instead.","line":112,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":112,"endColumn":20},{"ruleId":"prefer-const","severity":2,"message":"'$thumbnailLink' is never reassigned. Use 'const' instead.","line":115,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":115,"endColumn":17},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":128,"column":3,"nodeType":"CallExpression","endLine":130,"endColumn":6}],"suppressedMessages":[],"errorCount":10,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*\n * This file is part of the MediaWiki extension MediaUploader.\n *\n * MediaUploader is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * MediaUploader is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with MediaUploader. If not, see <http://www.gnu.org/licenses/>.\n */\n\n( function ( uw ) {\n\t/**\n\t * Represents the UI for the wizard's Thanks step.\n\t *\n\t * @class uw.ui.Thanks\n\t * @extends uw.ui.Step\n\t * @constructor\n\t * @param {Object} config\n\t */\n\tuw.ui.Thanks = function UWUIThanks( config ) {\n\t\tlet $header,\n\t\t\tbeginButtonTarget,\n\t\t\tthanks = this;\n\n\t\tthis.config = config;\n\n\t\tuw.ui.Step.call(\n\t\t\tthis,\n\t\t\t'thanks'\n\t\t);\n\n\t\tthis.$div.prepend(\n\t\t\t$( '<div>' ).attr( 'id', 'mediauploader-thanks' )\n\t\t);\n\n\t\t$( '<p>' )\n\t\t\t.addClass( 'mediauploader-thanks-explain' )\n\t\t\t.msg( 'mediauploader-thanks-explain' )\n\t\t\t.prependTo( this.$div );\n\n\t\t$header = $( '<h3>' )\n\t\t\t.addClass( 'mediauploader-thanks-header' )\n\t\t\t.prependTo( this.$div );\n\n\t\tif ( !this.config.display || !this.config.display.thanksLabel ) {\n\t\t\t$header.text( mw.message( 'mediauploader-thanks-intro' ).text() );\n\t\t} else {\n\t\t\t$header.html( this.config.display.thanksLabel );\n\t\t}\n\n\t\tthis.homeButton = new OO.ui.ButtonWidget( {\n\t\t\tlabel: this.getButtonConfig( 'homeButton', 'label' ) || mw.message( 'mediauploader-home' ).text(),\n\t\t\thref: this.getButtonConfig( 'homeButton', 'target' ) || mw.config.get( 'wgArticlePath' ).replace( '$1', '' )\n\t\t} );\n\n\t\tthis.beginButton = new OO.ui.ButtonWidget( {\n\t\t\tlabel: this.getButtonConfig( 'beginButton', 'label' ) || mw.message( 'mediauploader-upload-another' ).text(),\n\t\t\tflags: [ 'progressive', 'primary' ]\n\t\t} );\n\n\t\t// TODO: make the step order configurable by campaign definitions instead of using these hacks\n\t\tbeginButtonTarget = this.getButtonConfig( 'beginButton', 'target' );\n\t\tif ( !beginButtonTarget ) {\n\t\t\tthis.beginButton.on( 'click', () => {\n\t\t\t\tthanks.emit( 'next-step' );\n\t\t\t} );\n\t\t} else {\n\t\t\tthis.beginButton.setHref( beginButtonTarget );\n\t\t}\n\t\tthis.beginButton.on( 'click', () => {\n\t\t\tmw.DestinationChecker.clearCache();\n\t\t} );\n\n\t\tthis.buttonGroup = new OO.ui.HorizontalLayout( {\n\t\t\titems: [ this.homeButton, this.beginButton ]\n\t\t} );\n\n\t\tthis.$buttons.append( this.buttonGroup.$element );\n\t};\n\n\tOO.inheritClass( uw.ui.Thanks, uw.ui.Step );\n\n\t/**\n\t * Adds an upload to the Thanks interface.\n\t *\n\t * @param {mw.UploadWizardUpload} upload\n\t */\n\tuw.ui.Thanks.prototype.addUpload = function ( upload ) {\n\t\tlet thumbWikiText, $thanksDiv, $thumbnailWrapDiv, $thumbnailDiv, $thumbnailCaption, $thumbnailLink;\n\n\t\tthumbWikiText = '[[' + [\n\t\t\tupload.details.getTitle().getPrefixedText(),\n\t\t\t'thumb',\n\t\t\tupload.details.getThumbnailCaption()\n\t\t].join( '|' ) + ']]';\n\n\t\t$thanksDiv = $( '<div>' )\n\t\t\t.addClass( 'mediauploader-thanks ui-helper-clearfix' );\n\t\t$thumbnailWrapDiv = $( '<div>' )\n\t\t\t.addClass( 'mediauploader-thumbnail-side' )\n\t\t\t.appendTo( $thanksDiv );\n\t\t$thumbnailDiv = $( '<div>' )\n\t\t\t.addClass( 'mediauploader-thumbnail' )\n\t\t\t.appendTo( $thumbnailWrapDiv );\n\t\t$thumbnailCaption = $( '<div>' )\n\t\t\t.css( { 'text-align': 'center', 'font-size': 'small' } )\n\t\t\t.appendTo( $thumbnailWrapDiv );\n\t\t$thumbnailLink = $( '<a>' )\n\t\t\t.text( upload.details.getTitle().getMainText() )\n\t\t\t.appendTo( $thumbnailCaption );\n\n\t\t$( '<div>' )\n\t\t\t.addClass( 'mediauploader-data' )\n\t\t\t.appendTo( $thanksDiv )\n\t\t\t.append(\n\t\t\t\tthis.makeReadOnlyInput( thumbWikiText, mw.message( 'mediauploader-thanks-wikitext' ).text(), true ),\n\t\t\t\tthis.makeReadOnlyInput( upload.imageinfo.descriptionurl, mw.message( 'mediauploader-thanks-url' ).text() )\n\t\t\t);\n\n\t\t// This must match the CSS dimensions of .mediauploader-thumbnail\n\t\tupload.getThumbnail( 120, 120 ).done( ( thumb ) => {\n\t\t\tmw.UploadWizard.placeThumbnail( $thumbnailDiv, thumb );\n\t\t} );\n\n\t\t// Set the thumbnail links so that they point to the image description page\n\t\t$thumbnailLink.add( $thumbnailDiv.find( '.mediauploader-thumbnail-link' ) ).attr( {\n\t\t\thref: upload.imageinfo.descriptionurl,\n\t\t\ttarget: '_blank'\n\t\t} );\n\n\t\tthis.$div.find( '.mediauploader-buttons' ).before( $thanksDiv );\n\t};\n\n\t/**\n\t * Make an mw.widgets.CopyTextLayout, which features a button\n\t * to copy the text provided.\n\t *\n\t * @param {string} value Text it will contain\n\t * @param {string} label Label\n\t * @param {string} [useEditFont] Use edit font (for wikitext values)\n\t * @return {jQuery}\n\t */\n\tuw.ui.Thanks.prototype.makeReadOnlyInput = function ( value, label, useEditFont ) {\n\t\tconst copyText = new mw.widgets.CopyTextLayout( {\n\t\t\talign: 'top',\n\t\t\tlabel: label,\n\t\t\tcopyText: value\n\t\t} );\n\n\t\tif ( useEditFont ) {\n\t\t\t// The following classes are used here:\n\t\t\t// * mw-editfont-monospace\n\t\t\t// * mw-editfont-sans-serif\n\t\t\t// * mw-editfont-serif\n\t\t\tcopyText.textInput.$element.addClass( 'mw-editfont-' + mw.user.options.get( 'editfont' ) );\n\t\t}\n\n\t\treturn copyText.$element;\n\t};\n\n\t/**\n\t * Get button configuration options from a campaign definition\n\t *\n\t * @param {string} buttonName name of the button as defined in campaign configuration\n\t * @param {string} configField name of the button's attributes\n\t * @return {Object|undefined}\n\t */\n\tuw.ui.Thanks.prototype.getButtonConfig = function ( buttonName, configField ) {\n\t\tif ( !this.config.display || !this.config.display[ buttonName ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn this.config.display[ buttonName ][ configField ];\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/ui/steps/uw.ui.Tutorial.js","messages":[{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":125,"column":3,"nodeType":"CallExpression","endLine":131,"endColumn":6}],"suppressedMessages":[{"ruleId":"no-jquery/no-global-selector","severity":2,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":87,"column":24,"nodeType":"CallExpression","endLine":87,"endColumn":59,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":1,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*\n * This file is part of the MediaWiki extension MediaUploader.\n *\n * MediaUploader is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * MediaUploader is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with MediaUploader. If not, see <http://www.gnu.org/licenses/>.\n */\n\n( function ( uw ) {\n\t/**\n\t * Checkbox with popup information.\n\t *\n\t * @param {Object} config\n\t */\n\tfunction PopupCheckboxInputWidget( config ) {\n\t\t// Parent constructor\n\t\tPopupCheckboxInputWidget.parent.call( this, config );\n\n\t\t// Mixin constructors\n\t\tOO.ui.mixin.PopupElement.call( this, config );\n\n\t\t// Events\n\t\tthis.connect( this, { change: 'onChange' } );\n\n\t\t// Initialization\n\t\tthis.$element\n\t\t\t.addClass( 'oo-ui-popupCheckboxInputWidget' )\n\t\t\t.attr( 'aria-haspopup', 'true' )\n\t\t\t.append( this.popup.$element );\n\t}\n\tOO.inheritClass( PopupCheckboxInputWidget, OO.ui.CheckboxInputWidget );\n\tOO.mixinClass( PopupCheckboxInputWidget, OO.ui.mixin.PopupElement );\n\tPopupCheckboxInputWidget.prototype.onChange = function () {\n\t\tthis.popup.toggle( this.isSelected() );\n\t};\n\n\t/**\n\t * Represents the UI for the wizard's Tutorial step.\n\t *\n\t * @class uw.ui.Tutorial\n\t * @extends uw.ui.Step\n\t * @constructor\n\t */\n\tuw.ui.Tutorial = function UWUITutorial() {\n\t\tconst ui = this;\n\n\t\tuw.ui.Step.call(\n\t\t\tthis,\n\t\t\t'tutorial'\n\t\t);\n\n\t\t// 'Skip tutorial' checkbox\n\t\tthis.skipCheckbox = new PopupCheckboxInputWidget( {\n\t\t\tid: 'mediauploader-skip',\n\t\t\t// Add a friendly \"Here's how to get it back\" tooltip for users who check the \"Skip next time\" checkbox\n\t\t\tpopup: {\n\t\t\t\t$content: $( '<p>' ).msg(\n\t\t\t\t\t'mediauploader-tooltip-skiptutorial',\n\t\t\t\t\tmw.config.get( 'wgServer' ) + mw.util.getUrl( 'Special:Preferences' ) + '#mw-prefsection-uploads',\n\t\t\t\t\tmw.message( 'prefs-uploads' ).text(),\n\t\t\t\t\tmw.message( 'prefs-mediauploader-interface' ).text()\n\t\t\t\t),\n\t\t\t\tautoClose: false,\n\t\t\t\tpadded: true\n\t\t\t}\n\t\t} );\n\t\tthis.skipCheckboxLabel = new OO.ui.LabelWidget( {\n\t\t\tinput: this.skipCheckbox,\n\t\t\tlabel: mw.message( 'mediauploader-skip-tutorial-future' ).text()\n\t\t} );\n\n\t\tthis.skipCheckbox.on( 'change', () => {\n\t\t\tui.emit( 'skip-tutorial-click', ui.skipCheckbox.isSelected() );\n\t\t} );\n\n\t\t// grab the tutorial HTML that was injected into this document\n\t\t// eslint-disable-next-line no-jquery/no-global-selector\n\t\tthis.$tutorialHtml = $( '#mediauploader-tutorial-html' );\n\n\t\tthis.addPreviousButton();\n\t\tthis.addNextButton();\n\t};\n\n\tOO.inheritClass( uw.ui.Tutorial, uw.ui.Step );\n\n\tuw.ui.Tutorial.prototype.setSelected = function ( selected ) {\n\t\tthis.skipCheckbox.setSelected( selected );\n\t};\n\n\tuw.ui.Tutorial.prototype.load = function ( uploads ) {\n\t\tuw.ui.Step.prototype.load.call( this, uploads );\n\n\t\tthis.$div.prepend(\n\t\t\t$( '<div>' )\n\t\t\t\t.attr( 'id', 'mediauploader-tutorial' )\n\t\t\t\t.append(\n\t\t\t\t\t// TODO move this to JavaScript, too.\n\t\t\t\t\tthis.$tutorialHtml.show()\n\t\t\t\t)\n\t\t);\n\n\t\tthis.skipCheckbox.popup.updateDimensions();\n\t};\n\n\tuw.ui.Tutorial.prototype.addNextButton = function () {\n\t\tconst ui = this;\n\n\t\tthis.nextButton = new OO.ui.ButtonWidget( {\n\t\t\tclasses: [ 'mediauploader-button-next' ],\n\t\t\tlabel: mw.message( 'mediauploader-next' ).text(),\n\t\t\tflags: [ 'progressive', 'primary' ]\n\t\t} ).on( 'click', () => {\n\t\t\tui.emit( 'next-step' );\n\t\t} );\n\n\t\tthis.nextButtonPromise.done( () => {\n\t\t\tui.$buttons.append(\n\t\t\t\tnew OO.ui.HorizontalLayout( {\n\t\t\t\t\titems: [ ui.skipCheckbox, ui.skipCheckboxLabel, ui.nextButton ]\n\t\t\t\t} ).$element\n\t\t\t);\n\t\t} );\n\t};\n}( mw.uploadWizard ) );\n","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-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/resources/ui/steps/uw.ui.Upload.js","messages":[{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":210,"column":6,"nodeType":"CallExpression","endLine":212,"endColumn":9},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":222,"column":3,"nodeType":"CallExpression","endLine":270,"endColumn":6}],"suppressedMessages":[{"ruleId":"no-jquery/no-sizzle","severity":2,"message":"Positional selector extensions are not allowed","line":132,"column":4,"nodeType":"CallExpression","endLine":132,"endColumn":39,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-sizzle","severity":2,"message":"Positional selector extensions are not allowed","line":134,"column":4,"nodeType":"CallExpression","endLine":134,"endColumn":40,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":2,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*\n * This file is part of the MediaWiki extension MediaUploader.\n *\n * MediaUploader is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * MediaUploader is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with MediaUploader. If not, see <http://www.gnu.org/licenses/>.\n */\n\n( function ( uw ) {\n\t/**\n\t * Represents the UI for the wizard's Upload step.\n\t *\n\t * @class uw.ui.Upload\n\t * @extends uw.ui.Step\n\t * @constructor\n\t * @param {Object} config UploadWizard config object.\n\t */\n\tuw.ui.Upload = function UWUIUpload( config ) {\n\t\tconst upload = this;\n\n\t\tthis.config = config;\n\n\t\tuw.ui.Step.call(\n\t\t\tthis,\n\t\t\t'file'\n\t\t);\n\n\t\tthis.$addFileContainer = $( '<div>' )\n\t\t\t.attr( 'id', 'mediauploader-add-file-container' )\n\t\t\t.addClass( 'mediauploader-add-files-0' );\n\n\t\tthis.$uploadCtrl = $( '<div>' )\n\t\t\t.attr( 'id', 'mediauploader-upload-ctrls' )\n\t\t\t.addClass( 'mediauploader-file ui-helper-clearfix' )\n\t\t\t.append( this.$addFileContainer );\n\n\t\tthis.addFile = new OO.ui.SelectFileWidget( {\n\t\t\tclasses: [ 'mediauploader-add-file' ],\n\t\t\tmultiple: true,\n\t\t\tshowDropTarget: true,\n\t\t\tbutton: {\n\t\t\t\tlabel: mw.message( 'mediauploader-add-file-0-free' ).text(),\n\t\t\t\tflags: [ 'progressive', 'primary' ]\n\t\t\t}\n\t\t} );\n\n\t\tthis.$addFileContainer.append( this.addFile.$element );\n\n\t\tthis.nextStepButtonAllOk = new OO.ui.ButtonWidget( {\n\t\t\tlabel: mw.message( 'mediauploader-next-file' ).text(),\n\t\t\tflags: [ 'progressive', 'primary' ]\n\t\t} ).on( 'click', () => {\n\t\t\tupload.emit( 'next-step' );\n\t\t} );\n\n\t\tthis.retryButtonSomeFailed = new OO.ui.ButtonWidget( {\n\t\t\tlabel: mw.message( 'mediauploader-file-retry' ).text(),\n\t\t\tflags: [ 'progressive' ]\n\t\t} ).on( 'click', () => {\n\t\t\tupload.hideEndButtons();\n\t\t\tupload.emit( 'retry' );\n\t\t} );\n\n\t\tthis.nextStepButtonSomeFailed = new OO.ui.ButtonWidget( {\n\t\t\tlabel: mw.message( 'mediauploader-next-file-despite-failures' ).text(),\n\t\t\tflags: [ 'progressive', 'primary' ]\n\t\t} ).on( 'click', () => {\n\t\t\tupload.emit( 'next-step' );\n\t\t} );\n\n\t\tthis.retryButtonAllFailed = new OO.ui.ButtonWidget( {\n\t\t\tlabel: mw.message( 'mediauploader-file-retry' ).text(),\n\t\t\tflags: [ 'progressive' ]\n\t\t} ).on( 'click', () => {\n\t\t\tupload.hideEndButtons();\n\t\t\tupload.emit( 'retry' );\n\t\t} );\n\n\t\tthis.$fileList = $( '<div>' )\n\t\t\t.attr( 'id', 'mediauploader-filelist' )\n\t\t\t.addClass( 'ui-corner-all' );\n\n\t\tthis.$progress = $( '<div>' )\n\t\t\t.attr( 'id', 'mediauploader-progress' )\n\t\t\t.addClass( 'ui-helper-clearfix' );\n\n\t\tthis.addPreviousButton();\n\t\tthis.addNextButton();\n\t};\n\n\tOO.inheritClass( uw.ui.Upload, uw.ui.Step );\n\n\tuw.ui.Upload.prototype.showProgressBar = function () {\n\t\tthis.$progress.show();\n\t};\n\n\t/**\n\t * Updates the interface based on the number of uploads.\n\t *\n\t * @param {boolean} haveUploads Whether there are any uploads at all.\n\t * @param {boolean} fewerThanMax Whether we can add more uploads.\n\t */\n\tuw.ui.Upload.prototype.updateFileCounts = function ( haveUploads, fewerThanMax ) {\n\t\tthis.$fileList.toggleClass( 'mediauploader-filled-filelist', haveUploads );\n\t\tthis.$addFileContainer.toggleClass( 'mediauploader-add-files-0', !haveUploads );\n\n\t\tthis.setAddButtonText( haveUploads );\n\n\t\tif ( haveUploads ) {\n\t\t\t// we have uploads ready to go, so allow us to proceed\n\t\t\tthis.$addFileContainer.add( this.$buttons ).show();\n\n\t\t\t// fix the rounded corners on file elements.\n\t\t\t// we want them to be rounded only when their edge touched the top or bottom of the filelist.\n\t\t\tthis.$fileListings = this.$fileList.find( '.filled' );\n\n\t\t\tthis.$visibleFileListings = this.$fileListings.find( '.mediauploader-visible-file' );\n\t\t\tthis.$visibleFileListings.removeClass( 'ui-corner-top ui-corner-bottom' );\n\t\t\tthis.$visibleFileListings.first().addClass( 'ui-corner-top' );\n\t\t\tthis.$visibleFileListings.last().addClass( 'ui-corner-bottom' );\n\n\t\t\t// eslint-disable-next-line no-jquery/no-sizzle\n\t\t\tthis.$fileListings.filter( ':odd' ).addClass( 'odd' );\n\t\t\t// eslint-disable-next-line no-jquery/no-sizzle\n\t\t\tthis.$fileListings.filter( ':even' ).removeClass( 'odd' );\n\t\t} else {\n\t\t\tthis.hideEndButtons();\n\t\t}\n\n\t\tthis.addFile.setDisabled( !fewerThanMax );\n\t};\n\n\t/**\n\t * Changes the initial centered invitation button to something like \"add another file\"\n\t *\n\t * @param {boolean} more\n\t */\n\tuw.ui.Upload.prototype.setAddButtonText = function ( more ) {\n\t\tlet msg = 'mediauploader-add-file-';\n\n\t\tif ( more ) {\n\t\t\tmsg += 'n';\n\t\t} else {\n\t\t\tmsg += '0-free';\n\t\t}\n\n\t\t// Messages that can be used here:\n\t\t// * mediauploader-add-file-0-free\n\t\t// * mediauploader-add-file-n\n\t\tthis.addFile.selectButton.setLabel( mw.message( msg ).text() );\n\t};\n\n\tuw.ui.Upload.prototype.load = function ( uploads ) {\n\t\tconst ui = this;\n\n\t\tuw.ui.Step.prototype.load.call( this, uploads );\n\n\t\tif ( uploads.length === 0 ) {\n\t\t\tthis.$fileList.removeClass( 'mediauploader-filled-filelist' );\n\t\t}\n\n\t\tthis.$div.prepend(\n\t\t\t$( '<div>' )\n\t\t\t\t.attr( 'id', 'mediauploader-files' )\n\t\t\t\t.append(\n\t\t\t\t\tthis.$fileList,\n\t\t\t\t\tthis.$uploadCtrl\n\t\t\t\t)\n\t\t);\n\n\t\tthis.addFile.on( 'change', ( files ) => {\n\t\t\tui.emit( 'files-added', files );\n\t\t\tui.addFile.setValue( null );\n\t\t} );\n\t};\n\n\tuw.ui.Upload.prototype.displayUploads = function ( uploads ) {\n\t\tlet thumbPromise,\n\t\t\t$uploadInterfaceDivs = $( [] );\n\n\t\tuploads.forEach( ( upload ) => {\n\t\t\t// We'll attach all interfaces to the DOM at once rather than one-by-one, for better\n\t\t\t// performance\n\t\t\t$uploadInterfaceDivs = $uploadInterfaceDivs.add( upload.ui.$div );\n\t\t} );\n\n\t\t// Attach all interfaces to the DOM\n\t\tthis.$fileList.append( $uploadInterfaceDivs );\n\n\t\t// Display thumbnails, but not all at once because they're somewhat expensive to generate.\n\t\t// This will wait for each thumbnail to be complete before starting the next one.\n\t\tthumbPromise = $.Deferred().resolve();\n\t\tuploads.forEach( ( upload ) => {\n\t\t\tthumbPromise = thumbPromise.then( () => {\n\t\t\t\tconst deferred = $.Deferred();\n\t\t\t\tsetTimeout( function () {\n\t\t\t\t\tif ( this.movedFrom ) {\n\t\t\t\t\t\t// We're no longer displaying any of these thumbnails, stop\n\t\t\t\t\t\tdeferred.reject();\n\t\t\t\t\t}\n\t\t\t\t\tupload.ui.showThumbnail().done( () => {\n\t\t\t\t\t\tdeferred.resolve();\n\t\t\t\t\t} );\n\t\t\t\t} );\n\t\t\t\treturn deferred.promise();\n\t\t\t} );\n\t\t} );\n\t};\n\n\tuw.ui.Upload.prototype.addNextButton = function () {\n\t\tconst ui = this;\n\n\t\tthis.nextButtonPromise.done( () => {\n\t\t\tui.$buttons.append(\n\t\t\t\t$( '<div>' )\n\t\t\t\t\t.addClass( 'mediauploader-file-next-all-ok mediauploader-file-endchoice' )\n\t\t\t\t\t.append(\n\t\t\t\t\t\tnew OO.ui.HorizontalLayout( {\n\t\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t\tnew OO.ui.LabelWidget( {\n\t\t\t\t\t\t\t\t\tlabel: mw.message( 'mediauploader-file-all-ok' ).text()\n\t\t\t\t\t\t\t\t} ),\n\t\t\t\t\t\t\t\tui.nextStepButtonAllOk\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t} ).$element\n\t\t\t\t\t)\n\t\t\t);\n\n\t\t\tui.$buttons.append(\n\t\t\t\t$( '<div>' )\n\t\t\t\t\t.addClass( 'mediauploader-file-next-some-failed mediauploader-file-endchoice' )\n\t\t\t\t\t.append(\n\t\t\t\t\t\tnew OO.ui.HorizontalLayout( {\n\t\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t\tnew OO.ui.LabelWidget( {\n\t\t\t\t\t\t\t\t\tlabel: mw.message( 'mediauploader-file-some-failed' ).text()\n\t\t\t\t\t\t\t\t} ),\n\t\t\t\t\t\t\t\tui.retryButtonSomeFailed,\n\t\t\t\t\t\t\t\tui.nextStepButtonSomeFailed\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t} ).$element\n\t\t\t\t\t)\n\t\t\t);\n\n\t\t\tui.$buttons.append(\n\t\t\t\t$( '<div>' )\n\t\t\t\t\t.addClass( 'mediauploader-file-next-all-failed mediauploader-file-endchoice' )\n\t\t\t\t\t.append(\n\t\t\t\t\t\tnew OO.ui.HorizontalLayout( {\n\t\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t\tnew OO.ui.LabelWidget( {\n\t\t\t\t\t\t\t\t\tlabel: mw.message( 'mediauploader-file-all-failed' ).text()\n\t\t\t\t\t\t\t\t} ),\n\t\t\t\t\t\t\t\tui.retryButtonAllFailed\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t} ).$element\n\t\t\t\t\t)\n\t\t\t);\n\n\t\t\tui.$buttons.append( ui.$progress );\n\t\t} );\n\t};\n\n\t/**\n\t * Hide the buttons for moving to the next step.\n\t */\n\tuw.ui.Upload.prototype.hideEndButtons = function () {\n\t\tthis.$div\n\t\t\t.find( '.mediauploader-buttons .mediauploader-file-endchoice' )\n\t\t\t.hide();\n\t};\n\n\t/**\n\t * Shows an error dialog informing the user that some uploads have been omitted\n\t * since they went over the max files limit.\n\t *\n\t * @param {number} filesUploaded The number of files that have been attempted to upload\n\t */\n\tuw.ui.Upload.prototype.showTooManyFilesError = function ( filesUploaded ) {\n\t\tmw.errorDialog(\n\t\t\tmw.message(\n\t\t\t\t'mediauploader-too-many-files-text',\n\t\t\t\tthis.config.maxUploads,\n\t\t\t\tfilesUploaded\n\t\t\t).text(),\n\t\t\tmw.message( 'mediauploader-too-many-files' ).text()\n\t\t);\n\t};\n\n\t/**\n\t * Shows an error dialog informing the user that an upload omitted because\n\t * it is too large.\n\t *\n\t * @param {number} maxSize The max upload file size\n\t * @param {number} size The actual upload file size\n\t */\n\tuw.ui.Upload.prototype.showFileTooLargeError = function ( maxSize, size ) {\n\t\tmw.errorDialog(\n\t\t\tmw.message(\n\t\t\t\t'mediauploader-file-too-large-text',\n\t\t\t\tuw.units.bytes( maxSize ),\n\t\t\t\tuw.units.bytes( size )\n\t\t\t).text(),\n\t\t\tmw.message( 'mediauploader-file-too-large' ).text()\n\t\t);\n\t};\n\n\t/**\n\t * @param {string} filename\n\t * @param {string} extension\n\t */\n\tuw.ui.Upload.prototype.showBadExtensionError = function ( filename, extension ) {\n\t\tconst $errorMessage = $( '<p>' ).msg( 'mediauploader-upload-error-bad-filename-extension', extension );\n\t\tthis.showFilenameError( $errorMessage );\n\t};\n\n\tuw.ui.Upload.prototype.showMissingExtensionError = function () {\n\t\tconst $errorMessage = $( '<p>' ).msg( 'mediauploader-upload-error-bad-filename-no-extension' );\n\t\tthis.showFilenameError(\n\t\t\t$( '<div>' ).append(\n\t\t\t\t$errorMessage,\n\t\t\t\t$( '<p>' ).msg( 'mediauploader-allowed-filename-extensions' ),\n\t\t\t\t$( '<blockquote>' ).append( $( '<tt>' ).append(\n\t\t\t\t\tmw.UploadWizard.config.fileExtensions.join( ' ' )\n\t\t\t\t) )\n\t\t\t)\n\t\t);\n\t};\n\n\t/**\n\t * @param {string} filename\n\t * @param {string} basename\n\t */\n\tuw.ui.Upload.prototype.showDuplicateError = function ( filename, basename ) {\n\t\tthis.showFilenameError( $( '<p>' ).msg( 'mediauploader-upload-error-duplicate-filename-error', basename ) );\n\t};\n\n\t/**\n\t * @param {string} filename\n\t */\n\tuw.ui.Upload.prototype.showUnparseableFilenameError = function ( filename ) {\n\t\tthis.showFilenameError( mw.message( 'mediauploader-unparseable-filename', filename ).escaped() );\n\t};\n\n\t/**\n\t * Shows an error dialog informing the user that an upload has been omitted\n\t * over its filename.\n\t *\n\t * @param {jQuery|string} message The error message\n\t */\n\tuw.ui.Upload.prototype.showFilenameError = function ( message ) {\n\t\tmw.errorDialog( message );\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/ui/uw.ui.DeedPreview.js","messages":[{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":30,"column":3,"nodeType":"CallExpression","endLine":32,"endColumn":6}],"suppressedMessages":[{"ruleId":"no-jquery/no-global-selector","severity":2,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":34,"column":3,"nodeType":"CallExpression","endLine":34,"endColumn":41,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":1,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*\n * This file is part of the MediaWiki extension MediaUploader.\n *\n * MediaUploader is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * MediaUploader is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with MediaUploader. If not, see <http://www.gnu.org/licenses/>.\n */\n\n( function ( uw ) {\n\t/**\n\t * Represents the UI for a thumbnail in the Deed step.\n\t *\n\t * @class uw.ui.DeedPreview\n\t * @constructor\n\t * @param {mw.UploadWizardUpload} upload\n\t */\n\tuw.ui.DeedPreview = function UWUIDeedPreview( upload ) {\n\t\tconst $thumbnailDiv = $( '<div>' ).addClass( 'mediauploader-thumbnail' );\n\t\tthis.$thumbnailDiv = $thumbnailDiv;\n\t\t// This must match the CSS dimensions of .mediauploader-thumbnail\n\t\tupload.getThumbnail( 120, 120 ).done( ( thumb ) => {\n\t\t\tmw.UploadWizard.placeThumbnail( $thumbnailDiv, thumb );\n\t\t} );\n\t\t// eslint-disable-next-line no-jquery/no-global-selector\n\t\t$( '#mediauploader-deeds-thumbnails' ).append( this.$thumbnailDiv );\n\t};\n\n\tuw.ui.DeedPreview.prototype.remove = function () {\n\t\tif ( this.$thumbnailDiv ) {\n\t\t\tthis.$thumbnailDiv.remove();\n\t\t}\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/ui/uw.ui.Step.js","messages":[{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":101,"column":3,"nodeType":"CallExpression","endLine":103,"endColumn":6},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":119,"column":3,"nodeType":"CallExpression","endLine":121,"endColumn":6}],"suppressedMessages":[{"ruleId":"no-jquery/no-global-selector","severity":2,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":39,"column":3,"nodeType":"CallExpression","endLine":39,"endColumn":32,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-global-selector","severity":2,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":56,"column":18,"nodeType":"CallExpression","endLine":56,"endColumn":27,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-global-selector","severity":2,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":64,"column":3,"nodeType":"CallExpression","endLine":64,"endColumn":20,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":2,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*\n * This file is part of the MediaWiki extension MediaUploader.\n *\n * MediaUploader is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * MediaUploader is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with MediaUploader. If not, see <http://www.gnu.org/licenses/>.\n */\n\n( function ( uw ) {\n\t/**\n\t * Represents a generic UI for a step.\n\t *\n\t * @class uw.ui.Step\n\t * @constructor\n\t * @param {string} name The name of this step\n\t */\n\tuw.ui.Step = function UWUIStep( name ) {\n\t\tOO.EventEmitter.call( this );\n\n\t\tthis.name = name;\n\n\t\tthis.$buttons = $( '<div>' ).addClass( 'mediauploader-buttons' );\n\n\t\tthis.$div = $( '<div>' )\n\t\t\t.attr( 'id', 'mediauploader-stepdiv-' + this.name )\n\t\t\t.addClass( 'mediauploader-stepdiv' )\n\t\t\t.hide();\n\n\t\t// eslint-disable-next-line no-jquery/no-global-selector\n\t\t$( '#mediauploader-content' ).append( this.$div );\n\n\t\t// this will make sure that buttons will only be added if they've been\n\t\t// set in the controller, otherwise there's nowhere to go...\n\t\tthis.nextButtonPromise = $.Deferred();\n\t\tthis.previousButtonPromise = $.Deferred();\n\t};\n\n\tOO.mixinClass( uw.ui.Step, OO.EventEmitter );\n\n\t/**\n\t * Initialize this step.\n\t *\n\t * @param {mw.UploadWizardUpload[]} uploads\n\t */\n\tuw.ui.Step.prototype.load = function ( uploads ) {\n\t\t// eslint-disable-next-line no-jquery/no-global-selector\n\t\tconst offset = $( 'h1' ).first().offset();\n\n\t\tthis.movedFrom = false;\n\n\t\tthis.uploads = uploads;\n\t\tthis.$div.append( this.$buttons ).show();\n\n\t\t// eslint-disable-next-line no-jquery/no-global-selector\n\t\t$( 'html, body' ).animate( {\n\t\t\tscrollTop: offset.top,\n\t\t\tscrollLeft: offset.left\n\t\t}, 'slow' );\n\t};\n\n\t/**\n\t * Cleanup this step.\n\t */\n\tuw.ui.Step.prototype.unload = function () {\n\t\tthis.movedFrom = true;\n\n\t\tthis.$div.children().detach();\n\t};\n\n\tuw.ui.Step.prototype.enableNextButton = function () {\n\t\tthis.nextButtonPromise.resolve();\n\t};\n\n\tuw.ui.Step.prototype.enablePreviousButton = function () {\n\t\tthis.previousButtonPromise.resolve();\n\t};\n\n\t/**\n\t * Add a 'next' button to the step's button container\n\t */\n\tuw.ui.Step.prototype.addNextButton = function () {\n\t\tconst ui = this;\n\n\t\tthis.nextButton = new OO.ui.ButtonWidget( {\n\t\t\tclasses: [ 'mediauploader-button-next' ],\n\t\t\tlabel: mw.message( 'mediauploader-next' ).text(),\n\t\t\tflags: [ 'progressive', 'primary' ]\n\t\t} ).on( 'click', () => {\n\t\t\tui.emit( 'next-step' );\n\t\t} );\n\n\t\tthis.nextButtonPromise.done( () => {\n\t\t\tui.$buttons.append( ui.nextButton.$element );\n\t\t} );\n\t};\n\n\t/**\n\t * Add a 'previous' button to the step's button container\n\t */\n\tuw.ui.Step.prototype.addPreviousButton = function () {\n\t\tconst ui = this;\n\n\t\tthis.previousButton = new OO.ui.ButtonWidget( {\n\t\t\tclasses: [ 'mediauploader-button-previous' ],\n\t\t\tlabel: mw.message( 'mediauploader-previous' ).text()\n\t\t} ).on( 'click', () => {\n\t\t\tui.emit( 'previous-step' );\n\t\t} );\n\n\t\tthis.previousButtonPromise.done( () => {\n\t\t\tui.$buttons.append( ui.previousButton.$element );\n\t\t} );\n\t};\n}( mw.uploadWizard ) );\n","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-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/resources/ui/uw.ui.Wizard.js","messages":[],"suppressedMessages":[{"ruleId":"no-jquery/no-global-selector","severity":2,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":49,"column":23,"nodeType":"CallExpression","endLine":49,"endColumn":41,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-sizzle","severity":2,"message":"Positional selector extensions are not allowed","line":66,"column":3,"nodeType":"CallExpression","endLine":66,"endColumn":51,"suppressions":[{"kind":"directive","justification":""}]}],"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-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/resources/ui/uw.ui.base.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-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/resources/uw.ConcurrentQueue.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'index' is never reassigned. Use 'const' instead.","line":117,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":117,"endColumn":8},{"ruleId":"prefer-const","severity":2,"message":"'item' is never reassigned. Use 'const' instead.","line":139,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":139,"endColumn":7},{"ruleId":"prefer-const","severity":2,"message":"'promise' is never reassigned. Use 'const' instead.","line":145,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":145,"endColumn":10}],"suppressedMessages":[],"errorCount":3,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"( function ( uw ) {\n\n\t/**\n\t * A queue that will execute the asynchronous function `action` for each item in the queue in\n\t * order, taking care not to allow more than `count` instances to be executing at the same time.\n\t *\n\t * Items can be added or removed (#addItem, #removeItem) while the queue is already being\n\t * executed.\n\t *\n\t * @param {Object} options\n\t * @param {Function} options.action Action to execute for each item, must return a Promise\n\t * @param {number} options.count Number of functions to execute concurrently\n\t */\n\tuw.ConcurrentQueue = function UWConcurrentQueue( options ) {\n\t\tOO.EventEmitter.call( this );\n\n\t\tthis.count = options.count;\n\t\tthis.action = options.action;\n\n\t\tthis.queued = [];\n\t\tthis.running = [];\n\t\tthis.done = [];\n\t\tthis.runningPromises = [];\n\n\t\tthis.completed = false;\n\t\tthis.executing = false;\n\t};\n\tOO.initClass( uw.ConcurrentQueue );\n\tOO.mixinClass( uw.ConcurrentQueue, OO.EventEmitter );\n\n\t/**\n\t * A 'progress' event is emitted when one of the functions' promises is resolved or rejected.\n\t *\n\t * @event progress\n\t */\n\n\t/**\n\t * A 'complete' event is emitted when all of the functions' promises have been resolved or rejected.\n\t *\n\t * @event complete\n\t */\n\n\t/**\n\t * A 'change' event is emitted when an item is added to or removed from the queue.\n\t *\n\t * @event change\n\t */\n\n\t/**\n\t * Add an item to the queue.\n\t *\n\t * @param {Object} item\n\t * @return {boolean} true\n\t */\n\tuw.ConcurrentQueue.prototype.addItem = function ( item ) {\n\t\tthis.queued.push( item );\n\t\tthis.emit( 'change' );\n\t\tif ( this.executing ) {\n\t\t\tthis.executeNext();\n\t\t}\n\t\treturn true;\n\t};\n\n\t/**\n\t * Remove an item from the queue.\n\t *\n\t * While it's possible to remove an item that is being executed, it doesn't stop the execution.\n\t *\n\t * @param {Object} item\n\t * @return {boolean} Whether the item was removed\n\t */\n\tuw.ConcurrentQueue.prototype.removeItem = function ( item ) {\n\t\tlet index, found;\n\n\t\tfound = false;\n\n\t\tindex = this.queued.indexOf( item );\n\t\tif ( index !== -1 ) {\n\t\t\tthis.queued.splice( index, 1 );\n\t\t\tfound = true;\n\t\t}\n\n\t\tindex = this.done.indexOf( item );\n\t\tif ( index !== -1 ) {\n\t\t\tthis.done.splice( index, 1 );\n\t\t\tfound = true;\n\t\t}\n\n\t\tindex = this.running.indexOf( item );\n\t\tif ( index !== -1 ) {\n\t\t\t// Try aborting the promise if possible\n\t\t\tif ( this.runningPromises[ index ].abort ) {\n\t\t\t\tthis.runningPromises[ index ].abort();\n\t\t\t}\n\t\t\tthis.running.splice( index, 1 );\n\t\t\tthis.runningPromises.splice( index, 1 );\n\t\t\tfound = true;\n\t\t}\n\n\t\tif ( found ) {\n\t\t\tthis.emit( 'change' );\n\t\t\tthis.checkIfComplete();\n\t\t}\n\n\t\t// Ensure we're still using as many threads as requested\n\t\tthis.executeNext();\n\n\t\treturn found;\n\t};\n\n\t/**\n\t * @private\n\t * @param {Object} item\n\t */\n\tuw.ConcurrentQueue.prototype.promiseComplete = function ( item ) {\n\t\tlet index;\n\t\tindex = this.running.indexOf( item );\n\t\t// Check that this item wasn't removed while it was being executed\n\t\tif ( index !== -1 ) {\n\t\t\tthis.running.splice( index, 1 );\n\t\t\tthis.runningPromises.splice( index, 1 );\n\t\t\tthis.done.push( item );\n\t\t\tthis.emit( 'progress' );\n\t\t}\n\n\t\tthis.checkIfComplete();\n\n\t\tthis.executeNext();\n\t};\n\n\t/**\n\t * @private\n\t */\n\tuw.ConcurrentQueue.prototype.executeNext = function () {\n\t\tlet item, promise;\n\t\tif ( this.running.length === this.count || !this.executing ) {\n\t\t\treturn;\n\t\t}\n\t\titem = this.queued.shift();\n\t\tif ( !item ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.running.push( item );\n\t\tpromise = this.action.call( null, item );\n\t\tthis.runningPromises.push( promise );\n\t\tpromise.always( this.promiseComplete.bind( this, item ) );\n\t};\n\n\t/**\n\t * Start executing the queue. If the queue is already executing, do nothing.\n\t *\n\t * When the queue finishes executing, a 'complete' event will be emitted.\n\t */\n\tuw.ConcurrentQueue.prototype.startExecuting = function () {\n\t\tlet i;\n\t\tif ( this.executing ) {\n\t\t\treturn;\n\t\t}\n\t\tthis.completed = false;\n\t\tthis.executing = true;\n\t\tfor ( i = 0; i < this.count; i++ ) {\n\t\t\tthis.executeNext();\n\t\t}\n\t\t// In case the queue was empty\n\t\tthis.checkIfComplete();\n\t};\n\n\t/**\n\t * Abort executing the queue. Remove all queued items and abort running ones.\n\t */\n\tuw.ConcurrentQueue.prototype.abortExecuting = function () {\n\t\twhile ( this.queued.length > 0 ) {\n\t\t\tthis.removeItem( this.queued[ 0 ] );\n\t\t}\n\t\twhile ( this.running.length > 0 ) {\n\t\t\tthis.removeItem( this.running[ 0 ] );\n\t\t}\n\t};\n\n\t/**\n\t * @private\n\t */\n\tuw.ConcurrentQueue.prototype.checkIfComplete = function () {\n\t\tif ( this.running.length === 0 && this.queued.length === 0 ) {\n\t\t\tif ( !this.completed ) {\n\t\t\t\tthis.completed = true;\n\t\t\t\tthis.executing = false;\n\t\t\t\tthis.emit( 'complete' );\n\t\t\t}\n\t\t}\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/uw.CopyMetadataWidget.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'checkboxes' is never reassigned. Use 'const' instead.","line":14,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":14,"endColumn":14},{"ruleId":"prefer-const","severity":2,"message":"'$copyMetadataWrapperDiv' is never reassigned. Use 'const' instead.","line":15,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":15,"endColumn":27},{"ruleId":"prefer-const","severity":2,"message":"'$copyMetadataDiv' is never reassigned. Use 'const' instead.","line":16,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":16,"endColumn":20},{"ruleId":"prefer-const","severity":2,"message":"'uploads' is never reassigned. Use 'const' instead.","line":157,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":157,"endColumn":11},{"ruleId":"prefer-const","severity":2,"message":"'sourceUpload' is never reassigned. Use 'const' instead.","line":158,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":158,"endColumn":16},{"ruleId":"prefer-const","severity":2,"message":"'serialized' is never reassigned. Use 'const' instead.","line":159,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":159,"endColumn":14},{"ruleId":"prefer-const","severity":2,"message":"'sourceValue' is never reassigned. Use 'const' instead.","line":161,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":161,"endColumn":15},{"ruleId":"prefer-const","severity":2,"message":"'uploads' is never reassigned. Use 'const' instead.","line":214,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":214,"endColumn":11}],"suppressedMessages":[{"ruleId":"no-jquery/no-fade","severity":2,"message":"Prefer CSS transitions to .fadeOut","line":127,"column":3,"nodeType":"CallExpression","endLine":130,"endColumn":30,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-fade","severity":2,"message":"Prefer CSS transitions to .fadeOut","line":144,"column":3,"nodeType":"CallExpression","endLine":147,"endColumn":30,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-loop-func","severity":2,"message":"Function declared in a loop contains unsafe references to variable(s) 'i'.","line":196,"column":6,"nodeType":"ArrowFunctionExpression","messageId":"unsafeRefs","endLine":200,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":8,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"( function ( uw ) {\n\n\t/**\n\t * Metadata copier in UploadWizard's \"Details\" step form.\n\t *\n\t * @extends OO.ui.Widget\n\t * @constructor\n\t * @param {Object} [config] Configuration options\n\t * @cfg {mw.UploadWizardUpload} copyFrom Upload to copy the details from\n\t * @cfg {mw.UploadWizardUpload[]} copyTo Uploads to copy the details to\n\t */\n\tuw.CopyMetadataWidget = function UWCopyMetadataWidget( config ) {\n\t\tlet metadataType, defaultStatus, copyMetadataMsg,\n\t\t\tcheckboxes = [],\n\t\t\t$copyMetadataWrapperDiv = $( '<div>' ),\n\t\t\t$copyMetadataDiv = $( '<div>' );\n\n\t\tuw.CopyMetadataWidget.parent.call( this );\n\n\t\tthis.copyFrom = config.copyFrom;\n\t\tthis.copyTo = config.copyTo;\n\t\tthis.savedSerializedData = [];\n\n\t\tfor ( metadataType in uw.CopyMetadataWidget.static.copyMetadataTypes ) {\n\t\t\tif ( Object.prototype.hasOwnProperty.call( uw.CopyMetadataWidget.static.copyMetadataTypes, metadataType ) ) {\n\t\t\t\tdefaultStatus = uw.CopyMetadataWidget.static.copyMetadataTypes[ metadataType ];\n\t\t\t\t// Messages that can be used here:\n\t\t\t\t// * mediauploader-copy-title\n\t\t\t\t// * mediauploader-copy-description\n\t\t\t\t// * mediauploader-copy-date\n\t\t\t\t// * mediauploader-copy-categories\n\t\t\t\t// * mediauploader-copy-location\n\t\t\t\t// * mediauploader-copy-other\n\t\t\t\tcopyMetadataMsg = mw.message( 'mediauploader-copy-' + metadataType ).text();\n\n\t\t\t\tcheckboxes.push( new OO.ui.CheckboxMultioptionWidget( {\n\t\t\t\t\tdata: metadataType,\n\t\t\t\t\tlabel: copyMetadataMsg,\n\t\t\t\t\tselected: defaultStatus\n\t\t\t\t} ) );\n\t\t\t}\n\t\t}\n\n\t\tthis.$success = $( '<span>' );\n\t\tthis.checkboxesWidget = new OO.ui.CheckboxMultiselectWidget( {\n\t\t\titems: checkboxes\n\t\t} );\n\t\tthis.copyButton = new OO.ui.ButtonWidget( {\n\t\t\tlabel: mw.message( 'mediauploader-copy-metadata-button' ).text(),\n\t\t\tflags: [ 'progressive' ]\n\t\t} );\n\t\tthis.undoButton = new OO.ui.ButtonWidget( {\n\t\t\tlabel: mw.message( 'mediauploader-copy-metadata-button-undo' ).text()\n\t\t} );\n\n\t\tthis.checkboxesWidget.connect( this, {\n\t\t\tselect: 'onCheckboxesSelect'\n\t\t} );\n\t\tthis.copyButton.connect( this, {\n\t\t\tclick: 'onCopyClick'\n\t\t} );\n\t\tthis.undoButton.connect( this, {\n\t\t\tclick: 'onUndoClick'\n\t\t} );\n\n\t\tthis.undoButton.toggle( false );\n\t\t$copyMetadataDiv.append(\n\t\t\tthis.checkboxesWidget.$element,\n\t\t\tthis.copyButton.$element,\n\t\t\tthis.undoButton.$element,\n\t\t\tthis.$success\n\t\t);\n\n\t\t$copyMetadataWrapperDiv\n\t\t\t.append(\n\t\t\t\t$( '<a>' ).text( mw.msg( 'mediauploader-copy-metadata' ) )\n\t\t\t\t\t.prepend( $( '<span>' ).addClass( 'mw-toggle-icon' ) )\n\t\t\t\t\t.addClass( 'mediauploader-details-copy-metadata mw-collapsible-toggle' ),\n\t\t\t\t$copyMetadataDiv.addClass( 'mw-collapsible-content' )\n\t\t\t)\n\t\t\t.makeCollapsible( { collapsed: true } );\n\n\t\tthis.$element\n\t\t\t.addClass( 'mediauploader-copyMetadataWidget' )\n\t\t\t.append( $copyMetadataWrapperDiv );\n\t};\n\tOO.inheritClass( uw.CopyMetadataWidget, OO.ui.Widget );\n\n\t/**\n\t * Metadata which we can copy over to other details objects.\n\t *\n\t * Object with key: metadata name and value: boolean value indicating default checked status\n\t *\n\t * @property {Object}\n\t * @static\n\t */\n\tuw.CopyMetadataWidget.static.copyMetadataTypes = {\n\t\ttitle: true,\n\t\tdescription: true,\n\t\tdate: false,\n\t\tcategories: true,\n\t\tlocation: false,\n\t\tother: true\n\t};\n\n\t/**\n\t * Checkbox multiselect widget select event handler.\n\t *\n\t * @private\n\t */\n\tuw.CopyMetadataWidget.prototype.onCheckboxesSelect = function () {\n\t\tthis.copyButton.setDisabled( this.checkboxesWidget.findSelectedItemsData().length === 0 );\n\t};\n\n\t/**\n\t * Button click event handler.\n\t *\n\t * @private\n\t */\n\tuw.CopyMetadataWidget.prototype.onCopyClick = function () {\n\t\tconst metadataTypes = this.checkboxesWidget.findSelectedItemsData();\n\t\tthis.copyMetadata( metadataTypes );\n\n\t\tthis.undoButton.toggle( true );\n\t\t// FIXME: Use CSS transition\n\t\t// eslint-disable-next-line no-jquery/no-fade\n\t\tthis.$success\n\t\t\t.text( mw.message( 'mediauploader-copied-metadata' ).text() )\n\t\t\t.show()\n\t\t\t.fadeOut( 5000, 'linear' );\n\t};\n\n\t/**\n\t * Button click event handler.\n\t *\n\t * @private\n\t */\n\tuw.CopyMetadataWidget.prototype.onUndoClick = function () {\n\t\tthis.restoreMetadata();\n\n\t\tthis.undoButton.toggle( false );\n\t\t// FIXME: Use CSS transition\n\t\t// eslint-disable-next-line no-jquery/no-fade\n\t\tthis.$success\n\t\t\t.text( mw.message( 'mediauploader-undid-metadata' ).text() )\n\t\t\t.show()\n\t\t\t.fadeOut( 5000, 'linear' );\n\t};\n\n\t/**\n\t * Copy metadata from the first upload to other uploads.\n\t *\n\t * @param {string[]} metadataTypes Types to copy, as defined in the copyMetadataTypes property\n\t */\n\tuw.CopyMetadataWidget.prototype.copyMetadata = function ( metadataTypes ) {\n\t\tlet titleZero, matches, i,\n\t\t\tuploads = this.copyTo,\n\t\t\tsourceUpload = this.copyFrom,\n\t\t\tserialized = sourceUpload.details.getSerialized(),\n\t\t\t// Values to copy\n\t\t\tsourceValue = {},\n\t\t\t// Checks for extra behaviors\n\t\t\tcopyingTitle = false,\n\t\t\tcopyingOther = false;\n\n\t\t// Filter serialized data to only the types we want to copy\n\t\tmetadataTypes.forEach( ( type ) => {\n\t\t\tsourceValue[ type ] = serialized[ type ];\n\t\t\tcopyingTitle = copyingTitle || type === 'title';\n\t\t\tcopyingOther = copyingOther || type === 'other';\n\t\t} );\n\n\t\tif ( copyingOther ) {\n\t\t\t// Campaign fields are grouped with this, hmph\n\t\t\tsourceValue.campaigns = serialized.campaigns;\n\t\t}\n\n\t\tif ( copyingTitle ) {\n\t\t\ttitleZero = sourceValue.title.title;\n\t\t\t// Add number suffix to first title if no numbering present\n\t\t\tmatches = titleZero.match( /(\\D+)(\\d{1,3})(\\.\\D*)?$/ );\n\t\t\tif ( matches === null ) {\n\t\t\t\ttitleZero = titleZero + ' 01';\n\t\t\t}\n\t\t}\n\n\t\t// And apply\n\t\tfor ( i = 0; i < uploads.length; i++ ) {\n\t\t\tif ( copyingTitle ) {\n\t\t\t\t// Overwrite remaining title inputs with first title + increment of rightmost\n\t\t\t\t// number in the title. Note: We ignore numbers with more than three digits, because these\n\t\t\t\t// are more likely to be years (\"Wikimania 2011 Celebration\") or other non-sequence\n\t\t\t\t// numbers.\n\t\t\t\tsourceValue.title.title = titleZero.replace( /(\\D+)(\\d{1,3})(\\D*)$/,\n\t\t\t\t\t// eslint-disable-next-line no-loop-func\n\t\t\t\t\t( str, m1, m2, m3 ) => {\n\t\t\t\t\t\tconst newstr = String( +m2 + i );\n\t\t\t\t\t\treturn m1 + new Array( m2.length + 1 - newstr.length )\n\t\t\t\t\t\t\t.join( '0' ) + newstr + m3;\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tthis.savedSerializedData[ i ] = uploads[ i ].details.getSerialized();\n\t\t\tuploads[ i ].details.setSerialized( sourceValue );\n\t\t}\n\t};\n\n\t/**\n\t * Restore previously saved metadata that we backed up when copying.\n\t */\n\tuw.CopyMetadataWidget.prototype.restoreMetadata = function () {\n\t\tlet i,\n\t\t\tuploads = this.copyTo;\n\n\t\tfor ( i = 0; i < uploads.length; i++ ) {\n\t\t\tuploads[ i ].details.setSerialized( this.savedSerializedData[ i ] );\n\t\t}\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/uw.DetailsWidget.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-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/resources/uw.FieldLayout.js","messages":[{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":20,"column":12,"nodeType":"MemberExpression","messageId":"forbidden","endLine":20,"endColumn":25}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"( function ( uw ) {\n\n\t/**\n\t * FieldLayout with some UploadWizard-specific bonuses.\n\t *\n\t * @extends OO.ui.FieldLayout\n\t *\n\t * @constructor\n\t * @inheritdoc\n\t * @param {OO.ui.Widget} fieldWidget\n\t * @param {Object} [config]\n\t * @param {boolean} [config.required=false] Whether to mark this field as required\n\t * @param {boolean} [config.align='top']\n\t */\n\tuw.FieldLayout = function UWFieldLayout( fieldWidget, config ) {\n\t\t// FieldLayout will add an icon which, when clicked, reveals more information\n\t\t// about the input. We'll want to display that by default, so we're getting\n\t\t// rid of the \"help\" property here & will later append that after the header\n\t\tconst help = config && config.help ? config.help : '';\n\t\tconfig = Object.assign( { align: 'top', required: false }, config, { help: '' } );\n\n\t\tuw.FieldLayout.parent.call( this, fieldWidget, config );\n\t\tuw.ValidationMessageElement.call( this, { validatedWidget: fieldWidget } );\n\n\t\tthis.required = null;\n\t\tthis.optionalMarker = new OO.ui.LabelWidget( {\n\t\t\tclasses: [ 'mediauploader-fieldLayout-indicator' ],\n\t\t\tlabel: mw.msg( 'mediauploader-label-optional' )\n\t\t} );\n\n\t\tthis.$element.addClass( 'mediauploader-fieldLayout' );\n\n\t\tthis.$element.addClass( 'mediauploader-details-fieldname-input' );\n\t\tthis.$label.addClass( 'mediauploader-details-fieldname' );\n\t\tthis.$field.addClass( 'mediauploader-details-input' );\n\n\t\tif ( help ) {\n\t\t\tthis.help = new OO.ui.LabelWidget( { label: help } );\n\t\t\tthis.$header.after( this.help.$element.addClass( 'mediauploader-details-help' ) );\n\t\t}\n\n\t\tthis.setRequired( config.required );\n\t};\n\tOO.inheritClass( uw.FieldLayout, OO.ui.FieldLayout );\n\tOO.mixinClass( uw.FieldLayout, uw.ValidationMessageElement );\n\n\t/**\n\t * @param {boolean} required Whether to mark this field as required\n\t */\n\tuw.FieldLayout.prototype.setRequired = function ( required ) {\n\t\tthis.required = !!required;\n\t\t// only add 'optional' marker after the label if that label\n\t\t// has content...\n\t\tif ( !this.required && this.$label.text() !== '' ) {\n\t\t\tthis.$header.after( this.optionalMarker.$element );\n\t\t} else {\n\t\t\tthis.optionalMarker.$element.remove();\n\t\t}\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/uw.LicenseGroup.js","messages":[{"ruleId":"es-x/no-object-assign","severity":1,"message":"ES2015 'Object.assign' method is forbidden.","line":37,"column":17,"nodeType":"MemberExpression","messageId":"forbidden","endLine":37,"endColumn":30},{"ruleId":"prefer-const","severity":2,"message":"'option' is never reassigned. Use 'const' instead.","line":132,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":132,"endColumn":10},{"ruleId":"prefer-const","severity":2,"message":"'option' is never reassigned. Use 'const' instead.","line":167,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":167,"endColumn":10},{"ruleId":"prefer-const","severity":2,"message":"'self' is never reassigned. Use 'const' instead.","line":191,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":191,"endColumn":8},{"ruleId":"prefer-const","severity":2,"message":"'values' is never reassigned. Use 'const' instead.","line":192,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":192,"endColumn":10},{"ruleId":"prefer-const","severity":2,"message":"'wikiTexts' is never reassigned. Use 'const' instead.","line":194,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":194,"endColumn":12},{"ruleId":"prefer-const","severity":2,"message":"'value' is never reassigned. Use 'const' instead.","line":196,"column":5,"nodeType":"Identifier","messageId":"useConst","endLine":196,"endColumn":10},{"ruleId":"prefer-const","severity":2,"message":"'self' is never reassigned. Use 'const' instead.","line":222,"column":7,"nodeType":"Identifier","messageId":"useConst","endLine":222,"endColumn":11},{"ruleId":"prefer-const","severity":2,"message":"'result' is never reassigned. Use 'const' instead.","line":223,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":223,"endColumn":10},{"ruleId":"prefer-const","severity":2,"message":"'self' is never reassigned. Use 'const' instead.","line":248,"column":7,"nodeType":"Identifier","messageId":"useConst","endLine":248,"endColumn":11},{"ruleId":"prefer-const","severity":2,"message":"'selectArray' is never reassigned. Use 'const' instead.","line":249,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":249,"endColumn":15},{"ruleId":"prefer-const","severity":2,"message":"'licenseInfo' is never reassigned. Use 'const' instead.","line":303,"column":7,"nodeType":"Identifier","messageId":"useConst","endLine":303,"endColumn":18},{"ruleId":"prefer-const","severity":2,"message":"'licenseText' is never reassigned. Use 'const' instead.","line":306,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":306,"endColumn":14},{"ruleId":"prefer-const","severity":2,"message":"'licenseInfo' is never reassigned. Use 'const' instead.","line":319,"column":7,"nodeType":"Identifier","messageId":"useConst","endLine":319,"endColumn":18},{"ruleId":"prefer-const","severity":2,"message":"'messageKey' is never reassigned. Use 'const' instead.","line":320,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":320,"endColumn":14},{"ruleId":"prefer-const","severity":2,"message":"'languageCode' is never reassigned. Use 'const' instead.","line":323,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":323,"endColumn":16},{"ruleId":"prefer-const","severity":2,"message":"'$icons' is never reassigned. Use 'const' instead.","line":328,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":328,"endColumn":10},{"ruleId":"prefer-const","severity":2,"message":"'$licenseLink' is never reassigned. Use 'const' instead.","line":334,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":334,"endColumn":15},{"ruleId":"prefer-const","severity":2,"message":"'$label' is never reassigned. Use 'const' instead.","line":343,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":343,"endColumn":9},{"ruleId":"prefer-const","severity":2,"message":"'self' is never reassigned. Use 'const' instead.","line":361,"column":7,"nodeType":"Identifier","messageId":"useConst","endLine":361,"endColumn":11},{"ruleId":"prefer-const","severity":2,"message":"'button' is never reassigned. Use 'const' instead.","line":372,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":372,"endColumn":9},{"ruleId":"prefer-const","severity":2,"message":"'input' is never reassigned. Use 'const' instead.","line":397,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":397,"endColumn":8},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":413,"column":3,"nodeType":"CallExpression","endLine":413,"endColumn":57},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .fail","line":413,"column":3,"nodeType":"CallExpression","endLine":413,"endColumn":71}],"suppressedMessages":[{"ruleId":"mediawiki/msg-doc","severity":1,"message":"All possible message keys should be documented. See https://w.wiki/4r9a for details.","line":89,"column":37,"nodeType":"CallExpression","endLine":91,"endColumn":41,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"mediawiki/msg-doc","severity":1,"message":"All possible message keys should be documented. See https://w.wiki/4r9a for details.","line":93,"column":38,"nodeType":"CallExpression","endLine":95,"endColumn":44,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"mediawiki/class-doc","severity":1,"message":"All possible CSS classes should be documented. See https://w.wiki/PS2 for details.","line":148,"column":39,"nodeType":"ObjectExpression","endLine":148,"endColumn":75,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"mediawiki/class-doc","severity":1,"message":"All possible CSS classes should be documented. See https://w.wiki/PS2 for details.","line":183,"column":47,"nodeType":"ObjectExpression","endLine":183,"endColumn":83,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"mediawiki/class-doc","severity":1,"message":"All possible CSS classes should be documented. See https://w.wiki/PS2 for details.","line":338,"column":20,"nodeType":"CallExpression","endLine":338,"endColumn":106,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"mediawiki/msg-doc","severity":1,"message":"All possible message keys should be documented. See https://w.wiki/4r9a for details.","line":343,"column":12,"nodeType":"CallExpression","endLine":344,"endColumn":53,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":23,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"( function ( uw ) {\n\n\t/**\n\t * @extends OO.ui.LicenseGroup\n\t *\n\t * @constructor\n\t * @inheritdoc\n\t * @param {Object} config License configuration\n\t * @param {Array} config.licenses Array of license names\n\t * @param {string} [config.head] Header for the group of licenses (if present, the group of\n\t * licenses will be collapsed and this will be the clickable title to expand the group)\n\t * @param {string} [config.subhead] Subtitle for the group of licenses\n\t * @param {string} [config.special] 'custom' if a text input field should be added\n\t * @param {string} [config.licenseWikitext] Wraps the wikitext of ONE license, $1 is the license.\n\t * '$1' by default.\n\t * @param {string} [config.licenseSeparator] Used for joining several licenses wrapped by\n\t * 'licenseWikitext'. ' ' by default.\n\t * @param {string} [config.wrapper] Wraps the list of licenses. $1 – licenses, $2 – number of licenses.\n\t * '$1' by default.\n\t * @param {string} type 'radio' or 'checkbox'\n\t * @param {mw.Api} api API object, used for wikitext previews\n\t * @param {number} count Number of the things we are licensing (it matters to some texts)\n\t */\n\tuw.LicenseGroup = function UWLicenseGroup( config, type, api, count ) {\n\t\tconst self = this;\n\n\t\tuw.LicenseGroup.parent.call( this, {} );\n\n\t\tif ( typeof config.licenses !== 'object' ) {\n\t\t\tthrow new Error( 'improper license config' );\n\t\t}\n\n\t\tif ( ![ 'radio', 'checkbox' ].includes( type ) ) {\n\t\t\tthrow new Error( 'Invalid type: ' + type );\n\t\t}\n\n\t\tthis.config = Object.assign( {\n\t\t\tlicenseWikitext: '$1',\n\t\t\tlicenseSeparator: ' ',\n\t\t\twrapper: '$1'\n\t\t}, config );\n\t\tthis.type = type;\n\t\tthis.api = api;\n\t\tthis.count = count;\n\t\tthis.collapsible = !!this.config.head;\n\t\tthis.textareas = {};\n\t\tthis.previewDialog = new uw.LicensePreviewDialog();\n\t\tthis.windowManager = new OO.ui.WindowManager();\n\t\tthis.windowManager.addWindows( [ this.previewDialog ] );\n\t\t$( document.body ).append( this.windowManager.$element );\n\n\t\tif ( this.type === 'radio' ) {\n\t\t\tthis.group = this.createRadioGroup( [ 'mediauploader-deed-license-group-body' ] );\n\t\t\tthis.group.connect( this, { choose: [ 'emit', 'change', this ] } );\n\t\t} else if ( this.type === 'checkbox' ) {\n\t\t\tthis.group = this.createCheckboxGroup( [ 'mediauploader-deed-license-group-body' ] );\n\t\t\tthis.group.connect( this, { select: [ 'emit', 'change', this ] } );\n\t\t}\n\n\t\t// when selecting an item that has a custom textarea, we'll immediately focus it\n\t\tthis.on( 'change', ( group, item ) => {\n\t\t\tif ( item && item.isSelected && item.isSelected() ) {\n\t\t\t\t// wrapped inside setTimeout to ensure it goes at the end of the call stack,\n\t\t\t\t// just in case something steals focus in the meantime...\n\t\t\t\tsetTimeout( () => {\n\t\t\t\t\tconst name = item.getData();\n\t\t\t\t\tif ( self.textareas[ name ] ) {\n\t\t\t\t\t\tself.textareas[ name ].focus();\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\n\t\tthis.fieldset = this.createFieldset( this.group );\n\t\tthis.$element = this.fieldset.$element;\n\t};\n\tOO.inheritClass( uw.LicenseGroup, OO.ui.Widget );\n\n\tuw.LicenseGroup.prototype.unload = function () {\n\t\tthis.windowManager.$element.remove();\n\t};\n\n\t/**\n\t * @param {OO.ui.RadioSelectWidget|OO.ui.CheckboxMultiselectInputWidget} group\n\t * @return {OO.ui.FieldsetLayout}\n\t */\n\tuw.LicenseGroup.prototype.createFieldset = function ( group ) {\n\t\t/* eslint-disable mediawiki/msg-doc */\n\t\tconst $head = this.config.head && $( '<a>' )\n\t\t\t\t.addClass( 'mediauploader-deed-license-group-head' )\n\t\t\t\t.msg( this.config.head, this.count )\n\t\t\t\t.prepend( $( '<span>' ).addClass( 'mw-toggle-icon' ) ),\n\t\t\t$subhead = this.config.subhead && $( '<div>' )\n\t\t\t\t.addClass( 'mediauploader-deed-license-group-subhead' )\n\t\t\t\t.msg( this.config.subhead, this.count ),\n\t\t\tfieldset = new OO.ui.FieldsetLayout( {\n\t\t\t\tlabel: $head,\n\t\t\t\titems: [ group ],\n\t\t\t\tclasses: [ 'mediauploader-deed-license-group' ]\n\t\t\t} );\n\t\t/* eslint-enable mediawiki/msg-doc */\n\n\t\tif ( this.collapsible ) {\n\t\t\tfieldset.$group.makeCollapsible( { collapsed: true, $customTogglers: $head, toggleClasses: true } );\n\t\t}\n\t\tif ( this.config.subhead ) {\n\t\t\tfieldset.addItems(\n\t\t\t\t[ new OO.ui.FieldLayout( new OO.ui.Widget( { content: [] } ), { label: $subhead, align: 'top' } ) ],\n\t\t\t\t0 // = index; add to top\n\t\t\t);\n\t\t}\n\n\t\treturn fieldset;\n\t};\n\n\t/**\n\t * @param {Array} classes to add\n\t * @return {OO.ui.RadioSelectWidget}\n\t */\n\tuw.LicenseGroup.prototype.createRadioGroup = function ( classes ) {\n\t\tconst self = this,\n\t\t\toptions = [];\n\n\t\tthis.config.licenses.forEach( ( licenseName ) => {\n\t\t\tlet option;\n\n\t\t\tif ( mw.UploadWizard.config.licenses[ licenseName ] === undefined ) {\n\t\t\t\t// unknown license\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\toption = new OO.ui.RadioOptionWidget( {\n\t\t\t\tlabel: self.createLabel( licenseName ),\n\t\t\t\tdata: licenseName\n\t\t\t} );\n\n\t\t\t// when custom text area receives focus, we should make sure this element is selected\n\t\t\tif ( self.textareas[ licenseName ] ) {\n\t\t\t\tself.textareas[ licenseName ].on( 'focus', () => {\n\t\t\t\t\toption.setSelected( true );\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\toptions.push( option );\n\t\t} );\n\n\t\t// eslint-disable-next-line mediawiki/class-doc\n\t\treturn new OO.ui.RadioSelectWidget( { items: options, classes: classes } );\n\t};\n\n\t/**\n\t * @param {Array} classes to add\n\t * @return {OO.ui.CheckboxMultiselectInputWidget}\n\t */\n\tuw.LicenseGroup.prototype.createCheckboxGroup = function ( classes ) {\n\t\tconst self = this,\n\t\t\toptions = [];\n\n\t\tthis.config.licenses.forEach( ( licenseName ) => {\n\t\t\tlet option;\n\n\t\t\tif ( mw.UploadWizard.config.licenses[ licenseName ] === undefined ) {\n\t\t\t\t// unknown license\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\toption = new OO.ui.CheckboxMultioptionWidget( {\n\t\t\t\tlabel: self.createLabel( licenseName ),\n\t\t\t\tdata: licenseName\n\t\t\t} );\n\n\t\t\t// when custom text area receives focus, we should make sure this element is selected\n\t\t\tif ( self.textareas[ licenseName ] ) {\n\t\t\t\tself.textareas[ licenseName ].on( 'focus', () => {\n\t\t\t\t\toption.setSelected( true );\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\toptions.push( option );\n\t\t} );\n\n\t\t// eslint-disable-next-line mediawiki/class-doc\n\t\treturn new OO.ui.CheckboxMultiselectWidget( { items: options, classes: classes } );\n\t};\n\n\t/**\n\t * @return {string}\n\t */\n\tuw.LicenseGroup.prototype.getWikiText = function () {\n\t\tlet wikiTexts,\n\t\t\tself = this,\n\t\t\tvalues = this.getValue();\n\n\t\twikiTexts = Object.keys( values ).map( ( name ) => {\n\t\t\tlet wikiText = self.getLicenseWikiText( name ),\n\t\t\t\tvalue = values[ name ];\n\t\t\tif ( typeof value === 'string' ) {\n\t\t\t\t// `value` is custom input\n\t\t\t\twikiText += '\\n' + value.trim();\n\t\t\t}\n\t\t\treturn wikiText.trim();\n\t\t} );\n\n\t\treturn this.config.wrapper\n\t\t\t.replace( '$1', wikiTexts.join( this.config.licenseSeparator ).trim() )\n\t\t\t.replace( '$2', Object.keys( values ).length.toString() );\n\t};\n\n\t/**\n\t * Returns a string unique to the group (if defined)\n\t *\n\t * @return {string}\n\t */\n\tuw.LicenseGroup.prototype.getGroup = function () {\n\t\treturn this.config.head || '';\n\t};\n\n\t/**\n\t * @return {Object} Map of { licenseName: true }, or { licenseName: \"custom input\" }\n\t */\n\tuw.LicenseGroup.prototype.getValue = function () {\n\t\tlet self = this,\n\t\t\tresult = {},\n\t\t\tselected,\n\t\t\tname;\n\n\t\tif ( this.type === 'radio' ) {\n\t\t\tselected = this.group.findSelectedItem();\n\t\t\tif ( selected ) {\n\t\t\t\tname = selected.getData();\n\t\t\t\tresult[ name ] = !this.textareas[ name ] || this.textareas[ name ].getValue();\n\t\t\t}\n\t\t} else if ( this.type === 'checkbox' ) {\n\t\t\tselected = this.group.findSelectedItems();\n\t\t\tselected.forEach( ( item ) => {\n\t\t\t\tname = item.getData();\n\t\t\t\tresult[ name ] = !self.textareas[ name ] || self.textareas[ name ].getValue();\n\t\t\t} );\n\t\t}\n\n\t\treturn result;\n\t};\n\n\t/**\n\t * @param {Object} values Map of { licenseName: true }, or { licenseName: \"custom input\" }\n\t */\n\tuw.LicenseGroup.prototype.setValue = function ( values ) {\n\t\tlet self = this,\n\t\t\tselectArray = [],\n\t\t\tselected;\n\n\t\tObject.keys( values ).forEach( ( name ) => {\n\t\t\tconst value = values[ name ];\n\t\t\tif ( typeof value === 'string' && self.textareas[ name ] ) {\n\t\t\t\tself.textareas[ name ].setValue( value );\n\t\t\t\t// add to list of items to select\n\t\t\t\tselectArray.push( name );\n\t\t\t}\n\n\t\t\t// add to list of items to select\n\t\t\t// (only true/string values should be included in `values`, but might\n\t\t\t// as well play it safe...)\n\t\t\tif ( value === true ) {\n\t\t\t\tselectArray.push( name );\n\t\t\t}\n\t\t} );\n\n\t\tif ( this.type === 'radio' ) {\n\t\t\tthis.group.selectItemByData( selectArray[ 0 ] );\n\t\t\tselected = this.group.findSelectedItem() !== null;\n\t\t} else if ( this.type === 'checkbox' ) {\n\t\t\tthis.group.selectItemsByData( selectArray );\n\t\t\tselected = this.group.findSelectedItems().length > 0;\n\t\t}\n\n\t\t// pop open the 'toggle' group if is now on. Do nothing if it is now off.\n\t\tif ( selected && this.collapsible ) {\n\t\t\tthis.fieldset.$group.data( 'mw-collapsible' ).expand();\n\t\t}\n\t};\n\n\t/**\n\t * @private\n\t * @param {string} name\n\t * @return {Object}\n\t */\n\tuw.LicenseGroup.prototype.getLicenseInfo = function ( name ) {\n\t\treturn {\n\t\t\tname: name,\n\t\t\tprops: mw.UploadWizard.config.licenses[ name ]\n\t\t};\n\t};\n\n\t/**\n\t * License templates are these abstract ideas like cc-by-sa.\n\t * The 'license' and 'licensing' configs define how to translate them into wikitext.\n\t *\n\t * @private\n\t * @param {string} name license template name\n\t * @return {string} of wikitext\n\t */\n\tuw.LicenseGroup.prototype.getLicenseWikiText = function ( name ) {\n\t\tlet licenseInfo = this.getLicenseInfo( name ),\n\t\t\tlicenseText;\n\n\t\tlicenseText = licenseInfo.props.wikitext !== undefined ?\n\t\t\tlicenseInfo.props.wikitext : licenseInfo.name;\n\t\treturn this.config.licenseWikitext.replace( '$1', licenseText );\n\t};\n\n\t/**\n\t * Get a label for the form element\n\t *\n\t * @private\n\t * @param {string} name license template name\n\t * @return {jQuery}\n\t */\n\tuw.LicenseGroup.prototype.createLabel = function ( name ) {\n\t\tlet licenseInfo = this.getLicenseInfo( name ),\n\t\t\tmessageKey = licenseInfo.props.msg === undefined ?\n\t\t\t\t'[missing msg for ' + licenseInfo.name + ']' :\n\t\t\t\tlicenseInfo.props.msg,\n\t\t\tlanguageCode = mw.config.get( 'wgUserLanguage' ),\n\t\t\t// The URL is optional, but if the message includes it as $2, we surface the fact\n\t\t\t// that it's missing.\n\t\t\tlicenseURL = licenseInfo.props.url === undefined ? '#missing license URL' : licenseInfo.props.url,\n\t\t\t$licenseLink,\n\t\t\t$icons = $( '<span>' ),\n\t\t\t$label;\n\n\t\tif ( licenseInfo.props.languageCodePrefix !== undefined ) {\n\t\t\tlicenseURL += licenseInfo.props.languageCodePrefix + languageCode;\n\t\t}\n\t\t$licenseLink = $( '<a>' ).attr( { target: '_blank', href: licenseURL } );\n\t\tif ( licenseInfo.props.icons !== undefined ) {\n\t\t\tlicenseInfo.props.icons.forEach( ( icon ) => {\n\t\t\t\t// eslint-disable-next-line mediawiki/class-doc\n\t\t\t\t$icons.append( $( '<span>' ).addClass( 'mediauploader-license-icon mediauploader-' + icon + '-icon' ) );\n\t\t\t} );\n\t\t}\n\n\t\t// eslint-disable-next-line mediawiki/msg-doc\n\t\t$label = $( '<label>' )\n\t\t\t.msg( messageKey, this.count || 0, $licenseLink )\n\t\t\t.append( $icons ).addClass( 'mediauploader-copyright-info' );\n\n\t\tif ( this.config.special === 'custom' ) {\n\t\t\t$label.append( this.createCustom( name, licenseInfo.props.defaultText ) );\n\t\t}\n\n\t\treturn $label.contents();\n\t};\n\n\t/**\n\t * @private\n\t * @param {string} name license name\n\t * @param {string} [defaultText] Default custom license text\n\t * @return {jQuery} Wrapped textarea\n\t */\n\tuw.LicenseGroup.prototype.createCustom = function ( name, defaultText ) {\n\t\tlet self = this,\n\t\t\tbutton;\n\n\t\tthis.textareas[ name ] = new OO.ui.MultilineTextInputWidget( {\n\t\t\tvalue: defaultText,\n\t\t\tautosize: true\n\t\t} );\n\n\t\t// Update displayed errors as the user is typing\n\t\tthis.textareas[ name ].on( 'change', OO.ui.debounce( this.emit.bind( this, 'change', this ), 500 ) );\n\n\t\tbutton = new OO.ui.ButtonWidget( {\n\t\t\tlabel: mw.message( 'mediauploader-license-custom-preview' ).text(),\n\t\t\tflags: [ 'progressive' ]\n\t\t} ).on( 'click', () => {\n\t\t\tself.showPreview( self.textareas[ name ].getValue() );\n\t\t} );\n\n\t\treturn $( '<div>' ).addClass( 'mediauploader-license-custom' ).append(\n\t\t\tbutton.$element,\n\t\t\tthis.textareas[ name ].$element\n\t\t);\n\t};\n\n\t/**\n\t * Preview wikitext in a popup window\n\t *\n\t * @private\n\t * @param {string} wikiText\n\t */\n\tuw.LicenseGroup.prototype.showPreview = function ( wikiText ) {\n\t\tlet input;\n\n\t\tthis.previewDialog.setLoading( true );\n\t\tthis.windowManager.openWindow( this.previewDialog );\n\n\t\tinput = this;\n\n\t\tfunction show( html ) {\n\t\t\tinput.previewDialog.setPreview( html );\n\t\t\tinput.windowManager.openWindow( input.previewDialog );\n\t\t}\n\n\t\tfunction error( code, result ) {\n\t\t\tconst message = result.errors[ 0 ].html;\n\n\t\t\tshow( $( '<div>' ).append(\n\t\t\t\t$( '<h3>' ).append( code ),\n\t\t\t\t$( '<p>' ).append( message )\n\t\t\t) );\n\t\t}\n\n\t\tthis.api.parse( wikiText, { pst: true } ).done( show ).fail( error );\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/uw.LicensePreviewDialog.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-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/resources/uw.ValidationMessageElement.js","messages":[{"ruleId":"jsdoc/require-returns-check","severity":1,"message":"JSDoc @return declaration present but return expression not available in function.","line":39,"column":2,"nodeType":"Block","endLine":44,"endColumn":5},{"ruleId":"prefer-const","severity":2,"message":"'$listItem' is never reassigned. Use 'const' instead.","line":91,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":91,"endColumn":12}],"suppressedMessages":[{"ruleId":"mediawiki/class-doc","severity":1,"message":"All possible CSS classes should be documented. See https://w.wiki/PS2 for details.","line":91,"column":15,"nodeType":"CallExpression","endLine":92,"endColumn":65,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":1,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"( function ( uw ) {\n\n\t/**\n\t * Element that is able to display validation messages from itself or another widget.\n\t *\n\t * @abstract\n\t * @class\n\t *\n\t * @constructor\n\t * @param {Object} [config]\n\t * @param {OO.ui.Widget} [config.validatedWidget] Widget to validate\n\t */\n\tuw.ValidationMessageElement = function UWValidationMessageElement( config ) {\n\t\tconfig = config || {};\n\n\t\tthis.validatedWidget = config.validatedWidget || this;\n\t\tthis.$messages = $( '<ul>' );\n\n\t\tthis.errors = [];\n\t\tthis.warnings = [];\n\t\tthis.successMessages = [];\n\t\tthis.notices = [];\n\n\t\tthis.validatedWidget.connect( this, {\n\t\t\tchange: 'checkValidity'\n\t\t} );\n\n\t\tthis.$messages.addClass( 'oo-ui-fieldLayout-messages' );\n\t\tthis.$element.addClass( 'mediauploader-validationMessageElement' );\n\t};\n\n\t// Hack: Steal methods from OO.ui.FieldLayout.\n\t// TODO: Upstream ValidationMessageElement to OOUI, make FieldLayout use it.\n\tuw.ValidationMessageElement.prototype.makeMessage = OO.ui.FieldLayout.prototype.makeMessage;\n\tuw.ValidationMessageElement.prototype.setErrors = OO.ui.FieldLayout.prototype.setErrors;\n\tuw.ValidationMessageElement.prototype.setNotices = OO.ui.FieldLayout.prototype.setNotices;\n\tuw.ValidationMessageElement.prototype.updateMessages = OO.ui.FieldLayout.prototype.updateMessages;\n\n\t/**\n\t * Check the field's widget for errors and warnings and display them in the UI.\n\t *\n\t * @param {boolean} thorough True to perform a thorough validity check. Defaults to false for a fast on-change check.\n\t * @return {jQuery.Promise}\n\t */\n\tuw.ValidationMessageElement.prototype.checkValidity = function ( thorough ) {\n\t\tconst element = this;\n\t\tthorough = thorough || false;\n\n\t\tif ( !this.validatedWidget.getWarnings || !this.validatedWidget.getErrors ) {\n\t\t\t// Don't do anything for non-Details widgets\n\t\t\treturn;\n\t\t}\n\t\tif ( this.validatedWidget.pushPending ) {\n\t\t\tthis.validatedWidget.pushPending();\n\t\t}\n\n\t\treturn $.when(\n\t\t\tthis.validatedWidget.getWarnings( thorough ),\n\t\t\tthis.validatedWidget.getErrors( thorough )\n\t\t).then( ( warnings, errors ) => {\n\t\t\t// this.notices and this.errors are arrays of mw.Messages and not strings in this subclass\n\t\t\telement.setNotices( warnings );\n\t\t\telement.setErrors( errors );\n\n\t\t\treturn $.Deferred().resolve( warnings, errors ).promise();\n\t\t} ).always( () => {\n\t\t\tif ( element.validatedWidget.popPending ) {\n\t\t\t\telement.validatedWidget.popPending();\n\t\t\t}\n\t\t} );\n\t};\n\n\t/**\n\t * @protected\n\t * @param {string} kind 'error' or 'notice'\n\t * @param {mw.Message|Object} error Message, or an object in { key: ..., html: ... } format\n\t * @return {jQuery}\n\t */\n\tuw.ValidationMessageElement.prototype.makeMessage = function ( kind, error ) {\n\t\tlet code, $content, $listItem;\n\t\tif ( error.parseDom ) {\n\t\t\t// mw.Message object\n\t\t\tcode = error.key;\n\t\t\t$content = error.parseDom();\n\t\t} else {\n\t\t\t// { key: ..., html: ... } object (= formatted API error responses)\n\t\t\tcode = error.code;\n\t\t\t$content = $( $.parseHTML( error.html ) );\n\t\t}\n\t\t// eslint-disable-next-line mediawiki/class-doc\n\t\t$listItem = OO.ui.FieldLayout.prototype.makeMessage.call( this, kind, $content )\n\t\t\t.addClass( 'mediauploader-fieldLayout-' + kind + '-' + code );\n\t\treturn $listItem;\n\t};\n\n}( mw.uploadWizard ) );\n","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-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/resources/uw.base.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-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/resources/uw.units.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-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/schemas/campaign.yaml","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-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":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/schemas/json-schema-draft-4.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/sql/tables.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/.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/controller/uw.controller.Deed.test.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-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/tests/qunit/controller/uw.controller.Details.test.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'step' is never reassigned. Use 'const' instead.","line":57,"column":7,"nodeType":"Identifier","messageId":"useConst","endLine":57,"endColumn":11},{"ruleId":"prefer-const","severity":2,"message":"'stepUiStub' is never reassigned. Use 'const' instead.","line":61,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":61,"endColumn":14},{"ruleId":"prefer-const","severity":2,"message":"'done' is never reassigned. Use 'const' instead.","line":110,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":110,"endColumn":8},{"ruleId":"prefer-const","severity":2,"message":"'donestub' is never reassigned. Use 'const' instead.","line":111,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":111,"endColumn":12},{"ruleId":"prefer-const","severity":2,"message":"'ds' is never reassigned. Use 'const' instead.","line":112,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":112,"endColumn":6},{"ruleId":"prefer-const","severity":2,"message":"'ps' is never reassigned. Use 'const' instead.","line":113,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":113,"endColumn":6},{"ruleId":"prefer-const","severity":2,"message":"'tostub' is never reassigned. Use 'const' instead.","line":117,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":117,"endColumn":9},{"ruleId":"prefer-const","severity":2,"message":"'step' is never reassigned. Use 'const' instead.","line":124,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":124,"endColumn":7},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":135,"column":3,"nodeType":"CallExpression","endLine":135,"endColumn":40}],"suppressedMessages":[],"errorCount":9,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*\n * This file is part of the MediaWiki extension MediaUploader.\n *\n * MediaUploader is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * MediaUploader is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with MediaUploader. If not, see <http://www.gnu.org/licenses/>.\n */\n\n( function ( uw ) {\n\tQUnit.module( 'uw.controller.Details', QUnit.newMwEnvironment() );\n\n\tfunction createTestUpload( sandbox, customDeedChooser, aborted ) {\n\t\tconst stubs = {\n\t\t\tucdc: sandbox.stub(),\n\t\t\tgetSerialized: sandbox.stub(),\n\t\t\tsetSerialized: sandbox.stub(),\n\t\t\tattach: sandbox.stub()\n\t\t};\n\n\t\treturn {\n\t\t\tdeedChooser: { deed: { name: customDeedChooser ? 'custom' : 'cc-by-sa-4.0' } },\n\n\t\t\ton: function () {},\n\n\t\t\tdetails: {\n\t\t\t\tuseCustomDeedChooser: stubs.ucdc,\n\t\t\t\tgetSerialized: stubs.getSerialized,\n\t\t\t\tsetSerialized: stubs.setSerialized,\n\t\t\t\tattach: stubs.attach\n\t\t\t},\n\n\t\t\tstate: aborted ? 'aborted' : 'stashed',\n\n\t\t\tstubs: stubs\n\t\t};\n\t}\n\n\tQUnit.test( 'Constructor sanity test', ( assert ) => {\n\t\tconst step = new uw.controller.Details( new mw.Api(), {\n\t\t\tmaxSimultaneousConnections: 1\n\t\t} );\n\t\tassert.true( !!step );\n\t\tassert.true( step instanceof uw.controller.Step );\n\t\tassert.true( !!step.ui );\n\t} );\n\n\tQUnit.test( 'load', function ( assert ) {\n\t\tlet step = new uw.controller.Details( new mw.Api(), {\n\t\t\t\tmaxSimultaneousConnections: 1\n\t\t\t} ),\n\t\t\ttestUpload = createTestUpload( this.sandbox ),\n\t\t\tstepUiStub = this.sandbox.stub( step.ui, 'load' );\n\n\t\t// replace createDetails with a stub; UploadWizardDetails needs way too\n\t\t// much setup to actually be able to create it\n\t\tstep.createDetails = this.sandbox.stub();\n\n\t\tstep.load( [ testUpload ] );\n\n\t\tassert.strictEqual( testUpload.stubs.ucdc.called, false );\n\t\tassert.strictEqual( step.createDetails.callCount, 1 );\n\t\tassert.true( stepUiStub.called );\n\n\t\ttestUpload = createTestUpload( this.sandbox, true );\n\t\tstep.load( [ testUpload ] );\n\n\t\tassert.true( testUpload.stubs.ucdc.called );\n\t\tassert.strictEqual( step.createDetails.callCount, 2 );\n\t\tassert.true( stepUiStub.called );\n\n\t\ttestUpload = createTestUpload( this.sandbox );\n\t\tstep.load( [ testUpload, createTestUpload( this.sandbox ) ] );\n\n\t\tassert.strictEqual( testUpload.stubs.ucdc.called, false );\n\t\tassert.strictEqual( step.createDetails.callCount, 4 );\n\t\tassert.true( stepUiStub.called );\n\n\t\ttestUpload = createTestUpload( this.sandbox );\n\t\tstep.load( [ testUpload, createTestUpload( this.sandbox, false, true ) ] );\n\n\t\tassert.strictEqual( testUpload.stubs.ucdc.called, false );\n\t\tassert.strictEqual( step.createDetails.callCount, 6 );\n\t\tassert.true( stepUiStub.called );\n\t} );\n\n\tQUnit.test( 'canTransition', ( assert ) => {\n\t\tconst upload = {},\n\t\t\tstep = new uw.controller.Details( new mw.Api(), {\n\t\t\t\tmaxSimultaneousConnections: 1\n\t\t\t} );\n\n\t\tassert.strictEqual( step.canTransition( upload ), false );\n\t\tupload.state = 'details';\n\t\tassert.strictEqual( step.canTransition( upload ), true );\n\t\tupload.state = 'complete';\n\t\tassert.strictEqual( step.canTransition( upload ), false );\n\t} );\n\n\tQUnit.test( 'transitionAll', function ( assert ) {\n\t\tlet tostub,\n\t\t\tdone = assert.async(),\n\t\t\tdonestub = this.sandbox.stub(),\n\t\t\tds = [ $.Deferred(), $.Deferred(), $.Deferred() ],\n\t\t\tps = [ ds[ 0 ].promise(), ds[ 1 ].promise(), ds[ 2 ].promise() ],\n\t\t\tcalls = [],\n\t\t\tstep;\n\n\t\ttostub = this.sandbox.stub( uw.controller.Details.prototype, 'transitionOne' );\n\t\ttostub.onFirstCall().returns( ps[ 0 ] );\n\t\ttostub.onSecondCall().returns( ps[ 1 ] );\n\t\ttostub.onThirdCall().returns( ps[ 2 ] );\n\n\t\tthis.sandbox.stub( uw.controller.Details.prototype, 'canTransition' ).returns( true );\n\n\t\tstep = new uw.controller.Details( new mw.Api(), {\n\t\t\tmaxSimultaneousConnections: 3\n\t\t} );\n\n\t\tstep.uploads = [\n\t\t\t{ id: 15 },\n\t\t\tundefined,\n\t\t\t{ id: 21 },\n\t\t\t{ id: 'aoeu' }\n\t\t];\n\n\t\tstep.transitionAll().done( donestub );\n\t\tsetTimeout( () => {\n\t\t\tcalls = [ tostub.getCall( 0 ), tostub.getCall( 1 ), tostub.getCall( 2 ) ];\n\n\t\t\tassert.strictEqual( calls[ 0 ].args[ 0 ].id, 15 );\n\t\t\tassert.strictEqual( calls[ 1 ].args[ 0 ].id, 21 );\n\n\t\t\tds[ 0 ].resolve();\n\t\t\tds[ 1 ].resolve();\n\t\t\tsetTimeout( () => {\n\t\t\t\tassert.strictEqual( donestub.called, false );\n\n\t\t\t\tds[ 2 ].resolve();\n\t\t\t\tsetTimeout( () => {\n\t\t\t\t\tassert.true( donestub.called );\n\n\t\t\t\t\tdone();\n\t\t\t\t} );\n\t\t\t} );\n\t\t} );\n\t} );\n\n}( mw.uploadWizard ) );\n","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-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/tests/qunit/controller/uw.controller.Step.test.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-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/tests/qunit/controller/uw.controller.Thanks.test.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-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/tests/qunit/controller/uw.controller.Tutorial.test.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'acwStub' is never reassigned. Use 'const' instead.","line":33,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":33,"endColumn":11},{"ruleId":"prefer-const","severity":2,"message":"'mnStub' is never reassigned. Use 'const' instead.","line":54,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":54,"endColumn":9}],"suppressedMessages":[],"errorCount":2,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*\n * This file is part of the MediaWiki extension MediaUploader.\n *\n * MediaUploader is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * MediaUploader is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with MediaUploader. If not, see <http://www.gnu.org/licenses/>.\n */\n\n( function ( uw ) {\n\tQUnit.module( 'uw.controller.Tutorial', QUnit.newMwEnvironment() );\n\n\tQUnit.test( 'Constructor sanity test', ( assert ) => {\n\t\tconst step = new uw.controller.Tutorial( new mw.Api() );\n\t\tassert.true( !!step );\n\t\tassert.true( step instanceof uw.controller.Step );\n\t\tassert.true( !!step.ui );\n\t\tassert.true( !!step.api );\n\t} );\n\n\tQUnit.test( 'setSkipPreference', function ( assert ) {\n\t\tlet mnStub,\n\t\t\tapi = new mw.Api(),\n\t\t\tstep = new uw.controller.Tutorial( api ),\n\t\t\tacwStub = { release: this.sandbox.stub() },\n\t\t\tpwtd = $.Deferred();\n\n\t\tthis.sandbox.stub( mw, 'confirmCloseWindow' ).returns( acwStub );\n\t\tthis.sandbox.stub( api, 'postWithToken' ).returns( pwtd.promise() );\n\n\t\tstep.setSkipPreference( true );\n\n\t\tassert.true( mw.confirmCloseWindow.called );\n\t\tassert.true( api.postWithToken.calledWithExactly( 'options', {\n\t\t\taction: 'options',\n\t\t\tchange: 'upwiz_skiptutorial=1'\n\t\t} ) );\n\n\t\tpwtd.resolve();\n\t\tassert.true( acwStub.release.called );\n\n\t\tapi = new mw.Api();\n\t\tstep = new uw.controller.Tutorial( api );\n\t\tacwStub.release.reset();\n\t\tpwtd = $.Deferred();\n\t\tmnStub = this.sandbox.stub( mw, 'notify' );\n\n\t\tthis.sandbox.stub( api, 'postWithToken' ).returns( pwtd.promise() );\n\n\t\tstep.setSkipPreference( true );\n\t\tassert.false( acwStub.release.called );\n\n\t\tpwtd.reject( 'http', { textStatus: 'Foo bar' } );\n\t\tassert.true( mnStub.calledWith( 'Foo bar' ) );\n\t} );\n}( mw.uploadWizard ) );\n","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-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/tests/qunit/controller/uw.controller.Upload.test.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-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/tests/qunit/mw.UploadWizardLicenseInput.test.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'config' is never reassigned. Use 'const' instead.","line":17,"column":6,"nodeType":"Identifier","messageId":"useConst","endLine":17,"endColumn":12},{"ruleId":"prefer-const","severity":2,"message":"'$fixture' is never reassigned. Use 'const' instead.","line":18,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":18,"endColumn":11},{"ruleId":"prefer-const","severity":2,"message":"'uwLicenseInput' is never reassigned. Use 'const' instead.","line":21,"column":2,"nodeType":"Identifier","messageId":"useConst","endLine":21,"endColumn":16},{"ruleId":"prefer-const","severity":2,"message":"'config' is never reassigned. Use 'const' instead.","line":27,"column":6,"nodeType":"Identifier","messageId":"useConst","endLine":27,"endColumn":12},{"ruleId":"prefer-const","severity":2,"message":"'$fixture' is never reassigned. Use 'const' instead.","line":28,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":28,"endColumn":11},{"ruleId":"prefer-const","severity":2,"message":"'uwLicenseInput' is never reassigned. Use 'const' instead.","line":33,"column":2,"nodeType":"Identifier","messageId":"useConst","endLine":33,"endColumn":16},{"ruleId":"prefer-const","severity":2,"message":"'$input' is never reassigned. Use 'const' instead.","line":37,"column":2,"nodeType":"Identifier","messageId":"useConst","endLine":37,"endColumn":8},{"ruleId":"prefer-const","severity":2,"message":"'$label' is never reassigned. Use 'const' instead.","line":41,"column":2,"nodeType":"Identifier","messageId":"useConst","endLine":41,"endColumn":8},{"ruleId":"prefer-const","severity":2,"message":"'config' is never reassigned. Use 'const' instead.","line":46,"column":6,"nodeType":"Identifier","messageId":"useConst","endLine":46,"endColumn":12},{"ruleId":"prefer-const","severity":2,"message":"'$fixture' is never reassigned. Use 'const' instead.","line":56,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":56,"endColumn":11},{"ruleId":"prefer-const","severity":2,"message":"'uwLicenseInput' is never reassigned. Use 'const' instead.","line":59,"column":2,"nodeType":"Identifier","messageId":"useConst","endLine":59,"endColumn":16}],"suppressedMessages":[],"errorCount":11,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"QUnit.module( 'ext.uploadWizardLicenseInput', QUnit.newMwEnvironment( {\n\tbeforeEach: function () {\n\t\tmw.UploadWizard.config = {\n\t\t\tlicenses: {\n\t\t\t\t'cc-by-sa-3.0': {\n\t\t\t\t\tmsg: 'mediauploader-license-cc-by-sa-3.0',\n\t\t\t\t\ticons: [ 'cc-by', 'cc-sa' ],\n\t\t\t\t\turl: '//creativecommons.org/licenses/by-sa/3.0/',\n\t\t\t\t\tlanguageCodePrefix: 'deed.'\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} ) );\n\nQUnit.test( 'Smoke test', ( assert ) => {\n\tlet config = { type: 'radio', licenses: [] },\n\t\t$fixture = $( '<div>' ),\n\t\tuwLicenseInput;\n\n\tuwLicenseInput = new mw.UploadWizardLicenseInput( config );\n\t$fixture.append( uwLicenseInput.$element );\n\tassert.true( !!uwLicenseInput, 'LicenseInput object created !' );\n} );\n\nQUnit.test( 'createInputs()', ( assert ) => {\n\tlet config = { type: 'radio', licenses: [ 'cc-by-sa-3.0' ] },\n\t\t$fixture = $( '<div>' ),\n\t\tuwLicenseInput,\n\t\t$input,\n\t\t$label;\n\n\tuwLicenseInput = new mw.UploadWizardLicenseInput( config );\n\t$fixture.append( uwLicenseInput.$element );\n\n\t// Check radio button is there\n\t$input = $fixture.find( '.oo-ui-radioInputWidget .oo-ui-inputWidget-input[value=\"cc-by-sa-3.0\"]' );\n\tassert.strictEqual( $input.length, 1, 'Radio button created.' );\n\n\t// Check label is there\n\t$label = $input.closest( '.oo-ui-radioOptionWidget' ).find( '.oo-ui-labelElement-label' );\n\tassert.strictEqual( $label.length, 1, 'Label created.' );\n} );\n\nQUnit.test( 'createGroupedInputs()', ( assert ) => {\n\tlet config = {\n\t\t\ttype: 'checkbox',\n\t\t\tlicenseGroups: [\n\t\t\t\t{\n\t\t\t\t\thead: 'mediauploader-license-cc-head',\n\t\t\t\t\tsubhead: 'mediauploader-license-cc-subhead',\n\t\t\t\t\tlicenses: [ 'cc-by-sa-3.0' ]\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t$fixture = $( '<div>' ),\n\t\tuwLicenseInput;\n\n\tuwLicenseInput = new mw.UploadWizardLicenseInput( config );\n\t$fixture.append( uwLicenseInput.$element );\n\n\t// Check license group is there\n\tassert.strictEqual( $fixture.find( '.mediauploader-deed-license-group' ).length, 1, 'License group created.' );\n\n\t// Check subheader is there\n\tassert.strictEqual( $fixture.find( '.mediauploader-deed-license-group-subhead' ).length, 1, 'License subheader created.' );\n\n\t// Check license is there\n\tassert.strictEqual( $fixture.find( '.mediauploader-deed-license-group .oo-ui-fieldsetLayout-group' ).length, 1, 'License created.' );\n} );\n","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-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/tests/qunit/mw.UploadWizardUpload.test.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'oldconf' is never reassigned. Use 'const' instead.","line":23,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":23,"endColumn":11},{"ruleId":"prefer-const","severity":2,"message":"'upload' is never reassigned. Use 'const' instead.","line":27,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":27,"endColumn":9}],"suppressedMessages":[],"errorCount":2,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*\n * This file is part of the MediaWiki extension MediaUploader.\n *\n * MediaUploader is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * MediaUploader is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with MediaUploader. If not, see <http://www.gnu.org/licenses/>.\n */\n\n( function () {\n\tQUnit.module( 'mw.UploadWizardUpload', QUnit.newMwEnvironment() );\n\n\tfunction createUpload( filename ) {\n\t\tlet upload,\n\t\t\toldconf = mw.UploadWizard.config;\n\n\t\tmw.UploadWizard.config = {};\n\n\t\tupload = new mw.UploadWizardUpload( {\n\t\t\tapi: {\n\t\t\t\tdefaults: {\n\t\t\t\t\tajax: {}\n\t\t\t\t}\n\t\t\t}\n\t\t}, {\n\t\t\tname: filename\n\t\t} );\n\n\t\tmw.UploadWizard.config = oldconf;\n\n\t\treturn upload;\n\t}\n\n\tQUnit.test( 'constructor sanity test', ( assert ) => {\n\t\tconst upload = createUpload();\n\n\t\tassert.true( !!upload );\n\t} );\n\n\tQUnit.test( 'getBasename', ( assert ) => {\n\t\tlet upload;\n\n\t\tupload = createUpload( 'path/to/filename.png' );\n\t\tassert.strictEqual( upload.getBasename(), 'filename.png', 'Path is stripped' );\n\n\t\tupload = createUpload( 'filename.png' );\n\t\tassert.strictEqual( upload.getBasename(), 'filename.png', 'Only filename is left alone' );\n\n\t\tupload = createUpload( '///////////' );\n\t\tassert.strictEqual( upload.getBasename(), '', 'Nonsensical path is just removed' );\n\t} );\n}() );\n","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-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/tests/qunit/mw.fileApi.test.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'testFile' is never reassigned. Use 'const' instead.","line":46,"column":15,"nodeType":"Identifier","messageId":"useConst","endLine":46,"endColumn":23},{"ruleId":"prefer-const","severity":2,"message":"'fakeVideo' is never reassigned. Use 'const' instead.","line":47,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":47,"endColumn":13}],"suppressedMessages":[],"errorCount":2,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*\n * This file is part of the MediaWiki extension MediaUploader.\n *\n * MediaUploader is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * MediaUploader is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with MediaUploader. If not, see <http://www.gnu.org/licenses/>.\n */\n\n( function () {\n\tQUnit.module( 'mw.fileApi', QUnit.newMwEnvironment() );\n\n\tQUnit.test( 'isPreviewableFile', function ( assert ) {\n\t\tconst testFile = {};\n\n\t\ttestFile.type = 'image/png';\n\t\ttestFile.size = 5 * 1024 * 1024;\n\t\tassert.strictEqual( mw.fileApi.isPreviewableFile( testFile ), true );\n\n\t\ttestFile.type = 'image/gif';\n\t\tassert.strictEqual( mw.fileApi.isPreviewableFile( testFile ), true );\n\n\t\ttestFile.type = 'image/jpeg';\n\t\tassert.strictEqual( mw.fileApi.isPreviewableFile( testFile ), true );\n\n\t\ttestFile.size = 11 * 1024 * 1024;\n\t\tassert.strictEqual( mw.fileApi.isPreviewableFile( testFile ), false );\n\n\t\ttestFile.size = 5 * 1024 * 1024;\n\t\ttestFile.type = 'unplayable/type';\n\t\tassert.strictEqual( mw.fileApi.isPreviewableFile( testFile ), false );\n\n\t\tthis.sandbox.stub( mw.fileApi, 'isPreviewableVideo' ).returns( true );\n\t\tassert.strictEqual( mw.fileApi.isPreviewableFile( testFile ), true );\n\t} );\n\n\tQUnit.test( 'isPreviewableVideo', function ( assert ) {\n\t\tlet result, testFile = {},\n\t\t\tfakeVideo = {\n\t\t\t\tcanPlayType: this.sandbox.stub().returns( 'yes' )\n\t\t\t};\n\n\t\tthis.sandbox.stub( document, 'createElement' ).returns( fakeVideo );\n\t\tresult = mw.fileApi.isPreviewableVideo( testFile );\n\t\tdocument.createElement.restore();\n\n\t\tassert.strictEqual( result, true );\n\t\tassert.strictEqual( fakeVideo.canPlayType.callCount, 1 );\n\n\t\tfakeVideo.canPlayType = this.sandbox.stub().returns( 'no' );\n\t\tthis.sandbox.stub( document, 'createElement' ).returns( fakeVideo );\n\t\tresult = mw.fileApi.isPreviewableVideo( testFile );\n\t\tdocument.createElement.restore();\n\n\t\tassert.strictEqual( result, false );\n\t\tassert.strictEqual( fakeVideo.canPlayType.callCount, 1 );\n\t} );\n\n}() );\n","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-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/tests/qunit/transports/mw.FormDataTransport.test.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'config' is never reassigned. Use 'const' instead.","line":27,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":27,"endColumn":9},{"ruleId":"prefer-const","severity":2,"message":"'transport' is never reassigned. Use 'const' instead.","line":86,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":86,"endColumn":13},{"ruleId":"prefer-const","severity":2,"message":"'fakeFile' is never reassigned. Use 'const' instead.","line":87,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":87,"endColumn":12},{"ruleId":"prefer-const","severity":2,"message":"'request' is never reassigned. Use 'const' instead.","line":97,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":97,"endColumn":10},{"ruleId":"prefer-const","severity":2,"message":"'transport' is never reassigned. Use 'const' instead.","line":107,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":107,"endColumn":13},{"ruleId":"prefer-const","severity":2,"message":"'fakeFile' is never reassigned. Use 'const' instead.","line":108,"column":4,"nodeType":"Identifier","messageId":"useConst","endLine":108,"endColumn":12},{"ruleId":"prefer-const","severity":2,"message":"'request' is never reassigned. Use 'const' instead.","line":125,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":125,"endColumn":10},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .fail","line":146,"column":3,"nodeType":"CallExpression","endLine":152,"endColumn":6},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":179,"column":10,"nodeType":"CallExpression","endLine":182,"endColumn":6},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":198,"column":10,"nodeType":"CallExpression","endLine":201,"endColumn":6},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .fail","line":218,"column":3,"nodeType":"CallExpression","endLine":222,"endColumn":6}],"suppressedMessages":[],"errorCount":11,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*\n * This file is part of the MediaWiki extension MediaUploader.\n *\n * MediaUploader is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * MediaUploader is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with MediaUploader. If not, see <http://www.gnu.org/licenses/>.\n */\n\n( function () {\n\tQUnit.module( 'mw.FormDataTransport', QUnit.newMwEnvironment() );\n\n\tfunction createTransport( chunkSize, api ) {\n\t\tlet config;\n\n\t\tchunkSize = chunkSize || 0;\n\t\tapi = api || {};\n\n\t\tconfig = {\n\t\t\tuseRetryTimeout: false,\n\t\t\tchunkSize: chunkSize,\n\t\t\tmaxPhpUploadSize: chunkSize\n\t\t};\n\n\t\treturn new mw.FormDataTransport( api, {}, config );\n\t}\n\n\tQUnit.test( 'Constructor sanity test', ( assert ) => {\n\t\tconst transport = createTransport();\n\n\t\tassert.true( !!transport );\n\t} );\n\n\tQUnit.test( 'abort', function ( assert ) {\n\t\tconst transport = createTransport( 0 ),\n\t\t\trequest = $.Deferred().promise( { abort: this.sandbox.stub() } );\n\n\t\ttransport.request = request;\n\n\t\tassert.true( request.abort.notCalled );\n\n\t\ttransport.abort();\n\n\t\tassert.true( request.abort.called );\n\t\tassert.true( transport.aborted );\n\t} );\n\n\tQUnit.test( 'createParams', ( assert ) => {\n\t\tconst transport = createTransport( 10 ),\n\t\t\tparams = transport.createParams( 'foobar.jpg', 0 );\n\n\t\tassert.true( !!params );\n\n\t\tassert.strictEqual( params.filename, 'foobar.jpg' );\n\t\tassert.strictEqual( params.offset, 0 );\n\t} );\n\n\tQUnit.test( 'post', function ( assert ) {\n\t\tconst stub = this.sandbox.stub(),\n\t\t\t// post() works on a promise and binds .then, so we have to make\n\t\t\t// sure it actually is a promise, but also that it calls our stub\n\t\t\ttransport = createTransport( 10, { post: function () {\n\t\t\t\tstub();\n\t\t\t\treturn $.Deferred().resolve();\n\t\t\t} } );\n\n\t\tthis.sandbox.useFakeServer();\n\n\t\tassert.true( stub.notCalled );\n\n\t\ttransport.post( {} );\n\n\t\tassert.true( stub.called );\n\t} );\n\n\tQUnit.test( 'upload', function ( assert ) {\n\t\tlet request,\n\t\t\ttransport = createTransport( 10, new mw.Api() ),\n\t\t\tfakeFile = {\n\t\t\t\tname: 'test file for fdt.jpg',\n\t\t\t\tsize: 5\n\t\t\t};\n\n\t\tthis.sandbox.useFakeServer();\n\n\t\ttransport.upload( fakeFile, 'test file for fdt.jpg' );\n\n\t\tassert.strictEqual( this.sandbox.server.requests.length, 1 );\n\t\trequest = this.sandbox.server.requests[ 0 ];\n\t\tassert.strictEqual( request.method, 'POST' );\n\t\tassert.strictEqual( request.url, mw.util.wikiScript( 'api' ) );\n\t\tassert.true( request.async );\n\n\t\ttransport.abort();\n\t} );\n\n\tQUnit.test( 'uploadChunk', function ( assert ) {\n\t\tlet request,\n\t\t\ttransport = createTransport( 10, new mw.Api() ),\n\t\t\tfakeFile = {\n\t\t\t\tname: 'test file for fdt.jpg',\n\t\t\t\tsize: 20,\n\t\t\t\tslice: function ( offset ) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tname: 'test file for fdt.jpg',\n\t\t\t\t\t\toffset: offset,\n\t\t\t\t\t\tsize: 10\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t};\n\n\t\tthis.sandbox.useFakeServer();\n\n\t\ttransport.uploadChunk( fakeFile, 0 );\n\n\t\tassert.strictEqual( this.sandbox.server.requests.length, 1 );\n\t\trequest = this.sandbox.server.requests[ 0 ];\n\t\tassert.strictEqual( request.method, 'POST' );\n\t\tassert.strictEqual( request.url, mw.util.wikiScript( 'api' ) );\n\t\tassert.true( request.async );\n\n\t\ttransport.abort();\n\t} );\n\n\t// test invalid server response (in missing 'stage' param)\n\tQUnit.test( 'checkStatus invalid API response', function ( assert ) {\n\t\tconst done = assert.async(),\n\t\t\ttransport = createTransport( 10, new mw.Api() ),\n\t\t\ttstub = this.sandbox.stub(),\n\t\t\tpoststub = this.sandbox.stub( transport.api, 'post' ),\n\t\t\tpostd = $.Deferred();\n\n\t\t// prepare a bogus invalid API result\n\t\tpoststub.returns( postd.promise() );\n\t\tpostd.resolve( { upload: { result: 'Poll' } } );\n\n\t\t// call tstub upon checkStatus failure, and verify it got called correctly\n\t\ttransport.checkStatus().fail( tstub, () => {\n\t\t\tassert.true( tstub.calledWith( 'server-error', { errors: [ {\n\t\t\t\tcode: 'server-error',\n\t\t\t\thtml: mw.message( 'api-clientside-error-invalidresponse' ).parse()\n\t\t\t} ] } ) );\n\t\t\tdone();\n\t\t} );\n\t} );\n\n\t// test retry after server responds upload is still incomplete\n\tQUnit.test( 'checkStatus retry', function ( assert ) {\n\t\tconst transport = createTransport( 10, new mw.Api() ),\n\t\t\tusstub = this.sandbox.stub(),\n\t\t\tpoststub = this.sandbox.stub( transport.api, 'post' ),\n\t\t\tpostd = $.Deferred(),\n\t\t\tpostd2 = $.Deferred();\n\n\t\ttransport.on( 'update-stage', usstub );\n\n\t\t// prepare a first API call that responds with 'Poll' (upload\n\t\t// concatenation is not yet complete) followed by a second call that\n\t\t// marks the upload successful\n\t\tpoststub\n\t\t\t.onFirstCall().returns( postd.promise() )\n\t\t\t.onSecondCall().returns( postd2.promise() );\n\n\t\t// resolve 3 API calls, where server first responds upload is not yet\n\t\t// assembled, and second says it's published\n\t\tpostd.resolve( { upload: { result: 'Poll', stage: 'queued' } } );\n\t\tpostd2.resolve( { upload: { result: 'Success' } } );\n\n\t\t// confirm that, once second API call was successful, status resolves,\n\t\t// 2 API calls have gone out & the failed call updates stage accordingly\n\t\treturn transport.checkStatus().done( () => {\n\t\t\tassert.true( poststub.calledTwice );\n\t\t\tassert.true( usstub.firstCall.calledWith( 'queued' ) );\n\t\t} );\n\t} );\n\n\tQUnit.test( 'checkStatus success', function ( assert ) {\n\t\tconst transport = createTransport( 10, new mw.Api() ),\n\t\t\ttstub = this.sandbox.stub(),\n\t\t\tusstub = this.sandbox.stub(),\n\t\t\tpoststub = this.sandbox.stub( transport.api, 'post' ),\n\t\t\tpostd = $.Deferred();\n\n\t\ttransport.on( 'update-stage', usstub );\n\n\t\t// prepare a bogus valid API result\n\t\tpoststub.returns( postd.promise() );\n\t\tpostd.resolve( 'testing' );\n\n\t\treturn transport.checkStatus().done( tstub, () => {\n\t\t\tassert.true( tstub.calledWith( 'testing' ) );\n\t\t\tassert.false( usstub.called );\n\t\t} );\n\t} );\n\n\tQUnit.test( 'checkStatus error API response', function ( assert ) {\n\t\tconst done = assert.async(),\n\t\t\ttransport = createTransport( 10, new mw.Api() ),\n\t\t\ttstub = this.sandbox.stub(),\n\t\t\tusstub = this.sandbox.stub(),\n\t\t\tpoststub = this.sandbox.stub( transport.api, 'post' ),\n\t\t\tpostd = $.Deferred();\n\n\t\ttransport.on( 'update-stage', usstub );\n\n\t\t// prepare an error API response\n\t\tpoststub.returns( postd.promise() );\n\t\tpostd.reject( 'testing', { error: 'testing' } );\n\n\t\ttransport.checkStatus().fail( tstub, () => {\n\t\t\tassert.true( tstub.calledWith( 'testing', { error: 'testing' } ) );\n\t\t\tassert.false( usstub.called );\n\t\t\tdone();\n\t\t} );\n\t} );\n\n}() );\n","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-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/tests/qunit/uw.ConcurrentQueue.test.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'calls' is never reassigned. Use 'const' instead.","line":38,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":38,"endColumn":8},{"ruleId":"prefer-const","severity":2,"message":"'done' is never reassigned. Use 'const' instead.","line":65,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":65,"endColumn":7},{"ruleId":"prefer-const","severity":2,"message":"'action' is never reassigned. Use 'const' instead.","line":66,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":66,"endColumn":9},{"ruleId":"prefer-const","severity":2,"message":"'queue' is never reassigned. Use 'const' instead.","line":67,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":67,"endColumn":8},{"ruleId":"prefer-const","severity":2,"message":"'done' is never reassigned. Use 'const' instead.","line":98,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":98,"endColumn":7},{"ruleId":"prefer-const","severity":2,"message":"'changeHandler' is never reassigned. Use 'const' instead.","line":99,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":99,"endColumn":16},{"ruleId":"prefer-const","severity":2,"message":"'progressHandler' is never reassigned. Use 'const' instead.","line":100,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":100,"endColumn":18},{"ruleId":"prefer-const","severity":2,"message":"'completeHandler' is never reassigned. Use 'const' instead.","line":101,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":101,"endColumn":18},{"ruleId":"prefer-const","severity":2,"message":"'queue' is never reassigned. Use 'const' instead.","line":102,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":102,"endColumn":8},{"ruleId":"prefer-const","severity":2,"message":"'done' is never reassigned. Use 'const' instead.","line":139,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":139,"endColumn":7},{"ruleId":"prefer-const","severity":2,"message":"'queue' is never reassigned. Use 'const' instead.","line":140,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":140,"endColumn":8},{"ruleId":"prefer-const","severity":2,"message":"'done' is never reassigned. Use 'const' instead.","line":167,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":167,"endColumn":7},{"ruleId":"prefer-const","severity":2,"message":"'queue' is never reassigned. Use 'const' instead.","line":168,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":168,"endColumn":8},{"ruleId":"prefer-const","severity":2,"message":"'done' is never reassigned. Use 'const' instead.","line":184,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":184,"endColumn":7},{"ruleId":"prefer-const","severity":2,"message":"'changeHandler' is never reassigned. Use 'const' instead.","line":185,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":185,"endColumn":16},{"ruleId":"prefer-const","severity":2,"message":"'progressHandler' is never reassigned. Use 'const' instead.","line":186,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":186,"endColumn":18},{"ruleId":"prefer-const","severity":2,"message":"'completeHandler' is never reassigned. Use 'const' instead.","line":187,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":187,"endColumn":18},{"ruleId":"prefer-const","severity":2,"message":"'queue' is never reassigned. Use 'const' instead.","line":188,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":188,"endColumn":8},{"ruleId":"prefer-const","severity":2,"message":"'done' is never reassigned. Use 'const' instead.","line":240,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":240,"endColumn":7},{"ruleId":"prefer-const","severity":2,"message":"'changeHandler' is never reassigned. Use 'const' instead.","line":241,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":241,"endColumn":16},{"ruleId":"prefer-const","severity":2,"message":"'progressHandler' is never reassigned. Use 'const' instead.","line":242,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":242,"endColumn":18},{"ruleId":"prefer-const","severity":2,"message":"'completeHandler' is never reassigned. Use 'const' instead.","line":243,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":243,"endColumn":18},{"ruleId":"prefer-const","severity":2,"message":"'queue' is never reassigned. Use 'const' instead.","line":244,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":244,"endColumn":8},{"ruleId":"prefer-const","severity":2,"message":"'done' is never reassigned. Use 'const' instead.","line":297,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":297,"endColumn":7},{"ruleId":"prefer-const","severity":2,"message":"'action' is never reassigned. Use 'const' instead.","line":298,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":298,"endColumn":9},{"ruleId":"prefer-const","severity":2,"message":"'changeHandler' is never reassigned. Use 'const' instead.","line":299,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":299,"endColumn":16},{"ruleId":"prefer-const","severity":2,"message":"'progressHandler' is never reassigned. Use 'const' instead.","line":300,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":300,"endColumn":18},{"ruleId":"prefer-const","severity":2,"message":"'completeHandler' is never reassigned. Use 'const' instead.","line":301,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":301,"endColumn":18},{"ruleId":"prefer-const","severity":2,"message":"'queue' is never reassigned. Use 'const' instead.","line":302,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":302,"endColumn":8},{"ruleId":"prefer-const","severity":2,"message":"'done' is never reassigned. Use 'const' instead.","line":353,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":353,"endColumn":7},{"ruleId":"prefer-const","severity":2,"message":"'action' is never reassigned. Use 'const' instead.","line":355,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":355,"endColumn":9},{"ruleId":"prefer-const","severity":2,"message":"'changeHandler' is never reassigned. Use 'const' instead.","line":356,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":356,"endColumn":16},{"ruleId":"prefer-const","severity":2,"message":"'progressHandler' is never reassigned. Use 'const' instead.","line":357,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":357,"endColumn":18},{"ruleId":"prefer-const","severity":2,"message":"'completeHandler' is never reassigned. Use 'const' instead.","line":358,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":358,"endColumn":18},{"ruleId":"prefer-const","severity":2,"message":"'queue' is never reassigned. Use 'const' instead.","line":359,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":359,"endColumn":8},{"ruleId":"prefer-const","severity":2,"message":"'onProgress' is never reassigned. Use 'const' instead.","line":402,"column":3,"nodeType":"Identifier","messageId":"useConst","endLine":402,"endColumn":13}],"suppressedMessages":[],"errorCount":36,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*\n * This file is part of the MediaWiki extension MediaUploader.\n *\n * MediaUploader is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * MediaUploader is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with MediaUploader. If not, see <http://www.gnu.org/licenses/>.\n */\n\n( function ( uw ) {\n\tQUnit.module( 'uw.ConcurrentQueue', QUnit.newMwEnvironment() );\n\n\t// This is a bogus action that will be executed for every item added to the\n\t// queue. We just need to make sure that the action doesn't complete\n\t// immediately, or the order some methods are called in could be slightly\n\t// different (e.g. when adding a new item after one has just completed will\n\t// trigger the next one to execute, which would terminate immediately,\n\t// instead of giving time for a second new thingy to be added)\n\tfunction queueAction() {\n\t\tconst deferred = $.Deferred();\n\t\tsetTimeout( deferred.resolve, 10 );\n\t\treturn deferred.promise();\n\t}\n\n\t// Asserts that the given stub functions were called in the given order.\n\t// SinonJS's assert.callOrder doesn't allow to check individual calls.\n\tfunction assertCalledInOrder() {\n\t\tlet calls, i, currSpyCall, nextSpyCall;\n\t\t// Map stubs to specific calls\n\t\tcalls = Array.prototype.map.call( arguments, ( spy ) => {\n\t\t\tif ( !spy.assertCallsInOrderLastCall ) {\n\t\t\t\tspy.assertCallsInOrderLastCall = 0;\n\t\t\t}\n\t\t\treturn spy.getCall( spy.assertCallsInOrderLastCall++ );\n\t\t} );\n\t\t// Assert stuff\n\t\tfor ( i = 0; i < calls.length - 1; i++ ) {\n\t\t\tcurrSpyCall = calls[ i ];\n\t\t\tnextSpyCall = calls[ i + 1 ];\n\t\t\tif ( currSpyCall ) {\n\t\t\t\tQUnit.assert.true(\n\t\t\t\t\tcurrSpyCall.callId < ( nextSpyCall ? nextSpyCall.callId : -1 ),\n\t\t\t\t\t'Call ' + ( i + 1 ) + ' (callId ' + currSpyCall.callId + ') is in the right order'\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tQUnit.assert.true( false, 'Call ' + ( i + 1 ) + ' (never called) is in the right order' );\n\t\t\t}\n\t\t}\n\t\tQUnit.assert.true(\n\t\t\t!!nextSpyCall,\n\t\t\t'Call ' + calls.length + ' is in the right order'\n\t\t);\n\t}\n\n\tQUnit.test( 'Basic behavior', ( assert ) => {\n\t\tlet done, action, queue;\n\t\tdone = assert.async();\n\t\taction = sinon.spy( queueAction );\n\t\tqueue = new uw.ConcurrentQueue( {\n\t\t\tcount: 3,\n\t\t\taction: action\n\t\t} );\n\n\t\tqueue.on( 'progress', () => {\n\t\t\tQUnit.assert.true( queue.running.length <= 3, 'No more than 3 items are executing' );\n\t\t} );\n\n\t\tqueue.on( 'complete', () => {\n\t\t\t// All items executed\n\t\t\tsinon.assert.callCount( action, 5 );\n\t\t\t// All items executed in the expected order\n\t\t\tsinon.assert.calledWith( action.getCall( 0 ), 'a' );\n\t\t\tsinon.assert.calledWith( action.getCall( 1 ), 'b' );\n\t\t\tsinon.assert.calledWith( action.getCall( 2 ), 'c' );\n\t\t\tsinon.assert.calledWith( action.getCall( 3 ), 'd' );\n\t\t\tsinon.assert.calledWith( action.getCall( 4 ), 'e' );\n\n\t\t\tdone();\n\t\t} );\n\n\t\t[ 'a', 'b', 'c', 'd', 'e' ].forEach( ( v ) => {\n\t\t\tqueue.addItem( v );\n\t\t} );\n\n\t\tqueue.startExecuting();\n\t} );\n\n\tQUnit.test( 'Event emitting', ( assert ) => {\n\t\tlet done, changeHandler, progressHandler, completeHandler, queue;\n\t\tdone = assert.async();\n\t\tchangeHandler = sinon.stub();\n\t\tprogressHandler = sinon.stub();\n\t\tcompleteHandler = sinon.stub();\n\t\tqueue = new uw.ConcurrentQueue( {\n\t\t\tcount: 3,\n\t\t\taction: queueAction\n\t\t} );\n\n\t\tqueue.connect( null, {\n\t\t\tchange: changeHandler,\n\t\t\tprogress: progressHandler,\n\t\t\tcomplete: completeHandler\n\t\t} );\n\n\t\tqueue.on( 'complete', () => {\n\t\t\tsinon.assert.callCount( changeHandler, 3 );\n\t\t\tsinon.assert.callCount( progressHandler, 3 );\n\t\t\tsinon.assert.callCount( completeHandler, 1 );\n\n\t\t\tassertCalledInOrder(\n\t\t\t\tchangeHandler, // Added 'a'\n\t\t\t\tchangeHandler, // Added 'b'\n\t\t\t\tchangeHandler, // Added 'c'\n\t\t\t\tprogressHandler, // Finished 'a', 'b' or 'c'\n\t\t\t\tprogressHandler, // Finished 'a', 'b' or 'c'\n\t\t\t\tprogressHandler, // Finished 'a', 'b' or 'c'\n\t\t\t\tcompleteHandler\n\t\t\t);\n\n\t\t\tdone();\n\t\t} );\n\n\t\tqueue.addItem( 'a' );\n\t\tqueue.addItem( 'b' );\n\t\tqueue.addItem( 'c' );\n\t\tqueue.startExecuting();\n\t} );\n\n\tQUnit.test( 'Restarting a completed queue', ( assert ) => {\n\t\tlet done, queue;\n\t\tdone = assert.async();\n\t\tqueue = new uw.ConcurrentQueue( {\n\t\t\tcount: 3,\n\t\t\taction: queueAction\n\t\t} );\n\n\t\tqueue.addItem( 'a' );\n\t\tqueue.addItem( 'b' );\n\t\tqueue.addItem( 'c' );\n\n\t\tqueue.once( 'complete', () => {\n\t\t\tQUnit.assert.equal( queue.completed, true );\n\t\t\tqueue.addItem( 'd' );\n\t\t\tqueue.addItem( 'e' );\n\n\t\t\tqueue.once( 'complete', () => {\n\t\t\t\tQUnit.assert.equal( queue.completed, true );\n\t\t\t\tdone();\n\t\t\t} );\n\n\t\t\tqueue.startExecuting();\n\t\t} );\n\n\t\tqueue.startExecuting();\n\t} );\n\n\tQUnit.test( 'Empty queue completes', ( assert ) => {\n\t\tlet done, queue;\n\t\tdone = assert.async();\n\t\tqueue = new uw.ConcurrentQueue( {\n\t\t\tcount: 3,\n\t\t\taction: queueAction\n\t\t} );\n\n\t\tqueue.on( 'complete', () => {\n\t\t\tQUnit.assert.equal( queue.completed, true );\n\n\t\t\tdone();\n\t\t} );\n\n\t\tqueue.startExecuting();\n\t} );\n\n\tQUnit.test( 'Adding new items while queue running', ( assert ) => {\n\t\tlet done, changeHandler, progressHandler, completeHandler, queue;\n\t\tdone = assert.async();\n\t\tchangeHandler = sinon.stub();\n\t\tprogressHandler = sinon.stub();\n\t\tcompleteHandler = sinon.stub();\n\t\tqueue = new uw.ConcurrentQueue( {\n\t\t\tcount: 2,\n\t\t\taction: queueAction\n\t\t} );\n\n\t\tqueue.connect( null, {\n\t\t\tchange: changeHandler,\n\t\t\tprogress: progressHandler,\n\t\t\tcomplete: completeHandler\n\t\t} );\n\n\t\tqueue.on( 'complete', () => {\n\t\t\tsinon.assert.callCount( changeHandler, 6 );\n\t\t\tsinon.assert.callCount( progressHandler, 6 );\n\t\t\tsinon.assert.callCount( completeHandler, 1 );\n\n\t\t\tassertCalledInOrder(\n\t\t\t\tchangeHandler, // Added 'a'\n\t\t\t\tchangeHandler, // Added 'b'\n\t\t\t\tchangeHandler, // Added 'c'\n\t\t\t\tprogressHandler, // Finished 'a' or 'b'\n\t\t\t\tchangeHandler, // Added 'd'\n\t\t\t\tchangeHandler, // Added 'e'\n\t\t\t\tprogressHandler, // Finished 'a', 'b' or 'c'\n\t\t\t\tprogressHandler, // Finished 'a', 'b', 'c' or 'd'\n\t\t\t\tprogressHandler, // Finished 'a', 'b', 'c', 'd' or 'e'\n\t\t\t\tprogressHandler, // Finished 'a', 'b', 'c', 'd' or 'e'\n\t\t\t\tchangeHandler, // Added 'f'\n\t\t\t\tprogressHandler, // Finished f'\n\t\t\t\tcompleteHandler\n\t\t\t);\n\n\t\t\tdone();\n\t\t} );\n\n\t\tqueue.addItem( 'a' );\n\t\tqueue.addItem( 'b' );\n\t\tqueue.addItem( 'c' );\n\t\tqueue.once( 'progress', () => {\n\t\t\tqueue.addItem( 'd' );\n\t\t\tqueue.addItem( 'e' );\n\t\t} );\n\t\tqueue.on( 'progress', () => {\n\t\t\tif ( queue.done.length === 5 ) {\n\t\t\t\tqueue.addItem( 'f' );\n\t\t\t}\n\t\t} );\n\t\tqueue.startExecuting();\n\t} );\n\n\tQUnit.test( 'Deleting items while queue running', ( assert ) => {\n\t\tlet done, changeHandler, progressHandler, completeHandler, queue;\n\t\tdone = assert.async();\n\t\tchangeHandler = sinon.stub();\n\t\tprogressHandler = sinon.stub();\n\t\tcompleteHandler = sinon.stub();\n\t\tqueue = new uw.ConcurrentQueue( {\n\t\t\tcount: 2,\n\t\t\taction: queueAction\n\t\t} );\n\n\t\tqueue.connect( null, {\n\t\t\tchange: changeHandler,\n\t\t\tprogress: progressHandler,\n\t\t\tcomplete: completeHandler\n\t\t} );\n\n\t\tqueue.on( 'complete', () => {\n\t\t\tsinon.assert.callCount( changeHandler, 8 );\n\t\t\tsinon.assert.callCount( progressHandler, 4 );\n\t\t\tsinon.assert.callCount( completeHandler, 1 );\n\n\t\t\tassertCalledInOrder(\n\t\t\t\tchangeHandler, // Added 'a'\n\t\t\t\tchangeHandler, // Added 'b'\n\t\t\t\tchangeHandler, // Added 'c'\n\t\t\t\tchangeHandler, // Added 'd'\n\t\t\t\tchangeHandler, // Added 'e'\n\t\t\t\tchangeHandler, // Added 'f'\n\t\t\t\tprogressHandler, // Finished 'a' or 'b'\n\t\t\t\tchangeHandler, // Removed first of the queued (not executing), which is 'd'\n\t\t\t\tprogressHandler, // Finished 'a', 'b' or 'c'\n\t\t\t\tchangeHandler, // Removed the last one queued (not executing), which is 'f'\n\t\t\t\tprogressHandler, // Finished 'a', 'b', 'c' or 'e'\n\t\t\t\tprogressHandler, // Finished 'a', 'b', 'c' or 'e'\n\t\t\t\tcompleteHandler\n\t\t\t);\n\n\t\t\tdone();\n\t\t} );\n\n\t\tqueue.addItem( 'a' );\n\t\tqueue.addItem( 'b' );\n\t\tqueue.addItem( 'c' );\n\t\tqueue.addItem( 'd' );\n\t\tqueue.addItem( 'e' );\n\t\tqueue.addItem( 'f' );\n\t\tqueue.once( 'progress', () => {\n\t\t\tqueue.removeItem( queue.queued[ 0 ] );\n\n\t\t\tqueue.once( 'progress', () => {\n\t\t\t\tqueue.removeItem( queue.queued[ 0 ] );\n\t\t\t} );\n\t\t} );\n\t\tqueue.startExecuting();\n\t} );\n\n\tQUnit.test( 'Deleting currently running item', ( assert ) => {\n\t\tlet done, action, changeHandler, progressHandler, completeHandler, queue;\n\t\tdone = assert.async();\n\t\taction = sinon.spy( queueAction );\n\t\tchangeHandler = sinon.stub();\n\t\tprogressHandler = sinon.stub();\n\t\tcompleteHandler = sinon.stub();\n\t\tqueue = new uw.ConcurrentQueue( {\n\t\t\tcount: 2,\n\t\t\taction: action\n\t\t} );\n\n\t\tqueue.connect( null, {\n\t\t\tchange: changeHandler,\n\t\t\tprogress: progressHandler,\n\t\t\tcomplete: completeHandler\n\t\t} );\n\n\t\tqueue.on( 'complete', () => {\n\t\t\t// Every item in the queue was executed...\n\t\t\tsinon.assert.callCount( action, 4 );\n\n\t\t\tsinon.assert.callCount( changeHandler, 5 );\n\t\t\t// ...but the one we removed wasn't registered as finished\n\t\t\tsinon.assert.callCount( progressHandler, 3 );\n\t\t\tsinon.assert.callCount( completeHandler, 1 );\n\n\t\t\tassertCalledInOrder(\n\t\t\t\tchangeHandler, // Added 'a'\n\t\t\t\tchangeHandler, // Added 'b'\n\t\t\t\tchangeHandler, // Added 'c'\n\t\t\t\tchangeHandler, // Added 'd'\n\t\t\t\taction, // Started 'a'\n\t\t\t\taction, // Started 'b'\n\t\t\t\tprogressHandler, // Finished 'a' or 'b'\n\t\t\t\tchangeHandler, // Removed first of the executing, which is 'a' or 'b'\n\t\t\t\taction, // Started 'c'\n\t\t\t\taction, // Started 'd' - note how two threads are running still\n\t\t\t\tprogressHandler, // Finished 'c' or 'd'\n\t\t\t\tprogressHandler, // Finished 'c' or 'd'\n\t\t\t\tcompleteHandler\n\t\t\t);\n\n\t\t\tdone();\n\t\t} );\n\n\t\tqueue.addItem( 'a' );\n\t\tqueue.addItem( 'b' );\n\t\tqueue.addItem( 'c' );\n\t\tqueue.addItem( 'd' );\n\t\tqueue.once( 'progress', () => {\n\t\t\tqueue.removeItem( queue.running[ 0 ] );\n\t\t} );\n\t\tqueue.startExecuting();\n\t} );\n\n\tQUnit.test( 'Adding a new item when almost done', ( assert ) => {\n\t\tlet done, action, changeHandler, progressHandler, completeHandler, queue, onProgress;\n\t\tdone = assert.async();\n\t\t// This test seems extra flaky and was occasionally failing, double the delays\n\t\taction = sinon.spy( queueAction );\n\t\tchangeHandler = sinon.stub();\n\t\tprogressHandler = sinon.stub();\n\t\tcompleteHandler = sinon.stub();\n\t\tqueue = new uw.ConcurrentQueue( {\n\t\t\tcount: 2,\n\t\t\taction: action\n\t\t} );\n\n\t\tqueue.connect( null, {\n\t\t\tchange: changeHandler,\n\t\t\tprogress: progressHandler,\n\t\t\tcomplete: completeHandler\n\t\t} );\n\n\t\tqueue.on( 'complete', () => {\n\t\t\tsinon.assert.callCount( action, 5 );\n\t\t\tsinon.assert.callCount( changeHandler, 5 );\n\t\t\tsinon.assert.callCount( progressHandler, 5 );\n\t\t\tsinon.assert.callCount( completeHandler, 1 );\n\n\t\t\tassertCalledInOrder(\n\t\t\t\tchangeHandler, // Added 'a'\n\t\t\t\tchangeHandler, // Added 'b'\n\t\t\t\tchangeHandler, // Added 'c'\n\t\t\t\tchangeHandler, // Added 'd'\n\t\t\t\taction, // Started 'a'\n\t\t\t\taction, // Started 'b'\n\t\t\t\tprogressHandler, // Finished 'a' or 'b'\n\t\t\t\taction, // Started 'c'\n\t\t\t\tprogressHandler, // Finished 'a', 'b' or 'c'\n\t\t\t\taction, // Started 'd'\n\t\t\t\tprogressHandler, // Finished 'a', 'b', 'c' or 'd'\n\t\t\t\tchangeHandler, // Added 'e'\n\t\t\t\taction, // Started 'e' -- this starts a new thread\n\t\t\t\tprogressHandler, // Finished 'a', 'b', 'c', 'd' or 'e'\n\t\t\t\tprogressHandler, // Finished 'a', 'b', 'c', 'd' or 'e'\n\t\t\t\tcompleteHandler\n\t\t\t);\n\n\t\t\tdone();\n\t\t} );\n\n\t\tqueue.addItem( 'a' );\n\t\tqueue.addItem( 'b' );\n\t\tqueue.addItem( 'c' );\n\t\tqueue.addItem( 'd' );\n\t\tonProgress = function () {\n\t\t\tif ( queue.done.length === 3 ) {\n\t\t\t\tqueue.addItem( 'e' );\n\t\t\t\tqueue.off( 'progress', onProgress );\n\t\t\t}\n\t\t};\n\t\tqueue.on( 'progress', onProgress );\n\t\tqueue.startExecuting();\n\t} );\n\n}( mw.uploadWizard ) );\n","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-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/tests/qunit/uw.TitleDetailsWidget.test.js","messages":[{"ruleId":"prefer-const","severity":2,"message":"'fileNs' is never reassigned. Use 'const' instead.","line":5,"column":2,"nodeType":"Identifier","messageId":"useConst","endLine":5,"endColumn":8},{"ruleId":"prefer-const","severity":2,"message":"'makeTitleInFileNSCases' is never reassigned. Use 'const' instead.","line":6,"column":2,"nodeType":"Identifier","messageId":"useConst","endLine":6,"endColumn":24}],"suppressedMessages":[],"errorCount":2,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"( function ( uw ) {\n\t'use strict';\n\n\tlet fileNs, makeTitleInFileNSCases;\n\tfileNs = mw.config.get( 'wgFormattedNamespaces' )[ 6 ];\n\tmakeTitleInFileNSCases = [ {\n\t\tfilename: 'foo.png',\n\t\tprefixedText: fileNs + ':Foo.png',\n\t\tdesc: 'filename without namespace starting with a lower case letter'\n\t}, {\n\t\tfilename: 'foo_bar-baz.jpg',\n\t\tprefixedText: fileNs + ':Foo bar-baz.jpg',\n\t\tdesc: 'filename without namespace with space in it'\n\t}, {\n\t\tfilename: 'MediaWiki:foo_bar.jpg',\n\t\tprefixedText: null,\n\t\tdesc: 'filename starting with MediaWiki: (colons are disallowed)'\n\t}, {\n\t\tfilename: 'File:foo_bar.jpg',\n\t\tprefixedText: fileNs + ':Foo bar.jpg',\n\t\tdesc: 'filename starting with File:'\n\t}, {\n\t\tfilename: 'file:foo_bar.jpg',\n\t\tprefixedText: fileNs + ':Foo bar.jpg',\n\t\tdesc: 'filename starting with file:'\n\t}, {\n\t\tfilename: 'Foo part 1/2.jpg',\n\t\tprefixedText: null,\n\t\tdesc: 'filename with characters disallowed in file names'\n\t}, {\n\t\tfilename: 'Foo #1.jpg',\n\t\tprefixedText: null,\n\t\tdesc: 'filename including a # (disallowed in file names)'\n\t} ];\n\n\tQUnit.module( 'uw.TitleDetailsWidget', QUnit.newMwEnvironment() );\n\n\tQUnit.test( '.static.makeTitleInFileNS()', ( assert ) => {\n\t\tconst makeTitleInFileNS = uw.TitleDetailsWidget.static.makeTitleInFileNS;\n\n\t\tmakeTitleInFileNSCases.forEach( ( test ) => {\n\t\t\tconst title = makeTitleInFileNS( test.filename );\n\t\t\tassert.strictEqual(\n\t\t\t\ttitle ? title.getPrefixedText() : title,\n\t\t\t\ttest.prefixedText,\n\t\t\t\ttest.desc\n\t\t\t);\n\t\t} );\n\t} );\n}( mw.uploadWizard ) );\n","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-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 --- Disabling eslint rule 'no-mixed-spaces-and-tabs' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'implicit-arrow-linebreak' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'no-jquery/no-done-fail' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'no-jquery/no-done-fail' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'no-jquery/no-done-fail' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'no-mixed-spaces-and-tabs' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'implicit-arrow-linebreak' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'no-jquery/no-done-fail' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'no-mixed-spaces-and-tabs' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'implicit-arrow-linebreak' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'no-mixed-spaces-and-tabs' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'implicit-arrow-linebreak' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'no-mixed-spaces-and-tabs' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'no-jquery/no-done-fail' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'implicit-arrow-linebreak' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'no-jquery/no-done-fail' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'no-redeclare' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'no-jquery/no-done-fail' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'no-jquery/no-done-fail' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'no-jquery/no-done-fail' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'no-jquery/no-done-fail' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'no-jquery/no-done-fail' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'no-jquery/no-done-fail' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'no-jquery/no-done-fail' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'no-jquery/no-done-fail' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'no-jquery/no-done-fail' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'no-jquery/no-done-fail' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'prefer-const' (broken in .eslintrc.json) on .eslintrc.json Disabling eslint rule 'no-jquery/no-done-fail' (broken in tests/qunit/.eslintrc.json) on tests/qunit/.eslintrc.json Disabling eslint rule 'prefer-const' (broken in tests/qunit/.eslintrc.json) on tests/qunit/.eslintrc.json Disabling eslint rule 'prefer-const' (broken in tests/qunit/.eslintrc.json) on tests/qunit/.eslintrc.json Disabling eslint rule 'prefer-const' (broken in tests/qunit/.eslintrc.json) on tests/qunit/.eslintrc.json Disabling eslint rule 'prefer-const' (broken in tests/qunit/.eslintrc.json) on tests/qunit/.eslintrc.json Disabling eslint rule 'prefer-const' (broken in tests/qunit/.eslintrc.json) on tests/qunit/.eslintrc.json Disabling eslint rule 'no-jquery/no-done-fail' (broken in tests/qunit/.eslintrc.json) on tests/qunit/.eslintrc.json Disabling eslint rule 'prefer-const' (broken in tests/qunit/.eslintrc.json) on tests/qunit/.eslintrc.json Disabling eslint rule 'prefer-const' (broken in tests/qunit/.eslintrc.json) on tests/qunit/.eslintrc.json Disabling eslint rule 'prefer-const' (broken in tests/qunit/.eslintrc.json) on tests/qunit/.eslintrc.json $ ./node_modules/.bin/grunt stylelint --- stdout --- Running "stylelint:all" (stylelint) task >> Linted 14 files without errors Done. --- end --- $ /usr/bin/npm ci --- stdout --- added 438 packages, and audited 439 packages in 5s 97 packages are looking for funding run `npm fund` for details 1 high severity vulnerability To address all issues, run: npm audit fix Run `npm audit` for details. --- end --- $ /usr/bin/npm test --- stdout --- > test > grunt test Running "eslint:all" (eslint) task /src/repo/resources/controller/uw.controller.Deed.js 44:4 warning 'deedController' is never reassigned. Use 'const' instead prefer-const 52:3 warning 'valid' is never reassigned. Use 'const' instead prefer-const 57:4 warning Mixed spaces and tabs no-mixed-spaces-and-tabs 57:6 warning Expected no linebreak before this expression implicit-arrow-linebreak 58:3 warning Mixed spaces and tabs no-mixed-spaces-and-tabs /src/repo/resources/controller/uw.controller.Details.js 65:4 warning 'serialized' is never reassigned. Use 'const' instead prefer-const 96:4 warning 'invalidStates' is never reassigned. Use 'const' instead prefer-const 97:4 warning 'invalids' is never reassigned. Use 'const' instead prefer-const 98:4 warning 'valids' is never reassigned. Use 'const' instead prefer-const 153:3 warning Prefer .then to .done no-jquery/no-done-fail 238:4 warning '$message' is never reassigned. Use 'const' instead prefer-const 239:4 warning '$ul' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/controller/uw.controller.Step.js 223:7 warning 'okCount' is never reassigned. Use 'const' instead prefer-const 233:3 warning '$buttons' is never reassigned. Use 'const' instead prefer-const 324:4 warning 'copy' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/controller/uw.controller.Tutorial.js 63:3 warning Prefer .then to .done no-jquery/no-done-fail 63:3 warning Prefer .then to .fail no-jquery/no-done-fail /src/repo/resources/controller/uw.controller.Upload.js 69:4 warning 'max' is never reassigned. Use 'const' instead prefer-const 71:3 warning 'haveUploads' is never reassigned. Use 'const' instead prefer-const 72:3 warning 'fewerThanMax' is never reassigned. Use 'const' instead prefer-const 223:3 warning 'upload' is never reassigned. Use 'const' instead prefer-const 251:4 warning 'uploadObjs' is never reassigned. Use 'const' instead prefer-const 252:4 warning 'controller' is never reassigned. Use 'const' instead prefer-const 307:4 warning 'actualMaxSize' is never reassigned. Use 'const' instead prefer-const 311:4 warning 'filename' is never reassigned. Use 'const' instead prefer-const 312:4 warning 'basename' is never reassigned. Use 'const' instead prefer-const 335:3 warning 'extension' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/deed/uw.deed.External.js 66:10 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign /src/repo/resources/deed/uw.deed.OwnWork.js 29:7 warning 'deed' is never reassigned. Use 'const' instead prefer-const 88:3 warning 'deed' is never reassigned. Use 'const' instead prefer-const 89:3 warning 'languageCode' is never reassigned. Use 'const' instead prefer-const 91:3 warning 'defaultLicense' is never reassigned. Use 'const' instead prefer-const 92:3 warning 'defaultLicConfig' is never reassigned. Use 'const' instead prefer-const 99:3 warning '$defaultLicenseLink' is never reassigned. Use 'const' instead prefer-const 125:3 warning '$crossfader' is never reassigned. Use 'const' instead prefer-const 128:3 warning '$customDiv' is never reassigned. Use 'const' instead prefer-const 136:3 warning 'crossfaderWidget' is never reassigned. Use 'const' instead prefer-const 148:3 warning '$formFields' is never reassigned. Use 'const' instead prefer-const 152:3 warning '$toggler' is never reassigned. Use 'const' instead prefer-const 192:7 warning 'author' is never reassigned. Use 'const' instead prefer-const 200:3 warning 'userPageTitle' is never reassigned. Use 'const' instead prefer-const 215:10 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 255:16 warning 'ownWork' is never reassigned. Use 'const' instead prefer-const 277:3 warning Prefer .then to .done no-jquery/no-done-fail 297:3 warning Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/deed/uw.deed.ThirdParty.js 178:10 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign /src/repo/resources/details/uw.CategoriesDetailsWidget.js 87:3 warning Mixed spaces and tabs no-mixed-spaces-and-tabs 87:5 warning Expected no linebreak before this expression implicit-arrow-linebreak 88:2 warning Mixed spaces and tabs no-mixed-spaces-and-tabs 98:3 warning 'categories' is never reassigned. Use 'const' instead prefer-const 128:3 warning Mixed spaces and tabs no-mixed-spaces-and-tabs 128:5 warning Expected no linebreak before this expression implicit-arrow-linebreak 129:2 warning Mixed spaces and tabs no-mixed-spaces-and-tabs /src/repo/resources/details/uw.DropdownWidget.js 13:12 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign /src/repo/resources/details/uw.LocationDetailsWidget.js 12:17 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 71:3 warning Prefer .then to .done no-jquery/no-done-fail 84:3 warning Prefer .then to .done no-jquery/no-done-fail 115:7 warning 'errors' is never reassigned. Use 'const' instead prefer-const 116:4 warning 'serialized' is never reassigned. Use 'const' instead prefer-const 117:4 warning 'parsed' is never reassigned. Use 'const' instead prefer-const 165:4 warning 'serialized' is never reassigned. Use 'const' instead prefer-const 194:4 warning 'result' is never reassigned. Use 'const' instead prefer-const 210:4 warning 'result' is never reassigned. Use 'const' instead prefer-const 211:4 warning 'serialized' is never reassigned. Use 'const' instead prefer-const 258:7 warning 'sign' is never reassigned. Use 'const' instead prefer-const 268:3 warning 'parts' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/details/uw.MultipleLanguageInputWidget.js 16:17 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 50:26 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 60:7 warning 'allLanguages' is never reassigned. Use 'const' instead prefer-const 61:4 warning 'unusedLanguages' is never reassigned. Use 'const' instead prefer-const 73:16 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 78:12 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 82:3 warning 'item' is never reassigned. Use 'const' instead prefer-const 100:7 warning 'allLanguages' is never reassigned. Use 'const' instead prefer-const 101:4 warning 'unusedLanguages' is never reassigned. Use 'const' instead prefer-const 102:4 warning 'items' is never reassigned. Use 'const' instead prefer-const 114:16 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 192:4 warning 'errors' is never reassigned. Use 'const' instead prefer-const 215:7 warning 'values' is never reassigned. Use 'const' instead prefer-const 216:4 warning 'widgets' is never reassigned. Use 'const' instead prefer-const 272:13 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign /src/repo/resources/details/uw.SingleLanguageInputWidget.js 17:17 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 226:4 warning 'text' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/details/uw.TextWidget.js 13:17 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign /src/repo/resources/details/uw.TitleDetailsWidget.js 49:4 warning 'illegalFileChars' is never reassigned. Use 'const' instead prefer-const 82:3 warning 'value' is never reassigned. Use 'const' instead prefer-const 94:3 warning 'title' is never reassigned. Use 'const' instead prefer-const 156:7 warning Mixed spaces and tabs no-mixed-spaces-and-tabs 156:9 warning Expected no linebreak before this expression implicit-arrow-linebreak 157:6 warning Mixed spaces and tabs no-mixed-spaces-and-tabs 181:3 warning 'errors' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/handlers/mw.ApiUploadHandler.js 224:7 warning 'allDuplicates' is never reassigned. Use 'const' instead prefer-const 224:23 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 225:4 warning '$extra' is never reassigned. Use 'const' instead prefer-const 226:4 warning '$ul' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/jquery.arrowSteps/jquery.arrowSteps.js 39:4 warning '$el' is never reassigned. Use 'const' instead prefer-const 42:3 warning '$steps' is never reassigned. Use 'const' instead prefer-const 44:3 warning 'width' is never reassigned. Use 'const' instead prefer-const 71:4 warning '$steps' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.DestinationChecker.js 77:4 warning Mixed spaces and tabs no-mixed-spaces-and-tabs 77:6 warning Expected no linebreak before this expression implicit-arrow-linebreak 78:3 warning Mixed spaces and tabs no-mixed-spaces-and-tabs 94:8 warning 'checker' is never reassigned. Use 'const' instead prefer-const 95:5 warning 'NS_FILE' is never reassigned. Use 'const' instead prefer-const 98:4 warning 'titleObj' is never reassigned. Use 'const' instead prefer-const 99:4 warning 'ext' is never reassigned. Use 'const' instead prefer-const 101:4 warning 'prefix' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.Escaper.js 31:4 warning 'extractedTemplates' is never reassigned. Use 'const' instead prefer-const 32:4 warning 'extractedLinks' is never reassigned. Use 'const' instead prefer-const 34:43 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 52:8 warning 'extracts' is never reassigned. Use 'const' instead prefer-const 61:5 warning 'regex' is never reassigned. Use 'const' instead prefer-const 62:5 warning 'callback' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.GroupProgressBar.js 59:8 warning 'bar' is never reassigned. Use 'const' instead prefer-const 146:5 warning 'remainingTime' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.UploadWizard.js 4:1 warning Missing JSDoc @param "uw" type jsdoc/require-param-type 22:3 warning 'maxSimPref' is never reassigned. Use 'const' instead prefer-const 64:8 warning 'self' is never reassigned. Use 'const' instead prefer-const 65:5 warning 'steps' is never reassigned. Use 'const' instead prefer-const 74:4 warning 'uploadStep' is never reassigned. Use 'const' instead prefer-const 127:5 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 134:5 warning 'original' is never reassigned. Use 'const' instead prefer-const 138:5 warning 'override' is never reassigned. Use 'const' instead prefer-const 187:4 warning 'deeds' is never reassigned. Use 'const' instead prefer-const 188:4 warning 'doOwnWork' is never reassigned. Use 'const' instead prefer-const 189:4 warning 'doThirdParty' is never reassigned. Use 'const' instead prefer-const 197:3 warning 'api' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.UploadWizardDetails.js 45:8 warning '$moreDetailsWrapperDiv' is never reassigned. Use 'const' instead prefer-const 47:5 warning 'details' is never reassigned. Use 'const' instead prefer-const 48:5 warning 'config' is never reassigned. Use 'const' instead prefer-const 56:13 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 73:48 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 83:40 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 90:55 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 98:57 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 105:44 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 113:47 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 118:51 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 123:53 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 151:4 warning '$moreDetailsDiv' is never reassigned. Use 'const' instead prefer-const 215:5 warning Prefer .then to .done no-jquery/no-done-fail 255:4 warning Prefer .then to .done no-jquery/no-done-fail 383:4 warning Mixed spaces and tabs no-mixed-spaces-and-tabs 383:6 warning Expected no linebreak before this expression implicit-arrow-linebreak 384:3 warning Mixed spaces and tabs no-mixed-spaces-and-tabs 448:5 warning 'yyyyMmDdRegex' is never reassigned. Use 'const' instead prefer-const 449:5 warning 'timeRegex' is never reassigned. Use 'const' instead prefer-const 470:7 warning 'dateInfo' is never reassigned. Use 'const' instead prefer-const 508:4 warning 'saneTime' is never reassigned. Use 'const' instead prefer-const 601:5 warning 'm' is never reassigned. Use 'const' instead prefer-const 603:5 warning 'values' is never reassigned. Use 'const' instead prefer-const 653:4 warning 'languages' is never reassigned. Use 'const' instead prefer-const 662:3 warning JSDoc @return declaration present but return expression not available in function jsdoc/require-returns-check 672:21 warning 'serialized' is never reassigned. Use 'const' instead prefer-const 734:5 warning 'substitutions' is never reassigned. Use 'const' instead prefer-const 734:25 warning 'substList' is never reassigned. Use 'const' instead prefer-const 735:5 warning 'deed' is never reassigned. Use 'const' instead prefer-const 793:10 warning ES2015 RegExp 'u' flag is forbidden es-x/no-regexp-u-flag 813:8 warning 'details' is never reassigned. Use 'const' instead prefer-const 823:4 warning 'wikitext' is never reassigned. Use 'const' instead prefer-const 824:4 warning 'promise' is never reassigned. Use 'const' instead prefer-const 843:5 warning 'tags' is never reassigned. Use 'const' instead prefer-const 844:5 warning 'deed' is never reassigned. Use 'const' instead prefer-const 846:5 warning 'config' is never reassigned. Use 'const' instead prefer-const 869:4 warning 'params' is never reassigned. Use 'const' instead prefer-const 936:5 warning 'details' is never reassigned. Use 'const' instead prefer-const 939:5 warning 'deferred' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.UploadWizardLicenseInput.js 17:7 warning 'self' is never reassigned. Use 'const' instead prefer-const 18:4 warning 'groups' is never reassigned. Use 'const' instead prefer-const 77:2 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 183:9 warning 'templates' is never reassigned. Use 'const' instead prefer-const 209:5 warning 'addError' is never reassigned. Use 'const' instead prefer-const 216:5 warning 'selectedInputs' is never reassigned. Use 'const' instead prefer-const 226:7 warning 'data' is never reassigned. Use 'const' instead prefer-const 232:6 warning 'wikitext' is never reassigned. Use 'const' instead prefer-const 268:28 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign /src/repo/resources/mw.UploadWizardPage.js 31:4 warning 'config' is never reassigned. Use 'const' instead prefer-const 53:3 warning 'uploadWizard' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.UploadWizardUpload.js 8:1 warning Missing JSDoc @param "uw" type jsdoc/require-param-type 11:14 warning 'uw' is defined but never used no-unused-vars 204:4 warning 'deferred' is never reassigned. Use 'const' instead prefer-const 205:4 warning 'upload' is never reassigned. Use 'const' instead prefer-const 222:16 warning 'Uint8Array' is already defined as a built-in global variable no-redeclare 223:16 warning ES2015 'Uint8Array' is forbidden es-x/no-typed-arrays 314:4 warning 'upload' is never reassigned. Use 'const' instead prefer-const 382:3 warning Prefer .then to .done no-jquery/no-done-fail 382:3 warning Prefer .then to .fail no-jquery/no-done-fail 396:7 warning 'requestedTitle' is never reassigned. Use 'const' instead prefer-const 430:3 warning 'params' is never reassigned. Use 'const' instead prefer-const 448:3 warning Prefer .then to .done no-jquery/no-done-fail 448:3 warning Prefer .then to .fail no-jquery/no-done-fail 488:21 warning 'image' is never reassigned. Use 'const' instead prefer-const 585:5 warning 'constraint' is never reassigned. Use 'const' instead prefer-const 629:3 warning 'scaling' is never reassigned. Use 'const' instead prefer-const 631:3 warning 'width' is never reassigned. Use 'const' instead prefer-const 632:3 warning 'height' is never reassigned. Use 'const' instead prefer-const 640:3 warning 'dx' is never reassigned. Use 'const' instead prefer-const 641:3 warning 'dy' is never reassigned. Use 'const' instead prefer-const 666:3 warning '$canvas' is never reassigned. Use 'const' instead prefer-const 667:3 warning 'ctx' is never reassigned. Use 'const' instead prefer-const 715:7 warning 'constraints' is never reassigned. Use 'const' instead prefer-const 767:3 warning Prefer .then to .done no-jquery/no-done-fail 767:3 warning Prefer .then to .fail no-jquery/no-done-fail 775:6 warning Prefer .then to .done no-jquery/no-done-fail 778:7 warning Prefer .then to .done no-jquery/no-done-fail 802:4 warning 'deferred' is never reassigned. Use 'const' instead prefer-const 803:4 warning 'upload' is never reassigned. Use 'const' instead prefer-const 828:9 warning 'canvas' is never reassigned. Use 'const' instead prefer-const 831:8 warning 'context' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.UploadWizardUploadInterface.js 206:3 warning Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/transports/mw.FormDataTransport.js 97:3 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 156:4 warning 'deferred' is never reassigned. Use 'const' instead prefer-const 157:4 warning 'fileSize' is never reassigned. Use 'const' instead prefer-const 158:4 warning 'chunkSize' is never reassigned. Use 'const' instead prefer-const 159:4 warning 'transport' is never reassigned. Use 'const' instead prefer-const 169:5 warning Prefer .then to .done no-jquery/no-done-fail 170:6 warning Prefer .then to .done no-jquery/no-done-fail 170:6 warning Prefer .then to .fail no-jquery/no-done-fail 194:7 warning 'params' is never reassigned. Use 'const' instead prefer-const 195:4 warning 'transport' is never reassigned. Use 'const' instead prefer-const 196:4 warning 'bytesAvailable' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/ui/steps/uw.ui.Deed.js 55:3 warning Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/ui/steps/uw.ui.Details.js 90:3 warning Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/ui/steps/uw.ui.Thanks.js 30:4 warning 'thanks' is never reassigned. Use 'const' instead prefer-const 48:3 warning '$header' is never reassigned. Use 'const' instead prefer-const 69:3 warning 'beginButtonTarget' is never reassigned. Use 'const' instead prefer-const 98:3 warning 'thumbWikiText' is never reassigned. Use 'const' instead prefer-const 104:3 warning '$thanksDiv' is never reassigned. Use 'const' instead prefer-const 106:3 warning '$thumbnailWrapDiv' is never reassigned. Use 'const' instead prefer-const 109:3 warning '$thumbnailDiv' is never reassigned. Use 'const' instead prefer-const 112:3 warning '$thumbnailCaption' is never reassigned. Use 'const' instead prefer-const 115:3 warning '$thumbnailLink' is never reassigned. Use 'const' instead prefer-const 128:3 warning Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/ui/steps/uw.ui.Tutorial.js 125:3 warning Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/ui/steps/uw.ui.Upload.js 210:6 warning Prefer .then to .done no-jquery/no-done-fail 222:3 warning Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/ui/uw.ui.DeedPreview.js 30:3 warning Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/ui/uw.ui.Step.js 101:3 warning Prefer .then to .done no-jquery/no-done-fail 119:3 warning Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/uw.ConcurrentQueue.js 117:3 warning 'index' is never reassigned. Use 'const' instead prefer-const 139:3 warning 'item' is never reassigned. Use 'const' instead prefer-const 145:3 warning 'promise' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/uw.CopyMetadataWidget.js 14:4 warning 'checkboxes' is never reassigned. Use 'const' instead prefer-const 15:4 warning '$copyMetadataWrapperDiv' is never reassigned. Use 'const' instead prefer-const 16:4 warning '$copyMetadataDiv' is never reassigned. Use 'const' instead prefer-const 157:4 warning 'uploads' is never reassigned. Use 'const' instead prefer-const 158:4 warning 'sourceUpload' is never reassigned. Use 'const' instead prefer-const 159:4 warning 'serialized' is never reassigned. Use 'const' instead prefer-const 161:4 warning 'sourceValue' is never reassigned. Use 'const' instead prefer-const 214:4 warning 'uploads' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/uw.FieldLayout.js 20:12 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign /src/repo/resources/uw.LicenseGroup.js 37:17 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 132:4 warning 'option' is never reassigned. Use 'const' instead prefer-const 167:4 warning 'option' is never reassigned. Use 'const' instead prefer-const 191:4 warning 'self' is never reassigned. Use 'const' instead prefer-const 192:4 warning 'values' is never reassigned. Use 'const' instead prefer-const 194:3 warning 'wikiTexts' is never reassigned. Use 'const' instead prefer-const 196:5 warning 'value' is never reassigned. Use 'const' instead prefer-const 222:7 warning 'self' is never reassigned. Use 'const' instead prefer-const 223:4 warning 'result' is never reassigned. Use 'const' instead prefer-const 248:7 warning 'self' is never reassigned. Use 'const' instead prefer-const 249:4 warning 'selectArray' is never reassigned. Use 'const' instead prefer-const 303:7 warning 'licenseInfo' is never reassigned. Use 'const' instead prefer-const 306:3 warning 'licenseText' is never reassigned. Use 'const' instead prefer-const 319:7 warning 'licenseInfo' is never reassigned. Use 'const' instead prefer-const 320:4 warning 'messageKey' is never reassigned. Use 'const' instead prefer-const 323:4 warning 'languageCode' is never reassigned. Use 'const' instead prefer-const 328:4 warning '$icons' is never reassigned. Use 'const' instead prefer-const 334:3 warning '$licenseLink' is never reassigned. Use 'const' instead prefer-const 343:3 warning '$label' is never reassigned. Use 'const' instead prefer-const 361:7 warning 'self' is never reassigned. Use 'const' instead prefer-const 372:3 warning 'button' is never reassigned. Use 'const' instead prefer-const 397:3 warning 'input' is never reassigned. Use 'const' instead prefer-const 413:3 warning Prefer .then to .done no-jquery/no-done-fail 413:3 warning Prefer .then to .fail no-jquery/no-done-fail /src/repo/resources/uw.ValidationMessageElement.js 39:2 warning JSDoc @return declaration present but return expression not available in function jsdoc/require-returns-check 91:3 warning '$listItem' is never reassigned. Use 'const' instead prefer-const /src/repo/tests/qunit/controller/uw.controller.Details.test.js 57:7 warning 'step' is never reassigned. Use 'const' instead prefer-const 61:4 warning 'stepUiStub' is never reassigned. Use 'const' instead prefer-const 110:4 warning 'done' is never reassigned. Use 'const' instead prefer-const 111:4 warning 'donestub' is never reassigned. Use 'const' instead prefer-const 112:4 warning 'ds' is never reassigned. Use 'const' instead prefer-const 113:4 warning 'ps' is never reassigned. Use 'const' instead prefer-const 117:3 warning 'tostub' is never reassigned. Use 'const' instead prefer-const 124:3 warning 'step' is never reassigned. Use 'const' instead prefer-const 135:3 warning Prefer .then to .done no-jquery/no-done-fail /src/repo/tests/qunit/controller/uw.controller.Tutorial.test.js 33:4 warning 'acwStub' is never reassigned. Use 'const' instead prefer-const 54:3 warning 'mnStub' is never reassigned. Use 'const' instead prefer-const /src/repo/tests/qunit/mw.UploadWizardLicenseInput.test.js 17:6 warning 'config' is never reassigned. Use 'const' instead prefer-const 18:3 warning '$fixture' is never reassigned. Use 'const' instead prefer-const 21:2 warning 'uwLicenseInput' is never reassigned. Use 'const' instead prefer-const 27:6 warning 'config' is never reassigned. Use 'const' instead prefer-const 28:3 warning '$fixture' is never reassigned. Use 'const' instead prefer-const 33:2 warning 'uwLicenseInput' is never reassigned. Use 'const' instead prefer-const 37:2 warning '$input' is never reassigned. Use 'const' instead prefer-const 41:2 warning '$label' is never reassigned. Use 'const' instead prefer-const 46:6 warning 'config' is never reassigned. Use 'const' instead prefer-const 56:3 warning '$fixture' is never reassigned. Use 'const' instead prefer-const 59:2 warning 'uwLicenseInput' is never reassigned. Use 'const' instead prefer-const /src/repo/tests/qunit/mw.UploadWizardUpload.test.js 23:4 warning 'oldconf' is never reassigned. Use 'const' instead prefer-const 27:3 warning 'upload' is never reassigned. Use 'const' instead prefer-const /src/repo/tests/qunit/mw.fileApi.test.js 46:15 warning 'testFile' is never reassigned. Use 'const' instead prefer-const 47:4 warning 'fakeVideo' is never reassigned. Use 'const' instead prefer-const /src/repo/tests/qunit/transports/mw.FormDataTransport.test.js 27:3 warning 'config' is never reassigned. Use 'const' instead prefer-const 86:4 warning 'transport' is never reassigned. Use 'const' instead prefer-const 87:4 warning 'fakeFile' is never reassigned. Use 'const' instead prefer-const 97:3 warning 'request' is never reassigned. Use 'const' instead prefer-const 107:4 warning 'transport' is never reassigned. Use 'const' instead prefer-const 108:4 warning 'fakeFile' is never reassigned. Use 'const' instead prefer-const 125:3 warning 'request' is never reassigned. Use 'const' instead prefer-const 146:3 warning Prefer .then to .fail no-jquery/no-done-fail 179:10 warning Prefer .then to .done no-jquery/no-done-fail 198:10 warning Prefer .then to .done no-jquery/no-done-fail 218:3 warning Prefer .then to .fail no-jquery/no-done-fail /src/repo/tests/qunit/uw.ConcurrentQueue.test.js 38:3 warning 'calls' is never reassigned. Use 'const' instead prefer-const 65:3 warning 'done' is never reassigned. Use 'const' instead prefer-const 66:3 warning 'action' is never reassigned. Use 'const' instead prefer-const 67:3 warning 'queue' is never reassigned. Use 'const' instead prefer-const 98:3 warning 'done' is never reassigned. Use 'const' instead prefer-const 99:3 warning 'changeHandler' is never reassigned. Use 'const' instead prefer-const 100:3 warning 'progressHandler' is never reassigned. Use 'const' instead prefer-const 101:3 warning 'completeHandler' is never reassigned. Use 'const' instead prefer-const 102:3 warning 'queue' is never reassigned. Use 'const' instead prefer-const 139:3 warning 'done' is never reassigned. Use 'const' instead prefer-const 140:3 warning 'queue' is never reassigned. Use 'const' instead prefer-const 167:3 warning 'done' is never reassigned. Use 'const' instead prefer-const 168:3 warning 'queue' is never reassigned. Use 'const' instead prefer-const 184:3 warning 'done' is never reassigned. Use 'const' instead prefer-const 185:3 warning 'changeHandler' is never reassigned. Use 'const' instead prefer-const 186:3 warning 'progressHandler' is never reassigned. Use 'const' instead prefer-const 187:3 warning 'completeHandler' is never reassigned. Use 'const' instead prefer-const 188:3 warning 'queue' is never reassigned. Use 'const' instead prefer-const 240:3 warning 'done' is never reassigned. Use 'const' instead prefer-const 241:3 warning 'changeHandler' is never reassigned. Use 'const' instead prefer-const 242:3 warning 'progressHandler' is never reassigned. Use 'const' instead prefer-const 243:3 warning 'completeHandler' is never reassigned. Use 'const' instead prefer-const 244:3 warning 'queue' is never reassigned. Use 'const' instead prefer-const 297:3 warning 'done' is never reassigned. Use 'const' instead prefer-const 298:3 warning 'action' is never reassigned. Use 'const' instead prefer-const 299:3 warning 'changeHandler' is never reassigned. Use 'const' instead prefer-const 300:3 warning 'progressHandler' is never reassigned. Use 'const' instead prefer-const 301:3 warning 'completeHandler' is never reassigned. Use 'const' instead prefer-const 302:3 warning 'queue' is never reassigned. Use 'const' instead prefer-const 353:3 warning 'done' is never reassigned. Use 'const' instead prefer-const 355:3 warning 'action' is never reassigned. Use 'const' instead prefer-const 356:3 warning 'changeHandler' is never reassigned. Use 'const' instead prefer-const 357:3 warning 'progressHandler' is never reassigned. Use 'const' instead prefer-const 358:3 warning 'completeHandler' is never reassigned. Use 'const' instead prefer-const 359:3 warning 'queue' is never reassigned. Use 'const' instead prefer-const 402:3 warning 'onProgress' is never reassigned. Use 'const' instead prefer-const /src/repo/tests/qunit/uw.TitleDetailsWidget.test.js 5:2 warning 'fileNs' is never reassigned. Use 'const' instead prefer-const 6:2 warning 'makeTitleInFileNSCases' is never reassigned. Use 'const' instead prefer-const ✖ 352 problems (0 errors, 352 warnings) Running "stylelint:all" (stylelint) task >> Linted 14 files without errors Running "banana:MediaUploader" (banana) task >> 3 message directories checked. Done. --- end --- Upgrading c:mediawiki/mediawiki-codesniffer from 45.0.0 -> 47.0.0 $ /usr/bin/composer update --- stderr --- Loading composer repositories with package information Updating dependencies Lock file operations: 0 installs, 2 updates, 0 removals - Upgrading mediawiki/mediawiki-codesniffer (v45.0.0 => v47.0.0) - Upgrading squizlabs/php_codesniffer (3.10.3 => 3.12.2) Writing lock file Installing dependencies from lock file (including require-dev) Package operations: 0 installs, 2 updates, 0 removals 0 [>---------------------------] 0 [->--------------------------] - Upgrading squizlabs/php_codesniffer (3.10.3 => 3.12.2): Extracting archive - Upgrading mediawiki/mediawiki-codesniffer (v45.0.0 => v47.0.0): Extracting archive 0/2 [>---------------------------] 0% 1/2 [==============>-------------] 50% 2/2 [============================] 100% Generating autoload files 17 packages you are using are looking for funding. Use the `composer fund` command to find out more! No security vulnerability advisories found --- stdout --- PHP CodeSniffer Config installed_paths set to ../../mediawiki/mediawiki-codesniffer,../../phpcsstandards/phpcsextra,../../phpcsstandards/phpcsutils --- end --- Previously failing phpcs rules: {'MediaWiki.WhiteSpace.SpaceBeforeSingleLineComment.NewLineComment', 'MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic'} $ vendor/bin/phpcs --report=json --- stdout --- {"totals":{"errors":3,"warnings":1,"fixable":0},"files":{"\/src\/repo\/MediaUploader.namespaces.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/defines.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/Exception\/InvalidCampaignException.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/Exception\/BaseCampaignException.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/Exception\/InvalidFormatException.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/Exception\/IncompleteRecordException.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/MediaUploaderResourceModuleFactory.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Hooks\/RegistrationHooks.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Config\/RawConfig.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/MediaUploaderResourceModule.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Config\/ConfigUnitTestCase.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Config\/ConfigBase.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/CampaignContent.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/CampaignSelectQueryBuilder.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Config\/ConfigCacheInvalidator.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Config\/GlobalConfigAnchorUpdateJob.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/ServiceWiring.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Hooks\/Hooks.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/.phan\/config.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/Validator.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Config\/CampaignParsedConfig.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/Exception\/InvalidSchemaException.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Config\/GlobalParsedConfig.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Config\/ConfigFactoryTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/MediaUploader.alias.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Config\/ConfigParserFactory.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Config\/RequestConfig.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Config\/RequestConfigTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/CampaignRecord.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/MediaUploaderServices.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Special\/Campaigns.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Campaign\/InvalidCampaignExceptionTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Special\/MediaUploaderSimpleForm.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/integration\/Api\/QueryAllCampaignsTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Campaign\/CampaignRecordTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/CampaignPageFormatter.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Api\/QueryAllCampaigns.php":{"errors":3,"warnings":0,"messages":[{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":159,"column":12},{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":163,"column":12},{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":189,"column":12}]},"\/src\/repo\/includes\/Hooks\/CampaignContentHooks.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Config\/ConfigBaseTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Hooks\/CampaignHooks.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Config\/RawConfigTest.php":{"errors":0,"warnings":1,"messages":[{"message":"Comments should start on new line.","source":"MediaWiki.WhiteSpace.SpaceBeforeSingleLineComment.NewLineComment","severity":5,"fixable":false,"type":"WARNING","line":32,"column":49}]},"\/src\/repo\/MediaUploader.config.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Config\/ParsedConfig.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Campaign\/CampaignStoreTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Config\/ConfigCacheInvalidatorTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/integration\/CampaignStoreTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Config\/ConfigParser.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Config\/ConfigFactory.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Hooks\/CampaignContentHooksTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/integration\/MediaUploaderResourceModuleTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/integration\/MaintenanceMigrateCampaignsTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/integration\/MediaUploaderServicesTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/maintenance\/MigrateCampaigns.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/CampaignContentHandler.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/integration\/CampaignStatsTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/integration\/SpecialMediaUploaderTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/integration\/ConfigParserTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/CampaignStore.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Hooks\/CampaignHooksTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Config\/ParsedConfigTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Hooks\/RegistrationHooksTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/integration\/GlobalConfigAnchorUpdateJobTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Special\/MediaUploader.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/CampaignStats.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Campaign\/CampaignContentTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Config\/GlobalParsedConfigTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Config\/ConfigParserTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Campaign\/ValidatorTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Config\/CampaignParsedConfigTest.php":{"errors":0,"warnings":0,"messages":[]}}} --- end --- PHPCS run failed $ vendor/bin/phpcs --report=json --- stdout --- {"totals":{"errors":3,"warnings":1,"fixable":0},"files":{"\/src\/repo\/defines.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/MediaUploader.namespaces.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/Exception\/InvalidCampaignException.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/Exception\/IncompleteRecordException.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/Exception\/BaseCampaignException.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/Exception\/InvalidFormatException.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Config\/RawConfig.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/MediaUploaderResourceModuleFactory.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Config\/GlobalParsedConfig.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Config\/GlobalConfigAnchorUpdateJob.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/ServiceWiring.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Config\/ConfigBase.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Hooks\/RegistrationHooks.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Config\/ConfigUnitTestCase.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/MediaUploaderResourceModule.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/MediaUploader.alias.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Config\/ConfigCacheInvalidator.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/Validator.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/Exception\/InvalidSchemaException.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Special\/Campaigns.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Special\/MediaUploaderSimpleForm.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/.phan\/config.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Config\/ParsedConfig.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Hooks\/Hooks.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Config\/ConfigFactoryTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Config\/RequestConfigTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/CampaignRecord.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Api\/QueryAllCampaigns.php":{"errors":3,"warnings":0,"messages":[{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":159,"column":12},{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":163,"column":12},{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":189,"column":12}]},"\/src\/repo\/includes\/Campaign\/CampaignContent.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Config\/RequestConfig.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/CampaignPageFormatter.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Campaign\/InvalidCampaignExceptionTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Config\/CampaignParsedConfig.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/MediaUploaderServices.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Config\/ConfigParserFactory.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Config\/RawConfigTest.php":{"errors":0,"warnings":1,"messages":[{"message":"Comments should start on new line.","source":"MediaWiki.WhiteSpace.SpaceBeforeSingleLineComment.NewLineComment","severity":5,"fixable":false,"type":"WARNING","line":32,"column":49}]},"\/src\/repo\/includes\/Hooks\/CampaignContentHooks.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Config\/ConfigBaseTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/CampaignSelectQueryBuilder.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/integration\/Api\/QueryAllCampaignsTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/maintenance\/MigrateCampaigns.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Config\/ConfigParser.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/MediaUploader.config.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Campaign\/CampaignStoreTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Campaign\/CampaignRecordTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Config\/ConfigCacheInvalidatorTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Hooks\/CampaignContentHooksTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/integration\/MediaUploaderResourceModuleTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Hooks\/CampaignHooks.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/CampaignStore.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Config\/ConfigFactory.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/integration\/MediaUploaderServicesTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/CampaignContentHandler.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/integration\/CampaignStoreTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/integration\/CampaignStatsTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Campaign\/CampaignStats.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Config\/GlobalParsedConfigTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/integration\/MaintenanceMigrateCampaignsTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/integration\/ConfigParserTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/integration\/GlobalConfigAnchorUpdateJobTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Config\/ParsedConfigTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/Special\/MediaUploader.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/integration\/SpecialMediaUploaderTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Campaign\/CampaignContentTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Config\/ConfigParserTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Campaign\/ValidatorTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Hooks\/CampaignHooksTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Hooks\/RegistrationHooksTest.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/tests\/phpunit\/unit\/Config\/CampaignParsedConfigTest.php":{"errors":0,"warnings":0,"messages":[]}}} --- end --- $ git checkout .phpcs.xml --- stderr --- Updated 1 path from the index --- stdout --- --- end --- $ /usr/bin/composer install --- stderr --- Installing dependencies from lock file (including require-dev) Verifying lock file contents can be installed on current platform. Nothing to install, update or remove Generating autoload files 17 packages you are using are looking for funding. Use the `composer fund` command to find out more! --- stdout --- --- end --- $ /usr/bin/composer test --- stderr --- > parallel-lint . --exclude vendor --exclude node_modules > phpcs -sp --cache > minus-x check . --- stdout --- PHP 8.2.28 | 10 parallel jobs ............................................................ 60/69 ( 86%) ......... 69/69 (100%) Checked 69 files in 0.3 seconds No syntax error found ................................... 35 / 35 (100%) Time: 249ms; Memory: 10MB MinusX ====== Processing /src/repo... ............................................................. ............................................................. ............................................................. ............................................................. ............................................................. All good! --- end --- $ /usr/bin/npm audit --json --- stdout --- { "auditReportVersion": 2, "vulnerabilities": { "cross-spawn": { "name": "cross-spawn", "severity": "high", "isDirect": false, "via": [ { "source": 1104664, "name": "cross-spawn", "dependency": "cross-spawn", "title": "Regular Expression Denial of Service (ReDoS) in cross-spawn", "url": "https://github.com/advisories/GHSA-3xgq-45jj-v275", "severity": "high", "cwe": [ "CWE-1333" ], "cvss": { "score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H" }, "range": ">=7.0.0 <7.0.5" } ], "effects": [], "range": "7.0.0 - 7.0.4", "nodes": [ "node_modules/cross-spawn" ], "fixAvailable": true } }, "metadata": { "vulnerabilities": { "info": 0, "low": 0, "moderate": 0, "high": 1, "critical": 0, "total": 1 }, "dependencies": { "prod": 1, "dev": 438, "optional": 0, "peer": 1, "peerOptional": 0, "total": 438 } } } --- end --- Attempting to npm audit fix $ /usr/bin/npm audit fix --dry-run --only=dev --json --- stderr --- npm WARN invalid config only="dev" set in command line options npm WARN invalid config Must be one of: null, prod, production --- stdout --- { "added": 0, "removed": 0, "changed": 1, "audited": 439, "funding": 97, "audit": { "auditReportVersion": 2, "vulnerabilities": { "cross-spawn": { "name": "cross-spawn", "severity": "high", "isDirect": false, "via": [ { "source": 1104664, "name": "cross-spawn", "dependency": "cross-spawn", "title": "Regular Expression Denial of Service (ReDoS) in cross-spawn", "url": "https://github.com/advisories/GHSA-3xgq-45jj-v275", "severity": "high", "cwe": [ "CWE-1333" ], "cvss": { "score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H" }, "range": ">=7.0.0 <7.0.5" } ], "effects": [], "range": "7.0.0 - 7.0.4", "nodes": [ "" ], "fixAvailable": true } }, "metadata": { "vulnerabilities": { "info": 0, "low": 0, "moderate": 0, "high": 1, "critical": 0, "total": 1 }, "dependencies": { "prod": 1, "dev": 438, "optional": 0, "peer": 1, "peerOptional": 0, "total": 438 } } } } --- end --- {"added": 0, "removed": 0, "changed": 1, "audited": 439, "funding": 97, "audit": {"auditReportVersion": 2, "vulnerabilities": {"cross-spawn": {"name": "cross-spawn", "severity": "high", "isDirect": false, "via": [{"source": 1104664, "name": "cross-spawn", "dependency": "cross-spawn", "title": "Regular Expression Denial of Service (ReDoS) in cross-spawn", "url": "https://github.com/advisories/GHSA-3xgq-45jj-v275", "severity": "high", "cwe": ["CWE-1333"], "cvss": {"score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}, "range": ">=7.0.0 <7.0.5"}], "effects": [], "range": "7.0.0 - 7.0.4", "nodes": [""], "fixAvailable": true}}, "metadata": {"vulnerabilities": {"info": 0, "low": 0, "moderate": 0, "high": 1, "critical": 0, "total": 1}, "dependencies": {"prod": 1, "dev": 438, "optional": 0, "peer": 1, "peerOptional": 0, "total": 438}}}} $ /usr/bin/npm audit fix --only=dev --- stderr --- npm WARN invalid config only="dev" set in command line options npm WARN invalid config Must be one of: null, prod, production --- stdout --- up to date, audited 439 packages in 1s 97 packages are looking for funding run `npm fund` for details found 0 vulnerabilities --- end --- Verifying that tests still pass $ /usr/bin/npm ci --- stdout --- added 438 packages, and audited 439 packages in 5s 97 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/resources/controller/uw.controller.Deed.js 44:4 warning 'deedController' is never reassigned. Use 'const' instead prefer-const 52:3 warning 'valid' is never reassigned. Use 'const' instead prefer-const 57:4 warning Mixed spaces and tabs no-mixed-spaces-and-tabs 57:6 warning Expected no linebreak before this expression implicit-arrow-linebreak 58:3 warning Mixed spaces and tabs no-mixed-spaces-and-tabs /src/repo/resources/controller/uw.controller.Details.js 65:4 warning 'serialized' is never reassigned. Use 'const' instead prefer-const 96:4 warning 'invalidStates' is never reassigned. Use 'const' instead prefer-const 97:4 warning 'invalids' is never reassigned. Use 'const' instead prefer-const 98:4 warning 'valids' is never reassigned. Use 'const' instead prefer-const 153:3 warning Prefer .then to .done no-jquery/no-done-fail 238:4 warning '$message' is never reassigned. Use 'const' instead prefer-const 239:4 warning '$ul' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/controller/uw.controller.Step.js 223:7 warning 'okCount' is never reassigned. Use 'const' instead prefer-const 233:3 warning '$buttons' is never reassigned. Use 'const' instead prefer-const 324:4 warning 'copy' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/controller/uw.controller.Tutorial.js 63:3 warning Prefer .then to .done no-jquery/no-done-fail 63:3 warning Prefer .then to .fail no-jquery/no-done-fail /src/repo/resources/controller/uw.controller.Upload.js 69:4 warning 'max' is never reassigned. Use 'const' instead prefer-const 71:3 warning 'haveUploads' is never reassigned. Use 'const' instead prefer-const 72:3 warning 'fewerThanMax' is never reassigned. Use 'const' instead prefer-const 223:3 warning 'upload' is never reassigned. Use 'const' instead prefer-const 251:4 warning 'uploadObjs' is never reassigned. Use 'const' instead prefer-const 252:4 warning 'controller' is never reassigned. Use 'const' instead prefer-const 307:4 warning 'actualMaxSize' is never reassigned. Use 'const' instead prefer-const 311:4 warning 'filename' is never reassigned. Use 'const' instead prefer-const 312:4 warning 'basename' is never reassigned. Use 'const' instead prefer-const 335:3 warning 'extension' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/deed/uw.deed.External.js 66:10 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign /src/repo/resources/deed/uw.deed.OwnWork.js 29:7 warning 'deed' is never reassigned. Use 'const' instead prefer-const 88:3 warning 'deed' is never reassigned. Use 'const' instead prefer-const 89:3 warning 'languageCode' is never reassigned. Use 'const' instead prefer-const 91:3 warning 'defaultLicense' is never reassigned. Use 'const' instead prefer-const 92:3 warning 'defaultLicConfig' is never reassigned. Use 'const' instead prefer-const 99:3 warning '$defaultLicenseLink' is never reassigned. Use 'const' instead prefer-const 125:3 warning '$crossfader' is never reassigned. Use 'const' instead prefer-const 128:3 warning '$customDiv' is never reassigned. Use 'const' instead prefer-const 136:3 warning 'crossfaderWidget' is never reassigned. Use 'const' instead prefer-const 148:3 warning '$formFields' is never reassigned. Use 'const' instead prefer-const 152:3 warning '$toggler' is never reassigned. Use 'const' instead prefer-const 192:7 warning 'author' is never reassigned. Use 'const' instead prefer-const 200:3 warning 'userPageTitle' is never reassigned. Use 'const' instead prefer-const 215:10 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 255:16 warning 'ownWork' is never reassigned. Use 'const' instead prefer-const 277:3 warning Prefer .then to .done no-jquery/no-done-fail 297:3 warning Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/deed/uw.deed.ThirdParty.js 178:10 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign /src/repo/resources/details/uw.CategoriesDetailsWidget.js 87:3 warning Mixed spaces and tabs no-mixed-spaces-and-tabs 87:5 warning Expected no linebreak before this expression implicit-arrow-linebreak 88:2 warning Mixed spaces and tabs no-mixed-spaces-and-tabs 98:3 warning 'categories' is never reassigned. Use 'const' instead prefer-const 128:3 warning Mixed spaces and tabs no-mixed-spaces-and-tabs 128:5 warning Expected no linebreak before this expression implicit-arrow-linebreak 129:2 warning Mixed spaces and tabs no-mixed-spaces-and-tabs /src/repo/resources/details/uw.DropdownWidget.js 13:12 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign /src/repo/resources/details/uw.LocationDetailsWidget.js 12:17 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 71:3 warning Prefer .then to .done no-jquery/no-done-fail 84:3 warning Prefer .then to .done no-jquery/no-done-fail 115:7 warning 'errors' is never reassigned. Use 'const' instead prefer-const 116:4 warning 'serialized' is never reassigned. Use 'const' instead prefer-const 117:4 warning 'parsed' is never reassigned. Use 'const' instead prefer-const 165:4 warning 'serialized' is never reassigned. Use 'const' instead prefer-const 194:4 warning 'result' is never reassigned. Use 'const' instead prefer-const 210:4 warning 'result' is never reassigned. Use 'const' instead prefer-const 211:4 warning 'serialized' is never reassigned. Use 'const' instead prefer-const 258:7 warning 'sign' is never reassigned. Use 'const' instead prefer-const 268:3 warning 'parts' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/details/uw.MultipleLanguageInputWidget.js 16:17 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 50:26 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 60:7 warning 'allLanguages' is never reassigned. Use 'const' instead prefer-const 61:4 warning 'unusedLanguages' is never reassigned. Use 'const' instead prefer-const 73:16 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 78:12 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 82:3 warning 'item' is never reassigned. Use 'const' instead prefer-const 100:7 warning 'allLanguages' is never reassigned. Use 'const' instead prefer-const 101:4 warning 'unusedLanguages' is never reassigned. Use 'const' instead prefer-const 102:4 warning 'items' is never reassigned. Use 'const' instead prefer-const 114:16 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 192:4 warning 'errors' is never reassigned. Use 'const' instead prefer-const 215:7 warning 'values' is never reassigned. Use 'const' instead prefer-const 216:4 warning 'widgets' is never reassigned. Use 'const' instead prefer-const 272:13 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign /src/repo/resources/details/uw.SingleLanguageInputWidget.js 17:17 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 226:4 warning 'text' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/details/uw.TextWidget.js 13:17 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign /src/repo/resources/details/uw.TitleDetailsWidget.js 49:4 warning 'illegalFileChars' is never reassigned. Use 'const' instead prefer-const 82:3 warning 'value' is never reassigned. Use 'const' instead prefer-const 94:3 warning 'title' is never reassigned. Use 'const' instead prefer-const 156:7 warning Mixed spaces and tabs no-mixed-spaces-and-tabs 156:9 warning Expected no linebreak before this expression implicit-arrow-linebreak 157:6 warning Mixed spaces and tabs no-mixed-spaces-and-tabs 181:3 warning 'errors' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/handlers/mw.ApiUploadHandler.js 224:7 warning 'allDuplicates' is never reassigned. Use 'const' instead prefer-const 224:23 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 225:4 warning '$extra' is never reassigned. Use 'const' instead prefer-const 226:4 warning '$ul' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/jquery.arrowSteps/jquery.arrowSteps.js 39:4 warning '$el' is never reassigned. Use 'const' instead prefer-const 42:3 warning '$steps' is never reassigned. Use 'const' instead prefer-const 44:3 warning 'width' is never reassigned. Use 'const' instead prefer-const 71:4 warning '$steps' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.DestinationChecker.js 77:4 warning Mixed spaces and tabs no-mixed-spaces-and-tabs 77:6 warning Expected no linebreak before this expression implicit-arrow-linebreak 78:3 warning Mixed spaces and tabs no-mixed-spaces-and-tabs 94:8 warning 'checker' is never reassigned. Use 'const' instead prefer-const 95:5 warning 'NS_FILE' is never reassigned. Use 'const' instead prefer-const 98:4 warning 'titleObj' is never reassigned. Use 'const' instead prefer-const 99:4 warning 'ext' is never reassigned. Use 'const' instead prefer-const 101:4 warning 'prefix' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.Escaper.js 31:4 warning 'extractedTemplates' is never reassigned. Use 'const' instead prefer-const 32:4 warning 'extractedLinks' is never reassigned. Use 'const' instead prefer-const 34:43 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 52:8 warning 'extracts' is never reassigned. Use 'const' instead prefer-const 61:5 warning 'regex' is never reassigned. Use 'const' instead prefer-const 62:5 warning 'callback' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.GroupProgressBar.js 59:8 warning 'bar' is never reassigned. Use 'const' instead prefer-const 146:5 warning 'remainingTime' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.UploadWizard.js 4:1 warning Missing JSDoc @param "uw" type jsdoc/require-param-type 22:3 warning 'maxSimPref' is never reassigned. Use 'const' instead prefer-const 64:8 warning 'self' is never reassigned. Use 'const' instead prefer-const 65:5 warning 'steps' is never reassigned. Use 'const' instead prefer-const 74:4 warning 'uploadStep' is never reassigned. Use 'const' instead prefer-const 127:5 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 134:5 warning 'original' is never reassigned. Use 'const' instead prefer-const 138:5 warning 'override' is never reassigned. Use 'const' instead prefer-const 187:4 warning 'deeds' is never reassigned. Use 'const' instead prefer-const 188:4 warning 'doOwnWork' is never reassigned. Use 'const' instead prefer-const 189:4 warning 'doThirdParty' is never reassigned. Use 'const' instead prefer-const 197:3 warning 'api' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.UploadWizardDetails.js 45:8 warning '$moreDetailsWrapperDiv' is never reassigned. Use 'const' instead prefer-const 47:5 warning 'details' is never reassigned. Use 'const' instead prefer-const 48:5 warning 'config' is never reassigned. Use 'const' instead prefer-const 56:13 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 73:48 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 83:40 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 90:55 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 98:57 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 105:44 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 113:47 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 118:51 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 123:53 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 151:4 warning '$moreDetailsDiv' is never reassigned. Use 'const' instead prefer-const 215:5 warning Prefer .then to .done no-jquery/no-done-fail 255:4 warning Prefer .then to .done no-jquery/no-done-fail 383:4 warning Mixed spaces and tabs no-mixed-spaces-and-tabs 383:6 warning Expected no linebreak before this expression implicit-arrow-linebreak 384:3 warning Mixed spaces and tabs no-mixed-spaces-and-tabs 448:5 warning 'yyyyMmDdRegex' is never reassigned. Use 'const' instead prefer-const 449:5 warning 'timeRegex' is never reassigned. Use 'const' instead prefer-const 470:7 warning 'dateInfo' is never reassigned. Use 'const' instead prefer-const 508:4 warning 'saneTime' is never reassigned. Use 'const' instead prefer-const 601:5 warning 'm' is never reassigned. Use 'const' instead prefer-const 603:5 warning 'values' is never reassigned. Use 'const' instead prefer-const 653:4 warning 'languages' is never reassigned. Use 'const' instead prefer-const 662:3 warning JSDoc @return declaration present but return expression not available in function jsdoc/require-returns-check 672:21 warning 'serialized' is never reassigned. Use 'const' instead prefer-const 734:5 warning 'substitutions' is never reassigned. Use 'const' instead prefer-const 734:25 warning 'substList' is never reassigned. Use 'const' instead prefer-const 735:5 warning 'deed' is never reassigned. Use 'const' instead prefer-const 793:10 warning ES2015 RegExp 'u' flag is forbidden es-x/no-regexp-u-flag 813:8 warning 'details' is never reassigned. Use 'const' instead prefer-const 823:4 warning 'wikitext' is never reassigned. Use 'const' instead prefer-const 824:4 warning 'promise' is never reassigned. Use 'const' instead prefer-const 843:5 warning 'tags' is never reassigned. Use 'const' instead prefer-const 844:5 warning 'deed' is never reassigned. Use 'const' instead prefer-const 846:5 warning 'config' is never reassigned. Use 'const' instead prefer-const 869:4 warning 'params' is never reassigned. Use 'const' instead prefer-const 936:5 warning 'details' is never reassigned. Use 'const' instead prefer-const 939:5 warning 'deferred' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.UploadWizardLicenseInput.js 17:7 warning 'self' is never reassigned. Use 'const' instead prefer-const 18:4 warning 'groups' is never reassigned. Use 'const' instead prefer-const 77:2 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 183:9 warning 'templates' is never reassigned. Use 'const' instead prefer-const 209:5 warning 'addError' is never reassigned. Use 'const' instead prefer-const 216:5 warning 'selectedInputs' is never reassigned. Use 'const' instead prefer-const 226:7 warning 'data' is never reassigned. Use 'const' instead prefer-const 232:6 warning 'wikitext' is never reassigned. Use 'const' instead prefer-const 268:28 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign /src/repo/resources/mw.UploadWizardPage.js 31:4 warning 'config' is never reassigned. Use 'const' instead prefer-const 53:3 warning 'uploadWizard' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.UploadWizardUpload.js 8:1 warning Missing JSDoc @param "uw" type jsdoc/require-param-type 11:14 warning 'uw' is defined but never used no-unused-vars 204:4 warning 'deferred' is never reassigned. Use 'const' instead prefer-const 205:4 warning 'upload' is never reassigned. Use 'const' instead prefer-const 222:16 warning 'Uint8Array' is already defined as a built-in global variable no-redeclare 223:16 warning ES2015 'Uint8Array' is forbidden es-x/no-typed-arrays 314:4 warning 'upload' is never reassigned. Use 'const' instead prefer-const 382:3 warning Prefer .then to .done no-jquery/no-done-fail 382:3 warning Prefer .then to .fail no-jquery/no-done-fail 396:7 warning 'requestedTitle' is never reassigned. Use 'const' instead prefer-const 430:3 warning 'params' is never reassigned. Use 'const' instead prefer-const 448:3 warning Prefer .then to .done no-jquery/no-done-fail 448:3 warning Prefer .then to .fail no-jquery/no-done-fail 488:21 warning 'image' is never reassigned. Use 'const' instead prefer-const 585:5 warning 'constraint' is never reassigned. Use 'const' instead prefer-const 629:3 warning 'scaling' is never reassigned. Use 'const' instead prefer-const 631:3 warning 'width' is never reassigned. Use 'const' instead prefer-const 632:3 warning 'height' is never reassigned. Use 'const' instead prefer-const 640:3 warning 'dx' is never reassigned. Use 'const' instead prefer-const 641:3 warning 'dy' is never reassigned. Use 'const' instead prefer-const 666:3 warning '$canvas' is never reassigned. Use 'const' instead prefer-const 667:3 warning 'ctx' is never reassigned. Use 'const' instead prefer-const 715:7 warning 'constraints' is never reassigned. Use 'const' instead prefer-const 767:3 warning Prefer .then to .done no-jquery/no-done-fail 767:3 warning Prefer .then to .fail no-jquery/no-done-fail 775:6 warning Prefer .then to .done no-jquery/no-done-fail 778:7 warning Prefer .then to .done no-jquery/no-done-fail 802:4 warning 'deferred' is never reassigned. Use 'const' instead prefer-const 803:4 warning 'upload' is never reassigned. Use 'const' instead prefer-const 828:9 warning 'canvas' is never reassigned. Use 'const' instead prefer-const 831:8 warning 'context' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/mw.UploadWizardUploadInterface.js 206:3 warning Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/transports/mw.FormDataTransport.js 97:3 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 156:4 warning 'deferred' is never reassigned. Use 'const' instead prefer-const 157:4 warning 'fileSize' is never reassigned. Use 'const' instead prefer-const 158:4 warning 'chunkSize' is never reassigned. Use 'const' instead prefer-const 159:4 warning 'transport' is never reassigned. Use 'const' instead prefer-const 169:5 warning Prefer .then to .done no-jquery/no-done-fail 170:6 warning Prefer .then to .done no-jquery/no-done-fail 170:6 warning Prefer .then to .fail no-jquery/no-done-fail 194:7 warning 'params' is never reassigned. Use 'const' instead prefer-const 195:4 warning 'transport' is never reassigned. Use 'const' instead prefer-const 196:4 warning 'bytesAvailable' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/ui/steps/uw.ui.Deed.js 55:3 warning Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/ui/steps/uw.ui.Details.js 90:3 warning Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/ui/steps/uw.ui.Thanks.js 30:4 warning 'thanks' is never reassigned. Use 'const' instead prefer-const 48:3 warning '$header' is never reassigned. Use 'const' instead prefer-const 69:3 warning 'beginButtonTarget' is never reassigned. Use 'const' instead prefer-const 98:3 warning 'thumbWikiText' is never reassigned. Use 'const' instead prefer-const 104:3 warning '$thanksDiv' is never reassigned. Use 'const' instead prefer-const 106:3 warning '$thumbnailWrapDiv' is never reassigned. Use 'const' instead prefer-const 109:3 warning '$thumbnailDiv' is never reassigned. Use 'const' instead prefer-const 112:3 warning '$thumbnailCaption' is never reassigned. Use 'const' instead prefer-const 115:3 warning '$thumbnailLink' is never reassigned. Use 'const' instead prefer-const 128:3 warning Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/ui/steps/uw.ui.Tutorial.js 125:3 warning Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/ui/steps/uw.ui.Upload.js 210:6 warning Prefer .then to .done no-jquery/no-done-fail 222:3 warning Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/ui/uw.ui.DeedPreview.js 30:3 warning Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/ui/uw.ui.Step.js 101:3 warning Prefer .then to .done no-jquery/no-done-fail 119:3 warning Prefer .then to .done no-jquery/no-done-fail /src/repo/resources/uw.ConcurrentQueue.js 117:3 warning 'index' is never reassigned. Use 'const' instead prefer-const 139:3 warning 'item' is never reassigned. Use 'const' instead prefer-const 145:3 warning 'promise' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/uw.CopyMetadataWidget.js 14:4 warning 'checkboxes' is never reassigned. Use 'const' instead prefer-const 15:4 warning '$copyMetadataWrapperDiv' is never reassigned. Use 'const' instead prefer-const 16:4 warning '$copyMetadataDiv' is never reassigned. Use 'const' instead prefer-const 157:4 warning 'uploads' is never reassigned. Use 'const' instead prefer-const 158:4 warning 'sourceUpload' is never reassigned. Use 'const' instead prefer-const 159:4 warning 'serialized' is never reassigned. Use 'const' instead prefer-const 161:4 warning 'sourceValue' is never reassigned. Use 'const' instead prefer-const 214:4 warning 'uploads' is never reassigned. Use 'const' instead prefer-const /src/repo/resources/uw.FieldLayout.js 20:12 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign /src/repo/resources/uw.LicenseGroup.js 37:17 warning ES2015 'Object.assign' method is forbidden es-x/no-object-assign 132:4 warning 'option' is never reassigned. Use 'const' instead prefer-const 167:4 warning 'option' is never reassigned. Use 'const' instead prefer-const 191:4 warning 'self' is never reassigned. Use 'const' instead prefer-const 192:4 warning 'values' is never reassigned. Use 'const' instead prefer-const 194:3 warning 'wikiTexts' is never reassigned. Use 'const' instead prefer-const 196:5 warning 'value' is never reassigned. Use 'const' instead prefer-const 222:7 warning 'self' is never reassigned. Use 'const' instead prefer-const 223:4 warning 'result' is never reassigned. Use 'const' instead prefer-const 248:7 warning 'self' is never reassigned. Use 'const' instead prefer-const 249:4 warning 'selectArray' is never reassigned. Use 'const' instead prefer-const 303:7 warning 'licenseInfo' is never reassigned. Use 'const' instead prefer-const 306:3 warning 'licenseText' is never reassigned. Use 'const' instead prefer-const 319:7 warning 'licenseInfo' is never reassigned. Use 'const' instead prefer-const 320:4 warning 'messageKey' is never reassigned. Use 'const' instead prefer-const 323:4 warning 'languageCode' is never reassigned. Use 'const' instead prefer-const 328:4 warning '$icons' is never reassigned. Use 'const' instead prefer-const 334:3 warning '$licenseLink' is never reassigned. Use 'const' instead prefer-const 343:3 warning '$label' is never reassigned. Use 'const' instead prefer-const 361:7 warning 'self' is never reassigned. Use 'const' instead prefer-const 372:3 warning 'button' is never reassigned. Use 'const' instead prefer-const 397:3 warning 'input' is never reassigned. Use 'const' instead prefer-const 413:3 warning Prefer .then to .done no-jquery/no-done-fail 413:3 warning Prefer .then to .fail no-jquery/no-done-fail /src/repo/resources/uw.ValidationMessageElement.js 39:2 warning JSDoc @return declaration present but return expression not available in function jsdoc/require-returns-check 91:3 warning '$listItem' is never reassigned. Use 'const' instead prefer-const /src/repo/tests/qunit/controller/uw.controller.Details.test.js 57:7 warning 'step' is never reassigned. Use 'const' instead prefer-const 61:4 warning 'stepUiStub' is never reassigned. Use 'const' instead prefer-const 110:4 warning 'done' is never reassigned. Use 'const' instead prefer-const 111:4 warning 'donestub' is never reassigned. Use 'const' instead prefer-const 112:4 warning 'ds' is never reassigned. Use 'const' instead prefer-const 113:4 warning 'ps' is never reassigned. Use 'const' instead prefer-const 117:3 warning 'tostub' is never reassigned. Use 'const' instead prefer-const 124:3 warning 'step' is never reassigned. Use 'const' instead prefer-const 135:3 warning Prefer .then to .done no-jquery/no-done-fail /src/repo/tests/qunit/controller/uw.controller.Tutorial.test.js 33:4 warning 'acwStub' is never reassigned. Use 'const' instead prefer-const 54:3 warning 'mnStub' is never reassigned. Use 'const' instead prefer-const /src/repo/tests/qunit/mw.UploadWizardLicenseInput.test.js 17:6 warning 'config' is never reassigned. Use 'const' instead prefer-const 18:3 warning '$fixture' is never reassigned. Use 'const' instead prefer-const 21:2 warning 'uwLicenseInput' is never reassigned. Use 'const' instead prefer-const 27:6 warning 'config' is never reassigned. Use 'const' instead prefer-const 28:3 warning '$fixture' is never reassigned. Use 'const' instead prefer-const 33:2 warning 'uwLicenseInput' is never reassigned. Use 'const' instead prefer-const 37:2 warning '$input' is never reassigned. Use 'const' instead prefer-const 41:2 warning '$label' is never reassigned. Use 'const' instead prefer-const 46:6 warning 'config' is never reassigned. Use 'const' instead prefer-const 56:3 warning '$fixture' is never reassigned. Use 'const' instead prefer-const 59:2 warning 'uwLicenseInput' is never reassigned. Use 'const' instead prefer-const /src/repo/tests/qunit/mw.UploadWizardUpload.test.js 23:4 warning 'oldconf' is never reassigned. Use 'const' instead prefer-const 27:3 warning 'upload' is never reassigned. Use 'const' instead prefer-const /src/repo/tests/qunit/mw.fileApi.test.js 46:15 warning 'testFile' is never reassigned. Use 'const' instead prefer-const 47:4 warning 'fakeVideo' is never reassigned. Use 'const' instead prefer-const /src/repo/tests/qunit/transports/mw.FormDataTransport.test.js 27:3 warning 'config' is never reassigned. Use 'const' instead prefer-const 86:4 warning 'transport' is never reassigned. Use 'const' instead prefer-const 87:4 warning 'fakeFile' is never reassigned. Use 'const' instead prefer-const 97:3 warning 'request' is never reassigned. Use 'const' instead prefer-const 107:4 warning 'transport' is never reassigned. Use 'const' instead prefer-const 108:4 warning 'fakeFile' is never reassigned. Use 'const' instead prefer-const 125:3 warning 'request' is never reassigned. Use 'const' instead prefer-const 146:3 warning Prefer .then to .fail no-jquery/no-done-fail 179:10 warning Prefer .then to .done no-jquery/no-done-fail 198:10 warning Prefer .then to .done no-jquery/no-done-fail 218:3 warning Prefer .then to .fail no-jquery/no-done-fail /src/repo/tests/qunit/uw.ConcurrentQueue.test.js 38:3 warning 'calls' is never reassigned. Use 'const' instead prefer-const 65:3 warning 'done' is never reassigned. Use 'const' instead prefer-const 66:3 warning 'action' is never reassigned. Use 'const' instead prefer-const 67:3 warning 'queue' is never reassigned. Use 'const' instead prefer-const 98:3 warning 'done' is never reassigned. Use 'const' instead prefer-const 99:3 warning 'changeHandler' is never reassigned. Use 'const' instead prefer-const 100:3 warning 'progressHandler' is never reassigned. Use 'const' instead prefer-const 101:3 warning 'completeHandler' is never reassigned. Use 'const' instead prefer-const 102:3 warning 'queue' is never reassigned. Use 'const' instead prefer-const 139:3 warning 'done' is never reassigned. Use 'const' instead prefer-const 140:3 warning 'queue' is never reassigned. Use 'const' instead prefer-const 167:3 warning 'done' is never reassigned. Use 'const' instead prefer-const 168:3 warning 'queue' is never reassigned. Use 'const' instead prefer-const 184:3 warning 'done' is never reassigned. Use 'const' instead prefer-const 185:3 warning 'changeHandler' is never reassigned. Use 'const' instead prefer-const 186:3 warning 'progressHandler' is never reassigned. Use 'const' instead prefer-const 187:3 warning 'completeHandler' is never reassigned. Use 'const' instead prefer-const 188:3 warning 'queue' is never reassigned. Use 'const' instead prefer-const 240:3 warning 'done' is never reassigned. Use 'const' instead prefer-const 241:3 warning 'changeHandler' is never reassigned. Use 'const' instead prefer-const 242:3 warning 'progressHandler' is never reassigned. Use 'const' instead prefer-const 243:3 warning 'completeHandler' is never reassigned. Use 'const' instead prefer-const 244:3 warning 'queue' is never reassigned. Use 'const' instead prefer-const 297:3 warning 'done' is never reassigned. Use 'const' instead prefer-const 298:3 warning 'action' is never reassigned. Use 'const' instead prefer-const 299:3 warning 'changeHandler' is never reassigned. Use 'const' instead prefer-const 300:3 warning 'progressHandler' is never reassigned. Use 'const' instead prefer-const 301:3 warning 'completeHandler' is never reassigned. Use 'const' instead prefer-const 302:3 warning 'queue' is never reassigned. Use 'const' instead prefer-const 353:3 warning 'done' is never reassigned. Use 'const' instead prefer-const 355:3 warning 'action' is never reassigned. Use 'const' instead prefer-const 356:3 warning 'changeHandler' is never reassigned. Use 'const' instead prefer-const 357:3 warning 'progressHandler' is never reassigned. Use 'const' instead prefer-const 358:3 warning 'completeHandler' is never reassigned. Use 'const' instead prefer-const 359:3 warning 'queue' is never reassigned. Use 'const' instead prefer-const 402:3 warning 'onProgress' is never reassigned. Use 'const' instead prefer-const /src/repo/tests/qunit/uw.TitleDetailsWidget.test.js 5:2 warning 'fileNs' is never reassigned. Use 'const' instead prefer-const 6:2 warning 'makeTitleInFileNSCases' is never reassigned. Use 'const' instead prefer-const ✖ 352 problems (0 errors, 352 warnings) Running "stylelint:all" (stylelint) task >> Linted 14 files without errors Running "banana:MediaUploader" (banana) task >> 3 message directories checked. Done. --- end --- {"1104664": {"source": 1104664, "name": "cross-spawn", "dependency": "cross-spawn", "title": "Regular Expression Denial of Service (ReDoS) in cross-spawn", "url": "https://github.com/advisories/GHSA-3xgq-45jj-v275", "severity": "high", "cwe": ["CWE-1333"], "cvss": {"score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}, "range": ">=7.0.0 <7.0.5"}} Upgrading n:cross-spawn from 7.0.3 -> 7.0.6 $ package-lock-lint package-lock.json --- stdout --- Checking package-lock.json --- end --- build: Updating dependencies composer: * mediawiki/mediawiki-codesniffer: 45.0.0 → 47.0.0 npm: * eslint-config-wikimedia: 0.28.2 → 0.30.0 The following rules are failing and were disabled: * prefer-const * implicit-arrow-linebreak * no-mixed-spaces-and-tabs * no-jquery/no-done-fail * no-redeclare * tests/qunit: * no-jquery/no-done-fail * prefer-const * stylelint-config-wikimedia: 0.17.2 → 0.18.0 * cross-spawn: 7.0.3 → 7.0.6 * https://github.com/advisories/GHSA-3xgq-45jj-v275 Additional changes: * eslint: Replaced `wikimedia/client-es5` with `wikimedia/client`. * Enable stylelint caching. $ git add . --- stdout --- --- end --- $ git commit -F /tmp/tmpfbn804um --- stdout --- [master 38631ab] build: Updating dependencies 71 files changed, 1164 insertions(+), 1454 deletions(-) --- end --- $ git format-patch HEAD~1 --stdout --- stdout --- From 38631ab1fe7ee83b8e993c041e314a7e0e682c6b Mon Sep 17 00:00:00 2001 From: libraryupgrader <tools.libraryupgrader@tools.wmflabs.org> Date: Fri, 6 Jun 2025 02:50:32 +0000 Subject: [PATCH] build: Updating dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit composer: * mediawiki/mediawiki-codesniffer: 45.0.0 → 47.0.0 npm: * eslint-config-wikimedia: 0.28.2 → 0.30.0 The following rules are failing and were disabled: * prefer-const * implicit-arrow-linebreak * no-mixed-spaces-and-tabs * no-jquery/no-done-fail * no-redeclare * tests/qunit: * no-jquery/no-done-fail * prefer-const * stylelint-config-wikimedia: 0.17.2 → 0.18.0 * cross-spawn: 7.0.3 → 7.0.6 * https://github.com/advisories/GHSA-3xgq-45jj-v275 Additional changes: * eslint: Replaced `wikimedia/client-es5` with `wikimedia/client`. * Enable stylelint caching. Change-Id: Ia730ad52e2026c7af9d42668f7c1921f9b703c75 --- .eslintrc.json | 9 +- .gitignore | 1 + Gruntfile.js | 5 +- composer.json | 2 +- package-lock.json | 1283 +++++++---------- package.json | 4 +- resources/controller/uw.controller.Deed.js | 18 +- resources/controller/uw.controller.Details.js | 54 +- resources/controller/uw.controller.Step.js | 42 +- resources/controller/uw.controller.Thanks.js | 4 +- .../controller/uw.controller.Tutorial.js | 12 +- resources/controller/uw.controller.Upload.js | 28 +- resources/deed/uw.deed.OwnWork.js | 32 +- resources/deed/uw.deed.ThirdParty.js | 8 +- .../details/uw.CategoriesDetailsWidget.js | 40 +- resources/details/uw.DateDetailsWidget.js | 14 +- .../details/uw.DeedChooserDetailsWidget.js | 4 +- resources/details/uw.DropdownWidget.js | 8 +- .../details/uw.LanguageDropdownWidget.js | 16 +- resources/details/uw.LocationDetailsWidget.js | 26 +- .../details/uw.MultipleLanguageInputWidget.js | 42 +- .../details/uw.SingleLanguageInputWidget.js | 10 +- resources/details/uw.TextWidget.js | 4 +- resources/details/uw.TitleDetailsWidget.js | 28 +- resources/details/uw.UlsWidget.js | 8 +- resources/ext.mediaUploader.campaignEditor.js | 2 +- .../handlers/mw.ApiUploadFormDataHandler.js | 12 +- resources/handlers/mw.ApiUploadHandler.js | 56 +- .../jquery.arrowSteps/jquery.arrowSteps.js | 6 +- resources/jquery/jquery.morphCrossfade.js | 12 +- resources/mw.DestinationChecker.js | 36 +- resources/mw.Escaper.js | 20 +- resources/mw.GroupProgressBar.js | 24 +- resources/mw.QuickTitleChecker.js | 8 +- resources/mw.UploadWizard.js | 22 +- resources/mw.UploadWizardDeedChooser.js | 22 +- resources/mw.UploadWizardDetails.js | 88 +- resources/mw.UploadWizardLicenseInput.js | 56 +- resources/mw.UploadWizardPage.js | 6 +- resources/mw.UploadWizardUpload.js | 74 +- resources/mw.UploadWizardUploadInterface.js | 16 +- resources/mw.fileApi.js | 6 +- resources/transports/mw.FormDataTransport.js | 36 +- resources/ui/steps/uw.ui.Deed.js | 4 +- resources/ui/steps/uw.ui.Details.js | 16 +- resources/ui/steps/uw.ui.Thanks.js | 12 +- resources/ui/steps/uw.ui.Tutorial.js | 10 +- resources/ui/steps/uw.ui.Upload.js | 36 +- resources/ui/uw.ui.DeedPreview.js | 4 +- resources/ui/uw.ui.Step.js | 14 +- resources/ui/uw.ui.Wizard.js | 14 +- resources/uw.ConcurrentQueue.js | 8 +- resources/uw.CopyMetadataWidget.js | 14 +- resources/uw.FieldLayout.js | 2 +- resources/uw.LicenseGroup.js | 58 +- resources/uw.LicensePreviewDialog.js | 8 +- resources/uw.ValidationMessageElement.js | 8 +- resources/uw.units.js | 4 +- tests/qunit/.eslintrc.json | 4 + .../controller/uw.controller.Deed.test.js | 6 +- .../controller/uw.controller.Details.test.js | 20 +- .../controller/uw.controller.Step.test.js | 4 +- .../controller/uw.controller.Thanks.test.js | 10 +- .../controller/uw.controller.Tutorial.test.js | 6 +- .../controller/uw.controller.Upload.test.js | 12 +- .../qunit/mw.UploadWizardLicenseInput.test.js | 12 +- tests/qunit/mw.UploadWizardUpload.test.js | 10 +- tests/qunit/mw.fileApi.test.js | 4 +- .../transports/mw.FormDataTransport.test.js | 34 +- tests/qunit/uw.ConcurrentQueue.test.js | 70 +- tests/qunit/uw.TitleDetailsWidget.test.js | 10 +- 71 files changed, 1164 insertions(+), 1454 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index feb9364..66461eb 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,7 +1,7 @@ { "root": true, "extends": [ - "wikimedia/client-es5", + "wikimedia/client", "wikimedia/jquery", "wikimedia/mediawiki" ], @@ -23,6 +23,11 @@ "es-x/no-regexp-u-flag": "warn", "es-x/no-typed-arrays": "warn", "no-unused-vars": "warn", - "es-x/no-object-assign": "warn" + "es-x/no-object-assign": "warn", + "no-mixed-spaces-and-tabs": "warn", + "prefer-const": "warn", + "implicit-arrow-linebreak": "warn", + "no-jquery/no-done-fail": "warn", + "no-redeclare": "warn" } } diff --git a/.gitignore b/.gitignore index de0ffeb..39e6140 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ vendor composer.lock .DS_Store .eslintcache +/.stylelintcache diff --git a/Gruntfile.js b/Gruntfile.js index d870d7c..3b065aa 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -5,7 +5,7 @@ /* eslint-env node */ module.exports = function ( grunt ) { - var conf = grunt.file.readJSON( 'extension.json' ); + const conf = grunt.file.readJSON( 'extension.json' ); grunt.loadNpmTasks( 'grunt-banana-checker' ); grunt.loadNpmTasks( 'grunt-contrib-watch' ); @@ -21,6 +21,9 @@ module.exports = function ( grunt ) { all: '.' }, stylelint: { + options: { + cache: true + }, all: 'resources/{**/,}*.{css,less}' }, banana: conf.MessagesDirs, diff --git a/composer.json b/composer.json index ca9ae93..3e0546b 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,7 @@ "ext-json": "*" }, "require-dev": { - "mediawiki/mediawiki-codesniffer": "45.0.0", + "mediawiki/mediawiki-codesniffer": "47.0.0", "mediawiki/mediawiki-phan-config": "0.15.1", "mediawiki/minus-x": "1.1.3", "php-parallel-lint/php-console-highlighter": "1.0.0", diff --git a/package-lock.json b/package-lock.json index 89c6fb1..3b9381f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,13 +6,13 @@ "": { "name": "MediaUploader", "devDependencies": { - "eslint-config-wikimedia": "0.28.2", + "eslint-config-wikimedia": "0.30.0", "grunt": "1.6.1", "grunt-banana-checker": "0.13.0", "grunt-contrib-watch": "1.1.0", "grunt-eslint": "24.3.0", "grunt-stylelint": "0.20.1", - "stylelint-config-wikimedia": "0.17.2" + "stylelint-config-wikimedia": "0.18.0" } }, "node_modules/@babel/code-frame": { @@ -124,9 +124,9 @@ } }, "node_modules/@csstools/css-parser-algorithms": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.7.1.tgz", - "integrity": "sha512-2SJS42gxmACHgikc1WGesXLIT8d/q2l0UFM7TaEeIzdFCE/FPMtTiizcPGGJtlPo2xuQzY09OhrLTzRxqJqwGw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", "dev": true, "funding": [ { @@ -139,16 +139,16 @@ } ], "engines": { - "node": "^14 || ^16 || >=18" + "node": ">=18" }, "peerDependencies": { - "@csstools/css-tokenizer": "^2.4.1" + "@csstools/css-tokenizer": "^3.0.4" } }, "node_modules/@csstools/css-tokenizer": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.4.1.tgz", - "integrity": "sha512-eQ9DIktFJBhGjioABJRtUucoWR2mwllurfnM8LuNGAqX3ViZXaUchqk+1s7jjtkFiT9ySdACsFEA3etErkALUg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", "dev": true, "funding": [ { @@ -161,36 +161,13 @@ } ], "engines": { - "node": "^14 || ^16 || >=18" + "node": ">=18" } }, "node_modules/@csstools/media-query-list-parser": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.13.tgz", - "integrity": "sha512-XaHr+16KRU9Gf8XLi3q8kDlI18d5vzKSKCY510Vrtc9iNR0NJzbY9hhTmwhzYZj/ZwGL4VmB3TA9hJW0Um2qFA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "engines": { - "node": "^14 || ^16 || >=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^2.7.1", - "@csstools/css-tokenizer": "^2.4.1" - } - }, - "node_modules/@csstools/selector-specificity": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.1.1.tgz", - "integrity": "sha512-a7cxGcJ2wIlMFLlh8z2ONm+715QkPHiyJcxwQlKOz/03GPw1COpfhcmC9wm4xlZfp//jWHNNMwzjtqHXVWU9KA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-3.0.1.tgz", + "integrity": "sha512-HNo8gGD02kHmcbX6PvCoUuOQvn4szyB9ca63vZHKX5A81QytgDG4oxG4IaEfHTlEZSZ6MjPEMWIVU+zF2PZcgw==", "dev": true, "funding": [ { @@ -203,10 +180,11 @@ } ], "engines": { - "node": "^14 || ^16 || >=18" + "node": ">=18" }, "peerDependencies": { - "postcss-selector-parser": "^6.0.13" + "@csstools/css-parser-algorithms": "^3.0.1", + "@csstools/css-tokenizer": "^3.0.1" } }, "node_modules/@dual-bundle/import-meta-resolve": { @@ -397,40 +375,40 @@ } }, "node_modules/@stylistic/stylelint-config": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@stylistic/stylelint-config/-/stylelint-config-1.0.1.tgz", - "integrity": "sha512-JgFP88HZEyo34k9RpWVdcQJtLPrMxYE58IO3qypXhmvE/NmZohj+xjDtQ8UfaarnYsLecnldw57/GHum07Ctdw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@stylistic/stylelint-config/-/stylelint-config-2.0.0.tgz", + "integrity": "sha512-8J4YAxggy2Nzkb8KJIOLbtMXTPZ5gpKVmyhiiuKEUgCl9XFND5lM0e/ZZBMGEYZ68h5qcsS/jgg1wh235erRAw==", "dev": true, "dependencies": { - "@stylistic/stylelint-plugin": "^2.0.0" + "@stylistic/stylelint-plugin": "^3.0.0" }, "engines": { "node": "^18.12 || >=20.9" }, "peerDependencies": { - "stylelint": "^16.0.2" + "stylelint": "^16.8.0" } }, "node_modules/@stylistic/stylelint-plugin": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-2.0.0.tgz", - "integrity": "sha512-dHKuT6PGd1WGZLOTuozAM7GdQzdmlmnFXYzvV1jYJXXpcCpV/OJ3+n8TXpMkoOeKHpJydY43EOoZTO1W/FOA4Q==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-3.1.1.tgz", + "integrity": "sha512-XagAHHIa528EvyGybv8EEYGK5zrVW74cHpsjhtovVATbhDRuJYfE+X4HCaAieW9lCkwbX6L+X0I4CiUG3w/hFw==", "dev": true, "dependencies": { - "@csstools/css-parser-algorithms": "^2.3.2", - "@csstools/css-tokenizer": "^2.2.1", - "@csstools/media-query-list-parser": "^2.1.5", + "@csstools/css-parser-algorithms": "^3.0.1", + "@csstools/css-tokenizer": "^3.0.1", + "@csstools/media-query-list-parser": "^3.0.1", "is-plain-object": "^5.0.0", - "postcss-selector-parser": "^6.0.13", + "postcss-selector-parser": "^6.1.2", "postcss-value-parser": "^4.2.0", "style-search": "^0.1.0", - "stylelint": "^16.0.2" + "stylelint": "^16.8.2" }, "engines": { "node": "^18.12 || >=20.9" }, "peerDependencies": { - "stylelint": "^16.0.2" + "stylelint": "^16.8.0" } }, "node_modules/@stylistic/stylelint-plugin/node_modules/is-plain-object": { @@ -442,6 +420,19 @@ "node": ">=0.10.0" } }, + "node_modules/@stylistic/stylelint-plugin/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@types/eslint": { "version": "8.56.10", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", @@ -804,9 +795,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.0.tgz", + "integrity": "sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==", "dev": true, "funding": [ { @@ -823,10 +814,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001718", + "electron-to-chromium": "^1.5.160", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" @@ -882,9 +873,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001612", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz", - "integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==", + "version": "1.0.30001721", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001721.tgz", + "integrity": "sha512-cOuvmUVtKrtEaoKiO0rSc29jcjwMwX5tOHDy4MgVFEWiUXj4uBMJkwI8MDySkgXidpMiHUcviogAvFi4pA2hDQ==", "dev": true, "funding": [ { @@ -1085,9 +1076,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "dependencies": { "path-key": "^3.1.0", @@ -1114,9 +1105,9 @@ } }, "node_modules/css-functions-list": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.2.tgz", - "integrity": "sha512-c+N0v6wbKVxTu5gOBBFkr9BEdBWaqqjQeiJ8QvSRIJOf+UxlJh930m8e6/WNeODIK0mYLFkoONrnj16i2EcvfQ==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz", + "integrity": "sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==", "dev": true, "engines": { "node": ">=12 || >=16" @@ -1133,12 +1124,12 @@ } }, "node_modules/css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", "dev": true, "dependencies": { - "mdn-data": "2.0.30", + "mdn-data": "2.12.2", "source-map-js": "^1.0.1" }, "engines": { @@ -1167,12 +1158,12 @@ } }, "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "dev": true, "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -1223,20 +1214,19 @@ } }, "node_modules/doiuse": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/doiuse/-/doiuse-6.0.2.tgz", - "integrity": "sha512-eBTs23NOX+EAYPr4RbCR6J4DRW/TML3uMo37y0X1whlkersDYFCk9HmCl09KX98cis22VKsV1QaxfVNauJ3NBw==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/doiuse/-/doiuse-6.0.5.tgz", + "integrity": "sha512-ljuf9ndGqKST0GlPAYyCg04hbQAeR1xIIWVDjQaDDkoTY/Y1Vb+8FNoy6NuVuJIEEKe/nKUH8NRWjG7JJxZ9Eg==", "dev": true, "dependencies": { - "browserslist": "^4.21.5", - "caniuse-lite": "^1.0.30001487", + "browserslist": "^4.24.0", + "caniuse-lite": "^1.0.30001669", "css-tokenize": "^1.0.1", - "duplexify": "^4.1.2", - "ldjson-stream": "^1.2.1", + "duplexify": "^4.1.3", "multimatch": "^5.0.0", - "postcss": "^8.4.21", + "postcss": "^8.4.47", "source-map": "^0.7.4", - "yargs": "^17.7.1" + "yargs": "^17.7.2" }, "bin": { "doiuse": "bin/cli.js" @@ -1287,9 +1277,9 @@ } }, "node_modules/domutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", "dev": true, "dependencies": { "dom-serializer": "^2.0.0", @@ -1336,9 +1326,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.750", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.750.tgz", - "integrity": "sha512-9ItEpeu15hW5m8jKdriL+BQrgwDTXEL9pn4SkillWFu73ZNNNQ2BKKLS+ZHv2vC9UkNhosAeyfxOf/5OSeTCPA==", + "version": "1.5.165", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.165.tgz", + "integrity": "sha512-naiMx1Z6Nb2TxPU6fiFrUrDTjyPMLdTtaOd2oLmG8zVSg2hCWGkhPyxwk+qRmZ1ytwVqUv0u7ZcDA5+ALhaUtw==", "dev": true }, "node_modules/emoji-regex": { @@ -1410,9 +1400,9 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "engines": { "node": ">=6" @@ -1501,9 +1491,9 @@ } }, "node_modules/eslint-config-wikimedia": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.28.2.tgz", - "integrity": "sha512-5+rdnT7wH1gpKAO6tHYThg78eMhZMruJzvqku3Y5iaEY/A7kSKLFpA/vOj/snys9fKjDHC9BXmArQh+agkOoJQ==", + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.30.0.tgz", + "integrity": "sha512-i8ESzSoo0x3Jur/0JhAgCVPxbV51zfdI3MN3MVQPnjiFdmo21CNKmiBBmw8JnJ3fx/d5zHDrBa+yDjxSLpnDlA==", "dev": true, "dependencies": { "browserslist-config-wikimedia": "^0.7.0", @@ -1516,13 +1506,16 @@ "eslint-plugin-mediawiki": "^0.7.0", "eslint-plugin-mocha": "^10.4.3", "eslint-plugin-n": "^17.7.0", - "eslint-plugin-no-jquery": "^3.0.1", + "eslint-plugin-no-jquery": "^3.1.1", "eslint-plugin-qunit": "^8.1.1", "eslint-plugin-security": "^1.7.1", "eslint-plugin-unicorn": "^53.0.0", "eslint-plugin-vue": "^9.26.0", "eslint-plugin-wdio": "^8.24.12", "eslint-plugin-yml": "^1.14.0" + }, + "engines": { + "node": ">=18 <23" } }, "node_modules/eslint-plugin-compat": { @@ -1720,9 +1713,9 @@ } }, "node_modules/eslint-plugin-no-jquery": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-3.0.2.tgz", - "integrity": "sha512-n/+6p6PFhWDNPVLJj1463hw4OTIRBbROGcbhmtOHTgw7yihSKzkwZiQ00EJTneyeR3jRiw5lpWSMCCBhtb8t2g==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-3.1.1.tgz", + "integrity": "sha512-LTLO3jH/Tjr1pmxCEqtV6qmt+OChv8La4fwgG470JRpgxyFF4NOzoC9CRy92GIWD3Yjl0qLEgPmD2FLQWcNEjg==", "dev": true, "peerDependencies": { "eslint": ">=8.0.0" @@ -2167,10 +2160,20 @@ "dev": true }, "node_modules/fast-uri": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", - "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", - "dev": true + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ] }, "node_modules/fastest-levenshtein": { "version": "1.0.16", @@ -3156,21 +3159,11 @@ } }, "node_modules/known-css-properties": { - "version": "0.34.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.34.0.tgz", - "integrity": "sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==", + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.35.0.tgz", + "integrity": "sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==", "dev": true }, - "node_modules/ldjson-stream": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ldjson-stream/-/ldjson-stream-1.2.1.tgz", - "integrity": "sha512-xw/nNEXafuPSLu8NjjG3+atVVw+8U1APZAQylmwQn19Hgw6rC7QjHvP6MupnHWCrzSm9m0xs5QWkCLuRvBPjgQ==", - "dev": true, - "dependencies": { - "split2": "^0.2.1", - "through2": "^0.6.1" - } - }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -3301,9 +3294,9 @@ } }, "node_modules/mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", "dev": true }, "node_modules/meow": { @@ -3362,9 +3355,9 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "node_modules/multimatch": { @@ -3387,9 +3380,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, "funding": [ { @@ -3411,9 +3404,9 @@ "dev": true }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "dev": true }, "node_modules/nopt": { @@ -3738,9 +3731,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true }, "node_modules/picomatch": { @@ -3765,9 +3758,9 @@ } }, "node_modules/postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.4.tgz", + "integrity": "sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==", "dev": true, "funding": [ { @@ -3784,22 +3777,22 @@ } ], "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" } }, "node_modules/postcss-html": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.6.0.tgz", - "integrity": "sha512-OWgQ9/Pe23MnNJC0PL4uZp8k0EDaUvqpJFSiwFxOLClAhmD7UEisyhO3x5hVsD4xFrjReVTXydlrMes45dJ71w==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.7.0.tgz", + "integrity": "sha512-MfcMpSUIaR/nNgeVS8AyvyDugXlADjN9AcV7e5rDfrF1wduIAGSkL4q2+wgrZgA3sHVAHLDO9FuauHhZYW2nBw==", "dev": true, "dependencies": { "htmlparser2": "^8.0.0", - "js-tokens": "^8.0.0", + "js-tokens": "^9.0.0", "postcss": "^8.4.0", "postcss-safe-parser": "^6.0.0" }, @@ -3808,27 +3801,11 @@ } }, "node_modules/postcss-html/node_modules/js-tokens": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.3.tgz", - "integrity": "sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", "dev": true }, - "node_modules/postcss-html/node_modules/postcss-safe-parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", - "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", - "dev": true, - "engines": { - "node": ">=12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.3.3" - } - }, "node_modules/postcss-less": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-6.0.0.tgz", @@ -3842,35 +3819,25 @@ } }, "node_modules/postcss-resolve-nested-selector": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", - "integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz", + "integrity": "sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==", "dev": true }, "node_modules/postcss-safe-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.0.tgz", - "integrity": "sha512-ovehqRNVCpuFzbXoTb4qLtyzK3xn3t/CUBxOs8LsnQjQrShaB4lKiHoVqY8ANaC0hBMHq5QVWk77rwGklFUDrg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", + "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss-safe-parser" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "engines": { - "node": ">=18.0" + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" }, "peerDependencies": { - "postcss": "^8.4.31" + "postcss": "^8.3.3" } }, "node_modules/postcss-selector-parser": { @@ -4409,9 +4376,9 @@ } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -4459,15 +4426,6 @@ "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", "dev": true }, - "node_modules/split2": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/split2/-/split2-0.2.1.tgz", - "integrity": "sha512-D/oTExYAkC9nWleOCTOyNmAuzfAT/6rHGBA9LIK7FVnGo13CSvrKCUzKenwH6U1s2znY9MqH6v0UQTEDa3vJmg==", - "dev": true, - "dependencies": { - "through2": "~0.6.1" - } - }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -4549,9 +4507,9 @@ "dev": true }, "node_modules/stylelint": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.7.0.tgz", - "integrity": "sha512-Q1ATiXlz+wYr37a7TGsfvqYn2nSR3T/isw3IWlZQzFzCNoACHuGBb6xBplZXz56/uDRJHIygxjh7jbV/8isewA==", + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.12.0.tgz", + "integrity": "sha512-F8zZ3L/rBpuoBZRvI4JVT20ZanPLXfQLzMOZg1tzPflRVh9mKpOZ8qcSIhh1my3FjAjZWG4T2POwGnmn6a6hbg==", "dev": true, "funding": [ { @@ -4564,44 +4522,43 @@ } ], "dependencies": { - "@csstools/css-parser-algorithms": "^2.7.1", - "@csstools/css-tokenizer": "^2.4.1", - "@csstools/media-query-list-parser": "^2.1.13", - "@csstools/selector-specificity": "^3.1.1", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/media-query-list-parser": "^4.0.2", + "@csstools/selector-specificity": "^5.0.0", "@dual-bundle/import-meta-resolve": "^4.1.0", "balanced-match": "^2.0.0", "colord": "^2.9.3", "cosmiconfig": "^9.0.0", - "css-functions-list": "^3.2.2", - "css-tree": "^2.3.1", - "debug": "^4.3.5", + "css-functions-list": "^3.2.3", + "css-tree": "^3.0.1", + "debug": "^4.3.7", "fast-glob": "^3.3.2", "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^9.0.0", + "file-entry-cache": "^9.1.0", "global-modules": "^2.0.0", "globby": "^11.1.0", "globjoin": "^0.1.4", "html-tags": "^3.3.1", - "ignore": "^5.3.1", + "ignore": "^6.0.2", "imurmurhash": "^0.1.4", "is-plain-object": "^5.0.0", - "known-css-properties": "^0.34.0", + "known-css-properties": "^0.35.0", "mathml-tag-names": "^2.1.3", "meow": "^13.2.0", - "micromatch": "^4.0.7", + "micromatch": "^4.0.8", "normalize-path": "^3.0.0", - "picocolors": "^1.0.1", - "postcss": "^8.4.39", - "postcss-resolve-nested-selector": "^0.1.1", - "postcss-safe-parser": "^7.0.0", - "postcss-selector-parser": "^6.1.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.49", + "postcss-resolve-nested-selector": "^0.1.6", + "postcss-safe-parser": "^7.0.1", + "postcss-selector-parser": "^7.0.0", "postcss-value-parser": "^4.2.0", "resolve-from": "^5.0.0", "string-width": "^4.2.3", - "strip-ansi": "^7.1.0", - "supports-hyperlinks": "^3.0.0", + "supports-hyperlinks": "^3.1.0", "svg-tags": "^1.0.0", - "table": "^6.8.2", + "table": "^6.9.0", "write-file-atomic": "^5.0.1" }, "bin": { @@ -4612,200 +4569,105 @@ } }, "node_modules/stylelint-config-recommended": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-14.0.0.tgz", - "integrity": "sha512-jSkx290CglS8StmrLp2TxAppIajzIBZKYm3IxT89Kg6fGlxbPiTiyH9PS5YUuVAFwaJLl1ikiXX0QWjI0jmgZQ==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-14.0.1.tgz", + "integrity": "sha512-bLvc1WOz/14aPImu/cufKAZYfXs/A/owZfSMZ4N+16WGXLoX5lOir53M6odBxvhgmgdxCVnNySJmZKx73T93cg==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + }, + { + "type": "github", + "url": "https://github.com/sponsors/stylelint" + } + ], "engines": { "node": ">=18.12.0" }, "peerDependencies": { - "stylelint": "^16.0.0" + "stylelint": "^16.1.0" } }, "node_modules/stylelint-config-wikimedia": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/stylelint-config-wikimedia/-/stylelint-config-wikimedia-0.17.2.tgz", - "integrity": "sha512-cc3PYhe1O/GTgsMOp+Ri3ru579YBbZ3Me0oU7xNb06n4iwyXYPz8qO5G4iQ13UH19UW2NIS8Tk0goPRrJ1RAfw==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/stylelint-config-wikimedia/-/stylelint-config-wikimedia-0.18.0.tgz", + "integrity": "sha512-Lr45NIe7pG8i7BPcMc6EddO1pRK8/KNG8gp4o/oOG1Ez10hglJuJb/QT17BlzX8NPkhtP2KdY63NS2f/Wcj6Ww==", "dev": true, "dependencies": { - "@stylistic/stylelint-config": "1.0.1", - "@stylistic/stylelint-plugin": "2.0.0", + "@stylistic/stylelint-config": "2.0.0", + "@stylistic/stylelint-plugin": "3.1.1", "browserslist-config-wikimedia": "0.7.0", - "postcss-html": "1.6.0", + "postcss-html": "1.7.0", "postcss-less": "6.0.0", - "stylelint": "16.2.0", - "stylelint-config-recommended": "14.0.0", - "stylelint-no-unsupported-browser-features": "8.0.1" + "stylelint": "16.12.0", + "stylelint-config-recommended": "14.0.1", + "stylelint-no-unsupported-browser-features": "8.0.2" }, "peerDependencies": { "postcss-less": "^6.0.0" } }, - "node_modules/stylelint-config-wikimedia/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/stylelint-config-wikimedia/node_modules/balanced-match": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", - "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", - "dev": true - }, - "node_modules/stylelint-config-wikimedia/node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/stylelint-config-wikimedia/node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/stylelint-config-wikimedia/node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stylelint-config-wikimedia/node_modules/known-css-properties": { - "version": "0.29.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.29.0.tgz", - "integrity": "sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==", - "dev": true - }, - "node_modules/stylelint-config-wikimedia/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/stylelint-config-wikimedia/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/stylelint-config-wikimedia/node_modules/stylelint": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.2.0.tgz", - "integrity": "sha512-gwqU5AkIb52wrAzzn+359S3NIJDMl02TXLUaV2tzA/L6jUdpTwNt+MCxHlc8+Hb2bUHlYVo92YeSIryF2gJthA==", + "node_modules/stylelint-no-unsupported-browser-features": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/stylelint-no-unsupported-browser-features/-/stylelint-no-unsupported-browser-features-8.0.2.tgz", + "integrity": "sha512-4PY2qJ3ZTEje9RgGfaQ82eJoPioXxs6hazeKpji/wzLNVzTX2wd4b0Ds3ewdLkH3ID+o63IInuTquU2MNJO3YQ==", "dev": true, "dependencies": { - "@csstools/css-parser-algorithms": "^2.5.0", - "@csstools/css-tokenizer": "^2.2.3", - "@csstools/media-query-list-parser": "^2.1.7", - "@csstools/selector-specificity": "^3.0.1", - "balanced-match": "^2.0.0", - "colord": "^2.9.3", - "cosmiconfig": "^9.0.0", - "css-functions-list": "^3.2.1", - "css-tree": "^2.3.1", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^8.0.0", - "global-modules": "^2.0.0", - "globby": "^11.1.0", - "globjoin": "^0.1.4", - "html-tags": "^3.3.1", - "ignore": "^5.3.0", - "imurmurhash": "^0.1.4", - "is-plain-object": "^5.0.0", - "known-css-properties": "^0.29.0", - "mathml-tag-names": "^2.1.3", - "meow": "^13.1.0", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.33", - "postcss-resolve-nested-selector": "^0.1.1", - "postcss-safe-parser": "^7.0.0", - "postcss-selector-parser": "^6.0.15", - "postcss-value-parser": "^4.2.0", - "resolve-from": "^5.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^7.1.0", - "supports-hyperlinks": "^3.0.0", - "svg-tags": "^1.0.0", - "table": "^6.8.1", - "write-file-atomic": "^5.0.1" - }, - "bin": { - "stylelint": "bin/stylelint.mjs" + "doiuse": "^6.0.5", + "postcss": "^8.4.32" }, "engines": { "node": ">=18.12.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/stylelint" + "peerDependencies": { + "stylelint": "^16.0.2" } }, - "node_modules/stylelint-no-unsupported-browser-features": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/stylelint-no-unsupported-browser-features/-/stylelint-no-unsupported-browser-features-8.0.1.tgz", - "integrity": "sha512-tc8Xn5DaqJhxTmbA4H8gZbYdAz027NfuSZv5+cVieQb7BtBrF/1/iKYdpcGwXPl3GtqkQrisiXuGqKkKnzWcLw==", + "node_modules/stylelint/node_modules/@csstools/media-query-list-parser": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz", + "integrity": "sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==", "dev": true, - "dependencies": { - "doiuse": "^6.0.2", - "postcss": "^8.4.32" - }, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "engines": { - "node": ">=18.12.0" + "node": ">=18" }, "peerDependencies": { - "stylelint": "^16.0.2" + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" } }, - "node_modules/stylelint/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "node_modules/stylelint/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "engines": { - "node": ">=12" + "node": ">=18" }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" } }, "node_modules/stylelint/node_modules/balanced-match": { @@ -4815,9 +4677,9 @@ "dev": true }, "node_modules/stylelint/node_modules/file-entry-cache": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.0.0.tgz", - "integrity": "sha512-6MgEugi8p2tiUhqO7GnPsmbCCzj0YRCwwaTbpGRyKZesjRSzkqkAE9fPp7V2yMs5hwfgbQLgdvSSkGNg1s5Uvw==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.1.0.tgz", + "integrity": "sha512-/pqPFG+FdxWQj+/WSuzXSDaNzxgTLr/OrR1QuqfEZzDakpdYE70PwUxL7BPUa8hpjbvY1+qvCl8k+8Tq34xJgg==", "dev": true, "dependencies": { "flat-cache": "^5.0.0" @@ -4839,6 +4701,15 @@ "node": ">=18" } }, + "node_modules/stylelint/node_modules/ignore": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-6.0.2.tgz", + "integrity": "sha512-InwqeHHN2XpumIkMvpl/DCJVrAHgCsG5+cn1XlnLWGwtZBm8QJfSusItfrwx81CTp5agNZqpKU2J/ccC5nGT4A==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/stylelint/node_modules/is-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", @@ -4848,28 +4719,52 @@ "node": ">=0.10.0" } }, - "node_modules/stylelint/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "node_modules/stylelint/node_modules/postcss-safe-parser": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz", + "integrity": "sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-safe-parser" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "engines": { - "node": ">=8" + "node": ">=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/stylelint/node_modules/strip-ansi": { + "node_modules/stylelint/node_modules/postcss-selector-parser": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", "dev": true, "dependencies": { - "ansi-regex": "^6.0.1" + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": ">=4" + } + }, + "node_modules/stylelint/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" } }, "node_modules/supports-color": { @@ -4885,9 +4780,9 @@ } }, "node_modules/supports-hyperlinks": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", - "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", + "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", "dev": true, "dependencies": { "has-flag": "^4.0.0", @@ -4895,6 +4790,9 @@ }, "engines": { "node": ">=14.18" + }, + "funding": { + "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" } }, "node_modules/supports-preserve-symlinks-flag": { @@ -4916,9 +4814,9 @@ "dev": true }, "node_modules/table": { - "version": "6.8.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", - "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", + "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", "dev": true, "dependencies": { "ajv": "^8.0.1", @@ -4968,28 +4866,6 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, - "node_modules/through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha512-RkK/CCESdTKQZHdmKICijdKKsCRVHs5KsLZ6pACAmF/1GPUQhonHSXWNERctxEp7RmvjdNbZTL5z9V7nSCXKcg==", - "dev": true, - "dependencies": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - } - }, - "node_modules/through2/node_modules/readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, "node_modules/tiny-lr": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", @@ -5108,9 +4984,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", "dev": true, "funding": [ { @@ -5127,8 +5003,8 @@ } ], "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -5471,29 +5347,22 @@ } }, "@csstools/css-parser-algorithms": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.7.1.tgz", - "integrity": "sha512-2SJS42gxmACHgikc1WGesXLIT8d/q2l0UFM7TaEeIzdFCE/FPMtTiizcPGGJtlPo2xuQzY09OhrLTzRxqJqwGw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", "dev": true, "requires": {} }, "@csstools/css-tokenizer": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.4.1.tgz", - "integrity": "sha512-eQ9DIktFJBhGjioABJRtUucoWR2mwllurfnM8LuNGAqX3ViZXaUchqk+1s7jjtkFiT9ySdACsFEA3etErkALUg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", "dev": true }, "@csstools/media-query-list-parser": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.13.tgz", - "integrity": "sha512-XaHr+16KRU9Gf8XLi3q8kDlI18d5vzKSKCY510Vrtc9iNR0NJzbY9hhTmwhzYZj/ZwGL4VmB3TA9hJW0Um2qFA==", - "dev": true, - "requires": {} - }, - "@csstools/selector-specificity": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.1.1.tgz", - "integrity": "sha512-a7cxGcJ2wIlMFLlh8z2ONm+715QkPHiyJcxwQlKOz/03GPw1COpfhcmC9wm4xlZfp//jWHNNMwzjtqHXVWU9KA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-3.0.1.tgz", + "integrity": "sha512-HNo8gGD02kHmcbX6PvCoUuOQvn4szyB9ca63vZHKX5A81QytgDG4oxG4IaEfHTlEZSZ6MjPEMWIVU+zF2PZcgw==", "dev": true, "requires": {} }, @@ -5637,28 +5506,28 @@ } }, "@stylistic/stylelint-config": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@stylistic/stylelint-config/-/stylelint-config-1.0.1.tgz", - "integrity": "sha512-JgFP88HZEyo34k9RpWVdcQJtLPrMxYE58IO3qypXhmvE/NmZohj+xjDtQ8UfaarnYsLecnldw57/GHum07Ctdw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@stylistic/stylelint-config/-/stylelint-config-2.0.0.tgz", + "integrity": "sha512-8J4YAxggy2Nzkb8KJIOLbtMXTPZ5gpKVmyhiiuKEUgCl9XFND5lM0e/ZZBMGEYZ68h5qcsS/jgg1wh235erRAw==", "dev": true, "requires": { - "@stylistic/stylelint-plugin": "^2.0.0" + "@stylistic/stylelint-plugin": "^3.0.0" } }, "@stylistic/stylelint-plugin": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-2.0.0.tgz", - "integrity": "sha512-dHKuT6PGd1WGZLOTuozAM7GdQzdmlmnFXYzvV1jYJXXpcCpV/OJ3+n8TXpMkoOeKHpJydY43EOoZTO1W/FOA4Q==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-3.1.1.tgz", + "integrity": "sha512-XagAHHIa528EvyGybv8EEYGK5zrVW74cHpsjhtovVATbhDRuJYfE+X4HCaAieW9lCkwbX6L+X0I4CiUG3w/hFw==", "dev": true, "requires": { - "@csstools/css-parser-algorithms": "^2.3.2", - "@csstools/css-tokenizer": "^2.2.1", - "@csstools/media-query-list-parser": "^2.1.5", + "@csstools/css-parser-algorithms": "^3.0.1", + "@csstools/css-tokenizer": "^3.0.1", + "@csstools/media-query-list-parser": "^3.0.1", "is-plain-object": "^5.0.0", - "postcss-selector-parser": "^6.0.13", + "postcss-selector-parser": "^6.1.2", "postcss-value-parser": "^4.2.0", "style-search": "^0.1.0", - "stylelint": "^16.0.2" + "stylelint": "^16.8.2" }, "dependencies": { "is-plain-object": { @@ -5666,6 +5535,16 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true + }, + "postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } } } }, @@ -5939,15 +5818,15 @@ } }, "browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.0.tgz", + "integrity": "sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001718", + "electron-to-chromium": "^1.5.160", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" } }, "browserslist-config-wikimedia": { @@ -5985,9 +5864,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001612", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz", - "integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==", + "version": "1.0.30001721", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001721.tgz", + "integrity": "sha512-cOuvmUVtKrtEaoKiO0rSc29jcjwMwX5tOHDy4MgVFEWiUXj4uBMJkwI8MDySkgXidpMiHUcviogAvFi4pA2hDQ==", "dev": true }, "chalk": { @@ -6124,9 +6003,9 @@ } }, "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "requires": { "path-key": "^3.1.0", @@ -6146,9 +6025,9 @@ } }, "css-functions-list": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.2.tgz", - "integrity": "sha512-c+N0v6wbKVxTu5gOBBFkr9BEdBWaqqjQeiJ8QvSRIJOf+UxlJh930m8e6/WNeODIK0mYLFkoONrnj16i2EcvfQ==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz", + "integrity": "sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==", "dev": true }, "css-tokenize": { @@ -6162,12 +6041,12 @@ } }, "css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", "dev": true, "requires": { - "mdn-data": "2.0.30", + "mdn-data": "2.12.2", "source-map-js": "^1.0.1" } }, @@ -6184,12 +6063,12 @@ "dev": true }, "debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "dev": true, "requires": { - "ms": "2.1.2" + "ms": "^2.1.3" } }, "deep-is": { @@ -6223,20 +6102,19 @@ } }, "doiuse": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/doiuse/-/doiuse-6.0.2.tgz", - "integrity": "sha512-eBTs23NOX+EAYPr4RbCR6J4DRW/TML3uMo37y0X1whlkersDYFCk9HmCl09KX98cis22VKsV1QaxfVNauJ3NBw==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/doiuse/-/doiuse-6.0.5.tgz", + "integrity": "sha512-ljuf9ndGqKST0GlPAYyCg04hbQAeR1xIIWVDjQaDDkoTY/Y1Vb+8FNoy6NuVuJIEEKe/nKUH8NRWjG7JJxZ9Eg==", "dev": true, "requires": { - "browserslist": "^4.21.5", - "caniuse-lite": "^1.0.30001487", + "browserslist": "^4.24.0", + "caniuse-lite": "^1.0.30001669", "css-tokenize": "^1.0.1", - "duplexify": "^4.1.2", - "ldjson-stream": "^1.2.1", + "duplexify": "^4.1.3", "multimatch": "^5.0.0", - "postcss": "^8.4.21", + "postcss": "^8.4.47", "source-map": "^0.7.4", - "yargs": "^17.7.1" + "yargs": "^17.7.2" } }, "dom-serializer": { @@ -6266,9 +6144,9 @@ } }, "domutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", "dev": true, "requires": { "dom-serializer": "^2.0.0", @@ -6311,9 +6189,9 @@ } }, "electron-to-chromium": { - "version": "1.4.750", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.750.tgz", - "integrity": "sha512-9ItEpeu15hW5m8jKdriL+BQrgwDTXEL9pn4SkillWFu73ZNNNQ2BKKLS+ZHv2vC9UkNhosAeyfxOf/5OSeTCPA==", + "version": "1.5.165", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.165.tgz", + "integrity": "sha512-naiMx1Z6Nb2TxPU6fiFrUrDTjyPMLdTtaOd2oLmG8zVSg2hCWGkhPyxwk+qRmZ1ytwVqUv0u7ZcDA5+ALhaUtw==", "dev": true }, "emoji-regex": { @@ -6373,9 +6251,9 @@ } }, "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true }, "escape-string-regexp": { @@ -6475,9 +6353,9 @@ } }, "eslint-config-wikimedia": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.28.2.tgz", - "integrity": "sha512-5+rdnT7wH1gpKAO6tHYThg78eMhZMruJzvqku3Y5iaEY/A7kSKLFpA/vOj/snys9fKjDHC9BXmArQh+agkOoJQ==", + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.30.0.tgz", + "integrity": "sha512-i8ESzSoo0x3Jur/0JhAgCVPxbV51zfdI3MN3MVQPnjiFdmo21CNKmiBBmw8JnJ3fx/d5zHDrBa+yDjxSLpnDlA==", "dev": true, "requires": { "browserslist-config-wikimedia": "^0.7.0", @@ -6490,7 +6368,7 @@ "eslint-plugin-mediawiki": "^0.7.0", "eslint-plugin-mocha": "^10.4.3", "eslint-plugin-n": "^17.7.0", - "eslint-plugin-no-jquery": "^3.0.1", + "eslint-plugin-no-jquery": "^3.1.1", "eslint-plugin-qunit": "^8.1.1", "eslint-plugin-security": "^1.7.1", "eslint-plugin-unicorn": "^53.0.0", @@ -6625,9 +6503,9 @@ } }, "eslint-plugin-no-jquery": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-3.0.2.tgz", - "integrity": "sha512-n/+6p6PFhWDNPVLJj1463hw4OTIRBbROGcbhmtOHTgw7yihSKzkwZiQ00EJTneyeR3jRiw5lpWSMCCBhtb8t2g==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-3.1.1.tgz", + "integrity": "sha512-LTLO3jH/Tjr1pmxCEqtV6qmt+OChv8La4fwgG470JRpgxyFF4NOzoC9CRy92GIWD3Yjl0qLEgPmD2FLQWcNEjg==", "dev": true, "requires": {} }, @@ -6914,9 +6792,9 @@ "dev": true }, "fast-uri": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", - "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", "dev": true }, "fastest-levenshtein": { @@ -7659,21 +7537,11 @@ "dev": true }, "known-css-properties": { - "version": "0.34.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.34.0.tgz", - "integrity": "sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==", + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.35.0.tgz", + "integrity": "sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==", "dev": true }, - "ldjson-stream": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ldjson-stream/-/ldjson-stream-1.2.1.tgz", - "integrity": "sha512-xw/nNEXafuPSLu8NjjG3+atVVw+8U1APZAQylmwQn19Hgw6rC7QjHvP6MupnHWCrzSm9m0xs5QWkCLuRvBPjgQ==", - "dev": true, - "requires": { - "split2": "^0.2.1", - "through2": "^0.6.1" - } - }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -7781,9 +7649,9 @@ "dev": true }, "mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", "dev": true }, "meow": { @@ -7824,9 +7692,9 @@ } }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "multimatch": { @@ -7843,9 +7711,9 @@ } }, "nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true }, "natural-compare": { @@ -7855,9 +7723,9 @@ "dev": true }, "node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "dev": true }, "nopt": { @@ -8100,9 +7968,9 @@ "dev": true }, "picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true }, "picomatch": { @@ -8118,40 +7986,33 @@ "dev": true }, "postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.4.tgz", + "integrity": "sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==", "dev": true, "requires": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" } }, "postcss-html": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.6.0.tgz", - "integrity": "sha512-OWgQ9/Pe23MnNJC0PL4uZp8k0EDaUvqpJFSiwFxOLClAhmD7UEisyhO3x5hVsD4xFrjReVTXydlrMes45dJ71w==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.7.0.tgz", + "integrity": "sha512-MfcMpSUIaR/nNgeVS8AyvyDugXlADjN9AcV7e5rDfrF1wduIAGSkL4q2+wgrZgA3sHVAHLDO9FuauHhZYW2nBw==", "dev": true, "requires": { "htmlparser2": "^8.0.0", - "js-tokens": "^8.0.0", + "js-tokens": "^9.0.0", "postcss": "^8.4.0", "postcss-safe-parser": "^6.0.0" }, "dependencies": { "js-tokens": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.3.tgz", - "integrity": "sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", "dev": true - }, - "postcss-safe-parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", - "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", - "dev": true, - "requires": {} } } }, @@ -8163,15 +8024,15 @@ "requires": {} }, "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=", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz", + "integrity": "sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==", "dev": true }, "postcss-safe-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.0.tgz", - "integrity": "sha512-ovehqRNVCpuFzbXoTb4qLtyzK3xn3t/CUBxOs8LsnQjQrShaB4lKiHoVqY8ANaC0hBMHq5QVWk77rwGklFUDrg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", + "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", "dev": true, "requires": {} }, @@ -8544,9 +8405,9 @@ "dev": true }, "source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true }, "spdx-correct": { @@ -8593,15 +8454,6 @@ "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", "dev": true }, - "split2": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/split2/-/split2-0.2.1.tgz", - "integrity": "sha512-D/oTExYAkC9nWleOCTOyNmAuzfAT/6rHGBA9LIK7FVnGo13CSvrKCUzKenwH6U1s2znY9MqH6v0UQTEDa3vJmg==", - "dev": true, - "requires": { - "through2": "~0.6.1" - } - }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -8668,57 +8520,64 @@ "dev": true }, "stylelint": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.7.0.tgz", - "integrity": "sha512-Q1ATiXlz+wYr37a7TGsfvqYn2nSR3T/isw3IWlZQzFzCNoACHuGBb6xBplZXz56/uDRJHIygxjh7jbV/8isewA==", + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.12.0.tgz", + "integrity": "sha512-F8zZ3L/rBpuoBZRvI4JVT20ZanPLXfQLzMOZg1tzPflRVh9mKpOZ8qcSIhh1my3FjAjZWG4T2POwGnmn6a6hbg==", "dev": true, "requires": { - "@csstools/css-parser-algorithms": "^2.7.1", - "@csstools/css-tokenizer": "^2.4.1", - "@csstools/media-query-list-parser": "^2.1.13", - "@csstools/selector-specificity": "^3.1.1", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/media-query-list-parser": "^4.0.2", + "@csstools/selector-specificity": "^5.0.0", "@dual-bundle/import-meta-resolve": "^4.1.0", "balanced-match": "^2.0.0", "colord": "^2.9.3", "cosmiconfig": "^9.0.0", - "css-functions-list": "^3.2.2", - "css-tree": "^2.3.1", - "debug": "^4.3.5", + "css-functions-list": "^3.2.3", + "css-tree": "^3.0.1", + "debug": "^4.3.7", "fast-glob": "^3.3.2", "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^9.0.0", + "file-entry-cache": "^9.1.0", "global-modules": "^2.0.0", "globby": "^11.1.0", "globjoin": "^0.1.4", "html-tags": "^3.3.1", - "ignore": "^5.3.1", + "ignore": "^6.0.2", "imurmurhash": "^0.1.4", "is-plain-object": "^5.0.0", - "known-css-properties": "^0.34.0", + "known-css-properties": "^0.35.0", "mathml-tag-names": "^2.1.3", "meow": "^13.2.0", - "micromatch": "^4.0.7", + "micromatch": "^4.0.8", "normalize-path": "^3.0.0", - "picocolors": "^1.0.1", - "postcss": "^8.4.39", - "postcss-resolve-nested-selector": "^0.1.1", - "postcss-safe-parser": "^7.0.0", - "postcss-selector-parser": "^6.1.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.49", + "postcss-resolve-nested-selector": "^0.1.6", + "postcss-safe-parser": "^7.0.1", + "postcss-selector-parser": "^7.0.0", "postcss-value-parser": "^4.2.0", "resolve-from": "^5.0.0", "string-width": "^4.2.3", - "strip-ansi": "^7.1.0", - "supports-hyperlinks": "^3.0.0", + "supports-hyperlinks": "^3.1.0", "svg-tags": "^1.0.0", - "table": "^6.8.2", + "table": "^6.9.0", "write-file-atomic": "^5.0.1" }, "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true + "@csstools/media-query-list-parser": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz", + "integrity": "sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==", + "dev": true, + "requires": {} + }, + "@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "dev": true, + "requires": {} }, "balanced-match": { "version": "2.0.0", @@ -8727,9 +8586,9 @@ "dev": true }, "file-entry-cache": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.0.0.tgz", - "integrity": "sha512-6MgEugi8p2tiUhqO7GnPsmbCCzj0YRCwwaTbpGRyKZesjRSzkqkAE9fPp7V2yMs5hwfgbQLgdvSSkGNg1s5Uvw==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.1.0.tgz", + "integrity": "sha512-/pqPFG+FdxWQj+/WSuzXSDaNzxgTLr/OrR1QuqfEZzDakpdYE70PwUxL7BPUa8hpjbvY1+qvCl8k+8Tq34xJgg==", "dev": true, "requires": { "flat-cache": "^5.0.0" @@ -8745,165 +8604,73 @@ "keyv": "^4.5.4" } }, + "ignore": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-6.0.2.tgz", + "integrity": "sha512-InwqeHHN2XpumIkMvpl/DCJVrAHgCsG5+cn1XlnLWGwtZBm8QJfSusItfrwx81CTp5agNZqpKU2J/ccC5nGT4A==", + "dev": true + }, "is-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true }, - "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 + "postcss-safe-parser": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz", + "integrity": "sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==", + "dev": true, + "requires": {} }, - "strip-ansi": { + "postcss-selector-parser": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", "dev": true, "requires": { - "ansi-regex": "^6.0.1" + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" } + }, + "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 } } }, "stylelint-config-recommended": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-14.0.0.tgz", - "integrity": "sha512-jSkx290CglS8StmrLp2TxAppIajzIBZKYm3IxT89Kg6fGlxbPiTiyH9PS5YUuVAFwaJLl1ikiXX0QWjI0jmgZQ==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-14.0.1.tgz", + "integrity": "sha512-bLvc1WOz/14aPImu/cufKAZYfXs/A/owZfSMZ4N+16WGXLoX5lOir53M6odBxvhgmgdxCVnNySJmZKx73T93cg==", "dev": true, "requires": {} }, "stylelint-config-wikimedia": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/stylelint-config-wikimedia/-/stylelint-config-wikimedia-0.17.2.tgz", - "integrity": "sha512-cc3PYhe1O/GTgsMOp+Ri3ru579YBbZ3Me0oU7xNb06n4iwyXYPz8qO5G4iQ13UH19UW2NIS8Tk0goPRrJ1RAfw==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/stylelint-config-wikimedia/-/stylelint-config-wikimedia-0.18.0.tgz", + "integrity": "sha512-Lr45NIe7pG8i7BPcMc6EddO1pRK8/KNG8gp4o/oOG1Ez10hglJuJb/QT17BlzX8NPkhtP2KdY63NS2f/Wcj6Ww==", "dev": true, "requires": { - "@stylistic/stylelint-config": "1.0.1", - "@stylistic/stylelint-plugin": "2.0.0", + "@stylistic/stylelint-config": "2.0.0", + "@stylistic/stylelint-plugin": "3.1.1", "browserslist-config-wikimedia": "0.7.0", - "postcss-html": "1.6.0", + "postcss-html": "1.7.0", "postcss-less": "6.0.0", - "stylelint": "16.2.0", - "stylelint-config-recommended": "14.0.0", - "stylelint-no-unsupported-browser-features": "8.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true - }, - "balanced-match": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", - "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", - "dev": true - }, - "file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, - "requires": { - "flat-cache": "^4.0.0" - } - }, - "flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, - "requires": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - } - }, - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true - }, - "known-css-properties": { - "version": "0.29.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.29.0.tgz", - "integrity": "sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==", - "dev": true - }, - "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-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - }, - "stylelint": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.2.0.tgz", - "integrity": "sha512-gwqU5AkIb52wrAzzn+359S3NIJDMl02TXLUaV2tzA/L6jUdpTwNt+MCxHlc8+Hb2bUHlYVo92YeSIryF2gJthA==", - "dev": true, - "requires": { - "@csstools/css-parser-algorithms": "^2.5.0", - "@csstools/css-tokenizer": "^2.2.3", - "@csstools/media-query-list-parser": "^2.1.7", - "@csstools/selector-specificity": "^3.0.1", - "balanced-match": "^2.0.0", - "colord": "^2.9.3", - "cosmiconfig": "^9.0.0", - "css-functions-list": "^3.2.1", - "css-tree": "^2.3.1", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^8.0.0", - "global-modules": "^2.0.0", - "globby": "^11.1.0", - "globjoin": "^0.1.4", - "html-tags": "^3.3.1", - "ignore": "^5.3.0", - "imurmurhash": "^0.1.4", - "is-plain-object": "^5.0.0", - "known-css-properties": "^0.29.0", - "mathml-tag-names": "^2.1.3", - "meow": "^13.1.0", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.33", - "postcss-resolve-nested-selector": "^0.1.1", - "postcss-safe-parser": "^7.0.0", - "postcss-selector-parser": "^6.0.15", - "postcss-value-parser": "^4.2.0", - "resolve-from": "^5.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^7.1.0", - "supports-hyperlinks": "^3.0.0", - "svg-tags": "^1.0.0", - "table": "^6.8.1", - "write-file-atomic": "^5.0.1" - } - } + "stylelint": "16.12.0", + "stylelint-config-recommended": "14.0.1", + "stylelint-no-unsupported-browser-features": "8.0.2" } }, "stylelint-no-unsupported-browser-features": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/stylelint-no-unsupported-browser-features/-/stylelint-no-unsupported-browser-features-8.0.1.tgz", - "integrity": "sha512-tc8Xn5DaqJhxTmbA4H8gZbYdAz027NfuSZv5+cVieQb7BtBrF/1/iKYdpcGwXPl3GtqkQrisiXuGqKkKnzWcLw==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/stylelint-no-unsupported-browser-features/-/stylelint-no-unsupported-browser-features-8.0.2.tgz", + "integrity": "sha512-4PY2qJ3ZTEje9RgGfaQ82eJoPioXxs6hazeKpji/wzLNVzTX2wd4b0Ds3ewdLkH3ID+o63IInuTquU2MNJO3YQ==", "dev": true, "requires": { - "doiuse": "^6.0.2", + "doiuse": "^6.0.5", "postcss": "^8.4.32" } }, @@ -8917,9 +8684,9 @@ } }, "supports-hyperlinks": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", - "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", + "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", "dev": true, "requires": { "has-flag": "^4.0.0", @@ -8939,9 +8706,9 @@ "dev": true }, "table": { - "version": "6.8.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", - "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", + "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", "dev": true, "requires": { "ajv": "^8.0.1", @@ -8983,30 +8750,6 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha512-RkK/CCESdTKQZHdmKICijdKKsCRVHs5KsLZ6pACAmF/1GPUQhonHSXWNERctxEp7RmvjdNbZTL5z9V7nSCXKcg==", - "dev": true, - "requires": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } - } - }, "tiny-lr": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", @@ -9093,13 +8836,13 @@ "dev": true }, "update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", "dev": true, "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" } }, "uri-js": { diff --git a/package.json b/package.json index ee929ed..6bb576e 100644 --- a/package.json +++ b/package.json @@ -6,12 +6,12 @@ "test-fix": "grunt test --fix" }, "devDependencies": { - "eslint-config-wikimedia": "0.28.2", + "eslint-config-wikimedia": "0.30.0", "grunt": "1.6.1", "grunt-banana-checker": "0.13.0", "grunt-contrib-watch": "1.1.0", "grunt-eslint": "24.3.0", "grunt-stylelint": "0.20.1", - "stylelint-config-wikimedia": "0.17.2" + "stylelint-config-wikimedia": "0.18.0" } } diff --git a/resources/controller/uw.controller.Deed.js b/resources/controller/uw.controller.Deed.js index d843eaf..533e591 100644 --- a/resources/controller/uw.controller.Deed.js +++ b/resources/controller/uw.controller.Deed.js @@ -40,7 +40,7 @@ OO.inheritClass( uw.controller.Deed, uw.controller.Step ); uw.controller.Deed.prototype.moveNext = function () { - var + let deedController = this, valid, fields, validityPromises; @@ -52,10 +52,10 @@ valid = this.deedChooser.valid(); if ( valid ) { fields = this.deedChooser.deed.getFields(); - validityPromises = fields.map( function ( fieldLayout ) { + validityPromises = fields.map( ( fieldLayout ) => // Update any error/warning messages - return fieldLayout.checkValidity( true ); - } ); + fieldLayout.checkValidity( true ) + ); if ( validityPromises.length === 1 ) { // validityPromises will hold all promises for all uploads; // adding a bogus promise (no warnings & errors) to @@ -73,7 +73,7 @@ // TODO Handle warnings with a confirmation dialog - var i; + let i; for ( i = 0; i < arguments.length; i++ ) { if ( arguments[ i ][ 1 ].length ) { // One of the fields has errors; refuse to proceed! @@ -87,10 +87,10 @@ }; uw.controller.Deed.prototype.unload = function () { - var deedController = this; + const deedController = this; uw.controller.Step.prototype.unload.call( this ); - Object.keys( this.deeds ).forEach( function ( name ) { + Object.keys( this.deeds ).forEach( ( name ) => { deedController.deeds[ name ].unload(); } ); }; @@ -101,7 +101,7 @@ * @param {mw.UploadWizardUpload[]} uploads */ uw.controller.Deed.prototype.load = function ( uploads ) { - var customDeed, previousDeed; + let customDeed, previousDeed; uw.controller.Step.prototype.load.call( this, uploads ); @@ -130,7 +130,7 @@ .insertBefore( this.deedChooser.$selector.find( '.mediauploader-deed-ownwork' ) ) .msg( 'mediauploader-deeds-macro-prompt', this.uploads.length, mw.user ); - uploads.forEach( function ( upload ) { + uploads.forEach( ( upload ) => { // Add previews and details to the DOM upload.deedPreview = new uw.ui.DeedPreview( upload ); } ); diff --git a/resources/controller/uw.controller.Details.js b/resources/controller/uw.controller.Details.js index 843a65b..82aa27b 100644 --- a/resources/controller/uw.controller.Details.js +++ b/resources/controller/uw.controller.Details.js @@ -51,15 +51,15 @@ * @param {mw.UploadWizardUpload[]} uploads List of uploads being carried forward. */ uw.controller.Details.prototype.load = function ( uploads ) { - var controller = this; + const controller = this; uw.controller.Step.prototype.load.call( this, uploads ); // make sure queue is empty before starting this step this.queue.abortExecuting(); - this.uploads.forEach( function ( upload ) { - var serialized; + this.uploads.forEach( ( upload ) => { + let serialized; // get existing details serialized = upload.details ? upload.details.getSerialized() : null; @@ -90,7 +90,7 @@ }; uw.controller.Details.prototype.addCopyMetadataFeature = function () { - var first, + let first, // uploads can only be edited when they're in a certain state: // a flat out upload failure or a completed upload can not be edited invalidStates = [ 'aborted', 'error', 'complete' ], @@ -107,8 +107,8 @@ // rest failed because of abusefilter (or another recoverable error), in // which case we'll want the "copy" feature to appear below the 2nd // upload (or the first not-yet-completed not flat-out-failed upload) - this.uploads.some( function ( upload ) { - if ( upload && invalidStates.indexOf( upload.state ) === -1 ) { + this.uploads.some( ( upload ) => { + if ( upload && !invalidStates.includes( upload.state ) ) { first = upload; return true; // Break Array.some loop } @@ -148,9 +148,9 @@ * TODO move the rest of the logic here from mw.UploadWizard */ uw.controller.Details.prototype.startDetails = function () { - var details = this; + const details = this; - this.valid().done( function ( valid ) { + this.valid().done( ( valid ) => { if ( valid ) { details.ui.hideEndButtons(); details.submit(); @@ -166,7 +166,7 @@ * @return {jQuery.Promise} */ uw.controller.Details.prototype.valid = function () { - var detailsController = this, + const detailsController = this, // validityPromises will hold all promises for all uploads; // prefilling with a bogus promise (no warnings & errors) to // ensure $.when always resolves with an array of multiple @@ -176,14 +176,14 @@ validityPromises = [ $.Deferred().resolve( [], [] ).promise() ], titles = []; - this.uploads.forEach( function ( upload ) { + this.uploads.forEach( ( upload ) => { // Update any error/warning messages about all DetailsWidgets - var promise = upload.details.checkValidity( true ).then( function () { - var warnings = [], + const promise = upload.details.checkValidity( true ).then( function () { + let warnings = [], errors = [], title; - Array.prototype.forEach.call( arguments, function ( result ) { + Array.prototype.forEach.call( arguments, ( result ) => { warnings = warnings.concat( result[ 0 ] ); errors = errors.concat( result[ 1 ] ); } ); @@ -211,10 +211,10 @@ // validityPromises is an array of promises that each resolve with [warnings, errors] // for each upload - now iterate them all to figure out if we can proceed return $.when.apply( $, validityPromises ).then( function () { - var warnings = [], + let warnings = [], errors = []; - Array.prototype.forEach.call( arguments, function ( result ) { + Array.prototype.forEach.call( arguments, ( result ) => { warnings = warnings.concat( result[ 0 ] ); errors = errors.concat( result[ 1 ] ); } ); @@ -234,19 +234,15 @@ }; uw.controller.Details.prototype.confirmationDialog = function ( warnings ) { - var i, + let i, $message = $( '<p>' ).text( mw.message( 'mediauploader-dialog-warning' ).text() ), $ul = $( '<ul>' ); // parse warning messages - warnings = warnings.map( function ( warning ) { - return warning.text(); - } ); + warnings = warnings.map( ( warning ) => warning.text() ); // omit duplicates - warnings = warnings.filter( function ( warning, j, warningsOld ) { - return warningsOld.indexOf( warning ) === j; - } ); + warnings = warnings.filter( ( warning, j, warningsOld ) => warningsOld.indexOf( warning ) === j ); for ( i = 0; i < warnings.length; i++ ) { $ul.append( $( '<li>' ).text( warnings[ i ] ) ); @@ -265,9 +261,7 @@ label: mw.msg( 'mediauploader-dialog-continue' ) } ] - } ).closed.then( function ( data ) { - return !!( data && data.action === 'continue' ); - } ); + } ).closed.then( ( data ) => !!( data && data.action === 'continue' ) ); }; uw.controller.Details.prototype.canTransition = function ( upload ) { @@ -293,11 +287,11 @@ * @return {jQuery.Promise} */ uw.controller.Details.prototype.transitionAll = function () { - var + const deferred = $.Deferred(), details = this; - this.uploads.forEach( function ( upload ) { + this.uploads.forEach( ( upload ) => { if ( details.canTransition( upload ) ) { details.queue.addItem( upload ); } @@ -315,9 +309,9 @@ * @return {jQuery.Promise} */ uw.controller.Details.prototype.submit = function () { - var details = this; + const details = this; - this.uploads.forEach( function ( upload ) { + this.uploads.forEach( ( upload ) => { // Clear error state if ( upload.state === 'error' || upload.state === 'recoverable-error' ) { upload.state = details.stepName; @@ -331,7 +325,7 @@ this.ui.disableEdits(); this.removeCopyMetadataFeature(); - return this.transitionAll().then( function () { + return this.transitionAll().then( () => { details.showErrors(); if ( details.showNext() ) { diff --git a/resources/controller/uw.controller.Step.js b/resources/controller/uw.controller.Step.js index f981299..fcea7f8 100644 --- a/resources/controller/uw.controller.Step.js +++ b/resources/controller/uw.controller.Step.js @@ -26,7 +26,7 @@ * @param {Object} config UploadWizard config object. */ uw.controller.Step = function UWControllerStep( ui, api, config ) { - var step = this; + const step = this; OO.EventEmitter.call( this ); @@ -60,11 +60,11 @@ 'remove-upload': this.removeUpload }; - this.ui.on( 'next-step', function () { + this.ui.on( 'next-step', () => { step.moveNext(); } ); - this.ui.on( 'previous-step', function () { + this.ui.on( 'previous-step', () => { step.movePrevious(); } ); @@ -109,7 +109,7 @@ * @param {mw.UploadWizardUpload[]} uploads List of uploads being carried forward. */ uw.controller.Step.prototype.load = function ( uploads ) { - var step = this; + const step = this; this.emit( 'load' ); @@ -120,7 +120,7 @@ test: step.hasData.bind( this ) } ); - this.uploads.forEach( function ( upload ) { + this.uploads.forEach( ( upload ) => { upload.state = step.stepName; step.bindUploadHandlers( upload ); @@ -133,9 +133,9 @@ * Cleanup this step. */ uw.controller.Step.prototype.unload = function () { - var step = this; + const step = this; - this.uploads.forEach( function ( upload ) { + this.uploads.forEach( ( upload ) => { step.unbindUploadHandlers( upload ); } ); @@ -173,10 +173,10 @@ * @param {mw.UploadWizardUpload} upload */ uw.controller.Step.prototype.bindUploadHandlers = function ( upload ) { - var controller = this; + const controller = this; - Object.keys( this.uploadHandlers ).forEach( function ( event ) { - var callback = controller.uploadHandlers[ event ]; + Object.keys( this.uploadHandlers ).forEach( ( event ) => { + const callback = controller.uploadHandlers[ event ]; upload.on( event, callback, [ upload ], controller ); } ); }; @@ -187,10 +187,10 @@ * @param {mw.UploadWizardUpload} upload */ uw.controller.Step.prototype.unbindUploadHandlers = function ( upload ) { - var controller = this; + const controller = this; - Object.keys( this.uploadHandlers ).forEach( function ( event ) { - var callback = controller.uploadHandlers[ event ]; + Object.keys( this.uploadHandlers ).forEach( ( event ) => { + const callback = controller.uploadHandlers[ event ]; upload.off( event, callback, controller ); } ); }; @@ -220,7 +220,7 @@ * @return {boolean} Whether all of the uploads are in a successful state. */ uw.controller.Step.prototype.showNext = function () { - var okCount = this.getUploadStatesCount( this.finishState ), + let okCount = this.getUploadStatesCount( this.finishState ), $buttons; // abort if all uploads have been removed @@ -256,13 +256,13 @@ * @return {number} */ uw.controller.Step.prototype.getUploadStatesCount = function ( states ) { - var count = 0; + let count = 0; // normalize to array of states, even though input can be 1 string states = Array.isArray( states ) ? states : [ states ]; - this.uploads.forEach( function ( upload ) { - if ( states.indexOf( upload.state ) > -1 ) { + this.uploads.forEach( ( upload ) => { + if ( states.includes( upload.state ) ) { count++; } } ); @@ -302,7 +302,7 @@ */ uw.controller.Step.prototype.removeUpload = function ( upload ) { // remove the upload from the uploads array - var index = this.uploads.indexOf( upload ); + const index = this.uploads.indexOf( upload ); if ( index !== -1 ) { this.uploads.splice( index, 1 ); } @@ -317,7 +317,7 @@ * @param {mw.UploadWizardUpload[]} uploads */ uw.controller.Step.prototype.removeUploads = function ( uploads ) { - var i, + let i, // clone the array of uploads, just to be sure it's not a reference // to this.uploads, which will be modified (and we can't have that // while we're looping it) @@ -334,8 +334,8 @@ uw.controller.Step.prototype.removeErrorUploads = function () { // We must not remove items from an array while iterating over it with $.each (it causes the // next item to be skipped). Find and queue them first, then remove them. - var toRemove = []; - this.uploads.forEach( function ( upload ) { + const toRemove = []; + this.uploads.forEach( ( upload ) => { if ( upload.state === 'error' || upload.state === 'recoverable-error' ) { toRemove.push( upload ); } diff --git a/resources/controller/uw.controller.Thanks.js b/resources/controller/uw.controller.Thanks.js index 45a81ac..e660395 100644 --- a/resources/controller/uw.controller.Thanks.js +++ b/resources/controller/uw.controller.Thanks.js @@ -38,7 +38,7 @@ OO.inheritClass( uw.controller.Thanks, uw.controller.Step ); uw.controller.Thanks.prototype.load = function ( uploads ) { - var thanks = this; + const thanks = this; uw.controller.Step.prototype.load.call( this, uploads ); @@ -48,7 +48,7 @@ return; } - uploads.forEach( function ( upload ) { + uploads.forEach( ( upload ) => { thanks.ui.addUpload( upload ); } ); }; diff --git a/resources/controller/uw.controller.Tutorial.js b/resources/controller/uw.controller.Tutorial.js index 2aee890..5c26eb8 100644 --- a/resources/controller/uw.controller.Tutorial.js +++ b/resources/controller/uw.controller.Tutorial.js @@ -26,7 +26,7 @@ * @param {Object} config UploadWizard config object. */ uw.controller.Tutorial = function UWControllerTutorial( api, config ) { - var controller = this; + const controller = this; this.skipPreference = Boolean( mw.user.options.get( 'upwiz_skiptutorial' ) ); this.newSkipPreference = this.skipPreference; @@ -35,7 +35,7 @@ uw.controller.Step.call( this, new uw.ui.Tutorial() - .on( 'skip-tutorial-click', function ( skipped ) { + .on( 'skip-tutorial-click', ( skipped ) => { // indicate that the skip preference has changed, so we can // alter the preference when we move to another step controller.newSkipPreference = skipped; @@ -57,23 +57,23 @@ * @param {boolean} skip */ uw.controller.Tutorial.prototype.setSkipPreference = function ( skip ) { - var controller = this, + const controller = this, allowCloseWindow = mw.confirmCloseWindow(); this.api.postWithToken( 'options', { action: 'options', change: skip ? 'upwiz_skiptutorial=1' : 'upwiz_skiptutorial' - } ).done( function () { + } ).done( () => { allowCloseWindow.release(); controller.skipPreference = skip; - } ).fail( function ( code, err ) { + } ).fail( ( code, err ) => { mw.notify( err.textStatus ); } ); }; uw.controller.Tutorial.prototype.load = function ( uploads ) { // tutorial can be skipped via preference, or config (e.g. campaign config) - var shouldSkipTutorial = this.skipPreference || ( this.config.tutorial && this.config.tutorial.skip ); + const shouldSkipTutorial = this.skipPreference || ( this.config.tutorial && this.config.tutorial.skip ); uw.controller.Step.prototype.load.call( this, uploads ); diff --git a/resources/controller/uw.controller.Upload.js b/resources/controller/uw.controller.Upload.js index 1fb75e2..43d416e 100644 --- a/resources/controller/uw.controller.Upload.js +++ b/resources/controller/uw.controller.Upload.js @@ -26,7 +26,7 @@ * @param {Object} config UploadWizard config object. */ uw.controller.Upload = function UWControllerUpload( api, config ) { - var step = this; + const step = this; uw.controller.Step.call( this, @@ -47,8 +47,8 @@ } ); this.queue.on( 'complete', this.showNext.bind( this ) ); - this.ui.on( 'files-added', function ( files ) { - var totalFiles = files.length + step.uploads.length, + this.ui.on( 'files-added', ( files ) => { + const totalFiles = files.length + step.uploads.length, tooManyFiles = totalFiles > step.config.maxUploads; if ( tooManyFiles ) { @@ -65,7 +65,7 @@ * Updates the upload step data when a file is added or removed. */ uw.controller.Upload.prototype.updateFileCounts = function () { - var fewerThanMax, haveUploads, + let fewerThanMax, haveUploads, max = this.config.maxUploads; haveUploads = this.uploads.length > 0; @@ -76,7 +76,7 @@ }; uw.controller.Upload.prototype.load = function ( uploads ) { - var controller = this; + const controller = this; uw.controller.Step.prototype.load.call( this, uploads ); this.updateFileCounts(); @@ -96,7 +96,7 @@ * with new uploads, and still understand the existing files that * we've just reset the state for. */ - uploads.forEach( function ( upload ) { + uploads.forEach( ( upload ) => { upload.state = upload.fileKey === undefined ? 'error' : controller.finishState; } ); @@ -167,7 +167,7 @@ * @return {jQuery.Promise} */ uw.controller.Upload.prototype.transitionOne = function ( upload ) { - var promise = upload.start(); + const promise = upload.start(); this.maybeStartProgressBar(); return promise; }; @@ -191,9 +191,9 @@ }; uw.controller.Upload.prototype.retry = function () { - var controller = this; + const controller = this; - this.uploads.forEach( function ( upload ) { + this.uploads.forEach( ( upload ) => { if ( upload.state === 'error' ) { // reset any uploads in error state back to be shiny & new upload.state = 'new'; @@ -214,7 +214,7 @@ * @return {mw.UploadWizardUpload|boolean} The new upload, or false if it can't be added */ uw.controller.Upload.prototype.addFile = function ( file ) { - var upload; + let upload; if ( this.uploads.length >= this.config.maxUploads ) { return false; @@ -244,7 +244,7 @@ * @param {FileList} files */ uw.controller.Upload.prototype.addFiles = function ( files ) { - var + let uploadObj, i, file, @@ -302,7 +302,7 @@ * @return {boolean} Error in [code, info] format, or empty [] for no errors */ uw.controller.Upload.prototype.validateFile = function ( upload ) { - var extension, + let extension, i, actualMaxSize = mw.UploadWizard.config.maxMwUploadSize, @@ -322,7 +322,7 @@ // check if the filename is valid upload.setTitle( basename ); if ( !upload.title ) { - if ( basename.indexOf( '.' ) === -1 ) { + if ( !basename.includes( '.' ) ) { this.ui.showMissingExtensionError( filename ); return false; } else { @@ -340,7 +340,7 @@ if ( mw.UploadWizard.config.fileExtensions !== null && - mw.UploadWizard.config.fileExtensions.indexOf( extension.toLowerCase() ) === -1 + !mw.UploadWizard.config.fileExtensions.includes( extension.toLowerCase() ) ) { this.ui.showBadExtensionError( filename, extension ); return false; diff --git a/resources/deed/uw.deed.OwnWork.js b/resources/deed/uw.deed.OwnWork.js index 50881cb..f287b98 100644 --- a/resources/deed/uw.deed.OwnWork.js +++ b/resources/deed/uw.deed.OwnWork.js @@ -26,7 +26,7 @@ * @param {mw.Api} api API object - useful for doing previews */ uw.deed.OwnWork = function UWDeedOwnWork( config, uploads, api ) { - var deed = this, + let deed = this, prefAuthName = mw.user.options.get( 'upwiz_licensename' ); uw.deed.Abstract.call( this, 'ownwork', config ); @@ -49,7 +49,7 @@ value: prefAuthName, classes: [ 'mediauploader-sign' ] } ); - this.authorInput.on( 'change', function () { + this.authorInput.on( 'change', () => { deed.fakeAuthorInput.setValue( deed.authorInput.getValue() ); } ); @@ -80,7 +80,7 @@ }; uw.deed.OwnWork.prototype.setFormFields = function ( $selector ) { - var $customDiv, $formFields, $toggler, crossfaderWidget, defaultLicense, + let $customDiv, $formFields, $toggler, crossfaderWidget, defaultLicense, defaultLicenseURL, $defaultLicenseLink, $standardDiv, $crossfader, deed, languageCode, defaultLicConfig; @@ -141,7 +141,7 @@ this.authorInputField = new uw.FieldLayout( crossfaderWidget ); // Aggregate 'change' event - this.authorInput.on( 'change', OO.ui.debounce( function () { + this.authorInput.on( 'change', OO.ui.debounce( () => { crossfaderWidget.emit( 'change' ); }, 500 ) ); @@ -152,7 +152,7 @@ $toggler = $( '<p>' ).addClass( 'mwe-more-options' ).css( 'text-align', 'right' ) .append( $( '<a>' ) .msg( 'mediauploader-license-show-all' ) - .on( 'click', function () { + .on( 'click', () => { if ( $crossfader.data( 'crossfadeDisplay' ).get( 0 ) === $customDiv.get( 0 ) ) { deed.standardLicense(); } else { @@ -171,8 +171,8 @@ }; uw.deed.OwnWork.prototype.setDefaultLicenses = function () { - var defaultLicenses = {}; - this.getDefaultLicenses().forEach( function ( licName ) { + const defaultLicenses = {}; + this.getDefaultLicenses().forEach( ( licName ) => { defaultLicenses[ licName ] = true; } ); this.licenseInput.setValues( defaultLicenses ); @@ -189,10 +189,10 @@ * @inheritdoc */ uw.deed.OwnWork.prototype.getAuthorWikiText = function () { - var author = this.authorInput.getValue(), + let author = this.authorInput.getValue(), userPageTitle; - if ( author.indexOf( '[' ) >= 0 || author.indexOf( '{' ) >= 0 ) { + if ( author.includes( '[' ) || author.includes( '{' ) ) { return author; } @@ -236,7 +236,7 @@ }; uw.deed.OwnWork.prototype.swapNodes = function ( a, b ) { - var + const parentA = a.parentNode, parentB = b.parentNode, nextA = a.nextSibling, @@ -252,7 +252,7 @@ * @return {string[]} */ uw.deed.OwnWork.prototype.getDefaultLicenses = function () { - var license, ownWork = this.config.licensing.ownWork; + let license, ownWork = this.config.licensing.ownWork; if ( this.config.licensing.defaultType === 'ownWork' ) { license = ownWork.defaults; @@ -267,7 +267,7 @@ }; uw.deed.OwnWork.prototype.standardLicense = function () { - var deed = this, + const deed = this, $crossfader = this.$selector.find( '.mediauploader-crossfader' ), $standardDiv = this.$selector.find( '.mediauploader-standard' ), $toggler = this.$selector.find( '.mwe-more-options a' ); @@ -275,7 +275,7 @@ this.setDefaultLicenses(); $crossfader.morphCrossfade( $standardDiv ) - .promise().done( function () { + .promise().done( () => { deed.swapNodes( deed.authorInput.$element[ 0 ], deed.fakeAuthorInput.$element[ 0 ] ); } ); @@ -289,13 +289,13 @@ }; uw.deed.OwnWork.prototype.customLicense = function () { - var deed = this, + const deed = this, $crossfader = this.$selector.find( '.mediauploader-crossfader' ), $customDiv = this.$selector.find( '.mediauploader-custom' ), $toggler = this.$selector.find( '.mwe-more-options a' ); $crossfader.morphCrossfade( $customDiv ) - .promise().done( function () { + .promise().done( () => { deed.swapNodes( deed.authorInput.$element[ 0 ], deed.fakeAuthorInput.$element[ 0 ] ); } ); @@ -313,7 +313,7 @@ * @return {jQuery.Promise} */ uw.deed.OwnWork.prototype.getAuthorErrors = function ( input ) { - var + const errors = [], minLength = this.config.minAuthorLength, maxLength = this.config.maxAuthorLength, diff --git a/resources/deed/uw.deed.ThirdParty.js b/resources/deed/uw.deed.ThirdParty.js index 0d70235..e2eebf8 100644 --- a/resources/deed/uw.deed.ThirdParty.js +++ b/resources/deed/uw.deed.ThirdParty.js @@ -26,7 +26,7 @@ * @param {mw.Api} api API object - useful for doing previews */ uw.deed.ThirdParty = function UWDeedThirdParty( config, uploads, api ) { - var deed = this; + const deed = this; uw.deed.Abstract.call( this, 'thirdparty', config ); @@ -40,7 +40,7 @@ this.sourceInput.$input.attr( 'id', 'mwe-source-' + this.getInstanceCount() ); // See uw.DetailsWidget this.sourceInput.getErrors = function () { - var + const errors = [], minLength = deed.config.minSourceLength, maxLength = deed.config.maxSourceLength, @@ -74,7 +74,7 @@ this.authorInput.$input.attr( 'id', 'mwe-author-' + this.getInstanceCount() ); // See uw.DetailsWidget this.authorInput.getErrors = function () { - var + const errors = [], minLength = deed.config.minAuthorLength, maxLength = deed.config.maxAuthorLength, @@ -127,7 +127,7 @@ }; uw.deed.ThirdParty.prototype.setFormFields = function ( $selector ) { - var $formFields = $( '<div>' ).addClass( 'mediauploader-deed-form-internal' ); + const $formFields = $( '<div>' ).addClass( 'mediauploader-deed-form-internal' ); this.$form = $( '<form>' ); diff --git a/resources/details/uw.CategoriesDetailsWidget.js b/resources/details/uw.CategoriesDetailsWidget.js index 1d12511..90c456a 100644 --- a/resources/details/uw.CategoriesDetailsWidget.js +++ b/resources/details/uw.CategoriesDetailsWidget.js @@ -1,6 +1,6 @@ ( function ( uw ) { - var NS_CATEGORY = mw.config.get( 'wgNamespaceIds' ).category; + const NS_CATEGORY = mw.config.get( 'wgNamespaceIds' ).category; /** * A categories field in UploadWizard's "Details" step form. @@ -9,7 +9,7 @@ * @param {Object} config */ uw.CategoriesDetailsWidget = function UWCategoriesDetailsWidget( config ) { - var catDetails = this; + const catDetails = this; this.config = config; uw.CategoriesDetailsWidget.parent.call( this, this.config ); @@ -19,7 +19,7 @@ } ); this.categoriesWidget.createTagItemWidget = function ( data ) { - var widget = this.constructor.prototype.createTagItemWidget.call( this, data ); + const widget = this.constructor.prototype.createTagItemWidget.call( this, data ); if ( !widget ) { return null; } @@ -43,7 +43,7 @@ * @inheritdoc */ uw.CategoriesDetailsWidget.prototype.getErrors = function () { - var errors = []; + const errors = []; if ( this.config.required && this.categoriesWidget.getItems().length === 0 ) { errors.push( mw.message( 'mediauploader-error-blank' ) ); @@ -56,12 +56,10 @@ * @inheritdoc */ uw.CategoriesDetailsWidget.prototype.getWarnings = function () { - var warnings = []; + const warnings = []; this.getEmptyWarning( this.categoriesWidget.getItems().length === 0, warnings ); - if ( this.categoriesWidget.getItems().some( function ( item ) { - return item.missing; - } ) ) { + if ( this.categoriesWidget.getItems().some( ( item ) => item.missing ) ) { warnings.push( mw.message( 'mediauploader-categories-missing' ) ); } return $.Deferred().resolve( warnings ).promise(); @@ -71,7 +69,7 @@ * @inheritdoc */ uw.CategoriesDetailsWidget.prototype.getWikiText = function () { - var hiddenCats, missingCatsWikiText, categories, wikiText; + let hiddenCats, missingCatsWikiText, categories, wikiText; hiddenCats = []; if ( this.config.hiddenDefault ) { @@ -84,10 +82,10 @@ hiddenCats.push( mw.UploadWizard.config.trackingCategory.campaign ); } } - hiddenCats = hiddenCats.filter( function ( cat ) { + hiddenCats = hiddenCats.filter( ( cat ) => // Keep only valid titles - return !!mw.Title.makeTitle( NS_CATEGORY, cat ); - } ); + !!mw.Title.makeTitle( NS_CATEGORY, cat ) + ); missingCatsWikiText = null; if ( @@ -97,15 +95,11 @@ missingCatsWikiText = this.config.missingWikitext; } - categories = this.categoriesWidget.getItems().map( function ( item ) { - return item.data; - } ); + categories = this.categoriesWidget.getItems().map( ( item ) => item.data ); // add all categories wikiText = categories.concat( hiddenCats ) - .map( function ( cat ) { - return '[[' + mw.Title.makeTitle( NS_CATEGORY, cat ).getPrefixedText() + ']]'; - } ) + .map( ( cat ) => '[[' + mw.Title.makeTitle( NS_CATEGORY, cat ).getPrefixedText() + ']]' ) .join( '\n' ); // if so configured, and there are no user-visible categories, add warning @@ -121,9 +115,7 @@ * @return {Object} See #setSerialized */ uw.CategoriesDetailsWidget.prototype.getSerialized = function () { - return this.categoriesWidget.getItems().map( function ( item ) { - return item.data; - } ); + return this.categoriesWidget.getItems().map( ( item ) => item.data ); }; /** @@ -131,10 +123,10 @@ * @param {string[]} serialized List of categories */ uw.CategoriesDetailsWidget.prototype.setSerialized = function ( serialized ) { - var categories = ( serialized || [] ).filter( function ( cat ) { + const categories = ( serialized || [] ).filter( ( cat ) => // Keep only valid titles - return !!mw.Title.makeTitle( NS_CATEGORY, cat ); - } ); + !!mw.Title.makeTitle( NS_CATEGORY, cat ) + ); this.categoriesWidget.setValue( categories ); }; diff --git a/resources/details/uw.DateDetailsWidget.js b/resources/details/uw.DateDetailsWidget.js index 198e7e2..f2fabc5 100644 --- a/resources/details/uw.DateDetailsWidget.js +++ b/resources/details/uw.DateDetailsWidget.js @@ -31,10 +31,10 @@ disabled: this.config.disabled } ) .selectItemByData( 'calendar' ) - .on( 'choose', function ( selectedItem ) { + .on( 'choose', ( selectedItem ) => { this.setupDateInput( selectedItem.getData() ); this.dateInputWidget.focus(); - }.bind( this ) ); + } ); this.$element.addClass( 'mediauploader-dateDetailsWidget' ); this.$element.append( @@ -52,7 +52,7 @@ * @private */ uw.DateDetailsWidget.prototype.setupDateInput = function ( mode ) { - var + const oldDateInputWidget = this.dateInputWidget; if ( mode === undefined ) { @@ -75,13 +75,13 @@ } ); // If the user types '{{', assume that they are trying to input template wikitext and switch // to 'arbitrary' mode. This might help confused power-users (T110026#1567714). - this.dateInputWidget.textInput.on( 'change', function ( value ) { + this.dateInputWidget.textInput.on( 'change', ( value ) => { if ( value === '{{' ) { this.setupDateInput( 'arbitrary' ); this.dateInputWidget.setValue( '{{' ); this.dateInputWidget.moveCursorToEnd(); } - }.bind( this ) ); + } ); } if ( oldDateInputWidget ) { @@ -121,7 +121,7 @@ * @inheritdoc */ uw.DateDetailsWidget.prototype.getWarnings = function () { - var warnings = [], + const warnings = [], dateVal = Date.parse( this.dateInputWidget.getValue().trim() ), now = new Date(); @@ -143,7 +143,7 @@ * @inheritdoc */ uw.DateDetailsWidget.prototype.getErrors = function () { - var errors = []; + const errors = []; if ( this.config.required && this.dateInputWidget.getValue().trim() === '' ) { errors.push( mw.message( 'mediauploader-error-blank' ) ); diff --git a/resources/details/uw.DeedChooserDetailsWidget.js b/resources/details/uw.DeedChooserDetailsWidget.js index 94e4fd9..1560271 100644 --- a/resources/details/uw.DeedChooserDetailsWidget.js +++ b/resources/details/uw.DeedChooserDetailsWidget.js @@ -25,7 +25,7 @@ * @param {mw.UploadWizardUpload} upload */ uw.DeedChooserDetailsWidget.prototype.useCustomDeedChooser = function ( upload ) { - var $deedDiv; + let $deedDiv; // Defining own deedChooser for uploads coming from external service if ( upload.file.fromURL ) { @@ -74,7 +74,7 @@ * @inheritdoc */ uw.DeedChooserDetailsWidget.prototype.getErrors = function () { - var errors = []; + const errors = []; if ( this.deedChooser ) { if ( !this.deedChooser.deed ) { errors.push( mw.message( 'mediauploader-deeds-need-deed' ) ); diff --git a/resources/details/uw.DropdownWidget.js b/resources/details/uw.DropdownWidget.js index ab6ec70..17db404 100644 --- a/resources/details/uw.DropdownWidget.js +++ b/resources/details/uw.DropdownWidget.js @@ -17,9 +17,7 @@ this.wikitext = config.wikitext; this.input = new OO.ui.DropdownInputWidget( { classes: [ 'mwe-idfield', 'mediauploader-dropdownWidget-input' ], - options: Object.keys( config.options ).map( function ( key ) { - return { data: key, label: config.options[ key ] }; - } ) + options: Object.keys( config.options ).map( ( key ) => ( { data: key, label: config.options[ key ] } ) ) } ); // Aggregate 'change' event @@ -37,7 +35,7 @@ * @inheritdoc */ uw.DropdownWidget.prototype.getErrors = function () { - var errors = []; + const errors = []; if ( this.required && this.input.getValue().trim() === '' ) { errors.push( mw.message( 'mediauploader-error-blank' ) ); } @@ -48,7 +46,7 @@ * @inheritdoc */ uw.DropdownWidget.prototype.getWarnings = function () { - var warnings = []; + const warnings = []; this.getEmptyWarning( this.input.getValue().trim() === '', warnings ); return $.Deferred().resolve( warnings ).promise(); diff --git a/resources/details/uw.LanguageDropdownWidget.js b/resources/details/uw.LanguageDropdownWidget.js index 8865ae8..b9e163d 100644 --- a/resources/details/uw.LanguageDropdownWidget.js +++ b/resources/details/uw.LanguageDropdownWidget.js @@ -28,15 +28,13 @@ * @param {Object} languages */ uw.LanguageDropdownWidget.prototype.updateLanguages = function ( languages ) { - var menu = this.languageDropdown.getMenu(), + const menu = this.languageDropdown.getMenu(), currentMenuItems = menu.getItems(), currentValue = this.getValue(); // remove all items except the one currently selected (don't want // to trigger another select by removing it) - menu.removeItems( currentMenuItems.filter( function ( item ) { - return !item.isSelected(); - } ) ); + menu.removeItems( currentMenuItems.filter( ( item ) => !item.isSelected() ) ); // and add the rest of the languages back in there delete languages[ currentValue ]; @@ -72,12 +70,10 @@ * @return {OO.ui.MenuOptionWidget[]} */ uw.LanguageDropdownWidget.prototype.getLanguageMenuOptionWidgets = function ( languages ) { - return Object.keys( languages ).map( function ( code ) { - return new OO.ui.MenuOptionWidget( { - data: code, - label: languages[ code ] - } ); - } ); + return Object.keys( languages ).map( ( code ) => new OO.ui.MenuOptionWidget( { + data: code, + label: languages[ code ] + } ) ); }; }( mw.uploadWizard ) ); diff --git a/resources/details/uw.LocationDetailsWidget.js b/resources/details/uw.LocationDetailsWidget.js index 76a0c18..b89a46e 100644 --- a/resources/details/uw.LocationDetailsWidget.js +++ b/resources/details/uw.LocationDetailsWidget.js @@ -68,10 +68,10 @@ this.connect( this, { change: 'onChange' } ); this.mapButton.toggle( false ); - mw.loader.using( [ 'ext.kartographer.box', 'ext.kartographer.editing' ] ).done( function () { + mw.loader.using( [ 'ext.kartographer.box', 'ext.kartographer.editing' ] ).done( () => { // Kartographer is installed and we'll be able to show the map. Display the button. this.mapButton.toggle( true ); - }.bind( this ) ); + } ); }; OO.inheritClass( uw.LocationDetailsWidget, uw.DetailsWidget ); @@ -80,8 +80,8 @@ * @private */ uw.LocationDetailsWidget.prototype.onChange = function () { - var widget = this; - this.getErrors().done( function ( errors ) { + const widget = this; + this.getErrors().done( ( errors ) => { widget.mapButton.setDisabled( !( errors.length === 0 && widget.getWikiText() !== '' ) ); } ); }; @@ -90,7 +90,7 @@ * @private */ uw.LocationDetailsWidget.prototype.onMapButtonClick = function () { - var coords = this.getSerializedParsed(); + const coords = this.getSerializedParsed(); // Disable clipping because it doesn't play nicely with the map this.mapButton.getPopup().toggleClipping( false ); @@ -112,7 +112,7 @@ * @inheritdoc */ uw.LocationDetailsWidget.prototype.getErrors = function () { - var errors = [], + let errors = [], serialized = this.getSerialized(), parsed = this.getSerializedParsed(), field; @@ -132,13 +132,13 @@ // coordinates that were derived from the input are 0, without a 0 even // being present in the input if ( this.config.showField.latitude && serialized.latitude ) { - if ( isNaN( parsed.latitude ) || parsed.latitude > 90 || parsed.latitude < -90 || ( parsed.latitude === 0 && serialized.latitude.indexOf( '0' ) < 0 ) ) { + if ( isNaN( parsed.latitude ) || parsed.latitude > 90 || parsed.latitude < -90 || ( parsed.latitude === 0 && !serialized.latitude.includes( '0' ) ) ) { errors.push( mw.message( 'mediauploader-error-latitude' ) ); } } if ( this.config.showField.longitude && serialized.longitude ) { - if ( isNaN( parsed.longitude ) || parsed.longitude > 180 || parsed.longitude < -180 || ( parsed.longitude === 0 && serialized.longitude.indexOf( '0' ) < 0 ) ) { + if ( isNaN( parsed.longitude ) || parsed.longitude > 180 || parsed.longitude < -180 || ( parsed.longitude === 0 && !serialized.longitude.includes( '0' ) ) ) { errors.push( mw.message( 'mediauploader-error-longitude' ) ); } } @@ -160,7 +160,7 @@ * @inheritdoc */ uw.LocationDetailsWidget.prototype.getWikiText = function () { - var field, + let field, result = '', serialized = this.getSerializedParsed(); @@ -190,7 +190,7 @@ * @return {Object} See #setSerialized */ uw.LocationDetailsWidget.prototype.getSerialized = function () { - var field, + let field, result = {}; for ( field in this.config.showField ) { @@ -206,7 +206,7 @@ * @return {Object} Serialized, parsed values of the subfields (numbers) */ uw.LocationDetailsWidget.prototype.getSerializedParsed = function () { - var field, + let field, result = {}, serialized = this.getSerialized(); @@ -232,7 +232,7 @@ * @param {string} serialized.heading Heading value */ uw.LocationDetailsWidget.prototype.setSerialized = function ( serialized ) { - var field; + let field; for ( field in this.config.showField ) { if ( serialized[ field ] !== undefined ) { @@ -255,7 +255,7 @@ * @return {number} */ uw.LocationDetailsWidget.prototype.normalizeCoordinate = function ( coordinate ) { - var sign = coordinate.match( /[sw]/i ) ? -1 : 1, + let sign = coordinate.match( /[sw]/i ) ? -1 : 1, parts, value; // fix commonly used character alternatives diff --git a/resources/details/uw.MultipleLanguageInputWidget.js b/resources/details/uw.MultipleLanguageInputWidget.js index 7816114..e3dcf27 100644 --- a/resources/details/uw.MultipleLanguageInputWidget.js +++ b/resources/details/uw.MultipleLanguageInputWidget.js @@ -57,7 +57,7 @@ * @param {string} [text] */ uw.MultipleLanguageInputWidget.prototype.addLanguageInput = function ( config, text ) { - var allLanguages = this.config.languages, + let allLanguages = this.config.languages, unusedLanguages = this.getUnusedLanguages(), languages = {}, item; @@ -97,7 +97,7 @@ * with the updated language selections. */ uw.MultipleLanguageInputWidget.prototype.onChangeLanguages = function () { - var allLanguages = this.config.languages, + let allLanguages = this.config.languages, unusedLanguages = this.getUnusedLanguages(), items = this.getItems(), languages, @@ -123,11 +123,11 @@ * @return {Object} */ uw.MultipleLanguageInputWidget.prototype.getUsedLanguages = function () { - var allLanguages = this.config.languages, + const allLanguages = this.config.languages, items = this.getItems(); - return items.reduce( function ( obj, item ) { - var languageCode = item.getLanguage(); + return items.reduce( ( obj, item ) => { + const languageCode = item.getLanguage(); obj[ languageCode ] = allLanguages[ languageCode ]; return obj; }, {} ); @@ -140,11 +140,11 @@ * @return {Object} */ uw.MultipleLanguageInputWidget.prototype.getUnusedLanguages = function () { - var allLanguages = this.config.languages, + const allLanguages = this.config.languages, usedLanguageCodes = Object.keys( this.getUsedLanguages() ); - return Object.keys( allLanguages ).reduce( function ( remaining, language ) { - if ( usedLanguageCodes.indexOf( language ) < 0 ) { + return Object.keys( allLanguages ).reduce( ( remaining, language ) => { + if ( !usedLanguageCodes.includes( language ) ) { remaining[ language ] = allLanguages[ language ]; } return remaining; @@ -155,7 +155,7 @@ * Update the button label after adding or removing inputs. */ uw.MultipleLanguageInputWidget.prototype.recount = function () { - var text = this.getLabelText(), + const text = this.getLabelText(), unusedLanguages = this.getUnusedLanguages(); this.addButton.setLabel( text ); @@ -174,7 +174,7 @@ * @inheritdoc */ uw.MultipleLanguageInputWidget.prototype.getWarnings = function () { - var warnings = []; + const warnings = []; this.getEmptyWarning( this.getWikiText() === '', warnings ); return $.Deferred().resolve( warnings ).promise(); @@ -185,12 +185,10 @@ */ uw.MultipleLanguageInputWidget.prototype.getErrors = function () { // Gather errors from each item - var errorPromises = this.getItems().map( function ( item ) { - return item.getErrors(); - } ); + const errorPromises = this.getItems().map( ( item ) => item.getErrors() ); return $.when.apply( $, errorPromises ).then( function () { - var i, errors; + let i, errors; errors = []; // Fold all errors into a single one (they are displayed in the UI for each item, but we still // need to return an error here to prevent form submission). @@ -214,7 +212,7 @@ * @return {Object} Object where the properties are language codes & values are input */ uw.MultipleLanguageInputWidget.prototype.getValues = function () { - var values = {}, + let values = {}, widgets = this.getItems(), language, text, @@ -238,11 +236,7 @@ uw.MultipleLanguageInputWidget.prototype.getWikiText = function () { // Some code here and in mw.UploadWizardDetails relies on this function returning an empty // string when there are some inputs, but all are empty. - return this.getItems().map( function ( widget ) { - return widget.getWikiText(); - } ).filter( function ( wikiText ) { - return !!wikiText; - } ).join( '\n' ); + return this.getItems().map( ( widget ) => widget.getWikiText() ).filter( ( wikiText ) => !!wikiText ).join( '\n' ); }; /** @@ -250,9 +244,7 @@ * @return {Object} See #setSerialized */ uw.MultipleLanguageInputWidget.prototype.getSerialized = function () { - var inputs = this.getItems().map( function ( widget ) { - return widget.getSerialized(); - } ); + const inputs = this.getItems().map( ( widget ) => widget.getSerialized() ); return { inputs: inputs }; @@ -265,7 +257,7 @@ * see uw.SingleLanguageInputWidget#setSerialized */ uw.MultipleLanguageInputWidget.prototype.setSerialized = function ( serialized ) { - var config = this.config, + let config = this.config, i; if ( typeof serialized === 'string' ) { @@ -288,7 +280,7 @@ * @return {string} */ uw.MultipleLanguageInputWidget.prototype.getCaption = function () { - var items = this.getItems(); + const items = this.getItems(); if ( items.length > 0 ) { return items[ 0 ].getCaption(); diff --git a/resources/details/uw.SingleLanguageInputWidget.js b/resources/details/uw.SingleLanguageInputWidget.js index 53cf62b..7107d37 100644 --- a/resources/details/uw.SingleLanguageInputWidget.js +++ b/resources/details/uw.SingleLanguageInputWidget.js @@ -81,7 +81,7 @@ * @private */ uw.SingleLanguageInputWidget.prototype.onRemoveClick = function () { - var element = this.getElementGroup(); + const element = this.getElementGroup(); if ( element && typeof element.removeItems === 'function' ) { element.removeItems( [ this ] ); @@ -120,7 +120,7 @@ * @return {string} */ uw.SingleLanguageInputWidget.prototype.getDefaultLanguage = function () { - var defaultLanguage; + let defaultLanguage; if ( this.defaultLanguage !== undefined ) { return this.defaultLanguage; @@ -153,7 +153,7 @@ * @inheritdoc */ uw.SingleLanguageInputWidget.prototype.getWarnings = function () { - var warnings = []; + const warnings = []; this.getEmptyWarning( this.textInput.getValue().trim() === '', warnings ); return $.Deferred().resolve( warnings ).promise(); @@ -163,7 +163,7 @@ * @inheritdoc */ uw.SingleLanguageInputWidget.prototype.getErrors = function () { - var + const errors = [], text = this.textInput.getValue().trim(); @@ -221,7 +221,7 @@ * @inheritdoc */ uw.SingleLanguageInputWidget.prototype.getWikiText = function () { - var + let language = this.getLanguage(), text = this.getText(); diff --git a/resources/details/uw.TextWidget.js b/resources/details/uw.TextWidget.js index 634e005..4a7f1f3 100644 --- a/resources/details/uw.TextWidget.js +++ b/resources/details/uw.TextWidget.js @@ -49,7 +49,7 @@ * @inheritdoc */ uw.TextWidget.prototype.getWarnings = function () { - var warnings = []; + const warnings = []; this.getEmptyWarning( this.textInput.getValue().trim() === '', warnings ); return $.Deferred().resolve( warnings ).promise(); @@ -59,7 +59,7 @@ * @inheritdoc */ uw.TextWidget.prototype.getErrors = function () { - var + const errors = [], text = this.textInput.getValue().trim(); diff --git a/resources/details/uw.TitleDetailsWidget.js b/resources/details/uw.TitleDetailsWidget.js index cce0d4c..8e69895 100644 --- a/resources/details/uw.TitleDetailsWidget.js +++ b/resources/details/uw.TitleDetailsWidget.js @@ -1,6 +1,6 @@ ( function ( uw ) { - var NS_FILE = mw.config.get( 'wgNamespaceIds' ).file, + const NS_FILE = mw.config.get( 'wgNamespaceIds' ).file, byteLength = require( 'mediawiki.String' ).byteLength; /** @@ -44,7 +44,7 @@ * @return {mw.Title|null} */ uw.TitleDetailsWidget.static.makeTitleInFileNS = function ( filename ) { - var + let mwTitle = mw.Title.newFromText( filename, NS_FILE ), illegalFileChars = new RegExp( '[' + mw.config.get( 'wgIllegalFileChars', '' ) + ']' ); if ( mwTitle && mwTitle.getNamespaceId() !== NS_FILE ) { @@ -78,7 +78,7 @@ * @return {mw.Title|null} */ uw.TitleDetailsWidget.prototype.getTitle = function () { - var value, extRegex, cleaned, title; + let value, extRegex, cleaned, title; value = this.titleInput.getValue().trim(); if ( !value ) { return null; @@ -99,7 +99,7 @@ * @inheritdoc */ uw.TitleDetailsWidget.prototype.getWarnings = function () { - var warnings = []; + const warnings = []; this.getEmptyWarning( this.titleInput.getValue().trim() === '', warnings ); return $.Deferred().resolve( warnings ).promise(); @@ -109,7 +109,7 @@ * @return {jQuery.Promise} */ uw.TitleDetailsWidget.prototype.getErrors = function () { - var + const errors = [], value = this.titleInput.getValue().trim(), processDestinationCheck = this.processDestinationCheck, @@ -142,28 +142,24 @@ } return mw.DestinationChecker.checkTitle( title.getPrefixedText() ) - .then( function ( result ) { - var moreErrors = processDestinationCheck( result ); + .then( ( result ) => { + let moreErrors = processDestinationCheck( result ); if ( result.blacklist.unavailable ) { // We don't have a title blacklist, so just check for some likely undesirable patterns. moreErrors = moreErrors.concat( - mw.QuickTitleChecker.checkTitle( title.getNameText() ).map( function ( errorCode ) { + mw.QuickTitleChecker.checkTitle( title.getNameText() ).map( ( errorCode ) => // Messages that can be used here: // * mediauploader-error-title-invalid // * mediauploader-error-title-senselessimagename // * mediauploader-error-title-thumbnail // * mediauploader-error-title-extension - return mw.message( 'mediauploader-error-title-' + errorCode ); - } ) + mw.message( 'mediauploader-error-title-' + errorCode ) + ) ); } return moreErrors; } ) - .then( function ( moreErrors ) { - return [].concat( errors, moreErrors ); - }, function () { - return $.Deferred().resolve( errors ); - } ); + .then( ( moreErrors ) => [].concat( errors, moreErrors ), () => $.Deferred().resolve( errors ) ); }; /** @@ -175,7 +171,7 @@ * @return {mw.Message[]} Error messages */ uw.TitleDetailsWidget.prototype.processDestinationCheck = function ( result ) { - var messageParams, errors, titleString; + let messageParams, errors, titleString; if ( result.unique.isUnique && result.blacklist.notBlacklisted && !result.unique.isProtected ) { return []; diff --git a/resources/details/uw.UlsWidget.js b/resources/details/uw.UlsWidget.js index 826aef6..54813ae 100644 --- a/resources/details/uw.UlsWidget.js +++ b/resources/details/uw.UlsWidget.js @@ -9,7 +9,7 @@ * @cfg {Array} [classes] Classes to apply to the ULS container div */ uw.UlsWidget = function UWUlsWidget( config ) { - var i; + let i; uw.UlsWidget.parent.call( this, config ); @@ -49,7 +49,7 @@ OO.mixinClass( uw.UlsWidget, OO.EventEmitter ); uw.UlsWidget.prototype.initialiseUls = function ( languages ) { - var ulsWidget = this; + const ulsWidget = this; this.languages = languages; @@ -63,7 +63,7 @@ onVisible: function () { // Re-position the ULS *after* the widget has been rendered, so that we can be // sure it's in the right place - var offset = ulsWidget.$element.offset(); + const offset = ulsWidget.$element.offset(); if ( this.$menu.css( 'direction' ) === 'rtl' ) { offset.left = offset.left - parseInt( this.$menu.css( 'width' ) ) + ulsWidget.$element.width(); @@ -85,7 +85,7 @@ * @param {string} value */ uw.UlsWidget.prototype.setValue = function ( value ) { - var current = this.languageValue; + const current = this.languageValue; this.languageValue = value; this.$element.find( '.oo-ui-labelElement-label' ).text( this.languages[ value ] ); if ( current !== value ) { diff --git a/resources/ext.mediaUploader.campaignEditor.js b/resources/ext.mediaUploader.campaignEditor.js index 3ca08a3..49d3aaf 100644 --- a/resources/ext.mediaUploader.campaignEditor.js +++ b/resources/ext.mediaUploader.campaignEditor.js @@ -3,7 +3,7 @@ /** * Sets up indentation settings appropriate for YAML if CodeEditor is loaded. */ - mw.hook( 'codeEditor.configure' ).add( function ( session ) { + mw.hook( 'codeEditor.configure' ).add( ( session ) => { session.setOptions( { useSoftTabs: true, tabSize: 2 diff --git a/resources/handlers/mw.ApiUploadFormDataHandler.js b/resources/handlers/mw.ApiUploadFormDataHandler.js index d4ec9b1..e1a571f 100644 --- a/resources/handlers/mw.ApiUploadFormDataHandler.js +++ b/resources/handlers/mw.ApiUploadFormDataHandler.js @@ -18,7 +18,7 @@ this.transport = new mw.FormDataTransport( this.api, this.formData - ).on( 'update-stage', function ( stage ) { + ).on( 'update-stage', ( stage ) => { upload.ui.setStatus( 'mediauploader-' + stage ); } ); }; @@ -33,15 +33,15 @@ * @return {jQuery.Promise} */ mw.ApiUploadFormDataHandler.prototype.submit = function () { - var handler = this; + const handler = this; - return this.configureEditToken().then( function () { + return this.configureEditToken().then( () => { handler.beginTime = Date.now(); handler.upload.ui.setStatus( 'mediauploader-transport-started' ); handler.upload.ui.showTransportProgress(); return handler.transport.upload( handler.upload.file, handler.upload.title.getMainText() ) - .progress( function ( fraction ) { + .progress( ( fraction ) => { if ( handler.upload.state === 'aborted' ) { handler.abort(); return; @@ -61,9 +61,9 @@ * @return {jQuery.Promise} */ mw.ApiUploadFormDataHandler.prototype.configureEditToken = function () { - var handler = this; + const handler = this; - return this.api.getEditToken().then( function ( token ) { + return this.api.getEditToken().then( ( token ) => { handler.formData.token = token; } ); }; diff --git a/resources/handlers/mw.ApiUploadHandler.js b/resources/handlers/mw.ApiUploadHandler.js index e84b50a..93beff8 100644 --- a/resources/handlers/mw.ApiUploadHandler.js +++ b/resources/handlers/mw.ApiUploadHandler.js @@ -1,5 +1,5 @@ ( function () { - var NS_FILE = mw.config.get( 'wgNamespaceIds' ).file; + const NS_FILE = mw.config.get( 'wgNamespaceIds' ).file; /** * @param {mw.UploadWizardUpload} upload @@ -51,7 +51,7 @@ * @param {Object} result */ mw.ApiUploadHandler.prototype.setTransported = function ( result ) { - var code; + let code; if ( result.upload && result.upload.warnings ) { for ( code in result.upload.warnings ) { if ( !this.isIgnoredWarning( code ) ) { @@ -81,7 +81,7 @@ * @param {Object} result The API result in parsed JSON form */ mw.ApiUploadHandler.prototype.setTransportWarning = function ( code, result ) { - var param, duplicates, links; + let param, duplicates, links; switch ( code ) { case 'duplicate': @@ -124,7 +124,7 @@ * @param {Object} result The API result in parsed JSON form */ mw.ApiUploadHandler.prototype.setTransportError = function ( code, result ) { - var $extra; + let $extra; if ( code === 'badtoken' ) { this.api.badToken( 'csrf' ); @@ -142,10 +142,10 @@ title: mw.message( 'mediauploader-override-upload' ).text(), flags: 'progressive', framed: false - } ).on( 'click', function () { + } ).on( 'click', () => { // No need to ignore the error, AbuseFilter will only return it once this.start(); - }.bind( this ) ).$element; + } ).$element; } this.setError( code, result.errors[ 0 ].html, $extra ); @@ -161,18 +161,18 @@ * @return {jQuery.Promise} */ mw.ApiUploadHandler.prototype.processDuplicateError = function ( code, result, duplicates ) { - var files = this.getFileLinks( duplicates ), + const files = this.getFileLinks( duplicates ), unknownAmount = duplicates.length - Object.keys( files ).length; return this.getDuplicateSource( Object.keys( files ) ).then( - function ( data ) { + ( data ) => { this.setDuplicateError( code, result, data.local, data.foreign, unknownAmount ); - }.bind( this ), - function () { + }, + () => { // if anything goes wrong trying to figure out the source of // duplicates, just move on with local duplicate handling this.setDuplicateError( code, result, files, {}, unknownAmount ); - }.bind( this ) + } ); }; @@ -181,8 +181,8 @@ * @return {jQuery.Promise} */ mw.ApiUploadHandler.prototype.getDuplicateSource = function ( duplicates ) { - return this.getImageInfo( duplicates, 'url' ).then( function ( result ) { - var local = [], + return this.getImageInfo( duplicates, 'url' ).then( ( result ) => { + const local = [], foreign = [], normalized = []; @@ -192,13 +192,13 @@ // map of normalized titles, so we can find original title if ( result.query.normalized ) { - result.query.normalized.forEach( function ( data ) { + result.query.normalized.forEach( ( data ) => { normalized[ data.to ] = data.from; } ); } - Object.keys( result.query.pages ).forEach( function ( pageId ) { - var page = result.query.pages[ pageId ], + Object.keys( result.query.pages ).forEach( ( pageId ) => { + const page = result.query.pages[ pageId ], title = page.title in normalized ? normalized[ page.title ] : page.title; if ( page.imagerepository === 'local' ) { local[ title ] = page.imageinfo[ 0 ].descriptionurl; @@ -221,7 +221,7 @@ * @param {number} unknownAmount Amount of unknown filenames (e.g. revdeleted) */ mw.ApiUploadHandler.prototype.setDuplicateError = function ( code, result, localDuplicates, foreignDuplicates, unknownAmount ) { - var allDuplicates = Object.assign( {}, localDuplicates, foreignDuplicates ), + let allDuplicates = Object.assign( {}, localDuplicates, foreignDuplicates ), $extra = $( '<div>' ), $ul = $( '<ul>' ).appendTo( $extra ), $a, @@ -230,8 +230,8 @@ unknownAmount = unknownAmount || 0; - Object.keys( allDuplicates ).forEach( function ( filename ) { - var href = allDuplicates[ filename ]; + Object.keys( allDuplicates ).forEach( ( filename ) => { + const href = allDuplicates[ filename ]; $a = $( '<a>' ).text( filename ); $a.attr( { href: href, target: '_blank' } ); $ul.append( $( '<li>' ).append( $a ) ); @@ -254,11 +254,11 @@ title: mw.message( 'mediauploader-override-upload' ).text(), flags: 'progressive', framed: false - } ).on( 'click', function () { + } ).on( 'click', () => { // mark this warning as ignored & process the API result again this.ignoreWarning( 'duplicate' ); this.setTransported( result ); - }.bind( this ) ); + } ); override.$element.appendTo( $extra ); } @@ -274,17 +274,17 @@ * @param {string} duplicate Duplicate filename */ mw.ApiUploadHandler.prototype.setDuplicateArchiveError = function ( code, result, duplicate ) { - var filename = mw.Title.makeTitle( NS_FILE, duplicate ).getPrefixedText(), + const filename = mw.Title.makeTitle( NS_FILE, duplicate ).getPrefixedText(), uploadDuplicate = new OO.ui.ButtonWidget( { label: mw.message( 'mediauploader-override' ).text(), title: mw.message( 'mediauploader-override-upload' ).text(), flags: 'progressive', framed: false - } ).on( 'click', function () { + } ).on( 'click', () => { // mark this warning as ignored & process the API result again this.ignoreWarning( 'duplicate-archive' ); this.setTransported( result ); - }.bind( this ) ); + } ); this.setError( code, mw.message( 'file-deleted-duplicate', filename ).parse(), uploadDuplicate.$element ); }; @@ -310,10 +310,10 @@ * @return {Object} Map of [prefixed filename => url] */ mw.ApiUploadHandler.prototype.getFileLinks = function ( filenames ) { - var files = []; + const files = []; - filenames.forEach( function ( filename ) { - var title; + filenames.forEach( ( filename ) => { + let title; try { title = mw.Title.makeTitle( NS_FILE, filename ); files[ title.getPrefixedText() ] = title.getUrl( {} ); @@ -357,6 +357,6 @@ * @return {boolean} */ mw.ApiUploadHandler.prototype.isIgnoredWarning = function ( code ) { - return this.ignoreWarnings.indexOf( code ) > -1; + return this.ignoreWarnings.includes( code ); }; }( mw.uploadWizard ) ); diff --git a/resources/jquery.arrowSteps/jquery.arrowSteps.js b/resources/jquery.arrowSteps/jquery.arrowSteps.js index 81115f8..b098721 100644 --- a/resources/jquery.arrowSteps/jquery.arrowSteps.js +++ b/resources/jquery.arrowSteps/jquery.arrowSteps.js @@ -35,7 +35,7 @@ * @chainable */ $.fn.arrowSteps = function () { - var $steps, width, + let $steps, width, $el = this; $el.addClass( 'arrowSteps' ); @@ -67,10 +67,10 @@ * @param {string} selector */ $.fn.arrowStepsHighlight = function ( selector ) { - var $previous, + let $previous, $steps = this.data( 'arrowSteps' ); $steps.each( function () { - var $step = $( this ); + const $step = $( this ); if ( $step.is( selector ) ) { if ( $previous ) { $previous.addClass( 'tail' ); diff --git a/resources/jquery/jquery.morphCrossfade.js b/resources/jquery/jquery.morphCrossfade.js index bc159ca..d6f79f3 100644 --- a/resources/jquery/jquery.morphCrossfade.js +++ b/resources/jquery/jquery.morphCrossfade.js @@ -47,7 +47,7 @@ * @chainable */ $.fn.morphCrossfader = function () { - var $this = $( this ); + const $this = $( this ); // the elements that are immediate children are the crossfadables // they must all be "on top" of each other, so position them relative $this.css( { @@ -64,7 +64,7 @@ // should achieve the same result as crossfade( this.children().first() ) but without // animation etc. $this.each( function () { - var $container = $( this ); + const $container = $( this ); $container.morphCrossfade( $container.children().first(), 0 ); } ); @@ -80,14 +80,14 @@ * @chainable */ $.fn.morphCrossfade = function ( newPanelSelector, speed ) { - var $this = $( this ); + const $this = $( this ); if ( typeof speed === 'undefined' ) { speed = 400; } $this.each( function () { - var $container = $( this ), + const $container = $( this ), $oldPanel = $( $container.data( 'crossfadeDisplay' ) ), $newPanel = ( typeof newPanelSelector === 'string' ) ? $container.find( newPanelSelector ) : $( newPanelSelector ); @@ -102,7 +102,7 @@ $oldPanel.css( { position: 'absolute' } ); // fade WITHOUT hiding when opacity = 0 // eslint-disable-next-line no-jquery/no-animate - $oldPanel.stop().animate( { opacity: 0 }, speed, 'linear', function () { + $oldPanel.stop().animate( { opacity: 0 }, speed, 'linear', () => { $oldPanel.css( { visibility: 'hidden' } ); } ); } @@ -110,7 +110,7 @@ $newPanel.css( { visibility: 'visible' } ); // eslint-disable-next-line no-jquery/no-animate - $container.stop().animate( { height: $newPanel.outerHeight() }, speed, 'linear', function () { + $container.stop().animate( { height: $newPanel.outerHeight() }, speed, 'linear', () => { // we place it back into the flow, in case its size changes. $newPanel.css( { position: 'relative' } ); // and allow the container to grow with it. diff --git a/resources/mw.DestinationChecker.js b/resources/mw.DestinationChecker.js index 6768d22..bcc18f6 100644 --- a/resources/mw.DestinationChecker.js +++ b/resources/mw.DestinationChecker.js @@ -22,13 +22,11 @@ return $.when( this.checkUnique( title ), this.checkBlacklist( title ) - ).then( function ( unique, blacklist ) { - return { - unique: unique, - blacklist: blacklist, - title: title - }; - } ); + ).then( ( unique, blacklist ) => ( { + unique: unique, + blacklist: blacklist, + title: title + } ) ); }, /** @@ -43,7 +41,7 @@ * {string} [return.done.blacklistLine] See mw.Api#isBlacklisted */ checkBlacklist: function ( title ) { - var checker = this; + const checker = this; /** * Process result of a TitleBlacklist API call. @@ -53,7 +51,7 @@ * @return {Object} */ function blacklistResultProcessor( blacklistResult ) { - var result; + let result; if ( blacklistResult === false ) { result = { notBlacklisted: true }; @@ -74,12 +72,10 @@ return $.Deferred().resolve( this.cachedBlacklist[ title ] ); } - return mw.loader.using( 'mediawiki.api.titleblacklist' ).then( function () { - return checker.api.isBlacklisted( title ).then( blacklistResultProcessor ); - }, function () { + return mw.loader.using( 'mediawiki.api.titleblacklist' ).then( () => checker.api.isBlacklisted( title ).then( blacklistResultProcessor ), () => // it's not blacklisted, because the API isn't even available - return $.Deferred().resolve( { notBlacklisted: true, unavailable: true } ); - } ); + $.Deferred().resolve( { notBlacklisted: true, unavailable: true } ) + ); }, /** @@ -95,7 +91,7 @@ * {string} [return.done.href] URL to file description page */ checkUnique: function ( title ) { - var checker = this, + let checker = this, NS_FILE = mw.config.get( 'wgNamespaceIds' ).file, titleObj, prefix, ext; @@ -112,7 +108,7 @@ * @return {Object} */ function checkUniqueProcessor( data ) { - var result, protection, pageId, ntitle, ntitleObj, img; + let result, protection, pageId, ntitle, ntitleObj, img; result = { isUnique: true }; @@ -124,8 +120,8 @@ if ( data.query.pages[ -1 ] && !data.query.pages[ -1 ].imageinfo ) { protection = data.query.pages[ -1 ].protection; if ( protection && protection.length > 0 ) { - protection.forEach( function ( val ) { - if ( mw.config.get( 'wgUserGroups' ).indexOf( val.level ) === -1 ) { + protection.forEach( ( val ) => { + if ( !mw.config.get( 'wgUserGroups' ).includes( val.level ) ) { result = { isUnique: true, isProtected: true @@ -211,8 +207,8 @@ iiprop: 'url|mime|size', iiurlwidth: 150 } ).then( checkUniqueProcessor ) - ).then( function ( exact, fuzzy ) { - var result; + ).then( ( exact, fuzzy ) => { + let result; if ( !exact.isUnique || exact.isProtected ) { result = exact; } else if ( !fuzzy.isUnique || fuzzy.isProtected ) { diff --git a/resources/mw.Escaper.js b/resources/mw.Escaper.js index d34b1d4..b5cfb7e 100644 --- a/resources/mw.Escaper.js +++ b/resources/mw.Escaper.js @@ -18,14 +18,12 @@ * @return {string} */ escapePipes: function ( wikitext ) { - var extractedTemplates, extractedLinks; + let extractedTemplates, extractedLinks; // Pipes (`|`) must be escaped because we'll be inserting this // content into a templates & pipes would mess up the syntax. // First, urlencode pipes inside links: - wikitext = wikitext.replace( /\bhttps?:\/\/[^\s]+/g, function ( match ) { - return match.replace( /\|/g, '%7C' ); - } ); + wikitext = wikitext.replace( /\bhttps?:\/\/[^\s]+/g, ( match ) => match.replace( /\|/g, '%7C' ) ); // Second, pipes can be valid inside other templates or links in // wikitext, so we'll first extract those from the content, then @@ -51,7 +49,7 @@ * @return {Array} [{string} wikitext, {Object} replacements] */ extractTemplates: function ( wikitext ) { - var extracts = {}, + let extracts = {}, previousExtracts = {}, extracted = wikitext, // the regex explained: @@ -62,7 +60,7 @@ // sequence, generated by an earlier run of this regex regex = /\{\{([^{]|\{(?!\{)|\{\{[0-9]+\}\})*?\}\}/g, callback = function ( match ) { - var replacement = '{{' + Object.keys( extracts ).length + '}}'; + const replacement = '{{' + Object.keys( extracts ).length + '}}'; // safeguard for not replacing already-replaced matches // this makes sure that when real content contains something @@ -96,10 +94,10 @@ * @return {Array} [{string} wikitext, {Object} replacements] */ extractLinks: function ( wikitext ) { - var extracts = {}; + const extracts = {}; - wikitext = wikitext.replace( /\[\[.*?\]\]/g, function ( match ) { - var replacement = '[[' + Object.keys( extracts ).length + ']]'; + wikitext = wikitext.replace( /\[\[.*?\]\]/g, ( match ) => { + const replacement = '[[' + Object.keys( extracts ).length + ']]'; extracts[ replacement ] = match; return replacement; } ); @@ -117,10 +115,10 @@ restoreExtracts: function ( wikitext, replacements ) { // turn search keys into a regular expression, allowing us to match // all of them at once - var searchValues = Object.keys( replacements ).map( mw.util.escapeRegExp ), + const searchValues = Object.keys( replacements ).map( mw.util.escapeRegExp ), searchRegex = new RegExp( '(' + searchValues.join( '|' ) + ')', 'g' ), callback = function ( match ) { - var replacement = replacements[ match ]; + const replacement = replacements[ match ]; // we matched something that has no replacement, must be valid // user input that just happens to look like on of the diff --git a/resources/mw.GroupProgressBar.js b/resources/mw.GroupProgressBar.js index 10c2bbe..d9c5fe3 100644 --- a/resources/mw.GroupProgressBar.js +++ b/resources/mw.GroupProgressBar.js @@ -56,30 +56,30 @@ * loop around the uploads, summing certain properties for a weighted total fraction */ start: function () { - var bar = this, + let bar = this, shown = false; this.setBeginTime(); function displayer() { - var totalWeight = 0.0, + let totalWeight = 0.0, fraction = 0.0, successStateCount = 0, errorStateCount = 0, hasData = false; - bar.uploads.forEach( function ( upload ) { + bar.uploads.forEach( ( upload ) => { totalWeight += upload[ bar.weightProperty ]; } ); - bar.uploads.forEach( function ( upload ) { + bar.uploads.forEach( ( upload ) => { if ( upload.state === 'aborted' ) { return; } - if ( bar.successStates.indexOf( upload.state ) !== -1 ) { + if ( bar.successStates.includes( upload.state ) ) { successStateCount++; } - if ( bar.errorStates.indexOf( upload.state ) !== -1 ) { + if ( bar.errorStates.includes( upload.state ) ) { errorStateCount++; } if ( upload[ bar.progressProperty ] !== undefined ) { @@ -106,7 +106,7 @@ } else { bar.showProgress( 1.0 ); bar.finished = true; - setTimeout( function () { + setTimeout( () => { bar.hideBar(); }, 500 ); } @@ -142,7 +142,7 @@ * @param {number} fraction The amount of whatever it is that's done whatever it's done */ showProgress: function ( fraction ) { - var t, timeString, + let t, timeString, remainingTime = this.getRemainingTime( fraction ); this.progressBarWidget.setProgress( parseInt( fraction * 100, 10 ) ); @@ -168,7 +168,7 @@ * @return {number} Estimated time remaining (in milliseconds) */ getRemainingTime: function ( fraction ) { - var elapsedTime, rate; + let elapsedTime, rate; if ( this.beginTime ) { elapsedTime = Date.now() - this.beginTime; if ( fraction > 0.0 && elapsedTime > 0 ) { // or some other minimums for good data @@ -185,7 +185,7 @@ * @param {number} completed The number of items that have done whatever has been done e.g. in "uploaded 2 of 5", this is the 2 */ showCount: function ( completed ) { - var total = this.uploads.length - this.countRemoved(); + const total = this.uploads.length - this.countRemoved(); this.$selector .find( '.mediauploader-count' ) // Hide if there are no uploads, show otherwise @@ -194,8 +194,8 @@ }, countRemoved: function () { - var count = 0; - this.uploads.forEach( function ( upload ) { + let count = 0; + this.uploads.forEach( ( upload ) => { if ( !upload || upload.state === 'aborted' ) { count += 1; } diff --git a/resources/mw.QuickTitleChecker.js b/resources/mw.QuickTitleChecker.js index 589cf37..d6723d5 100644 --- a/resources/mw.QuickTitleChecker.js +++ b/resources/mw.QuickTitleChecker.js @@ -70,10 +70,10 @@ * Possible error codes are 'invalid', 'senselessimagename', 'thumbnail', 'extension'. */ mw.QuickTitleChecker.checkTitle = function ( title ) { - var errors = []; - Object.keys( mw.QuickTitleChecker.regexSets ).forEach( function ( setName ) { - var regexes = mw.QuickTitleChecker.regexSets[ setName ]; - regexes.forEach( function ( regex ) { + const errors = []; + Object.keys( mw.QuickTitleChecker.regexSets ).forEach( ( setName ) => { + const regexes = mw.QuickTitleChecker.regexSets[ setName ]; + regexes.forEach( ( regex ) => { if ( title.match( regex ) ) { errors.push( setName ); } diff --git a/resources/mw.UploadWizard.js b/resources/mw.UploadWizard.js index a96c38e..5f3a29e 100644 --- a/resources/mw.UploadWizard.js +++ b/resources/mw.UploadWizard.js @@ -7,7 +7,7 @@ ( function ( uw ) { mw.UploadWizard = function ( config ) { - var maxSimPref; + let maxSimPref; this.api = this.getApi( { ajax: { timeout: 0 } } ); @@ -49,7 +49,7 @@ createInterface: function ( selector ) { this.ui = new uw.ui.Wizard( selector ); - this.initialiseSteps().then( function ( steps ) { + this.initialiseSteps().then( ( steps ) => { // "select" the first step - highlight, make it visible, hide all others steps[ 0 ].load( [] ); } ); @@ -61,7 +61,7 @@ * @return {jQuery.Promise} */ initialiseSteps: function () { - var self = this, + let self = this, steps = [], i, uploadStep; @@ -98,7 +98,7 @@ steps[ steps.length - 1 ].setNextStep( uploadStep ); return $.Deferred().resolve( steps ).promise() - .always( function ( stepsInner ) { + .always( ( stepsInner ) => { self.steps = stepsInner; self.ui.initialiseSteps( stepsInner ); } ); @@ -119,10 +119,10 @@ * @return {mw.Api} */ getApi: function ( options ) { - var api = new mw.Api( options ); + const api = new mw.Api( options ); api.ajax = function ( parameters, ajaxOptions ) { - var original, override; + let original, override; Object.assign( parameters, { errorformat: 'html', @@ -137,8 +137,8 @@ // output is always, reliably, in the same format override = original.then( null, // done handler - doesn't need overriding - function ( code, result ) { // fail handler - var response = { errors: [ { + ( code, result ) => { // fail handler + let response = { errors: [ { code: code, html: result.textStatus || mw.message( 'api-clientside-error-invalidresponse' ).parse() } ] }; @@ -183,10 +183,10 @@ * @return {mw.deed.Abstract[]} */ mw.UploadWizard.getLicensingDeeds = function ( uploads, config ) { - var deed, api, + let deed, api, deeds = {}, - doOwnWork = config.licensing.showTypes.indexOf( 'ownWork' ) > -1, - doThirdParty = config.licensing.showTypes.indexOf( 'thirdParty' ) > -1; + doOwnWork = config.licensing.showTypes.includes( 'ownWork' ), + doThirdParty = config.licensing.showTypes.includes( 'thirdParty' ); if ( !config.licensing.enabled ) { return { diff --git a/resources/mw.UploadWizardDeedChooser.js b/resources/mw.UploadWizardDeedChooser.js index 3cf37e3..88a7429 100644 --- a/resources/mw.UploadWizardDeedChooser.js +++ b/resources/mw.UploadWizardDeedChooser.js @@ -9,7 +9,7 @@ * @param {mw.UploadWizardUpload[]} uploads Uploads that this applies to (this is just to make deleting and plurals work) */ mw.UploadWizardDeedChooser = function ( config, selector, deeds, uploads ) { - var chooser = this; + const chooser = this; this.$selector = $( selector ); this.uploads = uploads; this.deeds = deeds; @@ -20,8 +20,8 @@ this.onLayoutReady = function () {}; - Object.keys( this.deeds ).forEach( function ( name ) { - var deed = chooser.deeds[ name ], + Object.keys( this.deeds ).forEach( ( name ) => { + const deed = chooser.deeds[ name ], radio = new OO.ui.RadioSelectWidget( { items: [ new OO.ui.RadioOptionWidget( { // eslint-disable-next-line mediawiki/msg-doc @@ -53,7 +53,7 @@ if ( config.licensing.defaultType.toLowerCase() === deed.name ) { chooser.onLayoutReady = chooser.selectDeed.bind( chooser, deed ); } - radio.on( 'choose', function () { + radio.on( 'choose', () => { chooser.selectDeed( deed ); } ); } @@ -84,7 +84,7 @@ uploads: [], selectDeed: function ( deed ) { - var $deedInterface = this.$selector.find( '.mediauploader-deed.mediauploader-deed-' + deed.name ); + const $deedInterface = this.$selector.find( '.mediauploader-deed.mediauploader-deed-' + deed.name ); this.choose( deed ); this.selectDeedInterface( $deedInterface ); @@ -92,11 +92,11 @@ }, choose: function ( deed ) { - var chooser = this; + const chooser = this; this.deed = deed; - this.uploads.forEach( function ( upload ) { + this.uploads.forEach( ( upload ) => { upload.deedChooser = chooser; } ); @@ -112,7 +112,7 @@ deselectDeedInterface: function ( $deedSelector ) { $deedSelector.removeClass( 'selected' ); $deedSelector.find( '.mediauploader-deed-form' ).each( function () { - var $form = $( this ); + const $form = $( this ); // Prevent validation of deselected deeds by disabling all form inputs // TODO: Use a tag selector // eslint-disable-next-line no-jquery/no-sizzle @@ -134,13 +134,13 @@ * @param {jQuery} $deedSelector */ selectDeedInterface: function ( $deedSelector ) { - var $otherDeeds = $deedSelector.siblings().filter( '.mediauploader-deed' ); + const $otherDeeds = $deedSelector.siblings().filter( '.mediauploader-deed' ); this.deselectDeedInterface( $otherDeeds ); // FIXME: Use CSS transition // eslint-disable-next-line no-jquery/no-fade $deedSelector.addClass( 'selected' ).fadeTo( 'fast', 1.0 ); $deedSelector.find( '.mediauploader-deed-form' ).each( function () { - var $form = $( this ); + const $form = $( this ); // (Re-)enable all form inputs // TODO: Use a tag selector // eslint-disable-next-line no-jquery/no-sizzle @@ -173,7 +173,7 @@ * @param {Object} serialized */ setSerialized: function ( serialized ) { - var deed; + let deed; if ( serialized.name && serialized.name in this.deeds ) { deed = this.deeds[ serialized.name ]; diff --git a/resources/mw.UploadWizardDetails.js b/resources/mw.UploadWizardDetails.js index c47e21e..30a63a6 100644 --- a/resources/mw.UploadWizardDetails.js +++ b/resources/mw.UploadWizardDetails.js @@ -1,6 +1,6 @@ ( function ( uw ) { - var NS_FILE = mw.config.get( 'wgNamespaceIds' ).file; + const NS_FILE = mw.config.get( 'wgNamespaceIds' ).file; /** * Object that represents the Details (step 2) portion of the UploadWizard @@ -42,7 +42,7 @@ * Build the interface and attach all elements - do this on demand. */ buildInterface: function () { - var $moreDetailsWrapperDiv, $moreDetailsDiv, + let $moreDetailsWrapperDiv, $moreDetailsDiv, fKey, fSpec, fieldWidget, fieldWrapper, fConfigBase, details = this, config = mw.UploadWizard.config; @@ -135,7 +135,7 @@ this.fieldMap[ fKey ] = fieldWidget; } - this.fieldList.sort( function ( a, b ) { + this.fieldList.sort( ( a, b ) => { if ( a.order < b.order ) { return -1; } @@ -175,7 +175,7 @@ $moreDetailsDiv.append( fieldWrapper.$element ); // If something changes the input "hidden" in the collapsed section, // expand it. - fieldWidget.on( 'change', function () { + fieldWidget.on( 'change', () => { $moreDetailsWrapperDiv.data( 'mw-collapsible' ).expand(); } ); } else { @@ -194,7 +194,7 @@ ) .makeCollapsible( { collapsed: true } ); - this.$form.on( 'submit', function ( e ) { + this.$form.on( 'submit', ( e ) => { // Prevent actual form submission e.preventDefault(); } ); @@ -211,10 +211,10 @@ flags: 'destructive', icon: 'trash', framed: false - } ).on( 'click', function () { + } ).on( 'click', () => { OO.ui.confirm( mw.message( 'mediauploader-license-confirm-remove' ).text(), { title: mw.message( 'mediauploader-license-confirm-remove-title' ).text() - } ).done( function ( confirmed ) { + } ).done( ( confirmed ) => { if ( confirmed ) { details.upload.emit( 'remove-upload' ); } @@ -272,7 +272,7 @@ * Will only append once. */ attach: function () { - var $window = $( window ), + const $window = $( window ), details = this; function maybeBuild() { @@ -301,7 +301,7 @@ * @return {mw.Title|null} */ getTitle: function () { - var titleField = mw.UploadWizard.config.content.titleField; + const titleField = mw.UploadWizard.config.content.titleField; // title will not be set until we've actually submitted the file if ( this.title === undefined ) { @@ -320,7 +320,7 @@ * @chainable */ setDuplicateTitleError: function () { - var titleField = mw.UploadWizard.config.content.titleField; + const titleField = mw.UploadWizard.config.content.titleField; // TODO This should give immediate response, not only when submitting the form this.fieldWrapperMap[ titleField ].setErrors( [ mw.message( 'mediauploader-error-title-duplicate' ) ] @@ -357,9 +357,7 @@ * empty arrays. */ getErrors: function () { - return $.when.apply( $, this.getAllFields().map( function ( fieldLayout ) { - return fieldLayout.fieldWidget.getErrors(); - } ) ); + return $.when.apply( $, this.getAllFields().map( ( fieldLayout ) => fieldLayout.fieldWidget.getErrors() ) ); }, /** @@ -368,9 +366,7 @@ * @return {jQuery.Promise} Same as #getErrors */ getWarnings: function () { - return $.when.apply( $, this.getAllFields().map( function ( fieldLayout ) { - return fieldLayout.fieldWidget.getWarnings(); - } ) ); + return $.when.apply( $, this.getAllFields().map( ( fieldLayout ) => fieldLayout.fieldWidget.getWarnings() ) ); }, /** @@ -380,12 +376,12 @@ * @return {jQuery.Promise} Combined promise of all fields' validation results. */ checkValidity: function ( thorough ) { - var fields = this.getAllFields(); + const fields = this.getAllFields(); - return $.when.apply( $, fields.map( function ( fieldLayout ) { + return $.when.apply( $, fields.map( ( fieldLayout ) => // Update any error/warning messages - return fieldLayout.checkValidity( thorough ); - } ) ); + fieldLayout.checkValidity( thorough ) + ) ); }, /** @@ -394,7 +390,7 @@ * @return {string} */ getThumbnailCaption: function () { - var captionField = mw.UploadWizard.config.content.captionField; + const captionField = mw.UploadWizard.config.content.captionField; // The caption field should be one of: // TextWidget, SingleLanguageInputWidget, MultipleLanguageInputWidget @@ -409,7 +405,7 @@ * @param {uw.DetailsWidget} widget */ prefillField: function ( fSpec, widget ) { - var dynPrefilled = false; + let dynPrefilled = false; // Try dynamic prefilling, if requested and available for this type if ( fSpec.autoFill ) { @@ -447,7 +443,7 @@ * @return {boolean} */ prefillDate: function ( widget ) { - var dateObj, metadata, dateStr, saneTime, + let dateObj, metadata, dateStr, saneTime, dateMode = 'calendar', yyyyMmDdRegex = /^(\d\d\d\d)[:/-](\d\d)[:/-](\d\d)\D.*/, timeRegex = /\D(\d\d):(\d\d):(\d\d)/; @@ -458,7 +454,7 @@ } function getSaneTime( date ) { - var str = ''; + let str = ''; str += pad( date.getHours() ) + ':'; str += pad( date.getMinutes() ) + ':'; @@ -469,8 +465,8 @@ if ( this.upload.imageinfo.metadata ) { metadata = this.upload.imageinfo.metadata; - [ 'datetimeoriginal', 'datetimedigitized', 'datetime', 'date' ].some( function ( propName ) { - var matches, timeMatches, + [ 'datetimeoriginal', 'datetimedigitized', 'datetime', 'date' ].some( ( propName ) => { + let matches, timeMatches, dateInfo = metadata[ propName ]; if ( dateInfo ) { matches = dateInfo.trim().match( yyyyMmDdRegex ); @@ -551,7 +547,7 @@ * @return {boolean} */ prefillDescription: function ( type, widget ) { - var m, descText; + let m, descText; if ( widget.getWikiText() === '' && @@ -601,7 +597,7 @@ * @return {boolean} */ prefillLocation: function ( widget ) { - var dir, + let dir, m = this.upload.imageinfo.metadata, modified = false, values = {}; @@ -652,7 +648,7 @@ * @return {Object} */ getLanguageOptions: function () { - var languages, code; + let languages, code; languages = {}; for ( code in mw.UploadWizard.config.languages ) { @@ -673,7 +669,7 @@ * @return {Object.<string,Object>} */ getSerialized: function () { - var fieldWidget, serialized = {}; + let fieldWidget, serialized = {}; if ( !this.interfaceBuilt ) { // We don't have the interface yet, but it'll get filled out as @@ -734,7 +730,7 @@ * @return {string} wikitext representing all details */ getWikiText: function () { - var wikiText = mw.UploadWizard.config.content.wikitext, + let wikiText = mw.UploadWizard.config.content.wikitext, substitutions = {}, substList = [], deed = this.upload.deedChooser.deed, fieldWidget, serialized, valueType, re, escapedKey, replaceValue; @@ -750,7 +746,7 @@ } function addSubstitution( key, value ) { - var v = value; + let v = value; if ( key in substitutions ) { return; } @@ -781,7 +777,7 @@ return; } // Also add "subfields" based on the serialized values. Just in case. - Object.keys( serialized ).forEach( function ( key ) { + Object.keys( serialized ).forEach( ( key ) => { replaceValue = serialized[ key ]; valueType = typeof replaceValue; if ( valueType === 'string' || valueType === 'number' || valueType === 'boolean' ) { @@ -791,11 +787,11 @@ }, this ); // Do the substitutions - substList.forEach( function ( substKey ) { + substList.forEach( ( substKey ) => { replaceValue = substitutions[ substKey ].trim(); escapedKey = substKey.replace( /[.*+?^${}()|[\]\\]/g, '\\$&' ); re = new RegExp( '\\{\\{\\{ *' + escapedKey + ' *(\\|(.*?))?\\}\\}\\}', 'giu' ); - wikiText = wikiText.replace( re, function ( match, _, defaultValue ) { + wikiText = wikiText.replace( re, ( match, _, defaultValue ) => { if ( !replaceValue ) { return defaultValue || ''; } else { @@ -814,7 +810,7 @@ * @return {jQuery.Promise} */ submit: function () { - var details = this, + let details = this, wikitext, promise; this.$containerDiv.find( 'form' ).trigger( 'submit' ); @@ -827,7 +823,7 @@ wikitext = this.getWikiText(); promise = this.submitWikiText( wikitext ); - return promise.then( function () { + return promise.then( () => { details.showIndicator( 'success' ); details.setStatus( mw.message( 'mediauploader-published' ).text() ); } ); @@ -843,7 +839,7 @@ * @return {jQuery.Promise} */ submitWikiText: function ( wikiText ) { - var params, + let params, tags = [ 'uploadwizard' ], deed = this.upload.deedChooser.deed, comment = '', @@ -900,7 +896,7 @@ * @return {jQuery.Promise} */ submitWikiTextInternal: function ( params ) { - var details = this, + const details = this, apiPromise = this.upload.api.postWithEditToken( params ); return apiPromise @@ -910,7 +906,7 @@ .then( this.validateWikiTextSubmitResult.bind( this, params ) ) // making it here means the upload is a success, or it would've been // rejected by now (either by HTTP status code, or in validateWikiTextSubmitResult) - .then( function ( result ) { + .then( ( result ) => { details.title = mw.Title.makeTitle( 6, result.upload.filename ); details.upload.extractImageInfo( result.upload.imageinfo ); details.upload.thisProgress = 1.0; @@ -918,7 +914,7 @@ return result; } ) // uh-oh - something went wrong! - .catch( function ( code, result ) { + .catch( ( code, result ) => { details.upload.state = 'error'; details.processError( code, result ); return $.Deferred().reject( code, result ); @@ -936,7 +932,7 @@ * @return {jQuery.Promise} */ validateWikiTextSubmitResult: function ( params, result ) { - var wx, warningsKeys, existingFile, existingFileUrl, existingFileExt, ourFileExt, code, message, + let wx, warningsKeys, existingFile, existingFileUrl, existingFileExt, ourFileExt, code, message, details = this, warnings = null, ignoreTheseWarnings = false, @@ -961,7 +957,7 @@ // * mediauploader-publish // * mediauploader-assembling this.setStatus( mw.message( 'mediauploader-' + result.upload.stage ).text() ); - setTimeout( function () { + setTimeout( () => { if ( details.upload.state !== 'aborted' ) { details.submitWikiTextInternal( { action: 'upload', @@ -1055,7 +1051,7 @@ * @param {string} html Error message to show. */ recoverFromError: function ( code, html ) { - var titleField = mw.UploadWizard.config.content.titleField; + const titleField = mw.UploadWizard.config.content.titleField; this.upload.state = 'recoverable-error'; this.$dataDiv.morphCrossfade( '.detailsForm' ); @@ -1080,7 +1076,7 @@ * @param {Object} result Result from ajax call */ processError: function ( code, result ) { - var recoverable = [ + const recoverable = [ 'abusefilter-disallowed', 'abusefilter-warning', 'spamblacklist', @@ -1117,7 +1113,7 @@ code = 'ratelimited'; } - if ( recoverable.indexOf( code ) > -1 ) { + if ( recoverable.includes( code ) ) { this.recoverFromError( code, result.errors[ 0 ].html ); return; } diff --git a/resources/mw.UploadWizardLicenseInput.js b/resources/mw.UploadWizardLicenseInput.js index b3696aa..00416ef 100644 --- a/resources/mw.UploadWizardLicenseInput.js +++ b/resources/mw.UploadWizardLicenseInput.js @@ -14,7 +14,7 @@ * @param {mw.Api} api API object, used for wikitext previews */ mw.UploadWizardLicenseInput = function ( config, count, api ) { - var self = this, + let self = this, groups = [], group; @@ -45,7 +45,7 @@ group = new uw.LicenseGroup( config, this.type, this.api, this.count ); groups.push( group ); } else { - config.licenseGroups.forEach( function ( groupConfig ) { + config.licenseGroups.forEach( ( groupConfig ) => { group = new uw.LicenseGroup( groupConfig, self.type, self.api, self.count ); groups.push( group ); @@ -54,8 +54,8 @@ // upon selecting a new item in any group, iterate the other groups and make // sure they're updated accordingly, deselecting previously selected items if ( self.type === 'radio' ) { - group.on( 'change', function ( currentGroup ) { - var value = currentGroup.getValue(), + group.on( 'change', ( currentGroup ) => { + const value = currentGroup.getValue(), group2 = currentGroup.getGroup(); self.setValues( value, group2 ); } ); @@ -76,7 +76,7 @@ Object.assign( mw.UploadWizardLicenseInput.prototype, { unload: function () { - this.getItems().forEach( function ( group ) { + this.getItems().forEach( ( group ) => { group.unload(); } ); }, @@ -89,10 +89,10 @@ * @param {string} [groupName] Name of group, when values are only relevant to this group */ setValues: function ( values, groupName ) { - var self = this, + const self = this, selectedGroups = []; - this.getItems().forEach( function ( group ) { + this.getItems().forEach( ( group ) => { if ( groupName === undefined || group.getGroup() === groupName ) { group.setValue( values ); if ( Object.keys( group.getValue() ).length > 0 ) { @@ -115,7 +115,7 @@ // 1 group // in that case, we're only going to select the *last* occurrence, which is what // a browser would do when trying to find/select a radio that occurs twice - selectedGroups.forEach( function ( group ) { + selectedGroups.forEach( ( group ) => { group.setValue( {} ); } ); } @@ -125,8 +125,8 @@ * Set the default configured licenses */ setDefaultValues: function () { - var values = {}; - this.defaults.forEach( function ( license ) { + const values = {}; + this.defaults.forEach( ( license ) => { values[ license ] = true; } ); this.setValues( values ); @@ -139,11 +139,11 @@ * @return {Object} */ getLicenses: function () { - var licenses = {}; + const licenses = {}; - this.getItems().forEach( function ( group ) { - var licenseNames = Object.keys( group.getValue() ); - licenseNames.forEach( function ( name ) { + this.getItems().forEach( ( group ) => { + const licenseNames = Object.keys( group.getValue() ); + licenseNames.forEach( ( name ) => { licenses[ name ] = mw.UploadWizard.config.licenses[ name ] || {}; } ); } ); @@ -157,9 +157,7 @@ * @return {string} of wikitext (empty string if no inputs set) */ getWikiText: function () { - return this.getItems().map( function ( group ) { - return group.getWikiText(); - } ).join( '' ).trim(); + return this.getItems().map( ( group ) => group.getWikiText() ).join( '' ).trim(); }, /** @@ -169,7 +167,7 @@ * @return {jQuery.Promise} Promise that resolves with an array of template names */ getUsedTemplates: function ( wikitext ) { - var input = this; + const input = this; if ( wikitext in this.templateCache ) { return $.Deferred().resolve( this.templateCache[ wikitext ] ).promise(); @@ -181,8 +179,8 @@ prop: 'templates', title: 'File:UploadWizard license verification.png', text: wikitext - } ).then( function ( result ) { - var templates = [], + } ).then( ( result ) => { + let templates = [], template, title, i; for ( i = 0; i < result.parse.templates.length; i++ ) { @@ -207,9 +205,9 @@ * @return {jQuery.Promise} */ getErrors: function () { - var errors = $.Deferred().resolve( [] ).promise(), + let errors = $.Deferred().resolve( [] ).promise(), addError = function ( message ) { - errors = errors.then( function ( errorsCopy ) { + errors = errors.then( ( errorsCopy ) => { // eslint-disable-next-line mediawiki/msg-doc errorsCopy.push( mw.message( message ) ); return errorsCopy; @@ -223,8 +221,8 @@ // It's pretty hard to screw up a radio button, so if even one of them is selected it's okay. // But also check that associated textareas are filled for if the input is selected, and that // they are the appropriate size. - Object.keys( selectedInputs ).forEach( function ( name ) { - var wikitext, + Object.keys( selectedInputs ).forEach( ( name ) => { + let wikitext, data = selectedInputs[ name ]; if ( typeof data !== 'string' ) { @@ -259,10 +257,10 @@ * @return {Object} */ getSerialized: function () { - var values = {}; + const values = {}; - this.getItems().forEach( function ( group ) { - var groupName = group.getGroup(), + this.getItems().forEach( ( group ) => { + const groupName = group.getGroup(), value = group.getValue(); if ( Object.keys( value ).length > 0 ) { @@ -278,9 +276,9 @@ * @param {Object} serialized */ setSerialized: function ( serialized ) { - var self = this; + const self = this; - Object.keys( serialized ).forEach( function ( group ) { + Object.keys( serialized ).forEach( ( group ) => { self.setValues( serialized[ group ], group ); } ); } diff --git a/resources/mw.UploadWizardPage.js b/resources/mw.UploadWizardPage.js index c874700..02f8086 100644 --- a/resources/mw.UploadWizardPage.js +++ b/resources/mw.UploadWizardPage.js @@ -10,7 +10,7 @@ ( function () { function isCompatible() { - var + const profile = $.client.profile(), // Firefox < 7.0 sends an empty string as filename for Blobs in FormData. // requests. https://bugzilla.mozilla.org/show_bug.cgi?id=649150 @@ -27,7 +27,7 @@ mw.UploadWizardPage = function () { - var uploadWizard, + let uploadWizard, config = mw.config.get( 'MediaUploaderConfig' ); // Default configuration value that cannot be removed @@ -54,7 +54,7 @@ uploadWizard.createInterface( '#upload-wizard' ); }; - $( function () { + $( () => { // show page. mw.UploadWizardPage(); } ); diff --git a/resources/mw.UploadWizardUpload.js b/resources/mw.UploadWizardUpload.js index a8ce368..b6db80f 100644 --- a/resources/mw.UploadWizardUpload.js +++ b/resources/mw.UploadWizardUpload.js @@ -167,7 +167,7 @@ * @return {string} basename */ mw.UploadWizardUpload.prototype.getBasename = function () { - var path = this.getFilename(); + const path = this.getFilename(); if ( path === undefined || path === null ) { return ''; @@ -200,7 +200,7 @@ * @return {jQuery.Promise} A promise, resolved when we're done */ mw.UploadWizardUpload.prototype.extractMetadataFromJpegMeta = function () { - var binReader, jpegmeta, + let binReader, jpegmeta, deferred = $.Deferred(), upload = this; if ( this.file && this.file.type === 'image/jpeg' ) { @@ -209,7 +209,7 @@ deferred.resolve(); }; binReader.onload = function () { - var binStr, arr, i, meta; + let binStr, arr, i, meta; if ( binReader.result === null ) { // Contrary to documentation, this sometimes fires for unsuccessful loads (T136235) deferred.resolve(); @@ -254,7 +254,7 @@ * @param {Object} meta As returned by jpegmeta */ mw.UploadWizardUpload.prototype.extractMetadataFromJpegMetaCallback = function ( meta ) { - var pixelHeightDim, pixelWidthDim, degrees; + let pixelHeightDim, pixelWidthDim, degrees; if ( meta !== undefined && meta !== null && typeof meta === 'object' ) { if ( this.imageinfo.metadata === undefined ) { @@ -310,7 +310,7 @@ * @param {Object} imageinfo JSON object obtained from API result. */ mw.UploadWizardUpload.prototype.extractImageInfo = function ( imageinfo ) { - var key, + let key, upload = this; for ( key in imageinfo ) { @@ -320,7 +320,7 @@ this.imageinfo.metadata = {}; } if ( imageinfo.metadata && imageinfo.metadata.length ) { - imageinfo.metadata.forEach( function ( pair ) { + imageinfo.metadata.forEach( ( pair ) => { if ( pair !== undefined ) { upload.imageinfo.metadata[ pair.name.toLowerCase() ] = pair.value; } @@ -343,7 +343,7 @@ * @param {number} [height] Height of thumbnail. Will force 'url' to be added to props */ mw.UploadWizardUpload.prototype.getStashImageInfo = function ( callback, props, width, height ) { - var params = { + const params = { prop: 'stashimageinfo', siifilekey: this.fileKey, siiprop: props.join( '|' ) @@ -368,7 +368,7 @@ } if ( width !== undefined || height !== undefined ) { - if ( props.indexOf( 'url' ) === -1 ) { + if ( !props.includes( 'url' ) ) { props.push( 'url' ); } if ( width !== undefined ) { @@ -393,15 +393,15 @@ * @param {number} [height] Height of thumbnail. Will force 'url' to be added to props */ mw.UploadWizardUpload.prototype.getImageInfo = function ( callback, props, width, height ) { - var requestedTitle, params; + let requestedTitle, params; function ok( data ) { - var found; + let found; if ( data && data.query && data.query.pages ) { found = false; - Object.keys( data.query.pages ).forEach( function ( pageId ) { - var page = data.query.pages[ pageId ]; + Object.keys( data.query.pages ).forEach( ( pageId ) => { + const page = data.query.pages[ pageId ]; if ( page.title && page.title === requestedTitle && page.imageinfo ) { found = true; callback( page.imageinfo ); @@ -434,7 +434,7 @@ }; if ( width !== undefined || height !== undefined ) { - if ( props.indexOf( 'url' ) === -1 ) { + if ( !props.includes( 'url' ) ) { props.push( 'url' ); } if ( width !== undefined ) { @@ -454,7 +454,7 @@ * @return {mw.ApiUploadFormDataHandler} upload handler object */ mw.UploadWizardUpload.prototype.getUploadHandler = function () { - var constructor; // must be the name of a function in 'mw' namespace + let constructor; // must be the name of a function in 'mw' namespace if ( !this.uploadHandler ) { constructor = 'ApiUploadFormDataHandler'; @@ -473,7 +473,7 @@ * couldn't be generated */ mw.UploadWizardUpload.prototype.getApiThumbnail = function ( width, height ) { - var deferred = $.Deferred(); + const deferred = $.Deferred(); function thumbnailPublisher( thumbnails ) { if ( thumbnails === null ) { @@ -484,8 +484,8 @@ // they are actually there yet. Keep trying to set the source ( which should trigger "error" or "load" event ) // on the image. If it loads publish the event with the image. If it errors out too many times, give up and publish // the event with a null. - thumbnails.forEach( function ( thumb ) { - var timeoutMs, image; + thumbnails.forEach( ( thumb ) => { + let timeoutMs, image; if ( thumb.thumberror || ( !( thumb.thumburl && thumb.thumbwidth && thumb.thumbheight ) ) ) { mw.log.warn( 'mw.UploadWizardUpload::getThumbnail> Thumbnail error or missing information' ); @@ -507,14 +507,14 @@ image.width = thumb.thumbwidth; image.height = thumb.thumbheight; $( image ) - .on( 'load', function () { + .on( 'load', () => { // publish the image to anyone who wanted it deferred.resolve( image ); } ) - .on( 'error', function () { + .on( 'error', () => { // retry with exponential backoff if ( timeoutMs < 8000 ) { - setTimeout( function () { + setTimeout( () => { timeoutMs = timeoutMs * 2 + Math.round( Math.random() * ( timeoutMs / 10 ) ); setSrc(); }, timeoutMs ); @@ -545,7 +545,7 @@ * @return {number} orientation in degrees: 0, 90, 180 or 270 */ mw.UploadWizardUpload.prototype.getOrientationDegrees = function () { - var orientation = 0; + let orientation = 0; if ( this.imageinfo && this.imageinfo.metadata && this.imageinfo.metadata.orientation ) { switch ( this.imageinfo.metadata.orientation ) { case 8: @@ -579,9 +579,9 @@ * @return {number} */ mw.UploadWizardUpload.prototype.getScalingFromConstraints = function ( image, constraints ) { - var scaling = 1; - Object.keys( constraints ).forEach( function ( dim ) { - var s, + let scaling = 1; + Object.keys( constraints ).forEach( ( dim ) => { + let s, constraint = constraints[ dim ]; if ( constraint && image[ dim ] > constraint ) { s = constraint / image[ dim ]; @@ -603,7 +603,7 @@ * @return {HTMLCanvasElement|null} */ mw.UploadWizardUpload.prototype.getTransformedCanvasElement = function ( image, constraints ) { - var angle, scaling, width, height, + let angle, scaling, width, height, dimensions, dx, dy, x, y, $canvas, ctx, scaleConstraints = constraints, rotation = 0; @@ -693,7 +693,7 @@ * @return {HTMLImageElement} with same src, but different attrs */ mw.UploadWizardUpload.prototype.getBrowserScaledImageElement = function ( image, constraints ) { - var scaling = this.getScalingFromConstraints( image, constraints ); + const scaling = this.getScalingFromConstraints( image, constraints ); return $( '<img>' ) .attr( { width: parseInt( image.width * scaling, 10 ), @@ -712,7 +712,7 @@ * @return {HTMLCanvasElement|HTMLImageElement} */ mw.UploadWizardUpload.prototype.getScaledImageElement = function ( image, width, height ) { - var constraints = {}, + let constraints = {}, transform; if ( width ) { @@ -742,7 +742,7 @@ * containing a thumbnail, or resolved with `null` when one can't be produced */ mw.UploadWizardUpload.prototype.getThumbnail = function ( width, height ) { - var upload = this, + const upload = this, deferred = $.Deferred(); if ( this.thumbnailPromise[ width + 'x' + height ] ) { @@ -767,14 +767,14 @@ this.extractMetadataFromJpegMeta() .then( upload.makePreview.bind( upload, width ) ) .done( imageCallback ) - .fail( function () { + .fail( () => { // Can't generate the thumbnail locally, get the thumbnail via API after // the file is uploaded. Queries are cached, so if this thumbnail was // already fetched for some reason, we'll get it immediately. if ( upload.state !== 'new' && upload.state !== 'transporting' && upload.state !== 'error' ) { upload.getApiThumbnail( width, height ).done( imageCallback ); } else { - upload.once( 'success', function () { + upload.once( 'success', () => { upload.getApiThumbnail( width, height ).done( imageCallback ); } ); } @@ -798,7 +798,7 @@ * @return {jQuery.Promise} */ mw.UploadWizardUpload.prototype.makePreview = function ( width ) { - var first, video, url, dataUrlReader, + let first, video, url, dataUrlReader, deferred = $.Deferred(), upload = this; @@ -809,12 +809,12 @@ first = true; video = document.createElement( 'video' ); - video.addEventListener( 'loadedmetadata', function () { + video.addEventListener( 'loadedmetadata', () => { // seek 2 seconds into video or to half if shorter video.currentTime = Math.min( 2, video.duration / 2 ); video.volume = 0; } ); - video.addEventListener( 'seeked', function () { + video.addEventListener( 'seeked', () => { // Firefox 16 sometimes does not work on first seek, seek again if ( first ) { first = false; @@ -823,8 +823,8 @@ } else { // Chrome sometimes shows black frames if grabbing right away. // wait 500ms before grabbing frame - setTimeout( function () { - var context, + setTimeout( () => { + let context, canvas = document.createElement( 'canvas' ); canvas.width = width; canvas.height = Math.round( canvas.width * video.videoHeight / video.videoWidth ); @@ -844,7 +844,7 @@ video.src = url; // If we can't get a frame within 10 seconds, something is probably seriously wrong. // This can happen for broken files where we can't actually seek to the time we wanted. - setTimeout( function () { + setTimeout( () => { deferred.reject(); upload.URL().revokeObjectURL( video.url ); }, 10000 ); @@ -871,7 +871,7 @@ * @param {jQuery.Deferred} deferred */ mw.UploadWizardUpload.prototype.loadImage = function ( url, deferred ) { - var image = document.createElement( 'img' ); + const image = document.createElement( 'img' ); image.onload = function () { deferred.resolve( image ); }; diff --git a/resources/mw.UploadWizardUploadInterface.js b/resources/mw.UploadWizardUploadInterface.js index 263787d..610a2bb 100644 --- a/resources/mw.UploadWizardUploadInterface.js +++ b/resources/mw.UploadWizardUploadInterface.js @@ -7,7 +7,7 @@ * @param {mw.UploadWizardUpload} upload */ mw.UploadWizardUploadInterface = function MWUploadWizardUploadInterface( upload ) { - var ui = this; + const ui = this; OO.EventEmitter.call( this ); @@ -47,7 +47,7 @@ flags: 'destructive', icon: 'trash', framed: false - } ).on( 'click', function () { + } ).on( 'click', () => { ui.emit( 'upload-removed' ); } ); @@ -63,7 +63,7 @@ // this.progressBar = ( no progress bar for individual uploads yet ) // we bind to the ui div since .off() doesn't work for non-DOM objects // TODO Convert this to an OO.EventEmitter, and use OOjs events - this.$div.on( 'transportProgressEvent', function () { + this.$div.on( 'transportProgressEvent', () => { ui.showTransportProgress(); } ); }; @@ -96,7 +96,7 @@ */ mw.UploadWizardUploadInterface.prototype.setStatus = function ( msgKey, args ) { // get the status line for our upload - var $status = this.$div.find( '.mediauploader-file-status' ); + const $status = this.$div.find( '.mediauploader-file-status' ); // eslint-disable-next-line mediawiki/msg-doc $status.msg( msgKey, args || [] ).show(); }; @@ -176,7 +176,7 @@ * @param {File} file */ mw.UploadWizardUploadInterface.prototype.fileChangedOk = function ( imageinfo, file ) { - var statusItems = []; + const statusItems = []; this.updateFilename(); @@ -200,10 +200,10 @@ * fails */ mw.UploadWizardUploadInterface.prototype.showThumbnail = function () { - var $preview = this.$div.find( '.mediauploader-file-preview' ), + const $preview = this.$div.find( '.mediauploader-file-preview' ), deferred = $.Deferred(); // This must match the CSS dimensions of .mediauploader-file-preview - this.upload.getThumbnail( 120, 120 ).done( function ( thumb ) { + this.upload.getThumbnail( 120, 120 ).done( ( thumb ) => { mw.UploadWizard.placeThumbnail( $preview, thumb ); deferred.resolve(); } ); @@ -219,7 +219,7 @@ * TODO silently fix to have unique filename? unnecessary at this point... */ mw.UploadWizardUploadInterface.prototype.updateFilename = function () { - var path = this.upload.getFilename(); + const path = this.upload.getFilename(); // visible filename this.$form.find( '.mediauploader-visible-file-filename-text' ) diff --git a/resources/mw.fileApi.js b/resources/mw.fileApi.js index cb80590..9216c24 100644 --- a/resources/mw.fileApi.js +++ b/resources/mw.fileApi.js @@ -15,9 +15,9 @@ * @return {boolean} */ isPreviewableFile: function ( file ) { - var known = [ 'image/png', 'image/gif', 'image/jpeg' ], + const known = [ 'image/png', 'image/gif', 'image/jpeg' ], tooHuge = 10 * 1024 * 1024; - return this.isPreviewableVideo( file ) || ( known.indexOf( file.type ) !== -1 ) && file.size > 0 && file.size < tooHuge; + return this.isPreviewableVideo( file ) || ( known.includes( file.type ) ) && file.size > 0 && file.size < tooHuge; }, /** @@ -27,7 +27,7 @@ * @return {boolean} */ isPreviewableVideo: function ( file ) { - var video = document.createElement( 'video' ); + const video = document.createElement( 'video' ); return video.canPlayType && video.canPlayType( file.type ).replace( 'no', '' ) !== ''; } diff --git a/resources/transports/mw.FormDataTransport.js b/resources/transports/mw.FormDataTransport.js index 95daece..b1c86ec 100644 --- a/resources/transports/mw.FormDataTransport.js +++ b/resources/transports/mw.FormDataTransport.js @@ -48,7 +48,7 @@ * @return {jQuery.Promise} */ mw.FormDataTransport.prototype.post = function ( params ) { - var deferred = $.Deferred(); + const deferred = $.Deferred(); this.request = this.api.post( params, { /* @@ -66,9 +66,9 @@ * out how much of the upload has already gone out, so let's add it! */ xhr: function () { - var xhr = $.ajaxSettings.xhr(); - xhr.upload.addEventListener( 'progress', function ( evt ) { - var fraction = null; + const xhr = $.ajaxSettings.xhr(); + xhr.upload.addEventListener( 'progress', ( evt ) => { + let fraction = null; if ( evt.lengthComputable ) { fraction = parseFloat( evt.loaded / evt.total ); } @@ -92,7 +92,7 @@ * @return {Object} */ mw.FormDataTransport.prototype.createParams = function ( filename, offset ) { - var params = OO.cloneObject( this.formData ); + const params = OO.cloneObject( this.formData ); Object.assign( params, { filename: filename, @@ -118,7 +118,7 @@ * @return {jQuery.Promise} */ mw.FormDataTransport.prototype.upload = function ( file, tempFileName ) { - var params, ext; + let params, ext; this.tempname = tempFileName; // Limit length to 240 bytes (limit hardcoded in UploadBase.php). @@ -150,7 +150,7 @@ * promise from #upload */ mw.FormDataTransport.prototype.chunkedUpload = function ( file ) { - var + let offset, prevPromise = $.Deferred().resolve(), deferred = $.Deferred(), @@ -162,15 +162,15 @@ // Capture offset in a closure // eslint-disable-next-line no-loop-func ( function ( offset2 ) { - var + const newPromise = $.Deferred(), isLastChunk = offset2 + chunkSize >= fileSize, thisChunkSize = isLastChunk ? ( fileSize % chunkSize ) : chunkSize; - prevPromise.done( function () { + prevPromise.done( () => { transport.uploadChunk( file, offset2 ) .done( isLastChunk ? deferred.resolve : newPromise.resolve ) .fail( deferred.reject ) - .progress( function ( fraction ) { + .progress( ( fraction ) => { // The progress notifications give us per-chunk progress. // Calculate progress for the whole file. deferred.notify( ( offset2 + fraction * thisChunkSize ) / fileSize ); @@ -191,7 +191,7 @@ * @return {jQuery.Promise} */ mw.FormDataTransport.prototype.uploadChunk = function ( file, offset ) { - var params = this.createParams( this.tempname, offset ), + let params = this.createParams( this.tempname, offset ), transport = this, bytesAvailable = file.size, chunk; @@ -229,7 +229,7 @@ params.filesize = bytesAvailable; params.chunk = chunk; - return this.post( params ).then( function ( response ) { + return this.post( params ).then( ( response ) => { if ( response.upload && response.upload.filekey ) { transport.filekey = response.upload.filekey; } @@ -256,7 +256,7 @@ file, offset ); } - }, function ( code, result ) { + }, ( code, result ) => { // Ain't this some great machine readable output eh if ( result.errors && @@ -323,7 +323,7 @@ * @return {jQuery.Promise} */ mw.FormDataTransport.prototype.retryWithMethod = function ( methodName, file, offset ) { - var + const transport = this, retryDeferred = $.Deferred(), retry = function () { @@ -345,7 +345,7 @@ * @return {jQuery.Promise} */ mw.FormDataTransport.prototype.checkStatus = function () { - var transport = this, + const transport = this, params = OO.cloneObject( this.formData ); if ( this.aborted ) { @@ -363,7 +363,7 @@ params.checkstatus = true; params.filekey = this.filekey; this.request = this.api.post( params ) - .then( function ( response ) { + .then( ( response ) => { if ( response.upload && response.upload.result === 'Poll' ) { // If concatenation takes longer than 10 minutes give up if ( ( Date.now() - transport.firstPoll ) > 10 * 60 * 1000 ) { @@ -390,9 +390,7 @@ } return response; - }, function ( code, result ) { - return $.Deferred().reject( code, result ); - } ); + }, ( code, result ) => $.Deferred().reject( code, result ) ); return this.request; }; diff --git a/resources/ui/steps/uw.ui.Deed.js b/resources/ui/steps/uw.ui.Deed.js index 21dcf59..e556430 100644 --- a/resources/ui/steps/uw.ui.Deed.js +++ b/resources/ui/steps/uw.ui.Deed.js @@ -36,7 +36,7 @@ OO.inheritClass( uw.ui.Deed, uw.ui.Step ); uw.ui.Deed.prototype.load = function ( uploads ) { - var ui = this; + const ui = this; uw.ui.Step.prototype.load.call( this, uploads ); @@ -52,7 +52,7 @@ .addClass( 'ui-helper-clearfix' ) ); - this.nextButtonPromise.done( function () { + this.nextButtonPromise.done( () => { // hide "next" button, controller will only show it once license has // been selected ui.nextButton.$element.hide(); diff --git a/resources/ui/steps/uw.ui.Details.js b/resources/ui/steps/uw.ui.Details.js index e5117db..793da75 100644 --- a/resources/ui/steps/uw.ui.Details.js +++ b/resources/ui/steps/uw.ui.Details.js @@ -24,7 +24,7 @@ * @constructor */ uw.ui.Details = function UWUIDetails() { - var details = this; + const details = this; function startDetails() { details.emit( 'start-details' ); @@ -48,7 +48,7 @@ this.nextButtonDespiteFailures = new OO.ui.ButtonWidget( { label: mw.message( 'mediauploader-next-file-despite-failures' ).text(), flags: [ 'progressive' ] - } ).on( 'click', function () { + } ).on( 'click', () => { details.emit( 'finalize-details-after-removal' ); } ); @@ -85,9 +85,9 @@ }; uw.ui.Details.prototype.addNextButton = function () { - var ui = this; + const ui = this; - this.nextButtonPromise.done( function () { + this.nextButtonPromise.done( () => { ui.$buttons.append( $( '<div>' ) .addClass( 'mediauploader-file-next-all-ok mediauploader-file-endchoice' ) @@ -164,14 +164,14 @@ * This method also opens up "more info" if the form has errors. */ uw.ui.Details.prototype.showErrors = function () { - var $errorElements = this.$div + const $errorElements = this.$div // TODO Evil .find( '.oo-ui-fieldLayout-messages-error' ), errorCount = $errorElements.length; // Open "more info" if that part of the form has errors $errorElements.each( function () { - var $collapsibleWrapper = $( this ).closest( '.mwe-more-details' ); + const $collapsibleWrapper = $( this ).closest( '.mwe-more-details' ); if ( $collapsibleWrapper.length ) { $collapsibleWrapper.data( 'mw-collapsible' ).expand(); } @@ -199,14 +199,14 @@ * See #showErrors for details. */ uw.ui.Details.prototype.showWarnings = function () { - var $warningElements = this.$div + const $warningElements = this.$div // TODO Evil .find( '.oo-ui-fieldLayout-messages-notice' ), warningCount = $warningElements.length; // Open "more info" if that part of the form has warnings $warningElements.each( function () { - var $collapsibleWrapper = $( this ).closest( '.mwe-more-details' ); + const $collapsibleWrapper = $( this ).closest( '.mwe-more-details' ); if ( $collapsibleWrapper.length ) { $collapsibleWrapper.data( 'mw-collapsible' ).expand(); } diff --git a/resources/ui/steps/uw.ui.Thanks.js b/resources/ui/steps/uw.ui.Thanks.js index 62290aa..fc56af0 100644 --- a/resources/ui/steps/uw.ui.Thanks.js +++ b/resources/ui/steps/uw.ui.Thanks.js @@ -25,7 +25,7 @@ * @param {Object} config */ uw.ui.Thanks = function UWUIThanks( config ) { - var $header, + let $header, beginButtonTarget, thanks = this; @@ -68,13 +68,13 @@ // TODO: make the step order configurable by campaign definitions instead of using these hacks beginButtonTarget = this.getButtonConfig( 'beginButton', 'target' ); if ( !beginButtonTarget ) { - this.beginButton.on( 'click', function () { + this.beginButton.on( 'click', () => { thanks.emit( 'next-step' ); } ); } else { this.beginButton.setHref( beginButtonTarget ); } - this.beginButton.on( 'click', function () { + this.beginButton.on( 'click', () => { mw.DestinationChecker.clearCache(); } ); @@ -93,7 +93,7 @@ * @param {mw.UploadWizardUpload} upload */ uw.ui.Thanks.prototype.addUpload = function ( upload ) { - var thumbWikiText, $thanksDiv, $thumbnailWrapDiv, $thumbnailDiv, $thumbnailCaption, $thumbnailLink; + let thumbWikiText, $thanksDiv, $thumbnailWrapDiv, $thumbnailDiv, $thumbnailCaption, $thumbnailLink; thumbWikiText = '[[' + [ upload.details.getTitle().getPrefixedText(), @@ -125,7 +125,7 @@ ); // This must match the CSS dimensions of .mediauploader-thumbnail - upload.getThumbnail( 120, 120 ).done( function ( thumb ) { + upload.getThumbnail( 120, 120 ).done( ( thumb ) => { mw.UploadWizard.placeThumbnail( $thumbnailDiv, thumb ); } ); @@ -148,7 +148,7 @@ * @return {jQuery} */ uw.ui.Thanks.prototype.makeReadOnlyInput = function ( value, label, useEditFont ) { - var copyText = new mw.widgets.CopyTextLayout( { + const copyText = new mw.widgets.CopyTextLayout( { align: 'top', label: label, copyText: value diff --git a/resources/ui/steps/uw.ui.Tutorial.js b/resources/ui/steps/uw.ui.Tutorial.js index 1b8d0d4..fa7fd0f 100644 --- a/resources/ui/steps/uw.ui.Tutorial.js +++ b/resources/ui/steps/uw.ui.Tutorial.js @@ -51,7 +51,7 @@ * @constructor */ uw.ui.Tutorial = function UWUITutorial() { - var ui = this; + const ui = this; uw.ui.Step.call( this, @@ -78,7 +78,7 @@ label: mw.message( 'mediauploader-skip-tutorial-future' ).text() } ); - this.skipCheckbox.on( 'change', function () { + this.skipCheckbox.on( 'change', () => { ui.emit( 'skip-tutorial-click', ui.skipCheckbox.isSelected() ); } ); @@ -112,17 +112,17 @@ }; uw.ui.Tutorial.prototype.addNextButton = function () { - var ui = this; + const ui = this; this.nextButton = new OO.ui.ButtonWidget( { classes: [ 'mediauploader-button-next' ], label: mw.message( 'mediauploader-next' ).text(), flags: [ 'progressive', 'primary' ] - } ).on( 'click', function () { + } ).on( 'click', () => { ui.emit( 'next-step' ); } ); - this.nextButtonPromise.done( function () { + this.nextButtonPromise.done( () => { ui.$buttons.append( new OO.ui.HorizontalLayout( { items: [ ui.skipCheckbox, ui.skipCheckboxLabel, ui.nextButton ] diff --git a/resources/ui/steps/uw.ui.Upload.js b/resources/ui/steps/uw.ui.Upload.js index 4ec5509..b7e38bf 100644 --- a/resources/ui/steps/uw.ui.Upload.js +++ b/resources/ui/steps/uw.ui.Upload.js @@ -25,7 +25,7 @@ * @param {Object} config UploadWizard config object. */ uw.ui.Upload = function UWUIUpload( config ) { - var upload = this; + const upload = this; this.config = config; @@ -58,14 +58,14 @@ this.nextStepButtonAllOk = new OO.ui.ButtonWidget( { label: mw.message( 'mediauploader-next-file' ).text(), flags: [ 'progressive', 'primary' ] - } ).on( 'click', function () { + } ).on( 'click', () => { upload.emit( 'next-step' ); } ); this.retryButtonSomeFailed = new OO.ui.ButtonWidget( { label: mw.message( 'mediauploader-file-retry' ).text(), flags: [ 'progressive' ] - } ).on( 'click', function () { + } ).on( 'click', () => { upload.hideEndButtons(); upload.emit( 'retry' ); } ); @@ -73,14 +73,14 @@ this.nextStepButtonSomeFailed = new OO.ui.ButtonWidget( { label: mw.message( 'mediauploader-next-file-despite-failures' ).text(), flags: [ 'progressive', 'primary' ] - } ).on( 'click', function () { + } ).on( 'click', () => { upload.emit( 'next-step' ); } ); this.retryButtonAllFailed = new OO.ui.ButtonWidget( { label: mw.message( 'mediauploader-file-retry' ).text(), flags: [ 'progressive' ] - } ).on( 'click', function () { + } ).on( 'click', () => { upload.hideEndButtons(); upload.emit( 'retry' ); } ); @@ -145,7 +145,7 @@ * @param {boolean} more */ uw.ui.Upload.prototype.setAddButtonText = function ( more ) { - var msg = 'mediauploader-add-file-'; + let msg = 'mediauploader-add-file-'; if ( more ) { msg += 'n'; @@ -160,7 +160,7 @@ }; uw.ui.Upload.prototype.load = function ( uploads ) { - var ui = this; + const ui = this; uw.ui.Step.prototype.load.call( this, uploads ); @@ -177,17 +177,17 @@ ) ); - this.addFile.on( 'change', function ( files ) { + this.addFile.on( 'change', ( files ) => { ui.emit( 'files-added', files ); ui.addFile.setValue( null ); } ); }; uw.ui.Upload.prototype.displayUploads = function ( uploads ) { - var thumbPromise, + let thumbPromise, $uploadInterfaceDivs = $( [] ); - uploads.forEach( function ( upload ) { + uploads.forEach( ( upload ) => { // We'll attach all interfaces to the DOM at once rather than one-by-one, for better // performance $uploadInterfaceDivs = $uploadInterfaceDivs.add( upload.ui.$div ); @@ -199,15 +199,15 @@ // Display thumbnails, but not all at once because they're somewhat expensive to generate. // This will wait for each thumbnail to be complete before starting the next one. thumbPromise = $.Deferred().resolve(); - uploads.forEach( function ( upload ) { - thumbPromise = thumbPromise.then( function () { - var deferred = $.Deferred(); + uploads.forEach( ( upload ) => { + thumbPromise = thumbPromise.then( () => { + const deferred = $.Deferred(); setTimeout( function () { if ( this.movedFrom ) { // We're no longer displaying any of these thumbnails, stop deferred.reject(); } - upload.ui.showThumbnail().done( function () { + upload.ui.showThumbnail().done( () => { deferred.resolve(); } ); } ); @@ -217,9 +217,9 @@ }; uw.ui.Upload.prototype.addNextButton = function () { - var ui = this; + const ui = this; - this.nextButtonPromise.done( function () { + this.nextButtonPromise.done( () => { ui.$buttons.append( $( '<div>' ) .addClass( 'mediauploader-file-next-all-ok mediauploader-file-endchoice' ) @@ -319,12 +319,12 @@ * @param {string} extension */ uw.ui.Upload.prototype.showBadExtensionError = function ( filename, extension ) { - var $errorMessage = $( '<p>' ).msg( 'mediauploader-upload-error-bad-filename-extension', extension ); + const $errorMessage = $( '<p>' ).msg( 'mediauploader-upload-error-bad-filename-extension', extension ); this.showFilenameError( $errorMessage ); }; uw.ui.Upload.prototype.showMissingExtensionError = function () { - var $errorMessage = $( '<p>' ).msg( 'mediauploader-upload-error-bad-filename-no-extension' ); + const $errorMessage = $( '<p>' ).msg( 'mediauploader-upload-error-bad-filename-no-extension' ); this.showFilenameError( $( '<div>' ).append( $errorMessage, diff --git a/resources/ui/uw.ui.DeedPreview.js b/resources/ui/uw.ui.DeedPreview.js index a30f6fb..a7b30b5 100644 --- a/resources/ui/uw.ui.DeedPreview.js +++ b/resources/ui/uw.ui.DeedPreview.js @@ -24,10 +24,10 @@ * @param {mw.UploadWizardUpload} upload */ uw.ui.DeedPreview = function UWUIDeedPreview( upload ) { - var $thumbnailDiv = $( '<div>' ).addClass( 'mediauploader-thumbnail' ); + const $thumbnailDiv = $( '<div>' ).addClass( 'mediauploader-thumbnail' ); this.$thumbnailDiv = $thumbnailDiv; // This must match the CSS dimensions of .mediauploader-thumbnail - upload.getThumbnail( 120, 120 ).done( function ( thumb ) { + upload.getThumbnail( 120, 120 ).done( ( thumb ) => { mw.UploadWizard.placeThumbnail( $thumbnailDiv, thumb ); } ); // eslint-disable-next-line no-jquery/no-global-selector diff --git a/resources/ui/uw.ui.Step.js b/resources/ui/uw.ui.Step.js index 6b19ffb..af3d8ae 100644 --- a/resources/ui/uw.ui.Step.js +++ b/resources/ui/uw.ui.Step.js @@ -53,7 +53,7 @@ */ uw.ui.Step.prototype.load = function ( uploads ) { // eslint-disable-next-line no-jquery/no-global-selector - var offset = $( 'h1' ).first().offset(); + const offset = $( 'h1' ).first().offset(); this.movedFrom = false; @@ -88,17 +88,17 @@ * Add a 'next' button to the step's button container */ uw.ui.Step.prototype.addNextButton = function () { - var ui = this; + const ui = this; this.nextButton = new OO.ui.ButtonWidget( { classes: [ 'mediauploader-button-next' ], label: mw.message( 'mediauploader-next' ).text(), flags: [ 'progressive', 'primary' ] - } ).on( 'click', function () { + } ).on( 'click', () => { ui.emit( 'next-step' ); } ); - this.nextButtonPromise.done( function () { + this.nextButtonPromise.done( () => { ui.$buttons.append( ui.nextButton.$element ); } ); }; @@ -107,16 +107,16 @@ * Add a 'previous' button to the step's button container */ uw.ui.Step.prototype.addPreviousButton = function () { - var ui = this; + const ui = this; this.previousButton = new OO.ui.ButtonWidget( { classes: [ 'mediauploader-button-previous' ], label: mw.message( 'mediauploader-previous' ).text() - } ).on( 'click', function () { + } ).on( 'click', () => { ui.emit( 'previous-step' ); } ); - this.previousButtonPromise.done( function () { + this.previousButtonPromise.done( () => { ui.$buttons.append( ui.previousButton.$element ); } ); }; diff --git a/resources/ui/uw.ui.Wizard.js b/resources/ui/uw.ui.Wizard.js index 804fbaa..5472285 100644 --- a/resources/ui/uw.ui.Wizard.js +++ b/resources/ui/uw.ui.Wizard.js @@ -46,7 +46,7 @@ */ uw.ui.Wizard.prototype.initHeader = function ( config ) { // eslint-disable-next-line no-jquery/no-global-selector - var $contentSub = $( '#contentSub' ); + const $contentSub = $( '#contentSub' ); if ( config.alternativeUploadToolsPage ) { this.$alternativeUploads = $( '<a>' ) @@ -72,7 +72,7 @@ * @param {Object|string} configAltUploadForm A link or map of languages to links, pointing at an alternate form. */ uw.ui.Wizard.prototype.initAltUploadForm = function ( configAltUploadForm ) { - var altUploadForm, userLanguage, title; + let altUploadForm, userLanguage, title; if ( typeof configAltUploadForm === 'object' ) { userLanguage = mw.config.get( 'wgUserLanguage' ); @@ -108,13 +108,13 @@ * @param {uw.controller.Step[]} steps */ uw.ui.Wizard.prototype.initialiseSteps = function ( steps ) { - var $steps = $( '<ul>' ) + const $steps = $( '<ul>' ) .attr( 'id', 'mediauploader-steps' ) .addClass( 'ui-helper-clearfix' ) .insertBefore( '#mediauploader-content' ); - steps.forEach( function ( step ) { - var $arrow = $( '<li>' ) + steps.forEach( ( step ) => { + const $arrow = $( '<li>' ) .attr( 'id', 'mediauploader-step-' + step.stepName ) .append( // Messages that can be used here: @@ -128,9 +128,9 @@ $steps.append( $arrow ); // once a (new) step loads, highlight it - step.on( 'load', function ( $arrow2 ) { + step.on( 'load', ( ( $arrow2 ) => { $steps.arrowStepsHighlight( $arrow2 ); - }.bind( step, $arrow ) ); + } ).bind( step, $arrow ) ); } ); $steps.arrowSteps(); diff --git a/resources/uw.ConcurrentQueue.js b/resources/uw.ConcurrentQueue.js index 2ec018f..48383eb 100644 --- a/resources/uw.ConcurrentQueue.js +++ b/resources/uw.ConcurrentQueue.js @@ -70,7 +70,7 @@ * @return {boolean} Whether the item was removed */ uw.ConcurrentQueue.prototype.removeItem = function ( item ) { - var index, found; + let index, found; found = false; @@ -113,7 +113,7 @@ * @param {Object} item */ uw.ConcurrentQueue.prototype.promiseComplete = function ( item ) { - var index; + let index; index = this.running.indexOf( item ); // Check that this item wasn't removed while it was being executed if ( index !== -1 ) { @@ -132,7 +132,7 @@ * @private */ uw.ConcurrentQueue.prototype.executeNext = function () { - var item, promise; + let item, promise; if ( this.running.length === this.count || !this.executing ) { return; } @@ -153,7 +153,7 @@ * When the queue finishes executing, a 'complete' event will be emitted. */ uw.ConcurrentQueue.prototype.startExecuting = function () { - var i; + let i; if ( this.executing ) { return; } diff --git a/resources/uw.CopyMetadataWidget.js b/resources/uw.CopyMetadataWidget.js index 784aab0..5fa1180 100644 --- a/resources/uw.CopyMetadataWidget.js +++ b/resources/uw.CopyMetadataWidget.js @@ -10,7 +10,7 @@ * @cfg {mw.UploadWizardUpload[]} copyTo Uploads to copy the details to */ uw.CopyMetadataWidget = function UWCopyMetadataWidget( config ) { - var metadataType, defaultStatus, copyMetadataMsg, + let metadataType, defaultStatus, copyMetadataMsg, checkboxes = [], $copyMetadataWrapperDiv = $( '<div>' ), $copyMetadataDiv = $( '<div>' ); @@ -118,7 +118,7 @@ * @private */ uw.CopyMetadataWidget.prototype.onCopyClick = function () { - var metadataTypes = this.checkboxesWidget.findSelectedItemsData(); + const metadataTypes = this.checkboxesWidget.findSelectedItemsData(); this.copyMetadata( metadataTypes ); this.undoButton.toggle( true ); @@ -153,7 +153,7 @@ * @param {string[]} metadataTypes Types to copy, as defined in the copyMetadataTypes property */ uw.CopyMetadataWidget.prototype.copyMetadata = function ( metadataTypes ) { - var titleZero, matches, i, + let titleZero, matches, i, uploads = this.copyTo, sourceUpload = this.copyFrom, serialized = sourceUpload.details.getSerialized(), @@ -164,7 +164,7 @@ copyingOther = false; // Filter serialized data to only the types we want to copy - metadataTypes.forEach( function ( type ) { + metadataTypes.forEach( ( type ) => { sourceValue[ type ] = serialized[ type ]; copyingTitle = copyingTitle || type === 'title'; copyingOther = copyingOther || type === 'other'; @@ -193,8 +193,8 @@ // numbers. sourceValue.title.title = titleZero.replace( /(\D+)(\d{1,3})(\D*)$/, // eslint-disable-next-line no-loop-func - function ( str, m1, m2, m3 ) { - var newstr = String( +m2 + i ); + ( str, m1, m2, m3 ) => { + const newstr = String( +m2 + i ); return m1 + new Array( m2.length + 1 - newstr.length ) .join( '0' ) + newstr + m3; } @@ -210,7 +210,7 @@ * Restore previously saved metadata that we backed up when copying. */ uw.CopyMetadataWidget.prototype.restoreMetadata = function () { - var i, + let i, uploads = this.copyTo; for ( i = 0; i < uploads.length; i++ ) { diff --git a/resources/uw.FieldLayout.js b/resources/uw.FieldLayout.js index 8d52198..7c5f4a5 100644 --- a/resources/uw.FieldLayout.js +++ b/resources/uw.FieldLayout.js @@ -16,7 +16,7 @@ // FieldLayout will add an icon which, when clicked, reveals more information // about the input. We'll want to display that by default, so we're getting // rid of the "help" property here & will later append that after the header - var help = config && config.help ? config.help : ''; + const help = config && config.help ? config.help : ''; config = Object.assign( { align: 'top', required: false }, config, { help: '' } ); uw.FieldLayout.parent.call( this, fieldWidget, config ); diff --git a/resources/uw.LicenseGroup.js b/resources/uw.LicenseGroup.js index c5d4f6f..5277ac0 100644 --- a/resources/uw.LicenseGroup.js +++ b/resources/uw.LicenseGroup.js @@ -22,7 +22,7 @@ * @param {number} count Number of the things we are licensing (it matters to some texts) */ uw.LicenseGroup = function UWLicenseGroup( config, type, api, count ) { - var self = this; + const self = this; uw.LicenseGroup.parent.call( this, {} ); @@ -30,7 +30,7 @@ throw new Error( 'improper license config' ); } - if ( [ 'radio', 'checkbox' ].indexOf( type ) < 0 ) { + if ( ![ 'radio', 'checkbox' ].includes( type ) ) { throw new Error( 'Invalid type: ' + type ); } @@ -58,12 +58,12 @@ } // when selecting an item that has a custom textarea, we'll immediately focus it - this.on( 'change', function ( group, item ) { + this.on( 'change', ( group, item ) => { if ( item && item.isSelected && item.isSelected() ) { // wrapped inside setTimeout to ensure it goes at the end of the call stack, // just in case something steals focus in the meantime... - setTimeout( function () { - var name = item.getData(); + setTimeout( () => { + const name = item.getData(); if ( self.textareas[ name ] ) { self.textareas[ name ].focus(); } @@ -86,7 +86,7 @@ */ uw.LicenseGroup.prototype.createFieldset = function ( group ) { /* eslint-disable mediawiki/msg-doc */ - var $head = this.config.head && $( '<a>' ) + const $head = this.config.head && $( '<a>' ) .addClass( 'mediauploader-deed-license-group-head' ) .msg( this.config.head, this.count ) .prepend( $( '<span>' ).addClass( 'mw-toggle-icon' ) ), @@ -118,11 +118,11 @@ * @return {OO.ui.RadioSelectWidget} */ uw.LicenseGroup.prototype.createRadioGroup = function ( classes ) { - var self = this, + const self = this, options = []; - this.config.licenses.forEach( function ( licenseName ) { - var option; + this.config.licenses.forEach( ( licenseName ) => { + let option; if ( mw.UploadWizard.config.licenses[ licenseName ] === undefined ) { // unknown license @@ -136,7 +136,7 @@ // when custom text area receives focus, we should make sure this element is selected if ( self.textareas[ licenseName ] ) { - self.textareas[ licenseName ].on( 'focus', function () { + self.textareas[ licenseName ].on( 'focus', () => { option.setSelected( true ); } ); } @@ -153,11 +153,11 @@ * @return {OO.ui.CheckboxMultiselectInputWidget} */ uw.LicenseGroup.prototype.createCheckboxGroup = function ( classes ) { - var self = this, + const self = this, options = []; - this.config.licenses.forEach( function ( licenseName ) { - var option; + this.config.licenses.forEach( ( licenseName ) => { + let option; if ( mw.UploadWizard.config.licenses[ licenseName ] === undefined ) { // unknown license @@ -171,7 +171,7 @@ // when custom text area receives focus, we should make sure this element is selected if ( self.textareas[ licenseName ] ) { - self.textareas[ licenseName ].on( 'focus', function () { + self.textareas[ licenseName ].on( 'focus', () => { option.setSelected( true ); } ); } @@ -187,12 +187,12 @@ * @return {string} */ uw.LicenseGroup.prototype.getWikiText = function () { - var wikiTexts, + let wikiTexts, self = this, values = this.getValue(); - wikiTexts = Object.keys( values ).map( function ( name ) { - var wikiText = self.getLicenseWikiText( name ), + wikiTexts = Object.keys( values ).map( ( name ) => { + let wikiText = self.getLicenseWikiText( name ), value = values[ name ]; if ( typeof value === 'string' ) { // `value` is custom input @@ -219,7 +219,7 @@ * @return {Object} Map of { licenseName: true }, or { licenseName: "custom input" } */ uw.LicenseGroup.prototype.getValue = function () { - var self = this, + let self = this, result = {}, selected, name; @@ -232,7 +232,7 @@ } } else if ( this.type === 'checkbox' ) { selected = this.group.findSelectedItems(); - selected.forEach( function ( item ) { + selected.forEach( ( item ) => { name = item.getData(); result[ name ] = !self.textareas[ name ] || self.textareas[ name ].getValue(); } ); @@ -245,12 +245,12 @@ * @param {Object} values Map of { licenseName: true }, or { licenseName: "custom input" } */ uw.LicenseGroup.prototype.setValue = function ( values ) { - var self = this, + let self = this, selectArray = [], selected; - Object.keys( values ).forEach( function ( name ) { - var value = values[ name ]; + Object.keys( values ).forEach( ( name ) => { + const value = values[ name ]; if ( typeof value === 'string' && self.textareas[ name ] ) { self.textareas[ name ].setValue( value ); // add to list of items to select @@ -300,7 +300,7 @@ * @return {string} of wikitext */ uw.LicenseGroup.prototype.getLicenseWikiText = function ( name ) { - var licenseInfo = this.getLicenseInfo( name ), + let licenseInfo = this.getLicenseInfo( name ), licenseText; licenseText = licenseInfo.props.wikitext !== undefined ? @@ -316,7 +316,7 @@ * @return {jQuery} */ uw.LicenseGroup.prototype.createLabel = function ( name ) { - var licenseInfo = this.getLicenseInfo( name ), + let licenseInfo = this.getLicenseInfo( name ), messageKey = licenseInfo.props.msg === undefined ? '[missing msg for ' + licenseInfo.name + ']' : licenseInfo.props.msg, @@ -333,7 +333,7 @@ } $licenseLink = $( '<a>' ).attr( { target: '_blank', href: licenseURL } ); if ( licenseInfo.props.icons !== undefined ) { - licenseInfo.props.icons.forEach( function ( icon ) { + licenseInfo.props.icons.forEach( ( icon ) => { // eslint-disable-next-line mediawiki/class-doc $icons.append( $( '<span>' ).addClass( 'mediauploader-license-icon mediauploader-' + icon + '-icon' ) ); } ); @@ -358,7 +358,7 @@ * @return {jQuery} Wrapped textarea */ uw.LicenseGroup.prototype.createCustom = function ( name, defaultText ) { - var self = this, + let self = this, button; this.textareas[ name ] = new OO.ui.MultilineTextInputWidget( { @@ -372,7 +372,7 @@ button = new OO.ui.ButtonWidget( { label: mw.message( 'mediauploader-license-custom-preview' ).text(), flags: [ 'progressive' ] - } ).on( 'click', function () { + } ).on( 'click', () => { self.showPreview( self.textareas[ name ].getValue() ); } ); @@ -389,7 +389,7 @@ * @param {string} wikiText */ uw.LicenseGroup.prototype.showPreview = function ( wikiText ) { - var input; + let input; this.previewDialog.setLoading( true ); this.windowManager.openWindow( this.previewDialog ); @@ -402,7 +402,7 @@ } function error( code, result ) { - var message = result.errors[ 0 ].html; + const message = result.errors[ 0 ].html; show( $( '<div>' ).append( $( '<h3>' ).append( code ), diff --git a/resources/uw.LicensePreviewDialog.js b/resources/uw.LicensePreviewDialog.js index 133d1b5..08f5231 100644 --- a/resources/uw.LicensePreviewDialog.js +++ b/resources/uw.LicensePreviewDialog.js @@ -7,7 +7,7 @@ uw.LicensePreviewDialog.static.name = 'licensePreviewDialog'; uw.LicensePreviewDialog.prototype.initialize = function () { - var dialog = this; + const dialog = this; uw.LicensePreviewDialog.parent.prototype.initialize.call( this ); @@ -16,7 +16,7 @@ this.$spinner = $.createSpinner( { size: 'large', type: 'block' } ) .css( { width: 200, padding: 20, float: 'none', margin: '0 auto' } ); - $( document.body ).on( 'click', function ( e ) { + $( document.body ).on( 'click', ( e ) => { if ( !$.contains( dialog.$body.get( 0 ), e.target ) ) { dialog.close(); } @@ -24,12 +24,12 @@ }; uw.LicensePreviewDialog.prototype.addCloseButton = function () { - var dialog = this, + const dialog = this, closeButton = new OO.ui.ButtonWidget( { label: OO.ui.msg( 'ooui-dialog-process-dismiss' ) } ); - closeButton.on( 'click', function () { + closeButton.on( 'click', () => { dialog.close(); } ); diff --git a/resources/uw.ValidationMessageElement.js b/resources/uw.ValidationMessageElement.js index 1a50d13..72c5e89 100644 --- a/resources/uw.ValidationMessageElement.js +++ b/resources/uw.ValidationMessageElement.js @@ -43,7 +43,7 @@ * @return {jQuery.Promise} */ uw.ValidationMessageElement.prototype.checkValidity = function ( thorough ) { - var element = this; + const element = this; thorough = thorough || false; if ( !this.validatedWidget.getWarnings || !this.validatedWidget.getErrors ) { @@ -57,13 +57,13 @@ return $.when( this.validatedWidget.getWarnings( thorough ), this.validatedWidget.getErrors( thorough ) - ).then( function ( warnings, errors ) { + ).then( ( warnings, errors ) => { // this.notices and this.errors are arrays of mw.Messages and not strings in this subclass element.setNotices( warnings ); element.setErrors( errors ); return $.Deferred().resolve( warnings, errors ).promise(); - } ).always( function () { + } ).always( () => { if ( element.validatedWidget.popPending ) { element.validatedWidget.popPending(); } @@ -77,7 +77,7 @@ * @return {jQuery} */ uw.ValidationMessageElement.prototype.makeMessage = function ( kind, error ) { - var code, $content, $listItem; + let code, $content, $listItem; if ( error.parseDom ) { // mw.Message object code = error.key; diff --git a/resources/uw.units.js b/resources/uw.units.js index 9720982..f36f63c 100644 --- a/resources/uw.units.js +++ b/resources/uw.units.js @@ -1,6 +1,6 @@ ( function ( uw ) { - var scaleMsgKeys = [ 'size-bytes', 'size-kilobytes', 'size-megabytes', 'size-gigabytes' ]; + const scaleMsgKeys = [ 'size-bytes', 'size-kilobytes', 'size-megabytes', 'size-gigabytes' ]; uw.units = { /** @@ -13,7 +13,7 @@ * @return {string} formatted size */ bytes: function ( size ) { - var i = 0; + let i = 0; while ( size >= 1024 && i < scaleMsgKeys.length - 1 ) { size /= 1024.0; i++; diff --git a/tests/qunit/.eslintrc.json b/tests/qunit/.eslintrc.json index a4f3832..f2a8a28 100644 --- a/tests/qunit/.eslintrc.json +++ b/tests/qunit/.eslintrc.json @@ -5,5 +5,9 @@ ], "globals": { "sinon": false + }, + "rules": { + "no-jquery/no-done-fail": "warn", + "prefer-const": "warn" } } diff --git a/tests/qunit/controller/uw.controller.Deed.test.js b/tests/qunit/controller/uw.controller.Deed.test.js index fa5b40c..98b5cbb 100644 --- a/tests/qunit/controller/uw.controller.Deed.test.js +++ b/tests/qunit/controller/uw.controller.Deed.test.js @@ -18,15 +18,15 @@ ( function ( uw ) { QUnit.module( 'uw.controller.Deed', QUnit.newMwEnvironment() ); - QUnit.test( 'Constructor sanity test', function ( assert ) { - var step = new uw.controller.Deed(); + QUnit.test( 'Constructor sanity test', ( assert ) => { + const step = new uw.controller.Deed(); assert.true( !!step ); assert.true( step instanceof uw.controller.Step ); assert.true( !!step.ui ); } ); QUnit.test( 'load', function ( assert ) { - var step = new uw.controller.Deed( + const step = new uw.controller.Deed( new mw.Api(), { licensing: { enabled: true, diff --git a/tests/qunit/controller/uw.controller.Details.test.js b/tests/qunit/controller/uw.controller.Details.test.js index 689c5f7..7b6a5d9 100644 --- a/tests/qunit/controller/uw.controller.Details.test.js +++ b/tests/qunit/controller/uw.controller.Details.test.js @@ -19,7 +19,7 @@ QUnit.module( 'uw.controller.Details', QUnit.newMwEnvironment() ); function createTestUpload( sandbox, customDeedChooser, aborted ) { - var stubs = { + const stubs = { ucdc: sandbox.stub(), getSerialized: sandbox.stub(), setSerialized: sandbox.stub(), @@ -44,8 +44,8 @@ }; } - QUnit.test( 'Constructor sanity test', function ( assert ) { - var step = new uw.controller.Details( new mw.Api(), { + QUnit.test( 'Constructor sanity test', ( assert ) => { + const step = new uw.controller.Details( new mw.Api(), { maxSimultaneousConnections: 1 } ); assert.true( !!step ); @@ -54,7 +54,7 @@ } ); QUnit.test( 'load', function ( assert ) { - var step = new uw.controller.Details( new mw.Api(), { + let step = new uw.controller.Details( new mw.Api(), { maxSimultaneousConnections: 1 } ), testUpload = createTestUpload( this.sandbox ), @@ -92,8 +92,8 @@ assert.true( stepUiStub.called ); } ); - QUnit.test( 'canTransition', function ( assert ) { - var upload = {}, + QUnit.test( 'canTransition', ( assert ) => { + const upload = {}, step = new uw.controller.Details( new mw.Api(), { maxSimultaneousConnections: 1 } ); @@ -106,7 +106,7 @@ } ); QUnit.test( 'transitionAll', function ( assert ) { - var tostub, + let tostub, done = assert.async(), donestub = this.sandbox.stub(), ds = [ $.Deferred(), $.Deferred(), $.Deferred() ], @@ -133,7 +133,7 @@ ]; step.transitionAll().done( donestub ); - setTimeout( function () { + setTimeout( () => { calls = [ tostub.getCall( 0 ), tostub.getCall( 1 ), tostub.getCall( 2 ) ]; assert.strictEqual( calls[ 0 ].args[ 0 ].id, 15 ); @@ -141,11 +141,11 @@ ds[ 0 ].resolve(); ds[ 1 ].resolve(); - setTimeout( function () { + setTimeout( () => { assert.strictEqual( donestub.called, false ); ds[ 2 ].resolve(); - setTimeout( function () { + setTimeout( () => { assert.true( donestub.called ); done(); diff --git a/tests/qunit/controller/uw.controller.Step.test.js b/tests/qunit/controller/uw.controller.Step.test.js index a30f7ae..17a5901 100644 --- a/tests/qunit/controller/uw.controller.Step.test.js +++ b/tests/qunit/controller/uw.controller.Step.test.js @@ -18,8 +18,8 @@ ( function ( uw ) { QUnit.module( 'uw.controller.Step', QUnit.newMwEnvironment() ); - QUnit.test( 'Constructor sanity test', function ( assert ) { - var step = new uw.controller.Step( { on: function () {} }, new mw.Api(), {} ); + QUnit.test( 'Constructor sanity test', ( assert ) => { + const step = new uw.controller.Step( { on: function () {} }, new mw.Api(), {} ); assert.true( !!step ); assert.true( !!step.ui ); } ); diff --git a/tests/qunit/controller/uw.controller.Thanks.test.js b/tests/qunit/controller/uw.controller.Thanks.test.js index c19f4d5..0929619 100644 --- a/tests/qunit/controller/uw.controller.Thanks.test.js +++ b/tests/qunit/controller/uw.controller.Thanks.test.js @@ -18,15 +18,15 @@ ( function ( uw ) { QUnit.module( 'uw.controller.Thanks', QUnit.newMwEnvironment() ); - QUnit.test( 'Constructor sanity test', function ( assert ) { - var step = new uw.controller.Thanks( new mw.Api(), { display: { thanksLabel: 'Thanks!' } } ); + QUnit.test( 'Constructor sanity test', ( assert ) => { + const step = new uw.controller.Thanks( new mw.Api(), { display: { thanksLabel: 'Thanks!' } } ); assert.true( !!step ); assert.true( step instanceof uw.controller.Step ); assert.true( !!step.ui ); } ); QUnit.test( 'load', function ( assert ) { - var step = new uw.controller.Thanks( new mw.Api(), {} ), + const step = new uw.controller.Thanks( new mw.Api(), {} ), auStub = this.sandbox.stub( step.ui, 'addUpload' ); this.sandbox.stub( step.ui, 'load' ); @@ -39,8 +39,8 @@ assert.strictEqual( auStub.callCount, 3 ); } ); - QUnit.test( 'Custom button configuration', function ( assert ) { - var config = { + QUnit.test( 'Custom button configuration', ( assert ) => { + const config = { display: { homeButton: { label: 'This is just a test', diff --git a/tests/qunit/controller/uw.controller.Tutorial.test.js b/tests/qunit/controller/uw.controller.Tutorial.test.js index 2a780a4..86122c1 100644 --- a/tests/qunit/controller/uw.controller.Tutorial.test.js +++ b/tests/qunit/controller/uw.controller.Tutorial.test.js @@ -18,8 +18,8 @@ ( function ( uw ) { QUnit.module( 'uw.controller.Tutorial', QUnit.newMwEnvironment() ); - QUnit.test( 'Constructor sanity test', function ( assert ) { - var step = new uw.controller.Tutorial( new mw.Api() ); + QUnit.test( 'Constructor sanity test', ( assert ) => { + const step = new uw.controller.Tutorial( new mw.Api() ); assert.true( !!step ); assert.true( step instanceof uw.controller.Step ); assert.true( !!step.ui ); @@ -27,7 +27,7 @@ } ); QUnit.test( 'setSkipPreference', function ( assert ) { - var mnStub, + let mnStub, api = new mw.Api(), step = new uw.controller.Tutorial( api ), acwStub = { release: this.sandbox.stub() }, diff --git a/tests/qunit/controller/uw.controller.Upload.test.js b/tests/qunit/controller/uw.controller.Upload.test.js index 4cd12dd..09febdd 100644 --- a/tests/qunit/controller/uw.controller.Upload.test.js +++ b/tests/qunit/controller/uw.controller.Upload.test.js @@ -18,8 +18,8 @@ ( function ( uw ) { QUnit.module( 'uw.controller.Upload', QUnit.newMwEnvironment() ); - QUnit.test( 'Constructor sanity test', function ( assert ) { - var step = new uw.controller.Upload( new mw.Api(), { + QUnit.test( 'Constructor sanity test', ( assert ) => { + const step = new uw.controller.Upload( new mw.Api(), { maxUploads: 10, maxSimultaneousConnections: 3 } ); @@ -29,7 +29,7 @@ } ); QUnit.test( 'updateFileCounts', function ( assert ) { - var step = new uw.controller.Upload( new mw.Api(), { + const step = new uw.controller.Upload( new mw.Api(), { maxUploads: 5, maxSimultaneousConnections: 3 } ), @@ -50,8 +50,8 @@ assert.true( ufcStub.calledWith( true, false ) ); } ); - QUnit.test( 'canTransition', function ( assert ) { - var upload = {}, + QUnit.test( 'canTransition', ( assert ) => { + const upload = {}, step = new uw.controller.Upload( new mw.Api(), { maxSimultaneousConnections: 1 } ); @@ -64,7 +64,7 @@ } ); QUnit.test( 'transitionOne', function ( assert ) { - var upload = { + const upload = { start: this.sandbox.stub() }, step = new uw.controller.Upload( new mw.Api(), { diff --git a/tests/qunit/mw.UploadWizardLicenseInput.test.js b/tests/qunit/mw.UploadWizardLicenseInput.test.js index f135b4b..2f84303 100644 --- a/tests/qunit/mw.UploadWizardLicenseInput.test.js +++ b/tests/qunit/mw.UploadWizardLicenseInput.test.js @@ -13,8 +13,8 @@ QUnit.module( 'ext.uploadWizardLicenseInput', QUnit.newMwEnvironment( { } } ) ); -QUnit.test( 'Smoke test', function ( assert ) { - var config = { type: 'radio', licenses: [] }, +QUnit.test( 'Smoke test', ( assert ) => { + let config = { type: 'radio', licenses: [] }, $fixture = $( '<div>' ), uwLicenseInput; @@ -23,8 +23,8 @@ QUnit.test( 'Smoke test', function ( assert ) { assert.true( !!uwLicenseInput, 'LicenseInput object created !' ); } ); -QUnit.test( 'createInputs()', function ( assert ) { - var config = { type: 'radio', licenses: [ 'cc-by-sa-3.0' ] }, +QUnit.test( 'createInputs()', ( assert ) => { + let config = { type: 'radio', licenses: [ 'cc-by-sa-3.0' ] }, $fixture = $( '<div>' ), uwLicenseInput, $input, @@ -42,8 +42,8 @@ QUnit.test( 'createInputs()', function ( assert ) { assert.strictEqual( $label.length, 1, 'Label created.' ); } ); -QUnit.test( 'createGroupedInputs()', function ( assert ) { - var config = { +QUnit.test( 'createGroupedInputs()', ( assert ) => { + let config = { type: 'checkbox', licenseGroups: [ { diff --git a/tests/qunit/mw.UploadWizardUpload.test.js b/tests/qunit/mw.UploadWizardUpload.test.js index ad76777..0d7673d 100644 --- a/tests/qunit/mw.UploadWizardUpload.test.js +++ b/tests/qunit/mw.UploadWizardUpload.test.js @@ -19,7 +19,7 @@ QUnit.module( 'mw.UploadWizardUpload', QUnit.newMwEnvironment() ); function createUpload( filename ) { - var upload, + let upload, oldconf = mw.UploadWizard.config; mw.UploadWizard.config = {}; @@ -39,14 +39,14 @@ return upload; } - QUnit.test( 'constructor sanity test', function ( assert ) { - var upload = createUpload(); + QUnit.test( 'constructor sanity test', ( assert ) => { + const upload = createUpload(); assert.true( !!upload ); } ); - QUnit.test( 'getBasename', function ( assert ) { - var upload; + QUnit.test( 'getBasename', ( assert ) => { + let upload; upload = createUpload( 'path/to/filename.png' ); assert.strictEqual( upload.getBasename(), 'filename.png', 'Path is stripped' ); diff --git a/tests/qunit/mw.fileApi.test.js b/tests/qunit/mw.fileApi.test.js index 9405e7c..cde0c62 100644 --- a/tests/qunit/mw.fileApi.test.js +++ b/tests/qunit/mw.fileApi.test.js @@ -19,7 +19,7 @@ QUnit.module( 'mw.fileApi', QUnit.newMwEnvironment() ); QUnit.test( 'isPreviewableFile', function ( assert ) { - var testFile = {}; + const testFile = {}; testFile.type = 'image/png'; testFile.size = 5 * 1024 * 1024; @@ -43,7 +43,7 @@ } ); QUnit.test( 'isPreviewableVideo', function ( assert ) { - var result, testFile = {}, + let result, testFile = {}, fakeVideo = { canPlayType: this.sandbox.stub().returns( 'yes' ) }; diff --git a/tests/qunit/transports/mw.FormDataTransport.test.js b/tests/qunit/transports/mw.FormDataTransport.test.js index 76b9c4b..f6c3a87 100644 --- a/tests/qunit/transports/mw.FormDataTransport.test.js +++ b/tests/qunit/transports/mw.FormDataTransport.test.js @@ -19,7 +19,7 @@ QUnit.module( 'mw.FormDataTransport', QUnit.newMwEnvironment() ); function createTransport( chunkSize, api ) { - var config; + let config; chunkSize = chunkSize || 0; api = api || {}; @@ -33,14 +33,14 @@ return new mw.FormDataTransport( api, {}, config ); } - QUnit.test( 'Constructor sanity test', function ( assert ) { - var transport = createTransport(); + QUnit.test( 'Constructor sanity test', ( assert ) => { + const transport = createTransport(); assert.true( !!transport ); } ); QUnit.test( 'abort', function ( assert ) { - var transport = createTransport( 0 ), + const transport = createTransport( 0 ), request = $.Deferred().promise( { abort: this.sandbox.stub() } ); transport.request = request; @@ -53,8 +53,8 @@ assert.true( transport.aborted ); } ); - QUnit.test( 'createParams', function ( assert ) { - var transport = createTransport( 10 ), + QUnit.test( 'createParams', ( assert ) => { + const transport = createTransport( 10 ), params = transport.createParams( 'foobar.jpg', 0 ); assert.true( !!params ); @@ -64,7 +64,7 @@ } ); QUnit.test( 'post', function ( assert ) { - var stub = this.sandbox.stub(), + const stub = this.sandbox.stub(), // post() works on a promise and binds .then, so we have to make // sure it actually is a promise, but also that it calls our stub transport = createTransport( 10, { post: function () { @@ -82,7 +82,7 @@ } ); QUnit.test( 'upload', function ( assert ) { - var request, + let request, transport = createTransport( 10, new mw.Api() ), fakeFile = { name: 'test file for fdt.jpg', @@ -103,7 +103,7 @@ } ); QUnit.test( 'uploadChunk', function ( assert ) { - var request, + let request, transport = createTransport( 10, new mw.Api() ), fakeFile = { name: 'test file for fdt.jpg', @@ -132,7 +132,7 @@ // test invalid server response (in missing 'stage' param) QUnit.test( 'checkStatus invalid API response', function ( assert ) { - var done = assert.async(), + const done = assert.async(), transport = createTransport( 10, new mw.Api() ), tstub = this.sandbox.stub(), poststub = this.sandbox.stub( transport.api, 'post' ), @@ -143,7 +143,7 @@ postd.resolve( { upload: { result: 'Poll' } } ); // call tstub upon checkStatus failure, and verify it got called correctly - transport.checkStatus().fail( tstub, function () { + transport.checkStatus().fail( tstub, () => { assert.true( tstub.calledWith( 'server-error', { errors: [ { code: 'server-error', html: mw.message( 'api-clientside-error-invalidresponse' ).parse() @@ -154,7 +154,7 @@ // test retry after server responds upload is still incomplete QUnit.test( 'checkStatus retry', function ( assert ) { - var transport = createTransport( 10, new mw.Api() ), + const transport = createTransport( 10, new mw.Api() ), usstub = this.sandbox.stub(), poststub = this.sandbox.stub( transport.api, 'post' ), postd = $.Deferred(), @@ -176,14 +176,14 @@ // confirm that, once second API call was successful, status resolves, // 2 API calls have gone out & the failed call updates stage accordingly - return transport.checkStatus().done( function () { + return transport.checkStatus().done( () => { assert.true( poststub.calledTwice ); assert.true( usstub.firstCall.calledWith( 'queued' ) ); } ); } ); QUnit.test( 'checkStatus success', function ( assert ) { - var transport = createTransport( 10, new mw.Api() ), + const transport = createTransport( 10, new mw.Api() ), tstub = this.sandbox.stub(), usstub = this.sandbox.stub(), poststub = this.sandbox.stub( transport.api, 'post' ), @@ -195,14 +195,14 @@ poststub.returns( postd.promise() ); postd.resolve( 'testing' ); - return transport.checkStatus().done( tstub, function () { + return transport.checkStatus().done( tstub, () => { assert.true( tstub.calledWith( 'testing' ) ); assert.false( usstub.called ); } ); } ); QUnit.test( 'checkStatus error API response', function ( assert ) { - var done = assert.async(), + const done = assert.async(), transport = createTransport( 10, new mw.Api() ), tstub = this.sandbox.stub(), usstub = this.sandbox.stub(), @@ -215,7 +215,7 @@ poststub.returns( postd.promise() ); postd.reject( 'testing', { error: 'testing' } ); - transport.checkStatus().fail( tstub, function () { + transport.checkStatus().fail( tstub, () => { assert.true( tstub.calledWith( 'testing', { error: 'testing' } ) ); assert.false( usstub.called ); done(); diff --git a/tests/qunit/uw.ConcurrentQueue.test.js b/tests/qunit/uw.ConcurrentQueue.test.js index 2bf97e4..c288d3e 100644 --- a/tests/qunit/uw.ConcurrentQueue.test.js +++ b/tests/qunit/uw.ConcurrentQueue.test.js @@ -25,7 +25,7 @@ // trigger the next one to execute, which would terminate immediately, // instead of giving time for a second new thingy to be added) function queueAction() { - var deferred = $.Deferred(); + const deferred = $.Deferred(); setTimeout( deferred.resolve, 10 ); return deferred.promise(); } @@ -33,9 +33,9 @@ // Asserts that the given stub functions were called in the given order. // SinonJS's assert.callOrder doesn't allow to check individual calls. function assertCalledInOrder() { - var calls, i, currSpyCall, nextSpyCall; + let calls, i, currSpyCall, nextSpyCall; // Map stubs to specific calls - calls = Array.prototype.map.call( arguments, function ( spy ) { + calls = Array.prototype.map.call( arguments, ( spy ) => { if ( !spy.assertCallsInOrderLastCall ) { spy.assertCallsInOrderLastCall = 0; } @@ -60,8 +60,8 @@ ); } - QUnit.test( 'Basic behavior', function ( assert ) { - var done, action, queue; + QUnit.test( 'Basic behavior', ( assert ) => { + let done, action, queue; done = assert.async(); action = sinon.spy( queueAction ); queue = new uw.ConcurrentQueue( { @@ -69,11 +69,11 @@ action: action } ); - queue.on( 'progress', function () { + queue.on( 'progress', () => { QUnit.assert.true( queue.running.length <= 3, 'No more than 3 items are executing' ); } ); - queue.on( 'complete', function () { + queue.on( 'complete', () => { // All items executed sinon.assert.callCount( action, 5 ); // All items executed in the expected order @@ -86,15 +86,15 @@ done(); } ); - [ 'a', 'b', 'c', 'd', 'e' ].forEach( function ( v ) { + [ 'a', 'b', 'c', 'd', 'e' ].forEach( ( v ) => { queue.addItem( v ); } ); queue.startExecuting(); } ); - QUnit.test( 'Event emitting', function ( assert ) { - var done, changeHandler, progressHandler, completeHandler, queue; + QUnit.test( 'Event emitting', ( assert ) => { + let done, changeHandler, progressHandler, completeHandler, queue; done = assert.async(); changeHandler = sinon.stub(); progressHandler = sinon.stub(); @@ -110,7 +110,7 @@ complete: completeHandler } ); - queue.on( 'complete', function () { + queue.on( 'complete', () => { sinon.assert.callCount( changeHandler, 3 ); sinon.assert.callCount( progressHandler, 3 ); sinon.assert.callCount( completeHandler, 1 ); @@ -134,8 +134,8 @@ queue.startExecuting(); } ); - QUnit.test( 'Restarting a completed queue', function ( assert ) { - var done, queue; + QUnit.test( 'Restarting a completed queue', ( assert ) => { + let done, queue; done = assert.async(); queue = new uw.ConcurrentQueue( { count: 3, @@ -146,12 +146,12 @@ queue.addItem( 'b' ); queue.addItem( 'c' ); - queue.once( 'complete', function () { + queue.once( 'complete', () => { QUnit.assert.equal( queue.completed, true ); queue.addItem( 'd' ); queue.addItem( 'e' ); - queue.once( 'complete', function () { + queue.once( 'complete', () => { QUnit.assert.equal( queue.completed, true ); done(); } ); @@ -162,15 +162,15 @@ queue.startExecuting(); } ); - QUnit.test( 'Empty queue completes', function ( assert ) { - var done, queue; + QUnit.test( 'Empty queue completes', ( assert ) => { + let done, queue; done = assert.async(); queue = new uw.ConcurrentQueue( { count: 3, action: queueAction } ); - queue.on( 'complete', function () { + queue.on( 'complete', () => { QUnit.assert.equal( queue.completed, true ); done(); @@ -179,8 +179,8 @@ queue.startExecuting(); } ); - QUnit.test( 'Adding new items while queue running', function ( assert ) { - var done, changeHandler, progressHandler, completeHandler, queue; + QUnit.test( 'Adding new items while queue running', ( assert ) => { + let done, changeHandler, progressHandler, completeHandler, queue; done = assert.async(); changeHandler = sinon.stub(); progressHandler = sinon.stub(); @@ -196,7 +196,7 @@ complete: completeHandler } ); - queue.on( 'complete', function () { + queue.on( 'complete', () => { sinon.assert.callCount( changeHandler, 6 ); sinon.assert.callCount( progressHandler, 6 ); sinon.assert.callCount( completeHandler, 1 ); @@ -223,11 +223,11 @@ queue.addItem( 'a' ); queue.addItem( 'b' ); queue.addItem( 'c' ); - queue.once( 'progress', function () { + queue.once( 'progress', () => { queue.addItem( 'd' ); queue.addItem( 'e' ); } ); - queue.on( 'progress', function () { + queue.on( 'progress', () => { if ( queue.done.length === 5 ) { queue.addItem( 'f' ); } @@ -235,8 +235,8 @@ queue.startExecuting(); } ); - QUnit.test( 'Deleting items while queue running', function ( assert ) { - var done, changeHandler, progressHandler, completeHandler, queue; + QUnit.test( 'Deleting items while queue running', ( assert ) => { + let done, changeHandler, progressHandler, completeHandler, queue; done = assert.async(); changeHandler = sinon.stub(); progressHandler = sinon.stub(); @@ -252,7 +252,7 @@ complete: completeHandler } ); - queue.on( 'complete', function () { + queue.on( 'complete', () => { sinon.assert.callCount( changeHandler, 8 ); sinon.assert.callCount( progressHandler, 4 ); sinon.assert.callCount( completeHandler, 1 ); @@ -282,18 +282,18 @@ queue.addItem( 'd' ); queue.addItem( 'e' ); queue.addItem( 'f' ); - queue.once( 'progress', function () { + queue.once( 'progress', () => { queue.removeItem( queue.queued[ 0 ] ); - queue.once( 'progress', function () { + queue.once( 'progress', () => { queue.removeItem( queue.queued[ 0 ] ); } ); } ); queue.startExecuting(); } ); - QUnit.test( 'Deleting currently running item', function ( assert ) { - var done, action, changeHandler, progressHandler, completeHandler, queue; + QUnit.test( 'Deleting currently running item', ( assert ) => { + let done, action, changeHandler, progressHandler, completeHandler, queue; done = assert.async(); action = sinon.spy( queueAction ); changeHandler = sinon.stub(); @@ -310,7 +310,7 @@ complete: completeHandler } ); - queue.on( 'complete', function () { + queue.on( 'complete', () => { // Every item in the queue was executed... sinon.assert.callCount( action, 4 ); @@ -342,14 +342,14 @@ queue.addItem( 'b' ); queue.addItem( 'c' ); queue.addItem( 'd' ); - queue.once( 'progress', function () { + queue.once( 'progress', () => { queue.removeItem( queue.running[ 0 ] ); } ); queue.startExecuting(); } ); - QUnit.test( 'Adding a new item when almost done', function ( assert ) { - var done, action, changeHandler, progressHandler, completeHandler, queue, onProgress; + QUnit.test( 'Adding a new item when almost done', ( assert ) => { + let done, action, changeHandler, progressHandler, completeHandler, queue, onProgress; done = assert.async(); // This test seems extra flaky and was occasionally failing, double the delays action = sinon.spy( queueAction ); @@ -367,7 +367,7 @@ complete: completeHandler } ); - queue.on( 'complete', function () { + queue.on( 'complete', () => { sinon.assert.callCount( action, 5 ); sinon.assert.callCount( changeHandler, 5 ); sinon.assert.callCount( progressHandler, 5 ); diff --git a/tests/qunit/uw.TitleDetailsWidget.test.js b/tests/qunit/uw.TitleDetailsWidget.test.js index 8992c60..571ab1c 100644 --- a/tests/qunit/uw.TitleDetailsWidget.test.js +++ b/tests/qunit/uw.TitleDetailsWidget.test.js @@ -1,7 +1,7 @@ ( function ( uw ) { 'use strict'; - var fileNs, makeTitleInFileNSCases; + let fileNs, makeTitleInFileNSCases; fileNs = mw.config.get( 'wgFormattedNamespaces' )[ 6 ]; makeTitleInFileNSCases = [ { filename: 'foo.png', @@ -35,11 +35,11 @@ QUnit.module( 'uw.TitleDetailsWidget', QUnit.newMwEnvironment() ); - QUnit.test( '.static.makeTitleInFileNS()', function ( assert ) { - var makeTitleInFileNS = uw.TitleDetailsWidget.static.makeTitleInFileNS; + QUnit.test( '.static.makeTitleInFileNS()', ( assert ) => { + const makeTitleInFileNS = uw.TitleDetailsWidget.static.makeTitleInFileNS; - makeTitleInFileNSCases.forEach( function ( test ) { - var title = makeTitleInFileNS( test.filename ); + makeTitleInFileNSCases.forEach( ( test ) => { + const title = makeTitleInFileNS( test.filename ); assert.strictEqual( title ? title.getPrefixedText() : title, test.prefixedText, -- 2.39.5 --- end ---