diff --git a/.user.php.ini b/.user.php.ini deleted file mode 100644 index 7660f85a..00000000 --- a/.user.php.ini +++ /dev/null @@ -1,2 +0,0 @@ -memory_limit = 256M -max_execution_time = 300 diff --git a/api.php b/api.php index 34ffe655..b986a655 100644 --- a/api.php +++ b/api.php @@ -18,28 +18,9 @@ $FTL_IP = "127.0.0.1"; $data = array(); // Common API functions -if (isset($_GET['status'])) -{ - $pistatus = pihole_execute('status web'); - if(isset($pistatus[0])) - { - $pistatus = $pistatus[0]; - } - else - { - $pistatus = null; - } - if ($pistatus === "1") - { - $data = array_merge($data, array("status" => "enabled")); - } - else - { - $data = array_merge($data, array("status" => "disabled")); - } -} -elseif (isset($_GET['enable']) && $auth) -{ +if (isset($_GET['status'])) { + $data = array_merge($data, array("status" => piholeStatusAPI())); +} elseif (isset($_GET['enable']) && $auth) { if(isset($_GET["auth"])) { if($_GET["auth"] !== $pwhash) @@ -160,17 +141,64 @@ elseif (isset($_GET['list'])) return; } +elseif(isset($_GET['customdns']) && $auth) +{ + if (isset($_GET["auth"])) { + if ($_GET["auth"] !== $pwhash) { + die("Not authorized!"); + } + } else { + // Skip token validation if explicit auth string is given + check_csrf($_GET['token']); + } + + switch ($_GET["action"]) { + case 'get': + $_POST['action'] = 'get'; + break; + case 'add': + $_POST['action'] = 'add'; + break; + case 'delete': + $_POST['action'] = 'delete'; + break; + } + + require("scripts/pi-hole/php/customdns.php"); +} +elseif(isset($_GET['customcname']) && $auth) +{ + if (isset($_GET["auth"])) { + if ($_GET["auth"] !== $pwhash) { + die("Not authorized!"); + } + } else { + // Skip token validation if explicit auth string is given + check_csrf($_GET['token']); + } + + switch ($_GET["action"]) { + case 'get': + $_POST['action'] = 'get'; + break; + case 'add': + $_POST['action'] = 'add'; + break; + case 'delete': + $_POST['action'] = 'delete'; + break; + } + + require("scripts/pi-hole/php/customcname.php"); +} // Other API functions require("api_FTL.php"); header('Content-type: application/json'); -if(isset($_GET["jsonForceObject"])) -{ - echo json_encode($data, JSON_FORCE_OBJECT); -} -else -{ - echo json_encode($data); +if(isset($_GET["jsonForceObject"])) { + echo json_encode($data, JSON_FORCE_OBJECT); +} else { + echo json_encode($data); } ?> diff --git a/api_FTL.php b/api_FTL.php index 13177a7e..b7bcf9fe 100644 --- a/api_FTL.php +++ b/api_FTL.php @@ -29,26 +29,48 @@ else $data["version"] = 3; } - if (isset($_GET['summary']) || isset($_GET['summaryRaw']) || !count($_GET)) - { + if (isset($_GET['summary']) || isset($_GET['summaryRaw']) || !count($_GET)) { require_once("scripts/pi-hole/php/gravity.php"); sendRequestFTL("stats"); $return = getResponseFTL(); $stats = []; - foreach($return as $line) - { + foreach($return as $line) { $tmp = explode(" ",$line); - if(($tmp[0] === "domains_being_blocked" && !is_numeric($tmp[1])) || $tmp[0] === "status") - $stats[$tmp[0]] = $tmp[1]; // Expect string response - else - $stats[$tmp[0]] = floatval($tmp[1]); // Expect float response + if($tmp[0] === "domains_being_blocked" && !is_numeric($tmp[1])) { + // Expect string response + $stats[$tmp[0]] = $tmp[1]; + } elseif ($tmp[0] === "status") { + // Expect string response + $stats[$tmp[0]] = piholeStatusAPI(); + } elseif (isset($_GET['summary'])) { + // "summary" expects a formmated string response + if($tmp[0] !== "ads_percentage_today") { + $stats[$tmp[0]] = number_format($tmp[1]); + } else { + $stats[$tmp[0]] = number_format($tmp[1], 1, '.', ''); + } + } else { + // Expect float response + $stats[$tmp[0]] = floatval($tmp[1]); + } + } $stats['gravity_last_updated'] = gravity_last_update(true); $data = array_merge($data,$stats); } + if (isset($_GET["getMaxlogage"]) && $auth) { + sendRequestFTL("maxlogage"); + // Convert seconds to hours and rounds to one decimal place. + $ret = round(intval(getResponseFTL()[0]) / 3600, 1); + // Return 24h if value is 0, empty, null or non numeric. + $ret = $ret ?: 24; + + $data = array_merge($data, array("maxlogage" => $ret)); + } + if (isset($_GET['overTimeData10mins'])) { sendRequestFTL("overTime"); diff --git a/api_db.php b/api_db.php index a861cbde..e5340ff3 100644 --- a/api_db.php +++ b/api_db.php @@ -87,17 +87,36 @@ if (isset($_GET['getAllQueries']) && $auth) $stmt->bindValue(":from", intval($from), SQLITE3_INTEGER); $stmt->bindValue(":until", intval($until), SQLITE3_INTEGER); $results = $stmt->execute(); - if(!is_bool($results)) - while ($row = $results->fetchArray()) - { - // Convert query type ID to name - $query_type = getQueryTypeStr($row[1]); + if (!is_bool($results)) { + // Start the JSON string + echo '{"data":['; - // Insert into array - // array: time type domain client status upstream destination - $allQueries[] = [$row[0], $query_type, utf8_encode(str_replace("~"," ",$row[2])), $row[3], $row[4], utf8_encode($row[5])]; + $first = true; + while ($row = $results->fetchArray()) { + // Insert a comma before the next record (except on the first one) + if (!$first) { + echo ","; + } else { + $first = false; + } + + // Convert query type ID to name, encode domain, encode destination + $query_type = getQueryTypeStr($row[1]); + $domain = utf8_encode(str_replace("~"," ",$row[2])); + $destination = utf8_encode($row[5]); + + // Insert into array and output it in JSON format + // array: time type domain client status upstream destination + echo json_encode([$row[0], $query_type, $domain, $row[3], $row[4], $destination]); } + + // Finish the JSON string + echo ']}'; + } + // exit at the end + exit(); } + // only used if getAllQueries==empty $result = array('data' => $allQueries); $data = array_merge($data, $result); } diff --git a/groups-adlists.php b/groups-adlists.php index 1fb04179..04ec7294 100644 --- a/groups-adlists.php +++ b/groups-adlists.php @@ -67,7 +67,7 @@ Status Comment Group assignment - Action +   diff --git a/groups-clients.php b/groups-clients.php index e5620138..420ce5c8 100644 --- a/groups-clients.php +++ b/groups-clients.php @@ -73,7 +73,7 @@ Client Comment Group assignment - Action +   diff --git a/groups-domains.php b/groups-domains.php index b1aca183..25f86eee 100644 --- a/groups-domains.php +++ b/groups-domains.php @@ -126,7 +126,7 @@ Status Comment Group assignment - Action +   diff --git a/groups.php b/groups.php index 64b957a0..0cf970f7 100644 --- a/groups.php +++ b/groups.php @@ -64,7 +64,7 @@ Name Status Description - Action +   diff --git a/index.php b/index.php index b6d1fa85..ace5f700 100644 --- a/index.php +++ b/index.php @@ -1,26 +1,14 @@ - @@ -72,7 +60,7 @@
-

Domains on Blocklist

+

Domains on Adlists

---

@@ -87,7 +75,7 @@
-

Total queries over last hours

+

Total queries over last 24 hours

@@ -112,7 +100,7 @@
-

Client activity over last hours

+

Client activity over last 24 hours

