mediawiki/extensions/WikiEditor (master)

sourcepatches
From 3cd2dfb88cc4a4e3ead2d9fb65d1d68f85cf94b1 Mon Sep 17 00:00:00 2001
From: libraryupgrader <tools.libraryupgrader@tools.wmflabs.org>
Date: Mon, 8 Mar 2021 09:54:06 +0000
Subject: [PATCH] build: Updating eslint-config-wikimedia to 0.18.2

Additional changes:
* Dropped .php5 and .inc files from .phpcs.xml (T200956).

Change-Id: Ice271e32dc3c36e9f012434b585952eda55dd036
---
 .phpcs.xml        |   2 +-
 package-lock.json | 320 +++++++++++++++++++++++-----------------------
 package.json      |   2 +-
 3 files changed, 159 insertions(+), 165 deletions(-)

diff --git a/.phpcs.xml b/.phpcs.xml
index 31dbc80..0fcdae0 100644
--- a/.phpcs.xml
+++ b/.phpcs.xml
@@ -6,6 +6,6 @@
 		<exclude name="MediaWiki.WhiteSpace.SpaceBeforeSingleLineComment.NewLineComment" />
 	</rule>
 	<file>.</file>
-	<arg name="extensions" value="php,php5,inc"/>
+	<arg name="extensions" value="php"/>
 	<arg name="encoding" value="UTF-8"/>
 </ruleset>
diff --git a/package-lock.json b/package-lock.json
index 1d07b8d..38a698e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -280,9 +280,9 @@
 			}
 		},
 		"@eslint/eslintrc": {
-			"version": "0.3.0",
-			"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.3.0.tgz",
-			"integrity": "sha512-1JTKgrOKAHVivSvOYw+sJOunkBjUOvjqWk1DPja7ZFhIS2mX/4EgTT8M7eTK9jrKhL/FvXXEbQwIs3pg1xp3dg==",
+			"version": "0.4.0",
+			"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz",
+			"integrity": "sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==",
 			"dev": true,
 			"requires": {
 				"ajv": "^6.12.4",
@@ -292,23 +292,10 @@
 				"ignore": "^4.0.6",
 				"import-fresh": "^3.2.1",
 				"js-yaml": "^3.13.1",
-				"lodash": "^4.17.20",
 				"minimatch": "^3.0.4",
 				"strip-json-comments": "^3.1.1"
 			},
 			"dependencies": {
-				"ajv": {
-					"version": "6.12.6",
-					"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
-					"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
-					"dev": true,
-					"requires": {
-						"fast-deep-equal": "^3.1.1",
-						"fast-json-stable-stringify": "^2.0.0",
-						"json-schema-traverse": "^0.4.1",
-						"uri-js": "^4.2.2"
-					}
-				},
 				"globals": {
 					"version": "12.4.0",
 					"resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
@@ -317,22 +304,6 @@
 					"requires": {
 						"type-fest": "^0.8.1"
 					}
-				},
-				"import-fresh": {
-					"version": "3.3.0",
-					"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
-					"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
-					"dev": true,
-					"requires": {
-						"parent-module": "^1.0.0",
-						"resolve-from": "^4.0.0"
-					}
-				},
-				"lodash": {
-					"version": "4.17.20",
-					"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
-					"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
-					"dev": true
 				}
 			}
 		},
