diff --git a/.eslintrc.json b/.eslintrc.json index 9d40203bee..c1bf1cb51b 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,9 +1,9 @@ { "extends": ["eslint:recommended", "plugin:prettier/recommended", "plugin:jsdoc/recommended"], - "plugins": ["prettier", "jsdoc", "jest"], + "plugins": ["prettier", "import", "jsdoc", "jest"], "env": { "browser": true, - "es6": true, + "es2022": true, "jest/globals": true, "node": true }, @@ -16,16 +16,18 @@ }, "parserOptions": { "sourceType": "module", - "ecmaVersion": 2020, + "ecmaVersion": 2022, "ecmaFeatures": { "globalReturn": true } }, "rules": { - "prettier/prettier": "error", "eqeqeq": "error", + "import/order": "error", "no-prototype-builtins": "off", + "no-throw-literal": "error", "no-unused-vars": "off", - "no-useless-return": "error" + "no-useless-return": "error", + "prefer-template": "error" } } diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 0cd23540e3..ce7cccb418 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -6,7 +6,7 @@ We hold our code to standard, and these standards are documented below. ## Linters -If you wish to run our linters, use `npm run lint` without any arguments. +We use prettier for automatic linting of all our files: `npm run lint:prettier`. ### JavaScript: Run ESLint @@ -18,7 +18,7 @@ To run ESLint, use `npm run lint:js`. ### CSS: Run StyleLint -We use [StyleLint](https://stylelint.io) to lint our CSS. Our configuration is in our .stylelintrc file. +We use [StyleLint](https://stylelint.io) to lint our CSS. Our configuration is in our `.stylelintrc` file. To run StyleLint, use `npm run lint:css`. @@ -28,7 +28,8 @@ We use [Jest](https://jestjs.io) for JavaScript testing. To run all tests, use `npm run test`. -The specific test commands are defined in `package.json`. So you can also run the specific tests with other commands, e.g. `npm run test:unit` or `npx jest tests/e2e/env_spec.js`. +The specific test commands are defined in `package.json`. +So you can also run the specific tests with other commands, e.g. `npm run test:unit` or `npx jest tests/e2e/env_spec.js`. ## Submitting Issues diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE/custom.md similarity index 100% rename from .github/ISSUE_TEMPLATE.md rename to .github/ISSUE_TEMPLATE/custom.md diff --git a/.github/codecov.yaml b/.github/codecov.yaml index 3f76e9b50d..3c73437547 100644 --- a/.github/codecov.yaml +++ b/.github/codecov.yaml @@ -4,3 +4,7 @@ coverage: default: # advanced settings informational: true + patch: + default: + threshold: 0% + target: 0 diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index 5ace4600a1..38ae723d5e 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -4,3 +4,4 @@ updates: directory: "/" schedule: interval: "weekly" + target-branch: "develop" diff --git a/.github/workflows/automated-tests.yaml b/.github/workflows/automated-tests.yaml index 05ce5e455e..28957b000d 100644 --- a/.github/workflows/automated-tests.yaml +++ b/.github/workflows/automated-tests.yaml @@ -20,14 +20,14 @@ jobs: matrix: node-version: [14.x, 16.x, 18.x] steps: - - name: Checkout code + - name: "Checkout code" uses: actions/checkout@v3 - - name: Use Node.js ${{ matrix.node-version }} + - name: "Use Node.js ${{ matrix.node-version }}" uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} cache: "npm" - - name: Install dependencies and run tests + - name: "Install dependencies and run tests" run: | Xvfb :99 -screen 0 1024x768x16 & export DISPLAY=:99 diff --git a/.github/workflows/codecov-test-suites.yaml b/.github/workflows/codecov-test-suites.yaml index b46a4724c8..8cdcccbb7e 100644 --- a/.github/workflows/codecov-test-suites.yaml +++ b/.github/workflows/codecov-test-suites.yaml @@ -17,16 +17,16 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 30 steps: - - name: Checkout code + - name: "Checkout code" uses: actions/checkout@v3 - - name: Install dependencies and run coverage + - name: "Install dependencies and run coverage" run: | Xvfb :99 -screen 0 1024x768x16 & export DISPLAY=:99 npm ci touch css/custom.css npm run test:coverage - - name: Upload coverage results to codecov + - name: "Upload coverage results to codecov" uses: codecov/codecov-action@v3 with: files: ./coverage/lcov.info diff --git a/.github/workflows/depsreview.yaml b/.github/workflows/depsreview.yaml index 745f4c5eee..308f0017d0 100644 --- a/.github/workflows/depsreview.yaml +++ b/.github/workflows/depsreview.yaml @@ -1,4 +1,8 @@ -name: "Dependency Review" +# This workflow scans your pull requests for dependency changes, and will raise an error if any vulnerabilities or invalid licenses are being introduced. +# For more information see: https://github.com/actions/dependency-review-action + +name: "Review Dependencies" + on: [pull_request] permissions: @@ -8,7 +12,7 @@ jobs: dependency-review: runs-on: ubuntu-latest steps: - - name: "Checkout Repository" + - name: "Checkout code" uses: actions/checkout@v3 - name: "Dependency Review" - uses: actions/dependency-review-action@v2 + uses: actions/dependency-review-action@v3 diff --git a/.github/workflows/enforce-changelog.yaml b/.github/workflows/enforce-changelog.yaml deleted file mode 100644 index 9632ac2d29..0000000000 --- a/.github/workflows/enforce-changelog.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# This workflow enforces the update of a changelog file on every pull request -# For more information see: https://github.com/dangoslen/changelog-enforcer - -name: "Enforce Changelog" - -on: - pull_request: - types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled] - -jobs: - check: - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - name: Enforce changelog️ - uses: dangoslen/changelog-enforcer@v3 - with: - changeLogPath: "CHANGELOG.md" - skipLabels: "Skip Changelog" diff --git a/.github/workflows/enforce-pullrequest-rules.yaml b/.github/workflows/enforce-pullrequest-rules.yaml new file mode 100644 index 0000000000..22d9c212ea --- /dev/null +++ b/.github/workflows/enforce-pullrequest-rules.yaml @@ -0,0 +1,28 @@ +# This workflow enforces on every pull request: +# - the update of our CHANGELOG.md file, see: https://github.com/dangoslen/changelog-enforcer +# - that the PR is not based against master, taken from https://github.com/oppia/oppia-android/pull/2832/files + +name: "Enforce Pull-Request Rules" + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled] + +jobs: + check: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: "Enforce changelog" + uses: dangoslen/changelog-enforcer@v3 + with: + changeLogPath: "CHANGELOG.md" + skipLabels: "Skip Changelog" + - name: "Enforce develop branch" + if: ${{ github.base_ref == 'master' && !contains(github.event.pull_request.labels.*.name, 'mastermerge') }} + run: | + echo "This PR is based against the master branch and not a release or hotfix." + echo "Please don't do this. Switch the branch to 'develop'." + exit 1 + env: + BASE_BRANCH: ${{ github.base_ref }} diff --git a/.stylelintrc.json b/.stylelintrc.json index d450c732dc..18ff23e703 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -1,5 +1,5 @@ { - "extends": ["stylelint-prettier/recommended"], + "extends": ["stylelint-config-standard"], "plugins": ["stylelint-prettier"], "rules": { "prettier/prettier": true diff --git a/CHANGELOG.md b/CHANGELOG.md index 400b4f5052..8b565fab08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,64 @@ This project adheres to [Semantic Versioning](https://semver.org/). ❤️ **Donate:** Enjoying MagicMirror²? [Please consider a donation!](https://magicmirror.builders/donate) With your help we can continue to improve the MagicMirror². +## [2.23.0] - 2023-04-04 + +Thanks to: @angeldeejay, @buxxi, @CarJem, @dariom, @DaveChild, @dWoolridge, @grenagit, @Hirschberger, @KristjanESPERANTO, @MagMar94, @naveensrinivasan, @nfogal, @psieg, @rajniszp, @retroflex, @SkySails and @tomzt. + +Special thanks to @khassel, @rejas and @sdetweil for taking over most (if not all) of the work on this release as project collaborators. This version would not be there without their effort. Thank you guys! You are awesome! + +### Added + +- Added increments for hourly forecasts in weather module (#2996) +- Added tests for hourly weather forecast +- Added possibility to ignore MagicMirror repo in updatenotification module +- Added Pirate Weather as new weather provider (#3005) +- Added possibility to use your own templates in Alert module +- Added error message if `.js` file is missing in module folder to get a hint in the logs (#2403) +- Added possibility to use environment variables in `config.js` (#1756) +- Added option `pastDaysCount` to default calendar module to control of how many days past events should be displayed +- Added thai language to alert module +- Added option `sendNotifications` in clock module (#3056) + +### Removed + +- Removed darksky weather provider +- Removed unneeded (and unwanted) '.' after the year in calendar repeatingCountTitle (#2896) + +### Updated + +- Use develop as target branch for dependabot +- Update issue template, contributing doc and sample config +- The weather modules clearly separates precipitation amount and probability (risk of rain/snow) + - This requires all providers that only supports probability to change the config from `showPrecipitationAmount` to `showPrecipitationProbability`. +- Update tests for weather and calendar module +- Changed updatenotification module for MagicMirror repo only: Send only notifications for `master` if there is a tag on a newer commit +- Update dates in Calendar widgets every minute +- Cleanup jest coverage for patches +- Update `stylelint` dependencies, switch to `stylelint-config-standard` and handle `stylelint` issues, update `main.css` matching new rules +- Update Eslint config, add new rule and handle issue +- Convert lots of callbacks to async/await +- Revise require imports (#3071 and #3072) + +### Fixed + +- Fix wrong day labels in envcanada forecast (#2987) +- Fix for missing default class name prefix for customEvents in calendar +- Fix electron flashing white screen on startup (#1919) +- Fix weathergov provider hourly forecast (#3008) +- Fix message display with HTML code into alert module (#2828) +- Fix typo in french translation +- Yr wind direction is no longer inverted +- Fix async node_helper stopping electron start (#2487) +- The wind direction arrow now points in the direction the wind is flowing, not into the wind (#3019) +- Fix precipitation css styles and rounding value +- Fix wrong vertical alignment of calendar title column when wrapEvents is true (#3053) +- Fix empty news feed stopping the reload forever +- Fix e2e tests (failed after async changes) by running calendar and newsfeed tests last +- Lint: Use template literals instead of string concatenation +- Fix default alert module to render HTML for title and message +- Fix Open-Meteo wind speed units + ## [2.22.0] - 2023-01-01 Thanks to: @angeldeejay, @buxxi, @dariom, @dWoolridge, @KristjanESPERANTO, @MagMar94, @naveensrinivasan, @retroflex, @SkySails and @Tom. @@ -13,9 +71,9 @@ Special thanks to @khassel, @rejas and @sdetweil for taking over most (if not al ### Added +- Added new calendar options for colored entries and improved styling (#3033) - Added test for remoteFile option in compliments module - Added hourlyWeather functionality to Weather.gov weather provider -- Removed weatherEndpoint definition from weathergov.js (not used) - Added css class names "today" and "tomorrow" for default calendar - Added Collaboration.md - Added new github action for dependency review (#2862) @@ -23,10 +81,12 @@ Special thanks to @khassel, @rejas and @sdetweil for taking over most (if not al - Added Yr as a weather provider - Added config options "ignoreXOriginHeader" and "ignoreContentSecurityPolicy" - Added thai language +- Added workflow rule to make sure PRs are based against develop ### Removed - Removed usage of internal fetch function of node until it is more stable +- Removed weatherEndpoint definition from weathergov.js (not used) ### Updated @@ -40,7 +100,7 @@ Special thanks to @khassel, @rejas and @sdetweil for taking over most (if not al - Reworked how weatherproviders handle units (#2849) - Use unix() method for parsing times, fix suntimes on the way (#2950) - Refactor conversion functions into utils class (#2958) -- The `cors`-method in `server.js` now supports sending and recieving HTTP headers +- The `cors`-method in `server.js` now supports sending and receiving HTTP headers - Replace `…` by `…` - Cleanup compliments module - Updated dependencies including electron to v22 (#2903) diff --git a/Collaboration.md b/Collaboration.md index 6be3fecb2a..079a355419 100644 --- a/Collaboration.md +++ b/Collaboration.md @@ -5,8 +5,14 @@ This document describes how collaborators of this repository should work togethe - never merge your own PR's - never merge without someone having approved (approving and merging from same person is allowed) - wait for all approvals requested (or the author decides something different in the comments) +- never merge to `master`, except for releases (because of update notification) +- merges to master should be tagged with the "mastermerge" label so that the test runs through ## Issues - "real" Issues are closed if the problem is solved and the fix is released - unrelated Issues (e.g. related to a foreign module) are closed immediately with a comment to open an issue in the module repository or to discuss this further in the forum or discord + +## Releases + +- are done by @MichMich only diff --git a/config/config.js.sample b/config/config.js.sample index a3460d6faf..799153b60c 100644 --- a/config/config.js.sample +++ b/config/config.js.sample @@ -6,17 +6,21 @@ * For more information on how you can configure this file * see https://docs.magicmirror.builders/configuration/introduction.html * and https://docs.magicmirror.builders/modules/configuration.html + * + * You can use environment variables using a `config.js.template` file instead of `config.js` + * which will be converted to `config.js` while starting. For more information + * see https://docs.magicmirror.builders/configuration/introduction.html#enviromnent-variables */ let config = { - address: "localhost", // Address to listen on, can be: + address: "localhost", // Address to listen on, can be: // - "localhost", "127.0.0.1", "::1" to listen on loopback interface // - another specific IPv4/6 to listen on a specific interface // - "0.0.0.0", "::" to listen on any interface // Default, when address config is left out or empty, is "localhost" port: 8080, - basePath: "/", // The URL path where MagicMirror² is hosted. If you are using a Reverse proxy - // you must set the sub path here. basePath must end with a / - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], // Set [] to allow all IP addresses + basePath: "/", // The URL path where MagicMirror² is hosted. If you are using a Reverse proxy + // you must set the sub path here. basePath must end with a / + ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], // Set [] to allow all IP addresses // or add a specific IPv4 of 192.168.1.5 : // ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.1.5"], // or IPv4 range of 192.168.3.0 --> 192.168.3.15 use CIDR format : @@ -31,11 +35,6 @@ let config = { logLevel: ["INFO", "LOG", "WARN", "ERROR"], // Add "DEBUG" for even more logging timeFormat: 24, units: "metric", - // serverOnly: true/false/"local" , - // local for armv6l processors, default - // starts serveronly and then starts chrome browser - // false, default for all NON-armv6l devices - // true, force serveronly mode, because you want to.. no UI on this device modules: [ { diff --git a/css/main.css b/css/main.css index 9206abca45..0aa5c3418e 100644 --- a/css/main.css +++ b/css/main.css @@ -3,22 +3,18 @@ --color-text-dimmed: #666; --color-text-bright: #fff; --color-background: #000; - --font-primary: "Roboto Condensed"; --font-secondary: "Roboto"; - --font-size: 20px; --font-size-xsmall: 0.75rem; --font-size-small: 1rem; --font-size-medium: 1.5rem; --font-size-large: 3.25rem; --font-size-xlarge: 3.75rem; - --gap-body-top: 60px; --gap-body-right: 60px; --gap-body-bottom: 60px; --gap-body-left: 60px; - --gap-modules: 30px; } @@ -175,10 +171,7 @@ sup { .region.fullscreen { position: absolute; - top: calc(-1 * var(--gap-body-top)); - left: calc(-1 * var(--gap-body-left)); - right: calc(-1 * var(--gap-body-right)); - bottom: calc(-1 * var(--gap-body-bottom)); + inset: calc(-1 * var(--gap-body-top)) calc(-1 * var(--gap-body-right)) calc(-1 * var(--gap-body-bottom)) calc(-1 * var(--gap-body-left)); pointer-events: none; } diff --git a/jest.config.js b/jest.config.js index a36db006fc..8a2403c289 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,7 +2,7 @@ module.exports = async () => { return { verbose: true, testTimeout: 20000, - testSequencer: "/tests/configs/test_sequencer.js", + testSequencer: "/tests/utils/test_sequencer.js", projects: [ { displayName: "unit", @@ -25,7 +25,7 @@ module.exports = async () => { testPathIgnorePatterns: ["/tests/e2e/helpers/", "/tests/e2e/mocks"] } ], - collectCoverageFrom: ["./clientonly/**/*.js", "./js/**/*.js", "./modules/**/*.js", "./serveronly/**/*.js"], + collectCoverageFrom: ["./clientonly/**/*.js", "./js/**/*.js", "./modules/default/**/*.js", "./serveronly/**/*.js"], coverageReporters: ["lcov", "text"], coverageProvider: "v8" }; diff --git a/js/app.js b/js/app.js index ae2d76f4df..22127b666b 100644 --- a/js/app.js +++ b/js/app.js @@ -10,6 +10,7 @@ require("module-alias/register"); const fs = require("fs"); const path = require("path"); +const envsub = require("envsub"); const Log = require("logger"); const Server = require(`${__dirname}/server`); const Utils = require(`${__dirname}/utils`); @@ -17,7 +18,7 @@ const defaultModules = require(`${__dirname}/../modules/default/defaultmodules`) // Get version number. global.version = require(`${__dirname}/../package.json`).version; -Log.log("Starting MagicMirror: v" + global.version); +Log.log(`Starting MagicMirror: v${global.version}`); // global absolute root path global.root_path = path.resolve(`${__dirname}/../`); @@ -51,25 +52,73 @@ function App() { let httpServer; /** - * Loads the config file. Combines it with the defaults, and runs the - * callback with the found config as argument. + * Loads the config file. Combines it with the defaults and returns the config * - * @param {Function} callback Function to be called after loading the config + * @async + * @returns {Promise} the loaded config or the defaults if something goes wrong */ - function loadConfig(callback) { + async function loadConfig() { Log.log("Loading config ..."); const defaults = require(`${__dirname}/defaults`); // For this check proposed to TestSuite // https://forum.magicmirror.builders/topic/1456/test-suite-for-magicmirror/8 const configFilename = path.resolve(global.configuration_file || `${global.root_path}/config/config.js`); + let templateFile = `${configFilename}.template`; + + // check if templateFile exists + try { + fs.accessSync(templateFile, fs.F_OK); + } catch (err) { + templateFile = null; + Log.debug("config template file not exists, no envsubst"); + } + + if (templateFile) { + // save current config.js + try { + if (fs.existsSync(configFilename)) { + fs.copyFileSync(configFilename, `${configFilename}_${Date.now()}`); + } + } catch (err) { + Log.warn(`Could not copy ${configFilename}: ${err.message}`); + } + + // check if config.env exists + const envFiles = []; + const configEnvFile = `${configFilename.substr(0, configFilename.lastIndexOf("."))}.env`; + try { + if (fs.existsSync(configEnvFile)) { + envFiles.push(configEnvFile); + } + } catch (err) { + Log.debug(`${configEnvFile} does not exist. ${err.message}`); + } + + let options = { + all: true, + diff: false, + envFiles: envFiles, + protect: false, + syntax: "default", + system: true + }; + + // envsubst variables in templateFile and create new config.js + // naming for envsub must be templateFile and outputFile + const outputFile = configFilename; + try { + await envsub({ templateFile, outputFile, options }); + } catch (err) { + Log.error(`Could not envsubst variables: ${err.message}`); + } + } try { fs.accessSync(configFilename, fs.F_OK); const c = require(configFilename); checkDeprecatedOptions(c); - const config = Object.assign(defaults, c); - callback(config); + return Object.assign(defaults, c); } catch (e) { if (e.code === "ENOENT") { Log.error(Utils.colors.error("WARNING! Could not find config file. Please create one. Starting with default configuration.")); @@ -78,8 +127,9 @@ function App() { } else { Log.error(Utils.colors.error(`WARNING! Could not load config file. Starting with default configuration. Error found: ${e}`)); } - callback(defaults); } + + return defaults; } /** @@ -102,9 +152,8 @@ function App() { * Loads a specific module. * * @param {string} module The name of the module (including subpath). - * @param {Function} callback Function to be called after loading */ - function loadModule(module, callback) { + function loadModule(module) { const elements = module.split("/"); const moduleName = elements[elements.length - 1]; let moduleFolder = `${__dirname}/../modules/${module}`; @@ -113,6 +162,14 @@ function App() { moduleFolder = `${__dirname}/../modules/default/${module}`; } + const moduleFile = `${moduleFolder}/${module}.js`; + + try { + fs.accessSync(moduleFile, fs.R_OK); + } catch (e) { + Log.warn(`No ${moduleFile} found for module: ${moduleName}.`); + } + const helperPath = `${moduleFolder}/node_helper.js`; let loadHelper = true; @@ -141,39 +198,37 @@ function App() { m.setPath(path.resolve(moduleFolder)); nodeHelpers.push(m); - m.loaded(callback); - } else { - callback(); + m.loaded(); } } /** * Loads all modules. * - * @param {Module[]} modules All modules to be loaded - * @param {Function} callback Function to be called after loading + * @param {string[]} modules All modules to be loaded */ - function loadModules(modules, callback) { - Log.log("Loading module helpers ..."); - - /** - * - */ - function loadNextModule() { - if (modules.length > 0) { - const nextModule = modules[0]; - loadModule(nextModule, function () { + async function loadModules(modules) { + return new Promise((resolve) => { + Log.log("Loading module helpers ..."); + + /** + * + */ + function loadNextModule() { + if (modules.length > 0) { + const nextModule = modules[0]; + loadModule(nextModule); modules = modules.slice(1); loadNextModule(); - }); - } else { - // All modules are loaded - Log.log("All module helpers loaded."); - callback(); + } else { + // All modules are loaded + Log.log("All module helpers loaded."); + resolve(); + } } - } - loadNextModule(); + loadNextModule(); + }); } /** @@ -203,58 +258,53 @@ function App() { /** * Start the core app. * - * It loads the config, then it loads all modules. When it's done it - * executes the callback with the config as argument. + * It loads the config, then it loads all modules. * - * @param {Function} callback Function to be called after start + * @async + * @returns {Promise} the config used */ - this.start = function (callback) { - loadConfig(function (c) { - config = c; - - Log.setLogLevel(config.logLevel); + this.start = async function () { + config = await loadConfig(); - let modules = []; + Log.setLogLevel(config.logLevel); - for (const module of config.modules) { - if (!modules.includes(module.module) && !module.disabled) { - modules.push(module.module); - } + let modules = []; + for (const module of config.modules) { + if (!modules.includes(module.module) && !module.disabled) { + modules.push(module.module); + } + } + await loadModules(modules); + + httpServer = new Server(config); + const { app, io } = await httpServer.open(); + Log.log("Server started ..."); + + const nodePromises = []; + for (let nodeHelper of nodeHelpers) { + nodeHelper.setExpressApp(app); + nodeHelper.setSocketIO(io); + + try { + nodePromises.push(nodeHelper.start()); + } catch (error) { + Log.error(`Error when starting node_helper for module ${nodeHelper.name}:`); + Log.error(error); } + } - loadModules(modules, async function () { - httpServer = new Server(config); - const { app, io } = await httpServer.open(); - Log.log("Server started ..."); - - const nodePromises = []; - for (let nodeHelper of nodeHelpers) { - nodeHelper.setExpressApp(app); - nodeHelper.setSocketIO(io); - - try { - nodePromises.push(nodeHelper.start()); - } catch (error) { - Log.error(`Error when starting node_helper for module ${nodeHelper.name}:`); - Log.error(error); - } - } + const results = await Promise.allSettled(nodePromises); - Promise.allSettled(nodePromises).then((results) => { - // Log errors that happened during async node_helper startup - results.forEach((result) => { - if (result.status === "rejected") { - Log.error(result.reason); - } - }); - - Log.log("Sockets connected & modules started ..."); - if (typeof callback === "function") { - callback(config); - } - }); - }); + // Log errors that happened during async node_helper startup + results.forEach((result) => { + if (result.status === "rejected") { + Log.error(result.reason); + } }); + + Log.log("Sockets connected & modules started ..."); + + return config; }; /** @@ -263,15 +313,40 @@ function App() { * * Added to fix #1056 * - * @param {Function} callback Function to be called after the app has stopped + * @returns {Promise} A promise that is resolved when all node_helpers and + * the http server has been closed */ - this.stop = function (callback) { - for (const nodeHelper of nodeHelpers) { - if (typeof nodeHelper.stop === "function") { - nodeHelper.stop(); + this.stop = async function () { + const nodePromises = []; + for (let nodeHelper of nodeHelpers) { + try { + if (typeof nodeHelper.stop === "function") { + nodePromises.push(nodeHelper.stop()); + } + } catch (error) { + Log.error(`Error when stopping node_helper for module ${nodeHelper.name}:`); + console.error(error); + } + } + + const results = await Promise.allSettled(nodePromises); + + // Log errors that happened during async node_helper stopping + results.forEach((result) => { + if (result.status === "rejected") { + Log.error(result.reason); } + }); + + Log.log("Node_helpers stopped ..."); + + // To be able to stop the app even if it hasn't been started (when + // running with Electron against another server) + if (!httpServer) { + return Promise.resolve(); } - httpServer.close().then(callback); + + return httpServer.close(); }; /** @@ -281,12 +356,12 @@ function App() { * Note: this is only used if running `server-only`. Otherwise * this.stop() is called by app.on("before-quit"... in `electron.js` */ - process.on("SIGINT", () => { + process.on("SIGINT", async () => { Log.log("[SIGINT] Received. Shutting down server..."); setTimeout(() => { process.exit(0); }, 3000); // Force quit after 3 seconds - this.stop(); + await this.stop(); process.exit(0); }); @@ -294,12 +369,12 @@ function App() { * Listen to SIGTERM signals so we can stop everything when we * are asked to stop by the OS. */ - process.on("SIGTERM", () => { + process.on("SIGTERM", async () => { Log.log("[SIGTERM] Received. Shutting down server..."); setTimeout(() => { process.exit(0); }, 3000); // Force quit after 3 seconds - this.stop(); + await this.stop(); process.exit(0); }); } diff --git a/js/check_config.js b/js/check_config.js index abc0940b09..24368734e8 100644 --- a/js/check_config.js +++ b/js/check_config.js @@ -5,11 +5,11 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -const Linter = require("eslint").Linter; -const linter = new Linter(); - const path = require("path"); const fs = require("fs"); +const { Linter } = require("eslint"); + +const linter = new Linter(); const rootPath = path.resolve(`${__dirname}/../`); const Log = require(`${rootPath}/js/logger.js`); diff --git a/js/electron.js b/js/electron.js index ac58657c30..8a474bb32e 100644 --- a/js/electron.js +++ b/js/electron.js @@ -1,8 +1,8 @@ "use strict"; const electron = require("electron"); -const core = require("./app.js"); -const Log = require("logger"); +const core = require("./app"); +const Log = require("./logger"); // Config let config = process.env.config ? JSON.parse(process.env.config) : {}; @@ -46,8 +46,10 @@ function createWindow() { if (config.kioskmode) { electronOptionsDefaults.kiosk = true; } else { - electronOptionsDefaults.fullscreen = true; - electronOptionsDefaults.autoHideMenuBar = true; + electronOptionsDefaults.show = false; + electronOptionsDefaults.frame = false; + electronOptionsDefaults.transparent = true; + electronOptionsDefaults.hasShadow = false; } const electronOptions = Object.assign({}, electronOptionsDefaults, config.electronOptions); @@ -117,6 +119,11 @@ function createWindow() { callback({ responseHeaders: curHeaders }); }); + + mainWindow.once("ready-to-show", () => { + mainWindow.setFullScreen(true); + mainWindow.show(); + }); } // This method will be called when Electron has finished @@ -150,18 +157,19 @@ app.on("activate", function () { * Note: this is only used if running Electron. Otherwise * core.stop() is called by process.on("SIGINT"... in `app.js` */ -app.on("before-quit", (event) => { +app.on("before-quit", async (event) => { Log.log("Shutting down server..."); event.preventDefault(); setTimeout(() => { process.exit(0); }, 3000); // Force-quit after 3 seconds. - core.stop(); + await core.stop(); process.exit(0); }); -/* handle errors from self signed certificates */ - +/** + * Handle errors from self-signed certificates + */ app.on("certificate-error", (event, webContents, url, error, certificate, callback) => { event.preventDefault(); callback(true); @@ -170,7 +178,5 @@ app.on("certificate-error", (event, webContents, url, error, certificate, callba // Start the core application if server is run on localhost // This starts all node helpers and starts the webserver. if (["localhost", "127.0.0.1", "::1", "::ffff:127.0.0.1", undefined].includes(config.address)) { - core.start(function (c) { - config = c; - }); + core.start().then((c) => (config = c)); } diff --git a/js/loader.js b/js/loader.js index 70ed32c5fe..930d57c86b 100644 --- a/js/loader.js +++ b/js/loader.js @@ -16,40 +16,27 @@ const Loader = (function () { /* Private Methods */ /** - * Loops thru all modules and requests load for every module. + * Loops through all modules and requests start for every module. */ - const loadModules = function () { - let moduleData = getModuleData(); - - const loadNextModule = function () { - if (moduleData.length > 0) { - const nextModule = moduleData[0]; - loadModule(nextModule, function () { - moduleData = moduleData.slice(1); - loadNextModule(); - }); - } else { - // All modules loaded. Load custom.css - // This is done after all the modules so we can - // overwrite all the defined styles. - - loadFile(config.customCss, function () { - // custom.css loaded. Start all modules. - startModules(); - }); + const startModules = async function () { + const modulePromises = []; + for (const module of moduleObjects) { + try { + modulePromises.push(module.start()); + } catch (error) { + Log.error(`Error when starting node_helper for module ${module.name}:`); + Log.error(error); } - }; + } - loadNextModule(); - }; + const results = await Promise.allSettled(modulePromises); - /** - * Loops thru all modules and requests start for every module. - */ - const startModules = function () { - for (const module of moduleObjects) { - module.start(); - } + // Log errors that happened during async node_helper startup + results.forEach((result) => { + if (result.status === "rejected") { + Log.error(result.reason); + } + }); // Notify core of loaded modules. MM.modulesStarted(moduleObjects); @@ -57,7 +44,7 @@ const Loader = (function () { // Starting modules also hides any modules that have requested to be initially hidden for (const thisModule of moduleObjects) { if (thisModule.data.hiddenOnStartup) { - Log.info("Initially hiding " + thisModule.name); + Log.info(`Initially hiding ${thisModule.name}`); thisModule.hide(); } } @@ -86,10 +73,10 @@ const Loader = (function () { const elements = module.split("/"); const moduleName = elements[elements.length - 1]; - let moduleFolder = config.paths.modules + "/" + module; + let moduleFolder = `${config.paths.modules}/${module}`; if (defaultModules.indexOf(moduleName) !== -1) { - moduleFolder = config.paths.modules + "/default/" + module; + moduleFolder = `${config.paths.modules}/default/${module}`; } if (moduleData.disabled === true) { @@ -98,16 +85,16 @@ const Loader = (function () { moduleFiles.push({ index: index, - identifier: "module_" + index + "_" + module, + identifier: `module_${index}_${module}`, name: moduleName, - path: moduleFolder + "/", - file: moduleName + ".js", + path: `${moduleFolder}/`, + file: `${moduleName}.js`, position: moduleData.position, hiddenOnStartup: moduleData.hiddenOnStartup, header: moduleData.header, configDeepMerge: typeof moduleData.configDeepMerge === "boolean" ? moduleData.configDeepMerge : false, config: moduleData.config, - classes: typeof moduleData.classes !== "undefined" ? moduleData.classes + " " + module : module + classes: typeof moduleData.classes !== "undefined" ? `${moduleData.classes} ${module}` : module }); }); @@ -115,32 +102,30 @@ const Loader = (function () { }; /** - * Load modules via ajax request and create module objects.s + * Load modules via ajax request and create module objects. * * @param {object} module Information about the module we want to load. - * @param {Function} callback Function called when done. + * @returns {Promise} resolved when module is loaded */ - const loadModule = function (module, callback) { + const loadModule = async function (module) { const url = module.path + module.file; - const afterLoad = function () { + /** + * @returns {Promise} + */ + const afterLoad = async function () { const moduleObject = Module.create(module.name); if (moduleObject) { - bootstrapModule(module, moduleObject, function () { - callback(); - }); - } else { - callback(); + await bootstrapModule(module, moduleObject); } }; if (loadedModuleFiles.indexOf(url) !== -1) { - afterLoad(); + await afterLoad(); } else { - loadFile(url, function () { - loadedModuleFiles.push(url); - afterLoad(); - }); + await loadFile(url); + loadedModuleFiles.push(url); + await afterLoad(); } }; @@ -149,76 +134,66 @@ const Loader = (function () { * * @param {object} module Information about the module we want to load. * @param {Module} mObj Modules instance. - * @param {Function} callback Function called when done. */ - const bootstrapModule = function (module, mObj, callback) { - Log.info("Bootstrapping module: " + module.name); - + const bootstrapModule = async function (module, mObj) { + Log.info(`Bootstrapping module: ${module.name}`); mObj.setData(module); - mObj.loadScripts(function () { - Log.log("Scripts loaded for: " + module.name); - mObj.loadStyles(function () { - Log.log("Styles loaded for: " + module.name); - mObj.loadTranslations(function () { - Log.log("Translations loaded for: " + module.name); - moduleObjects.push(mObj); - callback(); - }); - }); - }); + await mObj.loadScripts(); + Log.log(`Scripts loaded for: ${module.name}`); + + await mObj.loadStyles(); + Log.log(`Styles loaded for: ${module.name}`); + + await mObj.loadTranslations(); + Log.log(`Translations loaded for: ${module.name}`); + + moduleObjects.push(mObj); }; /** * Load a script or stylesheet by adding it to the dom. * * @param {string} fileName Path of the file we want to load. - * @param {Function} callback Function called when done. + * @returns {Promise} resolved when the file is loaded */ - const loadFile = function (fileName, callback) { + const loadFile = async function (fileName) { const extension = fileName.slice((Math.max(0, fileName.lastIndexOf(".")) || Infinity) + 1); let script, stylesheet; switch (extension.toLowerCase()) { case "js": - Log.log("Load script: " + fileName); - script = document.createElement("script"); - script.type = "text/javascript"; - script.src = fileName; - script.onload = function () { - if (typeof callback === "function") { - callback(); - } - }; - script.onerror = function () { - Log.error("Error on loading script:", fileName); - if (typeof callback === "function") { - callback(); - } - }; - - document.getElementsByTagName("body")[0].appendChild(script); - break; + return new Promise((resolve) => { + Log.log(`Load script: ${fileName}`); + script = document.createElement("script"); + script.type = "text/javascript"; + script.src = fileName; + script.onload = function () { + resolve(); + }; + script.onerror = function () { + Log.error("Error on loading script:", fileName); + resolve(); + }; + document.getElementsByTagName("body")[0].appendChild(script); + }); case "css": - Log.log("Load stylesheet: " + fileName); - stylesheet = document.createElement("link"); - stylesheet.rel = "stylesheet"; - stylesheet.type = "text/css"; - stylesheet.href = fileName; - stylesheet.onload = function () { - if (typeof callback === "function") { - callback(); - } - }; - stylesheet.onerror = function () { - Log.error("Error on loading stylesheet:", fileName); - if (typeof callback === "function") { - callback(); - } - }; - - document.getElementsByTagName("head")[0].appendChild(stylesheet); - break; + return new Promise((resolve) => { + Log.log(`Load stylesheet: ${fileName}`); + + stylesheet = document.createElement("link"); + stylesheet.rel = "stylesheet"; + stylesheet.type = "text/css"; + stylesheet.href = fileName; + stylesheet.onload = function () { + resolve(); + }; + stylesheet.onerror = function () { + Log.error("Error on loading stylesheet:", fileName); + resolve(); + }; + document.getElementsByTagName("head")[0].appendChild(stylesheet); + }); } }; @@ -227,8 +202,28 @@ const Loader = (function () { /** * Load all modules as defined in the config. */ - loadModules: function () { - loadModules(); + loadModules: async function () { + let moduleData = getModuleData(); + + /** + * @returns {Promise} when all modules are loaded + */ + const loadNextModule = async function () { + if (moduleData.length > 0) { + const nextModule = moduleData[0]; + await loadModule(nextModule); + moduleData = moduleData.slice(1); + await loadNextModule(); + } else { + // All modules loaded. Load custom.css + // This is done after all the modules so we can + // overwrite all the defined styles. + await loadFile(config.customCss); + // custom.css loaded. Start all modules. + await startModules(); + } + }; + await loadNextModule(); }, /** @@ -237,12 +232,11 @@ const Loader = (function () { * * @param {string} fileName Path of the file we want to load. * @param {Module} module The module that calls the loadFile function. - * @param {Function} callback Function called when done. + * @returns {Promise} resolved when the file is loaded */ - loadFile: function (fileName, module, callback) { + loadFileForModule: async function (fileName, module) { if (loadedFiles.indexOf(fileName.toLowerCase()) !== -1) { - Log.log("File already loaded: " + fileName); - callback(); + Log.log(`File already loaded: ${fileName}`); return; } @@ -250,22 +244,20 @@ const Loader = (function () { // This is an absolute or relative path. // Load it and then return. loadedFiles.push(fileName.toLowerCase()); - loadFile(fileName, callback); - return; + return loadFile(fileName); } if (vendor[fileName] !== undefined) { // This file is available in the vendor folder. // Load it from this vendor folder. loadedFiles.push(fileName.toLowerCase()); - loadFile(config.paths.vendor + "/" + vendor[fileName], callback); - return; + return loadFile(`${config.paths.vendor}/${vendor[fileName]}`); } // File not loaded yet. // Load it based on the module path. loadedFiles.push(fileName.toLowerCase()); - loadFile(module.file(fileName), callback); + return loadFile(module.file(fileName)); } }; })(); diff --git a/js/main.js b/js/main.js index 3eed494bff..6e3ec64caa 100644 --- a/js/main.js +++ b/js/main.js @@ -29,7 +29,7 @@ const MM = (function () { dom.className = module.name; if (typeof module.data.classes === "string") { - dom.className = "module " + dom.className + " " + module.data.classes; + dom.className = `module ${dom.className} ${module.data.classes}`; } dom.opacity = 0; @@ -243,7 +243,7 @@ const MM = (function () { const moduleWrapper = document.getElementById(module.identifier); if (moduleWrapper !== null) { - moduleWrapper.style.transition = "opacity " + speed / 1000 + "s"; + moduleWrapper.style.transition = `opacity ${speed / 1000}s`; moduleWrapper.style.opacity = 0; moduleWrapper.classList.add("hidden"); @@ -291,7 +291,7 @@ const MM = (function () { // Check if there are no more lockstrings set, or the force option is set. // Otherwise cancel show action. if (module.lockStrings.length !== 0 && options.force !== true) { - Log.log("Will not show " + module.name + ". LockStrings active: " + module.lockStrings.join(",")); + Log.log(`Will not show ${module.name}. LockStrings active: ${module.lockStrings.join(",")}`); if (typeof options.onError === "function") { options.onError(new Error("LOCK_STRING_ACTIVE")); } @@ -302,13 +302,13 @@ const MM = (function () { // If forced show, clean current lockstrings. if (module.lockStrings.length !== 0 && options.force === true) { - Log.log("Force show of module: " + module.name); + Log.log(`Force show of module: ${module.name}`); module.lockStrings = []; } const moduleWrapper = document.getElementById(module.identifier); if (moduleWrapper !== null) { - moduleWrapper.style.transition = "opacity " + speed / 1000 + "s"; + moduleWrapper.style.transition = `opacity ${speed / 1000}s`; // Restore the position. See hideModule() for more info. moduleWrapper.style.position = "static"; moduleWrapper.classList.remove("hidden"); @@ -479,14 +479,14 @@ const MM = (function () { /** * Main init method. */ - init: function () { + init: async function () { Log.info("Initializing MagicMirror²."); loadConfig(); Log.setLogLevel(config.logLevel); - Translator.loadCoreTranslations(config.language); - Loader.loadModules(); + await Translator.loadCoreTranslations(config.language); + await Loader.loadModules(); }, /** diff --git a/js/module.js b/js/module.js index 6d15452994..7f6b3804e2 100644 --- a/js/module.js +++ b/js/module.js @@ -25,7 +25,7 @@ const Module = Class.extend({ // visibility when hiding and showing module. lockStrings: [], - // Storage of the nunjuck Environment, + // Storage of the nunjucks Environment, // This should not be referenced directly. // Use the nunjucksEnvironment() to get it. _nunjucksEnvironment: null, @@ -40,8 +40,8 @@ const Module = Class.extend({ /** * Called when the module is started. */ - start: function () { - Log.info("Starting module: " + this.name); + start: async function () { + Log.info(`Starting module: ${this.name}`); }, /** @@ -127,7 +127,7 @@ const Module = Class.extend({ * @returns {string} The template string of filename. */ getTemplate: function () { - return '
' + this.name + '
' + this.identifier + "
"; + return `
${this.name}
${this.identifier}
`; }, /** @@ -185,21 +185,21 @@ const Module = Class.extend({ * @param {*} payload The payload of the notification. */ socketNotificationReceived: function (notification, payload) { - Log.log(this.name + " received a socket notification: " + notification + " - Payload: " + payload); + Log.log(`${this.name} received a socket notification: ${notification} - Payload: ${payload}`); }, /** * Called when the module is hidden. */ suspend: function () { - Log.log(this.name + " is suspended."); + Log.log(`${this.name} is suspended.`); }, /** * Called when the module is shown. */ resume: function () { - Log.log(this.name + " is resumed."); + Log.log(`${this.name} is resumed.`); }, /********************************************* @@ -255,57 +255,54 @@ const Module = Class.extend({ * @returns {string} the file path */ file: function (file) { - return (this.data.path + "/" + file).replace("//", "/"); + return `${this.data.path}/${file}`.replace("//", "/"); }, /** * Load all required stylesheets by requesting the MM object to load the files. * - * @param {Function} callback Function called when done. + * @returns {Promise} */ - loadStyles: function (callback) { - this.loadDependencies("getStyles", callback); + loadStyles: function () { + return this.loadDependencies("getStyles"); }, /** * Load all required scripts by requesting the MM object to load the files. * - * @param {Function} callback Function called when done. + * @returns {Promise} */ - loadScripts: function (callback) { - this.loadDependencies("getScripts", callback); + loadScripts: function () { + return this.loadDependencies("getScripts"); }, /** * Helper method to load all dependencies. * * @param {string} funcName Function name to call to get scripts or styles. - * @param {Function} callback Function called when done. + * @returns {Promise} */ - loadDependencies: function (funcName, callback) { + loadDependencies: async function (funcName) { let dependencies = this[funcName](); - const loadNextDependency = () => { + const loadNextDependency = async () => { if (dependencies.length > 0) { const nextDependency = dependencies[0]; - Loader.loadFile(nextDependency, this, () => { - dependencies = dependencies.slice(1); - loadNextDependency(); - }); + await Loader.loadFileForModule(nextDependency, this); + dependencies = dependencies.slice(1); + await loadNextDependency(); } else { - callback(); + return Promise.resolve(); } }; - loadNextDependency(); + await loadNextDependency(); }, /** * Load all translations. - * - * @param {Function} callback Function called when done. */ - loadTranslations(callback) { + loadTranslations: async function () { const translations = this.getTranslations() || {}; const language = config.language.toLowerCase(); @@ -313,7 +310,6 @@ const Module = Class.extend({ const fallbackLanguage = languages[0]; if (languages.length === 0) { - callback(); return; } @@ -321,17 +317,14 @@ const Module = Class.extend({ const translationsFallbackFile = translations[fallbackLanguage]; if (!translationFile) { - Translator.load(this, translationsFallbackFile, true, callback); - return; + return Translator.load(this, translationsFallbackFile, true); } - Translator.load(this, translationFile, false, () => { - if (translationFile !== translationsFallbackFile) { - Translator.load(this, translationsFallbackFile, true, callback); - } else { - callback(); - } - }); + await Translator.load(this, translationFile, false); + + if (translationFile !== translationsFallbackFile) { + return Translator.load(this, translationsFallbackFile, true); + } }, /** @@ -498,15 +491,15 @@ Module.create = function (name) { Module.register = function (name, moduleDefinition) { if (moduleDefinition.requiresVersion) { - Log.log("Check MagicMirror² version for module '" + name + "' - Minimum version: " + moduleDefinition.requiresVersion + " - Current version: " + window.mmVersion); + Log.log(`Check MagicMirror² version for module '${name}' - Minimum version: ${moduleDefinition.requiresVersion} - Current version: ${window.mmVersion}`); if (cmpVersions(window.mmVersion, moduleDefinition.requiresVersion) >= 0) { Log.log("Version is ok!"); } else { - Log.warn("Version is incorrect. Skip module: '" + name + "'"); + Log.warn(`Version is incorrect. Skip module: '${name}'`); return; } } - Log.log("Module registered: " + name); + Log.log(`Module registered: ${name}`); Module.definitions[name] = moduleDefinition; }; diff --git a/js/node_helper.js b/js/node_helper.js index fa8c568873..03c6dca796 100644 --- a/js/node_helper.js +++ b/js/node_helper.js @@ -4,18 +4,17 @@ * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ -const Class = require("./class.js"); -const Log = require("logger"); const express = require("express"); +const Log = require("logger"); +const Class = require("./class"); const NodeHelper = Class.extend({ init() { Log.log("Initializing new module helper ..."); }, - loaded(callback) { + loaded() { Log.log(`Module helper loaded: ${this.name}`); - callback(); }, start() { diff --git a/js/server.js b/js/server.js index 3aa246b5c1..1454621703 100644 --- a/js/server.js +++ b/js/server.js @@ -4,15 +4,18 @@ * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ -const express = require("express"); +const fs = require("fs"); +const http = require("http"); +const https = require("https"); const path = require("path"); +const express = require("express"); const ipfilter = require("express-ipfilter").IpFilter; -const fs = require("fs"); const helmet = require("helmet"); +const socketio = require("socket.io"); const Log = require("logger"); -const Utils = require("./utils.js"); -const { cors, getConfig, getHtml, getVersion } = require("./server_functions.js"); +const Utils = require("./utils"); +const { cors, getConfig, getHtml, getVersion } = require("./server_functions"); /** * Server @@ -38,11 +41,11 @@ function Server(config) { key: fs.readFileSync(config.httpsPrivateKey), cert: fs.readFileSync(config.httpsCertificate) }; - server = require("https").Server(options, app); + server = https.Server(options, app); } else { - server = require("http").Server(app); + server = http.Server(app); } - const io = require("socket.io")(server, { + const io = socketio(server, { cors: { origin: /.*$/, credentials: true diff --git a/js/server_functions.js b/js/server_functions.js index f210a8b848..6ecc6cae29 100644 --- a/js/server_functions.js +++ b/js/server_functions.js @@ -1,7 +1,7 @@ -const fetch = require("./fetch"); const fs = require("fs"); const path = require("path"); const Log = require("logger"); +const fetch = require("./fetch"); /** * Gets the config. @@ -14,7 +14,7 @@ function getConfig(req, res) { } /** - * A method that forewards HTTP Get-methods to the internet to avoid CORS-errors. + * A method that forwards HTTP Get-methods to the internet to avoid CORS-errors. * * Example input request url: /cors?sendheaders=header1:value1,header2:value2&expectedheaders=header1,header2&url=http://www.test.com/path?param1=value1 * @@ -26,11 +26,11 @@ function getConfig(req, res) { async function cors(req, res) { try { const urlRegEx = "url=(.+?)$"; - let url = ""; + let url; const match = new RegExp(urlRegEx, "g").exec(req.url); if (!match) { - url = "invalid url: " + req.url; + url = `invalid url: ${req.url}`; Log.error(url); res.send(url); } else { @@ -39,7 +39,7 @@ async function cors(req, res) { const headersToSend = getHeadersToSend(req.url); const expectedRecievedHeaders = geExpectedRecievedHeaders(req.url); - Log.log("cors url: " + url); + Log.log(`cors url: ${url}`); const response = await fetch(url, { headers: headersToSend }); for (const header of expectedRecievedHeaders) { @@ -56,13 +56,13 @@ async function cors(req, res) { } /** - * Gets headers and values to attatch to the web request. + * Gets headers and values to attach to the web request. * * @param {string} url - The url containing the headers and values to send. * @returns {object} An object specifying name and value of the headers. */ function getHeadersToSend(url) { - const headersToSend = { "User-Agent": "Mozilla/5.0 MagicMirror/" + global.version }; + const headersToSend = { "User-Agent": `Mozilla/5.0 MagicMirror/${global.version}` }; const headersToSendMatch = new RegExp("sendheaders=(.+?)(&|$)", "g").exec(url); if (headersToSendMatch) { const headers = headersToSendMatch[1].split(","); diff --git a/js/socketclient.js b/js/socketclient.js index 8b3aec827a..fce49d301d 100644 --- a/js/socketclient.js +++ b/js/socketclient.js @@ -18,8 +18,8 @@ const MMSocket = function (moduleName) { if (typeof config !== "undefined" && typeof config.basePath !== "undefined") { base = config.basePath; } - this.socket = io("/" + this.moduleName, { - path: base + "socket.io" + this.socket = io(`/${this.moduleName}`, { + path: `${base}socket.io` }); let notificationCallback = function () {}; diff --git a/js/translator.js b/js/translator.js index 77d4b8f0da..dd004d5414 100644 --- a/js/translator.js +++ b/js/translator.js @@ -11,26 +11,28 @@ const Translator = (function () { * Load a JSON file via XHR. * * @param {string} file Path of the file we want to load. - * @param {Function} callback Function called when done. + * @returns {Promise} the translations in the specified file */ - function loadJSON(file, callback) { + async function loadJSON(file) { const xhr = new XMLHttpRequest(); - xhr.overrideMimeType("application/json"); - xhr.open("GET", file, true); - xhr.onreadystatechange = function () { - if (xhr.readyState === 4 && xhr.status === 200) { - // needs error handler try/catch at least - let fileinfo = null; - try { - fileinfo = JSON.parse(xhr.responseText); - } catch (exception) { - // nothing here, but don't die - Log.error(" loading json file =" + file + " failed"); + return new Promise(function (resolve, reject) { + xhr.overrideMimeType("application/json"); + xhr.open("GET", file, true); + xhr.onreadystatechange = function () { + if (xhr.readyState === 4 && xhr.status === 200) { + // needs error handler try/catch at least + let fileinfo = null; + try { + fileinfo = JSON.parse(xhr.responseText); + } catch (exception) { + // nothing here, but don't die + Log.error(` loading json file =${file} failed`); + } + resolve(fileinfo); } - callback(fileinfo); - } - }; - xhr.send(null); + }; + xhr.send(null); + }); } return { @@ -48,7 +50,7 @@ const Translator = (function () { * @returns {string} the translated key */ translate: function (module, key, variables) { - variables = variables || {}; //Empty object by default + variables = variables || {}; // Empty object by default /** * Combines template and variables like: @@ -68,7 +70,7 @@ const Translator = (function () { template = variables.fallback; } return template.replace(new RegExp("{([^}]+)}", "g"), function (_unused, varName) { - return varName in variables ? variables[varName] : "{" + varName + "}"; + return varName in variables ? variables[varName] : `{${varName}}`; }); } @@ -101,21 +103,17 @@ const Translator = (function () { * @param {Module} module The module to load the translation file for. * @param {string} file Path of the file we want to load. * @param {boolean} isFallback Flag to indicate fallback translations. - * @param {Function} callback Function called when done. */ - load(module, file, isFallback, callback) { + async load(module, file, isFallback) { Log.log(`${module.name} - Load translation${isFallback ? " fallback" : ""}: ${file}`); if (this.translationsFallback[module.name]) { - callback(); return; } - loadJSON(module.file(file), (json) => { - const property = isFallback ? "translationsFallback" : "translations"; - this[property][module.name] = json; - callback(); - }); + const json = await loadJSON(module.file(file)); + const property = isFallback ? "translationsFallback" : "translations"; + this[property][module.name] = json; }, /** @@ -123,30 +121,26 @@ const Translator = (function () { * * @param {string} lang The language identifier of the core language. */ - loadCoreTranslations: function (lang) { + loadCoreTranslations: async function (lang) { if (lang in translations) { - Log.log("Loading core translation file: " + translations[lang]); - loadJSON(translations[lang], (translations) => { - this.coreTranslations = translations; - }); + Log.log(`Loading core translation file: ${translations[lang]}`); + this.coreTranslations = await loadJSON(translations[lang]); } else { Log.log("Configured language not found in core translations."); } - this.loadCoreTranslationsFallback(); + await this.loadCoreTranslationsFallback(); }, /** - * Load the core translations fallback. + * Load the core translations' fallback. * The first language defined in translations.js will be used. */ - loadCoreTranslationsFallback: function () { + loadCoreTranslationsFallback: async function () { let first = Object.keys(translations)[0]; if (first) { - Log.log("Loading core translation fallback file: " + translations[first]); - loadJSON(translations[first], (translations) => { - this.coreTranslationsFallback = translations; - }); + Log.log(`Loading core translation fallback file: ${translations[first]}`); + this.coreTranslationsFallback = await loadJSON(translations[first]); } } }; diff --git a/modules/default/alert/alert.js b/modules/default/alert/alert.js index 76bacc0248..1bd11d02f6 100644 --- a/modules/default/alert/alert.js +++ b/modules/default/alert/alert.js @@ -35,7 +35,8 @@ Module.register("alert", { fr: "translations/fr.json", hu: "translations/hu.json", nl: "translations/nl.json", - ru: "translations/ru.json" + ru: "translations/ru.json", + th: "translations/th.json" }; }, @@ -43,7 +44,7 @@ Module.register("alert", { return `templates/${type}.njk`; }, - start() { + async start() { Log.info(`Starting module: ${this.name}`); if (this.config.effect === "slide") { @@ -52,7 +53,7 @@ Module.register("alert", { if (this.config.welcome_message) { const message = this.config.welcome_message === true ? this.translate("welcome") : this.config.welcome_message; - this.showNotification({ title: this.translate("sysTitle"), message }); + await this.showNotification({ title: this.translate("sysTitle"), message }); } }, @@ -69,7 +70,7 @@ Module.register("alert", { }, async showNotification(notification) { - const message = await this.renderMessage("notification", notification); + const message = await this.renderMessage(notification.templateName || "notification", notification); new NotificationFx({ message, @@ -90,7 +91,7 @@ Module.register("alert", { this.toggleBlur(true); } - const message = await this.renderMessage("alert", alert); + const message = await this.renderMessage(alert.templateName || "alert", alert); // Store alert in this.alerts this.alerts[sender.name] = new NotificationFx({ diff --git a/modules/default/alert/notificationFx.js b/modules/default/alert/notificationFx.js index 3957abe814..8f8a84ccaa 100644 --- a/modules/default/alert/notificationFx.js +++ b/modules/default/alert/notificationFx.js @@ -80,7 +80,7 @@ NotificationFx.prototype._init = function () { // create HTML structure this.ntf = document.createElement("div"); - this.ntf.className = this.options.al_no + " ns-" + this.options.layout + " ns-effect-" + this.options.effect + " ns-type-" + this.options.type; + this.ntf.className = `${this.options.al_no} ns-${this.options.layout} ns-effect-${this.options.effect} ns-type-${this.options.type}`; let strinner = '
'; strinner += this.options.message; strinner += "
"; diff --git a/modules/default/alert/styles/notificationFx.css b/modules/default/alert/styles/notificationFx.css index 8e033e0d61..df3407514c 100644 --- a/modules/default/alert/styles/notificationFx.css +++ b/modules/default/alert/styles/notificationFx.css @@ -1,7 +1,7 @@ /* Based on work by https://tympanus.net/codrops/licensing/ */ .ns-box { - background-color: rgba(0, 0, 0, 0.93); + background-color: rgb(0 0 0 / 93%); padding: 17px; line-height: 1.4; margin-bottom: 10px; @@ -55,15 +55,15 @@ .ns-effect-flip.ns-show, .ns-effect-flip.ns-hide { - animation-name: animFlipFront; + animation-name: anim-flip-front; animation-duration: 0.3s; } .ns-effect-flip.ns-hide { - animation-name: animFlipBack; + animation-name: anim-flip-back; } -@keyframes animFlipFront { +@keyframes anim-flip-front { 0% { transform: perspective(1000px) rotate3d(1, 0, 0, -90deg); } @@ -73,7 +73,7 @@ } } -@keyframes animFlipBack { +@keyframes anim-flip-back { 0% { transform: perspective(1000px) rotate3d(1, 0, 0, 90deg); } @@ -85,11 +85,11 @@ .ns-effect-bouncyflip.ns-show, .ns-effect-bouncyflip.ns-hide { - animation-name: flipInX; + animation-name: flip-in-x; animation-duration: 0.8s; } -@keyframes flipInX { +@keyframes flip-in-x { 0% { transform: perspective(400px) rotate3d(1, 0, 0, -90deg); transition-timing-function: ease-in; @@ -117,11 +117,11 @@ } .ns-effect-bouncyflip.ns-hide { - animation-name: flipInXSimple; + animation-name: flip-in-x-simple; animation-duration: 0.3s; } -@keyframes flipInXSimple { +@keyframes flip-in-x-simple { 0% { transform: perspective(400px) rotate3d(1, 0, 0, -90deg); transition-timing-function: ease-in; @@ -141,11 +141,11 @@ } .ns-effect-exploader.ns-show { - animation-name: animLoad; + animation-name: anim-load; animation-duration: 1s; } -@keyframes animLoad { +@keyframes anim-load { 0% { opacity: 1; transform: scale3d(0, 0.3, 1); @@ -158,7 +158,7 @@ } .ns-effect-exploader.ns-hide { - animation-name: animFade; + animation-name: anim-fade; animation-duration: 0.3s; } @@ -170,15 +170,15 @@ } .ns-effect-exploader.ns-show .ns-close { - animation-name: animFade; + animation-name: anim-fade; } .ns-effect-exploader.ns-show .ns-box-inner { - animation-name: animFadeMove; + animation-name: anim-fade-move; animation-timing-function: ease-out; } -@keyframes animFadeMove { +@keyframes anim-fade-move { 0% { opacity: 0; transform: translate3d(0, 10px, 0); @@ -190,7 +190,7 @@ } } -@keyframes animFade { +@keyframes anim-fade { 0% { opacity: 0; } @@ -202,11 +202,11 @@ .ns-effect-scale.ns-show, .ns-effect-scale.ns-hide { - animation-name: animScale; + animation-name: anim-scale; animation-duration: 0.25s; } -@keyframes animScale { +@keyframes anim-scale { 0% { opacity: 0; transform: translate3d(0, 40px, 0) scale3d(0.1, 0.6, 1); @@ -219,168 +219,169 @@ } .ns-effect-jelly.ns-show { - animation-name: animJelly; + animation-name: anim-jelly; animation-duration: 1s; animation-timing-function: linear; } .ns-effect-jelly.ns-hide { - animation-name: animFade; + animation-name: anim-fade; animation-duration: 0.3s; } -@keyframes animFade { +@keyframes anim-fade { 0% { opacity: 0; } + 100% { opacity: 1; } } -@keyframes animJelly { +@keyframes anim-jelly { 0% { transform: matrix3d(0.7, 0, 0, 0, 0, 0.7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 2.083333% { - transform: matrix3d(0.75266, 0, 0, 0, 0, 0.76342, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.7527, 0, 0, 0, 0, 0.7634, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 4.166667% { - transform: matrix3d(0.81071, 0, 0, 0, 0, 0.84545, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.8107, 0, 0, 0, 0, 0.8454, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 6.25% { - transform: matrix3d(0.86808, 0, 0, 0, 0, 0.9286, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.8681, 0, 0, 0, 0, 0.929, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 8.333333% { - transform: matrix3d(0.92038, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9204, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 10.416667% { - transform: matrix3d(0.96482, 0, 0, 0, 0, 1.05202, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9648, 0, 0, 0, 0, 1.052, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 12.5% { - transform: matrix3d(1, 0, 0, 0, 0, 1.08204, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1.082, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 14.583333% { - transform: matrix3d(1.02563, 0, 0, 0, 0, 1.09149, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0256, 0, 0, 0, 0, 1.0915, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 16.666667% { - transform: matrix3d(1.04227, 0, 0, 0, 0, 1.08453, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0423, 0, 0, 0, 0, 1.0845, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 18.75% { - transform: matrix3d(1.05102, 0, 0, 0, 0, 1.06666, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.051, 0, 0, 0, 0, 1.0667, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 20.833333% { - transform: matrix3d(1.05334, 0, 0, 0, 0, 1.04355, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0533, 0, 0, 0, 0, 1.0436, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 22.916667% { - transform: matrix3d(1.05078, 0, 0, 0, 0, 1.02012, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0508, 0, 0, 0, 0, 1.0201, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 25% { - transform: matrix3d(1.04487, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0449, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 27.083333% { - transform: matrix3d(1.03699, 0, 0, 0, 0, 0.98534, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.037, 0, 0, 0, 0, 0.9853, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 29.166667% { - transform: matrix3d(1.02831, 0, 0, 0, 0, 0.97688, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0283, 0, 0, 0, 0, 0.9769, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 31.25% { - transform: matrix3d(1.01973, 0, 0, 0, 0, 0.97422, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0197, 0, 0, 0, 0, 0.9742, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 33.333333% { - transform: matrix3d(1.01191, 0, 0, 0, 0, 0.97618, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0119, 0, 0, 0, 0, 0.9762, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 35.416667% { - transform: matrix3d(1.00526, 0, 0, 0, 0, 0.98122, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0053, 0, 0, 0, 0, 0.9812, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 37.5% { - transform: matrix3d(1, 0, 0, 0, 0, 0.98773, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 0.9877, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 39.583333% { - transform: matrix3d(0.99617, 0, 0, 0, 0, 0.99433, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9962, 0, 0, 0, 0, 0.9943, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 41.666667% { - transform: matrix3d(0.99368, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9937, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 43.75% { - transform: matrix3d(0.99237, 0, 0, 0, 0, 1.00413, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9924, 0, 0, 0, 0, 1.0041, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 45.833333% { - transform: matrix3d(0.99202, 0, 0, 0, 0, 1.00651, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.992, 0, 0, 0, 0, 1.0065, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 47.916667% { - transform: matrix3d(0.99241, 0, 0, 0, 0, 1.00726, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9924, 0, 0, 0, 0, 1.0073, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 50% { - transform: matrix3d(0.99329, 0, 0, 0, 0, 1.00671, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9933, 0, 0, 0, 0, 1.0067, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 52.083333% { - transform: matrix3d(0.99447, 0, 0, 0, 0, 1.00529, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9945, 0, 0, 0, 0, 1.0053, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 54.166667% { - transform: matrix3d(0.99577, 0, 0, 0, 0, 1.00346, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9958, 0, 0, 0, 0, 1.0035, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 56.25% { - transform: matrix3d(0.99705, 0, 0, 0, 0, 1.0016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.997, 0, 0, 0, 0, 1.002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 58.333333% { - transform: matrix3d(0.99822, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9982, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 60.416667% { - transform: matrix3d(0.99921, 0, 0, 0, 0, 0.99884, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9992, 0, 0, 0, 0, 0.9989, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 62.5% { - transform: matrix3d(1, 0, 0, 0, 0, 0.99816, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 0.9982, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 64.583333% { - transform: matrix3d(1.00057, 0, 0, 0, 0, 0.99795, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0006, 0, 0, 0, 0, 0.998, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 66.666667% { - transform: matrix3d(1.00095, 0, 0, 0, 0, 0.99811, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.001, 0, 0, 0, 0, 0.9981, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 68.75% { - transform: matrix3d(1.00114, 0, 0, 0, 0, 0.99851, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0011, 0, 0, 0, 0, 0.9985, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 70.833333% { - transform: matrix3d(1.00119, 0, 0, 0, 0, 0.99903, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0012, 0, 0, 0, 0, 0.999, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 72.916667% { - transform: matrix3d(1.00114, 0, 0, 0, 0, 0.99955, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0011, 0, 0, 0, 0, 0.9996, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 75% { @@ -388,47 +389,47 @@ } 77.083333% { - transform: matrix3d(1.00083, 0, 0, 0, 0, 1.00033, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0008, 0, 0, 0, 0, 1.0003, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 79.166667% { - transform: matrix3d(1.00063, 0, 0, 0, 0, 1.00052, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0006, 0, 0, 0, 0, 1.0005, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 81.25% { - transform: matrix3d(1.00044, 0, 0, 0, 0, 1.00058, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0004, 0, 0, 0, 0, 1.0006, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 83.333333% { - transform: matrix3d(1.00027, 0, 0, 0, 0, 1.00053, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0003, 0, 0, 0, 0, 1.0005, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 85.416667% { - transform: matrix3d(1.00012, 0, 0, 0, 0, 1.00042, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0001, 0, 0, 0, 0, 1.0004, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 87.5% { - transform: matrix3d(1, 0, 0, 0, 0, 1.00027, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1.0003, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 89.583333% { - transform: matrix3d(0.99991, 0, 0, 0, 0, 1.00013, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9999, 0, 0, 0, 0, 1.0001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 91.666667% { - transform: matrix3d(0.99986, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9999, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 93.75% { - transform: matrix3d(0.99983, 0, 0, 0, 0, 0.99991, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9998, 0, 0, 0, 0, 0.9999, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 95.833333% { - transform: matrix3d(0.99982, 0, 0, 0, 0, 0.99985, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9998, 0, 0, 0, 0, 0.9999, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 97.916667% { - transform: matrix3d(0.99983, 0, 0, 0, 0, 0.99984, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9998, 0, 0, 0, 0, 0.9998, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 100% { @@ -437,162 +438,162 @@ } .ns-effect-slide-left.ns-show { - animation-name: animSlideElasticLeft; + animation-name: anim-slide-elastic-left; animation-duration: 1s; animation-timing-function: linear; } -@keyframes animSlideElasticLeft { +@keyframes anim-slide-elastic-left { 0% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1000, 0, 0, 1); } 1.666667% { - transform: matrix3d(1.92933, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -739.26805, 0, 0, 1); + transform: matrix3d(1.9293, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -739.2681, 0, 0, 1); } 3.333333% { - transform: matrix3d(1.96989, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -521.82545, 0, 0, 1); + transform: matrix3d(1.9699, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -521.8255, 0, 0, 1); } 5% { - transform: matrix3d(1.70901, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -349.26115, 0, 0, 1); + transform: matrix3d(1.709, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -349.2612, 0, 0, 1); } 6.666667% { - transform: matrix3d(1.4235, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -218.3238, 0, 0, 1); + transform: matrix3d(1.424, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -218.324, 0, 0, 1); } 8.333333% { - transform: matrix3d(1.21065, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -123.29848, 0, 0, 1); + transform: matrix3d(1.2107, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -123.2985, 0, 0, 1); } 10% { - transform: matrix3d(1.08167, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -57.59273, 0, 0, 1); + transform: matrix3d(1.0817, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -57.5927, 0, 0, 1); } 11.666667% { - transform: matrix3d(1.0165, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -14.72371, 0, 0, 1); + transform: matrix3d(1.017, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -14.7237, 0, 0, 1); } 13.333333% { - transform: matrix3d(0.99057, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.12794, 0, 0, 1); + transform: matrix3d(0.9906, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.1279, 0, 0, 1); } 15% { - transform: matrix3d(0.98478, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 24.86339, 0, 0, 1); + transform: matrix3d(0.9848, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 24.8634, 0, 0, 1); } 16.666667% { - transform: matrix3d(0.98719, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.40503, 0, 0, 1); + transform: matrix3d(0.9872, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.405, 0, 0, 1); } 18.333333% { - transform: matrix3d(0.9916, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.75275, 0, 0, 1); + transform: matrix3d(0.992, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.7528, 0, 0, 1); } 20% { - transform: matrix3d(0.99541, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 28.10141, 0, 0, 1); + transform: matrix3d(0.9954, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 28.1014, 0, 0, 1); } 21.666667% { - transform: matrix3d(0.99795, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 23.98271, 0, 0, 1); + transform: matrix3d(0.998, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 23.9827, 0, 0, 1); } 23.333333% { - transform: matrix3d(0.99936, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 19.40752, 0, 0, 1); + transform: matrix3d(0.9994, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 19.4075, 0, 0, 1); } 25% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 14.99558, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 14.9956, 0, 0, 1); } 26.666667% { - transform: matrix3d(1.00021, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.08575, 0, 0, 1); + transform: matrix3d(1.0002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.0858, 0, 0, 1); } 28.333333% { - transform: matrix3d(1.00022, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7.82507, 0, 0, 1); + transform: matrix3d(1.0002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7.8251, 0, 0, 1); } 30% { - transform: matrix3d(1.00016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5.23737, 0, 0, 1); + transform: matrix3d(1.0002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5.2374, 0, 0, 1); } 31.666667% { - transform: matrix3d(1.0001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3.27389, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3.2739, 0, 0, 1); } 33.333333% { - transform: matrix3d(1.00005, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1.84893, 0, 0, 1); + transform: matrix3d(1.0001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1.8489, 0, 0, 1); } 35% { - transform: matrix3d(1.00002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.86364, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.8636, 0, 0, 1); } 36.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.22079, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.2208, 0, 0, 1); } 38.333333% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16687, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.1669, 0, 0, 1); } 40% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.37284, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.3728, 0, 0, 1); } 41.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.45594, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.4559, 0, 0, 1); } 43.333333% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.46116, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.4612, 0, 0, 1); } 45% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.4214, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.421, 0, 0, 1); } 46.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.35963, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.3596, 0, 0, 1); } 48.333333% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.29103, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.291, 0, 0, 1); } 50% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.22487, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.2249, 0, 0, 1); } 51.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16624, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.1662, 0, 0, 1); } 53.333333% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.11734, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.1173, 0, 0, 1); } 55% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.07854, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0785, 0, 0, 1); } 56.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.04909, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0491, 0, 0, 1); } 58.333333% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.02773, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0277, 0, 0, 1); } 60% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.01295, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.013, 0, 0, 1); } 61.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00331, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0033, 0, 0, 1); } 63.333333% { @@ -600,67 +601,67 @@ } 65% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00559, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0056, 0, 0, 1); } 66.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00684, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0068, 0, 0, 1); } 68.333333% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00692, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0069, 0, 0, 1); } 70% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00632, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0063, 0, 0, 1); } 71.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00539, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0054, 0, 0, 1); } 73.333333% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00436, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0044, 0, 0, 1); } 75% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00337, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0034, 0, 0, 1); } 76.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00249, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0025, 0, 0, 1); } 78.333333% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00176, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0018, 0, 0, 1); } 80% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00118, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0012, 0, 0, 1); } 81.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00074, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0007, 0, 0, 1); } 83.333333% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00042, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0004, 0, 0, 1); } 85% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00019, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0002, 0, 0, 1); } 86.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00005, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0001, 0, 0, 1); } 88.333333% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00004, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); } 90% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); } 91.666667% { @@ -672,15 +673,15 @@ } 95% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00009, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); } 96.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); } 98.333333% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00007, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); } 100% { @@ -689,11 +690,11 @@ } .ns-effect-slide-left.ns-hide { - animation-name: animSlideLeft; + animation-name: anim-slide-left; animation-duration: 0.25s; } -@keyframes animSlideLeft { +@keyframes anim-slide-left { 0% { transform: translate3d(-30px, 0, 0) translate3d(-100%, 0, 0); } @@ -704,10 +705,10 @@ } .ns-effect-slide-right.ns-show { - animation: animSlideElasticRight 2000ms linear both; + animation: anim-slide-elastic-right 2000ms linear both; } -@keyframes animSlideElasticRight { +@keyframes anim-slide-elastic-right { 0% { transform: matrix3d(2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1000, 0, 0, 1); } @@ -786,11 +787,11 @@ } .ns-effect-slide-right.ns-hide { - animation-name: animSlideRight; + animation-name: anim-slide-right; animation-duration: 0.25s; } -@keyframes animSlideRight { +@keyframes anim-slide-right { 0% { transform: translate3d(30px, 0, 0) translate3d(100%, 0, 0); } @@ -801,10 +802,10 @@ } .ns-effect-slide-center.ns-show { - animation: animSlideElasticCenter 2000ms linear both; + animation: anim-slide-elastic-center 2000ms linear both; } -@keyframes animSlideElasticCenter { +@keyframes anim-slide-elastic-center { 0% { transform: matrix3d(1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, -300, 0, 1); } @@ -883,11 +884,11 @@ } .ns-effect-slide-center.ns-hide { - animation-name: animSlideCenter; + animation-name: anim-slide-center; animation-duration: 0.25s; } -@keyframes animSlideCenter { +@keyframes anim-slide-center { 0% { transform: translate3d(0, -30px, 0) translate3d(0, -100%, 0); } @@ -899,11 +900,11 @@ .ns-effect-genie.ns-show, .ns-effect-genie.ns-hide { - animation-name: animGenie; + animation-name: anim-genie; animation-duration: 0.4s; } -@keyframes animGenie { +@keyframes anim-genie { 0% { opacity: 0; transform: translate3d(0, calc(200% + 30px), 0) scale3d(0, 1, 1); diff --git a/modules/default/alert/templates/alert.njk b/modules/default/alert/templates/alert.njk index a748d2684e..7349a7ae3d 100644 --- a/modules/default/alert/templates/alert.njk +++ b/modules/default/alert/templates/alert.njk @@ -8,11 +8,11 @@
{% endif %} {% if title %} - {{ title }} + {{ title if titleType == 'text' else title | safe }} {% endif %} {% if message %} {% if title %}
{% endif %} - {{ message }} + {{ message if messageType == 'text' else message | safe }} {% endif %} diff --git a/modules/default/alert/templates/notification.njk b/modules/default/alert/templates/notification.njk index 1d67bcda7d..1594ad4866 100644 --- a/modules/default/alert/templates/notification.njk +++ b/modules/default/alert/templates/notification.njk @@ -1,9 +1,9 @@ {% if title %} - {{ title }} + {{ title if titleType == 'text' else title | safe }} {% endif %} {% if message %} {% if title %}
{% endif %} - {{ message }} + {{ message if messageType == 'text' else message | safe }} {% endif %} diff --git a/modules/default/alert/translations/th.json b/modules/default/alert/translations/th.json new file mode 100644 index 0000000000..a1894bf3f1 --- /dev/null +++ b/modules/default/alert/translations/th.json @@ -0,0 +1,4 @@ +{ + "sysTitle": "การแจ้งเตือน MagicMirror²", + "welcome": "ยินดีต้อนรับ การเริ่มต้นสำเร็จแล้ว!" +} diff --git a/modules/default/calendar/calendar.css b/modules/default/calendar/calendar.css index f04d683872..f8e3bd7929 100644 --- a/modules/default/calendar/calendar.css +++ b/modules/default/calendar/calendar.css @@ -14,6 +14,7 @@ .calendar .title { padding-left: 0; padding-right: 0; + vertical-align: top; } .calendar .time { diff --git a/modules/default/calendar/calendar.js b/modules/default/calendar/calendar.js index cecf80ea12..2ef9ca9c89 100644 --- a/modules/default/calendar/calendar.js +++ b/modules/default/calendar/calendar.js @@ -12,6 +12,7 @@ Module.register("calendar", { maximumEntries: 10, // Total Maximum Entries maximumNumberOfDays: 365, limitDays: 0, // Limit the number of days shown, 0 = no limit + pastDaysCount: 0, displaySymbol: true, defaultSymbol: "calendar-alt", // Fontawesome Symbol see https://fontawesome.com/cheatsheet?from=io defaultSymbolClassName: "fas fa-fw fa-", @@ -40,7 +41,6 @@ Module.register("calendar", { hideTime: false, showTimeToday: false, colored: false, - coloredSymbolOnly: false, customEvents: [], // Array of {keyword: "", symbol: "", color: ""} where Keyword is a regexp and symbol/color are to be applied for matched tableClass: "small", calendars: [ @@ -61,7 +61,13 @@ Module.register("calendar", { sliceMultiDayEvents: false, broadcastPastEvents: false, nextDaysRelative: false, - selfSignedCert: false + selfSignedCert: false, + coloredText: false, + coloredBorder: false, + coloredSymbol: false, + coloredBackground: false, + limitDaysNeverSkip: false, + flipDateHeaderTitle: false }, requiresVersion: "2.1.0", @@ -86,7 +92,20 @@ Module.register("calendar", { // Override start method. start: function () { - Log.info("Starting module: " + this.name); + const ONE_MINUTE = 60 * 1000; + + Log.info(`Starting module: ${this.name}`); + + if (this.config.colored) { + Log.warn("Your are using the deprecated config values 'colored'. Please switch to 'coloredSymbol' & 'coloredText'!"); + this.config.coloredText = true; + this.config.coloredSymbol = true; + } + if (this.config.coloredSymbolOnly) { + Log.warn("Your are using the deprecated config values 'coloredSymbolOnly'. Please switch to 'coloredSymbol' & 'coloredText'!"); + this.config.coloredText = false; + this.config.coloredSymbol = true; + } // Set locale. moment.updateLocale(config.language, this.getLocaleSpecification(config.timeFormat)); @@ -103,6 +122,7 @@ Module.register("calendar", { const calendarConfig = { maximumEntries: calendar.maximumEntries, maximumNumberOfDays: calendar.maximumNumberOfDays, + pastDaysCount: calendar.pastDaysCount, broadcastPastEvents: calendar.broadcastPastEvents, selfSignedCert: calendar.selfSignedCert }; @@ -131,6 +151,14 @@ Module.register("calendar", { // fetcher till cycle this.addCalendar(calendar.url, calendar.auth, calendarConfig); }); + + // Refresh the DOM every minute if needed: When using relative date format for events that start + // or end in less than an hour, the date shows minute granularity and we want to keep that accurate. + setTimeout(() => { + setInterval(() => { + this.updateDom(1); + }, ONE_MINUTE); + }, ONE_MINUTE - (new Date() % ONE_MINUTE)); }, // Override socket notification handler. @@ -175,13 +203,13 @@ Module.register("calendar", { if (this.error) { wrapper.innerHTML = this.error; - wrapper.className = this.config.tableClass + " dimmed"; + wrapper.className = `${this.config.tableClass} dimmed`; return wrapper; } if (events.length === 0) { wrapper.innerHTML = this.loaded ? this.translate("EMPTY") : this.translate("LOADING"); - wrapper.className = this.config.tableClass + " dimmed"; + wrapper.className = `${this.config.tableClass} dimmed`; return wrapper; } @@ -204,9 +232,12 @@ Module.register("calendar", { if (this.config.timeFormat === "dateheaders") { if (lastSeenDate !== dateAsString) { const dateRow = document.createElement("tr"); - dateRow.className = "normal"; + dateRow.className = "dateheader normal"; if (event.today) dateRow.className += " today"; + else if (event.dayBeforeYesterday) dateRow.className += " dayBeforeYesterday"; + else if (event.yesterday) dateRow.className += " yesterday"; else if (event.tomorrow) dateRow.className += " tomorrow"; + else if (event.dayAfterTomorrow) dateRow.className += " dayAfterTomorrow"; const dateCell = document.createElement("td"); dateCell.colSpan = "3"; @@ -227,23 +258,34 @@ Module.register("calendar", { const eventWrapper = document.createElement("tr"); - if (this.config.colored && !this.config.coloredSymbolOnly) { - eventWrapper.style.cssText = "color:" + this.colorForUrl(event.url); + if (this.config.coloredText) { + eventWrapper.style.cssText = `color:${this.colorForUrl(event.url, false)}`; + } + + if (this.config.coloredBackground) { + eventWrapper.style.backgroundColor = this.colorForUrl(event.url, true); } - eventWrapper.className = "normal event"; + if (this.config.coloredBorder) { + eventWrapper.style.borderColor = this.colorForUrl(event.url, false); + } + + eventWrapper.className = "event-wrapper normal event"; if (event.today) eventWrapper.className += " today"; + else if (event.dayBeforeYesterday) eventWrapper.className += " dayBeforeYesterday"; + else if (event.yesterday) eventWrapper.className += " yesterday"; else if (event.tomorrow) eventWrapper.className += " tomorrow"; + else if (event.dayAfterTomorrow) eventWrapper.className += " dayAfterTomorrow"; const symbolWrapper = document.createElement("td"); if (this.config.displaySymbol) { - if (this.config.colored && this.config.coloredSymbolOnly) { - symbolWrapper.style.cssText = "color:" + this.colorForUrl(event.url); + if (this.config.coloredSymbol) { + symbolWrapper.style.cssText = `color:${this.colorForUrl(event.url, false)}`; } const symbolClass = this.symbolClassForUrl(event.url); - symbolWrapper.className = "symbol align-right " + symbolClass; + symbolWrapper.className = `symbol align-right ${symbolClass}`; const symbols = this.symbolsForEvent(event); symbols.forEach((s, index) => { @@ -271,7 +313,7 @@ Module.register("calendar", { const thisYear = new Date(parseInt(event.startDate)).getFullYear(), yearDiff = thisYear - event.firstYear; - repeatingCountTitle = ", " + yearDiff + ". " + repeatingCountTitle; + repeatingCountTitle = `, ${yearDiff}. ${repeatingCountTitle}`; } } @@ -282,12 +324,12 @@ Module.register("calendar", { let needle = new RegExp(this.config.customEvents[ev].keyword, "gi"); if (needle.test(event.title)) { // Respect parameter ColoredSymbolOnly also for custom events - if (!this.config.coloredSymbolOnly) { - eventWrapper.style.cssText = "color:" + this.config.customEvents[ev].color; - titleWrapper.style.cssText = "color:" + this.config.customEvents[ev].color; + if (this.config.coloredText) { + eventWrapper.style.cssText = `color:${this.config.customEvents[ev].color}`; + titleWrapper.style.cssText = `color:${this.config.customEvents[ev].color}`; } - if (this.config.displaySymbol) { - symbolWrapper.style.cssText = "color:" + this.config.customEvents[ev].color; + if (this.config.displaySymbol && this.config.coloredSymbol) { + symbolWrapper.style.cssText = `color:${this.config.customEvents[ev].color}`; } break; } @@ -299,32 +341,35 @@ Module.register("calendar", { const titleClass = this.titleClassForUrl(event.url); - if (!this.config.colored) { - titleWrapper.className = "title bright " + titleClass; + if (!this.config.coloredText) { + titleWrapper.className = `title bright ${titleClass}`; } else { - titleWrapper.className = "title " + titleClass; + titleWrapper.className = `title ${titleClass}`; } if (this.config.timeFormat === "dateheaders") { + if (this.config.flipDateHeaderTitle) eventWrapper.appendChild(titleWrapper); + if (event.fullDayEvent) { titleWrapper.colSpan = "2"; titleWrapper.classList.add("align-left"); } else { const timeWrapper = document.createElement("td"); - timeWrapper.className = "time light align-left " + this.timeClassForUrl(event.url); + timeWrapper.className = `time light ${this.config.flipDateHeaderTitle ? "align-right " : "align-left "}${this.timeClassForUrl(event.url)}`; timeWrapper.style.paddingLeft = "2px"; + timeWrapper.style.textAlign = this.config.flipDateHeaderTitle ? "right" : "left"; timeWrapper.innerHTML = moment(event.startDate, "x").format("LT"); // Add endDate to dataheaders if showEnd is enabled if (this.config.showEnd) { - timeWrapper.innerHTML += " - " + moment(event.endDate, "x").format("LT"); + timeWrapper.innerHTML += ` - ${this.capFirst(moment(event.endDate, "x").format("LT"))}`; } eventWrapper.appendChild(timeWrapper); - titleWrapper.classList.add("align-right"); - } - eventWrapper.appendChild(titleWrapper); + if (!this.config.flipDateHeaderTitle) titleWrapper.classList.add("align-right"); + } + if (!this.config.flipDateHeaderTitle) eventWrapper.appendChild(titleWrapper); } else { const timeWrapper = document.createElement("td"); @@ -348,7 +393,7 @@ Module.register("calendar", { // Ongoing and getRelative is set timeWrapper.innerHTML = this.capFirst( this.translate("RUNNING", { - fallback: this.translate("RUNNING") + " {timeUntilEnd}", + fallback: `${this.translate("RUNNING")} {timeUntilEnd}`, timeUntilEnd: moment(event.endDate, "x").fromNow(true) }) ); @@ -360,6 +405,8 @@ Module.register("calendar", { // Full days events within the next two days if (event.today) { timeWrapper.innerHTML = this.capFirst(this.translate("TODAY")); + } else if (event.yesterday) { + timeWrapper.innerHTML = this.capFirst(this.translate("YESTERDAY")); } else if (event.startDate - now < ONE_DAY && event.startDate - now > 0) { timeWrapper.innerHTML = this.capFirst(this.translate("TOMORROW")); } else if (event.startDate - now < 2 * ONE_DAY && event.startDate - now > 0) { @@ -377,8 +424,8 @@ Module.register("calendar", { } else { timeWrapper.innerHTML = this.capFirst( moment(event.startDate, "x").calendar(null, { - sameDay: this.config.showTimeToday ? "LT" : "[" + this.translate("TODAY") + "]", - nextDay: "[" + this.translate("TOMORROW") + "]", + sameDay: this.config.showTimeToday ? "LT" : `[${this.translate("TODAY")}]`, + nextDay: `[${this.translate("TOMORROW")}]`, nextWeek: "dddd", sameElse: event.fullDayEvent ? this.config.fullDayEventDateFormat : this.config.dateFormat }) @@ -388,6 +435,12 @@ Module.register("calendar", { // Full days events within the next two days if (event.today) { timeWrapper.innerHTML = this.capFirst(this.translate("TODAY")); + } else if (event.dayBeforeYesterday) { + if (this.translate("DAYBEFOREYESTERDAY") !== "DAYBEFOREYESTERDAY") { + timeWrapper.innerHTML = this.capFirst(this.translate("DAYBEFOREYESTERDAY")); + } + } else if (event.yesterday) { + timeWrapper.innerHTML = this.capFirst(this.translate("YESTERDAY")); } else if (event.startDate - now < ONE_DAY && event.startDate - now > 0) { timeWrapper.innerHTML = this.capFirst(this.translate("TOMORROW")); } else if (event.startDate - now < 2 * ONE_DAY && event.startDate - now > 0) { @@ -403,36 +456,50 @@ Module.register("calendar", { // Ongoing event timeWrapper.innerHTML = this.capFirst( this.translate("RUNNING", { - fallback: this.translate("RUNNING") + " {timeUntilEnd}", + fallback: `${this.translate("RUNNING")} {timeUntilEnd}`, timeUntilEnd: moment(event.endDate, "x").fromNow(true) }) ); } } - timeWrapper.className = "time light " + this.timeClassForUrl(event.url); + timeWrapper.className = `time light ${this.timeClassForUrl(event.url)}`; eventWrapper.appendChild(timeWrapper); } - wrapper.appendChild(eventWrapper); - // Create fade effect. if (index >= startFade) { currentFadeStep = index - startFade; eventWrapper.style.opacity = 1 - (1 / fadeSteps) * currentFadeStep; } + wrapper.appendChild(eventWrapper); if (this.config.showLocation) { if (event.location !== false) { const locationRow = document.createElement("tr"); - locationRow.className = "normal xsmall light"; + locationRow.className = "event-wrapper-location normal xsmall light"; if (event.today) locationRow.className += " today"; + else if (event.dayBeforeYesterday) locationRow.className += " dayBeforeYesterday"; + else if (event.yesterday) locationRow.className += " yesterday"; else if (event.tomorrow) locationRow.className += " tomorrow"; + else if (event.dayAfterTomorrow) locationRow.className += " dayAfterTomorrow"; if (this.config.displaySymbol) { const symbolCell = document.createElement("td"); locationRow.appendChild(symbolCell); } + if (this.config.coloredText) { + locationRow.style.cssText = `color:${this.colorForUrl(event.url, false)}`; + } + + if (this.config.coloredBackground) { + locationRow.style.backgroundColor = this.colorForUrl(event.url, true); + } + + if (this.config.coloredBorder) { + locationRow.style.borderColor = this.colorForUrl(event.url, false); + } + const descCell = document.createElement("td"); descCell.className = "location"; descCell.colSpan = "2"; @@ -510,6 +577,7 @@ Module.register("calendar", { for (const calendarUrl in this.calendarData) { const calendar = this.calendarData[calendarUrl]; let remainingEntries = this.maximumEntriesForUrl(calendarUrl); + let maxPastDaysCompare = now - this.maximumPastDaysForUrl(calendarUrl) * ONE_DAY; for (const e in calendar) { const event = JSON.parse(JSON.stringify(calendar[e])); // clone object @@ -518,7 +586,7 @@ Module.register("calendar", { continue; } if (limitNumberOfEntries) { - if (event.endDate < now) { + if (event.endDate < maxPastDaysCompare) { continue; } if (this.config.hideOngoing && event.startDate < now) { @@ -533,7 +601,10 @@ Module.register("calendar", { } event.url = calendarUrl; event.today = event.startDate >= today && event.startDate < today + ONE_DAY; + event.dayBeforeYesterday = event.startDate >= today - ONE_DAY * 2 && event.startDate < today - ONE_DAY; + event.yesterday = event.startDate >= today - ONE_DAY && event.startDate < today; event.tomorrow = !event.today && event.startDate >= today + ONE_DAY && event.startDate < today + 2 * ONE_DAY; + event.dayAfterTomorrow = !event.tomorrow && event.startDate >= today + ONE_DAY * 2 && event.startDate < today + 3 * ONE_DAY; /* if sliceMultiDayEvents is set to true, multiday events (events exceeding at least one midnight) are sliced into days, * otherwise, esp. in dateheaders mode it is not clear how long these events are. @@ -548,7 +619,7 @@ Module.register("calendar", { thisEvent.today = thisEvent.startDate >= today && thisEvent.startDate < today + ONE_DAY; thisEvent.tomorrow = !thisEvent.today && thisEvent.startDate >= today + ONE_DAY && thisEvent.startDate < today + 2 * ONE_DAY; thisEvent.endDate = midnight; - thisEvent.title += " (" + count + "/" + maxCount + ")"; + thisEvent.title += ` (${count}/${maxCount})`; splitEvents.push(thisEvent); event.startDate = midnight; @@ -556,7 +627,7 @@ Module.register("calendar", { midnight = moment(midnight, "x").add(1, "day").format("x"); // next day } // Last day - event.title += " (" + count + "/" + maxCount + ")"; + event.title += ` (${count}/${maxCount})`; event.today += event.startDate >= today && event.startDate < today + ONE_DAY; event.tomorrow = !event.today && event.startDate >= today + ONE_DAY && event.startDate < today + 2 * ONE_DAY; splitEvents.push(event); @@ -592,7 +663,7 @@ Module.register("calendar", { // check if we already are showing max unique days if (eventDate > lastDate) { // if the only entry in the first day is a full day event that day is not counted as unique - if (newEvents.length === 1 && days === 1 && newEvents[0].fullDayEvent) { + if (!this.config.limitDaysNeverSkip && newEvents.length === 1 && days === 1 && newEvents[0].fullDayEvent) { days--; } days++; @@ -633,6 +704,7 @@ Module.register("calendar", { excludedEvents: calendarConfig.excludedEvents || this.config.excludedEvents, maximumEntries: calendarConfig.maximumEntries || this.config.maximumEntries, maximumNumberOfDays: calendarConfig.maximumNumberOfDays || this.config.maximumNumberOfDays, + pastDaysCount: calendarConfig.pastDaysCount || this.config.pastDaysCount, fetchInterval: this.config.fetchInterval, symbolClass: calendarConfig.symbolClass, titleClass: calendarConfig.titleClass, @@ -665,7 +737,9 @@ Module.register("calendar", { if (typeof ev.symbol !== "undefined" && ev.symbol !== "") { let needle = new RegExp(ev.keyword, "gi"); if (needle.test(event.title)) { - symbols[0] = ev.symbol; + // Get the default prefix for this class name and add to the custom symbol provided + const className = this.getCalendarProperty(event.url, "symbolClassName", this.config.defaultSymbolClassName); + symbols[0] = className + ev.symbol; break; } } @@ -726,10 +800,11 @@ Module.register("calendar", { * Retrieves the color for a specific calendar url. * * @param {string} url The calendar url + * @param {boolean} isBg Determines if we fetch the bgColor or not * @returns {string} The color */ - colorForUrl: function (url) { - return this.getCalendarProperty(url, "color", "#fff"); + colorForUrl: function (url, isBg) { + return this.getCalendarProperty(url, isBg ? "bgColor" : "color", "#fff"); }, /** @@ -752,6 +827,16 @@ Module.register("calendar", { return this.getCalendarProperty(url, "maximumEntries", this.config.maximumEntries); }, + /** + * Retrieves the maximum count of past days which events of should be displayed for a specific calendar url. + * + * @param {string} url The calendar url + * @returns {number} The maximum past days count + */ + maximumPastDaysForUrl: function (url) { + return this.getCalendarProperty(url, "pastDaysCount", this.config.pastDaysCount); + }, + /** * Helper method to retrieve the property for a specific calendar url. * @@ -809,7 +894,7 @@ Module.register("calendar", { const word = words[i]; if (currentLine.length + word.length < (typeof maxLength === "number" ? maxLength : 25) - 1) { // max - 1 to account for a space - currentLine += word + " "; + currentLine += `${word} `; } else { line++; if (line > maxTitleLines - 1) { @@ -820,9 +905,9 @@ Module.register("calendar", { } if (currentLine.length > 0) { - temp += currentLine + "
" + word + " "; + temp += `${currentLine}
${word} `; } else { - temp += word + "
"; + temp += `${word}
`; } currentLine = ""; } @@ -831,7 +916,7 @@ Module.register("calendar", { return (temp + currentLine).trim(); } else { if (maxLength && typeof maxLength === "number" && string.length > maxLength) { - return string.trim().slice(0, maxLength) + "…"; + return `${string.trim().slice(0, maxLength)}…`; } else { return string.trim(); } @@ -886,7 +971,7 @@ Module.register("calendar", { for (const event of eventList) { event.symbol = this.symbolsForEvent(event); event.calendarName = this.calendarNameForUrl(event.url); - event.color = this.colorForUrl(event.url); + event.color = this.colorForUrl(event.url, false); delete event.url; } diff --git a/modules/default/calendar/calendarfetcher.js b/modules/default/calendar/calendarfetcher.js index 0798d1785c..00688ee2bb 100644 --- a/modules/default/calendar/calendarfetcher.js +++ b/modules/default/calendar/calendarfetcher.js @@ -4,13 +4,14 @@ * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ -const CalendarUtils = require("./calendarutils"); -const Log = require("logger"); -const NodeHelper = require("node_helper"); + +const https = require("https"); +const digest = require("digest-fetch"); const ical = require("node-ical"); const fetch = require("fetch"); -const digest = require("digest-fetch"); -const https = require("https"); +const Log = require("logger"); +const NodeHelper = require("node_helper"); +const CalendarUtils = require("./calendarutils"); /** * @@ -41,7 +42,7 @@ const CalendarFetcher = function (url, reloadInterval, excludedEvents, maximumEn let fetcher = null; let httpsAgent = null; let headers = { - "User-Agent": "Mozilla/5.0 (Node.js " + nodeVersion + ") MagicMirror/" + global.version + "User-Agent": `Mozilla/5.0 (Node.js ${nodeVersion}) MagicMirror/${global.version}` }; if (selfSignedCert) { @@ -51,11 +52,11 @@ const CalendarFetcher = function (url, reloadInterval, excludedEvents, maximumEn } if (auth) { if (auth.method === "bearer") { - headers.Authorization = "Bearer " + auth.pass; + headers.Authorization = `Bearer ${auth.pass}`; } else if (auth.method === "digest") { fetcher = new digest(auth.user, auth.pass).fetch(url, { headers: headers, agent: httpsAgent }); } else { - headers.Authorization = "Basic " + Buffer.from(auth.user + ":" + auth.pass).toString("base64"); + headers.Authorization = `Basic ${Buffer.from(`${auth.user}:${auth.pass}`).toString("base64")}`; } } if (fetcher === null) { @@ -70,7 +71,7 @@ const CalendarFetcher = function (url, reloadInterval, excludedEvents, maximumEn try { data = ical.parseICS(responseData); - Log.debug("parsed data=" + JSON.stringify(data)); + Log.debug(`parsed data=${JSON.stringify(data)}`); events = CalendarUtils.filterEvents(data, { excludedEvents, includePastEvents, @@ -114,7 +115,7 @@ const CalendarFetcher = function (url, reloadInterval, excludedEvents, maximumEn * Broadcast the existing events. */ this.broadcastEvents = function () { - Log.info("Calendar-Fetcher: Broadcasting " + events.length + " events."); + Log.info(`Calendar-Fetcher: Broadcasting ${events.length} events.`); eventsReceivedCallback(this); }; diff --git a/modules/default/calendar/calendarutils.js b/modules/default/calendar/calendarutils.js index 20c8ff0a25..64a7b9f461 100644 --- a/modules/default/calendar/calendarutils.js +++ b/modules/default/calendar/calendarutils.js @@ -8,10 +8,10 @@ /** * @external Moment */ -const moment = require("moment"); const path = require("path"); +const moment = require("moment"); const zoneTable = require(path.join(__dirname, "windowsZones.json")); -const Log = require("../../../js/logger.js"); +const Log = require("../../../js/logger"); const CalendarUtils = { /** @@ -29,7 +29,7 @@ const CalendarUtils = { Log.debug(" if no tz, guess based on now"); event.start.tz = moment.tz.guess(); } - Log.debug("initial tz=" + event.start.tz); + Log.debug(`initial tz=${event.start.tz}`); // if there is a start date specified if (event.start.tz) { @@ -37,7 +37,7 @@ const CalendarUtils = { if (event.start.tz.includes(" ")) { // use the lookup table to get theIANA name as moment and date don't know MS timezones let tz = CalendarUtils.getIanaTZFromMS(event.start.tz); - Log.debug("corrected TZ=" + tz); + Log.debug(`corrected TZ=${tz}`); // watch out for unregistered windows timezone names // if we had a successful lookup if (tz) { @@ -46,7 +46,7 @@ const CalendarUtils = { // Log.debug("corrected timezone="+event.start.tz) } } - Log.debug("corrected tz=" + event.start.tz); + Log.debug(`corrected tz=${event.start.tz}`); let current_offset = 0; // offset from TZ string or calculated let mm = 0; // date with tz or offset let start_offset = 0; // utc offset of created with tz @@ -57,18 +57,18 @@ const CalendarUtils = { let start_offset = parseInt(start_offsetString[0]); start_offset *= event.start.tz[1] === "-" ? -1 : 1; adjustHours = start_offset; - Log.debug("defined offset=" + start_offset + " hours"); + Log.debug(`defined offset=${start_offset} hours`); current_offset = start_offset; event.start.tz = ""; - Log.debug("ical offset=" + current_offset + " date=" + date); + Log.debug(`ical offset=${current_offset} date=${date}`); mm = moment(date); let x = parseInt(moment(new Date()).utcOffset()); - Log.debug("net mins=" + (current_offset * 60 - x)); + Log.debug(`net mins=${current_offset * 60 - x}`); mm = mm.add(x - current_offset * 60, "minutes"); adjustHours = (current_offset * 60 - x) / 60; event.start = mm.toDate(); - Log.debug("adjusted date=" + event.start); + Log.debug(`adjusted date=${event.start}`); } else { // get the start time in that timezone let es = moment(event.start); @@ -76,18 +76,18 @@ const CalendarUtils = { if (es.format("YYYY") < 2007) { es.set("year", 2013); // if so, use a closer date } - Log.debug("start date/time=" + es.toDate()); + Log.debug(`start date/time=${es.toDate()}`); start_offset = moment.tz(es, event.start.tz).utcOffset(); - Log.debug("start offset=" + start_offset); + Log.debug(`start offset=${start_offset}`); - Log.debug("start date/time w tz =" + moment.tz(moment(event.start), event.start.tz).toDate()); + Log.debug(`start date/time w tz =${moment.tz(moment(event.start), event.start.tz).toDate()}`); // get the specified date in that timezone mm = moment.tz(moment(date), event.start.tz); - Log.debug("event date=" + mm.toDate()); + Log.debug(`event date=${mm.toDate()}`); current_offset = mm.utcOffset(); } - Log.debug("event offset=" + current_offset + " hour=" + mm.format("H") + " event date=" + mm.toDate()); + Log.debug(`event offset=${current_offset} hour=${mm.format("H")} event date=${mm.toDate()}`); // if the offset is greater than 0, east of london if (current_offset !== start_offset) { @@ -113,7 +113,7 @@ const CalendarUtils = { } } } - Log.debug("adjustHours=" + adjustHours); + Log.debug(`adjustHours=${adjustHours}`); return adjustHours; }, @@ -138,7 +138,7 @@ const CalendarUtils = { return CalendarUtils.isFullDayEvent(event) ? moment(event[time], "YYYYMMDD") : moment(new Date(event[time])); }; - Log.debug("There are " + Object.entries(data).length + " calendar entries."); + Log.debug(`There are ${Object.entries(data).length} calendar entries.`); Object.entries(data).forEach(([key, event]) => { Log.debug("Processing entry..."); const now = new Date(); @@ -160,7 +160,7 @@ const CalendarUtils = { } if (event.type === "VEVENT") { - Log.debug("Event:\n" + JSON.stringify(event)); + Log.debug(`Event:\n${JSON.stringify(event)}`); let startDate = eventDate(event, "start"); let endDate; @@ -177,12 +177,12 @@ const CalendarUtils = { } } - Log.debug("start: " + startDate.toDate()); - Log.debug("end:: " + endDate.toDate()); + Log.debug(`start: ${startDate.toDate()}`); + Log.debug(`end:: ${endDate.toDate()}`); // Calculate the duration of the event for use with recurring events. let duration = parseInt(endDate.format("x")) - parseInt(startDate.format("x")); - Log.debug("duration: " + duration); + Log.debug(`duration: ${duration}`); // FIXME: Since the parsed json object from node-ical comes with time information // this check could be removed (?) @@ -191,7 +191,7 @@ const CalendarUtils = { } const title = CalendarUtils.getTitleFromEvent(event); - Log.debug("title: " + title); + Log.debug(`title: ${title}`); let excluded = false, dateFilter = null; @@ -271,8 +271,8 @@ const CalendarUtils = { pastLocal = pastMoment.toDate(); futureLocal = futureMoment.toDate(); - Log.debug("pastLocal: " + pastLocal); - Log.debug("futureLocal: " + futureLocal); + Log.debug(`pastLocal: ${pastLocal}`); + Log.debug(`futureLocal: ${futureLocal}`); } else { // if we want past events if (config.includePastEvents) { @@ -284,9 +284,9 @@ const CalendarUtils = { } futureLocal = futureMoment.toDate(); // future } - Log.debug("Search for recurring events between: " + pastLocal + " and " + futureLocal); + Log.debug(`Search for recurring events between: ${pastLocal} and ${futureLocal}`); const dates = rule.between(pastLocal, futureLocal, true, limitFunction); - Log.debug("Title: " + event.summary + ", with dates: " + JSON.stringify(dates)); + Log.debug(`Title: ${event.summary}, with dates: ${JSON.stringify(dates)}`); // The "dates" array contains the set of dates within our desired date range range that are valid // for the recurrence rule. *However*, it's possible for us to have a specific recurrence that // had its date changed from outside the range to inside the range. For the time being, @@ -294,7 +294,7 @@ const CalendarUtils = { // because the logic below will filter out any recurrences that don't actually belong within // our display range. // Would be great if there was a better way to handle this. - Log.debug("event.recurrences: " + event.recurrences); + Log.debug(`event.recurrences: ${event.recurrences}`); if (event.recurrences !== undefined) { for (let r in event.recurrences) { // Only add dates that weren't already in the range we added from the rrule so that @@ -323,10 +323,10 @@ const CalendarUtils = { let dateoffset = date.getTimezoneOffset(); // Reduce the time by the following offset. - Log.debug(" recurring date is " + date + " offset is " + dateoffset); + Log.debug(` recurring date is ${date} offset is ${dateoffset}`); let dh = moment(date).format("HH"); - Log.debug(" recurring date is " + date + " offset is " + dateoffset / 60 + " Hour is " + dh); + Log.debug(` recurring date is ${date} offset is ${dateoffset / 60} Hour is ${dh}`); if (CalendarUtils.isFullDayEvent(event)) { Log.debug("Fullday"); @@ -342,7 +342,7 @@ const CalendarUtils = { // the duration was calculated way back at the top before we could correct the start time.. // fix it for this event entry //duration = 24 * 60 * 60 * 1000; - Log.debug("new recurring date1 fulldate is " + date); + Log.debug(`new recurring date1 fulldate is ${date}`); } } else { // if the timezones are the same, correct date if needed @@ -357,7 +357,7 @@ const CalendarUtils = { // the duration was calculated way back at the top before we could correct the start time.. // fix it for this event entry //duration = 24 * 60 * 60 * 1000; - Log.debug("new recurring date2 fulldate is " + date); + Log.debug(`new recurring date2 fulldate is ${date}`); } //} } @@ -376,7 +376,7 @@ const CalendarUtils = { // the duration was calculated way back at the top before we could correct the start time.. // fix it for this event entry //duration = 24 * 60 * 60 * 1000; - Log.debug("new recurring date1 is " + date); + Log.debug(`new recurring date1 is ${date}`); } } else { // if the timezones are the same, correct date if needed @@ -391,13 +391,13 @@ const CalendarUtils = { // the duration was calculated way back at the top before we could correct the start time.. // fix it for this event entry //duration = 24 * 60 * 60 * 1000; - Log.debug("new recurring date2 is " + date); + Log.debug(`new recurring date2 is ${date}`); } //} } } startDate = moment(date); - Log.debug("Corrected startDate: " + startDate.toDate()); + Log.debug(`Corrected startDate: ${startDate.toDate()}`); let adjustDays = CalendarUtils.calculateTimezoneAdjustment(event, date); @@ -413,7 +413,7 @@ const CalendarUtils = { // This date is an exception date, which means we should skip it in the recurrence pattern. showRecurrence = false; } - Log.debug("duration: " + duration); + Log.debug(`duration: ${duration}`); endDate = moment(parseInt(startDate.format("x")) + duration, "x"); if (startDate.format("x") === endDate.format("x")) { @@ -433,7 +433,7 @@ const CalendarUtils = { } if (showRecurrence === true) { - Log.debug("saving event: " + description); + Log.debug(`saving event: ${description}`); addedEvents++; newEvents.push({ title: recurrenceTitle, @@ -573,7 +573,7 @@ const CalendarUtils = { if (filter) { const until = filter.split(" "), value = parseInt(until[0]), - increment = until[1].slice(-1) === "s" ? until[1] : until[1] + "s", // Massage the data for moment js + increment = until[1].slice(-1) === "s" ? until[1] : `${until[1]}s`, // Massage the data for moment js filterUntil = moment(endDate.format()).subtract(value, increment); return now < filterUntil.format("x"); diff --git a/modules/default/calendar/debug.js b/modules/default/calendar/debug.js index 08cd377006..5e19e13134 100644 --- a/modules/default/calendar/debug.js +++ b/modules/default/calendar/debug.js @@ -8,7 +8,7 @@ // Alias modules mentioned in package.js under _moduleAliases. require("module-alias/register"); -const CalendarFetcher = require("./calendarfetcher.js"); +const CalendarFetcher = require("./calendarfetcher"); const url = "https://calendar.google.com/calendar/ical/pkm1t2uedjbp0uvq1o7oj1jouo%40group.calendar.google.com/private-08ba559f89eec70dd74bbd887d0a3598/basic.ics"; // Standard test URL //const url = "https://www.googleapis.com/calendar/v3/calendars/primary/events/"; // URL for Bearer auth (must be configured in Google OAuth2 first) diff --git a/modules/default/calendar/node_helper.js b/modules/default/calendar/node_helper.js index 2121c30925..08e6158bda 100644 --- a/modules/default/calendar/node_helper.js +++ b/modules/default/calendar/node_helper.js @@ -5,13 +5,13 @@ * MIT Licensed. */ const NodeHelper = require("node_helper"); -const CalendarFetcher = require("./calendarfetcher.js"); const Log = require("logger"); +const CalendarFetcher = require("./calendarfetcher"); module.exports = NodeHelper.create({ // Override start method. start: function () { - Log.log("Starting node helper for: " + this.name); + Log.log(`Starting node helper for: ${this.name}`); this.fetchers = []; }, @@ -55,7 +55,7 @@ module.exports = NodeHelper.create({ let fetcher; if (typeof this.fetchers[identifier + url] === "undefined") { - Log.log("Create new calendarfetcher for url: " + url + " - Interval: " + fetchInterval); + Log.log(`Create new calendarfetcher for url: ${url} - Interval: ${fetchInterval}`); fetcher = new CalendarFetcher(url, fetchInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth, broadcastPastEvents, selfSignedCert); fetcher.onReceive((fetcher) => { @@ -73,7 +73,7 @@ module.exports = NodeHelper.create({ this.fetchers[identifier + url] = fetcher; } else { - Log.log("Use existing calendarfetcher for url: " + url); + Log.log(`Use existing calendarfetcher for url: ${url}`); fetcher = this.fetchers[identifier + url]; fetcher.broadcastEvents(); } diff --git a/modules/default/clock/clock.js b/modules/default/clock/clock.js index 31922a5809..595057c491 100644 --- a/modules/default/clock/clock.js +++ b/modules/default/clock/clock.js @@ -22,6 +22,7 @@ Module.register("clock", { showTime: true, showWeek: false, dateFormat: "dddd, LL", + sendNotifications: false, /* specific to the analog clock */ analogSize: "200px", @@ -45,7 +46,7 @@ Module.register("clock", { }, // Define start sequence. start: function () { - Log.info("Starting module: " + this.name); + Log.info(`Starting module: ${this.name}`); // Schedule update interval. this.second = moment().second(); @@ -66,23 +67,27 @@ Module.register("clock", { const notificationTimer = () => { this.updateDom(); - // If seconds is displayed CLOCK_SECOND-notification should be sent (but not when CLOCK_MINUTE-notification is sent) - if (this.config.displaySeconds) { - this.second = moment().second(); - if (this.second !== 0) { - this.sendNotification("CLOCK_SECOND", this.second); - setTimeout(notificationTimer, delayCalculator(0)); - return; + if (this.config.sendNotifications) { + // If seconds is displayed CLOCK_SECOND-notification should be sent (but not when CLOCK_MINUTE-notification is sent) + if (this.config.displaySeconds) { + this.second = moment().second(); + if (this.second !== 0) { + this.sendNotification("CLOCK_SECOND", this.second); + setTimeout(notificationTimer, delayCalculator(0)); + return; + } } + + // If minute changed or seconds isn't displayed send CLOCK_MINUTE-notification + this.minute = moment().minute(); + this.sendNotification("CLOCK_MINUTE", this.minute); } - // If minute changed or seconds isn't displayed send CLOCK_MINUTE-notification - this.minute = moment().minute(); - this.sendNotification("CLOCK_MINUTE", this.minute); setTimeout(notificationTimer, delayCalculator(0)); }; - // Set the initial timeout with the amount of seconds elapsed as reducedSeconds so it will trigger when the minute changes + // Set the initial timeout with the amount of seconds elapsed as + // reducedSeconds, so it will trigger when the minute changes setTimeout(notificationTimer, delayCalculator(this.second)); // Set locale. @@ -91,13 +96,13 @@ Module.register("clock", { // Override dom generator. getDom: function () { const wrapper = document.createElement("div"); - wrapper.classList.add("clockGrid"); + wrapper.classList.add("clock-grid"); /************************************ * Create wrappers for analog and digital clock */ const analogWrapper = document.createElement("div"); - analogWrapper.className = "clockCircle"; + analogWrapper.className = "clock-circle"; const digitalWrapper = document.createElement("div"); digitalWrapper.className = "digital"; digitalWrapper.style.gridArea = "center"; @@ -137,9 +142,9 @@ Module.register("clock", { } if (this.config.clockBold) { - timeString = now.format(hourSymbol + '[]mm[]'); + timeString = now.format(`${hourSymbol}[]mm[]`); } else { - timeString = now.format(hourSymbol + ":mm"); + timeString = now.format(`${hourSymbol}:mm`); } if (this.config.showDate) { @@ -172,7 +177,7 @@ Module.register("clock", { * @returns {string} The formatted time string */ function formatTime(config, time) { - let formatString = hourSymbol + ":mm"; + let formatString = `${hourSymbol}:mm`; if (config.showPeriod && config.timeFormat !== 24) { formatString += config.showPeriodUpper ? "A" : "a"; } @@ -195,19 +200,11 @@ Module.register("clock", { nextEvent = tomorrowSunTimes.sunrise; } const untilNextEvent = moment.duration(moment(nextEvent).diff(now)); - const untilNextEventString = untilNextEvent.hours() + "h " + untilNextEvent.minutes() + "m"; + const untilNextEventString = `${untilNextEvent.hours()}h ${untilNextEvent.minutes()}m`; sunWrapper.innerHTML = - ' ' + - untilNextEventString + - "" + - ' ' + - formatTime(this.config, sunTimes.sunrise) + - "" + - ' ' + - formatTime(this.config, sunTimes.sunset) + - ""; + ` ${untilNextEventString}` + + ` ${formatTime(this.config, sunTimes.sunrise)}` + + ` ${formatTime(this.config, sunTimes.sunset)}`; digitalWrapper.appendChild(sunWrapper); } @@ -226,19 +223,11 @@ Module.register("clock", { moonSet = nextMoonTimes.set; } const isVisible = now.isBetween(moonRise, moonSet) || moonTimes.alwaysUp === true; - const illuminatedFractionString = Math.round(moonIllumination.fraction * 100) + "%"; + const illuminatedFractionString = `${Math.round(moonIllumination.fraction * 100)}%`; moonWrapper.innerHTML = - ' ' + - illuminatedFractionString + - "" + - ' ' + - (moonRise ? formatTime(this.config, moonRise) : "...") + - "" + - ' ' + - (moonSet ? formatTime(this.config, moonSet) : "...") + - ""; + ` ${illuminatedFractionString}` + + ` ${moonRise ? formatTime(this.config, moonRise) : "..."}` + + ` ${moonSet ? formatTime(this.config, moonSet) : "..."}`; digitalWrapper.appendChild(moonWrapper); } @@ -266,7 +255,7 @@ Module.register("clock", { analogWrapper.style.height = this.config.analogSize; if (this.config.analogFace !== "" && this.config.analogFace !== "simple" && this.config.analogFace !== "none") { - analogWrapper.style.background = "url(" + this.data.path + "faces/" + this.config.analogFace + ".svg)"; + analogWrapper.style.background = `url(${this.data.path}faces/${this.config.analogFace}.svg)`; analogWrapper.style.backgroundSize = "100%"; // The following line solves issue: https://github.com/MichMich/MagicMirror/issues/611 @@ -276,16 +265,16 @@ Module.register("clock", { analogWrapper.style.border = "2px solid white"; } const clockFace = document.createElement("div"); - clockFace.className = "clockFace"; + clockFace.className = "clock-face"; const clockHour = document.createElement("div"); - clockHour.id = "clockHour"; - clockHour.style.transform = "rotate(" + hour + "deg)"; - clockHour.className = "clockHour"; + clockHour.id = "clock-hour"; + clockHour.style.transform = `rotate(${hour}deg)`; + clockHour.className = "clock-hour"; const clockMinute = document.createElement("div"); - clockMinute.id = "clockMinute"; - clockMinute.style.transform = "rotate(" + minute + "deg)"; - clockMinute.className = "clockMinute"; + clockMinute.id = "clock-minute"; + clockMinute.style.transform = `rotate(${minute}deg)`; + clockMinute.className = "clock-minute"; // Combine analog wrappers clockFace.appendChild(clockHour); @@ -293,9 +282,9 @@ Module.register("clock", { if (this.config.displaySeconds) { const clockSecond = document.createElement("div"); - clockSecond.id = "clockSecond"; - clockSecond.style.transform = "rotate(" + second + "deg)"; - clockSecond.className = "clockSecond"; + clockSecond.id = "clock-second"; + clockSecond.style.transform = `rotate(${second}deg)`; + clockSecond.className = "clock-second"; clockSecond.style.backgroundColor = this.config.secondsColor; clockFace.appendChild(clockSecond); } @@ -308,15 +297,15 @@ Module.register("clock", { if (this.config.displayType === "analog") { // Display only an analog clock if (this.config.analogShowDate === "top") { - wrapper.classList.add("clockGrid--bottom"); + wrapper.classList.add("clock-grid-bottom"); } else if (this.config.analogShowDate === "bottom") { - wrapper.classList.add("clockGrid--top"); + wrapper.classList.add("clock-grid-top"); } wrapper.appendChild(analogWrapper); } else if (this.config.displayType === "digital") { wrapper.appendChild(digitalWrapper); } else if (this.config.displayType === "both") { - wrapper.classList.add("clockGrid--" + this.config.analogPlacement); + wrapper.classList.add(`clock-grid-${this.config.analogPlacement}`); wrapper.appendChild(analogWrapper); wrapper.appendChild(digitalWrapper); } diff --git a/modules/default/clock/clock_styles.css b/modules/default/clock/clock_styles.css index e3eb7e94cc..e938dd2e8e 100644 --- a/modules/default/clock/clock_styles.css +++ b/modules/default/clock/clock_styles.css @@ -1,37 +1,37 @@ -.clockGrid { +.clock-grid { display: inline-flex; gap: 15px; } -.clockGrid--left { +.clock-grid-left { flex-direction: row; } -.clockGrid--right { +.clock-grid-right { flex-direction: row-reverse; } -.clockGrid--top { +.clock-grid-top { flex-direction: column; } -.clockGrid--bottom { +.clock-grid-bottom { flex-direction: column-reverse; } -.clockCircle { +.clock-circle { place-self: center; position: relative; border-radius: 50%; background-size: 100%; } -.clockFace { +.clock-face { width: 100%; height: 100%; } -.clockFace::after { +.clock-face::after { position: absolute; top: 50%; left: 50%; @@ -44,7 +44,7 @@ display: block; } -.clockHour { +.clock-hour { width: 0; height: 0; position: absolute; @@ -57,7 +57,7 @@ border-radius: 3px 0 0 3px; } -.clockMinute { +.clock-minute { width: 0; height: 0; position: absolute; @@ -70,7 +70,7 @@ border-radius: 3px 0 0 3px; } -.clockSecond { +.clock-second { width: 0; height: 0; position: absolute; diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index a1fffb8455..555bfc4678 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -33,16 +33,15 @@ Module.register("compliments", { }, // Define start sequence. - start: function () { - Log.info("Starting module: " + this.name); + start: async function () { + Log.info(`Starting module: ${this.name}`); this.lastComplimentIndex = -1; if (this.config.remoteFile !== null) { - this.loadComplimentFile().then((response) => { - this.config.compliments = JSON.parse(response); - this.updateDom(); - }); + const response = await this.loadComplimentFile(); + this.config.compliments = JSON.parse(response); + this.updateDom(); } // Schedule update timer. diff --git a/modules/default/newsfeed/newsfeed.css b/modules/default/newsfeed/newsfeed.css index ea65eca294..2c690a48e2 100644 --- a/modules/default/newsfeed/newsfeed.css +++ b/modules/default/newsfeed/newsfeed.css @@ -1,5 +1,6 @@ iframe.newsfeed-fullarticle { width: 100vw; + /* very large height value to allow scrolling */ height: 3000px; top: 0; diff --git a/modules/default/newsfeed/newsfeed.js b/modules/default/newsfeed/newsfeed.js index 6b3bba7d29..320c5a5dc8 100644 --- a/modules/default/newsfeed/newsfeed.js +++ b/modules/default/newsfeed/newsfeed.js @@ -44,7 +44,7 @@ Module.register("newsfeed", { getUrlPrefix: function (item) { if (item.useCorsProxy) { - return location.protocol + "//" + location.host + "/cors?url="; + return `${location.protocol}//${location.host}/cors?url=`; } else { return ""; } @@ -70,7 +70,7 @@ Module.register("newsfeed", { // Define start sequence. start: function () { - Log.info("Starting module: " + this.name); + Log.info(`Starting module: ${this.name}`); // Set locale. moment.locale(config.language); @@ -346,7 +346,7 @@ Module.register("newsfeed", { this.activeItem = 0; } this.resetDescrOrFullArticleAndTimer(); - Log.debug(this.name + " - going from article #" + before + " to #" + this.activeItem + " (of " + this.newsItems.length + ")"); + Log.debug(`${this.name} - going from article #${before} to #${this.activeItem} (of ${this.newsItems.length})`); this.updateDom(100); } else if (notification === "ARTICLE_PREVIOUS") { this.activeItem--; @@ -354,7 +354,7 @@ Module.register("newsfeed", { this.activeItem = this.newsItems.length - 1; } this.resetDescrOrFullArticleAndTimer(); - Log.debug(this.name + " - going from article #" + before + " to #" + this.activeItem + " (of " + this.newsItems.length + ")"); + Log.debug(`${this.name} - going from article #${before} to #${this.activeItem} (of ${this.newsItems.length})`); this.updateDom(100); } // if "more details" is received the first time: show article summary, on second time show full article @@ -363,8 +363,8 @@ Module.register("newsfeed", { if (this.config.showFullArticle === true) { this.scrollPosition += this.config.scrollLength; window.scrollTo(0, this.scrollPosition); - Log.debug(this.name + " - scrolling down"); - Log.debug(this.name + " - ARTICLE_MORE_DETAILS, scroll position: " + this.config.scrollLength); + Log.debug(`${this.name} - scrolling down`); + Log.debug(`${this.name} - ARTICLE_MORE_DETAILS, scroll position: ${this.config.scrollLength}`); } else { this.showFullArticle(); } @@ -372,12 +372,12 @@ Module.register("newsfeed", { if (this.config.showFullArticle === true) { this.scrollPosition -= this.config.scrollLength; window.scrollTo(0, this.scrollPosition); - Log.debug(this.name + " - scrolling up"); - Log.debug(this.name + " - ARTICLE_SCROLL_UP, scroll position: " + this.config.scrollLength); + Log.debug(`${this.name} - scrolling up`); + Log.debug(`${this.name} - ARTICLE_SCROLL_UP, scroll position: ${this.config.scrollLength}`); } } else if (notification === "ARTICLE_LESS_DETAILS") { this.resetDescrOrFullArticleAndTimer(); - Log.debug(this.name + " - showing only article titles again"); + Log.debug(`${this.name} - showing only article titles again`); this.updateDom(100); } else if (notification === "ARTICLE_TOGGLE_FULL") { if (this.config.showFullArticle) { @@ -406,7 +406,7 @@ Module.register("newsfeed", { } clearInterval(this.timer); this.timer = null; - Log.debug(this.name + " - showing " + this.isShowingDescription ? "article description" : "full article"); + Log.debug(`${this.name} - showing ${this.isShowingDescription ? "article description" : "full article"}`); this.updateDom(100); } }); diff --git a/modules/default/newsfeed/newsfeedfetcher.js b/modules/default/newsfeed/newsfeedfetcher.js index be979b9311..039a3ea587 100644 --- a/modules/default/newsfeed/newsfeedfetcher.js +++ b/modules/default/newsfeed/newsfeedfetcher.js @@ -4,12 +4,13 @@ * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ -const Log = require("logger"); + +const stream = require("stream"); const FeedMe = require("feedme"); -const NodeHelper = require("node_helper"); -const fetch = require("fetch"); const iconv = require("iconv-lite"); -const stream = require("stream"); +const fetch = require("fetch"); +const Log = require("logger"); +const NodeHelper = require("node_helper"); /** * Responsible for requesting an update on the set interval and broadcasting the data. @@ -64,15 +65,14 @@ const NewsfeedFetcher = function (url, reloadInterval, encoding, logFeedWarnings } else if (logFeedWarnings) { Log.warn("Can't parse feed item:"); Log.warn(item); - Log.warn("Title: " + title); - Log.warn("Description: " + description); - Log.warn("Pubdate: " + pubdate); + Log.warn(`Title: ${title}`); + Log.warn(`Description: ${description}`); + Log.warn(`Pubdate: ${pubdate}`); } }); parser.on("end", () => { this.broadcastItems(); - scheduleTimer(); }); parser.on("error", (error) => { @@ -80,22 +80,27 @@ const NewsfeedFetcher = function (url, reloadInterval, encoding, logFeedWarnings scheduleTimer(); }); + //"end" event is not broadcast if the feed is empty but "finish" is used for both + parser.on("finish", () => { + scheduleTimer(); + }); + parser.on("ttl", (minutes) => { try { // 86400000 = 24 hours is mentioned in the docs as maximum value: const ttlms = Math.min(minutes * 60 * 1000, 86400000); if (ttlms > reloadInterval) { reloadInterval = ttlms; - Log.info("Newsfeed-Fetcher: reloadInterval set to ttl=" + reloadInterval + " for url " + url); + Log.info(`Newsfeed-Fetcher: reloadInterval set to ttl=${reloadInterval} for url ${url}`); } } catch (error) { - Log.warn("Newsfeed-Fetcher: feed ttl is no valid integer=" + minutes + " for url " + url); + Log.warn(`Newsfeed-Fetcher: feed ttl is no valid integer=${minutes} for url ${url}`); } }); const nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]); const headers = { - "User-Agent": "Mozilla/5.0 (Node.js " + nodeVersion + ") MagicMirror/" + global.version, + "User-Agent": `Mozilla/5.0 (Node.js ${nodeVersion}) MagicMirror/${global.version}`, "Cache-Control": "max-age=0, no-cache, no-store, must-revalidate", Pragma: "no-cache" }; @@ -155,7 +160,7 @@ const NewsfeedFetcher = function (url, reloadInterval, encoding, logFeedWarnings Log.info("Newsfeed-Fetcher: No items to broadcast yet."); return; } - Log.info("Newsfeed-Fetcher: Broadcasting " + items.length + " items."); + Log.info(`Newsfeed-Fetcher: Broadcasting ${items.length} items.`); itemsReceivedCallback(this); }; diff --git a/modules/default/newsfeed/node_helper.js b/modules/default/newsfeed/node_helper.js index 13b0f94aa2..534b702033 100644 --- a/modules/default/newsfeed/node_helper.js +++ b/modules/default/newsfeed/node_helper.js @@ -6,13 +6,13 @@ */ const NodeHelper = require("node_helper"); -const NewsfeedFetcher = require("./newsfeedfetcher.js"); const Log = require("logger"); +const NewsfeedFetcher = require("./newsfeedfetcher"); module.exports = NodeHelper.create({ // Override start method. start: function () { - Log.log("Starting node helper for: " + this.name); + Log.log(`Starting node helper for: ${this.name}`); this.fetchers = []; }, @@ -47,7 +47,7 @@ module.exports = NodeHelper.create({ let fetcher; if (typeof this.fetchers[url] === "undefined") { - Log.log("Create new newsfetcher for url: " + url + " - Interval: " + reloadInterval); + Log.log(`Create new newsfetcher for url: ${url} - Interval: ${reloadInterval}`); fetcher = new NewsfeedFetcher(url, reloadInterval, encoding, config.logFeedWarnings, useCorsProxy); fetcher.onReceive(() => { @@ -64,7 +64,7 @@ module.exports = NodeHelper.create({ this.fetchers[url] = fetcher; } else { - Log.log("Use existing newsfetcher for url: " + url); + Log.log(`Use existing newsfetcher for url: ${url}`); fetcher = this.fetchers[url]; fetcher.setReloadInterval(reloadInterval); fetcher.broadcastItems(); diff --git a/modules/default/updatenotification/git_helper.js b/modules/default/updatenotification/git_helper.js index 80cb75320a..b4e0299c18 100644 --- a/modules/default/updatenotification/git_helper.js +++ b/modules/default/updatenotification/git_helper.js @@ -36,7 +36,7 @@ class GitHelper { async add(moduleName) { let moduleFolder = BASE_DIR; - if (moduleName !== "default") { + if (moduleName !== "MagicMirror") { moduleFolder = `${moduleFolder}modules/${moduleName}`; } @@ -68,7 +68,7 @@ class GitHelper { isBehindInStatus: false }; - if (repo.module === "default") { + if (repo.module === "MagicMirror") { // the hash is only needed for the mm repo const { stderr, stdout } = await this.execShell(`cd ${repo.folder} && git rev-parse HEAD`); @@ -117,11 +117,11 @@ class GitHelper { return; } - if (gitInfo.isBehindInStatus) { + if (gitInfo.isBehindInStatus && (gitInfo.module !== "MagicMirror" || gitInfo.current !== "master")) { return gitInfo; } - const { stderr } = await this.execShell(`cd ${repo.folder} && git fetch --dry-run`); + const { stderr } = await this.execShell(`cd ${repo.folder} && git fetch -n --dry-run`); // example output: // From https://github.com/MichMich/MagicMirror @@ -129,16 +129,41 @@ class GitHelper { // here the result is in stderr (this is a git default, don't ask why ...) const matches = stderr.match(this.getRefRegex(gitInfo.current)); - if (!matches || !matches[0]) { - // no refs found, nothing to do - return; + // this is the default if there was no match from "git fetch -n --dry-run". + // Its a fallback because if there was a real "git fetch", the above "git fetch -n --dry-run" would deliver nothing. + let refDiff = `${gitInfo.current}..origin/${gitInfo.current}`; + if (matches && matches[0]) { + refDiff = matches[0]; } // get behind with refs try { - const { stdout } = await this.execShell(`cd ${repo.folder} && git rev-list --ancestry-path --count ${matches[0]}`); + const { stdout } = await this.execShell(`cd ${repo.folder} && git rev-list --ancestry-path --count ${refDiff}`); gitInfo.behind = parseInt(stdout); + // for MagicMirror-Repo and "master" branch avoid getting notified when no tag is in refDiff + // so only releases are reported and we can change e.g. the README.md without sending notifications + if (gitInfo.behind > 0 && gitInfo.module === "MagicMirror" && gitInfo.current === "master") { + let tagList = ""; + try { + const { stdout } = await this.execShell(`cd ${repo.folder} && git ls-remote -q --tags --refs`); + tagList = stdout.trim(); + } catch (err) { + Log.error(`Failed to get tag list for ${repo.module}: ${err}`); + } + // check if tag is between commits and only report behind > 0 if so + try { + const { stdout } = await this.execShell(`cd ${repo.folder} && git rev-list --ancestry-path ${refDiff}`); + let cnt = 0; + for (const ref of stdout.trim().split("\n")) { + if (tagList.includes(ref)) cnt++; // tag found + } + if (cnt === 0) gitInfo.behind = 0; + } catch (err) { + Log.error(`Failed to get git revisions for ${repo.module}: ${err}`); + } + } + return gitInfo; } catch (err) { Log.error(`Failed to get git revisions for ${repo.module}: ${err}`); diff --git a/modules/default/updatenotification/node_helper.js b/modules/default/updatenotification/node_helper.js index a0e6830509..ae3e03751d 100644 --- a/modules/default/updatenotification/node_helper.js +++ b/modules/default/updatenotification/node_helper.js @@ -1,6 +1,6 @@ -const GitHelper = require("./git_helper"); -const defaultModules = require("../defaultmodules"); const NodeHelper = require("node_helper"); +const defaultModules = require("../defaultmodules"); +const GitHelper = require("./git_helper"); const ONE_MINUTE = 60 * 1000; @@ -19,7 +19,9 @@ module.exports = NodeHelper.create({ } } - await this.gitHelper.add("default"); + if (!this.ignoreUpdateChecking("MagicMirror")) { + await this.gitHelper.add("MagicMirror"); + } }, async socketNotificationReceived(notification, payload) { diff --git a/modules/default/updatenotification/updatenotification.js b/modules/default/updatenotification/updatenotification.js index 7b4945c914..602e76f464 100644 --- a/modules/default/updatenotification/updatenotification.js +++ b/modules/default/updatenotification/updatenotification.js @@ -77,7 +77,7 @@ Module.register("updatenotification", { addFilters() { this.nunjucksEnvironment().addFilter("diffLink", (text, status) => { - if (status.module !== "default") { + if (status.module !== "MagicMirror") { return text; } diff --git a/modules/default/updatenotification/updatenotification.njk b/modules/default/updatenotification/updatenotification.njk index 3149816f0b..77d7975413 100644 --- a/modules/default/updatenotification/updatenotification.njk +++ b/modules/default/updatenotification/updatenotification.njk @@ -3,7 +3,7 @@
- {% set mainTextLabel = "UPDATE_NOTIFICATION" if name === "default" else "UPDATE_NOTIFICATION_MODULE" %} + {% set mainTextLabel = "UPDATE_NOTIFICATION" if name === "MagicMirror" else "UPDATE_NOTIFICATION_MODULE" %} {{ mainTextLabel | translate({MODULE_NAME: name}) }}
diff --git a/modules/default/utils.js b/modules/default/utils.js index fb2cab8f31..604ab0431f 100644 --- a/modules/default/utils.js +++ b/modules/default/utils.js @@ -5,8 +5,8 @@ * @param {string} type what contenttype to expect in the response, can be "json" or "xml" * @param {boolean} useCorsProxy A flag to indicate * @param {Array.<{name: string, value:string}>} requestHeaders the HTTP headers to send - * @param {Array.} expectedResponseHeaders the expected HTTP headers to recieve - * @returns {Promise} resolved when the fetch is done. The response headers is placed in a headers-property (provided the response does not allready contain a headers-property). + * @param {Array.} expectedResponseHeaders the expected HTTP headers to receive + * @returns {Promise} resolved when the fetch is done. The response headers is placed in a headers-property (provided the response does not already contain a headers-property). */ async function performWebRequest(url, type = "json", useCorsProxy = false, requestHeaders = undefined, expectedResponseHeaders = undefined) { const request = {}; @@ -36,7 +36,7 @@ async function performWebRequest(url, type = "json", useCorsProxy = false, reque * * @param {string} url the url to fetch from * @param {Array.<{name: string, value:string}>} requestHeaders the HTTP headers to send - * @param {Array.} expectedResponseHeaders the expected HTTP headers to recieve + * @param {Array.} expectedResponseHeaders the expected HTTP headers to receive * @returns {string} to be used as URL when calling CORS-method on server. */ const getCorsUrl = function (url, requestHeaders, expectedResponseHeaders) { @@ -84,7 +84,7 @@ const getRequestHeaderString = function (requestHeaders) { }; /** - * Gets headers and values to attatch to the web request. + * Gets headers and values to attach to the web request. * * @param {Array.<{name: string, value:string}>} requestHeaders the HTTP headers to send * @returns {object} An object specifying name and value of the headers. @@ -101,9 +101,9 @@ const getHeadersToSend = (requestHeaders) => { }; /** - * Gets the part of the CORS URL that represents the expected HTTP headers to recieve. + * Gets the part of the CORS URL that represents the expected HTTP headers to receive. * - * @param {Array.} expectedResponseHeaders the expected HTTP headers to recieve + * @param {Array.} expectedResponseHeaders the expected HTTP headers to receive * @returns {string} to be used as the expected HTTP-headers component in CORS URL. */ const getExpectedResponseHeadersString = function (expectedResponseHeaders) { @@ -124,7 +124,7 @@ const getExpectedResponseHeadersString = function (expectedResponseHeaders) { /** * Gets the values for the expected headers from the response. * - * @param {Array.} expectedResponseHeaders the expected HTTP headers to recieve + * @param {Array.} expectedResponseHeaders the expected HTTP headers to receive * @param {Response} response the HTTP response * @returns {string} to be used as the expected HTTP-headers component in CORS URL. */ diff --git a/modules/default/weather/current.njk b/modules/default/weather/current.njk index ae542caa9a..df673afeef 100644 --- a/modules/default/weather/current.njk +++ b/modules/default/weather/current.njk @@ -7,7 +7,7 @@ {% if config.showWindDirection %} {% if config.showWindDirectionAsArrow %} - + {% else %} {{ current.cardinalWindDirection() | translate }} {% endif %} @@ -16,7 +16,7 @@ {% endif %} {% if config.showHumidity and current.humidity %} - {{ current.humidity | decimalSymbol }}  + {{ current.humidity | decimalSymbol }}  {% endif %} {% if config.showSun %} @@ -54,16 +54,21 @@ {% endif %} - {% if (config.showFeelsLike or config.showPrecipitationAmount) and not config.onlyTemp %} + {% if (config.showFeelsLike or config.showPrecipitationAmount or config.showPrecipitationProbability) and not config.onlyTemp %}
{% if config.showFeelsLike %} {{ "FEELS" | translate({DEGREE: current.feelsLike() | roundValue | unit("temperature") | decimalSymbol }) }} - +
+ {% endif %} + {% if config.showPrecipitationAmount and current.precipitationAmount %} + + {{ "PRECIP_AMOUNT" | translate }} {{ current.precipitationAmount | unit("precip", current.precipitationUnits) }} +
{% endif %} - {% if config.showPrecipitationAmount %} + {% if config.showPrecipitationProbability and current.precipitationProbability %} - {{ "PRECIP" | translate }} {{ current.precipitation | unit("precip") }} + {{ "PRECIP_POP" | translate }} {{ current.precipitationProbability }}% {% endif %}
diff --git a/modules/default/weather/forecast.njk b/modules/default/weather/forecast.njk index 2bac7eae4b..0ea390f0a5 100644 --- a/modules/default/weather/forecast.njk +++ b/modules/default/weather/forecast.njk @@ -23,15 +23,14 @@ {{ f.minTemperature | roundValue | unit("temperature") | decimalSymbol }} {% if config.showPrecipitationAmount %} - {% if f.precipitationUnits %} - - {{ f.precipitation }}{{ f.precipitationUnits }} - - {% else %} - - {{ f.precipitation | unit("precip") }} - - {% endif %} + + {{ f.precipitationAmount | unit("precip", f.precipitationUnits) }} + + {% endif %} + {% if config.showPrecipitationProbability %} + + {{ f.precipitationProbability | unit("precip", "%") }} + {% endif %} {% set currentStep = currentStep + 1 %} diff --git a/modules/default/weather/hourly.njk b/modules/default/weather/hourly.njk index f58d31a0cf..a0699fab39 100644 --- a/modules/default/weather/hourly.njk +++ b/modules/default/weather/hourly.njk @@ -11,15 +11,14 @@ {{ hour.temperature | roundValue | unit("temperature") }} {% if config.showPrecipitationAmount %} - {% if hour.precipitationUnits %} - - {{ hour.precipitation }}{{ hour.precipitationUnits }} - - {% else %} - - {{ hour.precipitation | unit("precip") }} - - {% endif %} + + {{ hour.precipitationAmount | unit("precip", hour.precipitationUnits) }} + + {% endif %} + {% if config.showPrecipitationProbability %} + + {{ hour.precipitationProbability | unit("precip", "%") }} + {% endif %} {% set currentStep = currentStep + 1 %} diff --git a/modules/default/weather/providers/envcanada.js b/modules/default/weather/providers/envcanada.js index 4842446be6..39ddba2a1c 100644 --- a/modules/default/weather/providers/envcanada.js +++ b/modules/default/weather/providers/envcanada.js @@ -138,7 +138,7 @@ WeatherProvider.register("envcanada", { // being accessed. This is only pertinent when using the EC data elements that contain a textual forecast. // getUrl() { - return "https://dd.weather.gc.ca/citypage_weather/xml/" + this.config.provCode + "/" + this.config.siteCode + "_e.xml"; + return `https://dd.weather.gc.ca/citypage_weather/xml/${this.config.provCode}/${this.config.siteCode}_e.xml`; }, // @@ -165,7 +165,7 @@ WeatherProvider.register("envcanada", { currentWeather.windSpeed = WeatherUtils.convertWindToMs(ECdoc.querySelector("siteData currentConditions wind speed").textContent); - currentWeather.windDirection = ECdoc.querySelector("siteData currentConditions wind bearing").textContent; + currentWeather.windFromDirection = ECdoc.querySelector("siteData currentConditions wind bearing").textContent; currentWeather.humidity = ECdoc.querySelector("siteData currentConditions relativeHumidity").textContent; @@ -230,12 +230,7 @@ WeatherProvider.register("envcanada", { const foreGroup = ECdoc.querySelectorAll("siteData forecastGroup forecast"); - // For simplicity, we will only accumulate precipitation and will not try to break out - // rain vs snow accumulations - - weather.rain = null; - weather.snow = null; - weather.precipitation = null; + weather.precipitationAmount = null; // // The EC forecast is held in a 12-element array - Elements 0 to 11 - with each day encompassing @@ -336,16 +331,14 @@ WeatherProvider.register("envcanada", { // Add 1 to the date to reflect the current forecast day we are building lastDate = lastDate.add(1, "day"); - weather.date = moment.unix(lastDate); + weather.date = moment(lastDate); // Capture the temperatures for the current Element and the next Element in order to set // the Min and Max temperatures for the forecast this.setMinMaxTemps(weather, foreGroup, stepDay, true, currentTemp); - weather.rain = null; - weather.snow = null; - weather.precipitation = null; + weather.precipitationAmount = null; this.setPrecipitation(weather, foreGroup, stepDay); @@ -402,8 +395,7 @@ WeatherProvider.register("envcanada", { const precipLOP = hourGroup[stepHour].querySelector("lop").textContent * 1.0; if (precipLOP > 0) { - weather.precipitation = precipLOP; - weather.precipitationUnits = hourGroup[stepHour].querySelector("lop").getAttribute("units"); + weather.precipitationProbability = precipLOP; } // @@ -508,27 +500,14 @@ WeatherProvider.register("envcanada", { setPrecipitation(weather, foreGroup, today) { if (foreGroup[today].querySelector("precipitation accumulation")) { - weather.precipitation = foreGroup[today].querySelector("precipitation accumulation amount").textContent * 1.0; - - weather.precipitationUnits = " " + foreGroup[today].querySelector("precipitation accumulation amount").getAttribute("units"); - - if (this.config.units === "imperial") { - if (weather.precipitationUnits === " cm") { - weather.precipitation = (weather.precipitation * 0.394).toFixed(2); - weather.precipitationUnits = " in"; - } - if (weather.precipitationUnits === " mm") { - weather.precipitation = (weather.precipitation * 0.0394).toFixed(2); - weather.precipitationUnits = " in"; - } - } + weather.precipitationAmount = foreGroup[today].querySelector("precipitation accumulation amount").textContent * 1.0; + weather.precipitationUnits = foreGroup[today].querySelector("precipitation accumulation amount").getAttribute("units"); } // Check Today element for POP if (foreGroup[today].querySelector("abbreviatedForecast pop").textContent > 0) { - weather.precipitation = foreGroup[today].querySelector("abbreviatedForecast pop").textContent; - weather.precipitationUnits = foreGroup[today].querySelector("abbreviatedForecast pop").getAttribute("units"); + weather.precipitationProbability = foreGroup[today].querySelector("abbreviatedForecast pop").textContent; } }, diff --git a/modules/default/weather/providers/openmeteo.js b/modules/default/weather/providers/openmeteo.js index 83583d5cee..9d95aea1f7 100644 --- a/modules/default/weather/providers/openmeteo.js +++ b/modules/default/weather/providers/openmeteo.js @@ -24,7 +24,7 @@ WeatherProvider.register("openmeteo", { apiBase: OPEN_METEO_BASE, lat: 0, lon: 0, - past_days: 0, + pastDays: 0, type: "current" }, @@ -227,12 +227,12 @@ WeatherProvider.register("openmeteo", { longitude: this.config.lon, timeformat: "unixtime", timezone: "auto", - past_days: this.config.past_days ?? 0, + past_days: this.config.pastDays ?? 0, daily: this.dailyParams, hourly: this.hourlyParams, // Fixed units as metric temperature_unit: "celsius", - windspeed_unit: "kmh", + windspeed_unit: "ms", precipitation_unit: "mm" }; @@ -264,9 +264,9 @@ WeatherProvider.register("openmeteo", { switch (key) { case "hourly": case "daily": - return encodeURIComponent(key) + "=" + params[key].join(","); + return `${encodeURIComponent(key)}=${params[key].join(",")}`; default: - return encodeURIComponent(key) + "=" + encodeURIComponent(params[key]); + return `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`; } }) .join("&"); @@ -367,11 +367,11 @@ WeatherProvider.register("openmeteo", { * `current_weather` object. */ const h = moment().hour(); - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const currentWeather = new WeatherObject(); currentWeather.date = weather.current_weather.time; currentWeather.windSpeed = weather.current_weather.windspeed; - currentWeather.windDirection = weather.current_weather.winddirection; + currentWeather.windFromDirection = weather.current_weather.winddirection; currentWeather.sunrise = weather.daily[0].sunrise; currentWeather.sunset = weather.daily[0].sunset; currentWeather.temperature = parseFloat(weather.current_weather.temperature); @@ -381,7 +381,7 @@ WeatherProvider.register("openmeteo", { currentWeather.humidity = parseFloat(weather.hourly[h].relativehumidity_2m); currentWeather.rain = parseFloat(weather.hourly[h].rain); currentWeather.snow = parseFloat(weather.hourly[h].snowfall * 10); - currentWeather.precipitation = parseFloat(weather.hourly[h].precipitation); + currentWeather.precipitationAmount = parseFloat(weather.hourly[h].precipitation); return currentWeather; }, @@ -391,11 +391,11 @@ WeatherProvider.register("openmeteo", { const days = []; weathers.daily.forEach((weather, i) => { - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const currentWeather = new WeatherObject(); currentWeather.date = weather.time; currentWeather.windSpeed = weather.windspeed_10m_max; - currentWeather.windDirection = weather.winddirection_10m_dominant; + currentWeather.windFromDirection = weather.winddirection_10m_dominant; currentWeather.sunrise = weather.sunrise; currentWeather.sunset = weather.sunset; currentWeather.temperature = parseFloat((weather.apparent_temperature_max + weather.apparent_temperature_min) / 2); @@ -404,7 +404,7 @@ WeatherProvider.register("openmeteo", { currentWeather.weatherType = this.convertWeatherType(weather.weathercode, currentWeather.isDayTime()); currentWeather.rain = parseFloat(weather.rain_sum); currentWeather.snow = parseFloat(weather.snowfall_sum * 10); - currentWeather.precipitation = parseFloat(weather.precipitation_sum); + currentWeather.precipitationAmount = parseFloat(weather.precipitation_sum); days.push(currentWeather); }); @@ -422,12 +422,12 @@ WeatherProvider.register("openmeteo", { return; } - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const currentWeather = new WeatherObject(); const h = Math.ceil((i + 1) / 24) - 1; currentWeather.date = weather.time; currentWeather.windSpeed = weather.windspeed_10m; - currentWeather.windDirection = weather.winddirection_10m; + currentWeather.windFromDirection = weather.winddirection_10m; currentWeather.sunrise = weathers.daily[h].sunrise; currentWeather.sunset = weathers.daily[h].sunset; currentWeather.temperature = parseFloat(weather.apparent_temperature); @@ -437,7 +437,7 @@ WeatherProvider.register("openmeteo", { currentWeather.humidity = parseFloat(weather.relativehumidity_2m); currentWeather.rain = parseFloat(weather.rain); currentWeather.snow = parseFloat(weather.snowfall * 10); - currentWeather.precipitation = parseFloat(weather.precipitation); + currentWeather.precipitationAmount = parseFloat(weather.precipitation); hours.push(currentWeather); }); diff --git a/modules/default/weather/providers/openweathermap.js b/modules/default/weather/providers/openweathermap.js index f5f786fa01..d1bd378c55 100644 --- a/modules/default/weather/providers/openweathermap.js +++ b/modules/default/weather/providers/openweathermap.js @@ -132,7 +132,7 @@ WeatherProvider.register("openweathermap", { currentWeather.temperature = currentWeatherData.main.temp; currentWeather.feelsLikeTemp = currentWeatherData.main.feels_like; currentWeather.windSpeed = currentWeatherData.wind.speed; - currentWeather.windDirection = currentWeatherData.wind.deg; + currentWeather.windFromDirection = currentWeatherData.wind.deg; currentWeather.weatherType = this.convertWeatherType(currentWeatherData.weather[0].icon); currentWeather.sunrise = moment.unix(currentWeatherData.sys.sunrise); currentWeather.sunset = moment.unix(currentWeatherData.sys.sunset); @@ -145,9 +145,9 @@ WeatherProvider.register("openweathermap", { */ generateWeatherObjectsFromForecast(forecasts) { if (this.config.weatherEndpoint === "/forecast") { - return this.fetchForecastHourly(forecasts); + return this.generateForecastHourly(forecasts); } else if (this.config.weatherEndpoint === "/forecast/daily") { - return this.fetchForecastDaily(forecasts); + return this.generateForecastDaily(forecasts); } // if weatherEndpoint does not match forecast or forecast/daily, what should be returned? return [new WeatherObject()]; @@ -165,9 +165,10 @@ WeatherProvider.register("openweathermap", { }, /* - * fetch forecast information for 3-hourly forecast (available for free subscription). + * Generate forecast information for 3-hourly forecast (available for free + * subscription). */ - fetchForecastHourly(forecasts) { + generateForecastHourly(forecasts) { // initial variable declaration const days = []; // variables for temperature range and rain @@ -186,7 +187,7 @@ WeatherProvider.register("openweathermap", { weather.maxTemperature = Math.max.apply(null, maxTemp); weather.rain = rain; weather.snow = snow; - weather.precipitation = weather.rain + weather.snow; + weather.precipitationAmount = (weather.rain ?? 0) + (weather.snow ?? 0); // push weather information to days array days.push(weather); // create new weather-object @@ -216,20 +217,12 @@ WeatherProvider.register("openweathermap", { minTemp.push(forecast.main.temp_min); maxTemp.push(forecast.main.temp_max); - if (forecast.hasOwnProperty("rain")) { - if (this.config.units === "imperial" && !isNaN(forecast.rain["3h"])) { - rain += forecast.rain["3h"] / 25.4; - } else if (!isNaN(forecast.rain["3h"])) { - rain += forecast.rain["3h"]; - } + if (forecast.hasOwnProperty("rain") && !isNaN(forecast.rain["3h"])) { + rain += forecast.rain["3h"]; } - if (forecast.hasOwnProperty("snow")) { - if (this.config.units === "imperial" && !isNaN(forecast.snow["3h"])) { - snow += forecast.snow["3h"] / 25.4; - } else if (!isNaN(forecast.snow["3h"])) { - snow += forecast.snow["3h"]; - } + if (forecast.hasOwnProperty("snow") && !isNaN(forecast.snow["3h"])) { + snow += forecast.snow["3h"]; } } @@ -239,16 +232,17 @@ WeatherProvider.register("openweathermap", { weather.maxTemperature = Math.max.apply(null, maxTemp); weather.rain = rain; weather.snow = snow; - weather.precipitation = weather.rain + weather.snow; + weather.precipitationAmount = (weather.rain ?? 0) + (weather.snow ?? 0); // push weather information to days array days.push(weather); return days.slice(1); }, /* - * fetch forecast information for daily forecast (available for paid subscription or old apiKey). + * Generate forecast information for daily forecast (available for paid + * subscription or old apiKey). */ - fetchForecastDaily(forecasts) { + generateForecastDaily(forecasts) { // initial variable declaration const days = []; @@ -264,25 +258,18 @@ WeatherProvider.register("openweathermap", { // forecast.rain not available if amount is zero // The API always returns in millimeters - if (forecast.hasOwnProperty("rain")) { - if (this.config.units === "imperial" && !isNaN(forecast.rain)) { - weather.rain = forecast.rain / 25.4; - } else if (!isNaN(forecast.rain)) { - weather.rain = forecast.rain; - } + if (forecast.hasOwnProperty("rain") && !isNaN(forecast.rain)) { + weather.rain = forecast.rain; } // forecast.snow not available if amount is zero // The API always returns in millimeters - if (forecast.hasOwnProperty("snow")) { - if (this.config.units === "imperial" && !isNaN(forecast.snow)) { - weather.snow = forecast.snow / 25.4; - } else if (!isNaN(forecast.snow)) { - weather.snow = forecast.snow; - } + if (forecast.hasOwnProperty("snow") && !isNaN(forecast.snow)) { + weather.snow = forecast.snow; } - weather.precipitation = weather.rain + weather.snow; + weather.precipitationAmount = weather.rain + weather.snow; + weather.precipitationProbability = forecast.pop ? forecast.pop * 100 : undefined; days.push(weather); } @@ -303,30 +290,22 @@ WeatherProvider.register("openweathermap", { if (data.hasOwnProperty("current")) { current.date = moment.unix(data.current.dt).utcOffset(data.timezone_offset / 60); current.windSpeed = data.current.wind_speed; - current.windDirection = data.current.wind_deg; + current.windFromDirection = data.current.wind_deg; current.sunrise = moment.unix(data.current.sunrise).utcOffset(data.timezone_offset / 60); current.sunset = moment.unix(data.current.sunset).utcOffset(data.timezone_offset / 60); current.temperature = data.current.temp; current.weatherType = this.convertWeatherType(data.current.weather[0].icon); current.humidity = data.current.humidity; if (data.current.hasOwnProperty("rain") && !isNaN(data.current["rain"]["1h"])) { - if (this.config.units === "imperial") { - current.rain = data.current["rain"]["1h"] / 25.4; - } else { - current.rain = data.current["rain"]["1h"]; - } + current.rain = data.current["rain"]["1h"]; precip = true; } if (data.current.hasOwnProperty("snow") && !isNaN(data.current["snow"]["1h"])) { - if (this.config.units === "imperial") { - current.snow = data.current["snow"]["1h"] / 25.4; - } else { - current.snow = data.current["snow"]["1h"]; - } + current.snow = data.current["snow"]["1h"]; precip = true; } if (precip) { - current.precipitation = current.rain + current.snow; + current.precipitationAmount = (current.rain ?? 0) + (current.snow ?? 0); } current.feelsLikeTemp = data.current.feels_like; } @@ -342,27 +321,20 @@ WeatherProvider.register("openweathermap", { weather.feelsLikeTemp = hour.feels_like; weather.humidity = hour.humidity; weather.windSpeed = hour.wind_speed; - weather.windDirection = hour.wind_deg; + weather.windFromDirection = hour.wind_deg; weather.weatherType = this.convertWeatherType(hour.weather[0].icon); + weather.precipitationProbability = hour.pop ? hour.pop * 100 : undefined; precip = false; if (hour.hasOwnProperty("rain") && !isNaN(hour.rain["1h"])) { - if (this.config.units === "imperial") { - weather.rain = hour.rain["1h"] / 25.4; - } else { - weather.rain = hour.rain["1h"]; - } + weather.rain = hour.rain["1h"]; precip = true; } if (hour.hasOwnProperty("snow") && !isNaN(hour.snow["1h"])) { - if (this.config.units === "imperial") { - weather.snow = hour.snow["1h"] / 25.4; - } else { - weather.snow = hour.snow["1h"]; - } + weather.snow = hour.snow["1h"]; precip = true; } if (precip) { - weather.precipitation = weather.rain + weather.snow; + weather.precipitationAmount = (weather.rain ?? 0) + (weather.snow ?? 0); } hours.push(weather); @@ -381,27 +353,20 @@ WeatherProvider.register("openweathermap", { weather.maxTemperature = day.temp.max; weather.humidity = day.humidity; weather.windSpeed = day.wind_speed; - weather.windDirection = day.wind_deg; + weather.windFromDirection = day.wind_deg; weather.weatherType = this.convertWeatherType(day.weather[0].icon); + weather.precipitationProbability = day.pop ? day.pop * 100 : undefined; precip = false; if (!isNaN(day.rain)) { - if (this.config.units === "imperial") { - weather.rain = day.rain / 25.4; - } else { - weather.rain = day.rain; - } + weather.rain = day.rain; precip = true; } if (!isNaN(day.snow)) { - if (this.config.units === "imperial") { - weather.snow = day.snow / 25.4; - } else { - weather.snow = day.snow; - } + weather.snow = day.snow; precip = true; } if (precip) { - weather.precipitation = weather.rain + weather.snow; + weather.precipitationAmount = (weather.rain ?? 0) + (weather.snow ?? 0); } days.push(weather); @@ -448,8 +413,8 @@ WeatherProvider.register("openweathermap", { getParams() { let params = "?"; if (this.config.weatherEndpoint === "/onecall") { - params += "lat=" + this.config.lat; - params += "&lon=" + this.config.lon; + params += `lat=${this.config.lat}`; + params += `&lon=${this.config.lon}`; if (this.config.type === "current") { params += "&exclude=minutely,hourly,daily"; } else if (this.config.type === "hourly") { @@ -460,23 +425,23 @@ WeatherProvider.register("openweathermap", { params += "&exclude=minutely"; } } else if (this.config.lat && this.config.lon) { - params += "lat=" + this.config.lat + "&lon=" + this.config.lon; + params += `lat=${this.config.lat}&lon=${this.config.lon}`; } else if (this.config.locationID) { - params += "id=" + this.config.locationID; + params += `id=${this.config.locationID}`; } else if (this.config.location) { - params += "q=" + this.config.location; + params += `q=${this.config.location}`; } else if (this.firstEvent && this.firstEvent.geo) { - params += "lat=" + this.firstEvent.geo.lat + "&lon=" + this.firstEvent.geo.lon; + params += `lat=${this.firstEvent.geo.lat}&lon=${this.firstEvent.geo.lon}`; } else if (this.firstEvent && this.firstEvent.location) { - params += "q=" + this.firstEvent.location; + params += `q=${this.firstEvent.location}`; } else { this.hide(this.config.animationSpeed, { lockString: this.identifier }); return; } params += "&units=metric"; // WeatherProviders should use metric internally and use the units only for when displaying data - params += "&lang=" + this.config.lang; - params += "&APPID=" + this.config.apiKey; + params += `&lang=${this.config.lang}`; + params += `&APPID=${this.config.apiKey}`; return params; } diff --git a/modules/default/weather/providers/darksky.js b/modules/default/weather/providers/pirateweather.js similarity index 76% rename from modules/default/weather/providers/darksky.js rename to modules/default/weather/providers/pirateweather.js index aa48a12bd8..1bb956112a 100644 --- a/modules/default/weather/providers/darksky.js +++ b/modules/default/weather/providers/pirateweather.js @@ -2,24 +2,23 @@ /* MagicMirror² * Module: Weather - * Provider: Dark Sky + * Provider: Pirate Weather * - * By Nicholas Hubbard https://github.com/nhubbard + * Written by Nicholas Hubbard https://github.com/nhubbard for formerly Dark Sky Provider + * Modified by Karsten Hassel for Pirate Weather * MIT Licensed * - * This class is a provider for Dark Sky. - * Note that the Dark Sky API does not provide rainfall. Instead it provides - * snowfall and precipitation probability + * This class is a provider for Pirate Weather, it is a replacement for Dark Sky (same api). */ -WeatherProvider.register("darksky", { +WeatherProvider.register("pirateweather", { // Set the name of the provider. // Not strictly required, but helps for debugging. - providerName: "Dark Sky", + providerName: "pirateweather", // Set the default config properties that is specific to this provider defaults: { useCorsProxy: true, - apiBase: "https://api.darksky.net", + apiBase: "https://api.pirateweather.net", weatherEndpoint: "/forecast", apiKey: "", lat: 0, @@ -73,7 +72,7 @@ WeatherProvider.register("darksky", { currentWeather.humidity = parseFloat(currentWeatherData.currently.humidity); currentWeather.temperature = parseFloat(currentWeatherData.currently.temperature); currentWeather.windSpeed = parseFloat(currentWeatherData.currently.windSpeed); - currentWeather.windDirection = currentWeatherData.currently.windBearing; + currentWeather.windFromDirection = currentWeatherData.currently.windBearing; currentWeather.weatherType = this.convertWeatherType(currentWeatherData.currently.icon); currentWeather.sunrise = moment.unix(currentWeatherData.daily.data[0].sunriseTime); currentWeather.sunset = moment.unix(currentWeatherData.daily.data[0].sunsetTime); @@ -92,19 +91,21 @@ WeatherProvider.register("darksky", { weather.maxTemperature = forecast.temperatureMax; weather.weatherType = this.convertWeatherType(forecast.icon); weather.snow = 0; + weather.rain = 0; - // The API will return centimeters if units is 'si' and will return inches for 'us' - // Note that the Dark Sky API does not provide rainfall. - // Instead it provides snowfall and precipitation probability + let precip = 0; if (forecast.hasOwnProperty("precipAccumulation")) { - if (this.config.units === "imperial" && !isNaN(forecast.precipAccumulation)) { - weather.snow = forecast.precipAccumulation; - } else if (!isNaN(forecast.precipAccumulation)) { - weather.snow = forecast.precipAccumulation * 10; - } + precip = forecast.precipAccumulation * 10; } - weather.precipitation = weather.snow; + weather.precipitationAmount = precip; + if (forecast.hasOwnProperty("precipType")) { + if (forecast.precipType === "snow") { + weather.snow = precip; + } else { + weather.rain = precip; + } + } days.push(weather); } @@ -112,7 +113,7 @@ WeatherProvider.register("darksky", { return days; }, - // Map icons from Dark Sky to our icons. + // Map icons from Pirate Weather to our icons. convertWeatherType(weatherType) { const weatherTypes = { "clear-day": "day-sunny", diff --git a/modules/default/weather/providers/smhi.js b/modules/default/weather/providers/smhi.js index c3f51498a0..0115bcf5bb 100644 --- a/modules/default/weather/providers/smhi.js +++ b/modules/default/weather/providers/smhi.js @@ -33,7 +33,7 @@ WeatherProvider.register("smhi", { this.setFetchedLocation(this.config.location || `(${coordinates.lat},${coordinates.lon})`); this.setCurrentWeather(weatherObject); }) - .catch((error) => Log.error("Could not load data: " + error.message)) + .catch((error) => Log.error(`Could not load data: ${error.message}`)) .finally(() => this.updateAvailable()); }, @@ -48,7 +48,7 @@ WeatherProvider.register("smhi", { this.setFetchedLocation(this.config.location || `(${coordinates.lat},${coordinates.lon})`); this.setWeatherForecast(weatherObjects); }) - .catch((error) => Log.error("Could not load data: " + error.message)) + .catch((error) => Log.error(`Could not load data: ${error.message}`)) .finally(() => this.updateAvailable()); }, @@ -63,7 +63,7 @@ WeatherProvider.register("smhi", { this.setFetchedLocation(this.config.location || `(${coordinates.lat},${coordinates.lon})`); this.setWeatherHourly(weatherObjects); }) - .catch((error) => Log.error("Could not load data: " + error.message)) + .catch((error) => Log.error(`Could not load data: ${error.message}`)) .finally(() => this.updateAvailable()); }, @@ -75,7 +75,7 @@ WeatherProvider.register("smhi", { setConfig(config) { this.config = config; if (!config.precipitationValue || ["pmin", "pmean", "pmedian", "pmax"].indexOf(config.precipitationValue) === -1) { - Log.log("invalid or not set: " + config.precipitationValue); + Log.log(`invalid or not set: ${config.precipitationValue}`); config.precipitationValue = this.defaults.precipitationValue; } }, @@ -145,7 +145,7 @@ WeatherProvider.register("smhi", { currentWeather.humidity = this.paramValue(weatherData, "r"); currentWeather.temperature = this.paramValue(weatherData, "t"); currentWeather.windSpeed = this.paramValue(weatherData, "ws"); - currentWeather.windDirection = this.paramValue(weatherData, "wd"); + currentWeather.windFromDirection = this.paramValue(weatherData, "wd"); currentWeather.weatherType = this.convertWeatherType(this.paramValue(weatherData, "Wsymb2"), currentWeather.isDayTime()); currentWeather.feelsLikeTemp = this.calculateApparentTemperature(weatherData); @@ -157,19 +157,19 @@ WeatherProvider.register("smhi", { // 0 = No precipitation case 1: // Snow currentWeather.snow += precipitationValue; - currentWeather.precipitation += precipitationValue; + currentWeather.precipitationAmount += precipitationValue; break; case 2: // Snow and rain, treat it as 50/50 snow and rain currentWeather.snow += precipitationValue / 2; currentWeather.rain += precipitationValue / 2; - currentWeather.precipitation += precipitationValue; + currentWeather.precipitationAmount += precipitationValue; break; case 3: // Rain case 4: // Drizzle case 5: // Freezing rain case 6: // Freezing drizzle currentWeather.rain += precipitationValue; - currentWeather.precipitation += precipitationValue; + currentWeather.precipitationAmount += precipitationValue; break; } @@ -202,7 +202,7 @@ WeatherProvider.register("smhi", { currentWeather.maxTemperature = -Infinity; currentWeather.snow = 0; currentWeather.rain = 0; - currentWeather.precipitation = 0; + currentWeather.precipitationAmount = 0; result.push(currentWeather); } @@ -221,7 +221,7 @@ WeatherProvider.register("smhi", { currentWeather.maxTemperature = Math.max(currentWeather.maxTemperature, weatherObject.temperature); currentWeather.snow += weatherObject.snow; currentWeather.rain += weatherObject.rain; - currentWeather.precipitation += weatherObject.precipitation; + currentWeather.precipitationAmount += weatherObject.precipitationAmount; } return result; diff --git a/modules/default/weather/providers/ukmetoffice.js b/modules/default/weather/providers/ukmetoffice.js index d572e53eba..8f03cbe6af 100644 --- a/modules/default/weather/providers/ukmetoffice.js +++ b/modules/default/weather/providers/ukmetoffice.js @@ -100,9 +100,9 @@ WeatherProvider.register("ukmetoffice", { currentWeather.humidity = rep.H; currentWeather.temperature = rep.T; currentWeather.feelsLikeTemp = rep.F; - currentWeather.precipitation = parseInt(rep.Pp); + currentWeather.precipitationProbability = parseInt(rep.Pp); currentWeather.windSpeed = WeatherUtils.convertWindToMetric(rep.S); - currentWeather.windDirection = WeatherUtils.convertWindDirection(rep.D); + currentWeather.windFromDirection = WeatherUtils.convertWindDirection(rep.D); currentWeather.weatherType = this.convertWeatherType(rep.W); } } @@ -138,7 +138,7 @@ WeatherProvider.register("ukmetoffice", { weather.minTemperature = period.Rep[1].Nm; weather.maxTemperature = period.Rep[0].Dm; weather.weatherType = this.convertWeatherType(period.Rep[0].W); - weather.precipitation = parseInt(period.Rep[0].PPd); + weather.precipitationProbability = parseInt(period.Rep[0].PPd); days.push(weather); } @@ -195,8 +195,8 @@ WeatherProvider.register("ukmetoffice", { */ getParams(forecastType) { let params = "?"; - params += "res=" + forecastType; - params += "&key=" + this.config.apiKey; + params += `res=${forecastType}`; + params += `&key=${this.config.apiKey}`; return params; } }); diff --git a/modules/default/weather/providers/ukmetofficedatahub.js b/modules/default/weather/providers/ukmetofficedatahub.js index 049f9c4da3..a4d41267aa 100644 --- a/modules/default/weather/providers/ukmetofficedatahub.js +++ b/modules/default/weather/providers/ukmetofficedatahub.js @@ -55,9 +55,9 @@ WeatherProvider.register("ukmetofficedatahub", { // Build URL with query strings according to DataHub API (https://metoffice.apiconnect.ibmcloud.com/metoffice/production/api) getUrl(forecastType) { let queryStrings = "?"; - queryStrings += "latitude=" + this.config.lat; - queryStrings += "&longitude=" + this.config.lon; - queryStrings += "&includeLocationName=" + true; + queryStrings += `latitude=${this.config.lat}`; + queryStrings += `&longitude=${this.config.lon}`; + queryStrings += `&includeLocationName=${true}`; // Return URL, making sure there is a trailing "/" in the base URL. return this.config.apiBase + (this.config.apiBase.endsWith("/") ? "" : "/") + forecastType + queryStrings; @@ -104,7 +104,7 @@ WeatherProvider.register("ukmetofficedatahub", { }) // Catch any error(s) - .catch((error) => Log.error("Could not load data: " + error.message)) + .catch((error) => Log.error(`Could not load data: ${error.message}`)) // Let the module know there is data available .finally(() => this.updateAvailable()); @@ -126,7 +126,7 @@ WeatherProvider.register("ukmetofficedatahub", { if (nowUtc.isSameOrAfter(forecastTime) && nowUtc.isBefore(moment(forecastTime.add(1, "h")))) { currentWeather.date = forecastTime; currentWeather.windSpeed = forecastDataHours[hour].windSpeed10m; - currentWeather.windDirection = forecastDataHours[hour].windDirectionFrom10m; + currentWeather.windFromDirection = forecastDataHours[hour].windDirectionFrom10m; currentWeather.temperature = forecastDataHours[hour].screenTemperature; currentWeather.minTemperature = forecastDataHours[hour].minScreenAirTemp; currentWeather.maxTemperature = forecastDataHours[hour].maxScreenAirTemp; @@ -134,7 +134,7 @@ WeatherProvider.register("ukmetofficedatahub", { currentWeather.humidity = forecastDataHours[hour].screenRelativeHumidity; currentWeather.rain = forecastDataHours[hour].totalPrecipAmount; currentWeather.snow = forecastDataHours[hour].totalSnowAmount; - currentWeather.precipitation = forecastDataHours[hour].probOfPrecipitation; + currentWeather.precipitationProbability = forecastDataHours[hour].probOfPrecipitation; currentWeather.feelsLikeTemp = forecastDataHours[hour].feelsLikeTemperature; // Pass on full details, so they can be used in custom templates @@ -173,7 +173,7 @@ WeatherProvider.register("ukmetofficedatahub", { }) // Catch any error(s) - .catch((error) => Log.error("Could not load data: " + error.message)) + .catch((error) => Log.error(`Could not load data: ${error.message}`)) // Let the module know there is new data available .finally(() => this.updateAvailable()); @@ -204,9 +204,9 @@ WeatherProvider.register("ukmetofficedatahub", { // Using daytime forecast values forecastWeather.windSpeed = forecastDataDays[day].midday10MWindSpeed; - forecastWeather.windDirection = forecastDataDays[day].midday10MWindDirection; + forecastWeather.windFromDirection = forecastDataDays[day].midday10MWindDirection; forecastWeather.weatherType = this.convertWeatherType(forecastDataDays[day].daySignificantWeatherCode); - forecastWeather.precipitation = forecastDataDays[day].dayProbabilityOfPrecipitation; + forecastWeather.precipitationProbability = forecastDataDays[day].dayProbabilityOfPrecipitation; forecastWeather.temperature = forecastDataDays[day].dayMaxScreenTemperature; forecastWeather.humidity = forecastDataDays[day].middayRelativeHumidity; forecastWeather.rain = forecastDataDays[day].dayProbabilityOfRain; diff --git a/modules/default/weather/providers/weatherbit.js b/modules/default/weather/providers/weatherbit.js index 75f49a6984..7d0468bccb 100644 --- a/modules/default/weather/providers/weatherbit.js +++ b/modules/default/weather/providers/weatherbit.js @@ -55,7 +55,7 @@ WeatherProvider.register("weatherbit", { const forecast = this.generateWeatherObjectsFromForecast(data.data); this.setWeatherForecast(forecast); - this.fetchedLocationName = data.city_name + ", " + data.state_code; + this.fetchedLocationName = `${data.city_name}, ${data.state_code}`; }) .catch(function (request) { Log.error("Could not load data ... ", request); @@ -106,12 +106,12 @@ WeatherProvider.register("weatherbit", { currentWeather.humidity = parseFloat(currentWeatherData.data[0].rh); currentWeather.temperature = parseFloat(currentWeatherData.data[0].temp); currentWeather.windSpeed = parseFloat(currentWeatherData.data[0].wind_spd); - currentWeather.windDirection = currentWeatherData.data[0].wind_dir; + currentWeather.windFromDirection = currentWeatherData.data[0].wind_dir; currentWeather.weatherType = this.convertWeatherType(currentWeatherData.data[0].weather.icon); currentWeather.sunrise = moment(currentWeatherData.data[0].sunrise, "HH:mm").add(tzOffset, "m"); currentWeather.sunset = moment(currentWeatherData.data[0].sunset, "HH:mm").add(tzOffset, "m"); - this.fetchedLocationName = currentWeatherData.data[0].city_name + ", " + currentWeatherData.data[0].state_code; + this.fetchedLocationName = `${currentWeatherData.data[0].city_name}, ${currentWeatherData.data[0].state_code}`; return currentWeather; }, @@ -125,7 +125,8 @@ WeatherProvider.register("weatherbit", { weather.date = moment(forecast.datetime, "YYYY-MM-DD"); weather.minTemperature = forecast.min_temp; weather.maxTemperature = forecast.max_temp; - weather.precipitation = forecast.precip; + weather.precipitationAmount = forecast.precip; + weather.precipitationProbability = forecast.pop; weather.weatherType = this.convertWeatherType(forecast.weather.icon); days.push(weather); diff --git a/modules/default/weather/providers/weatherflow.js b/modules/default/weather/providers/weatherflow.js index d15023b5ab..aecfb63e41 100644 --- a/modules/default/weather/providers/weatherflow.js +++ b/modules/default/weather/providers/weatherflow.js @@ -32,7 +32,7 @@ WeatherProvider.register("weatherflow", { currentWeather.humidity = data.current_conditions.relative_humidity; currentWeather.temperature = data.current_conditions.air_temperature; currentWeather.windSpeed = WeatherUtils.convertWindToMs(data.current_conditions.wind_avg); - currentWeather.windDirection = data.current_conditions.wind_direction; + currentWeather.windFromDirection = data.current_conditions.wind_direction; currentWeather.weatherType = data.forecast.daily[0].icon; currentWeather.sunrise = moment.unix(data.forecast.daily[0].sunrise); currentWeather.sunset = moment.unix(data.forecast.daily[0].sunset); @@ -55,6 +55,7 @@ WeatherProvider.register("weatherflow", { weather.date = moment.unix(forecast.day_start_local); weather.minTemperature = forecast.air_temp_low; weather.maxTemperature = forecast.air_temp_high; + weather.precipitationProbability = forecast.precip_probability; weather.weatherType = forecast.icon; weather.snow = 0; diff --git a/modules/default/weather/providers/weathergov.js b/modules/default/weather/providers/weathergov.js index 19ce22e313..b1c69ee753 100644 --- a/modules/default/weather/providers/weathergov.js +++ b/modules/default/weather/providers/weathergov.js @@ -129,10 +129,10 @@ WeatherProvider.register("weathergov", { // points URL did not respond with usable data. return; } - this.fetchedLocationName = data.properties.relativeLocation.properties.city + ", " + data.properties.relativeLocation.properties.state; - Log.log("Forecast location is " + this.fetchedLocationName); - this.forecastURL = data.properties.forecast + "?units=si"; - this.forecastHourlyURL = data.properties.forecastHourly + "?units=si"; + this.fetchedLocationName = `${data.properties.relativeLocation.properties.city}, ${data.properties.relativeLocation.properties.state}`; + Log.log(`Forecast location is ${this.fetchedLocationName}`); + this.forecastURL = `${data.properties.forecast}?units=si`; + this.forecastHourlyURL = `${data.properties.forecastHourly}?units=si`; this.forecastGridDataURL = data.properties.forecastGridData; this.observationStationsURL = data.properties.observationStations; // with this URL, we chain another promise for the station obs URL @@ -143,7 +143,7 @@ WeatherProvider.register("weathergov", { // obs station URL did not respond with usable data. return; } - this.stationObsURL = obsData.features[0].id + "/observations/latest"; + this.stationObsURL = `${obsData.features[0].id}/observations/latest`; }) .catch((err) => { Log.error(err); @@ -179,9 +179,9 @@ WeatherProvider.register("weathergov", { } else { weather.windSpeed = forecast.windSpeed.slice(0, forecast.windSpeed.search(" ")); } - weather.windDirection = this.convertWindDirection(forecast.windDirection); + weather.windSpeed = WeatherUtils.convertWindToMs(weather.windSpeed); + weather.windFromDirection = forecast.windDirection; weather.temperature = forecast.temperature; - weather.tempUnits = forecast.temperatureUnit; // use the forecast isDayTime attribute to help build the weatherType label weather.weatherType = this.convertWeatherType(forecast.shortForecast, forecast.isDaytime); @@ -206,13 +206,11 @@ WeatherProvider.register("weathergov", { currentWeather.date = moment(currentWeatherData.timestamp); currentWeather.temperature = currentWeatherData.temperature.value; currentWeather.windSpeed = WeatherUtils.convertWindToMs(currentWeatherData.windSpeed.value); - currentWeather.windDirection = currentWeatherData.windDirection.value; + currentWeather.windFromDirection = currentWeatherData.windDirection.value; currentWeather.minTemperature = currentWeatherData.minTemperatureLast24Hours.value; currentWeather.maxTemperature = currentWeatherData.maxTemperatureLast24Hours.value; currentWeather.humidity = Math.round(currentWeatherData.relativeHumidity.value); - currentWeather.rain = null; - currentWeather.snow = null; - currentWeather.precipitation = this.convertLength(currentWeatherData.precipitationLastHour.value); + currentWeather.precipitationAmount = currentWeatherData.precipitationLastHour.value; if (currentWeatherData.heatIndex.value !== null) { currentWeather.feelsLikeTemp = currentWeatherData.heatIndex.value; } else if (currentWeatherData.windChill.value !== null) { @@ -240,6 +238,8 @@ WeatherProvider.register("weathergov", { * fetch forecast information for daily forecast. */ fetchForecastDaily(forecasts) { + const precipitationProbabilityRegEx = "Chance of precipitation is ([0-9]+?)%"; + // initial variable declaration const days = []; // variables for temperature range and rain @@ -248,7 +248,6 @@ WeatherProvider.register("weathergov", { // variable for date let date = ""; let weather = new WeatherObject(); - weather.precipitation = 0; for (const forecast of forecasts) { if (date !== moment(forecast.startTime).format("YYYY-MM-DD")) { @@ -263,7 +262,8 @@ WeatherProvider.register("weathergov", { minTemp = []; maxTemp = []; - weather.precipitation = 0; + const precipitation = new RegExp(precipitationProbabilityRegEx, "g").exec(forecast.detailedForecast); + if (precipitation) weather.precipitationProbability = precipitation[1]; // set new date date = moment(forecast.startTime).format("YYYY-MM-DD"); @@ -295,18 +295,6 @@ WeatherProvider.register("weathergov", { return days.slice(1); }, - /* - * Unit conversions - */ - // conversion to inches - convertLength(meters) { - if (this.config.units === "imperial") { - return meters * 39.3701; - } else { - return meters; - } - }, - /* * Convert the icons to a more usable name. */ diff --git a/modules/default/weather/providers/yr.js b/modules/default/weather/providers/yr.js index cc21611be3..09e2643df1 100644 --- a/modules/default/weather/providers/yr.js +++ b/modules/default/weather/providers/yr.js @@ -7,7 +7,7 @@ * By Magnus Marthinsen * MIT Licensed * - * This class is a provider for Yr.no, a norwegian sweather service. + * This class is a provider for Yr.no, a norwegian weather service. * * Terms of service: https://developer.yr.no/doc/TermsOfService/ */ @@ -47,7 +47,7 @@ WeatherProvider.register("yr", { const getRequests = [this.getWeatherData(), this.getStellarData()]; const [weatherData, stellarData] = await Promise.all(getRequests); if (!stellarData) { - Log.warn("No stelar data available."); + Log.warn("No stellar data available."); } if (!weatherData.properties.timeseries || !weatherData.properties.timeseries[0]) { Log.error("No weather data available."); @@ -65,7 +65,8 @@ WeatherProvider.register("yr", { } const forecastXHours = this.getForecastForXHoursFrom(forecast.data); forecast.weatherType = this.convertWeatherType(forecastXHours.summary.symbol_code, forecast.time); - forecast.precipitation = forecastXHours.details?.precipitation_amount; + forecast.precipitationAmount = forecastXHours.details?.precipitation_amount; + forecast.precipitationProbability = forecastXHours.details?.probability_of_precipitation; forecast.minTemperature = forecastXHours.details?.air_temperature_min; forecast.maxTemperature = forecastXHours.details?.air_temperature_max; return this.getWeatherDataFrom(forecast, stellarData, weatherData.properties.meta.units); @@ -251,12 +252,12 @@ WeatherProvider.register("yr", { this.cacheStellarData(stellarData); resolve(stellarData); } else { - reject("No stellar data returned from Yr for " + tomorrow); + reject(`No stellar data returned from Yr for ${tomorrow}`); } }) .catch((err) => { Log.error(err); - reject("Unable to get stellar data from Yr for " + tomorrow); + reject(`Unable to get stellar data from Yr for ${tomorrow}`); }) .finally(() => { localStorage.removeItem("yrIsFetchingStellarData"); @@ -274,7 +275,7 @@ WeatherProvider.register("yr", { this.cacheStellarData(stellarData); resolve(stellarData); } else { - Log.error("Something went wrong when fetching stellar data. Responses: " + stellarData); + Log.error(`Something went wrong when fetching stellar data. Responses: ${stellarData}`); reject(stellarData); } }) @@ -358,19 +359,20 @@ WeatherProvider.register("yr", { }, getWeatherDataFrom(forecast, stellarData, units) { - const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const weather = new WeatherObject(); const stellarTimesToday = stellarData?.today ? this.getStellarTimesFrom(stellarData.today, moment().format("YYYY-MM-DD")) : undefined; const stellarTimesTomorrow = stellarData?.tomorrow ? this.getStellarTimesFrom(stellarData.tomorrow, moment().add(1, "days").format("YYYY-MM-DD")) : undefined; weather.date = moment(forecast.time); weather.windSpeed = forecast.data.instant.details.wind_speed; - weather.windDirection = (forecast.data.instant.details.wind_from_direction + 180) % 360; + weather.windFromDirection = forecast.data.instant.details.wind_from_direction; weather.temperature = forecast.data.instant.details.air_temperature; weather.minTemperature = forecast.minTemperature; weather.maxTemperature = forecast.maxTemperature; weather.weatherType = forecast.weatherType; weather.humidity = forecast.data.instant.details.relative_humidity; - weather.precipitation = forecast.precipitation; + weather.precipitationAmount = forecast.precipitationAmount; + weather.precipitationProbability = forecast.precipitationProbability; weather.precipitationUnits = units.precipitation_amount; if (stellarTimesToday) { @@ -530,7 +532,7 @@ WeatherProvider.register("yr", { return; } if (!stellarData) { - Log.warn("No stelar data available."); + Log.warn("No stellar data available."); } let forecasts; switch (type) { @@ -554,7 +556,8 @@ WeatherProvider.register("yr", { for (const forecast of weatherData.properties.timeseries) { forecast.symbol = forecast.data.next_1_hours?.summary?.symbol_code; - forecast.precipitation = forecast.data.next_1_hours?.details?.precipitation_amount; + forecast.precipitationAmount = forecast.data.next_1_hours?.details?.precipitation_amount; + forecast.precipitationProbability = forecast.data.next_1_hours?.details?.probability_of_precipitation; forecast.minTemperature = forecast.data.next_1_hours?.details?.air_temperature_min; forecast.maxTemperature = forecast.data.next_1_hours?.details?.air_temperature_max; forecast.weatherType = this.convertWeatherType(forecast.symbol, forecast.time); @@ -599,7 +602,8 @@ WeatherProvider.register("yr", { const forecastXHours = forecast.data.next_12_hours ?? forecast.data.next_6_hours ?? forecast.data.next_1_hours; if (forecastXHours) { forecast.symbol = forecastXHours.summary?.symbol_code; - forecast.precipitation = forecastXHours.details?.precipitation_amount; + forecast.precipitationAmount = forecastXHours.details?.precipitation_amount ?? forecast.data.next_6_hours?.details?.precipitation_amount; // 6 hours is likely to have precipitation amount even if 12 hours does not + forecast.precipitationProbability = forecastXHours.details?.probability_of_precipitation; forecast.minTemperature = minTemperature; forecast.maxTemperature = maxTemperature; diff --git a/modules/default/weather/weather.css b/modules/default/weather/weather.css index 2d7600ad17..c2b7fe5ec1 100644 --- a/modules/default/weather/weather.css +++ b/modules/default/weather/weather.css @@ -6,7 +6,7 @@ transform: translate(0, -3px); } -.weather .humidityIcon { +.weather .humidity-icon { padding-right: 4px; } @@ -29,7 +29,8 @@ padding-right: 0; } -.weather .precipitation { +.weather .precipitation-amount, +.weather .precipitation-prob { padding-left: 20px; padding-right: 0; } diff --git a/modules/default/weather/weather.js b/modules/default/weather/weather.js index ab989f96ab..949c11cd24 100644 --- a/modules/default/weather/weather.js +++ b/modules/default/weather/weather.js @@ -12,23 +12,26 @@ Module.register("weather", { weatherProvider: "openweathermap", roundTemp: false, type: "current", // current, forecast, daily (equivalent to forecast), hourly (only with OpenWeatherMap /onecall endpoint) + lang: config.language, units: config.units, tempUnits: config.units, windUnits: config.units, + timeFormat: config.timeFormat, updateInterval: 10 * 60 * 1000, // every 10 minutes animationSpeed: 1000, - timeFormat: config.timeFormat, + showFeelsLike: true, + showHumidity: false, + showIndoorHumidity: false, + showIndoorTemperature: false, showPeriod: true, showPeriodUpper: false, + showPrecipitationAmount: false, + showPrecipitationProbability: false, + showSun: true, showWindDirection: true, showWindDirectionAsArrow: false, - lang: config.language, - showHumidity: false, - showSun: true, degreeLabel: false, decimalSymbol: ".", - showIndoorTemperature: false, - showIndoorHumidity: false, maxNumberOfDays: 5, maxEntries: 5, ignoreToday: false, @@ -39,10 +42,9 @@ Module.register("weather", { calendarClass: "calendar", tableClass: "small", onlyTemp: false, - showPrecipitationAmount: false, colored: false, - showFeelsLike: true, - absoluteDates: false + absoluteDates: false, + hourlyForecastIncrements: 1 }, // Module properties. @@ -58,13 +60,13 @@ Module.register("weather", { // Return the scripts that are necessary for the weather module. getScripts: function () { - return ["moment.js", this.file("../utils.js"), "weatherutils.js", "weatherprovider.js", "weatherobject.js", "suncalc.js", this.file("providers/" + this.config.weatherProvider.toLowerCase() + ".js")]; + return ["moment.js", this.file("../utils.js"), "weatherutils.js", "weatherprovider.js", "weatherobject.js", "suncalc.js", this.file(`providers/${this.config.weatherProvider.toLowerCase()}.js`)]; }, // Override getHeader method. getHeader: function () { if (this.config.appendLocationNameToHeader && this.weatherProvider) { - if (this.data.header) return this.data.header + " " + this.weatherProvider.fetchedLocation(); + if (this.data.header) return `${this.data.header} ${this.weatherProvider.fetchedLocation()}`; else return this.weatherProvider.fetchedLocation(); } @@ -137,13 +139,17 @@ Module.register("weather", { // Add all the data to the template. getTemplateData: function () { - const forecast = this.weatherProvider.weatherForecast(); + const currentData = this.weatherProvider.currentWeather(); + const forecastData = this.weatherProvider.weatherForecast(); + + // Skip some hourly forecast entries if configured + const hourlyData = this.weatherProvider.weatherHourly()?.filter((e, i) => (i + 1) % this.config.hourlyForecastIncrements === this.config.hourlyForecastIncrements - 1); return { config: this.config, - current: this.weatherProvider.currentWeather(), - forecast: forecast, - hourly: this.weatherProvider.weatherHourly(), + current: currentData, + forecast: forecastData, + hourly: hourlyData, indoor: { humidity: this.indoorHumidity, temperature: this.indoorTemperature @@ -225,9 +231,9 @@ Module.register("weather", { this.nunjucksEnvironment().addFilter( "unit", - function (value, type) { + function (value, type, valueUnit) { if (type === "temperature") { - value = this.roundValue(WeatherUtils.convertTemp(value, this.config.tempUnits)) + "°"; + value = `${this.roundValue(WeatherUtils.convertTemp(value, this.config.tempUnits))}°`; if (this.config.degreeLabel) { if (this.config.tempUnits === "metric") { value += "C"; @@ -241,11 +247,7 @@ Module.register("weather", { if (value === null || isNaN(value) || value === 0 || value.toFixed(2) === "0.00") { value = ""; } else { - if (this.config.weatherProvider === "ukmetoffice" || this.config.weatherProvider === "ukmetofficedatahub") { - value += "%"; - } else { - value = `${value.toFixed(2)} ${this.config.units === "imperial" ? "in" : "mm"}`; - } + value = WeatherUtils.convertPrecipitationUnit(value, valueUnit, this.config.units); } } else if (type === "humidity") { value += "%"; diff --git a/modules/default/weather/weatherobject.js b/modules/default/weather/weatherobject.js index 0e28b4f20b..565061da08 100644 --- a/modules/default/weather/weatherobject.js +++ b/modules/default/weather/weatherobject.js @@ -11,6 +11,10 @@ * Currently this is focused on the information which is necessary for the current weather. * As soon as we start implementing the forecast, mode properties will be added. */ + +/** + * @external Moment + */ class WeatherObject { /** * Constructor for a WeatherObject @@ -18,7 +22,7 @@ class WeatherObject { constructor() { this.date = null; this.windSpeed = null; - this.windDirection = null; + this.windFromDirection = null; this.sunrise = null; this.sunset = null; this.temperature = null; @@ -26,77 +30,65 @@ class WeatherObject { this.maxTemperature = null; this.weatherType = null; this.humidity = null; - this.rain = null; - this.snow = null; - this.precipitation = null; + this.precipitationAmount = null; this.precipitationUnits = null; + this.precipitationProbability = null; this.feelsLikeTemp = null; } cardinalWindDirection() { - if (this.windDirection > 11.25 && this.windDirection <= 33.75) { + if (this.windFromDirection > 11.25 && this.windFromDirection <= 33.75) { return "NNE"; - } else if (this.windDirection > 33.75 && this.windDirection <= 56.25) { + } else if (this.windFromDirection > 33.75 && this.windFromDirection <= 56.25) { return "NE"; - } else if (this.windDirection > 56.25 && this.windDirection <= 78.75) { + } else if (this.windFromDirection > 56.25 && this.windFromDirection <= 78.75) { return "ENE"; - } else if (this.windDirection > 78.75 && this.windDirection <= 101.25) { + } else if (this.windFromDirection > 78.75 && this.windFromDirection <= 101.25) { return "E"; - } else if (this.windDirection > 101.25 && this.windDirection <= 123.75) { + } else if (this.windFromDirection > 101.25 && this.windFromDirection <= 123.75) { return "ESE"; - } else if (this.windDirection > 123.75 && this.windDirection <= 146.25) { + } else if (this.windFromDirection > 123.75 && this.windFromDirection <= 146.25) { return "SE"; - } else if (this.windDirection > 146.25 && this.windDirection <= 168.75) { + } else if (this.windFromDirection > 146.25 && this.windFromDirection <= 168.75) { return "SSE"; - } else if (this.windDirection > 168.75 && this.windDirection <= 191.25) { + } else if (this.windFromDirection > 168.75 && this.windFromDirection <= 191.25) { return "S"; - } else if (this.windDirection > 191.25 && this.windDirection <= 213.75) { + } else if (this.windFromDirection > 191.25 && this.windFromDirection <= 213.75) { return "SSW"; - } else if (this.windDirection > 213.75 && this.windDirection <= 236.25) { + } else if (this.windFromDirection > 213.75 && this.windFromDirection <= 236.25) { return "SW"; - } else if (this.windDirection > 236.25 && this.windDirection <= 258.75) { + } else if (this.windFromDirection > 236.25 && this.windFromDirection <= 258.75) { return "WSW"; - } else if (this.windDirection > 258.75 && this.windDirection <= 281.25) { + } else if (this.windFromDirection > 258.75 && this.windFromDirection <= 281.25) { return "W"; - } else if (this.windDirection > 281.25 && this.windDirection <= 303.75) { + } else if (this.windFromDirection > 281.25 && this.windFromDirection <= 303.75) { return "WNW"; - } else if (this.windDirection > 303.75 && this.windDirection <= 326.25) { + } else if (this.windFromDirection > 303.75 && this.windFromDirection <= 326.25) { return "NW"; - } else if (this.windDirection > 326.25 && this.windDirection <= 348.75) { + } else if (this.windFromDirection > 326.25 && this.windFromDirection <= 348.75) { return "NNW"; } else { return "N"; } } - nextSunAction() { - return moment().isBetween(this.sunrise, this.sunset) ? "sunset" : "sunrise"; + /** + * Determines if the sun sets or rises next. Uses the current time and not + * the date from the weather-forecast. + * + * @param {Moment} date an optional date where you want to get the next + * action for. Useful only in tests, defaults to the current time. + * @returns {string} "sunset" or "sunrise" + */ + nextSunAction(date = moment()) { + return date.isBetween(this.sunrise, this.sunset) ? "sunset" : "sunrise"; } feelsLike() { if (this.feelsLikeTemp) { return this.feelsLikeTemp; } - const windInMph = WeatherUtils.convertWind(this.windSpeed, "imperial"); - const tempInF = WeatherUtils.convertTemp(this.temperature, "imperial"); - let feelsLike = tempInF; - - if (windInMph > 3 && tempInF < 50) { - feelsLike = Math.round(35.74 + 0.6215 * tempInF - 35.75 * Math.pow(windInMph, 0.16) + 0.4275 * tempInF * Math.pow(windInMph, 0.16)); - } else if (tempInF > 80 && this.humidity > 40) { - feelsLike = - -42.379 + - 2.04901523 * tempInF + - 10.14333127 * this.humidity - - 0.22475541 * tempInF * this.humidity - - 6.83783 * Math.pow(10, -3) * tempInF * tempInF - - 5.481717 * Math.pow(10, -2) * this.humidity * this.humidity + - 1.22874 * Math.pow(10, -3) * tempInF * tempInF * this.humidity + - 8.5282 * Math.pow(10, -4) * tempInF * this.humidity * this.humidity - - 1.99 * Math.pow(10, -6) * tempInF * tempInF * this.humidity * this.humidity; - } - - return ((feelsLike - 32) * 5) / 9; + return WeatherUtils.calculateFeelsLike(this.temperature, this.windSpeed, this.humidity); } /** @@ -105,7 +97,8 @@ class WeatherObject { * @returns {boolean} true if it is at dayTime */ isDayTime() { - return this.date.isBetween(this.sunrise, this.sunset, undefined, "[]"); + const now = !this.date ? moment() : this.date; + return now.isBetween(this.sunrise, this.sunset, undefined, "[]"); } /** diff --git a/modules/default/weather/weatherutils.js b/modules/default/weather/weatherutils.js index c0af86afc3..42b5da1ec9 100644 --- a/modules/default/weather/weatherutils.js +++ b/modules/default/weather/weatherutils.js @@ -12,7 +12,7 @@ const WeatherUtils = { * @returns {number} the speed in beaufort */ beaufortWindSpeed(speedInMS) { - const windInKmh = (speedInMS * 3600) / 1000; + const windInKmh = this.convertWind(speedInMS, "kmh"); const speeds = [1, 5, 11, 19, 28, 38, 49, 61, 74, 88, 102, 117, 1000]; for (const [index, speed] of speeds.entries()) { if (speed > windInKmh) { @@ -22,6 +22,29 @@ const WeatherUtils = { return 12; }, + /** + * Convert a value in a given unit to a string with a converted + * value and a postfix matching the output unit system. + * + * @param {number} value - The value to convert. + * @param {string} valueUnit - The unit the values has. Default is mm. + * @param {string} outputUnit - The unit system (imperial/metric) the return value should have. + * @returns {string} - A string with tha value and a unit postfix. + */ + convertPrecipitationUnit(value, valueUnit, outputUnit) { + if (outputUnit === "imperial") { + if (valueUnit && valueUnit.toLowerCase() === "cm") value = value * 0.3937007874; + else value = value * 0.03937007874; + valueUnit = "in"; + } else { + valueUnit = valueUnit ? valueUnit : "mm"; + } + + if (valueUnit === "%") return `${value.toFixed(0)} ${valueUnit}`; + + return `${value.toFixed(2)} ${valueUnit}`; + }, + /** * Convert temp (from degrees C) into imperial or metric unit depending on * your config @@ -90,6 +113,29 @@ const WeatherUtils = { convertWindToMs(kmh) { return kmh * 0.27777777777778; + }, + + calculateFeelsLike(temperature, windSpeed, humidity) { + const windInMph = this.convertWind(windSpeed, "imperial"); + const tempInF = this.convertTemp(temperature, "imperial"); + let feelsLike = tempInF; + + if (windInMph > 3 && tempInF < 50) { + feelsLike = Math.round(35.74 + 0.6215 * tempInF - 35.75 * Math.pow(windInMph, 0.16) + 0.4275 * tempInF * Math.pow(windInMph, 0.16)); + } else if (tempInF > 80 && humidity > 40) { + feelsLike = + -42.379 + + 2.04901523 * tempInF + + 10.14333127 * humidity - + 0.22475541 * tempInF * humidity - + 6.83783 * Math.pow(10, -3) * tempInF * tempInF - + 5.481717 * Math.pow(10, -2) * humidity * humidity + + 1.22874 * Math.pow(10, -3) * tempInF * tempInF * humidity + + 8.5282 * Math.pow(10, -4) * tempInF * humidity * humidity - + 1.99 * Math.pow(10, -6) * tempInF * tempInF * humidity * humidity; + } + + return ((feelsLike - 32) * 5) / 9; } }; diff --git a/package-lock.json b/package-lock.json index 5730fcb337..2a6e8a4987 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,56 +1,57 @@ { "name": "magicmirror", - "version": "2.22.0", + "version": "2.23.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "magicmirror", - "version": "2.22.0", + "version": "2.23.0", "hasInstallScript": true, "license": "MIT", "dependencies": { "colors": "^1.4.0", - "console-stamp": "^3.1.0", + "console-stamp": "^3.1.1", "digest-fetch": "^2.0.1", - "eslint": "^8.30.0", + "envsub": "^4.1.0", + "eslint": "^8.36.0", "express": "^4.18.2", "express-ipfilter": "^1.3.1", "feedme": "^2.0.2", "helmet": "^6.0.1", "iconv-lite": "^0.6.3", - "luxon": "^1.28.0", + "luxon": "^1.28.1", "module-alias": "^2.2.2", "moment": "^2.29.4", - "node-fetch": "^2.6.7", - "node-ical": "^0.15.3", - "socket.io": "^4.5.4" + "node-fetch": "^2.6.9", + "node-ical": "^0.16.0", + "socket.io": "^4.6.1" }, "devDependencies": { - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-jest": "^27.1.7", - "eslint-plugin-jsdoc": "^39.6.4", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jest": "^27.2.1", + "eslint-plugin-jsdoc": "^40.1.0", "eslint-plugin-prettier": "^4.2.1", "express-basic-auth": "^1.2.1", - "husky": "^8.0.2", - "jest": "^29.3.1", - "jsdom": "^20.0.3", + "husky": "^8.0.3", + "jest": "^29.5.0", + "jsdom": "^21.1.1", "lodash": "^4.17.21", - "playwright": "^1.29.1", - "prettier": "^2.8.1", + "playwright": "^1.32.1", + "prettier": "^2.8.7", "pretty-quick": "^3.1.3", - "sinon": "^15.0.1", - "stylelint": "^14.16.0", - "stylelint-config-prettier": "^9.0.4", - "stylelint-config-standard": "^29.0.0", - "stylelint-prettier": "^2.0.0", + "sinon": "^15.0.2", + "stylelint": "^15.3.0", + "stylelint-config-standard": "^31.0.0", + "stylelint-prettier": "^3.0.0", "suncalc": "^1.9.0" }, "engines": { "node": ">=14" }, "optionalDependencies": { - "electron": "^22.0.0" + "electron": "^22.3.4" } }, "node_modules/@ampproject/remapping": { @@ -79,34 +80,34 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", - "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.0.tgz", + "integrity": "sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.7.tgz", - "integrity": "sha512-t1ZjCluspe5DW24bn2Rr1CDb2v9rn/hROtg9a2tmd0+QYf4bsloYfLQzjG4qHPNMhWtKdGC33R5AxGR2Af2cBw==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.3.tgz", + "integrity": "sha512-qIJONzoa/qiHghnm0l1n4i/6IIziDpzqc36FBs4pzMhDUraHqponwJLiAKm1hGLP3OSB/TVNz6rMwVGpwxxySw==", "dev": true, "dependencies": { - "@ampproject/remapping": "^2.1.0", + "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", + "@babel/generator": "^7.21.3", "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-module-transforms": "^7.20.7", - "@babel/helpers": "^7.20.7", - "@babel/parser": "^7.20.7", + "@babel/helper-module-transforms": "^7.21.2", + "@babel/helpers": "^7.21.0", + "@babel/parser": "^7.21.3", "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.7", - "@babel/types": "^7.20.7", + "@babel/traverse": "^7.21.3", + "@babel/types": "^7.21.3", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", + "json5": "^2.2.2", "semver": "^6.3.0" }, "engines": { @@ -124,13 +125,14 @@ "dev": true }, "node_modules/@babel/generator": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", - "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.3.tgz", + "integrity": "sha512-QS3iR1GYC/YGUnW7IdggFeN5c1poPUurnGttOV/bZgPGV+izC/D8HnD6DLwod0fsatNyVn1G3EVWMYIF0nHbeA==", "dev": true, "dependencies": { - "@babel/types": "^7.20.7", + "@babel/types": "^7.21.3", "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "engines": { @@ -180,13 +182,13 @@ } }, "node_modules/@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", "dev": true, "dependencies": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" }, "engines": { "node": ">=6.9.0" @@ -217,9 +219,9 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.7.tgz", - "integrity": "sha512-FNdu7r67fqMUSVuQpFQGE6BPdhJIhitoxhGzDbAXNcA07uoVG37fOiMk3OSV8rEICuyG6t8LGkd9EE64qIEoIA==", + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", + "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.18.9", @@ -228,8 +230,8 @@ "@babel/helper-split-export-declaration": "^7.18.6", "@babel/helper-validator-identifier": "^7.19.1", "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/traverse": "^7.21.2", + "@babel/types": "^7.21.2" }, "engines": { "node": ">=6.9.0" @@ -287,23 +289,23 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", + "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.7.tgz", - "integrity": "sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz", + "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==", "dev": true, "dependencies": { "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/traverse": "^7.21.0", + "@babel/types": "^7.21.0" }, "engines": { "node": ">=6.9.0" @@ -395,9 +397,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz", - "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.3.tgz", + "integrity": "sha512-lobG0d7aOfQRXh8AyklEAgZGvA4FShxo6xQbUrrT/cNBPUdIDojlokwJsQyCC/eKia7ifqM0yP+2DRZ4WKw2RQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -598,19 +600,19 @@ } }, "node_modules/@babel/traverse": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.7.tgz", - "integrity": "sha512-xueOL5+ZKX2dJbg8z8o4f4uTRTqGDRjilva9D1hiRlayJbTY8jBRL+Ph67IeRTIE439/VifHk+Z4g0SwRtQE0A==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.3.tgz", + "integrity": "sha512-XLyopNeaTancVitYZe2MlUEvgKb6YVVPXzofHgqHijCImG33b/uTurMS488ht/Hbsb2XK3U2BnSTxKVNGV3nGQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", + "@babel/generator": "^7.21.3", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", + "@babel/helper-function-name": "^7.21.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", + "@babel/parser": "^7.21.3", + "@babel/types": "^7.21.3", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -628,9 +630,9 @@ } }, "node_modules/@babel/types": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", - "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.3.tgz", + "integrity": "sha512-sBGdETxC+/M4o/zKC0sl6sjWv62WFR/uzxrJ6uYyMLZOUlPnwzw0tKgVHOXxaAd5l2g8pEDM5RZ495GPQI77kg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.19.4", @@ -647,20 +649,66 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.0.1.tgz", + "integrity": "sha512-B9/8PmOtU6nBiibJg0glnNktQDZ3rZnGn/7UmDfrm2vMtrdlXO3p7ErE95N0up80IRk9YEtB5jyj/TmQ1WH3dw==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^2.0.0" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.1.0.tgz", + "integrity": "sha512-dtqFyoJBHUxGi9zPZdpCKP1xk8tq6KPHJ/NY4qWXiYo6IcSGwzk3L8x2XzZbbyOyBs9xQARoGveU2AsgLj6D2A==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + }, + "node_modules/@csstools/media-query-list-parser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.0.1.tgz", + "integrity": "sha512-X2/OuzEbjaxhzm97UJ+95GrMeT29d1Ib+Pu+paGLuRWZnWRK9sI9r3ikmKXPWGA1C4y4JEdBEFpp9jEqCvLeRA==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^2.0.0", + "@csstools/css-tokenizer": "^2.0.0" + } + }, "node_modules/@csstools/selector-specificity": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz", - "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.1.1.tgz", + "integrity": "sha512-jwx+WCqszn53YHOfvFMJJRd/B2GqkCBt+1MJSG6o5/s8+ytHMvDZXsJgUEWLk12UnLd7HYKac4BYU5i/Ron1Cw==", "dev": true, "engines": { - "node": "^12 || ^14 || >=16" + "node": "^14 || ^16 || >=18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "postcss": "^8.2", + "postcss": "^8.4", "postcss-selector-parser": "^6.0.10" } }, @@ -686,27 +734,49 @@ } }, "node_modules/@es-joy/jsdoccomment": { - "version": "0.36.1", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.36.1.tgz", - "integrity": "sha512-922xqFsTpHs6D0BUiG4toiyPOMc8/jafnWKxz1KWgS4XzKPy2qXf1Pe6UFuNSCQqt6tOuhAWXBNuuyUhJmw9Vg==", + "version": "0.37.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.37.0.tgz", + "integrity": "sha512-hjK0wnsPCYLlF+HHB4R/RbUjOWeLW2SlarB67+Do5WsKILOkmIZvvPJFbtWSmbypxcjpoECLAMzoao0D4Bg5ZQ==", "dev": true, "dependencies": { "comment-parser": "1.3.1", "esquery": "^1.4.0", - "jsdoc-type-pratt-parser": "~3.1.0" + "jsdoc-type-pratt-parser": "~4.0.0" }, "engines": { "node": "^14 || ^16 || ^17 || ^18 || ^19" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.3.0.tgz", + "integrity": "sha512-v3oplH6FYCULtFuCeqyuTd9D2WKO937Dxdq+GmHOLL72TTRriLxz2VLlNfkZRsvj6PKnOPAtuT6dwrs/pA5DvA==", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.0.tgz", + "integrity": "sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.0.tgz", - "integrity": "sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.1.tgz", + "integrity": "sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", + "espree": "^9.5.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -721,6 +791,14 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/js": { + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz", + "integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -866,16 +944,16 @@ } }, "node_modules/@jest/console": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.3.1.tgz", - "integrity": "sha512-IRE6GD47KwcqA09RIWrabKdHPiKDGgtAL31xDxbi/RjQMsr+lY+ppxmHwY0dUEV3qvvxZzoe5Hl0RXZJOjQNUg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.5.0.tgz", + "integrity": "sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==", "dev": true, "dependencies": { - "@jest/types": "^29.3.1", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.3.1", - "jest-util": "^29.3.1", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", "slash": "^3.0.0" }, "engines": { @@ -883,37 +961,37 @@ } }, "node_modules/@jest/core": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.3.1.tgz", - "integrity": "sha512-0ohVjjRex985w5MmO5L3u5GR1O30DexhBSpuwx2P+9ftyqHdJXnk7IUWiP80oHMvt7ubHCJHxV0a0vlKVuZirw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.5.0.tgz", + "integrity": "sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ==", "dev": true, "dependencies": { - "@jest/console": "^29.3.1", - "@jest/reporters": "^29.3.1", - "@jest/test-result": "^29.3.1", - "@jest/transform": "^29.3.1", - "@jest/types": "^29.3.1", + "@jest/console": "^29.5.0", + "@jest/reporters": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.2.0", - "jest-config": "^29.3.1", - "jest-haste-map": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.3.1", - "jest-resolve-dependencies": "^29.3.1", - "jest-runner": "^29.3.1", - "jest-runtime": "^29.3.1", - "jest-snapshot": "^29.3.1", - "jest-util": "^29.3.1", - "jest-validate": "^29.3.1", - "jest-watcher": "^29.3.1", + "jest-changed-files": "^29.5.0", + "jest-config": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-resolve-dependencies": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "jest-watcher": "^29.5.0", "micromatch": "^4.0.4", - "pretty-format": "^29.3.1", + "pretty-format": "^29.5.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, @@ -930,88 +1008,88 @@ } }, "node_modules/@jest/environment": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.3.1.tgz", - "integrity": "sha512-pMmvfOPmoa1c1QpfFW0nXYtNLpofqo4BrCIk6f2kW4JFeNlHV2t3vd+3iDLf31e2ot2Mec0uqZfmI+U0K2CFag==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.5.0.tgz", + "integrity": "sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==", "dev": true, "dependencies": { - "@jest/fake-timers": "^29.3.1", - "@jest/types": "^29.3.1", + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", - "jest-mock": "^29.3.1" + "jest-mock": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.3.1.tgz", - "integrity": "sha512-QivM7GlSHSsIAWzgfyP8dgeExPRZ9BIe2LsdPyEhCGkZkoyA+kGsoIzbKAfZCvvRzfZioKwPtCZIt5SaoxYCvg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.5.0.tgz", + "integrity": "sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==", "dev": true, "dependencies": { - "expect": "^29.3.1", - "jest-snapshot": "^29.3.1" + "expect": "^29.5.0", + "jest-snapshot": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.3.1.tgz", - "integrity": "sha512-wlrznINZI5sMjwvUoLVk617ll/UYfGIZNxmbU+Pa7wmkL4vYzhV9R2pwVqUh4NWWuLQWkI8+8mOkxs//prKQ3g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.5.0.tgz", + "integrity": "sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==", "dev": true, "dependencies": { - "jest-get-type": "^29.2.0" + "jest-get-type": "^29.4.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.3.1.tgz", - "integrity": "sha512-iHTL/XpnDlFki9Tq0Q1GGuVeQ8BHZGIYsvCO5eN/O/oJaRzofG9Xndd9HuSDBI/0ZS79pg0iwn07OMTQ7ngF2A==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.5.0.tgz", + "integrity": "sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==", "dev": true, "dependencies": { - "@jest/types": "^29.3.1", - "@sinonjs/fake-timers": "^9.1.2", + "@jest/types": "^29.5.0", + "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^29.3.1", - "jest-mock": "^29.3.1", - "jest-util": "^29.3.1" + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/globals": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.3.1.tgz", - "integrity": "sha512-cTicd134vOcwO59OPaB6AmdHQMCtWOe+/DitpTZVxWgMJ+YvXL1HNAmPyiGbSHmF/mXVBkvlm8YYtQhyHPnV6Q==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.5.0.tgz", + "integrity": "sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ==", "dev": true, "dependencies": { - "@jest/environment": "^29.3.1", - "@jest/expect": "^29.3.1", - "@jest/types": "^29.3.1", - "jest-mock": "^29.3.1" + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/types": "^29.5.0", + "jest-mock": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/reporters": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.3.1.tgz", - "integrity": "sha512-GhBu3YFuDrcAYW/UESz1JphEAbvUjaY2vShRZRoRY1mxpCMB3yGSJ4j9n0GxVlEOdCf7qjvUfBCrTUUqhVfbRA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.5.0.tgz", + "integrity": "sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA==", "dev": true, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.3.1", - "@jest/test-result": "^29.3.1", - "@jest/transform": "^29.3.1", - "@jest/types": "^29.3.1", + "@jest/console": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@jridgewell/trace-mapping": "^0.3.15", "@types/node": "*", "chalk": "^4.0.0", @@ -1024,9 +1102,9 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.3.1", - "jest-util": "^29.3.1", - "jest-worker": "^29.3.1", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", @@ -1045,21 +1123,21 @@ } }, "node_modules/@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", "dev": true, "dependencies": { - "@sinclair/typebox": "^0.24.1" + "@sinclair/typebox": "^0.25.16" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/source-map": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.2.0.tgz", - "integrity": "sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.3.tgz", + "integrity": "sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.15", @@ -1071,13 +1149,13 @@ } }, "node_modules/@jest/test-result": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.3.1.tgz", - "integrity": "sha512-qeLa6qc0ddB0kuOZyZIhfN5q0e2htngokyTWsGriedsDhItisW7SDYZ7ceOe57Ii03sL988/03wAcBh3TChMGw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.5.0.tgz", + "integrity": "sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==", "dev": true, "dependencies": { - "@jest/console": "^29.3.1", - "@jest/types": "^29.3.1", + "@jest/console": "^29.5.0", + "@jest/types": "^29.5.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -1086,14 +1164,14 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.3.1.tgz", - "integrity": "sha512-IqYvLbieTv20ArgKoAMyhLHNrVHJfzO6ARZAbQRlY4UGWfdDnLlZEF0BvKOMd77uIiIjSZRwq3Jb3Fa3I8+2UA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.5.0.tgz", + "integrity": "sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ==", "dev": true, "dependencies": { - "@jest/test-result": "^29.3.1", + "@jest/test-result": "^29.5.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.3.1", + "jest-haste-map": "^29.5.0", "slash": "^3.0.0" }, "engines": { @@ -1101,38 +1179,38 @@ } }, "node_modules/@jest/transform": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.3.1.tgz", - "integrity": "sha512-8wmCFBTVGYqFNLWfcOWoVuMuKYPUBTnTMDkdvFtAYELwDOl9RGwOsvQWGPFxDJ8AWY9xM/8xCXdqmPK3+Q5Lug==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.5.0.tgz", + "integrity": "sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", - "@jest/types": "^29.3.1", + "@jest/types": "^29.5.0", "@jridgewell/trace-mapping": "^0.3.15", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.3.1", - "jest-regex-util": "^29.2.0", - "jest-util": "^29.3.1", + "jest-haste-map": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", - "write-file-atomic": "^4.0.1" + "write-file-atomic": "^4.0.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/types": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.3.1.tgz", - "integrity": "sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", + "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", "dev": true, "dependencies": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -1223,9 +1301,9 @@ } }, "node_modules/@sinclair/typebox": { - "version": "0.24.51", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", - "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", "dev": true }, "node_modules/@sindresorhus/is": { @@ -1241,21 +1319,21 @@ } }, "node_modules/@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", "dev": true, "dependencies": { "type-detect": "4.0.8" } }, "node_modules/@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", + "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", "dev": true, "dependencies": { - "@sinonjs/commons": "^1.7.0" + "@sinonjs/commons": "^2.0.0" } }, "node_modules/@sinonjs/samsam": { @@ -1311,13 +1389,13 @@ } }, "node_modules/@types/babel__core": { - "version": "7.1.20", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz", - "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", + "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", "dev": true, "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" @@ -1377,9 +1455,9 @@ } }, "node_modules/@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", "dev": true, "dependencies": { "@types/node": "*" @@ -1421,6 +1499,12 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, "node_modules/@types/keyv": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", @@ -1443,9 +1527,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "16.18.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.10.tgz", - "integrity": "sha512-XU1+v7h81p7145ddPfjv7jtWvkSilpcnON3mQ+bDi9Yuf7OI56efOglXRyXWgQ57xH3fEQgh7WOJMncRHVew5w==" + "version": "16.18.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.18.tgz", + "integrity": "sha512-fwGw1uvQAzabxL1pyoknPlJIF2t7+K90uTqynleKRx24n3lYcxWa3+KByLhgkF8GEAK2c7hC8Ki0RkNM5H15jQ==" }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", @@ -1453,12 +1537,6 @@ "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, - "node_modules/@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true - }, "node_modules/@types/prettier": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", @@ -1487,9 +1565,9 @@ "dev": true }, "node_modules/@types/yargs": { - "version": "17.0.17", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.17.tgz", - "integrity": "sha512-72bWxFKTK6uwWJAVT+3rF6Jo6RTojiJ27FQo8Rf60AL+VZbzoVPnMFhKsUnbjR8A3BTCYQ7Mv3hnl8T0A+CX9g==", + "version": "17.0.22", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.22.tgz", + "integrity": "sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g==", "dev": true, "dependencies": { "@types/yargs-parser": "*" @@ -1511,13 +1589,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.47.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.0.tgz", - "integrity": "sha512-dvJab4bFf7JVvjPuh3sfBUWsiD73aiftKBpWSfi3sUkysDQ4W8x+ZcFpNp7Kgv0weldhpmMOZBjx1wKN8uWvAw==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.56.0.tgz", + "integrity": "sha512-jGYKyt+iBakD0SA5Ww8vFqGpoV2asSjwt60Gl6YcO8ksQ8s2HlUEyHBMSa38bdLopYqGf7EYQMUIGdT/Luw+sw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.47.0", - "@typescript-eslint/visitor-keys": "5.47.0" + "@typescript-eslint/types": "5.56.0", + "@typescript-eslint/visitor-keys": "5.56.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1528,9 +1606,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.47.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.0.tgz", - "integrity": "sha512-eslFG0Qy8wpGzDdYKu58CEr3WLkjwC5Usa6XbuV89ce/yN5RITLe1O8e+WFEuxnfftHiJImkkOBADj58ahRxSg==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.56.0.tgz", + "integrity": "sha512-JyAzbTJcIyhuUhogmiu+t79AkdnqgPUEsxMTMc/dCZczGMJQh1MK2wgrju++yMN6AWroVAy2jxyPcPr3SWCq5w==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1541,13 +1619,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.47.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.0.tgz", - "integrity": "sha512-LxfKCG4bsRGq60Sqqu+34QT5qT2TEAHvSCCJ321uBWywgE2dS0LKcu5u+3sMGo+Vy9UmLOhdTw5JHzePV/1y4Q==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.56.0.tgz", + "integrity": "sha512-41CH/GncsLXOJi0jb74SnC7jVPWeVJ0pxQj8bOjH1h2O26jXN3YHKDT1ejkVz5YeTEQPeLCCRY0U2r68tfNOcg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.47.0", - "@typescript-eslint/visitor-keys": "5.47.0", + "@typescript-eslint/types": "5.56.0", + "@typescript-eslint/visitor-keys": "5.56.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1601,18 +1679,18 @@ "dev": true }, "node_modules/@typescript-eslint/utils": { - "version": "5.47.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.47.0.tgz", - "integrity": "sha512-U9xcc0N7xINrCdGVPwABjbAKqx4GK67xuMV87toI+HUqgXj26m6RBp9UshEXcTrgCkdGYFzgKLt8kxu49RilDw==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.56.0.tgz", + "integrity": "sha512-XhZDVdLnUJNtbzaJeDSCIYaM+Tgr59gZGbFuELgF7m0IY03PlciidS7UQNKLE0+WpUTn1GlycEr6Ivb/afjbhA==", "dev": true, "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.47.0", - "@typescript-eslint/types": "5.47.0", - "@typescript-eslint/typescript-estree": "5.47.0", + "@typescript-eslint/scope-manager": "5.56.0", + "@typescript-eslint/types": "5.56.0", + "@typescript-eslint/typescript-estree": "5.56.0", "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", "semver": "^7.3.7" }, "engines": { @@ -1682,12 +1760,12 @@ "dev": true }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.47.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.0.tgz", - "integrity": "sha512-ByPi5iMa6QqDXe/GmT/hR6MZtVPi0SqMQPDx15FczCBXJo/7M8T88xReOALAfpBLm+zxpPfmhuEvPb577JRAEg==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.56.0.tgz", + "integrity": "sha512-1mFdED7u5bZpX6Xxf5N9U2c18sb+8EvU3tyOIj6LQZ5OOvnmj8BVeNNP603OFPm5KkS1a7IvCIcwrdHXaEMG/Q==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.47.0", + "@typescript-eslint/types": "5.56.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -1717,9 +1795,9 @@ } }, "node_modules/acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "bin": { "acorn": "bin/acorn" }, @@ -1848,6 +1926,18 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array-differ": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", @@ -1862,6 +1952,25 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "node_modules/array-includes": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -1871,6 +1980,42 @@ "node": ">=8" } }, + "node_modules/array.prototype.flat": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", + "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", @@ -1894,10 +2039,21 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/axios": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.1.3.tgz", - "integrity": "sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.4.tgz", + "integrity": "sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==", "dependencies": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", @@ -1905,15 +2061,15 @@ } }, "node_modules/babel-jest": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.3.1.tgz", - "integrity": "sha512-aard+xnMoxgjwV70t0L6wkW/3HQQtV+O0PEimxKgzNqCJnbYmroPojdP2tqKSOAt8QAKV/uSZU8851M7B5+fcA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.5.0.tgz", + "integrity": "sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q==", "dev": true, "dependencies": { - "@jest/transform": "^29.3.1", + "@jest/transform": "^29.5.0", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.2.0", + "babel-preset-jest": "^29.5.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" @@ -1942,9 +2098,9 @@ } }, "node_modules/babel-plugin-jest-hoist": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.2.0.tgz", - "integrity": "sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", + "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", "dev": true, "dependencies": { "@babel/template": "^7.3.3", @@ -1980,12 +2136,12 @@ } }, "node_modules/babel-preset-jest": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.2.0.tgz", - "integrity": "sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", + "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", "dev": true, "dependencies": { - "babel-plugin-jest-hoist": "^29.2.0", + "babel-plugin-jest-hoist": "^29.5.0", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { @@ -2031,6 +2187,11 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, "node_modules/body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", @@ -2106,9 +2267,9 @@ } }, "node_modules/browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", "dev": true, "funding": [ { @@ -2121,10 +2282,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" }, "bin": { "browserslist": "cli.js" @@ -2248,9 +2409,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001441", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001441.tgz", - "integrity": "sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg==", + "version": "1.0.30001468", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001468.tgz", + "integrity": "sha512-zgAo8D5kbOyUcRAgSmgyuvBkjrGk5CGYG5TYgFdpQv+ywcyEpo1LOWoG8YmoflGnh+V+UsNuKYedsoYs0hzV5A==", "dev": true, "funding": [ { @@ -2296,10 +2457,16 @@ } }, "node_modules/ci-info": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz", - "integrity": "sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], "engines": { "node": ">=8" } @@ -2403,6 +2570,14 @@ "node": ">= 0.8" } }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "engines": { + "node": ">= 6" + } + }, "node_modules/comment-parser": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz", @@ -2418,9 +2593,9 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/console-stamp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/console-stamp/-/console-stamp-3.1.0.tgz", - "integrity": "sha512-Vt22288o0Hrxb9uYwXMWYuw/Mu8iPSrFPtIiveq9uE0zWXPDDCAIvKZojqnwcyINnJY9tnTeG0neV/MD+2G5+g==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/console-stamp/-/console-stamp-3.1.1.tgz", + "integrity": "sha512-NTbqQ9X57xffQKTJbAm4h/ro7JNR2uD3369NeTjmRdfPJ2QmkmCUnMvC1QSxZPQOof3WPrkuA6DQV5+n35ZiIA==", "dependencies": { "chalk": "^4.1.2", "dateformat": "^4.6.3" @@ -2441,9 +2616,9 @@ } }, "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "engines": { "node": ">= 0.6" } @@ -2480,19 +2655,21 @@ } }, "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.1.3.tgz", + "integrity": "sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw==", "dev": true, "dependencies": { - "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" + "path-type": "^4.0.0" }, "engines": { - "node": ">=10" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" } }, "node_modules/cross-spawn": { @@ -2525,6 +2702,19 @@ "node": ">=12.22" } }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -2537,42 +2727,30 @@ "node": ">=4" } }, - "node_modules/cssom": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", - "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", - "dev": true - }, "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", + "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", "dev": true, "dependencies": { - "cssom": "~0.3.6" + "rrweb-cssom": "^0.6.0" }, "engines": { - "node": ">=8" + "node": ">=14" } }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - }, "node_modules/data-urls": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", - "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz", + "integrity": "sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==", "dev": true, "dependencies": { "abab": "^2.0.6", "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^11.0.0" + "whatwg-url": "^12.0.0" }, "engines": { - "node": ">=12" + "node": ">=14" } }, "node_modules/dateformat": { @@ -2678,9 +2856,9 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" }, "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, "engines": { "node": ">=0.10.0" @@ -2696,10 +2874,9 @@ } }, "node_modules/define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "optional": true, + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", "dependencies": { "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" @@ -2752,18 +2929,17 @@ "optional": true }, "node_modules/diff": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", - "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", - "dev": true, + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "engines": { "node": ">=0.3.1" } }, "node_modules/diff-sequences": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz", - "integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -2821,9 +2997,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron": { - "version": "22.0.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-22.0.0.tgz", - "integrity": "sha512-cgRc4wjyM+81A0E8UGv1HNJjL1HBI5cWNh/DUIjzYvoUuiEM0SS0hAH/zaFQ18xOz2ced6Yih8SybpOiOYJhdg==", + "version": "22.3.4", + "resolved": "https://registry.npmjs.org/electron/-/electron-22.3.4.tgz", + "integrity": "sha512-EY/ieC3gnKYUNOQPJSCIbiMBwEnGs/j0yIAUf0pXPK4BRh2nvXTD5d9OdouAIN7bRNLLPgqoTm0uXgZPAWTVkg==", "hasInstallScript": true, "optional": true, "dependencies": { @@ -2839,9 +3015,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", + "version": "1.4.333", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.333.tgz", + "integrity": "sha512-YyE8+GKyGtPEP1/kpvqsdhD6rA/TP1DUFDN4uiU/YI52NzDxmwHkEb3qjId8hLBa5siJvG0sfC3O66501jMruQ==", "dev": true }, "node_modules/emittery": { @@ -2880,9 +3056,9 @@ } }, "node_modules/engine.io": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz", - "integrity": "sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.1.tgz", + "integrity": "sha512-JFYQurD/nbsA5BSPmbaOSLa3tSVj8L6o4srSwXXY3NqE+gGUNmmPTbhn8tjzcCtSqhFgIeqef81ngny8JM25hw==", "dependencies": { "@types/cookie": "^0.4.1", "@types/cors": "^2.8.12", @@ -2893,16 +3069,16 @@ "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~5.0.3", - "ws": "~8.2.3" + "ws": "~8.11.0" }, "engines": { "node": ">=10.0.0" } }, "node_modules/engine.io-parser": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz", - "integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.6.tgz", + "integrity": "sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw==", "engines": { "node": ">=10.0.0" } @@ -2916,9 +3092,9 @@ } }, "node_modules/engine.io/node_modules/ws": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", "engines": { "node": ">=10.0.0" }, @@ -2956,6 +3132,37 @@ "node": ">=6" } }, + "node_modules/envsub": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/envsub/-/envsub-4.1.0.tgz", + "integrity": "sha512-B44hta3xNFu6+zDhOha1TIrZkQHGDO3G5K8D2sJIkm/s3XyQjxWBGp1B+b/Y74Go1PqMP+cp8moPR4JullnD9Q==", + "dependencies": { + "bluebird": "^3.7.2", + "chalk": "^3.0.0", + "commander": "^4.0.1", + "diff": "^4.0.1", + "handlebars": "^4.5.3", + "lodash": "^4.17.15", + "replace-last": "^1.2.6", + "string.prototype.matchall": "^4.0.8" + }, + "bin": { + "envsub": "bin/envsub.js", + "envsubh": "bin/envsubh.js" + } + }, + "node_modules/envsub/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -2965,6 +3172,91 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-abstract": { + "version": "1.21.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", + "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.2.0", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.7", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "dependencies": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", @@ -3070,11 +3362,14 @@ } }, "node_modules/eslint": { - "version": "8.30.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.30.0.tgz", - "integrity": "sha512-MGADB39QqYuzEGov+F/qb18r4i7DohCDOfatHaxI2iGlPuC65bwG2gxgO+7DkyL38dRFaRH7RaRAgU6JKL9rMQ==", - "dependencies": { - "@eslint/eslintrc": "^1.4.0", + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz", + "integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.1", + "@eslint/js": "8.36.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -3085,10 +3380,9 @@ "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", + "espree": "^9.5.0", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", @@ -3109,7 +3403,6 @@ "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" @@ -3125,9 +3418,9 @@ } }, "node_modules/eslint-config-prettier": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", - "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", + "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==", "dev": true, "bin": { "eslint-config-prettier": "bin/cli.js" @@ -3136,16 +3429,112 @@ "eslint": ">=7.0.0" } }, - "node_modules/eslint-plugin-jest": { - "version": "27.1.7", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.1.7.tgz", - "integrity": "sha512-0QVzf+og4YI1Qr3UoprkqqhezAZjFffdi62b0IurkCXMqPtRW84/UT4CKsYT80h/D82LA9avjO/80Ou1LdgbaQ==", + "node_modules/eslint-import-resolver-node": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz", + "integrity": "sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "^5.10.0" + "debug": "^3.2.7", + "is-core-module": "^2.11.0", + "resolve": "^1.22.1" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", + "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.27.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz", + "integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "array.prototype.flatmap": "^1.3.1", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.7", + "eslint-module-utils": "^2.7.4", + "has": "^1.0.3", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.6", + "resolve": "^1.22.1", + "semver": "^6.3.0", + "tsconfig-paths": "^3.14.1" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-jest": { + "version": "27.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.2.1.tgz", + "integrity": "sha512-l067Uxx7ZT8cO9NJuf+eJHvt6bqJyz2Z29wykyEdz/OtmcELQl2MQGQLX8J94O1cSJWAwUSEvCjwjA7KEK3Hmg==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "^5.10.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "@typescript-eslint/eslint-plugin": "^5.0.0", @@ -3161,16 +3550,16 @@ } }, "node_modules/eslint-plugin-jsdoc": { - "version": "39.6.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.6.4.tgz", - "integrity": "sha512-fskvdLCfwmPjHb6e+xNGDtGgbF8X7cDwMtVLAP2WwSf9Htrx68OAx31BESBM1FAwsN2HTQyYQq7m4aW4Q4Nlag==", + "version": "40.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-40.1.0.tgz", + "integrity": "sha512-ANvrhiu62VlSorARM0hup60VQsS3hNyp0Ca7cnJDj8tpJzM7tNhBVqMVYXSuLzEmqrpwx6aAh+NAN2DdAGG5fQ==", "dev": true, "dependencies": { - "@es-joy/jsdoccomment": "~0.36.1", + "@es-joy/jsdoccomment": "~0.37.0", "comment-parser": "1.3.1", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", - "esquery": "^1.4.0", + "esquery": "^1.5.0", "semver": "^7.3.8", "spdx-expression-parse": "^3.0.1" }, @@ -3247,31 +3636,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/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==", - "engines": { - "node": ">=10" - } - }, "node_modules/eslint-visitor-keys": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", @@ -3281,9 +3645,9 @@ } }, "node_modules/espree": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz", + "integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==", "dependencies": { "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", @@ -3310,9 +3674,9 @@ } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dependencies": { "estraverse": "^5.1.0" }, @@ -3400,16 +3764,16 @@ } }, "node_modules/expect": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.3.1.tgz", - "integrity": "sha512-gGb1yTgU30Q0O/tQq+z30KBWv24ApkMgFUpvKBkyLUBL68Wv8dHdJxTBZFl/iT8K/bqDHvUYRH6IIN3rToopPA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.5.0.tgz", + "integrity": "sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg==", "dev": true, "dependencies": { - "@jest/expect-utils": "^29.3.1", - "jest-get-type": "^29.2.0", - "jest-matcher-utils": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-util": "^29.3.1" + "@jest/expect-utils": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -3571,9 +3935,9 @@ } }, "node_modules/fastq": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz", - "integrity": "sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dependencies": { "reusify": "^1.0.4" } @@ -3712,6 +4076,14 @@ } } }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dependencies": { + "is-callable": "^1.1.3" + } + }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -3779,6 +4151,31 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -3798,9 +4195,9 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -3834,6 +4231,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -3953,9 +4365,9 @@ } }, "node_modules/globals": { - "version": "13.19.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", - "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dependencies": { "type-fest": "^0.20.2" }, @@ -3970,7 +4382,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "optional": true, "dependencies": { "define-properties": "^1.1.3" }, @@ -4007,6 +4418,17 @@ "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", "dev": true }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/got": { "version": "11.8.6", "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", @@ -4033,9 +4455,9 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "devOptional": true }, "node_modules/grapheme-splitter": { @@ -4043,6 +4465,26 @@ "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==" }, + "node_modules/handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, "node_modules/hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -4063,6 +4505,14 @@ "node": ">= 0.4.0" } }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -4075,7 +4525,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "optional": true, "dependencies": { "get-intrinsic": "^1.1.1" }, @@ -4083,6 +4532,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", @@ -4094,6 +4554,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/helmet": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/helmet/-/helmet-6.0.1.tgz", @@ -4163,9 +4637,9 @@ } }, "node_modules/http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", "optional": true }, "node_modules/http-errors": { @@ -4233,9 +4707,9 @@ } }, "node_modules/husky": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.2.tgz", - "integrity": "sha512-Tkv80jtvbnkK3mYWxPZePGFpQ/tT3HNSs/sasF9P2YfkMezDl3ON37YN6jUUI4eTg5LcyVynlb6r4eyvOmspvg==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", + "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", "dev": true, "bin": { "husky": "lib/bin.js" @@ -4346,6 +4820,19 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, + "node_modules/internal-slot": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "dependencies": { + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/ip": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", @@ -4367,17 +4854,67 @@ "node": ">= 0.10" } }, + "node_modules/is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-core-module": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", @@ -4390,6 +4927,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -4427,6 +4978,17 @@ "node": ">=0.10.0" } }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -4436,6 +4998,20 @@ "node": ">=0.12.0" } }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", @@ -4468,6 +5044,32 @@ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "dev": true }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -4480,6 +5082,63 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", @@ -4558,15 +5217,15 @@ } }, "node_modules/jest": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.3.1.tgz", - "integrity": "sha512-6iWfL5DTT0Np6UYs/y5Niu7WIfNv/wRTtN5RSXt2DIEft3dx3zPuw/3WJQBCJfmEzvDiEKwoqMbGD9n49+qLSA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.5.0.tgz", + "integrity": "sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==", "dev": true, "dependencies": { - "@jest/core": "^29.3.1", - "@jest/types": "^29.3.1", + "@jest/core": "^29.5.0", + "@jest/types": "^29.5.0", "import-local": "^3.0.2", - "jest-cli": "^29.3.1" + "jest-cli": "^29.5.0" }, "bin": { "jest": "bin/jest.js" @@ -4584,9 +5243,9 @@ } }, "node_modules/jest-changed-files": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.2.0.tgz", - "integrity": "sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.5.0.tgz", + "integrity": "sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==", "dev": true, "dependencies": { "execa": "^5.0.0", @@ -4597,28 +5256,29 @@ } }, "node_modules/jest-circus": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.3.1.tgz", - "integrity": "sha512-wpr26sEvwb3qQQbdlmei+gzp6yoSSoSL6GsLPxnuayZSMrSd5Ka7IjAvatpIernBvT2+Ic6RLTg+jSebScmasg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.5.0.tgz", + "integrity": "sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA==", "dev": true, "dependencies": { - "@jest/environment": "^29.3.1", - "@jest/expect": "^29.3.1", - "@jest/test-result": "^29.3.1", - "@jest/types": "^29.3.1", + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", "is-generator-fn": "^2.0.0", - "jest-each": "^29.3.1", - "jest-matcher-utils": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-runtime": "^29.3.1", - "jest-snapshot": "^29.3.1", - "jest-util": "^29.3.1", + "jest-each": "^29.5.0", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", "p-limit": "^3.1.0", - "pretty-format": "^29.3.1", + "pretty-format": "^29.5.0", + "pure-rand": "^6.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -4627,21 +5287,21 @@ } }, "node_modules/jest-cli": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.3.1.tgz", - "integrity": "sha512-TO/ewvwyvPOiBBuWZ0gm04z3WWP8TIK8acgPzE4IxgsLKQgb377NYGrQLc3Wl/7ndWzIH2CDNNsUjGxwLL43VQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.5.0.tgz", + "integrity": "sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw==", "dev": true, "dependencies": { - "@jest/core": "^29.3.1", - "@jest/test-result": "^29.3.1", - "@jest/types": "^29.3.1", + "@jest/core": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^29.3.1", - "jest-util": "^29.3.1", - "jest-validate": "^29.3.1", + "jest-config": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", "prompts": "^2.0.1", "yargs": "^17.3.1" }, @@ -4661,31 +5321,31 @@ } }, "node_modules/jest-config": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.3.1.tgz", - "integrity": "sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.5.0.tgz", + "integrity": "sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.3.1", - "@jest/types": "^29.3.1", - "babel-jest": "^29.3.1", + "@jest/test-sequencer": "^29.5.0", + "@jest/types": "^29.5.0", + "babel-jest": "^29.5.0", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^29.3.1", - "jest-environment-node": "^29.3.1", - "jest-get-type": "^29.2.0", - "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.3.1", - "jest-runner": "^29.3.1", - "jest-util": "^29.3.1", - "jest-validate": "^29.3.1", + "jest-circus": "^29.5.0", + "jest-environment-node": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^29.3.1", + "pretty-format": "^29.5.0", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, @@ -4706,24 +5366,24 @@ } }, "node_modules/jest-diff": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.3.1.tgz", - "integrity": "sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", + "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^29.3.1", - "jest-get-type": "^29.2.0", - "pretty-format": "^29.3.1" + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-docblock": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.2.0.tgz", - "integrity": "sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", + "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", "dev": true, "dependencies": { "detect-newline": "^3.0.0" @@ -4733,62 +5393,62 @@ } }, "node_modules/jest-each": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.3.1.tgz", - "integrity": "sha512-qrZH7PmFB9rEzCSl00BWjZYuS1BSOH8lLuC0azQE9lQrAx3PWGKHTDudQiOSwIy5dGAJh7KA0ScYlCP7JxvFYA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.5.0.tgz", + "integrity": "sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA==", "dev": true, "dependencies": { - "@jest/types": "^29.3.1", + "@jest/types": "^29.5.0", "chalk": "^4.0.0", - "jest-get-type": "^29.2.0", - "jest-util": "^29.3.1", - "pretty-format": "^29.3.1" + "jest-get-type": "^29.4.3", + "jest-util": "^29.5.0", + "pretty-format": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-environment-node": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.3.1.tgz", - "integrity": "sha512-xm2THL18Xf5sIHoU7OThBPtuH6Lerd+Y1NLYiZJlkE3hbE+7N7r8uvHIl/FkZ5ymKXJe/11SQuf3fv4v6rUMag==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.5.0.tgz", + "integrity": "sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw==", "dev": true, "dependencies": { - "@jest/environment": "^29.3.1", - "@jest/fake-timers": "^29.3.1", - "@jest/types": "^29.3.1", + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", - "jest-mock": "^29.3.1", - "jest-util": "^29.3.1" + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-get-type": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz", - "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-haste-map": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.3.1.tgz", - "integrity": "sha512-/FFtvoG1xjbbPXQLFef+WSU4yrc0fc0Dds6aRPBojUid7qlPqZvxdUBA03HW0fnVHXVCnCdkuoghYItKNzc/0A==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", + "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", "dev": true, "dependencies": { - "@jest/types": "^29.3.1", + "@jest/types": "^29.5.0", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.2.0", - "jest-util": "^29.3.1", - "jest-worker": "^29.3.1", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", "micromatch": "^4.0.4", "walker": "^1.0.8" }, @@ -4800,46 +5460,46 @@ } }, "node_modules/jest-leak-detector": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.3.1.tgz", - "integrity": "sha512-3DA/VVXj4zFOPagGkuqHnSQf1GZBmmlagpguxEERO6Pla2g84Q1MaVIB3YMxgUaFIaYag8ZnTyQgiZ35YEqAQA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz", + "integrity": "sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow==", "dev": true, "dependencies": { - "jest-get-type": "^29.2.0", - "pretty-format": "^29.3.1" + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.3.1.tgz", - "integrity": "sha512-fkRMZUAScup3txIKfMe3AIZZmPEjWEdsPJFK3AIy5qRohWqQFg1qrmKfYXR9qEkNc7OdAu2N4KPHibEmy4HPeQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", + "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^29.3.1", - "jest-get-type": "^29.2.0", - "pretty-format": "^29.3.1" + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-message-util": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.3.1.tgz", - "integrity": "sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", + "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.3.1", + "@jest/types": "^29.5.0", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.3.1", + "pretty-format": "^29.5.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -4848,14 +5508,14 @@ } }, "node_modules/jest-mock": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.3.1.tgz", - "integrity": "sha512-H8/qFDtDVMFvFP4X8NuOT3XRDzOUTz+FeACjufHzsOIBAxivLqkB1PoLCaJx9iPPQ8dZThHPp/G3WRWyMgA3JA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.5.0.tgz", + "integrity": "sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==", "dev": true, "dependencies": { - "@jest/types": "^29.3.1", + "@jest/types": "^29.5.0", "@types/node": "*", - "jest-util": "^29.3.1" + "jest-util": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -4879,28 +5539,28 @@ } }, "node_modules/jest-regex-util": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.2.0.tgz", - "integrity": "sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", + "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-resolve": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.3.1.tgz", - "integrity": "sha512-amXJgH/Ng712w3Uz5gqzFBBjxV8WFLSmNjoreBGMqxgCz5cH7swmBZzgBaCIOsvb0NbpJ0vgaSFdJqMdT+rADw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.5.0.tgz", + "integrity": "sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==", "dev": true, "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.3.1", + "jest-haste-map": "^29.5.0", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.3.1", - "jest-validate": "^29.3.1", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", + "resolve.exports": "^2.0.0", "slash": "^3.0.0" }, "engines": { @@ -4908,43 +5568,43 @@ } }, "node_modules/jest-resolve-dependencies": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.3.1.tgz", - "integrity": "sha512-Vk0cYq0byRw2WluNmNWGqPeRnZ3p3hHmjJMp2dyyZeYIfiBskwq4rpiuGFR6QGAdbj58WC7HN4hQHjf2mpvrLA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.5.0.tgz", + "integrity": "sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg==", "dev": true, "dependencies": { - "jest-regex-util": "^29.2.0", - "jest-snapshot": "^29.3.1" + "jest-regex-util": "^29.4.3", + "jest-snapshot": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-runner": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.3.1.tgz", - "integrity": "sha512-oFvcwRNrKMtE6u9+AQPMATxFcTySyKfLhvso7Sdk/rNpbhg4g2GAGCopiInk1OP4q6gz3n6MajW4+fnHWlU3bA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.5.0.tgz", + "integrity": "sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ==", "dev": true, "dependencies": { - "@jest/console": "^29.3.1", - "@jest/environment": "^29.3.1", - "@jest/test-result": "^29.3.1", - "@jest/transform": "^29.3.1", - "@jest/types": "^29.3.1", + "@jest/console": "^29.5.0", + "@jest/environment": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.13.1", "graceful-fs": "^4.2.9", - "jest-docblock": "^29.2.0", - "jest-environment-node": "^29.3.1", - "jest-haste-map": "^29.3.1", - "jest-leak-detector": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-resolve": "^29.3.1", - "jest-runtime": "^29.3.1", - "jest-util": "^29.3.1", - "jest-watcher": "^29.3.1", - "jest-worker": "^29.3.1", + "jest-docblock": "^29.4.3", + "jest-environment-node": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-leak-detector": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-resolve": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-util": "^29.5.0", + "jest-watcher": "^29.5.0", + "jest-worker": "^29.5.0", "p-limit": "^3.1.0", "source-map-support": "0.5.13" }, @@ -4953,31 +5613,31 @@ } }, "node_modules/jest-runtime": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.3.1.tgz", - "integrity": "sha512-jLzkIxIqXwBEOZx7wx9OO9sxoZmgT2NhmQKzHQm1xwR1kNW/dn0OjxR424VwHHf1SPN6Qwlb5pp1oGCeFTQ62A==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.3.1", - "@jest/fake-timers": "^29.3.1", - "@jest/globals": "^29.3.1", - "@jest/source-map": "^29.2.0", - "@jest/test-result": "^29.3.1", - "@jest/transform": "^29.3.1", - "@jest/types": "^29.3.1", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.5.0.tgz", + "integrity": "sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/globals": "^29.5.0", + "@jest/source-map": "^29.4.3", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-mock": "^29.3.1", - "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.3.1", - "jest-snapshot": "^29.3.1", - "jest-util": "^29.3.1", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, @@ -4986,9 +5646,9 @@ } }, "node_modules/jest-snapshot": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.3.1.tgz", - "integrity": "sha512-+3JOc+s28upYLI2OJM4PWRGK9AgpsMs/ekNryUV0yMBClT9B1DF2u2qay8YxcQd338PPYSFNb0lsar1B49sLDA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", + "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", @@ -4997,23 +5657,22 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.3.1", - "@jest/transform": "^29.3.1", - "@jest/types": "^29.3.1", + "@jest/expect-utils": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@types/babel__traverse": "^7.0.6", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.3.1", + "expect": "^29.5.0", "graceful-fs": "^4.2.9", - "jest-diff": "^29.3.1", - "jest-get-type": "^29.2.0", - "jest-haste-map": "^29.3.1", - "jest-matcher-utils": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-util": "^29.3.1", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", "natural-compare": "^1.4.0", - "pretty-format": "^29.3.1", + "pretty-format": "^29.5.0", "semver": "^7.3.5" }, "engines": { @@ -5054,12 +5713,12 @@ "dev": true }, "node_modules/jest-util": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.3.1.tgz", - "integrity": "sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", + "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", "dev": true, "dependencies": { - "@jest/types": "^29.3.1", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -5071,17 +5730,17 @@ } }, "node_modules/jest-validate": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.3.1.tgz", - "integrity": "sha512-N9Lr3oYR2Mpzuelp1F8negJR3YE+L1ebk1rYA5qYo9TTY3f9OWdptLoNSPP9itOCBIRBqjt/S5XHlzYglLN67g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.5.0.tgz", + "integrity": "sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ==", "dev": true, "dependencies": { - "@jest/types": "^29.3.1", + "@jest/types": "^29.5.0", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^29.2.0", + "jest-get-type": "^29.4.3", "leven": "^3.1.0", - "pretty-format": "^29.3.1" + "pretty-format": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -5100,18 +5759,18 @@ } }, "node_modules/jest-watcher": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.3.1.tgz", - "integrity": "sha512-RspXG2BQFDsZSRKGCT/NiNa8RkQ1iKAjrO0//soTMWx/QUt+OcxMqMSBxz23PYGqUuWm2+m2mNNsmj0eIoOaFg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.5.0.tgz", + "integrity": "sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA==", "dev": true, "dependencies": { - "@jest/test-result": "^29.3.1", - "@jest/types": "^29.3.1", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.13.1", - "jest-util": "^29.3.1", + "jest-util": "^29.5.0", "string-length": "^4.0.1" }, "engines": { @@ -5119,13 +5778,13 @@ } }, "node_modules/jest-worker": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.3.1.tgz", - "integrity": "sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", + "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", "dev": true, "dependencies": { "@types/node": "*", - "jest-util": "^29.3.1", + "jest-util": "^29.5.0", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, @@ -5149,9 +5808,9 @@ } }, "node_modules/js-sdsl": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", - "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/js-sdsl" @@ -5185,27 +5844,26 @@ } }, "node_modules/jsdoc-type-pratt-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-3.1.0.tgz", - "integrity": "sha512-MgtD0ZiCDk9B+eI73BextfRrVQl0oyzRG8B2BjORts6jbunj4ScKPcyXGTbB6eXL4y9TzxCm6hyeLq/2ASzNdw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", + "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", "dev": true, "engines": { "node": ">=12.0.0" } }, "node_modules/jsdom": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", - "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-21.1.1.tgz", + "integrity": "sha512-Jjgdmw48RKcdAIQyUD1UdBh2ecH7VqwaXPN3ehoZN6MqgVbMn+lRm1aAT1AsdJRAJpwfa4IpwgzySn61h2qu3w==", "dev": true, "dependencies": { "abab": "^2.0.6", - "acorn": "^8.8.1", + "acorn": "^8.8.2", "acorn-globals": "^7.0.0", - "cssom": "^0.5.0", - "cssstyle": "^2.3.0", - "data-urls": "^3.0.2", - "decimal.js": "^10.4.2", + "cssstyle": "^3.0.0", + "data-urls": "^4.0.0", + "decimal.js": "^10.4.3", "domexception": "^4.0.0", "escodegen": "^2.0.0", "form-data": "^4.0.0", @@ -5214,7 +5872,8 @@ "https-proxy-agent": "^5.0.1", "is-potential-custom-element-name": "^1.0.1", "nwsapi": "^2.2.2", - "parse5": "^7.1.1", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.6.0", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^4.1.2", @@ -5222,8 +5881,8 @@ "webidl-conversions": "^7.0.0", "whatwg-encoding": "^2.0.0", "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^11.0.0", - "ws": "^8.11.0", + "whatwg-url": "^12.0.1", + "ws": "^8.13.0", "xml-name-validator": "^4.0.0" }, "engines": { @@ -5279,9 +5938,9 @@ "optional": true }, "node_modules/json5": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", - "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, "bin": { "json5": "lib/cli.js" @@ -5333,9 +5992,9 @@ } }, "node_modules/known-css-properties": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.26.0.tgz", - "integrity": "sha512-5FZRzrZzNTBruuurWpvZnvP9pum+fe0HcK8z/ooo+U+Hmp4vtbyp1/QDsqmufirXy4egGzbaH/y2uCZf+6W5Kg==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.27.0.tgz", + "integrity": "sha512-uMCj6+hZYDoffuvAJjFAPz56E9uoowFHmTkqRtRq5WyC5Q6Cu/fTZKNQpX/RbzChBYLLl3lo8CjFZBAZXq9qFg==", "dev": true }, "node_modules/leven": { @@ -5420,9 +6079,9 @@ } }, "node_modules/luxon": { - "version": "1.28.0", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz", - "integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ==", + "version": "1.28.1", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.1.tgz", + "integrity": "sha512-gYHAa180mKrNIUJCbwpmD0aTu9kV0dREDrwNnuyFAsO1Wt0EVYSZelPnJlbj9HplzXX/YWXHFTL45kvZ53M0pw==", "engines": { "node": "*" } @@ -5495,6 +6154,12 @@ "is-buffer": "~1.1.6" } }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -5650,6 +6315,14 @@ "node": "*" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/minimist-options": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", @@ -5687,11 +6360,11 @@ } }, "node_modules/moment-timezone": { - "version": "0.5.40", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.40.tgz", - "integrity": "sha512-tWfmNkRYmBkPJz5mr9GVDn9vRlVZOTe6yqY92rFxiOdWXbjaR0+9LwQnZGGuNR63X456NqmEkbskte8tWL5ePg==", + "version": "0.5.41", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.41.tgz", + "integrity": "sha512-e0jGNZDOHfBXJGz8vR/sIMXvBIGJJcqFjmlg9lmE+5KX1U7/RZNMswfD8nKnNCnQdKTIj50IaRKwl1fvMLyyRg==", "dependencies": { - "moment": ">= 2.9.0" + "moment": "^2.29.4" }, "engines": { "node": "*" @@ -5752,6 +6425,11 @@ "node": ">= 0.6" } }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, "node_modules/nise": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", @@ -5765,24 +6443,6 @@ "path-to-regexp": "^1.7.0" } }, - "node_modules/nise/node_modules/@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/nise/node_modules/@sinonjs/fake-timers": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", - "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^2.0.0" - } - }, "node_modules/nise/node_modules/path-to-regexp": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", @@ -5793,9 +6453,9 @@ } }, "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", + "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -5831,11 +6491,11 @@ } }, "node_modules/node-ical": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/node-ical/-/node-ical-0.15.3.tgz", - "integrity": "sha512-OQ3xipexD/nI0jpoz+ELhMwV8liMMqM+rlxB5xHbPiJRYvueIT+4cipjdt4L64teXXHVmg+xf8OfwJE2LueVlw==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/node-ical/-/node-ical-0.16.0.tgz", + "integrity": "sha512-LgLN6gm2D1AIaBQnbAw8nz+lH2ZT08lOSGhpzi3z+f2JDt3rSkKrWCx96URO8RmGxgx2Cojw15OBWZSpL18kag==", "dependencies": { - "axios": "1.1.3", + "axios": "1.3.4", "moment-timezone": "^0.5.31", "rrule": "2.6.4", "uuid": "^9.0.0" @@ -5848,9 +6508,9 @@ "dev": true }, "node_modules/node-releases": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", - "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==", + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", "dev": true }, "node_modules/normalize-package-data": { @@ -5949,9 +6609,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -5960,11 +6620,44 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "optional": true, "engines": { "node": ">= 0.4" } }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -6252,13 +6945,13 @@ } }, "node_modules/playwright": { - "version": "1.29.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.29.1.tgz", - "integrity": "sha512-lasC+pMqsQ2uWhNurt3YK3xo0gWlMjslYUylKbHcqF/NTjwp9KStRGO7S6wwz2f52GcSnop8XUK/GymJjdzrxw==", + "version": "1.32.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.32.1.tgz", + "integrity": "sha512-GnEizysWMvoqHC3I9l8+4/ZxeLwLNdJJG76xdKGxzOcIZDcw5RSk/FKrFb5CuA+zcLpjIM2p9eR9Z4CuUDkWXg==", "dev": true, "hasInstallScript": true, "dependencies": { - "playwright-core": "1.29.1" + "playwright-core": "1.32.1" }, "bin": { "playwright": "cli.js" @@ -6268,9 +6961,9 @@ } }, "node_modules/playwright-core": { - "version": "1.29.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.29.1.tgz", - "integrity": "sha512-20Ai3d+lMkWpI9YZYlxk8gxatfgax5STW8GaMozAHwigLiyiKQrdkt7gaoT9UQR8FIVDg6qVXs9IoZUQrDjIIg==", + "version": "1.32.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.32.1.tgz", + "integrity": "sha512-KZYUQC10mXD2Am1rGlidaalNGYk3LU1vZqqNk0gT4XPty1jOqgup8KDP8l2CUlqoNKhXM5IfGjWgW37xvGllBA==", "dev": true, "bin": { "playwright": "cli.js" @@ -6280,9 +6973,9 @@ } }, "node_modules/postcss": { - "version": "8.4.20", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz", - "integrity": "sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==", + "version": "8.4.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", + "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", "dev": true, "funding": [ { @@ -6359,9 +7052,9 @@ } }, "node_modules/prettier": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz", - "integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==", + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz", + "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==", "dev": true, "bin": { "prettier": "bin-prettier.js" @@ -6386,12 +7079,12 @@ } }, "node_modules/pretty-format": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz", - "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "dependencies": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -6587,13 +7280,29 @@ } }, "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "engines": { "node": ">=6" } }, + "node_modules/pure-rand": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.1.tgz", + "integrity": "sha512-t+x1zEHDjBwkDGY5v5ApnZ/utcd4XYDiJsaQQoptTXgUXX95sDg1elCdJghzicm7n2mbCBJ3uYWr6M22SO19rg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -6838,15 +7547,28 @@ "node": ">=8" } }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "node_modules/regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/replace-last": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/replace-last/-/replace-last-1.2.6.tgz", + "integrity": "sha512-Cj+MK38VtNu1S5J73mEZY3ciQb9dJajNq1Q8inP4dn/MhJMjHwoAF3Z3FjspwAEV9pfABl565MQucmrjOkty4g==", + "engines": { + "node": ">= 4.0.0" } }, "node_modules/require-directory": { @@ -6926,9 +7648,9 @@ } }, "node_modules/resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.1.tgz", + "integrity": "sha512-OEJWVeimw8mgQuj3HfkNl4KqRevH7lzeQNaWRPfx0PPse7Jk6ozcsG4FKVgtzDsC1KUF+YlTHh17NcgHOPykLw==", "dev": true, "engines": { "node": ">=10" @@ -6997,6 +7719,12 @@ "luxon": "^1.21.3" } }, + "node_modules/rrweb-cssom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", + "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", + "dev": true + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -7038,6 +7766,19 @@ } ] }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -7201,16 +7942,16 @@ "dev": true }, "node_modules/sinon": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.0.1.tgz", - "integrity": "sha512-PZXKc08f/wcA/BMRGBze2Wmw50CWPiAH3E21EOi4B49vJ616vW4DQh4fQrqsYox2aNR/N3kCqLuB0PwwOucQrg==", + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.0.2.tgz", + "integrity": "sha512-PCVP63XZkg0/LOqQH5rEU4LILuvTFMb5tNxTHfs6VUMNnZz2XrnGSTZbAGITjzwQWbl/Bl/8hi4G3zZWjyBwHg==", "dev": true, "dependencies": { - "@sinonjs/commons": "^2.0.0", - "@sinonjs/fake-timers": "10.0.2", + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^10.0.2", "@sinonjs/samsam": "^7.0.1", - "diff": "^5.0.0", - "nise": "^5.1.2", + "diff": "^5.1.0", + "nise": "^5.1.4", "supports-color": "^7.2.0" }, "funding": { @@ -7219,21 +7960,21 @@ } }, "node_modules/sinon/node_modules/@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", "dev": true, "dependencies": { "type-detect": "4.0.8" } }, - "node_modules/sinon/node_modules/@sinonjs/fake-timers": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", - "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "node_modules/sinon/node_modules/diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", "dev": true, - "dependencies": { - "@sinonjs/commons": "^2.0.0" + "engines": { + "node": ">=0.3.1" } }, "node_modules/sisteransi": { @@ -7269,15 +8010,15 @@ } }, "node_modules/socket.io": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.4.tgz", - "integrity": "sha512-m3GC94iK9MfIEeIBfbhJs5BqFibMtkRk8ZpKwG2QwxV0m/eEhPIV4ara6XCF1LWNAus7z58RodiZlAH71U3EhQ==", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.1.tgz", + "integrity": "sha512-KMcaAi4l/8+xEjkRICl6ak8ySoxsYG+gG6/XfRCPJPQ/haCRIJBTL4wIl8YCsmtaBovcAXGLOShyVWQ/FG8GZA==", "dependencies": { "accepts": "~1.3.4", "base64id": "~2.0.0", "debug": "~4.3.2", - "engine.io": "~6.2.1", - "socket.io-adapter": "~2.4.0", + "engine.io": "~6.4.1", + "socket.io-adapter": "~2.5.2", "socket.io-parser": "~4.2.1" }, "engines": { @@ -7285,14 +8026,37 @@ } }, "node_modules/socket.io-adapter": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz", - "integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==" + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", + "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "dependencies": { + "ws": "~8.11.0" + } + }, + "node_modules/socket.io-adapter/node_modules/ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } }, "node_modules/socket.io-parser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz", - "integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.2.tgz", + "integrity": "sha512-DJtziuKypFkMMHCm2uIshOYC7QaylbtzQwiMYDuCKy3OPkjLzu4B2vAhTlqipRHHzrI0NJeBAizTK7X+6m1jVw==", "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1" @@ -7305,7 +8069,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -7330,9 +8093,9 @@ } }, "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, "dependencies": { "spdx-expression-parse": "^3.0.0", @@ -7356,9 +8119,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", - "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", + "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", "dev": true }, "node_modules/sprintf-js": { @@ -7423,6 +8186,66 @@ "node": ">=8" } }, + "node_modules/string.prototype.matchall": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", + "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.4.3", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", + "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -7482,16 +8305,20 @@ "dev": true }, "node_modules/stylelint": { - "version": "14.16.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.16.0.tgz", - "integrity": "sha512-X6uTi9DcxjzLV8ZUAjit1vsRtSwcls0nl07c9rqOPzvpA8IvTX/xWEkBRowS0ffevRrqkHa/ThDEu86u73FQDg==", + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.3.0.tgz", + "integrity": "sha512-9UYBYk7K9rtlKcTUDZrtntE840sZM00qyYBQHHe7tjwMNUsPsGvR6Fd43IxHEAhRrDLzpy3TVaHb6CReBB3eFg==", "dev": true, "dependencies": { - "@csstools/selector-specificity": "^2.0.2", + "@csstools/css-parser-algorithms": "^2.0.1", + "@csstools/css-tokenizer": "^2.1.0", + "@csstools/media-query-list-parser": "^2.0.1", + "@csstools/selector-specificity": "^2.1.1", "balanced-match": "^2.0.0", "colord": "^2.9.3", - "cosmiconfig": "^7.1.0", + "cosmiconfig": "^8.1.0", "css-functions-list": "^3.1.0", + "css-tree": "^2.3.1", "debug": "^4.3.4", "fast-glob": "^3.2.12", "fastest-levenshtein": "^1.0.16", @@ -7500,17 +8327,17 @@ "globby": "^11.1.0", "globjoin": "^0.1.4", "html-tags": "^3.2.0", - "ignore": "^5.2.1", + "ignore": "^5.2.4", "import-lazy": "^4.0.0", "imurmurhash": "^0.1.4", "is-plain-object": "^5.0.0", - "known-css-properties": "^0.26.0", + "known-css-properties": "^0.27.0", "mathml-tag-names": "^2.1.3", "meow": "^9.0.0", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "picocolors": "^1.0.0", - "postcss": "^8.4.19", + "postcss": "^8.4.21", "postcss-media-query-parser": "^0.2.3", "postcss-resolve-nested-selector": "^0.1.1", "postcss-safe-parser": "^6.0.0", @@ -7520,70 +8347,54 @@ "string-width": "^4.2.3", "strip-ansi": "^6.0.1", "style-search": "^0.1.0", - "supports-hyperlinks": "^2.3.0", + "supports-hyperlinks": "^3.0.0", "svg-tags": "^1.0.0", "table": "^6.8.1", "v8-compile-cache": "^2.3.0", - "write-file-atomic": "^4.0.2" + "write-file-atomic": "^5.0.0" }, "bin": { "stylelint": "bin/stylelint.js" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": "^14.13.1 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/stylelint" } }, - "node_modules/stylelint-config-prettier": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/stylelint-config-prettier/-/stylelint-config-prettier-9.0.4.tgz", - "integrity": "sha512-38nIGTGpFOiK5LjJ8Ma1yUgpKENxoKSOhbDNSemY7Ep0VsJoXIW9Iq/2hSt699oB9tReynfWicTAoIHiq8Rvbg==", - "dev": true, - "bin": { - "stylelint-config-prettier": "bin/check.js", - "stylelint-config-prettier-check": "bin/check.js" - }, - "engines": { - "node": ">= 12" - }, - "peerDependencies": { - "stylelint": ">=11.0.0" - } - }, "node_modules/stylelint-config-recommended": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-9.0.0.tgz", - "integrity": "sha512-9YQSrJq4NvvRuTbzDsWX3rrFOzOlYBmZP+o513BJN/yfEmGSr0AxdvrWs0P/ilSpVV/wisamAHu5XSk8Rcf4CQ==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-11.0.0.tgz", + "integrity": "sha512-SoGIHNI748OCZn6BxFYT83ytWoYETCINVHV3LKScVAWQQauWdvmdDqJC5YXWjpBbxg2E761Tg5aUGKLFOVhEkA==", "dev": true, "peerDependencies": { - "stylelint": "^14.10.0" + "stylelint": "^15.3.0" } }, "node_modules/stylelint-config-standard": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-29.0.0.tgz", - "integrity": "sha512-uy8tZLbfq6ZrXy4JKu3W+7lYLgRQBxYTUUB88vPgQ+ZzAxdrvcaSUW9hOMNLYBnwH+9Kkj19M2DHdZ4gKwI7tg==", + "version": "31.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-31.0.0.tgz", + "integrity": "sha512-CUGAmtROCvX0YgMY2+6P9tqSkHj5z/75XxrQ8bGxvkCa1xYdGDx4poM0pa7cXc3s74/PZLJH/okxZZouRfOSGw==", "dev": true, "dependencies": { - "stylelint-config-recommended": "^9.0.0" + "stylelint-config-recommended": "^11.0.0" }, "peerDependencies": { - "stylelint": "^14.14.0" + "stylelint": "^15.3.0" } }, "node_modules/stylelint-prettier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/stylelint-prettier/-/stylelint-prettier-2.0.0.tgz", - "integrity": "sha512-jvT3G+9lopkeB0ARmDPszyfaOnvnIF+30QCjZxyt7E6fynI1T9mOKgYDNb9bXX17M7PXMZaX3j/26wqakjp1tw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stylelint-prettier/-/stylelint-prettier-3.0.0.tgz", + "integrity": "sha512-kIks1xw6np0zElokMT2kP6ar3S4MBoj6vUtPJuND1pFELMpZxVS/0uHPR4HDAVn0WAD3I5oF0IA3qBFxBpMkLg==", "dev": true, "dependencies": { "prettier-linter-helpers": "^1.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^14.17.0 || >=16.0.0" }, "peerDependencies": { "prettier": ">=2.0.0", @@ -7605,6 +8416,19 @@ "node": ">=8" } }, + "node_modules/stylelint/node_modules/write-file-atomic": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.0.tgz", + "integrity": "sha512-R7NYMnHSlV42K54lwY9lvW6MnSm1HSJqZL3xiSgi9E7//FYaI74r2G0rd+/X6VAMkHEdzxQaU5HUOXWUz5kA/w==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/sumchecker": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", @@ -7635,16 +8459,16 @@ } }, "node_modules/supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", + "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", "dev": true, "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" }, "engines": { - "node": ">=8" + "node": ">=14.18" } }, "node_modules/supports-preserve-symlinks-flag": { @@ -7688,9 +8512,9 @@ } }, "node_modules/table/node_modules/ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", @@ -7783,29 +8607,62 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", "dev": true, - "engines": { - "node": ">= 4.0.0" + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/tr46": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "dev": true, + "dependencies": { + "punycode": "^2.3.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", + "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" } }, - "node_modules/tr46": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", - "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "dependencies": { - "punycode": "^2.1.1" + "minimist": "^1.2.0" }, - "engines": { - "node": ">=12" + "bin": { + "json5": "lib/cli.js" } }, - "node_modules/trim-newlines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", - "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, "engines": { - "node": ">=8" + "node": ">=4" } }, "node_modules/tslib": { @@ -7871,10 +8728,23 @@ "node": ">= 0.6" } }, + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typescript": { - "version": "4.9.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", - "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", + "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", "dev": true, "peer": true, "bin": { @@ -7882,7 +8752,33 @@ "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=12.20" + } + }, + "node_modules/uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/universalify": { @@ -7975,9 +8871,9 @@ "dev": true }, "node_modules/v8-to-istanbul": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", - "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", + "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", @@ -8064,16 +8960,16 @@ } }, "node_modules/whatwg-url": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", - "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", + "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", "dev": true, "dependencies": { - "tr46": "^3.0.0", + "tr46": "^4.1.1", "webidl-conversions": "^7.0.0" }, "engines": { - "node": ">=12" + "node": ">=14" } }, "node_modules/which": { @@ -8090,6 +8986,40 @@ "node": ">= 8" } }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -8098,6 +9028,11 @@ "node": ">=0.10.0" } }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -8134,16 +9069,16 @@ } }, "node_modules/ws": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", "dev": true, "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -8184,19 +9119,10 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, "node_modules/yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", "dev": true, "dependencies": { "cliui": "^8.0.1", @@ -8272,31 +9198,31 @@ } }, "@babel/compat-data": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", - "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.0.tgz", + "integrity": "sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==", "dev": true }, "@babel/core": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.7.tgz", - "integrity": "sha512-t1ZjCluspe5DW24bn2Rr1CDb2v9rn/hROtg9a2tmd0+QYf4bsloYfLQzjG4qHPNMhWtKdGC33R5AxGR2Af2cBw==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.3.tgz", + "integrity": "sha512-qIJONzoa/qiHghnm0l1n4i/6IIziDpzqc36FBs4pzMhDUraHqponwJLiAKm1hGLP3OSB/TVNz6rMwVGpwxxySw==", "dev": true, "requires": { - "@ampproject/remapping": "^2.1.0", + "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", + "@babel/generator": "^7.21.3", "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-module-transforms": "^7.20.7", - "@babel/helpers": "^7.20.7", - "@babel/parser": "^7.20.7", + "@babel/helper-module-transforms": "^7.21.2", + "@babel/helpers": "^7.21.0", + "@babel/parser": "^7.21.3", "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.7", - "@babel/types": "^7.20.7", + "@babel/traverse": "^7.21.3", + "@babel/types": "^7.21.3", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", + "json5": "^2.2.2", "semver": "^6.3.0" }, "dependencies": { @@ -8309,13 +9235,14 @@ } }, "@babel/generator": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", - "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.3.tgz", + "integrity": "sha512-QS3iR1GYC/YGUnW7IdggFeN5c1poPUurnGttOV/bZgPGV+izC/D8HnD6DLwod0fsatNyVn1G3EVWMYIF0nHbeA==", "dev": true, "requires": { - "@babel/types": "^7.20.7", + "@babel/types": "^7.21.3", "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "dependencies": { @@ -8352,13 +9279,13 @@ "dev": true }, "@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", "dev": true, "requires": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" } }, "@babel/helper-hoist-variables": { @@ -8380,9 +9307,9 @@ } }, "@babel/helper-module-transforms": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.7.tgz", - "integrity": "sha512-FNdu7r67fqMUSVuQpFQGE6BPdhJIhitoxhGzDbAXNcA07uoVG37fOiMk3OSV8rEICuyG6t8LGkd9EE64qIEoIA==", + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", + "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", "dev": true, "requires": { "@babel/helper-environment-visitor": "^7.18.9", @@ -8391,8 +9318,8 @@ "@babel/helper-split-export-declaration": "^7.18.6", "@babel/helper-validator-identifier": "^7.19.1", "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/traverse": "^7.21.2", + "@babel/types": "^7.21.2" } }, "@babel/helper-plugin-utils": { @@ -8432,20 +9359,20 @@ "dev": true }, "@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", + "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", "dev": true }, "@babel/helpers": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.7.tgz", - "integrity": "sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz", + "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==", "dev": true, "requires": { "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/traverse": "^7.21.0", + "@babel/types": "^7.21.0" } }, "@babel/highlight": { @@ -8518,9 +9445,9 @@ } }, "@babel/parser": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz", - "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.3.tgz", + "integrity": "sha512-lobG0d7aOfQRXh8AyklEAgZGvA4FShxo6xQbUrrT/cNBPUdIDojlokwJsQyCC/eKia7ifqM0yP+2DRZ4WKw2RQ==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -8661,19 +9588,19 @@ } }, "@babel/traverse": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.7.tgz", - "integrity": "sha512-xueOL5+ZKX2dJbg8z8o4f4uTRTqGDRjilva9D1hiRlayJbTY8jBRL+Ph67IeRTIE439/VifHk+Z4g0SwRtQE0A==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.3.tgz", + "integrity": "sha512-XLyopNeaTancVitYZe2MlUEvgKb6YVVPXzofHgqHijCImG33b/uTurMS488ht/Hbsb2XK3U2BnSTxKVNGV3nGQ==", "dev": true, "requires": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", + "@babel/generator": "^7.21.3", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", + "@babel/helper-function-name": "^7.21.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", + "@babel/parser": "^7.21.3", + "@babel/types": "^7.21.3", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -8687,9 +9614,9 @@ } }, "@babel/types": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", - "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.3.tgz", + "integrity": "sha512-sBGdETxC+/M4o/zKC0sl6sjWv62WFR/uzxrJ6uYyMLZOUlPnwzw0tKgVHOXxaAd5l2g8pEDM5RZ495GPQI77kg==", "dev": true, "requires": { "@babel/helper-string-parser": "^7.19.4", @@ -8703,10 +9630,30 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "@csstools/css-parser-algorithms": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.0.1.tgz", + "integrity": "sha512-B9/8PmOtU6nBiibJg0glnNktQDZ3rZnGn/7UmDfrm2vMtrdlXO3p7ErE95N0up80IRk9YEtB5jyj/TmQ1WH3dw==", + "dev": true, + "requires": {} + }, + "@csstools/css-tokenizer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.1.0.tgz", + "integrity": "sha512-dtqFyoJBHUxGi9zPZdpCKP1xk8tq6KPHJ/NY4qWXiYo6IcSGwzk3L8x2XzZbbyOyBs9xQARoGveU2AsgLj6D2A==", + "dev": true + }, + "@csstools/media-query-list-parser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.0.1.tgz", + "integrity": "sha512-X2/OuzEbjaxhzm97UJ+95GrMeT29d1Ib+Pu+paGLuRWZnWRK9sI9r3ikmKXPWGA1C4y4JEdBEFpp9jEqCvLeRA==", + "dev": true, + "requires": {} + }, "@csstools/selector-specificity": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz", - "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.1.1.tgz", + "integrity": "sha512-jwx+WCqszn53YHOfvFMJJRd/B2GqkCBt+1MJSG6o5/s8+ytHMvDZXsJgUEWLk12UnLd7HYKac4BYU5i/Ron1Cw==", "dev": true, "requires": {} }, @@ -8727,24 +9674,37 @@ } }, "@es-joy/jsdoccomment": { - "version": "0.36.1", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.36.1.tgz", - "integrity": "sha512-922xqFsTpHs6D0BUiG4toiyPOMc8/jafnWKxz1KWgS4XzKPy2qXf1Pe6UFuNSCQqt6tOuhAWXBNuuyUhJmw9Vg==", + "version": "0.37.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.37.0.tgz", + "integrity": "sha512-hjK0wnsPCYLlF+HHB4R/RbUjOWeLW2SlarB67+Do5WsKILOkmIZvvPJFbtWSmbypxcjpoECLAMzoao0D4Bg5ZQ==", "dev": true, "requires": { "comment-parser": "1.3.1", "esquery": "^1.4.0", - "jsdoc-type-pratt-parser": "~3.1.0" + "jsdoc-type-pratt-parser": "~4.0.0" + } + }, + "@eslint-community/eslint-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.3.0.tgz", + "integrity": "sha512-v3oplH6FYCULtFuCeqyuTd9D2WKO937Dxdq+GmHOLL72TTRriLxz2VLlNfkZRsvj6PKnOPAtuT6dwrs/pA5DvA==", + "requires": { + "eslint-visitor-keys": "^3.3.0" } }, + "@eslint-community/regexpp": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.0.tgz", + "integrity": "sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==" + }, "@eslint/eslintrc": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.0.tgz", - "integrity": "sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.1.tgz", + "integrity": "sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==", "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", + "espree": "^9.5.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -8753,6 +9713,11 @@ "strip-json-comments": "^3.1.1" } }, + "@eslint/js": { + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz", + "integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==" + }, "@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -8863,123 +9828,123 @@ "dev": true }, "@jest/console": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.3.1.tgz", - "integrity": "sha512-IRE6GD47KwcqA09RIWrabKdHPiKDGgtAL31xDxbi/RjQMsr+lY+ppxmHwY0dUEV3qvvxZzoe5Hl0RXZJOjQNUg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.5.0.tgz", + "integrity": "sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==", "dev": true, "requires": { - "@jest/types": "^29.3.1", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.3.1", - "jest-util": "^29.3.1", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", "slash": "^3.0.0" } }, "@jest/core": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.3.1.tgz", - "integrity": "sha512-0ohVjjRex985w5MmO5L3u5GR1O30DexhBSpuwx2P+9ftyqHdJXnk7IUWiP80oHMvt7ubHCJHxV0a0vlKVuZirw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.5.0.tgz", + "integrity": "sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ==", "dev": true, "requires": { - "@jest/console": "^29.3.1", - "@jest/reporters": "^29.3.1", - "@jest/test-result": "^29.3.1", - "@jest/transform": "^29.3.1", - "@jest/types": "^29.3.1", + "@jest/console": "^29.5.0", + "@jest/reporters": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.2.0", - "jest-config": "^29.3.1", - "jest-haste-map": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.3.1", - "jest-resolve-dependencies": "^29.3.1", - "jest-runner": "^29.3.1", - "jest-runtime": "^29.3.1", - "jest-snapshot": "^29.3.1", - "jest-util": "^29.3.1", - "jest-validate": "^29.3.1", - "jest-watcher": "^29.3.1", + "jest-changed-files": "^29.5.0", + "jest-config": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-resolve-dependencies": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "jest-watcher": "^29.5.0", "micromatch": "^4.0.4", - "pretty-format": "^29.3.1", + "pretty-format": "^29.5.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" } }, "@jest/environment": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.3.1.tgz", - "integrity": "sha512-pMmvfOPmoa1c1QpfFW0nXYtNLpofqo4BrCIk6f2kW4JFeNlHV2t3vd+3iDLf31e2ot2Mec0uqZfmI+U0K2CFag==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.5.0.tgz", + "integrity": "sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==", "dev": true, "requires": { - "@jest/fake-timers": "^29.3.1", - "@jest/types": "^29.3.1", + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", - "jest-mock": "^29.3.1" + "jest-mock": "^29.5.0" } }, "@jest/expect": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.3.1.tgz", - "integrity": "sha512-QivM7GlSHSsIAWzgfyP8dgeExPRZ9BIe2LsdPyEhCGkZkoyA+kGsoIzbKAfZCvvRzfZioKwPtCZIt5SaoxYCvg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.5.0.tgz", + "integrity": "sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==", "dev": true, "requires": { - "expect": "^29.3.1", - "jest-snapshot": "^29.3.1" + "expect": "^29.5.0", + "jest-snapshot": "^29.5.0" } }, "@jest/expect-utils": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.3.1.tgz", - "integrity": "sha512-wlrznINZI5sMjwvUoLVk617ll/UYfGIZNxmbU+Pa7wmkL4vYzhV9R2pwVqUh4NWWuLQWkI8+8mOkxs//prKQ3g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.5.0.tgz", + "integrity": "sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==", "dev": true, "requires": { - "jest-get-type": "^29.2.0" + "jest-get-type": "^29.4.3" } }, "@jest/fake-timers": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.3.1.tgz", - "integrity": "sha512-iHTL/XpnDlFki9Tq0Q1GGuVeQ8BHZGIYsvCO5eN/O/oJaRzofG9Xndd9HuSDBI/0ZS79pg0iwn07OMTQ7ngF2A==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.5.0.tgz", + "integrity": "sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==", "dev": true, "requires": { - "@jest/types": "^29.3.1", - "@sinonjs/fake-timers": "^9.1.2", + "@jest/types": "^29.5.0", + "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^29.3.1", - "jest-mock": "^29.3.1", - "jest-util": "^29.3.1" + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" } }, "@jest/globals": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.3.1.tgz", - "integrity": "sha512-cTicd134vOcwO59OPaB6AmdHQMCtWOe+/DitpTZVxWgMJ+YvXL1HNAmPyiGbSHmF/mXVBkvlm8YYtQhyHPnV6Q==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.5.0.tgz", + "integrity": "sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ==", "dev": true, "requires": { - "@jest/environment": "^29.3.1", - "@jest/expect": "^29.3.1", - "@jest/types": "^29.3.1", - "jest-mock": "^29.3.1" + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/types": "^29.5.0", + "jest-mock": "^29.5.0" } }, "@jest/reporters": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.3.1.tgz", - "integrity": "sha512-GhBu3YFuDrcAYW/UESz1JphEAbvUjaY2vShRZRoRY1mxpCMB3yGSJ4j9n0GxVlEOdCf7qjvUfBCrTUUqhVfbRA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.5.0.tgz", + "integrity": "sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.3.1", - "@jest/test-result": "^29.3.1", - "@jest/transform": "^29.3.1", - "@jest/types": "^29.3.1", + "@jest/console": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@jridgewell/trace-mapping": "^0.3.15", "@types/node": "*", "chalk": "^4.0.0", @@ -8992,9 +9957,9 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.3.1", - "jest-util": "^29.3.1", - "jest-worker": "^29.3.1", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", @@ -9002,18 +9967,18 @@ } }, "@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", "dev": true, "requires": { - "@sinclair/typebox": "^0.24.1" + "@sinclair/typebox": "^0.25.16" } }, "@jest/source-map": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.2.0.tgz", - "integrity": "sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.3.tgz", + "integrity": "sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==", "dev": true, "requires": { "@jridgewell/trace-mapping": "^0.3.15", @@ -9022,59 +9987,59 @@ } }, "@jest/test-result": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.3.1.tgz", - "integrity": "sha512-qeLa6qc0ddB0kuOZyZIhfN5q0e2htngokyTWsGriedsDhItisW7SDYZ7ceOe57Ii03sL988/03wAcBh3TChMGw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.5.0.tgz", + "integrity": "sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==", "dev": true, "requires": { - "@jest/console": "^29.3.1", - "@jest/types": "^29.3.1", + "@jest/console": "^29.5.0", + "@jest/types": "^29.5.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/test-sequencer": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.3.1.tgz", - "integrity": "sha512-IqYvLbieTv20ArgKoAMyhLHNrVHJfzO6ARZAbQRlY4UGWfdDnLlZEF0BvKOMd77uIiIjSZRwq3Jb3Fa3I8+2UA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.5.0.tgz", + "integrity": "sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ==", "dev": true, "requires": { - "@jest/test-result": "^29.3.1", + "@jest/test-result": "^29.5.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.3.1", + "jest-haste-map": "^29.5.0", "slash": "^3.0.0" } }, "@jest/transform": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.3.1.tgz", - "integrity": "sha512-8wmCFBTVGYqFNLWfcOWoVuMuKYPUBTnTMDkdvFtAYELwDOl9RGwOsvQWGPFxDJ8AWY9xM/8xCXdqmPK3+Q5Lug==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.5.0.tgz", + "integrity": "sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==", "dev": true, "requires": { "@babel/core": "^7.11.6", - "@jest/types": "^29.3.1", + "@jest/types": "^29.5.0", "@jridgewell/trace-mapping": "^0.3.15", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.3.1", - "jest-regex-util": "^29.2.0", - "jest-util": "^29.3.1", + "jest-haste-map": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", - "write-file-atomic": "^4.0.1" + "write-file-atomic": "^4.0.2" } }, "@jest/types": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.3.1.tgz", - "integrity": "sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", + "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", "dev": true, "requires": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -9144,9 +10109,9 @@ } }, "@sinclair/typebox": { - "version": "0.24.51", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", - "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", "dev": true }, "@sindresorhus/is": { @@ -9156,21 +10121,21 @@ "optional": true }, "@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", "dev": true, "requires": { "type-detect": "4.0.8" } }, "@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", + "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", "dev": true, "requires": { - "@sinonjs/commons": "^1.7.0" + "@sinonjs/commons": "^2.0.0" } }, "@sinonjs/samsam": { @@ -9222,13 +10187,13 @@ "dev": true }, "@types/babel__core": { - "version": "7.1.20", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz", - "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", + "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", "dev": true, "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" @@ -9288,9 +10253,9 @@ } }, "@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", "dev": true, "requires": { "@types/node": "*" @@ -9332,6 +10297,12 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, "@types/keyv": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", @@ -9354,9 +10325,9 @@ "dev": true }, "@types/node": { - "version": "16.18.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.10.tgz", - "integrity": "sha512-XU1+v7h81p7145ddPfjv7jtWvkSilpcnON3mQ+bDi9Yuf7OI56efOglXRyXWgQ57xH3fEQgh7WOJMncRHVew5w==" + "version": "16.18.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.18.tgz", + "integrity": "sha512-fwGw1uvQAzabxL1pyoknPlJIF2t7+K90uTqynleKRx24n3lYcxWa3+KByLhgkF8GEAK2c7hC8Ki0RkNM5H15jQ==" }, "@types/normalize-package-data": { "version": "2.4.1", @@ -9364,12 +10335,6 @@ "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true - }, "@types/prettier": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", @@ -9398,9 +10363,9 @@ "dev": true }, "@types/yargs": { - "version": "17.0.17", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.17.tgz", - "integrity": "sha512-72bWxFKTK6uwWJAVT+3rF6Jo6RTojiJ27FQo8Rf60AL+VZbzoVPnMFhKsUnbjR8A3BTCYQ7Mv3hnl8T0A+CX9g==", + "version": "17.0.22", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.22.tgz", + "integrity": "sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g==", "dev": true, "requires": { "@types/yargs-parser": "*" @@ -9422,29 +10387,29 @@ } }, "@typescript-eslint/scope-manager": { - "version": "5.47.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.0.tgz", - "integrity": "sha512-dvJab4bFf7JVvjPuh3sfBUWsiD73aiftKBpWSfi3sUkysDQ4W8x+ZcFpNp7Kgv0weldhpmMOZBjx1wKN8uWvAw==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.56.0.tgz", + "integrity": "sha512-jGYKyt+iBakD0SA5Ww8vFqGpoV2asSjwt60Gl6YcO8ksQ8s2HlUEyHBMSa38bdLopYqGf7EYQMUIGdT/Luw+sw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.47.0", - "@typescript-eslint/visitor-keys": "5.47.0" + "@typescript-eslint/types": "5.56.0", + "@typescript-eslint/visitor-keys": "5.56.0" } }, "@typescript-eslint/types": { - "version": "5.47.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.0.tgz", - "integrity": "sha512-eslFG0Qy8wpGzDdYKu58CEr3WLkjwC5Usa6XbuV89ce/yN5RITLe1O8e+WFEuxnfftHiJImkkOBADj58ahRxSg==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.56.0.tgz", + "integrity": "sha512-JyAzbTJcIyhuUhogmiu+t79AkdnqgPUEsxMTMc/dCZczGMJQh1MK2wgrju++yMN6AWroVAy2jxyPcPr3SWCq5w==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.47.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.0.tgz", - "integrity": "sha512-LxfKCG4bsRGq60Sqqu+34QT5qT2TEAHvSCCJ321uBWywgE2dS0LKcu5u+3sMGo+Vy9UmLOhdTw5JHzePV/1y4Q==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.56.0.tgz", + "integrity": "sha512-41CH/GncsLXOJi0jb74SnC7jVPWeVJ0pxQj8bOjH1h2O26jXN3YHKDT1ejkVz5YeTEQPeLCCRY0U2r68tfNOcg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.47.0", - "@typescript-eslint/visitor-keys": "5.47.0", + "@typescript-eslint/types": "5.56.0", + "@typescript-eslint/visitor-keys": "5.56.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -9479,18 +10444,18 @@ } }, "@typescript-eslint/utils": { - "version": "5.47.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.47.0.tgz", - "integrity": "sha512-U9xcc0N7xINrCdGVPwABjbAKqx4GK67xuMV87toI+HUqgXj26m6RBp9UshEXcTrgCkdGYFzgKLt8kxu49RilDw==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.56.0.tgz", + "integrity": "sha512-XhZDVdLnUJNtbzaJeDSCIYaM+Tgr59gZGbFuELgF7m0IY03PlciidS7UQNKLE0+WpUTn1GlycEr6Ivb/afjbhA==", "dev": true, "requires": { + "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.47.0", - "@typescript-eslint/types": "5.47.0", - "@typescript-eslint/typescript-estree": "5.47.0", + "@typescript-eslint/scope-manager": "5.56.0", + "@typescript-eslint/types": "5.56.0", + "@typescript-eslint/typescript-estree": "5.56.0", "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", "semver": "^7.3.7" }, "dependencies": { @@ -9537,12 +10502,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "5.47.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.0.tgz", - "integrity": "sha512-ByPi5iMa6QqDXe/GmT/hR6MZtVPi0SqMQPDx15FczCBXJo/7M8T88xReOALAfpBLm+zxpPfmhuEvPb577JRAEg==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.56.0.tgz", + "integrity": "sha512-1mFdED7u5bZpX6Xxf5N9U2c18sb+8EvU3tyOIj6LQZ5OOvnmj8BVeNNP603OFPm5KkS1a7IvCIcwrdHXaEMG/Q==", "dev": true, "requires": { - "@typescript-eslint/types": "5.47.0", + "@typescript-eslint/types": "5.56.0", "eslint-visitor-keys": "^3.3.0" } }, @@ -9562,9 +10527,9 @@ } }, "acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==" + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==" }, "acorn-globals": { "version": "7.0.1", @@ -9653,6 +10618,15 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, + "array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "requires": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + } + }, "array-differ": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", @@ -9664,12 +10638,49 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "array-includes": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "is-string": "^1.0.7" + } + }, "array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, + "array.prototype.flat": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", + "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + } + }, + "array.prototype.flatmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + } + }, "arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", @@ -9687,10 +10698,15 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, + "available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" + }, "axios": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.1.3.tgz", - "integrity": "sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.4.tgz", + "integrity": "sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==", "requires": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", @@ -9698,15 +10714,15 @@ } }, "babel-jest": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.3.1.tgz", - "integrity": "sha512-aard+xnMoxgjwV70t0L6wkW/3HQQtV+O0PEimxKgzNqCJnbYmroPojdP2tqKSOAt8QAKV/uSZU8851M7B5+fcA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.5.0.tgz", + "integrity": "sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q==", "dev": true, "requires": { - "@jest/transform": "^29.3.1", + "@jest/transform": "^29.5.0", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.2.0", + "babel-preset-jest": "^29.5.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" @@ -9726,9 +10742,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.2.0.tgz", - "integrity": "sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", + "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", "dev": true, "requires": { "@babel/template": "^7.3.3", @@ -9758,12 +10774,12 @@ } }, "babel-preset-jest": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.2.0.tgz", - "integrity": "sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", + "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^29.2.0", + "babel-plugin-jest-hoist": "^29.5.0", "babel-preset-current-node-syntax": "^1.0.0" } }, @@ -9799,6 +10815,11 @@ } } }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, "body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", @@ -9866,15 +10887,15 @@ } }, "browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" } }, "bser": { @@ -9964,9 +10985,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001441", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001441.tgz", - "integrity": "sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg==", + "version": "1.0.30001468", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001468.tgz", + "integrity": "sha512-zgAo8D5kbOyUcRAgSmgyuvBkjrGk5CGYG5TYgFdpQv+ywcyEpo1LOWoG8YmoflGnh+V+UsNuKYedsoYs0hzV5A==", "dev": true }, "chalk": { @@ -9990,9 +11011,9 @@ "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==" }, "ci-info": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz", - "integrity": "sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", "dev": true }, "cjs-module-lexer": { @@ -10070,6 +11091,11 @@ "delayed-stream": "~1.0.0" } }, + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" + }, "comment-parser": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz", @@ -10082,9 +11108,9 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "console-stamp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/console-stamp/-/console-stamp-3.1.0.tgz", - "integrity": "sha512-Vt22288o0Hrxb9uYwXMWYuw/Mu8iPSrFPtIiveq9uE0zWXPDDCAIvKZojqnwcyINnJY9tnTeG0neV/MD+2G5+g==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/console-stamp/-/console-stamp-3.1.1.tgz", + "integrity": "sha512-NTbqQ9X57xffQKTJbAm4h/ro7JNR2uD3369NeTjmRdfPJ2QmkmCUnMvC1QSxZPQOof3WPrkuA6DQV5+n35ZiIA==", "requires": { "chalk": "^4.1.2", "dateformat": "^4.6.3" @@ -10099,9 +11125,9 @@ } }, "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" }, "convert-source-map": { "version": "2.0.0", @@ -10129,16 +11155,15 @@ } }, "cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.1.3.tgz", + "integrity": "sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw==", "dev": true, "requires": { - "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" + "path-type": "^4.0.0" } }, "cross-spawn": { @@ -10162,44 +11187,40 @@ "integrity": "sha512-/9lCvYZaUbBGvYUgYGFJ4dcYiyqdhSjG7IPVluoV8A1ILjkF7ilmhp1OGUz8n+nmBcu0RNrQAzgD8B6FJbrt2w==", "dev": true }, + "css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "requires": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + } + }, "cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true }, - "cssom": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", - "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", - "dev": true - }, "cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", + "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", "dev": true, "requires": { - "cssom": "~0.3.6" - }, - "dependencies": { - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - } + "rrweb-cssom": "^0.6.0" } }, "data-urls": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", - "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz", + "integrity": "sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==", "dev": true, "requires": { "abab": "^2.0.6", "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^11.0.0" + "whatwg-url": "^12.0.0" } }, "dateformat": { @@ -10274,9 +11295,9 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" }, "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true }, "defer-to-connect": { @@ -10286,10 +11307,9 @@ "optional": true }, "define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "optional": true, + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", "requires": { "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" @@ -10323,15 +11343,14 @@ "optional": true }, "diff": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", - "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", - "dev": true + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" }, "diff-sequences": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz", - "integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", "dev": true }, "digest-fetch": { @@ -10377,9 +11396,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "electron": { - "version": "22.0.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-22.0.0.tgz", - "integrity": "sha512-cgRc4wjyM+81A0E8UGv1HNJjL1HBI5cWNh/DUIjzYvoUuiEM0SS0hAH/zaFQ18xOz2ced6Yih8SybpOiOYJhdg==", + "version": "22.3.4", + "resolved": "https://registry.npmjs.org/electron/-/electron-22.3.4.tgz", + "integrity": "sha512-EY/ieC3gnKYUNOQPJSCIbiMBwEnGs/j0yIAUf0pXPK4BRh2nvXTD5d9OdouAIN7bRNLLPgqoTm0uXgZPAWTVkg==", "optional": true, "requires": { "@electron/get": "^2.0.0", @@ -10388,9 +11407,9 @@ } }, "electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", + "version": "1.4.333", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.333.tgz", + "integrity": "sha512-YyE8+GKyGtPEP1/kpvqsdhD6rA/TP1DUFDN4uiU/YI52NzDxmwHkEb3qjId8hLBa5siJvG0sfC3O66501jMruQ==", "dev": true }, "emittery": { @@ -10420,9 +11439,9 @@ } }, "engine.io": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz", - "integrity": "sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.1.tgz", + "integrity": "sha512-JFYQurD/nbsA5BSPmbaOSLa3tSVj8L6o4srSwXXY3NqE+gGUNmmPTbhn8tjzcCtSqhFgIeqef81ngny8JM25hw==", "requires": { "@types/cookie": "^0.4.1", "@types/cors": "^2.8.12", @@ -10433,7 +11452,7 @@ "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~5.0.3", - "ws": "~8.2.3" + "ws": "~8.11.0" }, "dependencies": { "cookie": { @@ -10442,17 +11461,17 @@ "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" }, "ws": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", "requires": {} } } }, "engine.io-parser": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz", - "integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==" + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.6.tgz", + "integrity": "sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw==" }, "entities": { "version": "4.4.0", @@ -10466,6 +11485,32 @@ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "optional": true }, + "envsub": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/envsub/-/envsub-4.1.0.tgz", + "integrity": "sha512-B44hta3xNFu6+zDhOha1TIrZkQHGDO3G5K8D2sJIkm/s3XyQjxWBGp1B+b/Y74Go1PqMP+cp8moPR4JullnD9Q==", + "requires": { + "bluebird": "^3.7.2", + "chalk": "^3.0.0", + "commander": "^4.0.1", + "diff": "^4.0.1", + "handlebars": "^4.5.3", + "lodash": "^4.17.15", + "replace-last": "^1.2.6", + "string.prototype.matchall": "^4.0.8" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -10475,6 +11520,76 @@ "is-arrayish": "^0.2.1" } }, + "es-abstract": { + "version": "1.21.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", + "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==", + "requires": { + "array-buffer-byte-length": "^1.0.0", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.2.0", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.7", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.9" + } + }, + "es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "requires": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + } + }, + "es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, "es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", @@ -10552,11 +11667,14 @@ } }, "eslint": { - "version": "8.30.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.30.0.tgz", - "integrity": "sha512-MGADB39QqYuzEGov+F/qb18r4i7DohCDOfatHaxI2iGlPuC65bwG2gxgO+7DkyL38dRFaRH7RaRAgU6JKL9rMQ==", - "requires": { - "@eslint/eslintrc": "^1.4.0", + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz", + "integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==", + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.1", + "@eslint/js": "8.36.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -10567,10 +11685,9 @@ "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", + "espree": "^9.5.0", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", @@ -10591,39 +11708,123 @@ "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" } }, - "eslint-config-prettier": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", - "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", - "dev": true, - "requires": {} - }, + "eslint-config-prettier": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", + "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==", + "dev": true, + "requires": {} + }, + "eslint-import-resolver-node": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz", + "integrity": "sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "is-core-module": "^2.11.0", + "resolve": "^1.22.1" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-module-utils": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", + "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", + "dev": true, + "requires": { + "debug": "^3.2.7" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-plugin-import": { + "version": "2.27.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz", + "integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==", + "dev": true, + "requires": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "array.prototype.flatmap": "^1.3.1", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.7", + "eslint-module-utils": "^2.7.4", + "has": "^1.0.3", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.6", + "resolve": "^1.22.1", + "semver": "^6.3.0", + "tsconfig-paths": "^3.14.1" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + } + } + }, "eslint-plugin-jest": { - "version": "27.1.7", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.1.7.tgz", - "integrity": "sha512-0QVzf+og4YI1Qr3UoprkqqhezAZjFffdi62b0IurkCXMqPtRW84/UT4CKsYT80h/D82LA9avjO/80Ou1LdgbaQ==", + "version": "27.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.2.1.tgz", + "integrity": "sha512-l067Uxx7ZT8cO9NJuf+eJHvt6bqJyz2Z29wykyEdz/OtmcELQl2MQGQLX8J94O1cSJWAwUSEvCjwjA7KEK3Hmg==", "dev": true, "requires": { "@typescript-eslint/utils": "^5.10.0" } }, "eslint-plugin-jsdoc": { - "version": "39.6.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.6.4.tgz", - "integrity": "sha512-fskvdLCfwmPjHb6e+xNGDtGgbF8X7cDwMtVLAP2WwSf9Htrx68OAx31BESBM1FAwsN2HTQyYQq7m4aW4Q4Nlag==", + "version": "40.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-40.1.0.tgz", + "integrity": "sha512-ANvrhiu62VlSorARM0hup60VQsS3hNyp0Ca7cnJDj8tpJzM7tNhBVqMVYXSuLzEmqrpwx6aAh+NAN2DdAGG5fQ==", "dev": true, "requires": { - "@es-joy/jsdoccomment": "~0.36.1", + "@es-joy/jsdoccomment": "~0.37.0", "comment-parser": "1.3.1", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", - "esquery": "^1.4.0", + "esquery": "^1.5.0", "semver": "^7.3.8", "spdx-expression-parse": "^3.0.1" }, @@ -10672,30 +11873,15 @@ "estraverse": "^5.2.0" } }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "requires": { - "eslint-visitor-keys": "^2.0.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==" - } - } - }, "eslint-visitor-keys": { "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==" }, "espree": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz", + "integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==", "requires": { "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", @@ -10709,9 +11895,9 @@ "dev": true }, "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "requires": { "estraverse": "^5.1.0" } @@ -10771,16 +11957,16 @@ "dev": true }, "expect": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.3.1.tgz", - "integrity": "sha512-gGb1yTgU30Q0O/tQq+z30KBWv24ApkMgFUpvKBkyLUBL68Wv8dHdJxTBZFl/iT8K/bqDHvUYRH6IIN3rToopPA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.5.0.tgz", + "integrity": "sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg==", "dev": true, "requires": { - "@jest/expect-utils": "^29.3.1", - "jest-get-type": "^29.2.0", - "jest-matcher-utils": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-util": "^29.3.1" + "@jest/expect-utils": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0" } }, "express": { @@ -10920,9 +12106,9 @@ "dev": true }, "fastq": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz", - "integrity": "sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "requires": { "reusify": "^1.0.4" } @@ -11028,6 +12214,14 @@ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "requires": { + "is-callable": "^1.1.3" + } + }, "form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -11076,6 +12270,22 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + } + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==" + }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -11089,9 +12299,9 @@ "dev": true }, "get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -11113,6 +12323,15 @@ "pump": "^3.0.0" } }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -11206,9 +12425,9 @@ } }, "globals": { - "version": "13.19.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", - "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "requires": { "type-fest": "^0.20.2" } @@ -11217,7 +12436,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "optional": true, "requires": { "define-properties": "^1.1.3" } @@ -11242,6 +12460,14 @@ "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", "dev": true }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "requires": { + "get-intrinsic": "^1.1.3" + } + }, "got": { "version": "11.8.6", "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", @@ -11262,9 +12488,9 @@ } }, "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "devOptional": true }, "grapheme-splitter": { @@ -11272,6 +12498,18 @@ "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==" }, + "handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + } + }, "hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -11286,6 +12524,11 @@ "function-bind": "^1.1.1" } }, + "has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==" + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -11295,16 +12538,28 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "optional": true, "requires": { "get-intrinsic": "^1.1.1" } }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==" + }, "has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "requires": { + "has-symbols": "^1.0.2" + } + }, "helmet": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/helmet/-/helmet-6.0.1.tgz", @@ -11358,9 +12613,9 @@ "dev": true }, "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", "optional": true }, "http-errors": { @@ -11413,9 +12668,9 @@ "dev": true }, "husky": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.2.tgz", - "integrity": "sha512-Tkv80jtvbnkK3mYWxPZePGFpQ/tT3HNSs/sasF9P2YfkMezDl3ON37YN6jUUI4eTg5LcyVynlb6r4eyvOmspvg==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", + "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", "dev": true }, "iconv-lite": { @@ -11487,6 +12742,16 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, + "internal-slot": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "requires": { + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, "ip": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", @@ -11502,17 +12767,49 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, + "is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + } + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, + "is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" + }, "is-core-module": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", @@ -11522,6 +12819,14 @@ "has": "^1.0.3" } }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -11547,12 +12852,25 @@ "is-extglob": "^2.1.1" } }, + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==" + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, "is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", @@ -11576,12 +12894,65 @@ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "dev": true }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "requires": { + "call-bind": "^1.0.2" + } + }, "is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typed-array": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + } + }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "requires": { + "call-bind": "^1.0.2" + } + }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", @@ -11645,21 +13016,21 @@ } }, "jest": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.3.1.tgz", - "integrity": "sha512-6iWfL5DTT0Np6UYs/y5Niu7WIfNv/wRTtN5RSXt2DIEft3dx3zPuw/3WJQBCJfmEzvDiEKwoqMbGD9n49+qLSA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.5.0.tgz", + "integrity": "sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==", "dev": true, "requires": { - "@jest/core": "^29.3.1", - "@jest/types": "^29.3.1", + "@jest/core": "^29.5.0", + "@jest/types": "^29.5.0", "import-local": "^3.0.2", - "jest-cli": "^29.3.1" + "jest-cli": "^29.5.0" } }, "jest-changed-files": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.2.0.tgz", - "integrity": "sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.5.0.tgz", + "integrity": "sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==", "dev": true, "requires": { "execa": "^5.0.0", @@ -11667,204 +13038,205 @@ } }, "jest-circus": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.3.1.tgz", - "integrity": "sha512-wpr26sEvwb3qQQbdlmei+gzp6yoSSoSL6GsLPxnuayZSMrSd5Ka7IjAvatpIernBvT2+Ic6RLTg+jSebScmasg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.5.0.tgz", + "integrity": "sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA==", "dev": true, "requires": { - "@jest/environment": "^29.3.1", - "@jest/expect": "^29.3.1", - "@jest/test-result": "^29.3.1", - "@jest/types": "^29.3.1", + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", "is-generator-fn": "^2.0.0", - "jest-each": "^29.3.1", - "jest-matcher-utils": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-runtime": "^29.3.1", - "jest-snapshot": "^29.3.1", - "jest-util": "^29.3.1", + "jest-each": "^29.5.0", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", "p-limit": "^3.1.0", - "pretty-format": "^29.3.1", + "pretty-format": "^29.5.0", + "pure-rand": "^6.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-cli": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.3.1.tgz", - "integrity": "sha512-TO/ewvwyvPOiBBuWZ0gm04z3WWP8TIK8acgPzE4IxgsLKQgb377NYGrQLc3Wl/7ndWzIH2CDNNsUjGxwLL43VQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.5.0.tgz", + "integrity": "sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw==", "dev": true, "requires": { - "@jest/core": "^29.3.1", - "@jest/test-result": "^29.3.1", - "@jest/types": "^29.3.1", + "@jest/core": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^29.3.1", - "jest-util": "^29.3.1", - "jest-validate": "^29.3.1", + "jest-config": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", "prompts": "^2.0.1", "yargs": "^17.3.1" } }, "jest-config": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.3.1.tgz", - "integrity": "sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.5.0.tgz", + "integrity": "sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==", "dev": true, "requires": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.3.1", - "@jest/types": "^29.3.1", - "babel-jest": "^29.3.1", + "@jest/test-sequencer": "^29.5.0", + "@jest/types": "^29.5.0", + "babel-jest": "^29.5.0", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^29.3.1", - "jest-environment-node": "^29.3.1", - "jest-get-type": "^29.2.0", - "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.3.1", - "jest-runner": "^29.3.1", - "jest-util": "^29.3.1", - "jest-validate": "^29.3.1", + "jest-circus": "^29.5.0", + "jest-environment-node": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^29.3.1", + "pretty-format": "^29.5.0", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" } }, "jest-diff": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.3.1.tgz", - "integrity": "sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", + "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^29.3.1", - "jest-get-type": "^29.2.0", - "pretty-format": "^29.3.1" + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" } }, "jest-docblock": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.2.0.tgz", - "integrity": "sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", + "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", "dev": true, "requires": { "detect-newline": "^3.0.0" } }, "jest-each": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.3.1.tgz", - "integrity": "sha512-qrZH7PmFB9rEzCSl00BWjZYuS1BSOH8lLuC0azQE9lQrAx3PWGKHTDudQiOSwIy5dGAJh7KA0ScYlCP7JxvFYA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.5.0.tgz", + "integrity": "sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA==", "dev": true, "requires": { - "@jest/types": "^29.3.1", + "@jest/types": "^29.5.0", "chalk": "^4.0.0", - "jest-get-type": "^29.2.0", - "jest-util": "^29.3.1", - "pretty-format": "^29.3.1" + "jest-get-type": "^29.4.3", + "jest-util": "^29.5.0", + "pretty-format": "^29.5.0" } }, "jest-environment-node": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.3.1.tgz", - "integrity": "sha512-xm2THL18Xf5sIHoU7OThBPtuH6Lerd+Y1NLYiZJlkE3hbE+7N7r8uvHIl/FkZ5ymKXJe/11SQuf3fv4v6rUMag==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.5.0.tgz", + "integrity": "sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw==", "dev": true, "requires": { - "@jest/environment": "^29.3.1", - "@jest/fake-timers": "^29.3.1", - "@jest/types": "^29.3.1", + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", - "jest-mock": "^29.3.1", - "jest-util": "^29.3.1" + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" } }, "jest-get-type": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz", - "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", "dev": true }, "jest-haste-map": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.3.1.tgz", - "integrity": "sha512-/FFtvoG1xjbbPXQLFef+WSU4yrc0fc0Dds6aRPBojUid7qlPqZvxdUBA03HW0fnVHXVCnCdkuoghYItKNzc/0A==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", + "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", "dev": true, "requires": { - "@jest/types": "^29.3.1", + "@jest/types": "^29.5.0", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.3.2", "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.2.0", - "jest-util": "^29.3.1", - "jest-worker": "^29.3.1", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", "micromatch": "^4.0.4", "walker": "^1.0.8" } }, "jest-leak-detector": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.3.1.tgz", - "integrity": "sha512-3DA/VVXj4zFOPagGkuqHnSQf1GZBmmlagpguxEERO6Pla2g84Q1MaVIB3YMxgUaFIaYag8ZnTyQgiZ35YEqAQA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz", + "integrity": "sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow==", "dev": true, "requires": { - "jest-get-type": "^29.2.0", - "pretty-format": "^29.3.1" + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" } }, "jest-matcher-utils": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.3.1.tgz", - "integrity": "sha512-fkRMZUAScup3txIKfMe3AIZZmPEjWEdsPJFK3AIy5qRohWqQFg1qrmKfYXR9qEkNc7OdAu2N4KPHibEmy4HPeQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", + "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^29.3.1", - "jest-get-type": "^29.2.0", - "pretty-format": "^29.3.1" + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" } }, "jest-message-util": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.3.1.tgz", - "integrity": "sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", + "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.3.1", + "@jest/types": "^29.5.0", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.3.1", + "pretty-format": "^29.5.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-mock": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.3.1.tgz", - "integrity": "sha512-H8/qFDtDVMFvFP4X8NuOT3XRDzOUTz+FeACjufHzsOIBAxivLqkB1PoLCaJx9iPPQ8dZThHPp/G3WRWyMgA3JA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.5.0.tgz", + "integrity": "sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==", "dev": true, "requires": { - "@jest/types": "^29.3.1", + "@jest/types": "^29.5.0", "@types/node": "*", - "jest-util": "^29.3.1" + "jest-util": "^29.5.0" } }, "jest-pnp-resolver": { @@ -11875,101 +13247,101 @@ "requires": {} }, "jest-regex-util": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.2.0.tgz", - "integrity": "sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", + "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", "dev": true }, "jest-resolve": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.3.1.tgz", - "integrity": "sha512-amXJgH/Ng712w3Uz5gqzFBBjxV8WFLSmNjoreBGMqxgCz5cH7swmBZzgBaCIOsvb0NbpJ0vgaSFdJqMdT+rADw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.5.0.tgz", + "integrity": "sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==", "dev": true, "requires": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.3.1", + "jest-haste-map": "^29.5.0", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.3.1", - "jest-validate": "^29.3.1", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", + "resolve.exports": "^2.0.0", "slash": "^3.0.0" } }, "jest-resolve-dependencies": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.3.1.tgz", - "integrity": "sha512-Vk0cYq0byRw2WluNmNWGqPeRnZ3p3hHmjJMp2dyyZeYIfiBskwq4rpiuGFR6QGAdbj58WC7HN4hQHjf2mpvrLA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.5.0.tgz", + "integrity": "sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg==", "dev": true, "requires": { - "jest-regex-util": "^29.2.0", - "jest-snapshot": "^29.3.1" + "jest-regex-util": "^29.4.3", + "jest-snapshot": "^29.5.0" } }, "jest-runner": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.3.1.tgz", - "integrity": "sha512-oFvcwRNrKMtE6u9+AQPMATxFcTySyKfLhvso7Sdk/rNpbhg4g2GAGCopiInk1OP4q6gz3n6MajW4+fnHWlU3bA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.5.0.tgz", + "integrity": "sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ==", "dev": true, "requires": { - "@jest/console": "^29.3.1", - "@jest/environment": "^29.3.1", - "@jest/test-result": "^29.3.1", - "@jest/transform": "^29.3.1", - "@jest/types": "^29.3.1", + "@jest/console": "^29.5.0", + "@jest/environment": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.13.1", "graceful-fs": "^4.2.9", - "jest-docblock": "^29.2.0", - "jest-environment-node": "^29.3.1", - "jest-haste-map": "^29.3.1", - "jest-leak-detector": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-resolve": "^29.3.1", - "jest-runtime": "^29.3.1", - "jest-util": "^29.3.1", - "jest-watcher": "^29.3.1", - "jest-worker": "^29.3.1", + "jest-docblock": "^29.4.3", + "jest-environment-node": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-leak-detector": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-resolve": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-util": "^29.5.0", + "jest-watcher": "^29.5.0", + "jest-worker": "^29.5.0", "p-limit": "^3.1.0", "source-map-support": "0.5.13" } }, "jest-runtime": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.3.1.tgz", - "integrity": "sha512-jLzkIxIqXwBEOZx7wx9OO9sxoZmgT2NhmQKzHQm1xwR1kNW/dn0OjxR424VwHHf1SPN6Qwlb5pp1oGCeFTQ62A==", - "dev": true, - "requires": { - "@jest/environment": "^29.3.1", - "@jest/fake-timers": "^29.3.1", - "@jest/globals": "^29.3.1", - "@jest/source-map": "^29.2.0", - "@jest/test-result": "^29.3.1", - "@jest/transform": "^29.3.1", - "@jest/types": "^29.3.1", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.5.0.tgz", + "integrity": "sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==", + "dev": true, + "requires": { + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/globals": "^29.5.0", + "@jest/source-map": "^29.4.3", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-mock": "^29.3.1", - "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.3.1", - "jest-snapshot": "^29.3.1", - "jest-util": "^29.3.1", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", "slash": "^3.0.0", "strip-bom": "^4.0.0" } }, "jest-snapshot": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.3.1.tgz", - "integrity": "sha512-+3JOc+s28upYLI2OJM4PWRGK9AgpsMs/ekNryUV0yMBClT9B1DF2u2qay8YxcQd338PPYSFNb0lsar1B49sLDA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", + "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", "dev": true, "requires": { "@babel/core": "^7.11.6", @@ -11978,23 +13350,22 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.3.1", - "@jest/transform": "^29.3.1", - "@jest/types": "^29.3.1", + "@jest/expect-utils": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@types/babel__traverse": "^7.0.6", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.3.1", + "expect": "^29.5.0", "graceful-fs": "^4.2.9", - "jest-diff": "^29.3.1", - "jest-get-type": "^29.2.0", - "jest-haste-map": "^29.3.1", - "jest-matcher-utils": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-util": "^29.3.1", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", "natural-compare": "^1.4.0", - "pretty-format": "^29.3.1", + "pretty-format": "^29.5.0", "semver": "^7.3.5" }, "dependencies": { @@ -12025,12 +13396,12 @@ } }, "jest-util": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.3.1.tgz", - "integrity": "sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", + "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", "dev": true, "requires": { - "@jest/types": "^29.3.1", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -12039,17 +13410,17 @@ } }, "jest-validate": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.3.1.tgz", - "integrity": "sha512-N9Lr3oYR2Mpzuelp1F8negJR3YE+L1ebk1rYA5qYo9TTY3f9OWdptLoNSPP9itOCBIRBqjt/S5XHlzYglLN67g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.5.0.tgz", + "integrity": "sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ==", "dev": true, "requires": { - "@jest/types": "^29.3.1", + "@jest/types": "^29.5.0", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^29.2.0", + "jest-get-type": "^29.4.3", "leven": "^3.1.0", - "pretty-format": "^29.3.1" + "pretty-format": "^29.5.0" }, "dependencies": { "camelcase": { @@ -12061,29 +13432,29 @@ } }, "jest-watcher": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.3.1.tgz", - "integrity": "sha512-RspXG2BQFDsZSRKGCT/NiNa8RkQ1iKAjrO0//soTMWx/QUt+OcxMqMSBxz23PYGqUuWm2+m2mNNsmj0eIoOaFg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.5.0.tgz", + "integrity": "sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA==", "dev": true, "requires": { - "@jest/test-result": "^29.3.1", - "@jest/types": "^29.3.1", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.13.1", - "jest-util": "^29.3.1", + "jest-util": "^29.5.0", "string-length": "^4.0.1" } }, "jest-worker": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.3.1.tgz", - "integrity": "sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", + "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", "dev": true, "requires": { "@types/node": "*", - "jest-util": "^29.3.1", + "jest-util": "^29.5.0", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, @@ -12100,9 +13471,9 @@ } }, "js-sdsl": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", - "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==" + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==" }, "js-sha256": { "version": "0.9.0", @@ -12129,24 +13500,23 @@ } }, "jsdoc-type-pratt-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-3.1.0.tgz", - "integrity": "sha512-MgtD0ZiCDk9B+eI73BextfRrVQl0oyzRG8B2BjORts6jbunj4ScKPcyXGTbB6eXL4y9TzxCm6hyeLq/2ASzNdw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", + "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", "dev": true }, "jsdom": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", - "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-21.1.1.tgz", + "integrity": "sha512-Jjgdmw48RKcdAIQyUD1UdBh2ecH7VqwaXPN3ehoZN6MqgVbMn+lRm1aAT1AsdJRAJpwfa4IpwgzySn61h2qu3w==", "dev": true, "requires": { "abab": "^2.0.6", - "acorn": "^8.8.1", + "acorn": "^8.8.2", "acorn-globals": "^7.0.0", - "cssom": "^0.5.0", - "cssstyle": "^2.3.0", - "data-urls": "^3.0.2", - "decimal.js": "^10.4.2", + "cssstyle": "^3.0.0", + "data-urls": "^4.0.0", + "decimal.js": "^10.4.3", "domexception": "^4.0.0", "escodegen": "^2.0.0", "form-data": "^4.0.0", @@ -12155,7 +13525,8 @@ "https-proxy-agent": "^5.0.1", "is-potential-custom-element-name": "^1.0.1", "nwsapi": "^2.2.2", - "parse5": "^7.1.1", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.6.0", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^4.1.2", @@ -12163,8 +13534,8 @@ "webidl-conversions": "^7.0.0", "whatwg-encoding": "^2.0.0", "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^11.0.0", - "ws": "^8.11.0", + "whatwg-url": "^12.0.1", + "ws": "^8.13.0", "xml-name-validator": "^4.0.0" } }, @@ -12203,9 +13574,9 @@ "optional": true }, "json5": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", - "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true }, "jsonfile": { @@ -12245,9 +13616,9 @@ "dev": true }, "known-css-properties": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.26.0.tgz", - "integrity": "sha512-5FZRzrZzNTBruuurWpvZnvP9pum+fe0HcK8z/ooo+U+Hmp4vtbyp1/QDsqmufirXy4egGzbaH/y2uCZf+6W5Kg==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.27.0.tgz", + "integrity": "sha512-uMCj6+hZYDoffuvAJjFAPz56E9uoowFHmTkqRtRq5WyC5Q6Cu/fTZKNQpX/RbzChBYLLl3lo8CjFZBAZXq9qFg==", "dev": true }, "leven": { @@ -12317,9 +13688,9 @@ } }, "luxon": { - "version": "1.28.0", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz", - "integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ==" + "version": "1.28.1", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.1.tgz", + "integrity": "sha512-gYHAa180mKrNIUJCbwpmD0aTu9kV0dREDrwNnuyFAsO1Wt0EVYSZelPnJlbj9HplzXX/YWXHFTL45kvZ53M0pw==" }, "make-dir": { "version": "3.1.0", @@ -12370,6 +13741,12 @@ "is-buffer": "~1.1.6" } }, + "mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -12479,6 +13856,11 @@ "brace-expansion": "^1.1.7" } }, + "minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" + }, "minimist-options": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", @@ -12509,11 +13891,11 @@ "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" }, "moment-timezone": { - "version": "0.5.40", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.40.tgz", - "integrity": "sha512-tWfmNkRYmBkPJz5mr9GVDn9vRlVZOTe6yqY92rFxiOdWXbjaR0+9LwQnZGGuNR63X456NqmEkbskte8tWL5ePg==", + "version": "0.5.41", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.41.tgz", + "integrity": "sha512-e0jGNZDOHfBXJGz8vR/sIMXvBIGJJcqFjmlg9lmE+5KX1U7/RZNMswfD8nKnNCnQdKTIj50IaRKwl1fvMLyyRg==", "requires": { - "moment": ">= 2.9.0" + "moment": "^2.29.4" } }, "mri": { @@ -12556,6 +13938,11 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, "nise": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", @@ -12569,24 +13956,6 @@ "path-to-regexp": "^1.7.0" }, "dependencies": { - "@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", - "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^2.0.0" - } - }, "path-to-regexp": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", @@ -12599,9 +13968,9 @@ } }, "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", + "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", "requires": { "whatwg-url": "^5.0.0" }, @@ -12628,11 +13997,11 @@ } }, "node-ical": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/node-ical/-/node-ical-0.15.3.tgz", - "integrity": "sha512-OQ3xipexD/nI0jpoz+ELhMwV8liMMqM+rlxB5xHbPiJRYvueIT+4cipjdt4L64teXXHVmg+xf8OfwJE2LueVlw==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/node-ical/-/node-ical-0.16.0.tgz", + "integrity": "sha512-LgLN6gm2D1AIaBQnbAw8nz+lH2ZT08lOSGhpzi3z+f2JDt3rSkKrWCx96URO8RmGxgx2Cojw15OBWZSpL18kag==", "requires": { - "axios": "1.1.3", + "axios": "1.3.4", "moment-timezone": "^0.5.31", "rrule": "2.6.4", "uuid": "^9.0.0" @@ -12645,9 +14014,9 @@ "dev": true }, "node-releases": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", - "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==", + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", "dev": true }, "normalize-package-data": { @@ -12721,15 +14090,36 @@ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==" }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "optional": true + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + } + }, + "object.values": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } }, "on-finished": { "version": "2.4.1", @@ -12936,24 +14326,24 @@ } }, "playwright": { - "version": "1.29.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.29.1.tgz", - "integrity": "sha512-lasC+pMqsQ2uWhNurt3YK3xo0gWlMjslYUylKbHcqF/NTjwp9KStRGO7S6wwz2f52GcSnop8XUK/GymJjdzrxw==", + "version": "1.32.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.32.1.tgz", + "integrity": "sha512-GnEizysWMvoqHC3I9l8+4/ZxeLwLNdJJG76xdKGxzOcIZDcw5RSk/FKrFb5CuA+zcLpjIM2p9eR9Z4CuUDkWXg==", "dev": true, "requires": { - "playwright-core": "1.29.1" + "playwright-core": "1.32.1" } }, "playwright-core": { - "version": "1.29.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.29.1.tgz", - "integrity": "sha512-20Ai3d+lMkWpI9YZYlxk8gxatfgax5STW8GaMozAHwigLiyiKQrdkt7gaoT9UQR8FIVDg6qVXs9IoZUQrDjIIg==", + "version": "1.32.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.32.1.tgz", + "integrity": "sha512-KZYUQC10mXD2Am1rGlidaalNGYk3LU1vZqqNk0gT4XPty1jOqgup8KDP8l2CUlqoNKhXM5IfGjWgW37xvGllBA==", "dev": true }, "postcss": { - "version": "8.4.20", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz", - "integrity": "sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==", + "version": "8.4.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", + "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", "dev": true, "requires": { "nanoid": "^3.3.4", @@ -13002,9 +14392,9 @@ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" }, "prettier": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz", - "integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==", + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz", + "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==", "dev": true }, "prettier-linter-helpers": { @@ -13017,12 +14407,12 @@ } }, "pretty-format": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz", - "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "requires": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -13168,9 +14558,15 @@ } }, "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==" + }, + "pure-rand": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.1.tgz", + "integrity": "sha512-t+x1zEHDjBwkDGY5v5ApnZ/utcd4XYDiJsaQQoptTXgUXX95sDg1elCdJghzicm7n2mbCBJ3uYWr6M22SO19rg==", + "dev": true }, "qs": { "version": "6.11.0", @@ -13348,10 +14744,20 @@ "strip-indent": "^3.0.0" } }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==" + "regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + } + }, + "replace-last": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/replace-last/-/replace-last-1.2.6.tgz", + "integrity": "sha512-Cj+MK38VtNu1S5J73mEZY3ciQb9dJajNq1Q8inP4dn/MhJMjHwoAF3Z3FjspwAEV9pfABl565MQucmrjOkty4g==" }, "require-directory": { "version": "2.1.1", @@ -13411,9 +14817,9 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" }, "resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.1.tgz", + "integrity": "sha512-OEJWVeimw8mgQuj3HfkNl4KqRevH7lzeQNaWRPfx0PPse7Jk6ozcsG4FKVgtzDsC1KUF+YlTHh17NcgHOPykLw==", "dev": true }, "responselike": { @@ -13461,6 +14867,12 @@ "tslib": "^1.10.0" } }, + "rrweb-cssom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", + "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", + "dev": true + }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -13474,6 +14886,16 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, + "safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + } + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -13610,36 +15032,33 @@ "dev": true }, "sinon": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.0.1.tgz", - "integrity": "sha512-PZXKc08f/wcA/BMRGBze2Wmw50CWPiAH3E21EOi4B49vJ616vW4DQh4fQrqsYox2aNR/N3kCqLuB0PwwOucQrg==", + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.0.2.tgz", + "integrity": "sha512-PCVP63XZkg0/LOqQH5rEU4LILuvTFMb5tNxTHfs6VUMNnZz2XrnGSTZbAGITjzwQWbl/Bl/8hi4G3zZWjyBwHg==", "dev": true, "requires": { - "@sinonjs/commons": "^2.0.0", - "@sinonjs/fake-timers": "10.0.2", + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^10.0.2", "@sinonjs/samsam": "^7.0.1", - "diff": "^5.0.0", - "nise": "^5.1.2", + "diff": "^5.1.0", + "nise": "^5.1.4", "supports-color": "^7.2.0" }, "dependencies": { "@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", "dev": true, "requires": { "type-detect": "4.0.8" } }, - "@sinonjs/fake-timers": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", - "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^2.0.0" - } + "diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "dev": true } } }, @@ -13667,27 +15086,38 @@ } }, "socket.io": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.4.tgz", - "integrity": "sha512-m3GC94iK9MfIEeIBfbhJs5BqFibMtkRk8ZpKwG2QwxV0m/eEhPIV4ara6XCF1LWNAus7z58RodiZlAH71U3EhQ==", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.1.tgz", + "integrity": "sha512-KMcaAi4l/8+xEjkRICl6ak8ySoxsYG+gG6/XfRCPJPQ/haCRIJBTL4wIl8YCsmtaBovcAXGLOShyVWQ/FG8GZA==", "requires": { "accepts": "~1.3.4", "base64id": "~2.0.0", "debug": "~4.3.2", - "engine.io": "~6.2.1", - "socket.io-adapter": "~2.4.0", + "engine.io": "~6.4.1", + "socket.io-adapter": "~2.5.2", "socket.io-parser": "~4.2.1" } }, "socket.io-adapter": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz", - "integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==" + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", + "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "requires": { + "ws": "~8.11.0" + }, + "dependencies": { + "ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "requires": {} + } + } }, "socket.io-parser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz", - "integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.2.tgz", + "integrity": "sha512-DJtziuKypFkMMHCm2uIshOYC7QaylbtzQwiMYDuCKy3OPkjLzu4B2vAhTlqipRHHzrI0NJeBAizTK7X+6m1jVw==", "requires": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1" @@ -13696,8 +15126,7 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, "source-map-js": { "version": "1.0.2", @@ -13716,9 +15145,9 @@ } }, "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", @@ -13742,9 +15171,9 @@ } }, "spdx-license-ids": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", - "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", + "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", "dev": true }, "sprintf-js": { @@ -13796,6 +15225,51 @@ "strip-ansi": "^6.0.1" } }, + "string.prototype.matchall": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", + "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.4.3", + "side-channel": "^1.0.4" + } + }, + "string.prototype.trim": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", + "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "string.prototype.trimend": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "string.prototype.trimstart": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -13837,16 +15311,20 @@ "dev": true }, "stylelint": { - "version": "14.16.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.16.0.tgz", - "integrity": "sha512-X6uTi9DcxjzLV8ZUAjit1vsRtSwcls0nl07c9rqOPzvpA8IvTX/xWEkBRowS0ffevRrqkHa/ThDEu86u73FQDg==", + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.3.0.tgz", + "integrity": "sha512-9UYBYk7K9rtlKcTUDZrtntE840sZM00qyYBQHHe7tjwMNUsPsGvR6Fd43IxHEAhRrDLzpy3TVaHb6CReBB3eFg==", "dev": true, "requires": { - "@csstools/selector-specificity": "^2.0.2", + "@csstools/css-parser-algorithms": "^2.0.1", + "@csstools/css-tokenizer": "^2.1.0", + "@csstools/media-query-list-parser": "^2.0.1", + "@csstools/selector-specificity": "^2.1.1", "balanced-match": "^2.0.0", "colord": "^2.9.3", - "cosmiconfig": "^7.1.0", + "cosmiconfig": "^8.1.0", "css-functions-list": "^3.1.0", + "css-tree": "^2.3.1", "debug": "^4.3.4", "fast-glob": "^3.2.12", "fastest-levenshtein": "^1.0.16", @@ -13855,17 +15333,17 @@ "globby": "^11.1.0", "globjoin": "^0.1.4", "html-tags": "^3.2.0", - "ignore": "^5.2.1", + "ignore": "^5.2.4", "import-lazy": "^4.0.0", "imurmurhash": "^0.1.4", "is-plain-object": "^5.0.0", - "known-css-properties": "^0.26.0", + "known-css-properties": "^0.27.0", "mathml-tag-names": "^2.1.3", "meow": "^9.0.0", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "picocolors": "^1.0.0", - "postcss": "^8.4.19", + "postcss": "^8.4.21", "postcss-media-query-parser": "^0.2.3", "postcss-resolve-nested-selector": "^0.1.1", "postcss-safe-parser": "^6.0.0", @@ -13875,11 +15353,11 @@ "string-width": "^4.2.3", "strip-ansi": "^6.0.1", "style-search": "^0.1.0", - "supports-hyperlinks": "^2.3.0", + "supports-hyperlinks": "^3.0.0", "svg-tags": "^1.0.0", "table": "^6.8.1", "v8-compile-cache": "^2.3.0", - "write-file-atomic": "^4.0.2" + "write-file-atomic": "^5.0.0" }, "dependencies": { "balanced-match": { @@ -13893,36 +15371,39 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true + }, + "write-file-atomic": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.0.tgz", + "integrity": "sha512-R7NYMnHSlV42K54lwY9lvW6MnSm1HSJqZL3xiSgi9E7//FYaI74r2G0rd+/X6VAMkHEdzxQaU5HUOXWUz5kA/w==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } } } }, - "stylelint-config-prettier": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/stylelint-config-prettier/-/stylelint-config-prettier-9.0.4.tgz", - "integrity": "sha512-38nIGTGpFOiK5LjJ8Ma1yUgpKENxoKSOhbDNSemY7Ep0VsJoXIW9Iq/2hSt699oB9tReynfWicTAoIHiq8Rvbg==", - "dev": true, - "requires": {} - }, "stylelint-config-recommended": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-9.0.0.tgz", - "integrity": "sha512-9YQSrJq4NvvRuTbzDsWX3rrFOzOlYBmZP+o513BJN/yfEmGSr0AxdvrWs0P/ilSpVV/wisamAHu5XSk8Rcf4CQ==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-11.0.0.tgz", + "integrity": "sha512-SoGIHNI748OCZn6BxFYT83ytWoYETCINVHV3LKScVAWQQauWdvmdDqJC5YXWjpBbxg2E761Tg5aUGKLFOVhEkA==", "dev": true, "requires": {} }, "stylelint-config-standard": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-29.0.0.tgz", - "integrity": "sha512-uy8tZLbfq6ZrXy4JKu3W+7lYLgRQBxYTUUB88vPgQ+ZzAxdrvcaSUW9hOMNLYBnwH+9Kkj19M2DHdZ4gKwI7tg==", + "version": "31.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-31.0.0.tgz", + "integrity": "sha512-CUGAmtROCvX0YgMY2+6P9tqSkHj5z/75XxrQ8bGxvkCa1xYdGDx4poM0pa7cXc3s74/PZLJH/okxZZouRfOSGw==", "dev": true, "requires": { - "stylelint-config-recommended": "^9.0.0" + "stylelint-config-recommended": "^11.0.0" } }, "stylelint-prettier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/stylelint-prettier/-/stylelint-prettier-2.0.0.tgz", - "integrity": "sha512-jvT3G+9lopkeB0ARmDPszyfaOnvnIF+30QCjZxyt7E6fynI1T9mOKgYDNb9bXX17M7PXMZaX3j/26wqakjp1tw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stylelint-prettier/-/stylelint-prettier-3.0.0.tgz", + "integrity": "sha512-kIks1xw6np0zElokMT2kP6ar3S4MBoj6vUtPJuND1pFELMpZxVS/0uHPR4HDAVn0WAD3I5oF0IA3qBFxBpMkLg==", "dev": true, "requires": { "prettier-linter-helpers": "^1.0.0" @@ -13952,9 +15433,9 @@ } }, "supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", + "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", "dev": true, "requires": { "has-flag": "^4.0.0", @@ -13993,9 +15474,9 @@ }, "dependencies": { "ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -14075,12 +15556,12 @@ } }, "tr46": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", - "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", "dev": true, "requires": { - "punycode": "^2.1.1" + "punycode": "^2.3.0" } }, "trim-newlines": { @@ -14089,6 +15570,35 @@ "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true }, + "tsconfig-paths": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", + "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true + } + } + }, "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -14131,13 +15641,40 @@ "mime-types": "~2.1.24" } }, + "typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "requires": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + } + }, "typescript": { - "version": "4.9.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", - "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", + "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", "dev": true, "peer": true }, + "uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "optional": true + }, + "unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "requires": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + } + }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -14200,9 +15737,9 @@ "dev": true }, "v8-to-istanbul": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", - "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", + "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", "dev": true, "requires": { "@jridgewell/trace-mapping": "^0.3.12", @@ -14273,12 +15810,12 @@ "dev": true }, "whatwg-url": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", - "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", + "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", "dev": true, "requires": { - "tr46": "^3.0.0", + "tr46": "^4.1.1", "webidl-conversions": "^7.0.0" } }, @@ -14290,11 +15827,41 @@ "isexe": "^2.0.0" } }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" + } + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" + }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -14322,9 +15889,9 @@ } }, "ws": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", "dev": true, "requires": {} }, @@ -14352,16 +15919,10 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true - }, "yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", "dev": true, "requires": { "cliui": "^8.0.1", diff --git a/package.json b/package.json index fd7322dc8c..2f51a2da7c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "magicmirror", - "version": "2.22.0", + "version": "2.23.0", "description": "The open source modular smart mirror platform.", "main": "js/electron.js", "scripts": { @@ -13,10 +13,10 @@ "install-fonts": "echo \"Installing fonts ...\n\" && cd fonts && npm install --loglevel=error --no-audit --no-fund --no-update-notifier", "postinstall": "npm run install-vendor && npm run install-fonts && echo \"MagicMirror² installation finished successfully! \n\"", "test": "NODE_ENV=test jest -i --forceExit", - "test:coverage": "NODE_ENV=test jest --coverage -i --forceExit", + "test:coverage": "NODE_ENV=test jest --coverage -i --verbose false --forceExit", "test:electron": "NODE_ENV=test jest --selectProjects electron -i --forceExit", "test:e2e": "NODE_ENV=test jest --selectProjects e2e -i --forceExit", - "test:unit": "NODE_ENV=test jest --selectProjects unit -i --forceExit", + "test:unit": "NODE_ENV=test jest --selectProjects unit", "test:prettier": "prettier . --check", "test:js": "eslint 'js/**/*.js' 'modules/default/**/*.js' 'clientonly/*.js' 'serveronly/*.js' 'translations/*.js' 'vendor/*.js' 'tests/**/*.js' 'config/*' --config .eslintrc.json", "test:css": "stylelint 'css/main.css' 'fonts/*.css' 'modules/default/**/*.css' 'vendor/*.css' --config .stylelintrc.json", @@ -49,44 +49,45 @@ }, "homepage": "https://magicmirror.builders", "devDependencies": { - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-jest": "^27.1.7", - "eslint-plugin-jsdoc": "^39.6.4", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jest": "^27.2.1", + "eslint-plugin-jsdoc": "^40.1.0", "eslint-plugin-prettier": "^4.2.1", "express-basic-auth": "^1.2.1", - "husky": "^8.0.2", - "jest": "^29.3.1", - "jsdom": "^20.0.3", + "husky": "^8.0.3", + "jest": "^29.5.0", + "jsdom": "^21.1.1", "lodash": "^4.17.21", - "playwright": "^1.29.1", - "prettier": "^2.8.1", + "playwright": "^1.32.1", + "prettier": "^2.8.7", "pretty-quick": "^3.1.3", - "sinon": "^15.0.1", - "stylelint": "^14.16.0", - "stylelint-config-prettier": "^9.0.4", - "stylelint-config-standard": "^29.0.0", - "stylelint-prettier": "^2.0.0", + "sinon": "^15.0.2", + "stylelint": "^15.3.0", + "stylelint-config-standard": "^31.0.0", + "stylelint-prettier": "^3.0.0", "suncalc": "^1.9.0" }, "optionalDependencies": { - "electron": "^22.0.0" + "electron": "^22.3.4" }, "dependencies": { "colors": "^1.4.0", - "console-stamp": "^3.1.0", + "console-stamp": "^3.1.1", "digest-fetch": "^2.0.1", - "eslint": "^8.30.0", + "envsub": "^4.1.0", + "eslint": "^8.36.0", "express": "^4.18.2", "express-ipfilter": "^1.3.1", "feedme": "^2.0.2", "helmet": "^6.0.1", "iconv-lite": "^0.6.3", - "luxon": "^1.28.0", + "luxon": "^1.28.1", "module-alias": "^2.2.2", "moment": "^2.29.4", - "node-fetch": "^2.6.7", - "node-ical": "^0.15.3", - "socket.io": "^4.5.4" + "node-fetch": "^2.6.9", + "node-ical": "^0.16.0", + "socket.io": "^4.6.1" }, "_moduleAliases": { "node_helper": "js/node_helper.js", diff --git a/serveronly/index.js b/serveronly/index.js index 00d6b64be3..3cfa7969d2 100644 --- a/serveronly/index.js +++ b/serveronly/index.js @@ -1,8 +1,8 @@ -const app = require("../js/app.js"); -const Log = require("logger"); +const app = require("../js/app"); +const Log = require("../js/logger"); -app.start((config) => { +app.start().then((config) => { const bindAddress = config.address ? config.address : "localhost"; const httpType = config.useHttps ? "https" : "http"; - Log.log("\nReady to go! Please point your browser to: " + httpType + "://" + bindAddress + ":" + config.port); + Log.log(`\nReady to go! Please point your browser to: ${httpType}://${bindAddress}:${config.port}`); }); diff --git a/tests/configs/empty_ipWhiteList.js b/tests/configs/empty_ipWhiteList.js index d49f7a9f98..984d173856 100644 --- a/tests/configs/empty_ipWhiteList.js +++ b/tests/configs/empty_ipWhiteList.js @@ -3,7 +3,7 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = require(`${process.cwd()}/tests/configs/default.js`).configFactory({ ipWhitelist: [] }); diff --git a/tests/configs/modules/calendar/custom.js b/tests/configs/modules/calendar/custom.js index 54d117d7a7..993ac483e6 100644 --- a/tests/configs/modules/calendar/custom.js +++ b/tests/configs/modules/calendar/custom.js @@ -11,9 +11,10 @@ let config = { module: "calendar", position: "bottom_bar", config: { + customEvents: [{ keyword: "CustomEvent", symbol: "dice" }], calendars: [ { - maximumEntries: 4, + maximumEntries: 5, maximumNumberOfDays: 10000, symbol: "birthday-cake", fullDaySymbol: "calendar-day", diff --git a/tests/configs/modules/positions.js b/tests/configs/modules/positions.js index 77ad8f72c9..a40bfab959 100644 --- a/tests/configs/modules/positions.js +++ b/tests/configs/modules/positions.js @@ -14,7 +14,7 @@ let config = { module: "helloworld", position: positions[idx], config: { - text: "Text in " + positions[idx] + text: `Text in ${positions[idx]}` } }); } diff --git a/tests/configs/modules/weather/forecastweather_units.js b/tests/configs/modules/weather/forecastweather_units.js index 7e1ac86f28..22a9820a1e 100644 --- a/tests/configs/modules/weather/forecastweather_units.js +++ b/tests/configs/modules/weather/forecastweather_units.js @@ -15,7 +15,8 @@ let config = { location: "Munich", mockData: '"#####WEATHERDATA#####"', weatherEndpoint: "/forecast/daily", - decimalSymbol: "_" + decimalSymbol: "_", + showPrecipitationAmount: true } } ] diff --git a/tests/configs/modules/weather/hourlyweather_default.js b/tests/configs/modules/weather/hourlyweather_default.js new file mode 100644 index 0000000000..aca5ced8f8 --- /dev/null +++ b/tests/configs/modules/weather/hourlyweather_default.js @@ -0,0 +1,25 @@ +/* MagicMirror² Test config hourly weather + * + * By rejas https://github.com/rejas + * MIT Licensed. + */ +let config = { + timeFormat: 12, + + modules: [ + { + module: "weather", + position: "bottom_bar", + config: { + type: "hourly", + location: "Berlin", + mockData: '"#####WEATHERDATA#####"' + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/weather/hourlyweather_options.js b/tests/configs/modules/weather/hourlyweather_options.js new file mode 100644 index 0000000000..0d73311768 --- /dev/null +++ b/tests/configs/modules/weather/hourlyweather_options.js @@ -0,0 +1,26 @@ +/* MagicMirror² Test config hourly weather options + * + * By rejas https://github.com/rejas + * MIT Licensed. + */ +let config = { + timeFormat: 12, + + modules: [ + { + module: "weather", + position: "bottom_bar", + config: { + type: "hourly", + location: "Berlin", + mockData: '"#####WEATHERDATA#####"', + hourlyForecastIncrements: 2 + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/weather/hourlyweather_showPrecipitation.js b/tests/configs/modules/weather/hourlyweather_showPrecipitation.js new file mode 100644 index 0000000000..4ba579e1d3 --- /dev/null +++ b/tests/configs/modules/weather/hourlyweather_showPrecipitation.js @@ -0,0 +1,27 @@ +/* MagicMirror² Test config hourly weather + * + * By rejas https://github.com/rejas + * MIT Licensed. + */ +let config = { + timeFormat: 12, + + modules: [ + { + module: "weather", + position: "bottom_bar", + config: { + type: "hourly", + location: "Berlin", + mockData: '"#####WEATHERDATA#####"', + showPrecipitationAmount: true, + showPrecipitationProbability: true + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/noIpWhiteList.js b/tests/configs/noIpWhiteList.js index 36035c16b4..4e26b1a06c 100644 --- a/tests/configs/noIpWhiteList.js +++ b/tests/configs/noIpWhiteList.js @@ -3,7 +3,7 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = require(`${process.cwd()}/tests/configs/default.js`).configFactory({ ipWhitelist: ["x.x.x.x"] }); diff --git a/tests/configs/port_8090.js b/tests/configs/port_8090.js index df6bf7dc74..25d4bce224 100644 --- a/tests/configs/port_8090.js +++ b/tests/configs/port_8090.js @@ -3,7 +3,7 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = require(`${process.cwd()}/tests/configs/default.js`).configFactory({ port: 8090 }); diff --git a/tests/configs/port_variable.env b/tests/configs/port_variable.env new file mode 100644 index 0000000000..2b19af0113 --- /dev/null +++ b/tests/configs/port_variable.env @@ -0,0 +1 @@ +MM_PORT=8090 diff --git a/tests/configs/port_variable.js.template b/tests/configs/port_variable.js.template new file mode 100644 index 0000000000..3d8d9791ad --- /dev/null +++ b/tests/configs/port_variable.js.template @@ -0,0 +1,13 @@ +/* MagicMirror² Test config sample environment set port 8090 + * + * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com + * MIT Licensed. + */ +let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ + port: ${MM_PORT} +}); + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/e2e/fonts_spec.js b/tests/e2e/fonts_spec.js index b0d642d026..160359ecae 100644 --- a/tests/e2e/fonts_spec.js +++ b/tests/e2e/fonts_spec.js @@ -3,7 +3,7 @@ const helpers = require("./helpers/global-setup"); describe("All font files from roboto.css should be downloadable", () => { const fontFiles = []; // Statements below filters out all 'url' lines in the CSS file - const fileContent = require("fs").readFileSync(__dirname + "/../../fonts/roboto.css", "utf8"); + const fileContent = require("fs").readFileSync(`${__dirname}/../../fonts/roboto.css`, "utf8"); const regex = /\burl\(['"]([^'"]+)['"]\)/g; let match = regex.exec(fileContent); while (match !== null) { @@ -21,7 +21,7 @@ describe("All font files from roboto.css should be downloadable", () => { }); test.each(fontFiles)("should return 200 HTTP code for file '%s'", async (fontFile) => { - const fontUrl = "http://localhost:8080/fonts/" + fontFile; + const fontUrl = `http://localhost:8080/fonts/${fontFile}`; const res = await helpers.fetch(fontUrl); expect(res.status).toBe(200); }); diff --git a/tests/e2e/helpers/basic-auth.js b/tests/e2e/helpers/basic-auth.js index 84917a44f0..8307464e23 100644 --- a/tests/e2e/helpers/basic-auth.js +++ b/tests/e2e/helpers/basic-auth.js @@ -12,7 +12,7 @@ app.use(basicAuth); // Set available directories const directories = ["/tests/configs", "/tests/mocks"]; -const rootPath = path.resolve(__dirname + "/../../../"); +const rootPath = path.resolve(`${__dirname}/../../../`); for (let directory of directories) { app.use(directory, express.static(path.resolve(rootPath + directory))); diff --git a/tests/e2e/helpers/global-setup.js b/tests/e2e/helpers/global-setup.js index 582ab3ec81..b79c1f1f13 100644 --- a/tests/e2e/helpers/global-setup.js +++ b/tests/e2e/helpers/global-setup.js @@ -13,26 +13,22 @@ exports.startApplication = async (configFilename, exec) => { process.env.MM_CONFIG_FILE = configFilename; } if (exec) exec; - global.app = require("app.js"); + global.app = require("../../../js/app"); - return new Promise((resolve) => { - global.app.start(resolve); - }); + return global.app.start(); }; exports.stopApplication = async () => { - if (global.app) { - return new Promise((resolve) => { - global.app.stop(resolve); - delete global.app; - }); + if (!global.app) { + return Promise.resolve(); } - return Promise.resolve(); + await global.app.stop(); + delete global.app; }; exports.getDocument = () => { return new Promise((resolve) => { - const url = "http://" + (config.address || "localhost") + ":" + (config.port || "8080"); + const url = `http://${config.address || "localhost"}:${config.port || "8080"}`; jsdom.JSDOM.fromURL(url, { resources: "usable", runScripts: "dangerously" }).then((dom) => { dom.window.name = "jsdom"; dom.window.fetch = corefetch; diff --git a/tests/e2e/helpers/weather-functions.js b/tests/e2e/helpers/weather-functions.js index 5aa71c488a..e28eb9de02 100644 --- a/tests/e2e/helpers/weather-functions.js +++ b/tests/e2e/helpers/weather-functions.js @@ -1,7 +1,5 @@ +const { injectMockData } = require("../../utils/weather_mocker"); const helpers = require("./global-setup"); -const path = require("path"); -const fs = require("fs"); -const { generateWeather, generateWeatherForecast } = require("../../mocks/weather_test"); exports.getText = async (element, result) => { const elem = await helpers.waitForElement(element); @@ -14,16 +12,8 @@ exports.getText = async (element, result) => { ).toBe(result); }; -exports.startApp = async (configFile, additionalMockData) => { - let mockWeather; - if (configFile.includes("forecast")) { - mockWeather = generateWeatherForecast(additionalMockData); - } else { - mockWeather = generateWeather(additionalMockData); - } - let content = fs.readFileSync(path.resolve(__dirname + "../../../../" + configFile)).toString(); - content = content.replace("#####WEATHERDATA#####", mockWeather); - fs.writeFileSync(path.resolve(__dirname + "../../../../config/config.js"), content); +exports.startApp = async (configFileName, additionalMockData) => { + injectMockData(configFileName, additionalMockData); await helpers.startApplication(""); await helpers.getDocument(); }; diff --git a/tests/e2e/modules/calendar_spec.js b/tests/e2e/modules/calendar_spec.js index e1bee78e49..6932f124fa 100644 --- a/tests/e2e/modules/calendar_spec.js +++ b/tests/e2e/modules/calendar_spec.js @@ -1,5 +1,5 @@ const helpers = require("../helpers/global-setup"); -const serverBasicAuth = require("../helpers/basic-auth.js"); +const serverBasicAuth = require("../helpers/basic-auth"); describe("Calendar module", () => { /** @@ -48,14 +48,18 @@ describe("Calendar module", () => { await helpers.getDocument(); }); - it("should show the custom maximumEntries of 4", async () => { - await testElementLength(".calendar .event", 4); + it("should show the custom maximumEntries of 5", async () => { + await testElementLength(".calendar .event", 5); }); - it("should show the custom calendar symbol in each event", async () => { + it("should show the custom calendar symbol in four events", async () => { await testElementLength(".calendar .event .fa-birthday-cake", 4); }); + it("should show a customEvent calendar symbol in one event", async () => { + await testElementLength(".calendar .event .fa-dice", 1); + }); + it("should show two custom icons for repeating events", async () => { await testElementLength(".calendar .event .fa-undo", 2); }); @@ -87,7 +91,7 @@ describe("Calendar module", () => { await helpers.getDocument(); }); - it('should contain text "Mar 25th" in timezone UTC ' + -i, async () => { + it(`should contain text "Mar 25th" in timezone UTC ${-i}`, async () => { await testTextContain(".calendar", "Mar 25th"); }); }); diff --git a/tests/e2e/modules/clock_spec.js b/tests/e2e/modules/clock_spec.js index e91237b248..1ffa74a1bf 100644 --- a/tests/e2e/modules/clock_spec.js +++ b/tests/e2e/modules/clock_spec.js @@ -1,5 +1,5 @@ -const helpers = require("../helpers/global-setup"); const moment = require("moment"); +const helpers = require("../helpers/global-setup"); describe("Clock module", () => { afterAll(async () => { @@ -89,7 +89,7 @@ describe("Clock module", () => { it("should show the week with the correct number of week of year", async () => { const currentWeekNumber = moment().week(); - const weekToShow = "Week " + currentWeekNumber; + const weekToShow = `Week ${currentWeekNumber}`; const elem = await helpers.waitForElement(".clock .week"); expect(elem).not.toBe(null); expect(elem.textContent).toBe(weekToShow); @@ -103,7 +103,7 @@ describe("Clock module", () => { }); it("should show the analog clock face", async () => { - const elem = helpers.waitForElement(".clockCircle"); + const elem = helpers.waitForElement(".clock-circle"); expect(elem).not.toBe(null); }); }); diff --git a/tests/e2e/modules/weather_current_spec.js b/tests/e2e/modules/weather_current_spec.js index 97ae3eec85..6cea8e152f 100644 --- a/tests/e2e/modules/weather_current_spec.js +++ b/tests/e2e/modules/weather_current_spec.js @@ -46,7 +46,7 @@ describe("Weather module", () => { }); it("should render windDirection with an arrow", async () => { - const elem = await helpers.waitForElement(".weather .normal.medium sup i.fa-long-arrow-alt-up"); + const elem = await helpers.waitForElement(".weather .normal.medium sup i.fa-long-arrow-alt-down"); expect(elem).not.toBe(null); expect(elem.outerHTML).toContain("transform:rotate(250deg);"); }); diff --git a/tests/e2e/modules/weather_forecast_spec.js b/tests/e2e/modules/weather_forecast_spec.js index cd03691609..2f10692276 100644 --- a/tests/e2e/modules/weather_forecast_spec.js +++ b/tests/e2e/modules/weather_forecast_spec.js @@ -13,14 +13,14 @@ describe("Weather module: Weather Forecast", () => { const days = ["Today", "Tomorrow", "Sun", "Mon", "Tue"]; for (const [index, day] of days.entries()) { - it("should render day " + day, async () => { + it(`should render day ${day}`, async () => { await weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(1)`, day); }); } const icons = ["day-cloudy", "rain", "day-sunny", "day-sunny", "day-sunny"]; for (const [index, icon] of icons.entries()) { - it("should render icon " + icon, async () => { + it(`should render icon ${icon}`, async () => { const elem = await helpers.waitForElement(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(2) span.wi-${icon}`); expect(elem).not.toBe(null); }); @@ -28,21 +28,21 @@ describe("Weather module: Weather Forecast", () => { const maxTemps = ["24.4°", "21.0°", "22.9°", "23.4°", "20.6°"]; for (const [index, temp] of maxTemps.entries()) { - it("should render max temperature " + temp, async () => { + it(`should render max temperature ${temp}`, async () => { await weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(3)`, temp); }); } const minTemps = ["15.3°", "13.6°", "13.8°", "13.9°", "10.9°"]; for (const [index, temp] of minTemps.entries()) { - it("should render min temperature " + temp, async () => { + it(`should render min temperature ${temp}`, async () => { await weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(4)`, temp); }); } const opacities = [1, 1, 0.8, 0.5333333333333333, 0.2666666666666667]; for (const [index, opacity] of opacities.entries()) { - it("should render fading of rows with opacity=" + opacity, async () => { + it(`should render fading of rows with opacity=${opacity}`, async () => { const elem = await helpers.waitForElement(`.weather table.small tr:nth-child(${index + 1})`); expect(elem).not.toBe(null); expect(elem.outerHTML).toContain(``); @@ -57,7 +57,7 @@ describe("Weather module: Weather Forecast", () => { const days = ["Fri", "Sat", "Sun", "Mon", "Tue"]; for (const [index, day] of days.entries()) { - it("should render day " + day, async () => { + it(`should render day ${day}`, async () => { await weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(1)`, day); }); } @@ -79,18 +79,40 @@ describe("Weather module: Weather Forecast", () => { expect(table.rows).not.toBe(null); expect(table.rows.length).toBe(5); }); + + const precipitations = [undefined, "2.51 mm"]; + for (const [index, precipitation] of precipitations.entries()) { + if (precipitation) { + it(`should render precipitation amount ${precipitation}`, async () => { + await weatherFunc.getText(`.weather table tr:nth-child(${index + 1}) td.precipitation-amount`, precipitation); + }); + } + } }); - describe("Forecast weather units", () => { + describe("Forecast weather with imperial units", () => { beforeAll(async () => { await weatherFunc.startApp("tests/configs/modules/weather/forecastweather_units.js", {}); }); - const temperatures = ["75_9°", "69_8°", "73_2°", "74_1°", "69_1°"]; - for (const [index, temp] of temperatures.entries()) { - it("should render custom decimalSymbol = '_' for temp " + temp, async () => { - await weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(3)`, temp); - }); - } + describe("Temperature units", () => { + const temperatures = ["75_9°", "69_8°", "73_2°", "74_1°", "69_1°"]; + for (const [index, temp] of temperatures.entries()) { + it(`should render custom decimalSymbol = '_' for temp ${temp}`, async () => { + await weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(3)`, temp); + }); + } + }); + + describe("Precipitation units", () => { + const precipitations = [undefined, "0.10 in"]; + for (const [index, precipitation] of precipitations.entries()) { + if (precipitation) { + it(`should render precipitation amount ${precipitation}`, async () => { + await weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td.precipitation-amount`, precipitation); + }); + } + } + }); }); }); diff --git a/tests/e2e/modules/weather_hourly_spec.js b/tests/e2e/modules/weather_hourly_spec.js new file mode 100644 index 0000000000..3a5f03f138 --- /dev/null +++ b/tests/e2e/modules/weather_hourly_spec.js @@ -0,0 +1,64 @@ +const helpers = require("../helpers/global-setup"); +const weatherFunc = require("../helpers/weather-functions"); + +describe("Weather module: Weather Hourly Forecast", () => { + afterAll(async () => { + await helpers.stopApplication(); + }); + + describe("Default configuration", () => { + beforeAll(async () => { + await weatherFunc.startApp("tests/configs/modules/weather/hourlyweather_default.js", {}); + }); + + const minTemps = ["7:00 pm", "8:00 pm", "9:00 pm", "10:00 pm", "11:00 pm"]; + for (const [index, hour] of minTemps.entries()) { + it(`should render forecast for hour ${hour}`, async () => { + await weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td.day`, hour); + }); + } + }); + + describe("Hourly weather options", () => { + beforeAll(async () => { + await weatherFunc.startApp("tests/configs/modules/weather/hourlyweather_options.js", {}); + }); + + describe("Hourly increments of 2", () => { + const minTemps = ["7:00 pm", "9:00 pm", "11:00 pm", "1:00 am", "3:00 am"]; + for (const [index, hour] of minTemps.entries()) { + it(`should render forecast for hour ${hour}`, async () => { + await weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td.day`, hour); + }); + } + }); + }); + + describe("Show precipitations", () => { + beforeAll(async () => { + await weatherFunc.startApp("tests/configs/modules/weather/hourlyweather_showPrecipitation.js", {}); + }); + + describe("Shows precipitation amount", () => { + const amounts = [undefined, undefined, undefined, "0.13 mm", "0.13 mm"]; + for (const [index, amount] of amounts.entries()) { + if (amount) { + it(`should render precipitation amount ${amount}`, async () => { + await weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td.precipitation-amount`, amount); + }); + } + } + }); + + describe("Shows precipitation probability", () => { + const propabilities = [undefined, undefined, "12 %", "36 %", "44 %"]; + for (const [index, pop] of propabilities.entries()) { + if (pop) { + it(`should render probability ${pop}`, async () => { + await weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td.precipitation-prob`, pop); + }); + } + } + }); + }); +}); diff --git a/tests/e2e/modules_position_spec.js b/tests/e2e/modules_position_spec.js index 606c95a2bc..b23ebeb24e 100644 --- a/tests/e2e/modules_position_spec.js +++ b/tests/e2e/modules_position_spec.js @@ -13,10 +13,10 @@ describe("Position of modules", () => { for (const position of positions) { const className = position.replace("_", "."); - it("should show text in " + position, async () => { - const elem = await helpers.waitForElement("." + className); + it(`should show text in ${position}`, async () => { + const elem = await helpers.waitForElement(`.${className}`); expect(elem).not.toBe(null); - expect(elem.textContent).toContain("Text in " + position); + expect(elem.textContent).toContain(`Text in ${position}`); }); } }); diff --git a/tests/e2e/template_spec.js b/tests/e2e/template_spec.js new file mode 100644 index 0000000000..0c706c1cc5 --- /dev/null +++ b/tests/e2e/template_spec.js @@ -0,0 +1,15 @@ +const helpers = require("./helpers/global-setup"); + +describe("templated config with port variable", () => { + beforeAll(async () => { + await helpers.startApplication("tests/configs/port_variable.js"); + }); + afterAll(async () => { + await helpers.stopApplication(); + }); + + it("should return 200", async () => { + const res = await helpers.fetch("http://localhost:8090"); + expect(res.status).toBe(200); + }); +}); diff --git a/tests/e2e/translations_spec.js b/tests/e2e/translations_spec.js index 4d2d1c1e9d..ec1387572f 100644 --- a/tests/e2e/translations_spec.js +++ b/tests/e2e/translations_spec.js @@ -1,10 +1,10 @@ const fs = require("fs"); const path = require("path"); -const translations = require("../../translations/translations.js"); const helmet = require("helmet"); const { JSDOM } = require("jsdom"); const express = require("express"); const sinon = require("sinon"); +const translations = require("../../translations/translations"); describe("Translations", () => { let server; @@ -21,8 +21,8 @@ describe("Translations", () => { server = app.listen(3000); }); - afterAll(() => { - server.close(); + afterAll(async () => { + await server.close(); }); it("should have a translation file in the specified path", () => { @@ -48,17 +48,15 @@ describe("Translations", () => { dom.window.onload = async () => { const { Translator, Module, config } = dom.window; config.language = "en"; - Translator.load = sinon.stub().callsFake((_m, _f, _fb, callback) => callback()); + Translator.load = sinon.stub().callsFake((_m, _f, _fb) => null); Module.register("name", { getTranslations: () => translations }); const MMM = Module.create("name"); - const loaded = sinon.stub(); - MMM.loadTranslations(loaded); + await MMM.loadTranslations(); - expect(loaded.callCount).toBe(1); expect(Translator.load.args.length).toBe(1); - expect(Translator.load.calledWith(MMM, "translations/en.json", false, sinon.match.func)).toBe(true); + expect(Translator.load.calledWith(MMM, "translations/en.json", false)).toBe(true); done(); }; @@ -67,18 +65,16 @@ describe("Translations", () => { it("should load translation + fallback file", (done) => { dom.window.onload = async () => { const { Translator, Module } = dom.window; - Translator.load = sinon.stub().callsFake((_m, _f, _fb, callback) => callback()); + Translator.load = sinon.stub().callsFake((_m, _f, _fb) => null); Module.register("name", { getTranslations: () => translations }); const MMM = Module.create("name"); - const loaded = sinon.stub(); - MMM.loadTranslations(loaded); + await MMM.loadTranslations(); - expect(loaded.callCount).toBe(1); expect(Translator.load.args.length).toBe(2); - expect(Translator.load.calledWith(MMM, "translations/de.json", false, sinon.match.func)).toBe(true); - expect(Translator.load.calledWith(MMM, "translations/en.json", true, sinon.match.func)).toBe(true); + expect(Translator.load.calledWith(MMM, "translations/de.json", false)).toBe(true); + expect(Translator.load.calledWith(MMM, "translations/en.json", true)).toBe(true); done(); }; @@ -88,17 +84,15 @@ describe("Translations", () => { dom.window.onload = async () => { const { Translator, Module, config } = dom.window; config.language = "--"; - Translator.load = sinon.stub().callsFake((_m, _f, _fb, callback) => callback()); + Translator.load = sinon.stub().callsFake((_m, _f, _fb) => null); Module.register("name", { getTranslations: () => translations }); const MMM = Module.create("name"); - const loaded = sinon.stub(); - MMM.loadTranslations(loaded); + await MMM.loadTranslations(); - expect(loaded.callCount).toBe(1); expect(Translator.load.args.length).toBe(1); - expect(Translator.load.calledWith(MMM, "translations/en.json", true, sinon.match.func)).toBe(true); + expect(Translator.load.calledWith(MMM, "translations/en.json", true)).toBe(true); done(); }; @@ -112,10 +106,8 @@ describe("Translations", () => { Module.register("name", {}); const MMM = Module.create("name"); - const loaded = sinon.stub(); - MMM.loadTranslations(loaded); + await MMM.loadTranslations(); - expect(loaded.callCount).toBe(1); expect(Translator.load.callCount).toBe(0); done(); @@ -138,14 +130,13 @@ describe("Translations", () => {