diff --git a/package-lock.json b/package-lock.json index 82272b93..453fd561 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,331 +5,40 @@ "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", - "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", "dev": true, "requires": { - "@babel/highlight": "^7.16.0" - } - }, - "@babel/compat-data": { - "version": "7.16.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.4.tgz", - "integrity": "sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==", - "dev": true - }, - "@babel/core": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.5.tgz", - "integrity": "sha512-wUcenlLzuWMZ9Zt8S0KmFwGlH6QKRh3vsm/dhDA3CHkiTA45YuG1XkHRcNRl73EFPXDp/d5kVOU0/y7x2w6OaQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.0", - "@babel/generator": "^7.16.5", - "@babel/helper-compilation-targets": "^7.16.3", - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helpers": "^7.16.5", - "@babel/parser": "^7.16.5", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "@babel/eslint-parser": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.16.5.tgz", - "integrity": "sha512-mUqYa46lgWqHKQ33Q6LNCGp/wPR3eqOYTUixHFsfrSQqRxH0+WOzca75iEjFr5RDGH1dDz622LaHhLOzOuQRUA==", - "dev": true, - "requires": { - "eslint-scope": "^5.1.1", - "eslint-visitor-keys": "^2.1.0", - "semver": "^6.3.0" - }, - "dependencies": { - "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.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.5.tgz", - "integrity": "sha512-kIvCdjZqcdKqoDbVVdt5R99icaRtrtYhYK/xux5qiWCBmfdvEYMFZ68QCrpE5cbFM1JsuArUNs1ZkuKtTtUcZA==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.16.3", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.3.tgz", - "integrity": "sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.16.0", - "@babel/helper-validator-option": "^7.14.5", - "browserslist": "^4.17.5", - "semver": "^6.3.0" - }, - "dependencies": { - "browserslist": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", - "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001286", - "electron-to-chromium": "^1.4.17", - "escalade": "^3.1.1", - "node-releases": "^2.0.1", - "picocolors": "^1.0.0" - } - }, - "caniuse-lite": { - "version": "1.0.30001292", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001292.tgz", - "integrity": "sha512-jnT4Tq0Q4ma+6nncYQVe7d73kmDmE9C3OGTx3MvW7lBM/eY1S1DZTMBON7dqV481RhNiS5OxD7k9JQvmDOTirw==", - "dev": true - }, - "electron-to-chromium": { - "version": "1.4.26", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.26.tgz", - "integrity": "sha512-cA1YwlRzO6TGp7yd3+KAqh9Tt6Z4CuuKqsAJP6uF/H5MQryjAGDhMhnY5cEXo8MaRCczpzSBhMPdqRIodkbZYw==", - "dev": true - }, - "node-releases": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", - "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "@babel/helper-environment-visitor": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.5.tgz", - "integrity": "sha512-ODQyc5AnxmZWm/R2W7fzhamOk1ey8gSguo5SGvF0zcB3uUzRpTRmM/jmLSm9bDMyPlvbyJ+PwPEK0BWIoZ9wjg==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-function-name": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz", - "integrity": "sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.16.0", - "@babel/template": "^7.16.0", - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz", - "integrity": "sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz", - "integrity": "sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-module-imports": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz", - "integrity": "sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-module-transforms": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.5.tgz", - "integrity": "sha512-CkvMxgV4ZyyioElFwcuWnDCcNIeyqTkCm9BxXZi73RR1ozqlpboqsbGUNvRTflgZtFbbJ1v5Emvm+lkjMYY/LQ==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-simple-access": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0", - "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-simple-access": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz", - "integrity": "sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz", - "integrity": "sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0" + "@babel/highlight": "^7.16.7" } }, "@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", "dev": true }, - "@babel/helper-validator-option": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", - "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", - "dev": true - }, - "@babel/helpers": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.5.tgz", - "integrity": "sha512-TLgi6Lh71vvMZGEkFuIxzaPsyeYCHQ5jJOOX1f0xXn0uciFuE8cEk0wyBquMcCxBXZ5BJhE2aUB7pnWTD150Tw==", - "dev": true, - "requires": { - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" - } - }, "@babel/highlight": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz", - "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.15.7", + "@babel/helper-validator-identifier": "^7.16.7", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, - "@babel/parser": { - "version": "7.16.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.6.tgz", - "integrity": "sha512-Gr86ujcNuPDnNOY8mi383Hvi8IYrJVJYuf3XcuBM/Dgd+bINn/7tHqsj+tKkoreMbmGsFLsltI/JJd8fOFWGDQ==", - "dev": true - }, - "@babel/template": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz", - "integrity": "sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.0", - "@babel/parser": "^7.16.0", - "@babel/types": "^7.16.0" - } - }, - "@babel/traverse": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.5.tgz", - "integrity": "sha512-FOCODAzqUMROikDYLYxl4nmwiLlu85rNqBML/A5hKRVXG2LV8d0iMqgPzdYTcIpjZEBB7D6UDU9vxRZiriASdQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.0", - "@babel/generator": "^7.16.5", - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-hoist-variables": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0", - "@babel/parser": "^7.16.5", - "@babel/types": "^7.16.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", - "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.15.7", - "to-fast-properties": "^2.0.0" - } - }, "@eslint/eslintrc": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", - "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.1.0.tgz", + "integrity": "sha512-C1DfL7XX4nPqGd6jcP01W9pVM1HYCuUkFk1432D7F0v3JSlUIeOYn9oCoi3eoLZ+iwBSb29BMFxxny0YrrEZqg==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.2.0", + "espree": "^9.3.1", "globals": "^13.9.0", "ignore": "^4.0.6", "import-fresh": "^3.2.1", @@ -347,9 +56,9 @@ } }, "@humanwhocodes/config-array": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz", - "integrity": "sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.3.tgz", + "integrity": "sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", @@ -364,9 +73,9 @@ "dev": true }, "@mdn/browser-compat-data": { - "version": "3.3.14", - "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-3.3.14.tgz", - "integrity": "sha512-n2RC9d6XatVbWFdHLimzzUJxJ1KY8LdjqrW6YvGPiRmsHkhOUx74/Ct10x5Yo7bC/Jvqx7cDEW8IMPv/+vwEzA==", + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-4.1.6.tgz", + "integrity": "sha512-JbtcHGODAlkOT6eDV2rCyOguW3+o34ExMD9DOki6kxzeyN3IBtZ9PI0FlbKeD77Bm5U0UG5Heo4qnNbSajXUnw==", "dev": true }, "@nodelib/fs.scandir": { @@ -406,9 +115,9 @@ } }, "@types/estree": { - "version": "0.0.50", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", - "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", + "version": "0.0.51", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", + "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", "dev": true }, "@types/json-schema": { @@ -442,9 +151,9 @@ "dev": true }, "acorn": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.6.0.tgz", - "integrity": "sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", "dev": true }, "acorn-jsx": { @@ -465,12 +174,6 @@ "uri-js": "^4.2.2" } }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -568,16 +271,24 @@ "dev": true, "requires": { "@mdn/browser-compat-data": "^3.3.14" + }, + "dependencies": { + "@mdn/browser-compat-data": { + "version": "3.3.14", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-3.3.14.tgz", + "integrity": "sha512-n2RC9d6XatVbWFdHLimzzUJxJ1KY8LdjqrW6YvGPiRmsHkhOUx74/Ct10x5Yo7bC/Jvqx7cDEW8IMPv/+vwEzA==", + "dev": true + } } }, "autoprefixer": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.1.tgz", - "integrity": "sha512-B3ZEG7wtzXDRCEFsan7HmR2AeNsxdJB0+sEC0Hc5/c2NbhJqPwuZm+tn233GBVw82L+6CtD6IPSfVruwKjfV3A==", + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.2.tgz", + "integrity": "sha512-9fOPpHKuDW1w/0EKfRmVnxTDt8166MAnLI3mgZ1JCnhNtYWxcJ6Ud5CO/AVOZi/AvFa8DY9RTy3h3+tFBlrrdQ==", "dev": true, "requires": { "browserslist": "^4.19.1", - "caniuse-lite": "^1.0.30001294", + "caniuse-lite": "^1.0.30001297", "fraction.js": "^4.1.2", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", @@ -598,15 +309,15 @@ } }, "caniuse-lite": { - "version": "1.0.30001294", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001294.tgz", - "integrity": "sha512-LiMlrs1nSKZ8qkNhpUf5KD0Al1KCBE3zaT7OLOwEkagXMEDij98SiOovn9wxVGQpklk9vVC/pUSqgYmkmKOS8g==", + "version": "1.0.30001298", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001298.tgz", + "integrity": "sha512-AcKqikjMLlvghZL/vfTHorlQsLDhGRalYf1+GmWCf5SCMziSGjRYQW/JEksj14NaYHIR6KIhrFAy0HV5C25UzQ==", "dev": true }, "electron-to-chromium": { - "version": "1.4.31", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.31.tgz", - "integrity": "sha512-t3XVQtk+Frkv6aTD4RRk0OqosU+VLe1dQFW83MDer78ZD6a52frgXuYOIsLYTQiH2Lm+JB2OKYcn7zrX+YGAiQ==", + "version": "1.4.38", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.38.tgz", + "integrity": "sha512-WhHt3sZazKj0KK/UpgsbGQnUUoFeAHVishzHFExMxagpZgjiGYSC9S0ZlbhCfSH2L2i+2A1yyqOIliTctMx7KQ==", "dev": true }, "node-releases": { @@ -649,16 +360,16 @@ } }, "browserslist": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.0.tgz", - "integrity": "sha512-g2BJ2a0nEYvEFQC208q8mVAhfNwpZ5Mu8BwgtCdZKO3qx98HChmeg448fPdUzld8aFmfLgVh7yymqV+q1lJZ5g==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", + "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001254", - "colorette": "^1.3.0", - "electron-to-chromium": "^1.3.830", + "caniuse-lite": "^1.0.30001286", + "electron-to-chromium": "^1.4.17", "escalade": "^3.1.1", - "node-releases": "^1.1.75" + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" } }, "builtin-modules": { @@ -684,18 +395,18 @@ "dev": true }, "camelcase": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", - "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true }, "camelcase-keys": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-7.0.1.tgz", - "integrity": "sha512-P331lEls98pW8JLyodNWfzuz91BEDVA4VpW2/SwXnyv2K495tq1N777xzDbFgnEigfA7UIY0xa6PwR/H9jijjA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-7.0.2.tgz", + "integrity": "sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==", "dev": true, "requires": { - "camelcase": "^6.2.0", + "camelcase": "^6.3.0", "map-obj": "^4.1.0", "quick-lru": "^5.1.1", "type-fest": "^1.2.1" @@ -710,9 +421,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001256", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001256.tgz", - "integrity": "sha512-QirrvMLmB4txNnxiaG/xbm6FSzv9LqOZ3Jp9VtCYb3oPIfCHpr/oGn38pFq0udwlkctvXQgPthaXqJ76DaYGnA==", + "version": "1.0.30001307", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001307.tgz", + "integrity": "sha512-+MXEMczJ4FuxJAUp0jvAl6Df0NI/OfW1RWEE61eSmzS7hw6lz4IKutbhbXendwq8BljfFuHtu26VWsg4afQ7Ng==", "dev": true }, "chalk": { @@ -809,12 +520,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "colorette": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", - "dev": true - }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -828,24 +533,15 @@ "dev": true }, "confusing-browser-globals": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz", - "integrity": "sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", "dev": true }, - "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, "core-js": { - "version": "3.19.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.19.1.tgz", - "integrity": "sha512-Tnc7E9iKd/b/ff7GFbhwPVzJzPztGrChB8X8GLqoYGdEOG8IpLnK1xPyo3ZoO3HsK6TodJS58VGPOxA+hLHQMg==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.21.0.tgz", + "integrity": "sha512-YUdI3fFu4TF/2WykQ2xzSiTQdldLB4KVuL9WeAy5XONZYt5Cun/fpQvctoKbCgvPhmzADeesTk/j2Rdx77AcKQ==", "dev": true }, "cosmiconfig": { @@ -957,9 +653,9 @@ } }, "electron-to-chromium": { - "version": "1.3.836", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.836.tgz", - "integrity": "sha512-Ney3pHOJBWkG/AqYjrW0hr2AUCsao+2uvq9HUlRP8OlpSdk/zOHOUJP7eu0icDvePC9DlgffuelP4TnOJmMRUg==", + "version": "1.4.65", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.65.tgz", + "integrity": "sha512-0/d8Skk8sW3FxXP0Dd6MnBlrwx7Qo9cqQec3BlIAlvKnrmS3pHsIbaroEi+nd0kZkGpQ6apMEre7xndzjlEnLw==", "dev": true }, "emoji-regex": { @@ -988,15 +684,6 @@ "tapable": "^0.1.8" } }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, "env-editor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/env-editor/-/env-editor-1.0.0.tgz", @@ -1064,24 +751,23 @@ "dev": true }, "eslint": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.5.0.tgz", - "integrity": "sha512-tVGSkgNbOfiHyVte8bCM8OmX+xG9PzVG/B4UCF60zx7j61WIVY/AqJECDgpLD4DbbESD0e174gOg3ZlrX15GDg==", + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.9.0.tgz", + "integrity": "sha512-PB09IGwv4F4b0/atrbcMFboF/giawbBLVC7fyDamk5Wtey4Jh2K+rYaBhCAbUyEI4QzB1ly09Uglc9iCtFaG2Q==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.0.5", + "@eslint/eslintrc": "^1.1.0", "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.0", + "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.1.0", - "espree": "^9.2.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -1089,7 +775,7 @@ "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", "globals": "^13.6.0", - "ignore": "^4.0.6", + "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", @@ -1100,9 +786,7 @@ "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "progress": "^2.0.0", "regexpp": "^3.2.0", - "semver": "^7.2.1", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0", @@ -1152,9 +836,9 @@ "dev": true }, "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true }, "strip-ansi": { @@ -1184,12 +868,12 @@ "dev": true }, "eslint-config-xo": { - "version": "0.39.0", - "resolved": "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.39.0.tgz", - "integrity": "sha512-QX+ZnQgzy/UtgF8dksIiIBzpYoEKmiL0CmZ8O0Gnby7rGXg8Cny1CXirmHp1zKYIpO7BuTmtWj8eUYOsGr0IGQ==", + "version": "0.40.0", + "resolved": "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.40.0.tgz", + "integrity": "sha512-msI1O0JGxeK2bbExg3U6EGaWKcjhOFzEjwzObywG/DC5GSNZTOyJT+b2l9MZGBeZsVdxfIGwdXTNeWXl8cN9iw==", "dev": true, "requires": { - "confusing-browser-globals": "1.0.10" + "confusing-browser-globals": "1.0.11" } }, "eslint-formatter-pretty": { @@ -1293,14 +977,13 @@ } }, "eslint-module-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz", - "integrity": "sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==", + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", + "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", "dev": true, "requires": { "debug": "^3.2.7", - "find-up": "^2.1.0", - "pkg-dir": "^2.0.0" + "find-up": "^2.1.0" }, "dependencies": { "debug": { @@ -1354,22 +1037,13 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } } } }, "eslint-plugin-ava": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-ava/-/eslint-plugin-ava-13.1.0.tgz", - "integrity": "sha512-Bdwyqv4Xh+4ekqbk601HcZNcx8+9ClNGz5GdbC2hv977jUPHQPDMx2arTD3zi1EeyOnOG2Kx22Ow3wecbPCRjQ==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-ava/-/eslint-plugin-ava-13.2.0.tgz", + "integrity": "sha512-i5B5izsEdERKQLruk1nIWzTTE7C26/ju8qQf7JeyRv32XT2lRMW0zMFZNhIrEf5/5VvpSz2rqrV7UcjClGbKsw==", "dev": true, "requires": { "enhance-visitors": "^1.0.0", @@ -1383,27 +1057,19 @@ } }, "eslint-plugin-compat": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-4.0.0.tgz", - "integrity": "sha512-lg9CPq0bsGxNXcLZgxqVAYsUUELIKZPRiwnJJQOHH910zCHEiscO00Sp+w9wflKEa/OtVaYfNhI2jOViRPZtjw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-4.0.2.tgz", + "integrity": "sha512-xqvoO54CLTVaEYGMzhu35Wzwk/As7rCvz/2dqwnFiWi0OJccEtGIn+5qq3zqIu9nboXlpdBN579fZcItC73Ycg==", "dev": true, "requires": { - "@mdn/browser-compat-data": "^3.3.14", + "@mdn/browser-compat-data": "^4.1.5", "ast-metadata-inferer": "^0.7.0", "browserslist": "^4.16.8", - "caniuse-lite": "^1.0.30001267", + "caniuse-lite": "^1.0.30001304", "core-js": "^3.16.2", "find-up": "^5.0.0", "lodash.memoize": "4.1.2", "semver": "7.3.5" - }, - "dependencies": { - "caniuse-lite": { - "version": "1.0.30001282", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001282.tgz", - "integrity": "sha512-YhF/hG6nqBEllymSIjLtR2iWDDnChvhnVJqp+vloyt2tEHFG1yBR+ac2B/rOw0qOK0m0lEXU2dv4E/sMk5P9Kg==", - "dev": true - } } }, "eslint-plugin-es": { @@ -1444,9 +1110,9 @@ } }, "eslint-plugin-import": { - "version": "2.25.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.3.tgz", - "integrity": "sha512-RzAVbby+72IB3iOEL8clzPLzL3wpDrlwjsTBAQXgyp5SeTqqY+0bFubwuo+y/HLhNZcXV4XqTBO4LGsfyHIDXg==", + "version": "2.25.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz", + "integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==", "dev": true, "requires": { "array-includes": "^3.1.4", @@ -1454,14 +1120,14 @@ "debug": "^2.6.9", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.1", + "eslint-module-utils": "^2.7.2", "has": "^1.0.3", "is-core-module": "^2.8.0", "is-glob": "^4.0.3", "minimatch": "^3.0.4", "object.values": "^1.1.5", "resolve": "^1.20.0", - "tsconfig-paths": "^3.11.0" + "tsconfig-paths": "^3.12.0" }, "dependencies": { "debug": { @@ -1558,23 +1224,22 @@ } }, "eslint-plugin-unicorn": { - "version": "39.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-39.0.0.tgz", - "integrity": "sha512-fd5RK2FtYjGcIx3wra7csIE/wkkmBo22T1gZtRTsLr1Mb+KsFKJ+JOdSqhHXQUrI/JTs/Mon64cEYzTgSCbltw==", + "version": "40.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-40.1.0.tgz", + "integrity": "sha512-y5doK2DF9Sr5AqKEHbHxjFllJ167nKDRU01HDcWyv4Tnmaoe9iNxMrBnaybZvWZUaE3OC5Unu0lNIevYamloig==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.9", - "ci-info": "^3.2.0", + "@babel/helper-validator-identifier": "^7.15.7", + "ci-info": "^3.3.0", "clean-regexp": "^1.0.0", - "eslint-template-visitor": "^2.3.2", "eslint-utils": "^3.0.0", "esquery": "^1.4.0", - "indent-string": "4", + "indent-string": "^4.0.0", "is-builtin-module": "^3.1.0", "lodash": "^4.17.21", "pluralize": "^8.0.0", "read-pkg-up": "^7.0.1", - "regexp-tree": "^0.1.23", + "regexp-tree": "^0.1.24", "safe-regex": "^2.1.1", "semver": "^7.3.5", "strip-indent": "^3.0.0" @@ -1587,36 +1252,15 @@ "dev": true }, "eslint-scope": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", - "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, "requires": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, - "eslint-template-visitor": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.3.2.tgz", - "integrity": "sha512-3ydhqFpuV7x1M9EK52BPNj6V0Kwu0KKkcIAfpUhwHbR8ocRln/oUHgfxQupY8O1h4Qv/POHDumb/BwwNfxbtnA==", - "dev": true, - "requires": { - "@babel/core": "^7.12.16", - "@babel/eslint-parser": "^7.12.16", - "eslint-visitor-keys": "^2.0.0", - "esquery": "^1.3.1", - "multimap": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, "eslint-utils": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", @@ -1635,26 +1279,26 @@ } }, "eslint-visitor-keys": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", - "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true }, "esm-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/esm-utils/-/esm-utils-2.0.0.tgz", - "integrity": "sha512-FM1aYzy+6rfTR4XHE5CwGAEliEvKCpCgDpnjqtk2eYEcLuTHK5SzypGQrkyaFB21utY8EePOrZhQvk3ayZhQjQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/esm-utils/-/esm-utils-2.2.0.tgz", + "integrity": "sha512-kYj4yNRo4W3by0f1mj4AfRh1nsRTTpQG921Ik3AfyUq6upGlkI1fnMLypHn6XtFzZPdCYH1k9mtQA5MyZF9m+w==", "dev": true }, "espree": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.2.0.tgz", - "integrity": "sha512-oP3utRkynpZWF/F2x/HZJ+AGtnIclaR7z1pYPxy7NYM2fSO6LgK/Rkny8anRSPK/VwEA1eqm2squui0T7ZMOBg==", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", + "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", "dev": true, "requires": { - "acorn": "^8.6.0", + "acorn": "^8.7.0", "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.1.0" + "eslint-visitor-keys": "^3.3.0" } }, "espurify": { @@ -1866,9 +1510,9 @@ } }, "flatted": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", - "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", "dev": true }, "fraction.js": { @@ -1913,12 +1557,6 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -1988,9 +1626,9 @@ } }, "globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "version": "13.12.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", + "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -2229,9 +1867,9 @@ "dev": true }, "is-core-module": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", - "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", "dev": true, "requires": { "has": "^1.0.3" @@ -2460,12 +2098,6 @@ "argparse": "^2.0.1" } }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, "json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -2535,9 +2167,9 @@ }, "dependencies": { "type-fest": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.8.0.tgz", - "integrity": "sha512-O+V9pAshf9C6loGaH0idwsmugI2LxVNR7DtS40gVo2EXZVYFgz9OuNtOhgHLdHdapOEWNdvz9Ob/eeuaWwwlxA==", + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.11.2.tgz", + "integrity": "sha512-reW2Y2Mpn0QNA/5fvtm5doROLwDPu2zOm5RtY7xQQS05Q7xgC8MOZ3yPNaP9m/s/sNjjFQtHo7VCNqYW2iI+Ig==", "dev": true } } @@ -2713,9 +2345,9 @@ }, "dependencies": { "hosted-git-info": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", - "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -2805,9 +2437,9 @@ "dev": true }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -2844,16 +2476,10 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "multimap": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/multimap/-/multimap-1.1.0.tgz", - "integrity": "sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw==", - "dev": true - }, "nanoid": { - "version": "3.1.30", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz", - "integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", + "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==", "dev": true }, "natural-compare": { @@ -2863,9 +2489,9 @@ "dev": true }, "node-releases": { - "version": "1.1.75", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.75.tgz", - "integrity": "sha512-Qe5OUajvqrqDSy6wrWFmMwfJ0jVgwiw4T3KqmbTcZ62qW0gQkheXYhcFM1+lOVcGUoRxcEcfyvFMAnDgaF1VWw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", + "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", "dev": true }, "normalize-package-data": { @@ -3131,14 +2757,14 @@ "dev": true }, "postcss": { - "version": "8.4.5", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.5.tgz", - "integrity": "sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==", + "version": "8.4.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.6.tgz", + "integrity": "sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA==", "dev": true, "requires": { - "nanoid": "^3.1.30", + "nanoid": "^3.2.0", "picocolors": "^1.0.0", - "source-map-js": "^1.0.1" + "source-map-js": "^1.0.2" } }, "postcss-cli": { @@ -3219,12 +2845,6 @@ "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", "dev": true }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, "proto-props": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/proto-props/-/proto-props-2.0.0.tgz", @@ -3395,13 +3015,14 @@ "dev": true }, "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", "dev": true, "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" } }, "resolve-from": { @@ -3434,12 +3055,6 @@ "queue-microtask": "^1.2.2" } }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, "safe-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", @@ -3485,9 +3100,9 @@ } }, "signal-exit": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", - "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, "slash": { @@ -3496,16 +3111,10 @@ "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", "dev": true }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, "source-map-js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.1.tgz", - "integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", "dev": true }, "spdx-correct": { @@ -3643,6 +3252,12 @@ } } }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, "tapable": { "version": "0.1.10", "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.1.10.tgz", @@ -3665,12 +3280,6 @@ "is-negated-glob": "^1.0.0" } }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -3725,9 +3334,9 @@ "dev": true }, "typescript": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz", - "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==", + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", + "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", "dev": true }, "unbox-primitive": { @@ -3825,35 +3434,35 @@ "dev": true }, "xo": { - "version": "0.47.0", - "resolved": "https://registry.npmjs.org/xo/-/xo-0.47.0.tgz", - "integrity": "sha512-QHRIpaPSG7tK7PX4K4fqe0V4EH1u2IkM7Pr356u1fKcVsZskw7i9gfEqyBLsnnc4e4Y8gnLtIqasLJsGPqM8sA==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/xo/-/xo-0.48.0.tgz", + "integrity": "sha512-f0sbQGJoML3nwOLG7EIAJroBypmLokoGJqTPN+bI/oogKLMciqWBEiFh9Vpxnfwxafq1AkHoWrQZQWSflDCG1w==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.0.4", + "@eslint/eslintrc": "^1.0.5", "@typescript-eslint/eslint-plugin": "*", "@typescript-eslint/parser": "*", "arrify": "^3.0.0", "cosmiconfig": "^7.0.1", "define-lazy-prop": "^3.0.0", - "eslint": "^8.3.0", + "eslint": "^8.8.0", "eslint-config-prettier": "^8.3.0", - "eslint-config-xo": "^0.39.0", + "eslint-config-xo": "^0.40.0", "eslint-config-xo-typescript": "*", "eslint-formatter-pretty": "^4.1.0", "eslint-import-resolver-webpack": "^0.13.2", - "eslint-plugin-ava": "^13.1.0", + "eslint-plugin-ava": "^13.2.0", "eslint-plugin-eslint-comments": "^3.2.0", - "eslint-plugin-import": "^2.25.3", + "eslint-plugin-import": "^2.25.4", "eslint-plugin-no-use-extend-native": "^0.5.0", "eslint-plugin-node": "^11.1.0", "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-unicorn": "^39.0.0", - "esm-utils": "^2.0.0", + "eslint-plugin-unicorn": "^40.1.0", + "esm-utils": "^2.0.1", "find-cache-dir": "^3.3.2", - "find-up": "^6.2.0", + "find-up": "^6.3.0", "get-stdin": "^9.0.0", - "globby": "^12.0.2", + "globby": "^13.1.1", "imurmurhash": "^0.1.4", "json-stable-stringify-without-jsonify": "^1.0.1", "json5": "^2.2.0", @@ -3861,11 +3470,11 @@ "meow": "^10.1.2", "micromatch": "^4.0.4", "open-editor": "^4.0.0", - "prettier": "^2.5.0", + "prettier": "^2.5.1", "semver": "^7.3.5", "slash": "^4.0.0", "to-absolute-glob": "^2.0.2", - "typescript": "^4.5.2" + "typescript": "^4.5.5" }, "dependencies": { "@nodelib/fs.scandir": { @@ -3897,12 +3506,13 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.4.0", + "version": "5.11.0", "bundled": true, "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "5.4.0", - "@typescript-eslint/scope-manager": "5.4.0", + "@typescript-eslint/scope-manager": "5.11.0", + "@typescript-eslint/type-utils": "5.11.0", + "@typescript-eslint/utils": "5.11.0", "debug": "^4.3.2", "functional-red-black-tree": "^1.0.1", "ignore": "^5.1.8", @@ -3912,57 +3522,54 @@ }, "dependencies": { "ignore": { - "version": "5.1.9", + "version": "5.2.0", "bundled": true, "dev": true } } }, - "@typescript-eslint/experimental-utils": { - "version": "5.4.0", - "bundled": true, - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.4.0", - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/typescript-estree": "5.4.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - } - }, "@typescript-eslint/parser": { - "version": "5.4.0", + "version": "5.11.0", "bundled": true, "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.4.0", - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/typescript-estree": "5.4.0", + "@typescript-eslint/scope-manager": "5.11.0", + "@typescript-eslint/types": "5.11.0", + "@typescript-eslint/typescript-estree": "5.11.0", "debug": "^4.3.2" } }, "@typescript-eslint/scope-manager": { - "version": "5.4.0", + "version": "5.11.0", "bundled": true, "dev": true, "requires": { - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/visitor-keys": "5.4.0" + "@typescript-eslint/types": "5.11.0", + "@typescript-eslint/visitor-keys": "5.11.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.11.0", + "bundled": true, + "dev": true, + "requires": { + "@typescript-eslint/utils": "5.11.0", + "debug": "^4.3.2", + "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.4.0", + "version": "5.11.0", "bundled": true, "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.4.0", + "version": "5.11.0", "bundled": true, "dev": true, "requires": { - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/visitor-keys": "5.4.0", + "@typescript-eslint/types": "5.11.0", + "@typescript-eslint/visitor-keys": "5.11.0", "debug": "^4.3.2", "globby": "^11.0.4", "is-glob": "^4.0.3", @@ -3970,26 +3577,21 @@ "tsutils": "^3.21.0" }, "dependencies": { - "array-union": { - "version": "2.1.0", - "bundled": true, - "dev": true - }, "globby": { - "version": "11.0.4", + "version": "11.1.0", "bundled": true, "dev": true, "requires": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", "slash": "^3.0.0" } }, "ignore": { - "version": "5.1.9", + "version": "5.2.0", "bundled": true, "dev": true }, @@ -4000,15 +3602,33 @@ } } }, - "@typescript-eslint/visitor-keys": { - "version": "5.4.0", + "@typescript-eslint/utils": { + "version": "5.11.0", "bundled": true, "dev": true, "requires": { - "@typescript-eslint/types": "5.4.0", + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.11.0", + "@typescript-eslint/types": "5.11.0", + "@typescript-eslint/typescript-estree": "5.11.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.11.0", + "bundled": true, + "dev": true, + "requires": { + "@typescript-eslint/types": "5.11.0", "eslint-visitor-keys": "^3.0.0" } }, + "array-union": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, "braces": { "version": "3.0.2", "bundled": true, @@ -4018,7 +3638,7 @@ } }, "debug": { - "version": "4.3.2", + "version": "4.3.3", "bundled": true, "dev": true, "requires": { @@ -4041,7 +3661,7 @@ } }, "eslint-config-xo-typescript": { - "version": "0.47.1", + "version": "0.50.0", "bundled": true, "dev": true }, @@ -4077,7 +3697,7 @@ } }, "eslint-visitor-keys": { - "version": "3.1.0", + "version": "3.2.0", "bundled": true, "dev": true }, @@ -4095,7 +3715,7 @@ "dev": true }, "fast-glob": { - "version": "3.2.7", + "version": "3.2.11", "bundled": true, "dev": true, "requires": { @@ -4123,12 +3743,12 @@ } }, "find-up": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.2.0.tgz", - "integrity": "sha512-yWHzMzXCaFoABSnFTCPKNFlYoq4mSga9QLRRKOCLSJ33hSkzROB14ITbAWW0QDQDyuzsPQ33S1DsOWQb/oW1yA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", "dev": true, "requires": { - "locate-path": "^7.0.0", + "locate-path": "^7.1.0", "path-exists": "^5.0.0" } }, @@ -4145,6 +3765,25 @@ "is-glob": "^4.0.1" } }, + "globby": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.1.tgz", + "integrity": "sha512-XMzoDZbGZ37tufiv7g0N4F/zp3zkwdFtVbV3EHsVl1KQr4RPLfNoT068/97RPshz2J5xYNEjLKKBKaGHifBd3Q==", + "dev": true, + "requires": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.11", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^4.0.0" + } + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, "is-extglob": { "version": "2.1.1", "bundled": true, @@ -4164,9 +3803,9 @@ "dev": true }, "locate-path": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.0.0.tgz", - "integrity": "sha512-+cg2yXqDUKfo4hsFxwa3G1cBJeA+gs1vD8FyV9/odWoUlQe/4syxHQ5DPtKjtfm6gnKbZzjCqzX03kXosvZB1w==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.1.0.tgz", + "integrity": "sha512-HNx5uOnYeK4SxEoid5qnhRfprlJeGMzFRKPLCf/15N3/B4AiofNwC/yq7VBKdVk9dx7m+PiYCJOGg55JYTAqoQ==", "dev": true, "requires": { "p-locate": "^6.0.0" @@ -4224,7 +3863,7 @@ "dev": true }, "picomatch": { - "version": "2.3.0", + "version": "2.3.1", "bundled": true, "dev": true }, diff --git a/package.json b/package.json index abf8effd..63a65ab6 100644 --- a/package.json +++ b/package.json @@ -24,12 +24,12 @@ "testpr": "npm run prettier:fix && git diff --ws-error-highlight=all --color=always --exit-code && npm run xo" }, "devDependencies": { - "autoprefixer": "^10.4.1", - "eslint-plugin-compat": "^4.0.0", - "postcss": "^8.4.5", + "autoprefixer": "^10.4.2", + "eslint-plugin-compat": "^4.0.2", + "postcss": "^8.4.6", "postcss-cli": "^9.1.0", "prettier": "2.5.1", - "xo": "^0.47.0" + "xo": "^0.48.0" }, "browserslist": [ "defaults", diff --git a/queries.php b/queries.php index 951e61e7..256e2c96 100644 --- a/queries.php +++ b/queries.php @@ -50,9 +50,9 @@ else if(isset($_GET["client"])) } else if(isset($_GET["forwarddest"])) { - if($_GET["forwarddest"] === "blocklist") - $showing .= " queries answered from blocklists"; - elseif($_GET["forwarddest"] === "cache") + if($_GET["forwarddest"] === "blocked") + $showing .= " queries blocked by Pi-hole"; + elseif($_GET["forwarddest"] === "cached") $showing .= " queries answered from cache"; else $showing .= " queries for upstream destination ".htmlentities($_GET["forwarddest"]); diff --git a/scripts/pi-hole/js/db_queries.js b/scripts/pi-hole/js/db_queries.js index e5c4ea4d..aba0ea41 100644 --- a/scripts/pi-hole/js/db_queries.js +++ b/scripts/pi-hole/js/db_queries.js @@ -84,7 +84,8 @@ function handleAjaxError(xhr, textStatus) { alert( "An unknown error occurred while loading the data.\n" + xhr.responseText + - "\nCheck the server's log files (/var/log/lighttpd/error.log when you're using the default Pi-hole web server) for details. You may need to increase the memory available for Pi-hole in case you requested a lot of data." + "\nCheck the server's log files (/var/log/lighttpd/error.log) for details.\n\nYou may need to increase PHP memory limit." + + "\n\nYou can find more info in pi-hole's FAQ:\nhttps://docs.pi-hole.net/main/faq/#error-while-loading-data-from-the-long-term-database" ); } @@ -296,7 +297,7 @@ $(function () { } $(row).addClass(blocked === true ? "blocked-row" : "allowed-row"); - if (localStorage.getItem("colorfulQueryLog_chkbox") === "true") { + if (localStorage && localStorage.getItem("colorfulQueryLog_chkbox") === "true") { $(row).addClass(blocked === true ? "text-red" : "text-green"); } diff --git a/scripts/pi-hole/js/footer.js b/scripts/pi-hole/js/footer.js index 763e8ae9..5e386622 100644 --- a/scripts/pi-hole/js/footer.js +++ b/scripts/pi-hole/js/footer.js @@ -58,7 +58,9 @@ function countDown() { } else { ena.text("Enable"); piholeChanged("enabled"); - localStorage.removeItem("countDownTarget"); + if (localStorage) { + localStorage.removeItem("countDownTarget"); + } } } @@ -148,7 +150,7 @@ function initCheckboxRadioStyle() { } // Read from local storage, initialize if needed - var chkboxStyle = localStorage.getItem("theme_icheck"); + var chkboxStyle = localStorage ? localStorage.getItem("theme_icheck") : null; if (chkboxStyle === null) { chkboxStyle = "primary"; } @@ -172,7 +174,10 @@ function initCheckboxRadioStyle() { function initCPUtemp() { function setCPUtemp(unit) { - localStorage.setItem("tempunit", tempunit); + if (localStorage) { + localStorage.setItem("tempunit", tempunit); + } + var temperature = parseFloat($("#rawtemp").text()); var displaytemp = $("#tempdisplay"); if (!isNaN(temperature)) { @@ -195,7 +200,7 @@ function initCPUtemp() { } // Read from local storage, initialize if needed - var tempunit = localStorage.getItem("tempunit"); + var tempunit = localStorage ? localStorage.getItem("tempunit") : null; if (tempunit === null) { tempunit = "C"; } diff --git a/scripts/pi-hole/js/groups-adlists.js b/scripts/pi-hole/js/groups-adlists.js index 501ec2f2..1ff87a0d 100644 --- a/scripts/pi-hole/js/groups-adlists.js +++ b/scripts/pi-hole/js/groups-adlists.js @@ -122,7 +122,7 @@ function initTable() { { data: "enabled", searchable: false }, { data: "comment" }, { data: "groups", searchable: false }, - { data: null, width: "80px", orderable: false }, + { data: null, width: "22px", orderable: false }, ], columnDefs: [ { @@ -291,7 +291,8 @@ function initTable() { $("td:eq(5)", row).html(button); }, dom: - "<'row'<'col-sm-4'l><'col-sm-8'f>>" + + "<'row'<'col-sm-12'f>>" + + "<'row'<'col-sm-4'l><'col-sm-8'p>>" + "<'row'<'col-sm-12'<'table-responsive'tr>>>" + "<'row'<'col-sm-5'i><'col-sm-7'p>>", lengthMenu: [ diff --git a/scripts/pi-hole/js/groups-clients.js b/scripts/pi-hole/js/groups-clients.js index 171a939c..a2907426 100644 --- a/scripts/pi-hole/js/groups-clients.js +++ b/scripts/pi-hole/js/groups-clients.js @@ -95,7 +95,7 @@ function initTable() { { data: "ip", type: "ip-address" }, { data: "comment" }, { data: "groups", searchable: false }, - { data: "name", width: "80px", orderable: false }, + { data: "name", width: "22px", orderable: false }, ], columnDefs: [ { @@ -215,7 +215,8 @@ function initTable() { $("td:eq(3)", row).html(button); }, dom: - "<'row'<'col-sm-4'l><'col-sm-8'f>>" + + "<'row'<'col-sm-12'f>>" + + "<'row'<'col-sm-4'l><'col-sm-8'p>>" + "<'row'<'col-sm-12'<'table-responsive'tr>>>" + "<'row'<'col-sm-5'i><'col-sm-7'p>>", lengthMenu: [ diff --git a/scripts/pi-hole/js/groups-domains.js b/scripts/pi-hole/js/groups-domains.js index e70286d5..2faa9a83 100644 --- a/scripts/pi-hole/js/groups-domains.js +++ b/scripts/pi-hole/js/groups-domains.js @@ -74,7 +74,7 @@ function initTable() { { data: "enabled", searchable: false }, { data: "comment" }, { data: "groups", searchable: false, visible: showtype === "all" }, - { data: null, width: "80px", orderable: false }, + { data: null, width: "22px", orderable: false }, ], columnDefs: [ { @@ -244,7 +244,8 @@ function initTable() { } }, dom: - "<'row'<'col-sm-4'l><'col-sm-8'f>>" + + "<'row'<'col-sm-12'f>>" + + "<'row'<'col-sm-4'l><'col-sm-8'p>>" + "<'row'<'col-sm-12'<'table-responsive'tr>>>" + "<'row'<'col-sm-5'i><'col-sm-7'p>>", lengthMenu: [ diff --git a/scripts/pi-hole/js/groups.js b/scripts/pi-hole/js/groups.js index 417dd9ff..8b7e3b63 100644 --- a/scripts/pi-hole/js/groups.js +++ b/scripts/pi-hole/js/groups.js @@ -25,7 +25,7 @@ $(function () { { data: "name" }, { data: "enabled", searchable: false }, { data: "description" }, - { data: null, width: "60px", orderable: false }, + { data: null, width: "22px", orderable: false }, ], columnDefs: [ { @@ -84,7 +84,8 @@ $(function () { } }, dom: - "<'row'<'col-sm-4'l><'col-sm-8'f>>" + + "<'row'<'col-sm-12'f>>" + + "<'row'<'col-sm-4'l><'col-sm-8'p>>" + "<'row'<'col-sm-12'<'table-responsive'tr>>>" + "<'row'<'col-sm-5'i><'col-sm-7'p>>", lengthMenu: [ diff --git a/scripts/pi-hole/js/index.js b/scripts/pi-hole/js/index.js index d0f5d968..d7cce8e2 100644 --- a/scripts/pi-hole/js/index.js +++ b/scripts/pi-hole/js/index.js @@ -319,24 +319,71 @@ function updateQueryTypesPie() { queryTypePieChart.update(); // Don't use rotation animation for further updates queryTypePieChart.options.animation.duration = 0; + queryTypePieChart.options.legendCallback = customLegend; + // Generate legend in separate div $("#query-types-legend").html(queryTypePieChart.generateLegend()); - $("#query-types-legend > ul > li").prepend(createEyeConElement()); $("#query-types-legend > ul > li").click(function (e) { - if (isEyeCon(e.target)) { + if (iscolorBox(e.target)) { return false; } window.location.href = "queries.php?querytype=" + querytypeids[$(this).index()]; }); + $("#query-types-legend .colorBoxWrapper").click(function (e) { + hidePieSlice(e); + }); }).done(function () { // Reload graph after minute setTimeout(updateQueryTypesPie, 60000); }); } +function customLegend(chart) { + var text = []; + var data = chart.data; + var datasets = data.datasets; + var labels = data.labels; + + text.push('
    '); + + if (datasets.length > 0) { + for (var i = 0; i < datasets[0].data.length; ++i) { + var color = datasets[0].backgroundColor[i]; + + var txt = ""; + + // legend box icon + txt = + '' + + '' + + ""; + + // color block + txt += ''; + + // label + if (labels[i]) { + txt += + '' + + labels[i] + + ""; + } + + text.push("
  • " + txt + "
  • "); + } + } + + text.push("