@@ -464,9 +435,9 @@
 			"dev": true
 		},
 		"ajv": {
-			"version": "6.12.0",
-			"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz",
-			"integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==",
+			"version": "6.12.6",
+			"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+			"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
 			"dev": true,
 			"requires": {
 				"fast-deep-equal": "^3.1.1",
@@ -903,9 +874,9 @@
 			"dev": true
 		},
 		"core-js": {
-			"version": "3.8.3",
-			"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.3.tgz",
-			"integrity": "sha512-KPYXeVZYemC2TkNEkX/01I+7yd+nX3KddKwZ1Ww7SKWdI2wQprSgLmrTddT8nw92AjEklTsPBoSdQBhbI1bQ6Q==",
+			"version": "3.9.1",
+			"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.9.1.tgz",
+			"integrity": "sha512-gSjRvzkxQc1zjM/5paAmL4idJBFzuJoo+jDjF1tStYFMV2ERfD02HhahhCGXUyHxQRG4yFKVSdO6g62eoRMcDg==",
 			"dev": true
 		},
 		"core-util-is": {
@@ -1353,13 +1324,13 @@
 			"dev": true
 		},
 		"eslint": {
-			"version": "7.18.0",
-			"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.18.0.tgz",
-			"integrity": "sha512-fbgTiE8BfUJZuBeq2Yi7J3RB3WGUQ9PNuNbmgi6jt9Iv8qrkxfy19Ds3OpL1Pm7zg3BtTVhvcUZbIRQ0wmSjAQ==",
+			"version": "7.21.0",
+			"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.21.0.tgz",
+			"integrity": "sha512-W2aJbXpMNofUp0ztQaF40fveSsJBjlSCSWpy//gzfTvwC+USs/nceBrKmlJOiM8r1bLwP2EuYkCqArn/6QTIgg==",
 			"dev": true,
 			"requires": {
-				"@babel/code-frame": "^7.0.0",
-				"@eslint/eslintrc": "^0.3.0",
+				"@babel/code-frame": "7.12.11",
+				"@eslint/eslintrc": "^0.4.0",
 				"ajv": "^6.10.0",
 				"chalk": "^4.0.0",
 				"cross-spawn": "^7.0.2",
@@ -1370,9 +1341,9 @@
 				"eslint-utils": "^2.1.0",
 				"eslint-visitor-keys": "^2.0.0",
 				"espree": "^7.3.1",
-				"esquery": "^1.2.0",
+				"esquery": "^1.4.0",
 				"esutils": "^2.0.2",
-				"file-entry-cache": "^6.0.0",
+				"file-entry-cache": "^6.0.1",
 				"functional-red-black-tree": "^1.0.1",
 				"glob-parent": "^5.0.0",
 				"globals": "^12.1.0",
@@ -1397,13 +1368,43 @@
 				"v8-compile-cache": "^2.0.3"
 			},
 			"dependencies": {
-				"ansi-styles": {
-					"version": "4.3.0",
-					"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-					"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+				"@babel/code-frame": {
+					"version": "7.12.11",
+					"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
+					"integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==",
 					"dev": true,
 					"requires": {
-						"color-convert": "^2.0.1"
+						"@babel/highlight": "^7.10.4"
+					}
+				},
+				"@babel/helper-validator-identifier": {
+					"version": "7.12.11",
+					"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz",
+					"integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==",
+					"dev": true
+				},
+				"@babel/highlight": {
+					"version": "7.13.8",
+					"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.8.tgz",
+					"integrity": "sha512-4vrIhfJyfNf+lCtXC2ck1rKSzDwciqF7IWFhXXrSOUC2O5DrVp+w4c6ed4AllTxhTkUP5x2tYj41VaxdVMMRDw==",
+					"dev": true,
+					"requires": {
+						"@babel/helper-validator-identifier": "^7.12.11",
+						"chalk": "^2.0.0",
+						"js-tokens": "^4.0.0"
+					},
+					"dependencies": {
+						"chalk": {
+							"version": "2.4.2",
+							"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+							"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+							"dev": true,
+							"requires": {
+								"ansi-styles": "^3.2.1",
+								"escape-string-regexp": "^1.0.5",
+								"supports-color": "^5.3.0"
+							}
+						}
 					}
 				},
 				"chalk": {
@@ -1414,6 +1415,26 @@
 					"requires": {
 						"ansi-styles": "^4.1.0",
 						"supports-color": "^7.1.0"
+					},
+					"dependencies": {
+						"ansi-styles": {
+							"version": "4.3.0",
+							"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+							"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+							"dev": true,
+							"requires": {
+								"color-convert": "^2.0.1"
+							}
+						},
+						"supports-color": {
+							"version": "7.2.0",
+							"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+							"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+							"dev": true,
+							"requires": {
+								"has-flag": "^4.0.0"
+							}
+						}
 					}
 				},
 				"color-convert": {
@@ -1431,39 +1452,12 @@
 					"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
 					"dev": true
 				},
-				"eslint-scope": {
-					"version": "5.1.1",
-					"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
-					"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
-					"dev": true,
-					"requires": {
-						"esrecurse": "^4.3.0",
-						"estraverse": "^4.1.1"
-					}
-				},
 				"eslint-visitor-keys": {
 					"version": "2.0.0",
 					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz",
 					"integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==",
 					"dev": true
 				},
-				"esrecurse": {
-					"version": "4.3.0",
-					"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
-					"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
-					"dev": true,
-					"requires": {
-						"estraverse": "^5.2.0"
-					},
-					"dependencies": {
-						"estraverse": {
-							"version": "5.2.0",
-							"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
-							"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
-							"dev": true
-						}
-					}
-				},
 				"globals": {
 					"version": "12.4.0",
 					"resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
@@ -1480,9 +1474,9 @@
 					"dev": true
 				},
 				"lodash": {
-					"version": "4.17.20",
-					"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
-					"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+					"version": "4.17.21",
+					"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+					"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
 					"dev": true
 				},
 				"semver": {
@@ -1493,22 +1487,13 @@
 					"requires": {
 						"lru-cache": "^6.0.0"
 					}
-				},
-				"supports-color": {
-					"version": "7.2.0",
-					"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-					"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-					"dev": true,
-					"requires": {
-						"has-flag": "^4.0.0"
-					}
 				}
 			}
 		},
 		"eslint-config-wikimedia": {
-			"version": "0.18.1",
-			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.18.1.tgz",
-			"integrity": "sha512-93nHVH4CGxYwelbTjJQLr0xqn4XIe9WwWeGL4wMnELZW/Aceg52aT7AgIdV0659ReLzrCgxLPDvbeqB47LjBTQ==",
+			"version": "0.18.2",
+			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.18.2.tgz",
+			"integrity": "sha512-OllUgce2qODU/6481jg/a1kT/dygBDY1xhxXuAiQdYxJARV6LXyuiJw+wl1QBQz+huV9NXRxoJGC3L6x/NzC4g==",
 			"dev": true,
 			"requires": {
 				"eslint": "^7.17.0",
@@ -1516,12 +1501,12 @@
 				"eslint-plugin-es": "^4.1.0",
 				"eslint-plugin-jsdoc": "^30.7.13",
 				"eslint-plugin-json-es": "^1.5.1",
-				"eslint-plugin-mediawiki": "^0.2.6",
+				"eslint-plugin-mediawiki": "^0.2.7",
 				"eslint-plugin-mocha": "^8.0.0",
 				"eslint-plugin-no-jquery": "^2.5.0",
 				"eslint-plugin-node": "^11.1.0",
 				"eslint-plugin-qunit": "^5.2.0",
-				"eslint-plugin-vue": "^7.4.1",
+				"eslint-plugin-vue": "^7.7.0",
 				"eslint-plugin-wdio": "^6.0.12"
 			}
 		},
@@ -1542,9 +1527,9 @@
 			},
 			"dependencies": {
 				"caniuse-lite": {
-					"version": "1.0.30001181",
-					"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001181.tgz",
-					"integrity": "sha512-m5ul/ARCX50JB8BSNM+oiPmQrR5UmngaQ3QThTTp5HcIIQGP/nPBs82BYLE+tigzm3VW+F4BJIhUyaVtEweelQ==",
+					"version": "1.0.30001197",
+					"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001197.tgz",
+					"integrity": "sha512-8aE+sqBqtXz4G8g35Eg/XEaFr2N7rd/VQ6eABGBmNtcB8cN6qNJhMi6oSFy4UWWZgqgL3filHT8Nha4meu3tsw==",
 					"dev": true
 				},
 				"semver": {
@@ -1590,9 +1575,9 @@
 					}
 				},
 				"lodash": {
-					"version": "4.17.20",
-					"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
-					"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+					"version": "4.17.21",
+					"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+					"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
 					"dev": true
 				},
 				"semver": {
@@ -1607,42 +1592,37 @@
 			}
 		},
 		"eslint-plugin-json-es": {
-			"version": "1.5.1",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-json-es/-/eslint-plugin-json-es-1.5.1.tgz",
-			"integrity": "sha512-YMzAWMcmKOYWiH0MsN3JOr0AdtZ2Rvmk3YmscsX1rHYJZRsL4KRo+yj9ktRk7S7mgy+G5TORWJ5D3/vH/u7R5A==",
+			"version": "1.5.3",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-json-es/-/eslint-plugin-json-es-1.5.3.tgz",
+			"integrity": "sha512-9wWjwhoN+ipMel70ktkWy0H7jj9sm5OAbAy3N3F3AT0swpIofVsIjDXyjGZJwSzy9tZzDtI/aKIj2WsqMHw2QA==",
 			"dev": true,
 			"requires": {
-				"eslint-visitor-keys": "^1.3.0",
+				"eslint-visitor-keys": "^2.0.0",
 				"espree": "^7.3.1"
+			},
+			"dependencies": {
+				"eslint-visitor-keys": {
+					"version": "2.0.0",
+					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz",
+					"integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==",
+					"dev": true
+				}
 			}
 		},
 		"eslint-plugin-mediawiki": {
-			"version": "0.2.6",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.2.6.tgz",
-			"integrity": "sha512-e7gx15H39ceam9AnSr6DDyfhMM9L43PVagHzclH3CF33DvWKi/OA+j2dqzJTuJcl5P/EmVIQHG5qoTaepkADsw==",
+			"version": "0.2.7",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.2.7.tgz",
+			"integrity": "sha512-2ZvPvLEwCIqrJxV1349bdX5Q03c30WccuUMCfB1Gh2IVxbBSrY0gbzOk/gPZeYigVhODt9xoFWUCIz8jwTWfrA==",
 			"dev": true,
 			"requires": {
-				"eslint-plugin-vue": "^6.2.2",
+				"eslint-plugin-vue": "^7.7.0",
 				"upath": "^1.2.0"
-			},
-			"dependencies": {
-				"eslint-plugin-vue": {
-					"version": "6.2.2",
-					"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-6.2.2.tgz",
-					"integrity": "sha512-Nhc+oVAHm0uz/PkJAWscwIT4ijTrK5fqNqz9QB1D35SbbuMG1uB6Yr5AJpvPSWg+WOw7nYNswerYh0kOk64gqQ==",
-					"dev": true,
-					"requires": {
-						"natural-compare": "^1.4.0",
-						"semver": "^5.6.0",
-						"vue-eslint-parser": "^7.0.0"
-					}
-				}
 			}
 		},
 		"eslint-plugin-mocha": {
-			"version": "8.0.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-8.0.0.tgz",
-			"integrity": "sha512-n67etbWDz6NQM+HnTwZHyBwz/bLlYPOxUbw7bPuCyFujv7ZpaT/Vn6KTAbT02gf7nRljtYIjWcTxK/n8a57rQQ==",
+			"version": "8.1.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-8.1.0.tgz",
+			"integrity": "sha512-1EgHvXKRl7W3mq3sntZAi5T24agRMyiTPL4bSXe+B4GksYOjAPEWYx+J3eJg4It1l2NMNZJtk0gQyQ6mfiPhQg==",
 			"dev": true,
 			"requires": {
 				"eslint-utils": "^2.1.0",
@@ -1704,15 +1684,15 @@
 			}
 		},
 		"eslint-plugin-vue": {
-			"version": "7.5.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-7.5.0.tgz",
-			"integrity": "sha512-QnMMTcyV8PLxBz7QQNAwISSEs6LYk2LJvGlxalXvpCtfKnqo7qcY0aZTIxPe8QOnHd7WCwiMZLOJzg6A03T0Gw==",
+			"version": "7.7.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-7.7.0.tgz",
+			"integrity": "sha512-mYz4bpLGv5jx6YG/GvKkqbGSfV7uma2u1P3mLA41Q5vQl8W1MeuTneB8tfsLq6xxxesFubcrOC0BZBJ5R+eaCQ==",
 			"dev": true,
 			"requires": {
 				"eslint-utils": "^2.1.0",
 				"natural-compare": "^1.4.0",
 				"semver": "^7.3.2",
-				"vue-eslint-parser": "^7.4.1"
+				"vue-eslint-parser": "^7.6.0"
 			},
 			"dependencies": {
 				"semver": {
@@ -1783,18 +1763,18 @@
 			"dev": true
 		},
 		"esquery": {
-			"version": "1.3.1",
-			"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz",
-			"integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==",
+			"version": "1.4.0",
+			"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
+			"integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
 			"dev": true,
 			"requires": {
 				"estraverse": "^5.1.0"
 			},
 			"dependencies": {
 				"estraverse": {
-					"version": "5.1.0",
-					"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz",
-					"integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==",
+					"version": "5.2.0",
+					"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+					"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
 					"dev": true
 				}
 			}
@@ -2048,9 +2028,9 @@
 			}
 		},
 		"file-entry-cache": {
-			"version": "6.0.0",
-			"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz",
-			"integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==",
+			"version": "6.0.1",
+			"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+			"integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
 			"dev": true,
 			"requires": {
 				"flat-cache": "^3.0.4"
@@ -2398,12 +2378,11 @@
 			},
 			"dependencies": {
 				"ansi-styles": {
-					"version": "4.2.1",
-					"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
-					"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+					"version": "4.3.0",
+					"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+					"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
 					"dev": true,
 					"requires": {
-						"@types/color-name": "^1.1.1",
 						"color-convert": "^2.0.1"
 					}
 				},
@@ -2439,9 +2418,9 @@
 					"dev": true
 				},
 				"supports-color": {
-					"version": "7.1.0",
-					"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
-					"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+					"version": "7.2.0",
+					"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+					"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
 					"dev": true,
 					"requires": {
 						"has-flag": "^4.0.0"
@@ -2751,9 +2730,9 @@
 			"dev": true
 		},
 		"import-fresh": {
-			"version": "3.1.0",
-			"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz",
-			"integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==",
+			"version": "3.3.0",
+			"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+			"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
 			"dev": true,
 			"requires": {
 				"parent-module": "^1.0.0",
@@ -3051,9 +3030,9 @@
 			"dev": true
 		},
 		"js-yaml": {
-			"version": "3.13.1",
-			"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
-			"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+			"version": "3.14.1",
+			"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+			"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
 			"dev": true,
 			"requires": {
 				"argparse": "^1.0.7",
@@ -5204,9 +5183,9 @@
 			},
 			"dependencies": {
 				"ajv": {
-					"version": "7.0.3",
-					"resolved": "https://registry.npmjs.org/ajv/-/ajv-7.0.3.tgz",
-					"integrity": "sha512-R50QRlXSxqXcQP5SvKUrw8VZeypvo12i2IX0EeR5PiZ7bEKeHWgzgo264LDadUsCU42lTJVhFikTqJwNeH34gQ==",
+					"version": "7.2.1",
+					"resolved": "https://registry.npmjs.org/ajv/-/ajv-7.2.1.tgz",
+					"integrity": "sha512-+nu0HDv7kNSOua9apAVc979qd932rrZeb3WOvoiD31A/p1mIE5/9bN2027pE2rOPYEdS3UHzsvof4hY+lM9/WQ==",
 					"dev": true,
 					"requires": {
 						"fast-deep-equal": "^3.1.1",
@@ -5222,9 +5201,9 @@
 					"dev": true
 				},
 				"lodash": {
-					"version": "4.17.20",
-					"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
-					"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+					"version": "4.17.21",
+					"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+					"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
 					"dev": true
 				}
 			}
@@ -5485,9 +5464,9 @@
 			"dev": true
 		},
 		"v8-compile-cache": {
-			"version": "2.1.0",
-			"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz",
-			"integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==",
+			"version": "2.3.0",
+			"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
+			"integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
 			"dev": true
 		},
 		"v8flags": {
@@ -5539,16 +5518,16 @@
 			}
 		},
 		"vue-eslint-parser": {
-			"version": "7.4.1",
-			"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.4.1.tgz",
-			"integrity": "sha512-AFvhdxpFvliYq1xt/biNBslTHE/zbEvSnr1qfHA/KxRIpErmEDrQZlQnvEexednRHmLfDNOMuDYwZL5xkLzIXQ==",
+			"version": "7.6.0",
+			"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.6.0.tgz",
+			"integrity": "sha512-QXxqH8ZevBrtiZMZK0LpwaMfevQi9UL7lY6Kcp+ogWHC88AuwUPwwCIzkOUc1LR4XsYAt/F9yHXAB/QoD17QXA==",
 			"dev": true,
 			"requires": {
 				"debug": "^4.1.1",
 				"eslint-scope": "^5.0.0",
 				"eslint-visitor-keys": "^1.1.0",
 				"espree": "^6.2.1",
-				"esquery": "^1.0.1",
+				"esquery": "^1.4.0",
 				"lodash": "^4.17.15"
 			},
 			"dependencies": {
@@ -5562,6 +5541,21 @@
 						"acorn-jsx": "^5.2.0",
 						"eslint-visitor-keys": "^1.1.0"
 					}
+				},
+				"esquery": {
+					"version": "1.4.0",
+					"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
+					"integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+					"dev": true,
+					"requires": {
+						"estraverse": "^5.1.0"
+					}
+				},
+				"estraverse": {
+					"version": "5.2.0",
+					"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+					"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+					"dev": true
 				}
 			}
 		},
diff --git a/package.json b/package.json
index 13a1f04..503c274 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
 		"test": "grunt test"
 	},
 	"devDependencies": {
-		"eslint-config-wikimedia": "0.18.1",
+		"eslint-config-wikimedia": "0.18.2",
 		"grunt": "1.3.0",
 		"grunt-banana-checker": "0.9.0",
 		"grunt-eslint": "23.0.0",
-- 
2.20.1

$ date
Mon Mar  8 09:48:06 UTC 2021

$ git clone file:///srv/git/mediawiki-extensions-WikiEditor.git repo --depth=1 -b master
Cloning into 'repo'...

$ git config user.name libraryupgrader

$ git config user.email tools.libraryupgrader@tools.wmflabs.org

$ git submodule update --init

$ grr init
Installed commit-msg hook.

$ git show-ref refs/heads/master
efafd4ca0c137158b7ccbcb7a412c1b29ab8d04a refs/heads/master

$ composer install
Loading composer repositories with package information
Warning from https://repo.packagist.org: You are using an outdated version of Composer. Composer 2 is now available and you should upgrade. See https://getcomposer.org/2
Updating dependencies (including require-dev)
Package operations: 31 installs, 0 updates, 0 removals
  - Installing squizlabs/php_codesniffer (3.5.8): Loading from cache
  - Installing composer/spdx-licenses (1.5.5): Loading from cache
  - Installing composer/semver (3.2.4): Loading from cache
  - Installing mediawiki/mediawiki-codesniffer (v35.0.0): Loading from cache
  - Installing symfony/polyfill-php80 (v1.22.1): Loading from cache
  - Installing symfony/polyfill-mbstring (v1.22.1): Loading from cache
  - Installing symfony/polyfill-intl-normalizer (v1.22.1): Loading from cache
  - Installing symfony/polyfill-intl-grapheme (v1.22.1): Loading from cache
  - Installing symfony/polyfill-ctype (v1.22.1): Loading from cache
  - Installing symfony/string (v5.2.4): Loading from cache
  - Installing psr/container (1.1.1): Loading from cache
  - Installing symfony/service-contracts (v2.2.0): Loading from cache
  - Installing symfony/polyfill-php73 (v1.22.1): Loading from cache
  - Installing symfony/console (v5.2.4): Loading from cache
  - Installing psr/log (1.1.3): Loading from cache
  - Installing sabre/event (5.1.2): Loading from cache
  - Installing netresearch/jsonmapper (v2.1.0): Loading from cache
  - Installing microsoft/tolerant-php-parser (v0.0.23): Loading from cache
  - Installing phpdocumentor/reflection-common (2.2.0): Loading from cache
  - Installing webmozart/assert (1.9.1): Loading from cache
  - Installing phpdocumentor/type-resolver (1.4.0): Loading from cache
  - Installing phpdocumentor/reflection-docblock (5.2.2): Loading from cache
  - Installing felixfbecker/advanced-json-rpc (v3.2.0): Loading from cache
  - Installing composer/xdebug-handler (1.4.5): Loading from cache
  - Installing phan/phan (3.2.6): Loading from cache
  - Installing mediawiki/phan-taint-check-plugin (3.2.1): Loading from cache
  - Installing mediawiki/mediawiki-phan-config (0.10.6): Loading from cache
  - Installing mediawiki/minus-x (1.1.1): Loading from cache
  - Installing php-parallel-lint/php-console-color (v0.3): Loading from cache
  - Installing php-parallel-lint/php-console-highlighter (v0.5): Loading from cache
  - Installing php-parallel-lint/php-parallel-lint (v1.2.0): Loading from cache
symfony/service-contracts suggests installing symfony/service-implementation
symfony/console suggests installing symfony/event-dispatcher
symfony/console suggests installing symfony/lock
symfony/console suggests installing symfony/process
phan/phan suggests installing ext-ast (Needed for parsing ASTs (unless --use-fallback-parser is used). 1.0.1+ is needed, 1.0.8+ is recommended.)
Writing lock file
Generating autoload files
12 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

Upgrading n:eslint-config-wikimedia from 0.18.1 -> 0.18.2
$ npm install

> core-js@3.9.1 postinstall /src/repo/node_modules/core-js
> node -e "try{require('./postinstall')}catch(e){}"

Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library!

The project needs your help! Please consider supporting of core-js on Open Collective or Patreon: 
> https://opencollective.com/core-js 
> https://www.patreon.com/zloirock 

Also, the author of core-js ( https://github.com/zloirock ) is looking for a good job -)

added 647 packages from 345 contributors and audited 647 packages in 69.611s

69 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities


$ npm update eslint -depth 10
+ eslint@7.21.0
added 4 packages from 2 contributors, removed 6 packages, updated 12 packages, moved 2 packages and audited 645 packages in 98.783s

64 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities


$ npm install grunt-eslint@23.0.0 --save-exact
+ grunt-eslint@23.0.0
updated 3 packages and audited 645 packages in 26.944s

69 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities


$ ./node_modules/.bin/eslint i18n/lrc.json i18n/sms.json i18n/de-ch.json i18n/krc.json i18n/bs.json i18n/wuu.json i18n/trv.json i18n/nan.json i18n/se.json i18n/as.json i18n/bg.json i18n/pfl.json i18n/cy.json i18n/pl.json i18n/ug-arab.json i18n/th.json i18n/stq.json i18n/os.json i18n/mg.json i18n/tyv.json i18n/oc.json i18n/mr.json i18n/sk.json i18n/pt-br.json i18n/tn.json i18n/qu.json i18n/tg-latn.json i18n/yi.json i18n/gsw.json i18n/tay.json i18n/tpi.json i18n/jv.json i18n/ms.json i18n/he.json i18n/arc.json i18n/ba.json i18n/av.json i18n/nl.json i18n/kw.json i18n/kk-cyrl.json i18n/bar.json i18n/ca.json i18n/diq.json i18n/ru.json i18n/ia.json i18n/mk.json modules/jquery.wikiEditor.js i18n/dsb.json tests/qunit/ext.wikiEditor.toolbar.test.js i18n/cv.json i18n/sa.json i18n/br.json i18n/szl.json i18n/zu.json i18n/fr.json i18n/sw.json i18n/hy.json i18n/sl.json i18n/gu.json i18n/sd.json i18n/eml.json i18n/sco.json i18n/nds.json i18n/gv.json i18n/azb.json i18n/lzh.json i18n/sr-el.json i18n/olo.json i18n/sq.json i18n/rue.json i18n/xsy.json i18n/nah.json i18n/yue.json i18n/be.json i18n/ksh.json package.json i18n/gd.json i18n/hu.json i18n/ky.json i18n/tr.json i18n/grc.json i18n/qqq.json i18n/shn.json i18n/vo.json i18n/pnb.json i18n/fur.json package-lock.json i18n/ro.json i18n/nn.json i18n/pam.json i18n/om.json i18n/bjn.json Gruntfile.js i18n/co.json i18n/ciw.json i18n/cdo.json i18n/pdc.json i18n/cs.json i18n/ml.json i18n/hi.json modules/jquery.wikiEditor.toolbar.config.js i18n/ka.json i18n/bo.json i18n/or.json i18n/uz.json i18n/af.json i18n/ps.json i18n/zh-hans.json i18n/ang.json i18n/et.json i18n/is.json i18n/frp.json i18n/smn.json i18n/tcy.json i18n/de-formal.json i18n/lki.json i18n/de.json i18n/pa.json modules/jquery.wikiEditor.toolbar.js i18n/nap.json i18n/ltg.json i18n/id.json i18n/ta.json i18n/yo.json i18n/fit.json i18n/bho.json i18n/tg-cyrl.json i18n/pms.json i18n/ckb.json i18n/te.json i18n/da.json i18n/anp.json i18n/udm.json i18n/bn.json i18n/ami.json i18n/az.json i18n/vi.json i18n/ar.json i18n/nb.json i18n/en.json i18n/sat.json i18n/zh-hant.json i18n/be-tarask.json extension.json i18n/sr-ec.json i18n/ne.json i18n/tl.json i18n/lad.json i18n/li.json i18n/mwl.json i18n/bcc.json i18n/roa-tara.json i18n/ku-latn.json i18n/mzn.json i18n/hyw.json i18n/szy.json i18n/tzm.json i18n/nds-nl.json i18n/kbd-cyrl.json i18n/ga.json modules/ext.wikiEditor.js i18n/sh.json i18n/an.json i18n/kiu.json i18n/lmo.json i18n/ja.json i18n/fy.json i18n/bgn.json i18n/cu.json i18n/ti.json i18n/aln.json i18n/sah.json i18n/mt.json i18n/jbo.json i18n/kab.json i18n/nl-informal.json i18n/pnt.json i18n/tly.json i18n/my.json i18n/tk.json i18n/sc.json i18n/lus.json i18n/el.json i18n/nso.json i18n/lzz.json i18n/es.json i18n/io.json i18n/gcr.json i18n/sv.json i18n/fi.json i18n/ace.json i18n/sdh.json i18n/eo.json i18n/min.json i18n/kn.json i18n/km.json i18n/arz.json i18n/lb.json i18n/la.json i18n/eu.json i18n/hr.json i18n/si.json i18n/vec.json i18n/pt.json i18n/csb.json i18n/frr.json i18n/ko.json i18n/vep.json i18n/lij.json i18n/lv.json modules/jquery.wikiEditor.dialogs.js i18n/gl.json i18n/wa.json i18n/kjp.json i18n/ur.json i18n/ast.json i18n/sgs.json i18n/lfn.json i18n/su.json i18n/it.json i18n/scn.json i18n/lt.json i18n/ilo.json i18n/hsb.json i18n/atj.json i18n/ig.json i18n/so.json i18n/ce.json i18n/ha.json i18n/xmf.json i18n/bpy.json i18n/gom-latn.json modules/jquery.wikiEditor.dialogs.config.js i18n/wo.json i18n/mai.json i18n/mn.json i18n/myv.json i18n/hif-latn.json i18n/tt-cyrl.json i18n/ab.json i18n/shy-latn.json i18n/inh.json i18n/uk.json i18n/fa.json composer.json --fix

/src/repo/modules/jquery.wikiEditor.dialogs.config.js
  134:9  warning  All possible CSS classes should be documented. See https://w.wiki/PS2 for details  mediawiki/class-doc

/src/repo/modules/jquery.wikiEditor.js
  271:27  warning  'context' is already declared in the upper scope on line 226 column 7              no-shadow
  272:10  warning  'module' is already declared in the upper scope on line 227 column 19              no-shadow
  272:18  warning  'call' is already declared in the upper scope on line 227 column 38                no-shadow
  273:7   warning  'modules' is already declared in the upper scope on line 227 column 10             no-shadow
  328:29  warning  'module' is already declared in the upper scope on line 227 column 19              no-shadow
  397:23  warning  'options' is already declared in the upper scope on line 395 column 25             no-shadow
  439:13  warning  All possible CSS classes should be documented. See https://w.wiki/PS2 for details  mediawiki/class-doc

/src/repo/modules/jquery.wikiEditor.toolbar.js
  420:13  warning  '$options' is already declared in the upper scope on line 280 column 51  no-shadow

✖ 9 problems (0 errors, 9 warnings)


$ ./node_modules/.bin/eslint i18n/lrc.json i18n/sms.json i18n/de-ch.json i18n/krc.json i18n/bs.json i18n/wuu.json i18n/trv.json i18n/nan.json i18n/se.json i18n/as.json i18n/bg.json i18n/pfl.json i18n/cy.json i18n/pl.json i18n/ug-arab.json i18n/th.json i18n/stq.json i18n/os.json i18n/mg.json i18n/tyv.json i18n/oc.json i18n/mr.json i18n/sk.json i18n/pt-br.json i18n/tn.json i18n/qu.json i18n/tg-latn.json i18n/yi.json i18n/gsw.json i18n/tay.json i18n/tpi.json i18n/jv.json i18n/ms.json i18n/he.json i18n/arc.json i18n/ba.json i18n/av.json i18n/nl.json i18n/kw.json i18n/kk-cyrl.json i18n/bar.json i18n/ca.json i18n/diq.json i18n/ru.json i18n/ia.json i18n/mk.json modules/jquery.wikiEditor.js i18n/dsb.json tests/qunit/ext.wikiEditor.toolbar.test.js i18n/cv.json i18n/sa.json i18n/br.json i18n/szl.json i18n/zu.json i18n/fr.json i18n/sw.json i18n/hy.json i18n/sl.json i18n/gu.json i18n/sd.json i18n/eml.json i18n/sco.json i18n/nds.json i18n/gv.json i18n/azb.json i18n/lzh.json i18n/sr-el.json i18n/olo.json i18n/sq.json i18n/rue.json i18n/xsy.json i18n/nah.json i18n/yue.json i18n/be.json i18n/ksh.json package.json i18n/gd.json i18n/hu.json i18n/ky.json i18n/tr.json i18n/grc.json i18n/qqq.json i18n/shn.json i18n/vo.json i18n/pnb.json i18n/fur.json package-lock.json i18n/ro.json i18n/nn.json i18n/pam.json i18n/om.json i18n/bjn.json Gruntfile.js i18n/co.json i18n/ciw.json i18n/cdo.json i18n/pdc.json i18n/cs.json i18n/ml.json i18n/hi.json modules/jquery.wikiEditor.toolbar.config.js i18n/ka.json i18n/bo.json i18n/or.json i18n/uz.json i18n/af.json i18n/ps.json i18n/zh-hans.json i18n/ang.json i18n/et.json i18n/is.json i18n/frp.json i18n/smn.json i18n/tcy.json i18n/de-formal.json i18n/lki.json i18n/de.json i18n/pa.json modules/jquery.wikiEditor.toolbar.js i18n/nap.json i18n/ltg.json i18n/id.json i18n/ta.json i18n/yo.json i18n/fit.json i18n/bho.json i18n/tg-cyrl.json i18n/pms.json i18n/ckb.json i18n/te.json i18n/da.json i18n/anp.json i18n/udm.json i18n/bn.json i18n/ami.json i18n/az.json i18n/vi.json i18n/ar.json i18n/nb.json i18n/en.json i18n/sat.json i18n/zh-hant.json i18n/be-tarask.json extension.json i18n/sr-ec.json i18n/ne.json i18n/tl.json i18n/lad.json i18n/li.json i18n/mwl.json i18n/bcc.json i18n/roa-tara.json i18n/ku-latn.json i18n/mzn.json i18n/hyw.json i18n/szy.json i18n/tzm.json i18n/nds-nl.json i18n/kbd-cyrl.json i18n/ga.json modules/ext.wikiEditor.js i18n/sh.json i18n/an.json i18n/kiu.json i18n/lmo.json i18n/ja.json i18n/fy.json i18n/bgn.json i18n/cu.json i18n/ti.json i18n/aln.json i18n/sah.json i18n/mt.json i18n/jbo.json i18n/kab.json i18n/nl-informal.json i18n/pnt.json i18n/tly.json i18n/my.json i18n/tk.json i18n/sc.json i18n/lus.json i18n/el.json i18n/nso.json i18n/lzz.json i18n/es.json i18n/io.json i18n/gcr.json i18n/sv.json i18n/fi.json i18n/ace.json i18n/sdh.json i18n/eo.json i18n/min.json i18n/kn.json i18n/km.json i18n/arz.json i18n/lb.json i18n/la.json i18n/eu.json i18n/hr.json i18n/si.json i18n/vec.json i18n/pt.json i18n/csb.json i18n/frr.json i18n/ko.json i18n/vep.json i18n/lij.json i18n/lv.json modules/jquery.wikiEditor.dialogs.js i18n/gl.json i18n/wa.json i18n/kjp.json i18n/ur.json i18n/ast.json i18n/sgs.json i18n/lfn.json i18n/su.json i18n/it.json i18n/scn.json i18n/lt.json i18n/ilo.json i18n/hsb.json i18n/atj.json i18n/ig.json i18n/so.json i18n/ce.json i18n/ha.json i18n/xmf.json i18n/bpy.json i18n/gom-latn.json modules/jquery.wikiEditor.dialogs.config.js i18n/wo.json i18n/mai.json i18n/mn.json i18n/myv.json i18n/hif-latn.json i18n/tt-cyrl.json i18n/ab.json i18n/shy-latn.json i18n/inh.json i18n/uk.json i18n/fa.json composer.json -f json
[{"filePath":"/src/repo/Gruntfile.js","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/composer.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/extension.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ab.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ace.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/af.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/aln.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ami.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/an.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ang.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/anp.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ar.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/arc.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/arz.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/as.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ast.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/atj.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/av.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/az.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/azb.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ba.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/bar.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/bcc.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/be-tarask.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/be.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/bg.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/bgn.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/bho.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/bjn.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/bn.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/bo.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/bpy.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/br.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/bs.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ca.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/cdo.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ce.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ciw.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ckb.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/co.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/cs.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/csb.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/cu.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/cv.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/cy.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/da.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/de-ch.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/de-formal.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/de.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/diq.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/dsb.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/el.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/eml.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/en.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/eo.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/es.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/et.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/eu.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/fa.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/fi.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/fit.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/fr.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/frp.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/frr.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/fur.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/fy.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ga.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/gcr.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/gd.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/gl.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/gom-latn.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/grc.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/gsw.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/gu.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/gv.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ha.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/he.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/hi.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/hif-latn.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/hr.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/hsb.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/hu.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/hy.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/hyw.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ia.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/id.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ig.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ilo.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/inh.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/io.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/is.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/it.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ja.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/jbo.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/jv.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ka.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/kab.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/kbd-cyrl.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/kiu.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/kjp.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/kk-cyrl.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/km.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/kn.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ko.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/krc.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ksh.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ku-latn.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/kw.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ky.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/la.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/lad.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/lb.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/lfn.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/li.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/lij.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/lki.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/lmo.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/lrc.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/lt.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ltg.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/lus.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/lv.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/lzh.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/lzz.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/mai.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/mg.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/min.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/mk.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ml.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/mn.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/mr.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ms.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/mt.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/mwl.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/my.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/myv.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/mzn.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/nah.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/nan.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/nap.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/nb.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/nds-nl.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/nds.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ne.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/nl-informal.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/nl.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/nn.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/nso.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/oc.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/olo.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/om.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/or.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/os.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/pa.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/pam.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/pdc.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/pfl.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/pl.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/pms.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/pnb.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/pnt.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ps.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/pt-br.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/pt.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/qqq.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/qu.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ro.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/roa-tara.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ru.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/rue.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/sa.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/sah.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/sat.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/sc.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/scn.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/sco.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/sd.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/sdh.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/se.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/sgs.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/sh.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/shn.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/shy-latn.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/si.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/sk.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/sl.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/smn.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/sms.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/so.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/sq.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/sr-ec.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/sr-el.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/stq.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/su.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/sv.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/sw.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/szl.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/szy.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ta.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/tay.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/tcy.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/te.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/tg-cyrl.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/tg-latn.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/th.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ti.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/tk.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/tl.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/tly.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/tn.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/tpi.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/tr.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/trv.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/tt-cyrl.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/tyv.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/tzm.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/udm.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ug-arab.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/uk.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/ur.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/uz.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/vec.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/vep.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/vi.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/vo.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/wa.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/wo.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/wuu.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/xmf.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/xsy.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/yi.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/yo.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/yue.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/zh-hans.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/zh-hant.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/i18n/zu.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/modules/ext.wikiEditor.js","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/modules/jquery.wikiEditor.dialogs.config.js","messages":[{"ruleId":"mediawiki/class-doc","severity":1,"message":"All possible CSS classes should be documented. See https://w.wiki/PS2 for details.","line":134,"column":9,"nodeType":"CallExpression","endLine":134,"endColumn":91}],"errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Configuration of Dialog module for wikiEditor\n */\n( function () {\n\n\tvar hasOwn = Object.prototype.hasOwnProperty,\n\t\ttoolbarModule = require( './jquery.wikiEditor.toolbar.js' ),\n\t\tconfigData = require( './data.json' );\n\n\tfunction triggerButtonClick( element ) {\n\t\tvar $button,\n\t\t\t// The dialog action should always be a DOMElement.\n\t\t\tdialogAction = $( element ).data( 'dialogaction' );\n\t\t$button = dialogAction ? $( dialogAction ) : $( element ).find( 'button' ).first();\n\t\t// Since we're reading from data attribute, make sure we got an element before clicking.\n\t\t// Note when closing a dialog this can be false leading to TypeError: $button.trigger is not a function\n\t\t// (T261529)\n\t\tif ( $button ) {\n\t\t\t$button.trigger( 'click' );\n\t\t}\n\t}\n\n\tmodule.exports = {\n\n\t\treplaceIcons: function ( $textarea ) {\n\t\t\t$textarea\n\t\t\t\t.wikiEditor( 'addToToolbar', {\n\t\t\t\t\tsection: 'main',\n\t\t\t\t\tgroup: 'insert',\n\t\t\t\t\ttools: {\n\t\t\t\t\t\tlink: {\n\t\t\t\t\t\t\tlabelMsg: 'wikieditor-toolbar-tool-link',\n\t\t\t\t\t\t\ttype: 'button',\n\t\t\t\t\t\t\toouiIcon: 'link',\n\t\t\t\t\t\t\taction: {\n\t\t\t\t\t\t\t\ttype: 'dialog',\n\t\t\t\t\t\t\t\tmodule: 'insert-link'\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfile: {\n\t\t\t\t\t\t\tlabelMsg: 'wikieditor-toolbar-tool-file',\n\t\t\t\t\t\t\ttype: 'button',\n\t\t\t\t\t\t\toouiIcon: 'image',\n\t\t\t\t\t\t\taction: {\n\t\t\t\t\t\t\t\ttype: 'dialog',\n\t\t\t\t\t\t\t\tmodule: 'insert-file'\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\treference: {\n\t\t\t\t\t\t\tlabelMsg: 'wikieditor-toolbar-tool-reference',\n\t\t\t\t\t\t\tfilters: [ 'body.ns-subject' ],\n\t\t\t\t\t\t\ttype: 'button',\n\t\t\t\t\t\t\toouiIcon: 'reference',\n\t\t\t\t\t\t\taction: {\n\t\t\t\t\t\t\t\ttype: 'encapsulate',\n\t\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\t\tpre: '<ref>',\n\t\t\t\t\t\t\t\t\tpost: '</ref>'\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} )\n\t\t\t\t.wikiEditor( 'addToToolbar', {\n\t\t\t\t\tsection: 'advanced',\n\t\t\t\t\tgroup: 'insert',\n\t\t\t\t\ttools: {\n\t\t\t\t\t\ttable: {\n\t\t\t\t\t\t\tlabelMsg: 'wikieditor-toolbar-tool-table',\n\t\t\t\t\t\t\ttype: 'button',\n\t\t\t\t\t\t\toouiIcon: 'table',\n\t\t\t\t\t\t\taction: {\n\t\t\t\t\t\t\t\ttype: 'dialog',\n\t\t\t\t\t\t\t\tmodule: 'insert-table'\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} )\n\t\t\t\t.wikiEditor( 'addToToolbar', {\n\t\t\t\t\tsection: 'advanced',\n\t\t\t\t\tgroups: {\n\t\t\t\t\t\tsearch: {\n\t\t\t\t\t\t\ttools: {\n\t\t\t\t\t\t\t\treplace: {\n\t\t\t\t\t\t\t\t\tlabelMsg: 'wikieditor-toolbar-tool-replace',\n\t\t\t\t\t\t\t\t\ttype: 'button',\n\t\t\t\t\t\t\t\t\toouiIcon: 'articleSearch',\n\t\t\t\t\t\t\t\t\taction: {\n\t\t\t\t\t\t\t\t\t\ttype: 'dialog',\n\t\t\t\t\t\t\t\t\t\tmodule: 'search-and-replace'\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}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t},\n\n\t\tgetDefaultConfig: function () {\n\t\t\treturn { dialogs: {\n\t\t\t\t'insert-link': {\n\t\t\t\t\ttitleMsg: 'wikieditor-toolbar-tool-link-title',\n\t\t\t\t\tid: 'wikieditor-toolbar-link-dialog',\n\t\t\t\t\thtmlTemplate: 'dialogInsertLink.html',\n\n\t\t\t\t\tinit: function () {\n\t\t\t\t\t\tvar api = new mw.Api();\n\n\t\t\t\t\t\tfunction isExternalLink( s ) {\n\t\t\t\t\t\t\t// The following things are considered to be external links:\n\t\t\t\t\t\t\t// * Starts with a URL protocol\n\t\t\t\t\t\t\t// * Starts with www.\n\t\t\t\t\t\t\t// All of these are potentially valid titles, and the latter two categories match about 6300\n\t\t\t\t\t\t\t// titles in enwiki's ns0. Out of 6.9M titles, that's 0.09%\n\t\t\t\t\t\t\t/* eslint-disable no-caller */\n\t\t\t\t\t\t\tif ( typeof arguments.callee.regex === 'undefined' ) {\n\t\t\t\t\t\t\t\t// Cache the regex\n\t\t\t\t\t\t\t\targuments.callee.regex =\n\t\t\t\t\t\t\t\t\tnew RegExp( '^(' + mw.config.get( 'wgUrlProtocols' ) + '|www\\\\.)', 'i' );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn s.match( arguments.callee.regex );\n\t\t\t\t\t\t\t/* eslint-enable no-caller */\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Updates the status indicator above the target link\n\t\t\t\t\t\tfunction updateWidget( status, reason ) {\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-target-status' ).children().hide();\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-target' ).parent()\n\t\t\t\t\t\t\t\t.removeClass(\n\t\t\t\t\t\t\t\t\t'status-invalid status-external status-notexists status-exists status-loading'\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif ( status ) {\n\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-target-status-' + status ).show();\n\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-target' ).parent().addClass( 'status-' + status );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( status === 'invalid' ) {\n\t\t\t\t\t\t\t\t// eslint-disable-next-line no-jquery/no-sizzle\n\t\t\t\t\t\t\t\t$( '.ui-dialog:visible .ui-dialog-buttonpane button' ).first()\n\t\t\t\t\t\t\t\t\t.prop( 'disabled', true )\n\t\t\t\t\t\t\t\t\t.addClass( 'disabled' );\n\t\t\t\t\t\t\t\tif ( reason ) {\n\t\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-target-status-invalid' ).html( reason );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-target-status-invalid' )\n\t\t\t\t\t\t\t\t\t\t.text( mw.msg( 'wikieditor-toolbar-tool-link-int-target-status-invalid' ) );\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// eslint-disable-next-line no-jquery/no-sizzle\n\t\t\t\t\t\t\t\t$( '.ui-dialog:visible .ui-dialog-buttonpane button' ).first()\n\t\t\t\t\t\t\t\t\t.prop( 'disabled', false )\n\t\t\t\t\t\t\t\t\t.removeClass( 'disabled' );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Updates the UI to show if the page title being inputted by the user exists or not\n\t\t\t\t\t\t// accepts parameter internal for bypassing external link detection\n\t\t\t\t\t\tfunction updateExistence( internal ) {\n\t\t\t\t\t\t\t// Abort previous request\n\t\t\t\t\t\t\tvar request = $( '#wikieditor-toolbar-link-int-target-status' ).data( 'request' ),\n\t\t\t\t\t\t\t\ttarget = $( '#wikieditor-toolbar-link-int-target' ).val(),\n\t\t\t\t\t\t\t\tcache = $( '#wikieditor-toolbar-link-int-target-status' ).data( 'existencecache' ),\n\t\t\t\t\t\t\t\treasoncache = $( '#wikieditor-toolbar-link-int-target-status' ).data( 'reasoncache' );\n\t\t\t\t\t\t\t// ensure the internal parameter is a boolean\n\t\t\t\t\t\t\tif ( internal !== true ) {\n\t\t\t\t\t\t\t\tinternal = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( request ) {\n\t\t\t\t\t\t\t\trequest.abort();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( hasOwn.call( cache, target ) ) {\n\t\t\t\t\t\t\t\tupdateWidget( cache[ target ], reasoncache[ target ] );\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( target.replace( /^\\s+$/, '' ) === '' ) {\n\t\t\t\t\t\t\t\t// Hide the widget when the textbox is empty\n\t\t\t\t\t\t\t\tupdateWidget( false );\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// If the forced internal parameter was not true, check if the target is an external link\n\t\t\t\t\t\t\tif ( !internal && isExternalLink( target ) ) {\n\t\t\t\t\t\t\t\tupdateWidget( 'external' );\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Show loading spinner while waiting for the API to respond\n\t\t\t\t\t\t\tupdateWidget( 'loading' );\n\t\t\t\t\t\t\t// Call the API to check page status, saving the request object so it can be aborted if\n\t\t\t\t\t\t\t// necessary.\n\t\t\t\t\t\t\t// This used to request a page that would show whether or not the target exists, but we can\n\t\t\t\t\t\t\t// also check whether it has the disambiguation property and still get existence information.\n\t\t\t\t\t\t\t// If the Disambiguator extension is not installed then such a property won't be set.\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-target-status' ).data(\n\t\t\t\t\t\t\t\t'request',\n\t\t\t\t\t\t\t\tapi.get( {\n\t\t\t\t\t\t\t\t\tformatversion: 2,\n\t\t\t\t\t\t\t\t\taction: 'query',\n\t\t\t\t\t\t\t\t\tprop: 'pageprops',\n\t\t\t\t\t\t\t\t\ttitles: [ target ],\n\t\t\t\t\t\t\t\t\tppprop: 'disambiguation',\n\t\t\t\t\t\t\t\t\terrorformat: 'html',\n\t\t\t\t\t\t\t\t\terrorlang: mw.config.get( 'wgUserLanguage' )\n\t\t\t\t\t\t\t\t} ).done( function ( data ) {\n\t\t\t\t\t\t\t\t\tvar status, page, reason = null;\n\t\t\t\t\t\t\t\t\tif ( !data.query || !data.query.pages ) {\n\t\t\t\t\t\t\t\t\t\t// This happens in some weird cases like interwiki links\n\t\t\t\t\t\t\t\t\t\tstatus = false;\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tpage = data.query.pages[ 0 ];\n\t\t\t\t\t\t\t\t\t\tstatus = 'exists';\n\t\t\t\t\t\t\t\t\t\tif ( page.missing ) {\n\t\t\t\t\t\t\t\t\t\t\tstatus = 'notexists';\n\t\t\t\t\t\t\t\t\t\t} else if ( page.invalid ) {\n\t\t\t\t\t\t\t\t\t\t\tstatus = 'invalid';\n\t\t\t\t\t\t\t\t\t\t\treason = page.invalidreason && page.invalidreason.html;\n\t\t\t\t\t\t\t\t\t\t} else if ( page.pageprops ) {\n\t\t\t\t\t\t\t\t\t\t\tstatus = 'disambig';\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t// Cache the status of the link target if the force internal\n\t\t\t\t\t\t\t\t\t// parameter was not passed\n\t\t\t\t\t\t\t\t\tif ( !internal ) {\n\t\t\t\t\t\t\t\t\t\tcache[ target ] = status;\n\t\t\t\t\t\t\t\t\t\treasoncache[ target ] = reason;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tupdateWidget( status, reason );\n\t\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$( '#wikieditor-toolbar-link-type-int, #wikieditor-toolbar-link-type-ext' ).on( 'click', function () {\n\t\t\t\t\t\t\tvar request;\n\t\t\t\t\t\t\tif ( $( '#wikieditor-toolbar-link-type-ext' ).prop( 'checked' ) ) {\n\t\t\t\t\t\t\t\t// Abort previous request\n\t\t\t\t\t\t\t\trequest = $( '#wikieditor-toolbar-link-int-target-status' ).data( 'request' );\n\t\t\t\t\t\t\t\tif ( request ) {\n\t\t\t\t\t\t\t\t\trequest.abort();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tupdateWidget( 'external' );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( $( '#wikieditor-toolbar-link-type-int' ).prop( 'checked' ) ) {\n\t\t\t\t\t\t\t\tupdateExistence( true );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t\t// Set labels of tabs based on rel values\n\t\t\t\t\t\t$( this ).find( '[rel]' ).each( function () {\n\t\t\t\t\t\t\t// eslint-disable-next-line mediawiki/msg-doc\n\t\t\t\t\t\t\t$( this ).text( mw.msg( $( this ).attr( 'rel' ) ) );\n\t\t\t\t\t\t} );\n\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-target' ).attr( 'placeholder',\n\t\t\t\t\t\t\tmw.msg( 'wikieditor-toolbar-tool-link-int-target-tooltip' ) );\n\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-text' ).attr( 'placeholder',\n\t\t\t\t\t\t\tmw.msg( 'wikieditor-toolbar-tool-link-int-text-tooltip' ) );\n\t\t\t\t\t\t// Automatically copy the value of the internal link page title field to the link text field unless the\n\t\t\t\t\t\t// user has changed the link text field - this is a convenience thing since most link texts are going to\n\t\t\t\t\t\t// be the same as the page title - Also change the internal/external radio button accordingly\n\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-target' ).on( 'change keydown paste cut', function () {\n\t\t\t\t\t\t\t// $( this ).val() is the old value, before the keypress - Defer this until $( this ).val() has\n\t\t\t\t\t\t\t// been updated\n\t\t\t\t\t\t\tsetTimeout( function () {\n\t\t\t\t\t\t\t\tif ( isExternalLink( $( '#wikieditor-toolbar-link-int-target' ).val() ) ) {\n\t\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-type-ext' ).prop( 'checked', true );\n\t\t\t\t\t\t\t\t\tupdateWidget( 'external' );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-type-int' ).prop( 'checked', true );\n\t\t\t\t\t\t\t\t\tupdateExistence();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( $( '#wikieditor-toolbar-link-int-text' ).data( 'untouched' ) ) {\n\t\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-text' )\n\t\t\t\t\t\t\t\t\t\t.val( $( '#wikieditor-toolbar-link-int-target' ).val() )\n\t\t\t\t\t\t\t\t\t\t.trigger( 'change' );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}, 0 );\n\t\t\t\t\t\t} );\n\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-text' ).on( 'change keydown paste cut', function () {\n\t\t\t\t\t\t\tvar oldVal = $( this ).val(),\n\t\t\t\t\t\t\t\tthat = this;\n\t\t\t\t\t\t\tsetTimeout( function () {\n\t\t\t\t\t\t\t\tif ( $( that ).val() !== oldVal ) {\n\t\t\t\t\t\t\t\t\t$( that ).data( 'untouched', false );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}, 0 );\n\t\t\t\t\t\t} );\n\t\t\t\t\t\t// Add images to the page existence widget, which will be shown mutually exclusively to communicate if\n\t\t\t\t\t\t// the page exists, does not exist or the title is invalid (like if it contains a | character)\n\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-target-status' )\n\t\t\t\t\t\t\t.append( $( '<div>' )\n\t\t\t\t\t\t\t\t.attr( 'id', 'wikieditor-toolbar-link-int-target-status-exists' )\n\t\t\t\t\t\t\t\t.text( mw.msg( 'wikieditor-toolbar-tool-link-int-target-status-exists' ) )\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.append( $( '<div>' )\n\t\t\t\t\t\t\t\t.attr( 'id', 'wikieditor-toolbar-link-int-target-status-notexists' )\n\t\t\t\t\t\t\t\t.text( mw.msg( 'wikieditor-toolbar-tool-link-int-target-status-notexists' ) )\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.append( $( '<div>' )\n\t\t\t\t\t\t\t\t.attr( 'id', 'wikieditor-toolbar-link-int-target-status-invalid' )\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.append( $( '<div>' )\n\t\t\t\t\t\t\t\t.attr( 'id', 'wikieditor-toolbar-link-int-target-status-external' )\n\t\t\t\t\t\t\t\t.text( mw.msg( 'wikieditor-toolbar-tool-link-int-target-status-external' ) )\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.append( $( '<div>' )\n\t\t\t\t\t\t\t\t.attr( 'id', 'wikieditor-toolbar-link-int-target-status-loading' )\n\t\t\t\t\t\t\t\t.attr( 'title', mw.msg( 'wikieditor-toolbar-tool-link-int-target-status-loading' ) )\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.append( $( '<div>' )\n\t\t\t\t\t\t\t\t.attr( 'id', 'wikieditor-toolbar-link-int-target-status-disambig' )\n\t\t\t\t\t\t\t\t.text( mw.msg( 'wikieditor-toolbar-tool-link-int-target-status-disambig' ) )\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.data( 'existencecache', {} )\n\t\t\t\t\t\t\t.data( 'reasoncache', {} )\n\t\t\t\t\t\t\t.children().hide();\n\n\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-target' )\n\t\t\t\t\t\t\t.on( 'keyup paste cut', $.debounce( 500, updateExistence ) )\n\t\t\t\t\t\t\t.on( 'change', updateExistence ); // update right now\n\n\t\t\t\t\t\t// Title suggestions\n\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-target' ).data( 'suggcache', {} ).suggestions( {\n\t\t\t\t\t\t\tfetch: function () {\n\t\t\t\t\t\t\t\tvar cache, request,\n\t\t\t\t\t\t\t\t\tthat = this,\n\t\t\t\t\t\t\t\t\ttitle = $( this ).val();\n\n\t\t\t\t\t\t\t\tif ( isExternalLink( title ) || title.indexOf( '|' ) !== -1 || title === '' ) {\n\t\t\t\t\t\t\t\t\t$( this ).suggestions( 'suggestions', [] );\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tcache = $( this ).data( 'suggcache' );\n\t\t\t\t\t\t\t\tif ( hasOwn.call( cache, title ) ) {\n\t\t\t\t\t\t\t\t\t$( this ).suggestions( 'suggestions', cache[ title ] );\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\trequest = api.get( {\n\t\t\t\t\t\t\t\t\tformatversion: 2,\n\t\t\t\t\t\t\t\t\taction: 'opensearch',\n\t\t\t\t\t\t\t\t\tsearch: title,\n\t\t\t\t\t\t\t\t\tnamespace: 0,\n\t\t\t\t\t\t\t\t\tsuggest: ''\n\t\t\t\t\t\t\t\t} ).done( function ( data ) {\n\t\t\t\t\t\t\t\t\tcache[ title ] = data[ 1 ];\n\t\t\t\t\t\t\t\t\t$( that ).suggestions( 'suggestions', data[ 1 ] );\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t\t$( this ).data( 'request', request );\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tcancel: function () {\n\t\t\t\t\t\t\t\tvar request = $( this ).data( 'request' );\n\t\t\t\t\t\t\t\tif ( request ) {\n\t\t\t\t\t\t\t\t\trequest.abort();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t},\n\t\t\t\t\tdialog: {\n\t\t\t\t\t\twidth: 500,\n\t\t\t\t\t\tdialogClass: 'wikiEditor-toolbar-dialog',\n\t\t\t\t\t\tbuttons: {\n\t\t\t\t\t\t\t'wikieditor-toolbar-tool-link-insert': function () {\n\t\t\t\t\t\t\t\tvar match, buttons, escTarget, escText,\n\t\t\t\t\t\t\t\t\tthat = this,\n\t\t\t\t\t\t\t\t\tinsertText = '',\n\t\t\t\t\t\t\t\t\twhitespace = $( '#wikieditor-toolbar-link-dialog' ).data( 'whitespace' ),\n\t\t\t\t\t\t\t\t\ttarget = $( '#wikieditor-toolbar-link-int-target' ).val(),\n\t\t\t\t\t\t\t\t\ttext = $( '#wikieditor-toolbar-link-int-text' ).val();\n\n\t\t\t\t\t\t\t\tfunction escapeInternalText( s ) {\n\t\t\t\t\t\t\t\t\treturn s.replace( /(\\]{2,})/g, '<nowiki>$1</nowiki>' );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tfunction escapeExternalTarget( s ) {\n\t\t\t\t\t\t\t\t\treturn s.replace( / /g, '%20' )\n\t\t\t\t\t\t\t\t\t\t.replace( /\\[/g, '%5B' )\n\t\t\t\t\t\t\t\t\t\t.replace( /\\]/g, '%5D' );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tfunction escapeExternalText( s ) {\n\t\t\t\t\t\t\t\t\treturn s.replace( /(\\]+)/g, '<nowiki>$1</nowiki>' );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( target === '' ) {\n\t\t\t\t\t\t\t\t\t// eslint-disable-next-line no-alert\n\t\t\t\t\t\t\t\t\talert( mw.msg( 'wikieditor-toolbar-tool-link-empty' ) );\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( text.trim() === '' ) {\n\t\t\t\t\t\t\t\t\t// [[Foo| ]] creates an invisible link\n\t\t\t\t\t\t\t\t\t// Instead, generate [[Foo|]]\n\t\t\t\t\t\t\t\t\ttext = '';\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( $( '#wikieditor-toolbar-link-type-int' ).is( ':checked' ) ) {\n\t\t\t\t\t\t\t\t\t// FIXME: Exactly how fragile is this?\n\t\t\t\t\t\t\t\t\t// eslint-disable-next-line no-jquery/no-sizzle\n\t\t\t\t\t\t\t\t\tif ( $( '#wikieditor-toolbar-link-int-target-status-invalid' ).is( ':visible' ) ) {\n\t\t\t\t\t\t\t\t\t\t// Refuse to add links to invalid titles\n\t\t\t\t\t\t\t\t\t\t// eslint-disable-next-line no-alert\n\t\t\t\t\t\t\t\t\t\talert( mw.msg( 'wikieditor-toolbar-tool-link-int-invalid' ) );\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif ( target === text || !text.length ) {\n\t\t\t\t\t\t\t\t\t\tinsertText = '[[' + target + ']]';\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tinsertText = '[[' + target + '|' + escapeInternalText( text ) + ']]';\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\ttarget = target.trim();\n\t\t\t\t\t\t\t\t\t// Prepend http:// if there is no protocol\n\t\t\t\t\t\t\t\t\tif ( !target.match( /^[a-z]+:\\/\\/./ ) ) {\n\t\t\t\t\t\t\t\t\t\ttarget = 'http://' + target;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Detect if this is really an internal link in disguise\n\t\t\t\t\t\t\t\t\tmatch = target.match( $( this ).data( 'articlePathRegex' ) );\n\t\t\t\t\t\t\t\t\tif ( match && !$( this ).data( 'ignoreLooksInternal' ) ) {\n\t\t\t\t\t\t\t\t\t\tbuttons = {};\n\t\t\t\t\t\t\t\t\t\tbuttons[ mw.msg( 'wikieditor-toolbar-tool-link-lookslikeinternal-int' ) ] =\n\t\t\t\t\t\t\t\t\t\t\tfunction () {\n\t\t\t\t\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-target' ).val( match[ 1 ] ).trigger( 'change' );\n\t\t\t\t\t\t\t\t\t\t\t\t$( this ).dialog( 'close' );\n\t\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\tbuttons[ mw.msg( 'wikieditor-toolbar-tool-link-lookslikeinternal-ext' ) ] =\n\t\t\t\t\t\t\t\t\t\t\tfunction () {\n\t\t\t\t\t\t\t\t\t\t\t\t$( that ).data( 'ignoreLooksInternal', true );\n\t\t\t\t\t\t\t\t\t\t\t\t$( that ).closest( '.ui-dialog' ).find( 'button' ).first().trigger( 'click' );\n\t\t\t\t\t\t\t\t\t\t\t\t$( that ).data( 'ignoreLooksInternal', false );\n\t\t\t\t\t\t\t\t\t\t\t\t$( this ).dialog( 'close' );\n\t\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\t$.wikiEditor.modules.dialogs.quickDialog(\n\t\t\t\t\t\t\t\t\t\t\tmw.msg( 'wikieditor-toolbar-tool-link-lookslikeinternal', match[ 1 ] ),\n\t\t\t\t\t\t\t\t\t\t\t{ buttons: buttons }\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tescTarget = escapeExternalTarget( target );\n\t\t\t\t\t\t\t\t\tescText = escapeExternalText( text );\n\n\t\t\t\t\t\t\t\t\tif ( escTarget === escText ) {\n\t\t\t\t\t\t\t\t\t\tinsertText = escTarget;\n\t\t\t\t\t\t\t\t\t} else if ( text === '' ) {\n\t\t\t\t\t\t\t\t\t\tinsertText = '[' + escTarget + ']';\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tinsertText = '[' + escTarget + ' ' + escText + ']';\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\t// Preserve whitespace in selection when replacing\n\t\t\t\t\t\t\t\tif ( whitespace ) {\n\t\t\t\t\t\t\t\t\tinsertText = whitespace[ 0 ] + insertText + whitespace[ 1 ];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t$( this ).dialog( 'close' );\n\t\t\t\t\t\t\t\ttoolbarModule.fn.doAction( $( this ).data( 'context' ), {\n\t\t\t\t\t\t\t\t\ttype: 'replace',\n\t\t\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\t\t\tpre: insertText\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}, $( this ) );\n\n\t\t\t\t\t\t\t\t// Blank form\n\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-target, #wikieditor-toolbar-link-int-text' ).val( '' );\n\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-type-int, #wikieditor-toolbar-link-type-ext' )\n\t\t\t\t\t\t\t\t\t.prop( 'checked', false );\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t'wikieditor-toolbar-tool-link-cancel': function () {\n\t\t\t\t\t\t\t\t$( this ).dialog( 'close' );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\topen: function () {\n\t\t\t\t\t\t\tvar target, text, type, matches, context, selection,\n\t\t\t\t\t\t\t\t// Obtain the server name without the protocol. wgServer may be protocol-relative\n\t\t\t\t\t\t\t\tserverName = mw.config.get( 'wgServer' ).replace( /^(https?:)?\\/\\//, '' );\n\t\t\t\t\t\t\t// Cache the articlepath regex\n\t\t\t\t\t\t\t$( this ).data( 'articlePathRegex', new RegExp(\n\t\t\t\t\t\t\t\t'^https?://' + mw.util.escapeRegExp( serverName + mw.config.get( 'wgArticlePath' ) )\n\t\t\t\t\t\t\t\t\t.replace( /\\\\\\$1/g, '(.*)' ) + '$'\n\t\t\t\t\t\t\t) );\n\t\t\t\t\t\t\t// Pre-fill the text fields based on the current selection\n\t\t\t\t\t\t\tcontext = $( this ).data( 'context' );\n\t\t\t\t\t\t\tselection = context.$textarea.textSelection( 'getSelection' );\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-target' ).trigger( 'focus' );\n\t\t\t\t\t\t\t// Trigger the change event, so the link status indicator is up to date\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-target' ).trigger( 'change' );\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-dialog' ).data( 'whitespace', [ '', '' ] );\n\t\t\t\t\t\t\tif ( selection !== '' ) {\n\t\t\t\t\t\t\t\tif ( ( matches = selection.match( /^(\\s*)\\[\\[([^\\]|]+)(\\|([^\\]|]*))?\\]\\](\\s*)$/ ) ) ) {\n\t\t\t\t\t\t\t\t\t// [[foo|bar]] or [[foo]]\n\t\t\t\t\t\t\t\t\ttarget = matches[ 2 ];\n\t\t\t\t\t\t\t\t\ttext = ( matches[ 4 ] ? matches[ 4 ] : matches[ 2 ] );\n\t\t\t\t\t\t\t\t\ttype = 'int';\n\t\t\t\t\t\t\t\t\t// Preserve whitespace when replacing\n\t\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-dialog' ).data( 'whitespace', [ matches[ 1 ], matches[ 5 ] ] );\n\t\t\t\t\t\t\t\t} else if ( ( matches = selection.match( /^(\\s*)\\[([^\\] ]+)( ([^\\]]+))?\\](\\s*)$/ ) ) ) {\n\t\t\t\t\t\t\t\t\t// [http://www.example.com foo] or [http://www.example.com]\n\t\t\t\t\t\t\t\t\ttarget = matches[ 2 ];\n\t\t\t\t\t\t\t\t\ttext = ( matches[ 4 ] || '' );\n\t\t\t\t\t\t\t\t\ttype = 'ext';\n\t\t\t\t\t\t\t\t\t// Preserve whitespace when replacing\n\t\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-dialog' ).data( 'whitespace', [ matches[ 1 ], matches[ 5 ] ] );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t// Trim any leading and trailing whitespace from the selection,\n\t\t\t\t\t\t\t\t\t// but preserve it when replacing\n\t\t\t\t\t\t\t\t\ttarget = text = selection.trim();\n\t\t\t\t\t\t\t\t\tif ( target.length < selection.length ) {\n\t\t\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-dialog' ).data( 'whitespace', [\n\t\t\t\t\t\t\t\t\t\t\tselection.substr( 0, selection.indexOf( target.charAt( 0 ) ) ),\n\t\t\t\t\t\t\t\t\t\t\tselection.substr(\n\t\t\t\t\t\t\t\t\t\t\t\tselection.lastIndexOf( target.charAt( target.length - 1 ) ) + 1\n\t\t\t\t\t\t\t\t\t\t\t) ]\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Change the value by calling val() doesn't trigger the change event, so let's do that\n\t\t\t\t\t\t\t\t// ourselves\n\t\t\t\t\t\t\t\tif ( typeof text !== 'undefined' ) {\n\t\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-text' ).val( text ).trigger( 'change' );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( typeof target !== 'undefined' ) {\n\t\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-target' ).val( target ).trigger( 'change' );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( typeof type !== 'undefined' ) {\n\t\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-' + type ).prop( 'checked', true );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-text' ).data( 'untouched',\n\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-text' ).val() ===\n\t\t\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-target' ).val()\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-target' ).suggestions();\n\n\t\t\t\t\t\t\t// don't overwrite user's text\n\t\t\t\t\t\t\tif ( selection !== '' ) {\n\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-link-int-text' ).data( 'untouched', false );\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( !$( this ).data( 'dialogkeypressset' ) ) {\n\t\t\t\t\t\t\t\t$( this ).data( 'dialogkeypressset', true );\n\t\t\t\t\t\t\t\t// Execute the action associated with the first button\n\t\t\t\t\t\t\t\t// when the user presses Enter\n\t\t\t\t\t\t\t\t$( this ).closest( '.ui-dialog' ).on( 'keypress', function ( e ) {\n\t\t\t\t\t\t\t\t\tif ( ( e.keyCode || e.which ) === 13 ) {\n\t\t\t\t\t\t\t\t\t\ttriggerButtonClick( this );\n\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t\t\t// Make tabbing to a button and pressing\n\t\t\t\t\t\t\t\t// Enter do what people expect\n\t\t\t\t\t\t\t\t$( this ).closest( '.ui-dialog' ).find( 'button' ).on( 'focus', function () {\n\t\t\t\t\t\t\t\t\t$( this ).closest( '.ui-dialog' ).data( 'dialogaction', this );\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t'insert-file': {\n\t\t\t\t\ttitleMsg: 'wikieditor-toolbar-tool-file-title',\n\t\t\t\t\tid: 'wikieditor-toolbar-file-dialog',\n\t\t\t\t\thtmlTemplate: 'dialogInsertFile.html',\n\t\t\t\t\tinit: function () {\n\t\t\t\t\t\tvar magicWordsI18N = configData.magicWords,\n\t\t\t\t\t\t\tdefaultMsg = mw.msg( 'wikieditor-toolbar-file-default' ),\n\t\t\t\t\t\t\taltHelpText = mw.msg( 'wikieditor-toolbar-file-alt-help' ),\n\t\t\t\t\t\t\taltHelpLabel = mw.msg( 'wikieditor-toolbar-file-alt-help-label' );\n\n\t\t\t\t\t\t$( this ).find( '[data-i18n-magic]' )\n\t\t\t\t\t\t\t.text( function () {\n\t\t\t\t\t\t\t\treturn magicWordsI18N[ $( this ).attr( 'data-i18n-magic' ) ][ 0 ];\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.removeAttr( 'data-i18n-magic' );\n\t\t\t\t\t\t$( this ).find( '#wikieditor-toolbar-file-size' )\n\t\t\t\t\t\t\t.attr( 'placeholder', defaultMsg )\n\t\t\t\t\t\t\t// The message may be long in some languages\n\t\t\t\t\t\t\t.attr( 'size', defaultMsg.length );\n\t\t\t\t\t\t$( this ).find( '[rel]' )\n\t\t\t\t\t\t\t.text( function () {\n\t\t\t\t\t\t\t\t// eslint-disable-next-line mediawiki/msg-doc\n\t\t\t\t\t\t\t\treturn mw.msg( $( this ).attr( 'rel' ) );\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.removeAttr( 'rel' );\n\n\t\t\t\t\t\t// Expandable help message for 'alt text' field\n\t\t\t\t\t\t$( this ).find( '.wikieditor-toolbar-file-alt-help' ).text( altHelpLabel );\n\t\t\t\t\t\t$( '.wikieditor-toolbar-file-alt-help' ).on( 'click', function () {\n\t\t\t\t\t\t\t$( this ).text( function ( i, text ) {\n\t\t\t\t\t\t\t\treturn text === altHelpLabel ? altHelpText : altHelpLabel;\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t// Preload modules of file upload dialog.\n\t\t\t\t\t\tmw.loader.load( [\n\t\t\t\t\t\t\t'mediawiki.ForeignStructuredUpload.BookletLayout',\n\t\t\t\t\t\t\t'mediawiki.Upload.Dialog',\n\t\t\t\t\t\t\t'oojs-ui-windows'\n\t\t\t\t\t\t] );\n\t\t\t\t\t},\n\t\t\t\t\tdialog: {\n\t\t\t\t\t\tresizable: false,\n\t\t\t\t\t\tdialogClass: 'wikiEditor-toolbar-dialog',\n\t\t\t\t\t\twidth: 590,\n\t\t\t\t\t\tbuttons: {\n\t\t\t\t\t\t\t'wikieditor-toolbar-tool-file-insert': function () {\n\t\t\t\t\t\t\t\tvar fileName, caption, fileAlt, fileFloat, fileFormat,\n\t\t\t\t\t\t\t\t\tfileSize, whitespace, fileTitle, options, fileUse,\n\t\t\t\t\t\t\t\t\thasPxRgx = /.+px$/,\n\t\t\t\t\t\t\t\t\tmagicWordsI18N = configData.magicWords;\n\t\t\t\t\t\t\t\tfileName = $( '#wikieditor-toolbar-file-target' ).val();\n\t\t\t\t\t\t\t\tcaption = $( '#wikieditor-toolbar-file-caption' ).val();\n\t\t\t\t\t\t\t\tfileAlt = $( '#wikieditor-toolbar-file-alt' ).val();\n\t\t\t\t\t\t\t\tfileFloat = $( '#wikieditor-toolbar-file-float' ).val();\n\t\t\t\t\t\t\t\tfileFormat = $( '#wikieditor-toolbar-file-format' ).val();\n\t\t\t\t\t\t\t\tfileSize = $( '#wikieditor-toolbar-file-size' ).val();\n\t\t\t\t\t\t\t\twhitespace = $( '#wikieditor-toolbar-file-dialog' ).data( 'whitespace' );\n\t\t\t\t\t\t\t\t// Append px to end to size if not already contains it\n\t\t\t\t\t\t\t\tif ( fileSize !== '' && !hasPxRgx.test( fileSize ) ) {\n\t\t\t\t\t\t\t\t\tfileSize += 'px';\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( fileName !== '' ) {\n\t\t\t\t\t\t\t\t\tfileTitle = new mw.Title( fileName );\n\t\t\t\t\t\t\t\t\t// Append file namespace prefix to filename if not already contains it\n\t\t\t\t\t\t\t\t\tif ( fileTitle.getNamespaceId() !== 6 ) {\n\t\t\t\t\t\t\t\t\t\tfileTitle = new mw.Title( fileName, 6 );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tfileName = fileTitle.toText();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\toptions = [ fileSize, fileFormat, fileFloat ];\n\t\t\t\t\t\t\t\t// Filter empty values\n\t\t\t\t\t\t\t\toptions = options.filter( function ( val ) {\n\t\t\t\t\t\t\t\t\treturn val.length && val !== 'default';\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t\tif ( fileAlt.length ) {\n\t\t\t\t\t\t\t\t\toptions.push( magicWordsI18N.img_alt[ 0 ].replace( '$1', fileAlt ) );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( caption.length ) {\n\t\t\t\t\t\t\t\t\toptions.push( caption );\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tfileUse = options.length === 0 ? fileName : ( fileName + '|' + options.join( '|' ) );\n\t\t\t\t\t\t\t\t$( this ).dialog( 'close' );\n\t\t\t\t\t\t\t\ttoolbarModule.fn.doAction(\n\t\t\t\t\t\t\t\t\t$( this ).data( 'context' ),\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'replace',\n\t\t\t\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\t\t\t\tpre: whitespace[ 0 ] + '[[',\n\t\t\t\t\t\t\t\t\t\t\tperi: fileUse,\n\t\t\t\t\t\t\t\t\t\t\tpost: ']]' + whitespace[ 1 ],\n\t\t\t\t\t\t\t\t\t\t\townline: true\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t$( this )\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t// Restore form state\n\t\t\t\t\t\t\t\t$( [ '#wikieditor-toolbar-file-target',\n\t\t\t\t\t\t\t\t\t'#wikieditor-toolbar-file-caption',\n\t\t\t\t\t\t\t\t\t'#wikieditor-toolbar-file-alt',\n\t\t\t\t\t\t\t\t\t'#wikieditor-toolbar-file-size' ].join( ',' )\n\t\t\t\t\t\t\t\t).val( '' );\n\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-file-float' ).val( 'default' );\n\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-file-format' ).val( magicWordsI18N.img_thumbnail[ 0 ] );\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t'wikieditor-toolbar-tool-file-cancel': function () {\n\t\t\t\t\t\t\t\t$( this ).dialog( 'close' );\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t'wikieditor-toolbar-tool-file-upload': function () {\n\t\t\t\t\t\t\t\t$( this ).dialog( 'close' );\n\t\t\t\t\t\t\t\tmw.loader.using( [\n\t\t\t\t\t\t\t\t\t'mediawiki.ForeignStructuredUpload.BookletLayout',\n\t\t\t\t\t\t\t\t\t'mediawiki.Upload.Dialog',\n\t\t\t\t\t\t\t\t\t'oojs-ui-windows'\n\t\t\t\t\t\t\t\t] ).then( function () {\n\t\t\t\t\t\t\t\t\tvar windowManager = new OO.ui.WindowManager(),\n\t\t\t\t\t\t\t\t\t\tuploadDialog = new mw.Upload.Dialog( {\n\t\t\t\t\t\t\t\t\t\t\tbookletClass: mw.ForeignStructuredUpload.BookletLayout\n\t\t\t\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t\t\t\twindowManager.$element.appendTo( document.body );\n\t\t\t\t\t\t\t\t\twindowManager.addWindows( [ uploadDialog ] );\n\t\t\t\t\t\t\t\t\twindowManager.openWindow( uploadDialog );\n\n\t\t\t\t\t\t\t\t\tuploadDialog.uploadBooklet.on( 'fileSaved', function ( imageInfo ) {\n\t\t\t\t\t\t\t\t\t\tuploadDialog.close();\n\t\t\t\t\t\t\t\t\t\twindowManager.$element.remove();\n\n\t\t\t\t\t\t\t\t\t\t$.wikiEditor.modules.dialogs.api.openDialog( this, 'insert-file' );\n\t\t\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-file-target' ).val( imageInfo.canonicaltitle );\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},\n\t\t\t\t\t\topen: function () {\n\t\t\t\t\t\t\tvar context, selection, parseFileSyntax,\n\t\t\t\t\t\t\t\tmagicWordsI18N = configData.magicWords,\n\t\t\t\t\t\t\t\tfileData = {\n\t\t\t\t\t\t\t\t\tpre: '',\n\t\t\t\t\t\t\t\t\tpost: '',\n\t\t\t\t\t\t\t\t\tfileName: '',\n\t\t\t\t\t\t\t\t\tcaption: '',\n\t\t\t\t\t\t\t\t\tfileAlt: '',\n\t\t\t\t\t\t\t\t\tfileSize: '',\n\t\t\t\t\t\t\t\t\tfileFloat: 'default',\n\t\t\t\t\t\t\t\t\tfileFormat: magicWordsI18N.img_thumbnail[ 0 ]\n\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\tparseFileSyntax = function ( wikitext ) {\n\t\t\t\t\t\t\t\tvar escapedPipe = '\\u0001',\n\t\t\t\t\t\t\t\t\tresult = {},\n\t\t\t\t\t\t\t\t\tmatch, params, file, i, param, paramOrig;\n\t\t\t\t\t\t\t\tif ( wikitext.indexOf( escapedPipe ) !== -1 ) {\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tmatch = /^(\\s*)\\[\\[(.*)\\]\\](\\s*)$/.exec( wikitext );\n\t\t\t\t\t\t\t\tif ( !match ) {\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tresult.pre = match[ 1 ];\n\t\t\t\t\t\t\t\tresult.post = match[ 3 ];\n\t\t\t\t\t\t\t\t// Escape pipes inside links and templates,\n\t\t\t\t\t\t\t\t// then split the parameters at the remaining pipes\n\t\t\t\t\t\t\t\tparams = match[ 2 ].replace( /\\[\\[[^[\\]]*\\]\\]|\\{\\{[^{}]\\}\\}/g, function ( link ) {\n\t\t\t\t\t\t\t\t\treturn link.replace( /\\|/g, escapedPipe );\n\t\t\t\t\t\t\t\t} ).split( '|' );\n\t\t\t\t\t\t\t\tfile = new mw.Title( params[ 0 ] );\n\t\t\t\t\t\t\t\tif ( file.getNamespaceId() !== 6 ) {\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tresult.fileName = file.getMainText();\n\t\t\t\t\t\t\t\tfor ( i = 1; i < params.length; i++ ) {\n\t\t\t\t\t\t\t\t\tparamOrig = params[ i ];\n\t\t\t\t\t\t\t\t\tparam = paramOrig.toLowerCase();\n\t\t\t\t\t\t\t\t\tif ( magicWordsI18N.img_right.indexOf( param ) !== -1 ) {\n\t\t\t\t\t\t\t\t\t\tresult.fileFloat = magicWordsI18N.img_right[ 0 ];\n\t\t\t\t\t\t\t\t\t} else if ( magicWordsI18N.img_left.indexOf( param ) !== -1 ) {\n\t\t\t\t\t\t\t\t\t\tresult.fileFloat = magicWordsI18N.img_left[ 0 ];\n\t\t\t\t\t\t\t\t\t} else if ( magicWordsI18N.img_none.indexOf( param ) !== -1 ) {\n\t\t\t\t\t\t\t\t\t\tresult.fileFloat = magicWordsI18N.img_none[ 0 ];\n\t\t\t\t\t\t\t\t\t} else if ( magicWordsI18N.img_center.indexOf( param ) !== -1 ) {\n\t\t\t\t\t\t\t\t\t\tresult.fileFloat = magicWordsI18N.img_center[ 0 ];\n\t\t\t\t\t\t\t\t\t} else if ( magicWordsI18N.img_thumbnail.indexOf( param ) !== -1 ) {\n\t\t\t\t\t\t\t\t\t\tresult.fileFormat = magicWordsI18N.img_thumbnail[ 0 ];\n\t\t\t\t\t\t\t\t\t} else if ( magicWordsI18N.img_framed.indexOf( param ) !== -1 ) {\n\t\t\t\t\t\t\t\t\t\tresult.fileFormat = magicWordsI18N.img_framed[ 0 ];\n\t\t\t\t\t\t\t\t\t} else if ( magicWordsI18N.img_frameless.indexOf( param ) !== -1 ) {\n\t\t\t\t\t\t\t\t\t\tresult.fileFormat = magicWordsI18N.img_frameless[ 0 ];\n\t\t\t\t\t\t\t\t\t} else if ( magicWordsI18N.img_alt.indexOf( param.split( '=', 2 )[ 0 ] + '=$1' ) !== -1 ) {\n\t\t\t\t\t\t\t\t\t\tresult.fileAlt = paramOrig.split( '=', 2 )[ 1 ];\n\t\t\t\t\t\t\t\t\t} else if ( /.+px$/.test( param ) ) {\n\t\t\t\t\t\t\t\t\t\tresult.fileSize = param.replace( /px$/, '' );\n\t\t\t\t\t\t\t\t\t} else if ( param === '' ) {\n\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t} else if ( i === params.length - 1 ) { // Last param -> caption\n\t\t\t\t\t\t\t\t\t\tresult.caption = paramOrig.replace( new RegExp( mw.util.escapeRegExp( escapedPipe ), 'g' ), '|' );\n\t\t\t\t\t\t\t\t\t} else { // Unknown param\n\t\t\t\t\t\t\t\t\t\treturn false;\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\tif ( !result.fileFormat ) {\n\t\t\t\t\t\t\t\t\tresult.fileFormat = 'default';\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn result;\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t// Retrieve the current selection\n\t\t\t\t\t\t\tcontext = $( this ).data( 'context' );\n\t\t\t\t\t\t\tselection = context.$textarea.textSelection( 'getSelection' );\n\n\t\t\t\t\t\t\t// Pre-fill the text fields based on the current selection\n\t\t\t\t\t\t\tif ( selection !== '' ) {\n\t\t\t\t\t\t\t\tfileData = $.extend( fileData, parseFileSyntax( selection ) );\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Initialize the form fields\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-file-dialog' )\n\t\t\t\t\t\t\t\t.data( 'whitespace', [ fileData.pre, fileData.post ] );\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-file-target' ).val( fileData.fileName );\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-file-caption' ).val( fileData.caption );\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-file-alt' ).val( fileData.fileAlt );\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-file-float' ).val( fileData.fileFloat );\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-file-format' ).val( fileData.fileFormat );\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-file-size' ).val( fileData.fileSize );\n\n\t\t\t\t\t\t\t// Set focus\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-file-target' ).trigger( 'focus' );\n\n\t\t\t\t\t\t\tif ( !( $( this ).data( 'dialogkeypressset' ) ) ) {\n\t\t\t\t\t\t\t\t$( this ).data( 'dialogkeypressset', true );\n\t\t\t\t\t\t\t\t// Execute the action associated with the first button\n\t\t\t\t\t\t\t\t// when the user presses Enter\n\t\t\t\t\t\t\t\t$( this ).closest( '.ui-dialog' ).on( 'keypress', function ( e ) {\n\t\t\t\t\t\t\t\t\tif ( e.which === 13 ) {\n\t\t\t\t\t\t\t\t\t\ttriggerButtonClick( this );\n\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t\t\t// Make tabbing to a button and pressing\n\t\t\t\t\t\t\t\t// Enter do what people expect\n\t\t\t\t\t\t\t\t$( this ).closest( '.ui-dialog' ).find( 'button' ).on( 'focus', function () {\n\t\t\t\t\t\t\t\t\t$( this ).closest( '.ui-dialog' ).data( 'dialogaction', this );\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t'insert-table': {\n\t\t\t\t\ttitleMsg: 'wikieditor-toolbar-tool-table-title',\n\t\t\t\t\tid: 'wikieditor-toolbar-table-dialog',\n\t\t\t\t\thtmlTemplate: 'dialogInsertTable.html',\n\t\t\t\t\tinit: function () {\n\t\t\t\t\t\t$( this ).find( '[rel]' ).each( function () {\n\t\t\t\t\t\t\t// eslint-disable-next-line mediawiki/msg-doc\n\t\t\t\t\t\t\t$( this ).text( mw.msg( $( this ).attr( 'rel' ) ) );\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t$( '#wikieditor-toolbar-table-dimensions-rows' ).val( 3 );\n\t\t\t\t\t\t$( '#wikieditor-toolbar-table-dimensions-columns' ).val( 3 );\n\t\t\t\t\t\t$( '#wikieditor-toolbar-table-wikitable' ).on( 'click', function () {\n\t\t\t\t\t\t\t// eslint-disable-next-line no-jquery/no-class-state\n\t\t\t\t\t\t\t$( '.wikieditor-toolbar-table-preview' ).toggleClass( 'wikitable' );\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t// Hack for sortable preview: dynamically adding\n\t\t\t\t\t\t// sortable class doesn't work, so we use a clone\n\t\t\t\t\t\t$( '#wikieditor-toolbar-table-preview' )\n\t\t\t\t\t\t\t.clone()\n\t\t\t\t\t\t\t.attr( 'id', 'wikieditor-toolbar-table-preview2' )\n\t\t\t\t\t\t\t.addClass( 'sortable' )\n\t\t\t\t\t\t\t.insertAfter( $( '#wikieditor-toolbar-table-preview' ) )\n\t\t\t\t\t\t\t.hide();\n\n\t\t\t\t\t\tmw.loader.using( 'jquery.tablesorter', function () {\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-table-preview2' ).tablesorter();\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t$( '#wikieditor-toolbar-table-sortable' ).on( 'click', function () {\n\t\t\t\t\t\t\t// Swap the currently shown one clone with the other one\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-table-preview' )\n\t\t\t\t\t\t\t\t.hide()\n\t\t\t\t\t\t\t\t.attr( 'id', 'wikieditor-toolbar-table-preview3' );\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-table-preview2' )\n\t\t\t\t\t\t\t\t.attr( 'id', 'wikieditor-toolbar-table-preview' )\n\t\t\t\t\t\t\t\t.show();\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-table-preview3' ).attr( 'id', 'wikieditor-toolbar-table-preview2' );\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t$( '#wikieditor-toolbar-table-dimensions-header' ).on( 'click', function () {\n\t\t\t\t\t\t\t// Instead of show/hiding, switch the HTML around\n\t\t\t\t\t\t\t// We do this because the sortable tables script styles the first row,\n\t\t\t\t\t\t\t// visible or not\n\t\t\t\t\t\t\tvar $sortable,\n\t\t\t\t\t\t\t\theaderHTML = $( '.wikieditor-toolbar-table-preview-header' ).html(),\n\t\t\t\t\t\t\t\thiddenHTML = $( '.wikieditor-toolbar-table-preview-hidden' ).html();\n\t\t\t\t\t\t\t$( '.wikieditor-toolbar-table-preview-header' ).html( hiddenHTML );\n\t\t\t\t\t\t\t$( '.wikieditor-toolbar-table-preview-hidden' ).html( headerHTML );\n\t\t\t\t\t\t\t$sortable = $( '#wikieditor-toolbar-table-preview, #wikieditor-toolbar-table-preview2' )\n\t\t\t\t\t\t\t\t.filter( '.sortable' );\n\t\t\t\t\t\t\tmw.loader.using( 'jquery.tablesorter', function () {\n\t\t\t\t\t\t\t\t$sortable.tablesorter();\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} );\n\t\t\t\t\t},\n\t\t\t\t\tdialog: {\n\t\t\t\t\t\tresizable: false,\n\t\t\t\t\t\tdialogClass: 'wikiEditor-toolbar-dialog',\n\t\t\t\t\t\twidth: 590,\n\t\t\t\t\t\tbuttons: {\n\t\t\t\t\t\t\t'wikieditor-toolbar-tool-table-insert': function () {\n\t\t\t\t\t\t\t\tvar captionText, headerText, normalText, table, r, c,\n\t\t\t\t\t\t\t\t\tisHeader, delim, classes, classStr,\n\t\t\t\t\t\t\t\t\trowsVal = $( '#wikieditor-toolbar-table-dimensions-rows' ).val(),\n\t\t\t\t\t\t\t\t\tcolsVal = $( '#wikieditor-toolbar-table-dimensions-columns' ).val(),\n\t\t\t\t\t\t\t\t\trows = parseInt( rowsVal, 10 ),\n\t\t\t\t\t\t\t\t\tcols = parseInt( colsVal, 10 ),\n\t\t\t\t\t\t\t\t\theader = $( '#wikieditor-toolbar-table-dimensions-header' ).prop( 'checked' ) ? 1 : 0;\n\t\t\t\t\t\t\t\tif ( isNaN( rows ) || isNaN( cols ) || String( rows ) !== rowsVal || String( cols ) !== colsVal || rowsVal < 0 || colsVal < 0 ) {\n\t\t\t\t\t\t\t\t\t// eslint-disable-next-line no-alert\n\t\t\t\t\t\t\t\t\talert( mw.msg( 'wikieditor-toolbar-tool-table-invalidnumber' ) );\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( rows + header === 0 || cols === 0 ) {\n\t\t\t\t\t\t\t\t\t// eslint-disable-next-line no-alert\n\t\t\t\t\t\t\t\t\talert( mw.msg( 'wikieditor-toolbar-tool-table-zero' ) );\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( ( rows * cols ) > 1000 ) {\n\t\t\t\t\t\t\t\t\t// eslint-disable-next-line no-alert\n\t\t\t\t\t\t\t\t\talert( mw.msg( 'wikieditor-toolbar-tool-table-toomany', mw.language.convertNumber( 1000 ) ) );\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcaptionText = mw.msg( 'wikieditor-toolbar-tool-table-example-caption' );\n\t\t\t\t\t\t\t\theaderText = mw.msg( 'wikieditor-toolbar-tool-table-example-header' );\n\t\t\t\t\t\t\t\tnormalText = mw.msg( 'wikieditor-toolbar-tool-table-example' );\n\t\t\t\t\t\t\t\ttable = '';\n\t\t\t\t\t\t\t\ttable += '|+ ' + captionText + '\\n';\n\t\t\t\t\t\t\t\tfor ( r = 0; r < rows + header; r++ ) {\n\t\t\t\t\t\t\t\t\ttable += '|-\\n';\n\t\t\t\t\t\t\t\t\tfor ( c = 0; c < cols; c++ ) {\n\t\t\t\t\t\t\t\t\t\tisHeader = ( header && r === 0 );\n\t\t\t\t\t\t\t\t\t\tdelim = isHeader ? '!' : '|';\n\t\t\t\t\t\t\t\t\t\tif ( c > 0 ) {\n\t\t\t\t\t\t\t\t\t\t\tdelim += delim;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\ttable += delim + ' ' + ( isHeader ? headerText : normalText ) + ' ';\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t// Replace trailing space by newline\n\t\t\t\t\t\t\t\t\t// table[table.length - 1] is read-only\n\t\t\t\t\t\t\t\t\ttable = table.substr( 0, table.length - 1 ) + '\\n';\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tclasses = [];\n\t\t\t\t\t\t\t\tif ( $( '#wikieditor-toolbar-table-wikitable' ).is( ':checked' ) ) {\n\t\t\t\t\t\t\t\t\tclasses.push( 'wikitable' );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( $( '#wikieditor-toolbar-table-sortable' ).is( ':checked' ) ) {\n\t\t\t\t\t\t\t\t\tclasses.push( 'sortable' );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tclassStr = classes.length > 0 ? ' class=\"' + classes.join( ' ' ) + '\"' : '';\n\t\t\t\t\t\t\t\t$( this ).dialog( 'close' );\n\t\t\t\t\t\t\t\ttoolbarModule.fn.doAction(\n\t\t\t\t\t\t\t\t\t$( this ).data( 'context' ),\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'replace',\n\t\t\t\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\t\t\t\tpre: '{|' + classStr + '\\n',\n\t\t\t\t\t\t\t\t\t\t\tperi: table,\n\t\t\t\t\t\t\t\t\t\t\tpost: '|}',\n\t\t\t\t\t\t\t\t\t\t\townline: true\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t$( this )\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t// Restore form state\n\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-table-dimensions-rows' ).val( 3 );\n\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-table-dimensions-columns' ).val( 3 );\n\t\t\t\t\t\t\t\t// Simulate clicks instead of setting values, so the according\n\t\t\t\t\t\t\t\t// actions are performed\n\t\t\t\t\t\t\t\tif ( !$( '#wikieditor-toolbar-table-dimensions-header' ).is( ':checked' ) ) {\n\t\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-table-dimensions-header' ).trigger( 'click' );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( !$( '#wikieditor-toolbar-table-wikitable' ).is( ':checked' ) ) {\n\t\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-table-wikitable' ).trigger( 'click' );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( $( '#wikieditor-toolbar-table-sortable' ).is( ':checked' ) ) {\n\t\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-table-sortable' ).trigger( 'click' );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t'wikieditor-toolbar-tool-table-cancel': function () {\n\t\t\t\t\t\t\t\t$( this ).dialog( 'close' );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\topen: function () {\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-table-dimensions-rows' ).trigger( 'focus' );\n\t\t\t\t\t\t\tif ( !( $( this ).data( 'dialogkeypressset' ) ) ) {\n\t\t\t\t\t\t\t\t$( this ).data( 'dialogkeypressset', true );\n\t\t\t\t\t\t\t\t// Execute the action associated with the first button\n\t\t\t\t\t\t\t\t// when the user presses Enter\n\t\t\t\t\t\t\t\t$( this ).closest( '.ui-dialog' ).on( 'keypress', function ( e ) {\n\t\t\t\t\t\t\t\t\tif ( ( e.keyCode || e.which ) === 13 ) {\n\t\t\t\t\t\t\t\t\t\ttriggerButtonClick( this );\n\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t\t\t// Make tabbing to a button and pressing\n\t\t\t\t\t\t\t\t// Enter do what people expect\n\t\t\t\t\t\t\t\t$( this ).closest( '.ui-dialog' ).find( 'button' ).on( 'focus', function () {\n\t\t\t\t\t\t\t\t\t$( this ).closest( '.ui-dialog' ).data( 'dialogaction', this );\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t'search-and-replace': {\n\t\t\t\t\ttitleMsg: 'wikieditor-toolbar-tool-replace-title',\n\t\t\t\t\tid: 'wikieditor-toolbar-replace-dialog',\n\t\t\t\t\thtmlTemplate: 'dialogReplace.html',\n\t\t\t\t\tinit: function () {\n\t\t\t\t\t\t$( this ).find( '[rel]' ).each( function () {\n\t\t\t\t\t\t\t// eslint-disable-next-line mediawiki/msg-doc\n\t\t\t\t\t\t\t$( this ).text( mw.msg( $( this ).attr( 'rel' ) ) );\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t// TODO: Find a cleaner way to share this function\n\t\t\t\t\t\t$( this ).data( 'replaceCallback', function ( mode ) {\n\t\t\t\t\t\t\tvar offset, textRemainder, regex,\n\t\t\t\t\t\t\t\tsearchStr, replaceStr, flags, matchCase, matchWord, isRegex,\n\t\t\t\t\t\t\t\t$textarea, text, match,\n\t\t\t\t\t\t\t\tactualReplacement,\n\t\t\t\t\t\t\t\tstart, end;\n\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-replace-nomatch, #wikieditor-toolbar-replace-success, #wikieditor-toolbar-replace-emptysearch, #wikieditor-toolbar-replace-invalidregex' ).hide();\n\n\t\t\t\t\t\t\t// Search string cannot be empty\n\t\t\t\t\t\t\tsearchStr = $( '#wikieditor-toolbar-replace-search' ).val();\n\t\t\t\t\t\t\tif ( searchStr === '' ) {\n\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-replace-emptysearch' ).show();\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Replace string can be empty\n\t\t\t\t\t\t\treplaceStr = $( '#wikieditor-toolbar-replace-replace' ).val();\n\n\t\t\t\t\t\t\t// Prepare the regular expression flags\n\t\t\t\t\t\t\tflags = 'm';\n\t\t\t\t\t\t\tmatchCase = $( '#wikieditor-toolbar-replace-case' ).is( ':checked' );\n\t\t\t\t\t\t\tif ( !matchCase ) {\n\t\t\t\t\t\t\t\tflags += 'i';\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tisRegex = $( '#wikieditor-toolbar-replace-regex' ).is( ':checked' );\n\t\t\t\t\t\t\tif ( !isRegex ) {\n\t\t\t\t\t\t\t\tsearchStr = mw.util.escapeRegExp( searchStr );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tmatchWord = $( '#wikieditor-toolbar-replace-word' ).is( ':checked' );\n\t\t\t\t\t\t\tif ( matchWord ) {\n\t\t\t\t\t\t\t\tsearchStr = '\\\\b(?:' + searchStr + ')\\\\b';\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( mode === 'replaceAll' ) {\n\t\t\t\t\t\t\t\tflags += 'g';\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tregex = new RegExp( searchStr, flags );\n\t\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-replace-invalidregex' )\n\t\t\t\t\t\t\t\t\t.text( mw.msg( 'wikieditor-toolbar-tool-replace-invalidregex',\n\t\t\t\t\t\t\t\t\t\te.message ) )\n\t\t\t\t\t\t\t\t\t.show();\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t$textarea = $( this ).data( 'context' ).$textarea;\n\t\t\t\t\t\t\ttext = $textarea.textSelection( 'getContents' );\n\t\t\t\t\t\t\tmatch = false;\n\t\t\t\t\t\t\tif ( mode !== 'replaceAll' ) {\n\t\t\t\t\t\t\t\tif ( mode === 'replace' ) {\n\t\t\t\t\t\t\t\t\toffset = $( this ).data( 'matchIndex' );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\toffset = $( this ).data( 'offset' );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\ttextRemainder = text.substr( offset );\n\t\t\t\t\t\t\t\tmatch = textRemainder.match( regex );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( !match ) {\n\t\t\t\t\t\t\t\t// Search hit BOTTOM, continuing at TOP\n\t\t\t\t\t\t\t\t// TODO: Add a \"Wrap around\" option.\n\t\t\t\t\t\t\t\toffset = 0;\n\t\t\t\t\t\t\t\ttextRemainder = text;\n\t\t\t\t\t\t\t\tmatch = textRemainder.match( regex );\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( !match ) {\n\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-replace-nomatch' ).show();\n\t\t\t\t\t\t\t} else if ( mode === 'replaceAll' ) {\n\t\t\t\t\t\t\t\t$textarea.textSelection( 'setContents', text.replace( regex, replaceStr ) );\n\t\t\t\t\t\t\t\t$( '#wikieditor-toolbar-replace-success' )\n\t\t\t\t\t\t\t\t\t.text( mw.msg( 'wikieditor-toolbar-tool-replace-success', mw.language.convertNumber( match.length ) ) )\n\t\t\t\t\t\t\t\t\t.show();\n\t\t\t\t\t\t\t\t$( this ).data( 'offset', 0 );\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tif ( mode === 'replace' ) {\n\n\t\t\t\t\t\t\t\t\tif ( isRegex ) {\n\t\t\t\t\t\t\t\t\t\t// If backreferences (like $1) are used, the actual actual replacement string will be different\n\t\t\t\t\t\t\t\t\t\tactualReplacement = match[ 0 ].replace( regex, replaceStr );\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tactualReplacement = replaceStr;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif ( match ) {\n\t\t\t\t\t\t\t\t\t\t// Do the replacement\n\t\t\t\t\t\t\t\t\t\t$textarea.textSelection( 'encapsulateSelection', {\n\t\t\t\t\t\t\t\t\t\t\tperi: actualReplacement,\n\t\t\t\t\t\t\t\t\t\t\treplace: true,\n\t\t\t\t\t\t\t\t\t\t\tselectionStart: offset + match.index,\n\t\t\t\t\t\t\t\t\t\t\tselectionEnd: offset + match.index + match[ 0 ].length,\n\t\t\t\t\t\t\t\t\t\t\tselectPeri: true\n\t\t\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t\t\t\t// Reload the text after replacement\n\t\t\t\t\t\t\t\t\t\ttext = $textarea.textSelection( 'getContents' );\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Find the next instance\n\t\t\t\t\t\t\t\t\toffset = offset + match.index + actualReplacement.length;\n\t\t\t\t\t\t\t\t\ttextRemainder = text.substr( offset );\n\t\t\t\t\t\t\t\t\tmatch = textRemainder.match( regex );\n\n\t\t\t\t\t\t\t\t\tif ( match ) {\n\t\t\t\t\t\t\t\t\t\tstart = offset + match.index;\n\t\t\t\t\t\t\t\t\t\tend = start + match[ 0 ].length;\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t// If no new string was found, try searching from the beginning.\n\t\t\t\t\t\t\t\t\t\t// TODO: Add a \"Wrap around\" option.\n\t\t\t\t\t\t\t\t\t\ttextRemainder = text;\n\t\t\t\t\t\t\t\t\t\tmatch = textRemainder.match( regex );\n\t\t\t\t\t\t\t\t\t\tif ( match ) {\n\t\t\t\t\t\t\t\t\t\t\tstart = match.index;\n\t\t\t\t\t\t\t\t\t\t\tend = start + match[ 0 ].length;\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t// Give up\n\t\t\t\t\t\t\t\t\t\t\tstart = 0;\n\t\t\t\t\t\t\t\t\t\t\tend = 0;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tstart = offset + match.index;\n\t\t\t\t\t\t\t\t\tend = start + match[ 0 ].length;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t$( this ).data( 'matchIndex', start );\n\n\t\t\t\t\t\t\t\t$textarea.textSelection( 'setSelection', {\n\t\t\t\t\t\t\t\t\tstart: start,\n\t\t\t\t\t\t\t\t\tend: end } );\n\t\t\t\t\t\t\t\t$textarea.textSelection( 'scrollToCaretPosition' );\n\t\t\t\t\t\t\t\t$( this ).data( 'offset', end );\n\t\t\t\t\t\t\t\t$textarea[ 0 ].focus();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t},\n\t\t\t\t\tdialog: {\n\t\t\t\t\t\twidth: 500,\n\t\t\t\t\t\tdialogClass: 'wikiEditor-toolbar-dialog',\n\t\t\t\t\t\tmodal: false,\n\t\t\t\t\t\tbuttons: {\n\t\t\t\t\t\t\t'wikieditor-toolbar-tool-replace-button-findnext': function ( e ) {\n\t\t\t\t\t\t\t\t$( this ).closest( '.ui-dialog' ).data( 'dialogaction', e.target );\n\t\t\t\t\t\t\t\t$( this ).data( 'replaceCallback' ).call( this, 'find' );\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t'wikieditor-toolbar-tool-replace-button-replace': function ( e ) {\n\t\t\t\t\t\t\t\t$( this ).closest( '.ui-dialog' ).data( 'dialogaction', e.target );\n\t\t\t\t\t\t\t\t$( this ).data( 'replaceCallback' ).call( this, 'replace' );\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t'wikieditor-toolbar-tool-replace-button-replaceall': function ( e ) {\n\t\t\t\t\t\t\t\t$( this ).closest( '.ui-dialog' ).data( 'dialogaction', e.target );\n\t\t\t\t\t\t\t\t$( this ).data( 'replaceCallback' ).call( this, 'replaceAll' );\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t'wikieditor-toolbar-tool-replace-close': function () {\n\t\t\t\t\t\t\t\t$( this ).dialog( 'close' );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\topen: function () {\n\t\t\t\t\t\t\tvar $dialog, context, $textbox,\n\t\t\t\t\t\t\t\tthat = this;\n\t\t\t\t\t\t\t$( this ).data( 'offset', 0 );\n\t\t\t\t\t\t\t$( this ).data( 'matchIndex', 0 );\n\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-replace-search' ).trigger( 'focus' );\n\t\t\t\t\t\t\t$( '#wikieditor-toolbar-replace-nomatch, #wikieditor-toolbar-replace-success, #wikieditor-toolbar-replace-emptysearch, #wikieditor-toolbar-replace-invalidregex' ).hide();\n\t\t\t\t\t\t\tif ( !( $( this ).data( 'onetimeonlystuff' ) ) ) {\n\t\t\t\t\t\t\t\t$( this ).data( 'onetimeonlystuff', true );\n\t\t\t\t\t\t\t\t// Execute the action associated with the first button\n\t\t\t\t\t\t\t\t// when the user presses Enter\n\t\t\t\t\t\t\t\t$( this ).closest( '.ui-dialog' ).on( 'keypress', function ( e ) {\n\t\t\t\t\t\t\t\t\tif ( ( e.keyCode || e.which ) === 13 ) {\n\t\t\t\t\t\t\t\t\t\ttriggerButtonClick( this );\n\t\t\t\t\t\t\t\t\t\te.preventDefault();\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\t// Make tabbing to a button and pressing\n\t\t\t\t\t\t\t\t// Enter do what people expect\n\t\t\t\t\t\t\t\t$( this ).closest( '.ui-dialog' ).find( 'button' ).on( 'focus', function () {\n\t\t\t\t\t\t\t\t\t$( this ).closest( '.ui-dialog' ).data( 'dialogaction', this );\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$dialog = $( this ).closest( '.ui-dialog' );\n\t\t\t\t\t\t\tthat = this;\n\t\t\t\t\t\t\tcontext = $( this ).data( 'context' );\n\t\t\t\t\t\t\t$textbox = context.$textarea;\n\n\t\t\t\t\t\t\t$textbox\n\t\t\t\t\t\t\t\t.on( 'keypress.srdialog', function ( e ) {\n\t\t\t\t\t\t\t\t\tif ( e.which === 13 ) {\n\t\t\t\t\t\t\t\t\t\t// Enter\n\t\t\t\t\t\t\t\t\t\ttriggerButtonClick( $dialog );\n\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t} else if ( e.which === 27 ) {\n\t\t\t\t\t\t\t\t\t\t// Escape\n\t\t\t\t\t\t\t\t\t\t$( that ).dialog( 'close' );\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},\n\t\t\t\t\t\tclose: function () {\n\t\t\t\t\t\t\tvar context = $( this ).data( 'context' ),\n\t\t\t\t\t\t\t\t$textbox = context.$textarea;\n\t\t\t\t\t\t\t$textbox.off( 'keypress.srdialog' );\n\t\t\t\t\t\t\t$( this ).closest( '.ui-dialog' ).data( 'dialogaction', false );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} };\n\t\t}\n\n\t};\n\n}() );\n","usedDeprecatedRules":[]},{"filePath":"/src/repo/modules/jquery.wikiEditor.dialogs.js","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/modules/jquery.wikiEditor.js","messages":[{"ruleId":"no-shadow","severity":1,"message":"'context' is already declared in the upper scope on line 226 column 7.","line":271,"column":27,"nodeType":"Identifier","messageId":"noShadow","endLine":271,"endColumn":34},{"ruleId":"no-shadow","severity":1,"message":"'module' is already declared in the upper scope on line 227 column 19.","line":272,"column":10,"nodeType":"Identifier","messageId":"noShadow","endLine":272,"endColumn":16},{"ruleId":"no-shadow","severity":1,"message":"'call' is already declared in the upper scope on line 227 column 38.","line":272,"column":18,"nodeType":"Identifier","messageId":"noShadow","endLine":272,"endColumn":22},{"ruleId":"no-shadow","severity":1,"message":"'modules' is already declared in the upper scope on line 227 column 10.","line":273,"column":7,"nodeType":"Identifier","messageId":"noShadow","endLine":273,"endColumn":14},{"ruleId":"no-shadow","severity":1,"message":"'module' is already declared in the upper scope on line 227 column 19.","line":328,"column":29,"nodeType":"Identifier","messageId":"noShadow","endLine":328,"endColumn":35},{"ruleId":"no-shadow","severity":1,"message":"'options' is already declared in the upper scope on line 395 column 25.","line":397,"column":23,"nodeType":"Identifier","messageId":"noShadow","endLine":397,"endColumn":30},{"ruleId":"mediawiki/class-doc","severity":1,"message":"All possible CSS classes should be documented. See https://w.wiki/PS2 for details.","line":439,"column":13,"nodeType":"CallExpression","endLine":440,"endColumn":75}],"errorCount":0,"warningCount":7,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This plugin provides a way to build a wiki-text editing user interface around a textarea.\n *\n * @example To initialize without any modules,\n * overqualified `div#edittoolbar` to avoid MediaWiki's heading to id automatism:\n *     $( 'div#edittoolbar' ).wikiEditor();\n *\n * @example To initialize with one or more modules, or to add modules after it's already been initialized:\n *     $( 'textarea#wpTextbox1' ).wikiEditor( 'addModule', 'toolbar', { ... config ... } );\n *\n */\n( function () {\n\n\tvar hasOwn = Object.prototype.hasOwnProperty,\n\n\t\t/**\n\t\t * Array of language codes.\n\t\t */\n\t\tfallbackChain = ( function () {\n\t\t\t// eslint-disable-next-line no-jquery/no-class-state\n\t\t\tvar isRTL = $( document.body ).hasClass( 'rtl' ),\n\t\t\t\tchain = mw.language.getFallbackLanguageChain();\n\n\t\t\t// Do not fallback to 'en'\n\t\t\tif ( chain.length >= 2 && !/^en-/.test( chain[ chain.length - 2 ] ) ) {\n\t\t\t\tchain.pop();\n\t\t\t}\n\t\t\tif ( isRTL ) {\n\t\t\t\tchain.push( 'default-rtl' );\n\t\t\t}\n\t\t\tchain.push( 'default' );\n\t\t\treturn chain;\n\t\t}() );\n\n\t/**\n\t * Global static object for wikiEditor that provides generally useful functionality to all modules and contexts.\n\t */\n\t$.wikiEditor = {\n\t\t/**\n\t\t * For each module that is loaded, static code shared by all instances is loaded into this object organized by\n\t\t * module name. The existence of a module in this object only indicates the module is available. To check if a\n\t\t * module is in use by a specific context check the context.modules object.\n\t\t */\n\t\tmodules: {\n\t\t\ttoolbar: require( './jquery.wikiEditor.toolbar.js' ),\n\t\t\tdialogs: require( './jquery.wikiEditor.dialogs.js' )\n\t\t},\n\n\t\t/**\n\t\t * A context can be extended, such as adding iframe support, on a per-wikiEditor instance basis.\n\t\t */\n\t\textensions: {},\n\n\t\t/**\n\t\t * In some cases like with the iframe's HTML file, it's convenient to have a lookup table of all instances of the\n\t\t * WikiEditor. Each context contains an instance field which contains a key that corresponds to a reference to the\n\t\t * textarea which the WikiEditor was build around. This way, by passing a simple integer you can provide a way back\n\t\t * to a specific context.\n\t\t */\n\t\tinstances: [],\n\n\t\t/**\n\t\t * Path to images - this is a bit messy, and it would need to change if this code (and images) gets moved into the\n\t\t * core - or anywhere for that matter...\n\t\t */\n\t\timgPath: mw.config.get( 'wgExtensionAssetsPath' ) + '/WikiEditor/modules/images/',\n\n\t\t/**\n\t\t * Checks if a module has a specific requirement\n\t\t *\n\t\t * @param {Object} module Module object\n\t\t * @param {string} requirement String identifying requirement\n\t\t * @return {boolean}\n\t\t */\n\t\tisRequired: function ( module, requirement ) {\n\t\t\tvar req;\n\t\t\tif ( typeof module.req !== 'undefined' ) {\n\t\t\t\tfor ( req in module.req ) {\n\t\t\t\t\tif ( module.req[ req ] === requirement ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\n\t\t/**\n\t\t * Provides a way to extract messages from objects. Wraps a mw.message( ... ).text() call.\n\t\t *\n\t\t * FIXME: This is a security nightmare. Only use is for the help toolbar panel. Inline the\n\t\t *        special need instead?\n\t\t * FIXME: Also, this is ludicrously complex. Just use mw.message().text() directly.\n\t\t *\n\t\t * @param {Object} object Object to extract messages from\n\t\t * @param {string} property String of name of property which contains the message. This should be the base name of the\n\t\t * property, which means that in the case of the object { this: 'that', fooMsg: 'bar' }, passing property as 'this'\n\t\t * would return the raw text 'that', while passing property as 'foo' would return the internationalized message\n\t\t * with the key 'bar'.\n\t\t * @return {string}\n\t\t */\n\t\tautoMsg: function ( object, property ) {\n\t\t\tvar i, p;\n\t\t\t// Accept array of possible properties, of which the first one found will be used\n\t\t\tif ( typeof property === 'object' ) {\n\t\t\t\tfor ( i in property ) {\n\t\t\t\t\tif ( property[ i ] in object || property[ i ] + 'Msg' in object ) {\n\t\t\t\t\t\tproperty = property[ i ];\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( property in object ) {\n\t\t\t\treturn object[ property ];\n\t\t\t} else if ( property + 'Msg' in object ) {\n\t\t\t\tp = object[ property + 'Msg' ];\n\t\t\t\tif ( Array.isArray( p ) && p.length >= 2 ) {\n\t\t\t\t\treturn mw.message.apply( mw.message, p ).text();\n\t\t\t\t} else {\n\t\t\t\t\t// eslint-disable-next-line mediawiki/msg-doc\n\t\t\t\t\treturn mw.message( p ).text();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn '';\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Provides a way to extract messages from objects. Wraps a mw.message( ... ).escaped() call.\n\t\t *\n\t\t * FIXME: This is ludicrously complex. Just use mw.message().escaped() directly.\n\t\t *\n\t\t * @param {Object} object Object to extract messages from\n\t\t * @param {string} property String of name of property which contains the message. This should be the base name of the\n\t\t * property, which means that in the case of the object { this: 'that', fooMsg: 'bar' }, passing property as 'this'\n\t\t * would return the raw text 'that', while passing property as 'foo' would return the internationalized message\n\t\t * with the key 'bar'. This is then escaped.\n\t\t * @return {string}\n\t\t */\n\t\tautoSafeMsg: function ( object, property ) {\n\t\t\tvar i, p;\n\t\t\t// Accept array of possible properties, of which the first one found will be used\n\t\t\tif ( typeof property === 'object' ) {\n\t\t\t\tfor ( i in property ) {\n\t\t\t\t\tif ( property[ i ] in object || property[ i ] + 'Msg' in object ) {\n\t\t\t\t\t\tproperty = property[ i ];\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( property in object ) {\n\t\t\t\treturn object[ property ];\n\t\t\t} else if ( property + 'Msg' in object ) {\n\t\t\t\tp = object[ property + 'Msg' ];\n\t\t\t\tif ( Array.isArray( p ) && p.length >= 2 ) {\n\t\t\t\t\treturn mw.message.apply( mw.message, p ).escaped();\n\t\t\t\t} else {\n\t\t\t\t\t// eslint-disable-next-line mediawiki/msg-doc\n\t\t\t\t\treturn mw.message( p ).escaped();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn '';\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Provides a way to extract a property of an object in a certain language, falling back on the property keyed as\n\t\t * 'default' or 'default-rtl'. If such key doesn't exist, the object itself is considered the actual value, which\n\t\t * should ideally be the case so that you may use a string or object of any number of strings keyed by language\n\t\t * with a default.\n\t\t *\n\t\t * @param {Object} object Object to extract property from\n\t\t * @return {Object}\n\t\t */\n\t\tautoLang: function ( object ) {\n\t\t\tvar i, key;\n\n\t\t\tfor ( i = 0; i < fallbackChain.length; i++ ) {\n\t\t\t\tkey = fallbackChain[ i ];\n\t\t\t\tif ( hasOwn.call( object, key ) ) {\n\t\t\t\t\treturn object[ key ];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn object;\n\t\t},\n\n\t\t/**\n\t\t * Provides a way to extract the path of an icon in a certain language, automatically appending a version number for\n\t\t * caching purposes and prepending an image path when icon paths are relative.\n\t\t *\n\t\t * @param {Object} icon Icon object from e.g. toolbar config\n\t\t * @param {string} path Default icon path, defaults to $.wikiEditor.imgPath\n\t\t * @return {Object}\n\t\t */\n\t\tautoIcon: function ( icon, path ) {\n\t\t\tvar i, key, src;\n\n\t\t\tpath = path || $.wikiEditor.imgPath;\n\n\t\t\tfor ( i = 0; i < fallbackChain.length; i++ ) {\n\t\t\t\tkey = fallbackChain[ i ];\n\t\t\t\tif ( icon && hasOwn.call( icon, key ) ) {\n\t\t\t\t\tsrc = icon[ key ];\n\n\t\t\t\t\t// Return a data URL immediately\n\t\t\t\t\tif ( src.substr( 0, 5 ) === 'data:' ) {\n\t\t\t\t\t\treturn src;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prepend path if src is not absolute\n\t\t\t\t\tif ( src.substr( 0, 7 ) !== 'http://' && src.substr( 0, 8 ) !== 'https://' && src[ 0 ] !== '/' ) {\n\t\t\t\t\t\tsrc = path + src;\n\t\t\t\t\t}\n\t\t\t\t\treturn src;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn icon;\n\t\t}\n\t};\n\n\t/**\n\t * jQuery plugin that provides a way to initialize a wikiEditor instance on a textarea.\n\t *\n\t * @return {jQuery}\n\t */\n\t$.fn.wikiEditor = function () {\n\t\tvar context, hasFocus, cursorPos,\n\t\t\targs, modules, module, extension, call;\n\n\t\t/* Initialization */\n\n\t\t// The wikiEditor context is stored in the element's data, so when this function gets called again we can pick up right\n\t\t// where we left off\n\t\tcontext = $( this ).data( 'wikiEditor-context' );\n\t\t// On first call, we need to set things up, but on all following calls we can skip right to the API handling\n\t\tif ( !context || typeof context === 'undefined' ) {\n\n\t\t\t// Star filling the context with useful data - any jQuery selections, as usual should be named with a preceding $\n\t\t\tcontext = {\n\t\t\t\t// Reference to the textarea element which the wikiEditor is being built around\n\t\t\t\t$textarea: $( this ),\n\t\t\t\t// Reference to the focused element before the dialog opens, so it can be restored once it closes\n\t\t\t\t$focusedElem: null,\n\t\t\t\t// Container for any number of mutually exclusive views that are accessible by tabs\n\t\t\t\tviews: {},\n\t\t\t\t// Container for any number of module-specific data - only including data for modules in use on this context\n\t\t\t\tmodules: {},\n\t\t\t\t// General place to shove bits of data into\n\t\t\t\tdata: {},\n\t\t\t\t// Unique numeric ID of this instance used both for looking up and differentiating instances of wikiEditor\n\t\t\t\tinstance: $.wikiEditor.instances.push( $( this ) ) - 1,\n\t\t\t\t// Saved selection state for old IE (<=10)\n\t\t\t\tsavedSelection: null,\n\t\t\t\t// List of extensions active on this context\n\t\t\t\textensions: []\n\t\t\t};\n\n\t\t\t/**\n\t\t\t * Externally Accessible API\n\t\t\t *\n\t\t\t * These are available using calls to $( selection ).wikiEditor( call, data ) where selection is a jQuery selection\n\t\t\t * of the textarea that the wikiEditor instance was built around.\n\t\t\t */\n\n\t\t\tcontext.api = {\n\t\t\t\t/*!\n\t\t\t\t * Activates a module on a specific context with optional configuration data.\n\t\t\t\t *\n\t\t\t\t * @param data Either a string of the name of a module to add without any additional configuration parameters,\n\t\t\t\t * or an object with members keyed with module names and valued with configuration objects.\n\t\t\t\t */\n\t\t\t\taddModule: function ( context, data ) {\n\t\t\t\t\tvar module, call,\n\t\t\t\t\t\tmodules = {};\n\t\t\t\t\tif ( typeof data === 'string' ) {\n\t\t\t\t\t\tmodules[ data ] = {};\n\t\t\t\t\t} else if ( typeof data === 'object' ) {\n\t\t\t\t\t\tmodules = data;\n\t\t\t\t\t}\n\t\t\t\t\tfor ( module in modules ) {\n\t\t\t\t\t\t// Check for the existence of an available module with a matching name and a create function\n\t\t\t\t\t\tif ( typeof module === 'string' && typeof $.wikiEditor.modules[ module ] !== 'undefined' ) {\n\t\t\t\t\t\t\t// Extend the context's core API with this module's own API calls\n\t\t\t\t\t\t\tif ( 'api' in $.wikiEditor.modules[ module ] ) {\n\t\t\t\t\t\t\t\tfor ( call in $.wikiEditor.modules[ module ].api ) {\n\t\t\t\t\t\t\t\t\t// Modules may not overwrite existing API functions - first come, first serve\n\t\t\t\t\t\t\t\t\tif ( !( call in context.api ) ) {\n\t\t\t\t\t\t\t\t\t\tcontext.api[ call ] = $.wikiEditor.modules[ module ].api[ call ];\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\t// Activate the module on this context\n\t\t\t\t\t\t\tif ( 'fn' in $.wikiEditor.modules[ module ] &&\n\t\t\t\t\t\t\t\t'create' in $.wikiEditor.modules[ module ].fn &&\n\t\t\t\t\t\t\t\ttypeof context.modules[ module ] === 'undefined'\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t// Add a place for the module to put it's own stuff\n\t\t\t\t\t\t\t\tcontext.modules[ module ] = {};\n\t\t\t\t\t\t\t\t// Tell the module to create itself on the context\n\t\t\t\t\t\t\t\t$.wikiEditor.modules[ module ].fn.create( context, modules[ module ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t/**\n\t\t\t * Event Handlers\n\t\t\t *\n\t\t\t * These act as filters returning false if the event should be ignored or returning true if it should be passed\n\t\t\t * on to all modules. This is also where we can attach some extra information to the events.\n\t\t\t */\n\n\t\t\tcontext.evt = {\n\t\t\t\t/* Empty until extensions add some; see jquery.wikiEditor.iframe.js for examples. */\n\t\t\t};\n\n\t\t\t/* Internal Functions */\n\n\t\t\tcontext.fn = {\n\t\t\t\t/**\n\t\t\t\t * Executes core event filters as well as event handlers provided by modules.\n\t\t\t\t *\n\t\t\t\t * @param {string} name\n\t\t\t\t * @param {Object} event\n\t\t\t\t * @return {boolean}\n\t\t\t\t */\n\t\t\t\ttrigger: function ( name, event ) {\n\t\t\t\t\tvar returnFromModules, module, ret;\n\n\t\t\t\t\t// Event is an optional argument, but from here on out, at least the type field should be dependable\n\t\t\t\t\tif ( typeof event === 'undefined' ) {\n\t\t\t\t\t\tevent = { type: 'custom' };\n\t\t\t\t\t}\n\t\t\t\t\t// Ensure there's a place for extra information to live\n\t\t\t\t\tif ( typeof event.data === 'undefined' ) {\n\t\t\t\t\t\tevent.data = {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Allow filtering to occur\n\t\t\t\t\tif ( name in context.evt ) {\n\t\t\t\t\t\tif ( !context.evt[ name ]( event ) ) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturnFromModules = null; // they return null by default\n\t\t\t\t\t// Pass the event around to all modules activated on this context\n\n\t\t\t\t\tfor ( module in context.modules ) {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tmodule in $.wikiEditor.modules &&\n\t\t\t\t\t\t\t'evt' in $.wikiEditor.modules[ module ] &&\n\t\t\t\t\t\t\tname in $.wikiEditor.modules[ module ].evt\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tret = $.wikiEditor.modules[ module ].evt[ name ]( context, event );\n\t\t\t\t\t\t\tif ( ret !== null ) {\n\t\t\t\t\t\t\t\t// if 1 returns false, the end result is false\n\t\t\t\t\t\t\t\tif ( returnFromModules === null ) {\n\t\t\t\t\t\t\t\t\treturnFromModules = ret;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\treturnFromModules = returnFromModules && ret;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( returnFromModules !== null ) {\n\t\t\t\t\t\treturn returnFromModules;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\t/**\n\t\t\t\t * Adds a button to the UI\n\t\t\t\t *\n\t\t\t\t * @param {Object} options\n\t\t\t\t * @return {jQuery}\n\t\t\t\t */\n\t\t\t\taddButton: function ( options ) {\n\t\t\t\t\t// Ensure that buttons and tabs are visible\n\t\t\t\t\tcontext.$controls.show();\n\t\t\t\t\tcontext.$buttons.show();\n\t\t\t\t\treturn $( '<button>' )\n\t\t\t\t\t\t.text( $.wikiEditor.autoMsg( options, 'caption' ) )\n\t\t\t\t\t\t.on( 'click', options.action )\n\t\t\t\t\t\t.appendTo( context.$buttons );\n\t\t\t\t},\n\n\t\t\t\t/**\n\t\t\t\t * Adds a view to the UI, which is accessed using a set of tabs. Views are mutually exclusive and by default a\n\t\t\t\t * wikitext view will be present. Only when more than one view exists will the tabs will be visible.\n\t\t\t\t *\n\t\t\t\t * @param {Object} options\n\t\t\t\t * @return {jQuery}\n\t\t\t\t */\n\t\t\t\taddView: function ( options ) {\n\t\t\t\t\t// Adds a tab\n\t\t\t\t\tfunction addTab( options ) {\n\t\t\t\t\t\t// Ensure that buttons and tabs are visible\n\t\t\t\t\t\tcontext.$controls.show();\n\t\t\t\t\t\tcontext.$tabs.show();\n\t\t\t\t\t\t// Return the newly appended tab\n\t\t\t\t\t\treturn $( '<div>' )\n\t\t\t\t\t\t\t.attr( 'rel', 'wikiEditor-ui-view-' + options.name )\n\t\t\t\t\t\t\t.addClass( context.view === options.name ? 'current' : null )\n\t\t\t\t\t\t\t.append( $( '<a>' )\n\t\t\t\t\t\t\t\t.attr( 'tabindex', 0 )\n\t\t\t\t\t\t\t\t.on( 'mousedown', function () {\n\t\t\t\t\t\t\t\t\t// No dragging!\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t\t.on( 'click keydown', function ( event ) {\n\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\tevent.type === 'click' ||\n\t\t\t\t\t\t\t\t\t\tevent.type === 'keydown' && event.key === 'Enter'\n\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\tcontext.$ui.find( '.wikiEditor-ui-view' ).hide();\n\t\t\t\t\t\t\t\t\t\tcontext.$ui.find( '.' + $( this ).parent().attr( 'rel' ) ).show();\n\t\t\t\t\t\t\t\t\t\tcontext.$tabs.find( 'div' ).removeClass( 'current' );\n\t\t\t\t\t\t\t\t\t\t$( this ).parent().addClass( 'current' );\n\t\t\t\t\t\t\t\t\t\t$( this ).trigger( 'blur' );\n\t\t\t\t\t\t\t\t\t\tif ( 'init' in options && typeof options.init === 'function' ) {\n\t\t\t\t\t\t\t\t\t\t\toptions.init( context );\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\t\t\treturn false;\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\t.text( $.wikiEditor.autoMsg( options, 'title' ) )\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.appendTo( context.$tabs );\n\t\t\t\t\t}\n\t\t\t\t\t// Automatically add the previously not-needed wikitext tab\n\t\t\t\t\tif ( !context.$tabs.children().length ) {\n\t\t\t\t\t\taddTab( { name: 'wikitext', titleMsg: 'wikieditor-wikitext-tab' } );\n\t\t\t\t\t}\n\t\t\t\t\t// Add the tab for the view we were actually asked to add\n\t\t\t\t\taddTab( options );\n\t\t\t\t\t// Return newly appended view\n\t\t\t\t\treturn $( '<div>' )\n\t\t\t\t\t\t.addClass( 'wikiEditor-ui-view wikiEditor-ui-view-' + options.name )\n\t\t\t\t\t\t.hide()\n\t\t\t\t\t\t.appendTo( context.$ui );\n\t\t\t\t},\n\n\t\t\t\t/**\n\t\t\t\t * Save text selection\n\t\t\t\t */\n\t\t\t\tsaveSelection: function () {\n\t\t\t\t\tcontext.$focusedElem = $( ':focus' );\n\t\t\t\t\tcontext.$textarea.trigger( 'focus' );\n\t\t\t\t\tcontext.savedSelection = context.$textarea.textSelection( 'getCaretPosition', { startAndEnd: true } );\n\t\t\t\t},\n\n\t\t\t\t/**\n\t\t\t\t * Restore text selection\n\t\t\t\t */\n\t\t\t\trestoreSelection: function () {\n\t\t\t\t\tif ( context.savedSelection ) {\n\t\t\t\t\t\tcontext.$textarea.trigger( 'focus' );\n\t\t\t\t\t\tcontext.$textarea.textSelection( 'setSelection', { start: context.savedSelection[ 0 ], end: context.savedSelection[ 1 ] } );\n\t\t\t\t\t\tcontext.savedSelection = null;\n\t\t\t\t\t}\n\t\t\t\t\tif ( context.$focusedElem ) {\n\t\t\t\t\t\tcontext.$focusedElem.trigger( 'focus' );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t/**\n\t\t\t * Base UI Construction\n\t\t\t *\n\t\t\t * The UI is built from several containers, the outer-most being a div classed as \"wikiEditor-ui\". These containers\n\t\t\t * provide a certain amount of \"free\" layout, but in some situations procedural layout is needed, which is performed\n\t\t\t * as a response to the \"resize\" event.\n\t\t\t */\n\n\t\t\t// Assemble a temporary div to place over the wikiEditor while it's being constructed\n\t\t\t/* Disabling our loading div for now\n\t\t\tvar $loader = $( '<div>' )\n\t\t\t\t.addClass( 'wikiEditor-ui-loading' )\n\t\t\t\t.append( $( '<span>' + mw.msg( 'wikieditor-loading' ) + '</span>' )\n\t\t\t\t\t.css( 'marginTop', context.$textarea.height() / 2 ) );\n\t\t\t*/\n\t\t\t/* Preserving cursor and focus state, which will get lost due to wrapAll */\n\t\t\thasFocus = context.$textarea.is( ':focus' );\n\t\t\tcursorPos = context.$textarea.textSelection( 'getCaretPosition', { startAndEnd: true } );\n\t\t\t// Encapsulate the textarea with some containers for layout\n\t\t\tcontext.$textarea\n\t\t\t/* Disabling our loading div for now\n\t\t\t\t.after( $loader )\n\t\t\t\t.add( $loader )\n\t\t\t*/\n\t\t\t\t.wrapAll( $( '<div>' ).addClass( 'wikiEditor-ui' ) )\n\t\t\t\t.wrapAll( $( '<div>' ).addClass( 'wikiEditor-ui-view wikiEditor-ui-view-wikitext' ) )\n\t\t\t\t.wrapAll( $( '<div>' ).addClass( 'wikiEditor-ui-left' ) )\n\t\t\t\t.wrapAll( $( '<div>' ).addClass( 'wikiEditor-ui-bottom' ) )\n\t\t\t\t.wrapAll( $( '<div>' ).addClass( 'wikiEditor-ui-text' ) );\n\t\t\t// Restore scroll position after this wrapAll (tracked by mediawiki.action.edit)\n\t\t\tcontext.$textarea.prop( 'scrollTop', $( '#wpScrolltop' ).val() );\n\t\t\t// Restore focus and cursor if needed\n\t\t\tif ( hasFocus ) {\n\t\t\t\tcontext.$textarea.trigger( 'focus' );\n\t\t\t\tcontext.$textarea.textSelection( 'setSelection', { start: cursorPos[ 0 ], end: cursorPos[ 1 ] } );\n\t\t\t}\n\n\t\t\t// Get references to some of the newly created containers\n\t\t\tcontext.$ui = context.$textarea.parent().parent().parent().parent().parent();\n\t\t\tcontext.$wikitext = context.$textarea.parent().parent().parent().parent();\n\t\t\t// Add in tab and button containers\n\t\t\tcontext.$wikitext\n\t\t\t\t.before(\n\t\t\t\t\t$( '<div>' ).addClass( 'wikiEditor-ui-controls' )\n\t\t\t\t\t\t.append( $( '<div>' ).addClass( 'wikiEditor-ui-tabs' ).hide() )\n\t\t\t\t\t\t.append( $( '<div>' ).addClass( 'wikiEditor-ui-buttons' ) )\n\t\t\t\t)\n\t\t\t\t.before( $( '<div>' ).addClass( 'wikiEditor-ui-clear' ) );\n\t\t\t// Get references to some of the newly created containers\n\t\t\tcontext.$controls = context.$ui.find( '.wikiEditor-ui-buttons' ).hide();\n\t\t\tcontext.$buttons = context.$ui.find( '.wikiEditor-ui-buttons' );\n\t\t\tcontext.$tabs = context.$ui.find( '.wikiEditor-ui-tabs' );\n\t\t\t// Clear all floating after the UI\n\t\t\tcontext.$ui.after( $( '<div>' ).addClass( 'wikiEditor-ui-clear' ) );\n\t\t\t// Attach a right container\n\t\t\tcontext.$wikitext.append( $( '<div>' ).addClass( 'wikiEditor-ui-right' ) );\n\t\t\tcontext.$wikitext.append( $( '<div>' ).addClass( 'wikiEditor-ui-clear' ) );\n\t\t\t// Attach a top container to the left pane\n\t\t\tcontext.$wikitext.find( '.wikiEditor-ui-left' ).prepend( $( '<div>' ).addClass( 'wikiEditor-ui-top' ) );\n\t\t\t// Setup the initial view\n\t\t\tcontext.view = 'wikitext';\n\t\t\t// Trigger the \"resize\" event anytime the window is resized\n\t\t\t$( window ).on( 'resize', function ( event ) {\n\t\t\t\tcontext.fn.trigger( 'resize', event );\n\t\t\t} );\n\t\t}\n\n\t\t/* API Execution */\n\n\t\t// Since javascript gives arguments as an object, we need to convert them so they can be used more easily\n\t\targs = $.makeArray( arguments );\n\n\t\t// Dynamically setup core extensions for modules that are required\n\t\tif ( args[ 0 ] === 'addModule' && typeof args[ 1 ] !== 'undefined' ) {\n\t\t\tmodules = args[ 1 ];\n\t\t\tif ( typeof modules !== 'object' ) {\n\t\t\t\tmodules = {};\n\t\t\t\tmodules[ args[ 1 ] ] = '';\n\t\t\t}\n\t\t\tfor ( module in modules ) {\n\t\t\t\tif ( module in $.wikiEditor.modules ) {\n\t\t\t\t\t// Activate all required core extensions on context\n\t\t\t\t\tfor ( extension in $.wikiEditor.extensions ) {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t$.wikiEditor.isRequired( $.wikiEditor.modules[ module ], extension ) &&\n\t\t\t\t\t\t\tcontext.extensions.indexOf( extension ) === -1\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tcontext.extensions[ context.extensions.length ] = extension;\n\t\t\t\t\t\t\t$.wikiEditor.extensions[ extension ]( context );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// There would need to be some arguments if the API is being called\n\t\tif ( args.length > 0 ) {\n\t\t\t// Handle API calls\n\t\t\tcall = args.shift();\n\t\t\tif ( call in context.api ) {\n\t\t\t\tcontext.api[ call ]( context, typeof args[ 0 ] === 'undefined' ? {} : args[ 0 ] );\n\t\t\t}\n\t\t}\n\n\t\t// Store the context for next time, and support chaining\n\t\treturn $( this ).data( 'wikiEditor-context', context );\n\n\t};\n\n}() );\n","usedDeprecatedRules":[]},{"filePath":"/src/repo/modules/jquery.wikiEditor.toolbar.config.js","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/modules/jquery.wikiEditor.toolbar.js","messages":[{"ruleId":"no-shadow","severity":1,"message":"'$options' is already declared in the upper scope on line 280 column 51.","line":420,"column":13,"nodeType":"Identifier","messageId":"noShadow","endLine":420,"endColumn":21}],"errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Toolbar module for wikiEditor\n */\n( function () {\n\n\tvar toolbarModule = {\n\n\t\t/**\n\t\t * API accessible functions\n\t\t */\n\t\tapi: {\n\t\t\taddToToolbar: function ( context, data ) {\n\n\t\t\t\tvar section, type, i, group, $group, $section, $sections,\n\t\t\t\t\t$tabs, tool, $pages, $index, page, $table, $characters, actions;\n\n\t\t\t\tfor ( type in data ) {\n\t\t\t\t\tswitch ( type ) {\n\t\t\t\t\t\tcase 'sections':\n\t\t\t\t\t\t\t$sections = context.modules.toolbar.$toolbar.find( 'div.sections' );\n\t\t\t\t\t\t\t$tabs = context.modules.toolbar.$toolbar.find( 'div.tabs' );\n\t\t\t\t\t\t\tfor ( section in data[ type ] ) {\n\t\t\t\t\t\t\t\tif ( section === 'main' ) {\n\t\t\t\t\t\t\t\t\t// Section\n\t\t\t\t\t\t\t\t\tcontext.modules.toolbar.$toolbar.prepend(\n\t\t\t\t\t\t\t\t\t\ttoolbarModule.fn.buildSection(\n\t\t\t\t\t\t\t\t\t\t\tcontext, section, data[ type ][ section ]\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Section\n\t\t\t\t\t\t\t\t$sections.append(\n\t\t\t\t\t\t\t\t\ttoolbarModule.fn.buildSection( context, section, data[ type ][ section ] )\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t// Tab\n\t\t\t\t\t\t\t\t$tabs.append(\n\t\t\t\t\t\t\t\t\ttoolbarModule.fn.buildTab( context, section, data[ type ][ section ] )\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'groups':\n\t\t\t\t\t\t\tif ( !( 'section' in data ) ) {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$section = context.modules.toolbar.$toolbar.find( 'div[rel=\"' + data.section + '\"].section' );\n\t\t\t\t\t\t\tfor ( group in data[ type ] ) {\n\t\t\t\t\t\t\t\t// Group\n\t\t\t\t\t\t\t\t$section.append(\n\t\t\t\t\t\t\t\t\ttoolbarModule.fn.buildGroup( context, group, data[ type ][ group ] )\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'tools':\n\t\t\t\t\t\t\tif ( !( 'section' in data && 'group' in data ) ) {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$group = context.modules.toolbar.$toolbar.find(\n\t\t\t\t\t\t\t\t'div[rel=\"' + data.section + '\"].section ' +\n\t\t\t\t\t\t\t\t'div[rel=\"' + data.group + '\"].group'\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tfor ( tool in data[ type ] ) {\n\t\t\t\t\t\t\t\t// Tool\n\t\t\t\t\t\t\t\t$group.append( toolbarModule.fn.buildTool( context, tool, data[ type ][ tool ] ) );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( $group.children().length ) {\n\t\t\t\t\t\t\t\t$group.removeClass( 'empty' );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'pages':\n\t\t\t\t\t\t\tif ( !( 'section' in data ) ) {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$pages = context.modules.toolbar.$toolbar.find(\n\t\t\t\t\t\t\t\t'div[rel=\"' + data.section + '\"].section .pages'\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t$index = context.modules.toolbar.$toolbar.find(\n\t\t\t\t\t\t\t\t'div[rel=\"' + data.section + '\"].section .index'\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tfor ( page in data[ type ] ) {\n\t\t\t\t\t\t\t\t// Page\n\t\t\t\t\t\t\t\t$pages.append( toolbarModule.fn.buildPage( context, page, data[ type ][ page ] ) );\n\t\t\t\t\t\t\t\t// Index\n\t\t\t\t\t\t\t\t$index.append(\n\t\t\t\t\t\t\t\t\ttoolbarModule.fn.buildBookmark( context, page, data[ type ][ page ] )\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ttoolbarModule.fn.updateBookletSelection( context, data.section, $pages, $index );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'rows':\n\t\t\t\t\t\t\tif ( !( 'section' in data && 'page' in data ) ) {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$table = context.modules.toolbar.$toolbar.find(\n\t\t\t\t\t\t\t\t'div[rel=\"' + data.section + '\"].section ' +\n\t\t\t\t\t\t\t\t'div[rel=\"' + data.page + '\"].page table'\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tfor ( i = 0; i < data.rows.length; i++ ) {\n\t\t\t\t\t\t\t\t// Row\n\t\t\t\t\t\t\t\t$table.append( toolbarModule.fn.buildRow( context, data.rows[ i ] ) );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'characters':\n\t\t\t\t\t\t\tif ( !( 'section' in data && 'page' in data ) ) {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$characters = context.modules.toolbar.$toolbar.find(\n\t\t\t\t\t\t\t\t'div[rel=\"' + data.section + '\"].section ' +\n\t\t\t\t\t\t\t\t'div[rel=\"' + data.page + '\"].page div'\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tactions = $characters.data( 'actions' );\n\t\t\t\t\t\t\tfor ( i = 0; i < data.characters.length; i++ ) {\n\t\t\t\t\t\t\t\t// Character\n\t\t\t\t\t\t\t\t$characters.append(\n\t\t\t\t\t\t\t\t\t$( toolbarModule.fn.buildCharacter( data.characters[ i ], actions ) )\n\t\t\t\t\t\t\t\t\t\t.on( 'mousedown', function ( e ) {\n\t\t\t\t\t\t\t\t\t\t\t// No dragging!\n\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t\t\t\t.on( 'click', function ( e ) {\n\t\t\t\t\t\t\t\t\t\t\ttoolbarModule.fn.doAction( $( this ).parent().data( 'context' ),\n\t\t\t\t\t\t\t\t\t\t\t\t$( this ).parent().data( 'actions' )[ $( this ).attr( 'rel' ) ] );\n\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\treturn false;\n\t\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\tbreak;\n\t\t\t\t\t\tdefault: break;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tremoveFromToolbar: function ( context, data ) {\n\t\t\t\tvar index, $group, tab, target, group;\n\t\t\t\tif ( typeof data.section === 'string' ) {\n\t\t\t\t\t// Section\n\t\t\t\t\ttab = 'div.tabs span[rel=\"' + data.section + '\"].tab';\n\t\t\t\t\ttarget = 'div[rel=\"' + data.section + '\"].section';\n\t\t\t\t\tgroup = null;\n\t\t\t\t\tif ( typeof data.group === 'string' ) {\n\t\t\t\t\t\t// Toolbar group\n\t\t\t\t\t\ttarget += ' div[rel=\"' + data.group + '\"].group';\n\t\t\t\t\t\tif ( typeof data.tool === 'string' ) {\n\t\t\t\t\t\t\t// Save for later checking if empty\n\t\t\t\t\t\t\tgroup = target;\n\t\t\t\t\t\t\t// Tool\n\t\t\t\t\t\t\ttarget = target + ' [rel=\"' + data.tool + '\"].tool';\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if ( typeof data.page === 'string' ) {\n\t\t\t\t\t\t// Booklet page\n\t\t\t\t\t\tindex = target + ' div.index div[rel=\"' + data.page + '\"]';\n\t\t\t\t\t\ttarget += ' div.pages div[rel=\"' + data.page + '\"].page';\n\t\t\t\t\t\tif ( typeof data.character === 'string' ) {\n\t\t\t\t\t\t\t// Character\n\t\t\t\t\t\t\ttarget += ' span[rel=\"' + data.character + '\"]';\n\t\t\t\t\t\t} else if ( typeof data.row === 'number' ) {\n\t\t\t\t\t\t\t// Table row\n\t\t\t\t\t\t\ttarget += ' table tr:not(:has(th)):eq(' + data.row + ')';\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Just a page, remove the index too!\n\t\t\t\t\t\t\tcontext.modules.toolbar.$toolbar.find( index ).remove();\n\t\t\t\t\t\t\ttoolbarModule.fn.updateBookletSelection(\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\tdata.section,\n\t\t\t\t\t\t\t\tcontext.modules.toolbar.$toolbar.find( target ),\n\t\t\t\t\t\t\t\tcontext.modules.toolbar.$toolbar.find( index )\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Just a section, remove the tab too!\n\t\t\t\t\t\tcontext.modules.toolbar.$toolbar.find( tab ).remove();\n\t\t\t\t\t}\n\t\t\t\t\tcontext.modules.toolbar.$toolbar.find( target ).remove();\n\t\t\t\t\t// Hide empty groups\n\t\t\t\t\tif ( group ) {\n\t\t\t\t\t\t$group = context.modules.toolbar.$toolbar.find( group );\n\t\t\t\t\t\tif ( $group.children().length === 0 ) {\n\t\t\t\t\t\t\t$group.addClass( 'empty' );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Internally used functions\n\t\t */\n\t\tfn: {\n\t\t\t/**\n\t\t\t * Creates a toolbar module within a wikiEditor\n\t\t\t *\n\t\t\t * @param {Object} context Context object of editor to create module in\n\t\t\t * @param {Object} config Configuration object to create module from\n\t\t\t */\n\t\t\tcreate: function ( context, config ) {\n\t\t\t\tif ( '$toolbar' in context.modules.toolbar ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tcontext.modules.toolbar.$toolbar = $( '<div>' )\n\t\t\t\t\t.addClass( 'wikiEditor-ui-toolbar' )\n\t\t\t\t\t.attr( 'id', 'wikiEditor-ui-toolbar' );\n\t\t\t\ttoolbarModule.fn.build( context, config );\n\t\t\t\tcontext.$ui.find( '.wikiEditor-ui-top' ).append( context.modules.toolbar.$toolbar );\n\t\t\t},\n\t\t\t/**\n\t\t\t * Performs an operation based on parameters\n\t\t\t *\n\t\t\t * @param {Object} context\n\t\t\t * @param {Object} action\n\t\t\t */\n\t\t\tdoAction: function ( context, action ) {\n\t\t\t\tvar selection, parts, replace;\n\t\t\t\tswitch ( action.type ) {\n\t\t\t\t\tcase 'replace':\n\t\t\t\t\tcase 'encapsulate':\n\t\t\t\t\t\tif ( context.$textarea.prop( 'readonly' ) ) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tparts = {\n\t\t\t\t\t\t\tpre: $.wikiEditor.autoMsg( action.options, 'pre' ),\n\t\t\t\t\t\t\tperi: $.wikiEditor.autoMsg( action.options, 'peri' ),\n\t\t\t\t\t\t\tpost: $.wikiEditor.autoMsg( action.options, 'post' )\n\t\t\t\t\t\t};\n\t\t\t\t\t\treplace = action.type === 'replace';\n\t\t\t\t\t\tif ( 'regex' in action.options && 'regexReplace' in action.options ) {\n\t\t\t\t\t\t\tselection = context.$textarea.textSelection( 'getSelection' );\n\t\t\t\t\t\t\tif ( selection !== '' && selection.match( action.options.regex ) ) {\n\t\t\t\t\t\t\t\tparts.peri = selection.replace( action.options.regex,\n\t\t\t\t\t\t\t\t\taction.options.regexReplace );\n\t\t\t\t\t\t\t\tparts.pre = parts.post = '';\n\t\t\t\t\t\t\t\treplace = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontext.$textarea.textSelection(\n\t\t\t\t\t\t\t'encapsulateSelection',\n\t\t\t\t\t\t\t$.extend( {}, action.options, parts, { replace: replace } )\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'callback':\n\t\t\t\t\t\tif ( typeof action.execute === 'function' ) {\n\t\t\t\t\t\t\taction.execute( context );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'dialog':\n\t\t\t\t\t\tcontext.fn.saveSelection();\n\t\t\t\t\t\tcontext.$textarea.wikiEditor( 'openDialog', action.module );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault: break;\n\t\t\t\t}\n\t\t\t},\n\t\t\tbuildGroup: function ( context, id, group ) {\n\t\t\t\tvar $label, empty, tool,\n\t\t\t\t\t$group = $( '<div>' ).attr( { class: 'group group-' + id, rel: id } ),\n\t\t\t\t\tlabel = $.wikiEditor.autoMsg( group, 'label' );\n\t\t\t\tif ( label ) {\n\t\t\t\t\t$label = $( '<span>' )\n\t\t\t\t\t\t.addClass( 'label' )\n\t\t\t\t\t\t.text( label );\n\t\t\t\t\t$group.append( $label );\n\t\t\t\t}\n\t\t\t\tempty = true;\n\t\t\t\tif ( 'tools' in group ) {\n\t\t\t\t\tfor ( tool in group.tools ) {\n\t\t\t\t\t\ttool = toolbarModule.fn.buildTool( context, tool, group.tools[ tool ] );\n\t\t\t\t\t\tif ( tool ) {\n\t\t\t\t\t\t\t// Consider a group with only hidden tools empty as well\n\t\t\t\t\t\t\t// .is( ':visible' ) always returns false because tool is not attached to the DOM yet\n\t\t\t\t\t\t\tempty = empty && tool.css( 'display' ) === 'none';\n\t\t\t\t\t\t\t$group.append( tool );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ( empty ) {\n\t\t\t\t\t$group.addClass( 'empty' );\n\t\t\t\t}\n\t\t\t\treturn $group;\n\t\t\t},\n\t\t\tbuildTool: function ( context, id, tool ) {\n\t\t\t\tvar i, label, $button, config, icon, $select, $options, oouiButton,\n\t\t\t\t\toption, optionLabel, menuId;\n\t\t\t\tif ( 'filters' in tool ) {\n\t\t\t\t\tfor ( i = 0; i < tool.filters.length; i++ ) {\n\t\t\t\t\t\tif ( $( tool.filters[ i ] ).length === 0 ) {\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlabel = $.wikiEditor.autoMsg( tool, 'label' );\n\t\t\t\tswitch ( tool.type ) {\n\t\t\t\t\tcase 'button':\n\t\t\t\t\tcase 'toggle':\n\t\t\t\t\t\tif ( tool.oouiIcon ) {\n\t\t\t\t\t\t\tconfig = {\n\t\t\t\t\t\t\t\tframed: false,\n\t\t\t\t\t\t\t\tclasses: [ 'tool' ],\n\t\t\t\t\t\t\t\ticon: tool.oouiIcon,\n\t\t\t\t\t\t\t\ttitle: label\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tif ( tool.type === 'button' ) {\n\t\t\t\t\t\t\t\toouiButton = new OO.ui.ButtonWidget( config );\n\t\t\t\t\t\t\t} else if ( tool.type === 'toggle' ) {\n\t\t\t\t\t\t\t\toouiButton = new OO.ui.ToggleButtonWidget( config );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$button = oouiButton.$element;\n\t\t\t\t\t\t\t$button.attr( 'rel', id );\n\t\t\t\t\t\t\t$button.data( 'ooui', oouiButton );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$button = $( '<a>' )\n\t\t\t\t\t\t\t\t.attr( {\n\t\t\t\t\t\t\t\t\ttabindex: 0,\n\t\t\t\t\t\t\t\t\ttitle: label,\n\t\t\t\t\t\t\t\t\trel: id,\n\t\t\t\t\t\t\t\t\trole: 'button',\n\t\t\t\t\t\t\t\t\tclass: 'tool tool-button'\n\t\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t\t.text( label );\n\t\t\t\t\t\t\tif ( tool.icon ) {\n\t\t\t\t\t\t\t\ticon = $.wikiEditor.autoIcon(\n\t\t\t\t\t\t\t\t\ttool.icon,\n\t\t\t\t\t\t\t\t\t$.wikiEditor.imgPath + 'toolbar/'\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t$button.css( 'background-image', 'url(' + icon + ')' );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$button.data( 'setActive', function ( active ) {\n\t\t\t\t\t\t\t$button.toggleClass( 'tool-active', active );\n\n\t\t\t\t\t\t\t// OOUI button\n\t\t\t\t\t\t\tif ( $button.data( 'ooui' ) && tool.type === 'toggle' ) {\n\t\t\t\t\t\t\t\t$button.data( 'ooui' ).setValue( active );\n\t\t\t\t\t\t\t\t// Use progressive icon in WMUI theme\n\t\t\t\t\t\t\t\tif ( OO.ui.WikimediaUITheme && OO.ui.theme instanceof OO.ui.WikimediaUITheme ) {\n\t\t\t\t\t\t\t\t\t// Wait for updateElementClasses to run\n\t\t\t\t\t\t\t\t\tsetTimeout( function () {\n\t\t\t\t\t\t\t\t\t\t$button.data( 'ooui' ).$icon.toggleClass( 'oo-ui-image-progressive', active );\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} );\n\t\t\t\t\t\tif ( 'action' in tool ) {\n\t\t\t\t\t\t\t$button\n\t\t\t\t\t\t\t\t.data( 'action', tool.action )\n\t\t\t\t\t\t\t\t.data( 'context', context )\n\t\t\t\t\t\t\t\t.on( 'mousedown', function ( e ) {\n\t\t\t\t\t\t\t\t\t// No dragging!\n\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\tif ( $button.data( 'ooui' ) ) {\n\t\t\t\t\t\t\t\t$button.data( 'ooui' ).on( 'click', function () {\n\t\t\t\t\t\t\t\t\ttoolbarModule.fn.doAction(\n\t\t\t\t\t\t\t\t\t\tcontext, tool.action\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} else {\n\t\t\t\t\t\t\t\t$button.on( 'click keydown', function ( e ) {\n\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\te.type === 'click' ||\n\t\t\t\t\t\t\t\t\t\te.type === 'keydown' && e.key === 'Enter'\n\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\ttoolbarModule.fn.doAction(\n\t\t\t\t\t\t\t\t\t\t\tcontext, tool.action\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\treturn false;\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}\n\t\t\t\t\t\treturn $button;\n\t\t\t\t\tcase 'select':\n\t\t\t\t\t\tmenuId = 'menu-' + ( new Date() ).getTime();\n\t\t\t\t\t\t$select = $( '<div>' )\n\t\t\t\t\t\t\t.attr( { rel: id, class: 'tool tool-select' } );\n\t\t\t\t\t\t$options = $( '<div>' ).addClass( 'options' );\n\t\t\t\t\t\tif ( 'list' in tool ) {\n\t\t\t\t\t\t\tfor ( option in tool.list ) {\n\t\t\t\t\t\t\t\toptionLabel = $.wikiEditor.autoMsg( tool.list[ option ], 'label' );\n\t\t\t\t\t\t\t\t$options.append(\n\t\t\t\t\t\t\t\t\t$( '<a>' )\n\t\t\t\t\t\t\t\t\t\t.data( 'action', tool.list[ option ].action )\n\t\t\t\t\t\t\t\t\t\t.data( 'context', context )\n\t\t\t\t\t\t\t\t\t\t.on( 'mousedown', function ( e ) {\n\t\t\t\t\t\t\t\t\t\t\t// No dragging!\n\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t\t\t\t.on( 'click keydown', function ( e ) {\n\t\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\t\te.type === 'click' ||\n\t\t\t\t\t\t\t\t\t\t\t\te.type === 'keydown' && e.key === 'Enter'\n\t\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\t\ttoolbarModule.fn.doAction(\n\t\t\t\t\t\t\t\t\t\t\t\t\t$( this ).data( 'context' ), $( this ).data( 'action' ), $( this )\n\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t\t// Hide the dropdown\n\t\t\t\t\t\t\t\t\t\t\t\t$( this ).closest( '.tool-select' ).removeClass( 'options-shown' );\n\t\t\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t\t\t\t.text( optionLabel )\n\t\t\t\t\t\t\t\t\t\t.addClass( 'option' )\n\t\t\t\t\t\t\t\t\t\t.attr( { rel: option, tabindex: 0, role: 'menuitem' } )\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$select.append( $( '<a>' )\n\t\t\t\t\t\t\t.addClass( 'label' )\n\t\t\t\t\t\t\t.text( label )\n\t\t\t\t\t\t\t.data( 'options', $options )\n\t\t\t\t\t\t\t.attr( { role: 'button', tabindex: 0, 'aria-expanded': false, 'aria-controls': menuId, 'aria-haspopup': 'menu' } )\n\t\t\t\t\t\t\t.on( 'mousedown', function ( e ) {\n\t\t\t\t\t\t\t\t// No dragging!\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.on( 'click keydown', function ( e ) {\n\t\t\t\t\t\t\t\tvar $options, canShowOptions;\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\te.type === 'click' ||\n\t\t\t\t\t\t\t\t\te.type === 'keydown' && e.key === 'Enter'\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t$options = $( this ).data( 'options' );\n\t\t\t\t\t\t\t\t\t// eslint-disable-next-line no-jquery/no-class-state\n\t\t\t\t\t\t\t\t\tcanShowOptions = !$options.closest( '.tool-select' ).hasClass( 'options-shown' );\n\t\t\t\t\t\t\t\t\t$options.closest( '.tool-select' ).toggleClass( 'options-shown', canShowOptions );\n\t\t\t\t\t\t\t\t\t$( this ).attr( 'aria-expanded', canShowOptions.toString() );\n\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t);\n\t\t\t\t\t\t$select.append( $( '<div>' ).addClass( 'menu' ).append( $options ) );\n\t\t\t\t\t\treturn $select;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t},\n\t\t\tbuildBookmark: function ( context, id, page ) {\n\t\t\t\tvar label = $.wikiEditor.autoMsg( page, 'label' );\n\t\t\t\treturn $( '<div>' )\n\t\t\t\t\t.text( label )\n\t\t\t\t\t.attr( {\n\t\t\t\t\t\trel: id,\n\t\t\t\t\t\trole: 'option'\n\t\t\t\t\t} )\n\t\t\t\t\t.data( 'context', context )\n\t\t\t\t\t.on( 'mousedown', function ( e ) {\n\t\t\t\t\t\t// No dragging!\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t} )\n\t\t\t\t\t.on( 'click', function ( event ) {\n\t\t\t\t\t\tvar section;\n\t\t\t\t\t\t$( this ).parent().parent().find( '.page' ).hide();\n\t\t\t\t\t\t$( this ).parent().parent().find( '.page-' + $( this ).attr( 'rel' ) ).show().trigger( 'loadPage' );\n\t\t\t\t\t\t$( this ).siblings().removeClass( 'current' );\n\t\t\t\t\t\t$( this ).addClass( 'current' );\n\t\t\t\t\t\tsection = $( this ).parent().parent().attr( 'rel' );\n\t\t\t\t\t\t$.cookie(\n\t\t\t\t\t\t\t'wikiEditor-' + $( this ).data( 'context' ).instance + '-booklet-' + section + '-page',\n\t\t\t\t\t\t\t$( this ).attr( 'rel' ),\n\t\t\t\t\t\t\t{ expires: 30, path: '/' }\n\t\t\t\t\t\t);\n\t\t\t\t\t\t// No dragging!\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t} );\n\t\t\t},\n\t\t\tbuildPage: function ( context, id, page, deferLoad ) {\n\t\t\t\tvar $page = $( '<div>' ).attr( {\n\t\t\t\t\tclass: 'page page-' + id,\n\t\t\t\t\trel: id\n\t\t\t\t} );\n\t\t\t\tif ( deferLoad ) {\n\t\t\t\t\t$page.one( 'loadPage', function () {\n\t\t\t\t\t\ttoolbarModule.fn.reallyBuildPage( context, id, page, $page );\n\t\t\t\t\t} );\n\t\t\t\t} else {\n\t\t\t\t\ttoolbarModule.fn.reallyBuildPage( context, id, page, $page );\n\t\t\t\t}\n\t\t\t\treturn $page;\n\t\t\t},\n\t\t\treallyBuildPage: function ( context, id, page, $page ) {\n\t\t\t\tvar html, i, $characters, actions;\n\t\t\t\tswitch ( page.layout ) {\n\t\t\t\t\tcase 'table':\n\t\t\t\t\t\t$page.addClass( 'page-table' );\n\t\t\t\t\t\thtml =\n\t\t\t\t\t\t\t'<table class=\"table-' + id + '\">';\n\t\t\t\t\t\tif ( 'headings' in page ) {\n\t\t\t\t\t\t\thtml += toolbarModule.fn.buildHeading( context, page.headings );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( 'rows' in page ) {\n\t\t\t\t\t\t\tfor ( i = 0; i < page.rows.length; i++ ) {\n\t\t\t\t\t\t\t\thtml += toolbarModule.fn.buildRow( context, page.rows[ i ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$page.html( html + '</table>' );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'characters':\n\t\t\t\t\t\t$page.addClass( 'page-characters' );\n\t\t\t\t\t\t$characters = $( '<div>' ).data( 'context', context ).data( 'actions', {} );\n\t\t\t\t\t\tactions = $characters.data( 'actions' );\n\t\t\t\t\t\tif ( 'language' in page ) {\n\t\t\t\t\t\t\t$characters.attr( 'lang', page.language );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( 'direction' in page ) {\n\t\t\t\t\t\t\t$characters.attr( 'dir', page.direction );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// By default it should be explicit ltr for all scripts.\n\t\t\t\t\t\t\t// Without this some conjoined ltr characters look\n\t\t\t\t\t\t\t// weird in rtl wikis.\n\t\t\t\t\t\t\t$characters.attr( 'dir', 'ltr' );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( 'characters' in page ) {\n\t\t\t\t\t\t\thtml = '';\n\t\t\t\t\t\t\tfor ( i = 0; i < page.characters.length; i++ ) {\n\t\t\t\t\t\t\t\thtml += toolbarModule.fn.buildCharacter( page.characters[ i ], actions );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$characters\n\t\t\t\t\t\t\t\t.html( html )\n\t\t\t\t\t\t\t\t.children()\n\t\t\t\t\t\t\t\t.attr( 'role', 'option' )\n\t\t\t\t\t\t\t\t.on( 'mousedown', function ( e ) {\n\t\t\t\t\t\t\t\t\t// No dragging!\n\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t\t.on( 'click', function ( e ) {\n\t\t\t\t\t\t\t\t\ttoolbarModule.fn.doAction(\n\t\t\t\t\t\t\t\t\t\t$( this ).parent().data( 'context' ),\n\t\t\t\t\t\t\t\t\t\t$( this ).parent().data( 'actions' )[ $( this ).attr( 'rel' ) ],\n\t\t\t\t\t\t\t\t\t\t$( this )\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$page.append( $characters );\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t},\n\t\t\tbuildHeading: function ( context, headings ) {\n\t\t\t\tvar i, html = '<tr>';\n\t\t\t\tfor ( i = 0; i < headings.length; i++ ) {\n\t\t\t\t\thtml += '<th>' + $.wikiEditor.autoSafeMsg( headings[ i ], [ 'html', 'text' ] ) + '</th>';\n\t\t\t\t}\n\t\t\t\treturn html + '</tr>';\n\t\t\t},\n\t\t\tbuildRow: function ( context, row ) {\n\t\t\t\tvar cell,\n\t\t\t\t\thtml = '<tr>';\n\t\t\t\tfor ( cell in row ) {\n\t\t\t\t\t// FIXME: This currently needs to use the \"unsafe\" .text() message because it embeds raw HTML\n\t\t\t\t\t// in the messages (as used exclusively by the 'help' toolbar panel).\n\t\t\t\t\thtml += '<td class=\"cell cell-' + cell + '\"><span>' +\n\t\t\t\t\t\t$.wikiEditor.autoMsg( row[ cell ], [ 'html', 'text' ] ) + '</span></td>';\n\t\t\t\t}\n\t\t\t\treturn html + '</tr>';\n\t\t\t},\n\t\t\tbuildCharacter: function ( character, actions ) {\n\t\t\t\tif ( typeof character === 'string' ) {\n\t\t\t\t\tcharacter = {\n\t\t\t\t\t\tlabel: character,\n\t\t\t\t\t\taction: {\n\t\t\t\t\t\t\ttype: 'replace',\n\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\tperi: character,\n\t\t\t\t\t\t\t\tselectPeri: false\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t// In some cases the label for the character isn't the same as the\n\t\t\t\t// character that gets inserted (e.g. Hebrew vowels)\n\t\t\t\t} else if ( character && 0 in character && 1 in character ) {\n\t\t\t\t\tcharacter = {\n\t\t\t\t\t\tlabel: character[ 0 ],\n\t\t\t\t\t\taction: {\n\t\t\t\t\t\t\ttype: 'replace',\n\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\tperi: character[ 1 ],\n\t\t\t\t\t\t\t\tselectPeri: false\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tif ( character && 'action' in character && 'label' in character ) {\n\t\t\t\t\tactions[ character.label ] = character.action;\n\t\t\t\t\tif ( character.titleMsg !== undefined ) {\n\t\t\t\t\t\treturn mw.html.element(\n\t\t\t\t\t\t\t'span',\n\t\t\t\t\t\t\t// eslint-disable-next-line mediawiki/msg-doc\n\t\t\t\t\t\t\t{ rel: character.label, title: mw.msg( character.titleMsg ) },\n\t\t\t\t\t\t\tcharacter.label\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn mw.html.element( 'span', { rel: character.label }, character.label );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tmw.log( 'A character for the toolbar was undefined. This is not supposed to happen. Double check the config.' );\n\t\t\t\t// bug 31673; also an additional fix for bug 24208...\n\t\t\t\treturn '';\n\t\t\t},\n\t\t\tbuildTab: function ( context, id, section ) {\n\t\t\t\tvar $link, $sections, $section, show,\n\t\t\t\t\tselected = $.cookie( 'wikiEditor-' + context.instance + '-toolbar-section' );\n\t\t\t\t// Re-save cookie\n\t\t\t\tif ( selected !== null ) {\n\t\t\t\t\t$.cookie( 'wikiEditor-' + context.instance + '-toolbar-section', selected, { expires: 30, path: '/' } );\n\t\t\t\t}\n\t\t\t\t$link =\n\t\t\t\t\t$( '<a>' )\n\t\t\t\t\t\t.addClass( selected === id ? 'current' : null )\n\t\t\t\t\t\t.attr( {\n\t\t\t\t\t\t\ttabindex: 0,\n\t\t\t\t\t\t\trole: 'button',\n\t\t\t\t\t\t\t'aria-expanded': ( selected === id ).toString(),\n\t\t\t\t\t\t\t'aria-controls': 'wikiEditor-section-' + id\n\t\t\t\t\t\t} )\n\t\t\t\t\t\t.text( $.wikiEditor.autoMsg( section, 'label' ) )\n\t\t\t\t\t\t.data( 'context', context )\n\t\t\t\t\t\t.on( 'mouseup', function () {\n\t\t\t\t\t\t\t$( this ).trigger( 'blur' );\n\t\t\t\t\t\t} )\n\t\t\t\t\t\t.on( 'mousedown', function ( e ) {\n\t\t\t\t\t\t\t// No dragging!\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t} )\n\t\t\t\t\t\t.on( 'click keydown', function ( e ) {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\te.type !== 'click' &&\n\t\t\t\t\t\t\t\t( e.type !== 'keydown' || e.key !== 'Enter' )\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// We have to set aria-pressed over here, as NVDA wont recognize it\n\t\t\t\t\t\t\t// if we do it in the below .each as it seems\n\t\t\t\t\t\t\t$( this ).attr( 'aria-pressed', 'true' );\n\t\t\t\t\t\t\t$( '.tab > a' ).each( function ( i, elem ) {\n\t\t\t\t\t\t\t\tif ( elem !== e.target ) {\n\t\t\t\t\t\t\t\t\t$( elem ).attr( 'aria-pressed', 'false' );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t$sections = $( this ).data( 'context' ).$ui.find( '.sections' );\n\t\t\t\t\t\t\t$section = $sections.find( '.section-' + $( this ).parent().attr( 'rel' ) );\n\t\t\t\t\t\t\t// eslint-disable-next-line no-jquery/no-class-state\n\t\t\t\t\t\t\tshow = !$section.hasClass( 'section-visible' );\n\t\t\t\t\t\t\t$sections.find( '.section-visible' )\n\t\t\t\t\t\t\t\t.removeClass( 'section-visible' )\n\t\t\t\t\t\t\t\t.addClass( 'section-hidden' );\n\n\t\t\t\t\t\t\t$( this ).attr( 'aria-expanded', 'false' );\n\t\t\t\t\t\t\t$( this ).parent().parent().find( 'a' ).removeClass( 'current' );\n\t\t\t\t\t\t\tif ( show ) {\n\t\t\t\t\t\t\t\t$section\n\t\t\t\t\t\t\t\t\t.removeClass( 'section-hidden' )\n\t\t\t\t\t\t\t\t\t.attr( 'aria-expanded', 'true' )\n\t\t\t\t\t\t\t\t\t.addClass( 'section-visible' );\n\n\t\t\t\t\t\t\t\t$( this ).attr( 'aria-expanded', 'true' )\n\t\t\t\t\t\t\t\t\t.addClass( 'current' );\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Save the currently visible section\n\t\t\t\t\t\t\t$.cookie(\n\t\t\t\t\t\t\t\t'wikiEditor-' + $( this ).data( 'context' ).instance + '-toolbar-section',\n\t\t\t\t\t\t\t\tshow ? $section.attr( 'rel' ) : null,\n\t\t\t\t\t\t\t\t{ expires: 30, path: '/' }\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t} );\n\t\t\t\treturn $( '<span>' )\n\t\t\t\t\t.attr( {\n\t\t\t\t\t\tclass: 'tab tab-' + id,\n\t\t\t\t\t\trel: id\n\t\t\t\t\t} )\n\t\t\t\t\t.append( $link );\n\t\t\t},\n\t\t\tbuildSection: function ( context, id, section ) {\n\t\t\t\tvar selected, show,\n\t\t\t\t\t$section = $( '<div>' ).attr( {\n\t\t\t\t\t\tclass: section.type + ' section section-' + id,\n\t\t\t\t\t\trel: id,\n\t\t\t\t\t\tid: 'wikiEditor-section-' + id\n\t\t\t\t\t} );\n\t\t\t\tselected = $.cookie( 'wikiEditor-' + context.instance + '-toolbar-section' );\n\t\t\t\tshow = selected === id;\n\n\t\t\t\ttoolbarModule.fn.reallyBuildSection( context, id, section, $section, section.deferLoad );\n\n\t\t\t\t// Show or hide section\n\t\t\t\tif ( id !== 'main' ) {\n\t\t\t\t\t$section.attr( 'aria-expanded', show ? 'true' : 'false' );\n\n\t\t\t\t\tif ( show ) {\n\t\t\t\t\t\t$section.addClass( 'section-visible' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$section.addClass( 'section-hidden' );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn $section;\n\t\t\t},\n\t\t\treallyBuildSection: function ( context, id, section, $section, deferLoad ) {\n\t\t\t\tvar group, $pages, $index, page;\n\t\t\t\tcontext.$textarea.trigger( 'wikiEditor-toolbar-buildSection-' + $section.attr( 'rel' ), [ section ] );\n\t\t\t\tswitch ( section.type ) {\n\t\t\t\t\tcase 'toolbar':\n\t\t\t\t\t\tif ( 'groups' in section ) {\n\t\t\t\t\t\t\tfor ( group in section.groups ) {\n\t\t\t\t\t\t\t\t$section.append(\n\t\t\t\t\t\t\t\t\ttoolbarModule.fn.buildGroup( context, group, section.groups[ group ] )\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'booklet':\n\t\t\t\t\t\t$pages = $( '<div>' )\n\t\t\t\t\t\t\t.addClass( 'pages' )\n\t\t\t\t\t\t\t.attr( {\n\t\t\t\t\t\t\t\ttabindex: '0',\n\t\t\t\t\t\t\t\trole: 'listbox'\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.on( 'keydown', function ( event ) {\n\t\t\t\t\t\t\t\tvar $selected = $pages.children().filter( function () {\n\t\t\t\t\t\t\t\t\treturn $( this ).css( 'display' ) !== 'none';\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t\t$.wikiEditor.modules.toolbar.fn.handleKeyDown( $selected.children().first(), event, $pages );\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t$index = $( '<div>' )\n\t\t\t\t\t\t\t.addClass( 'index' )\n\t\t\t\t\t\t\t.attr( {\n\t\t\t\t\t\t\t\ttabindex: '0',\n\t\t\t\t\t\t\t\trole: 'listbox'\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.on( 'keydown', function ( event ) {\n\t\t\t\t\t\t\t\t$.wikiEditor.modules.toolbar.fn.handleKeyDown( $index, event, $index );\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\tif ( 'pages' in section ) {\n\t\t\t\t\t\t\tfor ( page in section.pages ) {\n\t\t\t\t\t\t\t\t$pages.append(\n\t\t\t\t\t\t\t\t\ttoolbarModule.fn.buildPage( context, page, section.pages[ page ], deferLoad )\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t$index.append(\n\t\t\t\t\t\t\t\t\ttoolbarModule.fn.buildBookmark( context, page, section.pages[ page ] )\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$section.append( $index ).append( $pages );\n\t\t\t\t\t\ttoolbarModule.fn.updateBookletSelection( context, id, $pages, $index );\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t},\n\t\t\tupdateBookletSelection: function ( context, id, $pages, $index ) {\n\t\t\t\tvar $selectedIndex,\n\t\t\t\t\tcookie = 'wikiEditor-' + context.instance + '-booklet-' + id + '-page',\n\t\t\t\t\tselected = $.cookie( cookie );\n\t\t\t\t// Re-save cookie\n\t\t\t\tif ( selected !== null ) {\n\t\t\t\t\t$.cookie( cookie, selected, { expires: 30, path: '/' } );\n\t\t\t\t}\n\t\t\t\t$selectedIndex = $index.find( '*[rel=\"' + selected + '\"]' );\n\t\t\t\tif ( $selectedIndex.length === 0 ) {\n\t\t\t\t\t$selectedIndex = $index.children().eq( 0 );\n\t\t\t\t\tselected = $selectedIndex.attr( 'rel' );\n\t\t\t\t}\n\t\t\t\t$pages.children().hide();\n\t\t\t\t$pages.find( '*[rel=\"' + selected + '\"]' ).show().trigger( 'loadPage' );\n\t\t\t\t$index.children().removeClass( 'current' );\n\t\t\t\t$selectedIndex.addClass( 'current' );\n\t\t\t},\n\t\t\tbuild: function ( context, config ) {\n\t\t\t\tvar section,\n\t\t\t\t\t$tabs = $( '<div>' ).addClass( 'tabs' ).appendTo( context.modules.toolbar.$toolbar ),\n\t\t\t\t\t$sections = $( '<div>' ).addClass( 'sections' ).appendTo( context.modules.toolbar.$toolbar );\n\t\t\t\tcontext.modules.toolbar.$toolbar.append( $( '<div>' ).css( 'clear', 'both' ) );\n\t\t\t\tfor ( section in config ) {\n\t\t\t\t\tif ( section === 'main' ) {\n\t\t\t\t\t\tcontext.modules.toolbar.$toolbar.prepend(\n\t\t\t\t\t\t\ttoolbarModule.fn.buildSection( context, section, config[ section ] )\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$sections.append( toolbarModule.fn.buildSection( context, section, config[ section ] ) );\n\t\t\t\t\t\t$tabs.append( toolbarModule.fn.buildTab( context, section, config[ section ] ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tsetTimeout( function () {\n\t\t\t\t\tcontext.$textarea.trigger( 'wikiEditor-toolbar-doneInitialSections' );\n\t\t\t\t\t// Use hook for attaching new toolbar tools to avoid race conditions\n\t\t\t\t\tmw.hook( 'wikiEditor.toolbarReady' ).fire( context.$textarea );\n\t\t\t\t} );\n\t\t\t},\n\t\t\thandleKeyDown: function ( $element, event, $parent ) {\n\t\t\t\tvar $nextItem,\n\t\t\t\t\t$currentItem = $element.find( '.wikiEditor-character-highlighted' ),\n\t\t\t\t\toptionTop = $parent.find( '.wikiEditor-character-highlighted' ).offset().top,\n\t\t\t\t\tselectTop = $parent.offset().top;\n\t\t\t\tswitch ( event.keyCode ) {\n\t\t\t\t\t// Up arrow\n\t\t\t\t\tcase 38:\n\t\t\t\t\t\tif ( $currentItem.length ) {\n\t\t\t\t\t\t\t$currentItem.removeClass( 'wikiEditor-character-highlighted' );\n\t\t\t\t\t\t\t$nextItem = $currentItem.prev();\n\t\t\t\t\t\t\t$nextItem = $nextItem.length ? $nextItem : $currentItem;\n\t\t\t\t\t\t\t$nextItem.addClass( 'wikiEditor-character-highlighted' );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$element.children().first().addClass( 'wikiEditor-character-highlighted' );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t// Down arrow\n\t\t\t\t\tcase 40:\n\t\t\t\t\t\tif ( $currentItem.length ) {\n\t\t\t\t\t\t\t$currentItem.removeClass( 'wikiEditor-character-highlighted' );\n\t\t\t\t\t\t\t$nextItem = $currentItem.next();\n\t\t\t\t\t\t\t$nextItem = $nextItem.length ? $nextItem : $currentItem;\n\t\t\t\t\t\t\t$nextItem.addClass( 'wikiEditor-character-highlighted' );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$element.children().first().addClass( 'wikiEditor-character-highlighted' );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t// Enter\n\t\t\t\t\tcase 13:\n\t\t\t\t\t\t$currentItem.trigger( 'click' );\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t$parent.scrollTop( $parent.scrollTop() + ( optionTop - selectTop ) );\n\t\t\t}\n\t\t}\n\t};\n\n\tmodule.exports = toolbarModule;\n\n}() );\n","usedDeprecatedRules":[]},{"filePath":"/src/repo/package-lock.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/package.json","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/src/repo/tests/qunit/ext.wikiEditor.toolbar.test.js","messages":[],"errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]}]

$ npm ci
npm WARN prepare removing existing node_modules/ before installation

> core-js@3.9.1 postinstall /src/repo/node_modules/core-js
> node -e "try{require('./postinstall')}catch(e){}"

Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library!

The project needs your help! Please consider supporting of core-js on Open Collective or Patreon: 
> https://opencollective.com/core-js 
> https://www.patreon.com/zloirock 

Also, the author of core-js ( https://github.com/zloirock ) is looking for a good job -)

added 645 packages in 14.934s

$ npm test

> @ test /src/repo
> grunt test

Running "eslint:all" (eslint) task

/src/repo/modules/jquery.wikiEditor.dialogs.config.js
  134:9  warning  All possible CSS classes should be documented. See https://w.wiki/PS2 for details  mediawiki/class-doc

/src/repo/modules/jquery.wikiEditor.js
  271:27  warning  'context' is already declared in the upper scope on line 226 column 7              no-shadow
  272:10  warning  'module' is already declared in the upper scope on line 227 column 19              no-shadow
  272:18  warning  'call' is already declared in the upper scope on line 227 column 38                no-shadow
  273:7   warning  'modules' is already declared in the upper scope on line 227 column 10             no-shadow
  328:29  warning  'module' is already declared in the upper scope on line 227 column 19              no-shadow
  397:23  warning  'options' is already declared in the upper scope on line 395 column 25             no-shadow
  439:13  warning  All possible CSS classes should be documented. See https://w.wiki/PS2 for details  mediawiki/class-doc

/src/repo/modules/jquery.wikiEditor.toolbar.js
  420:13  warning  '$options' is already declared in the upper scope on line 280 column 51  no-shadow

✖ 9 problems (0 errors, 9 warnings)


Running "stylelint:all" (stylelint) task
>> Linted 7 files without errors

Running "banana:WikiEditor" (banana) task
>> 1 message directory checked.

Done.

$ git add .

$ git commit -F /tmp/tmpzvf30hq3
[master 3cd2dfb] build: Updating eslint-config-wikimedia to 0.18.2
 3 files changed, 159 insertions(+), 165 deletions(-)

$ git format-patch HEAD~1 --stdout
From 3cd2dfb88cc4a4e3ead2d9fb65d1d68f85cf94b1 Mon Sep 17 00:00:00 2001
From: libraryupgrader <tools.libraryupgrader@tools.wmflabs.org>
Date: Mon, 8 Mar 2021 09:54:06 +0000
Subject: [PATCH] build: Updating eslint-config-wikimedia to 0.18.2

Additional changes:
* Dropped .php5 and .inc files from .phpcs.xml (T200956).

Change-Id: Ice271e32dc3c36e9f012434b585952eda55dd036
---
 .phpcs.xml        |   2 +-
 package-lock.json | 320 +++++++++++++++++++++++-----------------------
 package.json      |   2 +-
 3 files changed, 159 insertions(+), 165 deletions(-)

diff --git a/.phpcs.xml b/.phpcs.xml
index 31dbc80..0fcdae0 100644
--- a/.phpcs.xml
+++ b/.phpcs.xml
@@ -6,6 +6,6 @@
 		<exclude name="MediaWiki.WhiteSpace.SpaceBeforeSingleLineComment.NewLineComment" />
 	</rule>
 	<file>.</file>
-	<arg name="extensions" value="php,php5,inc"/>
+	<arg name="extensions" value="php"/>
 	<arg name="encoding" value="UTF-8"/>
 </ruleset>
diff --git a/package-lock.json b/package-lock.json
index 1d07b8d..38a698e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -280,9 +280,9 @@
 			}
 		},
 		"@eslint/eslintrc": {
-			"version": "0.3.0",
-			"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.3.0.tgz",
-			"integrity": "sha512-1JTKgrOKAHVivSvOYw+sJOunkBjUOvjqWk1DPja7ZFhIS2mX/4EgTT8M7eTK9jrKhL/FvXXEbQwIs3pg1xp3dg==",
+			"version": "0.4.0",
+			"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz",
+			"integrity": "sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==",
 			"dev": true,
 			"requires": {
 				"ajv": "^6.12.4",
@@ -292,23 +292,10 @@
 				"ignore": "^4.0.6",
 				"import-fresh": "^3.2.1",
 				"js-yaml": "^3.13.1",
-				"lodash": "^4.17.20",
 				"minimatch": "^3.0.4",
 				"strip-json-comments": "^3.1.1"
 			},
 			"dependencies": {
-				"ajv": {
-					"version": "6.12.6",
-					"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
-					"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
-					"dev": true,
-					"requires": {
-						"fast-deep-equal": "^3.1.1",
-						"fast-json-stable-stringify": "^2.0.0",
-						"json-schema-traverse": "^0.4.1",
-						"uri-js": "^4.2.2"
-					}
-				},
 				"globals": {
 					"version": "12.4.0",
 					"resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
@@ -317,22 +304,6 @@
 					"requires": {
 						"type-fest": "^0.8.1"
 					}
-				},
-				"import-fresh": {
-					"version": "3.3.0",
-					"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
-					"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
-					"dev": true,
-					"requires": {
-						"parent-module": "^1.0.0",
-						"resolve-from": "^4.0.0"
-					}
-				},
-				"lodash": {
-					"version": "4.17.20",
-					"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
-					"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
-					"dev": true
 				}
 			}
 		},
@@ -464,9 +435,9 @@
 			"dev": true
 		},
 		"ajv": {
-			"version": "6.12.0",
-			"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz",
-			"integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==",
+			"version": "6.12.6",
+			"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+			"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
 			"dev": true,
 			"requires": {
 				"fast-deep-equal": "^3.1.1",
@@ -903,9 +874,9 @@
 			"dev": true
 		},
 		"core-js": {
-			"version": "3.8.3",
-			"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.3.tgz",
-			"integrity": "sha512-KPYXeVZYemC2TkNEkX/01I+7yd+nX3KddKwZ1Ww7SKWdI2wQprSgLmrTddT8nw92AjEklTsPBoSdQBhbI1bQ6Q==",
+			"version": "3.9.1",
+			"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.9.1.tgz",
+			"integrity": "sha512-gSjRvzkxQc1zjM/5paAmL4idJBFzuJoo+jDjF1tStYFMV2ERfD02HhahhCGXUyHxQRG4yFKVSdO6g62eoRMcDg==",
 			"dev": true
 		},
 		"core-util-is": {
@@ -1353,13 +1324,13 @@
 			"dev": true
 		},
 		"eslint": {
-			"version": "7.18.0",
-			"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.18.0.tgz",
-			"integrity": "sha512-fbgTiE8BfUJZuBeq2Yi7J3RB3WGUQ9PNuNbmgi6jt9Iv8qrkxfy19Ds3OpL1Pm7zg3BtTVhvcUZbIRQ0wmSjAQ==",
+			"version": "7.21.0",
+			"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.21.0.tgz",
+			"integrity": "sha512-W2aJbXpMNofUp0ztQaF40fveSsJBjlSCSWpy//gzfTvwC+USs/nceBrKmlJOiM8r1bLwP2EuYkCqArn/6QTIgg==",
 			"dev": true,
 			"requires": {
-				"@babel/code-frame": "^7.0.0",
-				"@eslint/eslintrc": "^0.3.0",
+				"@babel/code-frame": "7.12.11",
+				"@eslint/eslintrc": "^0.4.0",
 				"ajv": "^6.10.0",
 				"chalk": "^4.0.0",
 				"cross-spawn": "^7.0.2",
@@ -1370,9 +1341,9 @@
 				"eslint-utils": "^2.1.0",
 				"eslint-visitor-keys": "^2.0.0",
 				"espree": "^7.3.1",
-				"esquery": "^1.2.0",
+				"esquery": "^1.4.0",
 				"esutils": "^2.0.2",
-				"file-entry-cache": "^6.0.0",
+				"file-entry-cache": "^6.0.1",
 				"functional-red-black-tree": "^1.0.1",
 				"glob-parent": "^5.0.0",
 				"globals": "^12.1.0",
@@ -1397,13 +1368,43 @@
 				"v8-compile-cache": "^2.0.3"
 			},
 			"dependencies": {
-				"ansi-styles": {
-					"version": "4.3.0",
-					"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-					"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+				"@babel/code-frame": {
+					"version": "7.12.11",
+					"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
+					"integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==",
 					"dev": true,
 					"requires": {
-						"color-convert": "^2.0.1"
+						"@babel/highlight": "^7.10.4"
+					}
+				},
+				"@babel/helper-validator-identifier": {
+					"version": "7.12.11",
+					"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz",
+					"integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==",
+					"dev": true
+				},
+				"@babel/highlight": {
+					"version": "7.13.8",
+					"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.8.tgz",
+					"integrity": "sha512-4vrIhfJyfNf+lCtXC2ck1rKSzDwciqF7IWFhXXrSOUC2O5DrVp+w4c6ed4AllTxhTkUP5x2tYj41VaxdVMMRDw==",
+					"dev": true,
+					"requires": {
+						"@babel/helper-validator-identifier": "^7.12.11",
+						"chalk": "^2.0.0",
+						"js-tokens": "^4.0.0"
+					},
+					"dependencies": {
+						"chalk": {
+							"version": "2.4.2",
+							"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+							"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+							"dev": true,
+							"requires": {
+								"ansi-styles": "^3.2.1",
+								"escape-string-regexp": "^1.0.5",
+								"supports-color": "^5.3.0"
+							}
+						}
 					}
 				},
 				"chalk": {
@@ -1414,6 +1415,26 @@
 					"requires": {
 						"ansi-styles": "^4.1.0",
 						"supports-color": "^7.1.0"
+					},
+					"dependencies": {
+						"ansi-styles": {
+							"version": "4.3.0",
+							"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+							"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+							"dev": true,
+							"requires": {
+								"color-convert": "^2.0.1"
+							}
+						},
+						"supports-color": {
+							"version": "7.2.0",
+							"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+							"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+							"dev": true,
+							"requires": {
+								"has-flag": "^4.0.0"
+							}
+						}
 					}
 				},
 				"color-convert": {
@@ -1431,39 +1452,12 @@
 					"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
 					"dev": true
 				},
-				"eslint-scope": {
-					"version": "5.1.1",
-					"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
-					"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
-					"dev": true,
-					"requires": {
-						"esrecurse": "^4.3.0",
-						"estraverse": "^4.1.1"
-					}
-				},
 				"eslint-visitor-keys": {
 					"version": "2.0.0",
 					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz",
 					"integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==",
 					"dev": true
 				},
-				"esrecurse": {
-					"version": "4.3.0",
-					"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
-					"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
-					"dev": true,
-					"requires": {
-						"estraverse": "^5.2.0"
-					},
-					"dependencies": {
-						"estraverse": {
-							"version": "5.2.0",
-							"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
-							"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
-							"dev": true
-						}
-					}
-				},
 				"globals": {
 					"version": "12.4.0",
 					"resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
@@ -1480,9 +1474,9 @@
 					"dev": true
 				},
 				"lodash": {
-					"version": "4.17.20",
-					"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
-					"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+					"version": "4.17.21",
+					"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+					"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
 					"dev": true
 				},
 				"semver": {
@@ -1493,22 +1487,13 @@
 					"requires": {
 						"lru-cache": "^6.0.0"
 					}
-				},
-				"supports-color": {
-					"version": "7.2.0",
-					"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-					"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-					"dev": true,
-					"requires": {
-						"has-flag": "^4.0.0"
-					}
 				}
 			}
 		},
 		"eslint-config-wikimedia": {
-			"version": "0.18.1",
-			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.18.1.tgz",
-			"integrity": "sha512-93nHVH4CGxYwelbTjJQLr0xqn4XIe9WwWeGL4wMnELZW/Aceg52aT7AgIdV0659ReLzrCgxLPDvbeqB47LjBTQ==",
+			"version": "0.18.2",
+			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.18.2.tgz",
+			"integrity": "sha512-OllUgce2qODU/6481jg/a1kT/dygBDY1xhxXuAiQdYxJARV6LXyuiJw+wl1QBQz+huV9NXRxoJGC3L6x/NzC4g==",
 			"dev": true,
 			"requires": {
 				"eslint": "^7.17.0",
@@ -1516,12 +1501,12 @@
 				"eslint-plugin-es": "^4.1.0",
 				"eslint-plugin-jsdoc": "^30.7.13",
 				"eslint-plugin-json-es": "^1.5.1",
-				"eslint-plugin-mediawiki": "^0.2.6",
+				"eslint-plugin-mediawiki": "^0.2.7",
 				"eslint-plugin-mocha": "^8.0.0",
 				"eslint-plugin-no-jquery": "^2.5.0",
 				"eslint-plugin-node": "^11.1.0",
 				"eslint-plugin-qunit": "^5.2.0",
-				"eslint-plugin-vue": "^7.4.1",
+				"eslint-plugin-vue": "^7.7.0",
 				"eslint-plugin-wdio": "^6.0.12"
 			}
 		},
@@ -1542,9 +1527,9 @@
 			},
 			"dependencies": {
 				"caniuse-lite": {
-					"version": "1.0.30001181",
-					"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001181.tgz",
-					"integrity": "sha512-m5ul/ARCX50JB8BSNM+oiPmQrR5UmngaQ3QThTTp5HcIIQGP/nPBs82BYLE+tigzm3VW+F4BJIhUyaVtEweelQ==",
+					"version": "1.0.30001197",
+					"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001197.tgz",
+					"integrity": "sha512-8aE+sqBqtXz4G8g35Eg/XEaFr2N7rd/VQ6eABGBmNtcB8cN6qNJhMi6oSFy4UWWZgqgL3filHT8Nha4meu3tsw==",
 					"dev": true
 				},
 				"semver": {
@@ -1590,9 +1575,9 @@
 					}
 				},
 				"lodash": {
-					"version": "4.17.20",
-					"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
-					"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+					"version": "4.17.21",
+					"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+					"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
 					"dev": true
 				},
 				"semver": {
@@ -1607,42 +1592,37 @@
 			}
 		},
 		"eslint-plugin-json-es": {
-			"version": "1.5.1",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-json-es/-/eslint-plugin-json-es-1.5.1.tgz",
-			"integrity": "sha512-YMzAWMcmKOYWiH0MsN3JOr0AdtZ2Rvmk3YmscsX1rHYJZRsL4KRo+yj9ktRk7S7mgy+G5TORWJ5D3/vH/u7R5A==",
+			"version": "1.5.3",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-json-es/-/eslint-plugin-json-es-1.5.3.tgz",
+			"integrity": "sha512-9wWjwhoN+ipMel70ktkWy0H7jj9sm5OAbAy3N3F3AT0swpIofVsIjDXyjGZJwSzy9tZzDtI/aKIj2WsqMHw2QA==",
 			"dev": true,
 			"requires": {
-				"eslint-visitor-keys": "^1.3.0",
+				"eslint-visitor-keys": "^2.0.0",
 				"espree": "^7.3.1"
+			},
+			"dependencies": {
+				"eslint-visitor-keys": {
+					"version": "2.0.0",
+					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz",
+					"integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==",
+					"dev": true
+				}
 			}
 		},
 		"eslint-plugin-mediawiki": {
-			"version": "0.2.6",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.2.6.tgz",
-			"integrity": "sha512-e7gx15H39ceam9AnSr6DDyfhMM9L43PVagHzclH3CF33DvWKi/OA+j2dqzJTuJcl5P/EmVIQHG5qoTaepkADsw==",
+			"version": "0.2.7",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.2.7.tgz",
+			"integrity": "sha512-2ZvPvLEwCIqrJxV1349bdX5Q03c30WccuUMCfB1Gh2IVxbBSrY0gbzOk/gPZeYigVhODt9xoFWUCIz8jwTWfrA==",
 			"dev": true,
 			"requires": {
-				"eslint-plugin-vue": "^6.2.2",
+				"eslint-plugin-vue": "^7.7.0",
 				"upath": "^1.2.0"
-			},
-			"dependencies": {
-				"eslint-plugin-vue": {
-					"version": "6.2.2",
-					"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-6.2.2.tgz",
-					"integrity": "sha512-Nhc+oVAHm0uz/PkJAWscwIT4ijTrK5fqNqz9QB1D35SbbuMG1uB6Yr5AJpvPSWg+WOw7nYNswerYh0kOk64gqQ==",
-					"dev": true,
-					"requires": {
-						"natural-compare": "^1.4.0",
-						"semver": "^5.6.0",
-						"vue-eslint-parser": "^7.0.0"
-					}
-				}
 			}
 		},
 		"eslint-plugin-mocha": {
-			"version": "8.0.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-8.0.0.tgz",
-			"integrity": "sha512-n67etbWDz6NQM+HnTwZHyBwz/bLlYPOxUbw7bPuCyFujv7ZpaT/Vn6KTAbT02gf7nRljtYIjWcTxK/n8a57rQQ==",
+			"version": "8.1.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-8.1.0.tgz",
+			"integrity": "sha512-1EgHvXKRl7W3mq3sntZAi5T24agRMyiTPL4bSXe+B4GksYOjAPEWYx+J3eJg4It1l2NMNZJtk0gQyQ6mfiPhQg==",
 			"dev": true,
 			"requires": {
 				"eslint-utils": "^2.1.0",
@@ -1704,15 +1684,15 @@
 			}
 		},
 		"eslint-plugin-vue": {
-			"version": "7.5.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-7.5.0.tgz",
-			"integrity": "sha512-QnMMTcyV8PLxBz7QQNAwISSEs6LYk2LJvGlxalXvpCtfKnqo7qcY0aZTIxPe8QOnHd7WCwiMZLOJzg6A03T0Gw==",
+			"version": "7.7.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-7.7.0.tgz",
+			"integrity": "sha512-mYz4bpLGv5jx6YG/GvKkqbGSfV7uma2u1P3mLA41Q5vQl8W1MeuTneB8tfsLq6xxxesFubcrOC0BZBJ5R+eaCQ==",
 			"dev": true,
 			"requires": {
 				"eslint-utils": "^2.1.0",
 				"natural-compare": "^1.4.0",
 				"semver": "^7.3.2",
-				"vue-eslint-parser": "^7.4.1"
+				"vue-eslint-parser": "^7.6.0"
 			},
 			"dependencies": {
 				"semver": {
@@ -1783,18 +1763,18 @@
 			"dev": true
 		},
 		"esquery": {
-			"version": "1.3.1",
-			"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz",
-			"integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==",
+			"version": "1.4.0",
+			"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
+			"integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
 			"dev": true,
 			"requires": {
 				"estraverse": "^5.1.0"
 			},
 			"dependencies": {
 				"estraverse": {
-					"version": "5.1.0",
-					"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz",
-					"integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==",
+					"version": "5.2.0",
+					"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+					"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
 					"dev": true
 				}
 			}
@@ -2048,9 +2028,9 @@
 			}
 		},
 		"file-entry-cache": {
-			"version": "6.0.0",
-			"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz",
-			"integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==",
+			"version": "6.0.1",
+			"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+			"integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
 			"dev": true,
 			"requires": {
 				"flat-cache": "^3.0.4"
@@ -2398,12 +2378,11 @@
 			},
 			"dependencies": {
 				"ansi-styles": {
-					"version": "4.2.1",
-					"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
-					"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+					"version": "4.3.0",
+					"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+					"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
 					"dev": true,
 					"requires": {
-						"@types/color-name": "^1.1.1",
 						"color-convert": "^2.0.1"
 					}
 				},
@@ -2439,9 +2418,9 @@
 					"dev": true
 				},
 				"supports-color": {
-					"version": "7.1.0",
-					"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
-					"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+					"version": "7.2.0",
+					"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+					"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
 					"dev": true,
 					"requires": {
 						"has-flag": "^4.0.0"
@@ -2751,9 +2730,9 @@
 			"dev": true
 		},
 		"import-fresh": {
-			"version": "3.1.0",
-			"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz",
-			"integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==",
+			"version": "3.3.0",
+			"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+			"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
 			"dev": true,
 			"requires": {
 				"parent-module": "^1.0.0",
@@ -3051,9 +3030,9 @@
 			"dev": true
 		},
 		"js-yaml": {
-			"version": "3.13.1",
-			"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
-			"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+			"version": "3.14.1",
+			"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+			"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
 			"dev": true,
 			"requires": {
 				"argparse": "^1.0.7",
@@ -5204,9 +5183,9 @@
 			},
 			"dependencies": {
 				"ajv": {
-					"version": "7.0.3",
-					"resolved": "https://registry.npmjs.org/ajv/-/ajv-7.0.3.tgz",
-					"integrity": "sha512-R50QRlXSxqXcQP5SvKUrw8VZeypvo12i2IX0EeR5PiZ7bEKeHWgzgo264LDadUsCU42lTJVhFikTqJwNeH34gQ==",
+					"version": "7.2.1",
+					"resolved": "https://registry.npmjs.org/ajv/-/ajv-7.2.1.tgz",
+					"integrity": "sha512-+nu0HDv7kNSOua9apAVc979qd932rrZeb3WOvoiD31A/p1mIE5/9bN2027pE2rOPYEdS3UHzsvof4hY+lM9/WQ==",
 					"dev": true,
 					"requires": {
 						"fast-deep-equal": "^3.1.1",
@@ -5222,9 +5201,9 @@
 					"dev": true
 				},
 				"lodash": {
-					"version": "4.17.20",
-					"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
-					"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+					"version": "4.17.21",
+					"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+					"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
 					"dev": true
 				}
 			}
@@ -5485,9 +5464,9 @@
 			"dev": true
 		},
 		"v8-compile-cache": {
-			"version": "2.1.0",
-			"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz",
-			"integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==",
+			"version": "2.3.0",
+			"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
+			"integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
 			"dev": true
 		},
 		"v8flags": {
@@ -5539,16 +5518,16 @@
 			}
 		},
 		"vue-eslint-parser": {
-			"version": "7.4.1",
-			"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.4.1.tgz",
-			"integrity": "sha512-AFvhdxpFvliYq1xt/biNBslTHE/zbEvSnr1qfHA/KxRIpErmEDrQZlQnvEexednRHmLfDNOMuDYwZL5xkLzIXQ==",
+			"version": "7.6.0",
+			"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.6.0.tgz",
+			"integrity": "sha512-QXxqH8ZevBrtiZMZK0LpwaMfevQi9UL7lY6Kcp+ogWHC88AuwUPwwCIzkOUc1LR4XsYAt/F9yHXAB/QoD17QXA==",
 			"dev": true,
 			"requires": {
 				"debug": "^4.1.1",
 				"eslint-scope": "^5.0.0",
 				"eslint-visitor-keys": "^1.1.0",
 				"espree": "^6.2.1",
-				"esquery": "^1.0.1",
+				"esquery": "^1.4.0",
 				"lodash": "^4.17.15"
 			},
 			"dependencies": {
@@ -5562,6 +5541,21 @@
 						"acorn-jsx": "^5.2.0",
 						"eslint-visitor-keys": "^1.1.0"
 					}
+				},
+				"esquery": {
+					"version": "1.4.0",
+					"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
+					"integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+					"dev": true,
+					"requires": {
+						"estraverse": "^5.1.0"
+					}
+				},
+				"estraverse": {
+					"version": "5.2.0",
+					"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+					"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+					"dev": true
 				}
 			}
 		},
diff --git a/package.json b/package.json
index 13a1f04..503c274 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
 		"test": "grunt test"
 	},
 	"devDependencies": {
-		"eslint-config-wikimedia": "0.18.1",
+		"eslint-config-wikimedia": "0.18.2",
 		"grunt": "1.3.0",
 		"grunt-banana-checker": "0.9.0",
 		"grunt-eslint": "23.0.0",
-- 
2.20.1

composer dependencies

Development dependencies

npm dependencies

Development dependencies

Logs

Source code is licensed under the AGPL.