diff --git a/.eslintrc.json b/.eslintrc.json index 3e685a0d..637b2eb7 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -25,6 +25,7 @@ "prettier/prettier": "error", "eqeqeq": "error", "no-prototype-builtins": "off", - "no-unused-vars": "off" + "no-unused-vars": "off", + "no-useless-return": "error" } } diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 56c6cfa9..d3912283 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -18,7 +18,7 @@ To run ESLint, use `npm run lint:js`. We use [StyleLint](https://stylelint.io) to lint our CSS. Our configuration is in our .stylelintrc file. -To run StyleLint, use `npm run lint:style`. +To run StyleLint, use `npm run lint:css`. ### Submitting Issues @@ -32,9 +32,9 @@ When submitting a new issue, please supply the following information: **Platform**: Place your platform here... give us your web browser/Electron version _and_ your hardware (Raspberry Pi 2/3/4, Windows, Mac, Linux, System V UNIX). -**Node Version**: Make sure it's version 10 or later. +**Node Version**: Make sure it's version 12 or later (recommended is 14). -**MagicMirror Version**: Now that the versions have split, tell us if you are using the PHP version (v1) or the newer JavaScript version (v2). +**MagicMirror Version**: Please let us know which version of MagicMirror you are running. It can be found in the `package.json` file. **Description**: Provide a detailed description about the issue and include specific details to help us understand the problem. Adding screenshots will help describing the problem. diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index e31c82eb..933a40f7 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,2 +1,2 @@ github: MichMich -custom: ['https://magicmirror.builders/#donate'] \ No newline at end of file +custom: ["https://magicmirror.builders/#donate"] diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 87635902..fd922dad 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -19,8 +19,10 @@ If you are facing an issue or found a bug while trying to install MagicMirror vi ## I found a bug in the MagicMirror Docker image -If you are facing an issue or found a bug while running MagicMirror inside a Docker container please create an issue in the GitHub repository of the MagicMirror Docker image: -[https://github.com/bastilimbach/docker-MagicMirror](https://github.com/bastilimbach/docker-MagicMirror) +If you are facing an issue or found a bug while running MagicMirror inside a Docker container please create an issue in the corresponding repository: + +- karsten13/magicmirror: [https://gitlab.com/khassel/magicmirror](https://gitlab.com/khassel/magicmirror) +- (deprecated) bastilimbach/docker-magicmirror: [https://github.com/bastilimbach/docker-MagicMirror](https://github.com/bastilimbach/docker-MagicMirror) --- @@ -31,9 +33,9 @@ When submitting a new issue, please supply the following information: **Platform**: Place your platform here... give us your web browser/Electron version _and_ your hardware (Raspberry Pi 2/3/4, Windows, Mac, Linux, System V UNIX). -**Node Version**: Make sure it's version 10 or later. +**Node Version**: Make sure it's version 12 or later (recommended is 14). -**MagicMirror Version**: Please let us now which version of MagicMirror you are running. It can be found in the `package.log` file. +**MagicMirror Version**: Please let us know which version of MagicMirror you are running. It can be found in the `package.json` file. **Description**: Provide a detailed description about the issue and include specific details to help us understand the problem. Adding screenshots will help describing the problem. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index bbb09f36..b1d5833f 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,23 +2,20 @@ Hello and thank you for wanting to contribute to the MagicMirror project **Please make sure that you have followed these 4 rules before submitting your Pull Request:** -> 1) Base your pull requests against the `develop` branch. +> 1. Base your pull requests against the `develop` branch. > +> 2. Include these infos in the description: > -> 2) Include these infos in the description: -> * Does the pull request solve a **related** issue? -> * If so, can you reference the issue like this `Fixes #`? -> * What does the pull request accomplish? Use a list if needed. -> * If it includes major visual changes please add screenshots. +> - Does the pull request solve a **related** issue? +> - If so, can you reference the issue like this `Fixes #`? +> - What does the pull request accomplish? Use a list if needed. +> - If it includes major visual changes please add screenshots. > +> 3. Please run `npm run lint:prettier` before submitting so that +> style issues are fixed. > -> 3) Please run `npm run lint:prettier` before submitting so that -> style issues are fixed. -> -> -> 4) Don't forget to add an entry about your changes to -> the CHANGELOG.md file. - +> 4. Don't forget to add an entry about your changes to +> the CHANGELOG.md file. **Note**: Sometimes the development moves very fast. It is highly recommended that you update your branch of `develop` before creating a diff --git a/.github/header.psd b/.github/header.psd deleted file mode 100644 index 6b97142e..00000000 Binary files a/.github/header.psd and /dev/null differ diff --git a/.github/workflows/automated-tests.yml b/.github/workflows/automated-tests.yml new file mode 100644 index 00000000..9e1047b3 --- /dev/null +++ b/.github/workflows/automated-tests.yml @@ -0,0 +1,37 @@ +# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions + +name: "Run Automated Tests" + +on: + push: + branches: [master, develop] + pull_request: + branches: [master, develop] + +jobs: + test: + runs-on: ubuntu-latest + timeout-minutes: 30 + strategy: + matrix: + node-version: [12.x, 14.x, 16.x] + steps: + - name: Checkout code + uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - name: Install dependencies and run tests + run: | + Xvfb :99 -screen 0 1024x768x16 & + export DISPLAY=:99 + npm install + touch css/custom.css + npm run test:prettier + npm run test:js + npm run test:css + npm run test:unit + npm run test:e2e + npm run test:electron diff --git a/.github/workflows/codecov-test-suites.yml b/.github/workflows/codecov-test-suites.yml index 1a6d4e0e..8c2be8da 100644 --- a/.github/workflows/codecov-test-suites.yml +++ b/.github/workflows/codecov-test-suites.yml @@ -4,22 +4,26 @@ name: "Run Codecov Tests" on: push: - branches: [ master, develop ] + branches: [master, develop] pull_request: - branches: [ master, develop ] + branches: [master, develop] jobs: run-and-upload-coverage-report: runs-on: ubuntu-latest timeout-minutes: 30 steps: - - uses: actions/checkout@v2 - - run: | + - name: Checkout code + uses: actions/checkout@v2 + - 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 - - uses: codecov/codecov-action@v1 + - name: Upload coverage results to codecov + uses: codecov/codecov-action@v1 with: file: ./coverage/lcov.info fail_ci_if_error: true diff --git a/.github/workflows/enforce-changelog.yml b/.github/workflows/enforce-changelog.yml index d4a5a994..e1c2856d 100644 --- a/.github/workflows/enforce-changelog.yml +++ b/.github/workflows/enforce-changelog.yml @@ -4,15 +4,17 @@ name: "Enforce Changelog" on: pull_request: - types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled] + types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled] jobs: check: runs-on: ubuntu-latest timeout-minutes: 10 steps: - - uses: actions/checkout@v2 - - uses: dangoslen/changelog-enforcer@v1.6.1 - with: - changeLogPath: 'CHANGELOG.md' - skipLabels: 'Skip Changelog' + - name: Checkout code + uses: actions/checkout@v2 + - name: Enforce changelog️ + uses: dangoslen/changelog-enforcer@v1.6.1 + with: + changeLogPath: "CHANGELOG.md" + skipLabels: "Skip Changelog" diff --git a/.github/workflows/node-ci.js.yml b/.github/workflows/node-ci.js.yml deleted file mode 100644 index b5dd7aee..00000000 --- a/.github/workflows/node-ci.js.yml +++ /dev/null @@ -1,33 +0,0 @@ -# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions - -name: "Run Automated Tests" - -on: - push: - branches: [ master, develop ] - pull_request: - branches: [ master, develop ] - -jobs: - test: - runs-on: ubuntu-latest - timeout-minutes: 30 - strategy: - matrix: - node-version: [12.x, 14.x, 16.x] - steps: - - uses: actions/checkout@v2 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - - run: | - Xvfb :99 -screen 0 1024x768x16 & - export DISPLAY=:99 - npm install - npm run test:prettier - npm run test:js - npm run test:css - npm run test:unit - npm run test:e2e diff --git a/.husky/.gitignore b/.husky/.gitignore deleted file mode 100644 index 31354ec1..00000000 --- a/.husky/.gitignore +++ /dev/null @@ -1 +0,0 @@ -_ diff --git a/.prettierignore b/.prettierignore index eeaa248d..c092da9b 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,8 +1,4 @@ /config /coverage -/vendor -!/vendor/vendor.js -.github .nyc_output package-lock.json -*.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index f8d57bfd..e468b929 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,38 @@ 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.17.0] - 2021-10-01 + +Special thanks to the following contributors: @apiontek, @eouia, @jupadin, @khassel and @rejas. + +### Added + +- Added showTime parameter to clock module for enabling/disabling time display in analog clock. +- Added custom electron switches from user config (`config.electronSwitches`). +- Added unit tests for updatenotification module. + +### Updated + +- Bump electron to v13 (and spectron to v15) and update other dependencies in package.json. +- Refactor test configs, use default test config for all tests. +- Updated github templates. +- Actually test all js and css files when lint script is run. +- Update jsdocs and print warnings during testing too. +- Update weathergov provider to try fetching not just current, but also foreacst, when API URLs available. +- Refactored clock layout. +- Refactored methods from weatherproviders into weatherobject (isDaytime, updateSunTime). +- Use of `logger.js` in jest tests. +- Run prettier over all relevant files. +- Move tests needing electron in new category `electron`, use `server only` mode in `e2e` tests. +- Update dependencies in package.json. + +### Fixed + +- Fix undefined error with ignoreToday option in weather module (#2620). +- Fix time zone correction in calendar module when the date hour is equal to the time zone correction value (#2632). +- Fix black cursor on startup when using electron. +- Fix update notification not working for own repository (#2644). + ## [2.16.0] - 2021-07-01 Special thanks to the following contributors: @210954, @B1gG, @codac, @Crazylegstoo, @daniel, @earlman, @ezeholz, @FrancoisRmn, @jupadin, @khassel, @KristjanESPERANTO, @njwilliams, @oemel09, @r3wald, @rejas, @rico24, Faizan Ahmed. @@ -412,6 +444,7 @@ Special thanks to @sdetweil for all his great contributions! - Update `ical.js` to solve various calendar issues. - Update weather city list url [#1676](https://github.com/MichMich/MagicMirror/issues/1676) - Only update clock once per minute when seconds aren't shown +- Update weatherprovider documentation. ### Fixed diff --git a/config/config.js.sample b/config/config.js.sample index d02c74ef..2edef29b 100644 --- a/config/config.js.sample +++ b/config/config.js.sample @@ -57,7 +57,8 @@ let config = { calendars: [ { symbol: "calendar-check", - url: "webcal://www.calendarlabs.com/ical-calendar/ics/76/US_Holidays.ics" } + url: "webcal://www.calendarlabs.com/ical-calendar/ics/76/US_Holidays.ics" + } ] } }, diff --git a/index.html b/index.html index c9f2239c..37fc2f6e 100644 --- a/index.html +++ b/index.html @@ -16,7 +16,7 @@ diff --git a/js/app.js b/js/app.js index 6315370b..9ead45b2 100644 --- a/js/app.js +++ b/js/app.js @@ -48,6 +48,7 @@ process.on("uncaughtException", function (err) { */ function App() { let nodeHelpers = []; + let httpServer; /** * Loads the config file. Combines it with the defaults, and runs the @@ -222,7 +223,7 @@ function App() { } loadModules(modules, function () { - const server = new Server(config, function (app, io) { + httpServer = new Server(config, function (app, io) { Log.log("Server started ..."); for (let nodeHelper of nodeHelpers) { @@ -253,6 +254,7 @@ function App() { nodeHelper.stop(); } } + httpServer.close(); }; /** diff --git a/js/class.js b/js/class.js index b25ced0a..339e24b2 100644 --- a/js/class.js +++ b/js/class.js @@ -8,8 +8,8 @@ * MIT Licensed. */ (function () { - var initializing = false; - var fnTest = /xyz/.test(function () { + let initializing = false; + const fnTest = /xyz/.test(function () { xyz; }) ? /\b_super\b/ @@ -20,27 +20,27 @@ // Create a new Class that inherits from this class Class.extend = function (prop) { - var _super = this.prototype; + let _super = this.prototype; // Instantiate a base class (but only create the instance, // don't run the init constructor) initializing = true; - var prototype = new this(); + const prototype = new this(); initializing = false; // Make a copy of all prototype properties, to prevent reference issues. - for (var p in prototype) { + for (const p in prototype) { prototype[p] = cloneObject(prototype[p]); } // Copy the properties over onto the new prototype - for (var name in prop) { + for (const name in prop) { // Check if we're overwriting an existing function prototype[name] = typeof prop[name] === "function" && typeof _super[name] === "function" && fnTest.test(prop[name]) ? (function (name, fn) { return function () { - var tmp = this._super; + const tmp = this._super; // Add a new ._super() method that is the same method // but on the super-class @@ -48,7 +48,7 @@ // The method only need to be bound temporarily, so we // remove it when we're done executing - var ret = fn.apply(this, arguments); + const ret = fn.apply(this, arguments); this._super = tmp; return ret; @@ -91,8 +91,8 @@ function cloneObject(obj) { return obj; } - var temp = obj.constructor(); // give temp the original obj's constructor - for (var key in obj) { + const temp = obj.constructor(); // give temp the original obj's constructor + for (const key in obj) { temp[key] = cloneObject(obj[key]); if (key === "lockStrings") { diff --git a/js/electron.js b/js/electron.js index a834f7ab..2c44ab02 100644 --- a/js/electron.js +++ b/js/electron.js @@ -19,7 +19,8 @@ let mainWindow; * */ function createWindow() { - app.commandLine.appendSwitch("autoplay-policy", "no-user-gesture-required"); + let electronSwitchesDefaults = ["autoplay-policy", "no-user-gesture-required"]; + app.commandLine.appendSwitch(...new Set(electronSwitchesDefaults, config.electronSwitches)); let electronOptionsDefaults = { width: 800, height: 600, @@ -65,12 +66,17 @@ function createWindow() { if (process.argv.includes("dev")) { if (process.env.JEST_WORKER_ID !== undefined) { // if we are running with jest - var devtools = new BrowserWindow(electronOptions); + const devtools = new BrowserWindow(electronOptions); mainWindow.webContents.setDevToolsWebContents(devtools.webContents); } mainWindow.webContents.openDevTools(); } + // simulate mouse move to hide black cursor on start + mainWindow.webContents.on("dom-ready", (event) => { + mainWindow.webContents.sendInputEvent({ type: "mouseMove", x: 0, y: 0 }); + }); + // Set responders for window events. mainWindow.on("closed", function () { mainWindow = null; @@ -102,7 +108,12 @@ app.on("ready", function () { // Quit when all windows are closed. app.on("window-all-closed", function () { - createWindow(); + if (process.env.JEST_WORKER_ID !== undefined) { + // if we are running with jest + app.quit(); + } else { + createWindow(); + } }); app.on("activate", function () { diff --git a/js/logger.js b/js/logger.js index 93a5bb53..0ea523d7 100644 --- a/js/logger.js +++ b/js/logger.js @@ -9,12 +9,13 @@ */ (function (root, factory) { if (typeof exports === "object") { - // add timestamps in front of log messages - require("console-stamp")(console, { - pattern: "yyyy-mm-dd HH:MM:ss.l", - include: ["debug", "log", "info", "warn", "error"] - }); - + if (process.env.JEST_WORKER_ID === undefined) { + // add timestamps in front of log messages + require("console-stamp")(console, { + pattern: "yyyy-mm-dd HH:MM:ss.l", + include: ["debug", "log", "info", "warn", "error"] + }); + } // Node, CommonJS-like module.exports = factory(root.config); } else { @@ -22,29 +23,57 @@ root.Log = factory(root.config); } })(this, function (config) { - const logLevel = { - debug: Function.prototype.bind.call(console.debug, console), - log: Function.prototype.bind.call(console.log, console), - info: Function.prototype.bind.call(console.info, console), - warn: Function.prototype.bind.call(console.warn, console), - error: Function.prototype.bind.call(console.error, console), - group: Function.prototype.bind.call(console.group, console), - groupCollapsed: Function.prototype.bind.call(console.groupCollapsed, console), - groupEnd: Function.prototype.bind.call(console.groupEnd, console), - time: Function.prototype.bind.call(console.time, console), - timeEnd: Function.prototype.bind.call(console.timeEnd, console), - timeStamp: Function.prototype.bind.call(console.timeStamp, console) - }; + let logLevel; + let enableLog; + if (typeof exports === "object") { + // in nodejs and not running with jest + enableLog = process.env.JEST_WORKER_ID === undefined; + } else { + // in browser and not running with jsdom + enableLog = typeof window === "object" && window.name !== "jsdom"; + } - logLevel.setLogLevel = function (newLevel) { - if (newLevel) { - Object.keys(logLevel).forEach(function (key, index) { - if (!newLevel.includes(key.toLocaleUpperCase())) { - logLevel[key] = function () {}; - } - }); - } - }; + if (enableLog) { + logLevel = { + debug: Function.prototype.bind.call(console.debug, console), + log: Function.prototype.bind.call(console.log, console), + info: Function.prototype.bind.call(console.info, console), + warn: Function.prototype.bind.call(console.warn, console), + error: Function.prototype.bind.call(console.error, console), + group: Function.prototype.bind.call(console.group, console), + groupCollapsed: Function.prototype.bind.call(console.groupCollapsed, console), + groupEnd: Function.prototype.bind.call(console.groupEnd, console), + time: Function.prototype.bind.call(console.time, console), + timeEnd: Function.prototype.bind.call(console.timeEnd, console), + timeStamp: Function.prototype.bind.call(console.timeStamp, console) + }; + + logLevel.setLogLevel = function (newLevel) { + if (newLevel) { + Object.keys(logLevel).forEach(function (key, index) { + if (!newLevel.includes(key.toLocaleUpperCase())) { + logLevel[key] = function () {}; + } + }); + } + }; + } else { + logLevel = { + debug: function () {}, + log: function () {}, + info: function () {}, + warn: function () {}, + error: function () {}, + group: function () {}, + groupCollapsed: function () {}, + groupEnd: function () {}, + time: function () {}, + timeEnd: function () {}, + timeStamp: function () {} + }; + + logLevel.setLogLevel = function () {}; + } return logLevel; }); diff --git a/js/module.js b/js/module.js index b754e197..84222fa3 100644 --- a/js/module.js +++ b/js/module.js @@ -7,7 +7,7 @@ * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ -var Module = Class.extend({ +const Module = Class.extend({ /********************************************************* * All methods (and properties) below can be subclassed. * *********************************************************/ @@ -498,8 +498,8 @@ 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.version); - if (cmpVersions(window.version, moduleDefinition.requiresVersion) >= 0) { + 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 + "'"); @@ -510,6 +510,8 @@ Module.register = function (name, moduleDefinition) { Module.definitions[name] = moduleDefinition; }; +window.Module = Module; + /** * Compare two semantic version numbers and return the difference. * diff --git a/js/server.js b/js/server.js index 5ce9435d..92607d39 100644 --- a/js/server.js +++ b/js/server.js @@ -23,6 +23,7 @@ const Utils = require("./utils.js"); */ function Server(config, callback) { const port = process.env.MM_PORT || config.port; + const serverSockets = new Set(); let server = null; if (config.useHttps) { @@ -42,6 +43,13 @@ function Server(config, callback) { allowEIO3: true }); + server.on("connection", (socket) => { + serverSockets.add(socket); + socket.on("close", () => { + serverSockets.delete(socket); + }); + }); + Log.log(`Starting server on port ${port} ... `); server.listen(port, config.address || "localhost"); @@ -92,6 +100,13 @@ function Server(config, callback) { if (typeof callback === "function") { callback(app, io); } + + this.close = function () { + for (const socket of serverSockets.values()) { + socket.destroy(); + } + server.close(); + }; } module.exports = Server; diff --git a/js/translator.js b/js/translator.js index 1144e899..d69a9a1a 100644 --- a/js/translator.js +++ b/js/translator.js @@ -6,7 +6,7 @@ * By Christopher Fenner https://github.com/CFenner * MIT Licensed. */ -var Translator = (function () { +const Translator = (function () { /** * Load a JSON file via XHR. * @@ -141,12 +141,7 @@ var Translator = (function () { * The first language defined in translations.js will be used. */ loadCoreTranslationsFallback: function () { - // The variable `first` will contain the first - // defined translation after the following line. - for (var first in translations) { - break; - } - + let first = Object.keys(translations)[0]; if (first) { Log.log("Loading core translation fallback file: " + translations[first]); loadJSON(translations[first], (translations) => { @@ -156,3 +151,5 @@ var Translator = (function () { } }; })(); + +window.Translator = Translator; diff --git a/module-types.ts b/module-types.ts index 3b8825eb..be1a2061 100644 --- a/module-types.ts +++ b/module-types.ts @@ -1,16 +1,16 @@ type ModuleProperties = { - defaults?: object, - start?(): void, - getHeader?(): string, - getTemplate?(): string, - getTemplateData?(): object, - notificationReceived?(notification: string, payload: any, sender: object): void, - socketNotificationReceived?(notification: string, payload: any): void, - suspend?(): void, - resume?(): void, - getDom?(): HTMLElement, - getStyles?(): string[], - [key: string]: any, + defaults?: object; + start?(): void; + getHeader?(): string; + getTemplate?(): string; + getTemplateData?(): object; + notificationReceived?(notification: string, payload: any, sender: object): void; + socketNotificationReceived?(notification: string, payload: any): void; + suspend?(): void; + resume?(): void; + getDom?(): HTMLElement; + getStyles?(): string[]; + [key: string]: any; }; export declare const Module: { @@ -18,14 +18,14 @@ export declare const Module: { }; export declare const Log: { - info(message?: any, ...optionalParams: any[]): void, - log(message?: any, ...optionalParams: any[]): void, - error(message?: any, ...optionalParams: any[]): void, - warn(message?: any, ...optionalParams: any[]): void, - group(groupTitle?: string, ...optionalParams: any[]): void, - groupCollapsed(groupTitle?: string, ...optionalParams: any[]): void, - groupEnd(): void, - time(timerName?: string): void, - timeEnd(timerName?: string): void, - timeStamp(timerName?: string): void, -}; \ No newline at end of file + info(message?: any, ...optionalParams: any[]): void; + log(message?: any, ...optionalParams: any[]): void; + error(message?: any, ...optionalParams: any[]): void; + warn(message?: any, ...optionalParams: any[]): void; + group(groupTitle?: string, ...optionalParams: any[]): void; + groupCollapsed(groupTitle?: string, ...optionalParams: any[]): void; + groupEnd(): void; + time(timerName?: string): void; + timeEnd(timerName?: string): void; + timeStamp(timerName?: string): void; +}; diff --git a/modules/default/calendar/calendarutils.js b/modules/default/calendar/calendarutils.js index 7f0b14b8..91679f13 100644 --- a/modules/default/calendar/calendarutils.js +++ b/modules/default/calendar/calendarutils.js @@ -138,13 +138,14 @@ 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(); const today = moment().startOf("day").toDate(); const future = moment().startOf("day").add(config.maximumNumberOfDays, "days").subtract(1, "seconds").toDate(); // Subtract 1 second so that events that start on the middle of the night will not repeat. let past = today; - Log.debug("have entries "); + if (config.includePastEvents) { past = moment().startOf("day").subtract(config.maximumNumberOfDays, "days").toDate(); } @@ -159,10 +160,10 @@ const CalendarUtils = { } if (event.type === "VEVENT") { + Log.debug("\nEvent: " + JSON.stringify(event)); let startDate = eventDate(event, "start"); let endDate; - Log.debug("\nevent=" + JSON.stringify(event)); if (typeof event.end !== "undefined") { endDate = eventDate(event, "end"); } else if (typeof event.duration !== "undefined") { @@ -176,16 +177,21 @@ const CalendarUtils = { } } - Log.debug(" start=" + startDate.toDate() + " end=" + endDate.toDate()); + Log.debug("startDate (local): " + startDate.toDate()); + Log.debug("endDate (local): " + endDate.toDate()); - // calculate the duration of the event for use with recurring events. + // 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); + // FIXME: Since the parsed json object from node-ical comes with time information + // this check could be removed (?) if (event.start.length === 8) { startDate = startDate.startOf("day"); } const title = CalendarUtils.getTitleFromEvent(event); + Log.debug("title: " + title); let excluded = false, dateFilter = null; @@ -260,9 +266,13 @@ const CalendarUtils = { let pastLocal = 0; let futureLocal = 0; if (CalendarUtils.isFullDayEvent(event)) { + Log.debug("fullday"); // if full day event, only use the date part of the ranges pastLocal = pastMoment.toDate(); futureLocal = futureMoment.toDate(); + + Log.debug("pastLocal: " + pastLocal); + Log.debug("futureLocal: " + futureLocal); } else { // if we want past events if (config.includePastEvents) { @@ -274,9 +284,9 @@ const CalendarUtils = { } futureLocal = futureMoment.toDate(); // future } - Log.debug(" between=" + pastLocal + " to " + futureLocal); + Log.debug("Search for recurring events between: " + pastLocal + " and " + futureLocal); const dates = rule.between(pastLocal, futureLocal, true, limitFunction); - Log.debug("title=" + event.summary + " 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, @@ -284,6 +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); 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 @@ -296,38 +307,42 @@ const CalendarUtils = { // Loop through the set of date entries to see which recurrences should be added to our event list. for (let d in dates) { let date = dates[d]; - // ical.js started returning recurrences and exdates as ISOStrings without time information. - // .toISOString().substring(0,10) is the method they use to calculate keys, so we'll do the same - // (see https://github.com/peterbraden/ical.js/pull/84 ) + // Remove the time information of each date by using its substring, using the following method: + // .toISOString().substring(0,10). + // since the date is given as ISOString with YYYY-MM-DDTHH:MM:SS.SSSZ + // (see https://momentjs.com/docs/#/displaying/as-iso-string/). const dateKey = date.toISOString().substring(0, 10); let curEvent = event; let showRecurrence = true; - // get the offset of today where we are processing - // this will be the correction we need to apply + // Get the offset of today where we are processing + // This will be the correction, we need to apply. let nowOffset = new Date().getTimezoneOffset(); - // for full day events, the time might be off from RRULE/Luxon problem - // get time zone offset of the rule calculated event + // For full day events, the time might be off from RRULE/Luxon problem + // Get time zone offset of the rule calculated event let dateoffset = date.getTimezoneOffset(); - // reduce the time by the offset + + // Reduce the time by the following offset. 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); + if (CalendarUtils.isFullDayEvent(event)) { - Log.debug("fullday"); - // if the offset is negative, east of GMT where the problem is + Log.debug("Fullday"); + // If the offset is negative (east of GMT), where the problem is if (dateoffset < 0) { - // if the date hour is less than the offset - if (dh < Math.abs(dateoffset / 60)) { - // reduce the time by the offset - Log.debug(" recurring date is " + date + " offset is " + dateoffset); - // apply the correction to the date/time to get it UTC relative - date = new Date(date.getTime() - Math.abs(nowOffset) * 60000); - // 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); - } + // Remove the offset, independently of the comparison between the date hour and the offset, + // since in the case that *date houre < offset*, the *new Date* command will handle this by + // representing the day before. + + // Reduce the time by the offset: + // Apply the correction to the date/time to get it UTC relative + date = new Date(date.getTime() - Math.abs(nowOffset) * 60000); + // 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); } else { // if the timezones are the same, correct date if needed if (event.start.tz === moment.tz.guess()) { @@ -348,9 +363,8 @@ const CalendarUtils = { if (dateoffset < 0) { // if the date hour is less than the offset if (dh < Math.abs(dateoffset / 60)) { - // reduce the time by the offset - Log.debug(" recurring date is " + date + " offset is " + dateoffset); - // apply the correction to the date/time to get it UTC relative + // Reduce the time by the offset: + // Apply the correction to the date/time to get it UTC relative date = new Date(date.getTime() - Math.abs(nowOffset) * 60000); // the duration was calculated way back at the top before we could correct the start time.. // fix it for this event entry @@ -373,6 +387,7 @@ const CalendarUtils = { } } startDate = moment(date); + Log.debug("Corrected startDate (local): " + startDate.toDate()); let adjustDays = CalendarUtils.calculateTimezoneAdjustment(event, date); @@ -388,7 +403,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")) { @@ -408,7 +423,7 @@ const CalendarUtils = { } if (showRecurrence === true) { - Log.debug("saving event =" + description); + Log.debug("saving event: " + description); addedEvents++; newEvents.push({ title: recurrenceTitle, @@ -424,7 +439,7 @@ const CalendarUtils = { }); } } - // end recurring event parsing + // End recurring event parsing. } else { // Single event. const fullDayEvent = isFacebookBirthday ? true : CalendarUtils.isFullDayEvent(event); diff --git a/modules/default/clock/clock.js b/modules/default/clock/clock.js index fbab09a0..52cdb7e0 100644 --- a/modules/default/clock/clock.js +++ b/modules/default/clock/clock.js @@ -12,11 +12,14 @@ Module.register("clock", { displayType: "digital", // options: digital, analog, both timeFormat: config.timeFormat, + timezone: null, + displaySeconds: true, showPeriod: true, showPeriodUpper: false, clockBold: false, showDate: true, + showTime: true, showWeek: false, dateFormat: "dddd, LL", @@ -24,9 +27,8 @@ Module.register("clock", { analogSize: "200px", analogFace: "simple", // options: 'none', 'simple', 'face-###' (where ### is 001 to 012 inclusive) analogPlacement: "bottom", // options: 'top', 'bottom', 'left', 'right' - analogShowDate: "top", // options: false, 'top', or 'bottom' + analogShowDate: "top", // OBSOLETE, can be replaced with analogPlacement and showTime, options: false, 'top', or 'bottom' secondsColor: "#888888", - timezone: null, showSunTimes: false, showMoonTimes: false, @@ -89,11 +91,20 @@ Module.register("clock", { // Override dom generator. getDom: function () { const wrapper = document.createElement("div"); + wrapper.classList.add("clockGrid"); + + /************************************ + * Create wrappers for analog and digital clock + */ + const analogWrapper = document.createElement("div"); + analogWrapper.className = "clockCircle"; + const digitalWrapper = document.createElement("div"); + digitalWrapper.className = "digital"; + digitalWrapper.style.gridArea = "center"; /************************************ * Create wrappers for DIGITAL clock */ - const dateWrapper = document.createElement("div"); const timeWrapper = document.createElement("div"); const secondsWrapper = document.createElement("sup"); @@ -101,10 +112,11 @@ Module.register("clock", { const sunWrapper = document.createElement("div"); const moonWrapper = document.createElement("div"); const weekWrapper = document.createElement("div"); + // Style Wrappers dateWrapper.className = "date normal medium"; timeWrapper.className = "time bright large light"; - secondsWrapper.className = "dimmed"; + secondsWrapper.className = "seconds dimmed"; sunWrapper.className = "sun dimmed small"; moonWrapper.className = "moon dimmed small"; weekWrapper.className = "week dimmed medium"; @@ -124,7 +136,7 @@ Module.register("clock", { hourSymbol = "h"; } - if (this.config.clockBold === true) { + if (this.config.clockBold) { timeString = now.format(hourSymbol + '[]mm[]'); } else { timeString = now.format(hourSymbol + ":mm"); @@ -132,22 +144,24 @@ Module.register("clock", { if (this.config.showDate) { dateWrapper.innerHTML = now.format(this.config.dateFormat); + digitalWrapper.appendChild(dateWrapper); } - if (this.config.showWeek) { - weekWrapper.innerHTML = this.translate("WEEK", { weekNumber: now.week() }); - } - timeWrapper.innerHTML = timeString; - secondsWrapper.innerHTML = now.format("ss"); - if (this.config.showPeriodUpper) { - periodWrapper.innerHTML = now.format("A"); - } else { - periodWrapper.innerHTML = now.format("a"); - } - if (this.config.displaySeconds) { - timeWrapper.appendChild(secondsWrapper); - } - if (this.config.showPeriod && this.config.timeFormat !== 24) { - timeWrapper.appendChild(periodWrapper); + + if (this.config.displayType !== "analog" && this.config.showTime) { + timeWrapper.innerHTML = timeString; + secondsWrapper.innerHTML = now.format("ss"); + if (this.config.showPeriodUpper) { + periodWrapper.innerHTML = now.format("A"); + } else { + periodWrapper.innerHTML = now.format("a"); + } + if (this.config.displaySeconds) { + timeWrapper.appendChild(secondsWrapper); + } + if (this.config.showPeriod && this.config.timeFormat !== 24) { + timeWrapper.appendChild(periodWrapper); + } + digitalWrapper.appendChild(timeWrapper); } /** @@ -165,6 +179,9 @@ Module.register("clock", { return moment(time).format(formatString); } + /**************************************************************** + * Create wrappers for Sun Times, only if specified in config + */ if (this.config.showSunTimes) { const sunTimes = SunCalc.getTimes(now, this.config.lat, this.config.lon); const isVisible = now.isBetween(sunTimes.sunrise, sunTimes.sunset); @@ -191,7 +208,12 @@ Module.register("clock", { ' ' + formatTime(this.config, sunTimes.sunset) + ""; + digitalWrapper.appendChild(sunWrapper); } + + /**************************************************************** + * Create wrappers for Moon Times, only if specified in config + */ if (this.config.showMoonTimes) { const moonIllumination = SunCalc.getMoonIllumination(now.toDate()); const moonTimes = SunCalc.getMoonTimes(now, this.config.lat, this.config.lon); @@ -217,13 +239,17 @@ Module.register("clock", { ' ' + (moonSet ? formatTime(this.config, moonSet) : "...") + ""; + digitalWrapper.appendChild(moonWrapper); + } + + if (this.config.showWeek) { + weekWrapper.innerHTML = this.translate("WEEK", { weekNumber: now.week() }); + digitalWrapper.appendChild(weekWrapper); } /**************************************************************** * Create wrappers for ANALOG clock, only if specified in config */ - const clockCircle = document.createElement("div"); - if (this.config.displayType !== "digital") { // If it isn't 'digital', then an 'analog' clock was also requested @@ -236,19 +262,18 @@ Module.register("clock", { hour = ((now.hours() % 12) / 12) * 360 + 90 + minute / 12; // Create wrappers - clockCircle.className = "clockCircle"; - clockCircle.style.width = this.config.analogSize; - clockCircle.style.height = this.config.analogSize; + analogWrapper.style.width = this.config.analogSize; + analogWrapper.style.height = this.config.analogSize; if (this.config.analogFace !== "" && this.config.analogFace !== "simple" && this.config.analogFace !== "none") { - clockCircle.style.background = "url(" + this.data.path + "faces/" + this.config.analogFace + ".svg)"; - clockCircle.style.backgroundSize = "100%"; + 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 - // clockCircle.style.border = "1px solid black"; - clockCircle.style.border = "rgba(0, 0, 0, 0.1)"; //Updated fix for Issue 611 where non-black backgrounds are used + // analogWrapper.style.border = "1px solid black"; + analogWrapper.style.border = "rgba(0, 0, 0, 0.1)"; //Updated fix for Issue 611 where non-black backgrounds are used } else if (this.config.analogFace !== "none") { - clockCircle.style.border = "2px solid white"; + analogWrapper.style.border = "2px solid white"; } const clockFace = document.createElement("div"); clockFace.className = "clockFace"; @@ -274,84 +299,28 @@ Module.register("clock", { clockSecond.style.backgroundColor = this.config.secondsColor; clockFace.appendChild(clockSecond); } - clockCircle.appendChild(clockFace); + analogWrapper.appendChild(clockFace); } /******************************************* - * Combine wrappers, check for .displayType + * Update placement, respect old analogShowDate even if its not needed anymore */ - - if (this.config.displayType === "digital") { - // Display only a digital clock - wrapper.appendChild(dateWrapper); - wrapper.appendChild(timeWrapper); - wrapper.appendChild(sunWrapper); - wrapper.appendChild(moonWrapper); - wrapper.appendChild(weekWrapper); - } else if (this.config.displayType === "analog") { + if (this.config.displayType === "analog") { // Display only an analog clock - - if (this.config.showWeek) { - weekWrapper.style.paddingBottom = "15px"; - } else { - dateWrapper.style.paddingBottom = "15px"; - } - if (this.config.analogShowDate === "top") { - wrapper.appendChild(dateWrapper); - wrapper.appendChild(weekWrapper); - wrapper.appendChild(clockCircle); + wrapper.classList.add("clockGrid--bottom"); } else if (this.config.analogShowDate === "bottom") { - wrapper.appendChild(clockCircle); - wrapper.appendChild(dateWrapper); - wrapper.appendChild(weekWrapper); + wrapper.classList.add("clockGrid--top"); } else { - wrapper.appendChild(clockCircle); - } - } else { - // Both clocks have been configured, check position - const placement = this.config.analogPlacement; - - const analogWrapper = document.createElement("div"); - analogWrapper.id = "analog"; - analogWrapper.style.cssFloat = "none"; - analogWrapper.appendChild(clockCircle); - - const digitalWrapper = document.createElement("div"); - digitalWrapper.id = "digital"; - digitalWrapper.style.cssFloat = "none"; - digitalWrapper.appendChild(dateWrapper); - digitalWrapper.appendChild(timeWrapper); - digitalWrapper.appendChild(sunWrapper); - digitalWrapper.appendChild(moonWrapper); - digitalWrapper.appendChild(weekWrapper); - - const appendClocks = (condition, pos1, pos2) => { - const padding = [0, 0, 0, 0]; - padding[placement === condition ? pos1 : pos2] = "20px"; - analogWrapper.style.padding = padding.join(" "); - if (placement === condition) { - wrapper.appendChild(analogWrapper); - wrapper.appendChild(digitalWrapper); - } else { - wrapper.appendChild(digitalWrapper); - wrapper.appendChild(analogWrapper); - } - }; - - if (placement === "left" || placement === "right") { - digitalWrapper.style.display = "inline-block"; - digitalWrapper.style.verticalAlign = "top"; - analogWrapper.style.display = "inline-block"; - - appendClocks("left", 1, 3); - } else { - digitalWrapper.style.textAlign = "center"; - - appendClocks("top", 2, 0); + //analogWrapper.style.gridArea = "center"; } + } else if (this.config.displayType === "both") { + wrapper.classList.add("clockGrid--" + this.config.analogPlacement); } + wrapper.appendChild(analogWrapper); + wrapper.appendChild(digitalWrapper); + // Return the wrapper to the dom. return wrapper; } diff --git a/modules/default/clock/clock_styles.css b/modules/default/clock/clock_styles.css index 0e74fd7a..e3eb7e94 100644 --- a/modules/default/clock/clock_styles.css +++ b/modules/default/clock/clock_styles.css @@ -1,5 +1,26 @@ +.clockGrid { + display: inline-flex; + gap: 15px; +} + +.clockGrid--left { + flex-direction: row; +} + +.clockGrid--right { + flex-direction: row-reverse; +} + +.clockGrid--top { + flex-direction: column; +} + +.clockGrid--bottom { + flex-direction: column-reverse; +} + .clockCircle { - margin: 0 auto; + place-self: center; position: relative; border-radius: 50%; background-size: 100%; diff --git a/modules/default/currentweather/currentweather.js b/modules/default/currentweather/currentweather.js index 0d22b40a..5a00fb99 100644 --- a/modules/default/currentweather/currentweather.js +++ b/modules/default/currentweather/currentweather.js @@ -1,3 +1,5 @@ +/* eslint-disable */ + /* Magic Mirror * Module: CurrentWeather * diff --git a/modules/default/updatenotification/git_helper.js b/modules/default/updatenotification/git_helper.js new file mode 100644 index 00000000..b165e7bc --- /dev/null +++ b/modules/default/updatenotification/git_helper.js @@ -0,0 +1,177 @@ +const util = require("util"); +const exec = util.promisify(require("child_process").exec); +const fs = require("fs"); +const path = require("path"); +const Log = require("logger"); + +class gitHelper { + constructor() { + this.gitRepos = []; + this.baseDir = path.normalize(__dirname + "/../../../"); + } + + getRefRegex(branch) { + return new RegExp("s*([a-z,0-9]+[.][.][a-z,0-9]+) " + branch, "g"); + } + + async execShell(command) { + let res = { stdout: "", stderr: "" }; + const { stdout, stderr } = await exec(command); + + res.stdout = stdout; + res.stderr = stderr; + return res; + } + + async isGitRepo(moduleFolder) { + let res = await this.execShell("cd " + moduleFolder + " && git remote -v"); + if (res.stderr) { + Log.error("Failed to fetch git data for " + moduleFolder + ": " + res.stderr); + return false; + } else { + return true; + } + } + + add(moduleName) { + let moduleFolder = this.baseDir; + if (moduleName !== "default") { + moduleFolder = moduleFolder + "modules/" + moduleName; + } + try { + Log.info("Checking git for module: " + moduleName); + // Throws error if file doesn't exist + fs.statSync(path.join(moduleFolder, ".git")); + // Fetch the git or throw error if no remotes + if (this.isGitRepo(moduleFolder)) { + // Folder has .git and has at least one git remote, watch this folder + this.gitRepos.unshift({ module: moduleName, folder: moduleFolder }); + } + } catch (err) { + // Error when directory .git doesn't exist or doesn't have any remotes + // This module is not managed with git, skip + } + } + + async getStatusInfo(repo) { + let gitInfo = { + module: repo.module, + // commits behind: + behind: 0, + // branch name: + current: "", + // current hash: + hash: "", + // remote branch: + tracking: "", + isBehindInStatus: false + }; + let res; + if (repo.module === "default") { + // the hash is only needed for the mm repo + res = await this.execShell("cd " + repo.folder + " && git rev-parse HEAD"); + if (res.stderr) { + Log.error("Failed to get current commit hash for " + repo.module + ": " + res.stderr); + } + gitInfo.hash = res.stdout; + } + if (repo.res) { + // mocking + res = repo.res; + } else { + res = await this.execShell("cd " + repo.folder + " && git status -sb"); + } + if (res.stderr) { + Log.error("Failed to get git status for " + repo.module + ": " + res.stderr); + // exit without git status info + return; + } + // only the first line of stdout is evaluated + let status = res.stdout.split("\n")[0]; + // examples for status: + // ## develop...origin/develop + // ## master...origin/master [behind 8] + status = status.match(/(?![.#])([^.]*)/g); + // examples for status: + // [ ' develop', 'origin/develop', '' ] + // [ ' master', 'origin/master [behind 8]', '' ] + gitInfo.current = status[0].trim(); + status = status[1].split(" "); + // examples for status: + // [ 'origin/develop' ] + // [ 'origin/master', '[behind', '8]' ] + gitInfo.tracking = status[0].trim(); + if (status[2]) { + // git fetch was already called before so `git status -sb` delivers already the behind number + gitInfo.behind = parseInt(status[2].substring(0, status[2].length - 1)); + gitInfo.isBehindInStatus = true; + } + return gitInfo; + } + + async getRepoInfo(repo) { + let gitInfo; + if (repo.gitInfo) { + // mocking + gitInfo = repo.gitInfo; + } else { + gitInfo = await this.getStatusInfo(repo); + } + if (!gitInfo) { + return; + } + if (gitInfo.isBehindInStatus) { + return gitInfo; + } + let res; + if (repo.res) { + // mocking + res = repo.res; + } else { + res = await this.execShell("cd " + repo.folder + " && git fetch --dry-run"); + } + // example output: + // From https://github.com/MichMich/MagicMirror + // e40ddd4..06389e3 develop -> origin/develop + // here the result is in stderr (this is a git default, don't ask why ...) + const matches = res.stderr.match(this.getRefRegex(gitInfo.current)); + if (!matches || !matches[0]) { + // no refs found, nothing to do + return; + } + // get behind with refs + try { + res = await this.execShell("cd " + repo.folder + " && git rev-list --ancestry-path --count " + matches[0]); + gitInfo.behind = parseInt(res.stdout); + return gitInfo; + } catch (err) { + Log.error("Failed to get git revisions for " + repo.module + ": " + err); + } + } + + async getStatus() { + const gitResultList = []; + for (let repo of this.gitRepos) { + const gitInfo = await this.getStatusInfo(repo); + if (gitInfo) { + gitResultList.unshift(gitInfo); + } + } + + return gitResultList; + } + + async getRepos() { + const gitResultList = []; + for (let repo of this.gitRepos) { + const gitInfo = await this.getRepoInfo(repo); + if (gitInfo) { + gitResultList.unshift(gitInfo); + } + } + + return gitResultList; + } +} + +module.exports.gitHelper = gitHelper; diff --git a/modules/default/updatenotification/node_helper.js b/modules/default/updatenotification/node_helper.js index e2e5617c..c24e190a 100644 --- a/modules/default/updatenotification/node_helper.js +++ b/modules/default/updatenotification/node_helper.js @@ -1,9 +1,5 @@ -const SimpleGit = require("simple-git"); -const simpleGits = []; -const fs = require("fs"); -const path = require("path"); +const GitHelper = require(__dirname + "/git_helper.js"); const defaultModules = require(__dirname + "/../defaultmodules.js"); -const Log = require("logger"); const NodeHelper = require("node_helper"); module.exports = NodeHelper.create({ @@ -12,32 +8,19 @@ module.exports = NodeHelper.create({ updateTimer: null, updateProcessStarted: false, + gitHelper: new GitHelper.gitHelper(), + start: function () {}, configureModules: async function (modules) { // Push MagicMirror itself , biggest chance it'll show up last in UI and isn't overwritten // others will be added in front // this method returns promises so we can't wait for every one to resolve before continuing - simpleGits.push({ module: "default", git: this.createGit(path.normalize(__dirname + "/../../../")) }); + this.gitHelper.add("default"); for (let moduleName in modules) { if (!this.ignoreUpdateChecking(moduleName)) { - // Default modules are included in the main MagicMirror repo - let moduleFolder = path.normalize(__dirname + "/../../" + moduleName); - - try { - Log.info("Checking git for module: " + moduleName); - // Throws error if file doesn't exist - fs.statSync(path.join(moduleFolder, ".git")); - // Fetch the git or throw error if no remotes - let git = await this.resolveRemote(moduleFolder); - // Folder has .git and has at least one git remote, watch this folder - simpleGits.unshift({ module: moduleName, git: git }); - } catch (err) { - // Error when directory .git doesn't exist or doesn't have any remotes - // This module is not managed with git, skip - continue; - } + this.gitHelper.add(moduleName); } } }, @@ -54,35 +37,9 @@ module.exports = NodeHelper.create({ } }, - resolveRemote: async function (moduleFolder) { - let git = this.createGit(moduleFolder); - let remotes = await git.getRemotes(true); - - if (remotes.length < 1 || remotes[0].name.length < 1) { - throw new Error("No valid remote for folder " + moduleFolder); - } - - return git; - }, - performFetch: async function () { - for (let sg of simpleGits) { - try { - let fetchData = await sg.git.fetch(["--dry-run"]).status(); - let logData = await sg.git.log({ "-1": null }); - - if (logData.latest && "hash" in logData.latest) { - this.sendSocketNotification("STATUS", { - module: sg.module, - behind: fetchData.behind, - current: fetchData.current, - hash: logData.latest.hash, - tracking: fetchData.tracking - }); - } - } catch (err) { - Log.error("Failed to fetch git data for " + sg.module + ": " + err); - } + for (let gitInfo of await this.gitHelper.getRepos()) { + this.sendSocketNotification("STATUS", gitInfo); } this.scheduleNextFetch(this.config.updateInterval); @@ -100,10 +57,6 @@ module.exports = NodeHelper.create({ }, delay); }, - createGit: function (folder) { - return SimpleGit({ baseDir: folder, timeout: { block: this.config.timeout } }); - }, - ignoreUpdateChecking: function (moduleName) { // Should not check for updates for default modules if (defaultModules.indexOf(moduleName) >= 0) { diff --git a/modules/default/weather/forecast.njk b/modules/default/weather/forecast.njk index 92a575cf..32a2e4a6 100644 --- a/modules/default/weather/forecast.njk +++ b/modules/default/weather/forecast.njk @@ -2,6 +2,9 @@ {% set numSteps = forecast | calcNumSteps %} {% set currentStep = 0 %} + {% if config.ignoreToday %} + {% set forecast = forecast.splice(1) %} + {% endif %} {% set forecast = forecast.slice(0, numSteps) %} {% for f in forecast %} @@ -20,10 +23,10 @@ {{ f.minTemperature | roundValue | unit("temperature") | decimalSymbol }} {% if config.showPrecipitationAmount %} - {% if f.precipitationUnits %} + {% if f.precipitationUnits %} + {% else %}
{{ f.precipitation }}{{ f.precipitationUnits }} - {{ f.precipitation | unit("precip") }} diff --git a/modules/default/weather/providers/README.md b/modules/default/weather/providers/README.md index f6e5d732..faa60a05 100755 --- a/modules/default/weather/providers/README.md +++ b/modules/default/weather/providers/README.md @@ -1,148 +1,3 @@ -# MagicMirror² Weather Module Weather Provider Development Documentation +# Weather Module Weather Provider Development Documentation -This document describes the way to develop your own MagicMirror² weather module weather provider. - -Table of Contents: - -- The weather provider file: yourprovider.js - - [Weather provider methods to implement](#weather-provider-methods-to-implement) - - [Weather Provider instance methods](#weather-provider-instance-methods) - - [WeatherObject](#weatherobject) - ---- - -## The weather provider file: yourprovider.js - -This is the script in which the weather provider will be defined. In its most simple form, the weather provider must implement the following: - -```javascript -WeatherProvider.register("yourprovider", { - providerName: "YourProvider", - - fetchCurrentWeather() {}, - - fetchWeatherForecast() {} -}); -``` - -### Weather provider methods to implement - -#### `fetchCurrentWeather()` - -This method is called when the weather module tries to fetch the current weather of your provider. The implementation of this method is required for current weather support. -The implementation can make use of the already implemented function `this.fetchData(url, method, data);`, which is returning a promise. -After the response is processed, the current weather information (as a [WeatherObject](#weatherobject)) needs to be set with `this.setCurrentWeather(currentWeather);`. -It will then automatically refresh the module DOM with the new data. - -#### `fetchWeatherForecast()` - -This method is called when the weather module tries to fetch the weather of your provider. The implementation of this method is required for forecast support. -The implementation can make use of the already implemented function `this.fetchData(url, method, data);`, which is returning a promise. -After the response is processed, the weather forecast information (as an array of [WeatherObject](#weatherobject)s) needs to be set with `this.setWeatherForecast(forecast);`. -It will then automatically refresh the module DOM with the new data. - -#### `fetchWeatherHourly()` - -This method is called when the weather module tries to fetch the weather of your provider. The implementation of this method is required for hourly support. -The implementation can make use of the already implemented function `this.fetchData(url, method, data);`, which is returning a promise. -After the response is processed, the hourly weather forecast information (as an array of [WeatherObject](#weatherobject)s) needs to be set with `this.setWeatherHourly(forecast);`. -It will then automatically refresh the module DOM with the new data. - -### Weather Provider instance methods - -#### `init()` - -Called when a weather provider is initialized. - -#### `setConfig(config)` - -Called to set the config, this config is the same as the weather module's config. - -#### `start()` - -Called when the weather provider is about to start. - -#### `currentWeather()` - -This returns a WeatherDay object for the current weather. - -#### `weatherForecast()` - -This returns an array of WeatherDay objects for the weather forecast. - -#### `weatherHourly()` - -This returns an array of WeatherDay objects for the hourly weather forecast. - -#### `fetchedLocation()` - -This returns the name of the fetched location or an empty string. - -#### `setCurrentWeather(currentWeatherObject)` - -Set the currentWeather and notify the delegate that new information is available. - -#### `setWeatherForecast(weatherForecastArray)` - -Set the weatherForecastArray and notify the delegate that new information is available. - -#### `setWeatherHourly(weatherHourlyArray)` - -Set the weatherHourlyArray and notify the delegate that new information is available. - -#### `setFetchedLocation(name)` - -Set the fetched location name. - -#### `updateAvailable()` - -Notify the delegate that new weather is available. - -#### `fetchData(url, method, data)` - -A convenience function to make requests. It returns a promise. - -### WeatherObject - -| Property | Type | Value/Unit | -| -------------- | -------- | --------------------------------------------------------------------------------------------------------------- | -| units | `string` | Gets initialized with the constructor.
Possible values: `metric`, `imperial` | -| tempUnits | `string` | Gets initialized with the constructor.
Possible values: `metric`, `imperial` | -| windUnits | `string` | Gets initialized with the constructor.
Possible values: `metric`, `imperial` | -| date | `object` | [Moment.js](https://momentjs.com/) object of the time/date. | -| windSpeed | `number` | Metric: `meter/second`
Imperial: `miles/hour` | -| windDirection | `number` | Direction of the wind in degrees. | -| sunrise | `object` | [Moment.js](https://momentjs.com/) object of sunrise. | -| sunset | `object` | [Moment.js](https://momentjs.com/) object of sunset. | -| temperature | `number` | Current temperature | -| minTemperature | `number` | Lowest temperature of the day. | -| maxTemperature | `number` | Highest temperature of the day. | -| weatherType | `string` | Icon name of the weather type.
Possible values: [WeatherIcons](https://www.npmjs.com/package/weathericons) | -| humidity | `number` | Percentage of humidity | -| rain | `number` | Metric: `millimeters`
Imperial: `inches` | -| snow | `number` | Metric: `millimeters`
Imperial: `inches` | -| precipitation | `number` | Metric: `millimeters`
Imperial: `inches`
UK Met Office provider: `percent` | - -#### Current weather - -For the current weather object the following properties are required: - -- humidity -- sunrise -- sunset -- temperature -- units -- weatherType -- windDirection -- windSpeed - -#### Weather forecast - -For the forecast weather object the following properties are required: - -- date -- maxTemperature -- minTemperature -- rain -- units -- weatherType +For how to develop your own weather provider, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/development/weather-provider.html). diff --git a/modules/default/weather/providers/darksky.js b/modules/default/weather/providers/darksky.js index ea073887..451ac98b 100755 --- a/modules/default/weather/providers/darksky.js +++ b/modules/default/weather/providers/darksky.js @@ -8,7 +8,8 @@ * 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 + * Note that the Dark Sky API does not provide rainfall. Instead it provides + * snowfall and precipitation probability */ WeatherProvider.register("darksky", { // Set the name of the provider. @@ -98,7 +99,8 @@ WeatherProvider.register("darksky", { weather.snow = 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 + // Note that the Dark Sky API does not provide rainfall. + // Instead it provides snowfall and precipitation probability if (forecast.hasOwnProperty("precipAccumulation")) { if (this.config.units === "imperial" && !isNaN(forecast.precipAccumulation)) { weather.snow = forecast.precipAccumulation; diff --git a/modules/default/weather/providers/envcanada.js b/modules/default/weather/providers/envcanada.js index db0773ea..868ee6e2 100644 --- a/modules/default/weather/providers/envcanada.js +++ b/modules/default/weather/providers/envcanada.js @@ -134,7 +134,7 @@ WeatherProvider.register("envcanada", { // fetchData: function (url, method = "GET", data = null) { return new Promise(function (resolve, reject) { - var request = new XMLHttpRequest(); + const request = new XMLHttpRequest(); request.open(method, url, true); request.onreadystatechange = function () { if (this.readyState === 4) { @@ -164,9 +164,7 @@ WeatherProvider.register("envcanada", { // CORS errors when accessing EC // getUrl() { - var path = "https://thingproxy.freeboard.io/fetch/https://dd.weather.gc.ca/citypage_weather/xml/" + this.config.provCode + "/" + this.config.siteCode + "_e.xml"; - - return path; + return "https://thingproxy.freeboard.io/fetch/https://dd.weather.gc.ca/citypage_weather/xml/" + this.config.provCode + "/" + this.config.siteCode + "_e.xml"; }, // @@ -232,7 +230,7 @@ WeatherProvider.register("envcanada", { // Capture the sunrise and sunset values from EC data // - var sunList = ECdoc.querySelectorAll("siteData riseSet dateTime"); + const sunList = ECdoc.querySelectorAll("siteData riseSet dateTime"); currentWeather.sunrise = moment(sunList[1].querySelector("timeStamp").textContent, "YYYYMMDDhhmmss"); currentWeather.sunset = moment(sunList[3].querySelector("timeStamp").textContent, "YYYYMMDDhhmmss"); @@ -249,14 +247,14 @@ WeatherProvider.register("envcanada", { const days = []; - var weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); - var foreBaseDates = ECdoc.querySelectorAll("siteData forecastGroup dateTime"); - var baseDate = foreBaseDates[1].querySelector("timeStamp").textContent; + const foreBaseDates = ECdoc.querySelectorAll("siteData forecastGroup dateTime"); + const baseDate = foreBaseDates[1].querySelector("timeStamp").textContent; weather.date = moment(baseDate, "YYYYMMDDhhmmss"); - var foreGroup = ECdoc.querySelectorAll("siteData forecastGroup forecast"); + 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 @@ -288,9 +286,9 @@ WeatherProvider.register("envcanada", { // where the next day's (aka Tomorrow's) forecast is located in the forecast array. // - var nextDay = 0; - var lastDay = 0; - var currentTemp = ECdoc.querySelector("siteData currentConditions temperature").textContent; + let nextDay = 0; + let lastDay = 0; + const currentTemp = ECdoc.querySelector("siteData currentConditions temperature").textContent; // // If the first Element is Current Today, look at Current Today and Current Tonight for the current day. @@ -356,10 +354,10 @@ WeatherProvider.register("envcanada", { // iteration looking at the current Element and the next Element. // - var lastDate = moment(baseDate, "YYYYMMDDhhmmss"); + let lastDate = moment(baseDate, "YYYYMMDDhhmmss"); - for (var stepDay = nextDay; stepDay < lastDay; stepDay += 2) { - var weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + for (let stepDay = nextDay; stepDay < lastDay; stepDay += 2) { + let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); // Add 1 to the date to reflect the current forecast day we are building @@ -402,23 +400,23 @@ WeatherProvider.register("envcanada", { // Get local timezone UTC offset so that each hourly time can be calculated properly - var baseHours = ECdoc.querySelectorAll("siteData hourlyForecastGroup dateTime"); - var hourOffset = baseHours[1].getAttribute("UTCOffset"); + const baseHours = ECdoc.querySelectorAll("siteData hourlyForecastGroup dateTime"); + const hourOffset = baseHours[1].getAttribute("UTCOffset"); // // The EC hourly forecast is held in a 24-element array - Elements 0 to 23 - with Element 0 holding // the forecast for the next 'on the hour' timeslot. This means the array is a rolling 24 hours. // - var hourGroup = ECdoc.querySelectorAll("siteData hourlyForecastGroup hourlyForecast"); + const hourGroup = ECdoc.querySelectorAll("siteData hourlyForecastGroup hourlyForecast"); - for (var stepHour = 0; stepHour < 24; stepHour += 1) { - var weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + for (let stepHour = 0; stepHour < 24; stepHour += 1) { + const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); // Determine local time by applying UTC offset to the forecast timestamp - var foreTime = moment(hourGroup[stepHour].getAttribute("dateTimeUTC"), "YYYYMMDDhhmmss"); - var currTime = foreTime.add(hourOffset, "hours"); + const foreTime = moment(hourGroup[stepHour].getAttribute("dateTimeUTC"), "YYYYMMDDhhmmss"); + const currTime = foreTime.add(hourOffset, "hours"); weather.date = moment(currTime, "X"); // Capture the temperature @@ -427,7 +425,7 @@ WeatherProvider.register("envcanada", { // Capture Likelihood of Precipitation (LOP) and unit-of-measure values - var precipLOP = hourGroup[stepHour].querySelector("lop").textContent * 1.0; + const precipLOP = hourGroup[stepHour].querySelector("lop").textContent * 1.0; if (precipLOP > 0) { weather.precipitation = precipLOP; @@ -453,9 +451,9 @@ WeatherProvider.register("envcanada", { // setMinMaxTemps(weather, foreGroup, today, fullDay, currentTemp) { - var todayTemp = foreGroup[today].querySelector("temperatures temperature").textContent; + const todayTemp = foreGroup[today].querySelector("temperatures temperature").textContent; - var todayClass = foreGroup[today].querySelector("temperatures temperature").getAttribute("class"); + const todayClass = foreGroup[today].querySelector("temperatures temperature").getAttribute("class"); // // The following logic is largely aimed at accommodating the Current day's forecast whereby we @@ -500,9 +498,9 @@ WeatherProvider.register("envcanada", { } } - var nextTemp = foreGroup[today + 1].querySelector("temperatures temperature").textContent; + const nextTemp = foreGroup[today + 1].querySelector("temperatures temperature").textContent; - var nextClass = foreGroup[today + 1].querySelector("temperatures temperature").getAttribute("class"); + const nextClass = foreGroup[today + 1].querySelector("temperatures temperature").getAttribute("class"); if (fullDay === true) { if (nextClass === "low") { @@ -513,8 +511,6 @@ WeatherProvider.register("envcanada", { weather.maxTemperature = this.convertTemp(nextTemp); } } - - return; }, // @@ -560,8 +556,6 @@ WeatherProvider.register("envcanada", { weather.precipitation = foreGroup[today].querySelector("abbreviatedForecast pop").textContent; weather.precipitationUnits = foreGroup[today].querySelector("abbreviatedForecast pop").getAttribute("units"); } - - return; }, // @@ -577,6 +571,7 @@ WeatherProvider.register("envcanada", { return temp; } }, + // // Convert km/h to mph // diff --git a/modules/default/weather/providers/openweathermap.js b/modules/default/weather/providers/openweathermap.js index bbe74d3b..d6779d8d 100755 --- a/modules/default/weather/providers/openweathermap.js +++ b/modules/default/weather/providers/openweathermap.js @@ -18,10 +18,10 @@ WeatherProvider.register("openweathermap", { defaults: { apiVersion: "2.5", apiBase: "https://api.openweathermap.org/data/", - weatherEndpoint: "", + weatherEndpoint: "", // can be "onecall", "forecast" or "weather" (for current) locationID: false, location: false, - lat: 0, + lat: 0, // the onecall endpoint needs lat / lon values, it doesn'T support the locationId lon: 0, apiKey: "" }, @@ -89,7 +89,7 @@ WeatherProvider.register("openweathermap", { /** * Overrides method for setting config to check if endpoint is correct for hourly * - * @param config + * @param {object} config The configuration object */ setConfig(config) { this.config = config; diff --git a/modules/default/weather/providers/smhi.js b/modules/default/weather/providers/smhi.js index efcf8bb0..603aa814 100644 --- a/modules/default/weather/providers/smhi.js +++ b/modules/default/weather/providers/smhi.js @@ -1,4 +1,4 @@ -/* global WeatherProvider, WeatherObject, SunCalc */ +/* global WeatherProvider, WeatherObject */ /* Magic Mirror * Module: Weather @@ -7,9 +7,8 @@ * By BuXXi https://github.com/buxxi * MIT Licensed * - * This class is a provider for SMHI (Sweden only). - * Note that SMHI doesn't provide sunrise and sundown, use SunCalc to calculate it. - * Metric system is the only supported unit. + * This class is a provider for SMHI (Sweden only). Metric system is the only + * supported unit. */ WeatherProvider.register("smhi", { providerName: "SMHI", @@ -56,11 +55,11 @@ WeatherProvider.register("smhi", { /** * Overrides method for setting config with checks for the precipitationValue being unset or invalid * - * @param config + * @param {object} config The configuration object */ setConfig(config) { this.config = config; - if (!config.precipitationValue || ["pmin", "pmean", "pmedian", "pmax"].indexOf(config.precipitationValue) == -1) { + if (!config.precipitationValue || ["pmin", "pmean", "pmedian", "pmax"].indexOf(config.precipitationValue) === -1) { console.log("invalid or not set: " + config.precipitationValue); config.precipitationValue = this.defaults.precipitationValue; } @@ -69,7 +68,8 @@ WeatherProvider.register("smhi", { /** * Of all the times returned find out which one is closest to the current time, should be the first if the data isn't old. * - * @param times + * @param {object[]} times Array of time objects + * @returns {object} The weatherdata closest to the current time */ getClosestToCurrentTime(times) { let now = moment(); @@ -85,6 +85,8 @@ WeatherProvider.register("smhi", { /** * Get the forecast url for the configured coordinates + * + * @returns {string} the url for the specified coordinates */ getURL() { let lon = this.config.lon; @@ -97,25 +99,25 @@ WeatherProvider.register("smhi", { * The returned units is always in metric system. * Requires coordinates to determine if its daytime or nighttime to know which icon to use and also to set sunrise and sunset. * - * @param weatherData - * @param coordinates - * @param weatherData - * @param coordinates + * @param {object} weatherData Weatherdata to convert + * @param {object} coordinates Coordinates of the locations of the weather + * @returns {WeatherObject} The converted weatherdata at the specified location */ convertWeatherDataToObject(weatherData, coordinates) { - let currentWeather = new WeatherObject("metric", "metric", "metric"); //Weather data is only for Sweden and nobody in Sweden would use imperial + // Weather data is only for Sweden and nobody in Sweden would use imperial + let currentWeather = new WeatherObject("metric", "metric", "metric"); currentWeather.date = moment(weatherData.validTime); - let times = SunCalc.getTimes(currentWeather.date.toDate(), coordinates.lat, coordinates.lon); - currentWeather.sunrise = moment(times.sunrise, "X"); - currentWeather.sunset = moment(times.sunset, "X"); + currentWeather.updateSunTime(coordinates.lat, coordinates.lon); 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.weatherType = this.convertWeatherType(this.paramValue(weatherData, "Wsymb2"), this.isDayTime(currentWeather)); + currentWeather.weatherType = this.convertWeatherType(this.paramValue(weatherData, "Wsymb2"), currentWeather.isDayTime()); - //Determine the precipitation amount and category and update the weatherObject with it, the valuetype to use can be configured or uses median as default. + // Determine the precipitation amount and category and update the + // weatherObject with it, the valuetype to use can be configured or uses + // median as default. let precipitationValue = this.paramValue(weatherData, this.config.precipitationValue); switch (this.paramValue(weatherData, "pcat")) { // 0 = No precipitation @@ -143,10 +145,9 @@ WeatherProvider.register("smhi", { /** * Takes all of the data points and converts it to one WeatherObject per day. * - * @param allWeatherData - * @param coordinates - * @param allWeatherData - * @param coordinates + * @param {object[]} allWeatherData Array of weatherdata + * @param {object} coordinates Coordinates of the locations of the weather + * @returns {WeatherObject[]} Array of weatherobjects */ convertWeatherDataGroupedByDay(allWeatherData, coordinates) { let currentWeather; @@ -170,7 +171,7 @@ WeatherProvider.register("smhi", { } //Keep track of what icons has been used for each hour of daytime and use the middle one for the forecast - if (this.isDayTime(weatherObject)) { + if (weatherObject.isDayTime()) { dayWeatherTypes.push(weatherObject.weatherType); } if (dayWeatherTypes.length > 0) { @@ -191,37 +192,31 @@ WeatherProvider.register("smhi", { }, /** - * Resolve coordinates from the response data (probably preferably to use this if it's not matching the config values exactly) + * Resolve coordinates from the response data (probably preferably to use + * this if it's not matching the config values exactly) * - * @param data + * @param {object} data Response data from the weather service + * @returns {{lon, lat}} the lat/long coordinates of the data */ resolveCoordinates(data) { return { lat: data.geometry.coordinates[0][1], lon: data.geometry.coordinates[0][0] }; }, - /** - * Checks if the weatherObject is at dayTime. - * - * @param weatherObject - */ - isDayTime(weatherObject) { - return weatherObject.date.isBetween(weatherObject.sunrise, weatherObject.sunset, undefined, "[]"); - }, - /** * The distance between the data points is increasing in the data the more distant the prediction is. * Find these gaps and fill them with the previous hours data to make the data returned a complete set. * - * @param data + * @param {object[]} data Response data from the weather service + * @returns {object[]} Given data with filled gaps */ fillInGaps(data) { let result = []; - for (const i = 1; i < data.length; i++) { + for (let i = 1; i < data.length; i++) { let to = moment(data[i].validTime); let from = moment(data[i - 1].validTime); let hours = moment.duration(to.diff(from)).asHours(); // For each hour add a datapoint but change the validTime - for (const j = 0; j < hours; j++) { + for (let j = 0; j < hours; j++) { let current = Object.assign({}, data[i]); current.validTime = from.clone().add(j, "hours").toISOString(); result.push(current); @@ -231,84 +226,81 @@ WeatherProvider.register("smhi", { }, /** - * Helper method to fetch a property from the returned data set. - * The returned values is an array with always one value in it. + * Helper method to get a property from the returned data set. * - * @param currentWeatherData - * @param name - * @param currentWeatherData - * @param name + * @param {object} currentWeatherData Weatherdata to get from + * @param {string} name The name of the property + * @returns {*} The value of the property in the weatherdata */ paramValue(currentWeatherData, name) { - return currentWeatherData.parameters.filter((p) => p.name == name).flatMap((p) => p.values)[0]; + return currentWeatherData.parameters.filter((p) => p.name === name).flatMap((p) => p.values)[0]; }, /** - * Map the icon value from SHMI to an icon that MagicMirror understands. + * Map the icon value from SMHI to an icon that MagicMirror understands. * Uses different icons depending if its daytime or nighttime. - * SHMI's description of what the numeric value means is the comment after the case. + * SMHI's description of what the numeric value means is the comment after the case. * - * @param input - * @param isDayTime - * @param input - * @param isDayTime + * @param {number} input The SMHI icon value + * @param {boolean} isDayTime True if the icon should be for daytime, false for nighttime + * @returns {string} The icon name for the MagicMirror */ convertWeatherType(input, isDayTime) { switch (input) { case 1: return isDayTime ? "day-sunny" : "night-clear"; // Clear sky case 2: - return isDayTime ? "day-sunny-overcast" : "night-partly-cloudy"; //Nearly clear sky + return isDayTime ? "day-sunny-overcast" : "night-partly-cloudy"; // Nearly clear sky case 3: - return isDayTime ? "day-cloudy" : "night-cloudy"; //Variable cloudiness + return isDayTime ? "day-cloudy" : "night-cloudy"; // Variable cloudiness case 4: - return isDayTime ? "day-cloudy" : "night-cloudy"; //Halfclear sky + return isDayTime ? "day-cloudy" : "night-cloudy"; // Halfclear sky case 5: - return "cloudy"; //Cloudy sky + return "cloudy"; // Cloudy sky case 6: - return "cloudy"; //Overcast + return "cloudy"; // Overcast case 7: - return "fog"; //Fog + return "fog"; // Fog case 8: - return "showers"; //Light rain showers + return "showers"; // Light rain showers case 9: - return "showers"; //Moderate rain showers + return "showers"; // Moderate rain showers case 10: - return "showers"; //Heavy rain showers + return "showers"; // Heavy rain showers case 11: - return "thunderstorm"; //Thunderstorm + return "thunderstorm"; // Thunderstorm case 12: - return "sleet"; //Light sleet showers + return "sleet"; // Light sleet showers case 13: - return "sleet"; //Moderate sleet showers + return "sleet"; // Moderate sleet showers case 14: - return "sleet"; //Heavy sleet showers + return "sleet"; // Heavy sleet showers case 15: - return "snow"; //Light snow showers + return "snow"; // Light snow showers case 16: - return "snow"; //Moderate snow showers + return "snow"; // Moderate snow showers case 17: - return "snow"; //Heavy snow showers + return "snow"; // Heavy snow showers case 18: - return "rain"; //Light rain + return "rain"; // Light rain case 19: - return "rain"; //Moderate rain + return "rain"; // Moderate rain case 20: - return "rain"; //Heavy rain + return "rain"; // Heavy rain case 21: - return "thunderstorm"; //Thunder + return "thunderstorm"; // Thunder case 22: return "sleet"; // Light sleet case 23: - return "sleet"; //Moderate sleet + return "sleet"; // Moderate sleet case 24: return "sleet"; // Heavy sleet case 25: return "snow"; // Light snowfall case 26: - return "snow"; //Moderate snowfall + return "snow"; // Moderate snowfall case 27: - return "snow"; //Heavy snowfall + return "snow"; // Heavy snowfall default: return ""; } diff --git a/modules/default/weather/providers/ukmetoffice.js b/modules/default/weather/providers/ukmetoffice.js index 27127806..158592bd 100755 --- a/modules/default/weather/providers/ukmetoffice.js +++ b/modules/default/weather/providers/ukmetoffice.js @@ -1,4 +1,4 @@ -/* global WeatherProvider, WeatherObject, SunCalc */ +/* global WeatherProvider, WeatherObject */ /* Magic Mirror * Module: Weather @@ -116,9 +116,7 @@ WeatherProvider.register("ukmetoffice", { } // determine the sunrise/sunset times - not supplied in UK Met Office data - let times = this.calcAstroData(location); - currentWeather.sunrise = times[0]; - currentWeather.sunset = times[1]; + currentWeather.updateSunTime(location.lat, location.lon); return currentWeather; }, @@ -154,20 +152,6 @@ WeatherProvider.register("ukmetoffice", { return days; }, - /* - * calculate the astronomical data - */ - calcAstroData(location) { - const sunTimes = []; - - // determine the sunrise/sunset times - let times = SunCalc.getTimes(new Date(), location.lat, location.lon); - sunTimes.push(moment(times.sunrise, "X")); - sunTimes.push(moment(times.sunset, "X")); - - return sunTimes; - }, - /* * Convert the Met Office icons to a more usable name. */ @@ -248,16 +232,16 @@ WeatherProvider.register("ukmetoffice", { return windCardinals.hasOwnProperty(windDirection) ? windCardinals[windDirection] : null; }, - /* + /** * Generates an url with api parameters based on the config. * - * return String - URL params. + * @param {string} forecastType daily or 3hourly forecast + * @returns {string} url */ getParams(forecastType) { let params = "?"; 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 d096c33b..bab1220d 100644 --- a/modules/default/weather/providers/ukmetofficedatahub.js +++ b/modules/default/weather/providers/ukmetofficedatahub.js @@ -1,3 +1,5 @@ +/* global WeatherProvider, WeatherObject */ + /* Magic Mirror * Module: Weather * @@ -11,9 +13,8 @@ * Hourly data for next 2 days ("hourly") - https://www.metoffice.gov.uk/binaries/content/assets/metofficegovuk/pdf/data/global-spot-data-hourly.pdf * 3-hourly data for the next 7 days ("3hourly") - https://www.metoffice.gov.uk/binaries/content/assets/metofficegovuk/pdf/data/global-spot-data-3-hourly.pdf * Daily data for the next 7 days ("daily") - https://www.metoffice.gov.uk/binaries/content/assets/metofficegovuk/pdf/data/global-spot-data-daily.pdf - */ - -/* NOTES + * + * NOTES * This provider requires longitude/latitude coordinates, rather than a location ID (as with the previous Met Office provider) * Provide the following in your config.js file: * weatherProvider: "ukmetofficedatahub", @@ -69,13 +70,11 @@ WeatherProvider.register("ukmetofficedatahub", { // For DataHub requests, the API key/secret are sent in the headers rather than as query strings. // Headers defined according to Data Hub API (https://metoffice.apiconnect.ibmcloud.com/metoffice/production/api) getHeaders() { - let headers = { + return { accept: "application/json", "x-ibm-client-id": this.config.apiKey, "x-ibm-client-secret": this.config.apiSecret }; - - return headers; }, // Fetch data using supplied URL and request headers @@ -91,7 +90,7 @@ WeatherProvider.register("ukmetofficedatahub", { this.fetchWeather(this.getUrl("hourly"), this.getHeaders()) .then((data) => { // Check data is useable - if (!data || !data.features || !data.features[0].properties || !data.features[0].properties.timeSeries || data.features[0].properties.timeSeries.length == 0) { + if (!data || !data.features || !data.features[0].properties || !data.features[0].properties.timeSeries || data.features[0].properties.timeSeries.length === 0) { // Did not receive usable new data. // Maybe this needs a better check? Log.error("Possibly bad current/hourly data?"); @@ -125,7 +124,7 @@ WeatherProvider.register("ukmetofficedatahub", { let nowUtc = moment.utc(); // Find hour that contains the current time - for (hour in forecastDataHours) { + for (let hour in forecastDataHours) { let forecastTime = moment.utc(forecastDataHours[hour].time); if (nowUtc.isSameOrAfter(forecastTime) && nowUtc.isBefore(moment(forecastTime.add(1, "h")))) { currentWeather.date = forecastTime; @@ -148,11 +147,9 @@ WeatherProvider.register("ukmetofficedatahub", { } // Determine the sunrise/sunset times - (still) not supplied in UK Met Office data - // Passes {longitude, latitude, height} to calcAstroData - // Could just pass lat/long from this.config, but returned data from MO also contains elevation - let times = this.calcAstroData(currentWeatherData.features[0].geometry.coordinates); - currentWeather.sunrise = times[0]; - currentWeather.sunset = times[1]; + // Passes {longitude, latitude} to SunCalc, could pass height to, but + // SunCalc.getTimes doesnt take that into account + currentWeather.updateSunTime(this.config.lat, this.config.lon); return currentWeather; }, @@ -162,7 +159,7 @@ WeatherProvider.register("ukmetofficedatahub", { this.fetchWeather(this.getUrl("daily"), this.getHeaders()) .then((data) => { // Check data is useable - if (!data || !data.features || !data.features[0].properties || !data.features[0].properties.timeSeries || data.features[0].properties.timeSeries.length == 0) { + if (!data || !data.features || !data.features[0].properties || !data.features[0].properties.timeSeries || data.features[0].properties.timeSeries.length === 0) { // Did not receive usable new data. // Maybe this needs a better check? Log.error("Possibly bad forecast data?"); @@ -196,7 +193,7 @@ WeatherProvider.register("ukmetofficedatahub", { let today = moment.utc().startOf("date"); // Go through each day in the forecasts - for (day in forecastDataDays) { + for (let day in forecastDataDays) { const forecastWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); // Get date of forecast @@ -221,7 +218,6 @@ WeatherProvider.register("ukmetofficedatahub", { // Pass on full details so they can be used in custom templates // Note the units of the supplied data when using this (see top of file) - forecastWeather.rawData = forecastDataDays[day]; dailyForecasts.push(forecastWeather); @@ -236,18 +232,6 @@ WeatherProvider.register("ukmetofficedatahub", { this.fetchedLocationName = name; }, - // Calculate sunrise/sunset times - calcAstroData(location) { - const sunTimes = []; - - // Careful to pass values to SunCalc in correct order (latitude, longitude, elevation) - let times = SunCalc.getTimes(new Date(), location[1], location[0], location[2]); - sunTimes.push(moment(times.sunrise, "X")); - sunTimes.push(moment(times.sunset, "X")); - - return sunTimes; - }, - // Convert temperatures to Fahrenheit (from degrees C), if required convertTemp(tempInC) { return this.config.tempUnits === "imperial" ? (tempInC * 9) / 5 + 32 : tempInC; @@ -258,11 +242,11 @@ WeatherProvider.register("ukmetofficedatahub", { // To use kilometres per hour, use "kph" // Else assumed imperial and the value is returned in miles per hour (a Met Office user is likely to be UK-based) convertWindSpeed(windInMpS) { - if (this.config.windUnits == "mps") { + if (this.config.windUnits === "mps") { return windInMpS; } - if (this.config.windUnits == "kph" || this.config.windUnits == "metric" || this.config.useKmh) { + if (this.config.windUnits === "kph" || this.config.windUnits === "metric" || this.config.useKmh) { return windInMpS * 3.6; } diff --git a/modules/default/weather/providers/weatherbit.js b/modules/default/weather/providers/weatherbit.js index afca0c83..17f27812 100644 --- a/modules/default/weather/providers/weatherbit.js +++ b/modules/default/weather/providers/weatherbit.js @@ -7,7 +7,8 @@ * By Andrew Pometti * MIT Licensed * - * This class is a provider for Weatherbit, based on Nicholas Hubbard's class for Dark Sky & Vince Peri's class for Weather.gov. + * This class is a provider for Weatherbit, based on Nicholas Hubbard's class + * for Dark Sky & Vince Peri's class for Weather.gov. */ WeatherProvider.register("weatherbit", { // Set the name of the provider. @@ -89,7 +90,6 @@ WeatherProvider.register("weatherbit", { currentWeather.windSpeed = parseFloat(currentWeatherData.data[0].wind_spd); currentWeather.windDirection = currentWeatherData.data[0].wind_dir; currentWeather.weatherType = this.convertWeatherType(currentWeatherData.data[0].weather.icon); - Log.log("Wx Icon: " + 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"); diff --git a/modules/default/weather/providers/weathergov.js b/modules/default/weather/providers/weathergov.js index ee418edc..31934784 100755 --- a/modules/default/weather/providers/weathergov.js +++ b/modules/default/weather/providers/weathergov.js @@ -1,4 +1,4 @@ -/* global WeatherProvider, WeatherObject, SunCalc */ +/* global WeatherProvider, WeatherObject */ /* Magic Mirror * Module: Weather @@ -21,7 +21,7 @@ WeatherProvider.register("weathergov", { // Set the default config properties that is specific to this provider defaults: { - apiBase: "https://api.weatherbit.io/v2.0", + apiBase: "https://api.weather.gov/points/", weatherEndpoint: "/forecast", lat: 0, lon: 0 @@ -129,7 +129,12 @@ WeatherProvider.register("weathergov", { .finally(() => { // excellent, let's fetch some actual wx data this.configURLs = true; - this.fetchCurrentWeather(); + // handle 'forecast' config, fall back to 'current' + if (config.type === "forecast") { + this.fetchWeatherForecast(); + } else { + this.fetchCurrentWeather(); + } }); }, @@ -153,18 +158,11 @@ WeatherProvider.register("weathergov", { currentWeather.precipitation = this.convertLength(currentWeatherData.precipitationLastHour.value); currentWeather.feelsLikeTemp = this.convertTemp(currentWeatherData.heatIndex.value); - let isDaytime = true; - if (currentWeatherData.icon.includes("day")) { - isDaytime = true; - } else { - isDaytime = false; - } - currentWeather.weatherType = this.convertWeatherType(currentWeatherData.textDescription, isDaytime); - // determine the sunrise/sunset times - not supplied in weather.gov data - let times = this.calcAstroData(this.config.lat, this.config.lon); - currentWeather.sunrise = times[0]; - currentWeather.sunset = times[1]; + currentWeather.updateSunTime(this.config.lat, this.config.lon); + + // update weatherType + currentWeather.weatherType = this.convertWeatherType(currentWeatherData.textDescription, currentWeather.isDayTime()); return currentWeather; }, @@ -267,20 +265,6 @@ WeatherProvider.register("weathergov", { } }, - /* - * Calculate the astronomical data - */ - calcAstroData(lat, lon) { - const sunTimes = []; - - // determine the sunrise/sunset times - let times = SunCalc.getTimes(new Date(), lat, lon); - sunTimes.push(moment(times.sunrise, "X")); - sunTimes.push(moment(times.sunset, "X")); - - return sunTimes; - }, - /* * Convert the icons to a more usable name. */ diff --git a/modules/default/weather/weather.js b/modules/default/weather/weather.js index 3386277c..62182211 100644 --- a/modules/default/weather/weather.js +++ b/modules/default/weather/weather.js @@ -132,10 +132,6 @@ Module.register("weather", { getTemplateData: function () { const forecast = this.weatherProvider.weatherForecast(); - if (this.config.ignoreToday) { - forecast.splice(0, 1); - } - return { config: this.config, current: this.weatherProvider.currentWeather(), diff --git a/modules/default/weather/weatherobject.js b/modules/default/weather/weatherobject.js index 5bd5be9a..4501f681 100755 --- a/modules/default/weather/weatherobject.js +++ b/modules/default/weather/weatherobject.js @@ -1,3 +1,5 @@ +/* global SunCalc */ + /* Magic Mirror * Module: Weather * @@ -10,6 +12,14 @@ * As soon as we start implementing the forecast, mode properties will be added. */ class WeatherObject { + /** + * Constructor for a WeatherObject + * + * @param {string} units what units to use, "imperial" or "metric" + * @param {string} tempUnits what tempunits to use + * @param {string} windUnits what windunits to use + * @param {boolean} useKmh use kmh if true, mps if false + */ constructor(units, tempUnits, windUnits, useKmh) { this.units = units; this.tempUnits = tempUnits; @@ -80,8 +90,7 @@ class WeatherObject { } kmhWindSpeed() { - const windInKmh = this.windUnits === "imperial" ? this.windSpeed * 1.609344 : (this.windSpeed * 60 * 60) / 1000; - return windInKmh; + return this.windUnits === "imperial" ? this.windSpeed * 1.609344 : (this.windSpeed * 60 * 60) / 1000; } nextSunAction() { @@ -113,4 +122,33 @@ class WeatherObject { return this.tempUnits === "imperial" ? feelsLike : ((feelsLike - 32) * 5) / 9; } + + /** + * Checks if the weatherObject is at dayTime. + * + * @returns {boolean} true if it is at dayTime + */ + isDayTime() { + return this.date.isBetween(this.sunrise, this.sunset, undefined, "[]"); + } + + /** + * Update the sunrise / sunset time depending on the location. This can be + * used if your provider doesnt provide that data by itself. Then SunCalc + * is used here to calculate them according to the location. + * + * @param {number} lat latitude + * @param {number} lon longitude + */ + updateSunTime(lat, lon) { + let now = !this.date ? new Date() : this.date.toDate(); + let times = SunCalc.getTimes(now, lat, lon); + this.sunrise = moment(times.sunrise, "X"); + this.sunset = moment(times.sunset, "X"); + } +} + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = WeatherObject; } diff --git a/modules/default/weatherforecast/weatherforecast.js b/modules/default/weatherforecast/weatherforecast.js index 50229262..50c1f3a7 100644 --- a/modules/default/weatherforecast/weatherforecast.js +++ b/modules/default/weatherforecast/weatherforecast.js @@ -1,3 +1,5 @@ +/* eslint-disable */ + /* Magic Mirror * Module: WeatherForecast * diff --git a/package-lock.json b/package-lock.json index c5e03f6b..c42d4b2d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,19 +1,19 @@ { "name": "magicmirror", - "version": "2.16.0", + "version": "2.17.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "magicmirror", - "version": "2.16.0", + "version": "2.17.0", "hasInstallScript": true, "license": "MIT", "dependencies": { "colors": "^1.4.0", - "console-stamp": "^3.0.2", - "digest-fetch": "^1.2.0", - "eslint": "^7.29.0", + "console-stamp": "^3.0.3", + "digest-fetch": "^1.2.1", + "eslint": "^7.32.0", "express": "^4.17.1", "express-ipfilter": "^1.2.0", "feedme": "^2.0.2", @@ -21,36 +21,36 @@ "iconv-lite": "^0.6.3", "module-alias": "^2.2.2", "moment": "^2.29.1", - "node-fetch": "^2.6.1", + "node-fetch": "^2.6.5", "node-ical": "^0.13.0", - "simple-git": "^2.40.0", - "socket.io": "^4.1.2" + "socket.io": "^4.2.0" }, "devDependencies": { "eslint-config-prettier": "^8.3.0", - "eslint-plugin-jest": "^24.3.6", - "eslint-plugin-jsdoc": "^35.4.0", - "eslint-plugin-prettier": "^3.4.0", + "eslint-plugin-jest": "^24.4.2", + "eslint-plugin-jsdoc": "^36.1.0", + "eslint-plugin-prettier": "^4.0.0", "express-basic-auth": "^1.2.0", - "husky": "^6.0.0", - "jest": "27.0.5", - "jsdom": "^16.6.0", + "husky": "^7.0.2", + "jest": "^27.2.2", + "jsdom": "^17.0.0", "lodash": "^4.17.21", "nyc": "^15.1.0", - "prettier": "^2.3.1", + "prettier": "^2.4.1", "pretty-quick": "^3.1.1", - "sinon": "^11.1.1", - "spectron": "^13.0.0", + "sinon": "^11.1.2", + "spectron": "^15.0.0", "stylelint": "^13.13.1", "stylelint-config-prettier": "^8.0.2", "stylelint-config-standard": "^22.0.0", - "stylelint-prettier": "^1.2.0" + "stylelint-prettier": "^1.2.0", + "suncalc": "^1.8.0" }, "engines": { "node": ">=12" }, "optionalDependencies": { - "electron": "^11.4.9" + "electron": "^13.5.0" } }, "node_modules/@babel/code-frame": { @@ -693,24 +693,33 @@ "global-tunnel-ng": "^2.7.1" } }, + "node_modules/@electron/remote": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@electron/remote/-/remote-1.2.0.tgz", + "integrity": "sha512-C774t2DFVJsa+dxU9Gc2nYzylRZoJ79I0Sxrh8T9cN69fBkntfGbyBEQiD9UfZopqL0CYLzk1anY2Ywhql6h1w==", + "dev": true, + "peerDependencies": { + "electron": ">= 10.0.0-beta.1" + } + }, "node_modules/@es-joy/jsdoccomment": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.8.0.tgz", - "integrity": "sha512-Xd3GzYsL2sz2pcdtYt5Q0Wz1ol/o9Nt2UQL4nFPDcaEomvPmwjJsbjkKx1SKhl2h3TgwazNBLdcNr2m0UiGiFA==", + "version": "0.10.8", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.10.8.tgz", + "integrity": "sha512-3P1JiGL4xaR9PoTKUHa2N/LKwa2/eUdRqGwijMWWgBqbFEqJUVpmaOi2TcjcemrsRMgFLBzQCK4ToPhrSVDiFQ==", "dev": true, "dependencies": { - "comment-parser": "^1.1.5", + "comment-parser": "1.2.4", "esquery": "^1.4.0", - "jsdoc-type-pratt-parser": "1.0.4" + "jsdoc-type-pratt-parser": "1.1.1" }, "engines": { - "node": ">=10.0.0" + "node": "^12 || ^14 || ^16" } }, "node_modules/@eslint/eslintrc": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", - "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dependencies": { "ajv": "^6.12.4", "debug": "^4.1.1", @@ -726,6 +735,24 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==" + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -761,16 +788,16 @@ } }, "node_modules/@jest/console": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.0.2.tgz", - "integrity": "sha512-/zYigssuHLImGeMAACkjI4VLAiiJznHgAl3xnFT19iWyct2LhrH3KXOjHRmxBGTkiPLZKKAJAgaPpiU9EZ9K+w==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.2.2.tgz", + "integrity": "sha512-m7tbzPWyvSFfoanTknJoDnaeruDARsUe555tkVjG/qeaRDKwyPqqbgs4yFx583gmoETiAts1deeYozR5sVRhNA==", "dev": true, "dependencies": { - "@jest/types": "^27.0.2", + "@jest/types": "^27.1.1", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^27.0.2", - "jest-util": "^27.0.2", + "jest-message-util": "^27.2.2", + "jest-util": "^27.2.0", "slash": "^3.0.0" }, "engines": { @@ -778,35 +805,35 @@ } }, "node_modules/@jest/core": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.0.5.tgz", - "integrity": "sha512-g73//jF0VwsOIrWUC9Cqg03lU3QoAMFxVjsm6n6yNmwZcQPN/o8w+gLWODw5VfKNFZT38otXHWxc6b8eGDUpEA==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.2.2.tgz", + "integrity": "sha512-4b9km/h9pAGdCkwWYtbfoeiOtajOlGmr5rL1Eq6JCAVbOevOqxWHxJ6daWxRJW9eF6keXJoJ1H+uVAVcdZu8Bg==", "dev": true, "dependencies": { - "@jest/console": "^27.0.2", - "@jest/reporters": "^27.0.5", - "@jest/test-result": "^27.0.2", - "@jest/transform": "^27.0.5", - "@jest/types": "^27.0.2", + "@jest/console": "^27.2.2", + "@jest/reporters": "^27.2.2", + "@jest/test-result": "^27.2.2", + "@jest/transform": "^27.2.2", + "@jest/types": "^27.1.1", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.8.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-changed-files": "^27.0.2", - "jest-config": "^27.0.5", - "jest-haste-map": "^27.0.5", - "jest-message-util": "^27.0.2", - "jest-regex-util": "^27.0.1", - "jest-resolve": "^27.0.5", - "jest-resolve-dependencies": "^27.0.5", - "jest-runner": "^27.0.5", - "jest-runtime": "^27.0.5", - "jest-snapshot": "^27.0.5", - "jest-util": "^27.0.2", - "jest-validate": "^27.0.2", - "jest-watcher": "^27.0.2", + "jest-changed-files": "^27.1.1", + "jest-config": "^27.2.2", + "jest-haste-map": "^27.2.2", + "jest-message-util": "^27.2.2", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.2.2", + "jest-resolve-dependencies": "^27.2.2", + "jest-runner": "^27.2.2", + "jest-runtime": "^27.2.2", + "jest-snapshot": "^27.2.2", + "jest-util": "^27.2.0", + "jest-validate": "^27.2.2", + "jest-watcher": "^27.2.2", "micromatch": "^4.0.4", "p-each-series": "^2.1.0", "rimraf": "^3.0.0", @@ -826,62 +853,62 @@ } }, "node_modules/@jest/environment": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.0.5.tgz", - "integrity": "sha512-IAkJPOT7bqn0GiX5LPio6/e1YpcmLbrd8O5EFYpAOZ6V+9xJDsXjdgN2vgv9WOKIs/uA1kf5WeD96HhlBYO+FA==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.2.2.tgz", + "integrity": "sha512-gO9gVnZfn5ldeOJ5q+35Kru9QWGHEqZCB7W/M+8mD6uCwOGC9HR6mzpLSNRuDsxY/KhaGBYHpgFqtpe4Rl1gDQ==", "dev": true, "dependencies": { - "@jest/fake-timers": "^27.0.5", - "@jest/types": "^27.0.2", + "@jest/fake-timers": "^27.2.2", + "@jest/types": "^27.1.1", "@types/node": "*", - "jest-mock": "^27.0.3" + "jest-mock": "^27.1.1" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.0.5.tgz", - "integrity": "sha512-d6Tyf7iDoKqeUdwUKrOBV/GvEZRF67m7lpuWI0+SCD9D3aaejiOQZxAOxwH2EH/W18gnfYaBPLi0VeTGBHtQBg==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.2.2.tgz", + "integrity": "sha512-gDIIqs0yxyjyxEI9HlJ8SEJ4uCc8qr8BupG1Hcx7tvyk/SLocyXE63rFxL+HQ0ZLMvSyEcJUmYnvvHH1osWiGA==", "dev": true, "dependencies": { - "@jest/types": "^27.0.2", + "@jest/types": "^27.1.1", "@sinonjs/fake-timers": "^7.0.2", "@types/node": "*", - "jest-message-util": "^27.0.2", - "jest-mock": "^27.0.3", - "jest-util": "^27.0.2" + "jest-message-util": "^27.2.2", + "jest-mock": "^27.1.1", + "jest-util": "^27.2.0" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/globals": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.0.5.tgz", - "integrity": "sha512-qqKyjDXUaZwDuccpbMMKCCMBftvrbXzigtIsikAH/9ca+kaae8InP2MDf+Y/PdCSMuAsSpHS6q6M25irBBUh+Q==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.2.2.tgz", + "integrity": "sha512-fWa/Luwod1hyehnuep+zCnOTqTVvyc4HLUU/1VpFNOEu0tCWNSODyvKSSOjtb1bGOpCNjgaDcyjzo5f7rl6a7g==", "dev": true, "dependencies": { - "@jest/environment": "^27.0.5", - "@jest/types": "^27.0.2", - "expect": "^27.0.2" + "@jest/environment": "^27.2.2", + "@jest/types": "^27.1.1", + "expect": "^27.2.2" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/reporters": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.0.5.tgz", - "integrity": "sha512-4uNg5+0eIfRafnpgu3jCZws3NNcFzhu5JdRd1mKQ4/53+vkIqwB6vfZ4gn5BdGqOaLtYhlOsPaL5ATkKzyBrJw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.2.2.tgz", + "integrity": "sha512-ufwZ8XoLChEfPffDeVGroYbhbcYPom3zKDiv4Flhe97rr/o2IfUXoWkDUDoyJ3/V36RFIMjokSu0IJ/pbFtbHg==", "dev": true, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.0.2", - "@jest/test-result": "^27.0.2", - "@jest/transform": "^27.0.5", - "@jest/types": "^27.0.2", + "@jest/console": "^27.2.2", + "@jest/test-result": "^27.2.2", + "@jest/transform": "^27.2.2", + "@jest/types": "^27.1.1", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", @@ -892,10 +919,10 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.0.2", - "jest-haste-map": "^27.0.5", - "jest-resolve": "^27.0.5", - "jest-util": "^27.0.2", - "jest-worker": "^27.0.2", + "jest-haste-map": "^27.2.2", + "jest-resolve": "^27.2.2", + "jest-util": "^27.2.0", + "jest-worker": "^27.2.2", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", @@ -915,9 +942,9 @@ } }, "node_modules/@jest/source-map": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.1.tgz", - "integrity": "sha512-yMgkF0f+6WJtDMdDYNavmqvbHtiSpwRN2U/W+6uztgfqgkq/PXdKPqjBTUF1RD/feth4rH5N3NW0T5+wIuln1A==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.6.tgz", + "integrity": "sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g==", "dev": true, "dependencies": { "callsites": "^3.0.0", @@ -929,13 +956,13 @@ } }, "node_modules/@jest/test-result": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.0.2.tgz", - "integrity": "sha512-gcdWwL3yP5VaIadzwQtbZyZMgpmes8ryBAJp70tuxghiA8qL4imJyZex+i+USQH2H4jeLVVszhwntgdQ97fccA==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.2.2.tgz", + "integrity": "sha512-yENoDEoWlEFI7l5z7UYyJb/y5Q8RqbPd4neAVhKr6l+vVaQOPKf8V/IseSMJI9+urDUIxgssA7RGNyCRhGjZvw==", "dev": true, "dependencies": { - "@jest/console": "^27.0.2", - "@jest/types": "^27.0.2", + "@jest/console": "^27.2.2", + "@jest/types": "^27.1.1", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -944,36 +971,36 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.0.5.tgz", - "integrity": "sha512-opztnGs+cXzZ5txFG2+omBaV5ge/0yuJNKbhE3DREMiXE0YxBuzyEa6pNv3kk2JuucIlH2Xvgmn9kEEHSNt/SA==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.2.2.tgz", + "integrity": "sha512-YnJqwNQP2Zeu0S4TMqkxg6NN7Y1EFq715n/nThNKrvIS9wmRZjDt2XYqsHbuvhAFjshi0iKDQ813NewFITBH+Q==", "dev": true, "dependencies": { - "@jest/test-result": "^27.0.2", + "@jest/test-result": "^27.2.2", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.0.5", - "jest-runtime": "^27.0.5" + "jest-haste-map": "^27.2.2", + "jest-runtime": "^27.2.2" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/transform": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.0.5.tgz", - "integrity": "sha512-lBD6OwKXSc6JJECBNk4mVxtSVuJSBsQrJ9WCBisfJs7EZuYq4K6vM9HmoB7hmPiLIDGeyaerw3feBV/bC4z8tg==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.2.2.tgz", + "integrity": "sha512-l4Z/7PpajrOjCiXLWLfMY7fgljY0H8EwW7qdzPXXuv2aQF8kY2+Uyj3O+9Popnaw1V7JCw32L8EeI/thqFDkPA==", "dev": true, "dependencies": { "@babel/core": "^7.1.0", - "@jest/types": "^27.0.2", + "@jest/types": "^27.1.1", "babel-plugin-istanbul": "^6.0.0", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.0.5", - "jest-regex-util": "^27.0.1", - "jest-util": "^27.0.2", + "jest-haste-map": "^27.2.2", + "jest-regex-util": "^27.0.6", + "jest-util": "^27.2.0", "micromatch": "^4.0.4", "pirates": "^4.0.1", "slash": "^3.0.0", @@ -985,9 +1012,9 @@ } }, "node_modules/@jest/types": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz", - "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==", + "version": "27.1.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.1.1.tgz", + "integrity": "sha512-yqJPDDseb0mXgKqmNqypCsb85C22K1aY5+LUxh7syIM9n/b0AsaltxNy+o6tt29VcfGDpYEve175bm3uOhcehA==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -1000,19 +1027,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@kwsites/file-exists": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", - "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", - "dependencies": { - "debug": "^4.1.1" - } - }, - "node_modules/@kwsites/promise-deferred": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", - "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==" - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1141,9 +1155,9 @@ } }, "node_modules/@types/babel__core": { - "version": "7.1.14", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.14.tgz", - "integrity": "sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g==", + "version": "7.1.16", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.16.tgz", + "integrity": "sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ==", "dev": true, "dependencies": { "@babel/parser": "^7.1.0", @@ -1154,18 +1168,18 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", - "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", + "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", "dev": true, "dependencies": { "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__template": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz", - "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", "dev": true, "dependencies": { "@babel/parser": "^7.1.0", @@ -1173,9 +1187,9 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.1.tgz", - "integrity": "sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", + "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", "dev": true, "dependencies": { "@babel/types": "^7.3.0" @@ -1199,14 +1213,14 @@ "integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg==" }, "node_modules/@types/cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg==" + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" }, "node_modules/@types/cors": { - "version": "2.8.10", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.10.tgz", - "integrity": "sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ==" + "version": "2.8.12", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", + "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" }, "node_modules/@types/graceful-fs": { "version": "4.1.5", @@ -1284,9 +1298,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "12.20.15", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.15.tgz", - "integrity": "sha512-F6S4Chv4JicJmyrwlDkxUdGNSplsQdGwp1A0AJloEVDirWdZOAiRHhovDlsFkKUrquUXhz1imJhXHsf59auyAg==" + "version": "14.17.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.4.tgz", + "integrity": "sha512-8kQ3+wKGRNN0ghtEn7EGps/B8CzuBz1nXZEIGGLP2GnwbqYn4dbTs7k+VKLTq1HvZLRCIDtN3Snx1Ege8B7L5A==" }, "node_modules/@types/normalize-package-data": { "version": "2.4.0", @@ -1301,9 +1315,9 @@ "dev": true }, "node_modules/@types/prettier": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.3.0.tgz", - "integrity": "sha512-hkc1DATxFLQo4VxPDpMH1gCkPpBbpOoJ/4nhuXw4n63/0R6bCpQECj4+K226UJ4JO/eJQz+1mC2I7JsWanAdQw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-Fo79ojj3vdEZOHg3wR9ksAMRz4P3S5fDB5e/YWZiFnyFQI1WY2Vftu9XoXVVtJfxB7Bpce/QTqWSSntkz2Znrw==", "dev": true }, "node_modules/@types/puppeteer": { @@ -1334,15 +1348,15 @@ } }, "node_modules/@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, "node_modules/@types/unist": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", - "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.4.tgz", + "integrity": "sha512-zfyYsDTK1HTGYXU3fTiM76+om93HcFtsZd2M0bO/CL4DiETV7mSa/pIVN/6+G3esOqEMdg2An5cHHbK5t+9w+A==", "dev": true }, "node_modules/@types/which": { @@ -1352,24 +1366,24 @@ "dev": true }, "node_modules/@types/yargs": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz", - "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==", + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", "dev": true, "dependencies": { "@types/yargs-parser": "*" } }, "node_modules/@types/yargs-parser": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", - "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==", + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", "dev": true }, "node_modules/@types/yauzl": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz", - "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", + "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", "dev": true, "optional": true, "dependencies": { @@ -1377,15 +1391,15 @@ } }, "node_modules/@typescript-eslint/experimental-utils": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.0.tgz", - "integrity": "sha512-9XD9s7mt3QWMk82GoyUpc/Ji03vz4T5AYlHF9DcoFNfJ/y3UAclRsfGiE2gLfXtyC+JRA3trR7cR296TEb1oiQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.1.tgz", + "integrity": "sha512-n8/ggadrZ+uyrfrSEchx3jgODdmcx7MzVM2sI3cTpI/YlfSm0+9HEUaWw3aQn2urL2KYlWYMDgn45iLfjDYB+Q==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.28.0", - "@typescript-eslint/types": "4.28.0", - "@typescript-eslint/typescript-estree": "4.28.0", + "@typescript-eslint/scope-manager": "4.28.1", + "@typescript-eslint/types": "4.28.1", + "@typescript-eslint/typescript-estree": "4.28.1", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, @@ -1419,13 +1433,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.0.tgz", - "integrity": "sha512-eCALCeScs5P/EYjwo6se9bdjtrh8ByWjtHzOkC4Tia6QQWtQr3PHovxh3TdYTuFcurkYI4rmFsRFpucADIkseg==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.1.tgz", + "integrity": "sha512-o95bvGKfss6705x7jFGDyS7trAORTy57lwJ+VsYwil/lOUxKQ9tA7Suuq+ciMhJc/1qPwB3XE2DKh9wubW8YYA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.28.0", - "@typescript-eslint/visitor-keys": "4.28.0" + "@typescript-eslint/types": "4.28.1", + "@typescript-eslint/visitor-keys": "4.28.1" }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" @@ -1436,9 +1450,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.0.tgz", - "integrity": "sha512-p16xMNKKoiJCVZY5PW/AfILw2xe1LfruTcfAKBj3a+wgNYP5I9ZEKNDOItoRt53p4EiPV6iRSICy8EPanG9ZVA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.1.tgz", + "integrity": "sha512-4z+knEihcyX7blAGi7O3Fm3O6YRCP+r56NJFMNGsmtdw+NCdpG5SgNz427LS9nQkRVTswZLhz484hakQwB8RRg==", "dev": true, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" @@ -1449,13 +1463,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.0.tgz", - "integrity": "sha512-m19UQTRtxMzKAm8QxfKpvh6OwQSXaW1CdZPoCaQuLwAq7VZMNuhJmZR4g5281s2ECt658sldnJfdpSZZaxUGMQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.1.tgz", + "integrity": "sha512-GhKxmC4sHXxHGJv8e8egAZeTZ6HI4mLU6S7FUzvFOtsk7ZIDN1ksA9r9DyOgNqowA9yAtZXV0Uiap61bIO81FQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.28.0", - "@typescript-eslint/visitor-keys": "4.28.0", + "@typescript-eslint/types": "4.28.1", + "@typescript-eslint/visitor-keys": "4.28.1", "debug": "^4.3.1", "globby": "^11.0.3", "is-glob": "^4.0.1", @@ -1491,12 +1505,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.0.tgz", - "integrity": "sha512-PjJyTWwrlrvM5jazxYF5ZPs/nl0kHDZMVbuIcbpawVXaDPelp3+S9zpOz5RmVUfS/fD5l5+ZXNKnWhNYjPzCvw==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.1.tgz", + "integrity": "sha512-K4HMrdFqr9PFquPu178SaSb92CaWe2yErXyPumc8cYWxFmhgJsNY9eSePmO05j0JhBvf2Cdhptd6E6Yv9HVHcg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.28.0", + "@typescript-eslint/types": "4.28.1", "eslint-visitor-keys": "^2.0.0" }, "engines": { @@ -1609,9 +1623,9 @@ } }, "node_modules/acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -1701,9 +1715,9 @@ } }, "node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "engines": { "node": ">=8" } @@ -1814,11 +1828,6 @@ "sprintf-js": "~1.0.2" } }, - "node_modules/argparse/node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, "node_modules/array-differ": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", @@ -1851,24 +1860,6 @@ "node": ">=8" } }, - "node_modules/asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -1932,32 +1923,17 @@ "url": "https://tidelift.com/funding/github/npm/autoprefixer" } }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true - }, "node_modules/babel-jest": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.0.5.tgz", - "integrity": "sha512-bTMAbpCX7ldtfbca2llYLeSFsDM257aspyAOpsdrdSrBqoLkWCy4HPYTXtXWaSLgFPjrJGACL65rzzr4RFGadw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.2.2.tgz", + "integrity": "sha512-XNFNNfGKnZXzhej7TleVP4s9ktH5JjRW8Rmcbb223JJwKB/gmTyeWN0JfiPtSgnjIjDXtKNoixiy0QUHtv3vFA==", "dev": true, "dependencies": { - "@jest/transform": "^27.0.5", - "@jest/types": "^27.0.2", + "@jest/transform": "^27.2.2", + "@jest/types": "^27.1.1", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^27.0.1", + "babel-preset-jest": "^27.2.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "slash": "^3.0.0" @@ -1986,9 +1962,9 @@ } }, "node_modules/babel-plugin-jest-hoist": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.0.1.tgz", - "integrity": "sha512-sqBF0owAcCDBVEDtxqfYr2F36eSHdx7lAVGyYuOBRnKdD6gzcy0I0XrAYCZgOA3CRrLhmR+Uae9nogPzmAtOfQ==", + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.2.0.tgz", + "integrity": "sha512-TOux9khNKdi64mW+0OIhcmbAn75tTlzKhxmiNXevQaPbrBYK7YKjP1jl6NHTJ6XR5UgUrJbCnWlKVnJn29dfjw==", "dev": true, "dependencies": { "@babel/template": "^7.3.3", @@ -2024,12 +2000,12 @@ } }, "node_modules/babel-preset-jest": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.0.1.tgz", - "integrity": "sha512-nIBIqCEpuiyhvjQs2mVNwTxQQa2xk70p9Dd/0obQGBf8FBzbnI8QhQKzLsWMN2i6q+5B0OcWDtrboBX5gmOLyA==", + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.2.0.tgz", + "integrity": "sha512-z7MgQ3peBwN5L5aCqBKnF6iqdlvZvFUQynEhu0J+X9nHLU72jO3iY331lcYrg+AssJ8q7xsv5/3AICzVmJ/wvg==", "dev": true, "dependencies": { - "babel-plugin-jest-hoist": "^27.0.1", + "babel-plugin-jest-hoist": "^27.2.0", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { @@ -2107,15 +2083,6 @@ "node": ">= 0.8" } }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -2397,31 +2364,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/camelcase-keys/node_modules/quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/caniuse-lite": { - "version": "1.0.30001239", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001239.tgz", - "integrity": "sha512-cyBkXJDMeI4wthy8xJ2FvDU6+0dtcZSJW3voUF8+e9f1bBeuvyZfc3PNbkOETyhbR+dGCPzn9E7MA3iwzusOhQ==", + "version": "1.0.30001242", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001242.tgz", + "integrity": "sha512-KvNuZ/duufelMB3w2xtf9gEWCSxJwUgoxOx5b6ScLXC4kPc9xsczUVCPrQU26j5kOsHM4pSUL54tAZt5THQKug==", "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/browserslist" } }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, "node_modules/chalk": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", @@ -2520,9 +2472,9 @@ "dev": true }, "node_modules/cjs-module-lexer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.1.tgz", - "integrity": "sha512-jVamGdJPDeuQilKhvVn1h3knuMOZzr8QDnpk+M9aMlCaMkTDd6fBWPhiDqFvFZ07pL0liqabAiuy8SY4jGHeaw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, "node_modules/clarinet": { @@ -2635,12 +2587,12 @@ } }, "node_modules/comment-parser": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.1.5.tgz", - "integrity": "sha512-RePCE4leIhBlmrqiYTvaqEeGYg7qpSl4etaIabKtdOQVi+mSTIBBklGUwIr79GXYnl3LpMwmDw4KeR2stNc6FA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.2.4.tgz", + "integrity": "sha512-pm0b+qv+CkWNriSTMsfnjChF9kH0kxz55y44Wo5le9qLxMj5xDQAaEd9ZN1ovSuk9CsrncWaFwgpOMg7ClJwkw==", "dev": true, "engines": { - "node": ">= 10.0.0" + "node": ">= 12.0.0" } }, "node_modules/commondir": { @@ -2692,10 +2644,10 @@ "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "devOptional": true, "engines": [ "node >= 0.8" ], - "optional": true, "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", @@ -2714,11 +2666,11 @@ } }, "node_modules/console-stamp": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/console-stamp/-/console-stamp-3.0.2.tgz", - "integrity": "sha512-nYIxVrp1Cau8wRy8RQJO1VNBTYQPnFcN7SrsLAStSavo38Y4+jcysh5n4nZNd/WkR2IOULgwr2+6qDxMUA7Hog==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/console-stamp/-/console-stamp-3.0.3.tgz", + "integrity": "sha512-6ltMcMEVDHb1bqb+qaVfCX7Vf3vEkfZEeKyReG1ny45Rv6YJynCcdv94j7whNVfxj/4/3Ji/QBHY6p4JI51Ucw==", "dependencies": { - "chalk": "^4.1.0", + "chalk": "^4.1.1", "dateformat": "^4.5.1" }, "engines": { @@ -2767,9 +2719,9 @@ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, "node_modules/core-js": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.15.1.tgz", - "integrity": "sha512-h8VbZYnc9pDzueiS2610IULDkpFFPunHwIpl8yRwFahAEEdSpHlTy3h3z3rKq5h11CaUdBEeRViu9AYvbxiMeg==", + "version": "3.15.2", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.15.2.tgz", + "integrity": "sha512-tKs41J7NJVuaya8DxIOCnl8QuPHx5/ZVbFo1oKgVl1qHFBBrDctzQGtuLjPpRdNTWmKPH6oEvgN/MUID+l485Q==", "hasInstallScript": true, "optional": true, "funding": { @@ -2900,9 +2852,9 @@ } }, "node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "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": { @@ -2923,30 +2875,18 @@ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", "dev": true }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.0.tgz", + "integrity": "sha512-4AefxbTTdFtxDUdh0BuMBs2qJVL25Mow2zlcuuePegQwgD6GEmQao42LLEeksOui8nL4RcNEugIpFP7eRd33xg==", "dev": true, "dependencies": { "abab": "^2.0.3", "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" + "whatwg-url": "^9.0.0" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/dateformat": { @@ -2958,9 +2898,9 @@ } }, "node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dependencies": { "ms": "2.1.2" }, @@ -3005,9 +2945,9 @@ } }, "node_modules/decimal.js": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.0.tgz", - "integrity": "sha512-MrQRs2gyD//7NeHi9TtsfClkf+cFAewDz+PZHR8ILKglLmBMyVX3ymQ+oeznE3tjrS7beTN+6JXb2C3JDHm7ug==", + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", "dev": true }, "node_modules/decompress-response": { @@ -3151,18 +3091,18 @@ } }, "node_modules/diff-sequences": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.1.tgz", - "integrity": "sha512-XPLijkfJUh/PIBnfkcSHgvD6tlYixmcMAn3osTk6jt+H0v/mgURto1XUiD9DKuGX5NDoVS6dSlA23gd9FUaCFg==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", + "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", "dev": true, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/digest-fetch": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.2.0.tgz", - "integrity": "sha512-DSbWN+dPXH+9A/aqmGnpI40cVKzJRgL4iDm1eGpsZ1MpW3tXQuBJN5xNY3PEqUx3QjkQIPyD99ypClHr9fW9Ow==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.2.1.tgz", + "integrity": "sha512-Do130fdya/9DPUl80PaltD7R0WIOKkROnLjrdh0CxvS+s3WGGWFMPZvB2eH48BRnVxlSKrLdp/wBH19f0Kag6Q==", "dependencies": { "base-64": "^0.1.0", "md5": "^2.3.0" @@ -3274,16 +3214,6 @@ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", "devOptional": true }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "node_modules/edge-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-2.2.1.tgz", @@ -3300,14 +3230,14 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "node_modules/electron": { - "version": "11.4.9", - "resolved": "https://registry.npmjs.org/electron/-/electron-11.4.9.tgz", - "integrity": "sha512-3TJG1vAnuR8p47mzorCW5l7uWCjdNUufIbZ+gKjm010dtHmhrO1zchP1a76vuT4BllK8q1iygFSkNnDlZ0i2pA==", + "version": "13.5.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-13.5.0.tgz", + "integrity": "sha512-s4+b1RFWkNKWp7WWrv2q60MuFljHUCbO7XAupBSCUz/NP1Hz4OenWbMPUt0H+fa8YZeN8CX3JDIA8Bet5uAJvw==", + "devOptional": true, "hasInstallScript": true, - "optional": true, "dependencies": { "@electron/get": "^1.0.1", - "@types/node": "^12.0.12", + "@types/node": "^14.6.2", "extract-zip": "^1.0.3" }, "bin": { @@ -3318,13 +3248,13 @@ } }, "node_modules/electron-chromedriver": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/electron-chromedriver/-/electron-chromedriver-11.0.0.tgz", - "integrity": "sha512-ayMJPBbB4puU0SqYbcD9XvF3/7GWIhqKE1n5lG2/GQPRnrZkNoPIilsrS0rQcD50Xhl69KowatDqLhUznZWtbA==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/electron-chromedriver/-/electron-chromedriver-13.0.0.tgz", + "integrity": "sha512-fID1ms8wT7qNfoKkXHNpH0ZE8/Nclb5YmkF3O0w57OxsR8S9PxgE9CJAgaSGroxBgZ+ge1i2OU0Aq/WE/e/Neg==", "dev": true, "hasInstallScript": true, "dependencies": { - "@electron/get": "^1.12.2", + "@electron/get": "^1.12.4", "extract-zip": "^2.0.0" }, "bin": { @@ -3370,9 +3300,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.3.756", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.756.tgz", - "integrity": "sha512-WsmJym1TMeHVndjPjczTFbnRR/c4sbzg8fBFtuhlb2Sru3i/S1VGpzDSrv/It8ctMU2bj8G7g7/O3FzYMGw6eA==", + "version": "1.3.766", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.766.tgz", + "integrity": "sha512-u2quJ862q9reRKh/je3GXis3w38+RoXH1J9N3XjtsS6NzmUAosNsyZgUVFZPN/ZlJ3v6T0rTyZR3q/J5c6Sy5w==", "dev": true }, "node_modules/emittery": { @@ -3410,9 +3340,9 @@ } }, "node_modules/engine.io": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-5.1.1.tgz", - "integrity": "sha512-aMWot7H5aC8L4/T8qMYbLdvKlZOdJTH54FxfdFunTGvhMx1BHkJOntWArsVfgAZVwAO9LC2sryPWRcEeUzCe5w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-5.2.0.tgz", + "integrity": "sha512-d1DexkQx87IFr1FLuV+0f5kAm1Hk1uOVijLOb+D1sDO2QMb7YjE02VHtZtxo7xIXMgcWLb+vl3HRT0rI9tr4jQ==", "dependencies": { "accepts": "~1.3.4", "base64id": "2.0.0", @@ -3427,9 +3357,9 @@ } }, "node_modules/engine.io-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz", - "integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.3.tgz", + "integrity": "sha512-xEAAY0msNnESNPc00e19y5heTPX4y/TJ36gr8t1voOaNmTojP9b3oK3BbJLFufW2XFPQaaijpFewm2g2Um3uqA==", "dependencies": { "base64-arraybuffer": "0.1.4" }, @@ -3445,6 +3375,26 @@ "node": ">= 0.6" } }, + "node_modules/engine.io/node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", @@ -3594,12 +3544,13 @@ } }, "node_modules/eslint": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.29.0.tgz", - "integrity": "sha512-82G/JToB9qIy/ArBzIWG9xvvwL3R86AlCjtGw+A29OMZDqhTybz/MByORSukGxeI+YPCR4coYyITKk8BFH9nDA==", + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "dependencies": { "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.2", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -3661,9 +3612,9 @@ } }, "node_modules/eslint-plugin-jest": { - "version": "24.3.6", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.3.6.tgz", - "integrity": "sha512-WOVH4TIaBLIeCX576rLcOgjNXqP+jNlCiEmRgFTfQtJ52DpwnIQKAVGlGPAN7CZ33bW6eNfHD6s8ZbEUTQubJg==", + "version": "24.4.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.4.2.tgz", + "integrity": "sha512-jNMnqwX75z0RXRMXkxwb/+9ylKJYJLJ8nT8nBT0XFM5qx4IQGxP4edMawa0qGkSbHae0BDPBmi8I2QF0/F04XQ==", "dev": true, "dependencies": { "@typescript-eslint/experimental-utils": "^4.0.1" @@ -3682,23 +3633,23 @@ } }, "node_modules/eslint-plugin-jsdoc": { - "version": "35.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-35.4.0.tgz", - "integrity": "sha512-0cr+NkPTxpTiMCtYOd8W5fd2IyC/CmaTHKb+0bzkpP9p8HfmJ3B2/M6FWj97rQJOLwLMkx+g2MIEZsrttpbFmQ==", + "version": "36.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-36.1.0.tgz", + "integrity": "sha512-Qpied2AJCQcScxfzTObLKRiP5QgLXjMU/ITjBagEV5p2Q/HpumD1EQtazdRYdjDSwPmXhwOl2yquwOGQ4HOJNw==", "dev": true, "dependencies": { - "@es-joy/jsdoccomment": "^0.8.0-alpha.2", - "comment-parser": "1.1.5", - "debug": "^4.3.1", + "@es-joy/jsdoccomment": "0.10.8", + "comment-parser": "1.2.4", + "debug": "^4.3.2", "esquery": "^1.4.0", - "jsdoc-type-pratt-parser": "^1.0.4", + "jsdoc-type-pratt-parser": "^1.1.1", "lodash": "^4.17.21", "regextras": "^0.8.0", "semver": "^7.3.5", "spdx-expression-parse": "^3.0.1" }, "engines": { - "node": ">=12" + "node": "^12 || ^14 || ^16" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0" @@ -3720,9 +3671,9 @@ } }, "node_modules/eslint-plugin-prettier": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz", - "integrity": "sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz", + "integrity": "sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==", "dev": true, "dependencies": { "prettier-linter-helpers": "^1.0.0" @@ -3731,8 +3682,8 @@ "node": ">=6.0.0" }, "peerDependencies": { - "eslint": ">=5.0.0", - "prettier": ">=1.13.0" + "eslint": ">=7.28.0", + "prettier": ">=2.0.0" }, "peerDependenciesMeta": { "eslint-config-prettier": { @@ -3957,17 +3908,17 @@ } }, "node_modules/expect": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.0.2.tgz", - "integrity": "sha512-YJFNJe2+P2DqH+ZrXy+ydRQYO87oxRUonZImpDodR1G7qo3NYd3pL+NQ9Keqpez3cehczYwZDBC3A7xk3n7M/w==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.2.2.tgz", + "integrity": "sha512-sjHBeEk47/eshN9oLbvPJZMgHQihOXXQzSMPCJ4MqKShbU9HOVFSNHEEU4dp4ujzxFSiNvPFzB2AMOFmkizhvA==", "dev": true, "dependencies": { - "@jest/types": "^27.0.2", + "@jest/types": "^27.1.1", "ansi-styles": "^5.0.0", - "jest-get-type": "^27.0.1", - "jest-matcher-utils": "^27.0.2", - "jest-message-util": "^27.0.2", - "jest-regex-util": "^27.0.1" + "jest-get-type": "^27.0.6", + "jest-matcher-utils": "^27.2.2", + "jest-message-util": "^27.2.2", + "jest-regex-util": "^27.0.6" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -4071,7 +4022,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", - "optional": true, + "devOptional": true, "dependencies": { "concat-stream": "^1.6.2", "debug": "^2.6.9", @@ -4086,7 +4037,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "optional": true, + "devOptional": true, "dependencies": { "ms": "2.0.0" } @@ -4095,16 +4046,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "optional": true - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true, - "engines": [ - "node >=0.6.0" - ] + "devOptional": true }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -4118,17 +4060,16 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", - "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.6.tgz", + "integrity": "sha512-GnLuqj/pvQ7pX8/L4J84nijv6sAnlwvSDpMkJi9i7nPmPxGtRPkBSStfvDW5l6nMdX9VWe+pkKWFTgD+vF2QSQ==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", + "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" + "micromatch": "^4.0.4" }, "engines": { "node": ">=8" @@ -4151,9 +4092,9 @@ "dev": true }, "node_modules/fastq": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", - "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.1.tgz", + "integrity": "sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -4285,9 +4226,9 @@ } }, "node_modules/flatted": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", - "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==" + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.0.tgz", + "integrity": "sha512-XprP7lDrVT+kE2c2YlfiV+IfS9zxukiIOvNamPNsImNhXadSsQEbosItdL9bUQlCZXR13SvPk20BjWSWLA7m4A==" }, "node_modules/foreground-child": { "version": "2.0.0", @@ -4302,19 +4243,10 @@ "node": ">=8.0.0" } }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dev": true, "dependencies": { "asynckit": "^0.4.0", @@ -4474,15 +4406,6 @@ "node": ">=6" } }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - } - }, "node_modules/glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -4600,9 +4523,9 @@ } }, "node_modules/globals": { - "version": "13.9.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", - "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz", + "integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==", "dependencies": { "type-fest": "^0.20.2" }, @@ -4613,17 +4536,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globals/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/globalthis": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.2.tgz", @@ -4723,29 +4635,6 @@ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dev": true, - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -4915,21 +4804,6 @@ "node": ">= 6" } }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, "node_modules/http2-wrapper": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", @@ -4943,6 +4817,18 @@ "node": ">=10.19.0" } }, + "node_modules/http2-wrapper/node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/https-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", @@ -4966,13 +4852,16 @@ } }, "node_modules/husky": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/husky/-/husky-6.0.0.tgz", - "integrity": "sha512-SQS2gDTB7tBN486QSoKPKQItZw97BMOd+Kdb6ghfpBc0yXyzrddI0oDV5MkDAbuB4X2mO3/nj60TRMcYxwzZeQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.2.tgz", + "integrity": "sha512-8yKEWNX4z2YsofXAMT7KvA1g8p+GxtB1ffV8XtpAEGuXNAbCV5wdNKH+qTpw8SM9fh4aMPDR+yQuKfgnreyZlg==", "dev": true, "bin": { "husky": "lib/bin.js" }, + "engines": { + "node": ">=12" + }, "funding": { "url": "https://github.com/sponsors/typicode" } @@ -5251,12 +5140,12 @@ } }, "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", "dev": true, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, "node_modules/is-potential-custom-element-name": { @@ -5333,12 +5222,6 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, "node_modules/istanbul-lib-coverage": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", @@ -5445,14 +5328,14 @@ } }, "node_modules/jest": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.0.5.tgz", - "integrity": "sha512-4NlVMS29gE+JOZvgmSAsz3eOjkSsHqjTajlIsah/4MVSmKvf3zFP/TvgcLoWe2UVHiE9KF741sReqhF0p4mqbQ==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.2.2.tgz", + "integrity": "sha512-XAB/9akDTe3/V0wPNKWfP9Y/NT1QPiCqyRBYGbC66EA9EvgAzdaFEqhFGLaDJ5UP2yIyXUMtju9a9IMrlYbZTQ==", "dev": true, "dependencies": { - "@jest/core": "^27.0.5", + "@jest/core": "^27.2.2", "import-local": "^3.0.2", - "jest-cli": "^27.0.5" + "jest-cli": "^27.2.2" }, "bin": { "jest": "bin/jest.js" @@ -5470,12 +5353,12 @@ } }, "node_modules/jest-changed-files": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.0.2.tgz", - "integrity": "sha512-eMeb1Pn7w7x3wue5/vF73LPCJ7DKQuC9wQUR5ebP9hDPpk5hzcT/3Hmz3Q5BOFpR3tgbmaWhJcMTVgC8Z1NuMw==", + "version": "27.1.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.1.1.tgz", + "integrity": "sha512-5TV9+fYlC2A6hu3qtoyGHprBwCAn0AuGA77bZdUgYvVlRMjHXo063VcWTEAyx6XAZ85DYHqp0+aHKbPlfRDRvA==", "dev": true, "dependencies": { - "@jest/types": "^27.0.2", + "@jest/types": "^27.1.1", "execa": "^5.0.0", "throat": "^6.0.1" }, @@ -5484,27 +5367,27 @@ } }, "node_modules/jest-circus": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.0.5.tgz", - "integrity": "sha512-p5rO90o1RTh8LPOG6l0Fc9qgp5YGv+8M5CFixhMh7gGHtGSobD1AxX9cjFZujILgY8t30QZ7WVvxlnuG31r8TA==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.2.2.tgz", + "integrity": "sha512-8txlqs0EDrvPasCgwfLMkG0l3F4FxqQa6lxOsvYfOl04eSJjRw3F4gk9shakuC00nMD+VT+SMtFYXxe64f0VZw==", "dev": true, "dependencies": { - "@jest/environment": "^27.0.5", - "@jest/test-result": "^27.0.2", - "@jest/types": "^27.0.2", + "@jest/environment": "^27.2.2", + "@jest/test-result": "^27.2.2", + "@jest/types": "^27.1.1", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", - "expect": "^27.0.2", + "expect": "^27.2.2", "is-generator-fn": "^2.0.0", - "jest-each": "^27.0.2", - "jest-matcher-utils": "^27.0.2", - "jest-message-util": "^27.0.2", - "jest-runtime": "^27.0.5", - "jest-snapshot": "^27.0.5", - "jest-util": "^27.0.2", - "pretty-format": "^27.0.2", + "jest-each": "^27.2.2", + "jest-matcher-utils": "^27.2.2", + "jest-message-util": "^27.2.2", + "jest-runtime": "^27.2.2", + "jest-snapshot": "^27.2.2", + "jest-util": "^27.2.0", + "pretty-format": "^27.2.2", "slash": "^3.0.0", "stack-utils": "^2.0.3", "throat": "^6.0.1" @@ -5513,563 +5396,22 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-config": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.0.5.tgz", - "integrity": "sha512-zCUIXag7QIXKEVN4kUKbDBDi9Q53dV5o3eNhGqe+5zAbt1vLs4VE3ceWaYrOub0L4Y7E9pGfM84TX/0ARcE+Qw==", + "node_modules/jest-cli": { + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.2.2.tgz", + "integrity": "sha512-jbEythw22LR/IHYgNrjWdO74wO9wyujCxTMjbky0GLav4rC4y6qDQr4TqQ2JPP51eDYJ2awVn83advEVSs5Brg==", "dev": true, "dependencies": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^27.0.5", - "@jest/types": "^27.0.2", - "babel-jest": "^27.0.5", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "is-ci": "^3.0.0", - "jest-circus": "^27.0.5", - "jest-environment-jsdom": "^27.0.5", - "jest-environment-node": "^27.0.5", - "jest-get-type": "^27.0.1", - "jest-jasmine2": "^27.0.5", - "jest-regex-util": "^27.0.1", - "jest-resolve": "^27.0.5", - "jest-runner": "^27.0.5", - "jest-util": "^27.0.2", - "jest-validate": "^27.0.2", - "micromatch": "^4.0.4", - "pretty-format": "^27.0.2" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-diff": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.2.tgz", - "integrity": "sha512-BFIdRb0LqfV1hBt8crQmw6gGQHVDhM87SpMIZ45FPYKReZYG5er1+5pIn2zKqvrJp6WNox0ylR8571Iwk2Dmgw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^27.0.1", - "jest-get-type": "^27.0.1", - "pretty-format": "^27.0.2" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-docblock": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.1.tgz", - "integrity": "sha512-TA4+21s3oebURc7VgFV4r7ltdIJ5rtBH1E3Tbovcg7AV+oLfD5DcJ2V2vJ5zFA9sL5CFd/d2D6IpsAeSheEdrA==", - "dev": true, - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-each": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.0.2.tgz", - "integrity": "sha512-OLMBZBZ6JkoXgUenDtseFRWA43wVl2BwmZYIWQws7eS7pqsIvePqj/jJmEnfq91ALk3LNphgwNK/PRFBYi7ITQ==", - "dev": true, - "dependencies": { - "@jest/types": "^27.0.2", - "chalk": "^4.0.0", - "jest-get-type": "^27.0.1", - "jest-util": "^27.0.2", - "pretty-format": "^27.0.2" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-jsdom": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.0.5.tgz", - "integrity": "sha512-ToWhViIoTl5738oRaajTMgYhdQL73UWPoV4GqHGk2DPhs+olv8OLq5KoQW8Yf+HtRao52XLqPWvl46dPI88PdA==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.0.5", - "@jest/fake-timers": "^27.0.5", - "@jest/types": "^27.0.2", - "@types/node": "*", - "jest-mock": "^27.0.3", - "jest-util": "^27.0.2", - "jsdom": "^16.6.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-node": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.0.5.tgz", - "integrity": "sha512-47qqScV/WMVz5OKF5TWpAeQ1neZKqM3ySwNveEnLyd+yaE/KT6lSMx/0SOx60+ZUcVxPiESYS+Kt2JS9y4PpkQ==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.0.5", - "@jest/fake-timers": "^27.0.5", - "@jest/types": "^27.0.2", - "@types/node": "*", - "jest-mock": "^27.0.3", - "jest-util": "^27.0.2" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-get-type": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz", - "integrity": "sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg==", - "dev": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.0.5.tgz", - "integrity": "sha512-3LFryGSHxwPFHzKIs6W0BGA2xr6g1MvzSjR3h3D8K8Uqy4vbRm/grpGHzbPtIbOPLC6wFoViRrNEmd116QWSkw==", - "dev": true, - "dependencies": { - "@jest/types": "^27.0.2", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^27.0.1", - "jest-serializer": "^27.0.1", - "jest-util": "^27.0.2", - "jest-worker": "^27.0.2", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/jest-jasmine2": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.0.5.tgz", - "integrity": "sha512-m3TojR19sFmTn79QoaGy1nOHBcLvtLso6Zh7u+gYxZWGcza4rRPVqwk1hciA5ZOWWZIJOukAcore8JRX992FaA==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^27.0.5", - "@jest/source-map": "^27.0.1", - "@jest/test-result": "^27.0.2", - "@jest/types": "^27.0.2", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.0.2", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.0.2", - "jest-matcher-utils": "^27.0.2", - "jest-message-util": "^27.0.2", - "jest-runtime": "^27.0.5", - "jest-snapshot": "^27.0.5", - "jest-util": "^27.0.2", - "pretty-format": "^27.0.2", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-leak-detector": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.0.2.tgz", - "integrity": "sha512-TZA3DmCOfe8YZFIMD1GxFqXUkQnIoOGQyy4hFCA2mlHtnAaf+FeOMxi0fZmfB41ZL+QbFG6BVaZF5IeFIVy53Q==", - "dev": true, - "dependencies": { - "jest-get-type": "^27.0.1", - "pretty-format": "^27.0.2" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-matcher-utils": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.0.2.tgz", - "integrity": "sha512-Qczi5xnTNjkhcIB0Yy75Txt+Ez51xdhOxsukN7awzq2auZQGPHcQrJ623PZj0ECDEMOk2soxWx05EXdXGd1CbA==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^27.0.2", - "jest-get-type": "^27.0.1", - "pretty-format": "^27.0.2" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-message-util": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.0.2.tgz", - "integrity": "sha512-rTqWUX42ec2LdMkoUPOzrEd1Tcm+R1KfLOmFK+OVNo4MnLsEaxO5zPDb2BbdSmthdM/IfXxOZU60P/WbWF8BTw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.0.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.4", - "pretty-format": "^27.0.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-message-util/node_modules/@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/jest-mock": { - "version": "27.0.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.0.3.tgz", - "integrity": "sha512-O5FZn5XDzEp+Xg28mUz4ovVcdwBBPfAhW9+zJLO0Efn2qNbYcDaJvSlRiQ6BCZUCVOJjALicuJQI9mRFjv1o9Q==", - "dev": true, - "dependencies": { - "@jest/types": "^27.0.2", - "@types/node": "*" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.1.tgz", - "integrity": "sha512-6nY6QVcpTgEKQy1L41P4pr3aOddneK17kn3HJw6SdwGiKfgCGTvH02hVXL0GU8GEKtPH83eD2DIDgxHXOxVohQ==", - "dev": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.0.5.tgz", - "integrity": "sha512-Md65pngRh8cRuWVdWznXBB5eDt391OJpdBaJMxfjfuXCvOhM3qQBtLMCMTykhuUKiBMmy5BhqCW7AVOKmPrW+Q==", - "dev": true, - "dependencies": { - "@jest/types": "^27.0.2", - "chalk": "^4.0.0", - "escalade": "^3.1.1", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.0.2", - "jest-validate": "^27.0.2", - "resolve": "^1.20.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.0.5.tgz", - "integrity": "sha512-xUj2dPoEEd59P+nuih4XwNa4nJ/zRd/g4rMvjHrZPEBWeWRq/aJnnM6mug+B+Nx+ILXGtfWHzQvh7TqNV/WbuA==", - "dev": true, - "dependencies": { - "@jest/types": "^27.0.2", - "jest-regex-util": "^27.0.1", - "jest-snapshot": "^27.0.5" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runner": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.0.5.tgz", - "integrity": "sha512-HNhOtrhfKPArcECgBTcWOc+8OSL8GoFoa7RsHGnfZR1C1dFohxy9eLtpYBS+koybAHlJLZzNCx2Y/Ic3iEtJpQ==", - "dev": true, - "dependencies": { - "@jest/console": "^27.0.2", - "@jest/environment": "^27.0.5", - "@jest/test-result": "^27.0.2", - "@jest/transform": "^27.0.5", - "@jest/types": "^27.0.2", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-docblock": "^27.0.1", - "jest-environment-jsdom": "^27.0.5", - "jest-environment-node": "^27.0.5", - "jest-haste-map": "^27.0.5", - "jest-leak-detector": "^27.0.2", - "jest-message-util": "^27.0.2", - "jest-resolve": "^27.0.5", - "jest-runtime": "^27.0.5", - "jest-util": "^27.0.2", - "jest-worker": "^27.0.2", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runtime": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.0.5.tgz", - "integrity": "sha512-V/w/+VasowPESbmhXn5AsBGPfb35T7jZPGZybYTHxZdP7Gwaa+A0EXE6rx30DshHKA98lVCODbCO8KZpEW3hiQ==", - "dev": true, - "dependencies": { - "@jest/console": "^27.0.2", - "@jest/environment": "^27.0.5", - "@jest/fake-timers": "^27.0.5", - "@jest/globals": "^27.0.5", - "@jest/source-map": "^27.0.1", - "@jest/test-result": "^27.0.2", - "@jest/transform": "^27.0.5", - "@jest/types": "^27.0.2", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.0.5", - "jest-message-util": "^27.0.2", - "jest-mock": "^27.0.3", - "jest-regex-util": "^27.0.1", - "jest-resolve": "^27.0.5", - "jest-snapshot": "^27.0.5", - "jest-util": "^27.0.2", - "jest-validate": "^27.0.2", - "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^16.0.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-serializer": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.1.tgz", - "integrity": "sha512-svy//5IH6bfQvAbkAEg1s7xhhgHTtXu0li0I2fdKHDsLP2P2MOiscPQIENQep8oU2g2B3jqLyxKKzotZOz4CwQ==", - "dev": true, - "dependencies": { - "@types/node": "*", - "graceful-fs": "^4.2.4" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-snapshot": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.0.5.tgz", - "integrity": "sha512-H1yFYdgnL1vXvDqMrnDStH6yHFdMEuzYQYc71SnC/IJnuuhW6J16w8GWG1P+qGd3Ag3sQHjbRr0TcwEo/vGS+g==", - "dev": true, - "dependencies": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/parser": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.0.5", - "@jest/types": "^27.0.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.0.2", - "graceful-fs": "^4.2.4", - "jest-diff": "^27.0.2", - "jest-get-type": "^27.0.1", - "jest-haste-map": "^27.0.5", - "jest-matcher-utils": "^27.0.2", - "jest-message-util": "^27.0.2", - "jest-resolve": "^27.0.5", - "jest-util": "^27.0.2", - "natural-compare": "^1.4.0", - "pretty-format": "^27.0.2", - "semver": "^7.3.2" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-util": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.2.tgz", - "integrity": "sha512-1d9uH3a00OFGGWSibpNYr+jojZ6AckOMCXV2Z4K3YXDnzpkAaXQyIpY14FOJPiUmil7CD+A6Qs+lnnh6ctRbIA==", - "dev": true, - "dependencies": { - "@jest/types": "^27.0.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^3.0.0", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-validate": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.0.2.tgz", - "integrity": "sha512-UgBF6/oVu1ofd1XbaSotXKihi8nZhg0Prm8twQ9uCuAfo59vlxCXMPI/RKmrZEVgi3Nd9dS0I8A0wzWU48pOvg==", - "dev": true, - "dependencies": { - "@jest/types": "^27.0.2", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.0.1", - "leven": "^3.1.0", - "pretty-format": "^27.0.2" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-watcher": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.0.2.tgz", - "integrity": "sha512-8nuf0PGuTxWj/Ytfw5fyvNn/R80iXY8QhIT0ofyImUvdnoaBdT6kob0GmhXR+wO+ALYVnh8bQxN4Tjfez0JgkA==", - "dev": true, - "dependencies": { - "@jest/test-result": "^27.0.2", - "@jest/types": "^27.0.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.0.2", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-worker": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.2.tgz", - "integrity": "sha512-EoBdilOTTyOgmHXtw/cPc+ZrCA0KJMrkXzkrPGNwLmnvvlN1nj7MPrxpT7m+otSv2e1TLaVffzDnE/LB14zJMg==", - "dev": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jest/node_modules/jest-cli": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.0.5.tgz", - "integrity": "sha512-kZqY020QFOFQKVE2knFHirTBElw3/Q0kUbDc3nMfy/x+RQ7zUY89SUuzpHHJoSX1kX7Lq569ncvjNqU3Td/FCA==", - "dev": true, - "dependencies": { - "@jest/core": "^27.0.5", - "@jest/test-result": "^27.0.2", - "@jest/types": "^27.0.2", + "@jest/core": "^27.2.2", + "@jest/test-result": "^27.2.2", + "@jest/types": "^27.1.1", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", "import-local": "^3.0.2", - "jest-config": "^27.0.5", - "jest-util": "^27.0.2", - "jest-validate": "^27.0.2", + "jest-config": "^27.2.2", + "jest-util": "^27.2.0", + "jest-validate": "^27.2.2", "prompts": "^2.0.1", "yargs": "^16.0.3" }, @@ -6088,42 +5430,157 @@ } } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "node_modules/jest-config": { + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.2.2.tgz", + "integrity": "sha512-2nhms3lp52ZpU0636bB6zIFHjDVtYxzFQIOHZjBFUeXcb6b41sEkWojbHaJ4FEIO44UbccTLa7tvNpiFCgPE7w==", + "dev": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^27.2.2", + "@jest/types": "^27.1.1", + "babel-jest": "^27.2.2", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "jest-circus": "^27.2.2", + "jest-environment-jsdom": "^27.2.2", + "jest-environment-node": "^27.2.2", + "jest-get-type": "^27.0.6", + "jest-jasmine2": "^27.2.2", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.2.2", + "jest-runner": "^27.2.2", + "jest-util": "^27.2.0", + "jest-validate": "^27.2.2", + "micromatch": "^4.0.4", + "pretty-format": "^27.2.2" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } } }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "node_modules/jest-diff": { + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.2.2.tgz", + "integrity": "sha512-o3LaDbQDSaMJif4yztJAULI4xVatxbBasbKLbEw3K8CiRdDdbxMrLArS9EKDHQFYh6Tgfrm1PC2mIYR1xhu0hQ==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.0.6", + "jest-get-type": "^27.0.6", + "pretty-format": "^27.2.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz", + "integrity": "sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-each": { + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.2.2.tgz", + "integrity": "sha512-ZCDhkvwHeXHsxoFxvW43fabL18iLiVDxaipG5XWG7dSd+XWXXpzMQvBWYT9Wvzhg5x4hvrLQ24LtiOKw3I09xA==", + "dev": true, + "dependencies": { + "@jest/types": "^27.1.1", + "chalk": "^4.0.0", + "jest-get-type": "^27.0.6", + "jest-util": "^27.2.0", + "pretty-format": "^27.2.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-jsdom": { + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.2.2.tgz", + "integrity": "sha512-mzCLEdnpGWDJmNB6WIPLlZM+hpXdeiya9TryiByqcUdpliNV1O+LGC2SewzjmB4IblabGfvr3KcPN0Nme2wnDw==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.2.2", + "@jest/fake-timers": "^27.2.2", + "@jest/types": "^27.1.1", + "@types/node": "*", + "jest-mock": "^27.1.1", + "jest-util": "^27.2.0", + "jsdom": "^16.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/acorn": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", "dev": true }, - "node_modules/jsdoc-type-pratt-parser": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-1.0.4.tgz", - "integrity": "sha512-jzmW9gokeq9+bHPDR1nCeidMyFUikdZlbOhKzh9+/nJqB75XhpNKec1/UuxW5c4+O+Pi31Gc/dCboyfSm/pSpQ==", + "node_modules/jest-environment-jsdom/node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", "dev": true, + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, "engines": { - "node": ">=12.0.0" + "node": ">=10" } }, - "node_modules/jsdom": { - "version": "16.6.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.6.0.tgz", - "integrity": "sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg==", + "node_modules/jest-environment-jsdom/node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", "dev": true, "dependencies": { "abab": "^2.0.5", @@ -6151,7 +5608,7 @@ "whatwg-encoding": "^1.0.5", "whatwg-mimetype": "^2.3.0", "whatwg-url": "^8.5.0", - "ws": "^7.4.5", + "ws": "^7.4.6", "xml-name-validator": "^3.0.0" }, "engines": { @@ -6166,6 +5623,534 @@ } } }, + "node_modules/jest-environment-jsdom/node_modules/whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "dev": true, + "dependencies": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-environment-node": { + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.2.2.tgz", + "integrity": "sha512-XgUscWs6H6UNqC96/QJjmUGZzzpql/JyprLSXVu7wkgM8tjbJdEkSqwrVAvJPm1yu526ImrmsIoh2BTHxkwL/g==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.2.2", + "@jest/fake-timers": "^27.2.2", + "@jest/types": "^27.1.1", + "@types/node": "*", + "jest-mock": "^27.1.1", + "jest-util": "^27.2.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", + "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.2.2.tgz", + "integrity": "sha512-kaKiq+GbAvk6/sq++Ymor4Vzk6+lr0vbKs2HDVPdkKsHX2lIJRyvhypZG/QsNfQnROKWIZSpUpGuv2HySSosvA==", + "dev": true, + "dependencies": { + "@jest/types": "^27.1.1", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^27.0.6", + "jest-serializer": "^27.0.6", + "jest-util": "^27.2.0", + "jest-worker": "^27.2.2", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-jasmine2": { + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.2.2.tgz", + "integrity": "sha512-SczhZNfmZID9HbJ1GHhO4EzeL/PMRGeAUw23ddPUdd6kFijEZpT2yOxyNCBUKAsVQ/14OB60kjgnbuFOboZUNg==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^27.2.2", + "@jest/source-map": "^27.0.6", + "@jest/test-result": "^27.2.2", + "@jest/types": "^27.1.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^27.2.2", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.2.2", + "jest-matcher-utils": "^27.2.2", + "jest-message-util": "^27.2.2", + "jest-runtime": "^27.2.2", + "jest-snapshot": "^27.2.2", + "jest-util": "^27.2.0", + "pretty-format": "^27.2.2", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-leak-detector": { + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.2.2.tgz", + "integrity": "sha512-fQIYKkhXUs/4EpE4wO1AVsv7aNH3o0km1BGq3vxvSfYdwG9GLMf+b0z/ghLmBYNxb+tVpm/zv2caoKm3GfTazg==", + "dev": true, + "dependencies": { + "jest-get-type": "^27.0.6", + "pretty-format": "^27.2.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.2.2.tgz", + "integrity": "sha512-xN3wT4p2i9DGB6zmL3XxYp5lJmq9Q6ff8XKlMtVVBS2SAshmgsPBALJFQ8dWRd2G/xf5q/N0SD0Mipt8QBA26A==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.2.2", + "jest-get-type": "^27.0.6", + "pretty-format": "^27.2.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.2.2.tgz", + "integrity": "sha512-/iS5/m2FSF7Nn6APFoxFymJpyhB/gPf0CJa7uFSkbYaWvrADUfQ9NTsuyjpszKErOS2/huFs44ysWhlQTKvL8Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.1.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.4", + "pretty-format": "^27.2.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-message-util/node_modules/@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/jest-mock": { + "version": "27.1.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.1.1.tgz", + "integrity": "sha512-SClsFKuYBf+6SSi8jtAYOuPw8DDMsTElUWEae3zq7vDhH01ayVSIHUSIa8UgbDOUalCFp6gNsaikN0rbxN4dbw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.1.1", + "@types/node": "*" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz", + "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.2.2.tgz", + "integrity": "sha512-tfbHcBs/hJTb3fPQ/3hLWR+TsLNTzzK98TU+zIAsrL9nNzWfWROwopUOmiSUqmHMZW5t9au/433kSF2/Af+tTw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.1.1", + "chalk": "^4.0.0", + "escalade": "^3.1.1", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.2.2", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.2.0", + "jest-validate": "^27.2.2", + "resolve": "^1.20.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.2.2.tgz", + "integrity": "sha512-nvJS+DyY51HHdZnMIwXg7fimQ5ylFx4+quQXspQXde2rXYy+4v75UYoX/J65Ln8mKCNc6YF8HEhfGaRBOrxxHg==", + "dev": true, + "dependencies": { + "@jest/types": "^27.1.1", + "jest-regex-util": "^27.0.6", + "jest-snapshot": "^27.2.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runner": { + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.2.2.tgz", + "integrity": "sha512-+bUFwBq+yTnvsOFuxetoQtkuOnqdAk2YuIGjlLmc7xLAXn/V1vjhXrLencgij0BUTTUvG9Aul3+5XDss4Wa8Eg==", + "dev": true, + "dependencies": { + "@jest/console": "^27.2.2", + "@jest/environment": "^27.2.2", + "@jest/test-result": "^27.2.2", + "@jest/transform": "^27.2.2", + "@jest/types": "^27.1.1", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-docblock": "^27.0.6", + "jest-environment-jsdom": "^27.2.2", + "jest-environment-node": "^27.2.2", + "jest-haste-map": "^27.2.2", + "jest-leak-detector": "^27.2.2", + "jest-message-util": "^27.2.2", + "jest-resolve": "^27.2.2", + "jest-runtime": "^27.2.2", + "jest-util": "^27.2.0", + "jest-worker": "^27.2.2", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.2.2.tgz", + "integrity": "sha512-PtTHCK5jT+KrIpKpjJsltu/dK5uGhBtTNLOk1Z+ZD2Jrxam2qQsOqDFYLszcK0jc2TLTNsrVpclqSftn7y3aXA==", + "dev": true, + "dependencies": { + "@jest/console": "^27.2.2", + "@jest/environment": "^27.2.2", + "@jest/fake-timers": "^27.2.2", + "@jest/globals": "^27.2.2", + "@jest/source-map": "^27.0.6", + "@jest/test-result": "^27.2.2", + "@jest/transform": "^27.2.2", + "@jest/types": "^27.1.1", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.2.2", + "jest-message-util": "^27.2.2", + "jest-mock": "^27.1.1", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.2.2", + "jest-snapshot": "^27.2.2", + "jest-util": "^27.2.0", + "jest-validate": "^27.2.2", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^16.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-serializer": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz", + "integrity": "sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.2.2.tgz", + "integrity": "sha512-7ODSvULMiiOVuuLvLZpDlpqqTqX9hDfdmijho5auVu9qRYREolvrvgH4kSNOKfcqV3EZOTuLKNdqsz1PM20PQA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/parser": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.2.2", + "@jest/types": "^27.1.1", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.2.2", + "graceful-fs": "^4.2.4", + "jest-diff": "^27.2.2", + "jest-get-type": "^27.0.6", + "jest-haste-map": "^27.2.2", + "jest-matcher-utils": "^27.2.2", + "jest-message-util": "^27.2.2", + "jest-resolve": "^27.2.2", + "jest-util": "^27.2.0", + "natural-compare": "^1.4.0", + "pretty-format": "^27.2.2", + "semver": "^7.3.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-util": { + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.2.0.tgz", + "integrity": "sha512-T5ZJCNeFpqcLBpx+Hl9r9KoxBCUqeWlJ1Htli+vryigZVJ1vuLB9j35grEBASp4R13KFkV7jM52bBGnArpJN6A==", + "dev": true, + "dependencies": { + "@jest/types": "^27.1.1", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-validate": { + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.2.2.tgz", + "integrity": "sha512-01mwTAs2kgDuX98Ua3Xhdhp5lXsLU4eyg6k56adTtrXnU/GbLd9uAsh5nc4MWVtUXMeNmHUyEiD4ibLqE8MuNw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.1.1", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^27.0.6", + "leven": "^3.1.0", + "pretty-format": "^27.2.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.2.2.tgz", + "integrity": "sha512-7HJwZq06BCfM99RacCVzXO90B20/dNJvq+Ouiu/VrFdFRCpbnnqlQUEk4KAhBSllgDrTPgKu422SCF5KKBHDRA==", + "dev": true, + "dependencies": { + "@jest/test-result": "^27.2.2", + "@jest/types": "^27.1.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^27.2.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-worker": { + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.2.2.tgz", + "integrity": "sha512-aG1xq9KgWB2CPC8YdMIlI8uZgga2LFNcGbHJxO8ctfXAydSaThR4EewKQGg3tBOC+kS3vhPGgymsBdi9VINjPw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdoc-type-pratt-parser": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-1.1.1.tgz", + "integrity": "sha512-uelRmpghNwPBuZScwgBG/OzodaFk5RbO5xaivBdsAY70icWfShwZ7PCMO0x1zSkOa8T1FzHThmrdoyg/0AwV5g==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/jsdom": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-17.0.0.tgz", + "integrity": "sha512-MUq4XdqwtNurZDVeKScENMPHnkgmdIvMzZ1r1NSwHkDuaqI6BouPjr+17COo4/19oLNnmdpFDPOHVpgIZmZ+VA==", + "dev": true, + "dependencies": { + "abab": "^2.0.5", + "acorn": "^8.4.1", + "acorn-globals": "^6.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.0", + "decimal.js": "^10.3.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^9.0.0", + "ws": "^8.0.0", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, "node_modules/jsdom/node_modules/acorn": { "version": "8.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", @@ -6178,6 +6163,27 @@ "node": ">=0.4.0" } }, + "node_modules/jsdom/node_modules/ws": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.0.tgz", + "integrity": "sha512-uYhVJ/m9oXwEI04iIVmgLmugh2qrZihkywG9y5FfZV2ATeLIzHf93qs+tUNqlttbQK957/VX3mtwAS+UfIwA4g==", + "dev": true, + "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/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -6202,12 +6208,6 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, - "node_modules/json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -6222,7 +6222,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "devOptional": true + "optional": true }, "node_modules/json5": { "version": "2.2.0", @@ -6248,21 +6248,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, "node_modules/just-extend": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", @@ -6849,15 +6834,6 @@ "node": ">=0.10.0" } }, - "node_modules/minimist-options/node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", @@ -6972,13 +6948,35 @@ } }, "node_modules/node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", + "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, "engines": { "node": "4.x || >=6.0.0" } }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/node-ical": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/node-ical/-/node-ical-0.13.0.tgz", @@ -7239,15 +7237,6 @@ "node": ">=6" } }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -7511,12 +7500,6 @@ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", "devOptional": true }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, "node_modules/picomatch": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", @@ -7780,9 +7763,9 @@ } }, "node_modules/prettier": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.1.tgz", - "integrity": "sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", "dev": true, "bin": { "prettier": "bin-prettier.js" @@ -7804,13 +7787,13 @@ } }, "node_modules/pretty-format": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", - "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.2.2.tgz", + "integrity": "sha512-+DdLh+rtaElc2SQOE/YPH8k2g3Rf2OXWEpy06p8Szs3hdVSYD87QOOlYRHWAeb/59XTmeVmRKvDD0svHqf6ycA==", "dev": true, "dependencies": { - "@jest/types": "^27.0.2", - "ansi-regex": "^5.0.0", + "@jest/types": "^27.1.1", + "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" }, @@ -8130,15 +8113,12 @@ ] }, "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/range_check": { @@ -8393,84 +8373,6 @@ "node": ">=0.10" } }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dev": true, - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request/node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/request/node_modules/qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/request/node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/request/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -8552,9 +8454,9 @@ } }, "node_modules/resq": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/resq/-/resq-1.10.0.tgz", - "integrity": "sha512-hCUd0xMalqtPDz4jXIqs0M5Wnv/LZXN8h7unFOo4/nvExT9dDPbhwd3udRxLlp0HgBnHcV009UlduE9NZi7A6w==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/resq/-/resq-1.10.1.tgz", + "integrity": "sha512-zhp1iyUH02MLciv3bIM2bNtTFx/fqRsK4Jk73jcPqp00d/sMTTjOtjdTMAcgjrQKGx5DvQ/HSpeqaMW0atGRJA==", "dev": true, "dependencies": { "fast-deep-equal": "^2.0.1" @@ -8613,6 +8515,12 @@ "node": ">=8.0" } }, + "node_modules/roarr/node_modules/sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "optional": true + }, "node_modules/rrule": { "version": "2.6.8", "resolved": "https://registry.npmjs.org/rrule/-/rrule-2.6.8.tgz", @@ -8745,6 +8653,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/serialize-error/node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/serve-static": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", @@ -8795,24 +8715,14 @@ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, - "node_modules/simple-git": { - "version": "2.40.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-2.40.0.tgz", - "integrity": "sha512-7IO/eQwrN5kvS38TTu9ljhG9tx2nn0BTqZOmqpPpp51TvE44YIvLA6fETqEVA8w/SeEfPaVv6mk7Tsk9Jns+ag==", - "dependencies": { - "@kwsites/file-exists": "^1.1.1", - "@kwsites/promise-deferred": "^1.1.1", - "debug": "^4.3.1" - } - }, "node_modules/sinon": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-11.1.1.tgz", - "integrity": "sha512-ZSSmlkSyhUWbkF01Z9tEbxZLF/5tRC9eojCdFh33gtQaP7ITQVaMWQHGuFM7Cuf/KEfihuh1tTl3/ABju3AQMg==", + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-11.1.2.tgz", + "integrity": "sha512-59237HChms4kg7/sXhiRcUzdSkKuydDeTiamT/jesUVHshBgL8XAmhgFo0GfK6RruMDM/iRSij1EybmMog9cJw==", "dev": true, "dependencies": { "@sinonjs/commons": "^1.8.3", - "@sinonjs/fake-timers": "^7.1.0", + "@sinonjs/fake-timers": "^7.1.2", "@sinonjs/samsam": "^6.0.2", "diff": "^5.0.0", "nise": "^5.1.0", @@ -8855,28 +8765,28 @@ } }, "node_modules/socket.io": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.1.2.tgz", - "integrity": "sha512-xK0SD1C7hFrh9+bYoYCdVt+ncixkSLKtNLCax5aEy1o3r5PaO5yQhVb97exIe67cE7lAK+EpyMytXWTWmyZY8w==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.2.0.tgz", + "integrity": "sha512-sjlGfMmnaWvTRVxGRGWyhd9ctpg4APxWAxu85O/SxekkxHhfxmePWZbaYCkeX5QQX0z1YEnKOlNt6w82E4Nzug==", "dependencies": { - "@types/cookie": "^0.4.0", - "@types/cors": "^2.8.8", + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", "@types/node": ">=10.0.0", "accepts": "~1.3.4", "base64id": "~2.0.0", - "debug": "~4.3.1", - "engine.io": "~5.1.0", - "socket.io-adapter": "~2.3.0", - "socket.io-parser": "~4.0.3" + "debug": "~4.3.2", + "engine.io": "~5.2.0", + "socket.io-adapter": "~2.3.2", + "socket.io-parser": "~4.0.4" }, "engines": { "node": ">=10.0.0" } }, "node_modules/socket.io-adapter": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.3.1.tgz", - "integrity": "sha512-8cVkRxI8Nt2wadkY6u60Y4rpW3ejA1rxgcK2JuyIhmF+RMNpTy1QRtkHIDUOf3B4HlQwakMsWbKftMv/71VMmw==" + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.3.2.tgz", + "integrity": "sha512-PBZpxUPYjmoogY0aoaTmo1643JelsaS1CiAwNjRVdrI0X9Seuc19Y2Wife8k88avW6haG8cznvwbubAZwH4Mtg==" }, "node_modules/socket.io-parser": { "version": "4.0.4", @@ -8901,9 +8811,9 @@ } }, "node_modules/source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", "dev": true, "dependencies": { "buffer-from": "^1.0.0", @@ -8969,20 +8879,193 @@ } }, "node_modules/spectron": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/spectron/-/spectron-13.0.0.tgz", - "integrity": "sha512-7RPa6Fp8gqL4V0DubobnqIRFHIijkpjg6MFHcJlxoerWyvLJd+cQvOh756XpB1Z/U3DyA9jPcS+HE2PvYRP5+A==", + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/spectron/-/spectron-15.0.0.tgz", + "integrity": "sha512-eErHqymkEVb6H+LPZQoDYvWEv93o3nhxL7HXXdmC61ncV0jBckh8x3Qt6j+As2c1n0C/hKG9A2H1NnwGwD6agg==", "dev": true, "hasInstallScript": true, "dependencies": { + "@electron/remote": "^1.1.0", "dev-null": "^0.1.1", - "electron-chromedriver": "^11.0.0", - "request": "^2.88.2", + "electron-chromedriver": "^13.0.0", + "got": "^11.8.0", "split": "^1.0.1", "webdriverio": "^6.9.1" }, "engines": { - "node": ">=10.12.0" + "node": ">=12.20.0" + } + }, + "node_modules/spectron/node_modules/@sindresorhus/is": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.1.tgz", + "integrity": "sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/spectron/node_modules/@szmarczak/http-timer": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz", + "integrity": "sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==", + "dev": true, + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/spectron/node_modules/cacheable-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", + "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "dev": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/spectron/node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/spectron/node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/spectron/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/spectron/node_modules/got": { + "version": "11.8.2", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.2.tgz", + "integrity": "sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.1", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/spectron/node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/spectron/node_modules/keyv": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", + "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/spectron/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/spectron/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/spectron/node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/spectron/node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/spectron/node_modules/responselike": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", + "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", + "dev": true, + "dependencies": { + "lowercase-keys": "^2.0.0" } }, "node_modules/split": { @@ -8998,40 +9081,14 @@ } }, "node_modules/sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "optional": true - }, - "node_modules/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "node_modules/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -9315,6 +9372,12 @@ "node": ">= 8.0" } }, + "node_modules/suncalc": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/suncalc/-/suncalc-1.8.0.tgz", + "integrity": "sha1-HZiYEJVjB4dQ9JlKlZ5lTYdqy/U=", + "dev": true + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -9368,9 +9431,9 @@ } }, "node_modules/table/node_modules/ajv": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.0.tgz", - "integrity": "sha512-cnUG4NSBiM4YFBxgZIj/In3/6KX+rQ2l2YPRVcvAMQGWEPKuXoPIhxzwqh31jA3IPbI4qEOp/5ILI4ynioXsGQ==", + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.1.tgz", + "integrity": "sha512-42VLtQUOLefAvKFAQIxIZDaThq6om/PrfP0CYk3/vn+y4BMNkKnbli8ON2QCiHov4KkzOSJ/xSoBJdayiiYvVQ==", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -9477,9 +9540,9 @@ "dev": true }, "node_modules/tmpl": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", - "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true }, "node_modules/to-fast-properties": { @@ -9594,24 +9657,6 @@ "node": ">=0.6.11 <=0.7.0 || >=0.7.3" } }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -9633,10 +9678,9 @@ } }, "node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "optional": true, + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "engines": { "node": ">=10" }, @@ -9660,7 +9704,7 @@ "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "optional": true + "devOptional": true }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", @@ -9671,6 +9715,20 @@ "is-typedarray": "^1.0.0" } }, + "node_modules/typescript": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", + "dev": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/ua-parser-js": { "version": "0.7.28", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.28.tgz", @@ -9741,6 +9799,15 @@ "node": ">=4" } }, + "node_modules/unified/node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/unist-util-find-all-after": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-3.0.2.tgz", @@ -9842,9 +9909,9 @@ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" }, "node_modules/v8-to-istanbul": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.0.0.tgz", - "integrity": "sha512-LkmXi8UUNxnCC+JlH7/fsfsKr5AU110l+SYGJimWNkWhxbN5EyeOtm1MJ0hhvqMMOhGwBj1Fp70Yv9i+hX0QAg==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", + "integrity": "sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.1", @@ -9882,20 +9949,6 @@ "node": ">= 0.8" } }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, "node_modules/vfile": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", @@ -10244,18 +10297,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/webdriverio/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/webdriverio/node_modules/universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -10302,17 +10343,16 @@ "dev": true }, "node_modules/whatwg-url": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.6.0.tgz", - "integrity": "sha512-os0KkeeqUOl7ccdDT1qqUcS4KH4tcBTSKK5Nl5WKb2lyxInIZ/CpjkqKa1Ss12mjfdcRX9mHmPPs7/SxG1Hbdw==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-9.1.0.tgz", + "integrity": "sha512-CQ0UcrPHyomtlOCot1TL77WyMIm/bCwrJ2D6AOKGwEczU9EpyoqAokfqrf/MioU9kHcMsmJZcg1egXix2KYEsA==", "dev": true, "dependencies": { - "lodash": "^4.7.0", "tr46": "^2.1.0", "webidl-conversions": "^6.1.0" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/which": { @@ -10378,9 +10418,10 @@ } }, "node_modules/ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.2.tgz", + "integrity": "sha512-lkF7AWRicoB9mAgjeKbGqVUekLnSNO4VjKVnuPHpQeOxZOErX6BPXwJk70nFslRCEEA8EVW7ZjKwXaP9N+1sKQ==", + "dev": true, "engines": { "node": ">=8.3.0" }, @@ -10997,21 +11038,28 @@ "sumchecker": "^3.0.1" } }, + "@electron/remote": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@electron/remote/-/remote-1.2.0.tgz", + "integrity": "sha512-C774t2DFVJsa+dxU9Gc2nYzylRZoJ79I0Sxrh8T9cN69fBkntfGbyBEQiD9UfZopqL0CYLzk1anY2Ywhql6h1w==", + "dev": true, + "requires": {} + }, "@es-joy/jsdoccomment": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.8.0.tgz", - "integrity": "sha512-Xd3GzYsL2sz2pcdtYt5Q0Wz1ol/o9Nt2UQL4nFPDcaEomvPmwjJsbjkKx1SKhl2h3TgwazNBLdcNr2m0UiGiFA==", + "version": "0.10.8", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.10.8.tgz", + "integrity": "sha512-3P1JiGL4xaR9PoTKUHa2N/LKwa2/eUdRqGwijMWWgBqbFEqJUVpmaOi2TcjcemrsRMgFLBzQCK4ToPhrSVDiFQ==", "dev": true, "requires": { - "comment-parser": "^1.1.5", + "comment-parser": "1.2.4", "esquery": "^1.4.0", - "jsdoc-type-pratt-parser": "1.0.4" + "jsdoc-type-pratt-parser": "1.1.1" } }, "@eslint/eslintrc": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", - "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "requires": { "ajv": "^6.12.4", "debug": "^4.1.1", @@ -11024,6 +11072,21 @@ "strip-json-comments": "^3.1.1" } }, + "@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==" + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -11052,49 +11115,49 @@ "dev": true }, "@jest/console": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.0.2.tgz", - "integrity": "sha512-/zYigssuHLImGeMAACkjI4VLAiiJznHgAl3xnFT19iWyct2LhrH3KXOjHRmxBGTkiPLZKKAJAgaPpiU9EZ9K+w==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.2.2.tgz", + "integrity": "sha512-m7tbzPWyvSFfoanTknJoDnaeruDARsUe555tkVjG/qeaRDKwyPqqbgs4yFx583gmoETiAts1deeYozR5sVRhNA==", "dev": true, "requires": { - "@jest/types": "^27.0.2", + "@jest/types": "^27.1.1", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^27.0.2", - "jest-util": "^27.0.2", + "jest-message-util": "^27.2.2", + "jest-util": "^27.2.0", "slash": "^3.0.0" } }, "@jest/core": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.0.5.tgz", - "integrity": "sha512-g73//jF0VwsOIrWUC9Cqg03lU3QoAMFxVjsm6n6yNmwZcQPN/o8w+gLWODw5VfKNFZT38otXHWxc6b8eGDUpEA==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.2.2.tgz", + "integrity": "sha512-4b9km/h9pAGdCkwWYtbfoeiOtajOlGmr5rL1Eq6JCAVbOevOqxWHxJ6daWxRJW9eF6keXJoJ1H+uVAVcdZu8Bg==", "dev": true, "requires": { - "@jest/console": "^27.0.2", - "@jest/reporters": "^27.0.5", - "@jest/test-result": "^27.0.2", - "@jest/transform": "^27.0.5", - "@jest/types": "^27.0.2", + "@jest/console": "^27.2.2", + "@jest/reporters": "^27.2.2", + "@jest/test-result": "^27.2.2", + "@jest/transform": "^27.2.2", + "@jest/types": "^27.1.1", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.8.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-changed-files": "^27.0.2", - "jest-config": "^27.0.5", - "jest-haste-map": "^27.0.5", - "jest-message-util": "^27.0.2", - "jest-regex-util": "^27.0.1", - "jest-resolve": "^27.0.5", - "jest-resolve-dependencies": "^27.0.5", - "jest-runner": "^27.0.5", - "jest-runtime": "^27.0.5", - "jest-snapshot": "^27.0.5", - "jest-util": "^27.0.2", - "jest-validate": "^27.0.2", - "jest-watcher": "^27.0.2", + "jest-changed-files": "^27.1.1", + "jest-config": "^27.2.2", + "jest-haste-map": "^27.2.2", + "jest-message-util": "^27.2.2", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.2.2", + "jest-resolve-dependencies": "^27.2.2", + "jest-runner": "^27.2.2", + "jest-runtime": "^27.2.2", + "jest-snapshot": "^27.2.2", + "jest-util": "^27.2.0", + "jest-validate": "^27.2.2", + "jest-watcher": "^27.2.2", "micromatch": "^4.0.4", "p-each-series": "^2.1.0", "rimraf": "^3.0.0", @@ -11103,53 +11166,53 @@ } }, "@jest/environment": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.0.5.tgz", - "integrity": "sha512-IAkJPOT7bqn0GiX5LPio6/e1YpcmLbrd8O5EFYpAOZ6V+9xJDsXjdgN2vgv9WOKIs/uA1kf5WeD96HhlBYO+FA==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.2.2.tgz", + "integrity": "sha512-gO9gVnZfn5ldeOJ5q+35Kru9QWGHEqZCB7W/M+8mD6uCwOGC9HR6mzpLSNRuDsxY/KhaGBYHpgFqtpe4Rl1gDQ==", "dev": true, "requires": { - "@jest/fake-timers": "^27.0.5", - "@jest/types": "^27.0.2", + "@jest/fake-timers": "^27.2.2", + "@jest/types": "^27.1.1", "@types/node": "*", - "jest-mock": "^27.0.3" + "jest-mock": "^27.1.1" } }, "@jest/fake-timers": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.0.5.tgz", - "integrity": "sha512-d6Tyf7iDoKqeUdwUKrOBV/GvEZRF67m7lpuWI0+SCD9D3aaejiOQZxAOxwH2EH/W18gnfYaBPLi0VeTGBHtQBg==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.2.2.tgz", + "integrity": "sha512-gDIIqs0yxyjyxEI9HlJ8SEJ4uCc8qr8BupG1Hcx7tvyk/SLocyXE63rFxL+HQ0ZLMvSyEcJUmYnvvHH1osWiGA==", "dev": true, "requires": { - "@jest/types": "^27.0.2", + "@jest/types": "^27.1.1", "@sinonjs/fake-timers": "^7.0.2", "@types/node": "*", - "jest-message-util": "^27.0.2", - "jest-mock": "^27.0.3", - "jest-util": "^27.0.2" + "jest-message-util": "^27.2.2", + "jest-mock": "^27.1.1", + "jest-util": "^27.2.0" } }, "@jest/globals": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.0.5.tgz", - "integrity": "sha512-qqKyjDXUaZwDuccpbMMKCCMBftvrbXzigtIsikAH/9ca+kaae8InP2MDf+Y/PdCSMuAsSpHS6q6M25irBBUh+Q==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.2.2.tgz", + "integrity": "sha512-fWa/Luwod1hyehnuep+zCnOTqTVvyc4HLUU/1VpFNOEu0tCWNSODyvKSSOjtb1bGOpCNjgaDcyjzo5f7rl6a7g==", "dev": true, "requires": { - "@jest/environment": "^27.0.5", - "@jest/types": "^27.0.2", - "expect": "^27.0.2" + "@jest/environment": "^27.2.2", + "@jest/types": "^27.1.1", + "expect": "^27.2.2" } }, "@jest/reporters": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.0.5.tgz", - "integrity": "sha512-4uNg5+0eIfRafnpgu3jCZws3NNcFzhu5JdRd1mKQ4/53+vkIqwB6vfZ4gn5BdGqOaLtYhlOsPaL5ATkKzyBrJw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.2.2.tgz", + "integrity": "sha512-ufwZ8XoLChEfPffDeVGroYbhbcYPom3zKDiv4Flhe97rr/o2IfUXoWkDUDoyJ3/V36RFIMjokSu0IJ/pbFtbHg==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.0.2", - "@jest/test-result": "^27.0.2", - "@jest/transform": "^27.0.5", - "@jest/types": "^27.0.2", + "@jest/console": "^27.2.2", + "@jest/test-result": "^27.2.2", + "@jest/transform": "^27.2.2", + "@jest/types": "^27.1.1", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", @@ -11160,10 +11223,10 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.0.2", - "jest-haste-map": "^27.0.5", - "jest-resolve": "^27.0.5", - "jest-util": "^27.0.2", - "jest-worker": "^27.0.2", + "jest-haste-map": "^27.2.2", + "jest-resolve": "^27.2.2", + "jest-util": "^27.2.0", + "jest-worker": "^27.2.2", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", @@ -11172,9 +11235,9 @@ } }, "@jest/source-map": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.1.tgz", - "integrity": "sha512-yMgkF0f+6WJtDMdDYNavmqvbHtiSpwRN2U/W+6uztgfqgkq/PXdKPqjBTUF1RD/feth4rH5N3NW0T5+wIuln1A==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.6.tgz", + "integrity": "sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g==", "dev": true, "requires": { "callsites": "^3.0.0", @@ -11183,45 +11246,45 @@ } }, "@jest/test-result": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.0.2.tgz", - "integrity": "sha512-gcdWwL3yP5VaIadzwQtbZyZMgpmes8ryBAJp70tuxghiA8qL4imJyZex+i+USQH2H4jeLVVszhwntgdQ97fccA==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.2.2.tgz", + "integrity": "sha512-yENoDEoWlEFI7l5z7UYyJb/y5Q8RqbPd4neAVhKr6l+vVaQOPKf8V/IseSMJI9+urDUIxgssA7RGNyCRhGjZvw==", "dev": true, "requires": { - "@jest/console": "^27.0.2", - "@jest/types": "^27.0.2", + "@jest/console": "^27.2.2", + "@jest/types": "^27.1.1", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/test-sequencer": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.0.5.tgz", - "integrity": "sha512-opztnGs+cXzZ5txFG2+omBaV5ge/0yuJNKbhE3DREMiXE0YxBuzyEa6pNv3kk2JuucIlH2Xvgmn9kEEHSNt/SA==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.2.2.tgz", + "integrity": "sha512-YnJqwNQP2Zeu0S4TMqkxg6NN7Y1EFq715n/nThNKrvIS9wmRZjDt2XYqsHbuvhAFjshi0iKDQ813NewFITBH+Q==", "dev": true, "requires": { - "@jest/test-result": "^27.0.2", + "@jest/test-result": "^27.2.2", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.0.5", - "jest-runtime": "^27.0.5" + "jest-haste-map": "^27.2.2", + "jest-runtime": "^27.2.2" } }, "@jest/transform": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.0.5.tgz", - "integrity": "sha512-lBD6OwKXSc6JJECBNk4mVxtSVuJSBsQrJ9WCBisfJs7EZuYq4K6vM9HmoB7hmPiLIDGeyaerw3feBV/bC4z8tg==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.2.2.tgz", + "integrity": "sha512-l4Z/7PpajrOjCiXLWLfMY7fgljY0H8EwW7qdzPXXuv2aQF8kY2+Uyj3O+9Popnaw1V7JCw32L8EeI/thqFDkPA==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/types": "^27.0.2", + "@jest/types": "^27.1.1", "babel-plugin-istanbul": "^6.0.0", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.0.5", - "jest-regex-util": "^27.0.1", - "jest-util": "^27.0.2", + "jest-haste-map": "^27.2.2", + "jest-regex-util": "^27.0.6", + "jest-util": "^27.2.0", "micromatch": "^4.0.4", "pirates": "^4.0.1", "slash": "^3.0.0", @@ -11230,9 +11293,9 @@ } }, "@jest/types": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz", - "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==", + "version": "27.1.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.1.1.tgz", + "integrity": "sha512-yqJPDDseb0mXgKqmNqypCsb85C22K1aY5+LUxh7syIM9n/b0AsaltxNy+o6tt29VcfGDpYEve175bm3uOhcehA==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -11242,19 +11305,6 @@ "chalk": "^4.0.0" } }, - "@kwsites/file-exists": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", - "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", - "requires": { - "debug": "^4.1.1" - } - }, - "@kwsites/promise-deferred": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", - "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==" - }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -11357,9 +11407,9 @@ "dev": true }, "@types/babel__core": { - "version": "7.1.14", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.14.tgz", - "integrity": "sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g==", + "version": "7.1.16", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.16.tgz", + "integrity": "sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -11370,18 +11420,18 @@ } }, "@types/babel__generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", - "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", + "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", "dev": true, "requires": { "@babel/types": "^7.0.0" } }, "@types/babel__template": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz", - "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -11389,9 +11439,9 @@ } }, "@types/babel__traverse": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.1.tgz", - "integrity": "sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", + "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -11415,14 +11465,14 @@ "integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg==" }, "@types/cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg==" + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" }, "@types/cors": { - "version": "2.8.10", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.10.tgz", - "integrity": "sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ==" + "version": "2.8.12", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", + "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" }, "@types/graceful-fs": { "version": "4.1.5", @@ -11500,9 +11550,9 @@ "dev": true }, "@types/node": { - "version": "12.20.15", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.15.tgz", - "integrity": "sha512-F6S4Chv4JicJmyrwlDkxUdGNSplsQdGwp1A0AJloEVDirWdZOAiRHhovDlsFkKUrquUXhz1imJhXHsf59auyAg==" + "version": "14.17.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.4.tgz", + "integrity": "sha512-8kQ3+wKGRNN0ghtEn7EGps/B8CzuBz1nXZEIGGLP2GnwbqYn4dbTs7k+VKLTq1HvZLRCIDtN3Snx1Ege8B7L5A==" }, "@types/normalize-package-data": { "version": "2.4.0", @@ -11517,9 +11567,9 @@ "dev": true }, "@types/prettier": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.3.0.tgz", - "integrity": "sha512-hkc1DATxFLQo4VxPDpMH1gCkPpBbpOoJ/4nhuXw4n63/0R6bCpQECj4+K226UJ4JO/eJQz+1mC2I7JsWanAdQw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-Fo79ojj3vdEZOHg3wR9ksAMRz4P3S5fDB5e/YWZiFnyFQI1WY2Vftu9XoXVVtJfxB7Bpce/QTqWSSntkz2Znrw==", "dev": true }, "@types/puppeteer": { @@ -11550,15 +11600,15 @@ } }, "@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, "@types/unist": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", - "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.4.tgz", + "integrity": "sha512-zfyYsDTK1HTGYXU3fTiM76+om93HcFtsZd2M0bO/CL4DiETV7mSa/pIVN/6+G3esOqEMdg2An5cHHbK5t+9w+A==", "dev": true }, "@types/which": { @@ -11568,24 +11618,24 @@ "dev": true }, "@types/yargs": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz", - "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==", + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", "dev": true, "requires": { "@types/yargs-parser": "*" } }, "@types/yargs-parser": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", - "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==", + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", "dev": true }, "@types/yauzl": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz", - "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", + "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", "dev": true, "optional": true, "requires": { @@ -11593,15 +11643,15 @@ } }, "@typescript-eslint/experimental-utils": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.0.tgz", - "integrity": "sha512-9XD9s7mt3QWMk82GoyUpc/Ji03vz4T5AYlHF9DcoFNfJ/y3UAclRsfGiE2gLfXtyC+JRA3trR7cR296TEb1oiQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.1.tgz", + "integrity": "sha512-n8/ggadrZ+uyrfrSEchx3jgODdmcx7MzVM2sI3cTpI/YlfSm0+9HEUaWw3aQn2urL2KYlWYMDgn45iLfjDYB+Q==", "dev": true, "requires": { "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.28.0", - "@typescript-eslint/types": "4.28.0", - "@typescript-eslint/typescript-estree": "4.28.0", + "@typescript-eslint/scope-manager": "4.28.1", + "@typescript-eslint/types": "4.28.1", + "@typescript-eslint/typescript-estree": "4.28.1", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, @@ -11618,29 +11668,29 @@ } }, "@typescript-eslint/scope-manager": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.0.tgz", - "integrity": "sha512-eCALCeScs5P/EYjwo6se9bdjtrh8ByWjtHzOkC4Tia6QQWtQr3PHovxh3TdYTuFcurkYI4rmFsRFpucADIkseg==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.1.tgz", + "integrity": "sha512-o95bvGKfss6705x7jFGDyS7trAORTy57lwJ+VsYwil/lOUxKQ9tA7Suuq+ciMhJc/1qPwB3XE2DKh9wubW8YYA==", "dev": true, "requires": { - "@typescript-eslint/types": "4.28.0", - "@typescript-eslint/visitor-keys": "4.28.0" + "@typescript-eslint/types": "4.28.1", + "@typescript-eslint/visitor-keys": "4.28.1" } }, "@typescript-eslint/types": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.0.tgz", - "integrity": "sha512-p16xMNKKoiJCVZY5PW/AfILw2xe1LfruTcfAKBj3a+wgNYP5I9ZEKNDOItoRt53p4EiPV6iRSICy8EPanG9ZVA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.1.tgz", + "integrity": "sha512-4z+knEihcyX7blAGi7O3Fm3O6YRCP+r56NJFMNGsmtdw+NCdpG5SgNz427LS9nQkRVTswZLhz484hakQwB8RRg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.0.tgz", - "integrity": "sha512-m19UQTRtxMzKAm8QxfKpvh6OwQSXaW1CdZPoCaQuLwAq7VZMNuhJmZR4g5281s2ECt658sldnJfdpSZZaxUGMQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.1.tgz", + "integrity": "sha512-GhKxmC4sHXxHGJv8e8egAZeTZ6HI4mLU6S7FUzvFOtsk7ZIDN1ksA9r9DyOgNqowA9yAtZXV0Uiap61bIO81FQ==", "dev": true, "requires": { - "@typescript-eslint/types": "4.28.0", - "@typescript-eslint/visitor-keys": "4.28.0", + "@typescript-eslint/types": "4.28.1", + "@typescript-eslint/visitor-keys": "4.28.1", "debug": "^4.3.1", "globby": "^11.0.3", "is-glob": "^4.0.1", @@ -11660,12 +11710,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.0.tgz", - "integrity": "sha512-PjJyTWwrlrvM5jazxYF5ZPs/nl0kHDZMVbuIcbpawVXaDPelp3+S9zpOz5RmVUfS/fD5l5+ZXNKnWhNYjPzCvw==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.1.tgz", + "integrity": "sha512-K4HMrdFqr9PFquPu178SaSb92CaWe2yErXyPumc8cYWxFmhgJsNY9eSePmO05j0JhBvf2Cdhptd6E6Yv9HVHcg==", "dev": true, "requires": { - "@typescript-eslint/types": "4.28.0", + "@typescript-eslint/types": "4.28.1", "eslint-visitor-keys": "^2.0.0" } }, @@ -11747,9 +11797,9 @@ } }, "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "requires": {} }, "acorn-walk": { @@ -11811,9 +11861,9 @@ } }, "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "4.3.0", @@ -11900,13 +11950,6 @@ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "requires": { "sprintf-js": "~1.0.2" - }, - "dependencies": { - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - } } }, "array-differ": { @@ -11932,21 +11975,6 @@ "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", "dev": true }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, "astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -11991,29 +12019,17 @@ "postcss-value-parser": "^4.1.0" } }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true - }, "babel-jest": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.0.5.tgz", - "integrity": "sha512-bTMAbpCX7ldtfbca2llYLeSFsDM257aspyAOpsdrdSrBqoLkWCy4HPYTXtXWaSLgFPjrJGACL65rzzr4RFGadw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.2.2.tgz", + "integrity": "sha512-XNFNNfGKnZXzhej7TleVP4s9ktH5JjRW8Rmcbb223JJwKB/gmTyeWN0JfiPtSgnjIjDXtKNoixiy0QUHtv3vFA==", "dev": true, "requires": { - "@jest/transform": "^27.0.5", - "@jest/types": "^27.0.2", + "@jest/transform": "^27.2.2", + "@jest/types": "^27.1.1", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^27.0.1", + "babel-preset-jest": "^27.2.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "slash": "^3.0.0" @@ -12033,9 +12049,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.0.1.tgz", - "integrity": "sha512-sqBF0owAcCDBVEDtxqfYr2F36eSHdx7lAVGyYuOBRnKdD6gzcy0I0XrAYCZgOA3CRrLhmR+Uae9nogPzmAtOfQ==", + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.2.0.tgz", + "integrity": "sha512-TOux9khNKdi64mW+0OIhcmbAn75tTlzKhxmiNXevQaPbrBYK7YKjP1jl6NHTJ6XR5UgUrJbCnWlKVnJn29dfjw==", "dev": true, "requires": { "@babel/template": "^7.3.3", @@ -12065,12 +12081,12 @@ } }, "babel-preset-jest": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.0.1.tgz", - "integrity": "sha512-nIBIqCEpuiyhvjQs2mVNwTxQQa2xk70p9Dd/0obQGBf8FBzbnI8QhQKzLsWMN2i6q+5B0OcWDtrboBX5gmOLyA==", + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.2.0.tgz", + "integrity": "sha512-z7MgQ3peBwN5L5aCqBKnF6iqdlvZvFUQynEhu0J+X9nHLU72jO3iY331lcYrg+AssJ8q7xsv5/3AICzVmJ/wvg==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^27.0.1", + "babel-plugin-jest-hoist": "^27.2.0", "babel-preset-current-node-syntax": "^1.0.0" } }, @@ -12115,15 +12131,6 @@ "safe-buffer": "5.1.2" } }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, "bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -12337,26 +12344,12 @@ "camelcase": "^5.3.1", "map-obj": "^4.0.0", "quick-lru": "^4.0.1" - }, - "dependencies": { - "quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "dev": true - } } }, "caniuse-lite": { - "version": "1.0.30001239", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001239.tgz", - "integrity": "sha512-cyBkXJDMeI4wthy8xJ2FvDU6+0dtcZSJW3voUF8+e9f1bBeuvyZfc3PNbkOETyhbR+dGCPzn9E7MA3iwzusOhQ==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "version": "1.0.30001242", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001242.tgz", + "integrity": "sha512-KvNuZ/duufelMB3w2xtf9gEWCSxJwUgoxOx5b6ScLXC4kPc9xsczUVCPrQU26j5kOsHM4pSUL54tAZt5THQKug==", "dev": true }, "chalk": { @@ -12432,9 +12425,9 @@ "dev": true }, "cjs-module-lexer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.1.tgz", - "integrity": "sha512-jVamGdJPDeuQilKhvVn1h3knuMOZzr8QDnpk+M9aMlCaMkTDd6fBWPhiDqFvFZ07pL0liqabAiuy8SY4jGHeaw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, "clarinet": { @@ -12523,9 +12516,9 @@ } }, "comment-parser": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.1.5.tgz", - "integrity": "sha512-RePCE4leIhBlmrqiYTvaqEeGYg7qpSl4etaIabKtdOQVi+mSTIBBklGUwIr79GXYnl3LpMwmDw4KeR2stNc6FA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.2.4.tgz", + "integrity": "sha512-pm0b+qv+CkWNriSTMsfnjChF9kH0kxz55y44Wo5le9qLxMj5xDQAaEd9ZN1ovSuk9CsrncWaFwgpOMg7ClJwkw==", "dev": true }, "commondir": { @@ -12573,7 +12566,7 @@ "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "optional": true, + "devOptional": true, "requires": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", @@ -12592,11 +12585,11 @@ } }, "console-stamp": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/console-stamp/-/console-stamp-3.0.2.tgz", - "integrity": "sha512-nYIxVrp1Cau8wRy8RQJO1VNBTYQPnFcN7SrsLAStSavo38Y4+jcysh5n4nZNd/WkR2IOULgwr2+6qDxMUA7Hog==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/console-stamp/-/console-stamp-3.0.3.tgz", + "integrity": "sha512-6ltMcMEVDHb1bqb+qaVfCX7Vf3vEkfZEeKyReG1ny45Rv6YJynCcdv94j7whNVfxj/4/3Ji/QBHY6p4JI51Ucw==", "requires": { - "chalk": "^4.1.0", + "chalk": "^4.1.1", "dateformat": "^4.5.1" } }, @@ -12633,9 +12626,9 @@ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, "core-js": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.15.1.tgz", - "integrity": "sha512-h8VbZYnc9pDzueiS2610IULDkpFFPunHwIpl8yRwFahAEEdSpHlTy3h3z3rKq5h11CaUdBEeRViu9AYvbxiMeg==", + "version": "3.15.2", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.15.2.tgz", + "integrity": "sha512-tKs41J7NJVuaya8DxIOCnl8QuPHx5/ZVbFo1oKgVl1qHFBBrDctzQGtuLjPpRdNTWmKPH6oEvgN/MUID+l485Q==", "optional": true }, "core-util-is": { @@ -12733,9 +12726,9 @@ "dev": true }, "cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", "dev": true }, "cssstyle": { @@ -12755,24 +12748,15 @@ } } }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, "data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.0.tgz", + "integrity": "sha512-4AefxbTTdFtxDUdh0BuMBs2qJVL25Mow2zlcuuePegQwgD6GEmQao42LLEeksOui8nL4RcNEugIpFP7eRd33xg==", "dev": true, "requires": { "abab": "^2.0.3", "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" + "whatwg-url": "^9.0.0" } }, "dateformat": { @@ -12781,9 +12765,9 @@ "integrity": "sha512-OD0TZ+B7yP7ZgpJf5K2DIbj3FZvFvxgFUuaqA/V5zTjAtAAXZ1E8bktHxmAGs4x5b7PflqA9LeQ84Og7wYtF7Q==" }, "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "requires": { "ms": "2.1.2" } @@ -12813,9 +12797,9 @@ } }, "decimal.js": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.0.tgz", - "integrity": "sha512-MrQRs2gyD//7NeHi9TtsfClkf+cFAewDz+PZHR8ILKglLmBMyVX3ymQ+oeznE3tjrS7beTN+6JXb2C3JDHm7ug==", + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", "dev": true }, "decompress-response": { @@ -12932,15 +12916,15 @@ "dev": true }, "diff-sequences": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.1.tgz", - "integrity": "sha512-XPLijkfJUh/PIBnfkcSHgvD6tlYixmcMAn3osTk6jt+H0v/mgURto1XUiD9DKuGX5NDoVS6dSlA23gd9FUaCFg==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", + "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", "dev": true }, "digest-fetch": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.2.0.tgz", - "integrity": "sha512-DSbWN+dPXH+9A/aqmGnpI40cVKzJRgL4iDm1eGpsZ1MpW3tXQuBJN5xNY3PEqUx3QjkQIPyD99ypClHr9fW9Ow==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.2.1.tgz", + "integrity": "sha512-Do130fdya/9DPUl80PaltD7R0WIOKkROnLjrdh0CxvS+s3WGGWFMPZvB2eH48BRnVxlSKrLdp/wBH19f0Kag6Q==", "requires": { "base-64": "^0.1.0", "md5": "^2.3.0" @@ -13035,16 +13019,6 @@ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", "devOptional": true }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "edge-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-2.2.1.tgz", @@ -13061,23 +13035,23 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron": { - "version": "11.4.9", - "resolved": "https://registry.npmjs.org/electron/-/electron-11.4.9.tgz", - "integrity": "sha512-3TJG1vAnuR8p47mzorCW5l7uWCjdNUufIbZ+gKjm010dtHmhrO1zchP1a76vuT4BllK8q1iygFSkNnDlZ0i2pA==", - "optional": true, + "version": "13.5.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-13.5.0.tgz", + "integrity": "sha512-s4+b1RFWkNKWp7WWrv2q60MuFljHUCbO7XAupBSCUz/NP1Hz4OenWbMPUt0H+fa8YZeN8CX3JDIA8Bet5uAJvw==", + "devOptional": true, "requires": { "@electron/get": "^1.0.1", - "@types/node": "^12.0.12", + "@types/node": "^14.6.2", "extract-zip": "^1.0.3" } }, "electron-chromedriver": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/electron-chromedriver/-/electron-chromedriver-11.0.0.tgz", - "integrity": "sha512-ayMJPBbB4puU0SqYbcD9XvF3/7GWIhqKE1n5lG2/GQPRnrZkNoPIilsrS0rQcD50Xhl69KowatDqLhUznZWtbA==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/electron-chromedriver/-/electron-chromedriver-13.0.0.tgz", + "integrity": "sha512-fID1ms8wT7qNfoKkXHNpH0ZE8/Nclb5YmkF3O0w57OxsR8S9PxgE9CJAgaSGroxBgZ+ge1i2OU0Aq/WE/e/Neg==", "dev": true, "requires": { - "@electron/get": "^1.12.2", + "@electron/get": "^1.12.4", "extract-zip": "^2.0.0" }, "dependencies": { @@ -13105,9 +13079,9 @@ } }, "electron-to-chromium": { - "version": "1.3.756", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.756.tgz", - "integrity": "sha512-WsmJym1TMeHVndjPjczTFbnRR/c4sbzg8fBFtuhlb2Sru3i/S1VGpzDSrv/It8ctMU2bj8G7g7/O3FzYMGw6eA==", + "version": "1.3.766", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.766.tgz", + "integrity": "sha512-u2quJ862q9reRKh/je3GXis3w38+RoXH1J9N3XjtsS6NzmUAosNsyZgUVFZPN/ZlJ3v6T0rTyZR3q/J5c6Sy5w==", "dev": true }, "emittery": { @@ -13136,9 +13110,9 @@ } }, "engine.io": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-5.1.1.tgz", - "integrity": "sha512-aMWot7H5aC8L4/T8qMYbLdvKlZOdJTH54FxfdFunTGvhMx1BHkJOntWArsVfgAZVwAO9LC2sryPWRcEeUzCe5w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-5.2.0.tgz", + "integrity": "sha512-d1DexkQx87IFr1FLuV+0f5kAm1Hk1uOVijLOb+D1sDO2QMb7YjE02VHtZtxo7xIXMgcWLb+vl3HRT0rI9tr4jQ==", "requires": { "accepts": "~1.3.4", "base64id": "2.0.0", @@ -13153,13 +13127,19 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" + }, + "ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "requires": {} } } }, "engine.io-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz", - "integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.3.tgz", + "integrity": "sha512-xEAAY0msNnESNPc00e19y5heTPX4y/TJ36gr8t1voOaNmTojP9b3oK3BbJLFufW2XFPQaaijpFewm2g2Um3uqA==", "requires": { "base64-arraybuffer": "0.1.4" } @@ -13276,12 +13256,13 @@ } }, "eslint": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.29.0.tgz", - "integrity": "sha512-82G/JToB9qIy/ArBzIWG9xvvwL3R86AlCjtGw+A29OMZDqhTybz/MByORSukGxeI+YPCR4coYyITKk8BFH9nDA==", + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "requires": { "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.2", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -13339,25 +13320,25 @@ "requires": {} }, "eslint-plugin-jest": { - "version": "24.3.6", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.3.6.tgz", - "integrity": "sha512-WOVH4TIaBLIeCX576rLcOgjNXqP+jNlCiEmRgFTfQtJ52DpwnIQKAVGlGPAN7CZ33bW6eNfHD6s8ZbEUTQubJg==", + "version": "24.4.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.4.2.tgz", + "integrity": "sha512-jNMnqwX75z0RXRMXkxwb/+9ylKJYJLJ8nT8nBT0XFM5qx4IQGxP4edMawa0qGkSbHae0BDPBmi8I2QF0/F04XQ==", "dev": true, "requires": { "@typescript-eslint/experimental-utils": "^4.0.1" } }, "eslint-plugin-jsdoc": { - "version": "35.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-35.4.0.tgz", - "integrity": "sha512-0cr+NkPTxpTiMCtYOd8W5fd2IyC/CmaTHKb+0bzkpP9p8HfmJ3B2/M6FWj97rQJOLwLMkx+g2MIEZsrttpbFmQ==", + "version": "36.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-36.1.0.tgz", + "integrity": "sha512-Qpied2AJCQcScxfzTObLKRiP5QgLXjMU/ITjBagEV5p2Q/HpumD1EQtazdRYdjDSwPmXhwOl2yquwOGQ4HOJNw==", "dev": true, "requires": { - "@es-joy/jsdoccomment": "^0.8.0-alpha.2", - "comment-parser": "1.1.5", - "debug": "^4.3.1", + "@es-joy/jsdoccomment": "0.10.8", + "comment-parser": "1.2.4", + "debug": "^4.3.2", "esquery": "^1.4.0", - "jsdoc-type-pratt-parser": "^1.0.4", + "jsdoc-type-pratt-parser": "^1.1.1", "lodash": "^4.17.21", "regextras": "^0.8.0", "semver": "^7.3.5", @@ -13376,9 +13357,9 @@ } }, "eslint-plugin-prettier": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz", - "integrity": "sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz", + "integrity": "sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==", "dev": true, "requires": { "prettier-linter-helpers": "^1.0.0" @@ -13527,17 +13508,17 @@ "dev": true }, "expect": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.0.2.tgz", - "integrity": "sha512-YJFNJe2+P2DqH+ZrXy+ydRQYO87oxRUonZImpDodR1G7qo3NYd3pL+NQ9Keqpez3cehczYwZDBC3A7xk3n7M/w==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.2.2.tgz", + "integrity": "sha512-sjHBeEk47/eshN9oLbvPJZMgHQihOXXQzSMPCJ4MqKShbU9HOVFSNHEEU4dp4ujzxFSiNvPFzB2AMOFmkizhvA==", "dev": true, "requires": { - "@jest/types": "^27.0.2", + "@jest/types": "^27.1.1", "ansi-styles": "^5.0.0", - "jest-get-type": "^27.0.1", - "jest-matcher-utils": "^27.0.2", - "jest-message-util": "^27.0.2", - "jest-regex-util": "^27.0.1" + "jest-get-type": "^27.0.6", + "jest-matcher-utils": "^27.2.2", + "jest-message-util": "^27.2.2", + "jest-regex-util": "^27.0.6" }, "dependencies": { "ansi-styles": { @@ -13630,7 +13611,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", - "optional": true, + "devOptional": true, "requires": { "concat-stream": "^1.6.2", "debug": "^2.6.9", @@ -13642,7 +13623,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "optional": true, + "devOptional": true, "requires": { "ms": "2.0.0" } @@ -13651,16 +13632,10 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "optional": true + "devOptional": true } } }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -13673,17 +13648,16 @@ "dev": true }, "fast-glob": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", - "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.6.tgz", + "integrity": "sha512-GnLuqj/pvQ7pX8/L4J84nijv6sAnlwvSDpMkJi9i7nPmPxGtRPkBSStfvDW5l6nMdX9VWe+pkKWFTgD+vF2QSQ==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", + "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" + "micromatch": "^4.0.4" } }, "fast-json-stable-stringify": { @@ -13703,9 +13677,9 @@ "dev": true }, "fastq": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", - "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.1.tgz", + "integrity": "sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -13815,9 +13789,9 @@ } }, "flatted": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", - "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==" + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.0.tgz", + "integrity": "sha512-XprP7lDrVT+kE2c2YlfiV+IfS9zxukiIOvNamPNsImNhXadSsQEbosItdL9bUQlCZXR13SvPk20BjWSWLA7m4A==" }, "foreground-child": { "version": "2.0.0", @@ -13829,16 +13803,10 @@ "signal-exit": "^3.0.2" } }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dev": true, "requires": { "asynckit": "^0.4.0", @@ -13941,15 +13909,6 @@ "pump": "^3.0.0" } }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, "glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -14041,18 +14000,11 @@ } }, "globals": { - "version": "13.9.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", - "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz", + "integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==", "requires": { "type-fest": "^0.20.2" - }, - "dependencies": { - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" - } } }, "globalthis": { @@ -14132,22 +14084,6 @@ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "dev": true, - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, "hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -14284,17 +14220,6 @@ "debug": "4" } }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, "http2-wrapper": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", @@ -14303,6 +14228,14 @@ "requires": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.0.0" + }, + "dependencies": { + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true + } } }, "https-proxy-agent": { @@ -14322,9 +14255,9 @@ "dev": true }, "husky": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/husky/-/husky-6.0.0.tgz", - "integrity": "sha512-SQS2gDTB7tBN486QSoKPKQItZw97BMOd+Kdb6ghfpBc0yXyzrddI0oDV5MkDAbuB4X2mO3/nj60TRMcYxwzZeQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.2.tgz", + "integrity": "sha512-8yKEWNX4z2YsofXAMT7KvA1g8p+GxtB1ffV8XtpAEGuXNAbCV5wdNKH+qTpw8SM9fh4aMPDR+yQuKfgnreyZlg==", "dev": true }, "iconv-lite": { @@ -14511,9 +14444,9 @@ "dev": true }, "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", "dev": true }, "is-potential-custom-element-name": { @@ -14572,12 +14505,6 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, "istanbul-lib-coverage": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", @@ -14661,256 +14588,336 @@ } }, "jest": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.0.5.tgz", - "integrity": "sha512-4NlVMS29gE+JOZvgmSAsz3eOjkSsHqjTajlIsah/4MVSmKvf3zFP/TvgcLoWe2UVHiE9KF741sReqhF0p4mqbQ==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.2.2.tgz", + "integrity": "sha512-XAB/9akDTe3/V0wPNKWfP9Y/NT1QPiCqyRBYGbC66EA9EvgAzdaFEqhFGLaDJ5UP2yIyXUMtju9a9IMrlYbZTQ==", "dev": true, "requires": { - "@jest/core": "^27.0.5", + "@jest/core": "^27.2.2", "import-local": "^3.0.2", - "jest-cli": "^27.0.5" - }, - "dependencies": { - "jest-cli": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.0.5.tgz", - "integrity": "sha512-kZqY020QFOFQKVE2knFHirTBElw3/Q0kUbDc3nMfy/x+RQ7zUY89SUuzpHHJoSX1kX7Lq569ncvjNqU3Td/FCA==", - "dev": true, - "requires": { - "@jest/core": "^27.0.5", - "@jest/test-result": "^27.0.2", - "@jest/types": "^27.0.2", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "jest-config": "^27.0.5", - "jest-util": "^27.0.2", - "jest-validate": "^27.0.2", - "prompts": "^2.0.1", - "yargs": "^16.0.3" - } - } + "jest-cli": "^27.2.2" } }, "jest-changed-files": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.0.2.tgz", - "integrity": "sha512-eMeb1Pn7w7x3wue5/vF73LPCJ7DKQuC9wQUR5ebP9hDPpk5hzcT/3Hmz3Q5BOFpR3tgbmaWhJcMTVgC8Z1NuMw==", + "version": "27.1.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.1.1.tgz", + "integrity": "sha512-5TV9+fYlC2A6hu3qtoyGHprBwCAn0AuGA77bZdUgYvVlRMjHXo063VcWTEAyx6XAZ85DYHqp0+aHKbPlfRDRvA==", "dev": true, "requires": { - "@jest/types": "^27.0.2", + "@jest/types": "^27.1.1", "execa": "^5.0.0", "throat": "^6.0.1" } }, "jest-circus": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.0.5.tgz", - "integrity": "sha512-p5rO90o1RTh8LPOG6l0Fc9qgp5YGv+8M5CFixhMh7gGHtGSobD1AxX9cjFZujILgY8t30QZ7WVvxlnuG31r8TA==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.2.2.tgz", + "integrity": "sha512-8txlqs0EDrvPasCgwfLMkG0l3F4FxqQa6lxOsvYfOl04eSJjRw3F4gk9shakuC00nMD+VT+SMtFYXxe64f0VZw==", "dev": true, "requires": { - "@jest/environment": "^27.0.5", - "@jest/test-result": "^27.0.2", - "@jest/types": "^27.0.2", + "@jest/environment": "^27.2.2", + "@jest/test-result": "^27.2.2", + "@jest/types": "^27.1.1", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", - "expect": "^27.0.2", + "expect": "^27.2.2", "is-generator-fn": "^2.0.0", - "jest-each": "^27.0.2", - "jest-matcher-utils": "^27.0.2", - "jest-message-util": "^27.0.2", - "jest-runtime": "^27.0.5", - "jest-snapshot": "^27.0.5", - "jest-util": "^27.0.2", - "pretty-format": "^27.0.2", + "jest-each": "^27.2.2", + "jest-matcher-utils": "^27.2.2", + "jest-message-util": "^27.2.2", + "jest-runtime": "^27.2.2", + "jest-snapshot": "^27.2.2", + "jest-util": "^27.2.0", + "pretty-format": "^27.2.2", "slash": "^3.0.0", "stack-utils": "^2.0.3", "throat": "^6.0.1" } }, + "jest-cli": { + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.2.2.tgz", + "integrity": "sha512-jbEythw22LR/IHYgNrjWdO74wO9wyujCxTMjbky0GLav4rC4y6qDQr4TqQ2JPP51eDYJ2awVn83advEVSs5Brg==", + "dev": true, + "requires": { + "@jest/core": "^27.2.2", + "@jest/test-result": "^27.2.2", + "@jest/types": "^27.1.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "jest-config": "^27.2.2", + "jest-util": "^27.2.0", + "jest-validate": "^27.2.2", + "prompts": "^2.0.1", + "yargs": "^16.0.3" + } + }, "jest-config": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.0.5.tgz", - "integrity": "sha512-zCUIXag7QIXKEVN4kUKbDBDi9Q53dV5o3eNhGqe+5zAbt1vLs4VE3ceWaYrOub0L4Y7E9pGfM84TX/0ARcE+Qw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.2.2.tgz", + "integrity": "sha512-2nhms3lp52ZpU0636bB6zIFHjDVtYxzFQIOHZjBFUeXcb6b41sEkWojbHaJ4FEIO44UbccTLa7tvNpiFCgPE7w==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^27.0.5", - "@jest/types": "^27.0.2", - "babel-jest": "^27.0.5", + "@jest/test-sequencer": "^27.2.2", + "@jest/types": "^27.1.1", + "babel-jest": "^27.2.2", "chalk": "^4.0.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", "graceful-fs": "^4.2.4", "is-ci": "^3.0.0", - "jest-circus": "^27.0.5", - "jest-environment-jsdom": "^27.0.5", - "jest-environment-node": "^27.0.5", - "jest-get-type": "^27.0.1", - "jest-jasmine2": "^27.0.5", - "jest-regex-util": "^27.0.1", - "jest-resolve": "^27.0.5", - "jest-runner": "^27.0.5", - "jest-util": "^27.0.2", - "jest-validate": "^27.0.2", + "jest-circus": "^27.2.2", + "jest-environment-jsdom": "^27.2.2", + "jest-environment-node": "^27.2.2", + "jest-get-type": "^27.0.6", + "jest-jasmine2": "^27.2.2", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.2.2", + "jest-runner": "^27.2.2", + "jest-util": "^27.2.0", + "jest-validate": "^27.2.2", "micromatch": "^4.0.4", - "pretty-format": "^27.0.2" + "pretty-format": "^27.2.2" } }, "jest-diff": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.2.tgz", - "integrity": "sha512-BFIdRb0LqfV1hBt8crQmw6gGQHVDhM87SpMIZ45FPYKReZYG5er1+5pIn2zKqvrJp6WNox0ylR8571Iwk2Dmgw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.2.2.tgz", + "integrity": "sha512-o3LaDbQDSaMJif4yztJAULI4xVatxbBasbKLbEw3K8CiRdDdbxMrLArS9EKDHQFYh6Tgfrm1PC2mIYR1xhu0hQ==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^27.0.1", - "jest-get-type": "^27.0.1", - "pretty-format": "^27.0.2" + "diff-sequences": "^27.0.6", + "jest-get-type": "^27.0.6", + "pretty-format": "^27.2.2" } }, "jest-docblock": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.1.tgz", - "integrity": "sha512-TA4+21s3oebURc7VgFV4r7ltdIJ5rtBH1E3Tbovcg7AV+oLfD5DcJ2V2vJ5zFA9sL5CFd/d2D6IpsAeSheEdrA==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz", + "integrity": "sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA==", "dev": true, "requires": { "detect-newline": "^3.0.0" } }, "jest-each": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.0.2.tgz", - "integrity": "sha512-OLMBZBZ6JkoXgUenDtseFRWA43wVl2BwmZYIWQws7eS7pqsIvePqj/jJmEnfq91ALk3LNphgwNK/PRFBYi7ITQ==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.2.2.tgz", + "integrity": "sha512-ZCDhkvwHeXHsxoFxvW43fabL18iLiVDxaipG5XWG7dSd+XWXXpzMQvBWYT9Wvzhg5x4hvrLQ24LtiOKw3I09xA==", "dev": true, "requires": { - "@jest/types": "^27.0.2", + "@jest/types": "^27.1.1", "chalk": "^4.0.0", - "jest-get-type": "^27.0.1", - "jest-util": "^27.0.2", - "pretty-format": "^27.0.2" + "jest-get-type": "^27.0.6", + "jest-util": "^27.2.0", + "pretty-format": "^27.2.2" } }, "jest-environment-jsdom": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.0.5.tgz", - "integrity": "sha512-ToWhViIoTl5738oRaajTMgYhdQL73UWPoV4GqHGk2DPhs+olv8OLq5KoQW8Yf+HtRao52XLqPWvl46dPI88PdA==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.2.2.tgz", + "integrity": "sha512-mzCLEdnpGWDJmNB6WIPLlZM+hpXdeiya9TryiByqcUdpliNV1O+LGC2SewzjmB4IblabGfvr3KcPN0Nme2wnDw==", "dev": true, "requires": { - "@jest/environment": "^27.0.5", - "@jest/fake-timers": "^27.0.5", - "@jest/types": "^27.0.2", + "@jest/environment": "^27.2.2", + "@jest/fake-timers": "^27.2.2", + "@jest/types": "^27.1.1", "@types/node": "*", - "jest-mock": "^27.0.3", - "jest-util": "^27.0.2", + "jest-mock": "^27.1.1", + "jest-util": "^27.2.0", "jsdom": "^16.6.0" + }, + "dependencies": { + "acorn": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "dev": true + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "dev": true, + "requires": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + } + }, + "whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "dev": true, + "requires": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + } + } } }, "jest-environment-node": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.0.5.tgz", - "integrity": "sha512-47qqScV/WMVz5OKF5TWpAeQ1neZKqM3ySwNveEnLyd+yaE/KT6lSMx/0SOx60+ZUcVxPiESYS+Kt2JS9y4PpkQ==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.2.2.tgz", + "integrity": "sha512-XgUscWs6H6UNqC96/QJjmUGZzzpql/JyprLSXVu7wkgM8tjbJdEkSqwrVAvJPm1yu526ImrmsIoh2BTHxkwL/g==", "dev": true, "requires": { - "@jest/environment": "^27.0.5", - "@jest/fake-timers": "^27.0.5", - "@jest/types": "^27.0.2", + "@jest/environment": "^27.2.2", + "@jest/fake-timers": "^27.2.2", + "@jest/types": "^27.1.1", "@types/node": "*", - "jest-mock": "^27.0.3", - "jest-util": "^27.0.2" + "jest-mock": "^27.1.1", + "jest-util": "^27.2.0" } }, "jest-get-type": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz", - "integrity": "sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", + "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", "dev": true }, "jest-haste-map": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.0.5.tgz", - "integrity": "sha512-3LFryGSHxwPFHzKIs6W0BGA2xr6g1MvzSjR3h3D8K8Uqy4vbRm/grpGHzbPtIbOPLC6wFoViRrNEmd116QWSkw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.2.2.tgz", + "integrity": "sha512-kaKiq+GbAvk6/sq++Ymor4Vzk6+lr0vbKs2HDVPdkKsHX2lIJRyvhypZG/QsNfQnROKWIZSpUpGuv2HySSosvA==", "dev": true, "requires": { - "@jest/types": "^27.0.2", + "@jest/types": "^27.1.1", "@types/graceful-fs": "^4.1.2", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.3.2", "graceful-fs": "^4.2.4", - "jest-regex-util": "^27.0.1", - "jest-serializer": "^27.0.1", - "jest-util": "^27.0.2", - "jest-worker": "^27.0.2", + "jest-regex-util": "^27.0.6", + "jest-serializer": "^27.0.6", + "jest-util": "^27.2.0", + "jest-worker": "^27.2.2", "micromatch": "^4.0.4", "walker": "^1.0.7" } }, "jest-jasmine2": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.0.5.tgz", - "integrity": "sha512-m3TojR19sFmTn79QoaGy1nOHBcLvtLso6Zh7u+gYxZWGcza4rRPVqwk1hciA5ZOWWZIJOukAcore8JRX992FaA==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.2.2.tgz", + "integrity": "sha512-SczhZNfmZID9HbJ1GHhO4EzeL/PMRGeAUw23ddPUdd6kFijEZpT2yOxyNCBUKAsVQ/14OB60kjgnbuFOboZUNg==", "dev": true, "requires": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^27.0.5", - "@jest/source-map": "^27.0.1", - "@jest/test-result": "^27.0.2", - "@jest/types": "^27.0.2", + "@jest/environment": "^27.2.2", + "@jest/source-map": "^27.0.6", + "@jest/test-result": "^27.2.2", + "@jest/types": "^27.1.1", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^27.0.2", + "expect": "^27.2.2", "is-generator-fn": "^2.0.0", - "jest-each": "^27.0.2", - "jest-matcher-utils": "^27.0.2", - "jest-message-util": "^27.0.2", - "jest-runtime": "^27.0.5", - "jest-snapshot": "^27.0.5", - "jest-util": "^27.0.2", - "pretty-format": "^27.0.2", + "jest-each": "^27.2.2", + "jest-matcher-utils": "^27.2.2", + "jest-message-util": "^27.2.2", + "jest-runtime": "^27.2.2", + "jest-snapshot": "^27.2.2", + "jest-util": "^27.2.0", + "pretty-format": "^27.2.2", "throat": "^6.0.1" } }, "jest-leak-detector": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.0.2.tgz", - "integrity": "sha512-TZA3DmCOfe8YZFIMD1GxFqXUkQnIoOGQyy4hFCA2mlHtnAaf+FeOMxi0fZmfB41ZL+QbFG6BVaZF5IeFIVy53Q==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.2.2.tgz", + "integrity": "sha512-fQIYKkhXUs/4EpE4wO1AVsv7aNH3o0km1BGq3vxvSfYdwG9GLMf+b0z/ghLmBYNxb+tVpm/zv2caoKm3GfTazg==", "dev": true, "requires": { - "jest-get-type": "^27.0.1", - "pretty-format": "^27.0.2" + "jest-get-type": "^27.0.6", + "pretty-format": "^27.2.2" } }, "jest-matcher-utils": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.0.2.tgz", - "integrity": "sha512-Qczi5xnTNjkhcIB0Yy75Txt+Ez51xdhOxsukN7awzq2auZQGPHcQrJ623PZj0ECDEMOk2soxWx05EXdXGd1CbA==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.2.2.tgz", + "integrity": "sha512-xN3wT4p2i9DGB6zmL3XxYp5lJmq9Q6ff8XKlMtVVBS2SAshmgsPBALJFQ8dWRd2G/xf5q/N0SD0Mipt8QBA26A==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^27.0.2", - "jest-get-type": "^27.0.1", - "pretty-format": "^27.0.2" + "jest-diff": "^27.2.2", + "jest-get-type": "^27.0.6", + "pretty-format": "^27.2.2" } }, "jest-message-util": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.0.2.tgz", - "integrity": "sha512-rTqWUX42ec2LdMkoUPOzrEd1Tcm+R1KfLOmFK+OVNo4MnLsEaxO5zPDb2BbdSmthdM/IfXxOZU60P/WbWF8BTw==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.2.2.tgz", + "integrity": "sha512-/iS5/m2FSF7Nn6APFoxFymJpyhB/gPf0CJa7uFSkbYaWvrADUfQ9NTsuyjpszKErOS2/huFs44ysWhlQTKvL8Q==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.0.2", + "@jest/types": "^27.1.1", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.4", - "pretty-format": "^27.0.2", + "pretty-format": "^27.2.2", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -14927,12 +14934,12 @@ } }, "jest-mock": { - "version": "27.0.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.0.3.tgz", - "integrity": "sha512-O5FZn5XDzEp+Xg28mUz4ovVcdwBBPfAhW9+zJLO0Efn2qNbYcDaJvSlRiQ6BCZUCVOJjALicuJQI9mRFjv1o9Q==", + "version": "27.1.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.1.1.tgz", + "integrity": "sha512-SClsFKuYBf+6SSi8jtAYOuPw8DDMsTElUWEae3zq7vDhH01ayVSIHUSIa8UgbDOUalCFp6gNsaikN0rbxN4dbw==", "dev": true, "requires": { - "@jest/types": "^27.0.2", + "@jest/types": "^27.1.1", "@types/node": "*" } }, @@ -14944,107 +14951,109 @@ "requires": {} }, "jest-regex-util": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.1.tgz", - "integrity": "sha512-6nY6QVcpTgEKQy1L41P4pr3aOddneK17kn3HJw6SdwGiKfgCGTvH02hVXL0GU8GEKtPH83eD2DIDgxHXOxVohQ==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz", + "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==", "dev": true }, "jest-resolve": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.0.5.tgz", - "integrity": "sha512-Md65pngRh8cRuWVdWznXBB5eDt391OJpdBaJMxfjfuXCvOhM3qQBtLMCMTykhuUKiBMmy5BhqCW7AVOKmPrW+Q==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.2.2.tgz", + "integrity": "sha512-tfbHcBs/hJTb3fPQ/3hLWR+TsLNTzzK98TU+zIAsrL9nNzWfWROwopUOmiSUqmHMZW5t9au/433kSF2/Af+tTw==", "dev": true, "requires": { - "@jest/types": "^27.0.2", + "@jest/types": "^27.1.1", "chalk": "^4.0.0", "escalade": "^3.1.1", "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.2.2", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.0.2", - "jest-validate": "^27.0.2", + "jest-util": "^27.2.0", + "jest-validate": "^27.2.2", "resolve": "^1.20.0", "slash": "^3.0.0" } }, "jest-resolve-dependencies": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.0.5.tgz", - "integrity": "sha512-xUj2dPoEEd59P+nuih4XwNa4nJ/zRd/g4rMvjHrZPEBWeWRq/aJnnM6mug+B+Nx+ILXGtfWHzQvh7TqNV/WbuA==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.2.2.tgz", + "integrity": "sha512-nvJS+DyY51HHdZnMIwXg7fimQ5ylFx4+quQXspQXde2rXYy+4v75UYoX/J65Ln8mKCNc6YF8HEhfGaRBOrxxHg==", "dev": true, "requires": { - "@jest/types": "^27.0.2", - "jest-regex-util": "^27.0.1", - "jest-snapshot": "^27.0.5" + "@jest/types": "^27.1.1", + "jest-regex-util": "^27.0.6", + "jest-snapshot": "^27.2.2" } }, "jest-runner": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.0.5.tgz", - "integrity": "sha512-HNhOtrhfKPArcECgBTcWOc+8OSL8GoFoa7RsHGnfZR1C1dFohxy9eLtpYBS+koybAHlJLZzNCx2Y/Ic3iEtJpQ==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.2.2.tgz", + "integrity": "sha512-+bUFwBq+yTnvsOFuxetoQtkuOnqdAk2YuIGjlLmc7xLAXn/V1vjhXrLencgij0BUTTUvG9Aul3+5XDss4Wa8Eg==", "dev": true, "requires": { - "@jest/console": "^27.0.2", - "@jest/environment": "^27.0.5", - "@jest/test-result": "^27.0.2", - "@jest/transform": "^27.0.5", - "@jest/types": "^27.0.2", + "@jest/console": "^27.2.2", + "@jest/environment": "^27.2.2", + "@jest/test-result": "^27.2.2", + "@jest/transform": "^27.2.2", + "@jest/types": "^27.1.1", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.8.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-docblock": "^27.0.1", - "jest-environment-jsdom": "^27.0.5", - "jest-environment-node": "^27.0.5", - "jest-haste-map": "^27.0.5", - "jest-leak-detector": "^27.0.2", - "jest-message-util": "^27.0.2", - "jest-resolve": "^27.0.5", - "jest-runtime": "^27.0.5", - "jest-util": "^27.0.2", - "jest-worker": "^27.0.2", + "jest-docblock": "^27.0.6", + "jest-environment-jsdom": "^27.2.2", + "jest-environment-node": "^27.2.2", + "jest-haste-map": "^27.2.2", + "jest-leak-detector": "^27.2.2", + "jest-message-util": "^27.2.2", + "jest-resolve": "^27.2.2", + "jest-runtime": "^27.2.2", + "jest-util": "^27.2.0", + "jest-worker": "^27.2.2", "source-map-support": "^0.5.6", "throat": "^6.0.1" } }, "jest-runtime": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.0.5.tgz", - "integrity": "sha512-V/w/+VasowPESbmhXn5AsBGPfb35T7jZPGZybYTHxZdP7Gwaa+A0EXE6rx30DshHKA98lVCODbCO8KZpEW3hiQ==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.2.2.tgz", + "integrity": "sha512-PtTHCK5jT+KrIpKpjJsltu/dK5uGhBtTNLOk1Z+ZD2Jrxam2qQsOqDFYLszcK0jc2TLTNsrVpclqSftn7y3aXA==", "dev": true, "requires": { - "@jest/console": "^27.0.2", - "@jest/environment": "^27.0.5", - "@jest/fake-timers": "^27.0.5", - "@jest/globals": "^27.0.5", - "@jest/source-map": "^27.0.1", - "@jest/test-result": "^27.0.2", - "@jest/transform": "^27.0.5", - "@jest/types": "^27.0.2", + "@jest/console": "^27.2.2", + "@jest/environment": "^27.2.2", + "@jest/fake-timers": "^27.2.2", + "@jest/globals": "^27.2.2", + "@jest/source-map": "^27.0.6", + "@jest/test-result": "^27.2.2", + "@jest/transform": "^27.2.2", + "@jest/types": "^27.1.1", "@types/yargs": "^16.0.0", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.0.5", - "jest-message-util": "^27.0.2", - "jest-mock": "^27.0.3", - "jest-regex-util": "^27.0.1", - "jest-resolve": "^27.0.5", - "jest-snapshot": "^27.0.5", - "jest-util": "^27.0.2", - "jest-validate": "^27.0.2", + "jest-haste-map": "^27.2.2", + "jest-message-util": "^27.2.2", + "jest-mock": "^27.1.1", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.2.2", + "jest-snapshot": "^27.2.2", + "jest-util": "^27.2.0", + "jest-validate": "^27.2.2", "slash": "^3.0.0", "strip-bom": "^4.0.0", "yargs": "^16.0.3" } }, "jest-serializer": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.1.tgz", - "integrity": "sha512-svy//5IH6bfQvAbkAEg1s7xhhgHTtXu0li0I2fdKHDsLP2P2MOiscPQIENQep8oU2g2B3jqLyxKKzotZOz4CwQ==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz", + "integrity": "sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA==", "dev": true, "requires": { "@types/node": "*", @@ -15052,9 +15061,9 @@ } }, "jest-snapshot": { - "version": "27.0.5", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.0.5.tgz", - "integrity": "sha512-H1yFYdgnL1vXvDqMrnDStH6yHFdMEuzYQYc71SnC/IJnuuhW6J16w8GWG1P+qGd3Ag3sQHjbRr0TcwEo/vGS+g==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.2.2.tgz", + "integrity": "sha512-7ODSvULMiiOVuuLvLZpDlpqqTqX9hDfdmijho5auVu9qRYREolvrvgH4kSNOKfcqV3EZOTuLKNdqsz1PM20PQA==", "dev": true, "requires": { "@babel/core": "^7.7.2", @@ -15063,23 +15072,23 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.0.0", - "@jest/transform": "^27.0.5", - "@jest/types": "^27.0.2", + "@jest/transform": "^27.2.2", + "@jest/types": "^27.1.1", "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^27.0.2", + "expect": "^27.2.2", "graceful-fs": "^4.2.4", - "jest-diff": "^27.0.2", - "jest-get-type": "^27.0.1", - "jest-haste-map": "^27.0.5", - "jest-matcher-utils": "^27.0.2", - "jest-message-util": "^27.0.2", - "jest-resolve": "^27.0.5", - "jest-util": "^27.0.2", + "jest-diff": "^27.2.2", + "jest-get-type": "^27.0.6", + "jest-haste-map": "^27.2.2", + "jest-matcher-utils": "^27.2.2", + "jest-message-util": "^27.2.2", + "jest-resolve": "^27.2.2", + "jest-util": "^27.2.0", "natural-compare": "^1.4.0", - "pretty-format": "^27.0.2", + "pretty-format": "^27.2.2", "semver": "^7.3.2" }, "dependencies": { @@ -15095,12 +15104,12 @@ } }, "jest-util": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.2.tgz", - "integrity": "sha512-1d9uH3a00OFGGWSibpNYr+jojZ6AckOMCXV2Z4K3YXDnzpkAaXQyIpY14FOJPiUmil7CD+A6Qs+lnnh6ctRbIA==", + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.2.0.tgz", + "integrity": "sha512-T5ZJCNeFpqcLBpx+Hl9r9KoxBCUqeWlJ1Htli+vryigZVJ1vuLB9j35grEBASp4R13KFkV7jM52bBGnArpJN6A==", "dev": true, "requires": { - "@jest/types": "^27.0.2", + "@jest/types": "^27.1.1", "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -15109,17 +15118,17 @@ } }, "jest-validate": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.0.2.tgz", - "integrity": "sha512-UgBF6/oVu1ofd1XbaSotXKihi8nZhg0Prm8twQ9uCuAfo59vlxCXMPI/RKmrZEVgi3Nd9dS0I8A0wzWU48pOvg==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.2.2.tgz", + "integrity": "sha512-01mwTAs2kgDuX98Ua3Xhdhp5lXsLU4eyg6k56adTtrXnU/GbLd9uAsh5nc4MWVtUXMeNmHUyEiD4ibLqE8MuNw==", "dev": true, "requires": { - "@jest/types": "^27.0.2", + "@jest/types": "^27.1.1", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^27.0.1", + "jest-get-type": "^27.0.6", "leven": "^3.1.0", - "pretty-format": "^27.0.2" + "pretty-format": "^27.2.2" }, "dependencies": { "camelcase": { @@ -15131,24 +15140,24 @@ } }, "jest-watcher": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.0.2.tgz", - "integrity": "sha512-8nuf0PGuTxWj/Ytfw5fyvNn/R80iXY8QhIT0ofyImUvdnoaBdT6kob0GmhXR+wO+ALYVnh8bQxN4Tjfez0JgkA==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.2.2.tgz", + "integrity": "sha512-7HJwZq06BCfM99RacCVzXO90B20/dNJvq+Ouiu/VrFdFRCpbnnqlQUEk4KAhBSllgDrTPgKu422SCF5KKBHDRA==", "dev": true, "requires": { - "@jest/test-result": "^27.0.2", - "@jest/types": "^27.0.2", + "@jest/test-result": "^27.2.2", + "@jest/types": "^27.1.1", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^27.0.2", + "jest-util": "^27.2.0", "string-length": "^4.0.1" } }, "jest-worker": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.2.tgz", - "integrity": "sha512-EoBdilOTTyOgmHXtw/cPc+ZrCA0KJMrkXzkrPGNwLmnvvlN1nj7MPrxpT7m+otSv2e1TLaVffzDnE/LB14zJMg==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.2.2.tgz", + "integrity": "sha512-aG1xq9KgWB2CPC8YdMIlI8uZgga2LFNcGbHJxO8ctfXAydSaThR4EewKQGg3tBOC+kS3vhPGgymsBdi9VINjPw==", "dev": true, "requires": { "@types/node": "*", @@ -15181,34 +15190,28 @@ "esprima": "^4.0.0" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, "jsdoc-type-pratt-parser": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-1.0.4.tgz", - "integrity": "sha512-jzmW9gokeq9+bHPDR1nCeidMyFUikdZlbOhKzh9+/nJqB75XhpNKec1/UuxW5c4+O+Pi31Gc/dCboyfSm/pSpQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-1.1.1.tgz", + "integrity": "sha512-uelRmpghNwPBuZScwgBG/OzodaFk5RbO5xaivBdsAY70icWfShwZ7PCMO0x1zSkOa8T1FzHThmrdoyg/0AwV5g==", "dev": true }, "jsdom": { - "version": "16.6.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.6.0.tgz", - "integrity": "sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg==", + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-17.0.0.tgz", + "integrity": "sha512-MUq4XdqwtNurZDVeKScENMPHnkgmdIvMzZ1r1NSwHkDuaqI6BouPjr+17COo4/19oLNnmdpFDPOHVpgIZmZ+VA==", "dev": true, "requires": { "abab": "^2.0.5", - "acorn": "^8.2.4", + "acorn": "^8.4.1", "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", + "cssom": "^0.5.0", "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", + "data-urls": "^3.0.0", + "decimal.js": "^10.3.1", "domexception": "^2.0.1", "escodegen": "^2.0.0", - "form-data": "^3.0.0", + "form-data": "^4.0.0", "html-encoding-sniffer": "^2.0.1", "http-proxy-agent": "^4.0.1", "https-proxy-agent": "^5.0.0", @@ -15223,8 +15226,8 @@ "webidl-conversions": "^6.1.0", "whatwg-encoding": "^1.0.5", "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.5", + "whatwg-url": "^9.0.0", + "ws": "^8.0.0", "xml-name-validator": "^3.0.0" }, "dependencies": { @@ -15233,6 +15236,13 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", "dev": true + }, + "ws": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.0.tgz", + "integrity": "sha512-uYhVJ/m9oXwEI04iIVmgLmugh2qrZihkywG9y5FfZV2ATeLIzHf93qs+tUNqlttbQK957/VX3mtwAS+UfIwA4g==", + "dev": true, + "requires": {} } } }, @@ -15254,12 +15264,6 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -15274,7 +15278,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "devOptional": true + "optional": true }, "json5": { "version": "2.2.0", @@ -15294,18 +15298,6 @@ "graceful-fs": "^4.1.6" } }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, "just-extend": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", @@ -15756,12 +15748,6 @@ "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true } } }, @@ -15863,9 +15849,33 @@ } }, "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", + "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", + "requires": { + "whatwg-url": "^5.0.0" + }, + "dependencies": { + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } }, "node-ical": { "version": "0.13.0", @@ -16083,12 +16093,6 @@ } } }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -16279,12 +16283,6 @@ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", "devOptional": true }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, "picomatch": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", @@ -16488,9 +16486,9 @@ "devOptional": true }, "prettier": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.1.tgz", - "integrity": "sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", "dev": true }, "prettier-linter-helpers": { @@ -16503,13 +16501,13 @@ } }, "pretty-format": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", - "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.2.2.tgz", + "integrity": "sha512-+DdLh+rtaElc2SQOE/YPH8k2g3Rf2OXWEpy06p8Szs3hdVSYD87QOOlYRHWAeb/59XTmeVmRKvDD0svHqf6ycA==", "dev": true, "requires": { - "@jest/types": "^27.0.2", - "ansi-regex": "^5.0.0", + "@jest/types": "^27.1.1", + "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" }, @@ -16735,9 +16733,9 @@ "dev": true }, "quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true }, "range_check": { @@ -16940,69 +16938,6 @@ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - } - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -17068,9 +17003,9 @@ } }, "resq": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/resq/-/resq-1.10.0.tgz", - "integrity": "sha512-hCUd0xMalqtPDz4jXIqs0M5Wnv/LZXN8h7unFOo4/nvExT9dDPbhwd3udRxLlp0HgBnHcV009UlduE9NZi7A6w==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/resq/-/resq-1.10.1.tgz", + "integrity": "sha512-zhp1iyUH02MLciv3bIM2bNtTFx/fqRsK4Jk73jcPqp00d/sMTTjOtjdTMAcgjrQKGx5DvQ/HSpeqaMW0atGRJA==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1" @@ -17116,6 +17051,14 @@ "json-stringify-safe": "^5.0.1", "semver-compare": "^1.0.0", "sprintf-js": "^1.1.2" + }, + "dependencies": { + "sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "optional": true + } } }, "rrule": { @@ -17221,6 +17164,14 @@ "optional": true, "requires": { "type-fest": "^0.13.1" + }, + "dependencies": { + "type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "optional": true + } } }, "serve-static": { @@ -17264,24 +17215,14 @@ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, - "simple-git": { - "version": "2.40.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-2.40.0.tgz", - "integrity": "sha512-7IO/eQwrN5kvS38TTu9ljhG9tx2nn0BTqZOmqpPpp51TvE44YIvLA6fETqEVA8w/SeEfPaVv6mk7Tsk9Jns+ag==", - "requires": { - "@kwsites/file-exists": "^1.1.1", - "@kwsites/promise-deferred": "^1.1.1", - "debug": "^4.3.1" - } - }, "sinon": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-11.1.1.tgz", - "integrity": "sha512-ZSSmlkSyhUWbkF01Z9tEbxZLF/5tRC9eojCdFh33gtQaP7ITQVaMWQHGuFM7Cuf/KEfihuh1tTl3/ABju3AQMg==", + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-11.1.2.tgz", + "integrity": "sha512-59237HChms4kg7/sXhiRcUzdSkKuydDeTiamT/jesUVHshBgL8XAmhgFo0GfK6RruMDM/iRSij1EybmMog9cJw==", "dev": true, "requires": { "@sinonjs/commons": "^1.8.3", - "@sinonjs/fake-timers": "^7.1.0", + "@sinonjs/fake-timers": "^7.1.2", "@sinonjs/samsam": "^6.0.2", "diff": "^5.0.0", "nise": "^5.1.0", @@ -17311,25 +17252,25 @@ } }, "socket.io": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.1.2.tgz", - "integrity": "sha512-xK0SD1C7hFrh9+bYoYCdVt+ncixkSLKtNLCax5aEy1o3r5PaO5yQhVb97exIe67cE7lAK+EpyMytXWTWmyZY8w==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.2.0.tgz", + "integrity": "sha512-sjlGfMmnaWvTRVxGRGWyhd9ctpg4APxWAxu85O/SxekkxHhfxmePWZbaYCkeX5QQX0z1YEnKOlNt6w82E4Nzug==", "requires": { - "@types/cookie": "^0.4.0", - "@types/cors": "^2.8.8", + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", "@types/node": ">=10.0.0", "accepts": "~1.3.4", "base64id": "~2.0.0", - "debug": "~4.3.1", - "engine.io": "~5.1.0", - "socket.io-adapter": "~2.3.0", - "socket.io-parser": "~4.0.3" + "debug": "~4.3.2", + "engine.io": "~5.2.0", + "socket.io-adapter": "~2.3.2", + "socket.io-parser": "~4.0.4" } }, "socket.io-adapter": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.3.1.tgz", - "integrity": "sha512-8cVkRxI8Nt2wadkY6u60Y4rpW3ejA1rxgcK2JuyIhmF+RMNpTy1QRtkHIDUOf3B4HlQwakMsWbKftMv/71VMmw==" + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.3.2.tgz", + "integrity": "sha512-PBZpxUPYjmoogY0aoaTmo1643JelsaS1CiAwNjRVdrI0X9Seuc19Y2Wife8k88avW6haG8cznvwbubAZwH4Mtg==" }, "socket.io-parser": { "version": "4.0.4", @@ -17348,9 +17289,9 @@ "dev": true }, "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -17410,16 +17351,140 @@ "dev": true }, "spectron": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/spectron/-/spectron-13.0.0.tgz", - "integrity": "sha512-7RPa6Fp8gqL4V0DubobnqIRFHIijkpjg6MFHcJlxoerWyvLJd+cQvOh756XpB1Z/U3DyA9jPcS+HE2PvYRP5+A==", + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/spectron/-/spectron-15.0.0.tgz", + "integrity": "sha512-eErHqymkEVb6H+LPZQoDYvWEv93o3nhxL7HXXdmC61ncV0jBckh8x3Qt6j+As2c1n0C/hKG9A2H1NnwGwD6agg==", "dev": true, "requires": { + "@electron/remote": "^1.1.0", "dev-null": "^0.1.1", - "electron-chromedriver": "^11.0.0", - "request": "^2.88.2", + "electron-chromedriver": "^13.0.0", + "got": "^11.8.0", "split": "^1.0.1", "webdriverio": "^6.9.1" + }, + "dependencies": { + "@sindresorhus/is": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.1.tgz", + "integrity": "sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz", + "integrity": "sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==", + "dev": true, + "requires": { + "defer-to-connect": "^2.0.0" + } + }, + "cacheable-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", + "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + } + }, + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "requires": { + "mimic-response": "^3.1.0" + } + }, + "defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "got": { + "version": "11.8.2", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.2.tgz", + "integrity": "sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ==", + "dev": true, + "requires": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.1", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + } + }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "keyv": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", + "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", + "dev": true, + "requires": { + "json-buffer": "3.0.1" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + }, + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true + }, + "normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true + }, + "p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true + }, + "responselike": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", + "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", + "dev": true, + "requires": { + "lowercase-keys": "^2.0.0" + } + } } }, "split": { @@ -17432,32 +17497,14 @@ } }, "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "optional": true - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -17671,6 +17718,12 @@ "debug": "^4.1.0" } }, + "suncalc": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/suncalc/-/suncalc-1.8.0.tgz", + "integrity": "sha1-HZiYEJVjB4dQ9JlKlZ5lTYdqy/U=", + "dev": true + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -17715,9 +17768,9 @@ }, "dependencies": { "ajv": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.0.tgz", - "integrity": "sha512-cnUG4NSBiM4YFBxgZIj/In3/6KX+rQ2l2YPRVcvAMQGWEPKuXoPIhxzwqh31jA3IPbI4qEOp/5ILI4ynioXsGQ==", + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.1.tgz", + "integrity": "sha512-42VLtQUOLefAvKFAQIxIZDaThq6om/PrfP0CYk3/vn+y4BMNkKnbli8ON2QCiHov4KkzOSJ/xSoBJdayiiYvVQ==", "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -17809,9 +17862,9 @@ "dev": true }, "tmpl": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", - "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true }, "to-fast-properties": { @@ -17892,21 +17945,6 @@ "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", "optional": true }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -17922,10 +17960,9 @@ "dev": true }, "type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "optional": true + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" }, "type-is": { "version": "1.6.18", @@ -17940,7 +17977,7 @@ "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "optional": true + "devOptional": true }, "typedarray-to-buffer": { "version": "3.1.5", @@ -17951,6 +17988,13 @@ "is-typedarray": "^1.0.0" } }, + "typescript": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", + "dev": true, + "peer": true + }, "ua-parser-js": { "version": "0.7.28", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.28.tgz", @@ -17986,6 +18030,12 @@ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", "dev": true + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true } } }, @@ -18063,9 +18113,9 @@ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" }, "v8-to-istanbul": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.0.0.tgz", - "integrity": "sha512-LkmXi8UUNxnCC+JlH7/fsfsKr5AU110l+SYGJimWNkWhxbN5EyeOtm1MJ0hhvqMMOhGwBj1Fp70Yv9i+hX0QAg==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", + "integrity": "sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.1", @@ -18096,17 +18146,6 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, "vfile": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", @@ -18363,12 +18402,6 @@ "type-fest": "^0.20.2" } }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, "universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -18410,12 +18443,11 @@ "dev": true }, "whatwg-url": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.6.0.tgz", - "integrity": "sha512-os0KkeeqUOl7ccdDT1qqUcS4KH4tcBTSKK5Nl5WKb2lyxInIZ/CpjkqKa1Ss12mjfdcRX9mHmPPs7/SxG1Hbdw==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-9.1.0.tgz", + "integrity": "sha512-CQ0UcrPHyomtlOCot1TL77WyMIm/bCwrJ2D6AOKGwEczU9EpyoqAokfqrf/MioU9kHcMsmJZcg1egXix2KYEsA==", "dev": true, "requires": { - "lodash": "^4.7.0", "tr46": "^2.1.0", "webidl-conversions": "^6.1.0" } @@ -18468,9 +18500,10 @@ } }, "ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.2.tgz", + "integrity": "sha512-lkF7AWRicoB9mAgjeKbGqVUekLnSNO4VjKVnuPHpQeOxZOErX6BPXwJk70nFslRCEEA8EVW7ZjKwXaP9N+1sKQ==", + "dev": true, "requires": {} }, "xml-name-validator": { diff --git a/package.json b/package.json index 12f62e26..3b8a42d7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "magicmirror", - "version": "2.16.0", + "version": "2.17.0", "description": "The open source modular smart mirror platform.", "main": "js/electron.js", "scripts": { @@ -12,16 +12,17 @@ "postinstall": "npm run install-fonts && echo \"MagicMirror installation finished successfully! \n\"", "test": "NODE_ENV=test jest -i --forceExit", "test:coverage": "NODE_ENV=test nyc --reporter=lcov --reporter=text jest -i --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: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 --quiet", - "test:css": "stylelint css/main.css modules/default/**/*.css --config .stylelintrc.json", + "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", "test:calendar": "node ./modules/default/calendar/debug.js", "config:check": "node js/check_config.js", "lint:prettier": "prettier . --write", - "lint:js": "eslint js/**/*.js modules/default/**/*.js clientonly/*.js serveronly/*.js translations/*.js vendor/*.js tests/**/*.js config/* --config .eslintrc.json --fix", - "lint:css": "stylelint css/main.css modules/default/**/*.css --config .stylelintrc.json --fix", + "lint:js": "eslint 'js/**/*.js' 'modules/default/**/*.js' 'clientonly/*.js' 'serveronly/*.js' 'translations/*.js' 'vendor/*.js' 'tests/**/*.js' 'config/*' --config .eslintrc.json --fix", + "lint:css": "stylelint 'css/main.css' 'fonts/*.css' 'modules/default/**/*.css' 'vendor/*.css' --config .stylelintrc.json --fix", "lint:staged": "pretty-quick --staged", "prepare": "[ -f node_modules/.bin/husky ] && husky install || echo no husky installed." }, @@ -46,32 +47,33 @@ "homepage": "https://magicmirror.builders", "devDependencies": { "eslint-config-prettier": "^8.3.0", - "eslint-plugin-jsdoc": "^35.4.0", - "eslint-plugin-prettier": "^3.4.0", - "eslint-plugin-jest": "^24.3.6", + "eslint-plugin-jest": "^24.4.2", + "eslint-plugin-jsdoc": "^36.1.0", + "eslint-plugin-prettier": "^4.0.0", "express-basic-auth": "^1.2.0", - "husky": "^6.0.0", - "jest": "27.0.5", - "jsdom": "^16.6.0", + "husky": "^7.0.2", + "jest": "^27.2.2", + "jsdom": "^17.0.0", "lodash": "^4.17.21", "nyc": "^15.1.0", - "prettier": "^2.3.1", + "prettier": "^2.4.1", "pretty-quick": "^3.1.1", - "sinon": "^11.1.1", - "spectron": "^13.0.0", + "sinon": "^11.1.2", + "spectron": "^15.0.0", "stylelint": "^13.13.1", "stylelint-config-prettier": "^8.0.2", "stylelint-config-standard": "^22.0.0", - "stylelint-prettier": "^1.2.0" + "stylelint-prettier": "^1.2.0", + "suncalc": "^1.8.0" }, "optionalDependencies": { - "electron": "^11.4.9" + "electron": "^13.5.0" }, "dependencies": { "colors": "^1.4.0", - "console-stamp": "^3.0.2", - "digest-fetch": "^1.2.0", - "eslint": "^7.29.0", + "console-stamp": "^3.0.3", + "digest-fetch": "^1.2.1", + "eslint": "^7.32.0", "express": "^4.17.1", "express-ipfilter": "^1.2.0", "feedme": "^2.0.2", @@ -79,10 +81,9 @@ "iconv-lite": "^0.6.3", "module-alias": "^2.2.2", "moment": "^2.29.1", - "node-fetch": "^2.6.1", + "node-fetch": "^2.6.5", "node-ical": "^0.13.0", - "simple-git": "^2.40.0", - "socket.io": "^4.1.2" + "socket.io": "^4.2.0" }, "_moduleAliases": { "node_helper": "js/node_helper.js", @@ -96,6 +97,9 @@ "projects": [ { "displayName": "unit", + "moduleNameMapper": { + "logger": "/js/logger.js" + }, "testMatch": [ "**/tests/unit/**/*.[jt]s?(x)" ], @@ -103,14 +107,31 @@ "/tests/unit/mocks" ] }, + { + "displayName": "electron", + "testMatch": [ + "**/tests/electron/**/*.[jt]s?(x)" + ], + "testPathIgnorePatterns": [ + "/tests/electron/modules/mocks", + "/tests/electron/global-setup.js", + "/tests/electron/modules/basic-auth.js" + ] + }, { "displayName": "e2e", + "setupFilesAfterEnv": [ + "/tests/e2e/mock-console.js" + ], "testMatch": [ "**/tests/e2e/**/*.[jt]s?(x)" ], + "modulePaths": [ + "/js/" + ], "testPathIgnorePatterns": [ - "/tests/e2e/modules/mocks", - "/tests/e2e/global-setup.js" + "/tests/e2e/global-setup.js", + "/tests/e2e/mock-console.js" ] } ] diff --git a/tests/configs/default.js b/tests/configs/default.js new file mode 100644 index 00000000..5568e5e0 --- /dev/null +++ b/tests/configs/default.js @@ -0,0 +1,21 @@ +/* Magic Mirror Test default config for modules + * + * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com + * MIT Licensed. + */ +exports.configFactory = function (options) { + return Object.assign( + { + electronOptions: { + webPreferences: { + nodeIntegration: true, + enableRemoteModule: true, + contextIsolation: false + } + }, + + modules: [] + }, + options + ); +}; diff --git a/tests/configs/empty_ipWhiteList.js b/tests/configs/empty_ipWhiteList.js index 45728c71..cdf637c5 100644 --- a/tests/configs/empty_ipWhiteList.js +++ b/tests/configs/empty_ipWhiteList.js @@ -3,22 +3,9 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = { - port: 8080, - ipWhitelist: [], - - language: "en", - timeFormat: 24, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, - - modules: [] -}; +let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ + ipWhitelist: [] +}); /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/env.js b/tests/configs/env.js index 99bd6b4e..a2d81f67 100644 --- a/tests/configs/env.js +++ b/tests/configs/env.js @@ -3,22 +3,7 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", - timeFormat: 24, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, - - modules: [] -}; +let config = require(process.cwd() + "/tests/configs/default.js").configFactory(); /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/alert/default.js b/tests/configs/modules/alert/default.js index 8ee282d0..423260c7 100644 --- a/tests/configs/modules/alert/default.js +++ b/tests/configs/modules/alert/default.js @@ -4,19 +4,6 @@ * MIT Licensed. */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", - timeFormat: 24, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, - modules: [ { module: "alert", diff --git a/tests/configs/modules/calendar/auth-default.js b/tests/configs/modules/calendar/auth-default.js index 053c18ff..8375bfcd 100644 --- a/tests/configs/modules/calendar/auth-default.js +++ b/tests/configs/modules/calendar/auth-default.js @@ -3,19 +3,8 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", +let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { @@ -35,7 +24,7 @@ let config = { } } ] -}; +}); /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/calendar/basic-auth.js b/tests/configs/modules/calendar/basic-auth.js index c34998b8..a1150281 100644 --- a/tests/configs/modules/calendar/basic-auth.js +++ b/tests/configs/modules/calendar/basic-auth.js @@ -3,19 +3,8 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", +let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { @@ -36,7 +25,7 @@ let config = { } } ] -}; +}); /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/calendar/changed-port.js b/tests/configs/modules/calendar/changed-port.js index a7e3b34a..e43feafa 100644 --- a/tests/configs/modules/calendar/changed-port.js +++ b/tests/configs/modules/calendar/changed-port.js @@ -3,19 +3,8 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", +let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { @@ -35,7 +24,7 @@ let config = { } } ] -}; +}); /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/calendar/custom.js b/tests/configs/modules/calendar/custom.js index 6b0e6707..16f82ea0 100644 --- a/tests/configs/modules/calendar/custom.js +++ b/tests/configs/modules/calendar/custom.js @@ -3,19 +3,8 @@ * By Rejas * MIT Licensed. */ -let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", +let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { @@ -35,7 +24,7 @@ let config = { } } ] -}; +}); /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/calendar/default.js b/tests/configs/modules/calendar/default.js index 901a6667..5964b294 100644 --- a/tests/configs/modules/calendar/default.js +++ b/tests/configs/modules/calendar/default.js @@ -3,19 +3,8 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", +let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { @@ -31,7 +20,7 @@ let config = { } } ] -}; +}); /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/calendar/fail-basic-auth.js b/tests/configs/modules/calendar/fail-basic-auth.js index c48d2471..54d04064 100644 --- a/tests/configs/modules/calendar/fail-basic-auth.js +++ b/tests/configs/modules/calendar/fail-basic-auth.js @@ -5,19 +5,8 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", +let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { @@ -38,7 +27,7 @@ let config = { } } ] -}; +}); /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/calendar/old-basic-auth.js b/tests/configs/modules/calendar/old-basic-auth.js index 7d0a146b..06570eb1 100644 --- a/tests/configs/modules/calendar/old-basic-auth.js +++ b/tests/configs/modules/calendar/old-basic-auth.js @@ -3,19 +3,8 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", +let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { @@ -33,7 +22,7 @@ let config = { } } ] -}; +}); /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/calendar/recurring.js b/tests/configs/modules/calendar/recurring.js index 371446a3..879b966e 100644 --- a/tests/configs/modules/calendar/recurring.js +++ b/tests/configs/modules/calendar/recurring.js @@ -3,19 +3,8 @@ * By Rejas * MIT Licensed. */ -let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", +let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { @@ -32,7 +21,7 @@ let config = { } } ] -}; +}); /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/clock/clock_12hr.js b/tests/configs/modules/clock/clock_12hr.js index bf3cedff..6b8917bd 100644 --- a/tests/configs/modules/clock/clock_12hr.js +++ b/tests/configs/modules/clock/clock_12hr.js @@ -4,18 +4,7 @@ * MIT Licensed. */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { diff --git a/tests/configs/modules/clock/clock_24hr.js b/tests/configs/modules/clock/clock_24hr.js index 7813a10d..27f89d0c 100644 --- a/tests/configs/modules/clock/clock_24hr.js +++ b/tests/configs/modules/clock/clock_24hr.js @@ -4,19 +4,6 @@ * MIT Licensed. */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", - timeFormat: 24, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, - modules: [ { module: "clock", diff --git a/tests/configs/modules/clock/clock_analog.js b/tests/configs/modules/clock/clock_analog.js index b18412d0..cbe3fecc 100644 --- a/tests/configs/modules/clock/clock_analog.js +++ b/tests/configs/modules/clock/clock_analog.js @@ -3,19 +3,6 @@ * MIT Licensed. */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", - timeFormat: 24, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, - modules: [ { module: "clock", diff --git a/tests/configs/modules/clock/clock_displaySeconds_false.js b/tests/configs/modules/clock/clock_displaySeconds_false.js index 292a8283..57bf006a 100644 --- a/tests/configs/modules/clock/clock_displaySeconds_false.js +++ b/tests/configs/modules/clock/clock_displaySeconds_false.js @@ -4,18 +4,7 @@ * MIT Licensed. */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { diff --git a/tests/configs/modules/clock/clock_showPeriodUpper.js b/tests/configs/modules/clock/clock_showPeriodUpper.js index 5dd30222..1e01644f 100644 --- a/tests/configs/modules/clock/clock_showPeriodUpper.js +++ b/tests/configs/modules/clock/clock_showPeriodUpper.js @@ -4,18 +4,7 @@ * MIT Licensed. */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { diff --git a/tests/configs/modules/clock/clock_showTime.js b/tests/configs/modules/clock/clock_showTime.js new file mode 100644 index 00000000..37bdc5cc --- /dev/null +++ b/tests/configs/modules/clock/clock_showTime.js @@ -0,0 +1,23 @@ +/* Magic Mirror Test config for default clock module + * + * By Johan Hammar + * MIT Licensed. + */ +let config = { + timeFormat: 12, + + modules: [ + { + module: "clock", + position: "middle_center", + config: { + showTime: false + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/clock/clock_showWeek.js b/tests/configs/modules/clock/clock_showWeek.js index ca9d4384..2c421e85 100644 --- a/tests/configs/modules/clock/clock_showWeek.js +++ b/tests/configs/modules/clock/clock_showWeek.js @@ -4,18 +4,7 @@ * MIT Licensed. */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { diff --git a/tests/configs/modules/clock/es/clock_12hr.js b/tests/configs/modules/clock/es/clock_12hr.js index 82f5bfdb..07e5206a 100644 --- a/tests/configs/modules/clock/es/clock_12hr.js +++ b/tests/configs/modules/clock/es/clock_12hr.js @@ -4,18 +4,8 @@ * MIT Licensed. */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - language: "es", timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { diff --git a/tests/configs/modules/clock/es/clock_24hr.js b/tests/configs/modules/clock/es/clock_24hr.js index 8db5aae2..469f4e3b 100644 --- a/tests/configs/modules/clock/es/clock_24hr.js +++ b/tests/configs/modules/clock/es/clock_24hr.js @@ -4,18 +4,7 @@ * MIT Licensed. */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - language: "es", - timeFormat: 24, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { diff --git a/tests/configs/modules/clock/es/clock_showPeriodUpper.js b/tests/configs/modules/clock/es/clock_showPeriodUpper.js index 1d24a58a..0253c28c 100644 --- a/tests/configs/modules/clock/es/clock_showPeriodUpper.js +++ b/tests/configs/modules/clock/es/clock_showPeriodUpper.js @@ -4,18 +4,8 @@ * MIT Licensed. */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - language: "es", timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { diff --git a/tests/configs/modules/clock/es/clock_showWeek.js b/tests/configs/modules/clock/es/clock_showWeek.js index d86db2d7..dd8f6cd2 100644 --- a/tests/configs/modules/clock/es/clock_showWeek.js +++ b/tests/configs/modules/clock/es/clock_showWeek.js @@ -5,18 +5,8 @@ * MIT Licensed. */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - language: "es", timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { diff --git a/tests/configs/modules/compliments/compliments_anytime.js b/tests/configs/modules/compliments/compliments_anytime.js index 21db9ffb..2034b379 100644 --- a/tests/configs/modules/compliments/compliments_anytime.js +++ b/tests/configs/modules/compliments/compliments_anytime.js @@ -4,18 +4,7 @@ * MIT Licensed. */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { diff --git a/tests/configs/modules/compliments/compliments_date.js b/tests/configs/modules/compliments/compliments_date.js index cc2134bb..a89dd7de 100644 --- a/tests/configs/modules/compliments/compliments_date.js +++ b/tests/configs/modules/compliments/compliments_date.js @@ -4,18 +4,7 @@ * MIT Licensed. */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { diff --git a/tests/configs/modules/compliments/compliments_only_anytime.js b/tests/configs/modules/compliments/compliments_only_anytime.js index 145157d9..5261e58b 100644 --- a/tests/configs/modules/compliments/compliments_only_anytime.js +++ b/tests/configs/modules/compliments/compliments_only_anytime.js @@ -4,18 +4,7 @@ * MIT Licensed. */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { diff --git a/tests/configs/modules/compliments/compliments_parts_day.js b/tests/configs/modules/compliments/compliments_parts_day.js index c04b3a32..08c9d94e 100644 --- a/tests/configs/modules/compliments/compliments_parts_day.js +++ b/tests/configs/modules/compliments/compliments_parts_day.js @@ -4,18 +4,7 @@ * MIT Licensed. */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { diff --git a/tests/configs/modules/display.js b/tests/configs/modules/display.js index d22e3cf5..03aa4f19 100644 --- a/tests/configs/modules/display.js +++ b/tests/configs/modules/display.js @@ -4,22 +4,6 @@ * MIT Licensed. */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", - timeFormat: 24, - units: "metric", - electronOptions: { - fullscreen: false, - width: 800, - height: 600, - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, - modules: [ { module: "helloworld", diff --git a/tests/configs/modules/helloworld/helloworld.js b/tests/configs/modules/helloworld/helloworld.js index c0e00458..39480bc1 100644 --- a/tests/configs/modules/helloworld/helloworld.js +++ b/tests/configs/modules/helloworld/helloworld.js @@ -4,19 +4,6 @@ * MIT Licensed. */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", - timeFormat: 24, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, - modules: [ { module: "helloworld", diff --git a/tests/configs/modules/helloworld/helloworld_default.js b/tests/configs/modules/helloworld/helloworld_default.js index 9d516aef..ea95ad83 100644 --- a/tests/configs/modules/helloworld/helloworld_default.js +++ b/tests/configs/modules/helloworld/helloworld_default.js @@ -4,19 +4,6 @@ * MIT Licensed. */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", - timeFormat: 24, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, - modules: [ { module: "helloworld", diff --git a/tests/configs/modules/newsfeed/default.js b/tests/configs/modules/newsfeed/default.js index 94c9a47f..7758da0c 100644 --- a/tests/configs/modules/newsfeed/default.js +++ b/tests/configs/modules/newsfeed/default.js @@ -4,18 +4,7 @@ * MIT Licensed. */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { diff --git a/tests/configs/modules/newsfeed/incorrect_url.js b/tests/configs/modules/newsfeed/incorrect_url.js index 110a1968..522fa2d1 100644 --- a/tests/configs/modules/newsfeed/incorrect_url.js +++ b/tests/configs/modules/newsfeed/incorrect_url.js @@ -3,18 +3,7 @@ * MIT Licensed. */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { diff --git a/tests/configs/modules/newsfeed/prohibited_words.js b/tests/configs/modules/newsfeed/prohibited_words.js index f9bfa5cf..68d22f54 100644 --- a/tests/configs/modules/newsfeed/prohibited_words.js +++ b/tests/configs/modules/newsfeed/prohibited_words.js @@ -3,18 +3,7 @@ * MIT Licensed. */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { diff --git a/tests/configs/modules/positions.js b/tests/configs/modules/positions.js index b99316ce..186c25f9 100644 --- a/tests/configs/modules/positions.js +++ b/tests/configs/modules/positions.js @@ -4,19 +4,6 @@ * MIT Licensed. */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", - timeFormat: 24, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, - modules: // Using exotic content. This is why don't accept go to JSON configuration file (function () { diff --git a/tests/configs/modules/weather/currentweather_compliments.js b/tests/configs/modules/weather/currentweather_compliments.js index 0a039b36..35d5ffb5 100644 --- a/tests/configs/modules/weather/currentweather_compliments.js +++ b/tests/configs/modules/weather/currentweather_compliments.js @@ -3,21 +3,7 @@ * By rejas https://github.com/rejas * MIT Licensed. */ -let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", - timeFormat: 24, - units: "metric", - electronOptions: { - fullscreen: false, - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, - +let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ modules: [ { module: "compliments", @@ -39,7 +25,7 @@ let config = { } } ] -}; +}); /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/weather/currentweather_default.js b/tests/configs/modules/weather/currentweather_default.js index 440cc725..5c7edd5c 100644 --- a/tests/configs/modules/weather/currentweather_default.js +++ b/tests/configs/modules/weather/currentweather_default.js @@ -3,19 +3,8 @@ * By fewieden https://github.com/fewieden * MIT Licensed. */ -let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", +let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { @@ -28,7 +17,7 @@ let config = { } } ] -}; +}); /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/weather/currentweather_options.js b/tests/configs/modules/weather/currentweather_options.js index 3fcd49b9..f3ff9d5d 100644 --- a/tests/configs/modules/weather/currentweather_options.js +++ b/tests/configs/modules/weather/currentweather_options.js @@ -3,20 +3,7 @@ * By fewieden https://github.com/fewieden * MIT Licensed. */ -let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", - timeFormat: 24, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, - +let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ modules: [ { module: "weather", @@ -34,7 +21,7 @@ let config = { } } ] -}; +}); /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/weather/currentweather_units.js b/tests/configs/modules/weather/currentweather_units.js index 9eba6660..af73d058 100644 --- a/tests/configs/modules/weather/currentweather_units.js +++ b/tests/configs/modules/weather/currentweather_units.js @@ -3,19 +3,8 @@ * By fewieden https://github.com/fewieden * MIT Licensed. */ -let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", - timeFormat: 24, +let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ units: "imperial", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { @@ -30,7 +19,7 @@ let config = { } } ] -}; +}); /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/weather/forecastweather_default.js b/tests/configs/modules/weather/forecastweather_default.js index dbe2d7e3..f4b401f6 100644 --- a/tests/configs/modules/weather/forecastweather_default.js +++ b/tests/configs/modules/weather/forecastweather_default.js @@ -3,19 +3,8 @@ * By fewieden https://github.com/fewieden * MIT Licensed. */ -let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", +let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { @@ -30,7 +19,7 @@ let config = { } } ] -}; +}); /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/weather/forecastweather_options.js b/tests/configs/modules/weather/forecastweather_options.js index 32e0c8af..094d9a00 100644 --- a/tests/configs/modules/weather/forecastweather_options.js +++ b/tests/configs/modules/weather/forecastweather_options.js @@ -3,19 +3,8 @@ * By fewieden https://github.com/fewieden * MIT Licensed. */ -let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", +let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { @@ -33,7 +22,7 @@ let config = { } } ] -}; +}); /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/modules/weather/forecastweather_units.js b/tests/configs/modules/weather/forecastweather_units.js index 9d1a54ff..843f874b 100644 --- a/tests/configs/modules/weather/forecastweather_units.js +++ b/tests/configs/modules/weather/forecastweather_units.js @@ -3,19 +3,8 @@ * By rejas * MIT Licensed. */ -let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", - timeFormat: 24, +let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ units: "imperial", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, modules: [ { @@ -31,7 +20,7 @@ let config = { } } ] -}; +}); /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/noIpWhiteList.js b/tests/configs/noIpWhiteList.js index 28369bea..40655480 100644 --- a/tests/configs/noIpWhiteList.js +++ b/tests/configs/noIpWhiteList.js @@ -3,22 +3,9 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = { - port: 8080, - ipWhitelist: ["x.x.x.x"], - - language: "en", - timeFormat: 24, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, - - modules: [] -}; +let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ + ipWhitelist: ["x.x.x.x"] +}); /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/port_8090.js b/tests/configs/port_8090.js index 99386dd2..7756fb76 100644 --- a/tests/configs/port_8090.js +++ b/tests/configs/port_8090.js @@ -3,22 +3,9 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -let config = { - port: 8090, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - - language: "en", - timeFormat: 24, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - }, - - modules: [] -}; +let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ + port: 8090 +}); /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { diff --git a/tests/configs/without_modules.js b/tests/configs/without_modules.js index 8703374c..50ff521e 100644 --- a/tests/configs/without_modules.js +++ b/tests/configs/without_modules.js @@ -4,18 +4,7 @@ * MIT Licensed. */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.10.1"], - - language: "en", - timeFormat: 24, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - enableRemoteModule: true - } - } + ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.10.1"] }; /*************** DO NOT EDIT THE LINE BELOW ***************/ diff --git a/tests/e2e/env_spec.js b/tests/e2e/env_spec.js index 706274a2..b2a7238a 100644 --- a/tests/e2e/env_spec.js +++ b/tests/e2e/env_spec.js @@ -1,42 +1,13 @@ -const helpers = require("./global-setup"); const fetch = require("node-fetch"); +const helpers = require("./global-setup"); describe("Electron app environment", function () { - helpers.setupTimeout(this); - - let app = null; - - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/env.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/default.js"); + helpers.getDocument(done); }); - - beforeEach(function () { - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); - }); - - afterEach(function () { - return helpers.stopApplication(app); - }); - - it("should open a browserwindow", async function () { - await app.client.waitUntilWindowLoaded(); - app.browserWindow.focus(); - expect(await app.client.getWindowCount()).toBe(1); - expect(await app.browserWindow.isMinimized()).toBe(false); - expect(await app.browserWindow.isDevToolsOpened()).toBe(false); - expect(await app.browserWindow.isVisible()).toBe(true); - expect(await app.browserWindow.isFocused()).toBe(true); - const bounds = await app.browserWindow.getBounds(); - expect(bounds.width).toBeGreaterThan(0); - expect(bounds.height).toBeGreaterThan(0); - expect(await app.browserWindow.getTitle()).toBe("MagicMirror²"); + afterAll(function () { + helpers.stopApplication(); }); it("get request from http://localhost:8080 should return 200", function (done) { @@ -52,4 +23,10 @@ describe("Electron app environment", function () { done(); }); }); + + it("should show the title MagicMirror²", function () { + const elem = document.querySelector("title"); + expect(elem).not.toBe(null); + expect(elem.textContent).toBe("MagicMirror²"); + }); }); diff --git a/tests/e2e/fonts.js b/tests/e2e/fonts.js index b1459294..54cd2d87 100644 --- a/tests/e2e/fonts.js +++ b/tests/e2e/fonts.js @@ -1,10 +1,7 @@ -const helpers = require("./global-setup"); const fetch = require("node-fetch"); +const helpers = require("./global-setup"); describe("All font files from roboto.css should be downloadable", function () { - helpers.setupTimeout(this); - - let app; const fontFiles = []; // Statements below filters out all 'url' lines in the CSS file const fileContent = require("fs").readFileSync(__dirname + "/../../fonts/roboto.css", "utf8"); @@ -18,20 +15,10 @@ describe("All font files from roboto.css should be downloadable", function () { } beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/without_modules.js"; - - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); + helpers.startApplication("tests/configs/without_modules.js"); }); - afterAll(function () { - return helpers.stopApplication(app); + helpers.stopApplication(); }); test.each(fontFiles)("should return 200 HTTP code for file '%s'", (fontFile, done) => { diff --git a/tests/e2e/global-setup.js b/tests/e2e/global-setup.js index a1e0685b..45726493 100644 --- a/tests/e2e/global-setup.js +++ b/tests/e2e/global-setup.js @@ -1,53 +1,32 @@ -/* - * Magic Mirror Global Setup Test Suite - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ -const Application = require("spectron").Application; -const assert = require("assert"); -const path = require("path"); -const EventEmitter = require("events"); +const jsdom = require("jsdom"); -exports.getElectronPath = function () { - let electronPath = path.join(__dirname, "..", "..", "node_modules", ".bin", "electron"); - if (process.platform === "win32") { - electronPath += ".cmd"; +exports.startApplication = function (configFilename, exec) { + jest.resetModules(); + if (global.app) { + global.app.stop(); } - return electronPath; + // Set config sample for use in test + process.env.MM_CONFIG_FILE = configFilename; + if (exec) exec; + global.app = require("app.js"); + global.app.start(); }; -// Set timeout - if this is run as CI Job, increase timeout -exports.setupTimeout = function (test) { - if (process.env.CI) { - jest.setTimeout(30000); - } else { - jest.setTimeout(10000); +exports.stopApplication = function () { + if (global.app) { + global.app.stop(); } }; -exports.startApplication = function (options) { - const emitter = new EventEmitter(); - emitter.setMaxListeners(100); - - options.path = exports.getElectronPath(); - if (process.env.CI) { - options.startTimeout = 30000; - } - - const app = new Application(options); - return app.start().then(function () { - assert.strictEqual(app.isRunning(), true); - return app; - }); -}; - -exports.stopApplication = function (app) { - if (!app || !app.isRunning()) { - return; - } - - return app.stop().then(function () { - assert.strictEqual(app.isRunning(), false); +exports.getDocument = function (callback, ms) { + 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.onload = function () { + global.document = dom.window.document; + setTimeout(() => { + callback(); + }, ms); + }; }); }; diff --git a/tests/e2e/ipWhitelist_spec.js b/tests/e2e/ipWhitelist_spec.js index 3406e0e7..b518cfff 100644 --- a/tests/e2e/ipWhitelist_spec.js +++ b/tests/e2e/ipWhitelist_spec.js @@ -1,29 +1,13 @@ -const helpers = require("./global-setup"); const fetch = require("node-fetch"); +const helpers = require("./global-setup"); describe("ipWhitelist directive configuration", function () { - helpers.setupTimeout(this); - - let app = null; - - beforeEach(function () { - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); - }); - - afterEach(function () { - return helpers.stopApplication(app); - }); - describe("Set ipWhitelist without access", function () { beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/noIpWhiteList.js"; + helpers.startApplication("tests/configs/noIpWhiteList.js"); + }); + afterAll(function () { + helpers.stopApplication(); }); it("should return 403", function (done) { @@ -36,8 +20,10 @@ describe("ipWhitelist directive configuration", function () { describe("Set ipWhitelist []", function () { beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/empty_ipWhiteList.js"; + helpers.startApplication("tests/configs/empty_ipWhiteList.js"); + }); + afterAll(function () { + helpers.stopApplication(); }); it("should return 200", function (done) { diff --git a/tests/e2e/mock-console.js b/tests/e2e/mock-console.js new file mode 100644 index 00000000..90b70f12 --- /dev/null +++ b/tests/e2e/mock-console.js @@ -0,0 +1,21 @@ +/** + * Suppresses errors concerning web server already shut down. + * + * @param {string} err The error message. + */ +function mockError(err) { + if (err.includes("ECONNREFUSED") || err.includes("ECONNRESET") || err.includes("socket hang up") || err.includes("exports is not defined")) { + jest.fn(); + } else { + console.dir(err); + } +} + +global.console = { + log: jest.fn(), + dir: console.dir, + error: mockError, + warn: console.warn, + info: jest.fn(), + debug: console.debug +}; diff --git a/tests/e2e/modules/alert_spec.js b/tests/e2e/modules/alert_spec.js index 12e724f0..a557acc5 100644 --- a/tests/e2e/modules/alert_spec.js +++ b/tests/e2e/modules/alert_spec.js @@ -1,32 +1,17 @@ const helpers = require("../global-setup"); describe("Alert module", function () { - helpers.setupTimeout(this); - - let app = null; - - beforeEach(function () { - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/alert/default.js"); + helpers.getDocument(done, 1000); + }); + afterAll(function () { + helpers.stopApplication(); }); - afterEach(function () { - return helpers.stopApplication(app); - }); - - describe("Default configuration", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/alert/default.js"; - }); - - it("should show the welcome message", function () { - return app.client.waitUntilTextExists(".ns-box .ns-box-inner .light.bright.small", "Welcome, start was successful!", 10000); - }); + it("should show the welcome message", function () { + const elem = document.querySelector(".ns-box .ns-box-inner .light.bright.small"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("Welcome, start was successful!"); }); }); diff --git a/tests/e2e/modules/clock_es_spec.js b/tests/e2e/modules/clock_es_spec.js index f97fba2f..78818014 100644 --- a/tests/e2e/modules/clock_es_spec.js +++ b/tests/e2e/modules/clock_es_spec.js @@ -1,86 +1,71 @@ const helpers = require("../global-setup"); describe("Clock set to spanish language module", function () { - helpers.setupTimeout(this); + afterAll(function () { + helpers.stopApplication(); + }); - let app = null; - - testMatch = async function (element, regex) { - await app.client.waitUntilWindowLoaded(); - const elem = await app.client.$(element); - const txt = await elem.getText(element); - return expect(txt).toMatch(regex); + const testMatch = function (element, regex) { + const elem = document.querySelector(element); + expect(elem).not.toBe(null); + expect(elem.textContent).toMatch(regex); }; - beforeEach(function () { - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); - }); - - afterEach(function () { - return helpers.stopApplication(app); - }); - describe("with default 24hr clock config", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/es/clock_24hr.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/clock/es/clock_24hr.js"); + helpers.getDocument(done, 1000); }); - it("shows date with correct format", async function () { + it("shows date with correct format", function () { const dateRegex = /^(?:lunes|martes|miércoles|jueves|viernes|sábado|domingo), \d{1,2} de (?:enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre) de \d{4}$/; - return testMatch(".clock .date", dateRegex); + testMatch(".clock .date", dateRegex); }); - it("shows time in 24hr format", async function () { + it("shows time in 24hr format", function () { const timeRegex = /^(?:2[0-3]|[01]\d):[0-5]\d[0-5]\d$/; - return testMatch(".clock .time", timeRegex); + testMatch(".clock .time", timeRegex); }); }); describe("with default 12hr clock config", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/es/clock_12hr.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/clock/es/clock_12hr.js"); + helpers.getDocument(done, 1000); }); - it("shows date with correct format", async function () { + it("shows date with correct format", function () { const dateRegex = /^(?:lunes|martes|miércoles|jueves|viernes|sábado|domingo), \d{1,2} de (?:enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre) de \d{4}$/; - return testMatch(".clock .date", dateRegex); + testMatch(".clock .date", dateRegex); }); - it("shows time in 12hr format", async function () { + it("shows time in 12hr format", function () { const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[ap]m$/; - return testMatch(".clock .time", timeRegex); + testMatch(".clock .time", timeRegex); }); }); describe("with showPeriodUpper config enabled", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/es/clock_showPeriodUpper.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/clock/es/clock_showPeriodUpper.js"); + helpers.getDocument(done, 1000); }); - it("shows 12hr time with upper case AM/PM", async function () { + it("shows 12hr time with upper case AM/PM", function () { const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[AP]M$/; - return testMatch(".clock .time", timeRegex); + testMatch(".clock .time", timeRegex); }); }); describe("with showWeek config enabled", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/es/clock_showWeek.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/clock/es/clock_showWeek.js"); + helpers.getDocument(done, 1000); }); - it("shows week with correct format", async function () { + it("shows week with correct format", function () { const weekRegex = /^Semana [0-9]{1,2}$/; - return testMatch(".clock .week", weekRegex); + testMatch(".clock .week", weekRegex); }); }); }); diff --git a/tests/e2e/modules/clock_spec.js b/tests/e2e/modules/clock_spec.js index c09f44de..79e26f47 100644 --- a/tests/e2e/modules/clock_spec.js +++ b/tests/e2e/modules/clock_spec.js @@ -2,120 +2,115 @@ const helpers = require("../global-setup"); const moment = require("moment"); describe("Clock module", function () { - helpers.setupTimeout(this); + afterAll(function () { + helpers.stopApplication(); + }); - let app = null; - - testMatch = async function (element, regex) { - await app.client.waitUntilWindowLoaded(); - const elem = await app.client.$(element); - const txt = await elem.getText(element); - return expect(txt).toMatch(regex); + const testMatch = function (element, regex) { + const elem = document.querySelector(element); + expect(elem).not.toBe(null); + expect(elem.textContent).toMatch(regex); }; - beforeEach(function () { - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); - }); - - afterEach(function () { - return helpers.stopApplication(app); - }); - describe("with default 24hr clock config", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_24hr.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/clock/clock_24hr.js"); + helpers.getDocument(done, 1000); }); - it("should show the date in the correct format", async function () { + it("should show the date in the correct format", function () { const dateRegex = /^(?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), (?:January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}, \d{4}$/; - return testMatch(".clock .date", dateRegex); + testMatch(".clock .date", dateRegex); }); - it("should show the time in 24hr format", async function () { + it("should show the time in 24hr format", function () { const timeRegex = /^(?:2[0-3]|[01]\d):[0-5]\d[0-5]\d$/; - return testMatch(".clock .time", timeRegex); + testMatch(".clock .time", timeRegex); }); }); describe("with default 12hr clock config", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_12hr.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/clock/clock_12hr.js"); + helpers.getDocument(done, 1000); }); - it("should show the date in the correct format", async function () { + it("should show the date in the correct format", function () { const dateRegex = /^(?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), (?:January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}, \d{4}$/; - return testMatch(".clock .date", dateRegex); + testMatch(".clock .date", dateRegex); }); - it("should show the time in 12hr format", async function () { + it("should show the time in 12hr format", function () { const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[ap]m$/; - return testMatch(".clock .time", timeRegex); + testMatch(".clock .time", timeRegex); }); }); describe("with showPeriodUpper config enabled", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_showPeriodUpper.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/clock/clock_showPeriodUpper.js"); + helpers.getDocument(done, 1000); }); - it("should show 12hr time with upper case AM/PM", async function () { + it("should show 12hr time with upper case AM/PM", function () { const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[AP]M$/; - return testMatch(".clock .time", timeRegex); + testMatch(".clock .time", timeRegex); }); }); describe("with displaySeconds config disabled", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_displaySeconds_false.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/clock/clock_displaySeconds_false.js"); + helpers.getDocument(done, 1000); }); - it("should show 12hr time without seconds am/pm", async function () { + it("should show 12hr time without seconds am/pm", function () { const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[ap]m$/; - return testMatch(".clock .time", timeRegex); + testMatch(".clock .time", timeRegex); + }); + }); + + describe("with showTime config disabled", function () { + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/clock/clock_showTime.js"); + helpers.getDocument(done, 1000); + }); + + it("should show not show the time when digital clock is shown", function () { + const elem = document.querySelector(".clock .digital .time"); + expect(elem).toBe(null); }); }); describe("with showWeek config enabled", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_showWeek.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/clock/clock_showWeek.js"); + helpers.getDocument(done, 1000); }); - it("should show the week in the correct format", async function () { + it("should show the week in the correct format", function () { const weekRegex = /^Week [0-9]{1,2}$/; - return testMatch(".clock .week", weekRegex); + testMatch(".clock .week", weekRegex); }); - it("should show the week with the correct number of week of year", async function () { + it("should show the week with the correct number of week of year", function () { const currentWeekNumber = moment().week(); const weekToShow = "Week " + currentWeekNumber; - await app.client.waitUntilWindowLoaded(); - const elem = await app.client.$(".clock .week"); - const txt = await elem.getText(".clock .week"); - return expect(txt).toBe(weekToShow); + const elem = document.querySelector(".clock .week"); + expect(elem).not.toBe(null); + expect(elem.textContent).toBe(weekToShow); }); }); describe("with analog clock face enabled", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_analog.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/clock/clock_analog.js"); + helpers.getDocument(done, 1000); }); - it("should show the analog clock face", async () => { - await app.client.waitUntilWindowLoaded(); - const clock = await app.client.$$(".clockCircle"); - return expect(clock.length).toBe(1); + it("should show the analog clock face", () => { + const elem = document.querySelector(".clockCircle"); + expect(elem).not.toBe(null); }); }); }); diff --git a/tests/e2e/modules/compliments_spec.js b/tests/e2e/modules/compliments_spec.js index 81c6e982..73f851c5 100644 --- a/tests/e2e/modules/compliments_spec.js +++ b/tests/e2e/modules/compliments_spec.js @@ -1,106 +1,87 @@ const helpers = require("../global-setup"); +/** + * move similar tests in function doTest + * + * @param {Array} complimentsArray The array of compliments. + */ +function doTest(complimentsArray) { + let elem = document.querySelector(".compliments"); + expect(elem).not.toBe(null); + elem = document.querySelector(".module-content"); + expect(elem).not.toBe(null); + expect(complimentsArray).toContain(elem.textContent); +} + describe("Compliments module", function () { - helpers.setupTimeout(this); - - let app = null; - - beforeEach(function () { - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); - }); - - afterEach(function () { - return helpers.stopApplication(app); + afterAll(function () { + helpers.stopApplication(); }); describe("parts of days", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/compliments/compliments_parts_day.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/compliments/compliments_parts_day.js"); + helpers.getDocument(done, 1000); }); - it("if Morning compliments for that part of day", async function () { + it("if Morning compliments for that part of day", function () { const hour = new Date().getHours(); if (hour >= 3 && hour < 12) { // if morning check - const elem = await app.client.$(".compliments"); - return elem.getText(".compliments").then(function (text) { - expect(["Hi", "Good Morning", "Morning test"]).toContain(text); - }); + doTest(["Hi", "Good Morning", "Morning test"]); } }); - it("if Afternoon show Compliments for that part of day", async function () { + it("if Afternoon show Compliments for that part of day", function () { const hour = new Date().getHours(); if (hour >= 12 && hour < 17) { // if afternoon check - const elem = await app.client.$(".compliments"); - return elem.getText(".compliments").then(function (text) { - expect(["Hello", "Good Afternoon", "Afternoon test"]).toContain(text); - }); + doTest(["Hello", "Good Afternoon", "Afternoon test"]); } }); - it("if Evening show Compliments for that part of day", async function () { + it("if Evening show Compliments for that part of day", function () { const hour = new Date().getHours(); if (!(hour >= 3 && hour < 12) && !(hour >= 12 && hour < 17)) { // if evening check - const elem = await app.client.$(".compliments"); - return elem.getText(".compliments").then(function (text) { - expect(["Hello There", "Good Evening", "Evening test"]).toContain(text); - }); + doTest(["Hello There", "Good Evening", "Evening test"]); } }); }); describe("Feature anytime in compliments module", function () { describe("Set anytime and empty compliments for morning, evening and afternoon ", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/compliments/compliments_anytime.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/compliments/compliments_anytime.js"); + helpers.getDocument(done, 1000); }); - it("Show anytime because if configure empty parts of day compliments and set anytime compliments", async function () { - const elem = await app.client.$(".compliments"); - return elem.getText(".compliments").then(function (text) { - expect(["Anytime here"]).toContain(text); - }); + it("Show anytime because if configure empty parts of day compliments and set anytime compliments", function () { + doTest(["Anytime here"]); }); }); describe("Only anytime present in configuration compliments", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/compliments/compliments_only_anytime.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/compliments/compliments_only_anytime.js"); + helpers.getDocument(done, 1000); }); - it("Show anytime compliments", async function () { - const elem = await app.client.$(".compliments"); - return elem.getText(".compliments").then(function (text) { - expect(["Anytime here"]).toContain(text); - }); + it("Show anytime compliments", function () { + doTest(["Anytime here"]); }); }); }); describe("Feature date in compliments module", function () { describe("Set date and empty compliments for anytime, morning, evening and afternoon", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/compliments/compliments_date.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/compliments/compliments_date.js"); + helpers.getDocument(done, 1000); }); - it("Show happy new year compliment on new years day", async function () { - const elem = await app.client.$(".compliments"); - return elem.getText(".compliments").then(function (text) { - expect(["Happy new year!"]).toContain(text); - }); + it("Show happy new year compliment on new years day", function () { + doTest(["Happy new year!"]); }); }); }); diff --git a/tests/e2e/modules/helloworld_spec.js b/tests/e2e/modules/helloworld_spec.js index 95ee1a2d..d8f1a3c6 100644 --- a/tests/e2e/modules/helloworld_spec.js +++ b/tests/e2e/modules/helloworld_spec.js @@ -1,45 +1,33 @@ const helpers = require("../global-setup"); describe("Test helloworld module", function () { - helpers.setupTimeout(this); - - let app = null; - - beforeEach(function () { - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); - }); - - afterEach(function () { - return helpers.stopApplication(app); + afterAll(function () { + helpers.stopApplication(); }); describe("helloworld set config text", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/helloworld/helloworld.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/helloworld/helloworld.js"); + helpers.getDocument(done, 1000); }); - it("Test message helloworld module", async function () { - const elem = await app.client.$(".helloworld"); - return expect(await elem.getText(".helloworld")).toBe("Test HelloWorld Module"); + it("Test message helloworld module", function () { + const elem = document.querySelector(".helloworld"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("Test HelloWorld Module"); }); }); describe("helloworld default config text", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/helloworld/helloworld_default.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/helloworld/helloworld_default.js"); + helpers.getDocument(done, 1000); }); - it("Test message helloworld module", async function () { - const elem = await app.client.$(".helloworld"); - return expect(await elem.getText(".helloworld")).toBe("Hello World!"); + it("Test message helloworld module", function () { + const elem = document.querySelector(".helloworld"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("Hello World!"); }); }); }); diff --git a/tests/e2e/modules/newsfeed_spec.js b/tests/e2e/modules/newsfeed_spec.js index fe544a0b..d7a3b9fe 100644 --- a/tests/e2e/modules/newsfeed_spec.js +++ b/tests/e2e/modules/newsfeed_spec.js @@ -1,67 +1,63 @@ const helpers = require("../global-setup"); describe("Newsfeed module", function () { - helpers.setupTimeout(this); - - let app = null; - - beforeEach(function () { - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); - }); - - afterEach(function () { - return helpers.stopApplication(app); + afterAll(function () { + helpers.stopApplication(); }); describe("Default configuration", function () { - beforeAll(function () { - process.env.MM_CONFIG_FILE = "tests/configs/modules/newsfeed/default.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/newsfeed/default.js"); + helpers.getDocument(done, 3000); }); it("should show the newsfeed title", function () { - return app.client.waitUntilTextExists(".newsfeed .newsfeed-source", "Rodrigo Ramirez Blog", 10000); + const elem = document.querySelector(".newsfeed .newsfeed-source"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("Rodrigo Ramirez Blog"); }); it("should show the newsfeed article", function () { - return app.client.waitUntilTextExists(".newsfeed .newsfeed-title", "QPanel", 10000); + const elem = document.querySelector(".newsfeed .newsfeed-title"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("QPanel"); }); - it("should NOT show the newsfeed description", async () => { - await app.client.waitUntilTextExists(".newsfeed .newsfeed-title", "QPanel", 10000); - const events = await app.client.$$(".newsfeed .newsfeed-desc"); - return expect(events.length).toBe(0); + it("should NOT show the newsfeed description", () => { + const elem = document.querySelector(".newsfeed .newsfeed-desc"); + expect(elem).toBe(null); }); }); describe("Custom configuration", function () { - beforeAll(function () { - process.env.MM_CONFIG_FILE = "tests/configs/modules/newsfeed/prohibited_words.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/newsfeed/prohibited_words.js"); + helpers.getDocument(done, 3000); }); it("should not show articles with prohibited words", function () { - return app.client.waitUntilTextExists(".newsfeed .newsfeed-title", "Problema VirtualBox", 10000); + const elem = document.querySelector(".newsfeed .newsfeed-title"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("Problema VirtualBox"); }); - it("should show the newsfeed description", async () => { - await app.client.waitUntilTextExists(".newsfeed .newsfeed-title", "Problema VirtualBox", 10000); - const events = await app.client.$$(".newsfeed .newsfeed-desc"); - return expect(events.length).toBe(1); + it("should show the newsfeed description", () => { + const elem = document.querySelector(".newsfeed .newsfeed-desc"); + expect(elem).not.toBe(null); + expect(elem.textContent.length).not.toBe(0); }); }); describe("Invalid configuration", function () { - beforeAll(function () { - process.env.MM_CONFIG_FILE = "tests/configs/modules/newsfeed/incorrect_url.js"; + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/newsfeed/incorrect_url.js"); + helpers.getDocument(done, 3000); }); it("should show malformed url warning", function () { - return app.client.waitUntilTextExists(".newsfeed .small", "Error in the Newsfeed module. Malformed url.", 10000); + const elem = document.querySelector(".newsfeed .small"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("Error in the Newsfeed module. Malformed url."); }); }); }); diff --git a/tests/e2e/modules_display_spec.js b/tests/e2e/modules_display_spec.js index 6132c62f..4042e810 100644 --- a/tests/e2e/modules_display_spec.js +++ b/tests/e2e/modules_display_spec.js @@ -1,38 +1,24 @@ const helpers = require("./global-setup"); describe("Display of modules", function () { - helpers.setupTimeout(this); - - let app = null; - - beforeEach(function () { - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/display.js"); + helpers.getDocument(done); + }); + afterAll(function () { + helpers.stopApplication(); }); - afterEach(function () { - return helpers.stopApplication(app); + it("should show the test header", function () { + const elem = document.querySelector("#module_0_helloworld .module-header"); + expect(elem).not.toBe(null); + // textContent gibt hier lowercase zurück, das uppercase wird durch css realisiert, was daher nicht in textContent landet + expect(elem.textContent).toBe("test_header"); }); - describe("Using helloworld", function () { - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/display.js"; - }); - - it("should show the test header", async () => { - const elem = await app.client.$("#module_0_helloworld .module-header", 10000); - return expect(await elem.getText("#module_0_helloworld .module-header")).toBe("TEST_HEADER"); - }); - - it("should show no header if no header text is specified", async () => { - const elem = await app.client.$("#module_1_helloworld .module-header", 10000); - return expect(await elem.getText("#module_1_helloworld .module-header")).toBe(""); - }); + it("should show no header if no header text is specified", function () { + const elem = document.querySelector("#module_1_helloworld .module-header"); + expect(elem).not.toBe(null); + expect(elem.textContent).toBe("undefined"); }); }); diff --git a/tests/e2e/modules_position_spec.js b/tests/e2e/modules_position_spec.js index 7ac1cadd..79b9b96f 100644 --- a/tests/e2e/modules_position_spec.js +++ b/tests/e2e/modules_position_spec.js @@ -1,38 +1,22 @@ const helpers = require("./global-setup"); describe("Position of modules", function () { - helpers.setupTimeout(this); - - let app = null; - - describe("Using helloworld", function () { - afterAll(function () { - return helpers.stopApplication(app); - }); - - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/modules/positions.js"; - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); - }); - - const positions = ["top_bar", "top_left", "top_center", "top_right", "upper_third", "middle_center", "lower_third", "bottom_left", "bottom_center", "bottom_right", "bottom_bar", "fullscreen_above", "fullscreen_below"]; - - for (const position of positions) { - const className = position.replace("_", "."); - it("should show text in " + position, function () { - return app.client.$("." + className).then((result) => { - return result.getText("." + className).then((text) => { - return expect(text).toContain("Text in " + position); - }); - }); - }); - } + beforeAll(function (done) { + helpers.startApplication("tests/configs/modules/positions.js"); + helpers.getDocument(done, 1000); }); + afterAll(function () { + helpers.stopApplication(); + }); + + const positions = ["top_bar", "top_left", "top_center", "top_right", "upper_third", "middle_center", "lower_third", "bottom_left", "bottom_center", "bottom_right", "bottom_bar", "fullscreen_above", "fullscreen_below"]; + + for (const position of positions) { + const className = position.replace("_", "."); + it("should show text in " + position, function () { + const elem = document.querySelector("." + className); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("Text in " + position); + }); + } }); diff --git a/tests/e2e/port_config.js b/tests/e2e/port_config.js index da489414..329acab6 100644 --- a/tests/e2e/port_config.js +++ b/tests/e2e/port_config.js @@ -1,29 +1,13 @@ -const helpers = require("./global-setup"); const fetch = require("node-fetch"); +const helpers = require("./global-setup"); describe("port directive configuration", function () { - helpers.setupTimeout(this); - - let app = null; - - beforeEach(function () { - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); - }); - - afterEach(function () { - return helpers.stopApplication(app); - }); - describe("Set port 8090", function () { beforeAll(function () { - // Set config sample for use in this test - process.env.MM_CONFIG_FILE = "tests/configs/port_8090.js"; + helpers.startApplication("tests/configs/port_8090.js"); + }); + afterAll(function () { + helpers.stopApplication(); }); it("should return 200", function (done) { @@ -36,13 +20,10 @@ describe("port directive configuration", function () { describe("Set port 8100 on environment variable MM_PORT", function () { beforeAll(function () { - process.env.MM_PORT = 8100; - // Set config sample for use in this test - process.env.MM_CONFIG_FILE = "tests/configs/port_8090.js"; + helpers.startApplication("tests/configs/port_8090.js", (process.env.MM_PORT = 8100)); }); - afterAll(function () { - delete process.env.MM_PORT; + helpers.stopApplication(); }); it("should return 200", function (done) { diff --git a/tests/e2e/vendor_spec.js b/tests/e2e/vendor_spec.js index b5289c2f..f6917c0d 100644 --- a/tests/e2e/vendor_spec.js +++ b/tests/e2e/vendor_spec.js @@ -1,31 +1,17 @@ -const helpers = require("./global-setup"); const fetch = require("node-fetch"); - -const before = global.before; -const after = global.after; +const helpers = require("./global-setup"); describe("Vendors", function () { - helpers.setupTimeout(this); - - let app = null; - beforeAll(function () { - process.env.MM_CONFIG_FILE = "tests/configs/env.js"; - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); + helpers.startApplication("tests/configs/default.js"); }); - afterAll(function () { - return helpers.stopApplication(app); + helpers.stopApplication(); }); describe("Get list vendors", function () { const vendors = require(__dirname + "/../../vendor/vendor.js"); + Object.keys(vendors).forEach((vendor) => { it(`should return 200 HTTP code for vendor "${vendor}"`, function (done) { const urlVendor = "http://localhost:8080/vendor/" + vendors[vendor]; diff --git a/tests/e2e/without_modules.js b/tests/e2e/without_modules.js index 0214aed7..8aeeee28 100644 --- a/tests/e2e/without_modules.js +++ b/tests/e2e/without_modules.js @@ -1,36 +1,23 @@ const helpers = require("./global-setup"); describe("Check configuration without modules", function () { - helpers.setupTimeout(this); - - let app = null; - - beforeEach(function () { - return helpers - .startApplication({ - args: ["js/electron.js"] - }) - .then(function (startedApp) { - app = startedApp; - }); + beforeAll(function (done) { + helpers.startApplication("tests/configs/without_modules.js"); + helpers.getDocument(done, 1000); + }); + afterAll(function () { + helpers.stopApplication(); }); - afterEach(function () { - return helpers.stopApplication(app); + it("Show the message MagicMirror title", function () { + const elem = document.querySelector("#module_1_helloworld .module-content"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("Magic Mirror2"); }); - beforeAll(function () { - // Set config sample for use in test - process.env.MM_CONFIG_FILE = "tests/configs/without_modules.js"; - }); - - it("Show the message MagicMirror title", async function () { - const elem = await app.client.$("#module_1_helloworld .module-content"); - return expect(await elem.getText("#module_1_helloworld .module-content")).toBe("Magic Mirror2"); - }); - - it("Show the text Michael's website", async function () { - const elem = await app.client.$("#module_5_helloworld .module-content"); - return expect(await elem.getText("#module_5_helloworld .module-content")).toBe("www.michaelteeuw.nl"); + it("Show the text Michael's website", function () { + const elem = document.querySelector("#module_5_helloworld .module-content"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("www.michaelteeuw.nl"); }); }); diff --git a/tests/e2e/dev_console.js b/tests/electron/dev_console.js similarity index 100% rename from tests/e2e/dev_console.js rename to tests/electron/dev_console.js diff --git a/tests/electron/env_spec.js b/tests/electron/env_spec.js new file mode 100644 index 00000000..46efc719 --- /dev/null +++ b/tests/electron/env_spec.js @@ -0,0 +1,40 @@ +const helpers = require("./global-setup"); + +describe("Electron app environment", function () { + helpers.setupTimeout(this); + + let app = null; + + beforeAll(function () { + // Set config sample for use in test + process.env.MM_CONFIG_FILE = "tests/configs/env.js"; + }); + + beforeEach(function () { + return helpers + .startApplication({ + args: ["js/electron.js"] + }) + .then(function (startedApp) { + app = startedApp; + }); + }); + + afterEach(function () { + return helpers.stopApplication(app); + }); + + it("should open a browserwindow", async function () { + await app.client.waitUntilWindowLoaded(); + app.browserWindow.focus(); + expect(await app.client.getWindowCount()).toBe(1); + expect(await app.browserWindow.isMinimized()).toBe(false); + expect(await app.browserWindow.isDevToolsOpened()).toBe(false); + expect(await app.browserWindow.isVisible()).toBe(true); + expect(await app.browserWindow.isFocused()).toBe(true); + const bounds = await app.browserWindow.getBounds(); + expect(bounds.width).toBeGreaterThan(0); + expect(bounds.height).toBeGreaterThan(0); + expect(await app.browserWindow.getTitle()).toBe("MagicMirror²"); + }); +}); diff --git a/tests/electron/global-setup.js b/tests/electron/global-setup.js new file mode 100644 index 00000000..a1e0685b --- /dev/null +++ b/tests/electron/global-setup.js @@ -0,0 +1,53 @@ +/* + * Magic Mirror Global Setup Test Suite + * + * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com + * MIT Licensed. + */ +const Application = require("spectron").Application; +const assert = require("assert"); +const path = require("path"); +const EventEmitter = require("events"); + +exports.getElectronPath = function () { + let electronPath = path.join(__dirname, "..", "..", "node_modules", ".bin", "electron"); + if (process.platform === "win32") { + electronPath += ".cmd"; + } + return electronPath; +}; + +// Set timeout - if this is run as CI Job, increase timeout +exports.setupTimeout = function (test) { + if (process.env.CI) { + jest.setTimeout(30000); + } else { + jest.setTimeout(10000); + } +}; + +exports.startApplication = function (options) { + const emitter = new EventEmitter(); + emitter.setMaxListeners(100); + + options.path = exports.getElectronPath(); + if (process.env.CI) { + options.startTimeout = 30000; + } + + const app = new Application(options); + return app.start().then(function () { + assert.strictEqual(app.isRunning(), true); + return app; + }); +}; + +exports.stopApplication = function (app) { + if (!app || !app.isRunning()) { + return; + } + + return app.stop().then(function () { + assert.strictEqual(app.isRunning(), false); + }); +}; diff --git a/tests/servers/basic-auth.js b/tests/electron/modules/basic-auth.js similarity index 91% rename from tests/servers/basic-auth.js rename to tests/electron/modules/basic-auth.js index a8b5b6d6..fc08ae40 100644 --- a/tests/servers/basic-auth.js +++ b/tests/electron/modules/basic-auth.js @@ -12,7 +12,7 @@ app.use(basicAuth); // Set available directories const directories = ["/tests/configs"]; -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/modules/calendar_spec.js b/tests/electron/modules/calendar_spec.js similarity index 98% rename from tests/e2e/modules/calendar_spec.js rename to tests/electron/modules/calendar_spec.js index 980eca58..b6420e83 100644 --- a/tests/e2e/modules/calendar_spec.js +++ b/tests/electron/modules/calendar_spec.js @@ -1,5 +1,5 @@ const helpers = require("../global-setup"); -const serverBasicAuth = require("../../servers/basic-auth.js"); +const serverBasicAuth = require("./basic-auth.js"); describe("Calendar module", function () { helpers.setupTimeout(this); diff --git a/tests/e2e/modules/mocks/index.js b/tests/electron/modules/mocks/index.js similarity index 100% rename from tests/e2e/modules/mocks/index.js rename to tests/electron/modules/mocks/index.js diff --git a/tests/e2e/modules/mocks/weather_current.js b/tests/electron/modules/mocks/weather_current.js similarity index 87% rename from tests/e2e/modules/mocks/weather_current.js rename to tests/electron/modules/mocks/weather_current.js index a0c3401d..c466129a 100644 --- a/tests/e2e/modules/mocks/weather_current.js +++ b/tests/electron/modules/mocks/weather_current.js @@ -1,5 +1,9 @@ const _ = require("lodash"); +/** + * @param {object} extendedData extra data to add to the default mock data + * @returns {string} mocked current weather data + */ function generateWeather(extendedData = {}) { return JSON.stringify( _.merge( diff --git a/tests/e2e/modules/mocks/weather_forecast.js b/tests/electron/modules/mocks/weather_forecast.js similarity index 95% rename from tests/e2e/modules/mocks/weather_forecast.js rename to tests/electron/modules/mocks/weather_forecast.js index eaf2e375..4c0ef9c9 100644 --- a/tests/e2e/modules/mocks/weather_forecast.js +++ b/tests/electron/modules/mocks/weather_forecast.js @@ -1,5 +1,9 @@ const _ = require("lodash"); +/** + * @param {object} extendedData extra data to add to the default mock data + * @returns {string} mocked forecast weather data + */ function generateWeatherForecast(extendedData = {}) { return JSON.stringify( _.merge( diff --git a/tests/e2e/modules/weather_spec.js b/tests/electron/modules/weather_spec.js similarity index 95% rename from tests/e2e/modules/weather_spec.js rename to tests/electron/modules/weather_spec.js index 5698dc6a..6be9d6e2 100644 --- a/tests/e2e/modules/weather_spec.js +++ b/tests/electron/modules/weather_spec.js @@ -12,6 +12,11 @@ describe("Weather module", function () { helpers.setupTimeout(this); + /** + * + * @param {object} responses mocked data to be returned + * @returns {Promise} Resolved once the electron app is started + */ async function setup(responses) { app = await helpers.startApplication({ args: ["js/electron.js"], @@ -23,10 +28,20 @@ describe("Weather module", function () { app.client.setupStub(); } + /** + * + * @param {string} element css selector + * @returns {Promise} Promise with the element once it is rendered + */ async function getElement(element) { return await app.client.$(element); } + /** + * @param {string} element css selector + * @param {string} result Expected text in given selector + * @returns {Promise} Promise with True if the text matches + */ async function getText(element, result) { const elem = await getElement(element); return await elem.getText(element).then(function (text) { diff --git a/tests/unit/classes/translator_spec.js b/tests/unit/classes/translator_spec.js index fe942753..09e14f20 100644 --- a/tests/unit/classes/translator_spec.js +++ b/tests/unit/classes/translator_spec.js @@ -67,6 +67,9 @@ describe("Translator", function () { Fallback: "core fallback" }; + /** + * @param {object} Translator the global Translator object + */ function setTranslations(Translator) { Translator.translations = translations; Translator.coreTranslations = coreTranslations; diff --git a/tests/unit/functions/updatenotification_spec.js b/tests/unit/functions/updatenotification_spec.js new file mode 100644 index 00000000..f6214c1a --- /dev/null +++ b/tests/unit/functions/updatenotification_spec.js @@ -0,0 +1,126 @@ +const path = require("path"); +const git_Helper = require("../../../modules/default/updatenotification/git_helper.js"); +const gitHelper = new git_Helper.gitHelper(); +gitHelper.add("default"); + +const test1 = { + module: "test1", + folder: "", + res: { + stdout: "## master...origin/master [behind 8]", + stderr: "" + }, + gitInfo: { + module: "default", + // commits behind: + behind: 0, + // branch name: + current: "develop", + // current hash: + hash: "", + // remote branch: + tracking: "", + isBehindInStatus: false + } +}; + +const test2 = { + module: "test2", + folder: "", + res: { + stdout: "## develop...origin/develop", + stderr: "" + } +}; + +const test3 = { + module: "test3", + folder: "", + res: { + stdout: "", + stderr: "error" + }, + gitInfo: { + module: "default", + // commits behind: + behind: 2, + // branch name: + current: "develop", + // current hash: + hash: "", + // remote branch: + tracking: "", + isBehindInStatus: true + } +}; + +const test4 = { + module: "default", + folder: path.join(__dirname, "../../.."), + res: { + stdout: "", + stderr: " e40ddd4..06389e3 develop -> origin/develop" + }, + gitInfo: { + module: "default", + // commits behind: + behind: 0, + // branch name: + current: "develop", + // current hash: + hash: "", + // remote branch: + tracking: "", + isBehindInStatus: false + } +}; + +describe("Updatenotification", function () { + it("should return valid output for git status", async function () { + const arr = await gitHelper.getStatus(); + expect(arr.length).toBe(1); + const gitInfo = arr[0]; + expect(gitInfo.current).not.toBe(""); + expect(gitInfo.hash).not.toBe(""); + }, 15000); + + it("should return behind=8 for test1", async function () { + const gitInfo = await gitHelper.getStatusInfo(test1); + expect(gitInfo.behind).toBe(8); + expect(gitInfo.isBehindInStatus).toBe(true); + }); + + it("should return behind=0 for test2", async function () { + const gitInfo = await gitHelper.getStatusInfo(test2); + expect(gitInfo.behind).toBe(0); + expect(gitInfo.isBehindInStatus).toBe(false); + }); + + it("should return empty status object for test3", async function () { + const gitInfo = await gitHelper.getStatusInfo(test3); + expect(gitInfo).toBe(undefined); + }); + + it("should return empty repo object for test2", async function () { + // no gitInfo provided in res, so returns undefined + const gitInfo = await gitHelper.getRepoInfo(test2); + expect(gitInfo).toBe(undefined); + }); + + it("should return empty repo object for test1", async function () { + // no regex match for refs in empty string, so returns undefined + const gitInfo = await gitHelper.getRepoInfo(test1); + expect(gitInfo).toBe(undefined); + }); + + it("should return empty repo object for test4", async function () { + // git ref list throws error, so returns undefined + const gitInfo = await gitHelper.getRepoInfo(test4); + expect(gitInfo).toBe(undefined); + }); + + it("should return behind=2 for test3", async function () { + const gitInfo = await gitHelper.getRepoInfo(test3); + expect(gitInfo.behind).toBe(2); + }); +}); diff --git a/tests/unit/functions/weather_object_spec.js b/tests/unit/functions/weather_object_spec.js new file mode 100644 index 00000000..c8c0faa6 --- /dev/null +++ b/tests/unit/functions/weather_object_spec.js @@ -0,0 +1,31 @@ +const WeatherObject = require("../../../modules/default/weather/weatherobject.js"); + +global.moment = require("moment-timezone"); +global.SunCalc = require("suncalc"); + +describe("WeatherObject", function () { + let originalTimeZone; + let weatherobject; + + beforeAll(function () { + originalTimeZone = moment.tz.guess(); + moment.tz.setDefault("Africa/Dar_es_Salaam"); + weatherobject = new WeatherObject("metric", "metric", "metric", true); + }); + + it("should return true for daytime at noon", function () { + weatherobject.date = moment(12, "HH"); + weatherobject.updateSunTime(-6.774877582342688, 37.63345667023327); + expect(weatherobject.isDayTime()).toBe(true); + }); + + it("should return false for daytime at midnight", function () { + weatherobject.date = moment(0, "HH"); + weatherobject.updateSunTime(-6.774877582342688, 37.63345667023327); + expect(weatherobject.isDayTime()).toBe(false); + }); + + afterAll(function () { + moment.tz.setDefault(originalTimeZone); + }); +}); diff --git a/tests/unit/global_vars/defaults_modules_spec.js b/tests/unit/global_vars/defaults_modules_spec.js index c0a7f0e4..490a2510 100644 --- a/tests/unit/global_vars/defaults_modules_spec.js +++ b/tests/unit/global_vars/defaults_modules_spec.js @@ -1,47 +1,14 @@ const fs = require("fs"); const path = require("path"); -const vm = require("vm"); -const basedir = path.join(__dirname, "../../.."); - -beforeAll(function () { - const fileName = "js/app.js"; - const filePath = path.join(basedir, fileName); - const code = fs.readFileSync(filePath); - - sandbox = { - module: {}, - __dirname: path.dirname(filePath), - global: {}, - process: { - on: function () {}, - env: {} - } - }; - - sandbox.require = function (filename) { - // This modifies the global slightly, - // but supplies vm with essential code - if (filename === "logger") { - return require("../mocks/logger.js"); - } else { - try { - return require(filename); - } catch { - // ignore - } - } - }; - - vm.runInNewContext(code, sandbox, fileName); -}); +const root_path = path.join(__dirname, "../../.."); describe("Default modules set in modules/default/defaultmodules.js", function () { const expectedDefaultModules = require("../../../modules/default/defaultmodules"); for (const defaultModule of expectedDefaultModules) { it(`contains a folder for modules/default/${defaultModule}"`, function () { - expect(fs.existsSync(path.join(sandbox.global.root_path, "modules/default", defaultModule))).toBe(true); + expect(fs.existsSync(path.join(root_path, "modules/default", defaultModule))).toBe(true); }); } }); diff --git a/tests/unit/global_vars/root_path_spec.js b/tests/unit/global_vars/root_path_spec.js index 591f3ddb..1f86082b 100644 --- a/tests/unit/global_vars/root_path_spec.js +++ b/tests/unit/global_vars/root_path_spec.js @@ -1,47 +1,15 @@ const fs = require("fs"); const path = require("path"); -const vm = require("vm"); -beforeAll(function () { - const basedir = path.join(__dirname, "../../.."); - - const fileName = "js/app.js"; - const filePath = path.join(basedir, fileName); - const code = fs.readFileSync(filePath); - - sandbox = { - module: {}, - __dirname: path.dirname(filePath), - global: {}, - process: { - on: function () {}, - env: {} - } - }; - - sandbox.require = function (filename) { - // This modifies the global slightly, - // but supplies vm with essential code - if (filename === "logger") { - return require("../mocks/logger.js"); - } else { - try { - return require(filename); - } catch { - // ignore - } - } - }; - - vm.runInNewContext(code, sandbox, fileName); -}); +const root_path = path.join(__dirname, "../../.."); +const version = require(`${__dirname}/../../../package.json`).version; describe("'global.root_path' set in js/app.js", function () { const expectedSubPaths = ["modules", "serveronly", "js", "js/app.js", "js/main.js", "js/electron.js", "config"]; expectedSubPaths.forEach((subpath) => { it(`contains a file/folder "${subpath}"`, function () { - expect(fs.existsSync(path.join(sandbox.global.root_path, subpath))).toBe(true); + expect(fs.existsSync(path.join(root_path, subpath))).toBe(true); }); }); @@ -55,6 +23,6 @@ describe("'global.root_path' set in js/app.js", function () { it("should expect the global.version equals package.json file", function () { const versionPackage = JSON.parse(fs.readFileSync("package.json", "utf8")).version; - expect(sandbox.global.version).toBe(versionPackage); + expect(version).toBe(versionPackage); }); }); diff --git a/tests/unit/mocks/logger.js b/tests/unit/mocks/logger.js deleted file mode 100644 index 56b5b123..00000000 --- a/tests/unit/mocks/logger.js +++ /dev/null @@ -1,20 +0,0 @@ -(function (root, factory) { - // Node, CommonJS-like - module.exports = factory(root.config); -})(this, function (config) { - let logLevel = { - debug: function () {}, - log: function () {}, - info: function () {}, - warn: function () {}, - error: function () {}, - group: function () {}, - groupCollapsed: function () {}, - groupEnd: function () {}, - time: function () {}, - timeEnd: function () {}, - timeStamp: function () {} - }; - - return logLevel; -}); diff --git a/translations/translations.js b/translations/translations.js index cddd3b74..85182053 100644 --- a/translations/translations.js +++ b/translations/translations.js @@ -5,7 +5,7 @@ * MIT Licensed. */ -var translations = { +let translations = { en: "translations/en.json", // English nl: "translations/nl.json", // Dutch de: "translations/de.json", // German diff --git a/vendor/css/font-awesome.css b/vendor/css/font-awesome.css index 2ba4a708..0c52aa67 100644 --- a/vendor/css/font-awesome.css +++ b/vendor/css/font-awesome.css @@ -1,2 +1,2 @@ @import url("../node_modules/@fortawesome/fontawesome-free/css/all.min.css"); -@import url("../node_modules/@fortawesome/fontawesome-free/css/v4-shims.min.css"); \ No newline at end of file +@import url("../node_modules/@fortawesome/fontawesome-free/css/v4-shims.min.css"); diff --git a/vendor/package-lock.json b/vendor/package-lock.json index d20a096e..8654c60b 100644 --- a/vendor/package-lock.json +++ b/vendor/package-lock.json @@ -1,150 +1,154 @@ { - "name": "magicmirror-vendors", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "magicmirror-vendors", - "license": "MIT", - "dependencies": { - "@fortawesome/fontawesome-free": "^5.15.3", - "moment": "^2.29.1", - "moment-timezone": "^0.5.33", - "nunjucks": "^3.2.3", - "suncalc": "^1.8.0", - "weathericons": "^2.1.0" - } - }, - "node_modules/@fortawesome/fontawesome-free": { - "version": "5.15.3", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.3.tgz", - "integrity": "sha512-rFnSUN/QOtnOAgqFRooTA3H57JLDm0QEG/jPdk+tLQNL/eWd+Aok8g3qCI+Q1xuDPWpGW/i9JySpJVsq8Q0s9w==" - }, - "node_modules/a-sync-waterfall": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", - "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==" - }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" - }, - "node_modules/commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", - "engines": { - "node": "*" - } - }, - "node_modules/moment-timezone": { - "version": "0.5.33", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.33.tgz", - "integrity": "sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w==", - "dependencies": { - "moment": ">= 2.9.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/nunjucks": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.3.tgz", - "integrity": "sha512-psb6xjLj47+fE76JdZwskvwG4MYsQKXUtMsPh6U0YMvmyjRtKRFcxnlXGWglNybtNTNVmGdp94K62/+NjF5FDQ==", - "dependencies": { - "a-sync-waterfall": "^1.0.0", - "asap": "^2.0.3", - "commander": "^5.1.0" - }, - "bin": { - "nunjucks-precompile": "bin/precompile" - }, - "engines": { - "node": ">= 6.9.0" - }, - "peerDependencies": { - "chokidar": "^3.3.0" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/suncalc": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/suncalc/-/suncalc-1.8.0.tgz", - "integrity": "sha1-HZiYEJVjB4dQ9JlKlZ5lTYdqy/U=" - }, - "node_modules/weathericons": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/weathericons/-/weathericons-2.1.0.tgz", - "integrity": "sha1-dFOho14gAkXjiftQd9Un7/MLc7Q=" - } - }, - "dependencies": { - "@fortawesome/fontawesome-free": { - "version": "5.15.3", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.3.tgz", - "integrity": "sha512-rFnSUN/QOtnOAgqFRooTA3H57JLDm0QEG/jPdk+tLQNL/eWd+Aok8g3qCI+Q1xuDPWpGW/i9JySpJVsq8Q0s9w==" - }, - "a-sync-waterfall": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", - "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==" - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" - }, - "commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==" - }, - "moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" - }, - "moment-timezone": { - "version": "0.5.33", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.33.tgz", - "integrity": "sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w==", - "requires": { - "moment": ">= 2.9.0" - } - }, - "nunjucks": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.3.tgz", - "integrity": "sha512-psb6xjLj47+fE76JdZwskvwG4MYsQKXUtMsPh6U0YMvmyjRtKRFcxnlXGWglNybtNTNVmGdp94K62/+NjF5FDQ==", - "requires": { - "a-sync-waterfall": "^1.0.0", - "asap": "^2.0.3", - "commander": "^5.1.0" - } - }, - "suncalc": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/suncalc/-/suncalc-1.8.0.tgz", - "integrity": "sha1-HZiYEJVjB4dQ9JlKlZ5lTYdqy/U=" - }, - "weathericons": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/weathericons/-/weathericons-2.1.0.tgz", - "integrity": "sha1-dFOho14gAkXjiftQd9Un7/MLc7Q=" - } - } + "name": "magicmirror-vendors", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "magicmirror-vendors", + "license": "MIT", + "dependencies": { + "@fortawesome/fontawesome-free": "^5.15.4", + "moment": "^2.29.1", + "moment-timezone": "^0.5.33", + "nunjucks": "^3.2.3", + "suncalc": "^1.8.0", + "weathericons": "^2.1.0" + } + }, + "node_modules/@fortawesome/fontawesome-free": { + "version": "5.15.4", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz", + "integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg==", + "hasInstallScript": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/a-sync-waterfall": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", + "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==" + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", + "engines": { + "node": "*" + } + }, + "node_modules/moment-timezone": { + "version": "0.5.33", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.33.tgz", + "integrity": "sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w==", + "dependencies": { + "moment": ">= 2.9.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/nunjucks": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.3.tgz", + "integrity": "sha512-psb6xjLj47+fE76JdZwskvwG4MYsQKXUtMsPh6U0YMvmyjRtKRFcxnlXGWglNybtNTNVmGdp94K62/+NjF5FDQ==", + "dependencies": { + "a-sync-waterfall": "^1.0.0", + "asap": "^2.0.3", + "commander": "^5.1.0" + }, + "bin": { + "nunjucks-precompile": "bin/precompile" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "chokidar": "^3.3.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/suncalc": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/suncalc/-/suncalc-1.8.0.tgz", + "integrity": "sha1-HZiYEJVjB4dQ9JlKlZ5lTYdqy/U=" + }, + "node_modules/weathericons": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/weathericons/-/weathericons-2.1.0.tgz", + "integrity": "sha1-dFOho14gAkXjiftQd9Un7/MLc7Q=" + } + }, + "dependencies": { + "@fortawesome/fontawesome-free": { + "version": "5.15.4", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz", + "integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg==" + }, + "a-sync-waterfall": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", + "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==" + }, + "moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + }, + "moment-timezone": { + "version": "0.5.33", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.33.tgz", + "integrity": "sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w==", + "requires": { + "moment": ">= 2.9.0" + } + }, + "nunjucks": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.3.tgz", + "integrity": "sha512-psb6xjLj47+fE76JdZwskvwG4MYsQKXUtMsPh6U0YMvmyjRtKRFcxnlXGWglNybtNTNVmGdp94K62/+NjF5FDQ==", + "requires": { + "a-sync-waterfall": "^1.0.0", + "asap": "^2.0.3", + "commander": "^5.1.0" + } + }, + "suncalc": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/suncalc/-/suncalc-1.8.0.tgz", + "integrity": "sha1-HZiYEJVjB4dQ9JlKlZ5lTYdqy/U=" + }, + "weathericons": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/weathericons/-/weathericons-2.1.0.tgz", + "integrity": "sha1-dFOho14gAkXjiftQd9Un7/MLc7Q=" + } + } } diff --git a/vendor/package.json b/vendor/package.json index a52af548..3b0c802b 100755 --- a/vendor/package.json +++ b/vendor/package.json @@ -1,20 +1,20 @@ { - "name": "magicmirror-vendors", - "description": "Package for vendors use by MagicMirror Core.", - "repository": { - "type": "git", - "url": "git+https://github.com/MichMich/MagicMirror.git" - }, - "license": "MIT", - "bugs": { - "url": "https://github.com/MichMich/MagicMirror/issues" - }, - "dependencies": { - "@fortawesome/fontawesome-free": "^5.15.3", - "moment": "^2.29.1", - "moment-timezone": "^0.5.33", - "nunjucks": "^3.2.3", - "suncalc": "^1.8.0", - "weathericons": "^2.1.0" - } + "name": "magicmirror-vendors", + "description": "Package for vendors use by MagicMirror Core.", + "repository": { + "type": "git", + "url": "git+https://github.com/MichMich/MagicMirror.git" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/MichMich/MagicMirror/issues" + }, + "dependencies": { + "@fortawesome/fontawesome-free": "^5.15.4", + "moment": "^2.29.1", + "moment-timezone": "^0.5.33", + "nunjucks": "^3.2.3", + "suncalc": "^1.8.0", + "weathericons": "^2.1.0" + } }