"); + return text.join(""); +} + function hidePieSlice(event) { - toggleEyeCon(event.target); + togglecolorBox(event.target); var legendID = $(event.target).closest(".chart-legend").attr("id"); var ci = @@ -360,19 +407,19 @@ function hidePieSlice(event) { ci.update(); } -function toggleEyeCon(target) { +function togglecolorBox(target) { var parentListItem = $(target).closest("li"); - var eyeCon = $(parentListItem).find(".fa-eye, .fa-eye-slash"); + var colorBox = $(parentListItem).find(".fa-check-square, .fa-square"); - if (eyeCon) { - $(eyeCon).toggleClass("fa-eye"); - $(eyeCon).toggleClass("fa-eye-slash"); + if (colorBox) { + $(colorBox).toggleClass("fa-check-square"); + $(colorBox).toggleClass("fa-square"); } } -function isEyeCon(target) { - // See if click happened on eyeConWrapper or child SVG - if ($(target).closest(".eyeConWrapper")[0]) { +function iscolorBox(target) { + // See if click happened on colorBoxWrapper or child SVG + if ($(target).closest(".colorBoxWrapper")[0]) { return true; } @@ -468,16 +515,6 @@ function updateClientsOverTime() { }); } -function createEyeConElement() { - var eyeConWrapper = $("") - .addClass("eyeConWrapper") - .click(function (e) { - hidePieSlice(e); - }); - eyeConWrapper.append($("")); - return eyeConWrapper; -} - function updateForwardDestinationsPie() { $.getJSON("api.php?getForwardDestinations", function (data) { if ("FTLnotrunning" in data) { @@ -519,11 +556,12 @@ function updateForwardDestinationsPie() { forwardDestinationPieChart.update(); // Don't use rotation animation for further updates forwardDestinationPieChart.options.animation.duration = 0; + forwardDestinationPieChart.options.legendCallback = customLegend; + // Generate legend in separate div $("#forward-destinations-legend").html(forwardDestinationPieChart.generateLegend()); - $("#forward-destinations-legend > ul > li").prepend(createEyeConElement()); $("#forward-destinations-legend > ul > li").click(function (e) { - if (isEyeCon(e.target)) { + if (iscolorBox(e.target)) { return false; } @@ -532,6 +570,9 @@ function updateForwardDestinationsPie() { window.location.href = "queries.php?forwarddest=" + obj; } }); + $("#forward-destinations-legend .colorBoxWrapper").click(function (e) { + hidePieSlice(e); + }); }).done(function () { // Reload graph after one minute setTimeout(updateForwardDestinationsPie, 60000); @@ -723,7 +764,7 @@ function updateSummaryData(runOnce) { } }; - $.getJSON("api.php?summary", function (data) { + $.getJSON("api.php?summaryRaw", function (data) { updateSessionTimer(); if ("FTLnotrunning" in data) { @@ -795,7 +836,7 @@ function updateSummaryData(runOnce) { function doughnutTooltip(tooltipItems, data) { var dataset = data.datasets[tooltipItems.datasetIndex]; - var label = data.labels[tooltipItems.index]; + var label = " " + data.labels[tooltipItems.index]; // Compute share of total and of displayed var scale = 0, total = 0; @@ -813,16 +854,28 @@ function doughnutTooltip(tooltipItems, data) { return label + ": " + dataset.data[tooltipItems.index].toFixed(1) + "%"; return ( label + - ":
- " + + ":
• " + dataset.data[tooltipItems.index].toFixed(1) + - "% of all queries
- " + + "% of all queries
• " + ((dataset.data[tooltipItems.index] * 100) / (total - scale)).toFixed(1) + "% of shown items" ); } +var maxlogage = "24"; +function getMaxlogage() { + $.getJSON("api.php?getMaxlogage", function (data) { + if (!("FTLnotrunning" in data)) { + maxlogage = data.maxlogage; + } + }).done(function () { + $(".maxlogage-interval").html(maxlogage); + }); +} + $(function () { // Pull in data via AJAX + getMaxlogage(); updateSummaryData(); var gridColor = $(".graphs-grid").css("background-color"); diff --git a/scripts/pi-hole/js/messages.js b/scripts/pi-hole/js/messages.js index 8575b83f..f95777f6 100644 --- a/scripts/pi-hole/js/messages.js +++ b/scripts/pi-hole/js/messages.js @@ -174,7 +174,8 @@ $(function () { $("td:eq(3)", row).html(button); }, dom: - "<'row'<'col-sm-4'l><'col-sm-8'f>>" + + "<'row'<'col-sm-12'f>>" + + "<'row'<'col-sm-4'l><'col-sm-8'p>>" + "<'row'<'col-sm-12'<'table-responsive'tr>>>" + "<'row'<'col-sm-5'i><'col-sm-7'p>>", lengthMenu: [ diff --git a/scripts/pi-hole/js/queries.js b/scripts/pi-hole/js/queries.js index 7507e46d..091a6f98 100644 --- a/scripts/pi-hole/js/queries.js +++ b/scripts/pi-hole/js/queries.js @@ -231,7 +231,7 @@ $(function () { fieldtext += ''; $(row).addClass(blocked === true ? "blocked-row" : "allowed-row"); - if (localStorage.getItem("colorfulQueryLog_chkbox") === "true") { + if (localStorage && localStorage.getItem("colorfulQueryLog_chkbox") === "true") { $(row).addClass(blocked === true ? "text-red" : "text-green"); } diff --git a/scripts/pi-hole/js/settings.js b/scripts/pi-hole/js/settings.js index 3663822f..274d6adc 100644 --- a/scripts/pi-hole/js/settings.js +++ b/scripts/pi-hole/js/settings.js @@ -213,9 +213,15 @@ function loadCacheInfo() { var cachelivefreed = parseInt(data.cacheinfo["cache-live-freed"], 10); $("#cache-live-freed").text(cachelivefreed); if (cachelivefreed > 0) { - $("#cache-live-freed").parent("tr").addClass("lookatme"); + $("#cache-live-freed").parent("tr").children("th").children("span").addClass("lookatme"); + $("#cache-live-freed").parent("tr").children("td").addClass("lookatme"); + $("#cache-live-freed") + .parent("tr") + .children("td") + .attr("lookatme-text", cachelivefreed.toString()); } else { - $("#cache-live-freed").parent("tr").removeClass("lookatme"); + $("#cache-live-freed").parent("tr").children("th").children("span").removeClass("lookatme"); + $("#cache-live-freed").parent("tr").children("td").removeClass("lookatme"); } // Update cache info every 10 seconds @@ -228,7 +234,8 @@ $(function () { if (document.getElementById("DHCPLeasesTable")) { leasetable = $("#DHCPLeasesTable").DataTable({ dom: - "<'row'<'col-sm-4'l><'col-sm-8'f>>" + + "<'row'<'col-sm-12'f>>" + + "<'row'<'col-sm-4'l><'col-sm-8'p>>" + "<'row'<'col-sm-12'<'table-responsive'tr>>>" + "<'row'<'col-sm-5'i><'col-sm-7'p>>", lengthMenu: [ @@ -238,9 +245,23 @@ $(function () { columnDefs: [ { bSortable: false, orderable: false, targets: -1 }, { - targets: [0, 1, 2], + targets: [0, 1], render: $.fn.dataTable.render.text(), }, + { + targets: 2, + render: function (data) { + // Show "unknown", when host is "*" + var str; + if (data === "*") { + str = "unknown"; + } else { + str = typeof data === "string" ? utils.escapeHtml(data) : data; + } + + return str; + }, + }, ], paging: true, order: [[2, "asc"]], @@ -258,7 +279,8 @@ $(function () { if (document.getElementById("DHCPStaticLeasesTable")) { staticleasetable = $("#DHCPStaticLeasesTable").DataTable({ dom: - "<'row'<'col-sm-4'l><'col-sm-8'f>>" + + "<'row'<'col-sm-12'f>>" + + "<'row'<'col-sm-4'l><'col-sm-8'p>>" + "<'row'<'col-sm-12'<'table-responsive'tr>>>" + "<'row'<'col-sm-5'i><'col-sm-7'p>>", lengthMenu: [ @@ -342,7 +364,7 @@ $(".nav-tabs a").on("shown.bs.tab", function (e) { // Bar/Smooth chart toggle $(function () { var bargraphs = $("#bargraphs"); - var chkboxData = localStorage.getItem("barchart_chkbox"); + var chkboxData = localStorage ? localStorage.getItem("barchart_chkbox") : null; if (chkboxData !== null) { // Restore checkbox state @@ -350,7 +372,9 @@ $(function () { } else { // Initialize checkbox bargraphs.prop("checked", true); - localStorage.setItem("barchart_chkbox", true); + if (localStorage) { + localStorage.setItem("barchart_chkbox", true); + } } bargraphs.click(function () { @@ -360,7 +384,7 @@ $(function () { $(function () { var colorfulQueryLog = $("#colorfulQueryLog"); - var chkboxData = localStorage.getItem("colorfulQueryLog_chkbox"); + var chkboxData = localStorage ? localStorage.getItem("colorfulQueryLog_chkbox") : null; if (chkboxData !== null) { // Restore checkbox state @@ -368,7 +392,9 @@ $(function () { } else { // Initialize checkbox colorfulQueryLog.prop("checked", false); - localStorage.setItem("colorfulQueryLog_chkbox", false); + if (localStorage) { + localStorage.setItem("colorfulQueryLog_chkbox", false); + } } colorfulQueryLog.click(function () { diff --git a/scripts/pi-hole/js/utils.js b/scripts/pi-hole/js/utils.js index 7229231f..b9e1a573 100644 --- a/scripts/pi-hole/js/utils.js +++ b/scripts/pi-hole/js/utils.js @@ -229,13 +229,25 @@ function setBsSelectDefaults() { }; } +var backupStorage = {}; function stateSaveCallback(itemName, data) { - localStorage.setItem(itemName, JSON.stringify(data)); + if (localStorage === null) { + backupStorage[itemName] = JSON.stringify(data); + } else { + localStorage.setItem(itemName, JSON.stringify(data)); + } } function stateLoadCallback(itemName) { + var data; // Receive previous state from client's local storage area - var data = localStorage.getItem(itemName); + if (localStorage === null) { + var item = backupStorage[itemName]; + data = typeof item === "undefined" ? null : item; + } else { + data = localStorage.getItem(itemName); + } + // Return if not available if (data === null) { return null; @@ -259,7 +271,7 @@ function stateLoadCallback(itemName) { function getGraphType() { // Only return line if `barchart_chkbox` is explicitly set to false. Else return bar - return localStorage.getItem("barchart_chkbox") === "false" ? "line" : "bar"; + return localStorage && localStorage.getItem("barchart_chkbox") === "false" ? "line" : "bar"; } function addFromQueryLog(domain, list) { diff --git a/scripts/pi-hole/php/auth.php b/scripts/pi-hole/php/auth.php index 673bd480..fbf6b76c 100644 --- a/scripts/pi-hole/php/auth.php +++ b/scripts/pi-hole/php/auth.php @@ -73,7 +73,7 @@ function check_cors() { $server_host = str_replace(array("[","]"), array("",""), $server_host); if(isset($_SERVER['HTTP_HOST']) && !in_array($server_host, $AUTHORIZED_HOSTNAMES)) { - log_and_die("Failed Host Check: " . $server_host .' vs '. join(', ', $AUTHORIZED_HOSTNAMES)); + log_and_die("Failed Host Check: " . $server_host .' vs '. htmlspecialchars(join(', ', $AUTHORIZED_HOSTNAMES))); } if(isset($_SERVER['HTTP_ORIGIN'])) { @@ -88,7 +88,7 @@ function check_cors() { $server_origin = str_replace(array("[","]","http://","https://"), array("","","",""), $server_origin); if(!in_array($server_origin, $AUTHORIZED_HOSTNAMES)) { - log_and_die("Failed CORS: " . htmlspecialchars($server_origin) .' vs '. join(', ', $AUTHORIZED_HOSTNAMES)); + log_and_die("Failed CORS: " . htmlspecialchars($server_origin) .' vs '. htmlspecialchars(join(', ', $AUTHORIZED_HOSTNAMES))); } header("Access-Control-Allow-Origin: ${_SERVER['HTTP_ORIGIN']}"); } diff --git a/scripts/pi-hole/php/customcname.php b/scripts/pi-hole/php/customcname.php index 060799e2..a34a8915 100644 --- a/scripts/pi-hole/php/customcname.php +++ b/scripts/pi-hole/php/customcname.php @@ -5,11 +5,13 @@ require_once('auth.php'); // Authentication checks - if (isset($_POST['token'])) { - check_cors(); - check_csrf($_POST['token']); - } else { - log_and_die('Not allowed (login session invalid or expired, please relogin on the Pi-hole dashboard)!'); + if (!isset($api)) { + if (isset($_POST['token'])) { + check_cors(); + check_csrf($_POST['token']); + } else { + log_and_die('Not allowed (login session invalid or expired, please relogin on the Pi-hole dashboard)!'); + } } diff --git a/scripts/pi-hole/php/customdns.php b/scripts/pi-hole/php/customdns.php index 196ca281..bfa2fd80 100644 --- a/scripts/pi-hole/php/customdns.php +++ b/scripts/pi-hole/php/customdns.php @@ -5,11 +5,13 @@ require_once('auth.php'); // Authentication checks - if (isset($_POST['token'])) { - check_cors(); - check_csrf($_POST['token']); - } else { - log_and_die('Not allowed (login session invalid or expired, please relogin on the Pi-hole dashboard)!'); + if (!isset($api)) { + if (isset($_POST['token'])) { + check_cors(); + check_csrf($_POST['token']); + } else { + log_and_die('Not allowed (login session invalid or expired, please relogin on the Pi-hole dashboard)!'); + } } diff --git a/scripts/pi-hole/php/footer.php b/scripts/pi-hole/php/footer.php index 0d2d2485..24788a4d 100644 --- a/scripts/pi-hole/php/footer.php +++ b/scripts/pi-hole/php/footer.php @@ -49,14 +49,16 @@ $coreVersionStr = $core_current . (isset($core_commit) ? " (" . $core_branch . ", " . $core_commit . ")" : ""); $ftlVersionStr = $FTL_current . (isset($FTL_commit) ? " (" . $FTL_branch . ", " . $FTL_commit . ")" : ""); $webVersionStr = $web_current . (isset($web_commit) ? " (" . $web_branch . ", " . $web_commit . ")" : ""); - $dockerTag = getenv('PIHOLE_DOCKER_TAG'); + $dockerTag = htmlspecialchars(getenv('PIHOLE_DOCKER_TAG')); $githubBaseUrl = "https://github.com/pi-hole"; $coreUrl = $githubBaseUrl . "/pi-hole"; + $dockerUrl = $githubBaseUrl . "/docker-pi-hole"; $ftlUrl = $githubBaseUrl . "/FTL"; $webUrl = $githubBaseUrl . "/AdminLTE"; $coreReleasesUrl = $coreUrl . "/releases"; + $dockerReleasesUrl = $dockerUrl . "/releases"; $ftlReleasesUrl = $ftlUrl . "/releases"; $webReleasesUrl = $webUrl . "/releases"; ?> @@ -78,21 +80,26 @@ diff --git a/scripts/pi-hole/php/func.php b/scripts/pi-hole/php/func.php index 754277b5..10ad633b 100644 --- a/scripts/pi-hole/php/func.php +++ b/scripts/pi-hole/php/func.php @@ -483,4 +483,31 @@ function getQueryTypeStr($querytype) return "TYPE".($qtype - 100); } +// Returns an integer representing pihole blocking status +function piholeStatus() +{ + // Receive the return of "pihole status web" + $pistatus = pihole_execute('status web'); + return isset($pistatus[0]) ? intval($pistatus[0]) : -2; +} + +// Returns pihole status, using only valid API responses (enabled/disabled) +function piholeStatusAPI() +{ + // Receive the return of "pihole status web" + $pistatus = piholeStatus(); + + switch ($pistatus) { + case -2: // Unkown + case -1: // DNS service not running" + case 0: // Offline + $response = "disabled"; + break; + + default: + // DNS service running on port $returncode + $response = "enabled"; + } + return $response; +} ?> diff --git a/scripts/pi-hole/php/gravity.php b/scripts/pi-hole/php/gravity.php index 6daa603b..4852190c 100644 --- a/scripts/pi-hole/php/gravity.php +++ b/scripts/pi-hole/php/gravity.php @@ -47,15 +47,15 @@ function gravity_last_update($raw = false) if($gravitydiff->d > 1) { // String output (more than one day ago) - return $gravitydiff->format("Blocking list updated %a days, %H:%I (hh:mm) ago"); + return $gravitydiff->format("Adlists updated %a days, %H:%I (hh:mm) ago"); } elseif($gravitydiff->d == 1) { // String output (one day ago) - return $gravitydiff->format("Blocking list updated one day, %H:%I (hh:mm) ago"); + return $gravitydiff->format("Adlists updated one day, %H:%I (hh:mm) ago"); } // String output (less than one day ago) - return $gravitydiff->format("Blocking list updated %H:%I (hh:mm) ago"); + return $gravitydiff->format("Adlists updated %H:%I (hh:mm) ago"); } ?> diff --git a/scripts/pi-hole/php/header.php b/scripts/pi-hole/php/header.php index 175fd41f..d8ad253b 100644 --- a/scripts/pi-hole/php/header.php +++ b/scripts/pi-hole/php/header.php @@ -9,6 +9,7 @@ require "scripts/pi-hole/php/auth.php"; require "scripts/pi-hole/php/password.php"; require_once "scripts/pi-hole/php/FTL.php"; + require_once "scripts/pi-hole/php/func.php"; require "scripts/pi-hole/php/theme.php"; $scriptname = basename($_SERVER['SCRIPT_FILENAME']); $hostname = gethostname() ? gethostname() : ""; @@ -66,6 +67,8 @@ // Nothing can be colder than -273.15 degree Celsius (= 0 Kelvin) // This is the minimum temperature possible (AKA absolute zero) $celsius = -273.16; + // Set templimit to null if no tempsensor was found + $temperaturelimit = null; } // Get load @@ -331,19 +334,14 @@ if($auth) {

Status

Active'; } elseif ($pistatus == 0) { echo ' Offline'; } elseif ($pistatus == -1) { echo ' DNS service not running'; - } elseif ($pistatus == -2 || is_null($pistatus)) { + } elseif ($pistatus == -2) { echo ' Unknown'; } else { echo ' DNS service on port '.$pistatus.''; @@ -375,18 +373,16 @@ if($auth) { ?>
$temperaturelimit) { - $tempcolor = "text-red"; - } - echo ' '; - - if ($celsius >= -273.15) { + if ($celsius >= -273.15) { + // Only show temp info if any data is available --> + $tempcolor = "text-vivid-blue"; + if (isset($temperaturelimit) && $celsius > $temperaturelimit) { + $tempcolor = "text-red"; + } + echo ' '; echo 'Temp: '; - } else { - echo "No temp sensor found"; - } - echo ''; + echo ''; + } ?>
diff --git a/scripts/pi-hole/php/queryads.php b/scripts/pi-hole/php/queryads.php index 38d4e8d2..535dc146 100644 --- a/scripts/pi-hole/php/queryads.php +++ b/scripts/pi-hole/php/queryads.php @@ -17,7 +17,7 @@ header('Cache-Control: no-cache'); function echoEvent($datatext) { if(!isset($_GET["IE"])) - echo "data: ".implode("\ndata: ", explode("\n", $datatext))."\n\n"; + echo "data:".implode("\ndata:", explode("\n", $datatext))."\n\n"; else echo $datatext; } diff --git a/scripts/pi-hole/php/teleporter.php b/scripts/pi-hole/php/teleporter.php index d25f0509..774d10c7 100644 --- a/scripts/pi-hole/php/teleporter.php +++ b/scripts/pi-hole/php/teleporter.php @@ -84,11 +84,15 @@ function archive_restore_table($file, $table, $flush=false) if(is_null($contents)) return 0; - // Flush table if requested, only flush each table once + // Flush table if requested. Only flush each table once, and only if it exists if($flush && !in_array($table, $flushed_tables)) { - $db->exec("DELETE FROM \"".$table."\""); - array_push($flushed_tables, $table); + $tableExists = $db->querySingle("SELECT name FROM sqlite_master WHERE type='table' AND name='".$table."';"); + if ($tableExists) + { + $db->exec("DELETE FROM \"".$table."\""); + array_push($flushed_tables, $table); + } } // Prepare fields depending on the table we restore to @@ -337,18 +341,15 @@ if(isset($_POST["action"])) $source = $_FILES["zip_file"]["tmp_name"]; $type = mime_content_type($source); - $name = explode(".", $filename); + // verify the file mime type $accepted_types = array('application/gzip', 'application/tar', 'application/x-compressed', 'application/x-gzip'); - $okay = false; - foreach($accepted_types as $mime_type) { - if($mime_type == $type) { - $okay = true; - break; - } - } + $mime_valid = in_array($type, $accepted_types); - $continue = strtolower($name[1]) == 'tar' && strtolower($name[2]) == 'gz' ? true : false; - if(!$continue || !$okay) { + // verify the file extension (Looking for ".tar.gz" at the end of the file name) + $ext = array_slice(explode(".", $filename), -2, 2); + $ext_valid = strtolower($ext[0]) == "tar" && strtolower($ext[1]) == "gz" ? true : false; + + if(!$ext_valid || !$mime_valid) { die("The file you are trying to upload is not a .tar.gz file (filename: ".htmlentities($filename).", type: ".htmlentities($type)."). Please try again."); } diff --git a/settings.php b/settings.php index ec75d9e8..e59b1352 100644 --- a/settings.php +++ b/settings.php @@ -19,6 +19,12 @@ if(isset($last_error) && ($last_error["type"] === E_WARNING || $last_error["type $error .= "There was a problem applying your settings.
Debugging information:
PHP error (".htmlspecialchars($last_error["type"])."): ".htmlspecialchars($last_error["message"])." in ".htmlspecialchars($last_error["file"]).":".htmlspecialchars($last_error["line"]); } +# Timezone is set in docker via ENV otherwise get it from commandline +$timezone=htmlspecialchars(getenv("TZ")); +if (empty($timezone)) { + $timezone=shell_exec("date +'%Z'"); +} + ?>